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/HrManage/regular-apply/index.vue | 9
src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue | 6
src/api/officeProcessAutomation/enterpriseNews.js | 38 ++
src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsUtils.js | 43 ++
src/views/officeProcessAutomation/EnterpriseNews/news-manage/components/NewsDetailPanel.vue | 8
src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalInstanceFormConfigTable.js | 41 ++
src/views/officeProcessAutomation/EnterpriseNews/news-manage/index.vue | 298 +++++++++++-------
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js | 122 ++++++
src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsApprovalBridge.js | 109 ------
src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsMappers.js | 224 ++++++++++++++
src/views/officeProcessAutomation/EnterpriseNews/news-manage/useEnterpriseNewsList.js | 55 +++
11 files changed, 698 insertions(+), 255 deletions(-)
diff --git a/src/api/officeProcessAutomation/enterpriseNews.js b/src/api/officeProcessAutomation/enterpriseNews.js
new file mode 100644
index 0000000..52f345d
--- /dev/null
+++ b/src/api/officeProcessAutomation/enterpriseNews.js
@@ -0,0 +1,38 @@
+import request from "@/utils/request";
+
+/** 鍒嗛〉鏌ヨ浼佷笟鏂伴椈 */
+export function listEnterpriseNewsPage(params) {
+ return request({
+ url: "/enterpriseNews/listPage",
+ method: "get",
+ params,
+ });
+}
+
+/** 鏂板浼佷笟鏂伴椈 */
+export function saveEnterpriseNews(enterpriseNewsDto) {
+ return request({
+ url: "/enterpriseNews/save",
+ method: "post",
+ data: enterpriseNewsDto,
+ });
+}
+
+/** 淇敼浼佷笟鏂伴椈 */
+export function updateEnterpriseNews(enterpriseNewsDto) {
+ return request({
+ url: "/enterpriseNews/update",
+ method: "put",
+ data: enterpriseNewsDto,
+ });
+}
+
+/** 鍒犻櫎浼佷笟鏂伴椈锛坆ody 涓� ID 鏁扮粍锛� */
+export function deleteEnterpriseNews(ids) {
+ const idList = (Array.isArray(ids) ? ids : [ids]).filter((id) => id != null && id !== "");
+ return request({
+ url: "/enterpriseNews/delete",
+ method: "delete",
+ data: idList,
+ });
+}
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
index c16dcd8..4aa3c61 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -33,6 +33,7 @@
/** 鍒楄〃鏌ヨ锛氬鎵圭姸鎬侊紙涓庡悗绔� status 鏋氫妇涓�鑷达級 */
export const APPROVAL_STATUS_SEARCH_OPTIONS = [
+ { value: "DRAFT", label: "鑽夌" },
{ value: "PENDING", label: "寰呭鎵�" },
{ value: "APPROVED", label: "宸查�氳繃" },
{ value: "REJECTED", label: "宸查┏鍥�" },
@@ -40,34 +41,105 @@
/**
* 瀹℃壒鐘舵�佸睍绀猴紙涓庡悗绔� status 鏋氫妇涓�鑷达級
- * PENDING 鈫� 寰呭鎵�/杩涜涓� APPROVED 鈫� 宸查�氳繃/宸插畬鎴� REJECTED 鈫� 宸查┏鍥�
+ * DRAFT鈫掕崏绋� PENDING鈫掑緟瀹℃壒/杩涜涓� APPROVED鈫掑凡閫氳繃/宸插畬鎴� REJECTED鈫掑凡椹冲洖
*/
export const APPROVAL_STATUS_OPTIONS = [
+ { value: "draft", api: "DRAFT", label: "鑽夌" },
{ value: "pending", api: "PENDING", label: "寰呭鎵�" },
{ value: "approved", api: "APPROVED", label: "宸查�氳繃" },
{ value: "rejected", api: "REJECTED", label: "宸查┏鍥�" },
{ value: "cancelled", api: "CANCELLED", label: "宸叉挙閿�" },
];
+/** 鏁板瓧鐘舵�佺爜锛堥儴鍒嗗悗绔敤 0/1/2锛� */
+const STATUS_NUMERIC_MAP = {
+ 0: "pending",
+ 1: "approved",
+ 2: "rejected",
+ 3: "cancelled",
+ 4: "cancelled",
+};
+
/** 鍚庣 status / 椤甸潰 approvalStatus 鈫� 缁熶竴椤甸潰 key锛坧ending | approved | rejected | cancelled锛� */
export function normalizeApprovalStatusKey(v) {
- const s = String(v ?? "").trim();
+ if (v == null || v === "") return "pending";
+ if (typeof v === "number" || (typeof v === "string" && /^\d+$/.test(v.trim()))) {
+ const numKey = STATUS_NUMERIC_MAP[Number(v)];
+ if (numKey) return numKey;
+ }
+ const s = String(v).trim();
if (!s) return "pending";
const upper = s.toUpperCase();
- if (upper === "APPROVED" || upper === "APPROVE" || upper === "PASS") return "approved";
- if (upper === "REJECTED" || upper === "REJECT" || upper === "REFUSE") return "rejected";
- if (upper === "CANCELLED" || upper === "CANCEL") return "cancelled";
+ if (upper === "DRAFT") return "draft";
+ if (upper === "PUBLISHED") return "approved";
+ if (upper === "OFFLINE") return "cancelled";
+ if (upper === "APPROVED" || upper === "APPROVE" || upper === "PASS" || upper === "AGREE") {
+ return "approved";
+ }
+ if (
+ upper === "REJECTED" ||
+ upper === "REJECT" ||
+ upper === "REFUSE" ||
+ upper === "REFUSED" ||
+ upper === "DENIED"
+ ) {
+ return "rejected";
+ }
+ if (upper === "CANCELLED" || upper === "CANCEL" || upper === "REVOKED") return "cancelled";
if (
upper === "PENDING" ||
upper === "IN_PROGRESS" ||
upper === "PROCESSING" ||
- upper === "RUNNING"
+ upper === "RUNNING" ||
+ upper === "WAIT" ||
+ upper === "WAITING"
) {
return "pending";
}
+ if (s.includes("鑽夌")) return "draft";
+ if (s.includes("椹冲洖") || s.includes("鎷掔粷")) return "rejected";
+ if (s.includes("涓嬬嚎")) return "cancelled";
+ if (s.includes("鎾ら攢")) return "cancelled";
+ if (s.includes("鍙戝竷") || s.includes("閫氳繃") || s.includes("瀹屾垚")) return "approved";
+ if (s.includes("寰呭") || s.includes("杩涜涓�") || s.includes("瀹℃壒涓�")) return "pending";
const lower = s.toLowerCase();
- if (["pending", "approved", "rejected", "cancelled"].includes(lower)) return lower;
+ if (["draft", "pending", "approved", "rejected", "cancelled"].includes(lower)) return lower;
return "pending";
+}
+
+/** 浠庡垪琛�/璇︽儏琛岃В鏋愬悗绔師濮嬬姸鎬侊紙鍏煎澶氬瓧娈靛懡鍚嶏級 */
+export function resolveInstanceStatusRaw(row) {
+ if (!row || typeof row !== "object") return "";
+ const candidates = [
+ row.status,
+ row.statusRaw,
+ row.approvalStatus,
+ row.statusName,
+ row.statusLabel,
+ row.approvalStatusName,
+ row.statusDesc,
+ row.instanceStatus,
+ row.approvalInstanceStatus,
+ row.approveStatus,
+ row.auditStatus,
+ row.approvalInstance?.status,
+ row.approvalInstanceVo?.status,
+ ];
+ for (const c of candidates) {
+ if (c != null && c !== "") return c;
+ }
+ const tasks = row.tasks;
+ if (Array.isArray(tasks) && tasks.length) {
+ const rejected = tasks.some((t) =>
+ normalizeApprovalStatusKey(t?.status ?? t?.taskStatus) === "rejected"
+ );
+ if (rejected) return "REJECTED";
+ const allApproved = tasks.every((t) =>
+ normalizeApprovalStatusKey(t?.status ?? t?.taskStatus) === "approved"
+ );
+ if (allApproved) return "APPROVED";
+ }
+ return "";
}
/** 鎻愪氦寮圭獥锛氭ā鏉垮崱鐗囷紙鏉ヨ嚜鍚庣鍒楄〃锛� */
@@ -322,12 +394,15 @@
dto.id = existingRow?.id ?? submitForm?.instanceId;
dto.instanceNo = existingRow?.instanceNo ?? submitForm?.instanceNo ?? "";
dto.status =
- existingRow?.statusRaw || mapInstanceStatusToApi(existingRow?.approvalStatus) || "PENDING";
+ submitForm?.saveStatusApi ||
+ existingRow?.statusRaw ||
+ mapInstanceStatusToApi(existingRow?.approvalStatus) ||
+ "PENDING";
dto.currentLevel = existingRow?.currentLevel ?? submitForm?.currentLevel ?? 1;
dto.applicantId = existingRow?.applicantId ?? existingRow?.applicantNo;
dto.applicantName = existingRow?.applicantName || "";
} else {
- dto.status = "PENDING";
+ dto.status = submitForm?.saveStatusApi || "PENDING";
dto.currentLevel = 1;
dto.applicantId = userStore?.id;
dto.applicantName = userStore?.nickName || userStore?.name || "";
@@ -352,6 +427,12 @@
return normalizeApprovalStatusKey(status);
}
+/** 鍒楄〃/璇︽儏琛� 鈫� 椤甸潰 approvalStatus key */
+export function mapInstanceApprovalStatusFromRow(row) {
+ const raw = resolveInstanceStatusRaw(row);
+ return normalizeApprovalStatusKey(raw);
+}
+
/** 椤甸潰 approvalStatus 鈫� 鍚庣 status */
export function mapInstanceStatusToApi(approvalStatus) {
const key = normalizeApprovalStatusKey(approvalStatus);
@@ -370,7 +451,8 @@
/** 鍒嗛〉鍒楄〃椤� 鈫� 琛ㄦ牸琛� */
export function mapInstanceFromApi(row) {
if (!row) return {};
- const approvalStatus = mapInstanceStatusFromApi(row.status);
+ const statusRaw = resolveInstanceStatusRaw(row);
+ const approvalStatus = normalizeApprovalStatusKey(statusRaw);
const createTime = formatDisplayTime(row.createTime ?? row.applyTime ?? "");
const applyTime = formatDisplayTime(row.applyTime ?? "");
const finishTime = formatDisplayTime(row.finishTime ?? "");
@@ -397,7 +479,7 @@
unread: Boolean(row.isApprove) && approvalStatus === "pending",
isApprove: Boolean(row.isApprove),
approvalStatus,
- statusRaw: row.status,
+ statusRaw: statusRaw || row.status,
createTime,
applyTime: applyTime === "鈥�" ? "" : applyTime,
finishTime: finishTime === "鈥�" ? "" : finishTime,
@@ -439,10 +521,16 @@
}
export function buildApprovalInstanceListParams({ page, searchForm, businessType, extraParams }) {
+ const extra = { ...(extraParams && typeof extraParams === "object" ? extraParams : {}) };
+ if (extra.createTime != null && extra.createTimeStart == null) {
+ extra.createTimeStart = extra.createTime;
+ }
+ delete extra.createTime;
+
const params = {
current: page.current,
size: page.size,
- ...(extraParams && typeof extraParams === "object" ? extraParams : {}),
+ ...extra,
};
const bizType = businessType ?? searchForm?.businessType;
if (bizType != null && bizType !== "") {
@@ -451,9 +539,12 @@
if (searchForm?.status) {
params.status = searchForm.status;
}
- const range = searchForm?.createTimeRange;
+ const range =
+ searchForm?.createTimeRange ??
+ searchForm?.applyDateRange ??
+ searchForm?.transferDateRange;
if (Array.isArray(range) && range[0]) {
- params.createTime = range[0];
+ params.createTimeStart = range[0];
}
if (Array.isArray(range) && range[1]) {
params.createTimeEnd = range[1];
@@ -483,6 +574,7 @@
/** 涓氬姟鐢宠椤电姸鎬佹枃妗堬細PENDING鈫掕繘琛屼腑 APPROVED鈫掑凡瀹屾垚 REJECTED鈫掑凡椹冲洖 */
export function businessApprovalStatusLabel(v) {
const key = normalizeApprovalStatusKey(v);
+ if (key === "draft") return "鑽夌";
if (key === "pending") return "杩涜涓�";
if (key === "approved") return "宸插畬鎴�";
if (key === "rejected") return "宸查┏鍥�";
@@ -503,6 +595,7 @@
export function businessApprovalStatusTagType(v) {
const key = normalizeApprovalStatusKey(v);
+ if (key === "draft") return "info";
if (key === "approved") return "success";
if (key === "rejected") return "danger";
if (key === "cancelled") return "info";
@@ -511,6 +604,7 @@
export function approvalStatusTagType(v) {
const key = normalizeApprovalStatusKey(v);
+ if (key === "draft") return "info";
if (key === "approved") return "success";
if (key === "rejected") return "danger";
if (key === "cancelled") return "info";
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalInstanceFormConfigTable.js b/src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalInstanceFormConfigTable.js
index 895ff0d..fef178f 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalInstanceFormConfigTable.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalInstanceFormConfigTable.js
@@ -6,8 +6,41 @@
resolveInstanceFormFields,
} from "../approve-list/approveListConstants.js";
-/** 鍒楄〃/璇︽儏涓嶅洖鏄句负鐙珛鍒楃殑濉姤椤� key */
-const DEFAULT_EXCLUDE_KEYS = new Set(["summary"]);
+/** 鍒楄〃/璇︽儏涓嶅洖鏄句负鐙珛鍒楃殑濉姤椤� key锛堥伩鍏嶈鐩栧疄渚嬬郴缁熷瓧娈碉級 */
+const DEFAULT_EXCLUDE_KEYS = new Set([
+ "summary",
+ "status",
+ "approvalStatus",
+ "approvalstatus",
+ "instanceStatus",
+ "publishStatus",
+ "newsStatus",
+]);
+
+/** enrich 鍚庡繀椤讳繚鐣欑殑瀹炰緥瀛楁锛堜笉琚� formConfig 閾哄钩瑕嗙洊锛� */
+const PRESERVE_INSTANCE_FIELDS = [
+ "id",
+ "approvalStatus",
+ "statusRaw",
+ "status",
+ "instanceNo",
+ "templateId",
+ "templateName",
+ "businessType",
+ "businessId",
+ "businessName",
+ "applicantId",
+ "applicantNo",
+ "applicantName",
+ "createTime",
+ "applyTime",
+ "finishTime",
+ "title",
+ "isApprove",
+ "unread",
+ "currentLevel",
+ "newsStatus",
+];
/**
* 浠庤鏁版嵁 formConfig 瑙f瀽瀛楁瀹氫箟涓庡~鎶ュ�硷紝骞堕摵骞冲埌琛屼笂渚涗富琛� prop 缁戝畾锛堝睍绀虹敤鏍煎紡鍖栧�硷級
@@ -41,6 +74,10 @@
displayRow[f.key] = text;
}
+ for (const key of PRESERVE_INSTANCE_FIELDS) {
+ if (row[key] !== undefined) displayRow[key] = row[key];
+ }
+
return displayRow;
}
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/components/NewsDetailPanel.vue b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/components/NewsDetailPanel.vue
index bb25ba0..1124472 100644
--- a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/components/NewsDetailPanel.vue
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/components/NewsDetailPanel.vue
@@ -2,9 +2,9 @@
<template>
<el-descriptions :column="2" border>
<el-descriptions-item label="鏂伴椈缂栧彿">{{ row.newsNo || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鐘舵��">
- <el-tag :type="publishStatusTag(row.publishStatus)" size="small">
- {{ publishStatusLabel(row.publishStatus) }}
+ <el-descriptions-item label="鐘舵��">
+ <el-tag :type="publishStatusTag(row.newsStatus ?? row.publishStatus)" size="small">
+ {{ publishStatusLabel(row.newsStatus ?? row.publishStatus) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="鏂伴椈鍒嗙被">
@@ -57,7 +57,7 @@
</template>
<el-empty v-else description="鏆傛棤闄勪欢" :image-size="48" />
- <template v-if="row.newsType === 'culture' && row.publishStatus === 'published'">
+ <template v-if="row.newsType === 'culture' && (row.publishStatus === 'PUBLISHED' || row.publishStatus === 'published')">
<el-divider content-position="left">浜掑姩锛堢偣璧� {{ likeCount }} 路 璇勮 {{ commentCount }}锛�</el-divider>
<div class="interaction-bar">
<el-button type="primary" plain size="small" @click="$emit('like')">
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsApprovalBridge.js b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsApprovalBridge.js
index f61d9a9..b870ab7 100644
--- a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsApprovalBridge.js
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsApprovalBridge.js
@@ -1,98 +1,11 @@
-import {
- createEmptyForm,
- publishStatusLabel,
- PUBLISH_STATUS_OPTIONS,
-} from "./enterpriseNewsUtils.js";
-import { normalizeApprovalStatusKey } from "../../ApproveManage/approve-list/approveListConstants.js";
-
-/** formPayload 涓瓨鏀惧畬鏁翠紒涓氭柊闂讳笟鍔℃暟鎹殑閿� */
-export const ENTERPRISE_NEWS_PAYLOAD_KEY = "enterpriseNews";
-
-export function extractEnterpriseNewsFromRow(row) {
- const payload = row?.formPayload || {};
- const raw = payload[ENTERPRISE_NEWS_PAYLOAD_KEY];
- if (raw && typeof raw === "object") {
- return { ...createEmptyForm(), ...raw };
- }
- return {
- ...createEmptyForm(),
- title: payload.title || row?.title || "",
- summary: payload.summary || "",
- newsType: payload.newsType || "announcement",
- contentHtml: payload.contentHtml || "",
- };
-}
-
-/** 鍒楄〃琛屽寮猴細涓昏〃灞曠ず鏂伴椈瀛楁 */
-export function enrichEnterpriseNewsListRow(row) {
- const news = extractEnterpriseNewsFromRow(row);
- const publishStatus =
- news.publishStatus || mapApprovalStatusToPublishStatus(row?.approvalStatus);
- return {
- ...row,
- newsNo: news.newsNo || row.instanceNo || "鈥�",
- title: news.title || row.title || "鈥�",
- summary: news.summary,
- newsType: news.newsType,
- publisherName: news.publisherName || row.applicantName || "鈥�",
- publishTime: news.publishTime || row.createTime || "",
- updateTime: news.updateTime || row.createTime || "",
- publishStatus,
- _news: news,
- };
-}
-
-function mapApprovalStatusToPublishStatus(approvalStatus) {
- const key = normalizeApprovalStatusKey(approvalStatus);
- if (key === "approved") return "published";
- if (key === "pending") return "pending_review";
- if (key === "rejected") return "draft";
- return "draft";
-}
-
-/** 浼佷笟鏂伴椈琛ㄥ崟 鈫� 瀹℃壒瀹炰緥 formPayload */
-export function syncNewsFormToSubmitPayload(newsForm, submitForm) {
- const snapshot = JSON.parse(JSON.stringify(newsForm));
- submitForm.formPayload = {
- ...(submitForm.formPayload || {}),
- [ENTERPRISE_NEWS_PAYLOAD_KEY]: snapshot,
- title: snapshot.title,
- summary: snapshot.summary,
- };
-}
-
-export function buildEnterpriseNewsTableColumns(buildTableActions) {
- return [
- { label: "缂栧彿", prop: "newsNo", width: 150 },
- { label: "鏍囬", prop: "title", minWidth: 180, showOverflowTooltip: true },
- {
- label: "鍒嗙被",
- prop: "newsType",
- width: 100,
- dataType: "slot",
- slot: "newsType",
- },
- {
- label: "鐘舵��",
- prop: "publishStatus",
- width: 90,
- dataType: "tag",
- formatData: (v) => publishStatusLabel(v),
- formatType: (v) => {
- const hit = PUBLISH_STATUS_OPTIONS.find((x) => x.value === v);
- return hit?.tag || "info";
- },
- },
- { label: "鍙戝竷浜�", prop: "publisherName", width: 110 },
- { label: "鍙戝竷鏃堕棿", prop: "publishTime", width: 170 },
- { label: "鏇存柊鏃堕棿", prop: "updateTime", width: 170 },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 220,
- operation: buildTableActions(),
- },
- ];
-}
+/** @deprecated 璇蜂娇鐢� enterpriseNewsMappers.js */
+export {
+ ENTERPRISE_NEWS_PAYLOAD_KEY,
+ buildEnterpriseNewsSaveDto,
+ buildEnterpriseNewsTableColumns,
+ canEditEnterpriseNewsRow,
+ extractEnterpriseNewsFromRow,
+ mapApiRowToNewsForm,
+ mapEnterpriseNewsFromApi,
+ syncNewsFormToSubmitPayload,
+} from "./enterpriseNewsMappers.js";
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsMappers.js b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsMappers.js
new file mode 100644
index 0000000..5ef1a19
--- /dev/null
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsMappers.js
@@ -0,0 +1,224 @@
+import {
+ createEmptyForm,
+ normalizeEnterpriseNewsStatus,
+ publishStatusLabel,
+ PUBLISH_STATUS_OPTIONS,
+} from "./enterpriseNewsUtils.js";
+
+/** formPayload 涓瓨鏀惧畬鏁翠紒涓氭柊闂讳笟鍔℃暟鎹殑閿紙瀹℃壒瀹炰緥淇濆瓨鐢級 */
+export const ENTERPRISE_NEWS_PAYLOAD_KEY = "enterpriseNews";
+
+const READ_SCOPE_FROM_API = {
+ all: "all",
+ dept: "department",
+ department: "department",
+ custom: "custom",
+ management: "management",
+};
+
+const READ_SCOPE_TO_API = {
+ all: "all",
+ department: "dept",
+ dept: "dept",
+ custom: "custom",
+ management: "all",
+};
+
+export function mapReadScopeFromApi(scope) {
+ const key = String(scope ?? "").trim().toLowerCase();
+ return READ_SCOPE_FROM_API[key] || key || "all";
+}
+
+export function mapReadScopeToApi(scope) {
+ return READ_SCOPE_TO_API[scope] || scope || "all";
+}
+
+export function unwrapEnterpriseNewsPage(res) {
+ const data = res?.data ?? res;
+ if (!data || typeof data !== "object") {
+ return { records: [], total: 0 };
+ }
+ if (Array.isArray(data.records)) {
+ return { records: data.records, total: Number(data.total ?? 0) };
+ }
+ const nested = data.data;
+ if (nested && typeof nested === "object" && Array.isArray(nested.records)) {
+ return { records: nested.records, total: Number(nested.total ?? 0) };
+ }
+ return { records: [], total: 0 };
+}
+
+/** 缁勮 listPage 鏌ヨ鍙傛暟 */
+export function buildEnterpriseNewsListParams({ page, searchForm }) {
+ const params = {
+ current: page.current,
+ size: page.size,
+ };
+ const kw = (searchForm?.keyword || "").trim();
+ if (kw) params.title = kw;
+ if (searchForm?.newsType) params.category = searchForm.newsType;
+ if (searchForm?.status) params.status = searchForm.status;
+ const range = searchForm?.createTimeRange;
+ if (Array.isArray(range) && range[0]) {
+ params.createTimeStart = range[0];
+ }
+ if (Array.isArray(range) && range[1]) {
+ params.createTimeEnd = range[1];
+ }
+ return params;
+}
+
+/** 鎺ュ彛 EnterpriseNewsVo 鈫� 鍒楄〃琛� */
+export function mapEnterpriseNewsFromApi(row) {
+ if (!row) return {};
+ const newsStatus = normalizeEnterpriseNewsStatus(row.status);
+ return {
+ ...row,
+ newsNo: row.id != null ? String(row.id) : "鈥�",
+ newsType: row.category || "",
+ contentHtml: row.content || "",
+ publisherName: row.createUserName || "鈥�",
+ publishTime: row.createTime || "",
+ updateTime: row.updateTime || "",
+ newsStatus,
+ requireReadConfirm: row.isRequired === "1" || row.isRequired === 1,
+ readScope: mapReadScopeFromApi(row.readScope),
+ readCount: row.readCount ?? 0,
+ requiredReadCount: row.requiredReadCount ?? 0,
+ };
+}
+
+/** 鏄惁鍏佽淇敼锛堣崏绋裤�侀┏鍥炲彲鏀癸級 */
+export function canEditEnterpriseNewsRow(row) {
+ const status = normalizeEnterpriseNewsStatus(row?.newsStatus ?? row?.status);
+ return status === "DRAFT" || status === "REJECTED";
+}
+
+/** 鎺ュ彛琛� / 璇︽儏 鈫� 琛ㄥ崟 */
+export function mapApiRowToNewsForm(row) {
+ if (!row) return createEmptyForm();
+ return {
+ ...createEmptyForm(),
+ id: row.id != null ? String(row.id) : "",
+ newsNo: row.id != null ? String(row.id) : "",
+ title: row.title || "",
+ summary: row.summary || "",
+ contentHtml: row.content || row.contentHtml || "",
+ newsType: row.newsType || row.category || "announcement",
+ readScope: mapReadScopeFromApi(row.readScope),
+ requireReadConfirm: Boolean(row.requireReadConfirm ?? row.isRequired === "1"),
+ publisherName: row.createUserName || row.publisherName || "",
+ publishStatus: normalizeEnterpriseNewsStatus(row.newsStatus ?? row.status),
+ templateId: row.templateId,
+ templateName: row.templateName || "",
+ targetDeptIds: [...(row.deptIds || row.targetDeptIds || [])],
+ targetUserIds: [...(row.userIds || row.targetUserIds || [])],
+ };
+}
+
+/** 瀹℃壒瀹炰緥琛� formPayload 鈫� 琛ㄥ崟锛堝吋瀹规棫鏁版嵁锛� */
+export function extractEnterpriseNewsFromRow(row) {
+ if (!row?.formPayload && !row?.formFieldDefs && !row?.instanceNo) {
+ return mapApiRowToNewsForm(row);
+ }
+ const payload = row?.formPayload || {};
+ const raw = payload[ENTERPRISE_NEWS_PAYLOAD_KEY];
+ if (raw && typeof raw === "object") {
+ return { ...createEmptyForm(), ...raw };
+ }
+ return {
+ ...createEmptyForm(),
+ title: payload.title || row?.title || "",
+ summary: payload.summary || "",
+ newsType: payload.newsType || row?.category || "announcement",
+ contentHtml: payload.contentHtml || row?.content || "",
+ };
+}
+
+export function syncNewsFormToSubmitPayload(newsForm, submitForm) {
+ const snapshot = JSON.parse(JSON.stringify(newsForm));
+ submitForm.formPayload = {
+ ...(submitForm.formPayload || {}),
+ [ENTERPRISE_NEWS_PAYLOAD_KEY]: snapshot,
+ title: snapshot.title,
+ summary: snapshot.summary,
+ };
+}
+
+function toIdList(ids) {
+ if (!Array.isArray(ids) || !ids.length) return undefined;
+ const list = ids
+ .map((id) => (typeof id === "number" ? id : Number(id)))
+ .filter((n) => !Number.isNaN(n));
+ return list.length ? list : undefined;
+}
+
+/** 琛ㄥ崟 鈫� POST /enterpriseNews/save 璇锋眰浣� */
+export function buildEnterpriseNewsSaveDto(newsForm, { status } = {}) {
+ const dto = {
+ title: (newsForm.title || "").trim(),
+ summary: newsForm.summary || "",
+ content: newsForm.contentHtml || "",
+ category: newsForm.newsType || "",
+ readScope: mapReadScopeToApi(newsForm.readScope),
+ isRequired: newsForm.requireReadConfirm ? "1" : "0",
+ status: normalizeEnterpriseNewsStatus(status ?? newsForm.publishStatus),
+ };
+
+ const rawId = newsForm.id;
+ if (rawId != null && rawId !== "") {
+ const id = Number(rawId);
+ if (!Number.isNaN(id)) dto.id = id;
+ }
+
+ const deptIds = toIdList(newsForm.targetDeptIds);
+ if (deptIds) dto.deptIds = deptIds;
+
+ const userIds = toIdList(newsForm.targetUserIds);
+ if (userIds) dto.userIds = userIds;
+
+ const templateId = newsForm.templateId;
+ if (templateId != null && templateId !== "") {
+ const tid = Number(templateId);
+ if (!Number.isNaN(tid)) dto.templateId = tid;
+ }
+ if (newsForm.templateName) dto.templateName = newsForm.templateName;
+
+ return dto;
+}
+
+export function buildEnterpriseNewsTableColumns(buildTableActions) {
+ return [
+ { label: "缂栧彿", prop: "newsNo", width: 120 },
+ { label: "鏍囬", prop: "title", minWidth: 180, showOverflowTooltip: true },
+ {
+ label: "鍒嗙被",
+ prop: "newsType",
+ width: 100,
+ dataType: "slot",
+ slot: "newsType",
+ },
+ {
+ label: "鐘舵��",
+ prop: "newsStatus",
+ width: 100,
+ dataType: "tag",
+ formatData: (v) => publishStatusLabel(v),
+ formatType: (v) => {
+ const hit = PUBLISH_STATUS_OPTIONS.find((x) => x.value === v);
+ return hit?.tag || "info";
+ },
+ },
+ { label: "鍒涘缓浜�", prop: "publisherName", width: 110 },
+ { label: "鍒涘缓鏃堕棿", prop: "createTime", width: 170 },
+ { label: "鏇存柊鏃堕棿", prop: "updateTime", width: 170 },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 220,
+ operation: buildTableActions(),
+ },
+ ];
+}
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsUtils.js b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsUtils.js
index 4ba3085..71ceaba 100644
--- a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsUtils.js
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/enterpriseNewsUtils.js
@@ -8,13 +8,36 @@
{ value: "culture", label: "鏂囧寲娲诲姩", color: "#67c23a" },
];
-/** 鍙戝竷鐘舵�� */
+/** 浼佷笟鏂伴椈鐘舵�侊紙涓庡悗绔灇涓句竴鑷达級 */
export const PUBLISH_STATUS_OPTIONS = [
- { value: "draft", label: "鑽夌", tag: "info" },
- { value: "pending_review", label: "寰呭鏍�", tag: "warning" },
- { value: "published", label: "宸插彂甯�", tag: "success" },
- { value: "archived", label: "宸插綊妗�", tag: "" },
+ { value: "DRAFT", label: "鑽夌", tag: "info" },
+ { value: "PENDING", label: "寰呭鎵�", tag: "warning" },
+ { value: "PUBLISHED", label: "宸插彂甯�", tag: "success" },
+ { value: "REJECTED", label: "椹冲洖", tag: "danger" },
+ { value: "OFFLINE", label: "宸蹭笅绾�", tag: "info" },
];
+
+/** 浼佷笟鏂伴椈鍒楄〃绛涢�� */
+export const ENTERPRISE_NEWS_STATUS_SEARCH_OPTIONS = [...PUBLISH_STATUS_OPTIONS];
+
+const LEGACY_PUBLISH_STATUS_MAP = {
+ draft: "DRAFT",
+ pending_review: "PENDING",
+ published: "PUBLISHED",
+ archived: "OFFLINE",
+};
+
+/** 缁熶竴涓哄悗绔姸鎬佹灇涓惧�� */
+export function normalizeEnterpriseNewsStatus(v) {
+ if (v == null || v === "") return "DRAFT";
+ const upper = String(v).trim().toUpperCase();
+ if (upper === "APPROVED") return "PUBLISHED";
+ const hit = PUBLISH_STATUS_OPTIONS.find((x) => x.value === upper);
+ if (hit) return hit.value;
+ const legacy = LEGACY_PUBLISH_STATUS_MAP[String(v).trim().toLowerCase()];
+ if (legacy) return legacy;
+ return upper;
+}
/** 鎺掔増妯℃澘 */
export const LAYOUT_TEMPLATE_OPTIONS = [
@@ -63,11 +86,13 @@
}
export function publishStatusLabel(v) {
- return PUBLISH_STATUS_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
+ const key = normalizeEnterpriseNewsStatus(v);
+ return PUBLISH_STATUS_OPTIONS.find((x) => x.value === key)?.label || v || "鈥�";
}
export function publishStatusTag(v) {
- return PUBLISH_STATUS_OPTIONS.find((x) => x.value === v)?.tag || "info";
+ const key = normalizeEnterpriseNewsStatus(v);
+ return PUBLISH_STATUS_OPTIONS.find((x) => x.value === key)?.tag || "info";
}
export function layoutTemplateLabel(v) {
@@ -99,7 +124,7 @@
readScope: "all",
targetDeptIds: [],
targetUserIds: [],
- publishStatus: "draft",
+ publishStatus: "DRAFT",
publisherName: "",
publishTime: "",
readRecords: [],
@@ -109,6 +134,8 @@
versions: [],
versionNo: 1,
requireReadConfirm: false,
+ templateId: null,
+ templateName: "",
};
}
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>
diff --git a/src/views/officeProcessAutomation/EnterpriseNews/news-manage/useEnterpriseNewsList.js b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/useEnterpriseNewsList.js
new file mode 100644
index 0000000..66aef1e
--- /dev/null
+++ b/src/views/officeProcessAutomation/EnterpriseNews/news-manage/useEnterpriseNewsList.js
@@ -0,0 +1,55 @@
+import { listEnterpriseNewsPage } from "@/api/officeProcessAutomation/enterpriseNews.js";
+import { ElMessage } from "element-plus";
+import { reactive, ref } from "vue";
+import {
+ buildEnterpriseNewsListParams,
+ mapEnterpriseNewsFromApi,
+ unwrapEnterpriseNewsPage,
+} from "./enterpriseNewsMappers.js";
+
+/** 浼佷笟鏂伴椈鍒楄〃锛氬垎椤垫煡璇� /enterpriseNews/listPage */
+export function useEnterpriseNewsList() {
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+ const page = reactive({ current: 1, size: 10, total: 0 });
+ let lastSearchForm = null;
+
+ async function fetchList(searchForm = {}) {
+ tableLoading.value = true;
+ try {
+ const res = await listEnterpriseNewsPage(
+ buildEnterpriseNewsListParams({ page, searchForm })
+ );
+ const { records, total } = unwrapEnterpriseNewsPage(res);
+ tableData.value = records.map(mapEnterpriseNewsFromApi);
+ page.total = total;
+ } catch {
+ tableData.value = [];
+ page.total = 0;
+ ElMessage.error("浼佷笟鏂伴椈鍒楄〃鍔犺浇澶辫触");
+ } finally {
+ tableLoading.value = false;
+ }
+ }
+
+ function handleQuery(searchForm) {
+ lastSearchForm = searchForm;
+ page.current = 1;
+ return fetchList(searchForm);
+ }
+
+ function pagination({ page: p, limit }, searchForm) {
+ page.current = p;
+ page.size = limit;
+ return fetchList(searchForm ?? lastSearchForm ?? {});
+ }
+
+ return {
+ tableData,
+ tableLoading,
+ page,
+ fetchList,
+ handleQuery,
+ pagination,
+ };
+}
diff --git a/src/views/officeProcessAutomation/HrManage/regular-apply/index.vue b/src/views/officeProcessAutomation/HrManage/regular-apply/index.vue
index 83bfefb..ef4a1e8 100644
--- a/src/views/officeProcessAutomation/HrManage/regular-apply/index.vue
+++ b/src/views/officeProcessAutomation/HrManage/regular-apply/index.vue
@@ -95,11 +95,10 @@
const mod = useApprovalInstanceModule({
moduleKey: APPROVAL_MODULE_KEYS.REGULAR,
buildExtraListParams(sf) {
- const range = sf?.applyDateRange;
- if (Array.isArray(range) && range[0]) {
- return { createTime: range[0], createTimeEnd: range[1] };
- }
- return {};
+ const extra = {};
+ const name = (sf?.applicantName || "").trim();
+ if (name) extra.applicantName = name;
+ return extra;
},
});
diff --git a/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue b/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue
index 5be9b2b..4121157 100644
--- a/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue
+++ b/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue
@@ -137,11 +137,7 @@
const mod = useApprovalInstanceModule({
moduleKey: APPROVAL_MODULE_KEYS.TRANSFER,
- buildExtraListParams(sf) {
- const range = sf?.transferDateRange;
- if (Array.isArray(range) && range[0]) {
- return { createTime: range[0], createTimeEnd: range[1] };
- }
+ buildExtraListParams() {
return {};
},
});
--
Gitblit v1.9.3