feat(个人中心): 个人中心

个人中心完成
This commit is contained in:
猿小天
2023-03-12 21:22:22 +08:00
parent 888228fb1b
commit aef2becd01
9 changed files with 437 additions and 8 deletions

View File

@@ -14,6 +14,7 @@ export default {
limitsFrontEndBtn: 'FrontEndBtn',
limitsBackEnd: 'BackEnd',
limitsBackEndEndPage: 'BackEndEndPage',
personal: 'personal',
},
staticRoutes: {
signIn: 'signIn',

View File

@@ -25,6 +25,7 @@ export default {
limitsFrontEndBtn: '按钮权限',
limitsBackEnd: '后端控制',
limitsBackEndEndPage: '页面权限',
personal: '个人中心',
},
staticRoutes: {
signIn: '登录',

View File

@@ -1,8 +1,8 @@
<template>
<div class="layout-footer pb15">
<div class="layout-footer-warp">
<div>vue-next-adminMade by lyt with </div>
<div class="mt5">深圳市 xxx 公司版权所有</div>
<div> Powered by Django-Vue3-Admin </div>
<div class="mt5">Copyright dvadmin团队</div>
</div>
</div>
</template>

View File

@@ -39,7 +39,7 @@
<div class="layout-navbars-breadcrumb-user-icon">
<el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
<template #reference>
<el-badge :value="messageCenter.unread">
<el-badge :value="messageCenter.unread" :hidden="messageCenter.unread===0">
<el-icon :title="$t('message.user.title4')">
<ele-Bell />
</el-icon>
@@ -68,6 +68,7 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
<el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>
<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
</el-dropdown-menu>

View File

@@ -32,6 +32,20 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
},
children: [],
},
{
path: '/personal',
name: 'personal',
component: () => import('/@/views/system/personal/index.vue'),
meta: {
title: 'message.router.personal',
isLink: '',
isHide: false,
isKeepAlive: true,
isAffix: false,
isIframe: false,
icon: 'iconfont icon-gerenzhongxin',
},
}
];
/**

View File

@@ -96,7 +96,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 是否开启 TagsView 共用
isShareTagsView: false,
// 是否开启 Footer 底部版权信息
isFooter: false,
isFooter: true,
// 是否开启灰色模式
isGrayscale: false,
// 是否开启色弱模式

View File

@@ -17,12 +17,19 @@ declare type PersonalState = {
newsInfoList: NewInfo[];
recommendList: Recommend[];
personalForm: {
username: string;
name: string;
email: string;
autograph: string;
occupation: string;
phone: string;
sex: string;
mobile: string;
gender: number | string;
dept_info: {
dept_id: number;
dept_name: string;
}
role_info: [{
id: number;
name: string;
}]
};
};

View File

@@ -0,0 +1,22 @@
import { request } from '/@/utils/service';
import { PageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
export function GetUserInfo(query: PageQuery) {
return request({
url: '/api/system/user/user_info/',
method: 'get',
params: query
});
}
/**
* 更新用户信息
* @param data
*/
export function updateUserInfo(data: AddReq) {
return request({
url: '/api/system/user/update_user_info/',
method: 'put',
data: data
})
}

View File

