From 332678ba881eb326e707606032b3b1b3d72eb335 Mon Sep 17 00:00:00 2001 From: EchoByte Date: Fri, 12 Apr 2024 16:20:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=B4=A6=E6=88=B7?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=8A=9F=E8=83=BD=E9=A1=B5=E9=9D=A2=E4=B8=94?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E7=A7=BB=E5=8A=A8=E7=AB=AF=20(#1022)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.yaml | 3 +- locales/zh-CN.yaml | 3 +- mock/login.ts | 5 +- mock/mine.ts | 59 ++++++ mock/system.ts | 44 ++++- src/api/user.ts | 46 ++++- src/components/ReCropperPreview/index.ts | 7 + .../ReCropperPreview/src/index.vue} | 4 + src/components/ReDialog/index.vue | 4 + src/components/ReFlop/src/index.vue | 4 + src/components/ReText/src/index.vue | 4 + src/layout/components/navbar.vue | 12 +- src/layout/components/sidebar/horizontal.vue | 11 +- src/layout/components/sidebar/mixNav.vue | 11 +- src/layout/hooks/useNav.ts | 22 ++- src/router/modules/remaining.ts | 10 + src/store/modules/types.ts | 2 + src/store/modules/user.ts | 12 ++ src/utils/auth.ts | 30 ++- .../components/accountManagement.vue | 62 ++++++ .../components/preferences.vue | 65 ++++++ .../account-settings/components/profile.vue | 187 ++++++++++++++++++ .../components/securityLog.vue | 87 ++++++++ src/views/account-settings/index.vue | 183 +++++++++++++++++ src/views/system/user/utils/hook.tsx | 5 +- 25 files changed, 860 insertions(+), 22 deletions(-) create mode 100644 mock/mine.ts create mode 100644 src/components/ReCropperPreview/index.ts rename src/{views/system/user/upload.vue => components/ReCropperPreview/src/index.vue} (97%) create mode 100644 src/views/account-settings/components/accountManagement.vue create mode 100644 src/views/account-settings/components/preferences.vue create mode 100644 src/views/account-settings/components/profile.vue create mode 100644 src/views/account-settings/components/securityLog.vue create mode 100644 src/views/account-settings/index.vue diff --git a/locales/en.yaml b/locales/en.yaml index 299062bb0c..effc85b453 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -1,4 +1,5 @@ buttons: + pureAccountSettings: Account Settings pureLoginOut: LoginOut pureLogin: Login pureSystemSet: Open ProjectConfig @@ -175,4 +176,4 @@ login: purePassWordRuleReg: The password format should be any combination of 8-18 digits purePassWordSureReg: Please enter confirm password purePassWordDifferentReg: The two passwords do not match! - purePassWordUpdateReg: Password has been updated + purePassWordUpdateReg: Password has been updated \ No newline at end of file diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index ad36356fd8..69a6a86416 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -1,4 +1,5 @@ buttons: + pureAccountSettings: 账户设置 pureLoginOut: 退出系统 pureLogin: 登录 pureSystemSet: 打开项目配置 @@ -175,4 +176,4 @@ login: purePassWordRuleReg: 密码格式应为8-18位数字、字母、符号的任意两种组合 purePassWordSureReg: 请输入确认密码 purePassWordDifferentReg: 两次密码不一致! - purePassWordUpdateReg: 修改密码成功 + purePassWordUpdateReg: 修改密码成功 \ No newline at end of file diff --git a/mock/login.ts b/mock/login.ts index 62d21126a5..a9c71b15d1 100644 --- a/mock/login.ts +++ b/mock/login.ts @@ -10,7 +10,9 @@ export default defineFakeRoute([ return { success: true, data: { + avatar: "https://avatars.githubusercontent.com/u/44761321", username: "admin", + nickname: "小铭", // 一个用户可能有多个角色 roles: ["admin"], accessToken: "eyJhbGciOiJIUzUxMiJ9.admin", @@ -22,8 +24,9 @@ export default defineFakeRoute([ return { success: true, data: { + avatar: "https://avatars.githubusercontent.com/u/52823142", username: "common", - // 一个用户可能有多个角色 + nickname: "小林", roles: ["common"], accessToken: "eyJhbGciOiJIUzUxMiJ9.common", refreshToken: "eyJhbGciOiJIUzUxMiJ9.commonRefresh", diff --git a/mock/mine.ts b/mock/mine.ts new file mode 100644 index 0000000000..0f89661334 --- /dev/null +++ b/mock/mine.ts @@ -0,0 +1,59 @@ +import { defineFakeRoute } from "vite-plugin-fake-server/client"; +import { faker } from "@faker-js/faker/locale/zh_CN"; + +export default defineFakeRoute([ + // 账户设置-个人信息 + { + url: "/mine", + method: "get", + response: () => { + return { + success: true, + data: { + avatar: "https://avatars.githubusercontent.com/u/44761321", + username: "admin", + nickname: "小铭", + email: "pureadmin@163.com", + phone: "15888886789", + description: "一个热爱开源的前端工程师" + } + }; + } + }, + // 账户设置-个人安全日志 + { + url: "/mine-logs", + method: "get", + response: () => { + let list = [ + { + id: 1, + ip: faker.internet.ipv4(), + address: "中国河南省信阳市", + system: "macOS", + browser: "Chrome", + summary: "账户登录", // 详情 + operatingTime: new Date() // 时间 + }, + { + id: 2, + ip: faker.internet.ipv4(), + address: "中国广东省深圳市", + system: "Windows", + browser: "Firefox", + summary: "绑定了手机号码", + operatingTime: new Date().setDate(new Date().getDate() - 1) + } + ]; + return { + success: true, + data: { + list, + total: list.length, // 总条目数 + pageSize: 10, // 每页显示条目个数 + currentPage: 1 // 当前页数 + } + }; + } + } +]); diff --git a/mock/system.ts b/mock/system.ts index d7b7cf75ff..d34cd5fd8f 100644 --- a/mock/system.ts +++ b/mock/system.ts @@ -9,9 +9,9 @@ export default defineFakeRoute([ response: ({ body }) => { let list = [ { - username: "admin", - nickname: "admin", avatar: "https://avatars.githubusercontent.com/u/44761321", + username: "admin", + nickname: "小铭", phone: "15888886789", email: faker.internet.email(), sex: 0, @@ -27,9 +27,9 @@ export default defineFakeRoute([ createTime: 1605456000000 }, { - username: "common", - nickname: "common", avatar: "https://avatars.githubusercontent.com/u/52823142", + username: "common", + nickname: "小林", phone: "18288882345", email: faker.internet.email(), sex: 1, @@ -397,6 +397,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -420,6 +421,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -443,6 +445,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -466,6 +469,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -489,6 +493,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -512,6 +517,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -535,6 +541,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -558,6 +565,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -581,6 +589,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -604,6 +613,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -627,6 +637,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: true, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -651,6 +662,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -674,6 +686,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -697,6 +710,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -720,6 +734,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -743,6 +758,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -766,6 +782,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -790,6 +807,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -813,6 +831,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -836,6 +855,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -859,6 +879,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -882,6 +903,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -906,6 +928,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -929,6 +952,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -952,6 +976,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -975,6 +1000,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -998,6 +1024,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1022,6 +1049,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1045,6 +1073,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1068,6 +1097,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: false, showParent: false }, @@ -1091,6 +1121,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: false, showParent: false } @@ -1472,6 +1503,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1495,6 +1527,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1518,6 +1551,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1541,6 +1575,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false }, @@ -1564,6 +1599,7 @@ export default defineFakeRoute([ frameLoading: true, keepAlive: false, hiddenTag: false, + fixedTag: false, showLink: true, showParent: false } diff --git a/src/api/user.ts b/src/api/user.ts index 66a797cb9b..79c30ce0cf 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -28,12 +28,56 @@ export type RefreshTokenResult = { }; }; +export type UserInfo = { + /** 头像 */ + avatar: string; + /** 用户名 */ + username: string; + /** 昵称 */ + nickname: string; + /** 邮箱 */ + email: string; + /** 联系电话 */ + phone: string; + /** 简介 */ + description: string; +}; + +export type UserInfoResult = { + success: boolean; + data: UserInfo; +}; + +type ResultTable = { + success: boolean; + data?: { + /** 列表数据 */ + list: Array; + /** 总条目数 */ + total?: number; + /** 每页显示条目个数 */ + pageSize?: number; + /** 当前页数 */ + currentPage?: number; + }; +}; + /** 登录 */ export const getLogin = (data?: object) => { return http.request("post", "/login", { data }); }; -/** 刷新token */ +/** 刷新`token` */ export const refreshTokenApi = (data?: object) => { return http.request("post", "/refresh-token", { data }); }; + +/** 账户设置-个人信息 */ +export const getMine = (data?: object) => { + return http.request("get", "/mine", { data }); +}; + +/** 账户设置-个人安全日志 */ +export const getMineLogs = (data?: object) => { + return http.request("get", "/mine-logs", { data }); +}; diff --git a/src/components/ReCropperPreview/index.ts b/src/components/ReCropperPreview/index.ts new file mode 100644 index 0000000000..e7949feec5 --- /dev/null +++ b/src/components/ReCropperPreview/index.ts @@ -0,0 +1,7 @@ +import reCropperPreview from "./src/index.vue"; +import { withInstall } from "@pureadmin/utils"; + +/** 图片裁剪预览组件 */ +export const ReCropperPreview = withInstall(reCropperPreview); + +export default ReCropperPreview; diff --git a/src/views/system/user/upload.vue b/src/components/ReCropperPreview/src/index.vue similarity index 97% rename from src/views/system/user/upload.vue rename to src/components/ReCropperPreview/src/index.vue index 561013fc32..d567a3521f 100644 --- a/src/views/system/user/upload.vue +++ b/src/components/ReCropperPreview/src/index.vue @@ -3,6 +3,10 @@ import { ref } from "vue"; import ReCropper from "@/components/ReCropper"; import { formatBytes } from "@pureadmin/utils"; +defineOptions({ + name: "ReCropperPreview" +}); + const props = defineProps({ imgSrc: String }); diff --git a/src/components/ReDialog/index.vue b/src/components/ReDialog/index.vue index ba9ba1d005..1db105f535 100644 --- a/src/components/ReDialog/index.vue +++ b/src/components/ReDialog/index.vue @@ -11,6 +11,10 @@ import { isFunction } from "@pureadmin/utils"; import Fullscreen from "@iconify-icons/ri/fullscreen-fill"; import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill"; +defineOptions({ + name: "ReDialog" +}); + const fullscreen = ref(false); const footerButtons = computed(() => { diff --git a/src/components/ReFlop/src/index.vue b/src/components/ReFlop/src/index.vue index b77e0a3a54..52ae7d5cf3 100644 --- a/src/components/ReFlop/src/index.vue +++ b/src/components/ReFlop/src/index.vue @@ -2,6 +2,10 @@ import flippers from "./filpper"; import { ref, unref, nextTick, onUnmounted } from "vue"; +defineOptions({ + name: "ReFlop" +}); + const timer = ref(null); const flipObjs = ref([]); diff --git a/src/components/ReText/src/index.vue b/src/components/ReText/src/index.vue index 427af17432..ecaebdbb8e 100644 --- a/src/components/ReText/src/index.vue +++ b/src/components/ReText/src/index.vue @@ -2,6 +2,10 @@ import { h, onMounted, ref, useSlots } from "vue"; import { type TippyOptions, useTippy } from "vue-tippy"; +defineOptions({ + name: "ReText" +}); + const props = defineProps({ // 行数 lineClamp: { diff --git a/src/layout/components/navbar.vue b/src/layout/components/navbar.vue index 0d3b94088d..174a89e299 100644 --- a/src/layout/components/navbar.vue +++ b/src/layout/components/navbar.vue @@ -8,9 +8,11 @@ import Breadcrumb from "./sidebar/breadCrumb.vue"; import topCollapse from "./sidebar/topCollapse.vue"; import { useTranslationLang } from "../hooks/useTranslationLang"; import globalization from "@/assets/svg/globalization.svg?component"; +import AccountSettingsIcon from "@iconify-icons/ri/user-settings-line"; import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line"; import Setting from "@iconify-icons/ri/settings-3-line"; import Check from "@iconify-icons/ep/check"; + const { layout, device, @@ -21,6 +23,7 @@ const { userAvatar, avatarsStyle, toggleSideBar, + toAccountSettings, getDropdownItemStyle, getDropdownItemClass } = useNav(); @@ -91,6 +94,13 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();