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

847 lines
26 KiB

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