完善个人信息配置

This commit is contained in:
龙运模 2024-06-28 13:56:53 +08:00
parent f71caee898
commit 211e4c70b1
15 changed files with 818 additions and 73 deletions

80
src/api/model/user.js Normal file
View File

@ -0,0 +1,80 @@
import config from "@/config";
import http from "@/utils/request";
export default {
getInfo: {
url: `${config.API_URL}/user.bind.info`,
name: "获取绑定(微信、钉钉)个人中心",
post: async function (params) {
return await http.post(this.url, params);
},
},
uploadAvatar:{
url: `${config.API_URL}/user.update.avatar`,
name: "个人头像上传",
post: async function (params) {
return await http.post(this.url, params);
},
},
getInformation:{
url: `${config.API_URL}/user.information`,
name: "获取登录用户个人信息",
post: async function (params) {
return await http.post(this.url, params);
},
},
timeoutConfig:{
url: `${config.API_URL}/system.login.timeout.config`,
name: "登录超时退出配置",
post: async function (params) {
return await http.post(this.url, params);
},
},
timeoutGet:{
url: `${config.API_URL}/system.login.timeout.get`,
name: "获取登录超时时间",
post: async function (params) {
return await http.post(this.url, params);
},
},
subscribe:{
list:{
url: `${config.API_URL}/messages.subscribe.list`,
name: "消息订阅列表",
post: async function (params) {
return await http.post(this.url, params);
},
},
set:{
url: `${config.API_URL}/messages.user.subscribe`,
name: "消息订阅",
post: async function (params) {
return await http.post(this.url, params);
},
}
},
messages:{
list:{
url: `${config.API_URL}/messages.todo.list`,
name: "消息列表",
post: async function (params) {
return await http.post(this.url, params);
},
},
read:{
url: `${config.API_URL}/messages.todo.read`,
name: "消息已读",
post: async function (params) {
return await http.post(this.url, params);
},
},
delete:{
url: `${config.API_URL}/messages.todo.del`,
name: "删除待办消息",
post: async function (params) {
return await http.post(this.url, params);
},
}
}
};

File diff suppressed because one or more lines are too long

13
src/assets/icons/Log.vue Normal file
View File

