recording-history.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <cwg-header :title="t('Home.page_customer.item7')" />
  4. <view class="info-card">
  5. <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
  6. @reset="handleReset" />
  7. <cwg-tabel ref="tableRef" :columns="currentColumns" :immediate="false" :queryParams="search" :api="listApi"
  8. :show-operation="false">
  9. <!-- 状态列自定义渲染 -->
  10. <template #status="{ row }">
  11. <view v-if="getStatusText(row)" class="status-tag" :class="getStatusClass(row)">
  12. {{ getStatusText(row) }}
  13. </view>
  14. <view v-else></view>
  15. </template>
  16. <!-- 账户类型列自定义渲染 -->
  17. <template #accountType="{ row }">
  18. {{ getAccountTypeText(row.type || row.loginType) }}
  19. </template>
  20. <!-- 金额列格式化 -->
  21. <template #amount="{ row }">
  22. <view>-{{ formatNumber(row.withdrawAmount || row.amount) }}</view>
  23. </template>
  24. <!-- 备注列格式化 -->
  25. <template #note="{ row }">
  26. <view>{{ formatNote(row.approveDesc) }}</view>
  27. </template>
  28. </cwg-tabel>
  29. </view>
  30. </cwg-page-wrapper>
  31. </template>
  32. <script setup lang="ts">
  33. import { computed, ref, nextTick } from 'vue';
  34. import { useI18n } from 'vue-i18n';
  35. const { t, locale } = useI18n();
  36. import { customApi } from '@/service/custom';
  37. import useUserStore from "@/stores/use-user-store";
  38. const userStore = useUserStore();
  39. const userInfo = computed(() => userStore.userInfo);
  40. const search = ref({
  41. type: 1
  42. })
  43. const getInfoAgentTransfer = computed(() => userInfo.value.customInfo?.agentTransfer)
  44. const typeMap = computed(() => ([
  45. { value: 1, text: t('Custom.Recording.NewAccount') },
  46. { value: 7, text: t('Custom.NewAccount.BtnDome') },
  47. // { value: 2, text: t('Custom.Recording.LeverageApply') },
  48. { value: 3, text: t('Custom.Recording.InternalTransfer') },
  49. // { value: 4, text: t('Custom.Recording.ActivitiesApply') },
  50. ...(getInfoAgentTransfer.value == 1 ? [{ value: 5, text: t('Home.page_ib.item9') }] : [])
  51. ]));
  52. const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
  53. // 账户类型映射
  54. const accountTypeMap = {
  55. 1: 'AccountType.ClassicAccount',
  56. 2: 'AccountType.SeniorAccount',
  57. 5: 'AccountType.SpeedAccount',
  58. 6: 'AccountType.SpeedAccount',
  59. 7: 'AccountType.StandardAccount',
  60. 8: 'AccountType.CentAccount'
  61. }
  62. // 拒绝原因映射(示例)
  63. const reasons = ref({})
  64. // 根据类型获取列配置
  65. const getColumnsByType = (type: number) => {
  66. switch (type) {
  67. case 1: // 开户记录
  68. case 7: // 开户记录
  69. return [
  70. {
  71. prop: 'platform',
  72. label: t('Custom.Recording.Platform'),
  73. align: 'left'
  74. },
  75. {
  76. prop: 'type',
  77. label: t('Custom.PaymentHistory.payType'),
  78. align: 'left',
  79. slot: 'accountType'
  80. },
  81. {
  82. prop: 'withdrawCurrency',
  83. label: t('Custom.Recording.CurrencyType'),
  84. align: 'left',
  85. formatter: ({ row }) => row.currency || '--',
  86. },
  87. {
  88. prop: 'leverage',
  89. label: t('Custom.Recording.Lever'),
  90. formatter: ({ row }) => `1: ${row.leverage}` || '--',
  91. align: 'left'
  92. },
  93. {
  94. prop: 'addTime',
  95. label: t('Custom.PaymentHistory.ApplicationDate'),
  96. type: 'date',
  97. dateFormat: 'YYYY-MM-DD HH:mm',
  98. align: 'left'
  99. },
  100. {
  101. prop: 'status',
  102. label: t('Custom.Recording.Status'),
  103. slot: 'status',
  104. align: 'left'
  105. },
  106. {
  107. prop: 'note',
  108. label: t('Custom.Recording.Note'),
  109. type: 'note',
  110. align: 'left'
  111. }
  112. ]
  113. case 2: // 杠杆修改记录
  114. return [
  115. {
  116. prop: 'login',
  117. label: t('Custom.Recording.TradingAccount'),
  118. align: 'left',
  119. formatter: ({ row }) => row.login || '--'
  120. },
  121. {
  122. prop: 'oldLeverage',
  123. label: t('Custom.Recording.OldLever'),
  124. align: 'left',
  125. formatter: ({ row }) => row.oldLeverage ? `1:${row.oldLeverage}` : '--'
  126. },
  127. {
  128. prop: 'newLeverage',
  129. label: t('Custom.Recording.NewLever'),
  130. align: 'left',
  131. formatter: ({ row }) => row.newLeverage ? `1:${row.newLeverage}` : '--'
  132. },
  133. {
  134. prop: 'addTime',
  135. label: t('Custom.PaymentHistory.ApplicationDate'),
  136. type: 'date',
  137. dateFormat: 'YYYY-MM-DD HH:mm',
  138. align: 'left'
  139. },
  140. {
  141. prop: 'status',
  142. label: t('Custom.PaymentHistory.Status'),
  143. slot: 'status',
  144. align: 'left'
  145. },
  146. {
  147. prop: 'note',
  148. label: t('Custom.Recording.Note'),
  149. type: 'note',
  150. align: 'left'
  151. }
  152. ]
  153. case 3: // 转账记录
  154. case 5: // 内部转账记录
  155. return [
  156. {
  157. prop: 'withdrawLogin',
  158. label: t('Custom.Recording.TransferAccounts'),
  159. align: 'left',
  160. formatter: ({ row }) => row.withdrawLogin || '--'
  161. },
  162. {
  163. prop: 'depositLogin',
  164. label: t('Custom.Recording.IntoAccount'),
  165. align: 'left',
  166. formatter: ({ row }) => row.depositLogin || '--',
  167. },
  168. {
  169. prop: 'withdrawCurrency',
  170. label: t('Custom.Recording.CurrencyType'),
  171. align: 'left',
  172. formatter: ({ row }) => row.withdrawCurrency || '--',
  173. },
  174. {
  175. prop: 'withdrawAmount',
  176. label: t('Custom.Recording.Amount'),
  177. align: 'left',
  178. slot: 'amount'
  179. },
  180. {
  181. prop: 'addTime',
  182. label: t('Custom.PaymentHistory.ApplicationDate'),
  183. type: 'date',
  184. dateFormat: 'YYYY-MM-DD HH:mm',
  185. align: 'left'
  186. },
  187. {
  188. prop: 'status',
  189. label: t('Custom.PaymentHistory.Status'),
  190. slot: 'status',
  191. align: 'left'
  192. },
  193. {
  194. prop: 'note',
  195. label: t('Custom.Recording.Note'),
  196. type: 'note',
  197. align: 'left'
  198. }
  199. ]
  200. case 4: // 活动申请记录
  201. return [
  202. {
  203. prop: 'login',
  204. label: t('Custom.Recording.TradingAccount'),
  205. align: 'left',
  206. formatter: ({ row }) => row.login || '--'
  207. },
  208. {
  209. prop: 'loginType',
  210. label: t('Custom.Recording.AccountType'),
  211. align: 'left',
  212. slot: 'accountType'
  213. },
  214. {
  215. prop: 'title',
  216. label: t('Custom.Recording.ActivityName'),
  217. align: 'left',
  218. formatter: ({ row }) => row.title || '--'
  219. },
  220. {
  221. prop: 'addTime',
  222. label: t('Custom.PaymentHistory.ApplicationDate'),
  223. type: 'date',
  224. dateFormat: 'YYYY-MM-DD HH:mm',
  225. align: 'left'
  226. },
  227. {
  228. prop: 'status',
  229. label: t('Custom.PaymentHistory.Status'),
  230. slot: 'status',
  231. align: 'left'
  232. },
  233. {
  234. prop: 'note',
  235. label: t('Custom.Recording.Note'),
  236. type: 'note',
  237. align: 'left'
  238. }
  239. ]
  240. }
  241. }
  242. // 动态传入筛选字段配置
  243. const filterFields = computed(() => [
  244. { key: 'type', type: 'select', label: t('Custom.PaymentHistory.payType'), placeholder: t('placeholder.choose'), options: typeMap.value, defaultValue: 1 },
  245. { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
  246. ])
  247. const searchParams = ref({})
  248. const tableRef = ref(null)
  249. const handleSearch = (params) => {
  250. search.value = params
  251. nextTick(() => {
  252. tableRef.value.refreshTable()
  253. })
  254. }
  255. const handleReset = (params) => {
  256. search.value = params
  257. nextTick(() => {
  258. tableRef.value.refreshTable()
  259. })
  260. }
  261. // 当前列配置
  262. const currentColumns = computed(() => getColumnsByType(search.value.type))
  263. // 获取状态文本
  264. const getStatusText = (row: any) => {
  265. const status = row.status
  266. // 根据不同记录类型处理状态
  267. if (search.value.type === 1) {
  268. if (status === 1) return t('State.ToBeProcessed')
  269. if (status === 2 && row.accountStatus === 2) return t('State.Completed')
  270. if (status === 2 && (row.accountStatus === 1 || !row.accountStatus)) return t('State.InTheProcessing')
  271. if (status === 3) return t('State.Refused')
  272. } else if (search.value.type === 2) {
  273. if (status === 1) return t('State.ToBeProcessed')
  274. if (status === 2 && row.leverageStatus === 2) return t('State.Completed')
  275. if (status === 2 && row.leverageStatus === 1) return t('State.InTheProcessing')
  276. if (status === 3) return t('State.Refused')
  277. } else if (search.value.type === 3 || search.value.type === 5) {
  278. if (status === 1) return t('State.ToBeProcessed')
  279. if (status === 2 && row.withdrawStatus === 2 && row.depositStatus === 2) return t('State.Completed')
  280. if (status === 2 && (row.withdrawStatus === 1 || row.depositStatus === 1)) return t('State.InTheProcessing')
  281. if (status === 3 || row.withdrawStatus === 3 || row.depositStatus === 3) return t('State.Refused')
  282. } else {
  283. // 活动申请等
  284. if (status === 1) return t('State.ToBeProcessed')
  285. if (status === 2) return t('State.Completed')
  286. if (status === 3) return t('State.Refused')
  287. }
  288. return ''
  289. }
  290. // 获取状态样式类
  291. const getStatusClass = (row: any) => {
  292. const text = getStatusText(row)
  293. if (text === t('State.Refused')) return 'status-failed'
  294. if (text === t('State.ToBeProcessed')) return 'status-pending'
  295. if (text === t('State.Completed')) return 'status-success'
  296. if (text === t('State.InTheProcessing')) return 'status-processing'
  297. return ''
  298. }
  299. // 获取账户类型文本
  300. const getAccountTypeText = (type: number) => {
  301. const key = accountTypeMap[type as keyof typeof accountTypeMap]
  302. return key ? t(key) : '--'
  303. }
  304. // 格式化数字
  305. const formatNumber = (value: string | number) => {
  306. if (!value) return '--'
  307. const num = Number(value)
  308. return isNaN(num) ? '--' : num.toFixed(2)
  309. }
  310. // 格式化备注
  311. const formatNote = (approveDesc: string) => {
  312. if (!approveDesc) return '--'
  313. const reason = reasons.value[approveDesc as keyof typeof reasons.value]
  314. if (reason) {
  315. return isZh.value ? reason.content : reason.enContent
  316. }
  317. return approveDesc
  318. }
  319. const listApi = ref(null)
  320. listApi.value = customApi.CustomRecordAccount
  321. </script>
  322. <style scoped lang="scss">
  323. @import "@/uni.scss";
  324. .avatar {
  325. width: px2rpx(60);
  326. height: px2rpx(60);
  327. border-radius: 4px;
  328. }
  329. .content-title {
  330. display: flex;
  331. justify-content: space-between;
  332. align-items: center;
  333. font-size: px2rpx(20);
  334. font-weight: 500;
  335. .content-title-btns {
  336. margin: px2rpx(8) 0;
  337. display: flex;
  338. align-items: center;
  339. justify-content: center;
  340. gap: px2rpx(12);
  341. .btn-primary {
  342. min-width: px2rpx(120);
  343. background-color: var(--color-error);
  344. color: white;
  345. padding: 0 px2rpx(12);
  346. border: none;
  347. font-size: px2rpx(14);
  348. text-align: center;
  349. cursor: pointer;
  350. display: flex;
  351. align-items: center;
  352. justify-content: center;
  353. gap: px2rpx(8);
  354. }
  355. .btn-primary:active {
  356. background-color: #cf1322;
  357. ;
  358. }
  359. }
  360. }
  361. .operation-btn {
  362. :deep(span) {
  363. display: flex;
  364. align-items: center;
  365. justify-content: center;
  366. gap: px2rpx(4);
  367. cursor: pointer;
  368. background-color: var(--color-slate-150);
  369. padding: px2rpx(8) 0;
  370. }
  371. }
  372. .operation-btn.disabled {
  373. cursor: not-allowed;
  374. opacity: 0.5;
  375. }
  376. .search-bar {
  377. display: flex;
  378. align-items: center;
  379. justify-content: flex-start;
  380. flex-wrap: wrap;
  381. gap: px2rpx(16);
  382. margin: px2rpx(16) 0;
  383. .cwg-combox,
  384. .uni-easyinput,
  385. .uni-date {
  386. width: px2rpx(240) !important;
  387. flex: none;
  388. }
  389. }
  390. </style>