疗休养台账中加一个导出按钮,根据查询条件导出

This commit is contained in:
2026-10-10 15:27:21 +08:00
parent f7c381acbd
commit 3e99901d8e
4 changed files with 160 additions and 0 deletions
@@ -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<NutMap> 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<ExcelExportEntity> 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<NutMap> rows) {
HSSFWorkbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("报名汇总表");
@@ -20,6 +20,15 @@ public interface TourLedgerService extends BaseService<TourLedger> {
*/
List<NutMap> queryGroupOptions(Cnd cnd);
/**
* 按疗休养台账页面的完整查询条件获取导出数据,不进行分页。
*
* @param cnd 台账查询条件,包含年度范围、姓名或工号、所属工会、线路、出行时段、线路类型、
* 直系亲属单位线路人员、超出费用由单位承担人员及审批完成状态限制
* @return 台账导出数据列表;每项包含年度、人员、线路、成团、领办工会、报名、家属及参加状态信息
*/
List<NutMap> queryExportRows(Cnd cnd);
/**
* 按事项最大成团人数,将当前事项下未成团的报名教职工及家属整体自动分配到成团中。
*
@@ -56,6 +56,74 @@ public class TourLedgerServiceImpl extends BaseServiceImpl<TourLedger> implement
return sql.getList(NutMap.class);
}
/**
* 查询符合台账页面筛选条件的全部导出数据,关联线路、事项和家属数据以保持导出结果与列表一致。
*
* @param cnd 已包含页面全部筛选项和审批完成状态限制的台账查询条件
* @return 未分页的台账导出数据列表,每项为一名教职工的一条有效台账记录
*/
@Override
public List<NutMap> 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);
}
/**
* 自动分配当前事项下未成团的教职工台账,分配过程中出现容量不合法时整体中止。
*/
@@ -71,6 +71,7 @@ layout("/layouts/platform.html"){
<div class="tour-ledger-actions">
<el-button size="medium" type="primary" icon="el-icon-upload2" @click="showImportDialog = true">参加人员导入</el-button>
<el-button size="medium" type="primary" icon="el-icon-check" @click="setParticipants">设置参加人员</el-button>
<el-button size="medium" type="primary" icon="el-icon-download" @click="exportData">导出</el-button>
<el-button size="medium" type="primary" icon="el-icon-download" @click="exportUnionSignupZip">导出分工会报名压缩包</el-button>
</div>
<div class="tour-ledger-scope">
@@ -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()