feat: art-design-pro 脚手架落地与品牌化(八页骨架/代理配置/权限菜单)
- 模板 art-design-pro(MIT)GitHub 直连克隆后裁剪落地 admin/:删除演示页面/示例数据/mock/未用组件,保留构建与依赖清单 - 品牌化:应用名/标题/侧栏与登录页 logo/浏览器 favicon 全部替换为 all-kefu 自有资源(static/kefu-small.png),中文界面 - 八页骨架:login / force-change-password / dashboard / tenants / conversations / config / stats / settings 占位页 + 6 组路由模块 - 权限菜单:meta.roles 前端过滤,super 全量,tenant 隐藏 租户管理/平台设置(角色值与后端一致) - 开发代理:/api 直转 + /api/public 与 /static 携带租户 Host 改写(VITE_TENANT_PREVIEW_HOST),适配后端 TenantHostMiddleware - 认证 API 为开发桩(角色调试开关),Task 3 对接真实登录 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<!-- 强制修改密码(骨架占位页;登录对接与提交逻辑在后续任务实现) -->
|
||||
<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>
|
||||
Reference in New Issue
Block a user