@ -0,0 +1,13 @@
<template>
<svg t="1719541391658" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2890" width="200" height="200"><path d="M794.30468732 116.4921875H229.69531268A113.20312518 113.20312518 0 0 0 116.4921875 229.69531268v564.60937464A113.20312518 113.20312518 0 0 0 229.69531268 907.5078125h564.60937464A113.20312518 113.20312518 0 0 0 907.5078125 794.30468732V229.69531268A113.20312518 113.20312518 0 0 0 794.30468732 116.4921875z m56.33789098 677.81249982a56.38183559 56.38183559 0 0 1-56.33789097 56.33789097H229.69531268a56.38183559 56.38183559 0 0 1-56.33789098-56.33789097V229.69531268a56.33789097 56.33789097 0 0 1 56.33789097-56.86523421h564.60937465a56.33789097 56.33789097 0 0 1 56.33789097 56.38183559v565.09277326z" p-id="2891"></path><path d="M540.21289088 286.07714826H314.24609375a28.16894549 28.16894549 0 0 0 0 56.33789098h225.87890633a28.16894549 28.16894549 0 0 0 0-56.33789097zM483.83105451 455.66210903H314.29003915A28.16894549 28.16894549 0 0 0 314.24609375 512h169.54101537a28.16894549 28.16894549 0 0 0 0-56.33789097z m-56.33789019 169.54101615H314.24609375a28.16894549 28.16894549 0 0 0 0 56.38183558h113.20312518a28.16894549 28.16894549 0 1 0-1e-8-56.38183559z m290.21484358-338.15917969a27.68554688 27.68554688 0 0 0-35.15624991 19.29199201l-113.15917978 395.5078125a28.21289088 28.21289088 0 0 0 19.24804662 35.11230452h7.91015625a28.12500008 28.12500008 0 0 0 27.24609367-20.25878924l113.15917977-395.5078125a28.21289088 28.21289088 0 0 0-19.24804662-35.15624991v1.01074262z" p-id="2892"></path></svg>
</template>
<script>
export default {
name: "Log"
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,13 @@
<template>
<svg t="1719539812149" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3035" width="200" height="200"><path d="M932.67475344 743.99197344h-81.07032188V485.91012031a379.3941825 379.3941825 0 0 0-275.24466937-381.15310406 66.30603563 66.30603563 0 1 0-131.97246375 0 379.3941825 379.3941825 0 0 0-275.24466938 381.15310406v258.08185313h-80.484015a41.41462219 41.41462219 0 1 0 0 82.882545h256.85593782a165.12548156 165.12548156 0 1 0 330.30426375 0h256.90923843a41.41462219 41.41462219 0 1 0 0-82.882545zM510.64003344 901.44215844a82.24293656 82.24293656 0 0 1-82.24293656-74.62094063h164.53917375a82.24293656 82.24293656 0 0 1-82.29623719 74.62094063z m258.08185312-157.450185H251.9718725V485.91012031c0-166.29809625 118.38079219-300.66909 258.66816094-300.66909 140.28736875 0 258.08185313 134.31769313 258.08185312 300.66909v258.08185313z" p-id="3036"></path></svg>
</template>
<script>
export default {
name: "Notice"
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,13 @@
<template>
<svg t="1719539572083" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3320" width="200" height="200"><path d="M790.072889 348.16h-32.426667V258.161778c0-131.128889-110.136889-237.624889-245.475555-237.624889C376.376889 20.48 266.24 126.862222 266.24 258.104889V348.16h-32.426667a151.722667 151.722667 0 0 0-151.893333 151.495111v352.995556a151.324444 151.324444 0 0 0 151.893333 150.869333h556.373334c83.569778 0 151.893333-67.584 151.893333-150.869333V498.915556a151.096889 151.096889 0 0 0-151.893333-150.755556zM348.216889 258.161778C348.16 172.316444 421.774222 102.4 512.284444 102.4c90.225778 0 163.612444 69.802667 163.612445 155.704889V341.902222H348.16V258.104889z m512 594.488889c0 38.001778-31.402667 69.006222-70.030222 69.006222H233.870222c-38.570667 0-69.973333-30.890667-69.973333-69.006222V499.598222c0-38.286222 31.402667-69.518222 69.973333-69.518222h556.316445c38.627556 0 69.973333 30.947556 69.973333 69.006222v353.507556z" p-id="3321"></path><path d="M512 552.96a41.130667 41.130667 0 0 0-40.96 41.016889v163.84c0 22.471111 18.375111 40.96 40.96 40.96 22.528 0 40.96-18.375111 40.96-40.96V593.92A41.073778 41.073778 0 0 0 512 552.96z" p-id="3322"></path></svg>
</template>
<script>
export default {
name: "Password"
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,13 @@
<template>
<svg t="1719539829038" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3177" width="200" height="200"><path d="M512 32L97.38666687 201.33333313v367.19999999a425.22666656 425.22666656 0 0 0 92.47999969 266.40000001 409.06666688 409.06666688 0 0 0 644.05333313 0 429.6 429.6 0 0 0 92.53333406-266.4V201.33333313L512 32z m-37.33333312 892.37333344l-12-1.75999969c-8.10666656-1.33333313-16.37333344-2.4-24.42666657-4.37333344-4.58666625 0-9.17333344-2.4-13.76000062-3.46666687a361.97333344 361.97333344 0 0 1-21.86666625-6.34666688c-7.36000031-2.4-9.33333375-3.46666688-13.92-5.22666656a443.20000031 443.20000031 0 0 1-20.26666688-8.53333313l-13.54666687-6.72a237.06666656 237.06666656 0 0 1-19.2-10.66666687l-12.63999938-7.89333375c-6.34666687-4.15999969-12.26666625-8.74666687-18.34666687-13.33333313-6.13333313-4.53333375-7.84000031-5.65333313-11.57333344-8.69333343-3.73333313-3.09333375-12-10.66666687-17.86666687-16.15999969l-9.81333282-9.38666625-2.4-2.61333375a272.53333313 272.53333313 0 0 1 149.01333281-155.73333375 261.81333375 261.81333375 0 0 1 199.62666657 0 271.41333375 271.41333375 0 0 1 148.8 155.9466675l-2.4 2.66666625-10.23999938 9.6a382.39999969 382.39999969 0 0 1-17.28 15.67999969c-5.86666687 5.01333375-7.99999969 6.07999969-12 9.12a411.19999969 411.19999969 0 0 1-17.86666687 12.90666656l-13.06666688 8.05333406c-6.13333313 3.73333313-12.48 7.2-18.77333343 10.50666656-6.34666687 3.25333313-9.17333344 4.8-13.97333344 6.93333282l-19.83999938 8.32000031c-4.58666625 1.75999969-9.38666625 3.73333313-14.18666719 5.22666656-4.8 1.54666687-14.18666625 4.37333344-21.86666625 6.34666688-7.62666656 1.97333344-9.33333375 2.61333375-13.92 3.46666687-8.10666656 1.97333344-16.15999969 3.04000031-24.42666656 4.37333344l-12 1.75999969c-12.21333375 1.33333313-24.42666656 2.08000031-36.69333375 2.13333281a355.94666625 355.94666625 0 0 1-37.33333312-2.13333281z m36.63999937-349.12000032A104.10666656 104.10666656 0 1 1 611.73333313 471.46666625a102.07999969 102.07999969 0 0 1-99.73333313 103.2l-0.64000031 0.64000031z m349.12000031-6.07999968a366.29333344 366.29333344 0 0 1-54.77333344 192 335.35999969 335.35999969 0 0 0-169.33333312-157.54666688 226.24000031 226.24000031 0 0 0-15.67999969-5.65333312 169.97333344 169.97333344 0 0 0 55.83999938-126.55999969 165.86666625 165.86666625 0 0 0-331.62666657 0 169.75999969 169.75999969 0 0 0 58.02666657 126.13333312l-14.82666657 5.43999938A337.33333313 337.33333313 0 0 0 218.66666656 760.53333312a358.93333312 358.93333312 0 0 1-55.84000031-192V245.33333375l349.06666688-142.66666687 349.12000031 142.71999937-0.64000032 323.73333375z" p-id="3178"></path></svg>
</template>
<script>
export default {
name: "Secure"
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,24 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="54" viewBox="0 0 54 54" fill="none">
<g clip-path="url(#clip0_3488_24635)">
<circle cx="27" cy="27" r="27" fill="white"/>
<path d="M17.8433 17.9219C16.9042 17.9219 15.9651 18.548 15.9651 19.4871C15.9651 20.4262 16.9042 21.0523 17.8433 21.0523C18.7825 21.0523 19.4086 20.4262 19.4086 19.4871C19.4086 18.5088 18.7825 17.9219 17.8433 17.9219ZM30.5607 27.0001C29.9347 27.0001 29.3477 27.6654 29.3477 28.2523C29.3477 28.9175 29.9738 29.5045 30.5607 29.5045C31.4999 29.5045 32.126 28.8784 32.126 28.2523C32.126 27.6262 31.4999 27.0001 30.5607 27.0001ZM26.5303 21.0523C27.4694 21.0523 28.0955 20.3871 28.0955 19.4871C28.0955 18.548 27.4694 17.9219 26.5303 17.9219C25.5912 17.9219 24.652 18.548 24.652 19.4871C24.652 20.4262 25.5912 21.0523 26.5303 21.0523ZM37.3694 27.0001C36.7434 27.0001 36.1564 27.6654 36.1564 28.2523C36.1564 28.9175 36.7825 29.5045 37.3694 29.5045C38.3086 29.5045 38.9347 28.8784 38.9347 28.2523C38.9347 27.6262 38.3086 27.0001 37.3694 27.0001Z" fill="#28C445"/>
<path d="M27 0C12.0913 0 0 12.0913 0 27C0 41.9087 12.0913 54 27 54C41.9087 54 54 41.9087 54 27C54 12.0913 41.9087 0 27 0ZM21.8739 33.9261C20.3087 33.9261 19.0565 33.613 17.5696 33.2609L13.2652 35.4522L14.4783 31.6565C11.387 29.4652 9.50869 26.6087 9.5087 23.2043C9.5087 17.2174 15.1043 12.5217 21.8739 12.5217C27.9391 12.5217 33.3 16.2783 34.3565 21.3261C33.9652 21.287 33.5739 21.2478 33.1826 21.2478C27.313 21.3261 22.6957 25.7478 22.6957 31.2261C22.6957 32.1261 22.8522 32.987 23.087 33.8478C22.6957 33.887 22.2652 33.9261 21.8739 33.9261ZM40.187 38.3087L41.1261 41.4391L37.7609 39.5609C36.5478 39.8739 35.2957 40.187 34.0435 40.187C28.1348 40.187 23.4783 36.1174 23.4783 31.0696C23.4391 26.0609 28.0957 21.9913 33.9652 21.9913C39.5609 21.9913 44.4913 26.1 44.4913 31.1087C44.4913 33.9261 42.6522 36.4304 40.187 38.3087Z" fill="#28C445"/>
</g>
<defs>
<clipPath id="clip0_3488_24635">
<rect width="54" height="54" fill="white"/>
</clipPath>
</defs>
</svg>
</template>
<script>
export default {
name: "WechartRound"
}
</script>
<style scoped>
</style>

View File

@ -14,6 +14,12 @@ export { default as Bell } from './Bell.vue'
export { default as Full } from './Full.vue' export { default as Full } from './Full.vue'
export { default as Refresh } from './Refresh.vue' export { default as Refresh } from './Refresh.vue'
export { default as Search } from './Search.vue' export { default as Search } from './Search.vue'
export { default as Account } from './Account.vue'
export { default as Notice } from './Notice.vue'
export { default as Password } from './Password.vue'
export { default as Secure } from './Secure.vue'
export { default as UserLog } from './Log.vue'
export { default as WechartRound } from './WechartRound.vue'
export { default as Home } from './menu/Home.vue' export { default as Home } from './menu/Home.vue'
export { default as Setup } from './menu/Setup.vue' export { default as Setup } from './menu/Setup.vue'

View File

@ -2,8 +2,7 @@
.userAside{ .userAside{
border-right: 0; border-right: 0;
.el-header{ .el-header{
margin-bottom: 10px; border-bottom: 1px solid #f2f2f2;
border-bottom: 0;
background: var(--el-bg-color-overlay); background: var(--el-bg-color-overlay);
border-top-left-radius: 6px; border-top-left-radius: 6px;
border-top-right-radius: 6px; border-top-right-radius: 6px;
@ -41,7 +40,7 @@
box-sizing: border-box; box-sizing: border-box;
.el-card{ .el-card{
border:0; border:0;
height: 100%; height: calc(100%);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.el-card__header{ .el-card__header{
@ -53,7 +52,7 @@
} }
.el-card__body{ .el-card__body{
flex: 1; flex: 1;
padding: 20px 10px 0 10px; padding: 10px 10px 0 10px;
overflow: hidden; overflow: hidden;
.nopadding{ .nopadding{
height: 100%; height: 100%;

View File

@ -7,7 +7,7 @@
<el-avatar :size="70" src="img/avatar.jpg"></el-avatar> <el-avatar :size="70" src="img/avatar.jpg"></el-avatar>
<div class="userView"> <div class="userView">
<h2 class="name">{{ user.userName }}</h2> <h2 class="name">{{ user.userName }}</h2>
<p><el-tag effect="dark" round size="large" disable-transitions>{{ user.role }}</el-tag></p> <p><el-tag round effect="plain" size="small" disable-transitions>{{ user.role }}</el-tag></p>
</div> </div>
</div> </div>
</el-header> </el-header>
@ -50,65 +50,61 @@
password: defineAsyncComponent(() => import('./user/password')), password: defineAsyncComponent(() => import('./user/password')),
space: defineAsyncComponent(() => import('./user/space')), space: defineAsyncComponent(() => import('./user/space')),
logs: defineAsyncComponent(() => import('./user/logs')), logs: defineAsyncComponent(() => import('./user/logs')),
upToEnterprise: defineAsyncComponent(() => import('./user/upToEnterprise')) upToEnterprise: defineAsyncComponent(() => import('./user/upToEnterprise')),
bind: defineAsyncComponent(() => import('./user/bind')),
}, },
data() { data() {
return { return {
menu: [ menu: [
{ {
groupName: "基本设置", groupName: "账号设置",
list: [ list: [
{ {
icon: "el-icon-postcard", icon: "sc-icon-Account",
title: "账号信息", title: "账号信息",
component: "account" component: "account"
}, },
{ {
icon: "el-icon-operation", icon: "sc-icon-Password",
title: "个人设置",
component: "seting"
},
{
icon: "el-icon-lock",
title: "密码", title: "密码",
component: "password" component: "password"
}, },
{ {
icon: "el-icon-bell", icon: "sc-icon-Notice",
title: "通知设置", title: "通知设置",
component: "pushSettings" component: "pushSettings"
} },
{
icon: "sc-icon-Secure",
title: "账户安全",
component: "bind"
},
] ]
}, },
{ {
groupName: "数据管理", groupName: "数据管理",
list: [ list: [
{ {
icon: "el-icon-coin", icon: "sc-icon-UserLog",
title: "存储空间信息",
component: "space"
},
{
icon: "el-icon-clock",
title: "操作日志", title: "操作日志",
component: "logs" component: "logs"
} }
] ]
}, },
{ // {
groupName: "账号升级", // groupName: "",
list: [ // list: [
{ // {
icon: "el-icon-office-building", // icon: "el-icon-office-building",
title: "升级为企业账号", // title: "",
component: "upToEnterprise" // component: "upToEnterprise"
} // }
] // ]
} // }
], ],
user: { user: {
userName: "Sakuya", userName: "龙隆",
role: "超级管理员", role: "管理员",
}, },
page: "account" page: "account"
} }

View File

@ -1,21 +1,18 @@
<template> <template>
<el-alert title="异步组件动态加载使用了正处于试验阶段的<Suspense>组件, 其API和使用方式可能会改变. <Suspense> is an experimental feature and its API will likely change." type="warning" show-icon style="margin-bottom: 15px;"/> <el-card shadow="never" header="账户信息">
<el-form ref="form" :model="form" label-width="90px" style="margin-top:10px;width: 518px;">
<el-card shadow="never" header="个人信息">
<el-form ref="form" :model="form" label-width="120px" style="margin-top:20px;">
<el-form-item label="账号"> <el-form-item label="账号">
<el-input v-model="form.user" disabled></el-input> <el-input v-model="form.user" disabled></el-input>
<div class="el-form-item-msg">账号信息用于登录系统不允许修改</div> <div class="el-form-item-msg">账号信息用于登录系统不允许修改</div>
</el-form-item> </el-form-item>
<el-form-item label="姓名"> <el-form-item label="手机号码">
<el-input v-model="form.mobile"></el-input>
</el-form-item>
<el-form-item label="真实姓名">
<el-input v-model="form.name"></el-input> <el-input v-model="form.name"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="性别"> <el-form-item label="邮箱地址">
<el-select v-model="form.sex" placeholder="请选择"> <el-input v-model="form.email"></el-input>
<el-option label="保密" value="0"></el-option>
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="个性签名"> <el-form-item label="个性签名">
<el-input v-model="form.about" type="textarea"></el-input> <el-input v-model="form.about" type="textarea"></el-input>
@ -34,7 +31,8 @@
form: { form: {
user: "administrator@scuiadmin.com", user: "administrator@scuiadmin.com",
name: "Sakuya", name: "Sakuya",
sex: "0", mobile:'18828382888',
email:'',
about: "正所谓富贵险中求" about: "正所谓富贵险中求"
} }
} }

View File

@ -0,0 +1,398 @@
<template>
<el-card shadow="never" header="账户安全">
<div class="bindBxo">
<div class="title" style="margin-top: 5px;">账号绑定</div>
<div class="boxView">
<div class="leftImg">
<div class="leftIcon wechat" v-if="wechat.open_id=='' || wechat.avatar==''"><i class="el-icon"><sc-icon-WechartRound/></i></div>
<div class="leftIcon" v-else>
<el-avatar :size="38" :src="wechat.avatar" />
</div>
<div class="nameBox">
<div class="titleName nameRed" v-if="wechat.open_id==''">绑定微信</div>
<div class="titleName" v-else>{{wechat.nick_name==""?'-':wechat.nick_name}}</div>
<div class="msg">绑定微信用于账号登录,客服咨询及其它消息提醒</div>
</div>
</div>
<div class="rightBtn">
<el-button type="primary" :size="size" round v-if="wechat.open_id==''" @click="bindWechat">绑定</el-button>
<el-button type="primary" :size="size" round v-else plain @click="secureDingTalk(1)">解除</el-button>
</div>
</div>
<div class="boxView">
<div class="leftImg">
<div class="leftIcon alipay" v-if="dingTalk.open_id=='' || dingTalk.avatar==''"><i class="el-icon"><sc-icon-DingTalk/></i></div>
<div class="leftIcon" v-else>
<el-avatar :size="38" :src="dingTalk.avatar" />
</div>
<div class="nameBox">
<div class="titleName nameRed" v-if="dingTalk.open_id==''">绑定钉钉</div>
<div class="titleName" v-else>{{dingTalk.nick_name==""?'-':dingTalk.nick_name}}</div>
<div class="msg">绑定钉钉用于账号登录</div>
</div>
</div>
<div class="rightBtn">
<el-button type="primary" :size="size" round v-if="dingTalk.open_id==''" @click="bindDingTalk">绑定</el-button>
<el-button type="primary" :size="size" round v-else plain @click="secureDingTalk(2)">解除</el-button>
</div>
</div>
<div class="title">安全登录</div>
<div class="boxView boxViewCenter">
<div class="leftBox">允许多地登录</div>
<div class="rightBox">
<el-radio-group v-model="multipleLocation" @change="multipleLocationSet">
<el-radio :label="true">允许多地</el-radio>
<el-radio :label="false">限制单设备</el-radio>
</el-radio-group>
</div>
</div>
<div class="title">OA能力</div>
<div class="boxView boxViewCenter">
<div class="leftBox">启用阿里企业邮箱功能</div>
<div class="rightBox">
<el-radio-group v-model="multipleLocation" @change="multipleLocationSet">
<el-radio :label="true">启用</el-radio>
<el-radio :label="false">禁用</el-radio>
</el-radio-group>
</div>
</div>
<div class="title">使用Passkey</div>
<div class="boxView boxViewCenter">
<div class="nameBox passkeyView">
<el-button type="primary" round :size="size" @click="createPasskey">添加指纹</el-button>
<div class="msg">借助 Passkey你可以使用自己的指纹面孔屏锁设置或实体安全密钥登录你的账号请仅在你自有的设备上设置 Passkey</div>
</div>
</div>
</div>
</el-card>
<el-dialog
v-model="showWechatLogin"
title="微信绑定"
:width="500"
destroy-on-close
>
<div class="qrCodeLogin">
<div class="code_container">
<object :data="WechatLoginCode" width="430" height="430" type="text/html"></object>
</div>
<p class="error" v-if="bind_wechat_error!=''">{{bind_wechat_error}}请先解绑原账号绑定</p>
<p class="msg">
请使用微信扫一扫绑定
</p>
<div class="qrCodeLogin-result" v-if="isWechatLoginResult">
<el-result
icon="success"
title="绑定成功"
sub-title="您可以使用微信扫码登录了"
></el-result>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
data() {
return {
size:'', // small
wechat:{
avatar:'',
nick_name:'',
open_id:''
},
dingTalk:{
avatar:'',
nick_name:'',
open_id:'',
},
WechatLoginCode:'',
showWechatLogin:false,
isWechatLoginResult: false,
bind_wechat_error:'',
multipleLocation:false,
userInfo:{},
}
},
created() {
// addEventListener
window.addEventListener('storage',this.wechatStorageChange);
},
mounted() {
const userInfo = this.$TOOL.data.get("USER_INFO");
this.userInfo = userInfo;
// this.getUserInfo();
// this.getSso();
//
// this.$socketApi.getSock(this.getWsResult);
},
beforeUnmount() {
window.removeEventListener('storage', this.wechatStorageChange);
},
watch:{
},
methods:{
async getSso(){
const res = await this.$API.system.sso.get.post();
if(res.code == 200){
if(res.data.options){
this.multipleLocation = res.data.options.is_sso_login;
}
}
},
async multipleLocationSet(){
const res = await this.$API.system.sso.setup.post({is_sso_login:this.multipleLocation});
if(res.code == 200){
this.$message.success('配置成功');
}
},
getWsResult(res){
if(res.type == 7){
this.isWechatLoginResult = true;
setTimeout(()=>{
this.showWechatLogin = false;
this.getUserInfo();
},2000)
}
if(res.type == 12){
this.bind_wechat_error = res.msg;
}
},
async bindWechat(){
this.isWechatLoginResult = false;
const res = await this.$API.auth.bindWechat.post();
if(res.code == 200){
const url = JSON.parse(JSON.stringify(res.data.qrcode));
localStorage.setItem('bindWechat','2');
this.WechatLoginCode = url;
this.showWechatLogin = true;
}
},
async bindDingTalk(){
const res = await this.$API.auth.bindDingTalk.post();
if(res.code == 200){
const url = JSON.parse(JSON.stringify(res.data.redirect));
localStorage.setItem('bindDingTalk','2');
window.open(url);
}
},
wechatStorageChange(e){
let dingTalk = localStorage.getItem('bindDingTalk');
let wechat = localStorage.getItem('bindWechat');
if(e.key == 'DINGTALK_LOGIN_MESSAGE'){
if(dingTalk == 2 && typeof e.newValue =="string" && e.newValue!=''){
this.dingTalkBind(e.newValue)
}
localStorage.removeItem("DINGTALK_LOGIN_MESSAGE");
}
if(e.key == 'WECHAT_LOGIN_MESSAGE'){
if(wechat == 2 && typeof e.newValue =="string" && e.newValue!=''){
this.wechatBind(e.newValue);
}
localStorage.removeItem("WECHAT_LOGIN_MESSAGE");
}
},
wechatBind(){
},
async dingTalkBind(e){
let item = JSON.parse(e);
let params = {code:item.code,state:item.state}
const res = await this.$API.auth.bindDingTalkUser.post(params);
if(res.code == 200){
await this.getUserInfo()
}
},
async secureDingTalk(num){
let params = {app_type:num}
const res = await this.$API.auth.unbindUser.post(params);
if(res.code == 200){
await this.getUserInfo();
}
},
async getUserInfo(){
const res = await this.$API.user.getInfo.post();
if(res.code == 200){
this.wechat={
avatar:'',
nick_name:'',
open_id:''
}
this.dingTalk={
avatar:'',
nick_name:'',
open_id:''
}
if(res.data && res.data.length){
res.data.forEach(em=>{
if(em.app_type == 1){
this.wechat = em;
}
if(em.app_type ==2){
this.dingTalk = em;
}
})
}
}
},
//
async createPasskey() {
try {
const res = await this.$API.system.user.generateRegistration.post();
const publicKey= {
challenge:Uint8Array.from(res.data.challenge),
rp:{
name:res.data.rp.name,
id:res.data.rp.id
},
user:{
id:Uint8Array.from(res.data.user.id),
name:res.data.user.name,
displayName:res.data.user.displayName,
},
pubKeyCredParams:res.data.pubKeyCredParams,
authenticatorSelection:{
authenticatorAttachment:'',
userVerification:res.data.authenticatorSelection.userVerification,
},
timeout:res.data.timeout,
attestation:res.data.attestation
};
const credential = await navigator.credentials.create({ publicKey });
await this.storeCredential(credential);
} catch (error) {
this.$message.warning('创建通行秘钥失败');
}
},
async storeCredential(credential){
const params = {
id: credential.id,
rawId: this.bufferToBase64URL(credential.rawId),
type: credential.type,
response: {
clientDataJSON: this.bufferToBase64URL(credential.response.clientDataJSON),
attestationObject: this.bufferToBase64URL(credential.response.attestationObject),
},
authenticatorAttachment: credential.authenticatorAttachment,
}
const res = await this.$API.system.user.verifyResponse.post(params);
console.log(res,55)
// this.$message.success('');
},
bufferToBase64URL(buffer) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");
},
}
}
</script>
<style lang="scss" scoped>
.bindBxo{
padding: 0 10px;
.title{
font-size: 14px;
font-weight: 500;
margin: 25px 0 10px 0;
}
}
.boxView{
width: 460px;
display: flex;
align-items: end;
justify-content: space-between;
margin-top: 10px;
margin-left: 5px;
.leftImg{
display: flex;
align-items: center;
.leftIcon{
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-items: center;
margin-right: 10px;
.el-icon{
font-size: 34px;
}
}
.titleName{
margin-bottom: 5px;
font-size: var(--el-font-size-base);
}
.nameRed{
color: var(--el-color-danger);
}
.msg{
font-size: var(--el-font-size-extra-small);
color: #837e7e;
}
}
}
.boxViewCenter{
align-items: center;
.leftBox{
font-size: var(--el-font-size-base);
}
}
.bandTime{
align-items: baseline;
.tip{
margin-top: 6px;
color: #999;
}
}
.qrCodeLogin {
text-align: center;
position: relative;
padding: 0 0 20px 0;
}
.code_container{
width: 430px;
height:430px;
margin: 0 auto;
}
.qrCodeLogin img.qrCode {
background: #fff;
padding: 20px;
border-radius: 10px;
}
.qrCodeLogin .error{
color: var(--el-color-error);
}
.qrCodeLogin p.msg {
margin-top: 15px;
}
.qrCodeLogin .qrCodeLogin-result {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
text-align: center;
background: var(--el-mask-color);
display: flex;
flex-direction: column;
justify-content: center;
}
.passkeyView{
.msg{
margin-top: 10px;
color: var(--el-color-warning);
}
}
</style>

View File

@ -1,15 +1,33 @@
<template> <template>
<el-card shadow="never" header="修改密码"> <el-card shadow="never" header="修改密码">
<el-alert title="密码更新成功后,您将被重定向到登录页面,您可以使用新密码重新登录。" type="info" show-icon style="margin-bottom: 15px;"/> <el-alert title="密码更新成功后,您将被重定向到登录页面,您可以使用新密码重新登录。" type="error" show-icon style="margin-bottom: 15px;"/>
<el-form ref="form" :model="form" :rules="rules" label-width="120px" style="margin-top:20px;"> <el-form ref="form" :model="form" :rules="rules" label-width="120px" style="margin-top:20px;width: 518px;">
<el-form-item label="当前密码" prop="userPassword"> <el-form-item label="当前密码" prop="userPassword">
<el-input v-model="form.userPassword" type="password" show-password placeholder="请输入当前密码"></el-input> <el-input v-model="form.userPassword" type="password" show-password placeholder="请输入当前密码"></el-input>
<div class="el-form-item-msg">必须提供当前登录用户密码才能进行更改</div>
</el-form-item> </el-form-item>
<el-form-item label="新密码" prop="newPassword"> <el-form-item label="新密码" prop="newPassword">
<el-input v-model="form.newPassword" type="password" show-password placeholder="请输入新密码"></el-input> <el-popover
<sc-password-strength v-model="form.newPassword"></sc-password-strength> class="popoverPassword"
<div class="el-form-item-msg">请输入包含英文数字的8位以上密码</div> placement="right"
title=""
:width="360"
trigger="click"
content=""
>
<template #reference>
<el-input v-model="form.newPassword" type="password" show-password placeholder="请输入新密码"></el-input>
</template>
<template #default>
<div class="passwordView">
<div class="title">
<div class="name">安全程度等级:</div>
<div class="strength"><sc-password-strength v-model="form.newPassword"></sc-password-strength></div>
</div>
<div class="text"><div class="icon"></div>6-20位字符</div>
<div class="text"><div class="icon"></div>只能包含大小写字母数字和标点符号除空格</div>
</div>
</template>
</el-popover>
</el-form-item> </el-form-item>
<el-form-item label="确认新密码" prop="confirmNewPassword"> <el-form-item label="确认新密码" prop="confirmNewPassword">
<el-input v-model="form.confirmNewPassword" type="password" show-password placeholder="请再次输入新密码"></el-input> <el-input v-model="form.confirmNewPassword" type="password" show-password placeholder="请再次输入新密码"></el-input>

View File

@ -1,30 +1,192 @@
<template> <template>
<el-card shadow="never" header="事务待办"> <el-card shadow="never" header="">
<el-form ref="form" label-width="180px" label-position="left" style="margin-top:20px;"> <template #header>
<el-form-item label="有新的待办"> <div class="card-header-box">
<el-checkbox v-model="form.new">短信推送</el-checkbox> <div class="card-header">
<el-checkbox v-model="form.new_wx">微信推送</el-checkbox> <span>事务待办通知设置</span>
</el-form-item> </div>
<el-form-item label="待办有效时剩24小时"> <div class="card-btn">
<el-checkbox v-model="form.timeout">短信推送</el-checkbox> <el-button size="small" type="primary" @click="save">保存</el-button>
<el-checkbox v-model="form.timeout_wx">微信推送</el-checkbox> </div>
</el-form-item> </div>
</el-form> </template>
<div class="pushSetting" v-loading="loading" element-loading-text="努力加载中...">
<div class="headerNav">
<div class="item">通知事项</div>
<div class="item center" v-for="(item,index) in subscription_items" :key="index">
{{item.label}}
<template v-if="item.value==1">
<el-tooltip
class="box-item"
effect="dark"
content=""
placement="top-start"
>
<template #content>
<div>第一步账户安全里绑定微信号</div>
<div>第二步勾选想要接收的通知</div>
</template>
<span> <i class="sc-icon"><el-icon-QuestionFilled /></i></span>
</el-tooltip>
</template>
<template v-else-if="item.value==3">
<el-tooltip
class="box-item"
effect="dark"
content=""
placement="top-start"
>
<template #content>
<div>账号信息里绑定手机号</div>
<div>第二步勾选想要接收的通知</div>
</template>
<span><i class="sc-icon"><el-icon-QuestionFilled /></i></span>
</el-tooltip>
</template>
</div>
</div>
<div class="middleView">
<el-scrollbar height="100%">
<div class="listView" v-for="(item,index) in check_msg_temp" :key="index">
<div class="item">{{item.value}}</div>
<div class="item center" v-for="(em,ind) in item.subscription_items" :key="ind">
<el-checkbox :value="em.value" v-model="em.subscribed"></el-checkbox>
</div>
</div>
</el-scrollbar>
</div>
</div>
</el-card> </el-card>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
form: { subscription_items:[],
new: true, check_msg_temp:[],
timeout: true loading:false,
} };
},
mounted() {
// this.getList(true);
},
beforeUnmount() {
},
methods: {
async getList(isShow) {
if(isShow){
this.loading = true;
} }
const res = await this.$API.user.subscribe.list.post();
if(res.code == 200){
this.subscription_items = res.data.subscription_items;
this.check_msg_temp = res.data.check_msg_temp;
this.loading = false;
}
},
async save() {
let params = {
temps:this.setList()
};
const res = await this.$API.user.subscribe.set.post(params);
if (res.code == 200) {
this.$message.success('保存成功');
await this.getList();
}
},
setList(){
let list = JSON.parse(JSON.stringify(this.check_msg_temp));
let temps = [];
if(list.length>0){
list.forEach(item=>{
let obj = {
notice_item:item.notice_item,
value:item.value,
subscription_items:[]
}
if(item.subscription_items.length>0){
item.subscription_items.forEach(em=>{
if(em.subscribed){
obj.subscription_items.push(em.value);
}
})
}
if(obj.subscription_items.length>0){
temps.push(obj)
}
})
}
return temps
} }
} }
};
</script> </script>
<style> <style scoped lang="scss">
.card-header-box{
display: flex;
align-items: center;
justify-content: space-between;
}
.pushSetting{
padding: 0 0 15px 0;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
.headerNav{
padding: 10px 10px;
display: flex;
background: #F5F7FA;
.item{
flex: 1;
}
.center{
display: flex;
justify-content: center;
cursor: pointer;
.el-tooltip__trigger{
display: flex;
align-items: center;
}
}
.sc-icon{
display: inline-block;
width: 16px;
height: 16px;
margin-left: 6px;
color: var(--el-color-warning);
}
}
.middleView{
display: flex;
flex-direction: column;
padding: 10px 10px;
flex: 1;
overflow: hidden;
.listView{
display: flex;
}
.item{
flex: 1;
padding: 0 0;
display: flex;
align-items: center;
}
.center{
display: flex;
justify-content: center;
}
}
}
.dark{
.pushSetting .headerNav{
background: #313131;
}
}
</style> </style>

View File

@ -16,8 +16,7 @@
<div class="el-form-item-msg">{{ $t('user.language_msg') }}</div> <div class="el-form-item-msg">{{ $t('user.language_msg') }}</div>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card>
<el-card shadow="never" header="个人设置" style="margin-top:20px;">
<el-form ref="form" label-width="120px" style="margin-top:20px;"> <el-form ref="form" label-width="120px" style="margin-top:20px;">
<el-form-item label="自动登出"> <el-form-item label="自动登出">
<el-select v-model="config.autoExit"> <el-select v-model="config.autoExit">