|
@ -4,6 +4,7 @@ import { ref, reactive, onMounted } from "vue"; |
|
|
import { useChatStore } from "@/stores/chat"; |
|
|
import { useChatStore } from "@/stores/chat"; |
|
|
import { notifyError, notifySuccess } from "@/util/msg"; |
|
|
import { notifyError, notifySuccess } from "@/util/msg"; |
|
|
import { fetchGet, fetchPost, getSystemConfig, setSystemKey } from "@/system/config"; |
|
|
import { fetchGet, fetchPost, getSystemConfig, setSystemKey } from "@/system/config"; |
|
|
|
|
|
import { isMobileDevice } from '@/util/device'; |
|
|
const store = useChatStore() |
|
|
const store = useChatStore() |
|
|
// const form = ref({ |
|
|
// const form = ref({ |
|
|
// nickname: '', |
|
|
// nickname: '', |
|
@ -14,7 +15,7 @@ interface ImgItem { |
|
|
} |
|
|
} |
|
|
const editType = ref(0) |
|
|
const editType = ref(0) |
|
|
const userInfo = getSystemConfig().userInfo |
|
|
const userInfo = getSystemConfig().userInfo |
|
|
const userInfoForm: {[key: string]: any} = reactive({ |
|
|
const userInfoForm: { [key: string]: any } = reactive({ |
|
|
nickname: '', |
|
|
nickname: '', |
|
|
phone: '', |
|
|
phone: '', |
|
|
email: '', |
|
|
email: '', |
|
@ -24,12 +25,12 @@ const dialogShow = ref(false) |
|
|
let imgList = reactive<ImgItem[]>([]) |
|
|
let imgList = reactive<ImgItem[]>([]) |
|
|
let pos = ref(0) |
|
|
let pos = ref(0) |
|
|
// 换头像 |
|
|
// 换头像 |
|
|
const showChange = (val: boolean) =>{ |
|
|
const showChange = (val: boolean) => { |
|
|
dialogShow.value = val |
|
|
dialogShow.value = val |
|
|
} |
|
|
} |
|
|
// 获取头像列表 |
|
|
// 获取头像列表 |
|
|
const getHeadList = async () => { |
|
|
const getHeadList = async () => { |
|
|
let res = await fetchGet (`${userInfo.url}/files/avatarlist`) |
|
|
let res = await fetchGet(`${userInfo.url}/files/avatarlist`) |
|
|
// const apiUrl = getSystemConfig().apiUrl + '/upload/avatar/'; |
|
|
// const apiUrl = getSystemConfig().apiUrl + '/upload/avatar/'; |
|
|
const apiUrl = userInfo.url + '/upload/avatar/'; |
|
|
const apiUrl = userInfo.url + '/upload/avatar/'; |
|
|
if (res.ok) { |
|
|
if (res.ok) { |
|
@ -45,7 +46,7 @@ const getHeadList = async () => { |
|
|
const chooseImg = (index: number) => { |
|
|
const chooseImg = (index: number) => { |
|
|
pos.value = index |
|
|
pos.value = index |
|
|
} |
|
|
} |
|
|
const toChangeHead = async ()=>{ |
|
|
const toChangeHead = async () => { |
|
|
let res = await fetchGet(`${userInfo.url}/files/saveavatar?id=${userInfo.id}&name=${imgList[pos.value]?.name}`) |
|
|
let res = await fetchGet(`${userInfo.url}/files/saveavatar?id=${userInfo.id}&name=${imgList[pos.value]?.name}`) |
|
|
if (!res.ok) { |
|
|
if (!res.ok) { |
|
|
notifyError("头像换取失败") |
|
|
notifyError("头像换取失败") |
|
@ -59,26 +60,26 @@ const toChangeHead = async ()=>{ |
|
|
showChange(false) |
|
|
showChange(false) |
|
|
} |
|
|
} |
|
|
//修改资料 |
|
|
//修改资料 |
|
|
const userRef:any = ref(null) |
|
|
const userRef: any = ref(null) |
|
|
const userRule = { |
|
|
const userRule = { |
|
|
nickname: [ |
|
|
nickname: [ |
|
|
{ required: true, message: '昵称不能为空', trigger: 'blur'}, |
|
|
{ required: true, message: '昵称不能为空', trigger: 'blur' }, |
|
|
{ min: 2, max: 10, message: '昵称长度应该在2到10位', trigger: 'blur'} |
|
|
{ min: 2, max: 10, message: '昵称长度应该在2到10位', trigger: 'blur' } |
|
|
], |
|
|
], |
|
|
phone: [ |
|
|
phone: [ |
|
|
{ required: true, message: '手机号不能为空', trigger: 'blur'}, |
|
|
{ required: true, message: '手机号不能为空', trigger: 'blur' }, |
|
|
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur'} |
|
|
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' } |
|
|
], |
|
|
], |
|
|
email: [ |
|
|
email: [ |
|
|
{ required: true, message: '邮箱不能为空', trigger: 'blur'}, |
|
|
{ required: true, message: '邮箱不能为空', trigger: 'blur' }, |
|
|
{ pattern: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/, message: '邮箱格式不正确', trigger: 'blur'} |
|
|
{ pattern: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/, message: '邮箱格式不正确', trigger: 'blur' } |
|
|
] |
|
|
] |
|
|
// desc: [ |
|
|
// desc: [ |
|
|
// { required: true, message: '昵称不能为空', trigger: 'blur'}, |
|
|
// { required: true, message: '昵称不能为空', trigger: 'blur'}, |
|
|
// { min: 2, max: 10, message: '昵称长度应该在2到10位', trigger: 'blur'} |
|
|
// { min: 2, max: 10, message: '昵称长度应该在2到10位', trigger: 'blur'} |
|
|
// ], |
|
|
// ], |
|
|
} |
|
|
} |
|
|
const onSubmit = async () => { |
|
|
const onSubmit = async () => { |
|
|
try { |
|
|
try { |
|
|
for (const key in userInfoForm) { |
|
|
for (const key in userInfoForm) { |
|
|
userInfo[key] = userInfoForm[key] |
|
|
userInfo[key] = userInfoForm[key] |
|
@ -95,7 +96,7 @@ const onSubmit = async () => { |
|
|
} else { |
|
|
} else { |
|
|
notifyError(result?.message) |
|
|
notifyError(result?.message) |
|
|
} |
|
|
} |
|
|
}catch (e) { |
|
|
} catch (e) { |
|
|
console.log(e) |
|
|
console.log(e) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -105,7 +106,7 @@ const passwordForm = reactive({ |
|
|
newPassword: '', |
|
|
newPassword: '', |
|
|
confirmPassword: '' |
|
|
confirmPassword: '' |
|
|
}) |
|
|
}) |
|
|
const passwordRef:any = ref(null) |
|
|
const passwordRef: any = ref(null) |
|
|
const rules = { |
|
|
const rules = { |
|
|
oldPassword: [ |
|
|
oldPassword: [ |
|
|
{ required: true, message: '密码不能为空', trigger: 'blur' } |
|
|
{ required: true, message: '密码不能为空', trigger: 'blur' } |
|
@ -116,17 +117,19 @@ const rules = { |
|
|
], |
|
|
], |
|
|
confirmPassword: [ |
|
|
confirmPassword: [ |
|
|
{ required: true, message: '请再次输入密码', trigger: 'blur' }, |
|
|
{ required: true, message: '请再次输入密码', trigger: 'blur' }, |
|
|
{ validator: (rule: any, value:any, callback:any) => { |
|
|
{ |
|
|
console.log('rule:', rule); |
|
|
validator: (rule: any, value: any, callback: any) => { |
|
|
|
|
|
console.log('rule:', rule); |
|
|
if (value === '') { |
|
|
|
|
|
callback(new Error('请再次输入密码')); |
|
|
if (value === '') { |
|
|
} else if (value !== passwordForm.newPassword) { |
|
|
callback(new Error('请再次输入密码')); |
|
|
callback(new Error('两次输入的密码不一致')); |
|
|
} else if (value !== passwordForm.newPassword) { |
|
|
} else { |
|
|
callback(new Error('两次输入的密码不一致')); |
|
|
callback(); |
|
|
} else { |
|
|
|
|
|
callback(); |
|
|
|
|
|
} |
|
|
|
|
|
}, trigger: 'blur' |
|
|
} |
|
|
} |
|
|
}, trigger: 'blur' } |
|
|
|
|
|
], |
|
|
], |
|
|
} |
|
|
} |
|
|
const toChangePwd = async () => { |
|
|
const toChangePwd = async () => { |
|
@ -146,7 +149,7 @@ const toChangePwd = async () => { |
|
|
console.log(e) |
|
|
console.log(e) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
onMounted(()=>{ |
|
|
onMounted(() => { |
|
|
getHeadList() |
|
|
getHeadList() |
|
|
for (const key in userInfoForm) { |
|
|
for (const key in userInfoForm) { |
|
|
userInfoForm[key] = userInfo[key] |
|
|
userInfoForm[key] = userInfo[key] |
|
@ -157,13 +160,14 @@ onMounted(()=>{ |
|
|
<template> |
|
|
<template> |
|
|
<el-container> |
|
|
<el-container> |
|
|
<el-aside> |
|
|
<el-aside> |
|
|
<div @click="editType = 0" :class="{'is-active': editType == 0}">修改资料</div> |
|
|
<div @click="editType = 0" :class="{ 'is-active': editType == 0 }">修改资料</div> |
|
|
<div @click="editType = 1" :class="{'is-active': editType == 1}">修改密码</div> |
|
|
<div @click="editType = 1" :class="{ 'is-active': editType == 1 }">修改密码</div> |
|
|
</el-aside> |
|
|
</el-aside> |
|
|
<el-main> |
|
|
<el-main> |
|
|
<el-form v-if="editType == 0" :model="userInfoForm" :rules="userRule" ref="userRef" label-width="130px" style="padding: 30px;"> |
|
|
<el-form v-if="editType == 0" :model="userInfoForm" :rules="userRule" ref="userRef" |
|
|
|
|
|
:label-width="isMobileDevice() ? '90px' : '130px'" style="padding: 30px;"> |
|
|
<el-form-item label="头像"> |
|
|
<el-form-item label="头像"> |
|
|
<el-avatar :size="90" :src="store.userInfo.avatar" @click="showChange(true)"/> |
|
|
<el-avatar :size="90" :src="store.userInfo.avatar" @click="showChange(true)" /> |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item label="昵称" prop="nickname"> |
|
|
<el-form-item label="昵称" prop="nickname"> |
|
|
<el-input v-model="userInfoForm.nickname" /> |
|
|
<el-input v-model="userInfoForm.nickname" /> |
|
@ -175,33 +179,22 @@ onMounted(()=>{ |
|
|
<el-input v-model="userInfoForm.email" /> |
|
|
<el-input v-model="userInfoForm.email" /> |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item label="自我介绍" prop="desc"> |
|
|
<el-form-item label="自我介绍" prop="desc"> |
|
|
<el-input v-model="userInfoForm.desc" type="textarea" maxlength="100" show-word-limit/> |
|
|
<el-input v-model="userInfoForm.desc" type="textarea" maxlength="100" show-word-limit /> |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item> |
|
|
<el-form-item> |
|
|
<el-button type="primary" @click="onSubmit">保存</el-button> |
|
|
<el-button type="primary" @click="onSubmit">保存</el-button> |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
</el-form> |
|
|
</el-form> |
|
|
<el-form v-else :model="passwordForm" :rules="rules" ref="passwordRef" label-width="120px" style="padding: 30px;"> |
|
|
<el-form v-else :model="passwordForm" :rules="rules" ref="passwordRef" label-width="120px" |
|
|
|
|
|
style="padding: 30px;"> |
|
|
<el-form-item label="旧密码" prop="oldPassword"> |
|
|
<el-form-item label="旧密码" prop="oldPassword"> |
|
|
<el-input |
|
|
<el-input v-model="passwordForm.oldPassword" type="password" show-password /> |
|
|
v-model="passwordForm.oldPassword" |
|
|
|
|
|
type="password" |
|
|
|
|
|
show-password |
|
|
|
|
|
/> |
|
|
|
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item label="新密码" prop="newPassword"> |
|
|
<el-form-item label="新密码" prop="newPassword"> |
|
|
<el-input |
|
|
<el-input v-model="passwordForm.newPassword" type="password" show-password /> |
|
|
v-model="passwordForm.newPassword" |
|
|
|
|
|
type="password" |
|
|
|
|
|
show-password |
|
|
|
|
|
/> |
|
|
|
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item label="再次输入密码" prop="confirmPassword"> |
|
|
<el-form-item label="再次输入密码" prop="confirmPassword"> |
|
|
<el-input |
|
|
<el-input v-model="passwordForm.confirmPassword" type="password" show-password /> |
|
|
v-model="passwordForm.confirmPassword" |
|
|
|
|
|
type="password" |
|
|
|
|
|
show-password |
|
|
|
|
|
/> |
|
|
|
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
<el-form-item> |
|
|
<el-form-item> |
|
|
<el-button type="primary" @click="toChangePwd">保存</el-button> |
|
|
<el-button type="primary" @click="toChangePwd">保存</el-button> |
|
@ -210,28 +203,20 @@ onMounted(()=>{ |
|
|
</el-main> |
|
|
</el-main> |
|
|
<el-dialog v-model="dialogShow" title="修改头像" width="400px" draggable> |
|
|
<el-dialog v-model="dialogShow" title="修改头像" width="400px" draggable> |
|
|
<div> |
|
|
<div> |
|
|
<span |
|
|
<span v-for="(item, index) in imgList" :key="item.name" class="img-box"> |
|
|
v-for="(item, index) in imgList" |
|
|
<el-avatar :size="80" :src="item.url" @click="chooseImg(index)" |
|
|
:key="item.name" |
|
|
:class="{ 'is-active': pos == index }"> |
|
|
class="img-box" |
|
|
|
|
|
> |
|
|
|
|
|
<el-avatar |
|
|
|
|
|
:size="80" |
|
|
|
|
|
:src="item.url" |
|
|
|
|
|
@click="chooseImg(index)" |
|
|
|
|
|
:class="{'is-active': pos == index}" |
|
|
|
|
|
> |
|
|
|
|
|
</el-avatar> |
|
|
</el-avatar> |
|
|
<el-icon v-show="pos == index"><Select /></el-icon> |
|
|
<el-icon v-show="pos == index"><Select /></el-icon> |
|
|
</span> |
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
<template #footer> |
|
|
<template #footer> |
|
|
<div class="dialog-footer"> |
|
|
<div class="dialog-footer"> |
|
|
<el-button @click="showChange(false)">{{ t("cancel") }}</el-button> |
|
|
<el-button @click="showChange(false)">{{ t("cancel") }}</el-button> |
|
|
<el-button type="primary" @click="toChangeHead"> |
|
|
<el-button type="primary" @click="toChangeHead"> |
|
|
{{ t("confirm") }} |
|
|
{{ t("confirm") }} |
|
|
</el-button> |
|
|
</el-button> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
</el-dialog> |
|
|
</el-dialog> |
|
|
</el-container> |
|
|
</el-container> |
|
@ -244,17 +229,21 @@ onMounted(()=>{ |
|
|
overflow-y: scroll |
|
|
overflow-y: scroll |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.img-box { |
|
|
.img-box { |
|
|
position: relative; |
|
|
position: relative; |
|
|
|
|
|
|
|
|
.el-avatar { |
|
|
.el-avatar { |
|
|
margin: 10px; |
|
|
margin: 10px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.is-active { |
|
|
.is-active { |
|
|
width: 90px; |
|
|
width: 90px; |
|
|
height: 90px; |
|
|
height: 90px; |
|
|
border: 2px solid green; |
|
|
border: 2px solid green; |
|
|
box-sizing: border-box; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.el-icon { |
|
|
.el-icon { |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
bottom: 0; |
|
|
bottom: 0; |
|
@ -264,9 +253,10 @@ onMounted(()=>{ |
|
|
border-radius: 50%; |
|
|
border-radius: 50%; |
|
|
color: white; |
|
|
color: white; |
|
|
background-color: green; |
|
|
background-color: green; |
|
|
transform: translate(-50%,0) |
|
|
transform: translate(-50%, 0) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.el-container { |
|
|
.el-container { |
|
|
|
|
|
|
|
|
.el-aside { |
|
|
.el-aside { |
|
@ -281,14 +271,47 @@ onMounted(()=>{ |
|
|
height: 40px; |
|
|
height: 40px; |
|
|
font-size: 14px; |
|
|
font-size: 14px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.is-active, |
|
|
.is-active, |
|
|
div:hover { |
|
|
div:hover { |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
color: #16b777; |
|
|
color: #16b777; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.el-input { |
|
|
.el-input { |
|
|
width: 200px; |
|
|
width: 200px; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@media screen and (max-width: 768px) { |
|
|
|
|
|
.el-container { |
|
|
|
|
|
position: relative; |
|
|
|
|
|
|
|
|
|
|
|
.el-aside { |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
padding: 0; |
|
|
|
|
|
justify-content: space-between; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
border-bottom: 1px solid #f9f9f9; |
|
|
|
|
|
|
|
|
|
|
|
div { |
|
|
|
|
|
text-align: center; |
|
|
|
|
|
line-height: 40px; |
|
|
|
|
|
|
|
|
|
|
|
&:first-child { |
|
|
|
|
|
border-right: 1px solid #fff; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.el-form { |
|
|
|
|
|
margin-top: vh(60); |
|
|
|
|
|
padding: 0 !important; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |
|
|