mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2026-01-27 08:38:15 +00:00
插件支持任意网页拖放安装
This commit is contained in:
parent
db9f96baad
commit
5d15ddefe5
@ -55,3 +55,4 @@ export function useCool() {
|
||||
// 导出其他模块的功能
|
||||
export * from './browser';
|
||||
export * from './hmr';
|
||||
export * from './mitt';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Mitt, { type Emitter } from 'mitt';
|
||||
import { hmr } from './hmr';
|
||||
|
||||
const mitt: Emitter<any> = hmr.getData('mitt', Mitt());
|
||||
export const mitt: Emitter<any> = hmr.getData('mitt', Mitt());
|
||||
|
||||
// 返回 mitt 实例,用于在应用中进行事件的发布和订阅
|
||||
export function useMitt() {
|
||||
|
||||
@ -42,6 +42,7 @@ function toCode() {
|
||||
animation-fill-mode: forwards;
|
||||
-webkit-text-size-adjust: none;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.t2 {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { usePlugin } from './hooks';
|
||||
import { type ModuleConfig } from '/@/cool';
|
||||
|
||||
export default (): ModuleConfig => {
|
||||
@ -20,6 +21,10 @@ export default (): ModuleConfig => {
|
||||
},
|
||||
component: () => import('./views/ai-code.vue')
|
||||
}
|
||||
]
|
||||
],
|
||||
onLoad() {
|
||||
const { register } = usePlugin();
|
||||
register();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export * from './menu';
|
||||
export * from './plugin';
|
||||
|
||||
118
src/modules/helper/hooks/plugin.ts
Normal file
118
src/modules/helper/hooks/plugin.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { mitt, router, service } from '/@/cool';
|
||||
import { t } from '/@/plugins/i18n';
|
||||
|
||||
export const usePlugin = () => {
|
||||
function getName(file: File) {
|
||||
return file.name.replace('.cool', '');
|
||||
}
|
||||
|
||||
// 注册
|
||||
function register() {
|
||||
document.body.addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
});
|
||||
document.body.addEventListener('drop', e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (e.dataTransfer) {
|
||||
const file = e.dataTransfer.files[0];
|
||||
|
||||
ElMessageBox.confirm(
|
||||
t('检测到插件「{name}」,是否安装?', { name: getName(file) }),
|
||||
t('提示'),
|
||||
{
|
||||
type: 'warning',
|
||||
confirmButtonText: t('安装')
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
install(file);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 安装
|
||||
function install(file: File) {
|
||||
const next = (force: boolean) => {
|
||||
const data = new FormData();
|
||||
|
||||
data.append('files', file);
|
||||
data.append('force', String(force));
|
||||
|
||||
service.plugin.info
|
||||
.request({
|
||||
url: '/install',
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
// 发送事件
|
||||
mitt.emit('plugin.refresh');
|
||||
|
||||
// 标题
|
||||
const title = t('插件「{name}」安装成功', { name: getName(file) });
|
||||
|
||||
// 是否插件页面
|
||||
if (router.currentRoute.value.path == '/helper/plugins') {
|
||||
ElMessage.success(title);
|
||||
} else {
|
||||
ElMessageBox.alert(title, t('提示'), {
|
||||
type: 'success',
|
||||
confirmButtonText: t('点击查看'),
|
||||
showCancelButton: true
|
||||
})
|
||||
.then(() => {
|
||||
router.push('/helper/plugins');
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.type == 0) {
|
||||
ElMessageBox.confirm(res.message, t('提示'), {
|
||||
type: 'error',
|
||||
showConfirmButton: false
|
||||
})
|
||||
.then(() => {
|
||||
next(true);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
if (res.type == 1 || res.type == 2) {
|
||||
ElMessageBox.confirm(res.message, t('提示'), {
|
||||
type: 'warning',
|
||||
confirmButtonText: t('继续')
|
||||
})
|
||||
.then(() => {
|
||||
next(true);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
if (res.type == 3) {
|
||||
next(true);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
ElMessage.error(err.message);
|
||||
});
|
||||
};
|
||||
|
||||
next(false);
|
||||
}
|
||||
|
||||
return {
|
||||
register,
|
||||
install
|
||||
};
|
||||
};
|
||||
@ -1,64 +1,66 @@
|
||||
{
|
||||
"搜索插件名称": "Search Plugin Name",
|
||||
"后端": "Backend",
|
||||
"未知": "Unknown",
|
||||
"暂无描述": "No description yet",
|
||||
"示例": "Example",
|
||||
"预览": "Preview",
|
||||
"文档": "Documentation",
|
||||
"图片预览": "Image Preview",
|
||||
"说明文档": "Instruction Document",
|
||||
"作者": "Author",
|
||||
"更新时间": "Update Time",
|
||||
"格式化": "Format",
|
||||
"插入文件链接": "Insert File Link",
|
||||
"已安装": "Installed",
|
||||
"全部插件": "All Plugins",
|
||||
"插件开发": "Plugin Development",
|
||||
"插件安装成功": "Plugin Installed Successfully",
|
||||
"提示": "Tip",
|
||||
"继续": "Continue",
|
||||
"确定要卸载插件【{name}】吗?": "Are you sure you want to uninstall the plugin [{name}]?",
|
||||
"卸载成功": "Uninstall success",
|
||||
"启用成功": "Enable success",
|
||||
"禁用成功": "Disable success",
|
||||
"参数格式错误": "Parameter format error",
|
||||
"设置": "Settings",
|
||||
"参数": "Parameter",
|
||||
"修改成功": "Modify success",
|
||||
"检测到插件,是否安装": "Plugin detected. Install?",
|
||||
"安装": "Install",
|
||||
"确定要退出编码吗?": "Are you sure you want to exit encoding?",
|
||||
"创建目录:{name}": "Create directory: {name}",
|
||||
"创建菜单:{name}": "Create menu: {name}",
|
||||
"创建 Node 文件": "Create Node file",
|
||||
"正在重启服务": "Restarting service",
|
||||
"创建 Vue 文件": "Create Vue file",
|
||||
"自动添加": "Auto add",
|
||||
"权限名称": "Permission name",
|
||||
"实体数据": "Entity data",
|
||||
"自动添加权限": "Auto add permission",
|
||||
"一键添加": "Add in one click",
|
||||
"权限列表": "Permission List",
|
||||
"请选择实体数据": "Please Select Entity Data",
|
||||
"请填写权限名称": "Please Fill in Permission Name",
|
||||
"请至少选择一个权限": "Please Select at Least One Permission",
|
||||
"添加权限成功": "Permission Added Successfully",
|
||||
"快速创建": "Quick Create",
|
||||
"请选择数据结构": "Please Select Data Structure",
|
||||
"数据结构": "Data Structure",
|
||||
"上级节点": "Parent Node",
|
||||
"请选择上级节点": "Please Select Parent Node",
|
||||
"菜单名称": "Menu Name",
|
||||
"请输入菜单名称": "Please Enter Menu Name",
|
||||
"菜单路由": "Menu Route",
|
||||
"请输入菜单路由,如:/test": "Please Enter Menu Route, e.g.: /test",
|
||||
"必须以 / 开头": "Must Start with /",
|
||||
"菜单排序": "Menu Sort",
|
||||
"请填写菜单排序": "Please Fill in Menu Sort",
|
||||
"菜单图标": "Menu Icon",
|
||||
"请选择图标": "Please Select Icon",
|
||||
"路由缓存": "Route Cache",
|
||||
"开始创建": "Start Creation",
|
||||
"极速编码": "Fast Encoding"
|
||||
}
|
||||
"请选择图标": "Please select an icon",
|
||||
"路由缓存": "Routing cache",
|
||||
"开始创建": "Start creating",
|
||||
"AI极速编码": "AI Coding",
|
||||
"搜索插件名称": "Search plugin name",
|
||||
"后端": "Backend",
|
||||
"未知": "Unknown",
|
||||
"暂无描述": "No description available",
|
||||
"示例": "Example",
|
||||
"预览": "Preview",
|
||||
"文档": "Documentation",
|
||||
"图片预览": "Image preview",
|
||||
"说明文档": "Instruction document",
|
||||
"作者": "Author",
|
||||
"更新时间": "Update time",
|
||||
"格式化": "Formatting",
|
||||
"插入文件链接": "Insert file link",
|
||||
"已安装": "Installed",
|
||||
"全部插件": "All plugins",
|
||||
"插件开发": "Plugin development",
|
||||
"确定要卸载插件【{name}】吗?": "Are you sure you want to uninstall the plugin [{name}]?",
|
||||
"提示": "Prompt",
|
||||
"卸载成功": "Uninstallation successful",
|
||||
"启用成功": "Enablement successful",
|
||||
"禁用成功": "Disable successfully",
|
||||
"参数格式错误": "Parameter format error",
|
||||
"设置": "Settings",
|
||||
"参数": "Parameter",
|
||||
"修改成功": "Modify successfully",
|
||||
"确定要退出编码吗?": "Are you sure you want to exit the encoding?",
|
||||
"创建目录:{name}": "Create directory: {name}",
|
||||
"创建菜单:{name}": "Create menu: {name}",
|
||||
"创建 Java 文件": "Create Java file",
|
||||
"创建 Node 文件": "Create Node file",
|
||||
"正在重启服务": "Restarting service",
|
||||
"创建 Vue 文件": "Create Vue file",
|
||||
"检测到插件「{name}」,是否安装?": "Plugin 「{name}」 detected. Do you want to install it?",
|
||||
"安装": "Install",
|
||||
"插件「{name}」安装成功": "Plugin 「{name}」 installed successfully",
|
||||
"点击查看": "Click to view",
|
||||
"继续": "Continue",
|
||||
"自动添加": "Automatically add",
|
||||
"权限名称": "Permission name",
|
||||
"实体数据": "Entity data",
|
||||
"自动添加权限": "Automatically add permissions",
|
||||
"一键添加": "Add in one click",
|
||||
"权限列表": "Permission list",
|
||||
"请选择实体数据": "Please select entity data",
|
||||
"请填写权限名称": "Please fill in the permission name",
|
||||
"请至少选择一个权限": "Please select at least one permission",
|
||||
"添加权限成功": "Successfully added permissions",
|
||||
"快速创建": "Quick creation",
|
||||
"请选择数据结构": "Please select the data structure",
|
||||
"数据结构": "Data structure",
|
||||
"上级节点": "Parent node",
|
||||
"请选择上级节点": "Please select the parent node",
|
||||
"菜单名称": "Menu name",
|
||||
"请输入菜单名称": "Please enter the menu name",
|
||||
"菜单路由": "Menu route",
|
||||
"请输入菜单路由,如:/test": "Please enter the menu route, e.g.: /test",
|
||||
"必须以 / 开头": "Must start with /",
|
||||
"菜单排序": "Menu sorting",
|
||||
"请填写菜单排序": "Please fill in the menu sorting",
|
||||
"菜单图标": "Menu icon"
|
||||
}
|
||||
|
||||
@ -15,10 +15,8 @@
|
||||
"已安装": "已安装",
|
||||
"全部插件": "全部插件",
|
||||
"插件开发": "插件开发",
|
||||
"插件安装成功": "插件安装成功",
|
||||
"提示": "提示",
|
||||
"继续": "继续",
|
||||
"确定要卸载插件【{name}】吗?": "确定要卸载插件【{name}】吗?",
|
||||
"提示": "提示",
|
||||
"卸载成功": "卸载成功",
|
||||
"启用成功": "启用成功",
|
||||
"禁用成功": "禁用成功",
|
||||
@ -26,14 +24,18 @@
|
||||
"设置": "设置",
|
||||
"参数": "参数",
|
||||
"修改成功": "修改成功",
|
||||
"检测到插件,是否安装": "检测到插件,是否安装",
|
||||
"安装": "安装",
|
||||
"确定要退出编码吗?": "确定要退出编码吗?",
|
||||
"创建目录:{name}": "创建目录:{name}",
|
||||
"创建菜单:{name}": "创建菜单:{name}",
|
||||
"创建 Java 文件": "创建 Java 文件",
|
||||
"创建 Node 文件": "创建 Node 文件",
|
||||
"正在重启服务": "正在重启服务",
|
||||
"创建 Vue 文件": "创建 Vue 文件",
|
||||
"检测到插件「{name}」,是否安装?": "检测到插件「{name}」,是否安装?",
|
||||
"安装": "安装",
|
||||
"插件「{name}」安装成功": "插件「{name}」安装成功",
|
||||
"点击查看": "点击查看",
|
||||
"继续": "继续",
|
||||
"自动添加": "自动添加",
|
||||
"权限名称": "权限名称",
|
||||
"实体数据": "实体数据",
|
||||
@ -60,5 +62,5 @@
|
||||
"请选择图标": "请选择图标",
|
||||
"路由缓存": "路由缓存",
|
||||
"开始创建": "开始创建",
|
||||
"极速编码": "极速编码"
|
||||
"AI极速编码": "AI极速编码"
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
{
|
||||
"请选择图标": "請選擇圖標",
|
||||
"路由缓存": "路由緩存",
|
||||
"开始创建": "開始創建",
|
||||
"极速编码": "極速編碼",
|
||||
"AI极速编码": "AI極速編碼",
|
||||
"搜索插件名称": "搜尋插件名稱",
|
||||
"后端": "後端",
|
||||
"未知": "未知",
|
||||
@ -17,10 +19,8 @@
|
||||
"已安装": "已安裝",
|
||||
"全部插件": "全部插件",
|
||||
"插件开发": "插件開發",
|
||||
"插件安装成功": "插件安裝成功",
|
||||
"提示": "提示",
|
||||
"继续": "繼續",
|
||||
"确定要卸载插件【{name}】吗?": "確定要卸載插件【{name}】嗎?",
|
||||
"提示": "提示",
|
||||
"卸载成功": "卸載成功",
|
||||
"启用成功": "啟用成功",
|
||||
"禁用成功": "禁用成功",
|
||||
@ -28,14 +28,18 @@
|
||||
"设置": "設置",
|
||||
"参数": "參數",
|
||||
"修改成功": "修改成功",
|
||||
"检测到插件,是否安装": "檢測到插件,是否安裝",
|
||||
"安装": "安裝",
|
||||
"确定要退出编码吗?": "確定要退出編碼嗎?",
|
||||
"创建目录:{name}": "創建目錄:{name}",
|
||||
"创建菜单:{name}": "創建菜單:{name}",
|
||||
"创建 Java 文件": "創建 Java 文件",
|
||||
"创建 Node 文件": "創建 Node 文件",
|
||||
"正在重启服务": "正在重啟服務",
|
||||
"创建 Vue 文件": "創建 Vue 文件",
|
||||
"检测到插件「{name}」,是否安装?": "檢測到插件「{name}」,是否安裝?",
|
||||
"安装": "安裝",
|
||||
"插件「{name}」安装成功": "插件「{name}」安裝成功",
|
||||
"点击查看": "點擊查看",
|
||||
"继续": "繼續",
|
||||
"自动添加": "自動添加",
|
||||
"权限名称": "權限名稱",
|
||||
"实体数据": "實體數據",
|
||||
@ -58,7 +62,5 @@
|
||||
"必须以 / 开头": "必須以 / 開頭",
|
||||
"菜单排序": "菜單排序",
|
||||
"请填写菜单排序": "請填寫菜單排序",
|
||||
"菜单图标": "菜單圖標",
|
||||
"请选择图标": "請選擇圖標",
|
||||
"路由缓存": "路由緩存"
|
||||
"菜单图标": "菜單圖標"
|
||||
}
|
||||
@ -27,8 +27,6 @@
|
||||
:class="{
|
||||
'is-installed': isInstalled
|
||||
}"
|
||||
@dragover="onDragover"
|
||||
@drop="onDrop"
|
||||
@mousemove="onMousemove"
|
||||
>
|
||||
<el-row :gutter="10">
|
||||
@ -279,6 +277,7 @@ import {
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { marked } from 'marked';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { usePlugin } from '../hooks';
|
||||
|
||||
interface Plugin {
|
||||
name?: string;
|
||||
@ -297,9 +296,10 @@ interface Plugin {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const { router, service, refs, setRefs } = useCool();
|
||||
const { router, service, refs, setRefs, mitt } = useCool();
|
||||
const helper = module.get('helper');
|
||||
const { t } = useI18n();
|
||||
const { install } = usePlugin();
|
||||
|
||||
// 选项卡
|
||||
const tab = reactive({
|
||||
@ -354,66 +354,15 @@ const plugin = reactive({
|
||||
// 初始化
|
||||
init() {
|
||||
plugin.refresh();
|
||||
},
|
||||
|
||||
// 安装
|
||||
install(file: File) {
|
||||
const next = (force: boolean) => {
|
||||
const data = new FormData();
|
||||
// 移除事件
|
||||
mitt.off('plugin.refresh');
|
||||
|
||||
data.append('files', file);
|
||||
data.append('force', String(force));
|
||||
|
||||
service.plugin.info
|
||||
.request({
|
||||
url: '/install',
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
ElMessage.success(t('插件安装成功'));
|
||||
tab.change('installed');
|
||||
plugin.refresh();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.type == 0) {
|
||||
ElMessageBox.confirm(res.message, t('提示'), {
|
||||
type: 'error',
|
||||
showConfirmButton: false
|
||||
})
|
||||
.then(() => {
|
||||
next(true);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
if (res.type == 1 || res.type == 2) {
|
||||
ElMessageBox.confirm(res.message, t('提示'), {
|
||||
type: 'warning',
|
||||
confirmButtonText: t('继续')
|
||||
})
|
||||
.then(() => {
|
||||
next(true);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
if (res.type == 3) {
|
||||
next(true);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
ElMessage.error(err.message);
|
||||
});
|
||||
};
|
||||
|
||||
next(false);
|
||||
// 监听刷新事件
|
||||
mitt.on('plugin.refresh', () => {
|
||||
tab.change('installed');
|
||||
plugin.refresh();
|
||||
});
|
||||
},
|
||||
|
||||
// 卸载
|
||||
@ -786,33 +735,10 @@ const pic = reactive({
|
||||
|
||||
// 上传
|
||||
function onBeforeUpload(file: File) {
|
||||
plugin.install(file);
|
||||
install(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 拖拽
|
||||
function onDragover(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// 放下
|
||||
function onDrop(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
if (e.dataTransfer) {
|
||||
const file = e.dataTransfer.files[0];
|
||||
|
||||
ElMessageBox.confirm(t('检测到插件,是否安装'), t('提示'), {
|
||||
type: 'warning',
|
||||
confirmButtonText: t('安装')
|
||||
})
|
||||
.then(() => {
|
||||
plugin.install(file);
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标移动
|
||||
function onMousemove(e: MouseEvent) {
|
||||
if (!isInstalled.value) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user