金币系统前端
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.

856 lines
27 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
10 months ago
12 months ago
12 months ago
12 months ago
  1. <script setup>
  2. import { ref, onMounted, reactive, computed } from 'vue'
  3. import ElementPlus from 'element-plus'
  4. import { ElMessage, ElMessageBox } from 'element-plus'
  5. import { AiFillRead } from 'vue-icons-plus/ai'
  6. import axios from 'axios'
  7. import request from '@/util/http'
  8. import moment from 'moment'
  9. import API from '../../api/index.js'
  10. // 变量
  11. // 这是动态表头,
  12. const columnOptions = ref([
  13. { prop: 'username', label: '姓名', width: 125 },
  14. { prop: 'jwcode', label: '精网号', width: 125 },
  15. { prop: 'area', label: '所属地区', width: 125 },
  16. { prop: 'activityName', label: '活动名称', width: 150 },
  17. { prop: 'rechargeGold', label: '充值金额', width: 125, sortable: true },
  18. { prop: 'rechargeWay', label: '充值方式', width: 125 },
  19. { prop: 'paidGold', label: '永久金币', width: 125, sortable: true },
  20. { prop: 'freeGold', label: '免费金币', width: 125, sortable: true },
  21. { prop: 'remark', label: '备注', width: 200, showOverflowTooltip: true },
  22. { prop: 'payWay', label: '支付方式', width: 125 },
  23. { prop: 'rechargeVoucher', label: '支付凭证', width: 125 },
  24. { prop: 'name', label: '提交人', width: 125 },
  25. { prop: 'status', label: '审核状态', width: 125 },
  26. { prop: 'reson', label: '驳回理由', width: 200 },
  27. { prop: 'rechargeTime', label: '交款时间', width: 200, sortable: true },
  28. { prop: 'createTime', label: '提交时间', width: 200, sortable: true },
  29. { prop: 'auditTime', label:'审核时间', width:200, sortable:true}
  30. ])
  31. // 默认显示
  32. const defaultColumns = ['username', 'jwcode', 'area', 'activityName', 'rechargeGold', 'rechargeWay', 'paidGold', 'freeGold',
  33. 'remark', 'payWay', 'rechargeVoucher', 'name', 'status', 'reson', 'rechargeTime', 'createTime', 'auditTime']
  34. const selectedColumns = ref([...defaultColumns])
  35. //这是获取用户信息的接口
  36. const adminData = ref({})
  37. const getAdminData = async function () {
  38. try {
  39. const result = await request({
  40. url: '/admin/userinfo',
  41. data: {}
  42. })
  43. adminData.value = result
  44. console.log('请求成功', result)
  45. console.log('用户信息', adminData.value)
  46. } catch (error) {
  47. console.log('请求失败', error)
  48. }
  49. }
  50. // 充值明细表格
  51. const tableData = ref([])
  52. // 搜索======================================
  53. // 搜索rechargeVo
  54. const rechargeVo = ref({
  55. rechargeWay: '客服充值'
  56. })
  57. // 搜索对象
  58. const getObj = ref({
  59. pageNum: 1,
  60. pageSize: 50
  61. })
  62. //分页总条目
  63. const total = ref(100)
  64. // 搜索对象时间
  65. const getTime = ref([])
  66. // 搜索活动列表
  67. const activity = ref([])
  68. // 所有信息
  69. const allData = ref([])
  70. // 搜索地区列表
  71. const area = ref([])
  72. // 编辑======================================
  73. // 驳回弹出框
  74. const rejectVisible = ref(false)
  75. // 驳回对象
  76. const rejectObj = ref({})
  77. // 通过对象
  78. const passObj = ref({})
  79. //标签页默认高亮选项
  80. const activeName = ref('all')
  81. // 支付方式选项
  82. const payWay = [
  83. {
  84. value: '微信',
  85. label: '微信'
  86. },
  87. {
  88. value: '支付宝',
  89. label: '支付宝'
  90. },
  91. {
  92. value: '银联',
  93. label: '银联'
  94. },
  95. {
  96. value: '信用卡',
  97. label: '信用卡'
  98. },
  99. {
  100. value: '借记卡',
  101. label: '借记卡'
  102. }
  103. ]
  104. // //表格高度
  105. // const tableHeight = computed(function () {
  106. // return (getObj.value.pageSize + 2) * 60 + "px";
  107. // });
  108. // 表单验证ref
  109. const Ref = ref(null)
  110. // 方法
  111. // 合计数存储
  112. // 统计合计数
  113. const trueGold = ref(0)
  114. const trueCount = ref(0)
  115. const trueRGold = ref(0)
  116. const trueFGold = ref(0)
  117. // 转化一下,保留两位小数,展示时填充转化后的变量名
  118. const formattedTrueGold = computed(() => trueGold.value.toFixed(2))
  119. const formattedTrueRGold = computed(() => trueRGold.value.toFixed(2))
  120. const formattedTrueFGold = computed(() => trueFGold.value.toFixed(2))
  121. // 待审核条数
  122. const pendingCount = ref(0)
  123. // 待审核金币数
  124. const pendingGold = ref(0)
  125. const pendingRGold = ref(0)
  126. const pendingFGold = ref(0)
  127. // 已通过条数
  128. const approvedCount = ref(0)
  129. // 已通过金币数
  130. const approvedGold = ref(0)
  131. const approvedRGold = ref(0)
  132. const approvedFGold = ref(0)
  133. // 已驳回条数
  134. const rejectedCount = ref(0)
  135. // 已驳回金币数
  136. const rejectedGold = ref(0)
  137. const rejectedRGold = ref(0)
  138. const rejectedFGold = ref(0)
  139. // 搜索==============================================================
  140. // 搜索方法
  141. const get = async function (val) {
  142. try {
  143. // 地区赋值
  144. if (adminData.value.area === '泰国') {
  145. rechargeVo.value.areas = ['泰国', '越南']
  146. } else if (adminData.value.area !== '总部') {
  147. rechargeVo.value.area = adminData.value.area
  148. }
  149. // 搜索参数页码赋值
  150. if (typeof val === 'number') {
  151. getObj.value.pageNum = val
  152. }
  153. // 搜索参数时间赋值
  154. if (getTime.value != null) {
  155. if (getTime.value.startDate != '' && getTime.value.endDate != '') {
  156. rechargeVo.value.startDate = getTime.value[0]
  157. rechargeVo.value.endDate = getTime.value[1]
  158. }
  159. } else {
  160. rechargeVo.value.startDate = ''
  161. rechargeVo.value.endDate = ''
  162. }
  163. rechargeVo.value.sortField = sortField.value
  164. rechargeVo.value.sortOrder = sortOrder.value
  165. console.log('搜索参数', getObj.value)
  166. // 发送POST请求
  167. const result = await request({
  168. url: '/recharge/recharge',
  169. data: {
  170. pageNum: getObj.value.pageNum,
  171. pageSize: getObj.value.pageSize,
  172. rechargeVo: { ...rechargeVo.value }
  173. }
  174. })
  175. // 合计数的接口
  176. // 复制一份 rechargeVo.value 并移除排序字段和排序方式
  177. const detailWithoutSort = { ...rechargeVo.value }
  178. delete detailWithoutSort.sortField
  179. delete detailWithoutSort.sortOrder
  180. delete detailWithoutSort.status
  181. const result2 = await request({
  182. url: '/recharge/recharge/RechargeA',
  183. data: detailWithoutSort
  184. })
  185. // 做一个判断,如果result2.data[i].flag="待审核",那么 totalData.value = result2.data[i],否则就赋值为0
  186. // 统计合计数
  187. if (result2.data) {
  188. result2.data.forEach((item) => {
  189. switch (item.auditStatus) {
  190. case '待审核':
  191. // 若 item.raudit 为空则赋值为 0
  192. pendingCount.value = item.raudit || 0
  193. // 若 item.sumRaudit 为空则赋值为 0
  194. pendingGold.value = item.sumRaudit || 0
  195. pendingRGold.value = item.sumRaudit1 || 0
  196. pendingFGold.value = item.sumRaudit2 || 0
  197. break
  198. case '已通过':
  199. approvedCount.value = item.raudit || 0
  200. approvedGold.value = item.sumRaudit || 0
  201. approvedRGold.value = item.sumRaudit1 || 0
  202. approvedFGold.value = item.sumRaudit2 || 0
  203. break
  204. case '已驳回':
  205. rejectedCount.value = item.raudit || 0
  206. rejectedGold.value = item.sumRaudit || 0
  207. rejectedRGold.value = item.sumRaudit1 || 0
  208. rejectedFGold.value = item.sumRaudit2 || 0
  209. break
  210. }
  211. })
  212. }
  213. trueGold.value = pendingGold.value + approvedGold.value + rejectedGold.value
  214. trueCount.value =
  215. pendingCount.value + approvedCount.value + rejectedCount.value
  216. trueRGold.value =
  217. pendingRGold.value + approvedRGold.value + rejectedRGold.value
  218. trueFGold.value =
  219. pendingFGold.value + approvedFGold.value + rejectedFGold.value
  220. // 将响应结果存储到响应式数据中
  221. console.log('请求成功', result)
  222. console.log('这是分页', getObj.value)
  223. // 存储表格数据
  224. tableData.value = result.data.list
  225. console.log('tableData', tableData.value)
  226. // 存储分页总数
  227. total.value = result.data.total
  228. console.log('total', total.value)
  229. } catch (error) {
  230. console.log('请求失败', error)
  231. // 在这里可以处理错误逻辑,比如显示错误提示等
  232. }
  233. }
  234. // 搜索
  235. const search = function () {
  236. trimJwCode();
  237. getObj.value.pageNum = 1
  238. get()
  239. }
  240. // 重置
  241. const reset = function () {
  242. delete rechargeVo.value.activityId
  243. delete rechargeVo.value.jwcode
  244. delete rechargeVo.value.payWay
  245. delete rechargeVo.value.area
  246. delete rechargeVo.value.startDate
  247. delete rechargeVo.value.endDate
  248. getTime.value = {}
  249. }
  250. // 今天
  251. const getToday = function () {
  252. const today = new Date()
  253. const startDate = new Date(
  254. today.getFullYear(),
  255. today.getMonth(),
  256. today.getDate()
  257. )
  258. const endDate = new Date(
  259. today.getFullYear(),
  260. today.getMonth(),
  261. today.getDate() + 1
  262. )
  263. getTime.value = [startDate, endDate]
  264. console.log('getTime', getTime.value)
  265. get()
  266. }
  267. // 昨天
  268. const getYesterday = function () {
  269. const yesterday = new Date()
  270. yesterday.setDate(yesterday.getDate() - 1)
  271. const startDate = new Date(
  272. yesterday.getFullYear(),
  273. yesterday.getMonth(),
  274. yesterday.getDate()
  275. )
  276. const endDate = new Date(
  277. yesterday.getFullYear(),
  278. yesterday.getMonth(),
  279. yesterday.getDate() + 1
  280. )
  281. getTime.value = [startDate, endDate]
  282. console.log('getTime', getTime.value)
  283. get()
  284. }
  285. // 近7天
  286. const get7Days = function () {
  287. const today = new Date()
  288. const startDate = new Date(
  289. today.getFullYear(),
  290. today.getMonth(),
  291. today.getDate() - 6
  292. )
  293. const endDate = new Date(
  294. today.getFullYear(),
  295. today.getMonth(),
  296. today.getDate() + 1
  297. )
  298. getTime.value = [startDate, endDate]
  299. console.log('getTime', getTime.value)
  300. get()
  301. }
  302. //全部充值明细
  303. const adminAll = function () {
  304. console.log('adminAll')
  305. rechargeVo.value.status = ''
  306. getObj.value.pageNum = 1
  307. get()
  308. }
  309. //待审核充值明细
  310. const adminWait = async function () {
  311. rechargeVo.value.status = 0
  312. getObj.value.pageNum = 1
  313. await get()
  314. console.log('adminWait')
  315. trueCount.value = pendingCount.value
  316. trueGold.value = pendingGold.value
  317. trueRGold.value = pendingRGold.value
  318. trueFGold.value = pendingFGold.value
  319. }
  320. //已通过充值明细
  321. const adminPass = async function () {
  322. rechargeVo.value.status = 1
  323. getObj.value.pageNum = 1
  324. await get()
  325. console.log('adminPass')
  326. trueCount.value = approvedCount.value
  327. trueGold.value = approvedGold.value
  328. trueRGold.value = approvedRGold.value
  329. trueFGold.value = approvedFGold.value
  330. }
  331. //已驳回充值明细
  332. const adminReject = async function () {
  333. rechargeVo.value.status = 2
  334. getObj.value.pageNum = 1
  335. await get()
  336. console.log('adminReject')
  337. trueCount.value = rejectedCount.value
  338. trueGold.value = rejectedGold.value
  339. trueRGold.value = rejectedRGold.value
  340. trueFGold.value = rejectedFGold.value
  341. }
  342. //点击标签页
  343. const handleClick = function (tab, event) {
  344. if (tab.props.name === 'all') {
  345. adminAll()
  346. } else if (tab.props.name === 'wait') {
  347. adminWait()
  348. } else if (tab.props.name === 'pass') {
  349. adminPass()
  350. } else if (tab.props.name === 'reject') {
  351. adminReject()
  352. }
  353. }
  354. // 获取活动名称
  355. const getActivity = async function () {
  356. try {
  357. // 发送POST请求
  358. const result = await request({
  359. url: '/recharge/activity/select',
  360. data: {}
  361. })
  362. // 将响应结果存储到响应式数据中
  363. console.log('请求成功', result)
  364. // 存储表格数据
  365. activity.value = result.data
  366. console.log('activity', activity.value)
  367. } catch (error) {
  368. console.log('请求失败', error)
  369. // 在这里可以处理错误逻辑,比如显示错误提示等
  370. }
  371. }
  372. // 获取地区
  373. const getArea = async function () {
  374. try {
  375. // 发送POST请求
  376. const result = await request({
  377. url: '/recharge/user/search',
  378. data: {}
  379. })
  380. // 将响应结果存储到响应式数据中
  381. console.log('请求成功', result)
  382. // 存储地区信息
  383. area.value = result.data
  384. console.log('地区', area.value)
  385. } catch (error) {
  386. console.log('请求失败', error)
  387. // 在这里可以处理错误逻辑,比如显示错误提示等
  388. }
  389. }
  390. // 验证跳转输入框的数字是否合法
  391. const checkNumber = function () {
  392. if (typeof parseInt(getObj.value.pageNum) === 'number') {
  393. console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
  394. if (
  395. getObj.value.pageNum > 0 &&
  396. getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
  397. ) {
  398. console.log('输入的数字合法')
  399. getObj.value.pageNum = parseInt(getObj.value.pageNum)
  400. get()
  401. } else {
  402. //提示
  403. ElMessage({
  404. type: 'error',
  405. message: '请检查输入内容'
  406. })
  407. }
  408. } else {
  409. //提示
  410. ElMessage({
  411. type: 'error',
  412. message: '请检查输入内容'
  413. })
  414. }
  415. }
  416. const handlePageSizeChange = function (val) {
  417. getObj.value.pageSize = val
  418. get()
  419. }
  420. const handleCurrentChange = function (val) {
  421. getObj.value.pageNum = val
  422. get()
  423. }
  424. // 编辑====================================
  425. // 通过按钮
  426. const pass = function (row) {
  427. // 通过初始化
  428. passObj.value = row
  429. passObj.value.adminId = adminData.value.adminId
  430. passObj.value.auditId = row.auditId
  431. // passObj.value.status = 1
  432. passObj.value.rechargeId = row.rechargeId
  433. passObj.value.detailId = row.detailId
  434. passObj.value.jwcode = row.jwcode
  435. passObj.value.paidGold = row.paidGold
  436. passObj.value.freeGold = row.freeGold
  437. passObj.value.adminName = adminData.value.adminName
  438. console.log('通过对象', passObj.value)
  439. }
  440. // 通过确认
  441. const passConfirm = async function () {
  442. try {
  443. // 也许大概应该在点击确认时改变状态
  444. passObj.value.status = 1
  445. console.log('通过对象', passObj.value)
  446. // 发送POST请求
  447. // passObj.value.flag = 0;
  448. const result = await request({
  449. url: '/audit/audit/goldedit',
  450. data: passObj.value
  451. })
  452. // 将响应结果存储到响应式数据中
  453. console.log('请求成功', result)
  454. // 刷新表格数据
  455. get()
  456. //提示
  457. ElMessage({
  458. type: 'success',
  459. message: '通过成功!'
  460. })
  461. } catch (error) {
  462. console.error('请求失败', error);
  463. // 提示网络请求错误
  464. ElMessage({
  465. type: 'error',
  466. message: '网络请求出错,请检查网络连接!'
  467. });
  468. }
  469. }
  470. // 打开驳回弹出框
  471. const openRejectVisible = function () {
  472. rejectVisible.value = true
  473. }
  474. // 关闭驳回弹出框
  475. const closeRejectVisible = function () {
  476. rejectVisible.value = false
  477. }
  478. // 驳回按钮
  479. const reject = function (row) {
  480. // 驳回初始化
  481. rejectObj.value.adminId = adminData.value.adminId
  482. rejectObj.value.auditId = row.auditId
  483. rejectObj.value.status = 2
  484. rejectObj.value.reson = ''
  485. rejectObj.value.rechargeId = row.rechargeId
  486. rejectObj.value.detailId = row.detailId
  487. console.log('驳回对象', rejectObj.value)
  488. openRejectVisible()
  489. }
  490. // 驳回确认
  491. const rejectConfirm = async function () {
  492. Ref.value.validate(async (valid) => {
  493. if (valid) {
  494. try {
  495. console.log('驳回对象', rejectObj.value)
  496. // 发送POST请求
  497. const result = await request({
  498. url: '/audit/audit/goldedit',
  499. data: rejectObj.value
  500. })
  501. // 将响应结果存储到响应式数据中
  502. console.log('请求成功', result)
  503. // 刷新表格数据
  504. get()
  505. // 关闭弹出框
  506. closeRejectVisible()
  507. //提示
  508. ElMessage({
  509. type: 'success',
  510. message: '驳回成功!'
  511. })
  512. } catch (error) {
  513. console.log('请求失败', error)
  514. // 在这里可以处理错误逻辑,比如显示错误提示等
  515. }
  516. } else {
  517. //提示
  518. ElMessage({
  519. type: 'error',
  520. message: '请检查输入内容'
  521. })
  522. }
  523. })
  524. }
  525. // 表单验证
  526. const rules = reactive({
  527. reson: [{ required: true, message: '请输入驳回理由', trigger: 'blur' }]
  528. })
  529. // 挂载
  530. onMounted(async function () {
  531. await getAdminData()
  532. await getActivity()
  533. await get()
  534. await getArea()
  535. })
  536. // 新增排序字段和排序方式
  537. const sortField = ref('')
  538. const sortOrder = ref('')
  539. // 处理排序事件
  540. const handleSortChange = (column) => {
  541. console.log('排序字段:', column.prop)
  542. console.log('排序方式:', column.order)
  543. if (column.prop === 'rechargeGold') {
  544. sortField.value = 'recharge_gold'
  545. } else if (column.prop === 'freeGold') {
  546. sortField.value = 'free_gold'
  547. } else if (column.prop === 'rechargeTime') {
  548. sortField.value = 'recharge_time'
  549. } else if (column.prop === 'createTime') {
  550. sortField.value = 'create_time'
  551. } else if (column.prop === 'paidGold') {
  552. sortField.value = 'paid_gold'
  553. }else if (column.prop === 'auditTime') {
  554. sortField.value = 'audit_time'
  555. }
  556. sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
  557. get()
  558. }
  559. // 精网号去空格
  560. const trimJwCode = () => {
  561. if (rechargeVo.value.jwcode) {
  562. rechargeVo.value.jwcode = rechargeVo.value.jwcode.replace(/\s/g, '');
  563. }
  564. }
  565. </script>
  566. <template>
  567. <el-row>
  568. <el-col>
  569. <el-card style="margin-bottom: 20px">
  570. <el-row style="margin-bottom: 10px">
  571. <el-col :span="6">
  572. <div class="head-card-element">
  573. <el-text class="mx-1" size="large">精网号</el-text>
  574. <el-input v-model="rechargeVo.jwcode" placeholder="请输入精网号" style="width: 240px" clearable />
  575. </div>
  576. </el-col>
  577. <el-col :span="6">
  578. <div class="head-card-element">
  579. <el-text class="mx-1" size="large">活动名称</el-text>
  580. <el-select v-model="rechargeVo.activityId" placeholder="请选择活动名称" style="width: 240px"
  581. clearable>
  582. <el-option v-for="item in activity" :key="item.activityId" :label="item.activityName"
  583. :value="item.activityId" />
  584. </el-select>
  585. </div>
  586. </el-col>
  587. <el-col :span="6">
  588. <div class="head-card-element">
  589. <el-text class="mx-1" size="large">支付方式</el-text>
  590. <el-select v-model="rechargeVo.payWay" placeholder="请选择支付方式" style="width: 240px" clearable>
  591. <el-option v-for="item in payWay" :key="item.value" :label="item.label" :value="item.value" />
  592. </el-select>
  593. </div>
  594. </el-col>
  595. <el-col :span="6">
  596. <div class="head-card-element" v-if="adminData.area == '总部'">
  597. <el-text class="mx-1" size="large">所属地区</el-text>
  598. <el-select v-model="rechargeVo.area" placeholder="请选择所属地区" style="width: 240px" clearable>
  599. <el-option v-for="item in area" :key="item" :label="item" :value="item" />
  600. </el-select>
  601. </div>
  602. </el-col>
  603. </el-row>
  604. <el-row>
  605. <el-col :span="16">
  606. <div class="time-controls">
  607. <div class="time-group">
  608. <el-text class="mx-1" size="large">充值时间</el-text>
  609. <el-date-picker
  610. v-model="getTime"
  611. type="datetimerange"
  612. range-separator="至"
  613. start-placeholder="起始时间"
  614. end-placeholder="结束时间"
  615. style="width: 400px"
  616. />
  617. <el-button @click="getToday()" style="margin-left: 10px"> </el-button>
  618. <el-button @click="getYesterday()" style="margin-left: 10px"> </el-button>
  619. <el-button @click="get7Days()" style="margin-left: 10px"> 近7天 </el-button>
  620. </div>
  621. </div>
  622. </el-col>
  623. <el-col :span="8">
  624. <el-button @click="reset()" type="success" style="margin-right: 10px">重置</el-button>
  625. <el-button type="primary" @click="search()">查询</el-button>
  626. </el-col>
  627. </el-row>
  628. <el-row>
  629. <el-col :span="21">
  630. <div style="margin-top: 10px">
  631. <el-text class="mx-1" size="large">请选择您想看到的数据</el-text>
  632. <el-select v-model="selectedColumns" multiple placeholder="请选择您想看到的数据" size="large" style="width: 800px">
  633. <el-option v-for="item in columnOptions" :key="item.prop" :label="item.label" :value="item.prop" />
  634. </el-select>
  635. </div>
  636. </el-col>
  637. </el-row>
  638. </el-card>
  639. </el-col>
  640. </el-row>
  641. <el-row>
  642. <el-col>
  643. <el-card>
  644. <el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
  645. <el-tab-pane label="全部" name="all"></el-tab-pane>
  646. <el-tab-pane label="待审核" name="wait"></el-tab-pane>
  647. <el-tab-pane label="已通过" name="pass"></el-tab-pane>
  648. <el-tab-pane label="已驳回" name="reject"></el-tab-pane>
  649. <div>
  650. 总条数{{ trueCount }}总金币数{{
  651. formattedTrueGold
  652. }}金币永久金币{{ formattedTrueRGold }}金币免费金币{{ formattedTrueFGold }}金币
  653. </div>
  654. </el-tabs>
  655. <div style="height: 540px; overflow-y: auto">
  656. <el-table :data="tableData" style="width: 100%" height="540px" @sort-change="handleSortChange" :row-style="{ height: '50px' }">
  657. <el-table-column type="index" label="序号" width="100px" fixed="left">
  658. <template #default="scope">
  659. <span>{{
  660. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  661. }}</span>
  662. </template>
  663. </el-table-column>
  664. <!-- 动态列 -->
  665. <template v-for="col in columnOptions" :key="col.prop">
  666. <el-table-column v-if="selectedColumns.includes(col.prop)" :prop="col.prop" :label="col.label"
  667. :width="col.width" :sortable="col.sortable ? 'custom' : false"
  668. :show-overflow-tooltip="true" >
  669. <template #default="scope">
  670. <!-- 特殊列模板 -->
  671. <template v-if="col.prop === 'rechargeTime'">
  672. {{ moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss') }}
  673. </template>
  674. <template v-else-if="col.prop === 'createTime'">
  675. {{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
  676. </template>
  677. <template v-else-if="col.prop === 'auditTime'">
  678. {{ scope.row.auditTime ? moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') : '----' }}
  679. </template>
  680. <template v-else-if="col.prop === 'remark'">
  681. <span>{{ scope.row[col.prop] }}</span>
  682. </template>
  683. <template v-else-if="col.prop === 'rechargeVoucher'">
  684. <el-image :src="scope.row.rechargeVoucher" style="width: 50px; height: 50px" />
  685. </template>
  686. <template v-else-if="col.prop === 'status'">
  687. <div class="status">
  688. <span :class="{
  689. 'green-dot': scope.row.status === 1,
  690. 'grey-dot': scope.row.status === 0,
  691. 'red-dot': scope.row.status === 2
  692. }"></span>
  693. <span>{{
  694. scope.row.status === 1 ? '已通过' :
  695. scope.row.status === 0 ? '待审核' : '已驳回'
  696. }}</span>
  697. </div>
  698. </template>
  699. <template v-else-if="['paidGold', 'freeGold'].includes(col.prop)">
  700. {{ scope.row[col.prop] / 100 }}
  701. </template>
  702. <span v-else>
  703. {{ scope.row[col.prop] }}
  704. </span>
  705. </template>
  706. </el-table-column>
  707. </template>
  708. <el-table-column fixed="right" prop="operation" label="操作" width="150px">
  709. <template #default="scope">
  710. <div class="operation">
  711. <el-popconfirm title="确定要通过此条记录吗?" @confirm="passConfirm">
  712. <template #reference>
  713. <el-button :disabled="scope.row.status === 1 || scope.row.status === 2
  714. ? true
  715. : false
  716. " type="primary" text @click="pass(scope.row)">
  717. 通过
  718. </el-button>
  719. </template>
  720. <template #actions="{ confirm, cancel }">
  721. <el-button size="small" @click="cancel">取消</el-button>
  722. <el-button type="primary" size="small" @click="confirm">
  723. 确定
  724. </el-button>
  725. </template>
  726. </el-popconfirm>
  727. <el-button :disabled="scope.row.status === 1 || scope.row.status === 2
  728. ? true
  729. : false
  730. " type="primary" text @click="reject(scope.row)">
  731. 驳回
  732. </el-button>
  733. </div>
  734. </template>
  735. </el-table-column>
  736. </el-table>
  737. </div>
  738. <!-- 分页 -->
  739. <div class="pagination">
  740. <el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  741. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
  742. @current-change="handleCurrentChange"></el-pagination>
  743. </div>
  744. </el-card>
  745. </el-col>
  746. </el-row>
  747. <!-- 驳回弹出框 -->
  748. <el-dialog v-model="rejectVisible" title="驳回理由" width="500" :before-close="closeRejectVisible">
  749. <template #footer>
  750. <el-form :model="rejectObj" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px">
  751. <el-form-item prop="reson" label="驳回理由:">
  752. <el-input v-model="rejectObj.reson" maxlength="150" show-word-limit style="width: 350px" type="textarea"
  753. placeholder="请输入内容" />
  754. </el-form-item>
  755. </el-form>
  756. <div class="dialog-footer">
  757. <el-button @click="closeRejectVisible()">取消</el-button>
  758. <el-button type="primary" @click="rejectConfirm()"> 确定 </el-button>
  759. </div>
  760. </template>
  761. </el-dialog>
  762. </template>
  763. <style scoped>
  764. .pagination {
  765. display: flex;
  766. }
  767. .operation {
  768. display: flex;
  769. }
  770. .green-dot {
  771. background-color: #67C23A;
  772. }
  773. .grey-dot {
  774. background-color: #909399;
  775. }
  776. .red-dot {
  777. background-color: #F56C6C;
  778. }
  779. .time-controls {
  780. display: flex;
  781. align-items: center;
  782. }
  783. .time-group {
  784. display: flex;
  785. align-items: center;
  786. gap: 10px;
  787. }
  788. .quick-buttons {
  789. display: flex;
  790. align-items: center;
  791. }
  792. .status {
  793. display: flex;
  794. align-items: center; /* 确保子元素垂直居中对齐 */
  795. gap: 6px; /* 设置圆点和文字之间的间距 */
  796. }
  797. .green-dot, .grey-dot, .red-dot {
  798. display: inline-block;
  799. width: 8px;
  800. height: 8px;
  801. border-radius: 50%;
  802. flex-shrink: 0; /* 防止圆点在空间不足时缩小 */
  803. margin: 0; /* 移除原有的 margin-right */
  804. }
  805. /* 备注列样式 */
  806. .remark-cell {
  807. display: block;
  808. width: 100%;
  809. overflow: hidden;
  810. text-overflow: ellipsis;
  811. white-space: nowrap;
  812. }
  813. /* 设置单元格内容溢出隐藏 */
  814. .el-table .el-table__cell {
  815. overflow: hidden;
  816. text-overflow: ellipsis;
  817. white-space: nowrap;
  818. }
  819. </style>