| <template> | 
|   <a-card :bordered="false"> | 
|     <a-space :size="54"> | 
|       <a-upload | 
|         :custom-request="customRequest" | 
|         list-type="picture-card" | 
|         :file-list="fileList" | 
|         :show-upload-button="true" | 
|         :show-file-list="false" | 
|         @change="uploadChange" | 
|       > | 
|         <template #upload-button> | 
|           <a-avatar :size="100" class="info-avatar"> | 
|             <template #trigger-icon> | 
|               <icon-camera /> | 
|             </template> | 
|             <img v-if="fileList.length" :src="fileList[0].url" /> | 
|           </a-avatar> | 
|         </template> | 
|       </a-upload> | 
|       <a-descriptions | 
|         :data="renderData" | 
|         :column="2" | 
|         align="right" | 
|         layout="inline-horizontal" | 
|         :label-style="{ | 
|           width: '140px', | 
|           fontWeight: 'normal', | 
|           color: 'rgb(var(--gray-8))', | 
|         }" | 
|         :value-style="{ | 
|           width: '200px', | 
|           paddingLeft: '8px', | 
|           textAlign: 'left', | 
|         }" | 
|       > | 
|         <template #label="{ label }">{{ $t(label) }} :</template> | 
|         <template #value="{ value, data }"> | 
|           <a-tag | 
|             v-if="data.label === 'userSetting.label.certification'" | 
|             color="green" | 
|             size="small" | 
|           > | 
|             已认证 | 
|           </a-tag> | 
|           <span v-else>{{ value }}</span> | 
|         </template> | 
|       </a-descriptions> | 
|     </a-space> | 
|   </a-card> | 
| </template> | 
|   | 
| <script lang="ts" setup> | 
|   import { ref } from 'vue'; | 
|   import type { | 
|     FileItem, | 
|     RequestOption, | 
|   } from '@arco-design/web-vue/es/upload/interfaces'; | 
|   import { useUserStore } from '@/store'; | 
|   import { userUploadApi } from '@/api/user-center'; | 
|   import type { DescData } from '@arco-design/web-vue/es/descriptions/interface'; | 
|   | 
|   const userStore = useUserStore(); | 
|   const file = { | 
|     uid: '-2', | 
|     name: 'avatar.png', | 
|     url: userStore.avatar, | 
|   }; | 
|   const renderData = [ | 
|     { | 
|       label: 'userSetting.label.name', | 
|       value: userStore.name, | 
|     }, | 
|     { | 
|       label: 'userSetting.label.certification', | 
|       value: userStore.certification, | 
|     }, | 
|     { | 
|       label: 'userSetting.label.accountId', | 
|       value: userStore.accountId, | 
|     }, | 
|     { | 
|       label: 'userSetting.label.phone', | 
|       value: userStore.phone, | 
|     }, | 
|     { | 
|       label: 'userSetting.label.registrationDate', | 
|       value: userStore.registrationDate, | 
|     }, | 
|   ] as DescData[]; | 
|   const fileList = ref<FileItem[]>([file]); | 
|   const uploadChange = (fileItemList: FileItem[], fileItem: FileItem) => { | 
|     fileList.value = [fileItem]; | 
|   }; | 
|   const customRequest = (options: RequestOption) => { | 
|     // docs: https://axios-http.com/docs/cancellation | 
|     const controller = new AbortController(); | 
|   | 
|     (async function requestWrap() { | 
|       const { | 
|         onProgress, | 
|         onError, | 
|         onSuccess, | 
|         fileItem, | 
|         name = 'file', | 
|       } = options; | 
|       onProgress(20); | 
|       const formData = new FormData(); | 
|       formData.append(name as string, fileItem.file as Blob); | 
|       const onUploadProgress = (event: ProgressEvent) => { | 
|         let percent; | 
|         if (event.total > 0) { | 
|           percent = (event.loaded / event.total) * 100; | 
|         } | 
|         onProgress(parseInt(String(percent), 10), event); | 
|       }; | 
|   | 
|       try { | 
|         // https://github.com/axios/axios/issues/1630 | 
|         // https://github.com/nuysoft/Mock/issues/127 | 
|   | 
|         const res = await userUploadApi(formData, { | 
|           controller, | 
|           onUploadProgress, | 
|         }); | 
|         onSuccess(res); | 
|       } catch (error) { | 
|         onError(error); | 
|       } | 
|     })(); | 
|     return { | 
|       abort() { | 
|         controller.abort(); | 
|       }, | 
|     }; | 
|   }; | 
| </script> | 
|   | 
| <style scoped lang="less"> | 
|   .arco-card { | 
|     padding: 14px 0 4px 4px; | 
|     border-radius: 4px; | 
|   } | 
|   :deep(.arco-avatar-trigger-icon-button) { | 
|     width: 32px; | 
|     height: 32px; | 
|     line-height: 32px; | 
|     background-color: #e8f3ff; | 
|     .arco-icon-camera { | 
|       margin-top: 8px; | 
|       color: rgb(var(--arcoblue-6)); | 
|       font-size: 14px; | 
|     } | 
|   } | 
| </style> |