From a1df9699594b0a0e46d26a0394eafb1eb030c68b Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 20 五月 2026 17:42:09 +0800
Subject: [PATCH] 企业新闻
---
src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue | 298 +++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 179 insertions(+), 119 deletions(-)
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue
index f444153..13decff 100644
--- a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue
@@ -1,4 +1,4 @@
-<!--OA妯″潡锛欵nterpriseNews 浼佷笟鏂伴椈锛堝垪琛ㄨ蛋瀹℃壒瀹炰緥锛屾柊澧�/淇敼淇濈暀鍘熻〃鍗� + 妯℃澘瀹℃壒娴佺▼锛�-->
+<!--OA妯″潡锛欵nterpriseNews 浼佷笟鏂伴椈锛坙istPage|save|update|delete锛屾柊寤轰繚鐣欏鎵规ā鏉匡級-->
<template>
<div class="app-container enterprise-news-page">
<div class="search_form mb20">
@@ -7,7 +7,7 @@
<el-input
v-model="searchForm.keyword"
style="width: 200px"
- placeholder="鏍囬 / 缂栧彿 / 鎽樿"
+ placeholder="鏍囬"
clearable
:prefix-icon="Search"
@keyup.enter="onSearch"
@@ -16,16 +16,16 @@
<el-select v-model="searchForm.newsType" placeholder="鍏ㄩ儴" clearable style="width: 140px">
<el-option v-for="opt in NEWS_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
- <span class="search_title" style="margin-left: 12px">瀹℃壒鐘舵�侊細</span>
+ <span class="search_title" style="margin-left: 12px">鐘舵�侊細</span>
<el-select v-model="searchForm.status" placeholder="鍏ㄩ儴" clearable style="width: 120px">
<el-option
- v-for="opt in APPROVAL_STATUS_SEARCH_OPTIONS"
+ v-for="opt in ENTERPRISE_NEWS_STATUS_SEARCH_OPTIONS"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
- <span class="search_title" style="margin-left: 12px">鐢宠鏃ユ湡锛�</span>
+ <span class="search_title" style="margin-left: 12px">鍒涘缓鏃堕棿锛�</span>
<el-date-picker
v-model="searchForm.createTimeRange"
type="daterange"
@@ -72,7 +72,6 @@
@closed="onTemplateBindClosed"
/>
- <!-- 鏂板缓 / 缂栬緫锛氬師浼佷笟鏂伴椈琛ㄥ崟 + 妯℃澘瀹℃壒娴佺▼ -->
<el-dialog
v-model="newsFormDialog.visible"
:title="newsFormDialog.title"
@@ -171,45 +170,41 @@
<el-form-item label="鏀跨瓥绫诲繀璇�">
<el-switch v-model="newsForm.requireReadConfirm" active-text="闇�闃呰纭锛堜究浜庣粺璁℃湭璇伙級" />
</el-form-item>
- <el-form-item label="鍙戝竷浜�">
- <el-input v-model="newsForm.publisherName" placeholder="濡傦細浜哄姏璧勬簮閮�" maxlength="50" />
- </el-form-item>
- <template v-if="activeTemplate">
+ <template v-if="hasApprovalTemplate">
<el-divider content-position="left">瀹℃壒娴佺▼</el-divider>
<el-form-item label="瀹℃壒妯℃澘">
- <span class="template-name">{{ activeTemplate.label || submitForm.templateName }}</span>
+ <span class="template-name">{{ approvalTemplateLabel }}</span>
</el-form-item>
- <el-form-item label="瀹℃壒娴佺▼" required>
+ <el-form-item v-if="activeTemplate" label="瀹℃壒娴佺▼" required>
<TemplateFlowEditor v-model="submitForm.flowNodes" :user-options="flowUserOptions" />
<p class="section-tip">娴佺▼涓庡鎵逛汉鐢辨ā鏉块缃紝鍙寜闇�寰皟鑺傜偣瀹℃壒浜恒��</p>
</el-form-item>
</template>
- <el-alert v-else type="warning" show-icon :closable="false" title="璇峰厛閫氳繃銆屾柊寤烘柊闂汇�嶉�夋嫨瀹℃壒妯℃澘" />
+ <el-alert
+ v-else-if="!isNewsEdit"
+ type="warning"
+ show-icon
+ :closable="false"
+ title="璇峰厛閫氳繃銆屾柊寤烘柊闂汇�嶉�夋嫨瀹℃壒妯℃澘"
+ />
</el-form>
<template v-if="!newsFormDialog.readonly" #footer>
<el-button @click="newsFormDialog.visible = false">鍙� 娑�</el-button>
- <el-button :loading="submitSaving" @click="onNewsSave('draft')">瀛樿崏绋�</el-button>
- <el-button type="warning" :loading="submitSaving" @click="onNewsSave('submit_review')">
+ <el-button :loading="newsSaving" @click="onNewsSave('draft')">瀛樿崏绋�</el-button>
+ <el-button type="warning" :loading="newsSaving" @click="onNewsSave('submit_review')">
鎻愪氦瀹℃牳
</el-button>
- <el-button type="primary" :loading="submitSaving" @click="onNewsSave('submit_review')">
+ <el-button type="primary" :loading="newsSaving" @click="onNewsSave('submit_review')">
淇� 瀛�
</el-button>
</template>
</el-dialog>
- <!-- 璇︽儏 -->
<el-dialog v-model="detailDialog.visible" title="鏂伴椈璇︽儏" width="880px" append-to-body destroy-on-close>
<NewsDetailPanel :row="detailNewsRow" />
- <el-divider content-position="left">瀹℃壒淇℃伅</el-divider>
- <ApproveDetailPanel :row="detailRow" />
<template #footer>
- <el-button
- v-if="canEditBusinessInstanceRow(detailRow)"
- type="primary"
- @click="openNewsEditFromDetail"
- >
+ <el-button v-if="canEditEnterpriseNewsRow(detailRow)" type="primary" @click="openNewsEditFromDetail">
淇敼
</el-button>
<el-button @click="detailDialog.visible = false">鍏� 闂�</el-button>
@@ -220,22 +215,27 @@
<script setup>
import { Plus, RefreshRight, Search } from "@element-plus/icons-vue";
-import { ElMessage } from "element-plus";
+import { ElMessage, ElMessageBox } from "element-plus";
+import {
+ deleteEnterpriseNews,
+ saveEnterpriseNews,
+ updateEnterpriseNews,
+} from "@/api/officeProcessAutomation/enterpriseNews.js";
import { computed, onMounted, reactive, ref } from "vue";
-import useUserStore from "@/store/modules/user";
import Editor from "@/components/Editor/index.vue";
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
-import { APPROVAL_STATUS_SEARCH_OPTIONS } from "../../ApproveManage/approve-list/approveListConstants.js";
-import ApproveDetailPanel from "../../ApproveManage/approve-list/components/ApproveDetailPanel.vue";
-import { buildEditFormFromInstanceRow } from "../../ApproveManage/approve-list/approveListConstants.js";
import ApprovalTemplateBindDialog from "../../ApproveManage/approve-shared/components/ApprovalTemplateBindDialog.vue";
import TemplateFlowEditor from "../../ApproveManage/approve-template/components/TemplateFlowEditor.vue";
import {
applyBindingToForm,
validateTemplateBinding,
} from "../../ApproveManage/approve-shared/approvalTemplateBindingUtils.js";
+import { createEmptySubmitForm } from "../../ApproveManage/approve-list/approveListConstants.js";
import { APPROVAL_MODULE_KEYS } from "../../ApproveManage/approve-shared/approvalModuleRegistry.js";
-import { useApprovalInstanceModule } from "../../ApproveManage/approve-shared/useApprovalInstanceModule.js";
+import {
+ applyBindingToForm,
+ validateTemplateBinding,
+} from "../../ApproveManage/approve-shared/approvalTemplateBindingUtils.js";
import { useFlowUserOptions } from "../../ApproveManage/approve-shared/useFlowUserOptions.js";
import NewsDetailPanel from "./components/NewsDetailPanel.vue";
import {
@@ -245,18 +245,18 @@
PUBLISH_ROLE_OPTIONS,
DEPT_OPTIONS,
createEmptyForm,
+ ENTERPRISE_NEWS_STATUS_SEARCH_OPTIONS,
newsTypeColor,
newsTypeLabel,
validateNewsForm,
} from "./enterpriseNewsUtils.js";
import {
- enrichEnterpriseNewsListRow,
- extractEnterpriseNewsFromRow,
- syncNewsFormToSubmitPayload,
+ buildEnterpriseNewsSaveDto,
buildEnterpriseNewsTableColumns,
-} from "./enterpriseNewsApprovalBridge.js";
-
-const userStore = useUserStore();
+ canEditEnterpriseNewsRow,
+ mapApiRowToNewsForm,
+} from "./enterpriseNewsMappers.js";
+import { useEnterpriseNewsList } from "./useEnterpriseNewsList.js";
const searchForm = reactive({
keyword: "",
@@ -266,6 +266,8 @@
});
const newsFormDialog = reactive({ visible: false, title: "", mode: "add", readonly: false });
+const detailDialog = reactive({ visible: false });
+const detailRow = ref({});
const newsForm = reactive(createEmptyForm());
const newsFormRef = ref();
const galleryInput = ref("");
@@ -276,66 +278,44 @@
readScope: [{ required: true, message: "璇烽�夋嫨闃呰鑼冨洿", trigger: "change" }],
};
-const mod = useApprovalInstanceModule({
- moduleKey: APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS,
- enrichListRow: enrichEnterpriseNewsListRow,
- buildExtraListParams(sf) {
- const extra = {};
- const kw = (sf?.keyword || "").trim();
- if (kw) extra.title = kw;
- if (sf?.newsType) extra.newsType = sf.newsType;
- return extra;
- },
- async beforeSave(submitForm) {
- const v = validateNewsForm(newsForm);
- if (!v.ok) {
- ElMessage.warning(v.message);
- throw new Error(v.message);
- }
- if (!activeTemplate.value) {
- ElMessage.warning("璇峰厛閫夋嫨瀹℃壒妯℃澘");
- throw new Error("no template");
- }
- const bindingCheck = validateTemplateBinding({ flowNodes: submitForm.flowNodes });
- if (!bindingCheck.ok) {
- ElMessage.warning(bindingCheck.message);
- throw new Error(bindingCheck.message);
- }
- syncNewsFormToSubmitPayload(newsForm, submitForm);
- },
-});
+const newsList = useEnterpriseNewsList();
+const { tableData, tableLoading, page, handleQuery: fetchNewsList, pagination: paginateNewsList } =
+ newsList;
-const {
- tableData,
- tableLoading,
- page,
- detailDialog,
- detailRow,
- submitDialog,
- submitForm,
- submitSaving,
- isSubmitEdit,
- activeTemplate,
- templateBindVisible,
- pendingTemplateBinding,
- submitEditRow,
- handleQuery,
- initModuleList,
- pagination,
- openAddWithTemplate,
- onTemplateBound,
- resetSubmitForm,
- submitInstanceForm,
- removeInstance,
- canEditBusinessInstanceRow,
-} = mod;
+const submitForm = reactive(createEmptySubmitForm(""));
+const templateBindVisible = ref(false);
+const pendingTemplateBinding = ref(null);
+const newsSaving = ref(false);
+
+const isNewsEdit = computed(() => newsFormDialog.mode === "edit");
+const activeTemplate = computed(() => submitForm.templateSnapshot || null);
+const hasApprovalTemplate = computed(
+ () => Boolean(activeTemplate.value || newsForm.templateId)
+);
+const approvalTemplateLabel = computed(
+ () =>
+ activeTemplate.value?.label ||
+ newsForm.templateName ||
+ submitForm.templateName ||
+ "鈥�"
+);
const { flowUserOptions, loadFlowUsers } = useFlowUserOptions();
-const detailNewsRow = computed(() => {
- if (!detailRow.value?.id) return {};
- return extractEnterpriseNewsFromRow(detailRow.value);
-});
+function openAddWithTemplate() {
+ pendingTemplateBinding.value = null;
+ templateBindVisible.value = true;
+}
+
+function onTemplateBound(binding) {
+ pendingTemplateBinding.value = binding;
+}
+
+function resetSubmitForm() {
+ Object.assign(submitForm, createEmptySubmitForm(""));
+}
+
+const detailNewsRow = computed(() => mapApiRowToNewsForm(detailRow.value));
const tableColumn = ref(
buildEnterpriseNewsTableColumns(() => [
@@ -343,13 +323,14 @@
{
name: "淇敼",
type: "text",
- disabled: (row) => !canEditBusinessInstanceRow(row),
+ disabled: (row) => !canEditEnterpriseNewsRow(row),
clickFun: (row) => openNewsEdit(row),
},
{
name: "鍒犻櫎",
type: "danger",
- clickFun: (row) => removeInstance(row),
+ disabled: (row) => !canEditEnterpriseNewsRow(row),
+ clickFun: (row) => handleNewsDelete(row),
},
])
);
@@ -364,11 +345,9 @@
newsFormDialog.title =
mode === "add" ? "鏂板缓浼佷笟鏂伴椈" : mode === "edit" ? "缂栬緫浼佷笟鏂伴椈" : "鏌ョ湅浼佷笟鏂伴椈";
if (mode === "add") {
- resetNewsForm({
- publisherName: userStore?.nickName || userStore?.name || "褰撳墠鐢ㄦ埛",
- });
+ resetNewsForm();
} else if (row) {
- resetNewsForm(extractEnterpriseNewsFromRow(row));
+ resetNewsForm(mapApiRowToNewsForm(row));
}
newsFormDialog.visible = true;
}
@@ -379,19 +358,23 @@
pendingTemplateBinding.value = null;
resetSubmitForm();
applyBindingToForm(submitForm, binding);
- submitDialog.mode = "add";
- submitEditRow.value = null;
+ if (binding.templateId) {
+ newsForm.templateId = binding.templateId;
+ newsForm.templateName = binding.templateName || "";
+ }
openNewsFormDialog("add");
}
function openNewsEdit(row) {
- if (!canEditBusinessInstanceRow(row)) {
- ElMessage.warning("杩涜涓垨宸插畬鎴愮殑瀹℃壒涓嶅彲淇敼");
+ if (!canEditEnterpriseNewsRow(row)) {
+ ElMessage.warning("褰撳墠鐘舵�佷笉鍙慨鏀�");
return;
}
- submitDialog.mode = "edit";
- submitEditRow.value = { ...row };
- Object.assign(submitForm, buildEditFormFromInstanceRow(row));
+ resetSubmitForm();
+ if (row?.templateId != null) {
+ submitForm.templateId = row.templateId;
+ submitForm.templateName = row.templateName || "";
+ }
openNewsFormDialog("edit", row);
}
@@ -404,6 +387,40 @@
const row = detailRow.value;
detailDialog.visible = false;
openNewsEdit(row);
+}
+
+async function handleNewsDelete(row) {
+ if (!canEditEnterpriseNewsRow(row)) {
+ ElMessage.warning("褰撳墠鐘舵�佷笉鍙垹闄�");
+ return;
+ }
+ if (row?.id == null || row.id === "") {
+ ElMessage.warning("鏃犳硶鍒犻櫎锛氱己灏戞柊闂� ID");
+ return;
+ }
+ const title = (row.title || "").trim() || "璇ユ潯鏂伴椈";
+ try {
+ await ElMessageBox.confirm(
+ `纭畾瑕佸垹闄ゃ��${title}銆嶅悧锛熷垹闄ゅ悗涓嶅彲鎭㈠銆俙,
+ "鍒犻櫎纭",
+ {
+ type: "warning",
+ confirmButtonText: "纭畾鍒犻櫎",
+ cancelButtonText: "鍙栨秷",
+ distinguishCancelAndClose: true,
+ autofocus: false,
+ }
+ );
+ } catch {
+ return;
+ }
+ try {
+ await deleteEnterpriseNews([row.id]);
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ await fetchNewsList(searchForm);
+ } catch {
+ /* 閿欒鐢辫姹傛嫤鎴櫒鎻愮ず */
+ }
}
function onNewsFormClosed() {
@@ -425,19 +442,67 @@
ElMessage.warning("璇峰畬鍠勮〃鍗曞繀濉」鍚庡啀淇濆瓨");
return;
}
- if (action === "draft") newsForm.publishStatus = "draft";
- else newsForm.publishStatus = "pending_review";
- const ok = await submitInstanceForm({ skipValidate: true });
- if (ok) {
+ const v = validateNewsForm(newsForm);
+ if (!v.ok) {
+ ElMessage.warning(v.message);
+ return;
+ }
+ const status = action === "draft" ? "DRAFT" : "PENDING";
+ newsForm.publishStatus = status;
+
+ if (!isNewsEdit.value) {
+ const templateId = newsForm.templateId || submitForm.templateId;
+ if (!templateId) {
+ ElMessage.warning("璇峰厛閫夋嫨瀹℃壒妯℃澘");
+ return;
+ }
+ if (!newsForm.templateId) newsForm.templateId = templateId;
+ if (!newsForm.templateName && submitForm.templateName) {
+ newsForm.templateName = submitForm.templateName;
+ }
+ if (action !== "draft") {
+ const bindingCheck = validateTemplateBinding({ flowNodes: submitForm.flowNodes });
+ if (!bindingCheck.ok) {
+ ElMessage.warning(bindingCheck.message);
+ return;
+ }
+ }
+ } else if (!newsForm.templateId && submitForm.templateId) {
+ newsForm.templateId = submitForm.templateId;
+ newsForm.templateName = submitForm.templateName || newsForm.templateName;
+ }
+
+ const dto = buildEnterpriseNewsSaveDto(newsForm, { status });
+ if (isNewsEdit.value) {
+ if (dto.id == null) {
+ ElMessage.warning("鏃犳硶淇敼锛氱己灏戞柊闂� ID");
+ return;
+ }
+ }
+
+ if (newsSaving.value) return;
+ newsSaving.value = true;
+ try {
+ if (isNewsEdit.value) {
+ await updateEnterpriseNews(dto);
+ } else {
+ await saveEnterpriseNews(dto);
+ }
newsFormDialog.visible = false;
const msg =
- action === "draft" ? "宸蹭繚瀛樿崏绋�" : isSubmitEdit.value ? "淇敼鎴愬姛" : "宸叉彁浜ゅ鏍�";
+ action === "draft" ? "宸蹭繚瀛樿崏绋�" : isNewsEdit.value ? "淇敼鎴愬姛" : "宸叉彁浜ゅ鏍�";
ElMessage.success(msg);
+ if (!isNewsEdit.value) page.current = 1;
+ await fetchNewsList(searchForm);
+ } catch {
+ /* 閿欒鐢辫姹傛嫤鎴櫒鎻愮ず */
+ } finally {
+ newsSaving.value = false;
}
}
function onSearch() {
- handleQuery(searchForm);
+ fetchNewsList(searchForm);
}
function resetSearch() {
@@ -449,17 +514,12 @@
}
function onPagination(obj) {
- pagination(obj, searchForm);
+ paginateNewsList(obj, searchForm);
}
-onMounted(async () => {
- try {
- localStorage.removeItem("oa_enterprise_news_v1");
- } catch {
- /* 娓呴櫎鍘嗗彶鏈湴婕旂ず缂撳瓨 */
- }
+onMounted(() => {
loadFlowUsers();
- await initModuleList(searchForm);
+ fetchNewsList(searchForm);
});
</script>
--
Gitblit v1.9.3