@@ -132,8 +132,8 @@ function newQualificationDrafts(): QualificationDraft[] {
const definitions : Array < Pick < QualificationDraft , ' type ' | ' label ' | ' required ' > > = [
{ type : 'BUSINESS_LICENSE' , label : '营业执照' , required : true } ,
{ type : 'LEGAL_PERSON_ID' , label : '法人身份证' , required : true } ,
{ type : 'FREIGHT_FORWARDER_CERTIFICATE' , label : '货代资质证书' , required : true } ,
{ type : 'BANK_ACCOUNT_LICENSE' , label : '银行开户许可证' , required : true } ,
{ type : 'FREIGHT_FORWARDER_CERTIFICATE' , label : '货代资质证书' , required : false } ,
{ type : 'BANK_ACCOUNT_LICENSE' , label : '银行开户许可证' , required : false } ,
]
return definitions . map ( ( item ) => ( {
... item ,
@@ -648,7 +648,7 @@ onMounted(async () => {
< div class = "qualification-table" role = "table" aria -label = " 客户资质文件 " >
< div class = "qualification-row qualification-header" role = "row" > < span role = "columnheader" > 文件类型 < / span > < span role = "columnheader" > 上传文件 < / span > < span role = "columnheader" > 有效期 < / span > < / div >
< div v-for = "draft in qualifications" :key="draft.type" class="qualification-row" role="row" >
< div class = "qualification-label" role = "cell" > < span v-if = "draft.required" aria-hidden="true">*</span>{{ draft.label }}<CheckCircle2 v-if="draft.uploaded" :size="16" aria-label="已上传" / > < / div >
< div class = "qualification-label" role = "cell" > < span v-if = "draft.required" aria-hidden="true">*</span>{{ draft.label }}<small v-if="!draft.required" class="qualification-optional">选填</small>< CheckCircle2 v-if="draft.uploaded" :size="16" aria-label="已上传" / > < / div >
< div class = "qualification-file" role = "cell" >
< button v-if = "draft.file || draft.uploaded" type="button" class="qualification-preview-trigger" :class="{ 'is-loading': draft.previewLoading }" :disabled="draft.previewLoading" :aria-label="`预览${draft.label}: ${draft.file?.name || draft.uploadedName}`" @click="openQualificationPreview(draft)" >
< img v-if = "draft.previewUrl && draft.previewKind === 'image' && !draft.previewFailed" :src="draft.previewUrl" :alt="`${draft.label}预览`" @error="handleQualificationPreviewError(draft)" / >
@@ -708,6 +708,7 @@ onMounted(async () => {
. qualification - heading { display : flex ; align - items : flex - start ; justify - content : space - between ; gap : 16 px ; } . qualification - heading h3 { margin - bottom : 4 px ; } . qualification - heading p , . qualification - hint { margin : 0 ; color : var ( -- cc - muted ) ; font - size : 12 px ; line - height : 1.6 ; } . qualification - hint { margin - top : 12 px ; } . qualification - hint span , . qualification - label > span { color : var ( -- el - color - danger ) ; }
. qualification - table { overflow : hidden ; margin - top : 14 px ; border : 1 px solid var ( -- cc - border ) ; border - radius : 8 px ; } . qualification - row { display : grid ; grid - template - columns : 180 px minmax ( 300 px , 1 fr ) 180 px ; min - width : 0 ; border - top : 1 px solid var ( -- cc - border ) ; } . qualification - row : first - child { border - top : 0 ; } . qualification - row > * { display : flex ; min - width : 0 ; min - height : 68 px ; align - items : center ; padding : 12 px 14 px ; } . qualification - header { min - height : 44 px ; background : # f7f8fc ; color : var ( -- cc - muted ) ; font - size : 12 px ; font - weight : 600 ; } . qualification - header > * { min - height : 44 px ; }
. qualification - label { gap : 5 px ; font - weight : 600 ; } . qualification - label svg { margin - left : auto ; color : var ( -- el - color - success ) ; }
. qualification - optional { padding : 2 px 5 px ; border - radius : 4 px ; background : var ( -- el - fill - color - light ) ; color : var ( -- cc - muted ) ; font - size : 10 px ; font - weight : 500 ; line - height : 1.4 ; }
. qualification - file { gap : 12 px ; } . qualification - file - control { display : flex ; min - width : 0 ; flex : 1 ; flex - wrap : wrap ; align - items : center ; gap : 8 px ; } . file - picker { position : relative ; display : inline - flex ; min - height : 36 px ; flex : 0 0 auto ; align - items : center ; gap : 7 px ; overflow : hidden ; padding : 0 12 px ; border : 1 px solid var ( -- cc - border ) ; border - radius : 6 px ; background : # fff ; color : var ( -- cc - text ) ; cursor : pointer ; } . file - picker : focus - within { outline : 2 px solid color - mix ( in srgb , var ( -- cc - primary ) 35 % , transparent ) ; outline - offset : 2 px ; } . file - picker . is - disabled { cursor : not - allowed ; opacity : .6 ; } . file - picker input { position : absolute ; inset : 0 ; width : 100 % ; height : 100 % ; opacity : 0 ; cursor : inherit ; } . qualification - file - name { min - width : 0 ; max - width : 180 px ; overflow : hidden ; color : var ( -- cc - muted ) ; font - size : 12 px ; text - overflow : ellipsis ; white - space : nowrap ; } . qualification - error { width : 100 % ; color : var ( -- el - color - danger ) ; line - height : 1.4 ; }
. qualification - preview - trigger { position : relative ; display : grid ; width : 68 px ; height : 68 px ; flex : 0 0 68 px ; overflow : hidden ; place - items : center ; padding : 0 ; border : 1 px solid var ( -- cc - border ) ; border - radius : 6 px ; background : # f8fafc ; color : var ( -- cc - muted ) ; cursor : pointer ; }
. qualification - preview - trigger : hover { border - color : var ( -- cc - primary ) ; color : var ( -- cc - primary ) ; }