| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- <template>
- <div class="store-page">
- <Breadcrumb />
- <a-card title="首页弹窗公告">
- <a-space style="margin-bottom: 12px;">
- <a-button type="primary" @click="openCreate">新增公告</a-button>
- </a-space>
- <a-table :bordered="false"
- :data="data"
- :loading="loading"
- :pagination="{
- showPageSize: true,
- showJumper: true,
- showTotal: true,
- pageSize: pagination.pagesize,
- current: pagination.current,
- total: pagination.total
- }"
- @page-change="onPageChange"
- @page-size-change="onPageSizeChange"
- >
- <template #columns>
- <a-table-column title="ID" data-index="id" :width="80" />
- <a-table-column title="标题" data-index="title" :width="220" ellipsis tooltip />
- <a-table-column title="优先级" data-index="priority" :width="100" />
- <a-table-column title="状态" :width="100">
- <template #cell="{ record }">
- <a-tag :color="record.is_active ? 'green' : 'red'">{{ record.is_active ? '启用' : '停用' }}</a-tag>
- </template>
- </a-table-column>
- <a-table-column title="连续展示" :width="110">
- <template #cell="{ record }">
- <a-tag :color="record.repeat_show ? 'arcoblue' : 'gray'">{{ record.repeat_show ? '开启' : '关闭' }}</a-tag>
- </template>
- </a-table-column>
- <a-table-column title="已读人数" data-index="read_count" :width="100" />
- <a-table-column title="生效时间" :width="180">
- <template #cell="{ record }">{{ record.start_at || '-' }}</template>
- </a-table-column>
- <a-table-column title="失效时间" :width="180">
- <template #cell="{ record }">{{ record.end_at || '-' }}</template>
- </a-table-column>
- <a-table-column title="操作" :width="260">
- <template #cell="{ record }">
- <a-space>
- <a-button size="mini" @click="openEdit(record)">编辑</a-button>
- <a-button size="mini" @click="openReadList(record)">已读列表</a-button>
- <a-button status="danger" size="mini" @click="remove(record)">删除</a-button>
- </a-space>
- </template>
- </a-table-column>
- </template>
- </a-table>
- </a-card>
- <a-modal v-model:visible="editorVisible" :title="form.id ? '编辑公告' : '新增公告'" width="980px" @before-ok="submitEditor">
- <a-form :model="form" layout="vertical">
- <a-form-item label="标题">
- <a-input v-model="form.title" allow-clear />
- </a-form-item>
- <a-form-item label="优先级">
- <a-input-number v-model="form.priority" mode="button" />
- </a-form-item>
- <a-form-item label="状态">
- <a-switch v-model="form.is_active" :checked-value="1" :unchecked-value="0" />
- </a-form-item>
- <a-form-item label="连续展示(已读后仍展示)">
- <a-switch v-model="form.repeat_show" :checked-value="1" :unchecked-value="0" />
- </a-form-item>
- <a-form-item label="生效时间">
- <a-date-picker v-model="form.start_at" show-time format="YYYY-MM-DD HH:mm:ss" value-format="x" allow-clear />
- </a-form-item>
- <a-form-item label="失效时间">
- <a-date-picker v-model="form.end_at" show-time format="YYYY-MM-DD HH:mm:ss" value-format="x" allow-clear />
- </a-form-item>
- <a-form-item label="公告内容(富文本)">
- <WangEditor v-model="form.content_html" />
- </a-form-item>
- </a-form>
- </a-modal>
- <a-modal v-model:visible="readVisible" title="已读用户" :footer="false" width="860px" draggable>
- <a-table :bordered="false"
- :data="readData"
- :columns="readColumns"
- :loading="readLoading"
- :pagination="false"
- :scroll="{ y: 420 }"
- >
- <template #avatar="{ record }">
- <a-avatar :size="28">
- <img :src="record.avatar || 'https://lepao-cloud.xxoo365.top/view.php/25aa126dc406974ff3579a99a2c6501a.png'" />
- </a-avatar>
- {{ record.username || '-' }}
- </template>
- <template #read_at="{ record }">{{ formatTime(record.read_at) }}</template>
- <template #empty>
- <a-empty description="暂无已读记录" />
- </template>
- </a-table>
- </a-modal>
- </div>
- </template>
- <script setup>
- import { reactive, ref, onMounted } from 'vue'
- import { Modal, Notification, Message } from '@arco-design/web-vue'
- import WangEditor from '@/components/Editor/WangEditor.vue'
- import {
- getAdminPopupList,
- createAdminPopup,
- updateAdminPopup,
- deleteAdminPopup,
- getAdminPopupReadList
- } from '@/api/public'
- const loading = ref(false)
- const data = ref([])
- const pagination = reactive({ total: 0, current: 1, pagesize: 20 })
- const editorVisible = ref(false)
- const form = reactive({
- id: null,
- title: '',
- content_html: '',
- priority: 0,
- is_active: 1,
- repeat_show: 0,
- start_at: '',
- end_at: ''
- })
- const readVisible = ref(false)
- const readLoading = ref(false)
- const readData = ref([])
- const readColumns = [
- { title: '用户', slotName: 'avatar', width: 140 },
- { title: 'UUID', dataIndex: 'user_uuid', width: 220, ellipsis: true, tooltip: true },
- { title: '已读时间', slotName: 'read_at', width: 180 }
- ]
- const formatTime = (time) => new Date(time).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })
- const getList = async () => {
- try {
- loading.value = true
- const res = await getAdminPopupList({
- pagesize: pagination.pagesize,
- current: pagination.current
- })
- if (!res || res.code !== 0) {
- return Notification.error({
- title: '获取公告列表失败',
- content: res?.msg ?? '请稍后再试'
- })
- }
- data.value = res.data || []
- pagination.total = res.pagination?.total || 0
- } catch (error) {
- Notification.error({
- title: '获取公告列表失败',
- content: error.message || '请稍后再试'
- })
- } finally {
- loading.value = false
- }
- }
- const openCreate = () => {
- form.id = null
- form.title = ''
- form.content_html = ''
- form.priority = 0
- form.is_active = 1
- form.repeat_show = 0
- form.start_at = ''
- form.end_at = ''
- editorVisible.value = true
- }
- const openEdit = (record) => {
- form.id = record.id
- form.title = record.title
- form.content_html = record.content_html
- form.priority = record.priority
- form.is_active = record.is_active
- form.repeat_show = record.repeat_show ? 1 : 0
- form.start_at = record.start_at ? new Date(record.start_at).getTime() : ''
- form.end_at = record.end_at ? new Date(record.end_at).getTime() : ''
- editorVisible.value = true
- }
- const submitEditor = async () => {
- if (!form.title || !form.content_html) {
- Message.error('请填写标题和内容')
- return false
- }
- const payload = {
- id: form.id,
- title: form.title,
- content_html: form.content_html,
- priority: form.priority,
- is_active: form.is_active,
- repeat_show: form.repeat_show,
- start_at: form.start_at,
- end_at: form.end_at
- }
- const res = form.id ? await updateAdminPopup(payload) : await createAdminPopup(payload)
- if (!res || res.code !== 0) {
- Notification.error({
- title: form.id ? '更新公告失败' : '创建公告失败',
- content: res?.msg ?? '请稍后再试'
- })
- return false
- }
- Message.success(form.id ? '更新成功' : '创建成功')
- getList()
- return true
- }
- const remove = (record) => {
- Modal.confirm({
- title: '删除公告',
- content: `确定删除公告「${record.title}」吗?`,
- onOk: async () => {
- const res = await deleteAdminPopup({ id: record.id })
- if (!res || res.code !== 0) {
- return Notification.error({
- title: '删除公告失败',
- content: res?.msg ?? '请稍后再试'
- })
- }
- Message.success('删除成功')
- getList()
- }
- })
- }
- const openReadList = async (record) => {
- readVisible.value = true
- readLoading.value = true
- readData.value = []
- try {
- const res = await getAdminPopupReadList({
- popup_id: record.id,
- pagesize: 200,
- current: 1
- })
- if (!res || res.code !== 0)
- return Notification.error({
- title: '获取已读列表失败',
- content: res?.msg ?? '请稍后再试'
- })
- readData.value = Array.isArray(res.data) ? res.data : []
- } catch (error) {
- Notification.error({
- title: '获取已读列表失败',
- content: error.message || '请稍后再试'
- })
- } finally {
- readLoading.value = false
- }
- }
- const onPageChange = (page) => {
- pagination.current = page
- getList()
- }
- const onPageSizeChange = (size) => {
- pagination.pagesize = size
- pagination.current = 1
- getList()
- }
- onMounted(() => {
- getList()
- })
- </script>
- <style scoped>
- </style>
|