mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-08 17:37:24 +08:00
feat: add user settings page
This commit is contained in:
parent
e1432d7af8
commit
dd28b8de12
@ -1,4 +1,5 @@
|
|||||||
buttons:
|
buttons:
|
||||||
|
hsUserSettings: 账户设置
|
||||||
hsLoginOut: 退出系统
|
hsLoginOut: 退出系统
|
||||||
hsfullscreen: 全屏
|
hsfullscreen: 全屏
|
||||||
hsexitfullscreen: 退出全屏
|
hsexitfullscreen: 退出全屏
|
||||||
|
52
mock/region.ts
Normal file
52
mock/region.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { defineFakeRoute } from "vite-plugin-fake-server/client";
|
||||||
|
|
||||||
|
export default defineFakeRoute([
|
||||||
|
{
|
||||||
|
url: "/get-regions",
|
||||||
|
method: "get",
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
code: "001",
|
||||||
|
name: "中国",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
code: "001001",
|
||||||
|
name: "北京市",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
code: "001001001",
|
||||||
|
name: "东城区"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "001001002",
|
||||||
|
name: "西城区"
|
||||||
|
}
|
||||||
|
// 其他区
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "001002",
|
||||||
|
name: "上海市",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
code: "001002001",
|
||||||
|
name: "黄浦区"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "001002002",
|
||||||
|
name: "徐汇区"
|
||||||
|
}
|
||||||
|
// 其他区
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// 其他城市
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
21
mock/userInfo.ts
Normal file
21
mock/userInfo.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { defineFakeRoute } from "vite-plugin-fake-server/client";
|
||||||
|
|
||||||
|
export default defineFakeRoute([
|
||||||
|
{
|
||||||
|
url: "/get-user-info",
|
||||||
|
method: "get",
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
avatarUrl: "https://avatars.githubusercontent.com/u/44761321",
|
||||||
|
nickName: "企丸丸",
|
||||||
|
introduce: "我是幻兽帕鲁里的NO.1",
|
||||||
|
regionCode: "001002001",
|
||||||
|
address: "体育路冰鸟密域祭坛地下城",
|
||||||
|
userName: "admin"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
@ -23,3 +23,8 @@ export const formUpload = data => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**所在区域数据*/
|
||||||
|
export const getRegions = (params?: object) => {
|
||||||
|
return http.request<Result>("get", "/get-regions", { params });
|
||||||
|
};
|
||||||
|
@ -28,6 +28,20 @@ export type RefreshTokenResult = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UserInfo = {
|
||||||
|
avatarUrl: string;
|
||||||
|
nickName: string;
|
||||||
|
introduce: string;
|
||||||
|
regionCode: string;
|
||||||
|
address: string;
|
||||||
|
userName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UserInfoResult = {
|
||||||
|
success: boolean;
|
||||||
|
data: UserInfo;
|
||||||
|
};
|
||||||
|
|
||||||
/** 登录 */
|
/** 登录 */
|
||||||
export const getLogin = (data?: object) => {
|
export const getLogin = (data?: object) => {
|
||||||
return http.request<UserResult>("post", "/login", { data });
|
return http.request<UserResult>("post", "/login", { data });
|
||||||
@ -37,3 +51,8 @@ export const getLogin = (data?: object) => {
|
|||||||
export const refreshTokenApi = (data?: object) => {
|
export const refreshTokenApi = (data?: object) => {
|
||||||
return http.request<RefreshTokenResult>("post", "/refresh-token", { data });
|
return http.request<RefreshTokenResult>("post", "/refresh-token", { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**获取个人信息 */
|
||||||
|
export const getUserInfo = (data?: object) => {
|
||||||
|
return http.request<UserInfoResult>("get", "/get-user-info", { data });
|
||||||
|
};
|
||||||
|
@ -11,10 +11,13 @@ import globalization from "@/assets/svg/globalization.svg?component";
|
|||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
import Setting from "@iconify-icons/ri/settings-3-line";
|
||||||
import Check from "@iconify-icons/ep/check";
|
import Check from "@iconify-icons/ep/check";
|
||||||
|
import UserSettingsLine from "@iconify-icons/ri/user-settings-line";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
layout,
|
layout,
|
||||||
device,
|
device,
|
||||||
logout,
|
logout,
|
||||||
|
handleOpenUserSettings,
|
||||||
onPanel,
|
onPanel,
|
||||||
pureApp,
|
pureApp,
|
||||||
username,
|
username,
|
||||||
@ -91,6 +94,13 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
|
|||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu class="logout">
|
<el-dropdown-menu class="logout">
|
||||||
|
<el-dropdown-item @click="handleOpenUserSettings">
|
||||||
|
<IconifyIconOffline
|
||||||
|
:icon="UserSettingsLine"
|
||||||
|
style="margin: 5px"
|
||||||
|
/>
|
||||||
|
{{ t("buttons.hsUserSettings") }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item @click="logout">
|
<el-dropdown-item @click="logout">
|
||||||
<IconifyIconOffline
|
<IconifyIconOffline
|
||||||
:icon="LogoutCircleRLine"
|
:icon="LogoutCircleRLine"
|
||||||
|
@ -12,6 +12,7 @@ import globalization from "@/assets/svg/globalization.svg?component";
|
|||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
import Setting from "@iconify-icons/ri/settings-3-line";
|
||||||
import Check from "@iconify-icons/ep/check";
|
import Check from "@iconify-icons/ep/check";
|
||||||
|
import UserSettingsLine from "@iconify-icons/ri/user-settings-line";
|
||||||
|
|
||||||
const menuRef = ref();
|
const menuRef = ref();
|
||||||
|
|
||||||
@ -27,7 +28,8 @@ const {
|
|||||||
userAvatar,
|
userAvatar,
|
||||||
avatarsStyle,
|
avatarsStyle,
|
||||||
getDropdownItemStyle,
|
getDropdownItemStyle,
|
||||||
getDropdownItemClass
|
getDropdownItemClass,
|
||||||
|
handleOpenUserSettings
|
||||||
} = useNav();
|
} = useNav();
|
||||||
|
|
||||||
const defaultActive = computed(() =>
|
const defaultActive = computed(() =>
|
||||||
@ -107,6 +109,10 @@ nextTick(() => {
|
|||||||
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
|
<el-dropdown-item @click="handleOpenUserSettings">
|
||||||
|
<IconifyIconOffline :icon="UserSettingsLine" style="margin: 5px" />
|
||||||
|
{{ t("buttons.hsUserSettings") }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-menu class="logout">
|
<el-dropdown-menu class="logout">
|
||||||
<el-dropdown-item @click="logout">
|
<el-dropdown-item @click="logout">
|
||||||
<IconifyIconOffline
|
<IconifyIconOffline
|
||||||
|
@ -15,6 +15,7 @@ import globalization from "@/assets/svg/globalization.svg?component";
|
|||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
import Setting from "@iconify-icons/ri/settings-3-line";
|
||||||
import Check from "@iconify-icons/ep/check";
|
import Check from "@iconify-icons/ep/check";
|
||||||
|
import UserSettingsLine from "@iconify-icons/ri/user-settings-line";
|
||||||
|
|
||||||
const menuRef = ref();
|
const menuRef = ref();
|
||||||
const defaultActive = ref(null);
|
const defaultActive = ref(null);
|
||||||
@ -31,7 +32,8 @@ const {
|
|||||||
getDivStyle,
|
getDivStyle,
|
||||||
avatarsStyle,
|
avatarsStyle,
|
||||||
getDropdownItemStyle,
|
getDropdownItemStyle,
|
||||||
getDropdownItemClass
|
getDropdownItemClass,
|
||||||
|
handleOpenUserSettings
|
||||||
} = useNav();
|
} = useNav();
|
||||||
|
|
||||||
function getDefaultActive(routePath) {
|
function getDefaultActive(routePath) {
|
||||||
@ -140,6 +142,10 @@ watch(
|
|||||||
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
<p v-if="username" class="dark:text-white">{{ username }}</p>
|
||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
|
<el-dropdown-item @click="handleOpenUserSettings">
|
||||||
|
<IconifyIconOffline :icon="UserSettingsLine" style="margin: 5px" />
|
||||||
|
{{ t("buttons.hsUserSettings") }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-menu class="logout">
|
<el-dropdown-menu class="logout">
|
||||||
<el-dropdown-item @click="logout">
|
<el-dropdown-item @click="logout">
|
||||||
<IconifyIconOffline
|
<IconifyIconOffline
|
||||||
|
64
src/layout/components/userSettings/index.vue
Normal file
64
src/layout/components/userSettings/index.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, onBeforeUnmount } from "vue";
|
||||||
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
|
import leftLine from "@iconify-icons/ri/arrow-left-s-line";
|
||||||
|
import userLine from "@iconify-icons/ri/user-3-line";
|
||||||
|
import profileLine from "@iconify-icons/ri/profile-line";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { getUserInfo } from "@/api/user";
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const { userAvatar, getLogo, username } = useNav();
|
||||||
|
const defaultActive = ref<string>(route.path as string);
|
||||||
|
const userInfo = ref({
|
||||||
|
nickName: "",
|
||||||
|
avatarUrl: "",
|
||||||
|
userName: ""
|
||||||
|
});
|
||||||
|
getUserInfo().then(res => {
|
||||||
|
userInfo.value = res.data;
|
||||||
|
});
|
||||||
|
const handleBack = () => {
|
||||||
|
router.go(-1);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-container class="h-full py-8">
|
||||||
|
<el-aside class="w-70 pure-border-color px-4">
|
||||||
|
<el-menu :default-active="defaultActive" router>
|
||||||
|
<el-menu-item class="flex items-center" @click="handleBack">
|
||||||
|
<IconifyIconOffline :icon="leftLine" />
|
||||||
|
<img :src="getLogo()" class="w-6 h-6" alt="logo" />
|
||||||
|
<span class="ml-2">返回</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<li class="flex items-center ml-8 mt-4">
|
||||||
|
<div>
|
||||||
|
<el-avatar :size="80" :src="userInfo.avatarUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<p>{{ userInfo.nickName }}</p>
|
||||||
|
<el-text class="mt-2" type="info">{{ userInfo.userName }}</el-text>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<el-menu-item index="/user-settings/user-info-manage">
|
||||||
|
<el-icon><IconifyIconOffline :icon="userLine" /></el-icon>
|
||||||
|
<span>基本设置</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/user-settings/safe-manage">
|
||||||
|
<el-icon><IconifyIconOffline :icon="profileLine" /></el-icon>
|
||||||
|
<span>安全设置</span>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-aside>
|
||||||
|
<el-main>
|
||||||
|
<router-view />
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pure-border-color {
|
||||||
|
border-color: var(--pure-border-color); /* 使用边框颜色变量 */
|
||||||
|
}
|
||||||
|
</style>
|
7
src/layout/components/userSettings/safeManage.vue
Normal file
7
src/layout/components/userSettings/safeManage.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>安全设置</template>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
184
src/layout/components/userSettings/userInfoManage.vue
Normal file
184
src/layout/components/userSettings/userInfoManage.vue
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
// [TO DO] 只有销毁dialog,再修改cropper src,编辑的图片才变。
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
|
import uploadLine from "@iconify-icons/ri/upload-line";
|
||||||
|
import CroppingUpload from "@/views/system/user/upload.vue";
|
||||||
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
|
import { formUpload } from "@/api/mock";
|
||||||
|
import { message } from "@/utils/message";
|
||||||
|
import { createFormData } from "@pureadmin/utils";
|
||||||
|
import { getRegions } from "@/api/mock";
|
||||||
|
import { getUserInfo, UserInfo } from "@/api/user";
|
||||||
|
const { userAvatar, getLogo, username } = useNav();
|
||||||
|
const cropRef = ref();
|
||||||
|
const upload = ref();
|
||||||
|
const isShow = ref(false);
|
||||||
|
const userInfoFormRef = ref<FormInstance>();
|
||||||
|
// 从服务器拉取用户信息,然后填充表单
|
||||||
|
|
||||||
|
const userInfoFormData = reactive({
|
||||||
|
avatarUrl: "",
|
||||||
|
nickName: "",
|
||||||
|
introduce: "",
|
||||||
|
regionCode: "",
|
||||||
|
address: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
getUserInfo().then(res => {
|
||||||
|
Object.assign(userInfoFormData, res.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive<FormRules<UserInfo>>({
|
||||||
|
nickName: [
|
||||||
|
{ required: true, message: "昵称必填", trigger: "blur" },
|
||||||
|
{ min: 3, max: 5, message: "长度最小3最大16", trigger: "blur" }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const imgSrc = ref("");
|
||||||
|
const onChange = uploadFile => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = e => {
|
||||||
|
imgSrc.value = e.target.result as string;
|
||||||
|
isShow.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// reader.onloadend = () => {
|
||||||
|
// cropRef.value.init();
|
||||||
|
// };
|
||||||
|
reader.readAsDataURL(uploadFile.raw);
|
||||||
|
/* imgSrc.value = uploadFile.row;
|
||||||
|
isShow.value = true; */
|
||||||
|
};
|
||||||
|
|
||||||
|
let cropperInfo: any;
|
||||||
|
const onCropper = info => {
|
||||||
|
cropperInfo = info;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
cropRef.value.hidePopover();
|
||||||
|
upload.value.clearFiles();
|
||||||
|
isShow.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 在编辑弹框中上传图片,获取在服务器上的url,
|
||||||
|
const handleSubmitImage = () => {
|
||||||
|
const formData = createFormData({
|
||||||
|
files: new File([cropperInfo], "avatar") // file 文件
|
||||||
|
});
|
||||||
|
formUpload(formData)
|
||||||
|
.then(({ success, data }) => {
|
||||||
|
if (success) {
|
||||||
|
message("提交成功", { type: "success" });
|
||||||
|
handleClose();
|
||||||
|
} else {
|
||||||
|
message("提交失败");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
message(`提交异常 ${error}`, { type: "error" });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = ref(); // 级联选择器的选项数据
|
||||||
|
|
||||||
|
// 设置区域数据
|
||||||
|
getRegions().then(res => {
|
||||||
|
options.value = res.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听级联选择器的值变化
|
||||||
|
const handleCascaderChange = value => {
|
||||||
|
console.log(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新基本信息
|
||||||
|
const onSubmit = async (formEl: FormInstance) => {
|
||||||
|
await formEl.validate((valid, fields) => {
|
||||||
|
if (valid) {
|
||||||
|
console.log(userInfoFormData);
|
||||||
|
console.log("验证成功!");
|
||||||
|
} else {
|
||||||
|
console.log("error submit!", fields);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>基本信息</template>
|
||||||
|
<el-form
|
||||||
|
ref="userInfoFormRef"
|
||||||
|
label-position="top"
|
||||||
|
:rules="rules"
|
||||||
|
:model="userInfoFormData"
|
||||||
|
>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<el-avatar :size="80" :src="userAvatar" />
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
action="#"
|
||||||
|
:limit="1"
|
||||||
|
:auto-upload="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="onChange"
|
||||||
|
accept="image/*"
|
||||||
|
>
|
||||||
|
<el-button plain class="ml-4">
|
||||||
|
<IconifyIconOffline :icon="uploadLine" />
|
||||||
|
<span class="ml-2">更新头像</span>
|
||||||
|
</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="昵称" prop="nickName">
|
||||||
|
<el-input v-model="userInfoFormData.nickName" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介">
|
||||||
|
<el-input
|
||||||
|
v-model="userInfoFormData.introduce"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 4, maxRows: 6 }"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所在地区">
|
||||||
|
<el-cascader
|
||||||
|
v-model="userInfoFormData.regionCode"
|
||||||
|
:options="options"
|
||||||
|
:props="{ value: 'code', label: 'name', emitPath: false }"
|
||||||
|
placeholder="请选择"
|
||||||
|
@change="handleCascaderChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="街道地址">
|
||||||
|
<el-input
|
||||||
|
v-model="userInfoFormData.address"
|
||||||
|
placeholder="请输入"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSubmit(userInfoFormRef)"
|
||||||
|
>更新基本信息</el-button
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog
|
||||||
|
v-model="isShow"
|
||||||
|
title="编辑头像"
|
||||||
|
:before-close="handleClose"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<CroppingUpload ref="cropRef" :imgSrc="imgSrc" @cropper="onCropper" />
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmitImage">
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
@ -99,6 +99,10 @@ export function useNav() {
|
|||||||
emitter.emit("openPanel");
|
emitter.emit("openPanel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleOpenUserSettings() {
|
||||||
|
router.push({ name: "UserInfoManage" });
|
||||||
|
}
|
||||||
|
|
||||||
function toggleSideBar() {
|
function toggleSideBar() {
|
||||||
pureApp.toggleSideBar();
|
pureApp.toggleSideBar();
|
||||||
}
|
}
|
||||||
@ -160,6 +164,7 @@ export function useNav() {
|
|||||||
avatarsStyle,
|
avatarsStyle,
|
||||||
tooltipEffect,
|
tooltipEffect,
|
||||||
getDropdownItemStyle,
|
getDropdownItemStyle,
|
||||||
getDropdownItemClass
|
getDropdownItemClass,
|
||||||
|
handleOpenUserSettings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -38,5 +38,29 @@ export default [
|
|||||||
showLink: false,
|
showLink: false,
|
||||||
rank: 103
|
rank: 103
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/user-settings",
|
||||||
|
name: "UserSettings",
|
||||||
|
component: () => import("@/layout/components/userSettings/index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: $t("buttons.hsUserSettings"),
|
||||||
|
showLink: false,
|
||||||
|
rank: 103
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "user-info-manage",
|
||||||
|
name: "UserInfoManage",
|
||||||
|
component: () =>
|
||||||
|
import("@/layout/components/userSettings/userInfoManage.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "safe-manage",
|
||||||
|
name: "SafeManage",
|
||||||
|
component: () =>
|
||||||
|
import("@/layout/components/userSettings/safeManage.vue")
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
] satisfies Array<RouteConfigsTable>;
|
] satisfies Array<RouteConfigsTable>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user