Files
pc-10584/app/pages/console/account/security.vue
赵忠林 775841eed3 feat(core): 初始化项目基础架构和CMS功能模块
- 添加Docker相关配置文件(.dockerignore, .env.example, .gitignore)
- 实现服务端API代理功能,支持文件、模块和服务器API转发
- 创建文章详情页、栏目文章列表页和单页内容展示页面
- 集成Ant Design Vue组件库并实现SSR样式提取功能
- 定义API响应数据结构类型和应用布局组件
- 开发开发者应用中心和文章管理页面
- 实现CMS导航菜单获取和多租户切换功能
2026-01-27 00:14:08 +08:00

135 lines
3.9 KiB
Vue

<template>
<div class="space-y-4">
<a-page-header title="账号安全" sub-title="密码登录设备与安全设置">
<template #extra>
<a-space>
<a-button danger @click="logout">退出登录</a-button>
</a-space>
</template>
</a-page-header>
<a-row :gutter="[16, 16]">
<a-col :xs="24" :lg="12">
<a-card :bordered="false" class="card" title="修改密码">
<a-form ref="formRef" layout="vertical" :model="form" :rules="rules">
<a-form-item label="原密码" name="oldPassword">
<a-input-password v-model:value="form.oldPassword" placeholder="请输入原密码" />
</a-form-item>
<a-form-item label="新密码" name="password">
<a-input-password v-model:value="form.password" placeholder="请输入新密码(至少 6 位)" />
</a-form-item>
<a-form-item label="确认新密码" name="password2">
<a-input-password v-model:value="form.password2" placeholder="再次输入新密码" />
</a-form-item>
</a-form>
<div class="mt-2 flex justify-end gap-2">
<a-button @click="resetForm" :disabled="pending">重置</a-button>
<a-button type="primary" :loading="pending" @click="submit">保存</a-button>
</div>
<a-alert
class="mt-4"
show-icon
type="info"
message="修改密码后建议重新登录,以确保所有会话状态一致。"
/>
</a-card>
</a-col>
<a-col :xs="24" :lg="12">
<a-card :bordered="false" class="card" title="安全建议">
<a-list size="small" bordered :data-source="tips">
<template #renderItem="{ item }">
<a-list-item>{{ item }}</a-list-item>
</template>
</a-list>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { message, type FormInstance } from 'ant-design-vue'
import { updatePassword } from '@/api/layout'
import { removeToken } from '@/utils/token-util'
import { clearAuthz } from '@/utils/permission'
definePageMeta({ layout: 'console' })
const pending = ref(false)
const formRef = ref<FormInstance>()
const form = reactive<{ oldPassword: string; password: string; password2: string }>({
oldPassword: '',
password: '',
password2: ''
})
const rules = reactive({
oldPassword: [{ required: true, type: 'string', message: '请输入原密码' }],
password: [
{ required: true, type: 'string', message: '请输入新密码' },
{ min: 6, type: 'string', message: '新密码至少 6 位', trigger: 'blur' }
],
password2: [{ required: true, type: 'string', message: '请再次输入新密码' }]
})
const tips = [
'定期修改密码,避免与其他平台重复使用。',
'优先使用更长的随机密码。',
'不要将账号/密码分享给他人。',
'如怀疑账号被盗用,请立即修改密码并退出登录。'
]
function resetForm() {
form.oldPassword = ''
form.password = ''
form.password2 = ''
formRef.value?.clearValidate()
}
async function submit() {
try {
await formRef.value?.validate()
} catch {
return
}
if (form.password !== form.password2) {
message.error('两次输入的新密码不一致')
return
}
pending.value = true
try {
await updatePassword({ oldPassword: form.oldPassword, password: form.password })
message.success('密码修改成功')
resetForm()
} catch (e) {
message.error(e instanceof Error ? e.message : '密码修改失败')
} finally {
pending.value = false
}
}
function logout() {
removeToken()
try {
localStorage.removeItem('TenantId')
localStorage.removeItem('UserId')
} catch {
// ignore
}
clearAuthz()
navigateTo('/login')
}
</script>
<style scoped>
.card {
border-radius: 12px;
}
</style>