feat: 新增个人中心页
parent
5f8e795f64
commit
4146716655
@ -0,0 +1,96 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { FormSchema, Form } from '@/components/Form'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { ElDivider, ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
userInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const { required, phone, maxlength, email } = useValidator()
|
||||||
|
|
||||||
|
const formSchema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'realName',
|
||||||
|
label: '昵称',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'phoneNumber',
|
||||||
|
label: '手机号码',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'email',
|
||||||
|
label: '邮箱',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
realName: [required(), maxlength(50)],
|
||||||
|
phoneNumber: [phone()],
|
||||||
|
email: [email()]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { formRegister, formMethods } = useForm()
|
||||||
|
const { setValues, getElFormExpose } = formMethods
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.userInfo,
|
||||||
|
(value) => {
|
||||||
|
setValues(value)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const saveLoading = ref(false)
|
||||||
|
const save = async () => {
|
||||||
|
const elForm = await getElFormExpose()
|
||||||
|
const valid = await elForm?.validate().catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
if (valid) {
|
||||||
|
ElMessageBox.confirm('是否确认修改?', '提示', {
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
saveLoading.value = true
|
||||||
|
// 这里可以调用修改用户信息接口
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
} finally {
|
||||||
|
saveLoading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form :rules="rules" @register="formRegister" :schema="formSchema" />
|
||||||
|
<ElDivider />
|
||||||
|
<BaseButton type="primary" @click="save">保存</BaseButton>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Form, FormSchema } from '@/components/Form'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
|
import { ElMessage, ElMessageBox, ElDivider } from 'element-plus'
|
||||||
|
|
||||||
|
const { required } = useValidator()
|
||||||
|
|
||||||
|
const formSchema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'password',
|
||||||
|
label: '旧密码',
|
||||||
|
component: 'InputPassword',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'newPassword',
|
||||||
|
label: '新密码',
|
||||||
|
component: 'InputPassword',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
componentProps: {
|
||||||
|
strength: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'newPassword2',
|
||||||
|
label: '确认新密码',
|
||||||
|
component: 'InputPassword',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
componentProps: {
|
||||||
|
strength: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
password: [required()],
|
||||||
|
newPassword: [
|
||||||
|
required(),
|
||||||
|
{
|
||||||
|
asyncValidator: async (_, val, callback) => {
|
||||||
|
const formData = await getFormData()
|
||||||
|
const { newPassword2 } = formData
|
||||||
|
if (val !== newPassword2) {
|
||||||
|
callback(new Error('新密码与确认新密码不一致'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
newPassword2: [
|
||||||
|
required(),
|
||||||
|
{
|
||||||
|
asyncValidator: async (_, val, callback) => {
|
||||||
|
const formData = await getFormData()
|
||||||
|
const { newPassword } = formData
|
||||||
|
if (val !== newPassword) {
|
||||||
|
callback(new Error('确认新密码与新密码不一致'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { formRegister, formMethods } = useForm()
|
||||||
|
const { getFormData, getElFormExpose } = formMethods
|
||||||
|
|
||||||
|
const saveLoading = ref(false)
|
||||||
|
const save = async () => {
|
||||||
|
const elForm = await getElFormExpose()
|
||||||
|
const valid = await elForm?.validate().catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
if (valid) {
|
||||||
|
ElMessageBox.confirm('是否确认修改?', '提示', {
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
saveLoading.value = true
|
||||||
|
// 这里可以调用修改密码的接口
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
} finally {
|
||||||
|
saveLoading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form :rules="rules" @register="formRegister" :schema="formSchema" />
|
||||||
|
<ElDivider />
|
||||||
|
<BaseButton type="primary" @click="save">确认修改</BaseButton>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ImageCropping } from '@/components/ImageCropping'
|
||||||
|
import { ref, unref } from 'vue'
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const fileUrl = ref('')
|
||||||
|
|
||||||
|
const CropperRef = ref<ComponentRef<typeof ImageCropping>>()
|
||||||
|
|
||||||
|
const getBase64 = () => {
|
||||||
|
const base64 = unref(CropperRef)?.cropperExpose?.getCroppedCanvas()?.toDataURL() ?? ''
|
||||||
|
return base64
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getBase64
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ImageCropping ref="CropperRef" :image-url="fileUrl || url" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<script lang="ts" setup></script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<h1>个人设置</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
Loading…
Reference in New Issue