diff --git a/.gitignore b/.gitignore index 3399f39c0..df1f37a8a 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,10 @@ vite.config.ts.* *.sw? .history .cursor + +# AI +.agent +.agents +.claude +.codex +skills-lock.json diff --git a/.npmrc b/.npmrc index aeac1ae91..6d28fabf4 100644 --- a/.npmrc +++ b/.npmrc @@ -1,8 +1,8 @@ registry=https://registry.npmmirror.com public-hoist-pattern[]=lefthook public-hoist-pattern[]=eslint -public-hoist-pattern[]=prettier -public-hoist-pattern[]=prettier-plugin-tailwindcss +public-hoist-pattern[]=oxfmt +public-hoist-pattern[]=oxlint public-hoist-pattern[]=stylelint public-hoist-pattern[]=*postcss* public-hoist-pattern[]=@commitlint/* diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index d0b0ca133..000000000 --- a/.prettierignore +++ /dev/null @@ -1,18 +0,0 @@ -dist -dev-dist -.local -.output.js -node_modules -.nvmrc -coverage -CODEOWNERS -.nitro -.output - - -**/*.svg -**/*.sh - -public -.npmrc -*-lock.yaml diff --git a/.prettierrc.mjs b/.prettierrc.mjs deleted file mode 100644 index 3e25d2cfa..000000000 --- a/.prettierrc.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/prettier-config'; diff --git a/.stylelintignore b/.stylelintignore index f4b2db2c1..3adb33b22 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -2,3 +2,7 @@ dist public __tests__ coverage +.codex +.claude +.agent +.agents diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e8dc9ed9b..9da1daba8 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,12 +2,12 @@ "recommendations": [ // Vue 3 的语言支持 "Vue.volar", - // 将 ESLint JavaScript 集成到 VS Code 中。 - "dbaeumer.vscode-eslint", + // 将 oxlint 集成到 VS Code 中。 + "oxc.oxc-vscode", // Visual Studio Code 的官方 Stylelint 扩展 "stylelint.vscode-stylelint", - // 使用 Prettier 的代码格式化程序 - "esbenp.prettier-vscode", + // 使用 oxfmt 的代码格式化程序 + "oxc.oxc-vscode", // 支持 dotenv 文件语法 "mikestead.dotenv", // 源代码的拼写检查器 diff --git a/.vscode/settings.json b/.vscode/settings.json index 588357bba..d58dc940c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { - "tailwindCSS.experimental.configFile": "internal/tailwind-config/src/index.ts", + "tailwindCSS.experimental.configFile": "packages/@core/base/design/src/css/global.css", + "tailwindCSS.lint.suggestCanonicalClasses": "ignore", // workbench "workbench.list.smoothScrolling": true, "workbench.startupEditor": "newUntitledFile", @@ -31,39 +32,49 @@ "editor.autoClosingOvertype": "always", "editor.autoClosingQuotes": "beforeWhitespace", "editor.wordSeparators": "`~!@#%^&*()=+[{]}\\|;:'\",.<>/?", + "editor.quickSuggestions": { + "strings": "on" + }, + + // lint && format + "oxc.enable": true, + "oxc.typeAware": true, + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": "oxfmt.config.ts", "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit", + "source.fixAll.oxc": "explicit", "source.fixAll.stylelint": "explicit", "source.organizeImports": "never" }, - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "oxc.oxc-vscode", "[html]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[css]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[scss]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[markdown]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[vue]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, + // extensions "extensions.ignoreRecommendations": true, @@ -79,6 +90,7 @@ "files.insertFinalNewline": true, "files.simpleDialog.enable": true, "files.associations": { + "*.css": "tailwindcss", "*.ejs": "html", "*.art": "html", "**/tsconfig.json": "jsonc", @@ -118,7 +130,7 @@ // search "search.searchEditor.singleClickBehaviour": "peekDefinition", "search.followSymlinks": false, - // 在使用搜索功能时,将这些文件夹/文件排除在外 + // 使用搜索功能时,将这些文件和文件夹排除在外 "search.exclude": { "**/node_modules": true, "**/*.log": true, @@ -193,7 +205,7 @@ "*": false }, - "cssVariables.lookupFiles": ["packages/core/base/design/src/**/*.css"], + "cssVariables.lookupFiles": ["packages/@core/base/design/src/**/*.css"], "i18n-ally.localesPaths": [ "packages/locales/src/langs", @@ -218,12 +230,10 @@ "*.env": "$(capture).env.*", "README.md": "README*,CHANGELOG*,LICENSE,CNAME", "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json", - "eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml", - "tailwind.config.mjs": "postcss.*" + "oxlint.config.ts": ".eslintignore,.stylelintignore,.commitlintrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml,oxfmt.config.*,eslint.config.*" }, "commentTranslate.hover.enabled": false, "commentTranslate.multiLineMerge": true, "vue.server.hybridMode": true, - "typescript.tsdk": "node_modules/typescript/lib", - "oxc.enable": false + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/README.md b/README.md index 0b16aa1f6..b0d294bc2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 🐶 新手必读 -- nodejs > v20.19.0 | v22 | v24 && pnpm > 10.20.0 (强制使用pnpm) +- nodejs >= v20.19.0(推荐 v22 / v24) && pnpm >= 10.32.1(强制使用 pnpm) - 演示地址【Vue3 + element-plus】: - 演示地址【Vue3 + vben5(ant-design-vue)】: - 演示地址【Vue2 + element-ui】: @@ -20,12 +20,12 @@ **芋道**,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。 -- 采用最新 [vue-vben-admin](https://github.com/vbenjs/vue-vben-admin) v5 实现 +- 采用最新 [vue-vben-admin](https://github.com/vbenjs/vue-vben-admin) v5.7.0 实现 - 支持 [Ant Design Vue](https://www.antdv.com/) | [Element Plus](https://element-plus.org/zh-CN/) | [Naive UI](https://www.naiveui.com/) | [TDesign](https://tdesign.tencent.com/) 多种免费开源的中后台模版,具备如下特性: ![首页](.gitee/image/demo/vben.png) -- **最新技术栈**:使用 Vue3、Vite7 等前端前沿技术开发 +- **最新技术栈**:使用 Vue3、Vite8 等前端前沿技术开发 - **TypeScript**: 应用程序级 JavaScript 的语言 - **主题**: 提供多套主题色彩,可配置自定义主题 - **国际化**:内置完善的国际化方案 @@ -41,24 +41,24 @@ | 框架 | 说明 | 版本 | | --- | --- | --- | -| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.27 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 7.3.1 | +| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.30 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 8.0.0 | | [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 | -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.13.1 | -| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.43.2 | -| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.18.0 | +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.13.5 | +| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.44.1 | +| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.18.5 | | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 5.9.3 | | [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.4 | -| [vueuse](https://vueuse.org/) | 常用工具集 | 14.1.0 | -| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.2.8 | -| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.6.4 | -| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 3.4.19 | +| [vueuse](https://vueuse.org/) | 常用工具集 | 14.2.1 | +| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.3.0 | +| [vue-router](https://router.vuejs.org/) | Vue 路由 | 5.0.3 | +| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 4.2.1 | | [Iconify](https://iconify.design/) | 图标组件 | 5.0.0 | -| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.431 | +| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.449 | | [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 7.3.0 | | [Echarts](https://echarts.apache.org/) | 图表库 | 6.0.0 | -| [axios](https://axios-http.com/) | http客户端 | 1.13.2 | -| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.19 | +| [axios](https://axios-http.com/) | http客户端 | 1.13.6 | +| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.20 | | [vee-validate](https://vee-validate.logaretm.com/) | 表单验证 | 4.15.1 | | [zod](https://zod.dev/) | 数据验证 | 3.25.76 | diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index 75506ad31..904f69a77 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -1,6 +1,6 @@ { "name": "@vben/web-antd", - "version": "5.6.0", + "version": "5.7.0", "homepage": "https://vben.pro", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "repository": { diff --git a/apps/web-antd/postcss.config.mjs b/apps/web-antd/postcss.config.mjs deleted file mode 100644 index 3d8070455..000000000 --- a/apps/web-antd/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-antd/public/tinymce/tinymce.d.ts b/apps/web-antd/public/tinymce/tinymce.d.ts index 20f888b56..a87b1629a 100644 --- a/apps/web-antd/public/tinymce/tinymce.d.ts +++ b/apps/web-antd/public/tinymce/tinymce.d.ts @@ -2537,12 +2537,12 @@ interface EditorSelection { normalize: () => Range; selectorChanged: (selector: string, callback: (active: boolean, args: { node: Node; - selector: String; + selector: string; parents: Node[]; }) => void) => EditorSelection; selectorChangedWithUnbind: (selector: string, callback: (active: boolean, args: { node: Node; - selector: String; + selector: string; parents: Node[]; }) => void) => { unbind: () => void; @@ -3217,9 +3217,9 @@ interface Tools { (arr: ArrayLike | null | undefined, cb: ArrayCallback): R[]; (obj: Record | null | undefined, cb: ObjCallback): R[]; }; - extend: (obj: Object, ext: Object, ...objs: Object[]) => any; + extend: (obj: object, ext: object, ...objs: object[]) => any; walk: >(obj: T, f: WalkCallback, n?: keyof T, scope?: any) => void; - resolve: (path: string, o?: Object) => any; + resolve: (path: string, o?: object) => any; explode: (s: string | string[], d?: string | RegExp) => string[]; _addCacheSuffix: (url: string) => string; } diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index 15ab9212a..9bf5d0d04 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -199,7 +199,7 @@ setupVbenVxeTable({ vxeUI.renderer.add('CellOperation', { renderTableDefault({ attrs, options, props }, { column, row }) { const defaultProps = { size: 'small', type: 'link', ...props }; - let align = 'end'; + let align: string; switch (column.align) { case 'center': { align = 'center'; diff --git a/apps/web-antd/src/api/crm/customer/limitConfig/index.ts b/apps/web-antd/src/api/crm/customer/limitConfig/index.ts index f99a35f31..102e98db3 100644 --- a/apps/web-antd/src/api/crm/customer/limitConfig/index.ts +++ b/apps/web-antd/src/api/crm/customer/limitConfig/index.ts @@ -16,10 +16,10 @@ export namespace CrmCustomerLimitConfigApi { /** 客户限制配置类型 */ export enum LimitConfType { - /** 锁定客户数限制 */ - CUSTOMER_LOCK_LIMIT = 2, /** 拥有客户数限制 */ CUSTOMER_QUANTITY_LIMIT = 1, + /** 锁定客户数限制 */ + CUSTOMER_LOCK_LIMIT = 2, } /** 查询客户限制配置列表 */ diff --git a/apps/web-antd/src/api/crm/permission/index.ts b/apps/web-antd/src/api/crm/permission/index.ts index 296e442f0..b95e142b1 100644 --- a/apps/web-antd/src/api/crm/permission/index.ts +++ b/apps/web-antd/src/api/crm/permission/index.ts @@ -35,11 +35,11 @@ export namespace CrmPermissionApi { * CRM 业务类型枚举 */ export enum BizTypeEnum { - CRM_BUSINESS = 4, // 商机 CRM_CLUE = 1, // 线索 - CRM_CONTACT = 3, // 联系人 - CRM_CONTRACT = 5, // 合同 CRM_CUSTOMER = 2, // 客户 + CRM_CONTACT = 3, // 联系人 + CRM_BUSINESS = 4, // 商机 + CRM_CONTRACT = 5, // 合同 CRM_PRODUCT = 6, // 产品 CRM_RECEIVABLE = 7, // 回款 CRM_RECEIVABLE_PLAN = 8, // 回款计划 diff --git a/apps/web-antd/src/api/iot/device/modbus/point/index.ts b/apps/web-antd/src/api/iot/device/modbus/point/index.ts index fa5c6767d..11b440fae 100644 --- a/apps/web-antd/src/api/iot/device/modbus/point/index.ts +++ b/apps/web-antd/src/api/iot/device/modbus/point/index.ts @@ -37,16 +37,12 @@ export function getModbusPoint(id: number) { } /** 创建 Modbus 点位配置 */ -export function createModbusPoint( - data: IotDeviceModbusPointApi.ModbusPoint, -) { +export function createModbusPoint(data: IotDeviceModbusPointApi.ModbusPoint) { return requestClient.post('/iot/device-modbus-point/create', data); } /** 更新 Modbus 点位配置 */ -export function updateModbusPoint( - data: IotDeviceModbusPointApi.ModbusPoint, -) { +export function updateModbusPoint(data: IotDeviceModbusPointApi.ModbusPoint) { return requestClient.put('/iot/device-modbus-point/update', data); } diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts index 2568def87..15539ab93 100644 --- a/apps/web-antd/src/api/request.ts +++ b/apps/web-antd/src/api/request.ts @@ -119,7 +119,9 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { response.data = apiEncrypt.decryptResponse(response.data); } catch (error) { console.error('响应数据解密失败:', error); - throw new Error(`响应数据解密失败: ${(error as Error).message}`); + throw new Error(`响应数据解密失败: ${(error as Error).message}`, { + cause: error, + }); } } return response; diff --git a/apps/web-antd/src/components/description/use-description.ts b/apps/web-antd/src/components/description/use-description.ts index fd24920f0..e3b676af2 100644 --- a/apps/web-antd/src/components/description/use-description.ts +++ b/apps/web-antd/src/components/description/use-description.ts @@ -21,7 +21,7 @@ export function useDescription(options?: Partial) { inheritAttrs: false, setup(_props, { attrs, slots }) { return () => { - // @ts-ignore - 避免类型实例化过深 + // @ts-expect-error - 避免类型实例化过深 return h(Description, { ...propsState, ...attrs }, slots); }; }, diff --git a/apps/web-antd/src/components/form-create/components/area-select.vue b/apps/web-antd/src/components/form-create/components/area-select.vue index 9a025ed3e..9fa8d5b05 100644 --- a/apps/web-antd/src/components/form-create/components/area-select.vue +++ b/apps/web-antd/src/components/form-create/components/area-select.vue @@ -2,10 +2,11 @@ diff --git a/apps/web-antd/src/components/upload/image-upload.vue b/apps/web-antd/src/components/upload/image-upload.vue index b78d8f15d..7f0a62c1e 100644 --- a/apps/web-antd/src/components/upload/image-upload.vue +++ b/apps/web-antd/src/components/upload/image-upload.vue @@ -146,6 +146,7 @@ async function handlePreview(file: UploadFile) { async function handleRemove(file: UploadFile) { if (fileList.value) { const index = fileList.value.findIndex((item) => item.uid === file.uid); + // oxlint-disable-next-line no-unused-expressions index !== -1 && fileList.value.splice(index, 1); const value = getValue(); isInnerOperate.value = true; @@ -350,6 +351,8 @@ function getValue() { diff --git a/apps/web-antd/src/store/auth.ts b/apps/web-antd/src/store/auth.ts index dcef71175..7d09f0ec4 100644 --- a/apps/web-antd/src/store/auth.ts +++ b/apps/web-antd/src/store/auth.ts @@ -83,6 +83,7 @@ export const useAuthStore = defineStore('auth', () => { if (accessStore.loginExpired) { accessStore.setLoginExpired(false); } else { + // oxlint-disable-next-line no-unused-expressions onSuccess ? await onSuccess?.() : await router.push( @@ -132,6 +133,7 @@ export const useAuthStore = defineStore('auth', () => { async function fetchUserInfo() { // 加载 + // eslint-disable-next-line no-useless-assignment let authPermissionInfo: AuthPermissionInfo | null = null; authPermissionInfo = await getAuthPermissionInfoApi(); // userStore diff --git a/apps/web-antd/src/utils/index.ts b/apps/web-antd/src/utils/index.ts index 287c2c738..5e797abcb 100644 --- a/apps/web-antd/src/utils/index.ts +++ b/apps/web-antd/src/utils/index.ts @@ -34,9 +34,7 @@ export const findIndex = >( */ export const isUrl = (path: string): boolean => { // fix:修复hash路由无法跳转的问题 - /* eslint-disable regexp/no-unused-capturing-group, regexp/no-super-linear-backtracking, regexp/no-useless-quantifier */ const reg = /(((^https?:(?:\/\/)?)(?:[-:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%#/.\w-]*)?\??[-+=&%@.\w]*(?:#\w*)?)?)$/; return reg.test(path); - /* eslint-enable regexp/no-unused-capturing-group, regexp/no-super-linear-backtracking, regexp/no-useless-quantifier */ }; diff --git a/apps/web-antd/src/views/ai/chat/index/index.vue b/apps/web-antd/src/views/ai/chat/index/index.vue index 14440a3aa..4a42447c0 100644 --- a/apps/web-antd/src/views/ai/chat/index/index.vue +++ b/apps/web-antd/src/views/ai/chat/index/index.vue @@ -571,6 +571,7 @@ onMounted(async () => { size="small" @click="openChatConversationUpdateForm" > + diff --git a/apps/web-antd/src/views/ai/image/index/index.vue b/apps/web-antd/src/views/ai/image/index/index.vue index 16fdb5ba6..5ddc5c8bf 100644 --- a/apps/web-antd/src/views/ai/image/index/index.vue +++ b/apps/web-antd/src/views/ai/image/index/index.vue @@ -21,6 +21,7 @@ const imageListRef = ref(); // image 列表 ref const dall3Ref = ref(); // dall3(openai) ref const midjourneyRef = ref(); // midjourney ref const stableDiffusionRef = ref(); // stable diffusion ref +// @ts-expect-error: template ref is retained for future provider expansion const commonRef = ref(); // stable diffusion ref const selectPlatform = ref('common'); // 选中的平台 @@ -45,7 +46,9 @@ const platformOptions = [ const models = ref([]); // 模型列表 /** 绘画 start */ -async function handleDrawStart() {} +function handleDrawStart() { + // drawing state is handled by child components +} /** 绘画 complete */ async function handleDrawComplete() { diff --git a/apps/web-antd/src/views/ai/mindmap/index/modules/right.vue b/apps/web-antd/src/views/ai/mindmap/index/modules/right.vue index a2537f393..3e03e3735 100644 --- a/apps/web-antd/src/views/ai/mindmap/index/modules/right.vue +++ b/apps/web-antd/src/views/ai/mindmap/index/modules/right.vue @@ -150,10 +150,12 @@ defineExpose({ ref="mdContainerRef" class="wh-full overflow-y-auto" > +
+
('currentSong', {}); {{ currentSong.date }}
+
diff --git a/apps/web-antd/src/views/ai/workflow/form/modules/workflow-design.vue b/apps/web-antd/src/views/ai/workflow/form/modules/workflow-design.vue index 962fec60e..176b81555 100644 --- a/apps/web-antd/src/views/ai/workflow/form/modules/workflow-design.vue +++ b/apps/web-antd/src/views/ai/workflow/form/modules/workflow-design.vue @@ -106,7 +106,9 @@ async function goRun() { try { convertedParams[paramKey] = convertParamValue(value, dataType); } catch (error: any) { - throw new Error(`参数 ${paramKey} 转换失败: ${error.message}`); + throw new Error(`参数 ${paramKey} 转换失败: ${error.message}`, { + cause: error, + }); } } @@ -175,7 +177,7 @@ function convertParamValue(value: string, dataType: string) { try { return JSON.parse(value); } catch (error: any) { - throw new Error(`JSON格式错误: ${error.message}`); + throw new Error(`JSON格式错误: ${error.message}`, { cause: error }); } } default: { diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue index 14fdf8539..add772d32 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue @@ -22,7 +22,7 @@ import { import { Button, ButtonGroup, message, Modal, Tooltip } from 'ant-design-vue'; // 模拟流转流程 -// @ts-ignore +// @ts-expect-error: token simulation package does not ship compatible types import tokenSimulation from 'bpmn-js-token-simulation'; import BpmnModeler from 'bpmn-js/lib/Modeler'; // 代码高亮插件 @@ -132,6 +132,7 @@ const emit = defineEmits([ 'element-click', ]); +// @ts-expect-error: file input ref is set imperatively by the template const bpmnCanvas = ref(); const refFile = ref(); @@ -178,6 +179,7 @@ const additionalModules = computed(() => { ) { Modules.push(...(props.additionalModel as any[])); } else { + // oxlint-disable-next-line no-unused-expressions props.additionalModel && Modules.push(props.additionalModel); } @@ -417,6 +419,7 @@ const processSimulation = () => { // bpmnModeler.get('toggleMode', 'strict'), // "bpmnModeler.get('toggleMode')", // ); + // oxlint-disable-next-line no-unused-expressions props.simulation && bpmnModeler.get('toggleMode', 'strict').toggleMode(); }; const processRedo = () => { diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js index 638317fb8..b8f1dfef7 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js @@ -7,7 +7,7 @@ import { hasPrimaryModifier } from 'diagram-js/lib/util/Mouse'; /** * A provider for BPMN 2.0 elements context pad */ -export default function ContextPadProvider( +function ContextPadProvider( config, injector, eventBus, @@ -57,6 +57,8 @@ export default function ContextPadProvider( }); } +export default ContextPadProvider; + ContextPadProvider.$inject = [ 'config.contextPad', 'injector', diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js index 3956be680..325726a9b 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js @@ -3,7 +3,7 @@ import { isFunction, isObject } from '@vben/utils'; const WILDCARD = '*'; function CamundaModdleExtension(eventBus) { - // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias + // eslint-disable-next-line unicorn/no-this-assignment const self = this; eventBus.on('moddleCopy.canCopyProperty', (context) => { diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js index 75b491ccb..aa682e7db 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js @@ -1,6 +1,6 @@ import PaletteProvider from 'bpmn-js/lib/features/palette/PaletteProvider'; -export default function CustomPalette( +function CustomPalette( palette, create, elementFactory, @@ -24,11 +24,21 @@ export default function CustomPalette( ); } -const F = function () {}; // 核心,利用空对象作为中介; -F.prototype = PaletteProvider.prototype; // 核心,将父类的原型赋值给空对象F; +CustomPalette.$inject = [ + 'palette', + 'create', + 'elementFactory', + 'spaceTool', + 'lassoTool', + 'handTool', + 'globalConnect', + 'translate', +]; -// 利用中介函数重写原型链方法 -F.prototype.getPaletteEntries = function () { +CustomPalette.prototype = Object.create(PaletteProvider.prototype); +CustomPalette.prototype.constructor = CustomPalette; + +CustomPalette.prototype.getPaletteEntries = function () { const actions = {}; const create = this._create; const elementFactory = this._elementFactory; @@ -94,8 +104,7 @@ F.prototype.getPaletteEntries = function () { 'hand-tool': { group: 'tools', className: 'bpmn-icon-hand-tool', - title: '激活抓手工具', - // title: translate("Activate the hand tool"), + title: translate('Activate the hand tool'), action: { click(event) { handTool.activateHand(event); @@ -219,16 +228,4 @@ F.prototype.getPaletteEntries = function () { return actions; }; -CustomPalette.$inject = [ - 'palette', - 'create', - 'elementFactory', - 'spaceTool', - 'lassoTool', - 'handTool', - 'globalConnect', - 'translate', -]; - -CustomPalette.prototype = new F(); // 核心,将 F的实例赋值给子类; -CustomPalette.prototype.constructor = CustomPalette; // 修复子类CustomPalette的构造器指向,防止原型链的混乱; +export default CustomPalette; diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js index 70a27a9a6..9faa09737 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js @@ -1,7 +1,7 @@ /** * A palette provider for BPMN 2.0 elements. */ -export default function PaletteProvider( +function PaletteProvider( palette, create, elementFactory, @@ -23,6 +23,8 @@ export default function PaletteProvider( palette.registerProvider(this); } +export default PaletteProvider; + PaletteProvider.$inject = [ 'palette', 'create', diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js index 4d25da7f5..a573e5f2b 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js @@ -1,4 +1,3 @@ -/* eslint-disable no-template-curly-in-string */ /** * This is a sample file that should be replaced with the actual translation. * @@ -238,10 +237,8 @@ export default { 'Due Date': '到期时间', 'Follow Up Date': '跟踪日期', Priority: '优先级', - 'The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': - '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', - 'The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': - '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', + [`The follow up date as an EL expression (e.g. \${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)`]: `跟踪日期必须符合EL表达式,如: \${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00`, + [`The due date as an EL expression (e.g. \${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)`]: `跟踪日期必须符合EL表达式,如: \${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00`, Variables: '变量', 'Candidate Starter Configuration': '候选人起动器配置', 'Candidate Starter Groups': '候选人起动器组', diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue index 8c8cc6f11..656249b25 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue @@ -39,7 +39,7 @@ watch( val += props.businessObject.eventDefinitions[0]?.$type.split(':')[1] || ''; } - // @ts-ignore + // @ts-expect-error: async component registry is indexed dynamically customConfigComponent.value = ( CustomConfigMap as Record )[val]?.component; diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue index 6caf5c0ab..2883834d3 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue @@ -1,4 +1,3 @@ - diff --git a/apps/web-antdv-next/src/views/_core/authentication/forget-password.vue b/apps/web-antdv-next/src/views/_core/authentication/forget-password.vue index fef0d4279..10444d0ae 100644 --- a/apps/web-antdv-next/src/views/_core/authentication/forget-password.vue +++ b/apps/web-antdv-next/src/views/_core/authentication/forget-password.vue @@ -29,8 +29,7 @@ const formSchema = computed((): VbenFormSchema[] => { }); function handleSubmit(value: Recordable) { - // eslint-disable-next-line no-console - console.log('reset email:', value); + void value; } diff --git a/apps/web-antdv-next/src/views/_core/authentication/register.vue b/apps/web-antdv-next/src/views/_core/authentication/register.vue index b1a5de726..8c4295310 100644 --- a/apps/web-antdv-next/src/views/_core/authentication/register.vue +++ b/apps/web-antdv-next/src/views/_core/authentication/register.vue @@ -82,8 +82,7 @@ const formSchema = computed((): VbenFormSchema[] => { }); function handleSubmit(value: Recordable) { - // eslint-disable-next-line no-console - console.log('register submit:', value); + void value; } diff --git a/apps/web-antdv-next/src/views/dashboard/analytics/index.vue b/apps/web-antdv-next/src/views/dashboard/analytics/index.vue index 5e3d6d285..e794c99a9 100644 --- a/apps/web-antdv-next/src/views/dashboard/analytics/index.vue +++ b/apps/web-antdv-next/src/views/dashboard/analytics/index.vue @@ -76,10 +76,10 @@ const chartTabs: TabOption[] = [
- + - + diff --git a/apps/web-antdv-next/tailwind.config.mjs b/apps/web-antdv-next/tailwind.config.mjs deleted file mode 100644 index f17f556fa..000000000 --- a/apps/web-antdv-next/tailwind.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config'; diff --git a/apps/web-antdv-next/tsconfig.json b/apps/web-antdv-next/tsconfig.json index 02c287fe6..858a0ec08 100644 --- a/apps/web-antdv-next/tsconfig.json +++ b/apps/web-antdv-next/tsconfig.json @@ -2,7 +2,6 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@vben/tsconfig/web-app.json", "compilerOptions": { - "baseUrl": ".", "paths": { "#/*": ["./src/*"] } diff --git a/apps/web-antdv-next/tsconfig.node.json b/apps/web-antdv-next/tsconfig.node.json index c2f0d86cc..36e9fb5fb 100644 --- a/apps/web-antdv-next/tsconfig.node.json +++ b/apps/web-antdv-next/tsconfig.node.json @@ -6,5 +6,5 @@ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "noEmit": false }, - "include": ["vite.config.mts"] + "include": ["vite.config.ts"] } diff --git a/apps/web-antdv-next/vite.config.mts b/apps/web-antdv-next/vite.config.ts similarity index 100% rename from apps/web-antdv-next/vite.config.mts rename to apps/web-antdv-next/vite.config.ts diff --git a/apps/web-ele/package.json b/apps/web-ele/package.json index f04fa87b8..d842d8261 100644 --- a/apps/web-ele/package.json +++ b/apps/web-ele/package.json @@ -1,6 +1,6 @@ { "name": "@vben/web-ele", - "version": "5.6.0", + "version": "5.7.0", "homepage": "https://vben.pro", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "repository": { diff --git a/apps/web-ele/postcss.config.mjs b/apps/web-ele/postcss.config.mjs deleted file mode 100644 index 3d8070455..000000000 --- a/apps/web-ele/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-ele/public/tinymce/tinymce.d.ts b/apps/web-ele/public/tinymce/tinymce.d.ts index 20f888b56..a87b1629a 100644 --- a/apps/web-ele/public/tinymce/tinymce.d.ts +++ b/apps/web-ele/public/tinymce/tinymce.d.ts @@ -2537,12 +2537,12 @@ interface EditorSelection { normalize: () => Range; selectorChanged: (selector: string, callback: (active: boolean, args: { node: Node; - selector: String; + selector: string; parents: Node[]; }) => void) => EditorSelection; selectorChangedWithUnbind: (selector: string, callback: (active: boolean, args: { node: Node; - selector: String; + selector: string; parents: Node[]; }) => void) => { unbind: () => void; @@ -3217,9 +3217,9 @@ interface Tools { (arr: ArrayLike | null | undefined, cb: ArrayCallback): R[]; (obj: Record | null | undefined, cb: ObjCallback): R[]; }; - extend: (obj: Object, ext: Object, ...objs: Object[]) => any; + extend: (obj: object, ext: object, ...objs: object[]) => any; walk: >(obj: T, f: WalkCallback, n?: keyof T, scope?: any) => void; - resolve: (path: string, o?: Object) => any; + resolve: (path: string, o?: object) => any; explode: (s: string | string[], d?: string | RegExp) => string[]; _addCacheSuffix: (url: string) => string; } diff --git a/apps/web-ele/src/adapter/vxe-table.ts b/apps/web-ele/src/adapter/vxe-table.ts index 9f46883c2..724bd0df6 100644 --- a/apps/web-ele/src/adapter/vxe-table.ts +++ b/apps/web-ele/src/adapter/vxe-table.ts @@ -194,6 +194,7 @@ setupVbenVxeTable({ class: '!p-0', ...props, }; + // eslint-disable-next-line no-useless-assignment let align = 'end'; switch (column.align) { case 'center': { diff --git a/apps/web-ele/src/api/crm/customer/limitConfig/index.ts b/apps/web-ele/src/api/crm/customer/limitConfig/index.ts index f99a35f31..102e98db3 100644 --- a/apps/web-ele/src/api/crm/customer/limitConfig/index.ts +++ b/apps/web-ele/src/api/crm/customer/limitConfig/index.ts @@ -16,10 +16,10 @@ export namespace CrmCustomerLimitConfigApi { /** 客户限制配置类型 */ export enum LimitConfType { - /** 锁定客户数限制 */ - CUSTOMER_LOCK_LIMIT = 2, /** 拥有客户数限制 */ CUSTOMER_QUANTITY_LIMIT = 1, + /** 锁定客户数限制 */ + CUSTOMER_LOCK_LIMIT = 2, } /** 查询客户限制配置列表 */ diff --git a/apps/web-ele/src/api/crm/permission/index.ts b/apps/web-ele/src/api/crm/permission/index.ts index 296e442f0..b95e142b1 100644 --- a/apps/web-ele/src/api/crm/permission/index.ts +++ b/apps/web-ele/src/api/crm/permission/index.ts @@ -35,11 +35,11 @@ export namespace CrmPermissionApi { * CRM 业务类型枚举 */ export enum BizTypeEnum { - CRM_BUSINESS = 4, // 商机 CRM_CLUE = 1, // 线索 - CRM_CONTACT = 3, // 联系人 - CRM_CONTRACT = 5, // 合同 CRM_CUSTOMER = 2, // 客户 + CRM_CONTACT = 3, // 联系人 + CRM_BUSINESS = 4, // 商机 + CRM_CONTRACT = 5, // 合同 CRM_PRODUCT = 6, // 产品 CRM_RECEIVABLE = 7, // 回款 CRM_RECEIVABLE_PLAN = 8, // 回款计划 diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts index 97462d84a..0675f912c 100644 --- a/apps/web-ele/src/api/request.ts +++ b/apps/web-ele/src/api/request.ts @@ -119,7 +119,9 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { response.data = apiEncrypt.decryptResponse(response.data); } catch (error) { console.error('响应数据解密失败:', error); - throw new Error(`响应数据解密失败: ${(error as Error).message}`); + throw new Error(`响应数据解密失败: ${(error as Error).message}`, { + cause: error, + }); } } return response; diff --git a/apps/web-ele/src/components/cropper/cropper.vue b/apps/web-ele/src/components/cropper/cropper.vue index 5cdf1bc36..d768fd87a 100644 --- a/apps/web-ele/src/components/cropper/cropper.vue +++ b/apps/web-ele/src/components/cropper/cropper.vue @@ -89,6 +89,7 @@ async function init() { // Real-time display preview function realTimeCropped() { + // oxlint-disable-next-line no-unused-expressions props.realTimePreview && cropped(); } @@ -113,10 +114,9 @@ function cropped() { imgInfo, }); }; - // eslint-disable-next-line unicorn/prefer-add-event-listener - fileReader.onerror = () => { + fileReader.addEventListener('error', () => { emit('cropendError'); - }; + }); }, 'image/png'); } diff --git a/apps/web-ele/src/components/description/use-description.ts b/apps/web-ele/src/components/description/use-description.ts index fd24920f0..9559cb648 100644 --- a/apps/web-ele/src/components/description/use-description.ts +++ b/apps/web-ele/src/components/description/use-description.ts @@ -21,7 +21,6 @@ export function useDescription(options?: Partial) { inheritAttrs: false, setup(_props, { attrs, slots }) { return () => { - // @ts-ignore - 避免类型实例化过深 return h(Description, { ...propsState, ...attrs }, slots); }; }, diff --git a/apps/web-ele/src/components/form-create/components/area-select.vue b/apps/web-ele/src/components/form-create/components/area-select.vue index cd7345261..288101024 100644 --- a/apps/web-ele/src/components/form-create/components/area-select.vue +++ b/apps/web-ele/src/components/form-create/components/area-select.vue @@ -2,10 +2,11 @@ diff --git a/apps/web-ele/src/types/element-plus-style-css.d.ts b/apps/web-ele/src/types/element-plus-style-css.d.ts new file mode 100644 index 000000000..ba7a76672 --- /dev/null +++ b/apps/web-ele/src/types/element-plus-style-css.d.ts @@ -0,0 +1,4 @@ +declare module 'element-plus/es/components/*/style/css' { + const sideEffect: undefined; + export default sideEffect; +} diff --git a/apps/web-ele/src/utils/index.ts b/apps/web-ele/src/utils/index.ts index fc9d735de..9886b8d68 100644 --- a/apps/web-ele/src/utils/index.ts +++ b/apps/web-ele/src/utils/index.ts @@ -35,9 +35,7 @@ export const findIndex = >( */ export const isUrl = (path: string): boolean => { // fix:修复hash路由无法跳转的问题 - /* eslint-disable regexp/no-unused-capturing-group, regexp/no-super-linear-backtracking, regexp/no-useless-quantifier */ const reg = /(((^https?:(?:\/\/)?)(?:[-:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%#/.\w-]*)?\??[-+=&%@.\w]*(?:#\w*)?)?)$/; return reg.test(path); - /* eslint-enable regexp/no-unused-capturing-group, regexp/no-super-linear-backtracking, regexp/no-useless-quantifier */ }; diff --git a/apps/web-ele/src/views/ai/chat/index/index.vue b/apps/web-ele/src/views/ai/chat/index/index.vue index 693403c4a..72e38fef1 100644 --- a/apps/web-ele/src/views/ai/chat/index/index.vue +++ b/apps/web-ele/src/views/ai/chat/index/index.vue @@ -582,7 +582,7 @@ onMounted(async () => { size="small" @click="openChatConversationUpdateForm" > - + {{ activeConversation?.modelName }} (); // image 列表 ref const dall3Ref = ref(); // dall3(openai) ref const midjourneyRef = ref(); // midjourney ref const stableDiffusionRef = ref(); // stable diffusion ref +// @ts-expect-error: template ref is retained for future provider expansion const commonRef = ref(); // stable diffusion ref const selectPlatform = ref('common'); // 选中的平台 @@ -45,7 +46,9 @@ const platformOptions = [ const models = ref([]); // 模型列表 /** 绘画 start */ -async function handleDrawStart() {} +function handleDrawStart() { + // drawing state is handled by child components +} /** 绘画 complete */ async function handleDrawComplete() { diff --git a/apps/web-ele/src/views/ai/mindmap/index/modules/right.vue b/apps/web-ele/src/views/ai/mindmap/index/modules/right.vue index 5adc66aaf..8da862585 100644 --- a/apps/web-ele/src/views/ai/mindmap/index/modules/right.vue +++ b/apps/web-ele/src/views/ai/mindmap/index/modules/right.vue @@ -155,10 +155,12 @@ defineExpose({ ref="mdContainerRef" class="wh-full overflow-y-auto" > +
+
('currentSong', {}); {{ currentSong.date }}
信息复用 +
diff --git a/apps/web-ele/src/views/ai/workflow/form/modules/workflow-design.vue b/apps/web-ele/src/views/ai/workflow/form/modules/workflow-design.vue index 3acb5ad5b..9648fc710 100644 --- a/apps/web-ele/src/views/ai/workflow/form/modules/workflow-design.vue +++ b/apps/web-ele/src/views/ai/workflow/form/modules/workflow-design.vue @@ -106,7 +106,9 @@ async function goRun() { try { convertedParams[paramKey] = convertParamValue(value, dataType); } catch (error: any) { - throw new Error(`参数 ${paramKey} 转换失败: ${error.message}`); + throw new Error(`参数 ${paramKey} 转换失败: ${error.message}`, { + cause: error, + }); } } @@ -175,7 +177,7 @@ function convertParamValue(value: string, dataType: string) { try { return JSON.parse(value); } catch (error: any) { - throw new Error(`JSON格式错误: ${error.message}`); + throw new Error(`JSON格式错误: ${error.message}`, { cause: error }); } } default: { diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue index e77301f20..732b34a03 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue @@ -21,7 +21,7 @@ import { } from '@vben/icons'; // 模拟流转流程 -// @ts-ignore +// @ts-expect-error: token simulation package does not ship compatible types import tokenSimulation from 'bpmn-js-token-simulation'; import BpmnModeler from 'bpmn-js/lib/Modeler'; import { @@ -139,6 +139,7 @@ const emit = defineEmits([ 'element-click', ]); +// @ts-expect-error: file input ref is set imperatively by the template const bpmnCanvas = ref(); const refFile = ref(); @@ -185,6 +186,7 @@ const additionalModules = computed(() => { ) { Modules.push(...(props.additionalModel as any[])); } else { + // oxlint-disable-next-line no-unused-expressions props.additionalModel && Modules.push(props.additionalModel); } @@ -424,6 +426,7 @@ const processSimulation = () => { // bpmnModeler.get('toggleMode', 'strict'), // "bpmnModeler.get('toggleMode')", // ); + // oxlint-disable-next-line no-unused-expressions props.simulation && bpmnModeler.get('toggleMode', 'strict').toggleMode(); }; const processRedo = () => { diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js index 638317fb8..b8f1dfef7 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/content-pad/contentPadProvider.js @@ -7,7 +7,7 @@ import { hasPrimaryModifier } from 'diagram-js/lib/util/Mouse'; /** * A provider for BPMN 2.0 elements context pad */ -export default function ContextPadProvider( +function ContextPadProvider( config, injector, eventBus, @@ -57,6 +57,8 @@ export default function ContextPadProvider( }); } +export default ContextPadProvider; + ContextPadProvider.$inject = [ 'config.contextPad', 'injector', diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js index 3956be680..325726a9b 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/extension-moddle/camunda/extension.js @@ -3,7 +3,7 @@ import { isFunction, isObject } from '@vben/utils'; const WILDCARD = '*'; function CamundaModdleExtension(eventBus) { - // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias + // eslint-disable-next-line unicorn/no-this-assignment const self = this; eventBus.on('moddleCopy.canCopyProperty', (context) => { diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js index 75b491ccb..aa682e7db 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/CustomPalette.js @@ -1,6 +1,6 @@ import PaletteProvider from 'bpmn-js/lib/features/palette/PaletteProvider'; -export default function CustomPalette( +function CustomPalette( palette, create, elementFactory, @@ -24,11 +24,21 @@ export default function CustomPalette( ); } -const F = function () {}; // 核心,利用空对象作为中介; -F.prototype = PaletteProvider.prototype; // 核心,将父类的原型赋值给空对象F; +CustomPalette.$inject = [ + 'palette', + 'create', + 'elementFactory', + 'spaceTool', + 'lassoTool', + 'handTool', + 'globalConnect', + 'translate', +]; -// 利用中介函数重写原型链方法 -F.prototype.getPaletteEntries = function () { +CustomPalette.prototype = Object.create(PaletteProvider.prototype); +CustomPalette.prototype.constructor = CustomPalette; + +CustomPalette.prototype.getPaletteEntries = function () { const actions = {}; const create = this._create; const elementFactory = this._elementFactory; @@ -94,8 +104,7 @@ F.prototype.getPaletteEntries = function () { 'hand-tool': { group: 'tools', className: 'bpmn-icon-hand-tool', - title: '激活抓手工具', - // title: translate("Activate the hand tool"), + title: translate('Activate the hand tool'), action: { click(event) { handTool.activateHand(event); @@ -219,16 +228,4 @@ F.prototype.getPaletteEntries = function () { return actions; }; -CustomPalette.$inject = [ - 'palette', - 'create', - 'elementFactory', - 'spaceTool', - 'lassoTool', - 'handTool', - 'globalConnect', - 'translate', -]; - -CustomPalette.prototype = new F(); // 核心,将 F的实例赋值给子类; -CustomPalette.prototype.constructor = CustomPalette; // 修复子类CustomPalette的构造器指向,防止原型链的混乱; +export default CustomPalette; diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js index 70a27a9a6..9faa09737 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/palette/paletteProvider.js @@ -1,7 +1,7 @@ /** * A palette provider for BPMN 2.0 elements. */ -export default function PaletteProvider( +function PaletteProvider( palette, create, elementFactory, @@ -23,6 +23,8 @@ export default function PaletteProvider( palette.registerProvider(this); } +export default PaletteProvider; + PaletteProvider.$inject = [ 'palette', 'create', diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js index 4d25da7f5..a573e5f2b 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/designer/plugins/translate/zh.js @@ -1,4 +1,3 @@ -/* eslint-disable no-template-curly-in-string */ /** * This is a sample file that should be replaced with the actual translation. * @@ -238,10 +237,8 @@ export default { 'Due Date': '到期时间', 'Follow Up Date': '跟踪日期', Priority: '优先级', - 'The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': - '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', - 'The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': - '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', + [`The follow up date as an EL expression (e.g. \${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)`]: `跟踪日期必须符合EL表达式,如: \${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00`, + [`The due date as an EL expression (e.g. \${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)`]: `跟踪日期必须符合EL表达式,如: \${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00`, Variables: '变量', 'Candidate Starter Configuration': '候选人起动器配置', 'Candidate Starter Groups': '候选人起动器组', diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue index 8c8cc6f11..656249b25 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue @@ -39,7 +39,7 @@ watch( val += props.businessObject.eventDefinitions[0]?.$type.split(':')[1] || ''; } - // @ts-ignore + // @ts-expect-error: async component registry is indexed dynamically customConfigComponent.value = ( CustomConfigMap as Record )[val]?.component; diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue index f7ca14286..a9b2198e5 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue @@ -67,13 +67,13 @@ const bpmnElement = ref(null); const multiLoopInstance = ref(null); declare global { interface Window { - // @ts-ignore bpmnInstances?: () => any; } } const bpmnInstances = () => (window as any)?.bpmnInstances; +// @ts-expect-error: retained for legacy multi-instance mode compatibility // eslint-disable-next-line unused-imports/no-unused-vars const getElementLoop = (businessObject: any): void => { if (!businessObject.loopCharacteristics) { @@ -142,8 +142,7 @@ const changeLoopCharacteristicsType = (type: any): void => { isSequential: true, }) : bpmnInstances().moddle.create('bpmn:MultiInstanceLoopCharacteristics', { - // eslint-disable-next-line no-template-curly-in-string - collection: '${coll_userList}', + collection: `\${coll_userList}`, }); bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), { loopCharacteristics: toRaw(multiLoopInstance.value), @@ -234,7 +233,7 @@ const updateLoopAsync = (key: any): void => { extensionElements: null, }; } else { - // @ts-ignore + // @ts-expect-error: dynamic async flags are assigned by runtime key asyncAttr[key] = loopInstanceForm.value[key]; } bpmnInstances().modeling.updateModdleProperties( @@ -248,23 +247,20 @@ const changeConfig = (config: string): void => { switch (config) { case '会签': { changeLoopCharacteristicsType('ParallelMultiInstance'); - // eslint-disable-next-line no-template-curly-in-string - updateLoopCondition('${ nrOfCompletedInstances >= nrOfInstances }'); + updateLoopCondition(`\${ nrOfCompletedInstances >= nrOfInstances }`); break; } case '依次审批': { changeLoopCharacteristicsType('SequentialMultiInstance'); updateLoopCardinality('1'); - // eslint-disable-next-line no-template-curly-in-string - updateLoopCondition('${ nrOfCompletedInstances >= nrOfInstances }'); + updateLoopCondition(`\${ nrOfCompletedInstances >= nrOfInstances }`); break; } case '或签': { changeLoopCharacteristicsType('ParallelMultiInstance'); - // eslint-disable-next-line no-template-curly-in-string - updateLoopCondition('${ nrOfCompletedInstances > 0 }'); + updateLoopCondition(`\${ nrOfCompletedInstances > 0 }`); break; } @@ -332,8 +328,7 @@ const updateLoopCharacteristics = (): void => { if (approveMethod.value === ApproveMethodType.APPROVE_BY_RATIO) { multiLoopInstance.value = bpmnInstances().moddle.create( 'bpmn:MultiInstanceLoopCharacteristics', - // eslint-disable-next-line no-template-curly-in-string - { isSequential: false, collection: '${coll_userList}' }, + { isSequential: false, collection: `\${coll_userList}` }, ); multiLoopInstance.value.completionCondition = bpmnInstances().moddle.create('bpmn:FormalExpression', { @@ -345,20 +340,17 @@ const updateLoopCharacteristics = (): void => { if (approveMethod.value === ApproveMethodType.ANY_APPROVE) { multiLoopInstance.value = bpmnInstances().moddle.create( 'bpmn:MultiInstanceLoopCharacteristics', - // eslint-disable-next-line no-template-curly-in-string - { isSequential: false, collection: '${coll_userList}' }, + { isSequential: false, collection: `\${coll_userList}` }, ); multiLoopInstance.value.completionCondition = bpmnInstances().moddle.create('bpmn:FormalExpression', { - // eslint-disable-next-line no-template-curly-in-string - body: '${ nrOfCompletedInstances > 0 }', + body: `\${ nrOfCompletedInstances > 0 }`, }); } if (approveMethod.value === ApproveMethodType.SEQUENTIAL_APPROVE) { multiLoopInstance.value = bpmnInstances().moddle.create( 'bpmn:MultiInstanceLoopCharacteristics', - // eslint-disable-next-line no-template-curly-in-string - { isSequential: true, collection: '${coll_userList}' }, + { isSequential: true, collection: `\${coll_userList}` }, ); multiLoopInstance.value.loopCardinality = bpmnInstances().moddle.create( 'bpmn:FormalExpression', @@ -368,8 +360,7 @@ const updateLoopCharacteristics = (): void => { ); multiLoopInstance.value.completionCondition = bpmnInstances().moddle.create('bpmn:FormalExpression', { - // eslint-disable-next-line no-template-curly-in-string - body: '${ nrOfCompletedInstances >= nrOfInstances }', + body: `\${ nrOfCompletedInstances >= nrOfInstances }`, }); } bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), { diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/ElementTask.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/ElementTask.vue index 8775cb942..8d160c233 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/ElementTask.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/ElementTask.vue @@ -53,7 +53,7 @@ watch( () => props.type, () => { if (props.type) { - // @ts-ignore + // @ts-expect-error: installed task component map is indexed dynamically witchTaskComponent.value = installedComponent[props.type].component; } }, diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/CallActivity.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/CallActivity.vue index dfdf17647..37fd976c9 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/CallActivity.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/CallActivity.vue @@ -65,7 +65,7 @@ const initCallActivity = () => { // 初始化所有配置项 Object.keys(formData.value).forEach((key: string) => { - // @ts-ignore + // @ts-expect-error: form state is updated through dynamic schema keys formData.value[key] = bpmnElement.value.businessObject[key] ?? formData.value[key as keyof FormData]; @@ -183,6 +183,7 @@ const updateElementExtensions = () => { watch( () => props.id, (val) => { + // oxlint-disable-next-line no-unused-expressions val && val.length > 0 && nextTick(() => { diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ReceiveTask.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ReceiveTask.vue index affd1cd0a..0d5ea00db 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ReceiveTask.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ReceiveTask.vue @@ -82,7 +82,6 @@ onMounted(() => { bpmnRootElements.value .filter((el: any) => el.$type === 'bpmn:Message') .forEach((m: any) => { - // @ts-ignore if (bpmnMessageRefsMap.value) { bpmnMessageRefsMap.value[m.id] = m; } diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ScriptTask.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ScriptTask.vue index c15dad114..bff3cfe28 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ScriptTask.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ScriptTask.vue @@ -27,7 +27,7 @@ const bpmnInstances = () => (window as any)?.bpmnInstances; const resetTaskForm = () => { for (const key in defaultTaskForm.value) { - // @ts-ignore + // @ts-expect-error: form state is updated through dynamic schema keys scriptTaskForm.value[key] = bpmnElement.value?.businessObject[ key as keyof typeof defaultTaskForm.value diff --git a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ServiceTask.vue b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ServiceTask.vue index 2994f1eb9..ab8fddc0b 100644 --- a/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ServiceTask.vue +++ b/apps/web-ele/src/views/bpm/components/bpmn-process-designer/package/penal/task/task-components/ServiceTask.vue @@ -1,3 +1,4 @@ + - diff --git a/packages/@core/ui-kit/menu-ui/src/sub-menu.vue b/packages/@core/ui-kit/menu-ui/src/sub-menu.vue index e4d471fb0..57e17dee6 100644 --- a/packages/@core/ui-kit/menu-ui/src/sub-menu.vue +++ b/packages/@core/ui-kit/menu-ui/src/sub-menu.vue @@ -4,7 +4,6 @@ import type { MenuRecordRaw } from '@vben-core/typings'; import { computed } from 'vue'; import { MenuBadge, MenuItem, SubMenu as SubMenuComp } from './components'; -// eslint-disable-next-line import/no-self-import import SubMenu from './sub-menu.vue'; interface Props { diff --git a/packages/@core/ui-kit/menu-ui/tailwind.config.mjs b/packages/@core/ui-kit/menu-ui/tailwind.config.mjs deleted file mode 100644 index f17f556fa..000000000 --- a/packages/@core/ui-kit/menu-ui/tailwind.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config'; diff --git a/packages/@core/ui-kit/popup-ui/package.json b/packages/@core/ui-kit/popup-ui/package.json index 338da305f..fb885d3a5 100644 --- a/packages/@core/ui-kit/popup-ui/package.json +++ b/packages/@core/ui-kit/popup-ui/package.json @@ -1,6 +1,6 @@ { "name": "@vben-core/popup-ui", - "version": "5.6.0", + "version": "5.7.0", "homepage": "https://github.com/vbenjs/vue-vben-admin", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "repository": { diff --git a/packages/@core/ui-kit/popup-ui/postcss.config.mjs b/packages/@core/ui-kit/popup-ui/postcss.config.mjs deleted file mode 100644 index 3d8070455..000000000 --- a/packages/@core/ui-kit/popup-ui/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/packages/@core/ui-kit/popup-ui/src/alert/alert.vue b/packages/@core/ui-kit/popup-ui/src/alert/alert.vue index 6b52a1121..0aae28904 100644 --- a/packages/@core/ui-kit/popup-ui/src/alert/alert.vue +++ b/packages/@core/ui-kit/popup-ui/src/alert/alert.vue @@ -147,7 +147,7 @@ async function handleOpenChange(val: boolean) { :class=" cn( containerClass, - 'left-0 right-0 mx-auto flex max-h-[80%] flex-col p-0 duration-300 sm:w-[520px] sm:max-w-[80%] sm:rounded-[var(--radius)]', + 'inset-x-0 mx-auto flex max-h-[80%] flex-col p-0 duration-300 sm:w-[520px] sm:max-w-[80%] sm:rounded-(--radius)', { 'border border-border': bordered, 'shadow-3xl': !bordered, diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts b/packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts index 365a2e4a0..8420bb9cb 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts @@ -13,21 +13,20 @@ vi.mock('@vben-core/shared/store', () => { return this._state; } private _state: DrawerState; + private subscribers: Array<(state: DrawerState) => void> = []; - private options: any; - - constructor(initialState: DrawerState, options: any) { + constructor(initialState: DrawerState) { this._state = initialState; - this.options = options; - } - - batch(cb: () => void) { - cb(); } setState(fn: (prev: DrawerState) => DrawerState) { this._state = fn(this._state); - this.options.onUpdate(); + this.subscribers.forEach((sub) => sub(this._state)); + } + + subscribe(fn: (state: DrawerState) => void) { + this.subscribers.push(fn); + return { unsubscribe: () => {} }; } }, }; diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts b/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts index a4a3ac4aa..f5d9f3365 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts @@ -56,23 +56,18 @@ export class DrawerApi { title: '', }; - this.store = new Store( - { - ...defaultState, - ...storeState, - }, - { - onUpdate: () => { - const state = this.store.state; - if (state?.isOpen === this.state?.isOpen) { - this.state = state; - } else { - this.state = state; - this.api.onOpenChange?.(!!state?.isOpen); - } - }, - }, - ); + this.store = new Store({ + ...defaultState, + ...storeState, + }); + + this.store.subscribe((state) => { + const prevIsOpen = this.state?.isOpen; + this.state = state; + if (state?.isOpen !== prevIsOpen) { + this.api.onOpenChange?.(!!state?.isOpen); + } + }); this.state = this.store.state; this.api = { onBeforeClose, diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue index ceca51e77..ea7bcb230 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue @@ -186,8 +186,8 @@ const getForceMount = computed(() => { :append-to="getAppendTo" :class=" cn('flex w-[520px] flex-col', drawerClass, { - '!w-full': isMobile || placement === 'bottom' || placement === 'top', - 'max-h-[100vh]': placement === 'bottom' || placement === 'top', + 'w-full!': isMobile || placement === 'bottom' || placement === 'top', + 'max-h-screen': placement === 'bottom' || placement === 'top', hidden: isClosed, }) " @@ -210,7 +210,7 @@ const getForceMount = computed(() => { v-if="showHeader" :class=" cn( - '!flex flex-row items-center justify-between border-b px-6 py-5', + 'flex! flex-row items-center justify-between border-b px-6 py-5', headerClass, { 'px-4 py-3': closable, @@ -224,7 +224,7 @@ const getForceMount = computed(() => { v-if="closable && closeIconPlacement === 'left'" as-child :disabled="submitting" - class="ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-secondary" + class="ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary" > @@ -234,7 +234,7 @@ const getForceMount = computed(() => { @@ -265,7 +265,7 @@ const getForceMount = computed(() => { v-if="closable && closeIconPlacement === 'right'" as-child :disabled="submitting" - class="ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-secondary" + class="ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary" > diff --git a/packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts b/packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts index 1edd477e7..5067f5fa5 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts @@ -12,21 +12,20 @@ vi.mock('@vben-core/shared/store', () => { return this._state; } private _state: ModalState; + private subscribers: Array<(state: ModalState) => void> = []; - private options: any; - - constructor(initialState: ModalState, options: any) { + constructor(initialState: ModalState) { this._state = initialState; - this.options = options; - } - - batch(cb: () => void) { - cb(); } setState(fn: (prev: ModalState) => ModalState) { this._state = fn(this._state); - this.options.onUpdate(); + this.subscribers.forEach((sub) => sub(this._state)); + } + + subscribe(fn: (state: ModalState) => void) { + this.subscribers.push(fn); + return { unsubscribe: () => {} }; } }, }; diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts index f60870b3f..650155871 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts @@ -62,25 +62,19 @@ export class ModalApi { animationType: 'slide', }; - this.store = new Store( - { - ...defaultState, - ...storeState, - }, - { - onUpdate: () => { - const state = this.store.state; + this.store = new Store({ + ...defaultState, + ...storeState, + }); - // 每次更新状态时,都会调用 onOpenChange 回调函数 - if (state?.isOpen === this.state?.isOpen) { - this.state = state; - } else { - this.state = state; - this.api.onOpenChange?.(!!state?.isOpen); - } - }, - }, - ); + this.store.subscribe((state) => { + // 每次更新状态时,都会调用 onOpenChange 回调函数 + const prevIsOpen = this.state?.isOpen; + this.state = state; + if (state?.isOpen !== prevIsOpen) { + this.api.onOpenChange?.(!!state?.isOpen); + } + }); this.state = this.store.state; diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts index fa41344ee..4debaff4b 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts @@ -1,6 +1,6 @@ import type { Component, Ref } from 'vue'; -import type { MaybePromise } from '@vben-core/typings'; +import type { ClassType, MaybePromise } from '@vben-core/typings'; import type { ModalApi } from './modal-api'; @@ -30,7 +30,7 @@ export interface ModalProps { */ centered?: boolean; - class?: string; + class?: ClassType; /** * 是否显示右上角的关闭按钮 @@ -60,7 +60,7 @@ export interface ModalProps { * 确定按钮文字 */ confirmText?: string; - contentClass?: string; + contentClass?: ClassType; /** * 弹窗描述 */ @@ -79,7 +79,7 @@ export interface ModalProps { * @default true */ footer?: boolean; - footerClass?: string; + footerClass?: ClassType; /** * 是否全屏 * @default false @@ -95,7 +95,7 @@ export interface ModalProps { * @default true */ header?: boolean; - headerClass?: string; + headerClass?: ClassType; /** * 弹窗是否显示 * @default false diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue index e93e4c12d..0fe26f64b 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue @@ -240,14 +240,13 @@ function handleClosed() { :append-to="getAppendTo" :class=" cn( - 'left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col p-0', - shouldFullscreen ? 'sm:rounded-none' : 'sm:rounded-[var(--radius)]', + 'inset-x-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col p-0', + shouldFullscreen ? 'sm:rounded-none' : 'sm:rounded-(--radius)', modalClass, { 'border border-border': bordered, 'shadow-3xl': !bordered, - 'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0': - shouldFullscreen, + 'top-0 left-0 size-full max-h-full translate-0!': shouldFullscreen, 'top-1/2': centered && !shouldFullscreen, 'duration-300': !dragging, hidden: isClosed, @@ -320,7 +319,7 @@ function handleClosed() {