list.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <template>
  2. <el-card shadow="never" class="aui-card--fill">
  3. <div class="mod-home">
  4. <div class="title">活动列表</div>
  5. <el-row :gutter="20" style="margin-top: 20px;">
  6. <el-col :span="6" class="adfac">
  7. <div class="query_text">活动类型</div>
  8. <el-select v-model="queryParams.typeId" placeholder="请选择活动类型" class="select-box" style="width: 100%;" clearable>
  9. <el-option v-for="item in typeOptions" :key="item.id" :label="item.typeName" :value="item.id"></el-option>
  10. </el-select>
  11. </el-col>
  12. <el-col :span="6" class="adfac">
  13. <div class="query_text">活动分类</div>
  14. <el-select v-model="queryParams.categoryId" placeholder="请选择活动分类" class="select-box" style="width: 100%;" clearable>
  15. <el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
  16. </el-select>
  17. </el-col>
  18. </el-row>
  19. <el-row :gutter="20" style="margin-top: 20px;">
  20. <el-col :span="6" class="adfac">
  21. <div class="query_text">活动名称</div>
  22. <el-input v-model="queryParams.activityName" placeholder="请输入活动名称" class="input-box" clearable></el-input>
  23. </el-col>
  24. <el-col :span="6" class="adfac">
  25. <div class="query_text">活动时间</div>
  26. <el-date-picker v-model="queryParams.startEndDate" @change="handleDateChange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 100%;"></el-date-picker>
  27. </el-col>
  28. <el-col :span="12" class="adfac">
  29. <el-button type="default" @click="handleReset">重置</el-button>
  30. <el-button type="primary" @click="getList">查询</el-button>
  31. <el-button type="primary" @click="handleAdd" v-if="$hasPermission('core:activity:save')">新增活动</el-button>
  32. </el-col>
  33. </el-row>
  34. <el-table :data="dataList" border cell-class-name="vertical-top-cell" v-loading="loading" empty-text="暂无活动" style="margin-top: 24px;">
  35. <el-table-column prop="id" label="活动ID" width="200"></el-table-column>
  36. <el-table-column prop="activityName" label="活动名称" width="350"></el-table-column>
  37. <el-table-column prop="typeName" label="活动类型" width="120"></el-table-column>
  38. <el-table-column prop="categoryName" label="活动分类" width="120"></el-table-column>
  39. <el-table-column prop="" label="报名时间" width="320">
  40. <template #default="scope">{{ scope.row.signupStartTime }} - {{ scope.row.signupEndTime }}</template>
  41. </el-table-column>
  42. <el-table-column prop="" label="报名人数" width="120">
  43. <template #default="scope">
  44. <div class="adfac"><span style="color: #00AE57;">{{ scope.row.recruitmentNow||0 }}</span>/{{ scope.row.recruitmentMax||'无限制' }}</div>
  45. </template>
  46. </el-table-column>
  47. <el-table-column prop="" label="上下架" width="120">
  48. <template #default="scope">
  49. <span v-if="scope.row.state==1" style="color: #00AE57;">已上架</span>
  50. <span v-if="scope.row.state==0">已下架</span>
  51. </template>
  52. </el-table-column>
  53. <el-table-column prop="activeState" label="活动状态" width="150">
  54. <template #default="scope">
  55. <div class="as" :class="activeStateColorDict[scope.row.activeState]||'grey'">{{ activeStateCfg[scope.row.activeState] || '未知' }}</div>
  56. </template>
  57. </el-table-column>
  58. <el-table-column prop="" label="活动时间" width="320">
  59. <template #default="scope">{{ scope.row.activityStartTime }} - {{ scope.row.activityEndTime }}</template>
  60. </el-table-column>
  61. <el-table-column prop="channelName" label="渠道方" width="120"></el-table-column>
  62. <el-table-column prop="organizerName" label="举办方" width="120" show-overflow-tooltip></el-table-column>
  63. <el-table-column prop="createDate" label="创建时间" width="180"></el-table-column>
  64. <el-table-column label="操作" width="300" fixed="right">
  65. <template #default="scope">
  66. <!-- <el-button link type="text" @click="handleEdit(scope.row)" v-if="scope.row.activeState!=3&&$hasPermission('core:activity:update')">编辑</el-button> -->
  67. <el-button link type="text" @click="handleEdit(scope.row)" v-if="scope.row.activeState<2&&$hasPermission('core:activity:update')">编辑</el-button>
  68. <el-button link type="text" @click="handleDetail(scope.row)" v-if="$hasPermission('core:activity:detail')&&scope.row.activeState>-2">详情</el-button>
  69. <el-button link type="text" @click="handleInfo(scope.row)" v-if="$hasPermission('core:activity:info')&&scope.row.activeState>-2">报名信息</el-button>
  70. <el-button link type="text" @click="handleCode(scope.row)" v-if="!scope.row.signCode&&scope.row.activeState==2&&$hasPermission('core:activity:code')">生成签到码</el-button>
  71. <el-button link type="text" @click="handleReviewCode(scope.row)" v-if="scope.row.signCode&&scope.row.activeState==2&&$hasPermission('core:activity:code')">查看签到码</el-button>
  72. <!-- <el-button link type="text" @click="handleUpDown(scope.row,0)" v-if="scope.row.state==1&&(scope.row.activeState==0||scope.row.activeState==3)&&$hasPermission('core:activity:updown')">下架</el-button> -->
  73. <el-button link type="text" @click="handleUpDown(scope.row,0)" v-if="scope.row.state==1&&$hasPermission('core:activity:updown')&&scope.row.activeState>-2">下架</el-button>
  74. <el-button link type="text" @click="handleUpDown(scope.row,1)" v-if="scope.row.state==0&&$hasPermission('core:activity:updown')&&scope.row.activeState>-2">上架</el-button>
  75. <el-button link type="text" @click="handleCancel(scope.row)" v-if="$hasPermission('core:activity:cancel')&&scope.row.activeState!=-1&&(Date.parse(new Date())>Date.parse(scope.row.signupEndTime)&&Date.parse(new Date())<Date.parse(scope.row.activityStartTime))">取消</el-button>
  76. <el-button link type="text" @click="handleDelete(scope.row)" v-if="($hasPermission('core:activity:delete')&&scope.row.state==0&&scope.row.activeState==0)||($hasPermission('core:activity:delete')&&scope.row.activeState==-2)">删除</el-button>
  77. </template>
  78. </el-table-column>
  79. </el-table>
  80. <el-pagination
  81. :current-page="queryParams.page"
  82. :page-sizes="[10, 20, 50, 100]"
  83. :page-size="queryParams.limit"
  84. :total="total"
  85. layout="total, sizes, prev, pager, next, jumper"
  86. @size-change="pageSizeChangeHandle"
  87. @current-change="pageCurrentChangeHandle">
  88. </el-pagination>
  89. </div>
  90. <el-dialog width="600px" :visible.sync="show" title="签到码" @close="cancel">
  91. <div class="code-img adffcacjc">
  92. <img :src="signCodeUrl">
  93. </div>
  94. <div class="demo-drawer__footer" style="display: flex;justify-content: end;margin-top: 50px;">
  95. <el-button type="primary" @click="downloadImg">下 载</el-button>
  96. <el-button @click="cancel" style="margin-right: 5%;">取 消</el-button>
  97. </div>
  98. </el-dialog>
  99. </el-card>
  100. </template>
  101. <script>
  102. import moment from 'moment'
  103. export default {
  104. data () {
  105. return {
  106. activeStateCfg: {
  107. '-2': '草稿',
  108. '-1': '已取消',
  109. 0: '未开始',
  110. 1: '报名中',
  111. 2: '进行中',
  112. 3: '已结束'
  113. },
  114. activeStateColorDict: {
  115. '-2': 'grey',
  116. '-1': 'grey',
  117. 0: 'red',
  118. 1: 'yellow',
  119. 2: 'blue',
  120. 3: 'grey'
  121. },
  122. typeOptions: [],
  123. categoryOptions: [],
  124. queryParams: {
  125. page: 1,
  126. limit: 10,
  127. typeId: '',
  128. categoryId: '',
  129. activityName: '',
  130. startEndDate: '',
  131. startDate: '',
  132. endDate: ''
  133. },
  134. total: 0,
  135. dataList: [],
  136. loading: false,
  137. show: false,
  138. signCodeUrl: ''
  139. }
  140. },
  141. created () {
  142. this.getTypeOptions()
  143. this.getCategoryOptions()
  144. },
  145. mounted () {
  146. this.getList()
  147. },
  148. methods: {
  149. getList () {
  150. this.loading = true
  151. let { startEndDate, ...newParams } = JSON.parse(JSON.stringify(this.queryParams))
  152. this.$http.get('/core/activity/page', { params: newParams }).then(res => {
  153. if (res.data.code !== 0) return this.$message.error(res.data.msg)
  154. this.dataList = res.data.data.list || []
  155. this.total = res.data.data.total || 0
  156. this.loading = false
  157. })
  158. },
  159. handleReset () {
  160. this.queryParams = {
  161. page: 1,
  162. limit: 10,
  163. typeId: '',
  164. categoryId: '',
  165. activityName: '',
  166. startEndDate: '',
  167. startDate: '',
  168. endDate: ''
  169. }
  170. this.getList()
  171. },
  172. pageSizeChangeHandle (val) {
  173. this.queryParams.limit = val
  174. this.getList()
  175. },
  176. pageCurrentChangeHandle (val) {
  177. this.queryParams.page = val
  178. this.getList()
  179. },
  180. handleDateChange (val) {
  181. this.queryParams.startDate = moment(val[0]).format('YYYY-MM-DD')
  182. this.queryParams.endDate = moment(val[1]).format('YYYY-MM-DD')
  183. },
  184. getTypeOptions () {
  185. this.$http.get('/core/activity/type/page', { params: { page: 1, limit: -1 } }).then(res => {
  186. this.typeOptions = res.data.data.list || []
  187. })
  188. },
  189. getCategoryOptions () {
  190. this.$http.get('/core/activity/category/page', { params: { page: 1, limit: -1 } }).then(res => {
  191. this.categoryOptions = res.data.data.list || []
  192. })
  193. },
  194. handleAdd () {
  195. this.$router.push({ name: 'activityAdd' })
  196. },
  197. handleEdit (row) {
  198. this.$router.push({ name: 'activityAdd', query: { id: row.id } })
  199. },
  200. handleDetail (row) {
  201. this.$router.push({ name: 'activityDetail', query: { id: row.id } })
  202. },
  203. handleInfo (row) {
  204. this.$router.push({ name: 'activityApplyInfo', query: { id: row.id } })
  205. },
  206. handleCode (row) {
  207. this.$http.get('/core/activity/genSignCode/' + row.id).then(res => {
  208. if (res.data.code !== 0) return this.$message.error(res.data.msg)
  209. this.$message.success('生成成功')
  210. this.getList()
  211. })
  212. },
  213. handleReviewCode (row) {
  214. this.show = true
  215. this.signCodeUrl = row.signCode
  216. },
  217. cancel () {
  218. this.show = false
  219. },
  220. downloadImg () {
  221. const link = document.createElement('a')
  222. link.style.display = 'none'
  223. link.href = this.signCodeUrl
  224. link.setAttribute('download', '签到码')
  225. document.body.appendChild(link)
  226. link.click()
  227. document.body.removeChild(link)
  228. this.show = false
  229. },
  230. handleUpDown (row, state) {
  231. if ([0, 1, 2].includes(row.activeState) && row.recruitmentNow > 0) return this.$message.error(`当前活动已存在报名人数,无法${state ? '上架' : '下架'}`)
  232. this.$confirm(`是否确认${state ? '上架' : '下架'}活动【${row.activityName}】?`, '提示', {
  233. confirmButtonText: '确定',
  234. cancelButtonText: '取消',
  235. type: 'warning'
  236. }).then(() => {
  237. this.$http.post('/core/activity/updState', { id: row.id, state }).then(res => {
  238. if (res.data.code !== 0) return this.$message.error(res.data.msg)
  239. this.$message.success((state ? '上架' : '下架') + '成功')
  240. this.getList()
  241. })
  242. })
  243. },
  244. handleCancel (row) {
  245. this.$confirm(`是否确认取消活动【${row.activityName}】?`, '提示', {
  246. confirmButtonText: '确定',
  247. cancelButtonText: '取消',
  248. type: 'warning'
  249. }).then(() => {
  250. this.$http.get(`core/activity/cancelEvent/${row.id}`).then(res => {
  251. if (res.data.code !== 0) return this.$message.error(res.data.msg)
  252. this.$message.success('取消成功')
  253. this.getList()
  254. })
  255. }).catch(() => {})
  256. },
  257. handleDelete (row) {
  258. this.$confirm(`是否确认删除活动【${row.activityName}】?`, '提示', {
  259. confirmButtonText: '确定',
  260. cancelButtonText: '取消',
  261. type: 'warning'
  262. }).then(() => {
  263. this.$http.delete('/core/activity', { 'data': [row.id] }).then(res => {
  264. if (res.data.code !== 0) return this.$message.error(res.data.msg)
  265. this.$message.success('删除成功')
  266. this.getList()
  267. })
  268. }).catch(() => {
  269. this.$message({
  270. type: 'info',
  271. message: '已取消删除'
  272. })
  273. })
  274. }
  275. }
  276. }
  277. </script>
  278. <style scoped lang="scss">
  279. .title{
  280. font-family: PingFang-SC, PingFang-SC;
  281. font-weight: bold;
  282. font-size: 16px;
  283. color: #252525;
  284. line-height: 22px;
  285. }
  286. .query_text{
  287. font-family: PingFangSC, PingFang SC;
  288. font-weight: 400;
  289. font-size: 14px;
  290. color: #393939;
  291. line-height: 20px;
  292. width: 80px;
  293. margin-right: 16px;
  294. }
  295. .as{
  296. width: 58px;
  297. height: 24px;
  298. font-family: PingFangSC, PingFang SC;
  299. font-weight: 400;
  300. font-size: 14px;
  301. color: #646464;
  302. line-height: 24px;
  303. text-align: center;
  304. background: #F7F7F7;
  305. border-radius: 6px;
  306. display: inline-block;
  307. &.blue{
  308. background: rgba(46,105,235,0.08);
  309. color: #2E69EB;
  310. }
  311. &.red{
  312. background: rgba(253,79,102,0.11);
  313. color: #FD4F66;
  314. }
  315. &.yellow{
  316. background: rgba(255,152,10,0.08);
  317. color: #FF980A;
  318. }
  319. }
  320. .code-img{
  321. width: 100%;
  322. height: 500px;
  323. img{
  324. width: 100%;
  325. height: auto;
  326. }
  327. }
  328. </style>