index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <cwg-page-wrapper :isHeaderFixed="true">
  3. <cwg-header class="wallet-header" :title="t('wallet1.title')"
  4. backgrounds="hhh" />
  5. <view class="page">
  6. <view class="wallet-banner">
  7. <view class="balance">
  8. <view class="balance-item">
  9. <view class="r l" @click="setModelValue1">
  10. <image :src="imageSrc(balance)" alt="" srcset="" />
  11. <text>{{ balance }}</text>
  12. <cwg-icon name="icon_dropdown" :size="24" />
  13. </view>
  14. <view class="r">
  15. <text>$ {{ currencyList[0]?.amount }}</text>
  16. <text class="decimal">{{ currencyList[0]?.decimal }}</text>
  17. </view>
  18. </view>
  19. </view>
  20. </view>
  21. <view class="wallet-actions">
  22. <view class="cwg-button two-btn">
  23. <u-button type="primary" block @click="goToVaultody">{{ t('pages.wallet.vaultody') }}</u-button>
  24. <u-button plain block class="prev-btn" @click="goToWithdraw">{{ t('pages.wallet.withdraw') }}</u-button>
  25. </view>
  26. </view>
  27. <view class="wallet-page">
  28. <view class="global-title">{{ t("global.title1") }}</view>
  29. <view class="global-con">
  30. <view class="global-con-l">
  31. <image src="/static/images/currency/USD.png" alt="" srcset="" />
  32. <view class="r">
  33. <view>USD</view>
  34. </view>
  35. </view>
  36. <cwg-icon name="icon_transfer" :size="23" color="#1a1a1a" />
  37. <view class="global-con-r" @click="setModelValue">
  38. <image :src="imageSrc(currency)" alt="" srcset="" />
  39. <view class="r">
  40. <view>{{ currency }}</view>
  41. </view>
  42. <cwg-icon name="icon_dropdown" :size="24" />
  43. </view>
  44. </view>
  45. <view class="cwg-button">
  46. <u-button type="primary" block @click="goToGlobalRemit">{{
  47. t("global.title1")
  48. }}</u-button>
  49. </view>
  50. <view class="trans-header">
  51. <view class="record-title">{{ t("global.title") }} </view>
  52. <view class="all" @click="goRechargeRecord">{{
  53. t("card.Status.t22")
  54. }}</view>
  55. </view>
  56. <view class="transaction-list">
  57. <template v-if="globalOrdersList.length > 0">
  58. <view v-for="item in globalOrdersList" :key="item.id" class="transaction-item"
  59. @click="goToDeductionDetail(item)">
  60. <view class="transaction-left">
  61. <view class="transaction-icon">
  62. <text class="icon-text"><cwg-icon name="icon_transfer" :size="23" color="#1a1a1a" /></text>
  63. </view>
  64. <view class="transaction-info">
  65. <text class="transaction-status">{{ item.merchantOrderNo }}</text>
  66. <text class="transaction-time">{{ item.addTime }}</text>
  67. </view>
  68. </view>
  69. <view class="transaction-right">
  70. <text class="transaction-amount">{{ item.deductionAmount }} {{ item.sendCurrency }}</text>
  71. </view>
  72. </view>
  73. </template>
  74. <cwg-empty-state v-if="globalOrdersList.length == 0" />
  75. </view>
  76. </view>
  77. <cwg-currency-select v-model="modelValue" :show-search="true" :options="globalCurrenciesDropdown"
  78. @select="changeSelect" :placeholder="t('common.country')" />
  79. <cwg-currency-select v-model="modelValue1" :show-search="true" :options="globalCurrenciesDropdown"
  80. @select="changeSelect1" />
  81. </view>
  82. </cwg-page-wrapper>
  83. </template>
  84. <script setup lang="ts">
  85. import { ref, onMounted, watch, computed } from "vue";
  86. import { showToast } from "@/utils/toast";
  87. import { onLoad } from '@dcloudio/uni-app'
  88. import useRouter from "@/hooks/useRouter";
  89. import { useI18n } from "vue-i18n";
  90. import { ucardApi } from "@/api/ucard";
  91. import _ from "lodash";
  92. import useCardStore from "@/stores/use-card-store";
  93. const cardStore = useCardStore();
  94. const { t } = useI18n();
  95. const router = useRouter();
  96. onLoad((options) => {
  97. // id.value = options.id
  98. // type.value = options.type
  99. })
  100. const currency = ref("EUR");
  101. const balance = ref("USD");
  102. const modelValue = ref(false);
  103. const modelValue1 = ref(false);
  104. const currencyList = ref([]);
  105. const allAmount = ref(0);
  106. async function getBalance() {
  107. try {
  108. const res = await ucardApi.walletBalance();
  109. const n = Number.parseFloat(res.data.balance).toFixed(2);
  110. const { amount, decimal } = splitNumber(n);
  111. allAmount.value = n;
  112. currencyList.value.push({
  113. name: "USD",
  114. amount,
  115. decimal,
  116. });
  117. } catch (error) { }
  118. }
  119. async function getGlobalFieldParams() {
  120. try {
  121. const res = await ucardApi.getGlobalFieldParams();
  122. const sorted = res.data
  123. .sort((a, b) => {
  124. return (a.sorting || 0) - (b.sorting || 0);
  125. }).map((item) => {
  126. return { fieldUserType: item.fieldUserType, fieldName: item.fieldName, fieldType: item.fieldType }
  127. });
  128. cardStore.saveGlobalFieldParams(sorted);
  129. } catch (error) { }
  130. }
  131. function imageSrc(currency: string) {
  132. return `/static/images/currency/${currency}.png`;
  133. }
  134. const goToDeductionDetail = (record: RecordItem) => {
  135. console.log(record, 1212);
  136. cardStore.saveOrderDetail(record);
  137. router.push({
  138. path: '/pages/wallet/global-detail',
  139. query: { id: record.id }
  140. });
  141. };
  142. function splitNumber(n) {
  143. if (
  144. n === undefined ||
  145. n === null ||
  146. n === 0 ||
  147. (typeof n !== "number" && typeof n !== "string") ||
  148. (typeof n === "string" && !/^\d+(\.\d+)?$/.test(n))
  149. ) {
  150. return { amount: 0, decimal: "" };
  151. }
  152. const str = n.toString();
  153. if (!str.includes(".")) {
  154. return { amount: str, decimal: "" };
  155. }
  156. const [int, dec] = str.split(".");
  157. return {
  158. amount: `${int}.`,
  159. decimal: dec || "",
  160. };
  161. }
  162. function setModelValue() {
  163. modelValue.value = true;
  164. }
  165. function setModelValue1() {
  166. return;
  167. // modelValue1.value = true
  168. }
  169. function goRechargeRecord() {
  170. router.push(`/pages/wallet/global-list`);
  171. }
  172. function goToGlobalRemit() {
  173. router.push(
  174. `/pages/wallet/global-order?currency=${currency.value}`
  175. );
  176. }
  177. function goToVaultody() {
  178. router.push(`/pages/wallet/vaultody`);
  179. }
  180. function goToWithdraw() {
  181. router.push(`/pages/wallet/withdraw?allAmount=${allAmount.value}`);
  182. }
  183. function changeSelect(e) {
  184. currency.value = e.value;
  185. }
  186. function changeSelect1(e) {
  187. balance.value = e.value;
  188. }
  189. const globalCurrenciesDropdown = ref([]);
  190. const getGlobalCurrenciesDropdown = async () => {
  191. const res = await ucardApi.globalCurrenciesDropdown({ code: "", status: 'online' });
  192. if (res.code === 200 || res.code === 0) {
  193. globalCurrenciesDropdown.value = res.data.map((i) => {
  194. return { currency: i.payoutCurrency, text: i.country, value: i.payoutCurrency };
  195. }) || [];
  196. const data = _.cloneDeep(res.data);
  197. cardStore.saveCurrencyList(data)
  198. }
  199. };
  200. const globalOrdersList = ref<TransferInfo[]>([]);
  201. async function getGlobalOrdersList() {
  202. try {
  203. const res = await ucardApi.globalOrdersList({ page: { current: 1, row: 5 } });
  204. if (res.code === 200) {
  205. globalOrdersList.value = res.data;
  206. } else {
  207. globalOrdersList.value = [];
  208. }
  209. } catch (error) {
  210. showToast(t("common.error"));
  211. }
  212. }
  213. function goToTransferDetail(id: string) {
  214. router.push(`/transfer/detail?id=${id}`);
  215. }
  216. onMounted(() => {
  217. getGlobalCurrenciesDropdown()
  218. getGlobalOrdersList()
  219. getBalance();
  220. getGlobalFieldParams()
  221. });
  222. </script>
  223. <style scoped lang="scss">
  224. @import "@/uni.scss";
  225. .page-wrapper {
  226. padding-left: 0 !important;
  227. padding-right: 0 !important;
  228. border: 0 !important;
  229. }
  230. .page {
  231. box-sizing: border-box;
  232. background: var(--main-bg);
  233. }
  234. .wallet-page {
  235. padding: 0 px2rpx(24);
  236. box-sizing: border-box;
  237. }
  238. .wallet-header {
  239. // position: relative;
  240. // background: linear-gradient(90deg, #ea002a 0%, #eb4e6b 100%);
  241. // z-index: 1113;
  242. }
  243. .banner-title {
  244. color: #fff;
  245. font-family: Roboto;
  246. font-size: px2rpx(22);
  247. font-style: normal;
  248. font-weight: 600;
  249. line-height: px2rpx(28);
  250. padding: px2rpx(12) 0 px2rpx(31) 0;
  251. }
  252. .wallet-banner {
  253. background: linear-gradient(90deg, #ea002a 0%, #eb4e6b 100%);
  254. margin-bottom: px2rpx(20);
  255. padding: 0 px2rpx(31) px2rpx(62) px2rpx(31);
  256. color: #fff;
  257. .balance {
  258. display: flex;
  259. width: 100%;
  260. justify-content: space-between;
  261. align-items: center;
  262. }
  263. .balance-item {
  264. width: 100%;
  265. display: flex;
  266. padding: px2rpx(16) px2rpx(24);
  267. justify-content: center;
  268. align-items: center;
  269. gap: px2rpx(31);
  270. border-radius: px2rpx(8);
  271. border: 1px solid var(--Netural-color-content-color-stoke, #f4f4f4);
  272. background: #fff;
  273. color: var(--white);
  274. flex-direction: column;
  275. .r {
  276. display: flex;
  277. justify-content: center;
  278. align-items: flex-end;
  279. }
  280. .l {
  281. align-items: center;
  282. }
  283. text {
  284. color: #000;
  285. font-family: Roboto;
  286. font-size: px2rpx(44);
  287. font-style: normal;
  288. font-weight: 600;
  289. text-align: left;
  290. }
  291. .decimal {
  292. color: #1a1a1a;
  293. font-family: Roboto;
  294. font-size: px2rpx(14);
  295. font-style: normal;
  296. font-weight: 600;
  297. letter-spacing: px2rpx(0.07);
  298. }
  299. .l {
  300. text {
  301. color: #474747;
  302. font-size: px2rpx(31);
  303. line-height: px2rpx(44);
  304. }
  305. }
  306. image {
  307. width: px2rpx(28);
  308. height: px2rpx(28);
  309. margin-right: px2rpx(12);
  310. display: inline-block;
  311. }
  312. }
  313. }
  314. .global-title {
  315. margin: px2rpx(44) 0 px2rpx(36) 0;
  316. color: #000;
  317. font-family: Roboto;
  318. font-size: px2rpx(22);
  319. font-style: normal;
  320. font-weight: 600;
  321. line-height: px2rpx(28);
  322. }
  323. .global-con {
  324. display: flex;
  325. width: 100%;
  326. margin: px2rpx(44) 0;
  327. align-items: center;
  328. gap: px2rpx(12);
  329. color: #1a1a1a;
  330. .global-con-l,
  331. .global-con-r {
  332. display: flex;
  333. flex: 1;
  334. padding: px2rpx(12) px2rpx(8);
  335. align-items: center;
  336. gap: px2rpx(6);
  337. border-radius: px2rpx(12);
  338. box-shadow: 0px px2rpx(10) px2rpx(30) 0px rgba(5, 0, 1, 0.1);
  339. color: var(--white);
  340. view {
  341. color: #000;
  342. font-family: Roboto;
  343. font-size: px2rpx(24);
  344. font-style: normal;
  345. font-weight: 600;
  346. line-height: px2rpx(44);
  347. }
  348. image {
  349. width: px2rpx(36);
  350. height: px2rpx(36);
  351. border: 1px solid #f4f4f4;
  352. border-radius: 50%;
  353. }
  354. }
  355. }
  356. .trans-header {
  357. display: flex;
  358. align-items: center;
  359. justify-content: space-between;
  360. }
  361. .record-title {
  362. margin: px2rpx(44) 0 px2rpx(44) 0;
  363. color: #000;
  364. font-family: Roboto;
  365. font-size: px2rpx(22);
  366. font-style: normal;
  367. font-weight: 600;
  368. line-height: px2rpx(28);
  369. }
  370. .transaction-list {
  371. display: flex;
  372. flex-direction: column;
  373. .transaction-item {
  374. display: flex;
  375. justify-content: space-between;
  376. align-items: center;
  377. padding: px2rpx(16) 0;
  378. border-bottom: 1px solid #f3f4f6;
  379. }
  380. .transaction-item:last-child {
  381. border-bottom: none;
  382. }
  383. .transaction-left {
  384. display: flex;
  385. align-items: center;
  386. gap: px2rpx(12);
  387. }
  388. .transaction-icon {
  389. width: px2rpx(40);
  390. height: px2rpx(40);
  391. background-color: #f9fafb;
  392. border-radius: 50%;
  393. display: flex;
  394. align-items: center;
  395. justify-content: center;
  396. }
  397. .icon-text {
  398. font-size: px2rpx(20);
  399. color: #6b7280;
  400. }
  401. .transaction-info {
  402. display: flex;
  403. flex-direction: column;
  404. gap: px2rpx(4);
  405. }
  406. .transaction-status {
  407. font-size: px2rpx(14);
  408. color: #111827;
  409. }
  410. .transaction-time {
  411. font-size: px2rpx(12);
  412. color: #9ca3af;
  413. }
  414. .transaction-right {
  415. display: flex;
  416. flex-direction: column;
  417. align-items: flex-end;
  418. }
  419. .transaction-amount {
  420. font-size: px2rpx(16);
  421. font-weight: 600;
  422. color: #111827;
  423. }
  424. .transaction-amount.negative {
  425. color: #ef4444;
  426. }
  427. }
  428. .wallet-actions {
  429. padding: px2rpx(16) px2rpx(24);
  430. }
  431. .wallet-actions .two-btn {
  432. display: flex;
  433. gap: px2rpx(16);
  434. }
  435. .wallet-actions .prev-btn {
  436. border: 1px solid var(--main-yellow) !important;
  437. color: #fff !important;
  438. background: transparent;
  439. }
  440. </style>