feat(portal): implement security settings page and register ConfirmationService

This commit is contained in:
2025-12-26 14:09:57 +08:00
parent f8c312752e
commit eefcfc79a5
2 changed files with 146 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ import { createPinia } from 'pinia';
import PrimeVue from 'primevue/config';
import Aura from '@primevue/themes/aura';
import ToastService from 'primevue/toastservice';
import ConfirmationService from 'primevue/confirmationservice';
import App from './App.vue';
import router from './router';
@@ -14,6 +15,7 @@ const app = createApp(App);
app.use(createPinia());
app.use(router);
app.use(ToastService);
app.use(ConfirmationService);
app.use(PrimeVue, {
theme: {
preset: Aura,

View File

@@ -1,6 +1,147 @@
<template>
<div class="p-8">
<h1 class="text-2xl font-bold mb-4">Account Security</h1>
<p class="text-slate-400">(Password and bindings)</p>
<div class="bg-white rounded-xl shadow-sm border border-slate-100 min-h-[600px] p-8">
<h1 class="text-2xl font-bold text-slate-900 mb-8">账号安全</h1>
<!-- Security Level (Optional visual) -->
<div class="mb-10 p-6 bg-slate-50 rounded-xl border border-slate-100 flex items-center justify-between">
<div>
<div class="text-lg font-bold text-slate-900 mb-1">安全等级</div>
<p class="text-sm text-slate-500">建议绑定邮箱并完成实名认证提升账号安全性</p>
</div>
<div class="w-32 h-2 bg-slate-200 rounded-full overflow-hidden">
<div class="h-full bg-orange-500 w-1/2"></div>
</div>
</div>
<!-- Security Items -->
<div class="space-y-6">
<!-- Password -->
<div class="flex items-center justify-between py-4 border-b border-slate-50">
<div class="flex items-center gap-4">
<i class="pi pi-lock text-xl text-slate-400"></i>
<div>
<div class="font-bold text-slate-900">登录密码</div>
<div class="text-sm text-slate-500">已设置建议定期更换</div>
</div>
</div>
<button @click="openVerify('password')" class="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg hover:bg-slate-50 text-sm font-medium transition-colors">修改</button>
</div>
<!-- Phone -->
<div class="flex items-center justify-between py-4 border-b border-slate-50">
<div class="flex items-center gap-4">
<i class="pi pi-mobile text-xl text-slate-400"></i>
<div>
<div class="font-bold text-slate-900">手机绑定</div>
<div class="text-sm text-slate-500">已绑定138****8888</div>
</div>
</div>
<button @click="openVerify('phone')" class="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg hover:bg-slate-50 text-sm font-medium transition-colors">更换</button>
</div>
<!-- Email -->
<div class="flex items-center justify-between py-4 border-b border-slate-50">
<div class="flex items-center gap-4">
<i class="pi pi-envelope text-xl text-slate-400"></i>
<div>
<div class="font-bold text-slate-900">邮箱绑定</div>
<div class="text-sm text-slate-500">未绑定</div>
</div>
</div>
<button @click="openVerify('email')" class="px-4 py-2 text-primary-600 font-medium hover:text-primary-700 text-sm transition-colors">立即绑定</button>
</div>
<!-- Real-name Auth -->
<div class="flex items-center justify-between py-4 border-b border-slate-50">
<div class="flex items-center gap-4">
<i class="pi pi-id-card text-xl text-slate-400"></i>
<div>
<div class="font-bold text-slate-900">实名认证</div>
<div class="text-sm text-slate-500">未认证发布内容前需完成认证</div>
</div>
</div>
<button @click="$router.push('/creator/apply')" class="px-4 py-2 text-primary-600 font-medium hover:text-primary-700 text-sm transition-colors">去认证</button>
</div>
<!-- Delete Account -->
<div class="flex items-center justify-between py-4 pt-8">
<div class="flex items-center gap-4">
<i class="pi pi-exclamation-circle text-xl text-red-400"></i>
<div>
<div class="font-bold text-slate-900">注销账号</div>
<div class="text-sm text-slate-500">注销后账号及资产将无法找回请谨慎操作</div>
</div>
</div>
<button @click="confirmDelete" class="px-4 py-2 bg-red-50 text-red-600 rounded-lg hover:bg-red-100 text-sm font-medium transition-colors">注销</button>
</div>
</div>
<!-- Verification Dialog -->
<Dialog v-model:visible="verifyDialog" modal header="安全验证" :style="{ width: '25rem' }">
<div class="text-sm text-slate-600 mb-6">为了您的账号安全请先进行身份验证</div>
<div class="space-y-4">
<div>
<label class="block text-xs font-bold text-slate-500 mb-1">手机号</label>
<div class="text-lg font-bold text-slate-900">138****8888</div>
</div>
<div>
<label class="block text-xs font-bold text-slate-500 mb-2">验证码</label>
<div class="flex gap-2">
<input type="text" class="flex-1 h-10 px-3 rounded border border-slate-200 focus:border-primary-500 focus:outline-none" placeholder="6位数字">
<button class="px-3 h-10 border border-slate-200 rounded text-sm text-slate-600 hover:bg-slate-50">获取验证码</button>
</div>
</div>
</div>
<div class="flex justify-end gap-2 mt-8">
<button @click="verifyDialog = false" class="px-4 py-2 text-slate-500 hover:text-slate-700 text-sm">取消</button>
<button @click="handleVerifySuccess" class="px-4 py-2 bg-primary-600 text-white rounded hover:bg-primary-700 text-sm">下一步</button>
</div>
</Dialog>
<ConfirmDialog></ConfirmDialog>
<Toast />
</div>
</template>
<script setup>
import { ref } from 'vue';
import Dialog from 'primevue/dialog';
import ConfirmDialog from 'primevue/confirmdialog';
import Toast from 'primevue/toast';
import { useConfirm } from 'primevue/useconfirm';
import { useToast } from 'primevue/usetoast';
const confirm = useConfirm();
const toast = useToast();
const verifyDialog = ref(false);
const currentAction = ref('');
const openVerify = (action) => {
currentAction.value = action;
verifyDialog.value = true;
};
const handleVerifySuccess = () => {
verifyDialog.value = false;
toast.add({ severity: 'success', summary: '验证通过', detail: '即将跳转至操作页面...', life: 2000 });
// In real app, redirect to specific edit page
};
const confirmDelete = () => {
confirm.require({
message: '注销后,您的所有数据、资产、购买记录将永久丢失且无法找回。请输入“注销”以确认。',
header: '高风险操作确认',
icon: 'pi pi-info-circle',
rejectLabel: '取消',
acceptLabel: '确认注销',
rejectClass: 'p-button-secondary p-button-outlined',
acceptClass: 'p-button-danger',
accept: () => {
toast.add({ severity: 'error', summary: '已提交注销申请', detail: '账号将在 7 天后正式注销', life: 3000 });
}
});
};
</script>