初始版本提交
This commit is contained in:
59
src/views/system/setting/AccountBind.vue
Normal file
59
src/views/system/setting/AccountBind.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<CollapseContainer title="账号绑定" :canExpan="false">
|
||||
<List>
|
||||
<template v-for="item in list" :key="item.key">
|
||||
<ListItem>
|
||||
<ListItemMeta>
|
||||
<template #avatar>
|
||||
<Icon v-if="item.avatar" class="avatar" :icon="item.avatar" :color="item.color" />
|
||||
</template>
|
||||
<template #title>
|
||||
{{ item.title }}
|
||||
<a-button type="link" size="small" v-if="item.extra" class="extra">
|
||||
{{ item.extra }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #description>
|
||||
<div>{{ item.description }} </div>
|
||||
</template>
|
||||
</ListItemMeta>
|
||||
</ListItem>
|
||||
</template>
|
||||
</List>
|
||||
</CollapseContainer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { List } from 'ant-design-vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import Icon from '/@/components/Icon/index';
|
||||
|
||||
import { accountBindList } from './data';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CollapseContainer,
|
||||
List,
|
||||
ListItem: List.Item,
|
||||
ListItemMeta: List.Item.Meta,
|
||||
Icon,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
list: accountBindList,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.avatar {
|
||||
font-size: 40px !important;
|
||||
}
|
||||
|
||||
.extra {
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
margin-right: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
154
src/views/system/setting/BaseSetting.vue
Normal file
154
src/views/system/setting/BaseSetting.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="overflow-y-auto h-full overflow-x-hidden">
|
||||
<CollapseContainer :title="t('基本设置')">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="14">
|
||||
<BasicForm @register="register" />
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<div class="change-avatar">
|
||||
<div class="mb-2"> {{ t('头像') }} </div>
|
||||
<CropperAvatar
|
||||
:btnText="t('更换头像')"
|
||||
:uploadApi="uploadAvatar"
|
||||
:value="avatar"
|
||||
@change="uploadChange"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="handleSubmit"> {{ t('更新基本信息') }} </a-button>
|
||||
</CollapseContainer>
|
||||
<CollapseContainer :title="t('个人资料')">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="14">
|
||||
<a-descriptions :column="1">
|
||||
<a-descriptions-item
|
||||
label="所属组织"
|
||||
:contentStyle="contentStyle"
|
||||
:labelStyle="labelStyle"
|
||||
>
|
||||
<div v-for="item in departmentNameList" :key="item">{{ item }}</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
label="所属角色"
|
||||
:contentStyle="contentStyle"
|
||||
:labelStyle="labelStyle"
|
||||
>
|
||||
<div v-for="item in roleNameList" :key="item">{{ item }}</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
label="所属岗位"
|
||||
:contentStyle="contentStyle"
|
||||
:labelStyle="labelStyle"
|
||||
>
|
||||
<div v-for="item in postNameList" :key="item">{{ item }}</div>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Row, Col } from 'ant-design-vue';
|
||||
import { computed, defineComponent, onMounted, ref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { CropperAvatar } from '/@/components/Cropper';
|
||||
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import headerImg from '/@/assets/images/header.jpg';
|
||||
// import { accountInfoApi } from '/@/api/demo/account';
|
||||
import { baseSetschemas } from './data';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { getUserProfile, updateUserInfo, uploadAvatar } from '/@/api/system/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const contentStyle = { flexDirection: 'column' };
|
||||
const labelStyle = { width: '120px', textAlign: 'right', display: 'block' };
|
||||
export default defineComponent({
|
||||
components: {
|
||||
BasicForm,
|
||||
CollapseContainer,
|
||||
CropperAvatar,
|
||||
[Row.name]: Row,
|
||||
[Col.name]: Col,
|
||||
},
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
const userStore = useUserStore();
|
||||
const id = ref('');
|
||||
const departmentNameList = ref([]);
|
||||
const postNameList = ref([]);
|
||||
const roleNameList = ref([]);
|
||||
|
||||
const [register, { setFieldsValue, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: baseSetschemas,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const data = userStore.getUserInfo;
|
||||
id.value = data.id;
|
||||
setFieldsValue(data);
|
||||
getUserProfile().then((res) => {
|
||||
departmentNameList.value = res.departmentNameList || [];
|
||||
postNameList.value = res.postNameList || [];
|
||||
roleNameList.value = res.roleNameList || [];
|
||||
});
|
||||
});
|
||||
|
||||
const avatar = computed(() => {
|
||||
const { avatar } = userStore.getUserInfo;
|
||||
return avatar || headerImg;
|
||||
});
|
||||
|
||||
return {
|
||||
avatar,
|
||||
register,
|
||||
uploadAvatar,
|
||||
postNameList,
|
||||
roleNameList,
|
||||
departmentNameList,
|
||||
contentStyle,
|
||||
labelStyle,
|
||||
handleSubmit: async () => {
|
||||
const values = await validate();
|
||||
const userInfo = userStore.getUserInfo;
|
||||
|
||||
values.id = id.value;
|
||||
await updateUserInfo(values);
|
||||
|
||||
userInfo.id = id.value;
|
||||
userInfo.name = values.name;
|
||||
userInfo.mobile = values.mobile;
|
||||
userInfo.email = values.email;
|
||||
userInfo.remark = values.remark;
|
||||
userInfo.address = values.address;
|
||||
|
||||
userStore.setUserInfo(userInfo);
|
||||
|
||||
createMessage.success(t('更新成功!'));
|
||||
},
|
||||
uploadChange: (url: string) => {
|
||||
const userInfo = userStore.getUserInfo;
|
||||
userInfo.avatar = url;
|
||||
userStore.setUserInfo(userInfo);
|
||||
},
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.change-avatar {
|
||||
img {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
178
src/views/system/setting/HomeSetting.vue
Normal file
178
src/views/system/setting/HomeSetting.vue
Normal file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<PageLayout
|
||||
layout-class="!pl-0 -ml-14px"
|
||||
:hasOperationSlot="false"
|
||||
:searchConfig="searchConfig"
|
||||
@search="search"
|
||||
@scroll-height="scrollHeight"
|
||||
>
|
||||
<template #search> </template>
|
||||
<template #right>
|
||||
<div v-if="data.dataSource.length > 0">
|
||||
<a-radio-group v-model:value="data.checked" style="width: 100%" @change="handleChange">
|
||||
<a-row
|
||||
:gutter="16"
|
||||
class="list-box"
|
||||
:style="{ overflowY: 'auto', maxHeight: tableOptions.scrollHeight + 70 + 'px' }"
|
||||
:key="data.renderKey"
|
||||
>
|
||||
<a-col :span="6" class="item" v-for="(item, index) in data.dataSource" :key="index">
|
||||
<div class="image relative">
|
||||
<img :src="item.backgroundUrl" />
|
||||
<a-tag color="processing" v-if="item.isFirst" class="absolute right-0 bottom-2"
|
||||
>默认首页</a-tag
|
||||
>
|
||||
</div>
|
||||
<div class="main">
|
||||
<a-radio :value="item.id">{{ item.name }}</a-radio>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
<!-- <div class="page-box">
|
||||
<a-pagination
|
||||
v-model:current="data.pagination.current"
|
||||
:pageSize="data.pagination.pageSize"
|
||||
:total="data.pagination.total"
|
||||
show-less-items
|
||||
@change="getList"
|
||||
/>
|
||||
</div> -->
|
||||
</div>
|
||||
<div v-else>
|
||||
<EmptyBox />
|
||||
</div>
|
||||
</template>
|
||||
</PageLayout>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
|
||||
import { DesktopPageModel } from '/@/api/desktop/model';
|
||||
import { PageLayout, EmptyBox } from '/@/components/ModalPanel';
|
||||
import userTableScrollHeight from '/@/hooks/setting/userTableScrollHeight';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { getRolePrivateHome, setPrivateHome } from '/@/api/system/role';
|
||||
import { notification } from 'ant-design-vue';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const searchConfig = [
|
||||
{
|
||||
field: 'keyword',
|
||||
label: t('关键字'),
|
||||
type: 'input',
|
||||
},
|
||||
];
|
||||
const { tableOptions, scrollHeight } = userTableScrollHeight();
|
||||
let data: {
|
||||
dataSource: Array<DesktopPageModel>;
|
||||
renderKey: number;
|
||||
keyword: string;
|
||||
checked: string;
|
||||
// pagination: {
|
||||
// current: number;
|
||||
// total: number;
|
||||
// pageSize: number;
|
||||
// };
|
||||
} = reactive({
|
||||
dataSource: [],
|
||||
renderKey: 0,
|
||||
//pagination: { current: 1, total: 0, pageSize: 8 },
|
||||
keyword: '',
|
||||
checked: '',
|
||||
});
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.getUserInfo;
|
||||
onMounted(async () => {
|
||||
//data.pagination.current = 1;
|
||||
data.dataSource = [];
|
||||
await getList();
|
||||
setFirstHome();
|
||||
});
|
||||
async function getList() {
|
||||
let params = {
|
||||
//limit: data.pagination.current,
|
||||
//size: data.pagination.pageSize,
|
||||
keyword: data.keyword,
|
||||
};
|
||||
let res = await getRolePrivateHome(params);
|
||||
data.dataSource = res;
|
||||
|
||||
// data.pagination.total = res.total;
|
||||
data.renderKey++;
|
||||
}
|
||||
|
||||
function search(params?: any) {
|
||||
data.keyword = params.keyword;
|
||||
// data.pagination.current = 1;
|
||||
data.dataSource = [];
|
||||
getList();
|
||||
}
|
||||
function setFirstHome() {
|
||||
data.checked = userInfo.desktopSchema.id;
|
||||
}
|
||||
async function handleChange(v) {
|
||||
try {
|
||||
await setPrivateHome({ desktopId: v.target.value });
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('修改首页成功'),
|
||||
});
|
||||
const permissionStore = usePermissionStore();
|
||||
await permissionStore.changePermissionCode();
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t('修改首页失败'),
|
||||
onClose: () => {
|
||||
setFirstHome();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.list-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 10px -8px;
|
||||
|
||||
.ant-row {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-box {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
</style>
|
||||
53
src/views/system/setting/MsgNotify.vue
Normal file
53
src/views/system/setting/MsgNotify.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<CollapseContainer title="新消息通知" :canExpan="false">
|
||||
<List>
|
||||
<template v-for="item in list" :key="item.key">
|
||||
<ListItem>
|
||||
<ListItemMeta>
|
||||
<template #title>
|
||||
{{ item.title }}
|
||||
<Switch
|
||||
class="extra"
|
||||
checked-children="开"
|
||||
un-checked-children="关"
|
||||
default-checked
|
||||
/>
|
||||
</template>
|
||||
<template #description>
|
||||
<div>{{ item.description }} </div>
|
||||
</template>
|
||||
</ListItemMeta>
|
||||
</ListItem>
|
||||
</template>
|
||||
</List>
|
||||
</CollapseContainer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { List, Switch } from 'ant-design-vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
|
||||
import { msgNotifyList } from './data';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CollapseContainer,
|
||||
List,
|
||||
ListItem: List.Item,
|
||||
ListItemMeta: List.Item.Meta,
|
||||
Switch,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
list: msgNotifyList,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.extra {
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
</style>
|
||||
47
src/views/system/setting/SecureSetting.vue
Normal file
47
src/views/system/setting/SecureSetting.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<CollapseContainer title="安全设置" :canExpan="false">
|
||||
<List>
|
||||
<template v-for="item in list" :key="item.key">
|
||||
<ListItem>
|
||||
<ListItemMeta>
|
||||
<template #title>
|
||||
{{ item.title }}
|
||||
<div class="extra" v-if="item.extra">
|
||||
{{ item.extra }}
|
||||
</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<div>{{ item.description }} </div>
|
||||
</template>
|
||||
</ListItemMeta>
|
||||
</ListItem>
|
||||
</template>
|
||||
</List>
|
||||
</CollapseContainer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { List } from 'ant-design-vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
|
||||
import { secureSettingList } from './data';
|
||||
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer, List, ListItem: List.Item, ListItemMeta: List.Item.Meta },
|
||||
setup() {
|
||||
return {
|
||||
list: secureSettingList,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.extra {
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
margin-right: 30px;
|
||||
font-weight: normal;
|
||||
color: #1890ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
114
src/views/system/setting/UpdatePassword.vue
Normal file
114
src/views/system/setting/UpdatePassword.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<CollapseContainer :title="t('密码修改')" :canExpan="false">
|
||||
<div class="flex flex-col items-center justify-center py-8 bg-white">
|
||||
<BasicForm @register="register" />
|
||||
<div class="flex justify-center">
|
||||
<a-button @click="resetFields"> {{ t('重置') }} </a-button>
|
||||
<a-button class="!ml-4" type="primary" @click="handleSubmit"> {{ t('确认') }} </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</CollapseContainer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { BasicForm, useForm, FormSchema } from '/@/components/Form';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { updatePassword } from '/@/api/system/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const pwdScore = ref(0);
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'oldPassword',
|
||||
label: t('当前密码'),
|
||||
component: 'InputPassword',
|
||||
required: true,
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'newPassword',
|
||||
label: t('新密码'),
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
placeholder: t('新密码'),
|
||||
onChange: (_, score) => {
|
||||
pwdScore.value = score;
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('请输入新密码');
|
||||
}
|
||||
if (pwdScore.value < 50) {
|
||||
return Promise.reject('密码强度设置过低,请至少保证中等强度。');
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'confirmPassword',
|
||||
label: t('确认密码'),
|
||||
component: 'InputPassword',
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
|
||||
dynamicRules: ({ values }) => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject(t('密码不能为空'));
|
||||
}
|
||||
if (value !== values.newPassword) {
|
||||
return Promise.reject(t('两次输入的密码不一致!'));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ChangePassword',
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const go = useGo();
|
||||
const [register, { validate, resetFields }] = useForm({
|
||||
size: 'large',
|
||||
labelWidth: 100,
|
||||
showActionButtonGroup: false,
|
||||
schemas: formSchema,
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
// const { passwordOld, passwordNew } = values;
|
||||
|
||||
// TODO custom api
|
||||
await updatePassword(values);
|
||||
|
||||
go(PageEnum.BASE_LOGIN);
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
return { register, resetFields, handleSubmit, t };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
172
src/views/system/setting/data.ts
Normal file
172
src/views/system/setting/data.ts
Normal file
@ -0,0 +1,172 @@
|
||||
import { FormSchema } from '/@/components/Form/index';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
export interface ListItem {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
extra?: string;
|
||||
avatar?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
// tab的list
|
||||
export const settingList = [
|
||||
{
|
||||
key: '1',
|
||||
name: t('基本设置'),
|
||||
component: 'BaseSetting',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: t('密码修改'),
|
||||
component: 'UpdatePassword',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: t('首页设置'),
|
||||
component: 'HomeSetting',
|
||||
},
|
||||
// {
|
||||
// key: '2',
|
||||
// name: '安全设置',
|
||||
// component: 'SecureSetting',
|
||||
// },
|
||||
// {
|
||||
// key: '3',
|
||||
// name: '账号绑定',
|
||||
// component: 'AccountBind',
|
||||
// },
|
||||
// {
|
||||
// key: '4',
|
||||
// name: '新消息通知',
|
||||
// component: 'MsgNotify',
|
||||
// },
|
||||
];
|
||||
|
||||
// 基础设置 form
|
||||
export const baseSetschemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
component: 'Input',
|
||||
label: t('姓名'),
|
||||
colProps: { span: 18 },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'code',
|
||||
component: 'Input',
|
||||
label: t('编码'),
|
||||
colProps: { span: 18 },
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
component: 'Input',
|
||||
label: t('联系电话'),
|
||||
colProps: { span: 18 },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
component: 'Input',
|
||||
label: t('邮箱'),
|
||||
colProps: { span: 18 },
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
component: 'InputTextArea',
|
||||
label: t('备注'),
|
||||
colProps: { span: 18 },
|
||||
},
|
||||
|
||||
{
|
||||
field: 'address',
|
||||
component: 'InputTextArea',
|
||||
label: t('所在地区'),
|
||||
colProps: { span: 18 },
|
||||
},
|
||||
];
|
||||
|
||||
// 安全设置 list
|
||||
export const secureSettingList: ListItem[] = [
|
||||
{
|
||||
key: '1',
|
||||
title: '账户密码',
|
||||
description: '当前密码强度::强',
|
||||
extra: '修改',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
title: '密保手机',
|
||||
description: '已绑定手机::138****8293',
|
||||
extra: '修改',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
title: '密保问题',
|
||||
description: '未设置密保问题,密保问题可有效保护账户安全',
|
||||
extra: '修改',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
title: '备用邮箱',
|
||||
description: '已绑定邮箱::ant***sign.com',
|
||||
extra: '修改',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
title: 'MFA 设备',
|
||||
description: '未绑定 MFA 设备,绑定后,可以进行二次确认',
|
||||
extra: '修改',
|
||||
},
|
||||
];
|
||||
|
||||
// 账号绑定 list
|
||||
export const accountBindList: ListItem[] = [
|
||||
{
|
||||
key: '1',
|
||||
title: '绑定淘宝',
|
||||
description: '当前未绑定淘宝账号',
|
||||
extra: '绑定',
|
||||
avatar: 'ri:taobao-fill',
|
||||
color: '#ff4000',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
title: '绑定支付宝',
|
||||
description: '当前未绑定支付宝账号',
|
||||
extra: '绑定',
|
||||
avatar: 'fa-brands:alipay',
|
||||
color: '#2eabff',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
title: '绑定钉钉',
|
||||
description: '当前未绑定钉钉账号',
|
||||
extra: '绑定',
|
||||
avatar: 'ri:dingding-fill',
|
||||
color: '#2eabff',
|
||||
},
|
||||
];
|
||||
|
||||
// 新消息通知 list
|
||||
export const msgNotifyList: ListItem[] = [
|
||||
{
|
||||
key: '1',
|
||||
title: '账户密码',
|
||||
description: '其他用户的消息将以站内信的形式通知',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
title: '系统消息',
|
||||
description: '系统消息将以站内信的形式通知',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
title: '待办任务',
|
||||
description: '待办任务将以站内信的形式通知',
|
||||
},
|
||||
];
|
||||
73
src/views/system/setting/index.vue
Normal file
73
src/views/system/setting/index.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<ScrollContainer>
|
||||
<PageWrapper dense contentFullHeight fixedHeight>
|
||||
<div ref="wrapperRef" :class="prefixCls">
|
||||
<Tabs tab-position="left" :tabBarStyle="tabBarStyle" class="h-full">
|
||||
<template v-for="item in settingList" :key="item.key">
|
||||
<TabPane :tab="item.name" class="h-full">
|
||||
<component :is="item.component" />
|
||||
</TabPane>
|
||||
</template>
|
||||
</Tabs>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
</ScrollContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Tabs } from 'ant-design-vue';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { ScrollContainer } from '/@/components/Container/index';
|
||||
import { settingList } from './data';
|
||||
|
||||
import BaseSetting from './BaseSetting.vue';
|
||||
import SecureSetting from './SecureSetting.vue';
|
||||
import AccountBind from './AccountBind.vue';
|
||||
import MsgNotify from './MsgNotify.vue';
|
||||
import UpdatePassword from './UpdatePassword.vue';
|
||||
import HomeSetting from './HomeSetting.vue';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ScrollContainer,
|
||||
Tabs,
|
||||
TabPane: Tabs.TabPane,
|
||||
BaseSetting,
|
||||
SecureSetting,
|
||||
AccountBind,
|
||||
MsgNotify,
|
||||
UpdatePassword,
|
||||
HomeSetting,
|
||||
PageWrapper,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
prefixCls: 'account-setting',
|
||||
settingList,
|
||||
tabBarStyle: {
|
||||
width: '220px',
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.account-setting {
|
||||
height: 100%;
|
||||
background-color: @component-background;
|
||||
margin-right: 7px;
|
||||
|
||||
.base-title {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ant-tabs-tab-active {
|
||||
background-color: @item-active-bg;
|
||||
}
|
||||
|
||||
:deep(.ant-tabs-content-holder),
|
||||
:deep(.ant-tabs-content) {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user