Points.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <div class="page-container">
  3. <el-card>
  4. <div slot="header">
  5. <span>积分管理</span>
  6. <el-button
  7. type="primary"
  8. size="small"
  9. style="float: right"
  10. @click="handleRefresh"
  11. :loading="loading"
  12. >
  13. 刷新
  14. </el-button>
  15. </div>
  16. <!-- 搜索筛选 -->
  17. <el-form :inline="true" :model="searchForm" style="margin-bottom: 20px">
  18. <el-form-item label="孩子ID">
  19. <el-input
  20. v-model="searchForm.memberId"
  21. placeholder="请输入孩子ID"
  22. clearable
  23. @keyup.enter.native="handleSearch"
  24. ></el-input>
  25. </el-form-item>
  26. <el-form-item label="类型">
  27. <el-select v-model="searchForm.type" placeholder="全部类型" clearable @change="handleSearch">
  28. <el-option label="获得" value="earn"></el-option>
  29. <el-option label="消耗" value="spend"></el-option>
  30. <el-option label="奖励" value="bonus"></el-option>
  31. <el-option label="扣罚" value="penalty"></el-option>
  32. <el-option label="调整" value="adjust"></el-option>
  33. <el-option label="退还" value="refund"></el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item>
  37. <el-button type="primary" @click="handleSearch">搜索</el-button>
  38. <el-button @click="handleReset">重置</el-button>
  39. </el-form-item>
  40. </el-form>
  41. <!-- 积分流水列表 -->
  42. <el-table :data="tableData" border v-loading="loading" style="width: 100%" :max-height="tableHeight">
  43. <el-table-column prop="id" label="ID" width="80"></el-table-column>
  44. <el-table-column prop="childId" label="孩子ID" width="100"></el-table-column>
  45. <el-table-column prop="amount" label="积分变动" width="120">
  46. <template slot-scope="scope">
  47. <span :style="{ color: scope.row.amount > 0 ? '#67C23A' : '#F56C6C', fontWeight: 'bold' }">
  48. {{ scope.row.amount > 0 ? '+' : '' }}{{ scope.row.amount }}
  49. </span>
  50. </template>
  51. </el-table-column>
  52. <el-table-column prop="type" label="类型" width="100">
  53. <template slot-scope="scope">
  54. <el-tag :type="getTypeTag(scope.row.type)" size="small">
  55. {{ getTypeText(scope.row.type) }}
  56. </el-tag>
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="description" label="描述" min-width="200"></el-table-column>
  60. <el-table-column prop="taskId" label="任务ID" width="100">
  61. <template slot-scope="scope">
  62. <span>{{ scope.row.taskId || '-' }}</span>
  63. </template>
  64. </el-table-column>
  65. <el-table-column prop="createdAt" label="时间" width="180">
  66. <template slot-scope="scope">
  67. {{ formatDate(scope.row.createdAt) }}
  68. </template>
  69. </el-table-column>
  70. </el-table>
  71. <!-- 分页 -->
  72. <el-pagination
  73. style="margin-top: 20px; text-align: right"
  74. @size-change="handleSizeChange"
  75. @current-change="handleCurrentChange"
  76. :current-page="pagination.current"
  77. :page-sizes="[10, 20, 50, 100]"
  78. :page-size="pagination.size"
  79. :total="pagination.total"
  80. layout="total, sizes, prev, pager, next, jumper"
  81. ></el-pagination>
  82. </el-card>
  83. </div>
  84. </template>
  85. <script>
  86. import { getPointsLogs } from '@/api/admin'
  87. export default {
  88. name: 'Points',
  89. computed: {
  90. tableHeight() {
  91. return window.innerHeight - 340
  92. }
  93. },
  94. data() {
  95. return {
  96. loading: false,
  97. tableData: [],
  98. searchForm: {
  99. memberId: '',
  100. type: ''
  101. },
  102. pagination: {
  103. current: 1,
  104. size: 10,
  105. total: 0
  106. }
  107. }
  108. },
  109. mounted() {
  110. this.loadPointsLogs()
  111. },
  112. methods: {
  113. async loadPointsLogs() {
  114. this.loading = true
  115. try {
  116. const params = {
  117. page: this.pagination.current,
  118. size: this.pagination.size,
  119. ...this.searchForm
  120. }
  121. const res = await getPointsLogs(params)
  122. this.tableData = res.data.records || res.data || []
  123. this.pagination.total = res.data.total || this.tableData.length
  124. } catch (error) {
  125. this.$message.error(error.message || '加载积分流水失败')
  126. } finally {
  127. this.loading = false
  128. }
  129. },
  130. handleSearch() {
  131. this.pagination.current = 1
  132. this.loadPointsLogs()
  133. },
  134. handleReset() {
  135. this.searchForm = {
  136. memberId: '',
  137. type: ''
  138. }
  139. this.handleSearch()
  140. },
  141. handleRefresh() {
  142. this.loadPointsLogs()
  143. },
  144. handleSizeChange(val) {
  145. this.pagination.size = val
  146. this.pagination.current = 1
  147. this.loadPointsLogs()
  148. },
  149. handleCurrentChange(val) {
  150. this.pagination.current = val
  151. this.loadPointsLogs()
  152. },
  153. getTypeTag(type) {
  154. const tags = {
  155. earn: 'success',
  156. spend: 'warning',
  157. bonus: 'success',
  158. penalty: 'danger',
  159. adjust: 'info',
  160. reset: 'warning',
  161. refund: 'success'
  162. }
  163. return tags[type] || 'info'
  164. },
  165. getTypeText(type) {
  166. const texts = {
  167. earn: '获得',
  168. spend: '消耗',
  169. bonus: '奖励',
  170. penalty: '扣罚',
  171. adjust: '调整',
  172. reset: '清零',
  173. refund: '退还'
  174. }
  175. return texts[type] || type
  176. },
  177. formatDate(dateStr) {
  178. if (!dateStr) return '-'
  179. const date = new Date(dateStr)
  180. return date.toLocaleString('zh-CN')
  181. }
  182. }
  183. }
  184. </script>
  185. <style scoped>
  186. </style>