南京理工提案优化整改: 提案查询和导出新增字段,导出前确认搜索条件;

This commit is contained in:
2026-10-09 09:41:24 +08:00
parent b2fc1979fe
commit d6961ebf19
10 changed files with 535 additions and 84 deletions
@@ -32,6 +32,8 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -140,11 +142,19 @@ public class proposalExportCaseController {
@Ok("void")
@RequiresAuthentication
public void exportAllProposal(String props, PageForm page, ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
String searchName2, String searchKeyword2, HttpServletResponse response) throws Exception {
String searchName2, String searchKeyword2,
@Param("undertakeId") String undertakeId,
String[] determineTypeOptions,
String exportCondition,
String exportFileCondition,
HttpServletResponse response) throws Exception {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create(SQL);
if (StrUtil.isNotBlank(undertakeId)) {
cnd.and(Cnd.exps("zbpr.replyUnitId", "=", undertakeId).or("xbpr.replyUnitId", "=", undertakeId));
}
cnd.andEX("info.stateCode", "=", stateCode);
cnd.and("info.stateCode", ">", ProposalState.CASE);
if (!ShiroUtil.hasAnyRoles(new String[]{"sysadmin", "A06", "tamange", "jdhdbt01"})) {
@@ -160,6 +170,11 @@ public class proposalExportCaseController {
}
if (proposalResult != null && proposalResult.length > 0) {
cnd.and("info.resultCode", "in", proposalResult);
if (ArrayUtil.contains(proposalResult, ProposalConstant.DETERMINE)) {
if (determineTypeOptions != null && determineTypeOptions.length > 0) {
cnd.and("info.determineTypeCode", "in", determineTypeOptions);
}
}
}
cnd.asc("info.resultCode");
proposalInfoService.sortAndSearch(cnd, page, search);
@@ -189,8 +204,17 @@ public class proposalExportCaseController {
}
try {
ViTool.excelResponse(response, "提案立案汇总表.xlsx");
ExportParams exportParams = new ExportParams();
String exportTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String fileCondition = StrUtil.blankToDefault(exportFileCondition, "全部立案提案")
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
.replaceAll("\\s+", "");
if (fileCondition.length() > 80) {
fileCondition = fileCondition.substring(0, 80);
}
ViTool.excelResponse(response, "提案立案汇总表_" + fileCondition + "_"
+ exportTime.replaceAll("[-: ]", "") + ".xlsx");
ExportParams exportParams = new ExportParams("提案立案汇总表(查询条件:"
+ StrUtil.blankToDefault(exportCondition, "无") + ";导出时间:" + exportTime + ")", "立案汇总");
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, proposalList);
workbook.write(response.getOutputStream());
@@ -11,6 +11,7 @@ import io.v.nutz.annontation.ViReturn;
import io.v.nutz.base.utils.Vi;
import io.v.nutz.modules.models.PageForm;
import io.v.nutz.proposal.constants.ProposalConstant;
import io.v.nutz.proposal.constants.ProposalState;
import io.v.nutz.proposal.models.ProposalSearch;
import io.v.nutz.proposal.services.ProposalInfoService;
import io.v.nutz.util.ShiroUtil;
@@ -31,8 +32,12 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhf
@@ -151,12 +156,15 @@ public class proposalExportSummaryController {
Sql sql = Sqls.create("""
SELECT
info.id,
info.proposalCode,
info.proposalName,
info.brief,
info.measures,
info.createTime,
su.username,
su.loginname,
creatorUnit.`name` creatorUnitName,
state.stateName,
state.stateColor,
type.typeCode,
@@ -170,16 +178,24 @@ public class proposalExportSummaryController {
masterPu.unitCode AS pruMasterCode,
masterPr.replyContent,
masterPr.handleOpinion,
GROUP_CONCAT(slavePu.unitName) AS pruSlave,
masterPr.replyTime,
masterPr.implementState,
masterPr.leaderCheckTime,
masterPr.leaderCheckOpinion,
CASE WHEN masterPr.isReply = 1 THEN '已答复' ELSE '未答复' END replyStatus,
GROUP_CONCAT(DISTINCT slavePu.unitName) AS pruSlave,
pf.feedbackCodeByUnderTake,
pfDict.`name` feedbackResult
pfDict.`name` feedbackResult,
pf.feedbackOpinion,
pf.feedbackTime
FROM
proposal_info info
LEFT JOIN proposal_reply masterPr on masterPr.proposalId = info.id AND masterPr.undertakeType = 1
LEFT JOIN proposal_underTake masterPu on masterPu.id = masterPr.replyUnitId
LEFT JOIN proposal_reply slavePr on slavePr.proposalId = info.id AND slavePr.undertakeType = 2
LEFT JOIN proposal_underTake slavePu on slavePu.id = slavePr.replyUnitId
LEFT JOIN `user` su ON su.id = info.createUser
LEFT JOIN sys_user su ON su.id = info.createUser
LEFT JOIN sys_unit creatorUnit ON creatorUnit.id = su.unitid
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
LEFT JOIN proposal_type type ON type.id = info.typeId
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
@@ -207,20 +223,36 @@ public class proposalExportSummaryController {
List<String> proposalResult = mapCnd.getAsList("proposalResult", String.class);
cnd.andEX("info.resultCode", "in", proposalResult);
if (proposalResult != null && proposalResult.contains(ProposalConstant.DETERMINE)) {
List<String> determineTypeOptions = mapCnd.getAsList("proposalDetermineTypes", String.class);
cnd.andEX("info.determineTypeCode", "in", determineTypeOptions);
}
cnd.andEX("info.delegationId", "=", mapCnd.getString("delegationId"));
cnd.andEX("info.stateCode", "=", mapCnd.getString("stateCode"));
if (Boolean.TRUE.equals(mapCnd.getBoolean("caseOnly"))) {
cnd.and("info.stateCode", ">", ProposalState.CASE);
}
cnd.andEX("su.unionId", "=", mapCnd.getString("unionId"));
cnd.andEX("su.unitId", "=", mapCnd.getString("unitId"));
if (!ShiroUtil.hasAnyRoles(new String[]{"sysadmin", "A06", "tamange", "jdhdbt01"})) {
if (ShiroUtil.hasRole("H04")) {
cnd.and("su.unionid", " in ", vi.getMangeUnionStr());
}
}
cnd.asc("info.proposalCode");
cnd.groupBy("info.id");
sql.setCondition(cnd);
List<NutMap> list = proposalInfoService.listMap(sql);
fillExportDetails(list);
list.forEach(v -> {
v.put("brief", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("brief"))));
v.put("measures", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("measures"))));
v.put("replyContent", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("replyContent", ""))));
v.put("leaderCheckOpinion", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("leaderCheckOpinion", ""))));
v.put("feedbackOpinion", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("feedbackOpinion", ""))));
});
List<ExcelExportEntity> excelExportEntities = new ArrayList<ExcelExportEntity>();
@@ -230,8 +262,22 @@ public class proposalExportSummaryController {
});
try {
ViTool.excelResponse(response, "提案表.xlsx");
ExportParams exportParams = new ExportParams();
String exportTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String exportCondition = mapCnd.getString("exportCondition", "无").replaceAll("[\\r\\n]+", " ");
String exportFileCondition = mapCnd.getString("exportFileCondition", "")
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
.replaceAll("\\s+", "");
String exportTitle = mapCnd.getString("exportTitle", "提案汇总表")
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-");
if (exportFileCondition.length() > 80) {
exportFileCondition = exportFileCondition.substring(0, 80);
}
String fileName = exportTitle
+ (StrUtil.isBlank(exportFileCondition) ? "" : "_" + exportFileCondition)
+ "_" + exportTime.replaceAll("[-: ]", "") + ".xlsx";
ViTool.excelResponse(response, fileName);
ExportParams exportParams = new ExportParams(exportTitle + "(查询条件:" + exportCondition
+ ";导出时间:" + exportTime + ")", "提案汇总");
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
workbook.write(response.getOutputStream());
@@ -242,4 +288,70 @@ public class proposalExportSummaryController {
}
/**
* 补充附议人和审核记录,避免数据库聚合长度限制导致导出内容不完整
*
* @param list 提案数据
*/
private void fillExportDetails(List<NutMap> list) {
if (list == null || list.isEmpty()) {
return;
}
List<String> proposalIds = new ArrayList<>();
list.forEach(v -> proposalIds.add(v.getString("id")));
Sql secondedSql = Sqls.create("""
SELECT
ps.proposalId,
su.username,
su.loginname
FROM proposal_seconded ps
LEFT JOIN sys_user su ON su.id = ps.seconderId
WHERE ps.proposalId IN (@proposalIds)
AND ps.isAgree = 1
ORDER BY ps.secondedTime
""").setParam("proposalIds", proposalIds);
Map<String, List<String>> secondedMap = new HashMap<>();
proposalInfoService.listMap(secondedSql).forEach(v -> {
String username = v.getString("username", "");
String loginname = v.getString("loginname", "");
String seconderName = username + (StrUtil.isBlank(loginname) ? "" : "(" + loginname + ")");
secondedMap.computeIfAbsent(v.getString("proposalId"), key -> new ArrayList<>()).add(seconderName);
});
Sql auditSql = Sqls.create("""
SELECT
pa.proposalId,
pa.username,
pa.flag,
pa.opinion,
pa.auditTime,
dict.`name` auditTypeName
FROM proposal_audit pa
LEFT JOIN sys_dict dict ON dict.`code` = pa.other
WHERE pa.proposalId IN (@proposalIds)
ORDER BY pa.auditTime
""").setParam("proposalIds", proposalIds);
Map<String, List<String>> auditMap = new HashMap<>();
proposalInfoService.listMap(auditSql).forEach(v -> {
Boolean flag = v.getBoolean("flag");
String auditResult = flag == null ? "" : (flag ? "通过" : "不通过");
String auditTypeName = v.getString("auditTypeName", "");
String auditTitle = StrUtil.isBlank(auditTypeName) ? auditResult
: auditTypeName + (StrUtil.isBlank(auditResult) ? "" : "/" + auditResult);
String opinion = HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("opinion", "")));
String auditRecord = v.getString("username", "")
+ (StrUtil.isBlank(auditTitle) ? "" : "【" + auditTitle + "】")
+ (StrUtil.isBlank(opinion) ? "" : ":" + opinion)
+ (StrUtil.isBlank(v.getString("auditTime")) ? "" : "(" + v.getString("auditTime") + ")");
auditMap.computeIfAbsent(v.getString("proposalId"), key -> new ArrayList<>()).add(auditRecord);
});
list.forEach(v -> {
v.put("seconderNames", String.join("、", secondedMap.getOrDefault(v.getString("id"), new ArrayList<>())));
v.put("auditRecords", String.join(";", auditMap.getOrDefault(v.getString("id"), new ArrayList<>())));
});
}
}
@@ -133,7 +133,8 @@ public class proposalExportWholeController {
@Ok("void")
@RequiresAuthentication
public void exportAllProposal(ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
String searchName2, String searchKeyword2, HttpServletResponse response) throws Exception {
String searchName2, String searchKeyword2, String exportFileCondition,
HttpServletResponse response) throws Exception {
CndPlus cnd = CndPlus.create();
Sql sql = Sqls.create("""
SELECT
@@ -171,7 +172,14 @@ public class proposalExportWholeController {
response.reset();
response.setContentType("application/x-msdownload;charset=utf-8");
String fileName = "提案汇总文件夹";
String exportTime = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss", Locale.CHINA);
String fileCondition = StrUtil.blankToDefault(exportFileCondition, "全部提案")
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
.replaceAll("\\s+", "");
if (fileCondition.length() > 80) {
fileCondition = fileCondition.substring(0, 80);
}
String fileName = "提案汇总文件夹_" + fileCondition + "_" + exportTime;
// 创建临时文件夹