CashDiscountGrant.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <div class="cash-discount-grant">
  3. <el-card>
  4. <template #header>
  5. <div class="search-section">
  6. <el-form :model="searchForm" label-width="100px">
  7. <el-row :gutter="16">
  8. <el-col :span="8">
  9. <el-form-item label="客户号:">
  10. <el-input v-model="searchForm.customerId" placeholder="请输入客户号" clearable></el-input>
  11. </el-form-item>
  12. </el-col>
  13. <el-col :span="8">
  14. <el-form-item label="立减金类型:">
  15. <el-select v-model="searchForm.discountType" placeholder="请选择立减金类型" clearable style="width: 100%;">
  16. <el-option v-for="item in discountTypeOptions" :key="item" :label="item" :value="item"></el-option>
  17. </el-select>
  18. </el-form-item>
  19. </el-col>
  20. <el-col :span="8">
  21. <el-form-item label="发放时间:">
  22. <el-date-picker
  23. v-model="searchForm.grantDateRange"
  24. type="daterange"
  25. range-separator="至"
  26. start-placeholder="开始日期"
  27. end-placeholder="结束日期"
  28. value-format="yyyy-MM-dd"
  29. style="width: 100%;"
  30. ></el-date-picker>
  31. </el-form-item>
  32. </el-col>
  33. </el-row>
  34. <el-row :gutter="16">
  35. <el-col :span="8">
  36. <el-form-item label="是否领取:">
  37. <el-select v-model="searchForm.claimed" placeholder="请选择" clearable style="width: 100%;">
  38. <el-option label="是" value="是"></el-option>
  39. <el-option label="否" value="否"></el-option>
  40. </el-select>
  41. </el-form-item>
  42. </el-col>
  43. <el-col :span="8">
  44. <el-form-item label="是否使用:">
  45. <el-select v-model="searchForm.used" placeholder="请选择" clearable style="width: 100%;">
  46. <el-option label="是" value="是"></el-option>
  47. <el-option label="否" value="否"></el-option>
  48. </el-select>
  49. </el-form-item>
  50. </el-col>
  51. <el-col :span="8" class="action-col">
  52. <el-button type="primary" @click="handleSearch">查询</el-button>
  53. <el-button @click="handleReset">重置</el-button>
  54. <el-button type="success" @click="handleExport"><el-icon><Download /></el-icon>导出</el-button>
  55. </el-col>
  56. </el-row>
  57. </el-form>
  58. </div>
  59. </template>
  60. <el-table :data="pagedData" stripe border style="width: 100%;" v-loading="loading">
  61. <el-table-column prop="grantTime" label="发放时间" width="170"></el-table-column>
  62. <el-table-column prop="customerId" label="客户号" width="160"></el-table-column>
  63. <el-table-column prop="discountType" label="立减金类型" width="130"></el-table-column>
  64. <el-table-column prop="binRestriction" label="是否有bin卡限制" width="140">
  65. <template #default="scope">
  66. <el-tag :type="scope.row.binRestriction === '是' ? 'warning' : 'info'" size="small">{{ scope.row.binRestriction }}</el-tag>
  67. </template>
  68. </el-table-column>
  69. <el-table-column prop="grantAmount" label="发放金额" width="110">
  70. <template #default="scope">
  71. <span>¥{{ scope.row.grantAmount }}</span>
  72. </template>
  73. </el-table-column>
  74. <el-table-column prop="grantReason" label="发放事由" min-width="160" show-overflow-tooltip></el-table-column>
  75. <el-table-column prop="claimed" label="是否领取" width="100">
  76. <template #default="scope">
  77. <el-tag :type="scope.row.claimed === '是' ? 'success' : 'danger'" size="small">{{ scope.row.claimed }}</el-tag>
  78. </template>
  79. </el-table-column>
  80. <el-table-column prop="claimTime" label="领取时间" width="160"></el-table-column>
  81. <el-table-column prop="validPeriod" label="使用有效期" width="220"></el-table-column>
  82. <el-table-column prop="used" label="是否使用" width="100">
  83. <template #default="scope">
  84. <el-tag :type="scope.row.used === '是' ? 'success' : 'danger'" size="small">{{ scope.row.used }}</el-tag>
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="useTime" label="使用时间" width="160"></el-table-column>
  88. </el-table>
  89. <el-pagination
  90. style="margin-top: 20px; text-align: right;"
  91. @current-change="handlePageChange"
  92. :current-page="currentPage"
  93. :page-size="pageSize"
  94. layout="total, prev, pager, next, jumper"
  95. :total="filteredData.length"
  96. ></el-pagination>
  97. </el-card>
  98. </div>
  99. </template>
  100. <script>
  101. import { ElMessage } from 'element-plus'
  102. const DISCOUNT_TYPES = ['借记卡', '信用卡']
  103. const GRANT_REASONS = ['新开户礼遇', '月度消费达标奖励', '生日专属福利', '双十一营销活动', '服务补偿', '升级Premier礼遇', '推荐好友奖励', '季度活跃奖励']
  104. function pad(n) { return String(n).padStart(2, '0') }
  105. function randomDateTime(baseDate, offsetDays) {
  106. const d = new Date(baseDate)
  107. d.setDate(d.getDate() - Math.floor(Math.random() * offsetDays))
  108. d.setHours(Math.floor(Math.random() * 14 + 8), Math.floor(Math.random() * 60), Math.floor(Math.random() * 60))
  109. return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
  110. }
  111. function generateMockData() {
  112. const list = []
  113. const base = new Date(2026, 4, 15)
  114. const amounts = [10, 20, 30, 50, 88, 100, 128, 200]
  115. for (let i = 1; i <= 65; i++) {
  116. const grantTime = randomDateTime(base, 90)
  117. const grantDate = grantTime.slice(0, 10)
  118. const validEnd = new Date(grantDate)
  119. validEnd.setDate(validEnd.getDate() + 30 + Math.floor(Math.random() * 60))
  120. const validEndStr = `${validEnd.getFullYear()}-${pad(validEnd.getMonth() + 1)}-${pad(validEnd.getDate())}`
  121. const claimed = Math.random() > 0.25 ? '是' : '否'
  122. const used = claimed === '是' && Math.random() > 0.35 ? '是' : '否'
  123. list.push({
  124. id: i,
  125. customerId: 'CUST' + String(100000 + Math.floor(Math.random() * 900000)),
  126. discountType: DISCOUNT_TYPES[Math.floor(Math.random() * DISCOUNT_TYPES.length)],
  127. binRestriction: Math.random() > 0.5 ? '是' : '否',
  128. grantTime: grantTime,
  129. grantDate: grantDate,
  130. grantAmount: amounts[Math.floor(Math.random() * amounts.length)],
  131. grantReason: GRANT_REASONS[Math.floor(Math.random() * GRANT_REASONS.length)],
  132. validPeriod: claimed === '是' ? `${grantDate} 至 ${validEndStr}` : '-',
  133. claimed: claimed,
  134. claimTime: claimed === '是' ? randomDateTime(base, 60) : '-',
  135. used: used,
  136. useTime: used === '是' ? randomDateTime(base, 30) : '-'
  137. })
  138. }
  139. list.sort((a, b) => b.grantTime.localeCompare(a.grantTime))
  140. return list
  141. }
  142. export default {
  143. name: 'CashDiscountGrant',
  144. data() {
  145. return {
  146. searchForm: {
  147. customerId: '',
  148. discountType: '',
  149. grantDateRange: [],
  150. claimed: '',
  151. used: ''
  152. },
  153. loading: false,
  154. currentPage: 1,
  155. pageSize: 10,
  156. tableData: generateMockData(),
  157. discountTypeOptions: DISCOUNT_TYPES
  158. }
  159. },
  160. computed: {
  161. filteredData() {
  162. let list = this.tableData
  163. const customerId = this.searchForm.customerId.trim()
  164. if (customerId) {
  165. list = list.filter(item => item.customerId.includes(customerId))
  166. }
  167. if (this.searchForm.discountType) {
  168. list = list.filter(item => item.discountType === this.searchForm.discountType)
  169. }
  170. if (this.searchForm.grantDateRange && this.searchForm.grantDateRange.length === 2) {
  171. const [start, end] = this.searchForm.grantDateRange
  172. list = list.filter(item => item.grantDate >= start && item.grantDate <= end)
  173. }
  174. if (this.searchForm.claimed) {
  175. list = list.filter(item => item.claimed === this.searchForm.claimed)
  176. }
  177. if (this.searchForm.used) {
  178. list = list.filter(item => item.used === this.searchForm.used)
  179. }
  180. return list
  181. },
  182. pagedData() {
  183. const start = (this.currentPage - 1) * this.pageSize
  184. return this.filteredData.slice(start, start + this.pageSize)
  185. }
  186. },
  187. methods: {
  188. handleSearch() {
  189. this.currentPage = 1
  190. },
  191. handleReset() {
  192. this.searchForm = {
  193. customerId: '',
  194. discountType: '',
  195. grantDateRange: [],
  196. claimed: '',
  197. used: ''
  198. }
  199. this.currentPage = 1
  200. },
  201. handlePageChange(page) {
  202. this.currentPage = page
  203. },
  204. handleExport() {
  205. ElMessage.success('导出任务已提交,请稍后在下载中心查看')
  206. }
  207. }
  208. }
  209. </script>
  210. <style scoped>
  211. .search-section {
  212. display: flex;
  213. flex-direction: column;
  214. align-items: stretch;
  215. }
  216. .action-col {
  217. display: flex;
  218. align-items: center;
  219. gap: 8px;
  220. }
  221. </style>