From 3e99901d8e7f252ddd04bc962a33700ec2d61886 Mon Sep 17 00:00:00 2001 From: zhangrui Date: Sat, 10 Oct 2026 15:27:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=96=97=E4=BC=91=E5=85=BB=E5=8F=B0=E8=B4=A6?= =?UTF-8?q?=E4=B8=AD=E5=8A=A0=E4=B8=80=E4=B8=AA=E5=AF=BC=E5=87=BA=E6=8C=89?= =?UTF-8?q?=E9=92=AE=EF=BC=8C=E6=A0=B9=E6=8D=AE=E6=9F=A5=E8=AF=A2=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tour/controller/TourLedgerController.java | 65 ++++++++++++++++++ .../tour/service/TourLedgerService.java | 9 +++ .../service/impl/TourLedgerServiceImpl.java | 68 +++++++++++++++++++ .../zhgh/dayofficework/Tour/ledger/index.html | 18 +++++ 4 files changed, 160 insertions(+) diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/controller/TourLedgerController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/controller/TourLedgerController.java index 2da33f5..0381b0d 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/controller/TourLedgerController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/controller/TourLedgerController.java @@ -319,6 +319,59 @@ public class TourLedgerController { CommonDownloadUtil.download("参加人员导入模板.xlsx", workbook, response); } + /** + * 按台账页面当前查询条件导出全部匹配记录。 + * + * @param startYear 开始年度,传四位年度数字 + * @param endYear 结束年度,传四位年度数字 + * @param keyword 姓名或工号关键字,可为空 + * @param unionId 所属工会ID,可为空 + * @param lineId 线路ID;历史线路使用legacy:线路名称,可为空 + * @param travelPeriod 出行时段,格式为开始时间 至 结束时间,可为空 + * @param lineType 线路类型字典名称,可为空 + * @param directFamilyOnly 是否仅导出参加直系亲属单位线路人员 + * @param overCostOnly 是否仅导出申请超出费用由单位承担人员 + * @param response HTTP响应,返回XSSF格式的Excel文件流 + */ + @At + @Ok("void") + @SaCheckPermission("tour.ledger") + public void exportData(Integer startYear, Integer endYear, String keyword, String unionId, String lineId, + String travelPeriod, String lineType, Boolean directFamilyOnly, Boolean overCostOnly, + HttpServletResponse response) { + Cnd cnd = buildQueryCnd(startYear, endYear, keyword, unionId, lineId, travelPeriod, lineType, + directFamilyOnly, overCostOnly); + List rows = tourLedgerService.queryExportRows(cnd); + for (int i = 0; i < rows.size(); i++) { + NutMap row = rows.get(i); + row.put("index", i + 1); + row.put("groupInfo", formatGroupInfo(row)); + row.put("joinedName", row.getBoolean("joined", false) ? "是" : "否"); + row.put("overCostReimbursedName", row.getBoolean("overCostReimbursed", false) ? "是" : "否"); + } + + List entities = new ArrayList<>(); + entities.add(new ExcelExportEntity("序号", "index", 8)); + entities.add(new ExcelExportEntity("年度", "year", 12)); + entities.add(new ExcelExportEntity("工号", "jobNo", 18)); + entities.add(new ExcelExportEntity("姓名", "userName", 16)); + entities.add(new ExcelExportEntity("所在单位", "unitName", 28)); + entities.add(new ExcelExportEntity("报名线路", "lineName", 30)); + entities.add(new ExcelExportEntity("出行时段", "travelPeriod", 30)); + entities.add(new ExcelExportEntity("线路类型", "lineType", 16)); + entities.add(new ExcelExportEntity("成团信息", "groupInfo", 20)); + entities.add(new ExcelExportEntity("领办工会", "undertakeUnionName", 24)); + entities.add(new ExcelExportEntity("报名时间", "signupTime", 24)); + entities.add(new ExcelExportEntity("携带家属人数", "familyCount", 16)); + entities.add(new ExcelExportEntity("是否参加", "joinedName", 14)); + entities.add(new ExcelExportEntity("是否申请超出费用由单位承担", "overCostReimbursedName", 28)); + + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, rows); + CommonDownloadUtil.download("疗休养台账.xlsx", workbook, response); + } + @At @SaCheckPermission("tour.ledger") @Ok("void") @@ -420,6 +473,18 @@ public class TourLedgerController { return unionRows; } + /** + * 将成团编码和成团名称合并为列表一致的展示内容,任一字段为空时保留已有信息。 + */ + private String formatGroupInfo(NutMap row) { + String groupCode = row.getString("groupCode", ""); + String groupName = row.getString("groupName", ""); + if (StrUtil.isBlank(groupCode)) { + return groupName; + } + return StrUtil.isBlank(groupName) ? groupCode : groupCode + " " + groupName; + } + private Workbook buildUnionSignupWorkbook(String unionName, List rows) { HSSFWorkbook workbook = new HSSFWorkbook(); Sheet sheet = workbook.createSheet("报名汇总表"); diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/TourLedgerService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/TourLedgerService.java index d0d49be..c11d73f 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/TourLedgerService.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/TourLedgerService.java @@ -20,6 +20,15 @@ public interface TourLedgerService extends BaseService { */ List queryGroupOptions(Cnd cnd); + /** + * 按疗休养台账页面的完整查询条件获取导出数据,不进行分页。 + * + * @param cnd 台账查询条件,包含年度范围、姓名或工号、所属工会、线路、出行时段、线路类型、 + * 直系亲属单位线路人员、超出费用由单位承担人员及审批完成状态限制 + * @return 台账导出数据列表;每项包含年度、人员、线路、成团、领办工会、报名、家属及参加状态信息 + */ + List queryExportRows(Cnd cnd); + /** * 按事项最大成团人数,将当前事项下未成团的报名教职工及家属整体自动分配到成团中。 * diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/impl/TourLedgerServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/impl/TourLedgerServiceImpl.java index c9f8e08..b495ffd 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/impl/TourLedgerServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/tour/service/impl/TourLedgerServiceImpl.java @@ -56,6 +56,74 @@ public class TourLedgerServiceImpl extends BaseServiceImpl implement return sql.getList(NutMap.class); } + /** + * 查询符合台账页面筛选条件的全部导出数据,关联线路、事项和家属数据以保持导出结果与列表一致。 + * + * @param cnd 已包含页面全部筛选项和审批完成状态限制的台账查询条件 + * @return 未分页的台账导出数据列表,每项为一名教职工的一条有效台账记录 + */ + @Override + public List queryExportRows(Cnd cnd) { + Sql sql = Sqls.create(""" + SELECT + t.`year`, + t.jobNo, + t.userName, + t.unitName, + COALESCE(NULLIF(l.lineName, ''), t.lineName) AS lineName, + CASE + WHEN IFNULL(m.travelStartTime, '') <> '' AND IFNULL(m.travelEndTime, '') <> '' + THEN CONCAT(m.travelStartTime, ' 至 ', m.travelEndTime) + ELSE tp.travelPeriod + END AS travelPeriod, + t.lineType, + t.groupCode, + t.groupName, + t.undertakeUnionName, + t.signupTime, + IFNULL(f.familyCount, 0) AS familyCount, + t.joined, + t.overCostReimbursed + FROM tour_ledger t + LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id + LEFT JOIN ( + SELECT ledgerId, COUNT(1) AS familyCount + FROM tour_ledger_family + WHERE delFlag = 0 + GROUP BY ledgerId + ) f ON f.ledgerId = t.id + LEFT JOIN tour_matter m ON m.id = t.matterId AND m.delFlag = 0 + LEFT JOIN tour_line l ON l.id = t.lineId AND l.delFlag = 0 + LEFT JOIN tour_ledger_direct_relative dr ON dr.ledgerId = t.id AND dr.delFlag = 0 + LEFT JOIN ( + SELECT + `year`, + lineId, + GROUP_CONCAT( + DISTINCT CASE + WHEN IFNULL(travelStartTime, '') <> '' AND IFNULL(travelEndTime, '') <> '' + THEN CONCAT(travelStartTime, ' 至 ', travelEndTime) + ELSE NULL + END + ORDER BY travelStartTime ASC + SEPARATOR ';' + ) AS travelPeriod + FROM tour_matter + WHERE delFlag = 0 + AND lineId IS NOT NULL + AND lineId <> '' + GROUP BY `year`, lineId + ) tp ON (t.matterId IS NULL OR t.matterId = '') AND tp.`year` = t.`year` AND tp.lineId = t.lineId + $condition + GROUP BY t.id + ORDER BY t.`year` DESC, t.signupTime DESC, t.createdAt DESC + """); + sql.setCondition(cnd); + sql.setCallback(Sqls.callback.maps()); + dao().execute(sql); + return sql.getList(NutMap.class); + } + /** * 自动分配当前事项下未成团的教职工台账,分配过程中出现容量不合法时整体中止。 */ diff --git a/src/main/resources/views/platform/zhgh/dayofficework/Tour/ledger/index.html b/src/main/resources/views/platform/zhgh/dayofficework/Tour/ledger/index.html index 00287f3..c676a24 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/Tour/ledger/index.html +++ b/src/main/resources/views/platform/zhgh/dayofficework/Tour/ledger/index.html @@ -71,6 +71,7 @@ layout("/layouts/platform.html"){
参加人员导入 设置参加人员 + 导出 导出分工会报名压缩包
@@ -448,6 +449,23 @@ layout("/layouts/platform.html"){ } window.location.href = loc() + "/exportUnionSignupZip?" + params.toString() }, + // 导出台账时完整传递当前页面筛选项,两个特殊人员范围按钮也作为查询条件参与导出。 + exportData() { + const params = new URLSearchParams() + ;["startYear", "endYear", "keyword", "unionId", "lineId", "travelPeriod", "lineType"].forEach(key => { + const value = this.pageForm[key] + if (value !== undefined && value !== null && value !== "") { + params.append(key, value) + } + }) + if (this.pageForm.directFamilyOnly) { + params.append("directFamilyOnly", "true") + } + if (this.pageForm.overCostOnly) { + params.append("overCostOnly", "true") + } + window.location.href = loc() + "/exportData?" + params.toString() + }, afterImport() { this.showImportDialog = false this.clearTableSelection()