You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

812 lines
26 KiB

5 months ago
6 months ago
6 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
5 months ago
6 months ago
6 months ago
6 months ago
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
5 months ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
3 months ago
  1. <script setup>
  2. import { onMounted, ref, watch } from 'vue'
  3. import { ElMessage } from 'element-plus'
  4. import moment from 'moment'
  5. import API from '@/util/http.js'
  6. import { reverseMarketMapping } from '@/utils/marketMap.js';
  7. import dayjs from "dayjs";
  8. import { storeToRefs } from 'pinia'
  9. import { useAdminStore } from '@/store/index.js'
  10. const adminStore = useAdminStore()
  11. const { flag } = storeToRefs(adminStore)
  12. // 国际化
  13. import { useI18n } from 'vue-i18n';
  14. const { t } = useI18n();
  15. //新增员工数数据复选框,默认不勾选
  16. // const showEmployeeData = ref(false)
  17. // 监听全局flag状态变化
  18. watch(flag, (newFlag, oldFlag) => {
  19. if(newFlag !== oldFlag) {
  20. get()
  21. }
  22. })
  23. const trimJwCode = () => {
  24. if (rechargeUser.value.jwcode) {
  25. rechargeUser.value.jwcode = rechargeUser.value.jwcode.replace(/\s/g, '');
  26. }
  27. }
  28. //这是获取用户信息的接口
  29. const adminData = ref({})
  30. const getAdminData = async function () {
  31. try {
  32. const result = await API({ url: '/admin/userinfo', data: {} })
  33. adminData.value = result
  34. rechargeUser.value.adminId = adminData.value.id
  35. console.log('请求成功', result)
  36. console.log('用户信息', adminData.value)
  37. } catch (error) {
  38. console.log('请求失败', error)
  39. }
  40. }
  41. const defaultTime = [
  42. new Date(2000, 1, 1, 0, 0, 0),
  43. new Date(2000, 2, 1, 23, 59, 59),
  44. ]
  45. // 变量
  46. // 充值明细表格
  47. const tableData = ref([])
  48. // 标记当前激活的时间范围按钮
  49. const activeTimeRange = ref('')
  50. // 日期选择器变化时清除按钮激活状态
  51. const handleDatePickerChange = () => {
  52. activeTimeRange.value = ''
  53. }
  54. // 搜索===========================================
  55. // 搜索recharge
  56. const rechargeUser = ref({
  57. adminId: adminData.value.id,
  58. market: "",
  59. })
  60. /*//处理地区选择变化
  61. const handleMarketChange = (value) => {
  62. if (Array.isArray(value) && value.length > 0) {
  63. const ids = new Set();
  64. value.forEach(path => {
  65. const lastName = path[path.length - 1];
  66. const id = reverseMarketMapping[lastName];
  67. if (id) ids.add(Number(id));
  68. });
  69. // 添加额外处理:如果一个父节点下所有子节点都被选中,则把父节点也加入
  70. const getAllLeafNames = (nodes) => {
  71. const leafNames = [];
  72. const traverse = (node, parentName = null) => {
  73. if (!node.children || node.children.length === 0) {
  74. leafNames.push({ name: node.label, parent: parentName });
  75. } else {
  76. node.children.forEach(child => traverse(child, node.label));
  77. }
  78. };
  79. nodes.forEach(node => traverse(node));
  80. return leafNames;
  81. };
  82. const leafNameMap = getAllLeafNames(market.value); // 所有叶子节点和对应父级名称
  83. // 构建一个 { parentName: [childName1, childName2, ...] } 的结构
  84. const parentToChildren = {};
  85. leafNameMap.forEach(({ name, parent }) => {
  86. if (!parentToChildren[parent]) parentToChildren[parent] = [];
  87. parentToChildren[parent].push(name);
  88. });
  89. // 构建当前被选中的叶子节点
  90. const selectedLeafNames = value.map(path => path[path.length - 1]);
  91. // 如果 parent 下所有子节点都选中了,就把 parent 加进来
  92. Object.entries(parentToChildren).forEach(([parent, children]) => {
  93. const allChildrenSelected = children.every(child => selectedLeafNames.includes(child));
  94. if (allChildrenSelected && reverseMarketMapping[parent]) {
  95. ids.add(Number(reverseMarketMapping[parent]));
  96. }
  97. });
  98. // 修改:将数组转换为单个字符串(取第一个ID)
  99. const idArray = Array.from(ids);
  100. rechargeUser.value.market= idArray.length > 0 ? idArray[0].toString() : "";
  101. } else {
  102. rechargeUser.value.market = "";
  103. }
  104. console.log('最终映射后的 market IDs:', rechargeUser.value.market);
  105. };*/
  106. // 存储地区选择变化
  107. const selectedMarketPath = ref("")
  108. const handleMarketChange = (value) => {
  109. console.log('选择的地区路径初始值:', value);
  110. if (value && value.length > 0) {
  111. const lastValue = value[value.length - 1]
  112. console.log('选择的地区路径判断值:', lastValue);
  113. rechargeUser.value.market = reverseMarketMapping[lastValue]
  114. console.log('最终映射后的 未赋值的:', reverseMarketMapping[lastValue]);
  115. console.log('最终映射后的 market ID:', rechargeUser.value.market);
  116. } else {
  117. rechargeUser.value.market = ''
  118. }
  119. }
  120. /*// 处理地区选择变化单选场景
  121. const handleMarketChange = (value) => {
  122. // 重置为默认空值
  123. rechargeUser.value.market = "";
  124. // 检查是否有有效的选择值
  125. if (Array.isArray(value) && value.length > 0) {
  126. // 对于单选,value数组中通常只有一个路径
  127. const selectedPath = value[0];
  128. if (Array.isArray(selectedPath) && selectedPath.length > 0) {
  129. // 获取选中项的最后一级名称
  130. const lastName = selectedPath[selectedPath.length - 1];
  131. // 查找对应的ID
  132. const id = reverseMarketMapping[lastName];
  133. // 如果找到有效ID,转换为字符串格式
  134. if (id) {
  135. rechargeUser.value.market = String(id);
  136. }
  137. }
  138. }
  139. console.log('最终选中的 market ID:', rechargeUser.value.market);
  140. };*/
  141. // 搜索对象
  142. const getObj = ref({
  143. pageNum: 1,
  144. pageSize: 50
  145. })
  146. //分页总条目
  147. const total = ref(100)
  148. // 搜索对象时间
  149. const getTime = ref([])
  150. // 搜索活动列表
  151. const activity = ref([])
  152. // 所有信息
  153. const allData = ref([])
  154. // 搜索地区列表
  155. const market = ref("")
  156. //时间格式化
  157. const formatTime = (val) => val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : ''
  158. // 初始化 money 和 permanentGold 和 freeGold
  159. const money = ref(0)
  160. const permanentGold = ref(0)
  161. const freeGold = ref(0)
  162. // 定义响应式变量存储金币合计数
  163. const permanentGolds = ref(0)
  164. const freeGolds = ref(0)
  165. //无法选择的时间
  166. const disabledDate = (time) => {
  167. const limitDate = new Date(2025, 0, 1);
  168. return time.getTime() < limitDate.getTime();
  169. }
  170. // 支付方式选项
  171. const payModel = [
  172. {
  173. value: '微信',
  174. label: '微信'
  175. },
  176. {
  177. value: '支付宝',
  178. label: '支付宝'
  179. },
  180. {
  181. value: '银联',
  182. label: '银联'
  183. },
  184. {
  185. value: '信用卡',
  186. label: '信用卡'
  187. },
  188. {
  189. value: '借记卡',
  190. label: '借记卡'
  191. },
  192. {
  193. value: '现金充值',
  194. label: '现金充值'
  195. }
  196. ]
  197. // 删除==========================================================
  198. // 删除对象
  199. const delObj = ref({})
  200. // 获取活动名称
  201. const getActivity = async function () {
  202. try {
  203. // 发送POST请求
  204. const result = await API({ url: '/general/activity', data: {} })
  205. // 将响应结果存储到响应式数据中
  206. console.log('请求成功', result)
  207. // 检查返回的数据是否为数组
  208. if (Array.isArray(result.data)) {
  209. // 将字符串数组转换为 { value, label } 格式
  210. activity.value = result.data.map(item => ({ value: item, label: item }));
  211. } else {
  212. console.error('活动数据格式错误', result)
  213. ElMessage.error(t('elmessage.activityFormatError'))
  214. }
  215. console.log('activity', activity.value)
  216. } catch (error) {
  217. console.log('请求失败', error)
  218. // 在这里可以处理错误逻辑,比如显示错误提示等
  219. }
  220. }
  221. const marketsTree = ref("")
  222. // 获取地区,修改为级联下拉框
  223. const getArea = async function () {
  224. try {
  225. // 发送POST请求
  226. const result = await API({
  227. url: '/market/selectMarket',
  228. });
  229. // 将响应结果存储到响应式数据中
  230. console.log('请求成功', result)
  231. // 递归转换树形结构为级联选择器需要的格式(跳过第一级节点)
  232. const transformTree = (nodes) => {
  233. // 直接处理第一级节点的子节点
  234. const allChildren = nodes.flatMap(node => node.children || []);
  235. return allChildren.map(child => {
  236. const grandchildren = child.children && child.children.length
  237. ? transformTree([child]) // 递归处理子节点
  238. : null;
  239. return {
  240. value: child.name,
  241. label: child.name,
  242. children: grandchildren
  243. };
  244. });
  245. };
  246. // 存储地区信息
  247. market.value = transformTree(result.data)
  248. console.log('转换后的地区树==============', market.value)
  249. } catch (error) {
  250. console.log('请求失败', error)
  251. }
  252. }
  253. //定义充值方式的加载状态
  254. const isLoadingPlatform = ref(false)
  255. // 充值平台
  256. const platform = ref([])
  257. //获取充值方式的函数
  258. const getPlatform = async () => {
  259. isLoadingPlatform.value = true;
  260. try {
  261. const result = await API({
  262. url: '/general/platform',
  263. method: 'post',
  264. data: {}// 这里添加参数
  265. })
  266. // 假设后端返回的是字符串数组,转换为 { value, label } 格式
  267. if (Array.isArray(result.data)) {
  268. platform.value = result.data.map(item => ({ value: item, label: item }));
  269. } else {
  270. console.error('充值方式格式错误', result)
  271. ElMessage.error(t('elmessage.rechargeFormatError'))
  272. }
  273. } catch (error) {
  274. console.error('获取充值方式失败:', error);
  275. ElMessage.error(t('elmessage.getRechargeError'))
  276. } finally {
  277. isLoadingPlatform.value = false
  278. }
  279. }
  280. // 搜索===========================================================================
  281. // 搜索方法
  282. const get = async function (val) {
  283. try {
  284. // 搜索参数页码赋值
  285. if (typeof val === 'number') {
  286. getObj.value.pageNum = val
  287. }
  288. // 搜索参数时间赋值
  289. if (getTime.value != null) {
  290. if (getTime.value.startTime != '' && getTime.value.endTime != '') {
  291. rechargeUser.value.startTime = formatTime(getTime.value[0])
  292. rechargeUser.value.endTime = formatTime(getTime.value[1])
  293. }
  294. } else {
  295. rechargeUser.value.startTime = ''
  296. rechargeUser.value.endTime = ''
  297. }
  298. // 搜索参数赋值
  299. rechargeUser.value.sortField = sortField.value
  300. rechargeUser.value.sortOrder = sortOrder.value
  301. console.log('搜索参数', getObj.value)
  302. // 发送POST请求
  303. // if (rechargeUser.value.market === '9' || rechargeUser.value.market === '9999') {
  304. // rechargeUser.value.market = '';
  305. // }
  306. if (rechargeUser.value.jwcode) {
  307. // 纯数字
  308. const numberRegex = /^\d{1,9}$/;
  309. // 检查是否不是数字
  310. if (!numberRegex.test(rechargeUser.value.jwcode)) {
  311. ElMessage.error(t('elmessage.checkJwcodeFormat'))
  312. // 上面提示过了
  313. return
  314. }
  315. }
  316. const result = await API({
  317. url: '/recharge/selectBy',
  318. data: {
  319. ...getObj.value,
  320. rechargeUser: { ...rechargeUser.value, flag: flag.value }//新增flag参数
  321. }
  322. })
  323. // 复制一份 rechargeUser.value 并移除排序字段和排序方式
  324. const detailWithoutSort = ref({
  325. ...rechargeUser.value,
  326. sortField: undefined,
  327. sortOrder: undefined,
  328. flag: flag.value // 新增 flag 参数
  329. })
  330. const resultTotalGold = await API({
  331. url: '/recharge/statsGold',
  332. data: {
  333. ...detailWithoutSort.value
  334. }
  335. })
  336. if (resultTotalGold.code === 200 && resultTotalGold.data) {
  337. const data = resultTotalGold.data
  338. console.log('获取到的金币数据:', data)
  339. permanentGolds.value = (Number(data.permanentGolds) || 0)
  340. freeGolds.value = (Number(data.freeGolds) || 0)
  341. }
  342. // 将响应结果存储到响应式数据中
  343. console.log('请求成功', result)
  344. // 存储表格数据
  345. tableData.value = result.data.list
  346. // 处理表格中的充值金额、永久金币和免费金币数据,除以 100
  347. tableData.value = tableData.value.map(item => ({
  348. ...item,
  349. // 处理永久金币
  350. permanentGold: (Number(item.permanentGold) || 0),
  351. // 处理免费金币
  352. freeGold: (Number(item.freeGold) || 0),
  353. // 处理充值金额
  354. money: (Number(item.money) || 0)
  355. }))
  356. console.log('tableData', tableData.value)
  357. // 存储分页总数
  358. total.value = result.data.total
  359. console.log('total', total.value)
  360. } catch (error) {
  361. console.log('请求失败', error)
  362. // 在这里可以处理错误逻辑,比如显示错误提示等
  363. }
  364. }
  365. // 搜索
  366. const search = function () {
  367. trimJwCode()
  368. getObj.value.pageNum = 1
  369. get()
  370. }
  371. // 重置
  372. const reset = function () {
  373. delete rechargeUser.value.jwcode
  374. delete rechargeUser.value.activity
  375. delete rechargeUser.value.payPlatform
  376. rechargeUser.value.market = ""
  377. selectedMarketPath.value = "" // 重置地区选择路径
  378. delete rechargeUser.value.startTime
  379. delete rechargeUser.value.endTime
  380. delete sortField.value
  381. delete sortOrder.value
  382. getTime.value = {}
  383. activeTimeRange.value = '' // 清除激活状态
  384. // 重置页码
  385. getObj.value.pageNum = 1
  386. get()
  387. }
  388. // 今天
  389. const getToday = function () {
  390. const today = dayjs()
  391. const startTime = today.startOf('day').format('YYYY-MM-DD HH:mm:ss')
  392. const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
  393. getTime.value = [startTime, endTime]
  394. console.log('getTime', getTime.value)
  395. activeTimeRange.value = 'today' // 标记当前激活状态
  396. get()
  397. }
  398. const handlePageSizeChange = function (val) {
  399. getObj.value.pageSize = val
  400. get()
  401. }
  402. const handleCurrentChange = function (val) {
  403. getObj.value.pageNum = val
  404. get()
  405. }
  406. // 昨天
  407. const getYesterday = function () {
  408. const today = dayjs()
  409. const startTime = today.subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  410. const endTime = today.subtract(1, 'day').endOf('day').format('YYYY-MM-DD HH:mm:ss')
  411. getTime.value = [startTime, endTime]
  412. console.log('getTime', getTime.value)
  413. activeTimeRange.value = 'yesterday' // 标记当前激活状态
  414. get()
  415. }
  416. // 近7天
  417. const get7Days = function () {
  418. const today = dayjs()
  419. const startTime = today.subtract(6, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  420. const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
  421. getTime.value = [startTime, endTime]
  422. console.log('getTime', getTime.value)
  423. activeTimeRange.value = '7days' // 标记当前激活状态
  424. get()
  425. }
  426. const format3 = (num) => {
  427. // 每三位添加逗号
  428. return num.toLocaleString('en-US')
  429. }
  430. // 挂载
  431. onMounted(async function () {
  432. await get()
  433. await getActivity()
  434. await getAdminData()
  435. await getArea()
  436. await getPlatform()
  437. })
  438. // 新增排序字段和排序方式
  439. const sortField = ref()
  440. const sortOrder = ref()
  441. // 处理排序事件
  442. const handleSortChange = (column) => {
  443. console.log('排序字段:', column.prop)
  444. console.log('排序方式:', column.order)
  445. if (column.prop === 'money') {
  446. sortField.value = 'money'
  447. } else if (column.prop === 'freeGold') {
  448. sortField.value = 'freeGold'
  449. } else if (column.prop === 'auditTime') {
  450. sortField.value = 'auditTime'
  451. } else if (column.prop === 'createTime') {
  452. sortField.value = 'createTime'
  453. } else if (column.prop === 'permanentGold') {
  454. sortField.value = 'permanentGold'
  455. }
  456. sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
  457. console.log('传递给后端的排序字段:', sortField.value)
  458. console.log('传递给后端的排序方式:', sortOrder.value)
  459. get()
  460. }
  461. const exportExcel = async function () {
  462. const params = {
  463. rechargeUser: {
  464. ...rechargeUser.value,
  465. flag: flag.value
  466. },
  467. page: getObj.value.pageNum,
  468. size: total.value
  469. }
  470. try {
  471. const res = await API({ url: '/export/exportRecharge', data: params })
  472. if (res.code === 200) {
  473. ElMessage.success(t('elmessage.exportSuccess'))
  474. } else {
  475. ElMessage.error(res.message || t('elmessage.exportFailed'))
  476. }
  477. } catch (error) {
  478. console.log('请求失败', error)
  479. ElMessage.error(t('elmessage.exportFailed'))
  480. }
  481. }
  482. const exportListVisible = ref(false)
  483. // 打开导出列表弹窗
  484. const openExportList = () => {
  485. getExportList()
  486. exportListVisible.value = true
  487. }
  488. // 导出列表数据
  489. const exportList = ref([])
  490. // 导出列表加载状态
  491. const exportListLoading = ref(false)
  492. // 获取导出列表
  493. const getExportList = async () => {
  494. exportListLoading.value = true
  495. try {
  496. const result = await API({ url: '/export/export' })
  497. if (result.code === 200) {
  498. const filteredData = result.data.filter(item => {
  499. return item.type === 2; //2表示金币充值列表
  500. });
  501. exportList.value = filteredData
  502. } else {
  503. ElMessage.error(result.msg || t('elmessage.getExportListError'))
  504. }
  505. } catch (error) {
  506. console.error('获取导出列表出错:', error)
  507. ElMessage.error(t('elmessage.getExportListError'))
  508. } finally {
  509. exportListLoading.value = false
  510. }
  511. }
  512. // 下载导出文件
  513. const downloadExportFile = (item) => {
  514. if (item.state === 2) {
  515. const link = document.createElement('a')
  516. link.href = item.url
  517. link.download = item.fileName
  518. link.click()
  519. } else {
  520. ElMessage.warning(t('elmessage.exportingInProgress'))
  521. }
  522. }
  523. //根据状态返回对应的标签类型
  524. const getTagType = (state) => {
  525. switch (state) {
  526. case 0:
  527. return 'info';
  528. case 1:
  529. return 'primary';
  530. case 2:
  531. return 'success';
  532. case 3:
  533. return 'danger';
  534. default:
  535. return 'info';
  536. }
  537. }
  538. //根据状态返回对应的标签文案
  539. const getTagText = (state) => {
  540. switch (state) {
  541. case 0:
  542. return t('elmessage.pendingExecution');
  543. case 1:
  544. return t('elmessage.executing');
  545. case 2:
  546. return t('elmessage.executed');
  547. case 3:
  548. return t('elmessage.errorExecution');
  549. default:
  550. return t('elmessage.unknownStatus');
  551. }
  552. }
  553. </script>
  554. <template>
  555. <el-card class="card1" style="margin-bottom: 0.5vh">
  556. <el-col style="margin-bottom: 1vh">
  557. <div class="select">
  558. <div class="selectRow">
  559. <el-text class="text" size="large">{{ $t('common.jwcode') }}</el-text>
  560. <el-input class="selectContent" v-model="rechargeUser.jwcode" :placeholder="$t('common.jwcodePlaceholder')" clearable />
  561. </div>
  562. <div class="selectRow">
  563. <el-text class="text" size="large">{{ $t('common.activityName') }}</el-text>
  564. <el-select class="selectContent" v-model="rechargeUser.activity" :placeholder="$t('common.activityNamePlaceholder')" clearable>
  565. <el-option v-for="item in activity" :key="item.value" :label="item.label" :value="item.value" />
  566. </el-select>
  567. </div>
  568. <div class="selectRow" style="width: 15vw;">
  569. <el-text class="text" size="large">{{ $t('common.market') }}</el-text>
  570. <el-cascader class="selectContent" v-model="selectedMarketPath" :options="market" :placeholder="$t('common.marketPlaceholder')"
  571. clearable @change="handleMarketChange" />
  572. </div>
  573. <div class="selectRow" style="width: 15vw;">
  574. <el-text class="text" size="large">{{ $t('common.rechargePlatform') }}</el-text>
  575. <el-select class="selectContent" v-model="rechargeUser.payPlatform" :placeholder="$t('common.rechargePlatformPlaceholder')" clearable>
  576. <el-option v-for="item in platform" :key="item.value" :label="item.label" :value="item.value" />
  577. </el-select>
  578. </div>
  579. <!-- <el-checkbox v-model="showEmployeeData" @change="search()">员工数据</el-checkbox> -->
  580. </div>
  581. </el-col>
  582. <el-col>
  583. <div class="select">
  584. <div class="selectRow" style="width: 36vw;">
  585. <el-text class="text" size="large">{{ $t('common.rechargeTime') }}</el-text>
  586. <el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="$t('common.to')"
  587. :start-placeholder="$t('common.startTime')" :end-placeholder="$t('common.endTime')" style="margin-right:1vw;width:25vw"
  588. @change="handleDatePickerChange" :default-time="defaultTime" :disabled-date="disabledDate" />
  589. <div v-if="false">
  590. <el-button @click="getToday()" style="margin-left: 1vw"
  591. :type="activeTimeRange === 'today' ? 'primary' : ''">
  592. </el-button>
  593. <el-button @click="getYesterday()" style="margin-left: 1vw"
  594. :type="activeTimeRange === 'yesterday' ? 'primary' : ''">
  595. </el-button>
  596. <el-button @click="get7Days()" style="margin-left: 1vw"
  597. :type="activeTimeRange === '7days' ? 'primary' : ''">
  598. 近7天
  599. </el-button>
  600. </div>
  601. </div>
  602. <div class="selectRow" style="justify-content: flex-start;">
  603. <el-button type="primary" @click="search()">{{ $t('common.search') }}</el-button>
  604. <el-button type="primary" @click="exportExcel()">{{ $t('common.exportExcel') }}</el-button>
  605. <el-button type="primary" @click="openExportList">{{ $t('common.viewExportList') }}</el-button>
  606. <el-button type="success" @click="reset()">{{ $t('common.reset') }}</el-button>
  607. </div>
  608. </div>
  609. </el-col>
  610. </el-card>
  611. <el-card class="card2">
  612. <div class="goldStatistics">
  613. {{ $t('common.rechargeSGD') }}{{ format3(permanentGolds) }} {{ $t('common.SGD') }}&nbsp;&nbsp;&nbsp;&nbsp;
  614. {{ $t('common.totalGoldCoin') }}{{ format3(permanentGolds + freeGolds) }} {{ $t('common.goldCoin') }}&nbsp;&nbsp;&nbsp;&nbsp;
  615. {{ $t('common.permanentGold') }}{{ format3(permanentGolds) }} {{ $t('common.goldCoin') }}&nbsp;&nbsp;&nbsp;&nbsp;
  616. {{ $t('common.freeGold') }}{{ format3(freeGolds) }} {{ $t('common.goldCoin') }}
  617. </div>
  618. <!-- 设置表格容器的高度和滚动样式 -->
  619. <div style="height: 66vh;">
  620. <el-table :data="tableData" height="66vh" @sort-change="handleSortChange">
  621. <el-table-column type="index" :label="$t('common_list.id')" width="80px" fixed="left">
  622. <template #default="scope">
  623. <span>{{
  624. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  625. }}</span>
  626. </template>
  627. </el-table-column>
  628. <el-table-column fixed="left" prop="name" :label="$t('common_list.name')" width="150px" />
  629. <el-table-column fixed="left" prop="jwcode" :label="$t('common_list.jwcode')" width="110px" />
  630. <el-table-column prop="market" :label="$t('common_list.market')" width="120px" />
  631. <el-table-column prop="activity" :label="$t('common_list.activity')" width="110px" show-overflow-tooltip />
  632. <el-table-column prop="rateName" :label="$t('common_list.rateName')" width="110px" />
  633. <el-table-column prop="money" sortable="custom" :label="$t('common_list.rechargeAmount')" width="110px" />
  634. <el-table-column prop="permanentGold" :label="$t('common_list.permanentGold')" sortable="custom" width="130px" />
  635. <el-table-column prop="freeGold" :label="$t('common_list.freeGold')" sortable="custom" width="130px" />
  636. <el-table-column prop="payPlatform" :label="$t('common_list.rechargePlatform')" width="130px" />
  637. <el-table-column prop="payModel" :label="$t('common_list.payModel')" width="120px" />
  638. <el-table-column prop="remark" :label="$t('common_list.remark')" width="150px" show-overflow-tooltip />
  639. <el-table-column prop="isRefund" :label="$t('common_list.orderStatus')" width="200px" show-overflow-tooltip>
  640. <template #default="scope">
  641. <span v-if="scope.row.isRefund == 0">{{ $t('recharge.normal') }}</span>
  642. <span v-else-if="scope.row.isRefund == 1">{{ $t('recharge.refunded') }}</span>
  643. <span v-else>{{ $t('recharge.unknown') }}</span>
  644. </template>
  645. </el-table-column>
  646. <el-table-column prop="adminName" :label="$t('common_list.submitter')" width="100px" />
  647. <el-table-column prop="auditTime" sortable :label="$t('common_list.rechargeTime')" width="200px">
  648. <template #default="scope">
  649. {{ moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') }}
  650. </template>
  651. </el-table-column>
  652. </el-table>
  653. </div>
  654. <!-- 分页 -->
  655. <div style="margin-top: 1vh">
  656. <el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  657. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
  658. @current-change="handleCurrentChange"></el-pagination>
  659. </div>
  660. </el-card>
  661. <!-- 导出弹窗 -->
  662. <el-dialog v-model="exportListVisible" :title="$t('common_export.exportList')" width="80%">
  663. <el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
  664. <el-table-column prop="fileName" :label="$t('common_export.fileName')" />
  665. <el-table-column prop="state" :label="$t('common_export.status')">
  666. <template #default="scope">
  667. <el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
  668. {{ getTagText(scope.row.state) }}
  669. </el-tag>
  670. </template>
  671. </el-table-column>
  672. <el-table-column prop="createTime" :label="$t('common_export.createTime')">
  673. <template #default="scope">
  674. {{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
  675. </template>
  676. </el-table-column>
  677. <el-table-column :label="$t('common_export.operation')">
  678. <template #default="scope">
  679. <el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
  680. :disabled="scope.row.state !== 2">
  681. {{ $t('common_export.download') }}
  682. </el-button>
  683. </template>
  684. </el-table-column>
  685. </el-table>
  686. <template #footer>
  687. <div class="dialog-footer">
  688. <el-button text @click="exportListVisible = false">{{ $t('common_export.close') }}</el-button>
  689. </div>
  690. </template>
  691. </el-dialog>
  692. </template>
  693. <style scoped lang="scss">
  694. // 搜索的卡片样式
  695. .card1 {
  696. background: #F3FAFE;
  697. }
  698. // 表单的卡片样式
  699. .card2 {
  700. background: #E7F4FD;
  701. }
  702. // 新币总数等等
  703. .goldStatistics {
  704. margin-left: 1vw;
  705. margin-bottom: 1vh;
  706. color: #000000;
  707. font-family: "PingFang SC";
  708. font-size: 16px;
  709. font-style: normal;
  710. font-weight: 700;
  711. line-height: 20px;
  712. }
  713. // 表头背景等
  714. :deep(.el-table__header-wrapper),
  715. :deep(.el-table__body-wrapper),
  716. :deep(.el-table__cell),
  717. /* 表格 */
  718. :deep(.el-table__body td) {
  719. background-color: #F3FAFE !important;
  720. }
  721. /* 表头 */
  722. :deep(.el-table__header th) {
  723. background-color: #F3FAFE !important;
  724. }
  725. /* 鼠标悬停 */
  726. :deep(.el-table__row:hover > .el-table__cell) {
  727. background-color: #E5EBFE !important;
  728. }
  729. /** 上面搜索的布局 **/
  730. .select {
  731. display: flex;
  732. .selectRow {
  733. width: 17vw;
  734. display: flex;
  735. align-items: center;
  736. justify-content: center;
  737. padding: 0 0.5vw;
  738. .text {
  739. width: 5vw;
  740. font-size: 15px;
  741. }
  742. .selectContent {
  743. flex: 1;
  744. }
  745. }
  746. }
  747. </style>