diff --git a/.prettierignore b/.prettierignore index 44421a7a..bcd8ce89 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,12 +1,24 @@ +# 构建与测试产物 dist -node_modules +coverage +stats.html + +# 静态资源 public +src/assets + +# 依赖与工具目录 +node_modules .husky .vscode .idea + +# 锁文件 +pnpm-lock.yaml + +# 压缩产物 +*.min.* + +# 脚本与文档不参与格式化 *.sh *.md - -src/assets -stats.html -pnpm-lock.yaml diff --git a/.prettierrc.yaml b/.prettierrc.yaml index bfe6e8f6..c1816815 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -1,41 +1,8 @@ -# 在单参数箭头函数中始终添加括号 -arrowParens: "always" -# JSX 多行元素的闭合标签另起一行 -bracketSameLine: false -# 对象字面量中的括号之间添加空格 -bracketSpacing: true -# 自动格式化嵌入的代码(如 Markdown 和 HTML 内的代码) -embeddedLanguageFormatting: "auto" -# 忽略 HTML 空白敏感度,将空白视为非重要内容 -htmlWhitespaceSensitivity: "ignore" -# 不插入 @prettier 的 pragma 注释 -insertPragma: false -# 在 JSX 中使用双引号 -jsxSingleQuote: false -# 每行代码的最大长度限制为 100 字符 +# 每行最大宽度 printWidth: 100 -# 在 Markdown 中保留原有的换行格式 -proseWrap: "preserve" -# 仅在必要时添加对象属性的引号 -quoteProps: "as-needed" -# 不要求文件开头插入 @prettier 的 pragma 注释 -requirePragma: false -# 在语句末尾添加分号 -semi: true -# 使用双引号而不是单引号 -singleQuote: false -# 缩进使用 2 个空格 -tabWidth: 2 -# 在多行元素的末尾添加逗号(ES5 支持的对象、数组等) -trailingComma: "es5" -# 使用空格而不是制表符缩进 -useTabs: false -# Vue 文件中的 diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue index 330be6c3..2246ad6b 100644 --- a/src/components/Breadcrumb/index.vue +++ b/src/components/Breadcrumb/index.vue @@ -85,7 +85,7 @@ watch( return; } getBreadcrumb(); - } + }, ); onBeforeMount(() => { diff --git a/src/components/CommandPalette/useCommandPalette.ts b/src/components/CommandPalette/useCommandPalette.ts index c3f44bde..d74ac98f 100644 --- a/src/components/CommandPalette/useCommandPalette.ts +++ b/src/components/CommandPalette/useCommandPalette.ts @@ -64,7 +64,7 @@ export function useCommandPalette() { } const keywordText = keyword.value.toLowerCase(); results.value = menuItems.value.filter((item) => - item.title.toLowerCase().includes(keywordText) + item.title.toLowerCase().includes(keywordText), ); } diff --git a/src/components/CopyButton/index.vue b/src/components/CopyButton/index.vue index 4615251f..f2757130 100644 --- a/src/components/CopyButton/index.vue +++ b/src/components/CopyButton/index.vue @@ -39,7 +39,7 @@ function handleClipboard() { }, () => { ElMessage.warning("复制失败"); - } + }, ); } else { // 兼容性处理(useClipboard 有兼容性问题) diff --git a/src/components/Crud/CrudForm.vue b/src/components/Crud/CrudForm.vue index 0f21af72..95459b2b 100644 --- a/src/components/Crud/CrudForm.vue +++ b/src/components/Crud/CrudForm.vue @@ -162,7 +162,7 @@ const childrenMap = new Map([ ["checkbox", ElCheckbox], ]); const fields = reactive( - props.formConfig.fields.map((item) => ({ ...item, attrs: { ...item.attrs } })) + props.formConfig.fields.map((item) => ({ ...item, attrs: { ...item.attrs } })), ); const rowKey = props.formConfig.rowKey ?? "id"; const modalVisible = ref(false); @@ -171,7 +171,7 @@ const formData = reactive({}); const formMode = ref("create"); const targetId = ref(); const formDisable = computed( - () => formMode.value === "view" || props.formConfig.form?.disabled === true + () => formMode.value === "view" || props.formConfig.form?.disabled === true, ); const isLoading = ref(false); const isSaving = ref(false); @@ -202,7 +202,7 @@ const containerAttrs = computed(() => ({ : {}), })); const formRules = computed(() => - Object.fromEntries(fields.filter(isFieldVisible).map((item) => [item.prop, getFieldRules(item)])) + Object.fromEntries(fields.filter(isFieldVisible).map((item) => [item.prop, getFieldRules(item)])), ); onScopeDispose(() => { revision += 1; @@ -451,7 +451,7 @@ async function initializeFields(): Promise { isInitializing.value = true; optionError.value = ""; const results = await Promise.allSettled( - initializers.map((field) => Promise.resolve().then(() => field.onInit?.(field))) + initializers.map((field) => Promise.resolve().then(() => field.onInit?.(field))), ); const failure = results.find((result) => result.status === "rejected"); if (failure?.status === "rejected") diff --git a/src/components/Crud/CrudPage.vue b/src/components/Crud/CrudPage.vue index db0da445..de799dde 100644 --- a/src/components/Crud/CrudPage.vue +++ b/src/components/Crud/CrudPage.vue @@ -72,7 +72,7 @@ const slots = useSlots(); const resolvedFormConfig = computed(() => props.formConfig ? { ...props.formConfig, rowKey: props.formConfig.rowKey ?? props.tableConfig.rowKey } - : undefined + : undefined, ); const page = useCrudPage(); const { @@ -113,7 +113,7 @@ function handleCreate(): void { function openEdit( row: CrudRecord, loader = props.loadFormData, - target?: Ref + target?: Ref, ): Promise { return page.openEdit(row, loader, target); } @@ -124,7 +124,7 @@ function openEdit( function openView( row: CrudRecord, loader = props.loadFormData, - target?: Ref + target?: Ref, ): Promise { return page.openView(row, loader, target); } diff --git a/src/components/Crud/CrudSearch.vue b/src/components/Crud/CrudSearch.vue index a7aebd40..aff804a5 100644 --- a/src/components/Crud/CrudSearch.vue +++ b/src/components/Crud/CrudSearch.vue @@ -103,7 +103,7 @@ const isExpand = ref(false); const optionError = ref(""); const isInitializing = ref(false); const fields = reactive( - (props.searchConfig.fields ?? []).map((item) => ({ ...item, attrs: { ...item.attrs } })) + (props.searchConfig.fields ?? []).map((item) => ({ ...item, attrs: { ...item.attrs } })), ); const initialValues: CrudRecord = Object.fromEntries( fields.map((item) => [ @@ -115,14 +115,14 @@ const initialValues: CrudRecord = Object.fromEntries( ? [] : item.type === "input-number" ? null - : "" + : "", ), - ]) + ]), ); const queryParams = reactive(cloneDeep(initialValues)); const isExpandable = computed(() => props.searchConfig.isExpandable ?? true); const showNumber = computed(() => - isExpandable.value ? (props.searchConfig.showNumber ?? 3) : fields.length + isExpandable.value ? (props.searchConfig.showNumber ?? 3) : fields.length, ); const cardAttrs = computed>(() => ({ shadow: "never", @@ -133,7 +133,7 @@ const formAttrs = computed(() => ({ inline: true, ...props.searchConfig.form })) const layoutClass = computed(() => props.searchConfig.grid ? "grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 3xl:grid-cols-5 4xl:grid-cols-6 gap-5" - : "flex flex-wrap gap-x-8 gap-y-4" + : "flex flex-wrap gap-x-8 gap-y-4", ); /** * 加载字段选项;失败可重试,上一批结束前不重复加载。 @@ -144,7 +144,7 @@ async function initializeFields(): Promise { isInitializing.value = true; optionError.value = ""; const results = await Promise.allSettled( - initializers.map((field) => Promise.resolve().then(() => field.onInit?.(field))) + initializers.map((field) => Promise.resolve().then(() => field.onInit?.(field))), ); const failure = results.find((result) => result.status === "rejected"); if (failure?.status === "rejected") diff --git a/src/components/Crud/CrudTable.vue b/src/components/Crud/CrudTable.vue index 4c21c2ac..516e0c69 100644 --- a/src/components/Crud/CrudTable.vue +++ b/src/components/Crud/CrudTable.vue @@ -429,7 +429,7 @@ function hasActionPermission(action: string): boolean { */ function resolveActions( actions: Array, - buttonProps: CrudAction["buttonProps"] = {} + buttonProps: CrudAction["buttonProps"] = {}, ) { return actions.map((item) => { const isString = typeof item === "string"; @@ -589,7 +589,7 @@ const columns = ref( col.reserveSelection = true; } return col; - }) + }), ); const loading = ref(false); const loadError = ref(""); @@ -657,7 +657,7 @@ const defaultPagination = { const pagination = reactive( typeof props.tableConfig.pagination === "object" ? { ...defaultPagination, ...props.tableConfig.pagination } - : defaultPagination + : defaultPagination, ); const paginationKeys = props.tableConfig.paginationKeys ?? { page: "pageNum", @@ -713,7 +713,7 @@ function refresh(resetPage = false): Promise { */ async function handleDelete( id?: number | string, - permission?: string | string[] | null + permission?: string | string[] | null, ): Promise { const ids = id === undefined ? selectedKeys.value.join(",") : String(id); if (!ids) return; @@ -725,7 +725,7 @@ async function handleDelete( type: "warning", }).then( () => true, - () => false + () => false, ); if (!confirmed || (permission && !hasPerm(permission))) return; await action(ids); @@ -817,7 +817,7 @@ async function exportRows(): Promise { const exportColumns: Partial[] = columns.value .filter( (col) => - col.cellType !== "actions" && col.label && col.prop && exportForm.fields.includes(col.prop) + col.cellType !== "actions" && col.label && col.prop && exportForm.fields.includes(col.prop), ) .map((col) => ({ header: col.label, key: col.prop })); const scope = exportForm.scope; @@ -967,7 +967,7 @@ async function handleToolbar(key: string): Promise { if (config.value.importFile && config.value.importRows && !config.value.importMode) throw new Error("同时配置两种导入回调时,请指定 importMode"); handleOpenImportModal( - config.value.importMode ? config.value.importMode === "file" : !!config.value.importFile + config.value.importMode ? config.value.importMode === "file" : !!config.value.importFile, ); break; case "export": @@ -989,7 +989,7 @@ async function handleToolbar(key: string): Promise { async function handleModify( field: string, value: boolean | string | number, - row: CrudRecord + row: CrudRecord, ): Promise { const id = getRowKey(row); const original = confirmedRows.get(id); @@ -1079,7 +1079,7 @@ let appliedQuery: CrudRecord = {}; let lastSuccessfulQuery: CrudRecord | undefined; let pageSequence = 0; const canExport = computed( - () => !loading.value && !loadError.value && lastSuccessfulQuery !== undefined + () => !loading.value && !loadError.value && lastSuccessfulQuery !== undefined, ); onScopeDispose(() => { pageSequence += 1; diff --git a/src/components/Crud/useCrudPage.ts b/src/components/Crud/useCrudPage.ts index 5dd0e499..fed8a3e8 100644 --- a/src/components/Crud/useCrudPage.ts +++ b/src/components/Crud/useCrudPage.ts @@ -39,7 +39,7 @@ function useCrudPage() { mode: "edit" | "view", row: CrudRecord, loader?: (row: CrudRecord) => CrudRecord | Promise, - target: Ref = formRef + target: Ref = formRef, ): Promise { const form = target.value; if (!form?.openForm(mode, row)) return; @@ -52,7 +52,7 @@ function useCrudPage() { function openEdit( row: CrudRecord, loader?: (row: CrudRecord) => CrudRecord | Promise, - target?: Ref + target?: Ref, ): Promise { return openRecord("edit", row, loader, target); } @@ -63,7 +63,7 @@ function useCrudPage() { function openView( row: CrudRecord, loader?: (row: CrudRecord) => CrudRecord | Promise, - target?: Ref + target?: Ref, ): Promise { return openRecord("view", row, loader, target); } diff --git a/src/components/DictSelect/index.vue b/src/components/DictSelect/index.vue index bc279a9b..ca0eca4a 100644 --- a/src/components/DictSelect/index.vue +++ b/src/components/DictSelect/index.vue @@ -120,6 +120,6 @@ watch( } await dictStore.loadDictItems(code); }, - { immediate: true } + { immediate: true }, ); diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue index 585c4600..1bb19957 100644 --- a/src/components/DictTag/index.vue +++ b/src/components/DictTag/index.vue @@ -28,12 +28,12 @@ const item = computed(() => ? dictStore .getDictItems(props.code) .find((entry) => String(entry.value) === String(props.modelValue)) - : undefined + : undefined, ); const label = computed(() => item.value?.label ?? ""); const tagType = computed(() => item.value?.tagType || undefined); const tagSize = computed(() => - props.size === "large" || props.size === "small" ? props.size : "default" + props.size === "large" || props.size === "small" ? props.size : "default", ); watch( @@ -41,6 +41,6 @@ watch( async (code) => { if (code) await dictStore.loadDictItems(code); }, - { immediate: true } + { immediate: true }, ); diff --git a/src/components/ECharts/index.vue b/src/components/ECharts/index.vue index ae2a7dcf..fb6cf32b 100644 --- a/src/components/ECharts/index.vue +++ b/src/components/ECharts/index.vue @@ -88,7 +88,7 @@ watch( chartInstance.setOption(newOptions); } }, - { deep: true } + { deep: true }, ); onMounted(() => { diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue index d25d74af..b555675b 100644 --- a/src/components/IconSelect/index.vue +++ b/src/components/IconSelect/index.vue @@ -87,21 +87,12 @@ import { elementIconNames, svgIconNames } from "@/utils/icon"; * 图标选择器:内置图标库检索与选择 */ const props = defineProps({ - modelValue: { - type: String, - default: "", - }, width: { type: String, default: "500px", }, }); -/** - * 选中图标时回传图标名 - */ -const emit = defineEmits(["update:modelValue"]); - const iconSelectRef = ref(); const popoverContentRef = ref(); const popoverVisible = ref(false); @@ -111,7 +102,6 @@ const svgIcons = ref(svgIconNames); const elementIcons = ref(elementIconNames); const selectedIcon = defineModel("modelValue", { type: String, - required: true, default: "", }); @@ -141,7 +131,7 @@ function filterIcons() { } else { filteredElementIcons.value = filterText.value ? elementIcons.value.filter((icon) => - icon.toLowerCase().includes(filterText.value.toLowerCase()) + icon.toLowerCase().includes(filterText.value.toLowerCase()), ) : elementIcons.value; } @@ -152,7 +142,7 @@ function filterIcons() { */ function selectIcon(icon: string) { const iconName = activeTab.value === "element" ? "el-icon-" + icon : icon; - emit("update:modelValue", iconName); + selectedIcon.value = iconName; popoverVisible.value = false; } diff --git a/src/components/NoticeDetailDialog/index.vue b/src/components/NoticeDetailDialog/index.vue index 1d8beec4..be47dbd2 100644 --- a/src/components/NoticeDetailDialog/index.vue +++ b/src/components/NoticeDetailDialog/index.vue @@ -40,7 +40,7 @@ const props = defineProps<{ }>(); const contentHtml = computed(() => - DOMPurify.sanitize(props.detail?.content ?? "", { USE_PROFILES: { html: true } }) + DOMPurify.sanitize(props.detail?.content ?? "", { USE_PROFILES: { html: true } }), ); const visible = defineModel({ default: false }); diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue index d1679202..e44a5384 100644 --- a/src/components/Pagination/index.vue +++ b/src/components/Pagination/index.vue @@ -67,7 +67,7 @@ watch( currentPage.value = lastPage; emit("pagination", { page: currentPage.value, limit: pageSize.value }); } - } + }, ); /** diff --git a/src/components/TableActions/index.vue b/src/components/TableActions/index.vue index 98b00f54..feaec494 100644 --- a/src/components/TableActions/index.vue +++ b/src/components/TableActions/index.vue @@ -86,7 +86,7 @@ watch( () => overflowActions.value.length, (count) => { if (count === 0) expanded.value = false; - } + }, ); /** diff --git a/src/components/TableSelect/index.vue b/src/components/TableSelect/index.vue index 1171feb3..cc877548 100644 --- a/src/components/TableSelect/index.vue +++ b/src/components/TableSelect/index.vue @@ -200,7 +200,7 @@ const props = withDefaults( }>(), { text: "", - } + }, ); /** diff --git a/src/components/TextScroll/index.vue b/src/components/TextScroll/index.vue index 0e5b3bbf..958ed097 100644 --- a/src/components/TextScroll/index.vue +++ b/src/components/TextScroll/index.vue @@ -170,7 +170,7 @@ watch( stopTypewriter(); if (!closed.value && props.typewriter) startTypewriter(); }, - { immediate: true } + { immediate: true }, ); watch(() => [displayText.value, props.speed], calculateDuration, { flush: "post" }); onMounted(calculateDuration); diff --git a/src/components/Upload/SingleImageUpload.vue b/src/components/Upload/SingleImageUpload.vue index c53e1458..d5ed5c61 100644 --- a/src/components/Upload/SingleImageUpload.vue +++ b/src/components/Upload/SingleImageUpload.vue @@ -129,7 +129,7 @@ function handleUpload(options: UploadRequestOptions) { }, (error) => { reject(error); - } + }, ); }); } diff --git a/src/components/Upload/useUploadQueue.ts b/src/components/Upload/useUploadQueue.ts index eb576e71..c72b2d55 100644 --- a/src/components/Upload/useUploadQueue.ts +++ b/src/components/Upload/useUploadQueue.ts @@ -63,7 +63,7 @@ export function useUploadQueue(model: Ref, values: UploadValues) { (file) => file.status === "ready" || file.status === "uploading" || - (file.uid !== undefined && activeTasks.has(file.uid)) + (file.uid !== undefined && activeTasks.has(file.uid)), ) : []; fileList.value = [ @@ -75,7 +75,7 @@ export function useUploadQueue(model: Ref, values: UploadValues) { ]; }, // 同步消费回写标记,避免延迟侦听与下一次发布混淆。 - { immediate: true, flush: "sync" } + { immediate: true, flush: "sync" }, ); /** @@ -83,7 +83,7 @@ export function useUploadQueue(model: Ref, values: UploadValues) { */ function upload( options: UploadRequestOptions, - fields: { name: string; data: Record } + fields: { name: string; data: Record }, ): Promise { const uid = options.file.uid; const controller = new AbortController(); @@ -100,7 +100,7 @@ export function useUploadQueue(model: Ref, values: UploadValues) { const file = fileList.value.find((item) => item.uid === uid); if (file) file.percentage = percentage; }, - controller.signal + controller.signal, ).finally(() => { if (requests.get(uid) === controller) requests.delete(uid); }); diff --git a/src/components/WangEditor/index.vue b/src/components/WangEditor/index.vue index bbb416e3..3f6b06c3 100644 --- a/src/components/WangEditor/index.vue +++ b/src/components/WangEditor/index.vue @@ -107,7 +107,7 @@ watch( if (innerUpdating.value) return; editorRef.value = null; editorKey.value += 1; - } + }, ); // 组件销毁时,及时销毁编辑器 diff --git a/src/composables/usePageTable.ts b/src/composables/usePageTable.ts index b72b0856..a53919a7 100644 --- a/src/composables/usePageTable.ts +++ b/src/composables/usePageTable.ts @@ -7,7 +7,7 @@ import type { PageQuery, PageResult } from "@/api/common"; * 分页查询只接收最近一次请求的结果;勾选与弹窗状态由页面持有。 */ export function usePageTable( - options: UsePageTableOptions + options: UsePageTableOptions, ): UsePageTableReturn { const { request, onBeforeReset } = options; const initialParams = cloneDeep(options.initialParams); diff --git a/src/composables/useRealtime.ts b/src/composables/useRealtime.ts index ba7de6bd..6df04400 100644 --- a/src/composables/useRealtime.ts +++ b/src/composables/useRealtime.ts @@ -230,7 +230,7 @@ export function provideRealtime(): RealtimeContext { [...(user.userInfo.perms ?? [])].sort().join(), ].join("|"), resetConnection, - { flush: "sync" } + { flush: "sync" }, ); const context: RealtimeContext = { diff --git a/src/composables/useTableSelection.ts b/src/composables/useTableSelection.ts index cdaf108c..6c90075c 100644 --- a/src/composables/useTableSelection.ts +++ b/src/composables/useTableSelection.ts @@ -15,7 +15,7 @@ export function useTableSelection() { */ function handleSelectionChange(selection: T[]): void { selectedIds.value = selection.flatMap((item) => - item.id === undefined || item.id === null ? [] : [item.id] + item.id === undefined || item.id === null ? [] : [item.id], ); } diff --git a/src/directives/permission/index.ts b/src/directives/permission/index.ts index 1cc8d695..5c5e6c25 100644 --- a/src/directives/permission/index.ts +++ b/src/directives/permission/index.ts @@ -14,7 +14,7 @@ export const hasPerm: Directive = { if (!requiredPerms || (typeof requiredPerms !== "string" && !Array.isArray(requiredPerms))) { throw new Error( - "需要提供权限标识!例如:v-has-perm=\"'sys:user:create'\" 或 v-has-perm=\"['sys:user:create', 'sys:user:update']\"" + "需要提供权限标识!例如:v-has-perm=\"'sys:user:create'\" 或 v-has-perm=\"['sys:user:create', 'sys:user:update']\"", ); } diff --git a/src/layouts/BaseLayout.vue b/src/layouts/BaseLayout.vue index ef946ea3..cecacfa9 100644 --- a/src/layouts/BaseLayout.vue +++ b/src/layouts/BaseLayout.vue @@ -23,7 +23,7 @@ withDefaults( }>(), { showOverlay: true, - } + }, ); const { layoutClass, isSidebarOpen, isMobile, closeSidebar } = useLayout(); diff --git a/src/layouts/components/LayoutMenuIcon.vue b/src/layouts/components/LayoutMenuIcon.vue index d1e0aad6..8ccf43de 100644 --- a/src/layouts/components/LayoutMenuIcon.vue +++ b/src/layouts/components/LayoutMenuIcon.vue @@ -15,7 +15,7 @@ const props = withDefaults( }>(), { icon: "", - } + }, ); const isElementIcon = computed(() => (props.icon || "").startsWith("el-icon")); diff --git a/src/layouts/components/LayoutNavbar.vue b/src/layouts/components/LayoutNavbar.vue index 8c6d62ec..ace04cb0 100644 --- a/src/layouts/components/LayoutNavbar.vue +++ b/src/layouts/components/LayoutNavbar.vue @@ -23,7 +23,7 @@ const props = withDefaults( }>(), { toggleTarget: "primary", - } + }, ); const appStore = useAppStore(); @@ -34,7 +34,7 @@ const sidebarState = computed(() => opened: appStore.secondarySidebar?.opened ?? true, toggle: () => appStore.toggleSecondarySidebar(), } - : { opened: appStore.sidebar.opened, toggle: () => appStore.toggleSidebar() } + : { opened: appStore.sidebar.opened, toggle: () => appStore.toggleSidebar() }, ); diff --git a/src/layouts/components/LayoutSettings.vue b/src/layouts/components/LayoutSettings.vue index ef23619a..a41cb30c 100644 --- a/src/layouts/components/LayoutSettings.vue +++ b/src/layouts/components/LayoutSettings.vue @@ -381,7 +381,7 @@ function getColorLabel(name: ThemeColorName) { const activePaletteName = computed(() => settingsStore.activeThemePalette ? getPaletteName(settingsStore.activeThemePalette) - : t("settings.customPalette") + : t("settings.customPalette"), ); /** diff --git a/src/layouts/components/LayoutSidebar.vue b/src/layouts/components/LayoutSidebar.vue index b1c625eb..4bf513e8 100644 --- a/src/layouts/components/LayoutSidebar.vue +++ b/src/layouts/components/LayoutSidebar.vue @@ -133,7 +133,7 @@ watch( () => expandedMenuIndexes.value, () => { syncActiveParentMenus(); - } + }, ); // 水平菜单切换时收起弹出的垂直菜单 @@ -143,7 +143,7 @@ watch( if (newMode === "horizontal" && menuRef.value) { expandedMenuIndexes.value.forEach((item) => menuRef.value!.close(item)); } - } + }, ); // 路由激活项变化后同步父级菜单激活态 @@ -154,7 +154,7 @@ watch( syncActiveParentMenus(); }); }, - { immediate: true } + { immediate: true }, ); // TagsView 切换时重新计算父级菜单激活态 @@ -164,7 +164,7 @@ watch( nextTick(() => { syncActiveParentMenus(); }); - } + }, ); /** diff --git a/src/layouts/components/LayoutSidebarItem.vue b/src/layouts/components/LayoutSidebarItem.vue index 310fdad2..d68017f3 100644 --- a/src/layouts/components/LayoutSidebarItem.vue +++ b/src/layouts/components/LayoutSidebarItem.vue @@ -90,7 +90,7 @@ const props = defineProps({ }); const showingChildren = computed(() => - (props.item.children ?? []).filter((route) => !route.meta?.hidden) + (props.item.children ?? []).filter((route) => !route.meta?.hidden), ); const leafMenu = computed(() => { diff --git a/src/layouts/components/LayoutTagsView.vue b/src/layouts/components/LayoutTagsView.vue index 84fbedae..68d3a8bc 100644 --- a/src/layouts/components/LayoutTagsView.vue +++ b/src/layouts/components/LayoutTagsView.vue @@ -440,7 +440,7 @@ const closeSelectedTag = (tag: TagView | null) => { */ function closeDirectionalTags( source: Ref, - batchFn: (tag: TagView) => Promise<{ visitedViews: TagView[] }> + batchFn: (tag: TagView) => Promise<{ visitedViews: TagView[] }>, ) { const tag = source.value; if (!tag) return; @@ -530,7 +530,7 @@ watch( addCurrentTag(); updateCurrentTag(); }, - { immediate: true } + { immediate: true }, ); onMounted(() => { diff --git a/src/layouts/components/LayoutToolbar.vue b/src/layouts/components/LayoutToolbar.vue index 6242509f..db0c3f17 100644 --- a/src/layouts/components/LayoutToolbar.vue +++ b/src/layouts/components/LayoutToolbar.vue @@ -97,7 +97,7 @@ function handleTenantChange(tenantId: number) { (error: unknown) => { const message = error instanceof Error ? error.message : "切换租户失败"; ElMessage.error(message); - } + }, ); } diff --git a/src/layouts/composables/useMixMenu.ts b/src/layouts/composables/useMixMenu.ts index a1032ad4..9d72c35b 100644 --- a/src/layouts/composables/useMixMenu.ts +++ b/src/layouts/composables/useMixMenu.ts @@ -85,7 +85,7 @@ export function useMixMenu() { permissionStore.setMixLayoutSideMenus(topMenuPath); } }, - { immediate: true } + { immediate: true }, ); return { diff --git a/src/layouts/modes/MixLayout.vue b/src/layouts/modes/MixLayout.vue index 138d2eaa..d9c3beb1 100644 --- a/src/layouts/modes/MixLayout.vue +++ b/src/layouts/modes/MixLayout.vue @@ -107,7 +107,7 @@ const isLogoCollapsed = computed(() => width.value < 768); const useMenuColors = computed( () => settingsStore.resolvedTheme === ThemeMode.DARK || - settingsStore.sidebarColorScheme === SidebarColor.CLASSIC_BLUE + settingsStore.sidebarColorScheme === SidebarColor.CLASSIC_BLUE, ); diff --git a/src/plugins/form-create.ts b/src/plugins/form-create.ts index f92da61b..8d608cb1 100644 --- a/src/plugins/form-create.ts +++ b/src/plugins/form-create.ts @@ -156,7 +156,7 @@ let registered = false; function registerComponents( designer: typeof DesignerPlugin, dictSelect: Component, - fileUpload: Component + fileUpload: Component, ): void { if (registered) return; diff --git a/src/router/guards.ts b/src/router/guards.ts index e5027ab2..8ac102d0 100644 --- a/src/router/guards.ts +++ b/src/router/guards.ts @@ -24,7 +24,7 @@ export function setupPermissionGuard() { // 未登录处理 if (!isLoggedIn) { const isWhiteListed = whiteList.some( - (path) => to.path === path || to.path.startsWith(`${path}/`) + (path) => to.path === path || to.path.startsWith(`${path}/`), ); if (isWhiteListed) { return; diff --git a/src/router/views.ts b/src/router/views.ts index 17252295..5a264516 100644 --- a/src/router/views.ts +++ b/src/router/views.ts @@ -13,7 +13,7 @@ const VIEW_PREFIX = "/src/views/"; * 视图文件路径集合,元素形如 system/user/index */ export const viewPaths = new Set( - Object.keys(viewModules).map((key) => key.slice(VIEW_PREFIX.length).replace(/\.vue$/, "")) + Object.keys(viewModules).map((key) => key.slice(VIEW_PREFIX.length).replace(/\.vue$/, "")), ); /** @@ -156,7 +156,7 @@ export const pageComponentTree = buildTree(); */ export function filterPageComponent( query: string, - node: { label?: string; value?: string } + node: { label?: string; value?: string }, ): boolean { if (!query) return true; const keyword = query.toLowerCase(); diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 8a3404e5..b9834baf 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -21,20 +21,20 @@ export const useSettingsStore = defineStore("setting", () => { const showTagsView = useStorage(STORAGE_KEYS.SHOW_TAGS_VIEW, defaults.showTagsView); const tagsViewStyle = useStorage( STORAGE_KEYS.TAGS_VIEW_STYLE, - defaults.tagsViewStyle + defaults.tagsViewStyle, ); const showAppLogo = useStorage(STORAGE_KEYS.SHOW_APP_LOGO, defaults.showAppLogo); const showWatermark = useStorage(STORAGE_KEYS.SHOW_WATERMARK, defaults.showWatermark); const pageSwitchingAnimation = useStorage( STORAGE_KEYS.PAGE_SWITCHING_ANIMATION, - defaults.pageSwitchingAnimation + defaults.pageSwitchingAnimation, ); // 布局 const layout = useStorage(STORAGE_KEYS.LAYOUT, defaults.layout as LayoutMode); const sidebarColorScheme = useStorage( STORAGE_KEYS.SIDEBAR_COLOR_SCHEME, - defaults.sidebarColorScheme + defaults.sidebarColorScheme, ); // 主题 @@ -45,7 +45,7 @@ export const useSettingsStore = defineStore("setting", () => { }); const activeThemePalette = computed( - () => themePalettePresets.find((item) => item.id === themePalette.value) || null + () => themePalettePresets.find((item) => item.id === themePalette.value) || null, ); const resolvedTheme = ref(resolveThemeMode(theme.value)); @@ -71,7 +71,7 @@ export const useSettingsStore = defineStore("setting", () => { stopWatchingSystemTheme = undefined; } }, - { immediate: true } + { immediate: true }, ); watch( @@ -80,7 +80,7 @@ export const useSettingsStore = defineStore("setting", () => { toggleDarkMode(t === ThemeMode.DARK); applyTheme(generateThemeColors(colors, t)); }, - { immediate: true, deep: true } + { immediate: true, deep: true }, ); watch(sidebarColorScheme, (v) => toggleSidebarColor(v === SidebarColor.CLASSIC_BLUE), { @@ -93,7 +93,7 @@ export const useSettingsStore = defineStore("setting", () => { (v) => { document.documentElement.style.filter = v ? "grayscale(100%)" : ""; }, - { immediate: true } + { immediate: true }, ); // 色弱模式监听 @@ -102,7 +102,7 @@ export const useSettingsStore = defineStore("setting", () => { (v) => { document.documentElement.classList.toggle("color-weak", v); }, - { immediate: true } + { immediate: true }, ); /** diff --git a/src/stores/user.ts b/src/stores/user.ts index e9c75053..b9706c3c 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -52,7 +52,7 @@ export const useUserStore = defineStore("user", () => { () => { refreshPromise = null; }, - { flush: "sync" } + { flush: "sync" }, ); /** diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 28af3834..170c188b 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -46,7 +46,7 @@ export const AuthStorage = { accessToken: string, refreshToken: string, rememberMe: boolean, - renewing = false + renewing = false, ): void { Storage.set(STORAGE_KEYS.REMEMBER_ME, rememberMe); if (rememberMe) { diff --git a/src/utils/http-response.ts b/src/utils/http-response.ts index bd843413..94f4522b 100644 --- a/src/utils/http-response.ts +++ b/src/utils/http-response.ts @@ -5,7 +5,7 @@ import type { ApiResult } from "@/api/common"; * 读取文件接口返回的 JSON 业务结果,保留原始文件和响应头。 */ export async function readBinaryApiResult( - response: AxiosResponse + response: AxiosResponse, ): Promise { if (response.config.responseType !== "blob" && response.config.responseType !== "arraybuffer") { return undefined; diff --git a/src/utils/icon.ts b/src/utils/icon.ts index 7f66f63f..952dc720 100644 --- a/src/utils/icon.ts +++ b/src/utils/icon.ts @@ -7,7 +7,7 @@ import * as ElementPlusIconsVue from "@element-plus/icons-vue"; * 取自 src/assets/icons 下的文件名,存入菜单时无前缀 */ export const svgIconNames: string[] = Object.keys(import.meta.glob("../assets/icons/*.svg")).map( - (path) => path.replace(/.*\/(.*)\.svg$/, "$1") + (path) => path.replace(/.*\/(.*)\.svg$/, "$1"), ); /** @@ -53,7 +53,7 @@ export function matchIcon(keywords: string[]): string { keyword .trim() .toLowerCase() - .replace(/^el-icon-/, "") + .replace(/^el-icon-/, ""), ) .filter(Boolean); diff --git a/src/utils/realtime/client.ts b/src/utils/realtime/client.ts index a62bbfb2..9b154f9d 100644 --- a/src/utils/realtime/client.ts +++ b/src/utils/realtime/client.ts @@ -21,7 +21,7 @@ export enum RealtimeConnectionStatus { */ interface RealtimeClientOptions { readonly requestTicket: ( - request: CreateRealtimeTicketRequest + request: CreateRealtimeTicketRequest, ) => Promise; } @@ -161,7 +161,7 @@ export function createRealtimeClient(options: RealtimeClientOptions) { attempt.timer = null; if (checkDeadline(attempt)) armDeadline(attempt); }, - Math.min(Math.max(1, attempt.deadline - Date.now()), 2_147_483_647) + Math.min(Math.max(1, attempt.deadline - Date.now()), 2_147_483_647), ); } diff --git a/src/utils/request.ts b/src/utils/request.ts index 7c41300b..d0f7d46f 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -86,17 +86,17 @@ http.interceptors.response.use( ElMessage.error(msg || "请求失败"); return Promise.reject(error); - } + }, ); /** * 二进制保留响应头,JSON 返回业务 data;Axios 泛型适配集中在此处。 */ function request( - config: AxiosRequestConfig & { responseType: "blob" } + config: AxiosRequestConfig & { responseType: "blob" }, ): Promise>; function request( - config: AxiosRequestConfig & { responseType: "arraybuffer" } + config: AxiosRequestConfig & { responseType: "arraybuffer" }, ): Promise>; function request(config: AxiosRequestConfig): Promise; async function request(config: AxiosRequestConfig): Promise { diff --git a/src/utils/storage.ts b/src/utils/storage.ts index d39ee0f8..6b5b11c4 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -52,7 +52,7 @@ export class Storage { storage: Pick, key: string, defaultValue: T | undefined, - validate?: ValueGuard + validate?: ValueGuard, ): T | undefined { const raw = storage.getItem(key); if (raw === null) return defaultValue; diff --git a/src/views/codegen/components/FieldConfigStep.vue b/src/views/codegen/components/FieldConfigStep.vue index 24d63cf9..29a311c7 100644 --- a/src/views/codegen/components/FieldConfigStep.vue +++ b/src/views/codegen/components/FieldConfigStep.vue @@ -229,7 +229,7 @@ const aiChangedCount = computed(() => Object.keys(props.aiChanges ?? {}).length) const visibleFields = computed(() => { if (!onlyAiChanged.value) return fieldConfigs.value; return fieldConfigs.value.filter( - (row) => row.columnName && props.aiChanges?.[row.columnName]?.length + (row) => row.columnName && props.aiChanges?.[row.columnName]?.length, ); }); @@ -269,7 +269,7 @@ async function locateField(columnName: string) { await nextTick(); const cards = listRef.value?.querySelectorAll(".field-card"); const target = Array.from(cards ?? []).find( - (card) => card.querySelector(".field-column")?.textContent?.trim() === columnName + (card) => card.querySelector(".field-column")?.textContent?.trim() === columnName, ); if (!target) return; target.scrollIntoView({ behavior: "smooth", block: "center" }); diff --git a/src/views/codegen/components/GeneratorDrawer.vue b/src/views/codegen/components/GeneratorDrawer.vue index 83947303..00def4d8 100644 --- a/src/views/codegen/components/GeneratorDrawer.vue +++ b/src/views/codegen/components/GeneratorDrawer.vue @@ -366,7 +366,7 @@ async function handlePrev() { loading.value = true; try { genConfigFormData.value = applyDefaults( - await GeneratorAPI.getGenConfig(currentTableName.value) + await GeneratorAPI.getGenConfig(currentTableName.value), ); } finally { loading.value = false; diff --git a/src/views/codegen/composables/useAiFillDiff.ts b/src/views/codegen/composables/useAiFillDiff.ts index 9b6b8e5d..c13d4494 100644 --- a/src/views/codegen/composables/useAiFillDiff.ts +++ b/src/views/codegen/composables/useAiFillDiff.ts @@ -103,7 +103,7 @@ export function diffGenConfig(before: GenConfigForm, after: GenConfigForm): AiFi } const beforeFields = new Map( - (before.fieldConfigs ?? []).map((field) => [field.columnName, field]) + (before.fieldConfigs ?? []).map((field) => [field.columnName, field]), ); (after.fieldConfigs ?? []).forEach((field) => { const origin = beforeFields.get(field.columnName); @@ -148,8 +148,8 @@ export function useAiFillDiff() { fieldChangeCount: field.changes.length, first: index === 0, ...item, - })) - ) + })), + ), ); /** diff --git a/src/views/codegen/composables/useCodePreview.ts b/src/views/codegen/composables/useCodePreview.ts index 63e3f1e0..644a9278 100644 --- a/src/views/codegen/composables/useCodePreview.ts +++ b/src/views/codegen/composables/useCodePreview.ts @@ -46,8 +46,8 @@ export function useCodePreview(genConfigFormData: Ref) { new Set( previewList .map((item) => item.language || item.fileName.split(".").pop() || "") - .filter(Boolean) - ) + .filter(Boolean), + ), ); previewTypeOptions.value = typeOptions; previewTypes.value = [...typeOptions]; @@ -104,7 +104,7 @@ export function useCodePreview(genConfigFormData: Ref) { currentFileKey.value = first.key || ""; } }, - { immediate: true } + { immediate: true }, ); return { diff --git a/src/views/codegen/composables/useGenConfig.ts b/src/views/codegen/composables/useGenConfig.ts index 6a08af81..c60e8d1d 100644 --- a/src/views/codegen/composables/useGenConfig.ts +++ b/src/views/codegen/composables/useGenConfig.ts @@ -39,7 +39,7 @@ export function useGenConfig() { .map((s) => s.charAt(0).toUpperCase() + s.slice(1)) .join(""); genConfigFormData.value.entityName = camel; - } + }, ); // 日期类型字段默认用范围查询,比较符合直觉 @@ -59,7 +59,7 @@ export function useGenConfig() { } }); }, - { deep: true, immediate: true } + { deep: true, immediate: true }, ); /** diff --git a/src/views/codegen/composables/useLocalWrite.ts b/src/views/codegen/composables/useLocalWrite.ts index 9bd82af8..aed96d2b 100644 --- a/src/views/codegen/composables/useLocalWrite.ts +++ b/src/views/codegen/composables/useLocalWrite.ts @@ -19,10 +19,10 @@ export function useLocalWrite(genConfigFormData: Ref) { const lastPreviewFiles = ref([]); const needFrontend = computed(() => - lastPreviewFiles.value.some((f) => resolveRootForItem(f) === "frontend") + lastPreviewFiles.value.some((f) => resolveRootForItem(f) === "frontend"), ); const needBackend = computed(() => - lastPreviewFiles.value.some((f) => resolveRootForItem(f) === "backend") + lastPreviewFiles.value.some((f) => resolveRootForItem(f) === "backend"), ); // 只要有预览文件就可以点写入按钮,目录在弹窗里选 const canWriteToLocal = computed(() => lastPreviewFiles.value.length > 0); @@ -116,7 +116,7 @@ export function useLocalWrite(genConfigFormData: Ref) { async function writeFileToDir( dirHandle: FileSystemDirectoryHandle, filePath: string, - content: string + content: string, ) { const normalized = filePath.replace(/\\/g, "/"); const parts = normalized.split("/").filter(Boolean); @@ -134,7 +134,7 @@ export function useLocalWrite(genConfigFormData: Ref) { */ async function pathExists( dirHandle: FileSystemDirectoryHandle, - filePath: string + filePath: string, ): Promise { try { const normalized = filePath.replace(/\\/g, "/"); @@ -155,7 +155,7 @@ export function useLocalWrite(genConfigFormData: Ref) { async function isSameFile( dirHandle: FileSystemDirectoryHandle, filePath: string, - content: string + content: string, ): Promise { try { const normalized = filePath.replace(/\\/g, "/"); @@ -199,7 +199,7 @@ export function useLocalWrite(genConfigFormData: Ref) { const failed: string[] = []; const files = lastPreviewFiles.value.filter( - (f) => writeScope.value === "all" || resolveRootForItem(f) === writeScope.value + (f) => writeScope.value === "all" || resolveRootForItem(f) === writeScope.value, ); writeProgress.total = files.length; writeProgress.done = 0; @@ -256,7 +256,7 @@ export function useLocalWrite(genConfigFormData: Ref) { if (failed.length) { ElMessage.warning( - `部分文件写入失败 ${failed.length} 个,成功 前端 ${frontCount} 个,后端 ${backCount} 个` + `部分文件写入失败 ${failed.length} 个,成功 前端 ${frontCount} 个,后端 ${backCount} 个`, ); } else { ElMessage.success(`写入完成:前端 ${frontCount} 个文件,后端 ${backCount} 个文件`); diff --git a/src/views/codegen/utils/tree-builder.ts b/src/views/codegen/utils/tree-builder.ts index dc9150d1..3bec3f3d 100644 --- a/src/views/codegen/utils/tree-builder.ts +++ b/src/views/codegen/utils/tree-builder.ts @@ -103,7 +103,7 @@ export function getFileIcon(node: TreeNode): string { export function filterTree( nodes: TreeNode[], scope: "all" | "frontend" | "backend", - types: string[] + types: string[], ): TreeNode[] { /** * 判断节点是否命中当前筛选 diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 15304cee..e488d8d5 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -393,14 +393,14 @@ const tUv = useTransition( { duration: 800, transition: [0.25, 0.1, 0.25, 1.0], - } + }, ); const tPv = useTransition( computed(() => visitOverviewData.value.todayPvCount), { duration: 800, transition: [0.25, 0.1, 0.25, 1.0], - } + }, ); const displayTransitionUvCount = computed(() => Math.round(Number(tUv.value))); const displayTransitionPvCount = computed(() => Math.round(Number(tPv.value))); @@ -569,7 +569,7 @@ function updateVisitTrendChartOptions(d: VisitTrendDetail) { watch( () => visitTrendDateRange.value, () => fetchVisitTrendData(), - { immediate: true } + { immediate: true }, ); watch( () => [settingsStore.resolvedTheme, settingsStore.themeColors], @@ -580,7 +580,7 @@ watch( if (visitTrendData.value) updateVisitTrendChartOptions(visitTrendData.value); }); }, - { deep: true } + { deep: true }, ); onMounted(() => { fetchVisitOverviewData(); diff --git a/src/views/demo/component/table-select/index.vue b/src/views/demo/component/table-select/index.vue index 4b644898..96cb591c 100644 --- a/src/views/demo/component/table-select/index.vue +++ b/src/views/demo/component/table-select/index.vue @@ -57,7 +57,7 @@ function handleConfirm(data: IUser[]) { const text = computed(() => { const dictData = dictStore.getDictItems("gender"); const genderLabel = dictData.find( - (item) => String(item.value) === String(selectedUser.value?.gender) + (item) => String(item.value) === String(selectedUser.value?.gender), )?.label; return selectedUser.value ? `${selectedUser.value.username} - ${genderLabel} - ${selectedUser.value.deptName}` diff --git a/src/views/demo/component/upload.vue b/src/views/demo/component/upload.vue index 861c5a39..80737d66 100644 --- a/src/views/demo/component/upload.vue +++ b/src/views/demo/component/upload.vue @@ -134,10 +134,10 @@ const fileUrls = ref([ // 绑定值 JSON 预览 const picUrlJson = computed(() => (picUrl.value ? JSON.stringify(picUrl.value) : "// 暂无数据")); const picUrlsJson = computed(() => - picUrls.value.length ? JSON.stringify(picUrls.value, null, 2) : "// 暂无数据" + picUrls.value.length ? JSON.stringify(picUrls.value, null, 2) : "// 暂无数据", ); const fileUrlsJson = computed(() => - fileUrls.value.length ? JSON.stringify(fileUrls.value, null, 2) : "// 暂无数据" + fileUrls.value.length ? JSON.stringify(fileUrls.value, null, 2) : "// 暂无数据", ); diff --git a/src/views/demo/data-screen/components/base-chart.vue b/src/views/demo/data-screen/components/base-chart.vue index 3755db56..8332ef4b 100644 --- a/src/views/demo/data-screen/components/base-chart.vue +++ b/src/views/demo/data-screen/components/base-chart.vue @@ -113,7 +113,7 @@ const init = async () => { chartInstance.value = markRaw( echarts.init(chartRef.value, theme, { renderer: "canvas", - }) + }), ); } }; diff --git a/src/views/demo/route/multi-level/components/ToDetail.ts b/src/views/demo/route/multi-level/components/ToDetail.ts index b04fa2e5..81b14b9f 100644 --- a/src/views/demo/route/multi-level/components/ToDetail.ts +++ b/src/views/demo/route/multi-level/components/ToDetail.ts @@ -30,7 +30,7 @@ export default defineComponent({ type: "primary", onClick: () => navigateToDetail(1), }, - { default: () => "跳转详情1" } + { default: () => "跳转详情1" }, ), h( ElButton, @@ -38,7 +38,7 @@ export default defineComponent({ type: "success", onClick: () => navigateToDetail(2), }, - { default: () => "跳转详情2" } + { default: () => "跳转详情2" }, ), ]); }, diff --git a/src/views/dynamic-form/components/FormRenderer.vue b/src/views/dynamic-form/components/FormRenderer.vue index 33b54533..de4b8b92 100644 --- a/src/views/dynamic-form/components/FormRenderer.vue +++ b/src/views/dynamic-form/components/FormRenderer.vue @@ -70,7 +70,7 @@ watch( if (!submitted) { formData.value = {}; } - } + }, ); /** diff --git a/src/views/dynamic-form/components/PublishDialog.vue b/src/views/dynamic-form/components/PublishDialog.vue index 2e66ddbe..c4aef56c 100644 --- a/src/views/dynamic-form/components/PublishDialog.vue +++ b/src/views/dynamic-form/components/PublishDialog.vue @@ -151,12 +151,12 @@ const DEFAULT_CATALOG_NAME = "表单中心"; // 是否展示菜单入口配置块(已发布恒显示,未发布按第①步所选) const showMenuConfig = computed(() => - isPublished.value ? true : selectedMethods.value.includes("menu") + isPublished.value ? true : selectedMethods.value.includes("menu"), ); // 是否展示分享入口配置块 const showShareConfig = computed(() => - isPublished.value ? true : selectedMethods.value.includes("share") + isPublished.value ? true : selectedMethods.value.includes("share"), ); // 保存按钮文案(按配置的入口组合动态变化) @@ -167,7 +167,7 @@ const saveButtonLabel = computed(() => { // 分享链接(hash 路由:origin + pathname + #/f/formKey) const shareUrl = computed( - () => `${window.location.origin}${window.location.pathname}#/f/${props.formKey}` + () => `${window.location.origin}${window.location.pathname}#/f/${props.formKey}`, ); // 第③步分享汇总可见(配置了分享且开关开启) @@ -286,7 +286,7 @@ const menuBreadcrumb = computed(() => { const grantedRoleNames = computed(() => roleOptions.value .filter((role) => menuForm.roleIds?.includes(String(role.value))) - .map((role) => role.label) + .map((role) => role.label), ); // 菜单完整路由路径(目录路径链 + 表单标识) diff --git a/src/views/dynamic-form/components/publish/EntryConfigStep.vue b/src/views/dynamic-form/components/publish/EntryConfigStep.vue index a53d5d3c..ed273a10 100644 --- a/src/views/dynamic-form/components/publish/EntryConfigStep.vue +++ b/src/views/dynamic-form/components/publish/EntryConfigStep.vue @@ -174,7 +174,7 @@ const rules = computed>(() => menuName: [{ required: true, message: "请输入菜单名称", trigger: "blur" }], parentId: [{ required: true, message: "请选择上级菜单", trigger: "change" }], } - : {} + : {}, ); /** @@ -195,7 +195,7 @@ function validate(): Promise { } return menuFormRef.value.validate().then( () => true, - () => false + () => false, ); } diff --git a/src/views/dynamic-form/composables/useFormRenderer.ts b/src/views/dynamic-form/composables/useFormRenderer.ts index 9f6aa17c..432fbd6b 100644 --- a/src/views/dynamic-form/composables/useFormRenderer.ts +++ b/src/views/dynamic-form/composables/useFormRenderer.ts @@ -15,7 +15,7 @@ export interface FormRuleSource { * 加载规则并管理表单填写、公开访问与预览页的渲染状态。 */ export function useFormRenderer( - loader: () => Promise + loader: () => Promise, ) { // shallowRef:深响应式代理会破坏 form-create Rule 内部 Creator 结构 const rule = shallowRef([]); diff --git a/src/views/dynamic-form/data.vue b/src/views/dynamic-form/data.vue index 7f035618..b5f9831a 100644 --- a/src/views/dynamic-form/data.vue +++ b/src/views/dynamic-form/data.vue @@ -334,7 +334,7 @@ async function handleExport(): Promise { record.formVersion = row.formVersion; record.createTime = row.createTime; return record; - }) + }), ); const buffer = await workbook.xlsx.writeBuffer(); diff --git a/src/views/dynamic-form/index.vue b/src/views/dynamic-form/index.vue index 95baa09f..91460325 100644 --- a/src/views/dynamic-form/index.vue +++ b/src/views/dynamic-form/index.vue @@ -309,7 +309,7 @@ const categoryOptions: Record = { // 当前编辑表单状态:非草稿(已发布/已停用)时类型作为业务标识不可修改 const editingStatus = ref(null); const categoryDisabled = computed( - () => editingStatus.value !== null && editingStatus.value !== FormStatus.DRAFT + () => editingStatus.value !== null && editingStatus.value !== FormStatus.DRAFT, ); /** @@ -429,7 +429,7 @@ async function handleEditClick(row: FormDefinitionItem): Promise { async function handleSubmit(): Promise { const valid = await formDefinitionFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/dynamic-form/preview.vue b/src/views/dynamic-form/preview.vue index aa000dc4..8ee5e451 100644 --- a/src/views/dynamic-form/preview.vue +++ b/src/views/dynamic-form/preview.vue @@ -45,7 +45,7 @@ const title = computed(() => String(route.query.title ?? "表单预览")); // 走表单定义接口拉草稿规则:render 接口仅返回已发布表单,预览恰恰要覆盖未发布态 const { rule, option, loading, submitted, load, refill } = useFormRenderer(() => - FormAPI.getDefinitionForm(formId.value) + FormAPI.getDefinitionForm(formId.value), ); onMounted(async () => { diff --git a/src/views/dynamic-form/render.vue b/src/views/dynamic-form/render.vue index 8792ba48..f2d1e7da 100644 --- a/src/views/dynamic-form/render.vue +++ b/src/views/dynamic-form/render.vue @@ -46,7 +46,7 @@ const renderData = ref(); const submitting = ref(false); const { rule, option, loading, submitted, load, refill } = useFormRenderer(() => - FormAPI.getRender(formKey.value) + FormAPI.getRender(formKey.value), ); onMounted(async () => { diff --git a/src/views/dynamic-form/share.vue b/src/views/dynamic-form/share.vue index 2d53be72..be2fa75f 100644 --- a/src/views/dynamic-form/share.vue +++ b/src/views/dynamic-form/share.vue @@ -54,7 +54,7 @@ const submitting = ref(false); const loadError = ref(""); const { rule, option, loading, submitted, load, refill } = useFormRenderer(() => - FormAPI.getPublicRender(formKey.value) + FormAPI.getPublicRender(formKey.value), ); onMounted(async () => { diff --git a/src/views/internal/error/components/ErrorPage.vue b/src/views/internal/error/components/ErrorPage.vue index 4d436d48..0d729dab 100644 --- a/src/views/internal/error/components/ErrorPage.vue +++ b/src/views/internal/error/components/ErrorPage.vue @@ -79,7 +79,7 @@ const props = defineProps(); const visualIcon = computed(() => (props.variant === "locked" ? Lock : Search)); const visualName = computed(() => (props.variant === "locked" ? "ACCESS CONTROL" : "ROUTE TRACE")); const visualMeta = computed(() => - props.variant === "locked" ? "权限校验未通过" : "目标路由未匹配" + props.variant === "locked" ? "权限校验未通过" : "目标路由未匹配", ); diff --git a/src/views/login/index.vue b/src/views/login/index.vue index bc3efa77..18a25328 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -257,7 +257,7 @@ function getCaptcha() { async function handleLoginSubmit() { const valid = await loginFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; @@ -268,7 +268,7 @@ async function handleLoginSubmit() { const redirectPath = (route.query.redirect as string) || "/"; await router.push(decodeURIComponent(redirectPath)); }, - () => getCaptcha() + () => getCaptcha(), ); } finally { loading.value = false; diff --git a/src/views/system/app/index.vue b/src/views/system/app/index.vue index 72908669..cecb7540 100644 --- a/src/views/system/app/index.vue +++ b/src/views/system/app/index.vue @@ -356,7 +356,7 @@ async function handleStatusChange(row: AppItem): Promise { async function handleSubmit(): Promise { const valid = await dataFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue index 2d1e1ce8..ce13cbf7 100644 --- a/src/views/system/config/index.vue +++ b/src/views/system/config/index.vue @@ -293,7 +293,7 @@ async function handleDelete(id: string): Promise { type: "warning", }).then( () => true, - () => false + () => false, ); if (!confirmed) return; diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index ed90af94..a8fcf73a 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -330,7 +330,7 @@ async function openDialog(parentId?: string, deptId?: string): Promise { async function handleSubmit(): Promise { const valid = await deptFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/dict/components/DictItemPanel.vue b/src/views/system/dict/components/DictItemPanel.vue index 71f0e51b..65befb61 100644 --- a/src/views/system/dict/components/DictItemPanel.vue +++ b/src/views/system/dict/components/DictItemPanel.vue @@ -312,7 +312,7 @@ function invalidateDictCache(): void { async function handleSubmit(): Promise { const valid = await dictItemFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index 86e6eac3..1b200d64 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -282,7 +282,7 @@ async function handleEditClick(id?: string): Promise { async function handleSubmit(): Promise { const valid = await dictFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index 66da6263..46c92986 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -636,7 +636,7 @@ const formData = reactive({ ...initialFormData }); // AI 推断按钮的提示文案,未填名称时说明置灰原因 const aiTip = computed(() => - formData.name?.trim() ? "根据菜单名称推断访问路径、权限标识" : "先填写菜单名称" + formData.name?.trim() ? "根据菜单名称推断访问路径、权限标识" : "先填写菜单名称", ); // 上级菜单选项,顶级节点下挂完整菜单树 @@ -685,7 +685,7 @@ const typeLocked = computed(() => isEditing.value || typeOptions.value.length == // 类型被锁定的原因:编辑时不可改类型;页面下新增只能挂按钮 const typeLockedTip = computed(() => - isEditing.value ? "类型创建后不可修改" : "页面下只能挂按钮权限" + isEditing.value ? "类型创建后不可修改" : "页面下只能挂按钮权限", ); const visibleSwitch = computed({ @@ -722,7 +722,7 @@ watch( if (allowed.some((item) => item.value === formData.type)) return; formData.type = allowed[0]?.value ?? MenuTypeEnum.MENU; handleTypeChange(); - } + }, ); // 勾选生成按钮时按同级已有按钮推导权限前缀,用户已填则不覆盖 @@ -732,7 +732,7 @@ watch( if (!checked || formData.buttonPermPrefix?.trim()) return; formData.buttonPermPrefix = deriveButtonPermPrefix(); permPrefixAuto.value = true; - } + }, ); // 前缀是推导来的就跟随访问路径刷新,用户手改过则不再变动 @@ -742,28 +742,28 @@ watch( if (permPrefixAuto.value) { formData.buttonPermPrefix = deriveButtonPermPrefix(); } - } + }, ); // 上级路径逐级拼接,得到当前菜单的完整访问地址 const parentPath = computed(() => findMenuTrail(parentMenuTree.value, formData.parentId).reduce( (path, menu) => joinRoutePath(path, menu.routePath), - "" - ) + "", + ), ); const fullRoutePath = computed(() => - formData.routePath ? joinRoutePath(parentPath.value, formData.routePath) : "" + formData.routePath ? joinRoutePath(parentPath.value, formData.routePath) : "", ); const derivedRouteName = computed(() => - fullRoutePath.value ? deriveRouteName(fullRoutePath.value) : "" + fullRoutePath.value ? deriveRouteName(fullRoutePath.value) : "", ); // 页面路径对应的文件位置,输入带 .vue 后缀也能正确展示 const componentFilePath = computed(() => - formData.component ? `src/views/${normalizeViewPath(formData.component)}.vue` : "" + formData.component ? `src/views/${normalizeViewPath(formData.component)}.vue` : "", ); const previewText = computed(() => { @@ -819,7 +819,7 @@ const validateComponent = (_: unknown, value: string, callback: (error?: Error) // 未改动的历史值跳过存在性校验,避免旧数据无法保存 if (value !== originalComponent.value && !isViewComponent(value)) { callback( - new Error(componentManual.value ? "页面不存在,请检查路径" : "页面不存在,请重新选择") + new Error(componentManual.value ? "页面不存在,请检查路径" : "页面不存在,请重新选择"), ); return; } @@ -958,7 +958,7 @@ function getMenuAccessPath(row: MenuItem): string { if (row.type === MenuTypeEnum.BUTTON) return ""; return findMenuTrail(list.value, row.id).reduce( (path, menu) => joinRoutePath(path, menu.routePath), - "" + "", ); } @@ -1042,7 +1042,7 @@ function resolveSiblingPermModule(menus: MenuItem[], parentId: string): string { if (child.type !== MenuTypeEnum.BUTTON) return; const module = child.perm?.split(":")[0]; if (module) counter.set(module, (counter.get(module) ?? 0) + 1); - }) + }), ); let module = ""; @@ -1408,7 +1408,7 @@ async function handleSubmit(): Promise { if (saving.value) return; const valid = await menuFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue index 92cb9064..92b12625 100644 --- a/src/views/system/notice/index.vue +++ b/src/views/system/notice/index.vue @@ -506,7 +506,7 @@ function closeDialog(): void { async function handleSubmit(): Promise { const valid = await noticeFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 9fd3fac5..7d5540a9 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -559,14 +559,14 @@ const displayRows = computed(() => { // 带下级菜单行的节点 const collapsibleIds = computed(() => - permRows.value.filter((row) => row.group).map((row) => row.id) + permRows.value.filter((row) => row.group).map((row) => row.id), ); // 带下级菜单行的节点是否都已折叠 const isAllCollapsed = computed( () => collapsibleIds.value.length > 0 && - collapsibleIds.value.every((id) => collapsedIds.value.has(id)) + collapsibleIds.value.every((id) => collapsedIds.value.has(id)), ); /** @@ -822,7 +822,7 @@ async function handleEditClick(roleId?: string): Promise { async function handleSubmit(): Promise { const valid = await roleFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue index 6f7b258a..0db3f9eb 100644 --- a/src/views/system/tenant/index.vue +++ b/src/views/system/tenant/index.vue @@ -502,7 +502,7 @@ const menuTreeProps = { // 目标套餐未配置菜单时禁止提交 const isPlanMenuEmpty = computed( - () => tenantPlanId.value != null && planMenuIds.value.length === 0 + () => tenantPlanId.value != null && planMenuIds.value.length === 0, ); const hasPermTenantMenu = computed(() => hasPerm("sys:tenant:plan-assign")); @@ -551,7 +551,7 @@ function applyMenuOptionsDisabled(options: OptionItem[], disabled: boolean): Opt */ function filterMenuOptionsByIds( options: OptionItem[], - allowedMenuIdSet: Set + allowedMenuIdSet: Set, ): OptionItem[] { return options.reduce((acc, option) => { const children = option.children @@ -768,7 +768,7 @@ async function handleTenantPlanSelectSubmit(): Promise { type: "warning", confirmButtonText: "确认更换", cancelButtonText: "取消", - } + }, ); } catch { return; @@ -787,7 +787,7 @@ async function handleTenantPlanSelectSubmit(): Promise { if (hasPermTenantMenu.value) { const targetPlanMenuIdSet = new Set(planMenuIds.value); const keepMenuIds = originalEnabledMenuIds.value.filter((menuId) => - targetPlanMenuIdSet.has(menuId) + targetPlanMenuIdSet.has(menuId), ); await TenantAPI.updateTenantMenus(tenantId, keepMenuIds); } @@ -884,7 +884,7 @@ function closeDialog(): void { const handleSubmit = useDebounceFn(async (): Promise => { const valid = await tenantFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/tenant/plan.vue b/src/views/system/tenant/plan.vue index 4336cfd2..3428c075 100644 --- a/src/views/system/tenant/plan.vue +++ b/src/views/system/tenant/plan.vue @@ -360,7 +360,7 @@ async function handleEditClick(planId?: number): Promise { const handleSubmit = useDebounceFn(async (): Promise => { const valid = await planFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; diff --git a/src/views/system/user/components/UserDeptTree.vue b/src/views/system/user/components/UserDeptTree.vue index 51179b9e..ae72d4d3 100644 --- a/src/views/system/user/components/UserDeptTree.vue +++ b/src/views/system/user/components/UserDeptTree.vue @@ -51,7 +51,7 @@ watchEffect( }, { flush: "post", - } + }, ); /** diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index b89d2275..f29a188a 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -385,7 +385,7 @@ const roleOptions = ref([]); const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? "600px" : "90%")); const resetPasswordDialogWidth = computed(() => - appStore.device === DeviceEnum.DESKTOP ? "420px" : "90%" + appStore.device === DeviceEnum.DESKTOP ? "420px" : "90%", ); const rules: FormRules = { @@ -505,7 +505,7 @@ function getUserActions(row: UserItem): TableAction[] { const handleSubmit = useDebounceFn(async () => { const valid = await userFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; @@ -627,7 +627,7 @@ function resetResetPasswordForm(): void { const handleResetPasswordSubmit = useDebounceFn(async () => { const valid = await resetPasswordFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid || !resetPasswordDialog.userId) return; diff --git a/src/views/workflow/components/BpmnDesigner.vue b/src/views/workflow/components/BpmnDesigner.vue index f0dcadcf..695b423d 100644 --- a/src/views/workflow/components/BpmnDesigner.vue +++ b/src/views/workflow/components/BpmnDesigner.vue @@ -214,38 +214,38 @@ const dirty = ref(false); const selectedElement = shallowRef(null); const isUserTask = computed( - () => !!selectedElement.value && is(selectedElement.value, "bpmn:UserTask") + () => !!selectedElement.value && is(selectedElement.value, "bpmn:UserTask"), ); const isSequenceFlow = computed( - () => !!selectedElement.value && is(selectedElement.value, "bpmn:SequenceFlow") + () => !!selectedElement.value && is(selectedElement.value, "bpmn:SequenceFlow"), ); // 仅开始节点可绑定表单(后端只读开始节点 formKey 渲染发起表单,审批展示复用同一份数据) const isFormBindable = computed( - () => !!selectedElement.value && is(selectedElement.value, "bpmn:StartEvent") + () => !!selectedElement.value && is(selectedElement.value, "bpmn:StartEvent"), ); const selectedName = computed(() => selectedElement.value?.businessObject?.name ?? ""); const selectedFormKey = computed(() => selectedElement.value?.businessObject?.get("formKey") ?? ""); const selectedAssignee = computed( - () => selectedElement.value?.businessObject?.get("assignee") ?? "" + () => selectedElement.value?.businessObject?.get("assignee") ?? "", ); // 候选组(角色编码,逗号分隔)与办理人二选一配置,均空发布时会被后端拦截 const selectedCandidateGroups = computed( - () => selectedElement.value?.businessObject?.get("candidateGroups") ?? "" + () => selectedElement.value?.businessObject?.get("candidateGroups") ?? "", ); // 候选组多选值:XML 逗号串 ↔ 选项数组互转,数据结构保持引擎兼容 const candidateGroupCodes = computed(() => String(selectedCandidateGroups.value) .split(",") .map((code) => code.trim()) - .filter(Boolean) + .filter(Boolean), ); // 角色编码选项(label 角色名 / value 角色编码) const roleCodeOptions = ref([]); // 发起表单选项(label 表单名 / value formKey,仅已发布 workflow 类型) const workflowFormOptions = ref([]); const selectedCondition = computed( - () => selectedElement.value?.businessObject?.conditionExpression?.body ?? "" + () => selectedElement.value?.businessObject?.conditionExpression?.body ?? "", ); /** @@ -350,7 +350,7 @@ async function importXml(xml: string): Promise { watch( () => props.xml, - (xml) => importXml(xml) + (xml) => importXml(xml), ); onMounted(() => { diff --git a/src/views/workflow/components/BpmnViewer.vue b/src/views/workflow/components/BpmnViewer.vue index 3bae9851..dfc780f4 100644 --- a/src/views/workflow/components/BpmnViewer.vue +++ b/src/views/workflow/components/BpmnViewer.vue @@ -43,7 +43,7 @@ const viewer = shallowRef(); async function renderDiagram( xml: string, executedIds?: string[], - activeIds?: string[] + activeIds?: string[], ): Promise { if (!xml || !viewer.value) return; const canvas = viewer.value.get("canvas") as CanvasLike; @@ -64,9 +64,9 @@ watch( renderDiagram( xml as string, executedIds as string[] | undefined, - activeIds as string[] | undefined + activeIds as string[] | undefined, ), - { flush: "post" } + { flush: "post" }, ); onMounted(() => { diff --git a/src/views/workflow/components/FormDetail.vue b/src/views/workflow/components/FormDetail.vue index da1ac8e1..f2cb8ad3 100644 --- a/src/views/workflow/components/FormDetail.vue +++ b/src/views/workflow/components/FormDetail.vue @@ -56,7 +56,7 @@ watch( } formData.value = parseDataJson(props.dataJson); }, - { immediate: true } + { immediate: true }, ); /** diff --git a/src/views/workflow/components/InstanceDetailDrawer.vue b/src/views/workflow/components/InstanceDetailDrawer.vue index 2e48ac2b..3d7b47b3 100644 --- a/src/views/workflow/components/InstanceDetailDrawer.vue +++ b/src/views/workflow/components/InstanceDetailDrawer.vue @@ -104,7 +104,7 @@ watch( (value) => { if (!value) openSequence += 1; }, - { flush: "sync" } + { flush: "sync" }, ); onScopeDispose(() => { openSequence += 1; diff --git a/src/views/workflow/launch.vue b/src/views/workflow/launch.vue index c6ee38a5..df8cb7ab 100644 --- a/src/views/workflow/launch.vue +++ b/src/views/workflow/launch.vue @@ -113,7 +113,7 @@ const processList = ref([]); const selectedId = ref(""); const selectedProcess = computed(() => - processList.value.find((process) => process.id === selectedId.value) + processList.value.find((process) => process.id === selectedId.value), ); // 审批流程走向预览 @@ -167,7 +167,7 @@ function resetAutoName(): void { // 复用动态表单的规则加载与渲染状态。 const { rule, option, loading, submitted, load, refill } = useFormRenderer(() => - FormAPI.getRender(selectedProcess.value?.formKey ?? "") + FormAPI.getRender(selectedProcess.value?.formKey ?? ""), ); const starting = ref(false); diff --git a/src/views/workflow/model.vue b/src/views/workflow/model.vue index 68aceff4..5bb1f67e 100644 --- a/src/views/workflow/model.vue +++ b/src/views/workflow/model.vue @@ -356,7 +356,7 @@ function handleEditClick(row: WorkflowModelItem): void { async function handleSubmit(): Promise { const valid = await modelFormRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; @@ -445,7 +445,7 @@ async function handleResetDemo(): Promise { await ElMessageBox.confirm( "将清空所有流程(含用户自建)的模型、发布版本、实例与历史记录,恢复至 4 个初始演示流程。确定重置?", "重置工作流数据", - { confirmButtonText: "重置", cancelButtonText: "取消", type: "warning" } + { confirmButtonText: "重置", cancelButtonText: "取消", type: "warning" }, ); } catch { ElMessage.info("已取消重置"); @@ -492,7 +492,7 @@ async function handleDelete(id?: string): Promise { await ElMessageBox.confirm( "将删除该流程的设计、已发布版本及全部流程实例数据,不可恢复。确定删除?", "删除流程", - { confirmButtonText: "删除", cancelButtonText: "取消", type: "warning" } + { confirmButtonText: "删除", cancelButtonText: "取消", type: "warning" }, ); } catch { ElMessage.info("已取消删除"); diff --git a/src/views/workspace/account/components/IdentityBinding.vue b/src/views/workspace/account/components/IdentityBinding.vue index bf0c19c5..770c1d1b 100644 --- a/src/views/workspace/account/components/IdentityBinding.vue +++ b/src/views/workspace/account/components/IdentityBinding.vue @@ -109,7 +109,7 @@ async function saveIdentity(): Promise { try { const valid = await formRef.value?.validate().then( () => true, - () => false + () => false, ); if (!valid) return; @@ -134,10 +134,10 @@ async function removeIdentity(): Promise { const confirmed = await ElMessageBox.confirm( "确认解除统一认证身份吗?现有会话也会失效。", "解除绑定", - { type: "warning" } + { type: "warning" }, ).then( () => true, - () => false + () => false, ); if (!confirmed) return; diff --git a/src/views/workspace/apps/index.vue b/src/views/workspace/apps/index.vue index 9c1724fd..67368146 100644 --- a/src/views/workspace/apps/index.vue +++ b/src/views/workspace/apps/index.vue @@ -171,7 +171,7 @@ const appGroups = categories .map((category) => ({ category, apps: apps.filter((app) => app.category === category.key) })) // 未启用统一认证时不展示账号分组 .filter( - (group) => group.apps.length > 0 && (appConfig.oidcEnabled || group.category.key !== "account") + (group) => group.apps.length > 0 && (appConfig.oidcEnabled || group.category.key !== "account"), ); // 站内路径走路由跳转,外部地址新标签打开 diff --git a/.stylelintrc.cjs b/stylelint.config.cjs similarity index 54% rename from .stylelintrc.cjs rename to stylelint.config.cjs index f608406b..948e83ae 100644 --- a/.stylelintrc.cjs +++ b/stylelint.config.cjs @@ -1,28 +1,13 @@ module.exports = { extends: [ - "stylelint-config-recommended", "stylelint-config-recommended-scss", - "stylelint-config-recommended-vue/scss", - "stylelint-config-html/vue", "stylelint-config-recess-order", - ], - overrides: [ - { - files: ["**/*.css"], - rules: { "declaration-property-value-no-unknown": true }, - }, - { - files: ["**/*.{vue,html}"], - customSyntax: "postcss-html", - }, - { - files: ["**/*.{css,scss}"], - customSyntax: "postcss-scss", - }, + // 提供 Vue 解析与规则,必须放在最后 + "stylelint-config-recommended-vue/scss", ], rules: { "no-empty-source": null, - "declaration-property-value-no-unknown": null, + "no-invalid-position-declaration": null, "selector-pseudo-class-no-unknown": [ true, { @@ -35,8 +20,5 @@ module.exports = { ignorePseudoElements: ["deep", "slotted", "global", "v-deep", "v-slotted", "v-global"], }, ], - "no-invalid-position-declaration": null, - "at-rule-no-unknown": null, - "scss/at-rule-no-unknown": true, }, }; diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json deleted file mode 100644 index dc51755b..00000000 --- a/tsconfig.eslint.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*", "mock/**/*", "vite.config.ts", "uno.config.ts", "eslint.config.ts"] -} diff --git a/tsconfig.json b/tsconfig.json index ec2d93f1..9f5029d9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "target": "esnext", "module": "esnext", "moduleResolution": "bundler", - "lib": ["esnext", "dom"], + "lib": ["esnext", "dom", "dom.iterable"], "paths": { "@/*": ["./src/*"] }, diff --git a/types/modules.d.ts b/types/modules.d.ts index a3ef2268..1ba9223b 100644 --- a/types/modules.d.ts +++ b/types/modules.d.ts @@ -12,3 +12,13 @@ declare module "sockjs-client/dist/sockjs.min.js" { import Client from "sockjs-client"; export default Client; } + +declare module "vxe-pc-ui/lib/language/en-US" { + const language: Record; + export default language; +} + +declare module "vxe-pc-ui/lib/language/zh-CN" { + const language: Record; + export default language; +} diff --git a/uno.config.ts b/uno.config.ts index e5f994d6..80275dab 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -51,7 +51,7 @@ export default defineConfig({ [640, 768, 1024, 1280, 1536, 1920, 2560].map((size, index) => [ ["sm", "md", "lg", "xl", "2xl", "3xl", "4xl"][index], `${size}px`, - ]) + ]), ), }, presets: [ diff --git a/vite.config.ts b/vite.config.ts index 83d36769..5e850b23 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,5 @@ import vue from "@vitejs/plugin-vue"; -import { type ConfigEnv, type UserConfig, loadEnv, defineConfig } from "vite"; +import { type ConfigEnv, type Plugin, type UserConfig, loadEnv, defineConfig } from "vite"; import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; @@ -51,7 +51,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { target: proxyTarget, rewrite: (path: string) => path.slice(env.VITE_API_BASE.length), }, - // 通知中心 WebSocket,单独代理以完成 ws 升级 + // 通知中心 WebSocket,单独代理以转发握手请求 "/api/v1/realtime/ws": { changeOrigin: true, rewriteWsOrigin: true, @@ -192,7 +192,7 @@ function getElementPlusStyleDeps(): string[] { return readdirSync(componentsDir, { withFileTypes: true }) .filter( (entry) => - entry.isDirectory() && existsSync(resolve(componentsDir, entry.name, "style/index.mjs")) + entry.isDirectory() && existsSync(resolve(componentsDir, entry.name, "style/index.mjs")), ) .map((entry) => `element-plus/es/components/${entry.name}/style/index`); }