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.

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