index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <div class="container">
  3. <Breadcrumb :items="['公告管理', '横幅公告管理']" />
  4. <a-card title="横幅公告管理">
  5. <a-space style="margin-bottom: 12px;">
  6. <a-input v-model="query.keyword" placeholder="按标识或内容搜索" allow-clear style="width: 280px" />
  7. <a-button type="primary" @click="search">搜索</a-button>
  8. <a-button @click="openCreate">新增公告</a-button>
  9. </a-space>
  10. <a-table
  11. :data="data"
  12. :loading="loading"
  13. :pagination="{
  14. showPageSize: true,
  15. showJumper: true,
  16. showTotal: true,
  17. pageSize: pagination.pagesize,
  18. current: pagination.current,
  19. total: pagination.total
  20. }"
  21. @page-change="onPageChange"
  22. @page-size-change="onPageSizeChange"
  23. >
  24. <template #columns>
  25. <a-table-column title="公告标识" data-index="key" :width="220" />
  26. <a-table-column title="内容" data-index="content" ellipsis tooltip />
  27. <a-table-column title="操作" :width="180">
  28. <template #cell="{ record }">
  29. <a-space>
  30. <a-button size="mini" @click="openEdit(record)">编辑</a-button>
  31. <a-button status="danger" size="mini" @click="remove(record)">删除</a-button>
  32. </a-space>
  33. </template>
  34. </a-table-column>
  35. </template>
  36. </a-table>
  37. </a-card>
  38. <a-modal v-model:visible="editorVisible" :title="form.mode === 'create' ? '新增横幅公告' : '编辑横幅公告'" @before-ok="submitEditor">
  39. <a-form :model="form" layout="vertical">
  40. <a-form-item label="公告标识(key)">
  41. <a-input v-model="form.key" :disabled="form.mode === 'edit'" allow-clear />
  42. </a-form-item>
  43. <a-form-item label="公告内容">
  44. <a-textarea v-model="form.content" :max-length="{ length: 1000 }" show-word-limit allow-clear />
  45. </a-form-item>
  46. </a-form>
  47. </a-modal>
  48. </div>
  49. </template>
  50. <script setup>
  51. import { reactive, ref, onMounted } from 'vue'
  52. import { Modal, Notification, Message } from '@arco-design/web-vue'
  53. import { getAdminNoticeList, saveAdminNotice, deleteAdminNotice } from '@/api/public'
  54. const loading = ref(false)
  55. const data = ref([])
  56. const query = reactive({ keyword: '' })
  57. const pagination = reactive({ total: 0, current: 1, pagesize: 20 })
  58. const editorVisible = ref(false)
  59. const form = reactive({
  60. mode: 'create',
  61. key: '',
  62. content: ''
  63. })
  64. const getList = async () => {
  65. try {
  66. loading.value = true
  67. const res = await getAdminNoticeList({
  68. keyword: query.keyword,
  69. pagesize: pagination.pagesize,
  70. current: pagination.current
  71. })
  72. if (!res || res.code !== 0) {
  73. return Notification.error({
  74. title: '获取横幅公告失败',
  75. content: res?.msg ?? '请稍后再试'
  76. })
  77. }
  78. data.value = Array.isArray(res.data) ? res.data : []
  79. pagination.total = res.pagination?.total || 0
  80. } catch (error) {
  81. Notification.error({
  82. title: '获取横幅公告失败',
  83. content: error.message || '请稍后再试'
  84. })
  85. } finally {
  86. loading.value = false
  87. }
  88. }
  89. const search = () => {
  90. pagination.current = 1
  91. getList()
  92. }
  93. const openCreate = () => {
  94. form.mode = 'create'
  95. form.key = ''
  96. form.content = ''
  97. editorVisible.value = true
  98. }
  99. const openEdit = (record) => {
  100. form.mode = 'edit'
  101. form.key = record.key
  102. form.content = record.content
  103. editorVisible.value = true
  104. }
  105. const submitEditor = async () => {
  106. if (!form.key || !form.content) {
  107. Message.error('请填写完整公告信息')
  108. return false
  109. }
  110. const res = await saveAdminNotice({
  111. key: form.key,
  112. content: form.content
  113. })
  114. if (!res || res.code !== 0) {
  115. Notification.error({
  116. title: '保存横幅公告失败',
  117. content: res?.msg ?? '请稍后再试'
  118. })
  119. return false
  120. }
  121. Message.success('保存成功')
  122. getList()
  123. return true
  124. }
  125. const remove = (record) => {
  126. Modal.confirm({
  127. title: '删除横幅公告',
  128. content: `确定删除公告标识「${record.key}」吗?`,
  129. onOk: async () => {
  130. const res = await deleteAdminNotice({ key: record.key })
  131. if (!res || res.code !== 0) {
  132. return Notification.error({
  133. title: '删除横幅公告失败',
  134. content: res?.msg ?? '请稍后再试'
  135. })
  136. }
  137. Message.success('删除成功')
  138. getList()
  139. }
  140. })
  141. }
  142. const onPageChange = (page) => {
  143. pagination.current = page
  144. getList()
  145. }
  146. const onPageSizeChange = (size) => {
  147. pagination.pagesize = size
  148. pagination.current = 1
  149. getList()
  150. }
  151. onMounted(() => {
  152. getList()
  153. })
  154. </script>
  155. <style scoped>
  156. .container {
  157. padding: 0 20px 20px 20px;
  158. }
  159. </style>