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.

923 lines
28 KiB

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