diff --git a/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java b/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java index af8c650..838b77c 100644 --- a/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java +++ b/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java @@ -12,7 +12,17 @@ public class FieldDisplayNameQueryService { public String getDisplayName(String fieldName) { String jsonStr = configProvider.getBizConfigByKey(LeaseBillConstant.fieldDisplayMap); + if (jsonStr == null || jsonStr.trim().isEmpty()) { + throw new RuntimeException("字段显示名称映射配置为空,请检查插件配置 fieldDisplayMap"); + } Map map = (Map)JsonUtils.parseObject(jsonStr, Map.class); - return map.get(fieldName); + if (map == null) { + throw new RuntimeException("字段显示名称映射解析失败,配置内容:" + jsonStr); + } + String displayName = map.get(fieldName); + if (displayName == null) { + throw new RuntimeException("字段显示名称映射中未找到key:" + fieldName); + } + return displayName; } } diff --git a/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java b/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java index 1beb8ae..4ee2f3b 100644 --- a/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java +++ b/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java @@ -78,8 +78,34 @@ public class LeaseBillController extends BaseController { this.leaseBillDao = leaseBillDao; } - // ======================== 主入口:生成账单 ======================== + // ======================== 主入口 ======================== public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception { + String action = request.getParameter("action"); + if ("getFieldDisplayMap".equals(action)) { + return getFieldDisplayMap(request, response); + } + return generateBill(request, response); + } + + // ======================== 获取字段显示名称映射 ======================== + private ModelAndView getFieldDisplayMap(HttpServletRequest request, HttpServletResponse response) { + log.info("====== 获取字段显示名称映射 ======"); + Map res = new HashMap<>(); + try { + String jsonStr = configProvider.getBizConfigByKey(LeaseBillConstant.fieldDisplayMap); + res.put("success", true); + res.put("data", jsonStr); + } catch (Exception e) { + log.error("获取字段映射异常", e); + res.put("success", false); + res.put("s", "获取字段映射失败:" + e.getMessage()); + } + render(response, JSONUtil.toJSONString(res)); + return null; + } + + // ======================== 生成账单 ======================== + private ModelAndView generateBill(HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("====== 进入生成账单Ajax方法 ======"); ConfigVo configVo = getYdctLeaseBillConfig(); @@ -104,10 +130,17 @@ public class LeaseBillController extends BaseController { } String data = requestBody.toString(); + if (data.isEmpty()) { + res.put("success", false); + res.put("s", "请求参数为空"); + render(response, JSONUtil.toJSONString(res)); + return null; + } String decodedParam = URLDecoder.decode(data, "UTF-8"); String[] datas = decodedParam.split("&"); JSONObject jsonObject = new JSONObject(); for (String paramStr : datas) { + if (paramStr.isEmpty()) continue; String[] params = paramStr.split("="); if (params.length > 1) { jsonObject.put(params[0], params[1]); @@ -120,10 +153,13 @@ public class LeaseBillController extends BaseController { try { // ===================== 2. 账单编号处理 ===================== String bdidValue = jsonObject.getString("bdid"); + if (bdidValue == null) { + bdidValue = ""; + } log.info("当前账单编号:{}", bdidValue); String code = bdidValue; - if ("0".equals(bdidValue)) { + if ("0".equals(bdidValue) || bdidValue.isEmpty()) { // 编号为0 → 新建编号 code = sdfNo.format(new Date()); log.info("生成新账单编号:{}", code); @@ -175,10 +211,8 @@ public class LeaseBillController extends BaseController { // 年缴 → 判断年缴计算方式 String njiaofeifs = jsonObject.getString("njiaofeifs"); if (StringUtil.isEmpty(njiaofeifs)) { - res.put("success", true); - res.put("name", AppContext.currentUserLoginName()); + res.put("success", false); res.put("s", "请选择年缴费计算方式"); - res.put("num", ""); render(response, JSONUtil.toJSONString(res)); return null; } diff --git a/src/main/java/com/seeyon/apps/src_leasebill/util/DateUtil.java b/src/main/java/com/seeyon/apps/src_leasebill/util/DateUtil.java index 9cd3f6d..486e38f 100644 --- a/src/main/java/com/seeyon/apps/src_leasebill/util/DateUtil.java +++ b/src/main/java/com/seeyon/apps/src_leasebill/util/DateUtil.java @@ -23,7 +23,20 @@ public class DateUtil { int yearsDiff = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR); int monthsDiff = yearsDiff * 12 + endCalendar.get(Calendar.MONTH)- startCalendar.get(Calendar.MONTH); - if (endCalendar.get(Calendar.DAY_OF_MONTH) > startCalendar.get(Calendar.DAY_OF_MONTH)) { + + // 月末日期规范化:将起始日为月末的日期规范化为相同参考日,避免不同月份天数差异导致误判 + // 例如:1月31日→2月28日,规范化为 1月28日→2月28日,day相同不加月 + int startDay = startCalendar.get(Calendar.DAY_OF_MONTH); + int endDay = endCalendar.get(Calendar.DAY_OF_MONTH); + int startMaxDay = startCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); + int endMaxDay = endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); + if (startDay == startMaxDay) { + startDay = Math.min(startDay, endMaxDay); + } + if (endDay == endMaxDay) { + endDay = Math.min(endDay, startMaxDay); + } + if (endDay > startDay) { monthsDiff++; } return monthsDiff; @@ -106,19 +119,18 @@ public class DateUtil { public int getCycleNum (String cycle){ - int cycleNum = 1; if("月".equals(cycle)||"月付".equals(cycle)){ - cycleNum = 1; + return 1; }else if("季".equals(cycle)||"季付".equals(cycle)){ - cycleNum = 3; + return 3; }else if("半年".equals(cycle)||"半年付".equals(cycle)){ - cycleNum = 6; + return 6; }else if("年".equals(cycle)||"年付".equals(cycle)){ - cycleNum = 12; + return 12; }else if("一次性".equals(cycle)||"其他".equals(cycle)){ - cycleNum = 99; + return 99; } - return cycleNum; + throw new IllegalArgumentException("未识别的缴费方式:" + cycle + ",请检查表单缴费方式字段值"); } public double stringToNum(String str){ diff --git a/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java b/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java index 27af9a4..48b75df 100644 --- a/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java +++ b/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java @@ -22,9 +22,11 @@ public class LeaseBillUtil { (FieldDisplayNameQueryService) AppContext.getBean("fieldDisplayNameQueryService"); /** - * 日期格式化工具:yyyy-MM-dd + * 获取日期格式化工具(线程安全) */ - private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + private SimpleDateFormat getSdf() { + return new SimpleDateFormat("yyyy-MM-dd"); + } /** * 日期工具类实例 @@ -54,8 +56,8 @@ public class LeaseBillUtil { // ====================== 控制台打印:生成账单入参 ====================== System.out.println("======================================"); System.out.println("【主方法】生成账单参数开始"); - System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); - System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("租赁开始时间:" + getSdf().format(startTime.getTime())); + System.out.println("租赁结束时间:" + getSdf().format(endTime.getTime())); System.out.println("是否每月最后一天:" + isMonthLastDay); System.out.println("缴费周期(月):" + payCycleMonths); System.out.println("计费方式:" + chargeType); @@ -88,8 +90,8 @@ public class LeaseBillUtil { // ====================== 控制台打印:生成账单入参 ====================== System.out.println("======================================"); System.out.println("【按年方法1】生成账单参数开始"); - System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); - System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("租赁开始时间:" + getSdf().format(startTime.getTime())); + System.out.println("租赁结束时间:" + getSdf().format(endTime.getTime())); System.out.println("是否每月最后一天:" + isMonthLastDay); System.out.println("缴费周期(月):" + payCycleMonths); System.out.println("计费方式:" + chargeType); @@ -111,8 +113,8 @@ public class LeaseBillUtil { // ====================== 控制台打印:生成账单入参 ====================== System.out.println("======================================"); System.out.println("【按年方法2】生成账单参数开始"); - System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); - System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("租赁开始时间:" + getSdf().format(startTime.getTime())); + System.out.println("租赁结束时间:" + getSdf().format(endTime.getTime())); System.out.println("是否每月最后一天:" + isMonthLastDay); System.out.println("缴费周期(月):" + payCycleMonths); System.out.println("计费方式:" + chargeType); @@ -132,7 +134,7 @@ public class LeaseBillUtil { if (!tempStart.before(endTime)) break; Map bill = new HashMap<>(); - bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.format(tempStart.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), getSdf().format(tempStart.getTime())); // 设置为当年最后一天:12月31日 tempStart.set(Calendar.MONTH, 11); @@ -147,7 +149,7 @@ public class LeaseBillUtil { String rent = calculateRent(monthCount, params, chargeType); bill.put(fieldDisplayNameService.getDisplayName("租费"), rent); - bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(tempStart.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), getSdf().format(tempStart.getTime())); yearBaseCal = (Calendar) tempStart.clone(); } else { @@ -159,7 +161,7 @@ public class LeaseBillUtil { realEnd.add(Calendar.DATE, -1); bill.put(fieldDisplayNameService.getDisplayName("租费"), rent); - bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(realEnd.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), getSdf().format(realEnd.getTime())); } // 下一期开始时间 = 当前结束时间 + 1天 @@ -186,12 +188,12 @@ public class LeaseBillUtil { Map bill = new HashMap<>(); String rent = calculateRent(totalMonths, params, chargeType); - bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.format(startTime.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), getSdf().format(startTime.getTime())); // 结束时间 = 原结束时间 -1天 Calendar realEnd = (Calendar) endTime.clone(); realEnd.add(Calendar.DATE, -1); - bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(realEnd.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), getSdf().format(realEnd.getTime())); bill.put(fieldDisplayNameService.getDisplayName("租费"), rent); return bill; @@ -218,7 +220,7 @@ public class LeaseBillUtil { if (!tempStart.before(endTime)) break; Map bill = new HashMap<>(); - bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.format(tempStart.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), getSdf().format(tempStart.getTime())); // 计算本期结束日 = 开始时间 + 周期月数 - 1天 Calendar periodEnd = (Calendar) tempStart.clone(); @@ -229,7 +231,7 @@ public class LeaseBillUtil { // 正常完整周期 String rent = calculateRent(payCycleMonths, params, chargeType); bill.put(fieldDisplayNameService.getDisplayName("租费"), rent); - bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(periodEnd.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), getSdf().format(periodEnd.getTime())); } else { // 最后一期:不足一个缴费周期 int realMonths = dateUtil.betweenMonthByTwoCalendar(tempStart, endTime); @@ -239,7 +241,7 @@ public class LeaseBillUtil { realEnd.add(Calendar.DATE, -1); bill.put(fieldDisplayNameService.getDisplayName("租费"), rent); - bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(realEnd.getTime())); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), getSdf().format(realEnd.getTime())); } // 下一期开始时间 diff --git a/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js b/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js index 739698d..f4de38c 100644 --- a/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js +++ b/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js @@ -55,103 +55,79 @@ }, doBiz: function(privateId, messageObj, adaptation) { - var url2 = window.location.origin; + var self = this; messageObj = adaptation.childrenGetData(privateId); - const targetObj = messageObj.formdata.formmains[adaptation.formMessage.tableName] - var jifeifs;// 计费方式 - var jiaofeifs;// 缴费方式 - var njiaofeifs;// 年缴费方式类型 - var mjzj;// 面积单价 - var gdzj;// 固定租金单价 - var startDate;// 合同开始日期 - var endDate;// 合同结束日期 - var mj;// 租赁面积 - var bdid; // 账单编号 - var bdidFieldName; - if (targetObj) { - for (const key in targetObj) { - console.log(targetObj) - if (targetObj.hasOwnProperty(key) && !/^auxiliary/.test(key)) { - if (targetObj[key].display === "计费方式") { - jifeifs = targetObj[key].showValue - } - if(targetObj[key].display === "缴费方式") { - jiaofeifs = targetObj[key].showValue - } - if(targetObj[key].display === "年缴费方案选项") { - njiaofeifs = targetObj[key].showValue - } - if(targetObj[key].display === "租赁单价") { - mjzj = targetObj[key].showValue - } - if(targetObj[key].display === "固定租金标准") { - gdzj = targetObj[key].showValue - } - if(targetObj[key].display === "计租日期") { - startDate = targetObj[key].showValue - } - if(targetObj[key].display === "合同截止日期") { - endDate = targetObj[key].showValue - } - if(targetObj[key].display === "租赁面积") { - mj = targetObj[key].showValue - } - if(targetObj[key].display === "账单编号") { - bdidFieldName = key - bdid = targetObj[key].showValue - } + var targetObj = messageObj.formdata.formmains[adaptation.formMessage.tableName]; + + // 先获取字段显示名称映射,再执行业务逻辑 + $.ajax({ + type: 'get', + async: true, + url: encodeURI('/seeyon/leaseBillController.do?action=getFieldDisplayMap&datetime=' + Math.random()), + dataType: 'json', + success: function(mappingRes) { + if (!mappingRes.success) { + $.alert(mappingRes.s || "获取字段映射失败"); + return; + } + var fieldMap = JSON.parse(mappingRes.data); + self.doGenerateBill(targetObj, fieldMap, adaptation, privateId); + }, + error: function() { + $.alert("获取字段映射请求失败"); + } + }); + }, + + doGenerateBill: function(targetObj, fieldMap, adaptation, privateId) { + // 校验字段映射配置完整性 + var requiredKeys = ["计费方式", "缴费方式", "计租日期", "合同截止日期", "账单编号"]; + for (var i = 0; i < requiredKeys.length; i++) { + if (!fieldMap[requiredKeys[i]]) { + $.alert("字段映射配置缺少必要key:" + requiredKeys[i] + ",请联系管理员检查插件配置"); + return; + } + } + + var jifeifs, jiaofeifs, njiaofeifs, mjzj, gdzj, startDate, endDate, mj, bdid, bdidFieldName; + + if (targetObj) { + for (var key in targetObj) { + if (targetObj.hasOwnProperty(key) && !/^auxiliary/.test(key)) { + var display = targetObj[key].display; + if (display === fieldMap["计费方式"]) { + jifeifs = targetObj[key].showValue; + } else if (display === fieldMap["缴费方式"]) { + jiaofeifs = targetObj[key].showValue; + } else if (display === fieldMap["年缴费方案选项"]) { + njiaofeifs = targetObj[key].showValue; + } else if (display === fieldMap["租赁单价"]) { + mjzj = targetObj[key].showValue; + } else if (display === fieldMap["固定租金标准"]) { + gdzj = targetObj[key].showValue; + } else if (display === fieldMap["计租日期"]) { + startDate = targetObj[key].showValue; + } else if (display === fieldMap["合同截止日期"]) { + endDate = targetObj[key].showValue; + } else if (display === fieldMap["租赁面积"]) { + mj = targetObj[key].showValue; + } else if (display === fieldMap["账单编号"]) { + bdidFieldName = key; + bdid = targetObj[key].showValue; } } } - // var s = self; - // var recordId = self.messageObj.formdata.formsons.front_formson_7.records[0].recordId; - // 计费方式 - // var jifeifsfield = { - // fieldId: 'field0032' - // }; - // var jifeifs = csdk.core.getFieldData(jifeifsfield).showValue; - // 缴费方式 - // var jiaofeifsfield = { - // fieldId: 'field0033' - // }; - // var jiaofeifs = csdk.core.getFieldData(jiaofeifsfield).showValue; - // 年缴费方式类型 - // var njiaofeifsfield = { - // fieldId: 'field0034' - // }; - // var njiaofeifs = csdk.core.getFieldData(njiaofeifsfield).showValue; - // 面积单价 - // var mjzjfield = { - // fieldId: 'field0035' - // }; - // var mjzj = csdk.core.getFieldData(mjzjfield).value; - // 固定租金单价 - // var gdzjfield = { - // fieldId: 'field0038' - // }; - // var gdzj = csdk.core.getFieldData(gdzjfield).value; - // 合同开始日期 - // var startDatefield = { - // fieldId: 'field0041' - // }; - // var startDate = csdk.core.getFieldData(startDatefield).value; - // 合同结束日期 - // var endDatefield = { - // fieldId: 'field0042' - // }; - // var endDate = csdk.core.getFieldData(endDatefield).value; - // 租赁面积 - // var mjfield = { - // fieldId: 'field0081' - // }; - // var mj = csdk.core.getFieldData(mjfield).value; - // 账单编号 - // var field0083 = {fieldId: 'field0083'}; - // var field0083value = csdk.core.getFieldData(field0083).value; - // var bdidfield = { - // fieldId: 'field0101' - // }; - // var bdid = csdk.core.getFieldData(bdidfield).value; + } + + // 校验表单必填字段是否已匹配 + if (isEmpty(jifeifs)) { + $.alert("未找到计费方式字段或值为空,请检查表单"); + return; + } + if (isEmpty(jiaofeifs)) { + $.alert("未找到缴费方式字段或值为空,请检查表单"); + return; + } // 判断合同开始日期是否在合同结束日期之前 if (!isEmpty(startDate) || !isEmpty(endDate)) { @@ -172,11 +148,9 @@ } } - var str = ""; $.ajax({ type: 'post', async: true, - // 记得加随机数,不然如果ajax轮询请求会不执行 url: encodeURI('/seeyon/leaseBillController.do?datetime=' + Math.random()), data: { "jifeifs": jifeifs, @@ -192,29 +166,24 @@ dataType: 'json', contentType: 'application/json; charset=UTF-8', success: function(res) { - var randomNum = Math.floor(Math.random() * 10001); if (res.success) { - // $.alert("账单明细生成完成"); - if (bdid == "") { + if (bdid == "" || bdid == "0") { var data = { fieldId: bdidFieldName, fieldData: { - value: res.num + '', //数据值,存入数据库中的value值 - display: res.num + '', //字段渲染在页面上的显示值,通常是经过format后的值 + value: res.num + '', + display: res.num + '', auth: '' } }; csdk.core.setFieldData(data); } - // messageObj.formdata.formmains[adaptation.formMessage.tableName] - // self.adaptation.formdata.field0095.formmains.formmain_0228.field0064.value = randomNum; - // self.adaptation.formdata.field0100__.formmains.formmain_0033.field0102.value = randomNum; } else { $.alert(res.s); } } }); - }, + }, appendChildDom: function() { var self = this; var domStructure = '
' +