CfValueManage.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <template>
  2. <div class="cf-value admin-page">
  3. <div class="header">
  4. <h2>CF值(平台积分)管理</h2>
  5. <div class="filters">
  6. <el-input v-model="searchUserId" placeholder="用户ID搜索" style="width: 200px;" clearable @keyup.enter.native="searchBalance" />
  7. <el-button type="primary" @click="searchBalance">查询余额</el-button>
  8. </div>
  9. </div>
  10. <el-tabs v-model="activeTab">
  11. <el-tab-pane label="余额列表" name="balances">
  12. <el-table :data="balanceList" v-loading="loadingBalance" border stripe>
  13. <el-table-column prop="id" label="ID" width="70" />
  14. <el-table-column prop="userId" label="用户ID" width="100" />
  15. <el-table-column prop="familyId" label="家庭ID" width="100" />
  16. <el-table-column prop="totalEarned" label="累计获得" width="100" />
  17. <el-table-column prop="available" label="可用" width="80" />
  18. <el-table-column prop="frozen" label="冻结" width="80" />
  19. <el-table-column prop="withdrawn" label="已提现" width="80" />
  20. <el-table-column prop="exchanged" label="已兑换" width="80" />
  21. <el-table-column label="操作" width="100">
  22. <template slot-scope="{ row }">
  23. <el-button type="text" size="small" @click="viewLogs(row.userId)">流水</el-button>
  24. </template>
  25. </el-table-column>
  26. </el-table>
  27. <el-pagination v-if="balanceTotal > 0" :current-page="balancePage" :page-size="balanceSize" :total="balanceTotal" layout="prev, pager, next" @current-change="pageBalances" />
  28. </el-tab-pane>
  29. <el-tab-pane label="流水查询" name="logs">
  30. <div class="filters">
  31. <el-input v-model="logUserId" placeholder="用户ID" style="width: 200px;" clearable @keyup.enter.native="searchLogs" />
  32. <el-button type="primary" @click="searchLogs">查询流水</el-button>
  33. </div>
  34. <el-table :data="logList" v-loading="loadingLog" border stripe>
  35. <el-table-column prop="id" label="ID" width="70" />
  36. <el-table-column prop="userId" label="用户ID" width="80" />
  37. <el-table-column prop="type" label="类型" width="100">
  38. <template slot-scope="{ row }">
  39. <el-tag :type="typeTag(row.type)" size="small">{{ row.type }}</el-tag>
  40. </template>
  41. </el-table-column>
  42. <el-table-column prop="amount" label="数量" width="80" />
  43. <el-table-column prop="balanceAfter" label="变动后余额" width="100" />
  44. <el-table-column prop="refType" label="来源" width="130" />
  45. <el-table-column prop="refId" label="关联ID" width="80" />
  46. <el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
  47. <el-table-column prop="createdAt" label="时间" width="160" />
  48. </el-table>
  49. <el-pagination v-if="logTotal > 0" :current-page="logPage" :page-size="logSize" :total="logTotal" layout="prev, pager, next" @current-change="pageLogs" />
  50. </el-tab-pane>
  51. </el-tabs>
  52. </div>
  53. </template>
  54. <script>
  55. import { getCfValueBalance, getCfValueLogs, getCfValueAllBalances } from '@/api/admin'
  56. export default {
  57. data() {
  58. return {
  59. activeTab: 'balances',
  60. searchUserId: '',
  61. logUserId: '',
  62. // Balances
  63. balanceList: [],
  64. loadingBalance: false,
  65. balancePage: 1,
  66. balanceSize: 20,
  67. balanceTotal: 0,
  68. // Logs
  69. logList: [],
  70. loadingLog: false,
  71. logPage: 1,
  72. logSize: 20,
  73. logTotal: 0
  74. }
  75. },
  76. mounted() {
  77. this.loadBalances()
  78. },
  79. methods: {
  80. typeTag(type) {
  81. const map = { earn: 'success', spend: 'warning', freeze: 'info', unfreeze: 'info', withdraw: 'primary' }
  82. return map[type] || 'info'
  83. },
  84. loadBalances() {
  85. this.loadingBalance = true
  86. getCfValueAllBalances({ page: this.balancePage, size: this.balanceSize }).then(res => {
  87. if (res.code === 200) {
  88. this.balanceList = res.data.records || []
  89. this.balanceTotal = res.data.total || 0
  90. }
  91. }).finally(() => { this.loadingBalance = false })
  92. },
  93. pageBalances(page) {
  94. this.balancePage = page
  95. this.loadBalances()
  96. },
  97. searchBalance() {
  98. if (!this.searchUserId) { this.loadBalances(); return }
  99. this.loadingBalance = true
  100. getCfValueBalance({ userId: this.searchUserId }).then(res => {
  101. if (res.code === 200) {
  102. this.balanceList = [res.data]
  103. this.balanceTotal = 1
  104. }
  105. }).finally(() => { this.loadingBalance = false })
  106. },
  107. viewLogs(userId) {
  108. this.logUserId = String(userId)
  109. this.activeTab = 'logs'
  110. this.searchLogs()
  111. },
  112. searchLogs() {
  113. if (!this.logUserId) return
  114. this.loadingLog = true
  115. this.logPage = 1
  116. getCfValueLogs({ userId: this.logUserId, page: 1, size: this.logSize }).then(res => {
  117. if (res.code === 200) {
  118. this.logList = res.data.records || []
  119. this.logTotal = res.data.total || 0
  120. }
  121. }).finally(() => { this.loadingLog = false })
  122. },
  123. pageLogs(page) {
  124. this.logPage = page
  125. this.searchLogs()
  126. }
  127. }
  128. }
  129. </script>