From d7f9fc20b91f72f52cb76e699858458d995c6c76 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 21 五月 2026 10:51:55 +0800
Subject: [PATCH] 公告通知页面复用
---
/dev/null | 328 --------------------------------
src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue | 255 ------------------------
2 files changed, 7 insertions(+), 576 deletions(-)
diff --git a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/components/NoticeDetailPanel.vue b/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/components/NoticeDetailPanel.vue
deleted file mode 100644
index 9a490fc..0000000
--- a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/components/NoticeDetailPanel.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<!-- NoticeAnnouncement锛氬叕鍛婅鎯呭彧璇婚潰鏉� -->
-<template>
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鍏憡缂栧彿">{{ row.noticeNo || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鐘舵��">
- <el-tag :type="statusTag" size="small">{{ statusText }}</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鍏憡绫诲瀷">
- <span class="type-badge" :style="{ color: noticeTypeColor(row.noticeType) }">
- {{ noticeTypeLabel(row.noticeType) }}
- </span>
- </el-descriptions-item>
- <el-descriptions-item label="浼樺厛绾�">
- <el-tag :type="priorityTag(row.priority)" size="small">{{ priorityLabel(row.priority) }}</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鏍囬" :span="2">{{ row.title || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鏃ユ湡">{{ row.publishDate || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="杩囨湡鏃ユ湡">{{ row.expireDate || "闀挎湡鏈夋晥" }}</el-descriptions-item>
- <el-descriptions-item label="闃呰鑼冨洿">{{ readScopeLabel(row.readScope) }}</el-descriptions-item>
- <el-descriptions-item label="闇�闃呰纭">{{ row.requireReadConfirm ? "鏄�" : "鍚�" }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷浜�">{{ row.publisherName || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鏃堕棿">{{ row.publishTime || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="闃呰閲�">{{ row.readCount ?? 0 }}</el-descriptions-item>
- </el-descriptions>
-
- <el-divider content-position="left">鍏憡鍐呭</el-divider>
- <div v-if="row.priority === 'urgent'" class="urgent-banner">
- <el-alert title="绱ф�ラ�氱煡" type="error" :closable="false" show-icon />
- </div>
- <div v-if="row.contentHtml" class="notice-html-body" v-html="row.contentHtml" />
- <el-empty v-else description="鏆傛棤鍐呭" :image-size="48" />
-</template>
-
-<script setup>
-import { computed } from "vue";
-import {
- noticeTypeLabel,
- noticeTypeColor,
- priorityLabel,
- priorityTag,
- publishStatusLabel,
- publishStatusTag,
- readScopeLabel,
- isExpired,
-} from "../noticeAnnouncementUtils.js";
-
-const props = defineProps({
- row: { type: Object, default: () => ({}) },
-});
-
-const statusText = computed(() => {
- if (isExpired(props.row) && props.row.publishStatus === "published") return "宸茶繃鏈�";
- return publishStatusLabel(props.row.publishStatus);
-});
-
-const statusTag = computed(() => {
- if (isExpired(props.row) && props.row.publishStatus === "published") return "";
- return publishStatusTag(props.row.publishStatus);
-});
-</script>
-
-<style scoped>
-.type-badge {
- font-weight: 600;
-}
-.urgent-banner {
- margin-bottom: 12px;
-}
-.notice-html-body {
- padding: 12px;
- background: var(--el-fill-color-light);
- border-radius: 6px;
- max-height: 400px;
- overflow-y: auto;
- line-height: 1.7;
-}
-</style>
diff --git a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue b/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue
index 4599ced..3f65cb7 100644
--- a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue
+++ b/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue
@@ -1,253 +1,12 @@
-<!--OA妯″潡锛歂oticeAnnouncement 閫氱煡鍏憡-->
+<!--
+ 妯″潡涓枃鍚嶏細閫氱煡鍏憡
+ 鐩綍鏍囪瘑锛歂oticeAnnouncement/notice-manage
+ 澶嶇敤椤甸潰锛欯/views/collaborativeApproval/noticeManagement/index.vue锛堝崗鍚屽鎵�-閫氱煡鍏憡锛�
+-->
<template>
- <div class="app-container notice-announcement-page">
- <div class="search_form mb20">
- <div class="search_fields">
- <span class="search_title">鍏抽敭璇嶏細</span>
- <el-input
- v-model="searchForm.keyword"
- style="width: 200px"
- placeholder="鏍囬 / 缂栧彿"
- clearable
- :prefix-icon="Search"
- @keyup.enter="handleQuery"
- />
- <span class="search_title" style="margin-left: 12px">绫诲瀷锛�</span>
- <el-select v-model="searchForm.noticeType" placeholder="鍏ㄩ儴" clearable style="width: 130px">
- <el-option v-for="opt in NOTICE_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
- </el-select>
- <span class="search_title" style="margin-left: 12px">浼樺厛绾э細</span>
- <el-select v-model="searchForm.priority" placeholder="鍏ㄩ儴" clearable style="width: 110px">
- <el-option v-for="opt in PRIORITY_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
- </el-select>
- <span class="search_title" style="margin-left: 12px">鐘舵�侊細</span>
- <el-select v-model="searchForm.publishStatus" placeholder="鍏ㄩ儴" clearable style="width: 110px">
- <el-option v-for="opt in PUBLISH_STATUS_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
- </el-select>
- <span class="search_title" style="margin-left: 12px">鍙戝竷鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.publishDateRange"
- type="daterange"
- range-separator="-"
- start-placeholder="寮�濮�"
- end-placeholder="缁撴潫"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 260px"
- clearable
- />
- <el-button type="primary" :icon="Search" class="ml10" @click="handleQuery">鎼滅储</el-button>
- <el-button :icon="RefreshRight" @click="resetSearch">閲嶇疆</el-button>
- </div>
- <div class="search_actions">
- <el-button type="primary" :icon="Plus" @click="openFormDialog('add')">娣诲姞鍏憡</el-button>
- </div>
- </div>
-
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="false"
- :tableLoading="tableLoading"
- :total="page.total"
- @pagination="pagination"
- >
- <template #noticeType="{ row }">
- <span class="notice-type-tag" :style="{ color: noticeTypeColor(row.noticeType) }">
- {{ noticeTypeLabel(row.noticeType) }}
- </span>
- </template>
- </PIMTable>
- </div>
-
- <!-- 娣诲姞 / 淇敼 -->
- <el-dialog
- v-model="formDialog.visible"
- :title="formDialog.title"
- width="800px"
- append-to-body
- destroy-on-close
- class="notice-form-dialog"
- @closed="formRef?.resetFields?.()"
- >
- <el-form
- ref="formRef"
- :model="form"
- :rules="formRules"
- label-width="100px"
- :disabled="formDialog.readonly"
- >
- <el-form-item label="鏍囬" prop="title">
- <el-input v-model="form.title" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" maxlength="100" show-word-limit />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍏憡绫诲瀷" prop="noticeType">
- <el-select v-model="form.noticeType" placeholder="璇烽�夋嫨" style="width: 100%" @change="onNoticeTypeChange">
- <el-option v-for="opt in NOTICE_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浼樺厛绾�">
- <el-select v-model="form.priority" placeholder="璇烽�夋嫨" style="width: 100%">
- <el-option v-for="opt in PRIORITY_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍙戝竷鏃ユ湡" prop="publishDate">
- <el-date-picker
- v-model="form.publishDate"
- type="date"
- placeholder="鍙戝竷鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="杩囨湡鏃ユ湡">
- <el-date-picker
- v-model="form.expireDate"
- type="date"
- placeholder="鍙�夛紝鐣欑┖涓洪暱鏈熸湁鏁�"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="闃呰鑼冨洿">
- <el-radio-group v-model="form.readScope">
- <el-radio v-for="opt in READ_SCOPE_OPTIONS" :key="opt.value" :value="opt.value">
- {{ opt.label }}
- </el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item v-if="form.readScope === 'department'" label="鍙閮ㄩ棬">
- <el-select v-model="form.targetDeptIds" multiple placeholder="閫夋嫨閮ㄩ棬" style="width: 100%">
- <el-option v-for="d in DEPT_OPTIONS" :key="d.value" :label="d.label" :value="d.value" />
- </el-select>
- </el-form-item>
- <el-form-item v-if="form.noticeType === 'emergency'" label="蹇呰纭">
- <el-switch v-model="form.requireReadConfirm" active-text="绱ф�ラ�氱煡闇�鍛樺伐纭宸茶" />
- </el-form-item>
- <el-form-item label="鍐呭" prop="contentHtml">
- <Editor v-model="form.contentHtml" :min-height="280" placeholder="璇疯緭鍏ュ唴瀹�" />
- </el-form-item>
- <el-form-item label="鍙戝竷浜�">
- <el-input v-model="form.publisherName" placeholder="濡傦細琛屾斂閮�" maxlength="50" />
- </el-form-item>
- </el-form>
- <template v-if="!formDialog.readonly" #footer>
- <el-button @click="formDialog.visible = false">鍙� 娑�</el-button>
- <el-button @click="onSave(false)">瀛樿崏绋�</el-button>
- <el-button type="primary" @click="onSave(true)">纭� 瀹�</el-button>
- </template>
- </el-dialog>
-
- <!-- 璇︽儏 -->
- <el-dialog v-model="detailDialog.visible" title="鍏憡璇︽儏" width="800px" append-to-body destroy-on-close>
- <NoticeDetailPanel :row="detailRow" />
- <template #footer>
- <el-button @click="detailDialog.visible = false">鍏� 闂�</el-button>
- </template>
- </el-dialog>
- </div>
+ <NoticeManagement />
</template>
<script setup>
-import { Plus, RefreshRight } from "@element-plus/icons-vue";
-import { ElMessage } from "element-plus";
-import { onMounted } from "vue";
-import Editor from "@/components/Editor/index.vue";
-import { noticeTypeColor } from "./noticeAnnouncementUtils.js";
-import NoticeDetailPanel from "./components/NoticeDetailPanel.vue";
-import { useNoticeAnnouncement } from "./useNoticeAnnouncement.js";
-
-const {
- Search,
- NOTICE_TYPE_OPTIONS,
- PRIORITY_OPTIONS,
- PUBLISH_STATUS_OPTIONS,
- READ_SCOPE_OPTIONS,
- DEPT_OPTIONS,
- noticeTypeLabel,
- searchForm,
- tableLoading,
- page,
- tableData,
- tableColumn,
- formDialog,
- form,
- formRef,
- formRules,
- detailDialog,
- detailRow,
- handleQuery,
- resetSearch,
- pagination,
- openFormDialog,
- saveForm,
-} = useNoticeAnnouncement();
-
-function onNoticeTypeChange(type) {
- if (type === "emergency") {
- form.priority = "urgent";
- form.requireReadConfirm = true;
- }
-}
-
-function onSave(publish) {
- const ret = saveForm(publish);
- if (ret?.message) {
- ElMessage.warning(ret.message);
- return;
- }
- if (ret?.ok) {
- ElMessage.success(publish ? "鍏憡宸插彂甯�" : "宸蹭繚瀛樿崏绋�");
- }
-}
-
-onMounted(() => {
- handleQuery();
-});
+import NoticeManagement from "@/views/collaborativeApproval/noticeManagement/index.vue";
</script>
-
-<style scoped>
-.notice-announcement-page .search_form {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- align-items: flex-start;
- gap: 12px;
-}
-.search_fields {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 4px;
-}
-.search_actions {
- flex-shrink: 0;
-}
-.notice-type-tag {
- font-weight: 600;
- font-size: 13px;
-}
-.ml10 {
- margin-left: 10px;
-}
-.mb20 {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/noticeAnnouncementUtils.js b/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/noticeAnnouncementUtils.js
deleted file mode 100644
index 7fe3d6d..0000000
--- a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/noticeAnnouncementUtils.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import dayjs from "dayjs";
-
-/** 鍏憡绫诲瀷 */
-export const NOTICE_TYPE_OPTIONS = [
- { value: "emergency", label: "绱ф�ラ�氱煡", color: "#f56c6c" },
- { value: "employee", label: "鍛樺伐鍏憡", color: "#409eff" },
- { value: "company", label: "浼佷笟鍏憡", color: "#e6a23c" },
-];
-
-/** 浼樺厛绾� */
-export const PRIORITY_OPTIONS = [
- { value: "urgent", label: "绱ф��", tag: "danger" },
- { value: "high", label: "閲嶈", tag: "warning" },
- { value: "normal", label: "鏅��", tag: "info" },
-];
-
-/** 鍙戝竷鐘舵�� */
-export const PUBLISH_STATUS_OPTIONS = [
- { value: "draft", label: "鑽夌", tag: "info" },
- { value: "published", label: "宸插彂甯�", tag: "success" },
- { value: "withdrawn", label: "宸叉挙鍥�", tag: "warning" },
- { value: "expired", label: "宸茶繃鏈�", tag: "" },
-];
-
-/** 闃呰鑼冨洿 */
-export const READ_SCOPE_OPTIONS = [
- { value: "all", label: "鍏ㄥ憳鍙" },
- { value: "department", label: "鎸囧畾閮ㄩ棬" },
- { value: "management", label: "绠$悊灞�" },
-];
-
-export const DEPT_OPTIONS = [
- { value: "101", label: "鐮斿彂閮�" },
- { value: "102", label: "閿�鍞儴" },
- { value: "103", label: "琛屾斂閮�" },
- { value: "104", label: "璐㈠姟閮�" },
- { value: "105", label: "鎬荤粡鍔�" },
- { value: "106", label: "浜哄姏璧勬簮閮�" },
-];
-
-export function noticeTypeLabel(v) {
- return NOTICE_TYPE_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
-}
-
-export function noticeTypeColor(v) {
- return NOTICE_TYPE_OPTIONS.find((x) => x.value === v)?.color || "#909399";
-}
-
-export function priorityLabel(v) {
- return PRIORITY_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
-}
-
-export function priorityTag(v) {
- return PRIORITY_OPTIONS.find((x) => x.value === v)?.tag || "info";
-}
-
-export function publishStatusLabel(v) {
- return PUBLISH_STATUS_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
-}
-
-export function publishStatusTag(v) {
- return PUBLISH_STATUS_OPTIONS.find((x) => x.value === v)?.tag || "info";
-}
-
-export function readScopeLabel(v) {
- return READ_SCOPE_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
-}
-
-export function createEmptyForm() {
- return {
- id: "",
- noticeNo: "",
- title: "",
- noticeType: "employee",
- priority: "normal",
- contentHtml: "",
- publishDate: dayjs().format("YYYY-MM-DD"),
- expireDate: "",
- readScope: "all",
- targetDeptIds: [],
- requireReadConfirm: false,
- publishStatus: "draft",
- publisherName: "",
- publishTime: "",
- readCount: 0,
- createTime: "",
- updateTime: "",
- };
-}
-
-export function nextNoticeNo() {
- return `NA${dayjs().format("YYYYMMDD")}${String(Math.floor(Math.random() * 9000) + 1000)}`;
-}
-
-export function validateNoticeForm(form) {
- const title = (form.title || "").trim();
- if (!title) return { ok: false, message: "璇疯緭鍏ュ叕鍛婃爣棰�" };
- if (!form.publishDate) return { ok: false, message: "璇烽�夋嫨鍙戝竷鏃ユ湡" };
- if (!form.noticeType) return { ok: false, message: "璇烽�夋嫨鍏憡绫诲瀷" };
- if (form.readScope === "department" && !(form.targetDeptIds || []).length) {
- return { ok: false, message: "璇烽�夋嫨鍙閮ㄩ棬" };
- }
- return { ok: true, title };
-}
-
-export function isExpired(row) {
- if (!row.expireDate) return false;
- return dayjs(row.expireDate).endOf("day").isBefore(dayjs());
-}
diff --git a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/useNoticeAnnouncement.js b/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/useNoticeAnnouncement.js
deleted file mode 100644
index 67281c4..0000000
--- a/src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/useNoticeAnnouncement.js
+++ /dev/null
@@ -1,328 +0,0 @@
-import { Search } from "@element-plus/icons-vue";
-import dayjs from "dayjs";
-import { ElMessageBox } from "element-plus";
-import { computed, onMounted, reactive, ref, watch } from "vue";
-import {
- NOTICE_TYPE_OPTIONS,
- PRIORITY_OPTIONS,
- PUBLISH_STATUS_OPTIONS,
- READ_SCOPE_OPTIONS,
- DEPT_OPTIONS,
- createEmptyForm,
- nextNoticeNo,
- validateNoticeForm,
- noticeTypeLabel,
- priorityLabel,
- publishStatusLabel,
- isExpired,
-} from "./noticeAnnouncementUtils.js";
-
-export function useNoticeAnnouncement() {
- const allRows = ref([]);
-
- const searchForm = reactive({
- keyword: "",
- noticeType: "",
- priority: "",
- publishStatus: "",
- publishDateRange: [],
- });
-
- const tableLoading = ref(false);
- const page = reactive({ current: 1, size: 10, total: 0 });
-
- const formDialog = reactive({ visible: false, title: "", mode: "add", readonly: false });
- const form = reactive(createEmptyForm());
- const formRef = ref();
-
- const detailDialog = reactive({ visible: false });
- const detailRow = ref({});
-
- const filteredList = computed(() => {
- let list = [...allRows.value];
- const kw = (searchForm.keyword || "").trim().toLowerCase();
- if (kw) {
- list = list.filter((r) => (r.title || "").toLowerCase().includes(kw) || (r.noticeNo || "").toLowerCase().includes(kw));
- }
- if (searchForm.noticeType) list = list.filter((r) => r.noticeType === searchForm.noticeType);
- if (searchForm.priority) list = list.filter((r) => r.priority === searchForm.priority);
- if (searchForm.publishStatus) list = list.filter((r) => r.publishStatus === searchForm.publishStatus);
- const range = searchForm.publishDateRange;
- if (range?.length === 2 && range[0] && range[1]) {
- const start = dayjs(range[0]).startOf("day");
- const end = dayjs(range[1]).endOf("day");
- list = list.filter((r) => {
- if (!r.publishDate) return false;
- const t = dayjs(r.publishDate);
- return !t.isBefore(start) && !t.isAfter(end);
- });
- }
- return list.sort((a, b) => (String(a.updateTime) < String(b.updateTime) ? 1 : -1));
- });
-
- watch(
- filteredList,
- (list) => {
- page.total = list.length;
- const maxPage = Math.max(1, Math.ceil(list.length / page.size) || 1);
- if (page.current > maxPage) page.current = maxPage;
- },
- { immediate: true }
- );
-
- const tableData = computed(() => {
- const start = (page.current - 1) * page.size;
- return filteredList.value.slice(start, start + page.size);
- });
-
- const formRules = {
- title: [{ required: true, message: "璇疯緭鍏ュ叕鍛婃爣棰�", trigger: "blur" }],
- publishDate: [{ required: true, message: "璇烽�夋嫨鍙戝竷鏃ユ湡", trigger: "change" }],
- noticeType: [{ required: true, message: "璇烽�夋嫨鍏憡绫诲瀷", trigger: "change" }],
- };
-
- const tableColumn = ref([
- { label: "缂栧彿", prop: "noticeNo", width: 150 },
- { label: "鏍囬", prop: "title", minWidth: 200, showOverflowTooltip: true },
- {
- label: "绫诲瀷",
- prop: "noticeType",
- width: 100,
- dataType: "slot",
- slot: "noticeType",
- },
- {
- label: "浼樺厛绾�",
- prop: "priority",
- width: 90,
- dataType: "tag",
- formatData: (v) => priorityLabel(v),
- formatType: (v) => {
- const hit = PRIORITY_OPTIONS.find((x) => x.value === v);
- return hit?.tag || "info";
- },
- },
- {
- label: "鐘舵��",
- prop: "publishStatus",
- width: 90,
- dataType: "tag",
- formatData: (v, row) => (isExpired(row) && v === "published" ? "宸茶繃鏈�" : publishStatusLabel(v)),
- formatType: (v, row) => {
- if (isExpired(row) && v === "published") return "";
- const hit = PUBLISH_STATUS_OPTIONS.find((x) => x.value === v);
- return hit?.tag || "info";
- },
- },
- { label: "鍙戝竷鏃ユ湡", prop: "publishDate", width: 120 },
- { label: "鍙戝竷浜�", prop: "publisherName", width: 110 },
- { label: "闃呰閲�", prop: "readCount", width: 80, align: "center" },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 220,
- operation: [
- { name: "璇︽儏", type: "text", clickFun: (row) => openDetail(row) },
- {
- name: "淇敼",
- type: "text",
- disabled: (row) => row.publishStatus === "withdrawn",
- clickFun: (row) => openFormDialog("edit", row),
- },
- {
- name: "鍙戝竷",
- type: "text",
- disabled: (row) => row.publishStatus === "published",
- clickFun: (row) => publishNotice(row),
- },
- {
- name: "鎾ゅ洖",
- type: "text",
- disabled: (row) => row.publishStatus !== "published",
- clickFun: (row) => withdrawNotice(row),
- },
- { name: "鍒犻櫎", type: "text", clickFun: (row) => deleteNotice(row) },
- ],
- },
- ]);
-
- onMounted(() => {
- try {
- localStorage.removeItem("oa_notice_announcement_v1");
- } catch {
- /* 娓呴櫎鍘嗗彶鏈湴婕旂ず缂撳瓨 */
- }
- });
-
- function handleQuery() {
- tableLoading.value = true;
- page.current = 1;
- setTimeout(() => {
- tableLoading.value = false;
- }, 200);
- }
-
- function resetSearch() {
- searchForm.keyword = "";
- searchForm.noticeType = "";
- searchForm.priority = "";
- searchForm.publishStatus = "";
- searchForm.publishDateRange = [];
- handleQuery();
- }
-
- function pagination({ page: p, limit }) {
- page.current = p;
- page.size = limit;
- }
-
- function resetForm(target = createEmptyForm()) {
- Object.assign(form, createEmptyForm(), target);
- }
-
- function openFormDialog(mode, row) {
- formDialog.mode = mode;
- formDialog.readonly = mode === "view";
- formDialog.title =
- mode === "add" ? "娣诲姞鍏憡" : mode === "edit" ? "淇敼鍏憡" : "鏌ョ湅鍏憡";
- if (mode === "add") {
- resetForm({ publisherName: "褰撳墠鐢ㄦ埛", priority: "normal" });
- } else {
- resetForm({
- ...JSON.parse(JSON.stringify(row)),
- targetDeptIds: [...(row.targetDeptIds || [])],
- });
- }
- formDialog.visible = true;
- }
-
- function openDetail(row) {
- detailRow.value = { ...row };
- detailDialog.visible = true;
- }
-
- function saveForm(publish = false) {
- const v = validateNoticeForm(form);
- if (!v.ok) return { ok: false, message: v.message };
-
- const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
- const payload = {
- ...JSON.parse(JSON.stringify(form)),
- title: v.title,
- updateTime: now,
- };
-
- if (form.noticeType === "emergency" && payload.priority === "normal") {
- payload.priority = "urgent";
- }
-
- if (formDialog.mode === "add") {
- payload.id = `notice_${Date.now()}`;
- payload.noticeNo = nextNoticeNo();
- payload.createTime = now;
- payload.readCount = 0;
- if (publish) {
- payload.publishStatus = "published";
- payload.publishTime = now;
- } else {
- payload.publishStatus = "draft";
- }
- allRows.value.unshift(payload);
- } else {
- const idx = allRows.value.findIndex((r) => r.id === form.id);
- if (idx < 0) return { ok: false, message: "璁板綍涓嶅瓨鍦�" };
- const prev = allRows.value[idx];
- if (publish) {
- payload.publishStatus = "published";
- payload.publishTime = payload.publishTime || now;
- }
- allRows.value[idx] = { ...prev, ...payload };
- }
- formDialog.visible = false;
- return { ok: true };
- }
-
- async function publishNotice(row) {
- try {
- await ElMessageBox.confirm(`纭鍙戝竷銆�${row.title}銆嶏紵`, "鍙戝竷鍏憡", {
- type: "warning",
- confirmButtonText: "鍙戝竷",
- cancelButtonText: "鍙栨秷",
- });
- const hit = allRows.value.find((r) => r.id === row.id);
- if (!hit) return;
- const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
- hit.publishStatus = "published";
- hit.publishTime = now;
- hit.updateTime = now;
- if (hit.noticeType === "emergency") hit.priority = "urgent";
- return true;
- } catch {
- return false;
- }
- }
-
- async function withdrawNotice(row) {
- try {
- await ElMessageBox.confirm(`纭鎾ゅ洖銆�${row.title}銆嶏紵鎾ゅ洖鍚庡憳宸ョ灏嗕笉鍐嶅睍绀恒�俙, "鎾ゅ洖鍏憡", {
- type: "warning",
- confirmButtonText: "鎾ゅ洖",
- cancelButtonText: "鍙栨秷",
- });
- const hit = allRows.value.find((r) => r.id === row.id);
- if (!hit) return;
- hit.publishStatus = "withdrawn";
- hit.updateTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
- return true;
- } catch {
- return false;
- }
- }
-
- async function deleteNotice(row) {
- try {
- await ElMessageBox.confirm(`纭鍒犻櫎銆�${row.title}銆嶏紵姝ゆ搷浣滀笉鍙仮澶嶃�俙, "鍒犻櫎鍏憡", {
- type: "warning",
- confirmButtonText: "鍒犻櫎",
- cancelButtonText: "鍙栨秷",
- });
- allRows.value = allRows.value.filter((r) => r.id !== row.id);
- return true;
- } catch {
- return false;
- }
- }
-
- return {
- Search,
- NOTICE_TYPE_OPTIONS,
- PRIORITY_OPTIONS,
- PUBLISH_STATUS_OPTIONS,
- READ_SCOPE_OPTIONS,
- DEPT_OPTIONS,
- noticeTypeLabel,
- searchForm,
- tableLoading,
- page,
- tableData,
- tableColumn,
- formDialog,
- form,
- formRef,
- formRules,
- detailDialog,
- detailRow,
- isExpired,
- handleQuery,
- resetSearch,
- pagination,
- openFormDialog,
- openDetail,
- saveForm,
- publishNotice,
- withdrawNotice,
- deleteNotice,
- };
-}
--
Gitblit v1.9.3