mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-09 18:59:26 +08:00
feat: 新增修改手机号、修改邮箱、修改密码、修改基本信息
This commit is contained in:
@@ -7,6 +7,7 @@ export interface UserInfo {
|
||||
email: string
|
||||
phone: string
|
||||
avatar: string
|
||||
pwdResetTime: string
|
||||
registrationDate: string
|
||||
deptName: string
|
||||
roles: string[]
|
||||
|
@@ -2,9 +2,9 @@ export * from './user'
|
||||
export * from './role'
|
||||
export * from './menu'
|
||||
export * from './dept'
|
||||
export * from '../monitor/log'
|
||||
export * from './announcement'
|
||||
export * from './dict'
|
||||
export * from './file'
|
||||
export * from './storage'
|
||||
export * from './option'
|
||||
export * from './announcement'
|
||||
export * from './user-center'
|
||||
|
39
src/apis/system/user-center.ts
Normal file
39
src/apis/system/user-center.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import http from '@/utils/http'
|
||||
import type * as System from '@/apis/system/type'
|
||||
|
||||
const BASE_URL = '/system/user'
|
||||
|
||||
/** @desc 修改用户基本信息 */
|
||||
export function updateUserBaseInfo(data: { nickname: string; gender: number }) {
|
||||
return http.patch(`${BASE_URL}/basic/info`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改密码 */
|
||||
export function updateUserPassword(data: { oldPassword: string; newPassword: string }) {
|
||||
return http.patch(`${BASE_URL}/password`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改手机号 */
|
||||
export function updateUserPhone(data: { newPhone: string; captcha: string; currentPassword: string }) {
|
||||
return http.patch(`${BASE_URL}/phone`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改邮箱 */
|
||||
export function updateUserEmail(data: { newEmail: string; captcha: string; currentPassword: string }) {
|
||||
return http.patch(`${BASE_URL}/email`, data)
|
||||
}
|
||||
|
||||
/** @desc 获取绑定的三方账号 */
|
||||
export function listUserSocial() {
|
||||
return http.get<System.BindSocialAccountRes[]>(`${BASE_URL}/social`)
|
||||
}
|
||||
|
||||
/** @desc 绑定三方账号 */
|
||||
export function bindSocialAccount(source: string, data: any) {
|
||||
return http.post(`${BASE_URL}/social/${source}`, data)
|
||||
}
|
||||
|
||||
/** @desc 解绑三方账号 */
|
||||
export function unbindSocialAccount(source: string) {
|
||||
return http.del(`${BASE_URL}/social/${source}`)
|
||||
}
|
@@ -37,25 +37,3 @@ export function exportUser(query: System.UserQuery) {
|
||||
export function resetUserPwd(data: any, id: string) {
|
||||
return http.patch(`${BASE_URL}/${id}/password`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改用户基础信息 */
|
||||
export function updateUserBaseInfo(data: { nickname?: string; gender?: number }) {
|
||||
return http.patch(`${BASE_URL}/basic/info`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改邮箱 */
|
||||
export function updateUserEmail(data: { newEmail: string; captcha: string; currentPassword: string }) {
|
||||
return http.patch(`${BASE_URL}/email`, data)
|
||||
}
|
||||
/**@desc 绑定三方账号 */
|
||||
export function bindSocialAccount(source: string, data: any) {
|
||||
return http.post(`${BASE_URL}/social/${source}`, data)
|
||||
}
|
||||
/**@desc 获取绑定的三方账号 */
|
||||
export function getSocialAccount() {
|
||||
return http.get<System.BindSocialAccountRes[]>(`${BASE_URL}/social`)
|
||||
}
|
||||
/**@desc 解绑三方账号 */
|
||||
export function unbindSocialAccount(source: string) {
|
||||
return http.del(`${BASE_URL}/social/${source}`)
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ const storeSetup = () => {
|
||||
email: '',
|
||||
phone: '',
|
||||
avatar: '',
|
||||
pwdResetTime: '',
|
||||
registrationDate: '',
|
||||
deptName: '',
|
||||
roles: [],
|
||||
|
@@ -313,6 +313,12 @@
|
||||
.btn {
|
||||
height: 28px;
|
||||
width: 56px;
|
||||
&:hover {
|
||||
-webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, .15);
|
||||
box-shadow: 0 2px 3px rgba(0, 0, 0, .15);
|
||||
border-color: rgb(var(--primary-5));
|
||||
color: var(--color-text-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -74,8 +74,10 @@ const handleLogin = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const captchaTime = ref(60)
|
||||
const captchaTimer = ref()
|
||||
const captchaTime = ref(60)
|
||||
const captchaBtnName = ref('获取验证码')
|
||||
const captchaDisable = ref(false)
|
||||
// 重置验证码
|
||||
const resetCaptcha = () => {
|
||||
window.clearInterval(captchaTimer.value)
|
||||
@@ -84,15 +86,13 @@ const resetCaptcha = () => {
|
||||
captchaDisable.value = false
|
||||
}
|
||||
|
||||
const captchaBtnName = ref('获取验证码')
|
||||
const captchaLoading = ref(false)
|
||||
const captchaDisable = ref(false)
|
||||
// 获取验证码
|
||||
const onCaptcha = async () => {
|
||||
try {
|
||||
if (captchaLoading.value) return
|
||||
const isInvalid = await formRef.value?.validateField('email')
|
||||
if (isInvalid) return
|
||||
try {
|
||||
captchaLoading.value = true
|
||||
captchaBtnName.value = '发送中...'
|
||||
// await getEmailCaptcha({
|
||||
|
@@ -77,8 +77,10 @@ const handleLogin = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const captchaTime = ref(60)
|
||||
const captchaTimer = ref()
|
||||
const captchaTime = ref(60)
|
||||
const captchaBtnName = ref('获取验证码')
|
||||
const captchaDisable = ref(false)
|
||||
// 重置验证码
|
||||
const resetCaptcha = () => {
|
||||
window.clearInterval(captchaTimer.value)
|
||||
@@ -87,15 +89,13 @@ const resetCaptcha = () => {
|
||||
captchaDisable.value = false
|
||||
}
|
||||
|
||||
const captchaBtnName = ref('获取验证码')
|
||||
const captchaLoading = ref(false)
|
||||
const captchaDisable = ref(false)
|
||||
// 获取验证码
|
||||
const onCaptcha = async () => {
|
||||
try {
|
||||
if (captchaLoading.value) return
|
||||
const isInvalid = await formRef.value?.validateField('phone')
|
||||
if (isInvalid) return
|
||||
try {
|
||||
captchaLoading.value = true
|
||||
captchaBtnName.value = '发送中...'
|
||||
// await getSmsCaptcha({
|
||||
|
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="card_header">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
<div class="card_body">
|
||||
<slot name="body"> </slot>
|
||||
</div>
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
background: var(--color-bg-1);
|
||||
border: 1px solid var(--color-neutral-2);
|
||||
.card_header {
|
||||
padding: 18px 20px;
|
||||
background: -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
from(rgba(232, 244, 255, 0.5)),
|
||||
to(hsla(0, 0%, 100%, 0))
|
||||
);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
background: linear-gradient(180deg, rgba(232, 244, 255, 0.5), hsla(0, 0%, 100%, 0));
|
||||
}
|
||||
.card_body {
|
||||
flex: 1;
|
||||
padding: 15px 28px;
|
||||
}
|
||||
.card_footer {
|
||||
padding: 15px 28px;
|
||||
border-top: 1px solid var(--color-neutral-2);
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,107 +1,184 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :title="title" @before-ok="save" @cancel="handleCancel">
|
||||
<a-form :model="form" ref="formRef">
|
||||
<a-form-item
|
||||
field="newPhone"
|
||||
label="新手机号"
|
||||
:rules="[{ required: true, match: Regexp.Phone, message: '请输入正确的手机号' }]"
|
||||
v-if="verifyType === 'phone'"
|
||||
<a-modal v-model:visible="visible" :title="title" @before-ok="save" @close="reset">
|
||||
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns">
|
||||
<template #captcha>
|
||||
<a-input v-model="form.captcha" placeholder="请输入验证码" :max-length="4" allow-clear style="flex: 1 1" />
|
||||
<a-button
|
||||
class="captcha-btn"
|
||||
:loading="captchaLoading"
|
||||
:disabled="captchaDisable"
|
||||
size="large"
|
||||
@click="onCaptcha"
|
||||
>
|
||||
<a-input v-model="form.newPhone" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="email"
|
||||
label="邮箱"
|
||||
v-if="verifyType === 'email'"
|
||||
:rules="[{ required: true, match: Regexp.Email, message: '请输入正确的邮箱' }]"
|
||||
>
|
||||
<a-input v-model="form.email" />
|
||||
</a-form-item>
|
||||
<a-form-item field="verifyCode" label="验证码" :rules="[{ required: true, message: '请输入正确的验证码' }]">
|
||||
<a-input v-model="form.captcha" />
|
||||
<a-button type="outline" @click="onSendCaptcha">发送验证码</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="currentPassword"
|
||||
label="当前密码"
|
||||
:rules="[
|
||||
{ required: true, message: '请输入当前密码' },
|
||||
{ match: Regexp.Password, message: '请输入格式的密码' }
|
||||
]"
|
||||
>
|
||||
<a-input v-model="form.currentPassword" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
{{ captchaBtnName }}
|
||||
</a-button>
|
||||
</template>
|
||||
</GiForm>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { getSmsCaptcha, getEmailCaptcha, updateUserEmail } from '@/apis'
|
||||
import { encryptByRsa } from '@/utils/encrypt'
|
||||
// import { getSmsCaptcha, getEmailCaptcha, updateUserEmail, updateUserPhone } from '@/apis'
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
// import { encryptByRsa } from '@/utils/encrypt'
|
||||
import * as Regexp from '@/utils/regexp'
|
||||
import { Message, type Modal } from '@arco-design/web-vue'
|
||||
import { useUserStore } from '@/stores'
|
||||
const userStore = useUserStore()
|
||||
const visible = ref<boolean>(false)
|
||||
const form = reactive({
|
||||
import { type Columns, GiForm } from '@/components/GiForm'
|
||||
import { useForm } from '@/hooks'
|
||||
|
||||
const verifyType = ref()
|
||||
const title = computed(() => (verifyType.value === 'phone' ? '修改手机号' : '修改邮箱'))
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const options: Options = {
|
||||
form: {},
|
||||
col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
|
||||
btns: { hide: true }
|
||||
}
|
||||
|
||||
const columns: Columns = [
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'newPhone',
|
||||
type: 'input',
|
||||
rules: [
|
||||
{ required: true, message: '请输入手机号' },
|
||||
{ match: Regexp.Phone, message: '请输入正确的手机号' }
|
||||
],
|
||||
hide: () => {
|
||||
return verifyType.value !== 'phone'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
field: 'email',
|
||||
type: 'input',
|
||||
rules: [
|
||||
{ required: true, message: '请输入邮箱' },
|
||||
{ match: Regexp.Email, message: '请输入正确的邮箱' }
|
||||
],
|
||||
hide: () => {
|
||||
return verifyType.value !== 'email'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '验证码',
|
||||
field: 'captcha',
|
||||
type: 'input',
|
||||
rules: [{ required: true, message: '请输入验证码' }]
|
||||
},
|
||||
{
|
||||
label: '当前密码',
|
||||
field: 'currentPassword',
|
||||
type: 'input',
|
||||
rules: [{ required: true, message: '请输入当前密码' }]
|
||||
}
|
||||
]
|
||||
|
||||
const { form, resetForm } = useForm({
|
||||
newPhone: '',
|
||||
captcha: '',
|
||||
currentPassword: '',
|
||||
email: ''
|
||||
})
|
||||
const formRef = ref()
|
||||
const verifyType = ref()
|
||||
const title = computed(() => {
|
||||
return verifyType.value === 'phone' ? '修改手机号' : '修改邮箱'
|
||||
})
|
||||
const onSendCaptcha = () => {
|
||||
formRef.value.validateField(verifyType.value === 'phone' ? 'newPhone' : 'email', (validate) => {
|
||||
if (!validate) {
|
||||
// 发送验证码
|
||||
if (verifyType.value === 'phone') {
|
||||
//手机号
|
||||
getSmsCaptcha({ phone: form.newPhone }).then((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
} else if (verifyType.value === 'email') {
|
||||
//邮箱
|
||||
getEmailCaptcha({ email: form.email }).then((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
resetCaptcha()
|
||||
}
|
||||
const save: InstanceType<typeof Modal>['onBeforeOk'] = async () => {
|
||||
const flag = await formRef.value?.validate()
|
||||
if (flag) return false
|
||||
|
||||
const captchaTimer = ref()
|
||||
const captchaTime = ref(60)
|
||||
const captchaBtnName = ref('获取验证码')
|
||||
const captchaDisable = ref(false)
|
||||
// 重置验证码
|
||||
const resetCaptcha = () => {
|
||||
window.clearInterval(captchaTimer.value)
|
||||
captchaTime.value = 60
|
||||
captchaBtnName.value = '获取验证码'
|
||||
captchaDisable.value = false
|
||||
}
|
||||
|
||||
const captchaLoading = ref(false)
|
||||
// 获取验证码
|
||||
const onCaptcha = async () => {
|
||||
const isInvalid = await formRef.value?.formRef?.validateField(verifyType.value === 'phone' ? 'newPhone' : 'email')
|
||||
if (isInvalid) return false
|
||||
// 发送验证码
|
||||
try {
|
||||
const res = await updateUserEmail({
|
||||
newEmail: form.email,
|
||||
captcha: form.captcha,
|
||||
currentPassword: encryptByRsa(form.currentPassword) as string
|
||||
})
|
||||
if (res.code === 200) {
|
||||
Message.success('修改成功')
|
||||
visible.value = false
|
||||
// 修改成功后,重新获取用户信息
|
||||
userStore.getInfo()
|
||||
return true
|
||||
captchaLoading.value = true
|
||||
captchaBtnName.value = '发送中...'
|
||||
if (verifyType.value === 'phone') {
|
||||
// await getSmsCaptcha({
|
||||
// phone: form.newPhone
|
||||
// })
|
||||
} else if (verifyType.value === 'email') {
|
||||
// await getEmailCaptcha({
|
||||
// email: form.email
|
||||
// })
|
||||
}
|
||||
captchaLoading.value = false
|
||||
captchaDisable.value = true
|
||||
captchaBtnName.value = `获取验证码(${(captchaTime.value -= 1)}s)`
|
||||
// Message.success('发送成功')
|
||||
Message.success('仅提供效果演示,实际使用请查看代码取消相关注释')
|
||||
captchaTimer.value = window.setInterval(() => {
|
||||
captchaTime.value -= 1
|
||||
captchaBtnName.value = `获取验证码(${captchaTime.value}s)`
|
||||
if (captchaTime.value <= 0) {
|
||||
resetCaptcha()
|
||||
}
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
resetCaptcha()
|
||||
} finally {
|
||||
captchaLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const userStore = useUserStore()
|
||||
// 保存
|
||||
const save = async () => {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
try {
|
||||
if (verifyType.value === 'phone') {
|
||||
// await updateUserEmail({
|
||||
// newEmail: form.email,
|
||||
// captcha: form.captcha,
|
||||
// currentPassword: encryptByRsa(form.currentPassword) as string
|
||||
// })
|
||||
} else if (verifyType.value === 'email') {
|
||||
// await updateUserPhone({
|
||||
// newPhone: form.email,
|
||||
// captcha: form.captcha,
|
||||
// currentPassword: encryptByRsa(form.currentPassword) as string
|
||||
// })
|
||||
}
|
||||
Message.success('修改成功')
|
||||
// 修改成功后,重新获取用户信息
|
||||
await userStore.getInfo()
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
// return await saveApi()
|
||||
}
|
||||
const handleCancel = () => {
|
||||
formRef.value?.resetFields()
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
// 打开弹框
|
||||
const open = (type: string) => {
|
||||
verifyType.value = type
|
||||
visible.value = true
|
||||
}
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.captcha-btn {
|
||||
margin-left: 12px;
|
||||
min-width: 98px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<div class="name">
|
||||
<span style="margin-right: 10px">{{ userInfo.nickname }}</span>
|
||||
<icon-edit :size="16" class="btn" @click="onEditNickName" />
|
||||
<icon-edit :size="16" class="btn" @click="onUpdate" />
|
||||
</div>
|
||||
<div class="id">
|
||||
<GiSvgIcon name="id" :size="16" />
|
||||
@@ -43,22 +43,81 @@
|
||||
</div>
|
||||
<div class="footer">注册于 {{ userInfo.registrationDate }}</div>
|
||||
</a-card>
|
||||
<VerifyModel ref="verifyModelRef" />
|
||||
|
||||
<a-modal v-model:visible="visible" title="修改基本信息" @before-ok="save" @close="reset">
|
||||
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { updateUserBaseInfo } from '@/apis'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
import { updateUserBaseInfo, updateUserPassword } from '@/apis'
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { type Columns, GiForm } from '@/components/GiForm'
|
||||
import { useForm } from '@/hooks'
|
||||
import { useUserStore } from '@/stores'
|
||||
import { encryptByRsa } from '@/utils/encrypt'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
const onEditNickName = () => {
|
||||
userStore.editNickNameVisible = true
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const options: Options = {
|
||||
form: {},
|
||||
col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
|
||||
btns: { hide: true }
|
||||
}
|
||||
const openVerifyModel = (type: 'phone' | 'email') => {
|
||||
verifyModelRef.value?.open(type)
|
||||
|
||||
const columns: Columns = [
|
||||
{
|
||||
label: '昵称',
|
||||
field: 'nickname',
|
||||
type: 'input',
|
||||
rules: [{ required: true, message: '请输入昵称' }]
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'gender',
|
||||
type: 'radio-group',
|
||||
options: [
|
||||
{ label: '男', value: 1 },
|
||||
{ label: '女', value: 2 },
|
||||
{ label: '未知', value: 0, disabled: true }
|
||||
],
|
||||
rules: [{ required: true, message: '请选择性别' }]
|
||||
}
|
||||
]
|
||||
|
||||
const { form, resetForm } = useForm({
|
||||
nickname: userInfo.value.nickname,
|
||||
gender: userInfo.value.gender
|
||||
})
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
// 修改
|
||||
const onUpdate = async () => {
|
||||
reset()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
try {
|
||||
await updateUserBaseInfo(form)
|
||||
Message.success('修改成功')
|
||||
// 修改成功后,重新获取用户信息
|
||||
await userStore.getInfo()
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
v-if="item.jumpMode == 'modal'"
|
||||
class="btn"
|
||||
:type="item.status ? 'secondary' : 'primary'"
|
||||
@click="openVerifyModel(item.type, item.status)"
|
||||
@click="onUpdate(item.type, item.status)"
|
||||
>
|
||||
{{ item.status ? '修改' : '绑定' }}
|
||||
</a-button>
|
||||
@@ -44,19 +44,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { socialAuth, getSocialAccount, unbindSocialAccount } from '@/apis'
|
||||
import { socialAuth, listUserSocial, unbindSocialAccount } from '@/apis'
|
||||
import type { ModeItem } from '../type'
|
||||
import { useUserStore } from '@/stores'
|
||||
import VerifyModel from '../components/VerifyModel.vue'
|
||||
import { useUserStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
const openVerifyModel = (type: 'phone' | 'email') => {
|
||||
verifyModelRef.value?.open(type)
|
||||
}
|
||||
const socialList = ref<any>([])
|
||||
|
||||
const socialList = ref<any>([])
|
||||
const modeList = ref<ModeItem[]>([])
|
||||
modeList.value = [
|
||||
{
|
||||
@@ -94,12 +90,8 @@ modeList.value = [
|
||||
status: socialList.value.some((el) => el == 'github')
|
||||
}
|
||||
]
|
||||
const initData = () => {
|
||||
getSocialAccount().then((res) => {
|
||||
socialList.value = res.data.map((el) => el.source)
|
||||
})
|
||||
}
|
||||
|
||||
// 绑定
|
||||
const onBinding = (type: string, status: boolean) => {
|
||||
if (!status) {
|
||||
socialAuth(type).then((res) => {
|
||||
@@ -114,6 +106,19 @@ const onBinding = (type: string, status: boolean) => {
|
||||
}
|
||||
}
|
||||
|
||||
const verifyModelRef = ref<InstanceType<typeof VerifyModel>>()
|
||||
// 修改
|
||||
const onUpdate = (type: string) => {
|
||||
verifyModelRef.value?.open(type)
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
listUserSocial().then((res) => {
|
||||
socialList.value = res.data.map((el) => el.source)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initData()
|
||||
})
|
||||
|
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<a-switch disabled />
|
||||
<a-switch disabled title="未开放" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<div class="info-desc">为了您的账号安全,建议定期修改密码</div>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<a-button class="btn">修改</a-button>
|
||||
<a-button class="btn" @click="onUpdate">修改</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
@@ -31,8 +31,91 @@
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-modal v-model:visible="visible" title="修改密码" @before-ok="save" @close="reset">
|
||||
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import { updateUserPassword } from '@/apis'
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { encryptByRsa } from '@/utils/encrypt'
|
||||
import { type Columns, GiForm } from '@/components/GiForm'
|
||||
import { useForm } from '@/hooks'
|
||||
import { useUserStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const options: Options = {
|
||||
form: {},
|
||||
col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
|
||||
btns: { hide: true }
|
||||
}
|
||||
|
||||
const columns: Columns = [
|
||||
{
|
||||
label: '当前密码',
|
||||
field: 'oldPassword',
|
||||
type: 'input-password',
|
||||
rules: [{ required: true, message: '请输入当前密码' }],
|
||||
hide: () => {
|
||||
return userInfo.pwdResetTime
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '新密码',
|
||||
field: 'newPassword',
|
||||
type: 'input-password',
|
||||
rules: [{ required: true, message: '请输入新密码' }]
|
||||
},
|
||||
{
|
||||
label: '确认新密码',
|
||||
field: 'rePassword',
|
||||
type: 'input-password',
|
||||
rules: [{ required: true, message: '请再次输入新密码' }],
|
||||
props: {
|
||||
placeholder: '请再次输入新密码'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const { form, resetForm } = useForm({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
rePassword: ''
|
||||
})
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
// 修改
|
||||
const onUpdate = async () => {
|
||||
reset()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
try {
|
||||
await updateUserPassword({
|
||||
oldPassword: encryptByRsa(form.oldPassword) || '',
|
||||
newPassword: encryptByRsa(form.newPassword) || ''
|
||||
})
|
||||
Message.success('修改成功')
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
Reference in New Issue
Block a user