| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- import dayjs from "dayjs";
- import { message } from "@/utils/message";
- import { addDialog } from "@/components/ReDialog";
- import {
- getAnnouncementList,
- getAnnouncementById,
- createAnnouncement,
- updateAnnouncement,
- deleteAnnouncement,
- publishAnnouncement,
- offlineAnnouncement,
- setAnnouncementTop
- } from "@/api/announcement";
- import type { PaginationProps } from "@pureadmin/table";
- import { deviceDetection } from "@pureadmin/utils";
- import { onMounted, reactive, ref, toRaw } from "vue";
- import {
- ElForm,
- ElInput,
- ElFormItem,
- ElSelect,
- ElOption,
- ElRadioGroup,
- ElRadioButton
- } from "element-plus";
- import type { SearchFormProps, AnnouncementItemProps } from "./types";
- export function useAnnouncement() {
- const form = reactive<SearchFormProps>({
- title: "",
- type: undefined,
- status: undefined
- });
- const loading = ref(true);
- const dataList = ref([]);
- const pagination = reactive<PaginationProps>({
- total: 0,
- pageSize: 10,
- currentPage: 1,
- background: true
- });
- const typeMap = {
- 1: "系统公告",
- 2: "活动公告",
- 3: "维护公告",
- 4: "其他"
- };
- const statusMap = {
- 0: { text: "草稿", type: "info" },
- 1: { text: "已发布", type: "success" },
- 2: { text: "已下线", type: "warning" }
- };
- const columns: TableColumnList = [
- {
- label: "公告ID",
- prop: "id",
- width: 80
- },
- {
- label: "标题",
- prop: "title",
- minWidth: 200,
- showOverflowTooltip: true
- },
- {
- label: "类型",
- prop: "type",
- minWidth: 100,
- formatter: ({ type }) => typeMap[type] || "未知"
- },
- {
- label: "置顶",
- prop: "isTop",
- minWidth: 80,
- cellRenderer: ({ row }) => (
- <el-tag type={row.isTop === 1 ? "danger" : "info"}>
- {row.isTop === 1 ? "置顶" : "否"}
- </el-tag>
- )
- },
- {
- label: "阅读量",
- prop: "readCount",
- minWidth: 90
- },
- {
- label: "状态",
- prop: "status",
- minWidth: 100,
- cellRenderer: ({ row }) => {
- const item = statusMap[row.status] || { text: "未知", type: "info" };
- return <el-tag type={item.type}>{item.text}</el-tag>;
- }
- },
- {
- label: "发布时间",
- prop: "publishTime",
- minWidth: 160,
- formatter: ({ publishTime }) =>
- publishTime ? dayjs(publishTime).format("YYYY-MM-DD HH:mm:ss") : "-"
- },
- {
- label: "操作",
- fixed: "right",
- width: 280,
- slot: "operation"
- }
- ];
- async function onSearch() {
- loading.value = true;
- try {
- const searchParams: any = {
- page: pagination.currentPage,
- pageSize: pagination.pageSize
- };
-
- // 只添加非空的搜索条件
- if (form.title) searchParams.title = form.title;
- if (form.type !== undefined) searchParams.type = form.type;
- if (form.status !== undefined) searchParams.status = form.status;
-
- const { data } = await getAnnouncementList(searchParams);
- if (data) {
- dataList.value = data.list || [];
- pagination.total = data.total || 0;
- }
- } finally {
- loading.value = false;
- }
- }
- function resetForm(formEl) {
- if (!formEl) return;
- formEl.resetFields();
- pagination.currentPage = 1;
- onSearch();
- }
- async function handleDelete(row) {
- const { code } = await deleteAnnouncement(row.id);
- if (code === 0) {
- message("删除成功", { type: "success" });
- onSearch();
- }
- }
- async function handlePublish(row) {
- const { code } = await publishAnnouncement(row.id);
- if (code === 0) {
- message("发布成功", { type: "success" });
- onSearch();
- }
- }
- async function handleOffline(row) {
- const { code } = await offlineAnnouncement(row.id);
- if (code === 0) {
- message("下线成功", { type: "success" });
- onSearch();
- }
- }
- async function handleSetTop(row) {
- const newIsTop = row.isTop === 1 ? 0 : 1;
- const { code } = await setAnnouncementTop(row.id, newIsTop);
- if (code === 0) {
- message(newIsTop === 1 ? "置顶成功" : "取消置顶成功", { type: "success" });
- onSearch();
- }
- }
- function handleSizeChange(val: number) {
- pagination.pageSize = val;
- onSearch();
- }
- function handleCurrentChange(val: number) {
- pagination.currentPage = val;
- onSearch();
- }
- function openDialog(title = "新增", row?: AnnouncementItemProps) {
- const formInline = reactive({
- id: row?.id,
- title: row?.title ?? "",
- content: row?.content ?? "",
- type: row?.type ?? 1,
- coverImage: row?.coverImage ?? "",
- status: row?.status ?? 0
- });
- const ruleFormRef = ref();
- addDialog({
- title: `${title}公告`,
- props: {
- formInline,
- ruleFormRef
- },
- width: "46%",
- draggable: true,
- fullscreen: deviceDetection(),
- contentRenderer: () => (
- <ElForm
- ref={ruleFormRef}
- model={formInline}
- label-width="100px"
- >
- <ElFormItem
- label="公告标题"
- prop="title"
- rules={[{ required: true, message: "请输入公告标题", trigger: "blur" }]}
- >
- <ElInput v-model={formInline.title} placeholder="请输入公告标题" clearable />
- </ElFormItem>
- <ElFormItem
- label="公告类型"
- prop="type"
- rules={[{ required: true, message: "请选择公告类型", trigger: "change" }]}
- >
- <ElSelect v-model={formInline.type} placeholder="请选择类型" class="w-full">
- <ElOption label="系统公告" value={1} />
- <ElOption label="活动公告" value={2} />
- <ElOption label="维护公告" value={3} />
- <ElOption label="其他" value={4} />
- </ElSelect>
- </ElFormItem>
- <ElFormItem
- label="公告内容"
- prop="content"
- rules={[{ required: true, message: "请输入公告内容", trigger: "blur" }]}
- >
- <ElInput
- v-model={formInline.content}
- type="textarea"
- placeholder="请输入公告内容"
- rows={6}
- />
- </ElFormItem>
- <ElFormItem label="封面图片" prop="coverImage">
- <ElInput v-model={formInline.coverImage} placeholder="请输入封面图片URL" clearable />
- </ElFormItem>
- <ElFormItem label="状态" prop="status">
- <ElRadioGroup v-model={formInline.status}>
- <ElRadioButton value={0}>草稿</ElRadioButton>
- <ElRadioButton value={1}>立即发布</ElRadioButton>
- </ElRadioGroup>
- </ElFormItem>
- </ElForm>
- ),
- beforeSure: async (done, { options }) => {
- const formRef = options.props.ruleFormRef;
- if (!formRef.value) return;
- try {
- const valid = await formRef.value.validate().catch(() => false);
- if (!valid) return;
- const formData = toRaw(options.props.formInline);
- if (formData.id) {
- const { code } = await updateAnnouncement(formData.id, formData);
- if (code === 0) {
- message(`修改公告 ${formData.title} 成功`, { type: "success" });
- done();
- onSearch();
- }
- } else {
- const { code } = await createAnnouncement(formData);
- if (code === 0) {
- message(`新增公告 ${formData.title} 成功`, { type: "success" });
- done();
- onSearch();
- }
- }
- } catch (error) {
- message("操作失败", { type: "error" });
- }
- }
- });
- }
- onMounted(() => {
- onSearch();
- });
- return {
- form,
- loading,
- columns,
- dataList,
- pagination,
- typeMap,
- statusMap,
- onSearch,
- resetForm,
- openDialog,
- handleDelete,
- handlePublish,
- handleOffline,
- handleSetTop,
- handleSizeChange,
- handleCurrentChange
- };
- }
|