From 7e439e75460a9dba86346e89c03e21209651e11a Mon Sep 17 00:00:00 2001 From: cshaptx4869 <994774638@qq.com> Date: Wed, 14 Aug 2024 11:01:31 +0800 Subject: [PATCH 001/238] =?UTF-8?q?style:=20:lipstick:=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Sidebar/components/SidebarMixTopMenu.vue | 2 -- src/store/modules/tagsView.ts | 4 ++++ src/store/modules/user.ts | 5 ++--- src/utils/request.ts | 1 - src/views/login/index.vue | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue b/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue index 5893f155..6c431158 100644 --- a/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue +++ b/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue @@ -41,8 +41,6 @@ const appStore = useAppStore(); const permissionStore = usePermissionStore(); const router = useRouter(); -console.log("当前路由", useRoute().path); - // 避免 activeTopMenuPath 缓存被清理,从当前路由路径获取顶部菜单路径,eg. /system/user → /system const activeTopMenuPath = useRoute().path.match(/^\/[^\/]+/)?.[0] || "/"; appStore.activeTopMenu(activeTopMenuPath); diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts index a92e4fe8..53a1a05a 100644 --- a/src/store/modules/tagsView.ts +++ b/src/store/modules/tagsView.ts @@ -3,6 +3,7 @@ export const useTagsViewStore = defineStore("tagsView", () => { const cachedViews = ref([]); const router = useRouter(); const route = useRoute(); + /** * 添加已访问视图到已访问视图列表中 */ @@ -144,6 +145,7 @@ export const useTagsViewStore = defineStore("tagsView", () => { }); }); } + function delRightViews(view: TagView) { return new Promise((resolve) => { const currIndex = visitedViews.value.findIndex( @@ -209,6 +211,7 @@ export const useTagsViewStore = defineStore("tagsView", () => { } }); } + function isActive(tag: TagView) { return tag.path === route.path; } @@ -228,6 +231,7 @@ export const useTagsViewStore = defineStore("tagsView", () => { } } } + return { visitedViews, cachedViews, diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 43c92d55..4eea0408 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,8 +1,7 @@ -import AuthAPI, { LoginData } from "@/api/auth"; -import UserAPI, { UserInfo } from "@/api/user"; +import AuthAPI, { type LoginData } from "@/api/auth"; +import UserAPI, { type UserInfo } from "@/api/user"; import { resetRouter } from "@/router"; import { store } from "@/store"; - import { TOKEN_KEY } from "@/enums/CacheEnum"; export const useUserStore = defineStore("user", () => { diff --git a/src/utils/request.ts b/src/utils/request.ts index 407af7b0..3f89b54d 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -9,7 +9,6 @@ const service = axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API, timeout: 50000, headers: { "Content-Type": "application/json;charset=utf-8" }, - paramsSerializer: (params) => { return qs.stringify(params); }, diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 4ebe87c3..e2dd4699 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -120,7 +120,7 @@ import { LocationQuery, useRoute } from "vue-router"; // 内部依赖 import { useSettingsStore, useUserStore } from "@/store"; -import AuthAPI, { LoginData } from "@/api/auth"; +import AuthAPI, { type LoginData } from "@/api/auth"; import router from "@/router"; import defaultSettings from "@/settings"; import { ThemeEnum } from "@/enums/ThemeEnum"; @@ -158,7 +158,7 @@ const loginData = ref({ password: "123456", captchaKey: "", captchaCode: "", -} as LoginData); +}); const loginRules = computed(() => { return { From cd49a57aed8660478f56215fe389c61fa8594268 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 16 Aug 2024 07:37:37 +0800 Subject: [PATCH 002/238] =?UTF-8?q?build:=20:package:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20npm=20=E5=8C=85=EF=BC=8C=E4=BF=AE=E5=A4=8D=20mock=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=AF=BC=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 0a569ce4..d78c8cb7 100644 --- a/package.json +++ b/package.json @@ -45,39 +45,39 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", - "@vueuse/core": "^10.11.0", + "@vueuse/core": "^10.11.1", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "5.1.10", "animate.css": "^4.1.1", - "axios": "^1.7.3", + "axios": "^1.7.4", "codemirror": "^5.65.17", "codemirror-editor-vue3": "^2.7.0", "color": "^4.2.3", "echarts": "^5.5.1", - "element-plus": "^2.7.8", + "element-plus": "^2.8.0", "exceljs": "^4.4.0", "lodash-es": "^4.17.21", "net": "^1.0.2", "nprogress": "^0.2.0", "path-browserify": "^1.0.1", "path-to-regexp": "^6.2.2", - "pinia": "^2.2.0", + "pinia": "^2.2.2", "qs": "^6.13.0", "sockjs-client": "1.6.1", "sortablejs": "^1.15.2", "stompjs": "^2.3.3", - "vue": "^3.4.35", + "vue": "^3.4.38", "vue-i18n": "9.9.1", - "vue-router": "^4.4.2" + "vue-router": "^4.4.3" }, "devDependencies": { "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.3", - "@iconify-json/ep": "^1.1.15", + "@iconify-json/ep": "^1.1.16", "@types/codemirror": "^5.60.15", "@types/color": "^3.0.6", "@types/lodash": "^4.17.7", - "@types/node": "^20.14.14", + "@types/node": "^20.14.15", "@types/nprogress": "^0.2.3", "@types/path-browserify": "^1.0.2", "@types/qs": "^6.9.15", @@ -98,28 +98,28 @@ "eslint-plugin-vue": "^9.27.0", "fast-glob": "^3.3.2", "husky": "^9.1.4", - "lint-staged": "^15.2.8", - "postcss": "^8.4.40", + "lint-staged": "^15.2.9", + "postcss": "^8.4.41", "postcss-html": "^1.7.0", "postcss-scss": "^4.0.9", "prettier": "^3.3.3", "sass": "^1.77.8", - "stylelint": "^16.8.1", + "stylelint": "^16.8.2", "stylelint-config-html": "^1.1.0", "stylelint-config-recess-order": "^4.6.0", "stylelint-config-recommended-scss": "^14.1.0", "stylelint-config-recommended-vue": "^1.5.0", "stylelint-config-standard": "^36.0.1", - "terser": "^5.31.3", + "terser": "^5.31.6", "typescript": "^5.5.4", "unocss": "^0.58.9", "unplugin-auto-import": "^0.17.8", "unplugin-icons": "^0.18.5", "unplugin-vue-components": "^0.26.0", - "vite": "^5.3.5", - "vite-plugin-mock-dev-server": "^1.6.1", + "vite": "^5.4.1", + "vite-plugin-mock-dev-server": "^1.7.1", "vite-plugin-svg-icons": "^2.0.1", - "vite-plugin-vue-devtools": "^7.3.7", + "vite-plugin-vue-devtools": "^7.3.8", "vue-tsc": "^2.0.29" }, "repository": "https://gitee.com/youlaiorg/vue3-element-admin.git", @@ -127,5 +127,6 @@ "license": "MIT", "engines": { "node": ">=18.0.0" - } + }, + "packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd" } From bf63a20fb1977fa1231569a0d824c38591166901 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Tue, 20 Aug 2024 00:06:36 +0800 Subject: [PATCH 003/238] =?UTF-8?q?refactor:=20:recycle:=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/search.svg | 2 +- src/components/Upload/ImageUpload.vue | 1 - src/layout/components/NavBar/components/NavbarAction.vue | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg index 0cb0f832..2312daf9 100644 --- a/src/assets/icons/search.svg +++ b/src/assets/icons/search.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/components/Upload/ImageUpload.vue b/src/components/Upload/ImageUpload.vue index 11f59b3f..f2bbf349 100644 --- a/src/components/Upload/ImageUpload.vue +++ b/src/components/Upload/ImageUpload.vue @@ -47,7 +47,6 @@ From b2da5ff4c9472134c6755ef87c839fd1cca28d32 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 26 Aug 2024 00:16:34 +0800 Subject: [PATCH 017/238] =?UTF-8?q?fix:=20:bug:=20=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=95=B0=E6=8D=AE=E6=94=BE=E9=94=99=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/dashboard/index.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 142c3a35..734800cd 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -48,12 +48,12 @@ 在线用户 - {{ onlineUserCount }} + -
- 1 + {{ onlineUserCount }}
Date: Tue, 27 Aug 2024 18:11:34 +0800 Subject: [PATCH 018/238] =?UTF-8?q?feat:=20websocket=E7=9A=84=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=89=8D=E7=AB=AF=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit websocket的通知部分前端代码. --- src/api/notice-status.ts | 73 +++ src/api/notice.ts | 141 ++++++ src/enums/MessageTypeEnum.ts | 4 +- .../NavBar/components/NavbarAction.vue | 59 ++- src/views/system/notice-status/index.vue | 249 +++++++++ src/views/system/notice/index.vue | 478 ++++++++++++++++++ 6 files changed, 1000 insertions(+), 4 deletions(-) create mode 100644 src/api/notice-status.ts create mode 100644 src/api/notice.ts create mode 100644 src/views/system/notice-status/index.vue create mode 100644 src/views/system/notice/index.vue diff --git a/src/api/notice-status.ts b/src/api/notice-status.ts new file mode 100644 index 00000000..03433c37 --- /dev/null +++ b/src/api/notice-status.ts @@ -0,0 +1,73 @@ +import request from "@/utils/request"; + +const NOTICESTATUS_BASE_URL = "/api/v1/noticeStatuss"; + +class NoticeStatusAPI { + /** 获取用户公告状态分页数据 */ + static getPage(queryParams?: NoticeStatusPageQuery) { + return request>({ + url: `${NOTICESTATUS_BASE_URL}/page`, + method: "get", + params: queryParams, + }); + } + + /** + * 获取用户公告状态表单数据 + * + * @param id NoticeStatusID + * @returns NoticeStatus表单数据 + */ + static getFormData(id: number) { + return request({ + url: `${NOTICESTATUS_BASE_URL}/${id}/form`, + method: "get", + }); + } + + /** 添加用户公告状态*/ + static add(data: NoticeStatusForm) { + return request({ + url: `${NOTICESTATUS_BASE_URL}`, + method: "post", + data: data, + }); + } + + /** + * 更新用户公告状态 + * + * @param id NoticeStatusID + * @param data NoticeStatus表单数据 + */ + static update(id: number, data: NoticeStatusForm) { + return request({ + url: `${NOTICESTATUS_BASE_URL}/${id}`, + method: "put", + data: data, + }); + } + + /** + * 批量删除用户公告状态,多个以英文逗号(,)分割 + * + * @param ids 用户公告状态ID字符串,多个以英文逗号(,)分割 + */ + static deleteByIds(ids: string) { + return request({ + url: `${NOTICESTATUS_BASE_URL}/${ids}`, + method: "delete", + }); + } +} + +export default NoticeStatusAPI; + +/** 用户公告状态分页查询参数 */ +export interface NoticeStatusPageQuery extends PageQuery {} + +/** 用户公告状态表单对象 */ +export interface NoticeStatusForm {} + +/** 用户公告状态分页对象 */ +export interface NoticeStatusPageVO {} diff --git a/src/api/notice.ts b/src/api/notice.ts new file mode 100644 index 00000000..cb73bff0 --- /dev/null +++ b/src/api/notice.ts @@ -0,0 +1,141 @@ +import request from "@/utils/request"; + +const NOTICE_BASE_URL = "/api/v1/notices"; + +class NoticeAPI { + /** 获取通知公告分页数据 */ + static getPage(queryParams?: NoticePageQuery) { + return request>({ + url: `${NOTICE_BASE_URL}/page`, + method: "get", + params: queryParams, + }); + } + + /** + * 获取通知公告表单数据 + * + * @param id NoticeID + * @returns Notice表单数据 + */ + static getFormData(id: number) { + return request({ + url: `${NOTICE_BASE_URL}/${id}/form`, + method: "get", + }); + } + + /** 添加通知公告*/ + static add(data: NoticeForm) { + return request({ + url: `${NOTICE_BASE_URL}`, + method: "post", + data: data, + }); + } + + /** + * 更新通知公告 + * + * @param id NoticeID + * @param data Notice表单数据 + */ + static update(id: number, data: NoticeForm) { + return request({ + url: `${NOTICE_BASE_URL}/${id}`, + method: "put", + data: data, + }); + } + + /** + * 批量删除通知公告,多个以英文逗号(,)分割 + * + * @param ids 通知公告ID字符串,多个以英文逗号(,)分割 + */ + static deleteByIds(ids: string) { + return request({ + url: `${NOTICE_BASE_URL}/${ids}`, + method: "delete", + }); + } +} + +export default NoticeAPI; + +/** 通知公告分页查询参数 */ +export interface NoticePageQuery extends PageQuery { + id?: bigint; + /** 通知标题 */ + title?: string; + /** 通知内容 */ + content?: string; + /** 通知类型 */ + noticeType?: number; + /** 发布人 */ + releaseBy?: bigint; + /** 优先级(0-低 1-中 2-高) */ + priority?: number; + /** 目标类型(0-全体 1-指定) */ + tarType?: number; + /** 发布状态(0-未发布 1已发布 2已撤回) */ + sendStatus?: number; + /** 发布时间 */ + sendTime?: [string, string]; + /** 撤回时间 */ + recallTime?: [string, string]; + /** 创建时间 */ + createTime?: Date; + /** 更新时间 */ + updateTime?: Date; +} + +/** 通知公告表单对象 */ +export interface NoticeForm { + id?: bigint; + /** 通知标题 */ + title?: string; + /** 通知内容 */ + content?: string; + /** 通知类型 */ + noticeType?: number; + /** 发布人 */ + releaseBy?: bigint; + /** 优先级(0-低 1-中 2-高) */ + priority?: number; + /** 目标类型(0-全体 1-指定) */ + tarType?: number; + /** 发布状态(0-未发布 1已发布 2已撤回) */ + sendStatus?: number; + /** 发布时间 */ + sendTime?: Date; + /** 撤回时间 */ + recallTime?: Date; +} + +/** 通知公告分页对象 */ +export interface NoticePageVO { + id?: bigint; + /** 通知标题 */ + title?: string; + /** 通知内容 */ + content?: string; + /** 通知类型 */ + noticeType?: number; + /** 发布人 */ + releaseBy?: bigint; + /** 优先级(0-低 1-中 2-高) */ + priority?: number; + /** 目标类型(0-全体 1-指定) */ + tarType?: number; + /** 发布状态(0-未发布 1已发布 2已撤回) */ + sendStatus?: number; + /** 发布时间 */ + sendTime?: Date; + /** 撤回时间 */ + recallTime?: Date; + /** 创建时间 */ + createTime?: Date; + /** 更新时间 */ + updateTime?: Date; +} diff --git a/src/enums/MessageTypeEnum.ts b/src/enums/MessageTypeEnum.ts index 42a6fb94..5dbefb41 100644 --- a/src/enums/MessageTypeEnum.ts +++ b/src/enums/MessageTypeEnum.ts @@ -10,6 +10,6 @@ export const enum MessageTypeEnum { export const MessageTypeLabels = { [MessageTypeEnum.MESSAGE]: "消息", - [MessageTypeEnum.NOTICE]: "通知", - [MessageTypeEnum.TODO]: "待办", + // [MessageTypeEnum.NOTICE]: "通知", + // [MessageTypeEnum.TODO]: "待办", }; diff --git a/src/layout/components/NavBar/components/NavbarAction.vue b/src/layout/components/NavBar/components/NavbarAction.vue index f1b79e2d..3f6a4273 100644 --- a/src/layout/components/NavBar/components/NavbarAction.vue +++ b/src/layout/components/NavBar/components/NavbarAction.vue @@ -55,7 +55,9 @@
查看更多 - + + + 全部已读 @@ -114,6 +116,8 @@ import { import defaultSettings from "@/settings"; import { DeviceEnum } from "@/enums/DeviceEnum"; import { MessageTypeEnum, MessageTypeLabels } from "@/enums/MessageTypeEnum"; +import { Client } from "@stomp/stompjs"; +import { TOKEN_KEY } from "@/enums/CacheEnum"; const appStore = useAppStore(); const tagsViewStore = useTagsViewStore(); @@ -122,7 +126,8 @@ const settingStore = useSettingsStore(); const route = useRoute(); const router = useRouter(); - +const isConnected = ref(false); +const socketEndpoint = ref(import.meta.env.VITE_APP_WS_ENDPOINT); const isMobile = computed(() => appStore.device === DeviceEnum.MOBILE); const { isFullscreen, toggle } = useFullscreen(); @@ -192,6 +197,56 @@ function logout() { }); }); } + +let stompClient: Client; + +function connectWebSocket() { + stompClient = new Client({ + brokerURL: socketEndpoint.value, + connectHeaders: { + Authorization: localStorage.getItem(TOKEN_KEY) || "", + }, + debug: (str) => { + console.log(str); + }, + onConnect: () => { + console.log("连接成功"); + isConnected.value = true; + messages.value.push({ + sender: "Server", + content: "Websocket 已连接", + type: "tip", + }); + // 订阅 /topic/chat 主题 + stompClient.subscribe("/topic/chat", (res) => { + debugger; + console.log("收到消息:" + res.body); + // messages.value.push({ + // sender: "Server", + // content: res.body, + // }); + }); + }, + onStompError: (frame) => { + console.error("Broker reported error: " + frame.headers["message"]); + console.error("Additional details: " + frame.body); + }, + onDisconnect: () => { + isConnected.value = false; + messages.value.push({ + sender: "Server", + content: "Websocket 已断开", + type: "tip", + }); + }, + }); + + stompClient.activate(); +} + +onMounted(() => { + connectWebSocket(); +}); From d0f31715c415f5e92c46409581ca2570764b6159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Mon, 2 Sep 2024 16:25:00 +0800 Subject: [PATCH 030/238] =?UTF-8?q?wip:=20:construction:=20=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=85=AC=E5=91=8A=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通知公告临时提交 --- .../NavBar/components/NavbarAction.vue | 33 +++---------------- src/views/system/notice/index.vue | 4 +-- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/src/layout/components/NavBar/components/NavbarAction.vue b/src/layout/components/NavBar/components/NavbarAction.vue index def658a2..3ac541a7 100644 --- a/src/layout/components/NavBar/components/NavbarAction.vue +++ b/src/layout/components/NavBar/components/NavbarAction.vue @@ -201,6 +201,7 @@ function logout() { let stompClient: Client; function connectWebSocket() { + console.log("连接消息ws的url:" + socketEndpoint.value); stompClient = new Client({ brokerURL: socketEndpoint.value, connectHeaders: { @@ -210,32 +211,11 @@ function connectWebSocket() { console.log(str); }, onConnect: () => { - console.log("连接成功"); + console.log("消息ws连接成功"); isConnected.value = true; - // messages.value.push({ - // sender: "Server", - // content: "Websocket 已连接", - // type: "tip", - // }); - // 订阅 /topic/chat 主题 - while (messages.value.length > 3) { - messages.value.shift(); - } - stompClient.subscribe("/topic/chat", (res) => { + + stompClient.subscribe("/user/queue/message", (res) => { console.log("收到消息:" + res.body); - const message = JSON.parse(res.body); - console.log("当前有:" + message.id); - console.log("数组已更新,强制重新渲染"); - messages.value.push({ - id: message.id, - title: message.title, - type: MessageTypeEnum.MESSAGE, - }); - while (messages.value.length > 3) { - messages.value.shift(); - } - console.log("当前还有:" + messages.value); - nextTick(async () => {}); }); }, onStompError: (frame) => { @@ -244,11 +224,6 @@ function connectWebSocket() { }, onDisconnect: () => { isConnected.value = false; - // messages.value.push({ - // sender: "Server", - // content: "Websocket 已断开", - // type: "tip", - // }); }, }); diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue index 385d7b5f..1bc4dc3b 100644 --- a/src/views/system/notice/index.vue +++ b/src/views/system/notice/index.vue @@ -69,6 +69,7 @@ @selection-change="handleSelectionChange" > + From cba508bcc454fb5da4df49f505f1b736b079c281 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Thu, 5 Sep 2024 08:00:21 +0800 Subject: [PATCH 031/238] =?UTF-8?q?build:=20:package:=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?npm=E4=BE=9D=E8=B5=96=E5=8C=85=EF=BC=8Cvue=E6=9B=B4=E6=96=B03.5?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index c198c99a..316ad94f 100644 --- a/package.json +++ b/package.json @@ -45,16 +45,17 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", + "@stomp/stompjs": "^7.0.0", "@vueuse/core": "^10.11.1", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "5.1.10", "animate.css": "^4.1.1", - "axios": "^1.7.4", + "axios": "^1.7.7", "codemirror": "^5.65.17", "codemirror-editor-vue3": "^2.7.0", "color": "^4.2.3", "echarts": "^5.5.1", - "element-plus": "^2.8.0", + "element-plus": "^2.8.1", "exceljs": "^4.4.0", "lodash-es": "^4.17.21", "nprogress": "^0.2.0", @@ -62,45 +63,44 @@ "path-to-regexp": "^6.2.2", "pinia": "^2.2.2", "qs": "^6.13.0", - "sortablejs": "^1.15.2", - "@stomp/stompjs": "^7.0.0", - "vue": "^3.4.38", + "sortablejs": "^1.15.3", + "vue": "^3.5.1", "vue-i18n": "9.9.1", "vue-router": "^4.4.3" }, "devDependencies": { "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.3", - "@iconify-json/ep": "^1.1.16", + "@iconify-json/ep": "^1.2.0", "@types/codemirror": "^5.60.15", "@types/color": "^3.0.6", "@types/lodash": "^4.17.7", - "@types/node": "^20.14.15", + "@types/node": "^20.16.5", "@types/nprogress": "^0.2.3", - "@types/path-browserify": "^1.0.2", + "@types/path-browserify": "^1.0.3", "@types/qs": "^6.9.15", "@types/sortablejs": "^1.15.8", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", - "@vitejs/plugin-vue": "^5.1.2", + "@vitejs/plugin-vue": "^5.1.3", "@vitejs/plugin-vue-jsx": "^3.1.0", "autoprefixer": "^10.4.20", "commitizen": "^4.3.0", "cz-git": "^1.9.4", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.29.1", + "eslint-plugin-import": "^2.30.0", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-vue": "^9.27.0", + "eslint-plugin-vue": "^9.28.0", "fast-glob": "^3.3.2", - "husky": "^9.1.4", - "lint-staged": "^15.2.9", - "postcss": "^8.4.41", + "husky": "^9.1.5", + "lint-staged": "^15.2.10", + "postcss": "^8.4.45", "postcss-html": "^1.7.0", "postcss-scss": "^4.0.9", "prettier": "^3.3.3", - "sass": "^1.77.8", - "stylelint": "^16.8.2", + "sass": "^1.78.0", + "stylelint": "^16.9.0", "stylelint-config-html": "^1.1.0", "stylelint-config-recess-order": "^4.6.0", "stylelint-config-recommended-scss": "^14.1.0", @@ -112,11 +112,11 @@ "unplugin-auto-import": "^0.17.8", "unplugin-icons": "^0.18.5", "unplugin-vue-components": "^0.26.0", - "vite": "^5.4.1", + "vite": "^5.4.3", "vite-plugin-mock-dev-server": "^1.7.1", "vite-plugin-svg-icons": "^2.0.1", - "vite-plugin-vue-devtools": "^7.3.8", - "vue-tsc": "^2.0.29" + "vite-plugin-vue-devtools": "^7.4.4", + "vue-tsc": "^2.1.6" }, "repository": "https://gitee.com/youlaiorg/vue3-element-admin.git", "author": "有来开源组织", From b3a10f01528372184050155111bbb87dc9a9a0ad Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Thu, 5 Sep 2024 08:29:39 +0800 Subject: [PATCH 032/238] =?UTF-8?q?build:=20:package:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?node=E7=89=88=E6=9C=AC=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 316ad94f..d209bf11 100644 --- a/package.json +++ b/package.json @@ -118,10 +118,11 @@ "vite-plugin-vue-devtools": "^7.4.4", "vue-tsc": "^2.1.6" }, + "engines": { + "node": "^18.0.0 || ^20.7.0", + "pnpm": ">=9" + }, "repository": "https://gitee.com/youlaiorg/vue3-element-admin.git", "author": "有来开源组织", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } + "license": "MIT" } From baab1cc6a12cac96844b401aecf614a70561c00b Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Thu, 5 Sep 2024 08:30:17 +0800 Subject: [PATCH 033/238] =?UTF-8?q?refactor:=20:recycle:=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E5=BF=85=E5=A1=AB=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/generator/index.vue | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/views/generator/index.vue b/src/views/generator/index.vue index 2f823eb0..b1a6b1d2 100644 --- a/src/views/generator/index.vue +++ b/src/views/generator/index.vue @@ -97,15 +97,16 @@ v-show="active == 0" :model="genConfigFormData" :label-width="100" + :rules="genConfigFormRules" > - + - + - + - + - + ({ fieldConfigs: [], }); +const genConfigFormRules = { + tableName: [{ required: true, message: "请输入表名", trigger: "blur" }], + businessName: [{ required: true, message: "请输入业务名", trigger: "blur" }], + packageName: [{ required: true, message: "请输入包名", trigger: "blur" }], + moduleName: [{ required: true, message: "请输入模块名", trigger: "blur" }], + entityName: [{ required: true, message: "请输入实体名", trigger: "blur" }], +}; + const dialog = reactive({ visible: false, title: "", From 35a419ff8b6b2430c41f7f5284cf8ed37ba97048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Thu, 5 Sep 2024 17:10:29 +0800 Subject: [PATCH 034/238] =?UTF-8?q?wip:=20:construction:=20=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=85=AC=E5=91=8A=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通知公告临时提交 --- src/api/notice.ts | 11 ++ src/components/Notice/index.vue | 138 ++++++++++++++++++ .../NavBar/components/NavbarAction.vue | 127 +--------------- src/types/components.d.ts | 1 + 4 files changed, 151 insertions(+), 126 deletions(-) create mode 100644 src/components/Notice/index.vue diff --git a/src/api/notice.ts b/src/api/notice.ts index fd33b6e8..a395fff0 100644 --- a/src/api/notice.ts +++ b/src/api/notice.ts @@ -89,6 +89,17 @@ class NoticeAPI { method: "patch", }); } + + /** + * 获取我的通知公告n条 + * @returns 消息 + */ + static listNotice() { + return request({ + url: `${NOTICE_BASE_URL}/notice/5`, + method: "get", + }); + } } export default NoticeAPI; diff --git a/src/components/Notice/index.vue b/src/components/Notice/index.vue new file mode 100644 index 00000000..500fb6a6 --- /dev/null +++ b/src/components/Notice/index.vue @@ -0,0 +1,138 @@ + + diff --git a/src/layout/components/NavBar/components/NavbarAction.vue b/src/layout/components/NavBar/components/NavbarAction.vue index 3ac541a7..339fbb2d 100644 --- a/src/layout/components/NavBar/components/NavbarAction.vue +++ b/src/layout/components/NavBar/components/NavbarAction.vue @@ -23,49 +23,7 @@ - - -
- -
-
- -
+ @@ -115,9 +73,6 @@ import { } from "@/store"; import defaultSettings from "@/settings"; import { DeviceEnum } from "@/enums/DeviceEnum"; -import { MessageTypeEnum, MessageTypeLabels } from "@/enums/MessageTypeEnum"; -import { Client } from "@stomp/stompjs"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; const appStore = useAppStore(); const tagsViewStore = useTagsViewStore(); @@ -126,54 +81,10 @@ const settingStore = useSettingsStore(); const route = useRoute(); const router = useRouter(); -const isConnected = ref(false); -const socketEndpoint = ref(import.meta.env.VITE_APP_WS_ENDPOINT); const isMobile = computed(() => appStore.device === DeviceEnum.MOBILE); const { isFullscreen, toggle } = useFullscreen(); -const activeTab = ref(MessageTypeEnum.MESSAGE); - -const messages = ref([ - { - id: 1, - title: "系统升级通知:服务器将于今晚12点进行升级维护,请提前保存工作内容。", - type: MessageTypeEnum.MESSAGE, - }, - { - id: 2, - title: "新功能发布:我们的应用程序现在支持多语言功能。", - type: MessageTypeEnum.MESSAGE, - }, - { - id: 3, - title: "重要提醒:请定期更改您的密码以保证账户安全。", - type: MessageTypeEnum.MESSAGE, - }, - // { - // id: 4, - // title: "通知:您有一条未读的系统消息,请及时查看。", - // type: MessageTypeEnum.NOTICE, - // }, - // { - // id: 5, - // title: "新订单通知:您有一笔新的订单需要处理。", - // type: MessageTypeEnum.NOTICE, - // }, - // { - // id: 6, - // title: "审核提醒:您的审核请求已被批准。", - // type: MessageTypeEnum.NOTICE, - // }, - // { id: 7, title: "待办事项:完成用户权限设置。", type: MessageTypeEnum.TODO }, - // { id: 8, title: "待办事项:更新产品列表。", type: MessageTypeEnum.TODO }, - // { id: 9, title: "待办事项:备份数据库。", type: MessageTypeEnum.TODO }, -]); - -const getFilteredMessages = (type: MessageTypeEnum) => { - return messages.value.filter((message) => message.type === type); -}; - /** 打开个人中心 */ function handleOpenUserProfile() { router.push({ name: "Profile" }); @@ -197,42 +108,6 @@ function logout() { }); }); } - -let stompClient: Client; - -function connectWebSocket() { - console.log("连接消息ws的url:" + socketEndpoint.value); - stompClient = new Client({ - brokerURL: socketEndpoint.value, - connectHeaders: { - Authorization: localStorage.getItem(TOKEN_KEY) || "", - }, - debug: (str) => { - console.log(str); - }, - onConnect: () => { - console.log("消息ws连接成功"); - isConnected.value = true; - - stompClient.subscribe("/user/queue/message", (res) => { - console.log("收到消息:" + res.body); - }); - }, - onStompError: (frame) => { - console.error("Broker reported error: " + frame.headers["message"]); - console.error("Additional details: " + frame.body); - }, - onDisconnect: () => { - isConnected.value = false; - }, - }); - - stompClient.activate(); -} - -onMounted(() => { - connectWebSocket(); -}); diff --git a/src/enums/MessageTypeEnum.ts b/src/enums/MessageTypeEnum.ts index 5dbefb41..071f1b26 100644 --- a/src/enums/MessageTypeEnum.ts +++ b/src/enums/MessageTypeEnum.ts @@ -1,7 +1,7 @@ /* 消息类型枚举 */ export const enum MessageTypeEnum { /* 消息 */ - MESSAGE = "MESSAGE", + MESSAGE = "SYSTEM_MESSAGE", /* 通知 */ NOTICE = "NOTICE", /* 待办 */ diff --git a/src/types/components.d.ts b/src/types/components.d.ts index cd71a592..f947408e 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -75,6 +75,7 @@ declare module "vue" { LangSelect: (typeof import("./../components/LangSelect/index.vue"))["default"]; MenuSearch: (typeof import("./../components/MenuSearch/index.vue"))["default"]; Notice: (typeof import("./../components/Notice/index.vue"))["default"]; + NoticeModal: (typeof import("./../components/NoticeModal/index.vue"))["default"]; LayoutSelect: (typeof import("./../layout/components/Settings/components/LayoutSelect.vue"))["default"]; MultiUpload: (typeof import("./../components/Upload/MultiUpload.vue"))["default"]; NavBar: (typeof import("./../layout/components/NavBar/index.vue"))["default"]; diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 54c72c0a..bfa301c1 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -188,7 +188,7 @@ From 30428254faed65d77b2658827978e19310ec7987 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 9 Sep 2024 00:45:36 +0800 Subject: [PATCH 043/238] =?UTF-8?q?refactor:=20:recycle:=20=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E5=8F=82=E6=95=B0=E6=B7=BB=E5=8A=A0=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/menu/index.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index cacc4adb..7c9aedbd 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -318,7 +318,7 @@ = @@ -326,7 +326,7 @@ Date: Mon, 9 Sep 2024 00:46:17 +0800 Subject: [PATCH 044/238] =?UTF-8?q?refactor:=20:recycle:=20=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=B8=AD=E5=BF=83=E5=9B=BE=E6=A0=87=E5=90=88=E9=80=82?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/profile/index.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/profile/index.vue b/src/views/profile/index.vue index 6152e89f..21d8e768 100644 --- a/src/views/profile/index.vue +++ b/src/views/profile/index.vue @@ -67,14 +67,14 @@ {{ userProfile.deptName }} {{ userProfile.roleNames }} @@ -82,7 +82,7 @@ {{ userProfile.createTime }} From 3341abef64c39fed078d5d71c6ad6ecc3e57f4ce Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 9 Sep 2024 00:47:46 +0800 Subject: [PATCH 045/238] =?UTF-8?q?refactor:=20:recycle:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=A1=B5=E9=9D=A2=E8=83=8C=E6=99=AF=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/variables.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/variables.scss b/src/styles/variables.scss index f4e44145..7948a7c6 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -15,6 +15,10 @@ "info": ( "base": #a9aeb8, ), + ), + + $bg-color: ( + "page": #f5f8fd, ) ); From 248b86fe3c07321d840165f9a097f8030a638682 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 9 Sep 2024 00:48:11 +0800 Subject: [PATCH 046/238] =?UTF-8?q?refactor:=20:recycle:=20=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/gitee.svg | 1 + src/assets/icons/qq.svg | 1 + src/assets/icons/wechat.svg | 1 + src/assets/images/login-image.svg | 1 + src/lang/package/en.ts | 3 + src/lang/package/zh-cn.ts | 3 + src/styles/login.scss | 72 +++++--- src/views/login/index.vue | 262 +++++++++++++++++++----------- 8 files changed, 227 insertions(+), 117 deletions(-) create mode 100644 src/assets/icons/gitee.svg create mode 100644 src/assets/icons/qq.svg create mode 100644 src/assets/icons/wechat.svg create mode 100644 src/assets/images/login-image.svg diff --git a/src/assets/icons/gitee.svg b/src/assets/icons/gitee.svg new file mode 100644 index 00000000..c799c2f3 --- /dev/null +++ b/src/assets/icons/gitee.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/qq.svg b/src/assets/icons/qq.svg new file mode 100644 index 00000000..a59086b4 --- /dev/null +++ b/src/assets/icons/qq.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/wechat.svg b/src/assets/icons/wechat.svg new file mode 100644 index 00000000..2fc58038 --- /dev/null +++ b/src/assets/icons/wechat.svg @@ -0,0 +1 @@ + diff --git a/src/assets/images/login-image.svg b/src/assets/images/login-image.svg new file mode 100644 index 00000000..f42e56b6 --- /dev/null +++ b/src/assets/images/login-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts index 7eac43b3..77e9e4f9 100644 --- a/src/lang/package/en.ts +++ b/src/lang/package/en.ts @@ -11,6 +11,8 @@ export default { login: "Login", captchaCode: "Verify Code", capsLock: "Caps Lock is On", + rememberMe: "Remember Me", + forgetPassword: "Forget Password", message: { username: { required: "Please enter Username", @@ -23,6 +25,7 @@ export default { required: "Please enter Verify Code", }, }, + otherLoginMethods: "Other login methods", }, // 导航栏国际化 navbar: { diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts index 36764dc9..e8093cf1 100644 --- a/src/lang/package/zh-cn.ts +++ b/src/lang/package/zh-cn.ts @@ -11,6 +11,8 @@ export default { login: "登 录", captchaCode: "验证码", capsLock: "大写锁定已打开", + rememberMe: "记住我", + forgetPassword: "忘记密码", message: { username: { required: "请输入用户名", @@ -23,6 +25,7 @@ export default { required: "请输入验证码", }, }, + otherLoginMethods: "其他登录方式", }, // 导航栏国际化 navbar: { diff --git a/src/styles/login.scss b/src/styles/login.scss index ede34896..3f4f382c 100644 --- a/src/styles/login.scss +++ b/src/styles/login.scss @@ -8,25 +8,47 @@ background: url("@/assets/images/login-background-light.jpg") no-repeat center right; - .top-bar { - position: absolute; - top: 0; - left: 0; + .login-content { display: flex; - align-items: center; - justify-content: flex-end; width: 100%; - padding: 10px; - } + min-width: 400px; + max-width: 850px; + overflow: hidden; + background-color: #fff; + border-radius: 5px; + box-shadow: var(--el-box-shadow-light); + + @media (width <= 768px) { + flex-direction: column; + max-width: 100%; + height: 100vh; + border-radius: 0; + box-shadow: none; + } - .login-card { - width: 400px; - background: transparent; - border: none; - border-radius: 4%; + .login-image { + display: flex; + flex: 3; + align-items: center; + justify-content: center; + background: linear-gradient(60deg, #165dff, #6aa1ff); - @media (width <= 640px) { - width: 340px; + @media (width <= 768px) { + display: none; + } + } + + .login-box { + display: flex; + flex: 2; + flex-direction: column; + justify-content: center; + min-width: 400px; + padding: 30px; + + @media (width <= 768px) { + width: 100%; + } } .input-wrapper { @@ -43,13 +65,6 @@ } } - .icp-info { - position: absolute; - bottom: 4px; - font-size: 12px; - text-align: center; - } - .el-form-item { background: var(--el-input-bg-color); border: 1px solid var(--el-border-color); @@ -75,7 +90,14 @@ } } -html.dark .login-container { - background: url("@/assets/images/login-background-dark.jpg") no-repeat center - right; +html.dark { + .login-container { + background: url("@/assets/images/login-background-dark.jpg") no-repeat + center right; + + .login-content { + background: transparent; + box-shadow: var(--el-box-shadow); + } + } } diff --git a/src/views/login/index.vue b/src/views/login/index.vue index e2dd4699..5067f5fe 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -1,115 +1,181 @@ @@ -153,6 +219,12 @@ const captchaBase64 = ref(); // 登录表单ref const loginFormRef = ref(); +const logo = ref(new URL(`../../assets/logo.png`, import.meta.url).href); + +const loginImage = ref( + new URL(`../../assets/images/login-image.svg`, import.meta.url).href +); + const loginData = ref({ username: "admin", password: "123456", @@ -263,6 +335,12 @@ function checkCapslock(event: KeyboardEvent) { } } +/** 设置登录凭证 */ +const setLoginCredentials = (username: string, password: string) => { + loginData.value.username = username; + loginData.value.password = password; +}; + onMounted(() => { getCaptcha(); }); From 2155f9b7733e19821453e03e244b602634e98286 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 9 Sep 2024 00:49:08 +0800 Subject: [PATCH 047/238] =?UTF-8?q?build:=20:package:=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=89=88=E6=9C=AC=E5=8F=B72.15.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 542ece1c..2c4d8817 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue3-element-admin", - "version": "2.14.0", + "version": "2.15.0", "private": true, "type": "module", "scripts": { From f8efb238c57e457963fd50a6f2c6c21358fb5e22 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Mon, 9 Sep 2024 21:25:39 +0800 Subject: [PATCH 048/238] =?UTF-8?q?build:=20:package:=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?codemirror=E7=89=88=E6=9C=AC=E8=87=B32.7.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/main.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2c4d8817..4f82fd25 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "animate.css": "^4.1.1", "axios": "^1.7.7", "codemirror": "^5.65.17", - "codemirror-editor-vue3": "^2.7.0", + "codemirror-editor-vue3": "^2.7.1", "echarts": "^5.5.1", "element-plus": "^2.8.1", "exceljs": "^4.4.0", diff --git a/src/main.ts b/src/main.ts index ff813587..4ea367dc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,10 +10,10 @@ import "element-plus/theme-chalk/dark/css-vars.css"; import "@/styles/index.scss"; import "uno.css"; import "animate.css"; -import { InstallCodemirro } from "codemirror-editor-vue3"; +import { InstallCodeMirror } from "codemirror-editor-vue3"; const app = createApp(App); // 注册插件 app.use(setupPlugins); -app.use(InstallCodemirro); +app.use(InstallCodeMirror); app.mount("#app"); From 13eb4e1d7b690bdb2fc0774d4933684ed1220fb1 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Thu, 12 Sep 2024 07:53:09 +0800 Subject: [PATCH 049/238] =?UTF-8?q?docs:=20:memo:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=B8=BB=E6=8A=80=E6=9C=AF=E6=A0=88=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 57c992aa..502747d2 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ vue3-element-admin

vue3-element-admin

- - - + + + From f34df2bb400d9fb85f73680ccfc3d1aa824e79a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Thu, 12 Sep 2024 18:10:38 +0800 Subject: [PATCH 050/238] =?UTF-8?q?wip:=20:construction:=20=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=85=AC=E5=91=8A=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通知公告临时提交 --- src/api/notice.ts | 8 ++ src/components/Notice/index.vue | 12 ++- src/views/notice/index.vue | 170 +------------------------------- 3 files changed, 19 insertions(+), 171 deletions(-) diff --git a/src/api/notice.ts b/src/api/notice.ts index 6ccd44b0..f9ffb366 100644 --- a/src/api/notice.ts +++ b/src/api/notice.ts @@ -132,6 +132,14 @@ class NoticeAPI { method: "PATCH", }); } + + static getMyNoticePage(queryParams?: NoticePageQuery) { + return request>({ + url: `${NOTICE_BASE_URL}/my/page`, + method: "get", + params: queryParams, + }); + } } export default NoticeAPI; diff --git a/src/components/Notice/index.vue b/src/components/Notice/index.vue index aa3d68be..7247e5d4 100644 --- a/src/components/Notice/index.vue +++ b/src/components/Notice/index.vue @@ -70,10 +70,12 @@ import NoticeModal from "@/components/NoticeModal/index.vue"; const activeTab = ref(MessageTypeEnum.MESSAGE); const messages = ref([]); const noticeModalRef = ref(null); -const offset = ref<["number", "number"]>([-15, 15] as ["number", "number"]); +const offset = ref([-15, 15]); const getFilteredMessages = (type: MessageTypeEnum) => { - return messages.value.filter((message) => message.type === type); + return messages.value.filter( + (message: { type: MessageTypeEnum }) => message.type === type + ); }; /**' @@ -91,7 +93,7 @@ function connectWebSocket() { //获取到id let id = content.id; //确认messages里面是否有这个id - let index = messages.value.findIndex((item) => item.id === id); + let index = messages.value.findIndex((item: any) => item.id === id); if (index < 0) { let messageContent = { id: id, @@ -120,7 +122,9 @@ function listNotice() { * @param id */ function readNotice(id: number) { - let index = messages.value.findIndex((item) => item.id === id); + let index = messages.value.findIndex( + (item: { id: number }) => item.id === id + ); if (index >= 0) { messages.value.splice(index, 1); } diff --git a/src/views/notice/index.vue b/src/views/notice/index.vue index a0f7b12a..5957d303 100644 --- a/src/views/notice/index.vue +++ b/src/views/notice/index.vue @@ -10,28 +10,6 @@ @keyup.enter="handleQuery()" />
- - - - - - - - - - @@ -89,7 +67,7 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 全体 - 指定 - - - - - - - - - - - 未发布 - 已发布 - 已撤回 - - - - - - - - - - -
@@ -250,7 +111,7 @@ import NoticeAPI, { } from "@/api/notice"; const queryFormRef = ref(ElForm); -const dataFormRef = ref(ElForm); +const pageData = ref([]); const loading = ref(false); const ids = ref([]); @@ -261,35 +122,10 @@ const queryParams = reactive({ pageSize: 10, }); -// 通知公告表格数据 -const pageData = ref([]); - -// 弹窗 -const dialog = reactive({ - title: "", - visible: false, -}); - -// 通知公告表单数据 -const formData = reactive({ - sendStatus: 0, // 默认状态为未发布 - priority: 0, // 默认优先级为低 - tarType: 0, // 默认目标类型为全体 -}); - -// 通知公告表单校验规则 -const rules = reactive({ - title: [{ required: true, message: "请输入通知标题", trigger: "blur" }], - content: [{ required: true, message: "请输入通知内容", trigger: "blur" }], - // releaseBy: [{ required: true, message: "请输入发布人", trigger: "blur" }], - sendTime: [{ required: true, message: "请输入发布时间", trigger: "blur" }], - recallTime: [{ required: true, message: "请输入撤回时间", trigger: "blur" }], -}); - /** 查询通知公告 */ function handleQuery() { loading.value = true; - NoticeAPI.getPage(queryParams) + NoticeAPI.getMyNoticePage(queryParams) .then((data) => { pageData.value = data.list; total.value = data.total; From 5572ab894217690bf02a2ee30f87012cd378f606 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 13 Sep 2024 07:35:00 +0800 Subject: [PATCH 051/238] =?UTF-8?q?docs:=20:memo:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/user.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/user.ts b/src/api/user.ts index d37eacfb..47402eb0 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -186,7 +186,7 @@ class UserAPI { }); } - /** 丙丁个人中心用户邮箱 */ + /** 绑定个人中心用户邮箱 */ static bindEmail(data: EmailBindingForm) { return request({ url: `${USER_BASE_URL}/email`, From 6f63834491f98f687787c09b213804782c60fc37 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 13 Sep 2024 21:55:11 +0800 Subject: [PATCH 052/238] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8defineMod?= =?UTF-8?q?el=E6=9B=BF=E6=8D=A2useVModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Pagination/index.vue | 30 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue index c080e602..9cbaeafa 100644 --- a/src/components/Pagination/index.vue +++ b/src/components/Pagination/index.vue @@ -16,20 +16,12 @@ From f09973ddb7ff806f7c469a7a683356967b50bf4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Sat, 14 Sep 2024 09:37:59 +0800 Subject: [PATCH 053/238] =?UTF-8?q?fix:=20:bug:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=9B=BE=E7=89=87\=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E5=88=A0=E9=99=A4=E5=A4=B1=E8=B4=A5=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复图片\文件上传之后删除失败的bug --- src/components/Upload/FileUpload.vue | 1 + src/components/Upload/ImageUpload.vue | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/components/Upload/FileUpload.vue b/src/components/Upload/FileUpload.vue index 7c8251bd..a89b948f 100644 --- a/src/components/Upload/FileUpload.vue +++ b/src/components/Upload/FileUpload.vue @@ -206,6 +206,7 @@ watch( if (newVal.length <= 0) { fileList.value = []; + valFileList.value = []; return; } diff --git a/src/components/Upload/ImageUpload.vue b/src/components/Upload/ImageUpload.vue index f2bbf349..9598764a 100644 --- a/src/components/Upload/ImageUpload.vue +++ b/src/components/Upload/ImageUpload.vue @@ -159,6 +159,8 @@ watch( if (newVal.length <= 0) { fileList.value = []; + viewFileList.value = []; + valFileList.value = []; return; } From da2aba757aee7e412387d0567f5fb8dad47a0b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Sat, 14 Sep 2024 11:06:40 +0800 Subject: [PATCH 054/238] =?UTF-8?q?feat:=20:sparkles:=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=85=AC=E5=91=8A=E5=8F=91=E9=80=81ws?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增通知公告发送ws消息 --- src/components/Notice/index.vue | 13 ++- .../Sidebar/components/SidebarMenuItem.vue | 2 +- src/views/dashboard/index.vue | 1 - src/views/notice/index.vue | 95 ++----------------- src/views/system/notice/index.vue | 24 +++-- 5 files changed, 39 insertions(+), 96 deletions(-) diff --git a/src/components/Notice/index.vue b/src/components/Notice/index.vue index 7247e5d4..a4ba322c 100644 --- a/src/components/Notice/index.vue +++ b/src/components/Notice/index.vue @@ -40,7 +40,7 @@
- + 查看更多 @@ -66,10 +66,11 @@ import { MessageTypeEnum, MessageTypeLabels } from "@/enums/MessageTypeEnum"; import NoticeAPI from "@/api/notice"; import socket from "@/api/socket"; import NoticeModal from "@/components/NoticeModal/index.vue"; +import router from "@/router"; const activeTab = ref(MessageTypeEnum.MESSAGE); const messages = ref([]); -const noticeModalRef = ref(null); +const noticeModalRef = ref(NoticeModal); const offset = ref([-15, 15]); const getFilteredMessages = (type: MessageTypeEnum) => { @@ -131,6 +132,14 @@ function readNotice(id: number) { noticeModalRef.value?.open(id); // 调用 open 方法,传入 ID } +/** + * 查看更多 + */ +function more() { + //跳转到我的消息页面 + router.push({ path: "notice/notice" }); +} + /** * 全部已读 */ diff --git a/src/layout/components/Sidebar/components/SidebarMenuItem.vue b/src/layout/components/Sidebar/components/SidebarMenuItem.vue index e45ec8d1..b742eadf 100644 --- a/src/layout/components/Sidebar/components/SidebarMenuItem.vue +++ b/src/layout/components/Sidebar/components/SidebarMenuItem.vue @@ -55,7 +55,7 @@ defineOptions({ }); import path from "path-browserify"; -import { isExternal } from "@/utils/index"; +import { isExternal } from "@/utils"; import { RouteRecordRaw } from "vue-router"; const props = defineProps({ diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index bfa301c1..f7d1ce1f 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -391,7 +391,6 @@ const getNoticeLevelTag = (type: number) => { function connectWebSocket() { WebSocketManager.getWebSocketClient("/topic/onlineUserCount", (message) => { - console.log("收到消息:", message); onlineUserCount.value = JSON.parse(message); }); } diff --git a/src/views/notice/index.vue b/src/views/notice/index.vue index 5957d303..f6c68d5e 100644 --- a/src/views/notice/index.vue +++ b/src/views/notice/index.vue @@ -29,8 +29,8 @@ v-loading="loading" :data="pageData" highlight-current-row - @selection-change="handleSelectionChange" > + @@ -95,20 +95,19 @@ @pagination="handleQuery()" /> +
From b014e82f5b4c3df454fd61d3d9572a45d22f80f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=91=E7=BF=94?= <971366405@qq.com> Date: Wed, 18 Sep 2024 11:31:46 +0800 Subject: [PATCH 058/238] =?UTF-8?q?revert:=20:rewind:=20=E5=9B=9E=E9=80=80?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=AA=8C=E8=AF=81=E7=A0=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 回退关闭验证码功能 --- src/api/auth.ts | 10 ---------- src/views/login/index.vue | 15 ++------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/api/auth.ts b/src/api/auth.ts index 1ac19be0..eb904d87 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -35,16 +35,6 @@ class AuthAPI { method: "get", }); } - - /** - * 获取验证码规则 - */ - static getCaptchaRule() { - return request({ - url: `${AUTH_BASE_URL}/captcha/unable`, - method: "get", - }); - } } export default AuthAPI; diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 1c58a41b..7222319e 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -107,7 +107,7 @@ - +
(); -// 是否关闭验证码 -const closeCaptcha = ref(false); const logo = ref(new URL(`../../assets/logo.png`, import.meta.url).href); @@ -343,17 +341,8 @@ const setLoginCredentials = (username: string, password: string) => { loginData.value.password = password; }; -function getCaptchaRule() { - AuthAPI.getCaptchaRule().then((data) => { - closeCaptcha.value = data; - if (!closeCaptcha.value) { - getCaptcha(); - } - }); -} - onMounted(() => { - getCaptchaRule(); + getCaptcha(); }); From b0a210110df9a770b370396a6eddebd7852a1fb2 Mon Sep 17 00:00:00 2001 From: Wrong <33210369+wlonghaha@users.noreply.github.com> Date: Sat, 21 Sep 2024 13:21:23 +0800 Subject: [PATCH 059/238] =?UTF-8?q?chore:=20=F0=9F=94=A8=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9SidebarLogo=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sidebar/components/SidebarLogo.vue | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/layout/components/Sidebar/components/SidebarLogo.vue b/src/layout/components/Sidebar/components/SidebarLogo.vue index 90fc081f..11f1cfb8 100644 --- a/src/layout/components/Sidebar/components/SidebarLogo.vue +++ b/src/layout/components/Sidebar/components/SidebarLogo.vue @@ -1,23 +1,19 @@ diff --git a/src/views/notice/index.vue b/src/views/notice/index.vue index f6c68d5e..4ea6cadc 100644 --- a/src/views/notice/index.vue +++ b/src/views/notice/index.vue @@ -44,7 +44,16 @@ label="通知类型" prop="noticeType" min-width="150" - /> + > + + - + + + + + + + diff --git a/src/components/NoticeModal/index.vue b/src/components/NoticeModal/index.vue deleted file mode 100644 index 2a958e03..00000000 --- a/src/components/NoticeModal/index.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - diff --git a/src/components/Upload/FileUpload.vue b/src/components/Upload/FileUpload.vue index a89b948f..acade164 100644 --- a/src/components/Upload/FileUpload.vue +++ b/src/components/Upload/FileUpload.vue @@ -65,11 +65,11 @@ import { UploadProgressEvent, UploadFiles, } from "element-plus"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; + import FileAPI from "@/api/file"; -import { ref, watch } from "vue"; -import { ElMessage } from "element-plus"; +import { getToken } from "@/utils/auth"; import { ResultEnum } from "@/enums/ResultEnum"; + const emit = defineEmits(["update:modelValue"]); const props = defineProps({ /** @@ -149,7 +149,7 @@ const props = defineProps({ type: Object, default: () => { return { - Authorization: localStorage.getItem(TOKEN_KEY), + Authorization: getToken(), }; }, }, diff --git a/src/components/Upload/ImageUpload.vue b/src/components/Upload/ImageUpload.vue index 9598764a..457897eb 100644 --- a/src/components/Upload/ImageUpload.vue +++ b/src/components/Upload/ImageUpload.vue @@ -52,7 +52,7 @@ import { UploadProps, } from "element-plus"; import FileAPI from "@/api/file"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; +import { getToken } from "@/utils/auth"; import { ResultEnum } from "@/enums/ResultEnum"; const emit = defineEmits(["update:modelValue"]); @@ -79,7 +79,7 @@ const props = defineProps({ type: Object, default: () => { return { - Authorization: localStorage.getItem(TOKEN_KEY), + Authorization: getToken(), }; }, }, diff --git a/src/enums/CacheEnum.ts b/src/enums/CacheEnum.ts deleted file mode 100644 index f3c434ba..00000000 --- a/src/enums/CacheEnum.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 令牌缓存Key - */ -export const TOKEN_KEY = "accessToken"; diff --git a/src/layout/components/NavBar/components/NavbarAction.vue b/src/layout/components/NavBar/components/NavbarAction.vue index c107c5d9..2c0022c6 100644 --- a/src/layout/components/NavBar/components/NavbarAction.vue +++ b/src/layout/components/NavBar/components/NavbarAction.vue @@ -23,7 +23,7 @@ - + diff --git a/src/plugins/permission.ts b/src/plugins/permission.ts index f658a7ef..73376344 100644 --- a/src/plugins/permission.ts +++ b/src/plugins/permission.ts @@ -5,7 +5,8 @@ import { } from "vue-router"; import NProgress from "@/utils/nprogress"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; +import { isLogin } from "@/utils/auth"; + import router from "@/router"; import { usePermissionStore, useUserStore } from "@/store"; @@ -15,9 +16,7 @@ export function setupPermission() { router.beforeEach(async (to, from, next) => { NProgress.start(); - const hasToken = localStorage.getItem(TOKEN_KEY); - - if (hasToken) { + if (isLogin()) { if (to.path === "/login") { // 如果已登录,跳转到首页 next({ path: "/" }); diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 40bf52f2..c8aa2ce3 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -2,7 +2,7 @@ import AuthAPI, { type LoginData } from "@/api/auth"; import UserAPI, { type UserInfo } from "@/api/user"; import { resetRouter } from "@/router"; import { store } from "@/store"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; +import { setToken, removeToken } from "@/utils/auth"; export const useUserStore = defineStore("user", () => { const user = ref({ @@ -21,7 +21,7 @@ export const useUserStore = defineStore("user", () => { AuthAPI.login(loginData) .then((data) => { const { tokenType, accessToken } = data; - localStorage.setItem(TOKEN_KEY, tokenType + " " + accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx + setToken(tokenType + " " + accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx resolve(); }) .catch((error) => { @@ -57,7 +57,6 @@ export const useUserStore = defineStore("user", () => { return new Promise((resolve, reject) => { AuthAPI.logout() .then(() => { - localStorage.setItem(TOKEN_KEY, ""); location.reload(); // 清空路由 resolve(); }) diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 00000000..5268f1f4 --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,19 @@ +const TOKEN_KEY = "v3-admin-token"; + +function getToken(): string { + return localStorage.getItem(TOKEN_KEY) || ""; +} + +function setToken(token: string) { + return localStorage.setItem(TOKEN_KEY, token); +} + +function removeToken() { + return localStorage.removeItem(TOKEN_KEY); +} + +function isLogin(): boolean { + return !!getToken(); +} + +export { getToken, setToken, removeToken, isLogin }; diff --git a/src/utils/request.ts b/src/utils/request.ts index 3f89b54d..f925f5b8 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,7 +1,7 @@ import axios, { InternalAxiosRequestConfig, AxiosResponse } from "axios"; import { useUserStoreHook } from "@/store/modules/user"; import { ResultEnum } from "@/enums/ResultEnum"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; +import { getToken } from "@/utils/auth"; import qs from "qs"; // 创建 axios 实例 @@ -17,7 +17,7 @@ const service = axios.create({ // 请求拦截器 service.interceptors.request.use( (config: InternalAxiosRequestConfig) => { - const accessToken = localStorage.getItem(TOKEN_KEY); + const accessToken = getToken(); if (accessToken) { config.headers.Authorization = accessToken; } diff --git a/src/utils/socket.ts b/src/utils/socket.ts new file mode 100644 index 00000000..fa6a87e4 --- /dev/null +++ b/src/utils/socket.ts @@ -0,0 +1,150 @@ +import { Client } from "@stomp/stompjs"; +import { getToken } from "@/utils/auth"; + +const MAX_RECONNECT_ATTEMPTS = 3; // 最大重连尝试次数 +const RECONNECT_DELAY_MS = 5000; // 重连延迟时间(毫秒) +const HEARTBEAT_INTERVAL_MS = 30000; // 心跳间隔时间(毫秒) + +class WebSocketManager { + private clients: Map = new Map(); // 保存所有 WebSocket 客户端 + private reconnectAttempts: Map = new Map(); // 记录各地址的重连次数 + private messageHandlers: Map void)[]> = + new Map(); // 保存订阅的消息回调 + + constructor() {} + + /** + * 获取已有的 WebSocket 客户端 + * + * @param endpoint WebSocket 连接地址 + * @returns WebSocket Client 实例或 undefined + */ + public getClient(endpoint: string): Client | undefined { + return this.clients.get(endpoint); + } + + /** + * 获取 WebSocket 客户端,如果已存在则返回已有客户端,否则创建新的客户端 + * + * @param endpoint WebSocket 连接地址 + * @param onMessage 收到消息时的回调 + * @param onError 出现错误时的回调 + * @returns WebSocket Client 实例 + */ + public getOrCreateClient( + endpoint: string, + onMessage: (message: string) => void, + onError?: (error: any) => void + ): Client { + let client = this.getClient(endpoint); + if (client) { + // 如果该地址已有连接,直接添加消息回调 + this.messageHandlers.get(endpoint)?.push(onMessage); + } else { + // 否则创建新客户端 + client = this.createClient(endpoint, onMessage, onError); + this.clients.set(endpoint, client); + this.messageHandlers.set(endpoint, [onMessage]); + } + return client; + } + + /** + * 创建 WebSocket 客户端 + * + * @param endpoint WebSocket 连接地址 + * @param onMessage 收到消息时的回调 + * @param onError 出现错误时的回调 + * @returns WebSocket Client 实例 + * @private + */ + private createClient( + endpoint: string, + onMessage: (message: string) => void, + onError?: (error: any) => void + ): Client { + const client = new Client({ + brokerURL: endpoint, // 使用传入的 endpoint 动态设置连接地址 + connectHeaders: { + Authorization: getToken(), + }, + heartbeatIncoming: HEARTBEAT_INTERVAL_MS, + heartbeatOutgoing: HEARTBEAT_INTERVAL_MS, + onConnect: () => { + console.log(`已连接到 ${endpoint}`); + client.subscribe(endpoint, (message) => { + onMessage(message.body); // 收到消息时调用回调 + }); + }, + onStompError: (frame) => { + console.error( + `连接错误: ${endpoint}, 错误消息: ${frame.headers["message"]}` + ); + console.error(`错误详情: ${frame.body}`); + if (onError) { + onError(frame); + } + this.handleReconnect(endpoint); // 出现错误时处理重连 + }, + onDisconnect: () => { + console.log(`已断开连接: ${endpoint}`); + this.handleReconnect(endpoint); // 断开时处理重连 + }, + }); + + client.activate(); + return client; + } + + /** + * 处理 WebSocket 重连 + * + * @param endpoint WebSocket 连接地址 + * @private + */ + private handleReconnect(endpoint: string) { + const attemptCount = this.reconnectAttempts.get(endpoint) || 0; + + if (this.clients.has(endpoint)) { + const client = this.clients.get(endpoint); + if (client && client.connected) { + client.deactivate(); // 主动断开已有连接 + } + } + + // 重连次数未达到最大次数时继续重连 + if (attemptCount < MAX_RECONNECT_ATTEMPTS) { + this.reconnectAttempts.set(endpoint, attemptCount + 1); + console.log( + `尝试重连 (${attemptCount + 1}/${MAX_RECONNECT_ATTEMPTS}): ${endpoint}` + ); + setTimeout(() => { + const originalOnMessage = this.messageHandlers.get(endpoint) || []; + this.getOrCreateClient( + endpoint, + (message) => originalOnMessage.forEach((handler) => handler(message)), + () => {} + ); + }, RECONNECT_DELAY_MS); + } else { + console.error(`达到最大重连次数: ${endpoint}`); + this.reconnectAttempts.delete(endpoint); // 超过最大重连次数后清除重连记录 + } + } + + /** + * 断开所有 WebSocket 连接 + * + * @param delay 延迟断开时间(毫秒),默认为 0 + */ + public disconnectAll(delay: number = 0) { + this.clients.forEach((client, endpoint) => { + console.log(`断开 WebSocket 连接: ${endpoint}`); + setTimeout(() => client.deactivate(), delay); // 延迟断开连接 + }); + this.clients.clear(); + this.reconnectAttempts.clear(); + } +} + +export default new WebSocketManager(); diff --git a/src/views/demo/websocket.vue b/src/views/demo/websocket.vue index fe9c8e79..1a49af54 100644 --- a/src/views/demo/websocket.vue +++ b/src/views/demo/websocket.vue @@ -107,7 +107,7 @@ import { Client } from "@stomp/stompjs"; import { useUserStoreHook } from "@/store/modules/user"; -import { TOKEN_KEY } from "@/enums/CacheEnum"; +import { getToken } from "@/utils/auth"; const userStore = useUserStoreHook(); const isConnected = ref(false); @@ -141,7 +141,7 @@ function connectWebSocket() { stompClient = new Client({ brokerURL: socketEndpoint.value, connectHeaders: { - Authorization: localStorage.getItem(TOKEN_KEY) || "", + Authorization: getToken(), }, debug: (str) => { console.log(str); diff --git a/src/views/notice/index.vue b/src/views/notice/index.vue index 4ea6cadc..c446129f 100644 --- a/src/views/notice/index.vue +++ b/src/views/notice/index.vue @@ -119,13 +119,10 @@ @pagination="handleQuery()" /> -
From 463e5eb41996889287c4e3c1855f71e63e918035 Mon Sep 17 00:00:00 2001 From: Theo <971366405@qq.com> Date: Sat, 28 Sep 2024 00:12:29 +0800 Subject: [PATCH 064/238] =?UTF-8?q?refactor:=20:recycle:=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E9=A6=96=E9=A1=B5ws=E8=8E=B7=E5=8F=96=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E4=BA=BA=E6=95=B0=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构首页ws获取在线人数的代码 --- src/store/modules/user.ts | 2 +- src/views/dashboard/index.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index c8aa2ce3..db62ab55 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -69,7 +69,7 @@ export const useUserStore = defineStore("user", () => { // remove token function resetToken() { return new Promise((resolve) => { - localStorage.setItem(TOKEN_KEY, ""); + removeToken(); resetRouter(); resolve(); }); diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index f7d1ce1f..8a940a97 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -188,7 +188,7 @@ diff --git a/src/components/Notice/index.vue b/src/components/Notice/index.vue index 1caf557c..b7b63340 100644 --- a/src/components/Notice/index.vue +++ b/src/components/Notice/index.vue @@ -1,43 +1,41 @@ - + diff --git a/src/enums/MessageTypeEnum.ts b/src/enums/MessageTypeEnum.ts deleted file mode 100644 index 071f1b26..00000000 --- a/src/enums/MessageTypeEnum.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* 消息类型枚举 */ -export const enum MessageTypeEnum { - /* 消息 */ - MESSAGE = "SYSTEM_MESSAGE", - /* 通知 */ - NOTICE = "NOTICE", - /* 待办 */ - TODO = "TODO", -} - -export const MessageTypeLabels = { - [MessageTypeEnum.MESSAGE]: "消息", - // [MessageTypeEnum.NOTICE]: "通知", - // [MessageTypeEnum.TODO]: "待办", -}; diff --git a/src/layout/components/NavBar/components/NavbarAction.vue b/src/layout/components/NavBar/components/NavbarAction.vue index 2c0022c6..aba51152 100644 --- a/src/layout/components/NavBar/components/NavbarAction.vue +++ b/src/layout/components/NavBar/components/NavbarAction.vue @@ -124,11 +124,6 @@ function logout() { } } -:deep(.message .el-badge__content.is-fixed.is-dot) { - top: 5px; - right: 10px; -} - :deep(.el-divider--horizontal) { margin: 10px 0; } diff --git a/src/router/index.ts b/src/router/index.ts index 8f1f151e..b18a792d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -58,60 +58,14 @@ export const constantRoutes: RouteRecordRaw[] = [ component: () => import("@/views/profile/index.vue"), meta: { title: "个人中心", icon: "user", hidden: true }, }, + { + path: "myNotice", + name: "MyNotice", + component: () => import("@/views/system/notice/my-notice.vue"), + meta: { title: "我的通知", icon: "user", hidden: true }, + }, ], }, - - // 外部链接 - // { - // path: "/external-link", - // component: Layout, - // children: [ { - // component: () => import("@/views/external-link/index.vue"), - // path: "https://www.cnblogs.com/haoxianrui/", - // meta: { title: "外部链接", icon: "link" }, - // }, - // ], - // }, - // 多级嵌套路由 - /* { - path: '/nested', - component: Layout, - redirect: '/nested/level1/level2', - name: 'Nested', - meta: {title: '多级菜单', icon: 'nested'}, - children: [ - { - path: 'level1', - component: () => import('@/views/nested/level1/index.vue'), - name: 'Level1', - meta: {title: '菜单一级'}, - redirect: '/nested/level1/level2', - children: [ - { - path: 'level2', - component: () => import('@/views/nested/level1/level2/index.vue'), - name: 'Level2', - meta: {title: '菜单二级'}, - redirect: '/nested/level1/level2/level3', - children: [ - { - path: 'level3-1', - component: () => import('@/views/nested/level1/level2/level3/index1.vue'), - name: 'Level3-1', - meta: {title: '菜单三级-1'} - }, - { - path: 'level3-2', - component: () => import('@/views/nested/level1/level2/level3/index2.vue'), - name: 'Level3-2', - meta: {title: '菜单三级-2'} - } - ] - } - ] - }, - ] - }*/ ]; /** diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index c8aa2ce3..db62ab55 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -69,7 +69,7 @@ export const useUserStore = defineStore("user", () => { // remove token function resetToken() { return new Promise((resolve) => { - localStorage.setItem(TOKEN_KEY, ""); + removeToken(); resetRouter(); resolve(); }); diff --git a/src/types/components.d.ts b/src/types/components.d.ts index f947408e..fe6a01e9 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -13,10 +13,7 @@ declare module "vue" { Breadcrumb: (typeof import("./../components/Breadcrumb/index.vue"))["default"]; CopyButton: (typeof import("./../components/CopyButton/index.vue"))["default"]; CURD: (typeof import("./../components/CURD/index.vue"))["default"]; - DeptTree: (typeof import("./../views/system/user/components/dept-tree.vue"))["default"]; - UserImport: (typeof import("./../views/system/user/components/user-import.vue"))["default"]; Dictionary: (typeof import("./../components/Dictionary/index.vue"))["default"]; - DictItem: (typeof import("./../views/system/dict/components/dict-item.vue"))["default"]; ElBacktop: (typeof import("element-plus/es"))["ElBacktop"]; ElBreadcrumb: (typeof import("element-plus/es"))["ElBreadcrumb"]; ElBreadcrumbItem: (typeof import("element-plus/es"))["ElBreadcrumbItem"]; @@ -75,7 +72,7 @@ declare module "vue" { LangSelect: (typeof import("./../components/LangSelect/index.vue"))["default"]; MenuSearch: (typeof import("./../components/MenuSearch/index.vue"))["default"]; Notice: (typeof import("./../components/Notice/index.vue"))["default"]; - NoticeModal: (typeof import("./../components/NoticeModal/index.vue"))["default"]; + NoticeDetail: (typeof import("../views/system/notice/notice-detail.vue"))["default"]; LayoutSelect: (typeof import("./../layout/components/Settings/components/LayoutSelect.vue"))["default"]; MultiUpload: (typeof import("./../components/Upload/MultiUpload.vue"))["default"]; NavBar: (typeof import("./../layout/components/NavBar/index.vue"))["default"]; diff --git a/src/utils/socket.ts b/src/utils/socket.ts index fa6a87e4..e98ee6bc 100644 --- a/src/utils/socket.ts +++ b/src/utils/socket.ts @@ -1,79 +1,38 @@ import { Client } from "@stomp/stompjs"; import { getToken } from "@/utils/auth"; -const MAX_RECONNECT_ATTEMPTS = 3; // 最大重连尝试次数 -const RECONNECT_DELAY_MS = 5000; // 重连延迟时间(毫秒) -const HEARTBEAT_INTERVAL_MS = 30000; // 心跳间隔时间(毫秒) +const MAX_RECONNECT_ATTEMPTS = 3; +const RECONNECT_DELAY_MS = 5000; +const HEARTBEAT_INTERVAL_MS = 30000; class WebSocketManager { - private clients: Map = new Map(); // 保存所有 WebSocket 客户端 - private reconnectAttempts: Map = new Map(); // 记录各地址的重连次数 + private client: Client | null = null; + private reconnectAttempts: number = 0; private messageHandlers: Map void)[]> = - new Map(); // 保存订阅的消息回调 + new Map(); constructor() {} - /** - * 获取已有的 WebSocket 客户端 - * - * @param endpoint WebSocket 连接地址 - * @returns WebSocket Client 实例或 undefined - */ - public getClient(endpoint: string): Client | undefined { - return this.clients.get(endpoint); - } + private getOrCreateClient(onError?: (error: any) => void): Client { + const endpoint = import.meta.env.VITE_APP_WS_ENDPOINT; - /** - * 获取 WebSocket 客户端,如果已存在则返回已有客户端,否则创建新的客户端 - * - * @param endpoint WebSocket 连接地址 - * @param onMessage 收到消息时的回调 - * @param onError 出现错误时的回调 - * @returns WebSocket Client 实例 - */ - public getOrCreateClient( - endpoint: string, - onMessage: (message: string) => void, - onError?: (error: any) => void - ): Client { - let client = this.getClient(endpoint); - if (client) { - // 如果该地址已有连接,直接添加消息回调 - this.messageHandlers.get(endpoint)?.push(onMessage); - } else { - // 否则创建新客户端 - client = this.createClient(endpoint, onMessage, onError); - this.clients.set(endpoint, client); - this.messageHandlers.set(endpoint, [onMessage]); + if (this.client) { + return this.client; } - return client; - } - /** - * 创建 WebSocket 客户端 - * - * @param endpoint WebSocket 连接地址 - * @param onMessage 收到消息时的回调 - * @param onError 出现错误时的回调 - * @returns WebSocket Client 实例 - * @private - */ - private createClient( - endpoint: string, - onMessage: (message: string) => void, - onError?: (error: any) => void - ): Client { - const client = new Client({ - brokerURL: endpoint, // 使用传入的 endpoint 动态设置连接地址 + this.client = new Client({ + brokerURL: endpoint, connectHeaders: { Authorization: getToken(), }, heartbeatIncoming: HEARTBEAT_INTERVAL_MS, heartbeatOutgoing: HEARTBEAT_INTERVAL_MS, onConnect: () => { - console.log(`已连接到 ${endpoint}`); - client.subscribe(endpoint, (message) => { - onMessage(message.body); // 收到消息时调用回调 + console.log(`已连接到 WebSocket 服务器: ${endpoint}`); + this.messageHandlers.forEach((handlers, topic) => { + handlers.forEach((handler) => { + this.subscribeToTopic(topic, handler); + }); }); }, onStompError: (frame) => { @@ -84,66 +43,66 @@ class WebSocketManager { if (onError) { onError(frame); } - this.handleReconnect(endpoint); // 出现错误时处理重连 + this.handleReconnect(); }, onDisconnect: () => { console.log(`已断开连接: ${endpoint}`); - this.handleReconnect(endpoint); // 断开时处理重连 + this.handleReconnect(); }, }); - client.activate(); - return client; + this.client.activate(); + return this.client; } - /** - * 处理 WebSocket 重连 - * - * @param endpoint WebSocket 连接地址 - * @private - */ - private handleReconnect(endpoint: string) { - const attemptCount = this.reconnectAttempts.get(endpoint) || 0; + public subscribeToTopic( + topic: string, + onMessage: (message: string) => void, + onError?: (error: any) => void + ) { + if (!this.client || !this.client.connected) { + console.log("WebSocket 尚未连接,正在连接..."); + this.getOrCreateClient(onError); + } + + if (this.messageHandlers.has(topic)) { + this.messageHandlers.get(topic)?.push(onMessage); + } else { + this.messageHandlers.set(topic, [onMessage]); + } - if (this.clients.has(endpoint)) { - const client = this.clients.get(endpoint); - if (client && client.connected) { - client.deactivate(); // 主动断开已有连接 - } + if (this.client?.connected) { + console.log(`正在订阅主题: ${topic}`); + this.client.subscribe(topic, (message) => { + const handlers = this.messageHandlers.get(topic); + handlers?.forEach((handler) => handler(message.body)); + }); } + } - // 重连次数未达到最大次数时继续重连 - if (attemptCount < MAX_RECONNECT_ATTEMPTS) { - this.reconnectAttempts.set(endpoint, attemptCount + 1); + private handleReconnect() { + if (this.reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { + this.reconnectAttempts++; console.log( - `尝试重连 (${attemptCount + 1}/${MAX_RECONNECT_ATTEMPTS}): ${endpoint}` + `重连尝试 (${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})` ); + setTimeout(() => { - const originalOnMessage = this.messageHandlers.get(endpoint) || []; - this.getOrCreateClient( - endpoint, - (message) => originalOnMessage.forEach((handler) => handler(message)), - () => {} - ); + this.client?.deactivate(); + this.client = null; + this.getOrCreateClient(); }, RECONNECT_DELAY_MS); } else { - console.error(`达到最大重连次数: ${endpoint}`); - this.reconnectAttempts.delete(endpoint); // 超过最大重连次数后清除重连记录 + console.error("达到最大重连次数,停止重连"); } } - /** - * 断开所有 WebSocket 连接 - * - * @param delay 延迟断开时间(毫秒),默认为 0 - */ - public disconnectAll(delay: number = 0) { - this.clients.forEach((client, endpoint) => { - console.log(`断开 WebSocket 连接: ${endpoint}`); - setTimeout(() => client.deactivate(), delay); // 延迟断开连接 - }); - this.clients.clear(); - this.reconnectAttempts.clear(); + public disconnect() { + if (this.client) { + console.log("断开 WebSocket 连接"); + this.client.deactivate(); + this.client = null; + } } } diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index f7d1ce1f..0333d3e0 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -188,15 +188,13 @@ diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index 60d32252..0d32e299 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -1,12 +1,12 @@ - + diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 7222319e..217997ed 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -70,7 +70,9 @@
- + + +
- + + + - + 搜索 - + 重置 @@ -31,7 +35,9 @@ v-hasPerm="['sys:config:add']" @click="handleOpenDialog()" > - + 新增 - + 编辑 - + 删除 diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index 92256336..82457e49 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -23,11 +23,15 @@ - + 搜索 - + 重置 @@ -41,7 +45,9 @@ type="success" @click="handleOpenDialog(0, undefined)" > - + 新增 - + 删除 @@ -84,7 +92,9 @@ size="small" @click.stop="handleOpenDialog(scope.row.id, undefined)" > - + 新增 - + 编辑 - + 删除 diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue index 50913e89..908910e7 100644 --- a/src/views/system/dict/data.vue +++ b/src/views/system/dict/data.vue @@ -19,11 +19,15 @@ - + 搜索 - + 重置 @@ -33,7 +37,9 @@
- + 新增 - + 删除
@@ -73,7 +81,9 @@ size="small" @click.stop="handleOpenDialog(scope.row)" > - + 编辑 - + 删除 diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index 0d32e299..d3f2889e 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -13,12 +13,16 @@ - + 搜索 - - 重置 + @@ -27,7 +31,9 @@
- + 新增 - + 删除
@@ -65,7 +73,9 @@ size="small" @click.stop="handleOpenDictData(scope.row)" > - + 字典数据 @@ -75,7 +85,9 @@ size="small" @click.stop="handleEditClick(scope.row.id, scope.row.name)" > - + 编辑 - + 删除 diff --git a/src/views/system/log/index.vue b/src/views/system/log/index.vue index d234135c..358d8e7b 100644 --- a/src/views/system/log/index.vue +++ b/src/views/system/log/index.vue @@ -25,11 +25,15 @@ - + 搜索 - + 重置 diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index 7c9aedbd..5ba209aa 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -12,11 +12,11 @@ - + 搜索 - + 重置 @@ -30,7 +30,7 @@ type="success" @click="handleOpenDialog(0)" > - + 新增 @@ -133,7 +133,7 @@ size="small" @click.stop="handleOpenDialog(scope.row.id)" > - + 新增 @@ -144,7 +144,7 @@ size="small" @click.stop="handleOpenDialog(undefined, scope.row.id)" > - + 编辑 - + 删除 @@ -217,14 +217,17 @@ prop="routeName" > @@ -239,7 +242,7 @@ prop="routePath" > @@ -264,14 +269,16 @@ prop="component" > @@ -292,13 +299,15 @@ @@ -370,7 +379,7 @@ " > @@ -393,7 +404,7 @@ 开启 diff --git a/src/views/system/notice/components/NoticeDetail.vue b/src/views/system/notice/components/NoticeDetail.vue index 5ed9f2a5..f4f1acdf 100644 --- a/src/views/system/notice/components/NoticeDetail.vue +++ b/src/views/system/notice/components/NoticeDetail.vue @@ -18,7 +18,9 @@ - +
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue index 1b9e3fc4..f25054fa 100644 --- a/src/views/system/notice/index.vue +++ b/src/views/system/notice/index.vue @@ -29,11 +29,11 @@
- + 搜索 - + 重置 @@ -47,7 +47,7 @@ type="success" @click="handleOpenDialog()" > - + 新增通知 - + 删除 diff --git a/src/views/system/notice/my-notice.vue b/src/views/system/notice/my-notice.vue index caf17bc8..885cc4fb 100644 --- a/src/views/system/notice/my-notice.vue +++ b/src/views/system/notice/my-notice.vue @@ -12,11 +12,15 @@
- + 搜索 - + 重置 diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 2957cb89..ab0962f3 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -13,11 +13,11 @@ - + 搜索 - + 重置 @@ -27,7 +27,9 @@ @@ -69,7 +73,7 @@ link @click="handleOpenAssignPermDialog(scope.row)" > - + 分配权限 - + 编辑 - + 删除 @@ -172,13 +176,15 @@ placeholder="菜单权限名称" >
- + {{ isExpanded ? "收缩" : "展开" }} 如果只需勾选菜单权限,不需要勾选子菜单或者按钮权限,请关闭父子联动 - + > + +
diff --git a/src/views/system/user/dept-tree.vue b/src/views/system/user/dept-tree.vue index 2f386063..00cda400 100644 --- a/src/views/system/user/dept-tree.vue +++ b/src/views/system/user/dept-tree.vue @@ -3,7 +3,7 @@ diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index b90596f5..b3f0f98c 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -48,11 +48,11 @@ - + 搜索 - + 重置 @@ -68,7 +68,7 @@ type="success" @click="handleOpenDialog()" > - + 新增 - + 删除
- + 导入 - + 导出
@@ -163,7 +163,7 @@ link @click="hancleResetPassword(scope.row)" > - + 重置密码 - + 编辑 - + 删除 diff --git a/vite.config.ts b/vite.config.ts index 74aed0ea..3cf1fe97 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,8 +5,6 @@ import { UserConfig, ConfigEnv, loadEnv, defineConfig } from "vite"; import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; -import Icons from "unplugin-icons/vite"; -import IconsResolver from "unplugin-icons/resolver"; import { createSvgIconsPlugin } from "vite-plugin-svg-icons"; import mockDevServerPlugin from "vite-plugin-mock-dev-server"; @@ -88,8 +86,6 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { ElementPlusResolver({ importStyle: "sass", }), - // 自动导入图标组件 - IconsResolver({}), ], eslintrc: { // 是否自动生成 eslint 规则,建议生成之后设置 false @@ -110,11 +106,6 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { ElementPlusResolver({ importStyle: "sass", }), - // 自动注册图标组件 - IconsResolver({ - // element-plus图标库,其他图标库 https://icon-sets.iconify.design/ - enabledCollections: ["ep"], - }), ], // 指定自定义组件位置(默认:src/components) dirs: ["src/components", "src/**/components"], @@ -122,10 +113,6 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { dts: false, // dts: "src/types/components.d.ts", }), - Icons({ - // 自动安装图标库 - autoInstall: true, - }), createSvgIconsPlugin({ // 指定需要缓存的图标文件夹 iconDirs: [resolve(pathSrc, "assets/icons")], From 0783709ac745f42706b0aa7d8ed21910bc2c7278 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Tue, 8 Oct 2024 15:36:11 +0800 Subject: [PATCH 075/238] =?UTF-8?q?fix:=20:bug:=20=E9=94=81=E5=AE=9Asass?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=8C=E7=9B=AE=E5=89=8D1.79.x=E6=9C=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 ++--- tsconfig.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 42b50e8c..26609808 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "postcss-html": "^1.7.0", "postcss-scss": "^4.0.9", "prettier": "^3.3.3", - "sass": "^1.78.0", + "sass": "1.78.0", "stylelint": "^16.9.0", "stylelint-config-html": "^1.1.0", "stylelint-config-recess-order": "^4.6.0", @@ -120,6 +120,5 @@ }, "repository": "https://gitee.com/youlaiorg/vue3-element-admin.git", "author": "有来开源组织", - "license": "MIT", - "packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd" + "license": "MIT" } diff --git a/tsconfig.json b/tsconfig.json index f6db304b..7d515579 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "paths": { "@/*": ["src/*"] }, - "types": ["vite/client", "unplugin-icons/types/vue", "element-plus/global"] + "types": ["vite/client", "element-plus/global"] }, "include": [ "mock/**/*.ts", From d2b96ac74c9e6cf2f0378f74bbc77f1c053b1a16 Mon Sep 17 00:00:00 2001 From: Theo <971366405@qq.com> Date: Tue, 8 Oct 2024 16:32:21 +0800 Subject: [PATCH 076/238] =?UTF-8?q?fix:=20:bug:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E8=AE=BE=E7=BD=AE=E4=B8=BA=E6=B7=B7=E5=90=88?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=97=B6=E5=9B=BE=E6=A0=87=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复导航设置为混合模式时图标显示不正确的bug --- .../Sidebar/components/SidebarMixTopMenu.vue | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue b/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue index 6c431158..6982b815 100644 --- a/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue +++ b/src/layout/components/Sidebar/components/SidebarMixTopMenu.vue @@ -15,10 +15,16 @@ :index="route.path" > diff --git a/src/components/Dictionary/index.vue b/src/components/Dictionary/index.vue deleted file mode 100644 index 325337ee..00000000 --- a/src/components/Dictionary/index.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - diff --git a/src/store/modules/dict.ts b/src/store/modules/dict.ts new file mode 100644 index 00000000..f87ec5b5 --- /dev/null +++ b/src/store/modules/dict.ts @@ -0,0 +1,41 @@ +import { store } from "@/store"; +import DictionaryAPI, { type DictVO, type DictData } from "@/api/system/dict"; + +export const useDictStore = defineStore("dict", () => { + const dictionary = useStorage>("dictionary", {}); + + const setDictionary = (dict: DictVO) => { + dictionary.value[dict.dictCode] = dict.dictDataList; + }; + + const loadDictionaries = async () => { + const dictList = await DictionaryAPI.getList(); + dictList.forEach(setDictionary); + }; + + const getDictionary = (dictCode: string): DictData[] => { + return dictionary.value[dictCode] || []; + }; + + const clearDictionaryCache = () => { + dictionary.value = {}; + }; + + const updateDictionaryCache = async () => { + clearDictionaryCache(); // 先清除旧缓存 + await loadDictionaries(); // 重新加载最新字典数据 + }; + + return { + dictionary, + setDictionary, + loadDictionaries, + getDictionary, + clearDictionaryCache, + updateDictionaryCache, + }; +}); + +export function useDictStoreHook() { + return useDictStore(store); +} diff --git a/src/utils/cache.ts b/src/utils/cache.ts deleted file mode 100644 index 2a3b8c53..00000000 --- a/src/utils/cache.ts +++ /dev/null @@ -1,79 +0,0 @@ -const DEFAULT_CACHE_EXPIRY_TIME = 5 * 60 * 1000; // 默认缓存有效期为5分钟 - -/** - * 通用缓存工具类 - */ -class Cache { - private cachePrefix: string; - - constructor(prefix: string = "cache_") { - this.cachePrefix = prefix; - } - - /** - * 设置缓存 - * - * @param key 缓存的键 - * @param data 缓存的数据 - * @param expiryTime 缓存有效期(毫秒),默认5分钟 - */ - setCache( - key: string, - data: any, - expiryTime: number = DEFAULT_CACHE_EXPIRY_TIME - ) { - const expiryTimestamp = new Date().getTime() + expiryTime; - const cacheKey = this.cachePrefix + key; - const cacheData = { data, expiryTimestamp }; - - localStorage.setItem(cacheKey, JSON.stringify(cacheData)); - } - - /** - * 获取缓存 - * - * @param key 缓存的键 - * @returns 如果缓存有效则返回缓存的数据,否则返回 null - */ - getCache(key: string) { - const cacheKey = this.cachePrefix + key; - const cached = localStorage.getItem(cacheKey); - - if (cached) { - const { data, expiryTimestamp } = JSON.parse(cached); - const now = new Date().getTime(); - - // 如果缓存未过期,返回数据 - if (now < expiryTimestamp) { - return data; - } else { - // 如果缓存过期,移除缓存 - localStorage.removeItem(cacheKey); - } - } - return null; - } - - /** - * 移除缓存 - * - * @param key 缓存的键 - */ - removeCache(key: string) { - const cacheKey = this.cachePrefix + key; - localStorage.removeItem(cacheKey); - } - - /** - * 清空当前前缀下的所有缓存 - */ - clearCache() { - for (const key in localStorage) { - if (key.startsWith(this.cachePrefix)) { - localStorage.removeItem(key); - } - } - } -} - -export default Cache; diff --git a/src/utils/requestCache.ts b/src/utils/requestCache.ts deleted file mode 100644 index c3ed9a90..00000000 --- a/src/utils/requestCache.ts +++ /dev/null @@ -1,4 +0,0 @@ -// 创建一个共享的 requestCache -const requestCache = new Map>(); - -export default requestCache; diff --git a/src/views/demo/dict.vue b/src/views/demo/dictionary.vue similarity index 53% rename from src/views/demo/dict.vue rename to src/views/demo/dictionary.vue index 41191914..da817faf 100644 --- a/src/views/demo/dict.vue +++ b/src/views/demo/dictionary.vue @@ -2,12 +2,13 @@ From 605d87b3a7f6a47fdc78268e6923e273e93aedc8 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 18 Oct 2024 22:04:18 +0800 Subject: [PATCH 122/238] =?UTF-8?q?fix:=20:bug:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=B3=A8=E9=94=80=E7=99=BB=E5=BD=95location.reload=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=8E=A5=E5=8F=A3=E6=97=A0=E5=93=8D=E5=BA=94=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/permission.ts | 43 +++++++++++++------------- src/store/modules/permission.ts | 25 +++++++++++++++- src/store/modules/user.ts | 53 +++++++++++++++++++-------------- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/src/plugins/permission.ts b/src/plugins/permission.ts index 34056fe6..f93db995 100644 --- a/src/plugins/permission.ts +++ b/src/plugins/permission.ts @@ -3,10 +3,8 @@ import type { RouteLocationNormalized, RouteRecordRaw, } from "vue-router"; - import NProgress from "@/utils/nprogress"; -import { isLogin } from "@/utils/auth"; - +import { getToken } from "@/utils/auth"; import router from "@/router"; import { usePermissionStore, useUserStore } from "@/store"; @@ -16,22 +14,21 @@ export function setupPermission() { router.beforeEach(async (to, from, next) => { NProgress.start(); - if (isLogin()) { + + const isLogin = !!getToken(); // 判断是否登录 + if (isLogin) { if (to.path === "/login") { - // 如果已登录,跳转到首页 + // 已登录,访问登录页,跳转到首页 next({ path: "/" }); - NProgress.done(); } else { - const userStore = useUserStore(); - const hasRoles = - userStore.user.roles && userStore.user.roles.length > 0; - - if (hasRoles) { - // 如果未匹配到任何路由,跳转到404页面 + const permissionStore = usePermissionStore(); + // 判断路由是否加载过 + if (permissionStore.isRoutesLoaded) { if (to.matched.length === 0) { - next(from.name ? { name: from.name } : "/404"); + // 路由未匹配,跳转到404 + next("/404"); } else { - // 如果路由参数中有 title,覆盖路由元信息中的 title + // 动态设置页面标题 const title = (to.params.title as string) || (to.query.title as string); if (title) { @@ -40,35 +37,35 @@ export function setupPermission() { next(); } } else { - const permissionStore = usePermissionStore(); try { - await userStore.getUserInfo(); + // 生成动态路由 const dynamicRoutes = await permissionStore.generateRoutes(); dynamicRoutes.forEach((route: RouteRecordRaw) => router.addRoute(route) ); - next({ ...to, replace: true }); + next({ ...to, replace: true }); // 添加动态路由后重新导航 } catch (error) { console.error(error); - // 移除 token 并重定向到登录页,携带当前页面路由作为跳转参数 - await userStore.resetToken(); + // 路由加载失败,重置 token 并重定向到登录页 + await useUserStore().clearUserSession(); redirectToLogin(to, next); NProgress.done(); } } } } else { - // 未登录 + // 未登录,判断是否在白名单中 if (whiteList.includes(to.path)) { - next(); // 在白名单,直接进入 + next(); } else { // 不在白名单,重定向到登录页 redirectToLogin(to, next); - NProgress.done(); + NProgress.done(); // 关闭进度条 } } }); + // 后置守卫,保证每次路由跳转结束时关闭进度条 router.afterEach(() => { NProgress.done(); }); @@ -90,7 +87,7 @@ export function hasAuth( value: string | string[], type: "button" | "role" = "button" ) { - const { roles, perms } = useUserStore().user; + const { roles, perms } = useUserStore().userInfo; // 超级管理员 拥有所有权限 if (type === "button" && roles.includes("ROOT")) { diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 4b027c12..77940aed 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -1,17 +1,21 @@ import type { RouteRecordRaw } from "vue-router"; import { constantRoutes } from "@/router"; import { store } from "@/store"; -import MenuAPI, { type RouteVO } from "@/api/menu"; +import MenuAPI, { type RouteVO } from "@/api/system/menu"; const modules = import.meta.glob("../../views/**/**.vue"); const Layout = () => import("@/layout/index.vue"); +import router from "@/router"; + export const usePermissionStore = defineStore("permission", () => { /** 所有路由,包括静态和动态路由 */ const routes = ref([]); /** 混合模式左侧菜单 */ const mixLeftMenus = ref([]); + const isRoutesLoaded = ref(false); + /** * 生成动态路由 */ @@ -21,6 +25,7 @@ export const usePermissionStore = defineStore("permission", () => { .then((data) => { const dynamicRoutes = transformRoutes(data); routes.value = constantRoutes.concat(dynamicRoutes); + isRoutesLoaded.value = true; resolve(dynamicRoutes); }) .catch((error) => { @@ -41,11 +46,29 @@ export const usePermissionStore = defineStore("permission", () => { } }; + /** + * 重置路由 + */ + const resetRouter = () => { + // 删除动态路由,保留静态路由 + routes.value.forEach((route) => { + if (route.name && !constantRoutes.find((r) => r.name === route.name)) { + router.removeRoute(route.name); // 从 router 实例中移除动态路由 + } + }); + + routes.value = []; + mixLeftMenus.value = []; + isRoutesLoaded.value = false; + }; + return { routes, generateRoutes, mixLeftMenus, setMixLeftMenus, + isRoutesLoaded, + resetRouter, }; }); diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index db62ab55..f5251aa1 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,14 +1,14 @@ -import AuthAPI, { type LoginData } from "@/api/auth"; -import UserAPI, { type UserInfo } from "@/api/user"; -import { resetRouter } from "@/router"; import { store } from "@/store"; -import { setToken, removeToken } from "@/utils/auth"; +import { usePermissionStoreHook } from "@/store/modules/permission"; +import { useDictStoreHook } from "@/store/modules/dict"; + +import AuthAPI, { type LoginData } from "@/api/auth"; +import UserAPI, { type UserInfo } from "@/api/system/user"; + +import { setToken, clearToken } from "@/utils/auth"; export const useUserStore = defineStore("user", () => { - const user = ref({ - roles: [], - perms: [], - }); + const userInfo = useStorage("userInfo", {} as UserInfo); /** * 登录 @@ -30,7 +30,11 @@ export const useUserStore = defineStore("user", () => { }); } - // 获取信息(用户昵称、头像、角色集合、权限集合) + /** + * 获取用户信息 + * + * @returns {UserInfo} 用户信息 + */ function getUserInfo() { return new Promise((resolve, reject) => { UserAPI.getInfo() @@ -39,11 +43,7 @@ export const useUserStore = defineStore("user", () => { reject("Verification failed, please Login again."); return; } - if (!data.roles || data.roles.length <= 0) { - reject("getUserInfo: roles must be a non-null array!"); - return; - } - Object.assign(user.value, { ...data }); + Object.assign(userInfo.value, { ...data }); resolve(data); }) .catch((error) => { @@ -52,12 +52,14 @@ export const useUserStore = defineStore("user", () => { }); } - // user logout + /** + * 登出 + */ function logout() { return new Promise((resolve, reject) => { AuthAPI.logout() .then(() => { - location.reload(); // 清空路由 + clearUserSession(); resolve(); }) .catch((error) => { @@ -66,21 +68,26 @@ export const useUserStore = defineStore("user", () => { }); } - // remove token - function resetToken() { + /** + * 清理用户会话 + * + * @returns + */ + function clearUserSession() { return new Promise((resolve) => { - removeToken(); - resetRouter(); + clearToken(); + usePermissionStoreHook().resetRouter(); + useDictStoreHook().clearDictionaryCache(); resolve(); }); } return { - user, - login, + userInfo, getUserInfo, + login, logout, - resetToken, + clearUserSession, }; }); From 0cc300a0328f6c8d914fb392dd6e5400345dc4b4 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 18 Oct 2024 22:07:27 +0800 Subject: [PATCH 123/238] =?UTF-8?q?chore:=20:hammer:=20=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8F=82=E6=95=B0=E7=BB=9F=E4=B8=80=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Upload/FileUpload.vue | 4 +- src/components/Upload/ImageUpload.vue | 254 -------------------------- 2 files changed, 2 insertions(+), 256 deletions(-) delete mode 100644 src/components/Upload/ImageUpload.vue diff --git a/src/components/Upload/FileUpload.vue b/src/components/Upload/FileUpload.vue index 9b0a54cf..3ecca178 100644 --- a/src/components/Upload/FileUpload.vue +++ b/src/components/Upload/FileUpload.vue @@ -108,9 +108,9 @@ const props = defineProps({ default: true, }, /** - * 单个文件上传大小限制(单位byte) + * 单个文件上传大小限制(单位MB) */ - uploadMaxSize: { + maxSize: { type: Number, default: 2 * 1024 * 1024, }, diff --git a/src/components/Upload/ImageUpload.vue b/src/components/Upload/ImageUpload.vue deleted file mode 100644 index ddc1861a..00000000 --- a/src/components/Upload/ImageUpload.vue +++ /dev/null @@ -1,254 +0,0 @@ - - - - From af460b5dc33fc38dc1a3c927c2d4fc2aef197dd7 Mon Sep 17 00:00:00 2001 From: ray <1490493387@qq.com> Date: Fri, 18 Oct 2024 22:28:02 +0800 Subject: [PATCH 124/238] =?UTF-8?q?refactor:=20:recycle:=20aPI=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=A0=B9=E6=8D=AE=E6=A8=A1=E5=9D=97=E5=88=92=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/{auth.ts => auth/index.ts} | 0 src/api/{codegen.ts => codegen/index.ts} | 0 src/api/dict.ts | 148 ------------------ src/api/{file.ts => file/index.ts} | 0 src/api/{ => system}/config.ts | 0 src/api/{ => system}/dept.ts | 0 src/api/{ => system}/dict-data.ts | 0 src/api/{ => system}/log.ts | 0 src/api/{ => system}/menu.ts | 0 src/api/{ => system}/notice.ts | 0 src/api/{ => system}/role.ts | 0 src/api/{ => system}/user.ts | 0 src/components/Notice/index.vue | 2 +- src/lang/package/en.ts | 2 +- src/store/index.ts | 1 + src/utils/auth.ts | 8 +- src/utils/request.ts | 7 +- src/views/codegen/index.vue | 6 +- src/views/dashboard/components/VisitTrend.vue | 2 +- src/views/dashboard/index.vue | 14 +- src/views/demo/curd/config/add.ts | 2 +- src/views/demo/curd/config/content.ts | 4 +- src/views/demo/curd/config/edit.ts | 2 +- src/views/demo/curd/config/search.ts | 2 +- src/views/demo/curd/index.vue | 10 +- .../{icon-selector.vue => icon-select.vue} | 2 +- src/views/demo/table-select/config/select.ts | 2 +- src/views/demo/upload.vue | 120 +++++++------- src/views/demo/websocket.vue | 15 +- src/views/profile/index.vue | 4 +- src/views/system/config/index.vue | 6 +- src/views/system/dept/index.vue | 6 +- src/views/system/dict/data.vue | 4 +- src/views/system/dict/index.vue | 8 +- src/views/system/log/index.vue | 4 +- src/views/system/menu/index.vue | 6 +- .../system/notice/components/NoticeDetail.vue | 2 +- src/views/system/notice/index.vue | 20 +-- src/views/system/notice/my-notice.vue | 6 +- src/views/system/role/index.vue | 12 +- src/views/system/user/dept-tree.vue | 2 +- src/views/system/user/import.vue | 2 +- src/views/system/user/index.vue | 16 +- 43 files changed, 150 insertions(+), 297 deletions(-) rename src/api/{auth.ts => auth/index.ts} (100%) rename src/api/{codegen.ts => codegen/index.ts} (100%) delete mode 100644 src/api/dict.ts rename src/api/{file.ts => file/index.ts} (100%) rename src/api/{ => system}/config.ts (100%) rename src/api/{ => system}/dept.ts (100%) rename src/api/{ => system}/dict-data.ts (100%) rename src/api/{ => system}/log.ts (100%) rename src/api/{ => system}/menu.ts (100%) rename src/api/{ => system}/notice.ts (100%) rename src/api/{ => system}/role.ts (100%) rename src/api/{ => system}/user.ts (100%) rename src/views/demo/{icon-selector.vue => icon-select.vue} (90%) diff --git a/src/api/auth.ts b/src/api/auth/index.ts similarity index 100% rename from src/api/auth.ts rename to src/api/auth/index.ts diff --git a/src/api/codegen.ts b/src/api/codegen/index.ts similarity index 100% rename from src/api/codegen.ts rename to src/api/codegen/index.ts diff --git a/src/api/dict.ts b/src/api/dict.ts deleted file mode 100644 index 9566e889..00000000 --- a/src/api/dict.ts +++ /dev/null @@ -1,148 +0,0 @@ -import request from "@/utils/request"; - -const DICT_BASE_URL = "/api/v1/dict"; - -const DictAPI = { - /** - * 获取字典分页列表 - * - * @param queryParams 查询参数 - * @returns 字典分页结果 - */ - getPage(queryParams: DictPageQuery) { - return request>({ - url: `${DICT_BASE_URL}/page`, - method: "get", - params: queryParams, - }); - }, - - /** - * 获取字典表单数据 - * - * @param id 字典ID - * @returns 字典表单数据 - */ - getFormData(id: number) { - return request>({ - url: `${DICT_BASE_URL}/${id}/form`, - method: "get", - }); - }, - - /** - * 新增字典 - * - * @param data 字典表单数据 - */ - add(data: DictForm) { - return request({ - url: `${DICT_BASE_URL}`, - method: "post", - data: data, - }); - }, - - /** - * 修改字典 - * - * @param id 字典ID - * @param data 字典表单数据 - */ - update(id: number, data: DictForm) { - return request({ - url: `${DICT_BASE_URL}/${id}`, - method: "put", - data: data, - }); - }, - - /** - * 删除字典 - * - * @param ids 字典ID,多个以英文逗号(,)分隔 - */ - deleteByIds(ids: string) { - return request({ - url: `${DICT_BASE_URL}/${ids}`, - method: "delete", - }); - }, - - /** - * 获取字典列表 - * - * @returns 字典列表 - */ - getList() { - return request({ - url: `${DICT_BASE_URL}/list`, - method: "get", - }); - }, -}; - -export default DictAPI; - -/** - * 字典查询参数 - */ -export interface DictPageQuery extends PageQuery { - /** - * 关键字(字典名称/编码) - */ - keywords?: string; - - /** - * 字典状态(1:启用,0:禁用) - */ - status?: number; -} - -/** - * 字典分页对象 - */ -export interface DictPageVO { - /** - * 字典ID - */ - id: number; - /** - * 字典名称 - */ - name: string; - /** - * 字典编码 - */ - dictCode: string; - /** - * 字典状态(1:启用,0:禁用) - */ - status: number; -} - -/** - * 字典 - */ -export interface DictForm { - /** - * 字典ID - */ - id?: number; - /** - * 字典名称 - */ - name?: string; - /** - * 字典编码 - */ - dictCode?: string; - /** - * 字典状态(1-启用,0-禁用) - */ - status?: number; - /** - * 备注 - */ - remark?: string; -} diff --git a/src/api/file.ts b/src/api/file/index.ts similarity index 100% rename from src/api/file.ts rename to src/api/file/index.ts diff --git a/src/api/config.ts b/src/api/system/config.ts similarity index 100% rename from src/api/config.ts rename to src/api/system/config.ts diff --git a/src/api/dept.ts b/src/api/system/dept.ts similarity index 100% rename from src/api/dept.ts rename to src/api/system/dept.ts diff --git a/src/api/dict-data.ts b/src/api/system/dict-data.ts similarity index 100% rename from src/api/dict-data.ts rename to src/api/system/dict-data.ts diff --git a/src/api/log.ts b/src/api/system/log.ts similarity index 100% rename from src/api/log.ts rename to src/api/system/log.ts diff --git a/src/api/menu.ts b/src/api/system/menu.ts similarity index 100% rename from src/api/menu.ts rename to src/api/system/menu.ts diff --git a/src/api/notice.ts b/src/api/system/notice.ts similarity index 100% rename from src/api/notice.ts rename to src/api/system/notice.ts diff --git a/src/api/role.ts b/src/api/system/role.ts similarity index 100% rename from src/api/role.ts rename to src/api/system/role.ts diff --git a/src/api/user.ts b/src/api/system/user.ts similarity index 100% rename from src/api/user.ts rename to src/api/system/user.ts diff --git a/src/components/Notice/index.vue b/src/components/Notice/index.vue index 5e3a9f0e..e0a3b271 100644 --- a/src/components/Notice/index.vue +++ b/src/components/Notice/index.vue @@ -184,7 +184,7 @@ - diff --git a/src/views/demo/websocket.vue b/src/views/demo/websocket.vue index 9d585ba1..75bf366b 100644 --- a/src/views/demo/websocket.vue +++ b/src/views/demo/websocket.vue @@ -77,17 +77,18 @@ :class="{ 'tip-message': message.type === 'tip', message: message.type !== 'tip', - 'message--sent': message.sender === userStore.user.username, - 'message--received': message.sender !== userStore.user.username, + 'message--sent': message.sender === userStore.userInfo.username, + 'message--received': + message.sender !== userStore.userInfo.username, }" >
{{ message.sender }} @@ -131,7 +132,7 @@ const queneMessage = ref( "hi , " + receiver.value + " , 我是" + - userStore.user.username + + userStore.userInfo.username + " , 想和你交个朋友 ! " ); @@ -206,7 +207,7 @@ function sendToAll() { body: topicMessage.value, }); messages.value.push({ - sender: userStore.user.username, + sender: userStore.userInfo.username, content: topicMessage.value, }); } @@ -219,7 +220,7 @@ function sendToUser() { body: queneMessage.value, }); messages.value.push({ - sender: userStore.user.username, + sender: userStore.userInfo.username, content: queneMessage.value, }); } diff --git a/src/views/profile/index.vue b/src/views/profile/index.vue index fbf68c1c..0fbc29aa 100644 --- a/src/views/profile/index.vue +++ b/src/views/profile/index.vue @@ -190,7 +190,7 @@ - + @@ -300,7 +300,7 @@ import UserAPI, { MobileBindingForm, EmailBindingForm, UserProfileForm, -} from "@/api/user"; +} from "@/api/system/user"; import FileAPI from "@/api/file"; diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue index f60215ed..ac099608 100644 --- a/src/views/system/config/index.vue +++ b/src/views/system/config/index.vue @@ -1,7 +1,7 @@