@@ -0,0 +1,383 @@
<template>
<div class="personal layout-pd">
<el-row>
<!-- 个人信息 -->
<el-col :xs="24" :sm="16">
<el-card shadow="hover" header="个人信息">
<div class="personal-user">
<div class="personal-user-left">
<el-upload class="h100 personal-user-left-upload" action="https://jsonplaceholder.typicode.com/posts/" multiple :limit="1">
<img src="https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500" />
</el-upload>
</div>
<div class="personal-user-right">
<el-row>
<el-col :span="24" class="personal-title mb18">{{ currentTime }}{{state.personalForm.username}}生活变的再糟糕也不妨碍我变得更好 </el-col>
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="8" class="personal-item mb6">
<div class="personal-item-label">昵称</div>
<div class="personal-item-value">{{state.personalForm.name}}</div>
</el-col>
<el-col :xs="24" :sm="16" class="personal-item mb6">
<div class="personal-item-label">部门</div>
<div class="personal-item-value">{{state.personalForm.dept_info.dept_name}}</div>
</el-col>
</el-row>
</el-col>
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="24" class="personal-item mb6">
<div class="personal-item-label">角色</div>
<div class="personal-item-value">
<el-tag v-for="(item,index) in state.personalForm.role_info" :key="index">{{item.name}}</el-tag>
</div>
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</div>
</el-card>
</el-col>
<!-- 消息通知 -->
<el-col :xs="24" :sm="8" class="pl15 personal-info">
<el-card shadow="hover">
<template #header>
<span>消息通知</span>
<span class="personal-info-more">更多</span>
</template>
<div class="personal-info-box">
<ul class="personal-info-ul">
<li v-for="(v, k) in state.newsInfoList" :key="k" class="personal-info-li">
<a :href="v.link" target="_block" class="personal-info-li-title">{{ v.title }}</a>
</li>
</ul>
</div>
</el-card>
</el-col>
<!-- 更新信息 -->
<el-col :span="24">
<el-card shadow="hover" class="mt15 personal-edit" header="更新信息">
<div class="personal-edit-title">基本信息</div>
<el-form :model="state.personalForm" ref="userInfoFormRef" :rules="rules" size="default" label-width="50px" class="mt35 mb35">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="昵称" prop="name">
<el-input v-model="state.personalForm.name" placeholder="请输入昵称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="邮箱">
<el-input v-model="state.personalForm.email" placeholder="请输入邮箱" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="手机" prop="phone">
<el-input v-model="state.personalForm.mobile" placeholder="请输入手机" clearable></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="性别">
<el-select v-model="state.personalForm.gender" placeholder="请选择性别" clearable class="w100">
<el-option label="男" :value="1"></el-option>
<el-option label="女" :value="0"></el-option>
<el-option label="保密" :value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-form-item>
<el-button type="primary" @click="submitForm">
<el-icon>
<ele-Position />
</el-icon>
更新个人信息
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="personal-edit-title mb15">账号安全</div>
<div class="personal-edit-safe-box">
<div class="personal-edit-safe-item">
<div class="personal-edit-safe-item-left">
<div class="personal-edit-safe-item-left-label">账户密码</div>
<div class="personal-edit-safe-item-left-value">当前密码强度</div>
</div>
<div class="personal-edit-safe-item-right">
<el-button text type="primary">立即修改</el-button>
</div>
</div>
</div>
<div class="personal-edit-safe-box">
<div class="personal-edit-safe-item">
<div class="personal-edit-safe-item-left">
<div class="personal-edit-safe-item-left-label">密保手机</div>
<div class="personal-edit-safe-item-left-value">已绑定手机{{state.personalForm.mobile}}</div>
</div>
<div class="personal-edit-safe-item-right">
<!-- <el-button text type="primary">立即修改</el-button>-->
</div>
</div>
</div>
<div class="personal-edit-safe-box">
<div class="personal-edit-safe-item">
<div class="personal-edit-safe-item-left">
<div class="personal-edit-safe-item-left-label">绑定邮箱</div>
<div class="personal-edit-safe-item-left-value">已绑定邮箱{{state.personalForm.email}}</div>
</div>
<div class="personal-edit-safe-item-right">
<!-- <el-button text type="primary">立即设置</el-button>-->
</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts" name="personal">
import { reactive, computed,onMounted,ref } from 'vue';
import { formatAxis } from '/@/utils/formatTime';
import * as api from './api'
import {ElMessage } from "element-plus";
const userInfoFormRef = ref()
const rules = reactive({
name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
mobile: [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确手机号' }]
})
// 定义变量内容
const state = reactive<PersonalState>({
personalForm: {
username:'',
name: '',
email: '',
mobile: '',
gender:'',
dept_info:{
dept_id:0,
dept_name:''
},
role_info:[{
id:0,
name:''
}]
},
});
/**
* 获取用户个人信息
*/
const getUserInfo = function (){
api.GetUserInfo({}).then((res:any)=>{
const {data} = res
console.log(data)
state.personalForm.username = data.username || '';
state.personalForm.name = data.name || '';
state.personalForm.email = data.email || '';
state.personalForm.mobile = data.mobile || '';
state.personalForm.gender = data.gender || '';
state.personalForm.dept_info.dept_name = data.dept_info.dept_name || '';
state.personalForm.role_info = data.role_info || [];
})
}
/**
* 更新用户信息
* @param formEl
*/
const submitForm = async () => {
if (!userInfoFormRef.value) return
await userInfoFormRef.value.validate((valid, fields) => {
if (valid) {
api.updateUserInfo(state.personalForm).then((res:any)=>{
ElMessage.success('更新成功')
getUserInfo()
})
} else {
ElMessage.error('表单验证失败,请检查~')
}
})
}
onMounted(()=>{
getUserInfo();
})
// 当前时间提示语
const currentTime = computed(() => {
return formatAxis(new Date());
});
</script>
<style scoped lang="scss">
@import '/@/theme/mixins/index.scss';
.personal {
.personal-user {
height: 130px;
display: flex;
align-items: center;
.personal-user-left {
width: 100px;
height: 130px;
border-radius: 3px;
:deep(.el-upload) {
height: 100%;
}
.personal-user-left-upload {
img {
width: 100%;
height: 100%;
border-radius: 3px;
}
&:hover {
img {
animation: logoAnimation 0.3s ease-in-out;
}
}
}
}
.personal-user-right {
flex: 1;
padding: 0 15px;
.personal-title {
font-size: 18px;
@include text-ellipsis(1);
}
.personal-item {
display: flex;
align-items: center;
font-size: 13px;
.personal-item-label {
color: var(--el-text-color-secondary);
@include text-ellipsis(1);
}
.personal-item-value {
@include text-ellipsis(1);
}
}
}
}
.personal-info {
.personal-info-more {
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
&:hover {
color: var(--el-color-primary);
cursor: pointer;
}
}
.personal-info-box {
height: 130px;
overflow: hidden;
.personal-info-ul {
list-style: none;
.personal-info-li {
font-size: 13px;
padding-bottom: 10px;
.personal-info-li-title {
display: inline-block;
@include text-ellipsis(1);
color: var(--el-text-color-secondary);
text-decoration: none;
}
& a:hover {
color: var(--el-color-primary);
cursor: pointer;
}
}
}
}
}
.personal-recommend-row {
.personal-recommend-col {
.personal-recommend {
position: relative;
height: 100px;
border-radius: 3px;
overflow: hidden;
cursor: pointer;
&:hover {
i {
right: 0px !important;
bottom: 0px !important;
transition: all ease 0.3s;
}
}
i {
position: absolute;
right: -10px;
bottom: -10px;
font-size: 70px;
transform: rotate(-30deg);
transition: all ease 0.3s;
}
.personal-recommend-auto {
padding: 15px;
position: absolute;
left: 0;
top: 5%;
color: var(--next-color-white);
.personal-recommend-msg {
font-size: 12px;
margin-top: 10px;
}
}
}
}
}
.personal-edit {
.personal-edit-title {
position: relative;
padding-left: 10px;
color: var(--el-text-color-regular);
&::after {
content: '';
width: 2px;
height: 10px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
background: var(--el-color-primary);
}
}
.personal-edit-safe-box {
border-bottom: 1px solid var(--el-border-color-light, #ebeef5);
padding: 15px 0;
.personal-edit-safe-item {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.personal-edit-safe-item-left {
flex: 1;
overflow: hidden;
.personal-edit-safe-item-left-label {
color: var(--el-text-color-regular);
margin-bottom: 5px;
}
.personal-edit-safe-item-left-value {
color: var(--el-text-color-secondary);
@include text-ellipsis(1);
margin-right: 15px;
}
}
}
&:last-of-type {
padding-bottom: 0;
border-bottom: none;
}
}
}
}
</style>