96 lines
2.7 KiB
Vue
96 lines
2.7 KiB
Vue
|
|
<!-- 强制修改密码(骨架占位页;登录对接与提交逻辑在后续任务实现) -->
|
|||
|
|
<template>
|
|||
|
|
<div class="force-change-password flex-cc w-full h-screen">
|
|||
|
|
<ElCard shadow="never" class="card">
|
|||
|
|
<template #header>
|
|||
|
|
<span class="card-title">首次登录请修改密码</span>
|
|||
|
|
</template>
|
|||
|
|
<ElForm ref="formRef" :model="formData" :rules="rules" label-position="top">
|
|||
|
|
<ElFormItem prop="newPassword" label="新密码">
|
|||
|
|
<ElInput
|
|||
|
|
v-model.trim="formData.newPassword"
|
|||
|
|
type="password"
|
|||
|
|
placeholder="请输入新密码"
|
|||
|
|
show-password
|
|||
|
|
autocomplete="off"
|
|||
|
|
/>
|
|||
|
|
</ElFormItem>
|
|||
|
|
<ElFormItem prop="confirmPassword" label="确认新密码">
|
|||
|
|
<ElInput
|
|||
|
|
v-model.trim="formData.confirmPassword"
|
|||
|
|
type="password"
|
|||
|
|
placeholder="请再次输入新密码"
|
|||
|
|
show-password
|
|||
|
|
autocomplete="off"
|
|||
|
|
/>
|
|||
|
|
</ElFormItem>
|
|||
|
|
<ElButton type="primary" class="w-full" :loading="loading" @click="handleSubmit">
|
|||
|
|
提交修改
|
|||
|
|
</ElButton>
|
|||
|
|
</ElForm>
|
|||
|
|
<p class="tip">密码修改成功后方可进入后台(对接后端 API 在后续任务实现)</p>
|
|||
|
|
</ElCard>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup lang="ts">
|
|||
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|||
|
|
|
|||
|
|
defineOptions({ name: 'ForceChangePassword' })
|
|||
|
|
|
|||
|
|
const formRef = ref<FormInstance>()
|
|||
|
|
const loading = ref(false)
|
|||
|
|
|
|||
|
|
const formData = reactive({
|
|||
|
|
newPassword: '',
|
|||
|
|
confirmPassword: ''
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const rules: FormRules = {
|
|||
|
|
newPassword: [
|
|||
|
|
{ required: true, message: '请输入新密码', trigger: 'blur' },
|
|||
|
|
{ min: 8, message: '密码长度不少于 8 位', trigger: 'blur' }
|
|||
|
|
],
|
|||
|
|
confirmPassword: [
|
|||
|
|
{ required: true, message: '请再次输入新密码', trigger: 'blur' },
|
|||
|
|
{
|
|||
|
|
validator: (_rule, value, callback) => {
|
|||
|
|
if (value !== formData.newPassword) {
|
|||
|
|
callback(new Error('两次输入的密码不一致'))
|
|||
|
|
} else {
|
|||
|
|
callback()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
trigger: 'blur'
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 骨架阶段仅做表单校验,不发起请求(Task 3 对接 /api/platform/auth/*)
|
|||
|
|
const handleSubmit = async () => {
|
|||
|
|
if (!formRef.value) return
|
|||
|
|
const valid = await formRef.value.validate().catch(() => false)
|
|||
|
|
if (!valid) return
|
|||
|
|
loading.value = true
|
|||
|
|
setTimeout(() => {
|
|||
|
|
loading.value = false
|
|||
|
|
}, 600)
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="scss">
|
|||
|
|
.card {
|
|||
|
|
width: 400px;
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tip {
|
|||
|
|
margin-top: 12px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--art-gray-500);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|