From 897571c7ad3d41dcbd72a05d69d239bbf567c726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=9E=E4=BB=99=E9=83=BD=E6=B2=A1=E7=94=A8?= <615206459@qq.com> Date: Thu, 25 Jan 2024 17:30:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=207.1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/cool/demo.ts | 46 + build/cool/index.ts | 10 +- build/cool/svg/index.ts | 2 +- package.json | 6 +- packages/crud/index.d.ts | 73 +- packages/crud/package.json | 2 +- packages/crud/src/App.vue | 144 +- packages/crud/src/components/adv/search.tsx | 5 +- .../src/components/context-menu/index.tsx | 21 +- packages/crud/src/components/dialog/index.tsx | 35 +- packages/crud/src/components/form/index.tsx | 246 +-- packages/crud/src/components/search/index.tsx | 20 +- packages/crud/src/static/index.scss | 12 +- packages/crud/src/utils/form-hook.ts | 10 +- .../crud/types/components/dialog/index.d.ts | 9 + .../types/components/form/helper/index.d.ts | 10 +- .../types/components/table/helper/index.d.ts | 5 +- packages/crud/types/utils/form-hook.d.ts | 4 +- src/config/proxy.ts | 4 +- src/cool/bootstrap/module.ts | 14 +- src/cool/module/index.ts | 3 + src/cool/router/index.ts | 8 +- src/modules/base/components/avatar/index.scss | 10 - src/modules/base/components/avatar/index.tsx | 31 +- src/modules/base/components/dept/check.vue | 4 +- src/modules/base/components/image/index.vue | 25 +- src/modules/base/components/menu/check.vue | 2 +- src/modules/base/hooks/dept.tsx | 2 +- src/modules/base/hooks/index.ts | 1 - src/modules/base/views/info.vue | 2 +- .../base/views/menu/components/exp.vue | 5 +- src/modules/base/views/menu/index.vue | 6 +- src/modules/base/views/role.vue | 67 +- .../base/views/user/components/dept-list.vue | 6 +- src/modules/base/views/user/index.vue | 2 +- src/modules/chat/components/index.vue | 3 +- src/modules/cloud/config.ts | 2 +- src/modules/cloud/views/db.vue | 2 +- src/modules/demo/components/context-menu.vue | 4 +- src/modules/demo/components/copy.vue | 2 +- src/modules/demo/components/crud.vue | 2 +- src/modules/demo/components/design.vue | 2 +- src/modules/demo/components/editor.vue | 2 +- src/modules/demo/components/file.vue | 2 +- src/modules/demo/components/form.vue | 8 +- src/modules/demo/components/svg.vue | 2 +- src/modules/demo/components/upload.vue | 2 +- src/modules/demo/config.ts | 7 + .../views/crud/components/adv-search/base.vue | 138 ++ .../crud/components/adv-search/custom.vue | 152 ++ .../demo/views/crud/components/code.vue | 41 + .../components/crud/all.vue} | 207 ++- .../demo/views/crud/components/crud/base.vue | 145 ++ .../demo/views/crud/components/crud/dict.vue | 164 ++ .../demo/views/crud/components/crud/event.vue | 182 ++ .../views/crud/components/crud/service.vue | 185 ++ .../views/crud/components/form/children.vue | 118 ++ .../crud/components/form/component/index.vue | 106 ++ .../form/component/select-labels.vue | 38 + .../form/component/select-status.vue | 43 + .../components/form/component/select-work.vue | 59 + .../views/crud/components/form/config.vue | 122 ++ .../crud/components/form/crud.vue} | 88 +- .../views/crud/components/form/disabled.vue | 64 + .../demo/views/crud/components/form/event.vue | 93 + .../demo/views/crud/components/form/group.vue | 105 ++ .../views/crud/components/form/hidden.vue | 77 + .../views/crud/components/form/layout.vue | 116 ++ .../demo/views/crud/components/form/open.vue | 83 + .../views/crud/components/form/options.vue | 172 ++ .../crud/components/form/plugin/index.vue | 112 ++ .../views/crud/components/form/plugin/role.ts | 20 + .../views/crud/components/form/required.vue | 75 + .../demo/views/crud/components/form/rules.vue | 123 ++ .../crud/components/other}/select-user.vue | 2 +- .../demo/views/crud/components/other/tips.vue | 168 ++ .../crud/components/other/tsx/index.scss | 28 + .../views/crud/components/other/tsx/index.tsx | 107 ++ .../views/crud/components/search/base.vue | 143 ++ .../views/crud/components/search/custom.vue | 176 ++ .../demo/views/crud/components/table/base.vue | 109 ++ .../views/crud/components/table/children.vue | 98 + .../crud/components/table/column-custom.vue | 108 ++ .../crud/components/table/component/index.vue | 108 ++ .../components/table/component/user-info.vue | 30 + .../crud/components/table/context-menu.vue | 191 ++ .../demo/views/crud/components/table/dict.vue | 156 ++ .../views/crud/components/table/hidden.vue | 127 ++ .../demo/views/crud/components/table/op.vue | 163 ++ .../views/crud/components/table/search.vue | 143 ++ .../views/crud/components/table/selection.vue | 110 ++ .../demo/views/crud/components/table/slot.vue | 97 + .../crud/components/table/span-method.vue | 116 ++ .../views/crud/components/table/summary.vue | 95 + .../views/crud/components/upsert/base.vue | 133 ++ .../views/crud/components/upsert/event.vue | 210 +++ .../crud/components/upsert/hook/index.vue | 200 ++ .../crud/components/upsert/hook/reg-pca2.ts | 14 + .../views/crud/components/upsert/mode.vue | 146 ++ src/modules/demo/views/crud/index.vue | 288 +++ src/modules/demo/views/demo.vue | 32 +- src/modules/demo/views/editor.vue | 2 +- src/modules/demo/views/upload.vue | 86 +- src/modules/dict/views/list.vue | 3 +- src/modules/extend/config.ts | 21 - src/modules/extend/editor/preview.vue | 93 - src/modules/extend/index.ts | 1 - .../components/auto-menu/btn.vue | 2 +- .../components/auto-menu/index.vue | 0 .../components/auto-menu/quick.vue | 39 +- .../components/auto-perms/index.vue | 2 +- .../{magic => helper}/components/text.vue | 0 src/modules/{magic => helper}/config.ts | 11 +- src/modules/helper/dict/index.ts | 3 + src/modules/helper/hooks/ai.ts | 169 ++ .../hooks/menu.ts => helper/hooks/code.ts} | 320 ++-- src/modules/{magic => helper}/hooks/index.ts | 3 +- src/modules/helper/hooks/menu.ts | 85 + .../{magic => helper}/types/index.d.ts | 11 + src/modules/helper/utils/index.ts | 52 + .../{magic => helper}/views/ai-code.vue | 12 +- src/modules/helper/views/plugin.vue | 385 ++++ src/modules/iot/views/device.vue | 9 +- src/modules/magic/dict/index.ts | 254 --- src/modules/magic/hooks/ai.ts | 90 - src/modules/magic/utils/index.ts | 192 -- .../components/space-inner.vue | 34 +- .../{upload => space}/components/space.vue | 78 +- src/modules/space/config.ts | 18 + src/modules/space/hooks/index.ts | 19 + src/modules/{upload => space}/views/list.vue | 2 +- src/modules/task/views/list.vue | 4 +- src/modules/upload/hooks/index.ts | 8 - src/modules/upload/types/index.d.ts | 31 - src/modules/user/views/address.vue | 92 - src/modules/user/views/list.vue | 2 +- .../crud}/components/column-custom/index.vue | 2 +- .../crud}/components/date/picker.vue | 4 +- .../crud}/components/date/text.vue | 0 .../crud}/components/select/index.tsx | 10 +- .../crud}/components/switch/index.tsx | 0 src/{modules => plugins}/crud/config.ts | 16 +- src/plugins/distpicker/components/index.tsx | 21 + .../distpicker/config.ts} | 30 +- .../distpicker/data}/pca.json | 0 .../editor-monaco/components}/index.vue | 22 +- src/plugins/editor-monaco/config.ts | 10 + src/plugins/editor-monaco/index.ts | 1 + .../editor-monaco/utils}/config.ts | 0 .../editor-monaco/utils}/declare.ts | 0 .../editor-monaco/utils}/format.ts | 4 +- .../editor-monaco/utils}/theme.ts | 0 .../editor-monaco/utils}/types.ts | 0 .../editor-monaco/utils}/worker.ts | 0 .../editor-preview/components/preview.vue | 208 +++ src/plugins/editor-preview/config.ts | 7 + .../editor-wang/components}/wang.vue | 16 +- src/plugins/editor-wang/config.ts | 7 + .../excel/components}/export-btn.tsx | 4 +- .../excel/components}/import-btn.vue | 2 +- src/plugins/excel/config.ts | 10 + .../extend => plugins}/excel/utils/index.ts | 0 .../upload/components/upload-item/index.vue | 9 +- .../upload/components/upload-item/viewer.vue | 3 +- .../upload/components/upload-item/wps.vue | 0 .../upload/components/upload.vue | 87 +- src/{modules => plugins}/upload/config.ts | 16 +- .../upload/static/svg/audio.svg | 0 .../upload/static/svg/excel.svg | 0 .../upload/static/svg/file.svg | 0 .../upload/static/svg/image.svg | 0 .../upload/static/svg/pdf.svg | 0 .../upload/static/svg/ppt.svg | 0 .../upload/static/svg/rar.svg | 0 .../upload/static/svg/video.svg | 0 .../upload/static/svg/word.svg | 0 src/plugins/upload/types/index.d.ts | 18 + .../upload/utils/index.ts | 0 .../view/components/group.vue} | 2 +- .../view/components/head.vue} | 0 src/plugins/view/config.ts | 7 + src/plugins/view/hooks/group.ts | 14 + src/plugins/view/hooks/index.ts | 1 + src/plugins/view/index.ts | 2 + .../hook.ts => plugins/view/types/index.d.ts} | 13 - src/shims-vue.d.ts | 1 + stats.html | 60 +- yarn.lock | 1638 ++++++++--------- 188 files changed, 8820 insertions(+), 2576 deletions(-) create mode 100644 build/cool/demo.ts delete mode 100644 src/modules/base/components/avatar/index.scss create mode 100644 src/modules/demo/config.ts create mode 100644 src/modules/demo/views/crud/components/adv-search/base.vue create mode 100644 src/modules/demo/views/crud/components/adv-search/custom.vue create mode 100644 src/modules/demo/views/crud/components/code.vue rename src/modules/demo/views/{crud.vue => crud/components/crud/all.vue} (72%) create mode 100644 src/modules/demo/views/crud/components/crud/base.vue create mode 100644 src/modules/demo/views/crud/components/crud/dict.vue create mode 100644 src/modules/demo/views/crud/components/crud/event.vue create mode 100644 src/modules/demo/views/crud/components/crud/service.vue create mode 100644 src/modules/demo/views/crud/components/form/children.vue create mode 100644 src/modules/demo/views/crud/components/form/component/index.vue create mode 100644 src/modules/demo/views/crud/components/form/component/select-labels.vue create mode 100644 src/modules/demo/views/crud/components/form/component/select-status.vue create mode 100644 src/modules/demo/views/crud/components/form/component/select-work.vue create mode 100644 src/modules/demo/views/crud/components/form/config.vue rename src/modules/demo/{components/form-btn.vue => views/crud/components/form/crud.vue} (53%) create mode 100644 src/modules/demo/views/crud/components/form/disabled.vue create mode 100644 src/modules/demo/views/crud/components/form/event.vue create mode 100644 src/modules/demo/views/crud/components/form/group.vue create mode 100644 src/modules/demo/views/crud/components/form/hidden.vue create mode 100644 src/modules/demo/views/crud/components/form/layout.vue create mode 100644 src/modules/demo/views/crud/components/form/open.vue create mode 100644 src/modules/demo/views/crud/components/form/options.vue create mode 100644 src/modules/demo/views/crud/components/form/plugin/index.vue create mode 100644 src/modules/demo/views/crud/components/form/plugin/role.ts create mode 100644 src/modules/demo/views/crud/components/form/required.vue create mode 100644 src/modules/demo/views/crud/components/form/rules.vue rename src/modules/demo/{components => views/crud/components/other}/select-user.vue (98%) create mode 100644 src/modules/demo/views/crud/components/other/tips.vue create mode 100644 src/modules/demo/views/crud/components/other/tsx/index.scss create mode 100644 src/modules/demo/views/crud/components/other/tsx/index.tsx create mode 100644 src/modules/demo/views/crud/components/search/base.vue create mode 100644 src/modules/demo/views/crud/components/search/custom.vue create mode 100644 src/modules/demo/views/crud/components/table/base.vue create mode 100644 src/modules/demo/views/crud/components/table/children.vue create mode 100644 src/modules/demo/views/crud/components/table/column-custom.vue create mode 100644 src/modules/demo/views/crud/components/table/component/index.vue create mode 100644 src/modules/demo/views/crud/components/table/component/user-info.vue create mode 100644 src/modules/demo/views/crud/components/table/context-menu.vue create mode 100644 src/modules/demo/views/crud/components/table/dict.vue create mode 100644 src/modules/demo/views/crud/components/table/hidden.vue create mode 100644 src/modules/demo/views/crud/components/table/op.vue create mode 100644 src/modules/demo/views/crud/components/table/search.vue create mode 100644 src/modules/demo/views/crud/components/table/selection.vue create mode 100644 src/modules/demo/views/crud/components/table/slot.vue create mode 100644 src/modules/demo/views/crud/components/table/span-method.vue create mode 100644 src/modules/demo/views/crud/components/table/summary.vue create mode 100644 src/modules/demo/views/crud/components/upsert/base.vue create mode 100644 src/modules/demo/views/crud/components/upsert/event.vue create mode 100644 src/modules/demo/views/crud/components/upsert/hook/index.vue create mode 100644 src/modules/demo/views/crud/components/upsert/hook/reg-pca2.ts create mode 100644 src/modules/demo/views/crud/components/upsert/mode.vue create mode 100644 src/modules/demo/views/crud/index.vue delete mode 100644 src/modules/extend/config.ts delete mode 100644 src/modules/extend/editor/preview.vue delete mode 100644 src/modules/extend/index.ts rename src/modules/{magic => helper}/components/auto-menu/btn.vue (95%) rename src/modules/{magic => helper}/components/auto-menu/index.vue (100%) rename src/modules/{magic => helper}/components/auto-menu/quick.vue (85%) rename src/modules/{magic => helper}/components/auto-perms/index.vue (98%) rename src/modules/{magic => helper}/components/text.vue (100%) rename src/modules/{magic => helper}/config.ts (67%) create mode 100644 src/modules/helper/dict/index.ts create mode 100644 src/modules/helper/hooks/ai.ts rename src/modules/{magic/hooks/menu.ts => helper/hooks/code.ts} (51%) rename src/modules/{magic => helper}/hooks/index.ts (65%) create mode 100644 src/modules/helper/hooks/menu.ts rename src/modules/{magic => helper}/types/index.d.ts (73%) create mode 100644 src/modules/helper/utils/index.ts rename src/modules/{magic => helper}/views/ai-code.vue (98%) create mode 100644 src/modules/helper/views/plugin.vue delete mode 100644 src/modules/magic/dict/index.ts delete mode 100644 src/modules/magic/hooks/ai.ts delete mode 100644 src/modules/magic/utils/index.ts rename src/modules/{upload => space}/components/space-inner.vue (92%) rename src/modules/{upload => space}/components/space.vue (51%) create mode 100644 src/modules/space/config.ts create mode 100644 src/modules/space/hooks/index.ts rename src/modules/{upload => space}/views/list.vue (70%) delete mode 100644 src/modules/upload/hooks/index.ts delete mode 100644 src/modules/upload/types/index.d.ts delete mode 100644 src/modules/user/views/address.vue rename src/{modules/base => plugins/crud}/components/column-custom/index.vue (97%) rename src/{modules/base => plugins/crud}/components/date/picker.vue (97%) rename src/{modules/base => plugins/crud}/components/date/text.vue (100%) rename src/{modules/base => plugins/crud}/components/select/index.tsx (96%) rename src/{modules/base => plugins/crud}/components/switch/index.tsx (100%) rename src/{modules => plugins}/crud/config.ts (54%) create mode 100644 src/plugins/distpicker/components/index.tsx rename src/{modules/extend/distpicker/index.tsx => plugins/distpicker/config.ts} (52%) rename src/{modules/extend/distpicker => plugins/distpicker/data}/pca.json (100%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/components}/index.vue (92%) create mode 100644 src/plugins/editor-monaco/config.ts create mode 100644 src/plugins/editor-monaco/index.ts rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/config.ts (100%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/declare.ts (100%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/format.ts (96%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/theme.ts (100%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/types.ts (100%) rename src/{modules/extend/editor/monaco => plugins/editor-monaco/utils}/worker.ts (100%) create mode 100644 src/plugins/editor-preview/components/preview.vue create mode 100644 src/plugins/editor-preview/config.ts rename src/{modules/extend/editor => plugins/editor-wang/components}/wang.vue (95%) create mode 100644 src/plugins/editor-wang/config.ts rename src/{modules/extend/excel => plugins/excel/components}/export-btn.tsx (97%) rename src/{modules/extend/excel => plugins/excel/components}/import-btn.vue (98%) create mode 100644 src/plugins/excel/config.ts rename src/{modules/extend => plugins}/excel/utils/index.ts (100%) rename src/{modules => plugins}/upload/components/upload-item/index.vue (97%) rename src/{modules => plugins}/upload/components/upload-item/viewer.vue (95%) rename src/{modules => plugins}/upload/components/upload-item/wps.vue (100%) rename src/{modules => plugins}/upload/components/upload.vue (91%) rename src/{modules => plugins}/upload/config.ts (82%) rename src/{modules => plugins}/upload/static/svg/audio.svg (100%) rename src/{modules => plugins}/upload/static/svg/excel.svg (100%) rename src/{modules => plugins}/upload/static/svg/file.svg (100%) rename src/{modules => plugins}/upload/static/svg/image.svg (100%) rename src/{modules => plugins}/upload/static/svg/pdf.svg (100%) rename src/{modules => plugins}/upload/static/svg/ppt.svg (100%) rename src/{modules => plugins}/upload/static/svg/rar.svg (100%) rename src/{modules => plugins}/upload/static/svg/video.svg (100%) rename src/{modules => plugins}/upload/static/svg/word.svg (100%) create mode 100644 src/plugins/upload/types/index.d.ts rename src/{modules => plugins}/upload/utils/index.ts (100%) rename src/{modules/base/components/view/group/index.vue => plugins/view/components/group.vue} (99%) rename src/{modules/base/components/view/head/index.vue => plugins/view/components/head.vue} (100%) create mode 100644 src/plugins/view/config.ts create mode 100644 src/plugins/view/hooks/group.ts create mode 100644 src/plugins/view/hooks/index.ts create mode 100644 src/plugins/view/index.ts rename src/{modules/base/components/view/group/hook.ts => plugins/view/types/index.d.ts} (82%) diff --git a/build/cool/demo.ts b/build/cool/demo.ts new file mode 100644 index 0000000..0afcf30 --- /dev/null +++ b/build/cool/demo.ts @@ -0,0 +1,46 @@ +import type { Plugin } from "vite"; +import { glob } from "glob"; +import path from "path"; +import { readFileSync } from "fs"; + +export function demo(enable?: boolean): Plugin { + const virtualModuleIds = ["virtual:demo"]; + + return { + name: "vite-cool-demo", + enforce: "pre", + resolveId(id) { + if (virtualModuleIds.includes(id)) { + return "\0" + id; + } + }, + async load(id) { + if (id === "\0virtual:demo") { + const demo = {}; + + if (enable) { + const files = await glob("./src/modules/demo/views/crud/components/**", { + stat: true, + withFileTypes: true + }); + + for (const file of files) { + if (file.isFile()) { + const p = path.join(file.path, file.name); + + demo[ + p + .replace(/\\/g, "/") + .split("src/modules/demo/views/crud/components/")[1] + ] = readFileSync(p, "utf-8"); + } + } + } + + return ` + export const demo = ${JSON.stringify(demo)}; + `; + } + } + }; +} diff --git a/build/cool/index.ts b/build/cool/index.ts index 6013f1a..8c41ac1 100644 --- a/build/cool/index.ts +++ b/build/cool/index.ts @@ -1,6 +1,14 @@ import { base } from "./base"; import { virtual } from "./virtual"; +import { demo } from "./demo"; export function cool() { - return [base(), virtual()]; + return [ + // 基础 + base(), + // 虚拟模块 + virtual(), + // demo 官方示例,代码片段 + demo(true) + ]; } diff --git a/build/cool/svg/index.ts b/build/cool/svg/index.ts index 2b752e7..7be8179 100644 --- a/build/cool/svg/index.ts +++ b/build/cool/svg/index.ts @@ -42,7 +42,7 @@ function findFiles(dir: string): string[] { } export function createSvg(html: string) { - const res = findFiles("./src/modules/"); + const res = findFiles("./src/"); return html.replace( "", diff --git a/package.json b/package.json index ce2925d..9f82875 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cool-admin", - "version": "7.0.0", + "version": "7.1.0", "scripts": { "dev": "vite --host", "build": "vite build", @@ -9,7 +9,7 @@ "lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix" }, "dependencies": { - "@cool-vue/crud": "^7.1.3", + "@cool-vue/crud": "^7.1.10", "@element-plus/icons-vue": "^2.1.0", "@vueuse/core": "^10.4.0", "@wangeditor/editor": "^5.1.23", @@ -22,6 +22,7 @@ "element-plus": "^2.4.3", "file-saver": "^2.0.5", "lodash-es": "^4.17.21", + "marked": "^11.1.1", "mitt": "^3.0.1", "mockjs": "^1.1.0", "monaco-editor": "0.36.0", @@ -53,6 +54,7 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-vue": "^9.17.0", + "glob": "^10.3.10", "lodash": "^4.17.21", "magic-string": "^0.30.3", "prettier": "^3.1.0", diff --git a/packages/crud/index.d.ts b/packages/crud/index.d.ts index 27e69f7..6b44a00 100644 --- a/packages/crud/index.d.ts +++ b/packages/crud/index.d.ts @@ -82,39 +82,6 @@ declare type Browser = { isMini: boolean; }; -// hook -declare namespace Hook { - interface Options { - form: obj; - prop: string; - method: "submit" | "bind"; - } - - type fn = (value: any, options: Options) => any; - - type FormPipe = - | "number" - | "string" - | "split" - | "join" - | "boolean" - | "booleanNumber" - | "datetimeRange" - | "splitJoin" - | "json" - | "empty" - | fn; - - type FormPipes = FormPipe | FormPipe[]; - - type Form = - | string - | { - bind?: FormPipes; - submit?: FormPipes; - }; -} - // render declare namespace Render { type OpButton = @@ -473,6 +440,26 @@ declare namespace ClForm { [key: string]: any; } + type HookFn = ( + value: any, + options: { form: obj; prop: string; method: "submit" | "bind" } + ) => any; + + type HookKey = + | "number" + | "string" + | "split" + | "join" + | "boolean" + | "booleanNumber" + | "datetimeRange" + | "splitJoin" + | "json" + | "empty" + | (string & {}); + + type HookPipe = HookKey | HookFn; + interface Item { type?: "tabs"; prop?: PropKey; @@ -501,14 +488,19 @@ declare namespace ClForm { xl: any; tag: string; }; - hook?: Hook.Form; group?: string; collapse?: boolean; value?: any; label?: string; renderLabel?: any; flex?: boolean; - hidden?: (options: { scope: obj }) => boolean; + hook?: + | HookKey + | { + bind?: HookPipe | HookPipe[]; + submit?: HookPipe | HookPipe[]; + }; + hidden?: boolean | ((options: { scope: obj }) => boolean); prepend?: Render.Component; component?: Render.Component; append?: Render.Component; @@ -632,16 +624,12 @@ declare namespace ClUpsert { } } -interface UpsertOptions { - items: ClForm.Items; -} - declare namespace ClAdvSearch { interface Config { items?: ClForm.Item[]; title?: string; size?: string | number; - op?: Array<"clear" | "reset" | "close" | "search">; + op?: ("clear" | "reset" | "close" | "search" | `slot-${string}`)[]; onSearch?(data: T, options: { next: ClCrud.Service["api"]["page"]; close(): void }): void; } @@ -674,9 +662,8 @@ declare namespace ClSearch { declare namespace ClContextMenu { interface Item { label: string; - icon?: string; - prefixIcon?: string; - suffixIcon?: string; + prefixIcon?: any; + suffixIcon?: any; ellipsis?: boolean; disabled?: boolean; hidden?: boolean; diff --git a/packages/crud/package.json b/packages/crud/package.json index 7e9970d..fadd536 100644 --- a/packages/crud/package.json +++ b/packages/crud/package.json @@ -1,6 +1,6 @@ { "name": "@cool-vue/crud", - "version": "7.1.3", + "version": "7.1.10", "private": false, "main": "./dist/index.umd.min.js", "typings": "types/index.d.ts", diff --git a/packages/crud/src/App.vue b/packages/crud/src/App.vue index c3b32a0..a32fc2f 100644 --- a/packages/crud/src/App.vue +++ b/packages/crud/src/App.vue @@ -1,16 +1,36 @@ + + diff --git a/packages/crud/src/components/adv/search.tsx b/packages/crud/src/components/adv/search.tsx index a7320f3..cf56bf8 100644 --- a/packages/crud/src/components/adv/search.tsx +++ b/packages/crud/src/components/adv/search.tsx @@ -78,6 +78,7 @@ export default defineComponent({ function reset() { Form.value?.reset(); emit("reset"); + search(); } // 清空数据 @@ -160,9 +161,9 @@ export default defineComponent({ v-model={visible.value} direction="rtl" with-header={false} - size={browser.isMini ? "100%" : props.size}> + size={browser.isMini ? "100%" : config.size}>
- {props.title || crud.dict.label.advSearch} + {config.title || crud.dict.label.advSearch} diff --git a/packages/crud/src/components/context-menu/index.tsx b/packages/crud/src/components/context-menu/index.tsx index 15cdf6c..7d1333f 100644 --- a/packages/crud/src/components/context-menu/index.tsx +++ b/packages/crud/src/components/context-menu/index.tsx @@ -1,7 +1,9 @@ -import { defineComponent, nextTick, onMounted, reactive, ref, h, render } from "vue"; +import { defineComponent, nextTick, onMounted, reactive, ref, h, render, toRaw } from "vue"; import { isString } from "lodash-es"; import { addClass, contains, removeClass } from "../../utils"; import { useRefs } from "../../hooks"; +import { ElIcon } from "element-plus"; +import { ArrowRight } from "@element-plus/icons-vue"; const ClContextMenu = defineComponent({ name: "cl-context-menu", @@ -89,7 +91,7 @@ const ClContextMenu = defineComponent({ // 点击样式 if (options.hover) { - let d = options.hover === true ? {} : options.hover; + const d = options.hover === true ? {} : options.hover; targetEl = event.target; if (targetEl && isString(targetEl.className)) { @@ -187,15 +189,22 @@ const ClContextMenu = defineComponent({ .map((e, i) => { const id = `${pId}-${i}`; + if (!e.suffixIcon) { + // 默认图标 + if (e.children) { + e.suffixIcon = ArrowRight; + } + } + return (
{/* 前缀图标 */} - {e.prefixIcon && } + {e.prefixIcon && {h(toRaw(e.prefixIcon))}} {/* 标题 */} {/* 后缀图标 */} - {e.suffixIcon && } + {e.suffixIcon && {h(toRaw(e.suffixIcon))}} - {/* 子集*/} + {/* 子集 */} {e.children && e.showChildren && deep(e.children, id, level + 1)} diff --git a/packages/crud/src/components/dialog/index.tsx b/packages/crud/src/components/dialog/index.tsx index b8de293..bbf20fe 100644 --- a/packages/crud/src/components/dialog/index.tsx +++ b/packages/crud/src/components/dialog/index.tsx @@ -50,7 +50,12 @@ export default defineComponent({ // 隐藏头部元素 hideHeader: Boolean, // 关闭前 - beforeClose: Function + beforeClose: Function, + // 是否需要滚动条 + scrollbar: { + type: Boolean, + default: true + } }, emits: ["update:modelValue", "fullscreen-change"], @@ -242,16 +247,28 @@ export default defineComponent({ return renderHeader(); }, default() { - return ( - -
+ const height = isFullscreen.value ? "100%" : props.height; + + const style = { + padding: props.padding, + height + }; + + function content() { + return ( +
{slots.default?.()}
- - ); + ); + } + + if (props.scrollbar) { + style.height = "auto"; + + return {content()}; + } else { + return content(); + } }, footer() { const d = slots.footer?.(); diff --git a/packages/crud/src/components/form/index.tsx b/packages/crud/src/components/form/index.tsx index 0f79298..c0e8019 100644 --- a/packages/crud/src/components/form/index.tsx +++ b/packages/crud/src/components/form/index.tsx @@ -119,21 +119,32 @@ export default defineComponent({ // 拷贝表单值 const d = cloneDeep(form); - // 过滤隐藏的表单项 config.items.forEach((e) => { - if (e._hidden) { + function deep(e: ClForm.Item) { if (e.prop) { - delete d[e.prop]; + // 过滤隐藏的表单项 + if (e._hidden) { + if (e.prop) { + delete d[e.prop]; + } + } + + // hook 提交处理 + if (e.hook) { + formHook.submit({ + ...e, + value: e.prop ? d[e.prop] : undefined, + form: d + }); + } + } + + if (e.children) { + e.children.forEach(deep); } } - if (e.hook) { - formHook.submit({ - ...e, - value: e.prop ? d[e.prop] : undefined, - form: d - }); - } + deep(e); }); // 处理 "-" 多层级 @@ -152,7 +163,7 @@ export default defineComponent({ let f: any = d[a]; // 设置默认值 - arr.forEach((e: any) => { + arr.forEach((e) => { if (!f[e]) { f[e] = {}; } @@ -249,7 +260,7 @@ export default defineComponent({ } // 设置表单数据 - config.items.map((e) => { + config.items.forEach((e) => { function deep(e: ClForm.Item) { if (e.prop) { // 解析 prop @@ -260,7 +271,7 @@ export default defineComponent({ // prop 合并 Tabs.mergeProp(e); - // 绑定值 + // hook 绑定值 formHook.bind({ ...e, value: form[e.prop] !== undefined ? form[e.prop] : cloneDeep(e.value), @@ -274,17 +285,17 @@ export default defineComponent({ message: `${e.label}${dict.label.nonEmpty}` }; } - - // 子集 - if (e.children) { - e.children.forEach(deep); - } } // 设置 tabs 默认值 if (e.type == "tabs") { Tabs.set(e.value); } + + // 子集 + if (e.children) { + e.children.forEach(deep); + } } deep(e); @@ -312,11 +323,19 @@ export default defineComponent({ // 绑定表单数据 function bindForm(data: any) { config.items.forEach((e) => { - formHook.bind({ - ...e, - value: e.prop ? data[e.prop] : undefined, - form: data - }); + function deep(e: ClForm.Item) { + formHook.bind({ + ...e, + value: e.prop ? data[e.prop] : undefined, + form: data + }); + + if (e.children) { + e.children.forEach(deep); + } + } + + deep(e); }); Object.assign(form, data); @@ -344,105 +363,104 @@ export default defineComponent({ const isLoaded = e.component && Tabs.isLoaded(e.group); // 表单项 - const FormItem = isLoaded - ? h( - , - e.props, - { - label() { - return e.renderLabel - ? renderNode(e.renderLabel, { - scope: form, - render: "slot", - slots - }) - : e.label; - }, - default() { - return ( -
-
- {["prepend", "component", "append"] - .filter((k) => e[k]) - .map((name) => { - const children = e.children && ( -
- - {e.children.map(renderFormItem)} - -
- ); + const FormItem = h( + , + e.props, + { + label() { + return e.renderLabel + ? renderNode(e.renderLabel, { + scope: form, + render: "slot", + slots + }) + : e.label; + }, + default() { + return ( +
+
+ {["prepend", "component", "append"] + .filter((k) => e[k]) + .map((name) => { + const children = e.children && ( +
+ + {e.children.map(renderFormItem)} + +
+ ); - const Item = renderNode(e[name], { - item: e, - prop: e.prop, - scope: form, - slots, - children, - _data: { - isDisabled + const Item = renderNode(e[name], { + item: e, + prop: e.prop, + scope: form, + slots, + children, + _data: { + isDisabled + } + }); + + return ( +
+ {Item} +
+ ); + })} +
- return ( -
- {Item} -
- ); - })} -
- - {isBoolean(e.collapse) && ( -
{ - Action.collapseItem(e); - }}> - - {e.collapse - ? dict.label.seeMore - : dict.label.hideContent} - -
- )} + {isBoolean(e.collapse) && ( +
{ + Action.collapseItem(e); + }}> + + {e.collapse + ? dict.label.seeMore + : dict.label.hideContent} +
- ); - } - } - ) - : null; + )} +
+ ); + } + } + ); - // 行内 - if (props.inline) { - return FormItem; - } - - return ( - + // 是否行内 + const Item = props.inline ? ( + FormItem + ) : ( + {FormItem} ); + + return isLoaded ? Item : null; } // 渲染表单 diff --git a/packages/crud/src/components/search/index.tsx b/packages/crud/src/components/search/index.tsx index 72455cd..0eaabc8 100644 --- a/packages/crud/src/components/search/index.tsx +++ b/packages/crud/src/components/search/index.tsx @@ -87,8 +87,20 @@ export default defineComponent({ // 重置 function reset() { + const d: any = {}; + + config.items?.map((e) => { + d[e.prop!] = undefined; + }); + + // 重置表单 Form.value?.reset(); - emit("reset"); + + // 列表刷新 + crud.refresh(d); + + // 重置事件 + emit("reset", d); } expose({ @@ -123,6 +135,7 @@ export default defineComponent({ append() { return ( + {/* 搜索按钮 */} {crud.dict.label.search} + + {/* 重置按钮 */} {config.resetBtn && ( {crud.dict.label.reset} )} + + {/* 自定义按钮 */} + {slots?.buttons?.(Form.value?.form)} ); }, diff --git a/packages/crud/src/static/index.scss b/packages/crud/src/static/index.scss index 19d42fc..c31344e 100644 --- a/packages/crud/src/static/index.scss +++ b/packages/crud/src/static/index.scss @@ -371,6 +371,7 @@ ul { display: inline-flex; white-space: nowrap; + margin: 0; li { display: inline-flex; @@ -397,7 +398,9 @@ position: absolute; bottom: -1px; left: 0; - transition: transform 0.3s ease-in-out, width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1); + transition: + transform 0.3s ease-in-out, + width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1); background-color: var(--el-color-primary); } @@ -514,14 +517,7 @@ user-select: none; } - &__container { - & > .el-scrollbar__wrap > .el-scrollbar__view { - height: 100%; - } - } - &__default { - height: 100%; box-sizing: border-box; } diff --git a/packages/crud/src/utils/form-hook.ts b/packages/crud/src/utils/form-hook.ts index 3bdceeb..2a3c12c 100644 --- a/packages/crud/src/utils/form-hook.ts +++ b/packages/crud/src/utils/form-hook.ts @@ -1,6 +1,6 @@ -import { isArray, isFunction, isObject, isString } from "lodash-es"; +import { isArray, isEmpty, isFunction, isObject, isString } from "lodash-es"; -export const format: { [key: string]: Hook.fn } = { +export const format: { [key: string]: ClForm.HookFn } = { number(value) { return value ? (isArray(value) ? value.map(Number) : Number(value)) : value; }, @@ -63,6 +63,10 @@ export const format: { [key: string]: Hook.fn } = { return value === "" ? undefined : value; } + if (isArray(value)) { + return isEmpty(value) ? undefined : value; + } + return value; } }; @@ -139,7 +143,7 @@ const formHook = { } }; -export function registerFormHook(name: string, fn: Hook.fn) { +export function registerFormHook(name: string, fn: ClForm.HookFn) { format[name] = fn; } diff --git a/packages/crud/types/components/dialog/index.d.ts b/packages/crud/types/components/dialog/index.d.ts index 28dec25..06737a8 100644 --- a/packages/crud/types/components/dialog/index.d.ts +++ b/packages/crud/types/components/dialog/index.d.ts @@ -25,6 +25,10 @@ declare const _default: import("vue").DefineComponent<{ }; hideHeader: BooleanConstructor; beforeClose: FunctionConstructor; + scrollbar: { + type: BooleanConstructor; + default: boolean; + }; }, () => import("vue").VNode, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "fullscreen-change")[], "update:modelValue" | "fullscreen-change", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly> & { "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined; "onFullscreen-change"?: ((...args: any[]) => any) | undefined; @@ -66,5 +74,6 @@ declare const _default: import("vue").DefineComponent<{ controls: unknown[]; fullscreen: boolean; modelValue: boolean; + scrollbar: boolean; }, {}>; export default _default; diff --git a/packages/crud/types/components/form/helper/index.d.ts b/packages/crud/types/components/form/helper/index.d.ts index 0ce6b71..d311c9d 100644 --- a/packages/crud/types/components/form/helper/index.d.ts +++ b/packages/crud/types/components/form/helper/index.d.ts @@ -56,17 +56,17 @@ export declare function useForm(): { xl: any; tag: string; } | undefined; - hook?: string | { - bind?: Hook.FormPipe | Hook.FormPipe[] | undefined; - submit?: Hook.FormPipe | Hook.FormPipe[] | undefined; - } | undefined; group?: string | undefined; collapse?: boolean | undefined; value?: any; label?: string | undefined; renderLabel?: any; flex?: boolean | undefined; - hidden?: ((options: { + hook?: ClForm.HookKey | { + bind?: ClForm.HookPipe | ClForm.HookPipe[] | undefined; + submit?: ClForm.HookPipe | ClForm.HookPipe[] | undefined; + } | undefined; + hidden?: boolean | ((options: { scope: obj; }) => boolean) | undefined; prepend?: { diff --git a/packages/crud/types/components/table/helper/index.d.ts b/packages/crud/types/components/table/helper/index.d.ts index c55f28a..29fb9ad 100644 --- a/packages/crud/types/components/table/helper/index.d.ts +++ b/packages/crud/types/components/table/helper/index.d.ts @@ -143,9 +143,8 @@ export declare function useTable(props: any): { contextMenu: ("info" | "update" | "delete" | "edit" | "refresh" | { [x: string]: any; label: string; - icon?: string | undefined; - prefixIcon?: string | undefined; - suffixIcon?: string | undefined; + prefixIcon?: any; + suffixIcon?: any; ellipsis?: boolean | undefined; disabled?: boolean | undefined; hidden?: boolean | undefined; diff --git a/packages/crud/types/utils/form-hook.d.ts b/packages/crud/types/utils/form-hook.d.ts index 9cc0d82..ec74e29 100644 --- a/packages/crud/types/utils/form-hook.d.ts +++ b/packages/crud/types/utils/form-hook.d.ts @@ -1,10 +1,10 @@ /// export declare const format: { - [key: string]: Hook.fn; + [key: string]: ClForm.HookFn; }; declare const formHook: { bind(data: any): void; submit(data: any): void; }; -export declare function registerFormHook(name: string, fn: Hook.fn): void; +export declare function registerFormHook(name: string, fn: ClForm.HookFn): void; export default formHook; diff --git a/src/config/proxy.ts b/src/config/proxy.ts index 9d6c263..d938a07 100644 --- a/src/config/proxy.ts +++ b/src/config/proxy.ts @@ -1,6 +1,8 @@ export const proxy = { "/dev/": { - target: "http://127.0.0.1:8001", + target: "http://192.168.0.119:8001", + // target: "http://127.0.0.1:8004", + // target: "https://test-admin.cool-js.cloud", changeOrigin: true, rewrite: (path: string) => path.replace(/^\/dev/, "") }, diff --git a/src/cool/bootstrap/module.ts b/src/cool/bootstrap/module.ts index e611c4f..3f81f23 100644 --- a/src/cool/bootstrap/module.ts +++ b/src/cool/bootstrap/module.ts @@ -1,13 +1,16 @@ import { App } from "vue"; -import { isFunction, orderBy } from "lodash-es"; +import { isFunction, orderBy, chain } from "lodash-es"; import { filename } from "../utils"; import { module } from "../module"; import { hmr } from "../hook"; // 扫描文件 -const files: any = import.meta.glob("/src/modules/*/{config.ts,service/**,directives/**}", { - eager: true -}); +const files: any = import.meta.glob( + "/src/{modules,plugins}/*/{config.ts,service/**,directives/**}", + { + eager: true + } +); // 模块列表 module.list = hmr.getData("modules", []); @@ -15,7 +18,7 @@ module.list = hmr.getData("modules", []); // 解析 for (const i in files) { // 分割 - const [, , , name, action] = i.split("/"); + const [, , type, name, action] = i.split("/"); // 文件名 const fname = filename(i); @@ -29,6 +32,7 @@ for (const i in files) { // 数据 const d = m || { name, + type, value: null, services: [], directives: [] diff --git a/src/cool/module/index.ts b/src/cool/module/index.ts index 60bcb55..84b4082 100644 --- a/src/cool/module/index.ts +++ b/src/cool/module/index.ts @@ -13,6 +13,9 @@ const module = { get(name: string): Module { return this.list.find((e) => e.name == name)!; }, + config(name: string) { + return this.get(name).options || {}; + }, add(data: Module) { this.list.push(data); }, diff --git a/src/cool/router/index.ts b/src/cool/router/index.ts index 0a1b527..156e7f6 100644 --- a/src/cool/router/index.ts +++ b/src/cool/router/index.ts @@ -6,6 +6,9 @@ import { useBase } from "/$/base"; import { Loading } from "../utils"; import { config } from "/@/config"; +// 基本路径 +const baseUrl = import.meta.env.BASE_URL; + // 扫描文件 const files = import.meta.glob(["/src/modules/*/{views,pages}/**/*", "!**/components"]); @@ -26,7 +29,10 @@ const routes: RouteRecordRaw[] = [ // 创建路由器 const router = createRouter({ - history: config.app.router.mode == "history" ? createWebHistory() : createWebHashHistory(), + history: + config.app.router.mode == "history" + ? createWebHistory(baseUrl) + : createWebHashHistory(baseUrl), routes }) as Router; diff --git a/src/modules/base/components/avatar/index.scss b/src/modules/base/components/avatar/index.scss deleted file mode 100644 index ada1ec1..0000000 --- a/src/modules/base/components/avatar/index.scss +++ /dev/null @@ -1,10 +0,0 @@ -.cl-avatar { - .el-avatar { - display: block; - margin: 0 auto; - } - - img { - width: 100%; - } -} diff --git a/src/modules/base/components/avatar/index.tsx b/src/modules/base/components/avatar/index.tsx index e645d4d..20dcec0 100644 --- a/src/modules/base/components/avatar/index.tsx +++ b/src/modules/base/components/avatar/index.tsx @@ -1,5 +1,5 @@ -import { defineComponent, PropType } from "vue"; -import "./index.scss"; +import { defineComponent, type PropType } from "vue"; +import { UserFilled } from "@element-plus/icons-vue"; export default defineComponent({ name: "cl-avatar", @@ -7,7 +7,10 @@ export default defineComponent({ props: { modelValue: String, src: String, - icon: null, + icon: { + type: null, + default: UserFilled + }, size: [String, Number] as PropType<"large" | "default" | "small" | number>, shape: String as PropType<"circle" | "square">, fit: { @@ -19,18 +22,16 @@ export default defineComponent({ setup(props) { return () => { return ( -
- -
+ ); }; } diff --git a/src/modules/base/components/dept/check.vue b/src/modules/base/components/dept/check.vue index 1ff4d7a..a8cfad1 100644 --- a/src/modules/base/components/dept/check.vue +++ b/src/modules/base/components/dept/check.vue @@ -71,13 +71,13 @@ function onCheckChange(_: any, { checkedKeys }: any) { // 监听过滤 watch(keyword, (val: string) => { - Tree.value.filter(val); + Tree.value?.filter(val); }); useUpsert({ async onOpened() { await refresh(); - Tree.value.setCheckedKeys(props.modelValue || []); + Tree.value?.setCheckedKeys(props.modelValue || []); } }); diff --git a/src/modules/base/components/image/index.vue b/src/modules/base/components/image/index.vue index e22215b..b87f4e0 100644 --- a/src/modules/base/components/image/index.vue +++ b/src/modules/base/components/image/index.vue @@ -18,7 +18,7 @@ preview-teleported > @@ -27,7 +27,7 @@ diff --git a/src/modules/base/views/role.vue b/src/modules/base/views/role.vue index f7c0692..5756ade 100644 --- a/src/modules/base/views/role.vue +++ b/src/modules/base/views/role.vue @@ -19,19 +19,29 @@ @@ -96,30 +106,20 @@ const Upsert = useUpsert({ { label: "数据权限", prop: "relevance", - flex: false, component: { name: "slot-relevance" } - }, - { - label: "", - prop: "departmentIdList", - value: [], - component: { - name: "cl-dept-check", - props: {}, - style: { - marginTop: "-10px" - } - } } ], - plugins: [setFocus()], + onSubmit(data, { next }) { + next({ + ...data, + departmentIdList: data.departmentIdList || [] + }); + }, - onOpened(data) { - onRelevanceChange(data.relevance || 0); - } + plugins: [setFocus()] }); // cl-table @@ -164,11 +164,4 @@ const Table = useTable({ } ] }); - -// 是否关联上下级 -function onRelevanceChange(val: number | string | boolean) { - Upsert.value?.setProps("departmentIdList", { - checkStrictly: val == 0 - }); -} diff --git a/src/modules/base/views/user/components/dept-list.vue b/src/modules/base/views/user/components/dept-list.vue index e0b01d7..4917225 100644 --- a/src/modules/base/views/user/components/dept-list.vue +++ b/src/modules/base/views/user/components/dept-list.vue @@ -81,7 +81,8 @@ import { deepTree, revDeepTree } from "/@/cool/utils"; import { isArray } from "lodash-es"; import { ContextMenu, setFocus, useForm } from "@cool-vue/crud"; import { Refresh as RefreshIcon, Operation, MoreFilled } from "@element-plus/icons-vue"; -import { checkPerm, useViewGroup } from "/$/base"; +import { checkPerm } from "/$/base"; +import { useViewGroup } from "/@/plugins/view"; const props = defineProps({ drag: { @@ -97,9 +98,8 @@ const props = defineProps({ const emit = defineEmits(["refresh", "user-add"]); const { service, browser } = useCool(); -const { ViewGroup } = useViewGroup(); - const Form = useForm(); +const { ViewGroup } = useViewGroup(); // 树形列表 const list = ref([]); diff --git a/src/modules/base/views/user/index.vue b/src/modules/base/views/user/index.vue index e493fdf..d2c05ba 100644 --- a/src/modules/base/views/user/index.vue +++ b/src/modules/base/views/user/index.vue @@ -59,9 +59,9 @@ diff --git a/src/modules/demo/components/svg.vue b/src/modules/demo/components/svg.vue index f70e300..1a09ce6 100644 --- a/src/modules/demo/components/svg.vue +++ b/src/modules/demo/components/svg.vue @@ -1,7 +1,7 @@ + + diff --git a/src/plugins/editor-preview/config.ts b/src/plugins/editor-preview/config.ts new file mode 100644 index 0000000..188c944 --- /dev/null +++ b/src/plugins/editor-preview/config.ts @@ -0,0 +1,7 @@ +import { ModuleConfig } from "/@/cool"; + +export default (): ModuleConfig => { + return { + components: [() => import("./components/preview.vue")] + }; +}; diff --git a/src/modules/extend/editor/wang.vue b/src/plugins/editor-wang/components/wang.vue similarity index 95% rename from src/modules/extend/editor/wang.vue rename to src/plugins/editor-wang/components/wang.vue index 4fd620a..febe9cc 100644 --- a/src/modules/extend/editor/wang.vue +++ b/src/plugins/editor-wang/components/wang.vue @@ -42,7 +42,7 @@