NoticeManage.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <div class="admin-page">
  3. <el-card>
  4. <div slot="header" class="admin-page-header">
  5. <span class="admin-page-title">公告管理</span>
  6. <el-button type="primary" size="small" @click="openCreate">+ 新建公告</el-button>
  7. </div>
  8. <div class="table-scroll-wrap-lg">
  9. <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
  10. <el-table-column prop="id" label="ID" width="70" />
  11. <el-table-column label="类型" width="90">
  12. <template slot-scope="{ row }">
  13. <el-tag size="mini" :type="typeTagType(row.type)">{{ typeLabel(row.type) }}</el-tag>
  14. </template>
  15. </el-table-column>
  16. <el-table-column label="标题" min-width="200">
  17. <template slot-scope="{ row }">{{ row.title }}</template>
  18. </el-table-column>
  19. <el-table-column label="内容" min-width="200" show-overflow-tooltip>
  20. <template slot-scope="{ row }">{{ row.content }}</template>
  21. </el-table-column>
  22. <el-table-column label="状态" width="90">
  23. <template slot-scope="{ row }">
  24. <el-tag size="mini" :type="row.status === 'active' ? 'success' : 'info'">
  25. {{ row.status === 'active' ? '已发布' : '草稿' }}
  26. </el-tag>
  27. </template>
  28. </el-table-column>
  29. <el-table-column label="创建时间" width="160">
  30. <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
  31. </el-table-column>
  32. <el-table-column label="操作" width="140" fixed="right">
  33. <template slot-scope="{ row }">
  34. <el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
  35. <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
  36. </template>
  37. </el-table-column>
  38. </el-table>
  39. </div>
  40. </el-card>
  41. <!-- 创建/编辑弹窗 -->
  42. <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px" append-to-body>
  43. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  44. <el-form-item label="类型" prop="type">
  45. <el-radio-group v-model="form.type">
  46. <el-radio label="platform">平台公告</el-radio>
  47. <el-radio label="activity">活动</el-radio>
  48. <el-radio label="promotion">优惠</el-radio>
  49. </el-radio-group>
  50. </el-form-item>
  51. <el-form-item label="标题" prop="title">
  52. <el-input v-model="form.title" placeholder="请输入标题" maxlength="200" show-word-limit />
  53. </el-form-item>
  54. <el-form-item label="内容" prop="content">
  55. <el-input v-model="form.content" type="textarea" :rows="5" placeholder="请输入公告内容" />
  56. </el-form-item>
  57. </el-form>
  58. <div slot="footer">
  59. <el-button @click="dialogVisible = false">取消</el-button>
  60. <el-button type="primary" :loading="submitting" @click="handleSubmit">确定</el-button>
  61. </div>
  62. </el-dialog>
  63. </div>
  64. </template>
  65. <script>
  66. import { adminNoticeList, adminNoticeCreate, adminNoticeUpdate, adminNoticeDelete } from '@/api/notice'
  67. export default {
  68. name: 'NoticeManage',
  69. data() {
  70. return {
  71. list: [],
  72. loading: false,
  73. tableHeight: 400,
  74. dialogVisible: false,
  75. submitting: false,
  76. editId: null,
  77. form: {
  78. type: 'platform',
  79. title: '',
  80. content: ''
  81. },
  82. rules: {
  83. type: [{ required: true, message: '请选择类型', trigger: 'change' }],
  84. title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  85. content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
  86. }
  87. }
  88. },
  89. computed: {
  90. dialogTitle() {
  91. return this.editId ? '编辑公告' : '新建公告'
  92. }
  93. },
  94. mounted() {
  95. this.loadList()
  96. window.addEventListener('resize', this.calcHeight)
  97. this.calcHeight()
  98. },
  99. beforeDestroy() {
  100. window.removeEventListener('resize', this.calcHeight)
  101. },
  102. methods: {
  103. calcHeight() {
  104. this.tableHeight = window.innerHeight - 280
  105. },
  106. loadList() {
  107. this.loading = true
  108. adminNoticeList({ page: 1, size: 50 }).then(res => {
  109. this.list = res.data || []
  110. this.loading = false
  111. }).catch(() => {
  112. this.loading = false
  113. })
  114. },
  115. openCreate() {
  116. this.editId = null
  117. this.form = { type: 'platform', title: '', content: '' }
  118. this.dialogVisible = true
  119. this.$nextTick(() => { this.$refs.form && this.$refs.form.clearValidate() })
  120. },
  121. openEdit(row) {
  122. this.editId = row.id
  123. this.form = { type: row.type, title: row.title, content: row.content }
  124. this.dialogVisible = true
  125. this.$nextTick(() => { this.$refs.form && this.$refs.form.clearValidate() })
  126. },
  127. handleSubmit() {
  128. this.$refs.form.validate(valid => {
  129. if (!valid) return
  130. this.submitting = true
  131. var fn = this.editId ? adminNoticeUpdate : adminNoticeCreate
  132. fn(this.form).then(res => {
  133. this.submitting = false
  134. this.dialogVisible = false
  135. this.loadList()
  136. this.$message.success(this.editId ? '更新成功' : '创建成功')
  137. }).catch(() => {
  138. this.submitting = false
  139. })
  140. })
  141. },
  142. handleDelete(row) {
  143. this.$confirm('确定删除该公告?', '提示', { type: 'warning' }).then(() => {
  144. adminNoticeDelete({ id: row.id }).then(() => {
  145. this.loadList()
  146. this.$message.success('删除成功')
  147. })
  148. }).catch(() => {})
  149. },
  150. typeLabel(type) {
  151. var map = { platform: '公告', activity: '活动', promotion: '优惠' }
  152. return map[type] || type
  153. },
  154. typeTagType(type) {
  155. var map = { platform: 'warning', activity: 'primary', promotion: 'danger' }
  156. return map[type] || ''
  157. },
  158. formatTime(time) {
  159. if (!time) return '-'
  160. var d = new Date(time)
  161. return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0') + ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0')
  162. }
  163. }
  164. }
  165. </script>
  166. <style scoped>
  167. .admin-page-header {
  168. display: flex;
  169. justify-content: space-between;
  170. align-items: center;
  171. }
  172. </style>