info.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <template>
  2. <cwg-page-wrapper>
  3. <view class="user-profile-detail">
  4. <!-- Content -->
  5. <view class="content">
  6. <!-- Basic Information -->
  7. <view class="info-card">
  8. <view class="card-header">
  9. <cwg-icon name="icon_personal certification" :size="20" color="#2563eb" />
  10. <text class="card-title">{{ t('card.Info.s1') }}</text>
  11. </view>
  12. <view class="card-body">
  13. <info-row icon="xm" :label="t('card.Form.f5') + ' ' + t('card.Form.f4')"
  14. :value="userInfo.firstName + ' ' + userInfo.lastName" />
  15. <info-row icon="email-outline" :label="t('card.Form.f3')" :value="userInfo.email" />
  16. <info-row icon="phone" :label="t('card.Form.f2')"
  17. :value="userInfo.areaCode + ' ' + userInfo.mobile" />
  18. <info-row icon="cwg-calendar" :label="t('card.Form.f6')" :value="userInfo.birthday" />
  19. <info-row :icon="userInfo.gender == 'M' ? 'nan' : 'nv'" :label="t('card.Form.f8')"
  20. :value="userInfo.gender == 'M' ? t('card.Form.v1') : t('card.Form.v2')" :isLast="true" />
  21. </view>
  22. </view>
  23. <!-- Location Information -->
  24. <view class="info-card">
  25. <view class="card-header">
  26. <cwg-icon name="dw" :size="20" color="#16a34a" />
  27. <text class="card-title">{{ t('ImproveImmediately.Title.AddressInformation') }}</text>
  28. </view>
  29. <view class="card-body">
  30. <info-row icon="gj" :label="t('card.Form.f7')" :value="userInfo.countryCnName" />
  31. <info-row icon="dw" :label="t('card.Form.f9')" :value="userInfo.townEnName" />
  32. <info-row icon="xxdz" :label="t('card.Form.f10')" :value="userInfo.address" />
  33. <info-row icon="paperclip" :label="t('card.Form.f11')" :value="userInfo.postCode"
  34. :isLast="true" />
  35. </view>
  36. </view>
  37. <!-- Career Information -->
  38. <view class="info-card">
  39. <view class="card-header">
  40. <cwg-icon name="globe" :size="20" color="#9333ea" />
  41. <text class="card-title">{{ t('card.Info.s0') }}</text>
  42. </view>
  43. <view class="card-body">
  44. <info-row icon="globe" :label="t('card.Form.f12')" :value="userInfo.occupationDesc" />
  45. <info-row icon="location" :label="t('card.Form.f13')" :value="userInfo.annualSalary" />
  46. <info-row icon="globe" :label="t('card.Form.f14')" :value="userInfo.accountPurpose" />
  47. <info-row icon="gzcalendar" :label="t('card.Form.f15')" :value="userInfo.expectedMonthlyVolume"
  48. :isLast="true" />
  49. </view>
  50. </view>
  51. <!-- Identity Verification -->
  52. <view class="info-card">
  53. <view class="card-header">
  54. <cwg-icon name="checkmark" :size="20" color="#ea580c" />
  55. <text class="card-title">{{ t('card.Info.s2') }}</text>
  56. </view>
  57. <view class="card-body">
  58. <verification-row icon="checkmarkempty" :label="t('card.Form.f16')"
  59. :status="getIdentityStatus()" :date="getIdentityDate()" :idType="idTypeOptions[0]?.text"
  60. :idFrontUrl="userInfo.idFrontUrl" :idBackUrl="userInfo.idBackUrl"
  61. :idHoldUrl="userInfo.idHoldUrl" :isLast="true" />
  62. </view>
  63. </view>
  64. <!-- Action Buttons -->
  65. <!-- <view class="action-buttons">
  66. <button class="btn-primary" @click="handleEditProfile">{{ t('card.Btn.Edit') }}</button>
  67. <button class="btn-secondary" @click="handleChangePassword">{{ t('card.Btn.ChangePwd') }}</button>
  68. </view> -->
  69. </view>
  70. </view>
  71. </cwg-page-wrapper>
  72. </template>
  73. <script setup lang="ts">
  74. import { ref, onMounted, watch, computed, reactive } from "vue";
  75. import InfoRow from './components/InfoRow.vue';
  76. import VerificationRow from './components/VerificationRow.vue';
  77. import { useI18n } from "vue-i18n";
  78. import useUserStore from "@/stores/use-user-store";
  79. import useRouter from "@/hooks/useRouter";
  80. import useIdTypeOptions from "@/composables/useIdTypeOptions";
  81. const { allIdTypeOptions } = useIdTypeOptions()
  82. const userStore = useUserStore();
  83. const userInfo = computed(() => userStore.userInfo);
  84. const { t } = useI18n();
  85. const router = useRouter();
  86. const idTypeOptions = computed(() => {
  87. return allIdTypeOptions.value?.filter(item => item.value === userInfo.value?.idType);
  88. });
  89. // 获取身份认证状态
  90. function getIdentityStatus() {
  91. // 认证成功就是已认证;否则视为审核中(pending)
  92. if (userInfo.value?.approveStatus == 2 || userInfo.value?.kycStatus == 2) {
  93. return 'verified';
  94. }
  95. return 'pending';
  96. }
  97. // 获取身份认证日期
  98. function getIdentityDate() {
  99. // 如果有证件有效期,则使用证件签发日期
  100. if (userInfo.value?.issueDate) {
  101. return new Date(userInfo.value.issueDate).toLocaleDateString();
  102. }
  103. return '';
  104. }
  105. const handleEditProfile = () => {
  106. router.push('/pages/mine/improve');
  107. };
  108. const handleChangePassword = () => {
  109. uni.showToast({
  110. title: t('card.Msg.ComingSoon'),
  111. icon: 'none'
  112. });
  113. };
  114. </script>
  115. <style scoped lang="scss">
  116. @import "@/uni.scss";
  117. .page-wrapper {
  118. padding: 0;
  119. }
  120. .user-profile-detail {
  121. min-height: 100vh;
  122. background-color: #f9fafb;
  123. }
  124. .header {
  125. background: linear-gradient(to right, #2563eb, #60a5fa);
  126. padding: px2rpx(16);
  127. }
  128. .header-content {
  129. display: flex;
  130. align-items: center;
  131. gap: px2rpx(8);
  132. }
  133. .avatar {
  134. width: px2rpx(40);
  135. height: px2rpx(40);
  136. border-radius: 50%;
  137. background-color: white;
  138. border: px2rpx(2) solid white;
  139. box-shadow: 0 px2rpx(2) px2rpx(6) rgba(0, 0, 0, 0.1);
  140. }
  141. .header-info {
  142. flex: 1;
  143. display: flex;
  144. flex-direction: column;
  145. }
  146. .user-name {
  147. color: white;
  148. font-size: px2rpx(18);
  149. margin-bottom: px2rpx(2);
  150. }
  151. .user-email {
  152. color: #bfdbfe;
  153. font-size: px2rpx(12);
  154. }
  155. .content {
  156. padding: px2rpx(1) px2rpx(16) px2rpx(24);
  157. }
  158. .info-card {
  159. background-color: white;
  160. border-radius: px2rpx(8);
  161. box-shadow: 0 px2rpx(1) px2rpx(4) rgba(0, 0, 0, 0.1);
  162. margin-top: px2rpx(16);
  163. overflow: hidden;
  164. }
  165. .card-header {
  166. display: flex;
  167. align-items: center;
  168. gap: px2rpx(4);
  169. padding: px2rpx(12) px2rpx(16);
  170. border-bottom: 1px solid #f3f4f6;
  171. }
  172. .card-title {
  173. color: #1f2937;
  174. font-size: px2rpx(14);
  175. }
  176. .card-body {
  177. padding: px2rpx(16);
  178. }
  179. .action-buttons {
  180. margin-top: px2rpx(24);
  181. display: flex;
  182. flex-direction: column;
  183. gap: px2rpx(12);
  184. }
  185. .btn-primary {
  186. width: 100%;
  187. background-color: #2563eb;
  188. color: white;
  189. padding: px2rpx(12);
  190. border-radius: px2rpx(8);
  191. border: none;
  192. font-size: px2rpx(14);
  193. }
  194. .btn-primary:active {
  195. background-color: #1d4ed8;
  196. }
  197. .btn-secondary {
  198. width: 100%;
  199. background-color: white;
  200. color: #374151;
  201. padding: px2rpx(12);
  202. border-radius: px2rpx(8);
  203. border: 1px solid #d1d5db;
  204. font-size: px2rpx(14);
  205. }
  206. .btn-secondary:active {
  207. background-color: #f9fafb;
  208. }
  209. </style>