EquityGrantCampaign.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div class="equity-grant-campaign">
  3. <el-card>
  4. <template #header>
  5. <div class="search-section">
  6. <div class="search-row">
  7. <el-form :model="searchForm" label-width="100px" inline>
  8. <el-form-item label="发放计划名称:">
  9. <el-input v-model="searchForm.name" placeholder="关键字" clearable style="width:220px" />
  10. </el-form-item>
  11. <el-form-item label="发放计划时间:">
  12. <el-date-picker
  13. v-model="searchForm.dateRange"
  14. type="daterange"
  15. range-separator="至"
  16. start-placeholder="开始日期"
  17. end-placeholder="结束日期"
  18. value-format="YYYY-MM-DD"
  19. style="width:360px"
  20. />
  21. </el-form-item>
  22. <el-form-item label="状态:">
  23. <el-select v-model="searchForm.status" placeholder="全部" clearable style="width:140px">
  24. <el-option label="未开始" value="未开始" />
  25. <el-option label="进行中" value="进行中" />
  26. <el-option label="已结束" value="已结束" />
  27. </el-select>
  28. </el-form-item>
  29. <div class="button-group">
  30. <el-button type="primary" @click="handleSearch">查询</el-button>
  31. <el-button @click="handleReset">重置</el-button>
  32. </div>
  33. </el-form>
  34. </div>
  35. <div class="action-row">
  36. <el-button type="primary" @click="handleCreate">
  37. <el-icon><Plus /></el-icon>新建发放计划
  38. </el-button>
  39. </div>
  40. </div>
  41. </template>
  42. <el-table :data="filteredData" stripe border style="width:100%">
  43. <el-table-column label="操作" width="280" fixed="left">
  44. <template #default="scope">
  45. <el-button type="text" size="small" @click="handleView(scope.row)">查看</el-button>
  46. <el-button
  47. v-if="statusLabel(scope.row) !== '进行中'"
  48. type="text"
  49. size="small"
  50. @click="handleEdit(scope.row)"
  51. >编辑</el-button>
  52. <el-button
  53. type="text"
  54. size="small"
  55. @click="handleCopy(scope.row)"
  56. >复制</el-button>
  57. <el-button
  58. v-if="statusLabel(scope.row) === '进行中'"
  59. type="text"
  60. size="small"
  61. style="color:#E6A23C"
  62. @click="handleEnd(scope.row)"
  63. >结束</el-button>
  64. <el-button
  65. v-if="statusLabel(scope.row) !== '进行中'"
  66. type="text"
  67. size="small"
  68. style="color:#F56C6C"
  69. @click="handleDelete(scope.row)"
  70. >删除</el-button>
  71. </template>
  72. </el-table-column>
  73. <el-table-column prop="id" label="发放计划 ID" width="160" align="center" />
  74. <el-table-column prop="name" label="发放计划名称" min-width="200" show-overflow-tooltip />
  75. <el-table-column prop="startTime" label="开始时间" width="170" align="center" />
  76. <el-table-column prop="endTime" label="结束时间" width="170" align="center" />
  77. <el-table-column label="状态" width="100" align="center">
  78. <template #default="scope">
  79. <el-tag :type="statusTag(scope.row)" size="small">{{ statusLabel(scope.row) }}</el-tag>
  80. </template>
  81. </el-table-column>
  82. <el-table-column label="获取方式" width="110" align="center">
  83. <template #default="scope">
  84. <el-tag :type="scope.row.grantMode === 'direct' ? 'warning' : 'success'" size="small">
  85. {{ scope.row.grantMode === 'direct' ? '直接发放' : '用户领取' }}
  86. </el-tag>
  87. </template>
  88. </el-table-column>
  89. <el-table-column label="权益数量" width="150" align="center">
  90. <template #default="scope">
  91. {{ grantSummary(scope.row) }}
  92. </template>
  93. </el-table-column>
  94. <el-table-column label="权益有效期" min-width="200" align="center">
  95. <template #default="scope">
  96. {{ validitySummary(scope.row.validity) }}
  97. </template>
  98. </el-table-column>
  99. <el-table-column prop="createTime" label="创建时间" width="170" align="center" />
  100. </el-table>
  101. </el-card>
  102. </div>
  103. </template>
  104. <script>
  105. import { ElMessage, ElMessageBox } from 'element-plus'
  106. import request from '@/utils/request'
  107. const grantCycleLabelMap = { total: '整个周期', monthly: '每月', quarterly: '每季度', yearly: '每年' }
  108. export default {
  109. name: 'EquityGrantCampaign',
  110. data() {
  111. return {
  112. searchForm: { name: '', dateRange: [], status: '' },
  113. tableData: []
  114. }
  115. },
  116. computed: {
  117. filteredData() {
  118. if (!this.searchForm.status) return this.tableData
  119. return this.tableData.filter(r => this.statusLabel(r) === this.searchForm.status)
  120. }
  121. },
  122. created() {
  123. this.fetchList()
  124. },
  125. activated() {
  126. this.fetchList()
  127. },
  128. watch: {
  129. $route(to) {
  130. if (to.path === '/customization/hsbc/equity-grant-campaign') {
  131. this.fetchList()
  132. }
  133. }
  134. },
  135. methods: {
  136. async fetchList() {
  137. const params = { name: this.searchForm.name }
  138. if (this.searchForm.dateRange && this.searchForm.dateRange.length === 2) {
  139. params.startDate = this.searchForm.dateRange[0]
  140. params.endDate = this.searchForm.dateRange[1]
  141. }
  142. const res = await request.get('/api/equity-grant-campaign/list', { params })
  143. this.tableData = res.data || []
  144. },
  145. handleSearch() { this.fetchList() },
  146. handleReset() {
  147. this.searchForm = { name: '', dateRange: [], status: '' }
  148. this.fetchList()
  149. },
  150. handleCreate() {
  151. this.$router.push('/customization/hsbc/equity-grant-campaign/add')
  152. },
  153. handleEdit(row) {
  154. this.$router.push(`/customization/hsbc/equity-grant-campaign/edit/${row.id}`)
  155. },
  156. handleCopy(row) {
  157. this.$router.push(`/customization/hsbc/equity-grant-campaign/copy/${row.id}`)
  158. },
  159. handleView(row) {
  160. this.$router.push(`/customization/hsbc/equity-grant-campaign/view/${row.id}`)
  161. },
  162. async handleEnd(row) {
  163. await ElMessageBox.confirm(
  164. `确定结束发放计划「${row.name}」吗?结束后将立即生效,且不再继续发放权益。`,
  165. '结束发放计划',
  166. { type: 'warning', confirmButtonText: '确认结束', cancelButtonText: '取消' }
  167. )
  168. await request.post('/api/equity-grant-campaign/end', { id: row.id })
  169. ElMessage.success('已结束')
  170. this.fetchList()
  171. },
  172. async handleDelete(row) {
  173. await ElMessageBox.confirm('您确定要删除此条发放计划吗?删除后将无法恢复。', '确认删除', {
  174. type: 'warning',
  175. confirmButtonText: '确认删除',
  176. cancelButtonText: '取消'
  177. })
  178. await request.post('/api/equity-grant-campaign/delete', { id: row.id })
  179. ElMessage.success('删除成功')
  180. this.fetchList()
  181. },
  182. validitySummary(v) {
  183. if (!v) return '-'
  184. if (v.type === 'fixed') {
  185. if (!v.fixedRange || v.fixedRange.length !== 2) return '固定日期'
  186. return `${v.fixedRange[0]} 至 ${v.fixedRange[1]}`
  187. }
  188. if (v.type === 'relative') {
  189. return `自发放起 ${v.relativeDays || 0} 天内有效`
  190. }
  191. return '-'
  192. },
  193. grantSummary(row) {
  194. if (!row) return '-'
  195. const cycle = grantCycleLabelMap[row.grantCycle] || '整个周期'
  196. return `${cycle} ${row.grantQuantity || 0} 个`
  197. },
  198. statusLabel(row) {
  199. const now = Date.now()
  200. const s = new Date(row.startTime).getTime()
  201. const e = new Date(row.endTime).getTime()
  202. if (now < s) return '未开始'
  203. if (now > e) return '已结束'
  204. return '进行中'
  205. },
  206. statusTag(row) {
  207. const l = this.statusLabel(row)
  208. return { 未开始: 'info', 进行中: 'success', 已结束: '' }[l] || ''
  209. }
  210. }
  211. }
  212. </script>
  213. <style scoped>
  214. .search-section .search-row { margin-bottom: 0; }
  215. .search-section .action-row { margin-top: 15px; }
  216. .button-group { display: inline-block; margin-left: 20px; }
  217. </style>