调整模块为自动引入

This commit is contained in:
icssoa 2021-06-15 00:35:24 +08:00
parent 998456cc7e
commit 23e1ae9562
68 changed files with 404 additions and 554 deletions

View File

@ -1,6 +1,6 @@
{
"name": "front-next",
"version": "0.3.1",
"version": "0.4.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",
@ -17,7 +17,7 @@
"codemirror": "^5.60.0",
"core-js": "^3.6.5",
"echarts": "^5.0.2",
"element-plus": "^1.0.2-beta.45",
"element-plus": "^1.0.2-beta.48",
"file-saver": "^2.0.5",
"glob": "^7.1.6",
"js-beautify": "^1.13.5",

View File

@ -3,18 +3,6 @@ import "cl-admin-crud-vue3/dist/index.css";
export default {
modules: [
// 基础模块
"base",
// 文件上传
{
name: "upload",
options: {
icon: "el-icon-picture",
text: ""
}
},
// Excel 导出模块
"excel-export",
// crud 模块
{
name: "crud",
@ -29,16 +17,6 @@ export default {
}
}
}
},
// 客服聊天
"chat",
// 任务管理
"task",
// 复制指令
"copy",
// 示例页
"demo",
// 主题切换
"theme"
}
]
};

View File

@ -81,7 +81,7 @@ export default defineComponent({
//
function refresh() {
service.system.dept
service.base.system.dept
.list()
.then((res: any[]) => {
list.value = deepTree(res);

View File

@ -17,7 +17,7 @@ export default defineComponent({
// 刷新列表
async function refresh() {
return await service.system.dept.list().then(deepTree);
return await service.base.system.dept.list().then(deepTree);
}
// 转移
@ -52,7 +52,7 @@ export default defineComponent({
type: "warning"
})
.then(() => {
service.system.user
service.base.system.user
.move({
departmentId: id,
userIds: ids

View File

@ -113,7 +113,7 @@ export default defineComponent({
isDrag.value = false;
loading.value = true;
await service.system.dept.list().then((res: any[]) => {
await service.base.system.dept.list().then((res: any[]) => {
list.value = deepTree(res);
emit("list-change", list.value);
});
@ -181,7 +181,7 @@ export default defineComponent({
],
on: {
submit: (data: any, { done, close }: any) => {
service.system.dept[method]({
service.base.system.dept[method]({
id: e.id,
parentId: e.parentId,
name: data.name,
@ -204,7 +204,7 @@ export default defineComponent({
//
function rowDel(e: any) {
const del = async (f: boolean) => {
await service.system.dept
await service.base.system.dept
.delete({
ids: [e.id],
deleteUser: f
@ -261,7 +261,7 @@ export default defineComponent({
deep(list.value, null);
await service.system.dept
await service.base.system.dept
.order(
ids.map((e, i) => {
return {

View File

@ -11,6 +11,10 @@ import { isNumber } from "/@/core/utils";
export default defineComponent({
name: "icon-svg",
cool: {
global: true
},
props: {
name: {
type: String

View File

@ -1,39 +0,0 @@
import Avatar from "./avatar/index.vue";
import Scrollbar from "./scrollbar/index.vue";
import RouteNav from "./route-nav/index.vue";
import Process from "./process/index.vue";
import IconSvg from "./icon-svg/index.vue";
import DeptCheck from "./dept/check.vue";
import DeptMove from "./dept/move";
import DeptTree from "./dept/tree.vue";
import MenuSlider from "./menu/slider/index";
import MenuTopbar from "./menu/topbar.vue";
import MenuFile from "./menu/file.vue";
import MenuIcons from "./menu/icons.vue";
import MenuPerms from "./menu/perms.vue";
import MenuTree from "./menu/tree.vue";
import RoleSelect from "./role/select.vue";
import RolePerms from "./role/perms.vue";
import EditorQuill from "./editor-quill/index.vue";
import Codemirror from "./codemirror/index.vue";
export default {
Avatar,
Scrollbar,
RouteNav,
Process,
IconSvg,
DeptCheck,
DeptMove,
DeptTree,
MenuSlider,
MenuTopbar,
MenuFile,
MenuIcons,
MenuPerms,
MenuTree,
RoleSelect,
RolePerms,
EditorQuill,
Codemirror
};

View File

@ -70,7 +70,7 @@ export default defineComponent({
//
function refresh() {
service.system.menu.list().then((res: any) => {
service.base.system.menu.list().then((res: any) => {
const _list = res.filter((e: any) => e.type != 2);
_list.unshift({

View File

@ -85,7 +85,7 @@ export default defineComponent({
//
function refresh() {
service.system.menu
service.base.system.menu
.list()
.then((res: any[]) => {
list.value = deepTree(res);

View File

@ -45,7 +45,7 @@ export default defineComponent({
);
onMounted(async () => {
list.value = await service.system.role.list();
list.value = await service.base.system.role.list();
});
return {

View File

@ -1,7 +0,0 @@
import permission, { checkPerm } from "./permission";
export { checkPerm };
export default {
permission
};

View File

@ -33,12 +33,12 @@ function change(el: any, binding: any) {
}
export default {
inserted(el: any, binding: any) {
mounted(el: any, binding: any) {
el.setAttribute("_display", el.style.display || "");
change(el, binding);
},
update: change
updated: change
};
export { checkPerm };

View File

@ -1,11 +1,5 @@
import components from "./components";
import pages from "./pages";
import views from "./views";
import store from "./store";
import service from "./service";
import directives, { checkPerm } from "./directives";
import { checkPerm } from "./directives/permission";
import { iconList } from "./common";
import "./static/css/index.scss";
export { iconList, checkPerm };
export default { components, pages, views, store, service, directives };

View File

@ -6,6 +6,12 @@
import ErrorPage from "./components/error-page.vue";
export default {
cool: {
route: {
path: "/403"
}
},
components: {
ErrorPage
}

View File

@ -6,6 +6,12 @@
import ErrorPage from "./components/error-page.vue";
export default {
cool: {
route: {
path: "/404"
}
},
components: {
ErrorPage
}

View File

@ -6,6 +6,12 @@
import ErrorPage from "./components/error-page.vue";
export default {
cool: {
route: {
path: "/500"
}
},
components: {
ErrorPage
}

View File

@ -6,6 +6,12 @@
import ErrorPage from "./components/error-page.vue";
export default {
cool: {
route: {
path: "/502"
}
},
components: {
ErrorPage
}

View File

@ -1,22 +0,0 @@
export default [
{
path: "/403",
component: () => import("./error-page/403.vue")
},
{
path: "/404",
component: () => import("./error-page/404.vue")
},
{
path: "/500",
component: () => import("./error-page/500.vue")
},
{
path: "/502",
component: () => import("./error-page/502.vue")
},
{
path: "/login",
component: () => import("./login/index.vue")
}
];

View File

@ -18,7 +18,7 @@ export default defineComponent({
const service = inject<any>("service");
const refresh = () => {
service.open
service.base.open
.captcha({
height: 36,
width: 110

View File

@ -62,6 +62,12 @@ import Captcha from "./components/captcha.vue";
import { useRefs } from "/@/core";
export default defineComponent({
cool: {
route: {
path: "/login"
}
},
components: {
Captcha
},
@ -75,8 +81,8 @@ export default defineComponent({
//
const form = reactive({
username: "admin",
password: "123456",
username: "",
password: "",
captchaId: "",
verifyCode: ""
});

View File

@ -1,27 +0,0 @@
import Common from "./common";
import Open from "./open";
import SysUser from "./system/user";
import SysMenu from "./system/menu";
import SysRole from "./system/role";
import SysDept from "./system/dept";
import SysTask from "./system/task";
import SysParam from "./system/param";
import SysLog from "./system/log";
import PluginInfo from "./plugin/info";
export default {
common: new Common(),
open: new Open(),
system: {
user: new SysUser(),
menu: new SysMenu(),
role: new SysRole(),
dept: new SysDept(),
task: new SysTask(),
param: new SysParam(),
log: new SysLog()
},
plugin: {
info: new PluginInfo()
}
};

View File

@ -1,7 +0,0 @@
import user from "./user";
import app from "./app";
import process from "./process";
import module from "./module";
import menu from "./menu";
export default { user, app, process, module, menu };

View File

@ -85,7 +85,7 @@ const actions = {
// 监测自定义菜单
if (!getters.app.conf.customMenu) {
store.service.common
store.service.base.common
.permMenu()
.then((res: any) => {
next(res);

View File

@ -17,7 +17,7 @@ const getters = {
const actions = {
// 用户登录
userLogin({ commit }: any, form: any): Promise<any> {
return store.service.open.userLogin(form).then((res: Token) => {
return store.service.base.open.userLogin(form).then((res: Token) => {
commit("SET_TOKEN", res);
return res;
});
@ -25,13 +25,13 @@ const actions = {
// 用户退出
async userLogout({ dispatch }: any): Promise<any> {
await store.service.common.userLogout();
await store.service.base.common.userLogout();
return dispatch("userRemove");
},
// 用户信息
userInfo({ commit }: any): Promise<any> {
return store.service.common.userInfo().then((res: any) => {
return store.service.base.common.userInfo().then((res: any) => {
commit("SET_USERINFO", res);
return res;
});
@ -50,7 +50,7 @@ const actions = {
// 刷新token
refreshToken({ commit, dispatch }: any) {
return new Promise((resolve, reject) => {
store.service.open
store.service.base.open
.refreshToken(storage.get("refreshToken"))
.then((res: any) => {
commit("SET_TOKEN", res);

View File

@ -1,7 +0,0 @@
export default [
{
label: "个人中心",
path: "/my/info",
component: () => import("./info.vue")
}
];

View File

@ -30,6 +30,15 @@ import { useStore } from "vuex";
export default defineComponent({
name: "sys-info",
cool: {
route: {
path: "/my/info",
meta: {
label: "个人中心"
}
}
},
setup() {
const store = useStore();
const service = inject<any>("service");
@ -46,7 +55,7 @@ export default defineComponent({
saving.value = true;
await service.common
await service.base.common
.userUpdate({
headImg,
nickName,

View File

@ -4,7 +4,7 @@
<cl-refresh-btn />
<el-button
v-permission="service.system.log.permission.clear"
v-permission="service.base.system.log.permission.clear"
size="mini"
type="danger"
@click="clear"
@ -112,13 +112,13 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: CrudLoad) {
ctx.service(service.system.log).done();
ctx.service(service.base.system.log).done();
app.refresh();
}
//
function saveDay() {
service.system.log.setKeep(day.value).then(() => {
service.base.system.log.setKeep(day.value).then(() => {
ElMessage.success("保存成功");
});
}
@ -129,7 +129,7 @@ export default defineComponent({
type: "warning"
})
.then(() => {
service.system.log
service.base.system.log
.clear()
.then(() => {
ElMessage.success("清空成功");
@ -143,7 +143,7 @@ export default defineComponent({
}
//
service.system.log.getKeep().then((res: number) => {
service.base.system.log.getKeep().then((res: number) => {
day.value = Number(res);
});

View File

@ -93,13 +93,13 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: CrudLoad) {
ctx.service(service.system.menu).done();
ctx.service(service.base.system.menu).done();
app.refresh();
}
//
function onRefresh(_: any, { render }: RefreshOp) {
service.system.menu.list().then((list: any[]) => {
service.base.system.menu.list().then((list: any[]) => {
list.map((e) => {
e.permList = e.perms ? e.perms.split(",") : [];
});

View File

@ -159,7 +159,7 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: CrudLoad) {
ctx.service(service.system.param).done();
ctx.service(service.base.system.param).done();
app.refresh();
}

View File

@ -61,7 +61,7 @@ export default defineComponent({
const { refs, setRefs } = useRefs();
//
const { config, getConfig, enable } = service.plugin.info.permission;
const { config, getConfig, enable } = service.base.plugin.info.permission;
const perms = reactive<any>({
edit: checkPerm({
@ -72,7 +72,7 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: CrudLoad) {
ctx.service(service.plugin.info)
ctx.service(service.base.plugin.info)
.set("dict", {
api: {
page: "list"
@ -98,7 +98,7 @@ export default defineComponent({
//
function onEnableChange(val: boolean, item: any) {
service.plugin.info
service.base.plugin.info
.enable({
namespace: item.namespace,
enable: val
@ -113,7 +113,7 @@ export default defineComponent({
//
async function openConf({ name, namespace, view }: any) {
const form = await service.plugin.info.getConfig({
const form = await service.base.plugin.info.getConfig({
namespace
});
@ -131,7 +131,7 @@ export default defineComponent({
form,
on: {
submit: (data: any, { close, done }: any) => {
service.plugin.info
service.base.plugin.info
.config({
namespace,
config: data

View File

@ -153,7 +153,7 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: CrudLoad) {
ctx.service(service.system.role).done();
ctx.service(service.base.system.role).done();
app.refresh();
}

View File

@ -28,7 +28,7 @@
<cl-add-btn />
<cl-multi-delete-btn />
<el-button
v-permission="service.system.user.permission.move"
v-permission="service.base.system.user.permission.move"
size="mini"
type="success"
:disabled="selects.ids.length == 0"
@ -71,7 +71,7 @@
<!-- 单个转移 -->
<template #slot-move-btn="{ scope }">
<el-button
v-permission="service.system.user.permission.move"
v-permission="service.base.system.user.permission.move"
type="text"
size="mini"
@click="toMove(scope.row)"
@ -397,7 +397,7 @@ export default defineComponent({
// crud
function onLoad({ ctx, app }: any) {
ctx.service(service.system.user).done();
ctx.service(service.base.system.user).done();
app.refresh();
}

View File

@ -192,7 +192,7 @@ export default defineComponent({
mitt.emit("message.scrollToBottom");
//
service.im.message.read({
service.chat.message.read({
ids: [msgId],
session: session.value.id
});

View File

@ -270,7 +270,7 @@ export default defineComponent({
visible.value = true;
};
service.im.message
service.chat.message
.page(data)
.then((res: any) => {
//

View File

@ -26,7 +26,7 @@ export default {
methods: {
refresh() {
this.service.im.session.unreadCount().then((res) => {
this.service.chat.session.unreadCount().then((res) => {
this.number = Number(res);
});
},

View File

@ -90,7 +90,7 @@ export default defineComponent({
async function refresh(params?: any) {
loading.value = true;
const res = await service.im.session
const res = await service.chat.session
.page({
...pagination,
keyWord: keyWord.value,
@ -163,7 +163,7 @@ export default defineComponent({
label: "删除",
icon: "el-icon-delete",
callback: (_: any, done: Function) => {
service.im.session.delete({
service.chat.session.delete({
ids: id
});

View File

@ -1,5 +0,0 @@
import components from "./components";
import service from "./service";
import store from "./store";
export default { components, service, store };

View File

@ -1,9 +0,0 @@
import ImMessage from "./message";
import ImSession from "./session";
export default {
im: {
message: new ImMessage(),
session: new ImSession()
}
};

View File

@ -1,7 +0,0 @@
import session from "./session";
import message from "./message";
export default {
session,
message
};

View File

@ -22,7 +22,7 @@ export default {
el.className = el.className + " _copy-btn";
el.setAttribute("data-clipboard-text", binding.value);
},
beforeUpdate: (el: HTMLElement, binding: any) => {
updated: (el: HTMLElement, binding: any) => {
el.setAttribute("data-clipboard-text", binding.value);
}
};

View File

@ -1,7 +0,0 @@
import copy from "./directives";
export default {
directives: {
copy
}
};

View File

@ -1 +0,0 @@
export default {};

View File

@ -1,9 +0,0 @@
import ExportBtn from "./components/export-btn.vue";
export { ExportBtn };
export default {
components: {
ExportBtn
}
};

View File

@ -1,3 +0,0 @@
import service from "./service";
export default { service };

View File

@ -1,7 +0,0 @@
import Info from "./info";
export default {
task: {
info: new Info()
}
};

View File

@ -1,5 +0,0 @@
import Theme from "./theme.vue";
export default {
Theme
};

View File

@ -1,3 +0,0 @@
import components from "./components";
export default { components };

View File

@ -1,7 +0,0 @@
import Upload from "./index.vue";
import UploadSpace from "./space/index.vue";
export default {
Upload,
UploadSpace
};

View File

@ -472,7 +472,7 @@ export default {
data.append("file", file);
//
this.service.common
this.service.base.common
.request({
url: res.host,
method: "POST",
@ -504,7 +504,7 @@ export default {
host: "/upload"
});
} else {
this.service.common
this.service.base.common
.upload()
.then((res) => {
next(res);
@ -535,7 +535,7 @@ export default {
//
uploadMode() {
return this.service.common.uploadMode().then((res) => res.mode);
return this.service.base.common.uploadMode().then((res) => res.mode);
}
}
};

View File

@ -83,7 +83,7 @@ export default defineComponent({
//
function refresh() {
return service.space.type.list().then((res: any) => {
return service.upload.type.list().then((res: any) => {
res.unshift({
name: "全部文件",
id: null
@ -126,9 +126,9 @@ export default defineComponent({
let next = null;
if (!item.id) {
next = service.space.type.add(data);
next = service.upload.type.add(data);
} else {
next = service.space.type.update({
next = service.upload.type.update({
...data,
id: item.id
});
@ -192,7 +192,7 @@ export default defineComponent({
}
)
.then(() => {
service.space.type
service.upload.type
.delete({
ids: [id]
})

View File

@ -268,7 +268,7 @@ export default defineComponent({
if (item) {
item.url = res.data;
service.space.info
service.upload.info
.add({
url: res.data,
type: item.type,
@ -323,7 +323,7 @@ export default defineComponent({
//
loading.value = true;
await service.space.info
await service.upload.info
.page({
...pagination,
...params,
@ -388,7 +388,7 @@ export default defineComponent({
});
//
service.space.info
service.upload.info
.delete({
ids
})

View File

@ -0,0 +1,18 @@
export default {
// 上传的地址
action: "",
// 上传的文件类型
accept: "",
// 上传的文件字段名
name: "file",
// 尺寸
size: "128px",
// 显示图标
icon: "el-icon-picture",
// 显示文案
text: "选择文件",
// 上传大小限制
limitSize: 2,
// 是否已 uuid 重新命名
rename: true
};

View File

@ -1,4 +0,0 @@
import service from "./service";
import components from "./components";
export default { components, service };

View File

@ -1,9 +0,0 @@
import SpaceInfo from "./info";
import SpaceType from "./type";
export default {
space: {
info: new SpaceInfo(),
type: new SpaceType()
}
};

View File

@ -1,15 +1,21 @@
import { BaseService, Service, Permission } from "./service";
import { SET_SERVICE, SET_ROUTER, SET_MODULE } from "./set";
import BaseService from "./service/base";
import { Service, Permission, useService } from "./service";
import { useRefs } from "./hook/core";
import { useRouter } from "./router";
import { useModule } from "./module";
import router from "/@/router";
import store from "/@/store";
import "./common";
const services = useService();
async function bootstrap(app: any) {
SET_ROUTER();
SET_SERVICE(app);
SET_MODULE(app);
app.config.globalProperties.service = store.service = services;
app.provide("service", services);
useRouter();
useModule(app);
router.$plugin?.addViews(store.getters.routes || []);
}
export { Service, Permission, BaseService, bootstrap, useRefs };
export { Service, Permission, BaseService, services, bootstrap, useRefs };

166
src/core/module/index.ts Normal file
View File

@ -0,0 +1,166 @@
import cool from "/@/cool";
import store from "/@/store";
import router from "/@/router";
import { deepMerge, isFunction, isObject } from "../utils";
import { deepFiles } from "../service";
// 模块列表
const modules: any[] = [];
function useModule(app: any) {
// 安装模块
function install(mod: any) {
const { store: _store, service, directives, components, pages, views, name } = mod;
try {
// 注册vuex模块
if (_store) {
for (const i in _store) {
store.registerModule(`${name}-${i}`, _store[i]);
}
}
// 注册请求服务
if (service) {
// @ts-ignore
deepMerge(store.service, service);
}
// 注册组件
if (components) {
components.forEach((e: any) => {
if (e.name) {
if (e.cool?.global || e.name.indexOf("cl-") === 0) {
app.component(e.name, e);
}
}
});
}
// 注册指令
if (directives) {
for (const i in directives) {
app.directive(i, directives[i]);
}
}
// 注册页面
if (pages) {
pages.forEach((e: any) => {
router.addRoute(e);
});
}
// 注册视图
if (views) {
views.forEach((e: any) => {
if (!e.meta) {
e.meta = {};
}
if (e.path) {
router.$plugin?.addViews([e]);
} else {
console.error(`[${name}-views]:缺少 path 参数`);
}
});
}
} catch (e) {
console.error(`模块 ${name} 异常`, e);
}
}
const files = import.meta.globEager("/src/cool/modules/**/*");
for (const i in files) {
const [, , , , name, fn, cname] = i.split("/");
const value: any = files[i].default;
const fname: string = (cname || "").split(".")[0];
function next(d: any) {
switch (fn) {
case "service":
d._services.push({
path: i.replace(`/src/cool/modules/${name}/service`, `${name}`),
value: new value()
});
break;
case "pages":
case "views":
if (value.cool) {
d[fn].push({
...value.cool.route,
component: value
});
}
break;
case "components":
d.components.push(value);
break;
case "store":
d.store[fname] = value;
break;
case "directives":
d.directives[fname] = value;
break;
case "config.ts":
if (value) {
d.options = value;
}
break;
}
return d;
}
const item: any = modules.find((e) => e.name === name);
if (item) {
next(item);
} else {
modules.push(
next({
name,
options: {},
directives: {},
components: [],
pages: [],
views: [],
store: {},
_services: []
})
);
}
}
// 本地模块
modules.forEach((e) => {
e.service = deepFiles(e._services);
install(e);
});
// npm模块
cool.modules.forEach((e: any) => {
const d: any = e;
if (isObject(e.value)) {
if (isFunction(e.value.install)) {
Object.assign(d, e.value.install(app, e.options));
} else {
Object.assign(d, e.value);
}
}
install(d);
});
// 缓存模块
store.commit("SET_MODULE", modules);
}
export { useModule };

View File

@ -11,7 +11,7 @@ for (const i in views) {
delete views[i];
}
export default function () {
function useRouter() {
router.$plugin = {
addViews: (list: Array<any>, options: any) => {
if (!options) {
@ -101,3 +101,5 @@ export default function () {
}
});
}
export { useRouter };

View File

@ -1,4 +1,54 @@
import BaseService from "./base";
import { Service, Permission } from "./desorator";
import { Service, Permission } from "./decorator";
import { basename } from "../utils";
export { BaseService, Service, Permission };
function deepFiles(list: any[]) {
const modules: any = {};
list.forEach((e) => {
const arr: any[] = e.path.split("/");
const parents: any[] = arr.slice(0, arr.length - 1);
const name: string = basename(e.path).replace(".ts", "");
let curr: any = modules;
let prev: any = null;
let key: any = null;
parents.forEach((k) => {
if (!curr[k]) {
curr[k] = {};
}
prev = curr;
curr = curr[k];
key = k;
});
if (name == "index") {
prev[key] = e.value;
} else {
curr[name] = e.value;
}
});
return modules;
}
function useService() {
const files = import.meta.globEager("/src/service/**/*.ts");
const d: any = [];
for (const i in files) {
if (!i.includes("request.ts")) {
const value = files[i].default;
d.push({
path: i.replace("/src/service/", ""),
value: new value()
});
}
}
return deepFiles(d);
}
export { BaseService, Service, Permission, deepFiles, useService };

View File

@ -1,5 +0,0 @@
import SET_SERVICE from "./service";
import SET_ROUTER from "./router";
import SET_MODULE from "./module";
export { SET_SERVICE, SET_ROUTER, SET_MODULE };

View File

@ -1,150 +0,0 @@
import cool from "/@/cool";
import store from "/@/store";
import router from "/@/router";
import { deepMerge, isFunction, isArray, isObject, isString } from "../utils";
// 模块列表
const modules: any[] = [];
export default function (app: any) {
const files = import.meta.globEager("/src/cool/modules/*/index.ts");
// 本地模块
const local: any[] = [];
for (const i in files) {
const [, , , , name, , error] = i.split("/");
if (!error) {
local.push({
name,
value: files[i].default
});
}
}
// 安装模块
function install(mod: any) {
const { store: _store, components, service, directives, pages, views, name } = mod;
try {
// 注册vuex模块
if (_store) {
for (const i in _store) {
store.registerModule(`${name}-${i}`, _store[i]);
}
}
// 注册组件
if (components) {
for (const i in components) {
if (components[i].name) {
app.component(components[i].name, components[i]);
} else {
console.error(`组件 ${i} 缺少 name 参数`);
}
}
}
// 注册请求服务
if (service) {
// @ts-ignore
deepMerge(store.service, service);
}
// 注册指令
if (directives) {
for (const i in directives) {
app.directive(i, directives[i]);
}
}
// 注册页面
if (pages) {
pages.forEach((e: any) => {
router.addRoute(e);
});
}
// 注册视图
if (views) {
views.forEach((e: any) => {
if (!e.meta) {
e.meta = {};
}
if (e.path) {
router.$plugin?.addViews([e]);
} else {
console.error(`[${name}-views]:缺少 path 参数`);
}
});
}
} catch (e) {
console.error(`模块 ${name} 异常`, e);
}
}
// 解析模块
cool.modules.map((e: any) => {
if (!e) {
return null;
}
let mod: any = null;
// 解析格式
if (isString(e)) {
mod = {
name: e
};
} else if (isObject(e)) {
mod = e;
} else if (isArray(e)) {
mod = {
name: e[0],
value: e[1],
options: e[2]
};
} else {
console.error(e, "格式错误");
}
// 匹配本地模块
if (!mod.value) {
const item = local.find((m: any) => m.name === mod.name);
if (item) {
mod.value = item.value;
} else {
console.error(mod.name, "不是一个有效的模块");
}
}
// 兼容其他 vue 插件模式
if (mod.value) {
if (isFunction(mod.value.install)) {
mod.value = mod.value.install(app, mod.options);
}
}
// 是否开启
if (mod.options && mod.options.enable === false) {
return null;
}
if (mod) {
mod = {
name: mod.name,
options: mod.options || {},
...mod.value
};
modules.push(mod);
install(mod);
}
});
// 缓存模块
store.commit("SET_MODULE", modules);
}

View File

@ -1,51 +0,0 @@
import store from "/@/store";
import { last } from "../utils";
export default function (app: any) {
const files = import.meta.globEager("/src/service/*.ts");
const ignore = ["request.ts"];
const modules: any = {};
for (const i in files) {
const path: string = i.replace("/src/service/", "");
const inst: any = files[i].default;
if (ignore.includes(path)) {
continue;
}
const list = path.split("/");
const parents = list.slice(0, list.length - 1);
const name = last(list).replace(".ts", "");
let curr: any = modules;
let prev: any = null;
let key: any = null;
parents.forEach((k: any) => {
if (!curr[k]) {
curr[k] = {};
}
prev = curr;
curr = curr[k];
key = k;
});
if (inst) {
const service = new inst();
if (name == "index") {
prev[key] = service;
} else {
curr[name] = service;
}
} else {
console.error(`Service must export default in ${files[i]}`);
}
}
app.config.globalProperties.service = store.service = modules;
app.provide("service", modules);
}

View File

@ -27,10 +27,10 @@ const app = createApp(App);
bootstrap(app)
.then(() => {
// echarts 可视图表
// // echarts 可视图表
app.component("v-chart", VueECharts);
// 事件通讯
// // 事件通讯
app.provide("mitt", mitt());
app.use(store).use(router).use(ElementPlus, { locale }).mount("#app");

15
src/service/a/a.ts Normal file
View File

@ -0,0 +1,15 @@
import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/department")
class A extends BaseService {
@Permission("order")
order(data: any) {
return this.request({
url: "/order",
method: "POST",
data
});
}
}
export default A;

15
src/service/b/b.ts Normal file
View File

@ -0,0 +1,15 @@
import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/department")
class B extends BaseService {
@Permission("order")
order(data: any) {
return this.request({
url: "/order",
method: "POST",
data
});
}
}
export default B;

15
src/service/test.ts Normal file
View File

@ -0,0 +1,15 @@
import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/department")
class Test extends BaseService {
@Permission("order")
order(data: any) {
return this.request({
url: "/order",
method: "POST",
data
});
}
}
export default Test;

View File

@ -549,11 +549,7 @@ acorn@^7.1.1, acorn@^7.4.0:
adler-32@~1.2.0:
version "1.2.0"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/adler-32/download/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
=======
resolved "https://registry.nlark.com/adler-32/download/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=
dependencies:
exit-on-epipe "~1.0.1"
@ -934,17 +930,10 @@ change-case@^4.1.2:
optionalDependencies:
fsevents "~2.3.1"
<<<<<<< HEAD
cl-admin-crud-vue3@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/cl-admin-crud-vue3/-/cl-admin-crud-vue3-0.1.6.tgz#65ca232ccae7764f627c71facc6d4ac720ae8c42"
integrity sha512-mzl/WyEYeywu5I3J3Noe+X4dhcQ3vKkMOadSTbVAbxJbhEcdg+G7cNm91f3uIdmM5RB8BEA0QNi/pIpMa8Gh/A==
=======
cl-admin-crud-vue3@^0.1.3:
version "0.1.3"
resolved "https://registry.nlark.com/cl-admin-crud-vue3/download/cl-admin-crud-vue3-0.1.3.tgz?cache=0&sync_timestamp=1618901222085&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcl-admin-crud-vue3%2Fdownload%2Fcl-admin-crud-vue3-0.1.3.tgz#fc53ce0b42cecd243db6707f862d26a78406dcdb"
integrity sha1-/FPOC0LOzSQ9tnB/hi0mp4QG3Ns=
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
dependencies:
array.prototype.flat "^1.2.4"
core-js "^3.6.5"
@ -1048,20 +1037,12 @@ commander@^2.19.0:
commander@~2.14.1:
version "2.14.1"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/commander/download/commander-2.14.1.tgz?cache=0&sync_timestamp=1616364009866&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
=======
resolved "https://registry.nlark.com/commander/download/commander-2.14.1.tgz?cache=0&sync_timestamp=1618847060379&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-IjUSPjevjKPGXfRbAm29NXsBuao=
commander@~2.17.1:
version "2.17.1"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1616364009866&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
=======
resolved "https://registry.nlark.com/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1618847060379&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-vXerfebelCBc6sxy8XFtKfIKd78=
component-emitter@^1.2.1, component-emitter@~1.3.0:
@ -1338,24 +1319,10 @@ element-plus@^1.0.2-beta.40:
normalize-wheel "^1.0.1"
resize-observer-polyfill "^1.5.1"
element-plus@^1.0.2-beta.45:
version "1.0.2-beta.45"
resolved "https://registry.nlark.com/element-plus/download/element-plus-1.0.2-beta.45.tgz#d7d84d284ead4f9de5aa7289b9a2af4b7f109a1e"
integrity sha1-19hNKE6tT53lqnKJuaKvS38Qmh4=
dependencies:
"@popperjs/core" "^2.4.4"
"@types/lodash" "^4.14.161"
async-validator "^3.4.0"
dayjs "1.x"
lodash "^4.17.20"
mitt "^2.1.0"
normalize-wheel "^1.0.1"
resize-observer-polyfill "^1.5.1"
element-plus@^1.0.2-beta.40:
version "1.0.2-beta.40"
resolved "https://registry.npm.taobao.org/element-plus/download/element-plus-1.0.2-beta.40.tgz#30fc9b161496ae587fab86235c80b728ea43d909"
integrity sha1-MPybFhSWrlh/q4YjXIC3KOpD2Qk=
element-plus@^1.0.2-beta.48:
version "1.0.2-beta.48"
resolved "https://registry.nlark.com/element-plus/download/element-plus-1.0.2-beta.48.tgz#8da99decd397b9975cd894d389096d2ed58c699e"
integrity sha1-jamd7NOXuZdc2JTTiQltLtWMaZ4=
dependencies:
"@popperjs/core" "^2.4.4"
"@types/lodash" "^4.14.161"
@ -1716,11 +1683,7 @@ fastq@^1.6.0:
fflate@^0.3.8:
version "0.3.11"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/fflate/download/fflate-0.3.11.tgz?cache=0&sync_timestamp=1616295375703&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffflate%2Fdownload%2Ffflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d"
=======
resolved "https://registry.nlark.com/fflate/download/fflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-LEQNcYD964GeZImNiFivMnsEKl0=
file-entry-cache@^6.0.1:
@ -1732,11 +1695,7 @@ file-entry-cache@^6.0.1:
file-saver@^2.0.5:
version "2.0.5"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/file-saver/download/file-saver-2.0.5.tgz?cache=0&sync_timestamp=1605790887683&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-saver%2Fdownload%2Ffile-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
=======
resolved "https://registry.npm.taobao.org/file-saver/download/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-1hz+LOBZ9BTYmendbUEH7iVnDDg=
fill-range@^4.0.0:
@ -1781,11 +1740,7 @@ for-in@^1.0.2:
frac@~1.1.2:
version "1.1.2"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/frac/download/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
=======
resolved "https://registry.nlark.com/frac/download/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-PXT39keMiKG1AgMG10fcYxPHTQs=
fragment-cache@^0.2.1:
@ -2971,11 +2926,7 @@ prettier@^2.2.1:
printj@~1.1.0, printj@~1.1.2:
version "1.1.2"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/printj/download/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
=======
resolved "https://registry.nlark.com/printj/download/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-2Q3rKXWoufYA+zoclOP0xTx4oiI=
process-nextick-args@~2.0.0:
@ -3896,11 +3847,7 @@ which@^2.0.1:
wmf@~1.0.1:
version "1.0.2"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/wmf/download/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
=======
resolved "https://registry.nlark.com/wmf/download/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-fRnWIQcaCMK9xrfmiKnENSmMwto=
word-wrap@^1.2.3:
@ -3910,11 +3857,7 @@ word-wrap@^1.2.3:
word@~0.3.0:
version "0.3.0"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/word/download/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
=======
resolved "https://registry.nlark.com/word/download/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-hUIVfk+OhJ9KNjooiZLUdhLbmWE=
wrappy@1:
@ -3929,11 +3872,7 @@ ws@~7.4.2:
xlsx@^0.16.9:
version "0.16.9"
<<<<<<< HEAD
resolved "https://registry.npm.taobao.org/xlsx/download/xlsx-0.16.9.tgz?cache=0&sync_timestamp=1605857177269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxlsx%2Fdownload%2Fxlsx-0.16.9.tgz#dacd5bb46bda6dd3743940c9c3dc1e2171826256"
=======
resolved "https://registry.nlark.com/xlsx/download/xlsx-0.16.9.tgz#dacd5bb46bda6dd3743940c9c3dc1e2171826256"
>>>>>>> dc22b39fea31872cad95ffe85501a7d5b2eba504
integrity sha1-2s1btGvabdN0OUDJw9weIXGCYlY=
dependencies:
adler-32 "~1.2.0"