feat 个人中心

This commit is contained in:
Ironsp
2026-10-10 09:57:56 +08:00
parent 53f23d4e69
commit 0f038e7818
35 changed files with 2346 additions and 1656 deletions

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { StatusTag } from '@/components'
import { EllipsisText } from '@/components'
import type { Qualification, QualificationStatus } from '@/types/business/profile'
interface Props {
@@ -14,144 +14,144 @@ const emit = defineEmits<{
reupload: [qualification: Qualification]
}>()
const STATUS_VARIANTS: Record<QualificationStatus, 'success' | 'warning' | 'danger'> = {
已认证: 'success',
审核中: 'warning',
未通过: 'danger',
const STATUS_CLASS: Record<QualificationStatus, string> = {
已认证: 'is-certified',
审核中: 'is-reviewing',
未通过: 'is-rejected',
}
</script>
<template>
<article class="qual-card">
<div class="qual-card__head">
<h3 class="qual-card__name">
{{ qualification.certName }}
</h3>
<StatusTag
:label="qualification.status"
:variant="STATUS_VARIANTS[qualification.status]"
<article class="qual-row">
<div class="qual-row__col">
<p class="qual-row__label">资质类型</p>
<EllipsisText class="qual-row__value" :text="qualification.type" />
</div>
<div class="qual-row__col qual-row__col--name">
<p class="qual-row__label">证书名称</p>
<EllipsisText class="qual-row__value" :text="qualification.certName" />
</div>
<div class="qual-row__col">
<p class="qual-row__label">证书编号</p>
<EllipsisText class="qual-row__value" :text="qualification.certNo" />
</div>
<div class="qual-row__col">
<p class="qual-row__label">发证单位</p>
<EllipsisText class="qual-row__value" :text="qualification.issuer" />
</div>
<div class="qual-row__col qual-row__col--valid">
<p class="qual-row__label">有效期</p>
<EllipsisText
class="qual-row__value"
:text="qualification.validFrom + ' 至 ' + qualification.validTo"
/>
</div>
<ul class="qual-card__meta">
<li><span>资质类型:</span>{{ qualification.type }}</li>
<li><span>证书编号:</span>{{ qualification.certNo }}</li>
<li><span>发证单位:</span>{{ qualification.issuer }}</li>
<li><span>有效期:</span>{{ qualification.validFrom }} 至 {{ qualification.validTo }}</li>
</ul>
<div class="qual-card__actions">
<button class="qual-card__btn" @click="emit('edit', qualification)">
编辑
</button>
<button class="qual-card__btn qual-card__btn--danger" @click="emit('delete', qualification)">
<div class="qual-row__col qual-row__col--status">
<p class="qual-row__label">状态</p>
<p class="qual-row__value qual-row__status" :class="STATUS_CLASS[qualification.status]">
{{ qualification.status }}
</p>
</div>
<div class="qual-row__actions">
<button type="button" class="qual-row__btn" @click="emit('delete', qualification)">
删除
</button>
<button
v-if="qualification.status === '未通过'"
class="qual-card__btn qual-card__btn--warning"
type="button"
class="qual-row__btn"
@click="emit('reupload', qualification)"
>
重新上传
</button>
<button v-else type="button" class="qual-row__btn" @click="emit('edit', qualification)">
编辑
</button>
</div>
</article>
</template>
<style lang="less" scoped>
.qual-card {
.flex(column, flex-start);
gap: @spacing-sm;
padding: @spacing-base;
.qual-row {
position: relative;
.flex(row, flex-start, center);
min-height: 78px;
padding: 14px 24px 14px 52px;
border: 1px solid @profile-card-border;
border-radius: @radius-base;
border-radius: @radius-lg;
background: @white;
box-sizing: border-box;
&__head {
.flex(row, space-between, flex-start);
gap: @spacing-sm;
}
&__col {
flex: 0 0 200px;
min-width: 0;
padding-right: 20px;
box-sizing: border-box;
&__name {
font-size: 11px;
font-weight: 600;
color: @heading-color;
.multi-ellipsis(2);
}
&__meta {
.flex(column, flex-start);
gap: @spacing-xs;
list-style: none;
font-size: 11px;
color: @heading-color;
li {
.ellipsis();
font-weight: 600;
&--name {
flex: 0 0 270px;
}
span {
color: @text-color-secondary;
font-weight: 400;
&--valid {
flex: 0 0 250px;
}
&--status {
flex: 0 0 100px;
}
}
&__label {
font-size: @font-size-sm;
color: @finance-axis-text;
line-height: 16px;
}
&__value {
margin-top: 6px;
font-size: @font-size-base;
font-weight: 600;
color: @profile-ink;
line-height: 20px;
.ellipsis();
}
&__status {
&.is-reviewing {
color: @primary-strong;
}
&.is-certified {
color: @success-color;
}
&.is-rejected {
color: @danger-color;
}
}
&__actions {
.flex(row, center);
gap: @spacing-sm;
margin-top: auto;
padding-top: @spacing-sm;
border-top: 1px solid @profile-card-border;
width: 100%;
.flex(row, flex-start, center);
flex-shrink: 0;
gap: 12px;
margin-left: auto;
}
&__btn {
height: 24px;
padding: 0 10px;
border: 1px solid @profile-line;
border-radius: @profile-radius;
height: 28px;
padding: 0 14px;
border: 1px solid @profile-card-border;
border-radius: @radius-base;
background: @white;
color: @text-color;
font-size: 11px;
font-weight: 500;
color: @finance-entry-text;
font-size: @font-size-sm;
cursor: pointer;
transition: all 0.2s;
&:hover {
border-color: @primary-strong;
color: @primary-strong;
opacity: 1;
}
&--danger {
color: @text-color;
}
&--warning {
color: @text-color;
}
}
}
.qual-card .status-tag {
padding: 0;
background: transparent;
font-size: 12px;
font-weight: 700;
&--success {
background: transparent;
color: @heading-color;
}
&--warning {
background: transparent;
color: @heading-color;
}
&--danger {
background: transparent;
color: @danger-color;
}
}
</style>