Introducing new features. 修改个人信息修改

This commit is contained in:
aeizzz 2023-02-17 14:17:23 +08:00
parent 78d16b79e6
commit ab3fc356d6
7 changed files with 202 additions and 230 deletions

View File

@ -63,6 +63,14 @@ export function editInfo(obj: Object) {
})
}
export function password(obj: Object){
return request({
url: '/admin/user/password',
method: 'put',
data: obj
})
}
/**
*
*/
@ -107,3 +115,5 @@ export function validatePhone(rule: any, value: any, callback: any, isEdit: bool
}
})
}

View File

@ -14,14 +14,6 @@ export default {
limitsFrontEndBtn: '按钮权限',
limitsBackEnd: '后端控制',
limitsBackEndEndPage: '页面权限',
menu: '菜单嵌套',
menu1: '菜单1',
menu11: '菜单11',
menu12: '菜单12',
menu121: '菜单121',
menu122: '菜单122',
menu13: '菜单13',
menu2: '菜单2',
funIndex: '功能',
funTagsView: 'tagsView 操作',
funCountup: '数字滚动',

View File

@ -70,13 +70,14 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="/home">{{ $t('user.dropdown1') }}</el-dropdown-item>
<el-dropdown-item command="/personal">{{ $t('user.dropdown2') }}</el-dropdown-item>
<el-dropdown-item command="personal">{{ $t('user.dropdown2') }}</el-dropdown-item>
<el-dropdown-item divided command="logOut">{{ $t('user.dropdown5') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<Search ref="searchRef" />
<global-websocket uri="/admin/ws/info" v-if="websocketEnable" @rollback="rollback" />
<personal-drawer ref="personalDrawerRef"></personal-drawer>
</div>
</template>
@ -100,6 +101,8 @@ const GlobalWebsocket = defineAsyncComponent(() => import('/@/components/Websock
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue'));
const Search = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/search.vue'));
const personalDrawer = defineAsyncComponent(() => import("/@/views/personal/index.vue"))
//
const { locale, t } = useI18n();
const router = useRouter();
@ -109,6 +112,7 @@ const { userInfos } = storeToRefs(stores);
const { themeConfig } = storeToRefs(storesThemeConfig);
const searchRef = ref();
const newsRef = ref();
const personalDrawerRef = ref()
const state = reactive({
isScreenfull: false,
@ -179,8 +183,9 @@ const onHandleCommandClick = (path: string) => {
})
.catch(() => {
});
} else if (path === 'wareHouse') {
window.open('https://gitee.com/lyt-top/vue-next-admin');
} else if (path === 'personal') {
//
personalDrawerRef.value.open()
} else {
router.push(path);
}

View File

@ -0,0 +1,6 @@
export default {
personal: {
name: 'personal info',
passwordRule: 'The two passwords are inconsistent'
}
}

View File

@ -0,0 +1,6 @@
export default {
personal: {
name: '个人信息',
passwordRule: '两次输入密码不一致'
}
}

View File

@ -1,161 +1,137 @@
<template>
<div class="personal layout-pd">
<el-row>
<!-- 个人信息 -->
<el-col :span="24">
<el-card shadow="hover" header="个人信息">
<div class="personal-user">
<div class="personal-user-left">
<image-upload class="h100 personal-user-left-upload" @change="handleAvatarSuccess">
<img v-if="formData.avatar" :src="formData.avatar" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</image-upload>
</div>
<div class="personal-user-right">
<el-row>
<el-col :span="24" class="personal-title mb18">{{
currentTime
}}admin </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">{{ formData.nickname }}</div>
</el-col>
<el-col :xs="24" :sm="16" class="personal-item mb6">
<div class="personal-item-label">身份</div>
<div class="personal-item-value">超级管理</div>
</el-col>
</el-row>
</el-col>
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="8" class="personal-item mb6">
<div class="personal-item-label">登录IP</div>
<div class="personal-item-value">192.168.1.1</div>
</el-col>
<el-col :xs="24" :sm="16" class="personal-item mb6">
<div class="personal-item-label">登录时间</div>
<div class="personal-item-value">2021-02-05 18:47:26</div>
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</div>
</el-card>
</el-col>
<el-drawer v-model="visible" :title="$t('personal.name')" size="50%">
<el-tabs style="height: 200px" class="demo-tabs">
<el-tab-pane label="基本信息">
<el-card shadow="hover" class="layout-padding-auto">
<el-form :model="formData" :rules="ruleForm" label-width="100px" class="mt35 mb35" ref="formdataRef">
<el-row :gutter="20">
<el-col :span="24" class="mb20">
<el-form-item label="用户名" prop="avatar">
<image-upload class="h100 personal-user-left-upload" @change="handleAvatarSuccess">
<img v-if="formData.avatar" :src="formData.avatar" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</image-upload>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" clearable disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="手机" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入手机" clearable></el-input>
</el-form-item>
</el-col>
<!-- 更新信息 -->
<el-col :span="24">
<el-card shadow="hover" class="mt15 personal-edit" header="更新信息">
<div class="personal-edit-title">基本信息</div>
<el-form :model="formData" :rules="ruleForm" label-width="100px" class="mt35 mb35"
ref="formdataRef">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" clearable disabled></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="formData.phone" 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="email">
<el-input v-model="formData.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="nickname">
<el-input v-model="formData.nickname" 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="name">
<el-input v-model="formData.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="原密码" prop="password">
<el-input v-model="formData.password" placeholder="请输入密码" clearable
type="password"></el-input>
</el-form-item>
</el-col>
<el-col :lg="6" :md="8" :sm="12" :xl="4" :xs="24" class="mb20">
<el-form-item label="新密码" prop="newpassword1">
<el-input v-model="formData.newpassword1" clearable type="password"></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="newpassword2">
<el-input v-model="formData.newpassword2" clearable type="password"></el-input>
</el-form-item>
</el-col>
<el-col :lg="6" :md="8" :sm="12" :xl="4" :xs="24" class="mb20">
<el-form-item label="社交登录" prop="social">
<div @click="handleClick('wechat')">
<el-col :span="24" class="mb20">
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="昵称" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入昵称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="社交登录" prop="social">
<div @click="handleClick('wechat')">
<span :style="{ backgroundColor: '#6ba2d6' }" class="container">
<i class="iconfont icon-weixin" icon-class="wechat" />
</span>
<p class="title">微信</p>
</div>
<div @click="handleClick('tencent')">
<p class="title">微信</p>
</div>
<div @click="handleClick('tencent')">
<span :style="{ backgroundColor: '#8dc349' }" class="container">
<i class="iconfont icon-qq" icon-class="qq" />
</span>
<p class="title">QQ</p>
</div>
<div @click="handleClick('gitee')">
<p class="title">QQ</p>
</div>
<div @click="handleClick('gitee')">
<span :style="{ backgroundColor: '#bf3030' }" class="container">
<i class="iconfont icon-logo_gitee_icon" icon-class="qq" />
</span>
<p class="title">Gitee</p>
</div>
<div @click="handleClick('osc')">
<p class="title">Gitee</p>
</div>
<div @click="handleClick('osc')">
<span :style="{ backgroundColor: '#007B25' }" class="container">
<i class="iconfont icon-oschina" icon-class="qq" />
</span>
<p class="title">开源中国</p>
</div>
</el-form-item>
</el-col>
<p class="title">开源中国</p>
</div>
</el-form-item>
</el-col>
<el-col :lg="24" :md="24" :sm="24" :xl="24" :xs="24">
<el-form-item>
<el-button type="primary" @click="handleSaveUser">
<el-icon>
<ele-Position />
</el-icon>
更新个人信息
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-col>
</el-row>
</div>
<el-col :span="24" class="mb20">
<el-form-item>
<el-button type="primary" @click="handleSaveUser">
更新个人信息
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-tab-pane>
<el-tab-pane label="安全信息">
<el-card shadow="hover" class="layout-padding-auto">
<el-form :model="passwordFormData" :rules="passwordRuleForm" label-width="100px" class="mt35 mb35" ref="passwordFormdataRef">
<el-row :gutter="20">
<el-col :span="24" class="mb20">
<el-form-item label="原密码" prop="password">
<el-input v-model="passwordFormData.password" placeholder="请输入密码" clearable
type="password"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="新密码" prop="newpassword1">
<el-input v-model="passwordFormData.newpassword1" clearable type="password"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="确认密码" prop="newpassword2">
<el-input v-model="passwordFormData.newpassword2" clearable type="password"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item>
<el-button type="primary" @click="handleChangePassword">
修改密码
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-tab-pane>
</el-tabs>
</el-drawer>
</template>
<script setup lang="ts" name="personal">
import { computed, reactive } from 'vue';
import { formatAxis } from '/@/utils/formatTime';
import { useUserInfo } from '/@/stores/userInfo';
import { editInfo } from '/@/api/admin/user'
import { editInfo, password } from '/@/api/admin/user'
import { useMessage } from "/@/hooks/message";
import { rule } from "/@/utils/validate";
import other from '/@/utils/other';
import {Session} from "/@/utils/storage";
import { useI18n } from "vue-i18n";
const { t } = useI18n()
const ImageUpload = defineAsyncComponent(() => import('/@/components/Upload/Image.vue'))
const visible = ref(false)
//
const formData = reactive({
username: '',
@ -164,38 +140,77 @@ const formData = reactive({
avatar: '',
nickname: '',
phone: '',
password: '',
newpassword1: '',
newpassword2: ''
});
const passwordFormData = reactive({
password: '',
newpassword1: '',
newpassword2: ''
})
const formdataRef = ref()
const passwordFormdataRef = ref()
const ruleForm = reactive({
password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
phone: [{ required: true, message: "手机号不能为空", trigger: "blur" }, { validator: rule.validatePhone, trigger: 'blur' }],
nickname: [{ required: true, message: "昵称不能为空", trigger: "blur" }],
email: [{ required: true, message: "邮箱不能为空", trigger: "blur" }],
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
newpassword1: [{
min: 6,
max: 20,
message: "用户密码长度必须介于 6 和 20 之间",
trigger: "blur"
}]
})
const validatorPassword2 = (rule: any, value: any, callback: any) => {
if(value !== passwordFormData.newpassword1){
callback(new Error(t('personal.passwordRule')))
}else{
callback()
}
}
const passwordRuleForm = reactive({
password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
newpassword1: [{
min: 6,
max: 20,
message: "用户密码长度必须介于 6 和 20 之间",
trigger: "blur"
}],
newpassword2: [
{
min: 6,
max: 20,
message: "用户密码长度必须介于 6 和 20 之间",
trigger: "blur"
},{ validator: validatorPassword2, trigger: 'blur' }
]
})
onMounted(() => {
const data = useUserInfo().userInfos
Object.assign(formData, data.user)
formData.password = ''
})
//
const handleAvatarSuccess = (url: any) => {
formData.avatar = url;
}
const handleChangePassword = () => {
passwordFormdataRef.value.validate((valid: boolean) => {
if (!valid) {
return false
}
password(passwordFormData).then(() => {
useMessage().success("修改成功")
//
// /token
Session.clear();
// 使 reload resetRoute()
window.location.reload();
}).catch(err => {
useMessage().error(err.msg)
})
})
}
//
const handleSaveUser = () => {
@ -214,12 +229,6 @@ const handleSaveUser = () => {
}
//
const currentTime = computed(() => {
return formatAxis(new Date());
});
const handleClick = (thirdpart: string) => {
let appid, client_id, redirect_uri, url;
redirect_uri = encodeURIComponent(
@ -241,6 +250,16 @@ const handleClick = (thirdpart: string) => {
other.openWindow(url, thirdpart, 540, 540)
}
const open = () => {
visible.value = true
const data = useUserInfo().userInfos
Object.assign(formData, data.user)
}
//
defineExpose({
open,
});
</script>

View File

@ -1,66 +0,0 @@
/**
*
* @returns
*/
export const newsInfoList = [
{
title: '[发布] 2021年02月28日发布基于 vue3.x + vite v1.0.0 版本',
date: '02/28',
link: 'https://gitee.com/lyt-top/vue-next-admin',
},
{
title: '[发布] 2021年04月15日发布 vue2.x + webpack 重构版本',
date: '04/15',
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
},
{
title: '[重构] 2021年04月10日 重构 vue2.x + webpack v1.0.0 版本',
date: '04/10',
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
},
{
title: '[预览] 2020年12月08日基于 vue3.x 版本后台模板的预览',
date: '12/08',
link: 'http://lyt-top.gitee.io/vue-next-admin-preview/#/login',
},
{
title: '[预览] 2020年11月15日基于 vue2.x 版本后台模板的预览',
date: '11/15',
link: 'https://lyt-top.gitee.io/vue-prev-admin-preview/#/login',
},
];
/**
*
* @returns
*/
export const recommendList = [
{
title: '优惠券',
msg: '现金券、折扣券、营销必备',
icon: 'ele-Food',
bg: '#48D18D',
iconColor: '#64d89d',
},
{
title: '多人拼团',
msg: '社交电商、开辟流量',
icon: 'ele-ShoppingCart',
bg: '#F95959',
iconColor: '#F86C6B',
},
{
title: '分销中心',
msg: '轻松招募分销员,成功推广奖励',
icon: 'ele-School',
bg: '#8595F4',
iconColor: '#92A1F4',
},
{
title: '秒杀',
msg: '超低价抢购引导更多销量',
icon: 'ele-AlarmClock',
bg: '#FEBB50',
iconColor: '#FDC566',
},
];