From b8d53bba0b43d0e6cdfd1874830b8300d9907562 Mon Sep 17 00:00:00 2001
From: wsm <2746563060@侵权。>
Date: Wed, 13 May 2026 21:09:28 +0800
Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8Djson=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=EF=BC=8C=E7=94=A8=E6=9D=A5=E9=80=82=E9=85=8D=E5=90=8E=E7=AB=AF?=
=?UTF-8?q?=E4=BC=A0=E5=9B=9E=E7=9A=84json=E6=95=B0=E6=8D=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/bg/xispeak/BgXiSpeak.data.ts | 17 ++
src/views/bg/xispeak/BgXiSpeakList.vue | 381 +++++++++++++++++--------
2 files changed, 281 insertions(+), 117 deletions(-)
diff --git a/src/views/bg/xispeak/BgXiSpeak.data.ts b/src/views/bg/xispeak/BgXiSpeak.data.ts
index a3da185..9f7b973 100644
--- a/src/views/bg/xispeak/BgXiSpeak.data.ts
+++ b/src/views/bg/xispeak/BgXiSpeak.data.ts
@@ -114,6 +114,22 @@ export const columns: BasicColumn[] = [
align: 'center',
dataIndex: 'supervisionCount',
},
+ {
+ title: '审批信息',
+ align: 'center',
+ dataIndex: 'approveInfo',
+ customRender: ({ text }) => {
+ if (!text) return '-';
+ try {
+ const info = typeof text === 'string' ? JSON.parse(text) : text;
+ const keys = Object.keys(info);
+ if (keys.length === 0) return '-';
+ return `${keys.length} 项审批`;
+ } catch {
+ return '-';
+ }
+ },
+ },
];
//子表列表数据
@@ -240,4 +256,5 @@ export const superQuerySchema = {
sortOrder: { title: '同级数据排序号', order: 19, view: 'number', type: 'number' },
bpmStatus: { title: '流程引擎状态字段', order: 21, view: 'number', type: 'number' },
supervisionCount: { title: '督办次数', order: 22, view: 'number', type: 'number' },
+ approveInfo: { title: '审批信息', order: 23, view: 'text', type: 'string' },
};
diff --git a/src/views/bg/xispeak/BgXiSpeakList.vue b/src/views/bg/xispeak/BgXiSpeakList.vue
index 6a72fee..2660bf0 100644
--- a/src/views/bg/xispeak/BgXiSpeakList.vue
+++ b/src/views/bg/xispeak/BgXiSpeakList.vue
@@ -2,18 +2,16 @@
-
+
新增
- 导出
- 导入
+ 导出
+ 导入
@@ -31,6 +29,16 @@
+
+
+
+ onExpand(record, e)">
+
+
+
+
+
+
@@ -47,7 +55,7 @@
反馈信息
- {{ feedbackTableLoading ? '加载中' : `${getFeedbackCount(record)} 条` }}
+ {{ getFeedbackTableLoading(record) ? '加载中' : `${getFeedbackCount(record)} 条` }}
@@ -65,8 +73,8 @@
:showTableSetting="false"
:clickToRowSelect="false"
:columns="feedbackExpandColumns"
- :dataSource="feedbackTableData[record.id] || []"
- :loading="feedbackTableLoading"
+ :dataSource="getFeedbackTableData(record)"
+ :loading="getFeedbackTableLoading(record)"
:pagination="false"
:scroll="{ x: 1220 }"
>
@@ -110,11 +118,21 @@
import FlowScheduleStartModal from '/src/components/semri/process/FlowScheduleStartModal.vue';
import { columns as taskTaskColumns } from '/@/views/taskProcess/TaskTask.data';
import { columns, superQuerySchema, bgXiSpeakFeedbackColumns } from './BgXiSpeak.data';
- import { list, deleteBgXiSpeak, batchDeleteBgXiSpeak, getExportUrl, getImportUrl, getChildList, getChildListBatch, updateLaunchType, bgXiSpeakFeedbackList } from './BgXiSpeak.api';
+ import {
+ list,
+ deleteBgXiSpeak,
+ batchDeleteBgXiSpeak,
+ getExportUrl,
+ getImportUrl,
+ getChildList,
+ getChildListBatch,
+ updateLaunchType,
+ bgXiSpeakFeedbackList,
+ } from './BgXiSpeak.api';
const FLOW_CODE = 'dev_bg_xi_speak_001';
const FLOW_NAME = '习总书记重要讲话指示批示';
- const FLOW_CODE_JBR = 'process_1778315114392';
+ const FLOW_CODE_JBR = 'bg_xi_speak_fb_01';
const BUSINESS_TABLE_NAME = 'bg_xi_speak';
const FORM_URL = 'bg/xispeak/components/BgXiSpeakBPMForm';
@@ -129,7 +147,7 @@
const processColumns = taskTaskColumns;
const selectedFeedbackId = ref(null);
const feedbackTableData = reactive>({});
- const feedbackTableLoading = ref(false);
+ const feedbackTableLoading = reactive>({});
// 注册table数据
const feedbackExpandColumns: BasicColumn[] = [
@@ -155,10 +173,13 @@
canResize: false,
useSearchForm: false,
isTreeTable: true,
- indentSize: 30,
- expandIconColumnIndex: 1,
+ indentSize: 24, // 和 Jeecg 原生树形缩进保持一致
+ expandIconColumnIndex: 0,
clickToRowSelect: true,
- rowSelection: { type: 'radio' },
+ treeProps: {
+ children: 'children',
+ indent: 24, // 和 indentSize 保持一致,保证缩进对齐
+ },
actionColumn: {
width: 120,
fixed: 'right',
@@ -194,7 +215,7 @@
},
});
- const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
+ const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { selectedRowKeys }] = tableContext;
const mainId = computed(() => (unref(selectedRowKeys).length > 0 ? unref(selectedRowKeys)[0] : ''));
provide('mainId', mainId);
@@ -451,7 +472,7 @@
onClick: handleQueryProcess.bind(null, record),
},
{
- label: '查看反馈',
+ label: selectedFeedbackId.value === record.id ? '收起反馈信息' : '查看反馈',
onClick: handleViewFeedback.bind(null, record),
},
];
@@ -514,6 +535,76 @@
needSdwApproval: queryParam.value.needSdwApproval || '',
};
+ // 如果是经办人执行反馈流程,需要遍历每个部门单独发起
+ if (flowCode === FLOW_CODE_JBR) {
+ let approveInfo = {};
+ if (record.approveInfo) {
+ try {
+ approveInfo = typeof record.approveInfo === 'string' ? JSON.parse(record.approveInfo) : record.approveInfo;
+ } catch (e) {
+ createMessage.error('审批信息解析失败');
+ return;
+ }
+ }
+ const deptKeys = Object.keys(approveInfo);
+ if (deptKeys.length === 0) {
+ createMessage.warning('没有可用的部门审批信息');
+ return;
+ }
+
+ let successCount = 0;
+ const total = deptKeys.length;
+
+ for (const deptId of deptKeys) {
+ const deptApproveDetail = approveInfo[deptId];
+ const implUserIdList = deptApproveDetail.implUserIdList || [];
+ const implUserNameList = deptApproveDetail.implUserNameList || [];
+
+ const params = {
+ intervalType: options.intervalType,
+ startCount: options.startCount,
+ taskTask: {
+ triggerType: options.triggerType,
+ startTime: options.intervalStartTime,
+ flowCode: flowCode,
+ formUrl: FORM_URL,
+ flowName: '落实部门经办人执行反馈流程',
+ jsonData: {
+ ...recordWithSdwLeader,
+ currentDeptId: deptId,
+ currentApproverId: deptApproveDetail.approverId,
+ currentApproverName: deptApproveDetail.approverName,
+ implUserIdList: implUserIdList.join(','),
+ implUserNameList: implUserNameList.join(','),
+ },
+ businessTablename: BUSINESS_TABLE_NAME,
+ businessId: record.id,
+ deptHandlerName: deptApproveDetail.implUserNameList.join(','),
+ title: record.speakStatus,
+ content: record.implStatus,
+ urgencyLevel: record.completionStatus,
+ deptId: deptId,
+ deptLeaderId: deptApproveDetail.approverId,
+ requireFinishDate: formatDate(record.time, 'YYYY-MM-DD'),
+ deadline: formatDate(record.time, 'YYYY-MM-DD HH:mm:ss'),
+ },
+ };
+
+ try {
+ await startProcessSchedules(params);
+ successCount++;
+ if (successCount === total) {
+ createMessage.success(`成功发起 ${total} 个经办人执行反馈流程`);
+ reload();
+ }
+ } catch (e) {
+ createMessage.error(`部门 ${deptId} 流程发起失败`);
+ }
+ }
+ return;
+ }
+
+ // 原有的督办计划收集流程逻辑
const params = {
intervalType: options.intervalType,
startCount: options.startCount,
@@ -538,7 +629,7 @@
await startProcessSchedules(params);
createMessage.success('发起成功');
- handleSuccess({ isUpdate: false, values: {}, expandedArr: [], changeParent: false });
+ reload();
}
async function handlePreviewPic(record) {
@@ -548,8 +639,20 @@
});
}
+ function getFeedbackKey(record: Recordable) {
+ return String(record?.id ?? '');
+ }
+
+ function getFeedbackTableData(record: Recordable) {
+ return feedbackTableData[getFeedbackKey(record)] || [];
+ }
+
function getFeedbackCount(record: Recordable) {
- return (feedbackTableData[record.id] || []).length;
+ return getFeedbackTableData(record).length;
+ }
+
+ function getFeedbackTableLoading(record: Recordable) {
+ return !!feedbackTableLoading[getFeedbackKey(record)];
}
function handleCloseFeedback() {
@@ -557,7 +660,8 @@
}
async function loadFeedbackTableData(mainId: string | number) {
- feedbackTableLoading.value = true;
+ const key = String(mainId);
+ feedbackTableLoading[key] = true;
try {
const res = await bgXiSpeakFeedbackList({
mainId,
@@ -566,9 +670,9 @@
column: 'createTime',
order: 'desc',
});
- feedbackTableData[mainId] = Array.isArray(res) ? res : res?.records || [];
+ feedbackTableData[key] = Array.isArray(res) ? res : res?.records || [];
} finally {
- feedbackTableLoading.value = false;
+ feedbackTableLoading[key] = false;
}
}
@@ -697,10 +801,53 @@
transition: background 0.2s ease;
}
+ // 树形表格缩进样式,和 Jeecg 原生对齐
+ :deep(.ant-table-row) {
+ .ant-table-row-indent {
+ display: inline-block;
+ width: 24px; // 和 indentSize 保持一致
+ height: 1px;
+ }
+ }
+
:deep(.ant-table-tbody > tr:hover > td) {
background: #f5f7fa;
}
+ // Jeecg 原生风格的树形展开图标
+ :deep(.jeecg-tree-expand-icon) {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ margin-right: 6px;
+ cursor: pointer;
+ border-radius: 2px;
+ transition: all 0.2s;
+
+ &:hover {
+ background-color: #f0f0f0;
+ }
+
+ .anticon {
+ font-size: 14px;
+ color: #666;
+ transition: color 0.2s;
+ }
+
+ &:hover .anticon {
+ color: #1890ff;
+ }
+ }
+
+ :deep(.jeecg-tree-expand-placeholder) {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ margin-right: 6px;
+ }
+
// 操作按钮样式
:deep(.ant-btn-link) {
padding: 4px 8px;
@@ -761,107 +908,107 @@
}
}
- .feedback-expand-table {
- margin: 4px 10px 12px 42px;
- padding: 12px 14px 14px;
- background: #f6fbff;
- border: 1px solid #d6e8ff;
- border-left: 4px solid #1677ff;
- border-radius: 6px;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
+ .feedback-expand-table {
+ margin: 4px 10px 12px 42px;
+ padding: 12px 14px 14px;
+ background: #f6fbff;
+ border: 1px solid #d6e8ff;
+ border-left: 4px solid #1677ff;
+ border-radius: 6px;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
- .feedback-expand-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 10px;
+ .feedback-expand-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 10px;
+ }
+
+ .feedback-expand-title {
+ display: inline-flex;
+ align-items: center;
+ min-width: 0;
+ color: #1f2937;
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 24px;
+ }
+
+ .feedback-expand-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ margin-right: 8px;
+ color: #1677ff;
+ background: #e6f4ff;
+ border-radius: 50%;
+ }
+
+ .feedback-expand-count {
+ margin-left: 10px;
+ }
+
+ .feedback-expand-desc {
+ color: #64748b;
+ font-size: 13px;
+ line-height: 22px;
+ white-space: nowrap;
+ }
+
+ .feedback-expand-actions {
+ display: flex;
+ align-items: center;
+ }
+
+ :deep(.jeecg-basic-table) {
+ background: #fff;
+ }
+
+ :deep(.feedback-inner-table .ant-table-wrapper) {
+ padding: 0;
+ border-radius: 4px;
+ }
+
+ :deep(.feedback-inner-table .ant-table-thead > tr > th) {
+ background: #eef6ff;
+ color: #334155;
+ font-weight: 600;
+ }
+
+ :deep(.feedback-inner-table .ant-table-tbody > tr > td) {
+ background: #fff;
+ }
+
+ :deep(.feedback-inner-table .ant-table-tbody > tr:hover > td) {
+ background: #f8fbff;
+ }
+
+ .feedback-attachment-list {
+ min-width: 300px;
+
+ :deep(.file-list-wrapper) {
+ min-height: auto;
+ padding: 8px;
}
- .feedback-expand-title {
- display: inline-flex;
- align-items: center;
- min-width: 0;
- color: #1f2937;
- font-size: 14px;
- font-weight: 600;
- line-height: 24px;
+ :deep(.file-list-header) {
+ margin-bottom: 6px;
+ padding-bottom: 6px;
}
- .feedback-expand-icon {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 24px;
- height: 24px;
- margin-right: 8px;
- color: #1677ff;
- background: #e6f4ff;
- border-radius: 50%;
+ :deep(.file-list .file-item) {
+ padding: 8px;
+ margin-bottom: 6px;
}
- .feedback-expand-count {
- margin-left: 10px;
- }
-
- .feedback-expand-desc {
- color: #64748b;
- font-size: 13px;
- line-height: 22px;
- white-space: nowrap;
- }
-
- .feedback-expand-actions {
- display: flex;
- align-items: center;
- }
-
- :deep(.jeecg-basic-table) {
- background: #fff;
- }
-
- :deep(.feedback-inner-table .ant-table-wrapper) {
- padding: 0;
- border-radius: 4px;
- }
-
- :deep(.feedback-inner-table .ant-table-thead > tr > th) {
- background: #eef6ff;
- color: #334155;
- font-weight: 600;
- }
-
- :deep(.feedback-inner-table .ant-table-tbody > tr > td) {
- background: #fff;
- }
-
- :deep(.feedback-inner-table .ant-table-tbody > tr:hover > td) {
- background: #f8fbff;
- }
-
- .feedback-attachment-list {
- min-width: 300px;
-
- :deep(.file-list-wrapper) {
- min-height: auto;
- padding: 8px;
- }
-
- :deep(.file-list-header) {
- margin-bottom: 6px;
- padding-bottom: 6px;
- }
-
- :deep(.file-list .file-item) {
- padding: 8px;
- margin-bottom: 6px;
- }
-
- :deep(.ant-empty) {
- margin: 0;
- }
+ :deep(.ant-empty) {
+ margin: 0;
}
}
+ }
// 响应式适配
@media (max-width: 768px) {