From ff6f68c0ce3d119061bd6d49c6a8c6806a9771a8 Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Fri, 6 Mar 2026 22:47:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0mock=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=92=8C=E7=94=A8=E6=88=B7store=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构用户模块的异步函数,添加租户和租户计划的mock接口,优化字典表单和请求拦截器的实现。 --- .husky/pre-commit | 2 +- mock/menu.mock.ts | 196 +++++++++++++++++++++------ mock/role.mock.ts | 200 ++++++++------------------- mock/tenant-plan.mock.ts | 125 +++++++++++++++++ mock/tenant.mock.ts | 201 +++++++++++++++++++++++++++- mock/user.mock.ts | 47 ++++--- src/store/modules/user.ts | 111 +++++---------- src/utils/request.ts | 3 +- src/views/system/dict/dict-item.vue | 24 +++- src/views/system/dict/index.vue | 18 ++- vite.config.ts | 1 - 11 files changed, 631 insertions(+), 297 deletions(-) create mode 100644 mock/tenant-plan.mock.ts diff --git a/.husky/pre-commit b/.husky/pre-commit index b18d0418..2e44bfdc 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1 @@ -npm run lint:lint-staged +npm run lint:lint-staged -- --no-stash diff --git a/mock/menu.mock.ts b/mock/menu.mock.ts index d2187778..71d6cfdd 100644 --- a/mock/menu.mock.ts +++ b/mock/menu.mock.ts @@ -472,19 +472,6 @@ export default defineMock([ params: null, }, children: [ - { - path: "vxe-table", - component: "demo/vxe-table/index", - name: "VxeTable", - meta: { - title: "VxeTable", - icon: "el-icon-MagicStick", - hidden: false, - keepAlive: true, - alwaysShow: false, - params: null, - }, - }, { path: "icon-demo", component: "demo/icons", @@ -499,11 +486,24 @@ export default defineMock([ }, }, { - path: "/function/ai-command", - component: "demo/ai-command", - name: "/function/ai-command", + path: "dict-sync", + component: "demo/dict-sync", + name: "DictSync", meta: { - title: "AI 命令助手", + title: "字典实时同步", + icon: "", + hidden: false, + keepAlive: true, + alwaysShow: false, + params: null, + }, + }, + { + path: "vxe-table", + component: "demo/vxe-table/index", + name: "VxeTable", + meta: { + title: "VxeTable", icon: "el-icon-MagicStick", hidden: false, keepAlive: true, @@ -512,13 +512,14 @@ export default defineMock([ }, }, { - path: "other/:id", - component: "demo/other", - name: "Other/:id", + path: "curd-single", + component: "demo/curd-single", + name: "CurdSingle", meta: { - title: "敬请期待...", - icon: "", + title: "CURD单文件", + icon: "el-icon-Reading", hidden: false, + keepAlive: true, alwaysShow: false, params: null, }, @@ -1530,7 +1531,7 @@ export default defineMock([ ], }, { - id: 89, + id: 7, parentId: 0, name: "功能演示", type: "CATALOG", @@ -1544,8 +1545,8 @@ export default defineMock([ perm: null, children: [ { - id: 97, - parentId: 89, + id: 801, + parentId: 7, name: "Icons", type: "MENU", routeName: null, @@ -1559,20 +1560,50 @@ export default defineMock([ children: [], }, { - id: 91, - parentId: 89, - name: "敬请期待...", - type: "CATALOG", + id: 802, + parentId: 7, + name: "字典实时同步", + type: "MENU", routeName: null, - routePath: "other/:id", - component: "demo/other", - sort: 4, + routePath: "dict-sync", + component: "demo/dict-sync", + sort: 3, visible: 1, icon: "", redirect: "", perm: null, children: [], }, + { + id: 803, + parentId: 7, + name: "VxeTable", + type: "MENU", + routeName: null, + routePath: "vxe-table", + component: "demo/vxe-table/index", + sort: 4, + visible: 1, + icon: "el-icon-MagicStick", + redirect: "", + perm: null, + children: [], + }, + { + id: 804, + parentId: 7, + name: "CURD单文件", + type: "MENU", + routeName: null, + routePath: "curd-single", + component: "demo/curd-single", + sort: 5, + visible: 1, + icon: "el-icon-Reading", + redirect: "", + perm: null, + children: [], + }, ], }, ], @@ -1902,20 +1933,24 @@ export default defineMock([ ], }, { - value: "89", + value: "7", label: "功能演示", children: [ { - value: "97", + value: "801", label: "Icons", }, { - value: "90", - label: "Websocket", + value: "802", + label: "字典实时同步", }, { - value: "91", - label: "敬请期待...", + value: "803", + label: "VxeTable", + }, + { + value: "804", + label: "CURD单文件", }, ], }, @@ -2077,4 +2112,89 @@ const menuMap: Record = { keepAlive: 1, alwaysShow: null, }, + 7: { + id: 7, + parentId: 0, + name: "功能演示", + type: "CATALOG", + routeName: "", + routePath: "/function", + component: "Layout", + perm: null, + visible: 1, + sort: 3, + icon: "menu", + redirect: "/function/icon-demo", + keepAlive: null, + alwaysShow: null, + params: null, + }, + 801: { + id: 801, + parentId: 7, + name: "Icons", + type: "MENU", + routeName: "IconDemo", + routePath: "icon-demo", + component: "demo/icons", + perm: null, + visible: 1, + sort: 1, + icon: "el-icon-Notification", + redirect: null, + keepAlive: 1, + alwaysShow: null, + params: null, + }, + 802: { + id: 802, + parentId: 7, + name: "字典实时同步", + type: "MENU", + routeName: "DictSync", + routePath: "dict-sync", + component: "demo/dict-sync", + perm: null, + visible: 1, + sort: 2, + icon: "", + redirect: null, + keepAlive: 1, + alwaysShow: null, + params: null, + }, + 803: { + id: 803, + parentId: 7, + name: "VxeTable", + type: "MENU", + routeName: "VxeTable", + routePath: "vxe-table", + component: "demo/vxe-table/index", + perm: null, + visible: 1, + sort: 3, + icon: "el-icon-MagicStick", + redirect: null, + keepAlive: 1, + alwaysShow: null, + params: null, + }, + 804: { + id: 804, + parentId: 7, + name: "CURD单文件", + type: "MENU", + routeName: "CurdSingle", + routePath: "curd-single", + component: "demo/curd-single", + perm: null, + visible: 1, + sort: 4, + icon: "el-icon-Reading", + redirect: null, + keepAlive: 1, + alwaysShow: null, + params: null, + }, }; diff --git a/mock/role.mock.ts b/mock/role.mock.ts index 42d1c356..50999270 100644 --- a/mock/role.mock.ts +++ b/mock/role.mock.ts @@ -7,50 +7,12 @@ export default defineMock([ body: { code: "00000", data: [ - { - value: 2, - label: "系统管理员", - }, - { - value: 4, - label: "系统管理员1", - }, - { - value: 5, - label: "系统管理员2", - }, - { - value: 6, - label: "系统管理员3", - }, - { - value: 7, - label: "系统管理员4", - }, - { - value: 8, - label: "系统管理员5", - }, - { - value: 9, - label: "系统管理员6", - }, - { - value: 10, - label: "系统管理员7", - }, - { - value: 11, - label: "系统管理员8", - }, - { - value: 12, - label: "系统管理员9", - }, - { - value: 3, - label: "访问游客", - }, + { value: 2, label: "系统管理员" }, + { value: 4, label: "部门主管" }, + { value: 5, label: "部门成员" }, + { value: 6, label: "普通员工" }, + { value: 7, label: "自定义权限用户" }, + { value: 3, label: "访问游客" }, ], msg: "一切ok", }, @@ -69,6 +31,7 @@ export default defineMock([ code: "ADMIN", status: 1, sort: 2, + dataScope: 1, createTime: "2021-03-25 12:39:54", updateTime: null, }, @@ -78,83 +41,52 @@ export default defineMock([ code: "GUEST", status: 1, sort: 3, + dataScope: 3, createTime: "2021-05-26 15:49:05", updateTime: "2019-05-05 16:00:00", }, { id: 4, - name: "系统管理员1", - code: "ADMIN1", + name: "部门主管", + code: "DEPT_MANAGER", status: 1, - sort: 2, + sort: 4, + dataScope: 2, createTime: "2021-03-25 12:39:54", updateTime: null, }, { id: 5, - name: "系统管理员2", - code: "ADMIN2", + name: "部门成员", + code: "DEPT_MEMBER", status: 1, - sort: 2, + sort: 5, + dataScope: 3, createTime: "2021-03-25 12:39:54", updateTime: null, }, { id: 6, - name: "系统管理员3", - code: "ADMIN3", + name: "普通员工", + code: "EMPLOYEE", status: 1, - sort: 2, + sort: 6, + dataScope: 4, createTime: "2021-03-25 12:39:54", updateTime: null, }, { id: 7, - name: "系统管理员4", - code: "ADMIN4", + name: "自定义权限用户", + code: "CUSTOM_USER", status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - { - id: 8, - name: "系统管理员5", - code: "ADMIN5", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - { - id: 9, - name: "系统管理员6", - code: "ADMIN6", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: "2023-12-04 11:43:15", - }, - { - id: 10, - name: "系统管理员7", - code: "ADMIN7", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - { - id: 11, - name: "系统管理员8", - code: "ADMIN8", - status: 1, - sort: 2, + sort: 7, + dataScope: 5, createTime: "2021-03-25 12:39:54", updateTime: null, }, ], - total: 10, + total: 6, }, msg: "一切ok", }, @@ -236,6 +168,20 @@ export default defineMock([ msg: "一切ok", }, }, + + // 获取角色部门ID列表(自定义数据权限) + { + url: "roles/:id/dept-ids", + method: ["GET"], + body: ({ params }) => { + const role = roleMap[params.id]; + return { + code: "00000", + data: role?.dataScope === 5 ? role.deptIds || [1, 2] : [], + msg: "一切ok", + }; + }, + }, ]); // 角色映射表数据 @@ -246,6 +192,7 @@ const roleMap: Record = { code: "ADMIN", status: 1, sort: 2, + dataScope: 1, createTime: "2021-03-25 12:39:54", updateTime: null, }, @@ -255,79 +202,48 @@ const roleMap: Record = { code: "GUEST", status: 1, sort: 3, + dataScope: 3, createTime: "2021-05-26 15:49:05", updateTime: "2019-05-05 16:00:00", }, 4: { id: 4, - name: "系统管理员1", - code: "ADMIN1", + name: "部门主管", + code: "DEPT_MANAGER", status: 1, - sort: 2, + sort: 4, + dataScope: 2, createTime: "2021-03-25 12:39:54", updateTime: null, }, 5: { id: 5, - name: "系统管理员2", - code: "ADMIN2", + name: "部门成员", + code: "DEPT_MEMBER", status: 1, - sort: 2, + sort: 5, + dataScope: 3, createTime: "2021-03-25 12:39:54", updateTime: null, }, - 6: { id: 6, - name: "系统管理员3", - code: "ADMIN3", + name: "普通员工", + code: "EMPLOYEE", status: 1, - sort: 2, + sort: 6, + dataScope: 4, createTime: "2021-03-25 12:39:54", updateTime: null, }, 7: { id: 7, - name: "系统管理员4", - code: "ADMIN4", + name: "自定义权限用户", + code: "CUSTOM_USER", status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - 8: { - id: 8, - name: "系统管理员5", - code: "ADMIN5", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - 9: { - id: 9, - name: "系统管理员6", - code: "ADMIN6", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: "2023-12-04 11:43:15", - }, - 10: { - id: 10, - name: "系统管理员7", - code: "ADMIN7", - status: 1, - sort: 2, - createTime: "2021-03-25 12:39:54", - updateTime: null, - }, - 11: { - id: 11, - name: "系统管理员8", - code: "ADMIN8", - status: 1, - sort: 2, + sort: 7, + dataScope: 5, + deptIds: [1, 2], createTime: "2021-03-25 12:39:54", updateTime: null, }, diff --git a/mock/tenant-plan.mock.ts b/mock/tenant-plan.mock.ts new file mode 100644 index 00000000..395a06ca --- /dev/null +++ b/mock/tenant-plan.mock.ts @@ -0,0 +1,125 @@ +import { defineMock } from "./base"; + +export default defineMock([ + { + url: "tenant-plans", + method: ["GET"], + body: { + code: "00000", + data: { + list: [ + { + id: 1, + name: "基础版", + code: "BASIC", + status: 1, + sort: 1, + remark: "", + createTime: "2026-03-01 10:00:00", + updateTime: "2026-03-01 10:00:00", + }, + { + id: 2, + name: "专业版", + code: "PRO", + status: 1, + sort: 2, + remark: "", + createTime: "2026-03-02 10:00:00", + updateTime: "2026-03-02 10:00:00", + }, + ], + total: 2, + }, + msg: "一切ok", + }, + }, + { + url: "tenant-plans/options", + method: ["GET"], + body: { + code: "00000", + data: [ + { value: 1, label: "基础版" }, + { value: 2, label: "专业版" }, + ], + msg: "一切ok", + }, + }, + { + url: "tenant-plans/:planId/form", + method: ["GET"], + body: ({ params }) => { + const planId = Number(params.planId); + const form = + planId === 2 + ? { + id: 2, + name: "专业版", + code: "PRO", + status: 1, + sort: 2, + remark: "", + } + : { + id: 1, + name: "基础版", + code: "BASIC", + status: 1, + sort: 1, + remark: "", + }; + + return { + code: "00000", + data: form, + msg: "一切ok", + }; + }, + }, + { + url: "tenant-plans", + method: ["POST"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenant-plans/:planId", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenant-plans/:ids", + method: ["DELETE"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenant-plans/:planId/menuIds", + method: ["GET"], + body: { + code: "00000", + data: [1, 2, 3, 4, 5, 6], + msg: "一切ok", + }, + }, + { + url: "tenant-plans/:planId/menus", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, +]); diff --git a/mock/tenant.mock.ts b/mock/tenant.mock.ts index 012b1b03..63c189e5 100644 --- a/mock/tenant.mock.ts +++ b/mock/tenant.mock.ts @@ -2,7 +2,7 @@ import { defineMock } from "./base"; export default defineMock([ { - url: "tenants", + url: "tenants/options", method: ["GET"], body: { code: "00000", @@ -10,12 +10,32 @@ export default defineMock([ { id: 1, name: "默认租户", + code: "default", + contactName: "管理员", + contactPhone: "17621210366", + contactEmail: "", domain: "default", + logo: "", + planId: 1, + status: 1, + remark: "", + expireTime: null, + isDefault: true, }, { id: 2, name: "演示租户", + code: "demo", + contactName: "演示用户", + contactPhone: "17621210366", + contactEmail: "", domain: "demo", + logo: "", + planId: 2, + status: 1, + remark: "", + expireTime: null, + isDefault: false, }, ], msg: "一切ok", @@ -29,11 +49,170 @@ export default defineMock([ data: { id: 1, name: "默认租户", + code: "default", + contactName: "管理员", + contactPhone: "17621210366", + contactEmail: "", domain: "default", + logo: "", + planId: 1, + status: 1, + remark: "", + expireTime: null, + isDefault: true, }, msg: "一切ok", }, }, + { + url: "tenants", + method: ["GET"], + body: { + code: "00000", + data: { + list: [ + { + id: 1, + name: "默认租户", + code: "default", + contactName: "管理员", + contactPhone: "17621210366", + contactEmail: "", + domain: "default", + logo: "", + planId: 1, + status: 1, + remark: "", + expireTime: null, + createTime: "2026-03-01 10:00:00", + updateTime: "2026-03-01 10:00:00", + }, + { + id: 2, + name: "演示租户", + code: "demo", + contactName: "演示用户", + contactPhone: "17621210366", + contactEmail: "", + domain: "demo", + logo: "", + planId: 2, + status: 1, + remark: "", + expireTime: null, + createTime: "2026-03-02 10:00:00", + updateTime: "2026-03-02 10:00:00", + }, + ], + total: 2, + }, + msg: "一切ok", + }, + }, + { + url: "tenants/:tenantId/form", + method: ["GET"], + body: ({ params }) => { + const tenantId = Number(params.tenantId); + const form = + tenantId === 2 + ? { + id: 2, + name: "演示租户", + code: "demo", + domain: "demo", + contactName: "演示用户", + contactPhone: "17621210366", + contactEmail: "", + logo: "", + planId: 2, + status: 1, + remark: "", + expireTime: null, + } + : { + id: 1, + name: "默认租户", + code: "default", + domain: "default", + contactName: "管理员", + contactPhone: "17621210366", + contactEmail: "", + logo: "", + planId: 1, + status: 1, + remark: "", + expireTime: null, + }; + + return { + code: "00000", + data: form, + msg: "一切ok", + }; + }, + }, + { + url: "tenants", + method: ["POST"], + body: { + code: "00000", + data: { + tenantId: 3, + tenantCode: "test", + tenantName: "测试租户", + adminUsername: "admin", + adminInitialPassword: "123456", + adminRoleCode: "TENANT_ADMIN", + }, + msg: "一切ok", + }, + }, + { + url: "tenants/:tenantId", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenants/:ids", + method: ["DELETE"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenants/:tenantId/status", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, + { + url: "tenants/:tenantId/menuIds", + method: ["GET"], + body: { + code: "00000", + data: [1, 2, 3, 4, 5, 6], + msg: "一切ok", + }, + }, + { + url: "tenants/:tenantId/menus", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "一切ok", + }, + }, { url: "tenants/:tenantId/switch", method: ["POST"], @@ -44,12 +223,32 @@ export default defineMock([ { id: 1, name: "默认租户", + code: "default", + contactName: "管理员", + contactPhone: "17621210366", + contactEmail: "", domain: "default", + logo: "", + planId: 1, + status: 1, + remark: "", + expireTime: null, + isDefault: true, }, { id: 2, name: "演示租户", + code: "demo", + contactName: "演示用户", + contactPhone: "17621210366", + contactEmail: "", domain: "demo", + logo: "", + planId: 2, + status: 1, + remark: "", + expireTime: null, + isDefault: false, }, ]; diff --git a/mock/user.mock.ts b/mock/user.mock.ts index baacfa6f..f3c8d15c 100644 --- a/mock/user.mock.ts +++ b/mock/user.mock.ts @@ -13,49 +13,48 @@ export default defineMock([ avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif", roles: ["ADMIN"], perms: [ - "sys:user:query", - "sys:user:add", - "sys:user:edit", + "sys:user:list", + "sys:user:create", + "sys:user:update", "sys:user:delete", "sys:user:import", "sys:user:export", "sys:user:reset-password", - "sys:role:query", - "sys:role:add", - "sys:role:edit", + "sys:role:list", + "sys:role:create", + "sys:role:update", "sys:role:delete", - "sys:dept:query", - "sys:dept:add", - "sys:dept:edit", + "sys:dept:list", + "sys:dept:create", + "sys:dept:update", "sys:dept:delete", - "sys:menu:query", - "sys:menu:add", - "sys:menu:edit", + "sys:menu:list", + "sys:menu:create", + "sys:menu:update", "sys:menu:delete", - "sys:dict:query", - "sys:dict:add", - "sys:dict:edit", - "sys:dict:delete", + "sys:dict:list", + "sys:dict:create", + "sys:dict:update", "sys:dict:delete", - "sys:dict-item:query", - "sys:dict-item:add", - "sys:dict-item:edit", + "sys:dict-item:list", + "sys:dict-item:create", + "sys:dict-item:update", "sys:dict-item:delete", - "sys:notice:query", - "sys:notice:add", - "sys:notice:edit", + "sys:notice:list", + "sys:notice:create", + "sys:notice:update", "sys:notice:delete", "sys:notice:revoke", "sys:notice:publish", - "sys:config:query", - "sys:config:add", + "sys:config:list", + "sys:config:create", "sys:config:update", "sys:config:delete", "sys:config:refresh", diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 6e56edb4..b92d32dd 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -18,37 +18,24 @@ export const useUserStore = defineStore("user", () => { /** * 登录 - * - * @param {LoginRequest} - * @returns */ - function login(loginRequest: LoginRequest) { - return new Promise((resolve, reject) => { - AuthAPI.login(loginRequest) - .then((data) => { - const { accessToken, refreshToken } = data; - // 保存记住我状态和token - rememberMe.value = loginRequest.rememberMe ?? false; - AuthStorage.setTokens(accessToken, refreshToken, rememberMe.value); - resolve(); - }) - .catch((error) => { - reject(error); - }); - }); + async function login(loginRequest: LoginRequest): Promise { + const { accessToken, refreshToken } = await AuthAPI.login(loginRequest); + rememberMe.value = loginRequest.rememberMe ?? false; + AuthStorage.setTokens(accessToken, refreshToken, rememberMe.value); } let refreshPromise: Promise | null = null; /** - * 刷新 token(单飞)。 + * 刷新 token(单飞模式) * * 多个并发请求遇到 token 过期时,共享同一次 refresh 请求。 */ - function refreshTokenOnce() { + function refreshTokenOnce(): Promise { if (refreshPromise) return refreshPromise; - refreshPromise = refreshToken().finally(() => { + refreshPromise = doRefreshToken().finally(() => { refreshPromise = null; }); @@ -57,118 +44,84 @@ export const useUserStore = defineStore("user", () => { /** * 获取用户信息 - * - * @returns {UserInfo} 用户信息 */ - function getUserInfo() { - return new Promise((resolve, reject) => { - UserAPI.getInfo() - .then((data) => { - if (!data) { - reject("Verification failed, please Login again."); - return; - } - Object.assign(userInfo.value, { ...data }); - resolve(data); - }) - .catch((error) => { - reject(error); - }); - }); + async function getUserInfo(): Promise { + const data = await UserAPI.getInfo(); + if (!data) { + throw new Error("Verification failed, please Login again."); + } + Object.assign(userInfo.value, data); + return data; } /** * 登出 */ - function logout() { - return new Promise((resolve, reject) => { - AuthAPI.logout() - .then(() => { - // 重置所有系统状态 - resetAllState(); - resolve(); - }) - .catch((error) => { - reject(error); - }); - }); + async function logout(): Promise { + await AuthAPI.logout(); + resetAllState(); } /** * 重置所有系统状态 + * * 统一处理所有清理工作,包括用户凭证、路由、缓存等 */ - function resetAllState() { + function resetAllState(): void { // 1. 重置用户状态 resetUserState(); // 2. 重置其他模块状态 - // 重置路由 usePermissionStoreHook().resetRouter(); - // 清除字典缓存 useDictStoreHook().clearDictCache(); - // 清除标签视图 useTagsViewStore().delAllViews(); // 3. 清理 WebSocket 连接 cleanupWebSocket(); - console.log("[UserStore] WebSocket connections cleaned up"); - - return Promise.resolve(); } /** * 重置用户状态 + * * 仅处理用户模块内的状态 */ - function resetUserState() { - // 清除用户凭证 + function resetUserState(): void { AuthStorage.clearAuth(); - // 重置用户信息 userInfo.value = {} as UserInfo; } /** * 刷新 token */ - function refreshToken() { - const refreshToken = AuthStorage.getRefreshToken(); + async function doRefreshToken(): Promise { + const currentRefreshToken = AuthStorage.getRefreshToken(); - if (!refreshToken) { - return Promise.reject(new Error("没有有效的刷新令牌")); + if (!currentRefreshToken) { + throw new Error("没有有效的刷新令牌"); } - return new Promise((resolve, reject) => { - AuthAPI.refreshToken(refreshToken) - .then((data) => { - const { accessToken, refreshToken: newRefreshToken } = data; - // 更新令牌,保持当前记住我状态 - AuthStorage.setTokens(accessToken, newRefreshToken, AuthStorage.getRememberMe()); - resolve(); - }) - .catch((error) => { - console.log(" refreshToken 刷新失败", error); - reject(error); - }); - }); + const { accessToken, refreshToken: newRefreshToken } = + await AuthAPI.refreshToken(currentRefreshToken); + AuthStorage.setTokens(accessToken, newRefreshToken, AuthStorage.getRememberMe()); } return { userInfo, rememberMe, isLoggedIn: () => !!AuthStorage.getAccessToken(), - getUserInfo, login, logout, + getUserInfo, resetAllState, resetUserState, - refreshToken, + refreshToken: doRefreshToken, refreshTokenOnce, }; }); /** - * 在组件外部使用UserStore的钩子函数 + * 在组件外部使用 UserStore 的钩子函数 + * * @see https://pinia.vuejs.org/core-concepts/outside-component-usage.html */ export function useUserStoreHook() { diff --git a/src/utils/request.ts b/src/utils/request.ts index 63fcdc18..574b18dc 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -78,8 +78,7 @@ http.interceptors.response.use( const token = AuthStorage.getAccessToken(); if (token) { - config.headers = config.headers || ({} as any); - (config.headers as any).Authorization = `Bearer ${token}`; + config.headers.set("Authorization", `Bearer ${token}`); } return http(config); diff --git a/src/views/system/dict/dict-item.vue b/src/views/system/dict/dict-item.vue index 47d07f06..bc7f0d5d 100644 --- a/src/views/system/dict/dict-item.vue +++ b/src/views/system/dict/dict-item.vue @@ -184,7 +184,11 @@ const dialogState = reactive({ }); // 表单数据 -const formData = reactive({}); +const formData = reactive({ + sort: 1, + status: 1, + tagType: "", +}); // 标签类型选项 const tagType = ["primary", "success", "info", "warning", "danger"] as const; @@ -239,6 +243,7 @@ function handleSelectionChange(selection: DictItem[]): void { * @param row 字典项数据(编辑时传入) */ function openDialog(row?: DictItem): void { + resetForm(); dialogState.visible = true; dialogState.title = row ? "编辑字典值" : "新增字典值"; @@ -249,6 +254,17 @@ function openDialog(row?: DictItem): void { } } +function resetForm(): void { + dataFormRef.value?.clearValidate(); + formData.id = undefined; + formData.dictCode = dictCode.value; + formData.label = undefined; + formData.value = undefined; + formData.sort = 1; + formData.status = 1; + formData.tagType = ""; +} + /** * 提交表单 */ @@ -286,11 +302,7 @@ function handleSubmit(): void { function closeDialog(): void { dialogState.visible = false; dataFormRef.value?.resetFields(); - dataFormRef.value?.clearValidate(); - formData.id = undefined; - formData.sort = 1; - formData.status = 1; - formData.tagType = ""; + resetForm(); } /** diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index 70dbe308..79095613 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -162,7 +162,9 @@ const dialogState = reactive({ }); // 表单数据 -const formData = reactive({}); +const formData = reactive({ + status: 1, +}); // 验证规则 const rules: FormRules = { @@ -213,6 +215,7 @@ function handleSelectionChange(selection: DictTypeItem[]): void { * 新增按钮点击事件 */ function handleCreateClick(): void { + resetForm(); dialogState.visible = true; dialogState.title = "新增字典"; } @@ -222,6 +225,7 @@ function handleCreateClick(): void { * @param id 字典ID */ function handleEditClick(id: string): void { + resetForm(); dialogState.visible = true; dialogState.title = "修改字典"; DictAPI.getFormData(id).then((data) => { @@ -229,6 +233,15 @@ function handleEditClick(id: string): void { }); } +function resetForm(): void { + dataFormRef.value?.clearValidate(); + formData.id = undefined; + formData.name = undefined; + formData.dictCode = undefined; + formData.status = 1; + formData.remark = undefined; +} + /** * 提交表单 */ @@ -264,8 +277,7 @@ function handleSubmit(): void { function closeDialog(): void { dialogState.visible = false; dataFormRef.value?.resetFields(); - dataFormRef.value?.clearValidate(); - formData.id = undefined; + resetForm(); } /** diff --git a/vite.config.ts b/vite.config.ts index 18a0540e..6a34b70d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -97,7 +97,6 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { "axios", "@vueuse/core", "codemirror-editor-vue3", - "default-passive-events", "exceljs", "path-to-regexp", "echarts/core",