FirstApply.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <view class="page">
  3. <view class="status-box">
  4. <view v-t="'card.Info.s11'"></view>
  5. <image src="/static/images/card/img2.png" mode="aspectFit" />
  6. <view class="status-box-btn">
  7. <view v-t="'card.Btn.b7'" class="btn-apply" :class="{ disabled: !isAuthVerified || isLoading }"
  8. @click="handleApply"></view>
  9. </view>
  10. <view v-if="!isAuthVerified && !isLoading" class="auth-tip">
  11. {{ t('pages.card.authTip') || '请先完成身份认证' }}
  12. </view>
  13. <view v-t="'card.Info.s12'" class="a-title"></view>
  14. <view class="step-box">
  15. <view class="step-item">
  16. <view class="ids">1</view>
  17. <view v-t="'card.Info.s13'" class="k"></view>
  18. <view v-t="'card.Info.s14'" class="v"></view>
  19. </view>
  20. <view class="step-item">
  21. <view class="ids">2</view>
  22. <view v-t="'card.Info.s15'" class="k"></view>
  23. <view v-t="'card.Info.s16'" class="v"></view>
  24. </view>
  25. <view class="step-item">
  26. <view class="ids">3</view>
  27. <view v-t="'card.Info.s17'" class="k"></view>
  28. <view v-t="'card.Info.s18'" class="v"></view>
  29. </view>
  30. <view class="step-item">
  31. <view class="ids">4</view>
  32. <view v-t="'card.Info.s19'" class="k"></view>
  33. <view v-t="'card.Info.s20'" class="v"></view>
  34. </view>
  35. </view>
  36. <view v-t="'card.Info.s21'" class="f"></view>
  37. </view>
  38. </view>
  39. </template>
  40. <script setup lang="ts">
  41. import { ref, onMounted, computed } from "vue";
  42. import { useI18n } from "vue-i18n";
  43. import useRouter from "@/hooks/useRouter";
  44. import { userApi } from "@/api/user";
  45. import useUserStore from "@/stores/use-user-store";
  46. import { userToken } from "@/composables/config";
  47. const router = useRouter();
  48. const { t } = useI18n();
  49. const userStore = useUserStore();
  50. const userInfo = computed(() => userStore.userInfo);
  51. // 认证状态
  52. const isAuthVerified = ref(false);
  53. const isLoading = ref(true);
  54. // 检查认证状态
  55. function checkAuthStatus(userData: any) {
  56. // approveStatus == 2 或 kycStatus == 2 表示认证通过
  57. if (userData?.approveStatus == 2) {
  58. isAuthVerified.value = true;
  59. } else {
  60. isAuthVerified.value = false;
  61. }
  62. }
  63. // 获取用户详情
  64. async function getUserSingle() {
  65. if (!userToken.value) {
  66. isLoading.value = false;
  67. isAuthVerified.value = false;
  68. return;
  69. }
  70. try {
  71. isLoading.value = true;
  72. const res = await userApi.getUserSingle();
  73. if (res.code === 200 && res.data) {
  74. // 更新用户信息到 store
  75. userStore.saveUserInfo(res.data);
  76. // 检查认证状态
  77. checkAuthStatus(res.data);
  78. } else {
  79. isAuthVerified.value = false;
  80. }
  81. } catch (error: any) {
  82. console.error('获取用户详情失败:', error);
  83. isAuthVerified.value = false;
  84. } finally {
  85. isLoading.value = false;
  86. }
  87. }
  88. function handleApply() {
  89. if (!isAuthVerified.value || isLoading.value) {
  90. uni.showToast({
  91. title: t('pages.card.authTip') || '请先完成身份认证',
  92. icon: 'none'
  93. });
  94. return;
  95. }
  96. router.push("/pages/card/select");
  97. }
  98. onMounted(async () => {
  99. // 如果 store 中已有用户信息,先检查认证状态
  100. if (userInfo.value) {
  101. checkAuthStatus(userInfo.value);
  102. isLoading.value = false;
  103. }
  104. // 调用接口获取最新用户信息
  105. await getUserSingle();
  106. });
  107. </script>
  108. <style scoped lang="scss">
  109. @import "@/uni.scss";
  110. .page {
  111. // margin: 0 px2rpx(24) px2rpx(100) px2rpx(24);
  112. }
  113. .imgs {
  114. margin-left: px2rpx(74);
  115. margin-bottom: px2rpx(40);
  116. }
  117. .apply-card-steps {
  118. width: 100%;
  119. margin-bottom: px2rpx(52);
  120. display: flex;
  121. flex-direction: column;
  122. align-items: center;
  123. }
  124. .steps-top {
  125. display: flex;
  126. align-items: center;
  127. justify-content: center;
  128. width: 100%;
  129. position: relative;
  130. max-width: px2rpx(600);
  131. margin: 0 auto;
  132. }
  133. .step {
  134. display: flex;
  135. flex-direction: column;
  136. align-items: center;
  137. position: relative;
  138. z-index: 2;
  139. flex: 0 0 auto;
  140. }
  141. .step-circle {
  142. width: px2rpx(28);
  143. height: px2rpx(28);
  144. color: var(--main-yellow);
  145. border-radius: 50%;
  146. font-size: px2rpx(14);
  147. font-weight: bold;
  148. display: flex;
  149. align-items: center;
  150. justify-content: center;
  151. border: 2px solid var(--main-yellow);
  152. margin-bottom: px2rpx(8);
  153. transition: all 0.3s ease;
  154. }
  155. .step-circle:hover {
  156. transform: scale(1.1);
  157. box-shadow: 0 0 10px rgba(73, 247, 166, 0.3);
  158. }
  159. .step-dash {
  160. flex: 1;
  161. height: px2rpx(2);
  162. background: repeating-linear-gradient(to right,
  163. var(--main-yellow),
  164. var(--main-yellow) px2rpx(6),
  165. transparent px2rpx(6),
  166. transparent px2rpx(12));
  167. min-width: px2rpx(18);
  168. position: relative;
  169. top: -px2rpx(16);
  170. }
  171. .step-label {
  172. color: var(--white);
  173. font-size: px2rpx(14);
  174. font-weight: 500;
  175. text-align: center;
  176. line-height: 2;
  177. }
  178. .status-box {
  179. width: 100%;
  180. display: flex;
  181. justify-content: flex-start;
  182. flex-wrap: wrap;
  183. margin-bottom: px2rpx(20);
  184. gap: px2rpx(16);
  185. .status {
  186. width: 100%;
  187. color: #333333;
  188. font-size: px2rpx(26);
  189. font-family: PingFang SC;
  190. font-weight: 500;
  191. word-wrap: break-word;
  192. text-align: start;
  193. }
  194. view {
  195. width: 100%;
  196. text-align: start;
  197. color: #6f6f6f;
  198. font-size: px2rpx(18);
  199. font-family: PingFang SC;
  200. font-weight: 400;
  201. word-wrap: break-word;
  202. line-height: px2rpx(32);
  203. padding: px2rpx(20) px2rpx(30) px2rpx(20) 0;
  204. margin: 0;
  205. }
  206. .a-title {
  207. color: #333333;
  208. font-size: px2rpx(18);
  209. font-family: PingFang SC;
  210. font-weight: 500;
  211. word-wrap: break-word;
  212. margin-top: px2rpx(44);
  213. }
  214. .step-box {
  215. width: 100%;
  216. display: flex;
  217. flex-wrap: wrap;
  218. justify-content: space-between;
  219. margin-top: px2rpx(20);
  220. padding: 0 0;
  221. .step-item {
  222. width: 100%;
  223. padding: 0 0 px2rpx(10) px2rpx(60);
  224. text-align: center;
  225. position: relative;
  226. &::after {
  227. content: "";
  228. position: absolute;
  229. top: 0;
  230. left: px2rpx(15);
  231. width: 0;
  232. height: 100%;
  233. border-left: 1px dashed #ccc;
  234. z-index: 1;
  235. }
  236. &:last-child {
  237. &::after {
  238. display: none;
  239. }
  240. }
  241. .ids {
  242. position: absolute;
  243. left: 0;
  244. top: 0;
  245. width: px2rpx(30);
  246. height: px2rpx(30);
  247. padding: 0;
  248. position: absolute;
  249. color: #000;
  250. line-height: px2rpx(30);
  251. background-color: #fff;
  252. text-align: center;
  253. border-radius: px2rpx(9999);
  254. border: 1px #ccc dashed;
  255. z-index: 12;
  256. }
  257. .k {
  258. font-size: px2rpx(14);
  259. color: #333333;
  260. font-weight: bold;
  261. padding: 0;
  262. }
  263. .v {
  264. font-size: px2rpx(14);
  265. color: #6f6f6f;
  266. padding: 0;
  267. }
  268. }
  269. }
  270. .f {
  271. margin: px2rpx(20) 0 0 px2rpx(60);
  272. color: #333333;
  273. font-size: px2rpx(14);
  274. font-family: PingFang SC;
  275. font-weight: 500;
  276. word-wrap: break-word;
  277. }
  278. }
  279. .status-box-btn {
  280. margin-top: px2rpx(20);
  281. width: 100%;
  282. display: flex;
  283. justify-content: flex-start;
  284. .btn-apply {
  285. width: px2rpx(193);
  286. height: px2rpx(40);
  287. background: #eb3f57;
  288. border-radius: px2rpx(4);
  289. text-align: center;
  290. color: white;
  291. font-size: px2rpx(16);
  292. font-family: Roboto;
  293. font-weight: 600;
  294. line-height: px2rpx(40);
  295. cursor: pointer;
  296. user-select: none;
  297. padding: 0;
  298. transition: all 0.3s ease;
  299. &.disabled {
  300. background: #ccc;
  301. cursor: not-allowed;
  302. opacity: 0.6;
  303. }
  304. }
  305. }
  306. .status-box-btn1 {
  307. justify-content: center;
  308. }
  309. .auth-tip {
  310. margin-top: px2rpx(12);
  311. width: 100%;
  312. color: #ff6b6b;
  313. font-size: px2rpx(14);
  314. text-align: left;
  315. padding: 0 px2rpx(30) 0 0;
  316. }
  317. </style>