Points.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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.childId"
  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%">
  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. data() {
  90. return {
  91. loading: false,
  92. tableData: [],
  93. searchForm: {
  94. childId: '',
  95. type: ''
  96. },
  97. pagination: {
  98. current: 1,
  99. size: 10,
  100. total: 0
  101. }
  102. }
  103. },
  104. mounted() {
  105. this.loadPointsLogs()
  106. },
  107. methods: {
  108. async loadPointsLogs() {
  109. this.loading = true
  110. try {
  111. const params = {
  112. page: this.pagination.current,
  113. size: this.pagination.size,
  114. ...this.searchForm
  115. }
  116. const res = await getPointsLogs(params)
  117. this.tableData = res.data.records || res.data || []
  118. this.pagination.total = res.data.total || this.tableData.length
  119. } catch (error) {
  120. this.$message.error(error.message || '加载积分流水失败')
  121. } finally {
  122. this.loading = false
  123. }
  124. },
  125. handleSearch() {
  126. this.pagination.current = 1
  127. this.loadPointsLogs()
  128. },
  129. handleReset() {
  130. this.searchForm = {
  131. childId: '',
  132. type: ''
  133. }
  134. this.handleSearch()
  135. },
  136. handleRefresh() {
  137. this.loadPointsLogs()
  138. },
  139. handleSizeChange(val) {
  140. this.pagination.size = val
  141. this.loadPointsLogs()
  142. },
  143. handleCurrentChange(val) {
  144. this.pagination.current = val
  145. this.loadPointsLogs()
  146. },
  147. getTypeTag(type) {
  148. const tags = {
  149. earn: 'success',
  150. spend: 'warning',
  151. bonus: 'success',
  152. penalty: 'danger',
  153. adjust: 'info',
  154. reset: 'warning',
  155. refund: 'success'
  156. }
  157. return tags[type] || 'info'
  158. },
  159. getTypeText(type) {
  160. const texts = {
  161. earn: '获得',
  162. spend: '消耗',
  163. bonus: '奖励',
  164. penalty: '扣罚',
  165. adjust: '调整',
  166. reset: '清零',
  167. refund: '退还'
  168. }
  169. return texts[type] || type
  170. },
  171. formatDate(dateStr) {
  172. if (!dateStr) return '-'
  173. const date = new Date(dateStr)
  174. return date.toLocaleString('zh-CN')
  175. }
  176. }
  177. }
  178. </script>
  179. <style scoped>
  180. .page-container {
  181. padding: 20px;
  182. }
  183. </style>