diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java new file mode 100644 index 0000000..af8c650 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/config/FieldDisplayNameQueryService.java @@ -0,0 +1,18 @@ +package com.seeyon.apps.src_leasebill.config; + +import com.seeyon.aicloud.common.JsonUtils; +import com.seeyon.apps.src_leasebill.constant.LeaseBillConstant; +import com.seeyon.ctp.common.AppContext; + +import java.util.Map; + +public class FieldDisplayNameQueryService { + + private LeaseBillConfigProvider configProvider = (LeaseBillConfigProvider) AppContext.getBean("leaseBillConfigProvider"); + + public String getDisplayName(String fieldName) { + String jsonStr = configProvider.getBizConfigByKey(LeaseBillConstant.fieldDisplayMap); + Map map = (Map)JsonUtils.parseObject(jsonStr, Map.class); + return map.get(fieldName); + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/constant/LeaseBillConstant.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/constant/LeaseBillConstant.java index 722ba46..7669e33 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/constant/LeaseBillConstant.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/constant/LeaseBillConstant.java @@ -7,7 +7,10 @@ public enum LeaseBillConstant { annualPaymentTypeOneMapName("年方案一","年缴费方式一取值映射名称"), annualPaymentTypeTwoMapName("年方案二","年缴费方式二取值映射名称"), assistiveFormNo("ZJZDMX","账单生成辅助表表单编码"), - loginName("shenxian","辅助表创建人"); + loginName("shenxian","辅助表创建人"), + billAssistiveTableName("账单生成辅助表","账单生成辅助表明细表名称"), + fieldDisplayMap("","字段显示名称映射"), + ; // u8cUrl("http://ip:port", "U8C地址"), LeaseBillConstant(String defaultValue, String description) { diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java index ca9eea4..2776811 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/controller/LeaseBillController.java @@ -2,9 +2,9 @@ package com.seeyon.apps.src_leasebill.controller; import cn.hutool.log.Log; import com.alibaba.fastjson.JSONObject; -import com.seeyon.aicloud.common.JsonUtils; import com.seeyon.apps.common.config.ICstConfigApi; import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_leasebill.config.FieldDisplayNameQueryService; import com.seeyon.apps.src_leasebill.config.LeaseBillConfigProvider; import com.seeyon.apps.src_leasebill.constant.LeaseBillConstant; import com.seeyon.apps.src_leasebill.dao.ILeaseBillDao; @@ -29,14 +29,33 @@ import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.*; +/** + * 租金账单控制器 + * 功能:接收前端参数 → 调用账单工具类生成账单 → 保存至表单 + */ public class LeaseBillController extends BaseController { - private static Log log = Log.get(LeaseBillController.class); - private LeaseBillConfigProvider configProvider = (LeaseBillConfigProvider) AppContext.getBean("leaseBillConfigProvider"); - protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi"); + private static final Log log = Log.get(LeaseBillController.class); + /** 配置提供者 */ + private final LeaseBillConfigProvider configProvider = + (LeaseBillConfigProvider) AppContext.getBean("leaseBillConfigProvider"); + + /** 配置API */ + protected final ICstConfigApi cstConfigApi = + (ICstConfigApi) AppContext.getBean("cstConfigApi"); + + /** 字段名称查询服务 */ + private final FieldDisplayNameQueryService fieldDisplayNameQueryService = + (FieldDisplayNameQueryService) AppContext.getBean("fieldDisplayNameQueryService"); + + /** 表单工厂 */ private FormFactory formFactory; + /** 账单DAO */ + private ILeaseBillDao leaseBillDao; + + // ======================== 注入 ======================== public FormFactory getFormFactory() { if (formFactory == null) { formFactory = (FormFactory) AppContext.getBean("formFactory"); @@ -48,10 +67,6 @@ public class LeaseBillController extends BaseController { this.formFactory = formFactory; } - private ILeaseBillDao leaseBillDao; - public void setLeaseBillDao(ILeaseBillDao leaseBillDao) { - this.leaseBillDao = leaseBillDao; - } public ILeaseBillDao getLeaseBillDao() { if (leaseBillDao == null) { leaseBillDao = (ILeaseBillDao) AppContext.getBean("leaseBillDao"); @@ -59,157 +74,183 @@ public class LeaseBillController extends BaseController { return leaseBillDao; } + public void setLeaseBillDao(ILeaseBillDao leaseBillDao) { + this.leaseBillDao = leaseBillDao; + } + + // ======================== 主入口:生成账单 ======================== public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception { - log.info("进入生成账单ajax方法"); + log.info("====== 进入生成账单Ajax方法 ======"); + ConfigVo configVo = getYdctLeaseBillConfig(); DateUtil dateUtil = new DateUtil(); LeaseBillUtil leaseBillUtil = new LeaseBillUtil(); FormExportUtil formExportUtil = new FormExportUtil(); - // 设置返回值对象 + + // 返回结果 Map res = new HashMap<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmsssss"); + SimpleDateFormat sdfNo = new SimpleDateFormat("yyyyMMddHHmmsssss"); + request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); + // ===================== 1. 读取请求体参数 ===================== BufferedReader reader = request.getReader(); - String line; StringBuilder requestBody = new StringBuilder(); - while((line = reader.readLine())!=null){ + String line; + while ((line = reader.readLine()) != null) { requestBody.append(line); } + String data = requestBody.toString(); String decodedParam = URLDecoder.decode(data, "UTF-8"); - String[] datas = decodedParam.split("&"); + String[] datas = decodedParam.split("&"); JSONObject jsonObject = new JSONObject(); - for(int i = 0 ; i < datas.length ; i ++ ){ - String[] params = datas[i].split("="); - if(params.length>1){ - jsonObject.put(params[0],params[1]); - }else{ - if(params[0].equals("bdid")){ - jsonObject.put("bdid","0"); - } + for (String paramStr : datas) { + String[] params = paramStr.split("="); + if (params.length > 1) { + jsonObject.put(params[0], params[1]); + } else if (params[0].equals("bdid")) { + jsonObject.put("bdid", "0"); } } + + log.info("前端入参:{}", jsonObject.toString()); + try { + // ===================== 2. 账单编号处理 ===================== String bdidValue = jsonObject.getString("bdid"); - log.info("当前账单编号为:"+bdidValue); - if("0".equals(bdidValue)){ - Date formDate = new Date(); - String formId = simpleDateFormat.format(formDate); -// 账单编号 - bdidValue = formId; -// formDataVo.getNewFieldDataMap().put("账单编号", formId); - }else { - List ids = leaseBillDao.leaseBillByCode(bdidValue); - for (int i = 0; i < ids.size(); i++) { -// 删除明细账单 - leaseBillDao.deleteBillsByBillId(ids.get(i)); -// 删除主表数据 - leaseBillDao.deleteBillById(ids.get(i)); + log.info("当前账单编号:{}", bdidValue); + + String code = bdidValue; + if ("0".equals(bdidValue)) { + // 编号为0 → 新建编号 + code = sdfNo.format(new Date()); + log.info("生成新账单编号:{}", code); + } else { + // 已有编号 → 删除旧数据 + log.info("删除旧账单数据,编号:{}", bdidValue); + List ids = getLeaseBillDao().leaseBillByCode(bdidValue); + for (String id : ids) { + getLeaseBillDao().deleteBillsByBillId(id); + getLeaseBillDao().deleteBillById(id); } } - String code = bdidValue; -// 开始日期 + + // ===================== 3. 租赁起止时间 ===================== String startDateStr = jsonObject.getString("startDate"); - Date startDate = sdf.parse(startDateStr); -// 结束日期 String endDateStr = jsonObject.getString("endDate"); + Date startDate = sdf.parse(startDateStr); Date endDate = sdf.parse(endDateStr); -// 设置面积 - String jifeifs = jsonObject.getString("jifeifs"); -// 设置合同开始日期 + + // 开始时间 Calendar startTime = Calendar.getInstance(); startTime.setTime(startDate); -// 判断合同开始时间是否为月底 - log.info("入参: " + jsonObject.toString()); + + // 判断是否为月底 boolean isMaxDay = false; int currentDay = startTime.get(Calendar.DAY_OF_MONTH); int maxDay = startTime.getActualMaximum(Calendar.DAY_OF_MONTH); - if(currentDay==maxDay){ + if (currentDay == maxDay) { isMaxDay = true; } -// 设置合同结束日期 + + // 结束时间(+1天,左闭右开) Calendar endTime = Calendar.getInstance(); endTime.setTime(endDate); endTime.add(Calendar.DAY_OF_MONTH, 1); -// 根据缴费方式设置开始结束时间 + // ===================== 4. 缴费方式 ===================== String jiaofeifs = jsonObject.getString("jiaofeifs"); int jfzqNum = dateUtil.getCycleNum(jiaofeifs); + String jifeifs = jsonObject.getString("jifeifs"); + log.info("缴费方式:{},周期月数:{},计费方式:{}", jiaofeifs, jfzqNum, jifeifs); + + // ===================== 5. 生成账单 ===================== + List> rents = new ArrayList<>(); FormExport formExport = new FormExport(); -// 租金 - List> rents = new ArrayList>(); - if(jfzqNum==12){ + + if (jfzqNum == 12) { + // 年缴 → 判断年缴计算方式 String njiaofeifs = jsonObject.getString("njiaofeifs"); - if(StringUtil.isEmpty(njiaofeifs)){ + if (StringUtil.isEmpty(njiaofeifs)) { res.put("success", true); res.put("name", AppContext.currentUserLoginName()); res.put("s", "请选择年缴费计算方式"); res.put("num", ""); render(response, JSONUtil.toJSONString(res)); return null; - }else{ - if(njiaofeifs.equals(configProvider.getBizConfigByKey(LeaseBillConstant.annualPaymentTypeOneMapName))){ -// 采用方式一/正常年度 - System.out.println("开始生成账单数据"); - log.info("正常年度-生成账单数据"); - rents = leaseBillUtil.getLeaseBillYers1(startTime,endTime,isMaxDay,jfzqNum,jsonObject,jifeifs); - }else if(njiaofeifs.equals(configProvider.getBizConfigByKey(LeaseBillConstant.annualPaymentTypeTwoMapName))){ -// 采用方式二/非正常年度 - System.out.println("开始生成账单数据"); - log.info("非正常年度-生成账单数据"); - rents = leaseBillUtil.getLeaseBillYers2(startTime,endTime,isMaxDay,jfzqNum,jsonObject,jifeifs); - } } - }else{ -// 根据标准方法生成 - System.out.println("开始生成账单数据"); - log.info("开始用标准方法生成账单数据"); - rents = leaseBillUtil.getLeaseBill(startTime,endTime,isMaxDay,jfzqNum,jsonObject,jifeifs); + + String type1 = configProvider.getBizConfigByKey(LeaseBillConstant.annualPaymentTypeOneMapName); + String type2 = configProvider.getBizConfigByKey(LeaseBillConstant.annualPaymentTypeTwoMapName); + + if (njiaofeifs.equals(type1)) { + log.info("【年缴方式1】按周期年度生成账单"); + rents = leaseBillUtil.getLeaseBillYear1(startTime, endTime, isMaxDay, jfzqNum, jsonObject, jifeifs); + } else if (njiaofeifs.equals(type2)) { + log.info("【年缴方式2】按自然年度生成账单"); + rents = leaseBillUtil.getLeaseBillYear2(startTime, endTime, isMaxDay, jfzqNum, jsonObject, jifeifs); + } + } else { + // 月/季/半年/一次性 + log.info("【标准方式】生成账单"); + rents = leaseBillUtil.getLeaseBill(startTime, endTime, isMaxDay, jfzqNum, jsonObject, jifeifs); } - if(rents.size() == 0){ - log.info("要生成账单的数据为空"); + + if (rents.isEmpty()) { + log.info("====== 账单数据为空,无需生成 ======"); + } else { + log.info("====== 共生成 {} 期账单 ======", rents.size()); } - log.info("创建档案"); - List subordinateFormExports = formExportUtil.setSubordinateFormValue(rents); - Map billMap = new HashMap(); - billMap.put("账单编号", code); - List valueExports = formExportUtil.setFormValue(billMap); - formExport.setSubordinateForms(subordinateFormExports); - formExport.setValues(valueExports); + + // ===================== 6. 保存到表单 ===================== + log.info("====== 开始保存账单到表单 ======"); + List detailList = formExportUtil.setSubordinateFormValue(rents); + + Map mainData = new HashMap<>(); + mainData.put(fieldDisplayNameQueryService.getDisplayName("账单编号"), code); + + List mainFields = formExportUtil.setFormValue(mainData); + + formExport.setSubordinateForms(detailList); + formExport.setValues(mainFields); + String loginName = configProvider.getBizConfigByKey(LeaseBillConstant.loginName); - getFormFactory().importBusinessFormData(loginName, configProvider.getBizConfigByKey(LeaseBillConstant.assistiveFormNo), - formExport, new String[] {}); + String formNo = configProvider.getBizConfigByKey(LeaseBillConstant.assistiveFormNo); + + getFormFactory().importBusinessFormData(loginName, formNo, formExport, new String[]{}); + + // ===================== 7. 返回结果 ===================== res.put("success", true); res.put("name", AppContext.currentUserLoginName()); res.put("s", ""); res.put("num", code); - }catch (Exception e){ + + } catch (Exception e) { + log.error("生成账单异常", e); e.printStackTrace(); + res.put("success", false); + res.put("s", "生成账单失败:" + e.getMessage()); } + render(response, JSONUtil.toJSONString(res)); return null; } - - /** - * 给前台渲染json数据 - * @param response - * @param text - */ + // ======================== 输出JSON ======================== private void render(HttpServletResponse response, String text) { response.setContentType("application/json;charset=UTF-8"); try { - response.setContentLength(text.getBytes("UTF-8").length); response.getWriter().write(text); } catch (IOException e) { - e.printStackTrace(); + log.error("输出JSON异常", e); } } + // ======================== 配置 ======================== public ConfigVo getYdctLeaseBillConfig() { return cstConfigApi.getConfig(getPluginId()); } @@ -217,4 +258,4 @@ public class LeaseBillController extends BaseController { public String getPluginId() { return LeaseBillConstant.getPluginId(); } -} +} \ No newline at end of file diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/dao/impl/LeaseBillDaoImpl.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/dao/impl/LeaseBillDaoImpl.java index cf55557..4458e6b 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/dao/impl/LeaseBillDaoImpl.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/dao/impl/LeaseBillDaoImpl.java @@ -1,5 +1,6 @@ package com.seeyon.apps.src_leasebill.dao.impl; +import com.seeyon.apps.src_leasebill.config.FieldDisplayNameQueryService; import com.seeyon.apps.src_leasebill.config.LeaseBillConfigProvider; import com.seeyon.apps.src_leasebill.constant.LeaseBillConstant; import com.seeyon.apps.src_leasebill.dao.ILeaseBillDao; @@ -18,6 +19,7 @@ import java.util.List; public class LeaseBillDaoImpl implements ILeaseBillDao { private LeaseBillConfigProvider configProvider = (LeaseBillConfigProvider) AppContext.getBean("leaseBillConfigProvider"); + private FieldDisplayNameQueryService fieldDisplayNameQueryService = (FieldDisplayNameQueryService) AppContext.getBean("fieldDisplayNameQueryService"); private String getFormNo(){ return configProvider.getBizConfigByKey(LeaseBillConstant.assistiveFormNo); @@ -28,7 +30,7 @@ public class LeaseBillDaoImpl implements ILeaseBillDao { List lists = new ArrayList(); TableContext tableContext = FormTableExecutor.master(getFormNo()); List conditions = new ArrayList(); - conditions.add(FormWhereCondition.build().display("账单编号").value(code)); + conditions.add(FormWhereCondition.build().display(fieldDisplayNameQueryService.getDisplayName("账单编号")).value(code)); List queryColumns = new ArrayList(); queryColumns.add("ID"); List formColumns = FormTableExecutor.query(tableContext, queryColumns, conditions, false); @@ -48,7 +50,8 @@ public class LeaseBillDaoImpl implements ILeaseBillDao { @Override public int deleteBillsByBillId(String formmainId) throws BusinessException, SQLException { - TableContext sub = FormTableExecutor.sub(getFormNo(), "明细表1"); + String tableName = configProvider.getBizConfigByKey(LeaseBillConstant.billAssistiveTableName); + TableContext sub = FormTableExecutor.sub(getFormNo(), tableName); List conditions = new ArrayList<>(); conditions.add(FormWhereCondition.build().display("formmain_id").value(formmainId)); return FormTableExecutor.delete(sub,conditions); diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java index d155a26..d55b801 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_leasebill/util/LeaseBillUtil.java @@ -1,280 +1,278 @@ package com.seeyon.apps.src_leasebill.util; import com.alibaba.fastjson.JSONObject; +import com.seeyon.apps.src_leasebill.config.FieldDisplayNameQueryService; +import com.seeyon.ctp.common.AppContext; import java.text.SimpleDateFormat; import java.util.*; +/** + * 租金账单生成工具类 + * 功能:根据租赁周期、缴费方式、计费方式,自动拆分生成多期租金账单 + */ public class LeaseBillUtil { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + /** + * 字段名称查询服务(用于获取表单显示名称) + */ + private final FieldDisplayNameQueryService fieldDisplayNameService = + (FieldDisplayNameQueryService) AppContext.getBean("fieldDisplayNameQueryService"); /** - * 生成租金账单 - * @param startTime 开始时间 - * @param endTime 结束时间 - * @param isMaxDay 是否每月最后一天 - * @param jfzqNum 缴费周期月 - * @param jsonObject 请求参数 - * @param jifeifs 计费方式 - * @return + * 日期格式化工具:yyyy-MM-dd */ - public List> getLeaseBill(Calendar startTime, Calendar endTime, boolean isMaxDay, int jfzqNum, - JSONObject jsonObject,String jifeifs){ - List> rents = new ArrayList<>(); - System.out.println("生成账单的参数: " + startTime + ","+ endTime+"," + isMaxDay+"," + jfzqNum +","+ jsonObject.toString() +","+ jifeifs); - DateUtil dateUtil = new DateUtil(); -// 两个日期相差多少月 - int monthNum = dateUtil.betweenMonthByTwoCalendar(startTime,endTime); - if(jfzqNum==99){ -// 一次性账单生成 - Map rent = new HashMap<>(); - float zlmjFloat = 0; - double zf = 0; - if("面积计费".equals(jifeifs)){ - String mjStr = jsonObject.getString("mj"); - zlmjFloat = Float.parseFloat(mjStr); - String mjzjStr = jsonObject.getString("mjzj"); - double mjzj = dateUtil.stringToNum(mjzjStr); - zf = mjzj*zlmjFloat*monthNum; - }else if ("固定租金".equals(jifeifs)){ - zlmjFloat = 1; - String gdzjStr = jsonObject.getString("gdzj"); - double gdzj = dateUtil.stringToNum(gdzjStr); -// zf = gdzj*zlmjFloat*monthNum; - zf = gdzj*zlmjFloat; - } - rent.put("开始日期",sdf.format(startTime.getTime())); - endTime.add(Calendar.DATE, -1); - rent.put("结束日期",sdf.format(endTime.getTime())); - rent.put("租费",zf+""); - rents.add(rent); - }else{ -// 月,季,半年,账单生成 - int termNum = monthNum/jfzqNum; - int mo = monthNum%jfzqNum; - if(mo!=0){ - termNum++; - } - float zlmjFloat = 0; - double zf = 0; - if("面积计费".equals(jifeifs)){ - String mjStr = jsonObject.getString("mj"); - zlmjFloat = Float.parseFloat(mjStr); - String mjzjStr = jsonObject.getString("mjzj"); - double mjzj = dateUtil.stringToNum(mjzjStr); - zf = mjzj*zlmjFloat; - }else if ("固定租金".equals(jifeifs)){ - zlmjFloat = 1; - String gdzjStr = jsonObject.getString("gdzj"); - double gdzj = dateUtil.stringToNum(gdzjStr); - zf = gdzj*zlmjFloat; - } - for(int i = 0 ; i < termNum ; i ++) { - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { - Map rentMap = new HashMap(); -// 设置租费时间 - rentMap.put("开始日期", sdf.format(startTime.getTime())); - if (!isMaxDay) { - startTime.add(Calendar.MONTH, jfzqNum); - startTime.add(Calendar.DAY_OF_MONTH, -1); - }else{ - startTime.add(Calendar.MONTH, jfzqNum); - startTime.set(Calendar.DAY_OF_MONTH, startTime.getActualMaximum(Calendar.DAY_OF_MONTH)-1); - } - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { -// rentMap.put("期间月数-租金",jfzqNum+""); -// rentMap.put("租费", (zf * jfzqNum) + ""); - if("面积计费".equals(jifeifs)){ - rentMap.put("租费", (zf * jfzqNum) + ""); - }else if ("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - } - rentMap.put("结束日期", sdf.format(startTime.getTime())); - } else { - //两个日期相差多少月 - startTime.add(Calendar.MONTH, jfzqNum*-1); - startTime.add(Calendar.DAY_OF_MONTH, 1); - int qijianyueshu = dateUtil.betweenMonthByTwoCalendar(startTime, endTime); -// rentMap.put("期间月数-租金",qijianyueshu+""); - if("面积计费".equals(jifeifs)){ - rentMap.put("租费", (zf * qijianyueshu) + ""); - }else if ("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - } - - endTime.add(Calendar.DAY_OF_MONTH, -1); - rentMap.put("结束日期", sdf.format(endTime.getTime())); - } - startTime.add(Calendar.DAY_OF_MONTH, 1); - if (isMaxDay) { - startTime.set(Calendar.DAY_OF_MONTH, startTime.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - rents.add(rentMap); - } - } - } - return rents; - } - + private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); /** - * 生成租金账单 - * @param startTime 开始时间 - * @param endTime 结束时间 - * @param isMaxDay 是否每月最后一天 - * @param jfzqNum 缴费周期月 - * @param jsonObject 请求参数 - * @param jifeifs 计费方式 - * @return + * 日期工具类实例 */ - public List> getLeaseBillYers1(Calendar startTime, Calendar endTime, boolean isMaxDay, int jfzqNum, - JSONObject jsonObject,String jifeifs){ - System.out.println("生成账单的参数: " + startTime + ","+ endTime+"," + isMaxDay+"," + jfzqNum +","+ jsonObject.toString() +","+ jifeifs); - List> rents = new ArrayList<>(); - DateUtil dateUtil = new DateUtil(); -// 两个日期相差多少月 - int monthNum = dateUtil.betweenMonthByTwoCalendar(startTime,endTime); - int termNum = monthNum/jfzqNum; - int mo = monthNum%jfzqNum; - if(mo!=0){ - termNum++; - } - float zlmjFloat = 0; - double zf = 0; - if("面积计费".equals(jifeifs)){ - String mjStr = jsonObject.getString("mj"); - zlmjFloat = Float.parseFloat(mjStr); - String mjzjStr = jsonObject.getString("mjzj"); - double mjzj = dateUtil.stringToNum(mjzjStr); - zf = mjzj*zlmjFloat; - }else if ("固定租金".equals(jifeifs)){ - zlmjFloat = 1; - String gdzjStr = jsonObject.getString("gdzj"); - double gdzj = dateUtil.stringToNum(gdzjStr); - zf = gdzj*zlmjFloat; - } - for(int i = 0 ; i < termNum ; i ++) { - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { - Map rentMap = new HashMap(); -// 设置租费时间 - rentMap.put("开始日期", sdf.format(startTime.getTime())); - startTime.add(Calendar.MONTH, jfzqNum); - startTime.add(Calendar.DAY_OF_MONTH, -1); - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { -// rentMap.put("期间月数-租金",jfzqNum+""); -// rentMap.put("租费", (zf * jfzqNum) + ""); - if("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - }else{ - rentMap.put("租费", (zf * jfzqNum) + ""); - } - rentMap.put("结束日期", sdf.format(startTime.getTime())); - } else { - //两个日期相差多少月 - startTime.add(Calendar.MONTH, jfzqNum*-1); - startTime.add(Calendar.DAY_OF_MONTH, 1); - int qijianyueshu = dateUtil.betweenMonthByTwoCalendar(startTime, endTime); -// rentMap.put("期间月数-租金",qijianyueshu+""); -// rentMap.put("租费", (zf * qijianyueshu) + ""); - if("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - }else{ - rentMap.put("租费", (zf * qijianyueshu) + ""); - } - endTime.add(Calendar.DAY_OF_MONTH, -1); - rentMap.put("结束日期", sdf.format(endTime.getTime())); - } - startTime.add(Calendar.DAY_OF_MONTH, 1); - if (isMaxDay) { - startTime.set(Calendar.DAY_OF_MONTH, startTime.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - rents.add(rentMap); - } + private final DateUtil dateUtil = new DateUtil(); + + // ======================== 【1】主方法:生成租金账单(支持一次性/周期) ======================== + + /** + * 生成租金账单(对外主方法) + * + * @param startTime 租赁开始时间 + * @param endTime 租赁结束时间 + * @param isMonthLastDay 是否每月最后一天 + * @param payCycleMonths 缴费周期(月):1=月缴,3=季度缴,6=半年缴,12=年缴,99=一次性 + * @param params 表单参数JSON + * @param chargeType 计费方式:面积计费 / 固定租金 + * @return 每期账单集合(开始日期、结束日期、租费) + */ + public List> getLeaseBill(Calendar startTime, Calendar endTime, boolean isMonthLastDay, + int payCycleMonths, JSONObject params, String chargeType) { + // ====================== 控制台打印:生成账单入参 ====================== + System.out.println("======================================"); + System.out.println("【主方法】生成账单参数开始"); + System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); + System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("是否每月最后一天:" + isMonthLastDay); + System.out.println("缴费周期(月):" + payCycleMonths); + System.out.println("计费方式:" + chargeType); + System.out.println("表单参数:" + params.toString()); + System.out.println("【主方法】生成账单参数结束"); + System.out.println("======================================"); + + List> billList = new ArrayList<>(); + int totalLeaseMonths = dateUtil.betweenMonthByTwoCalendar(startTime, endTime); + + // 一次性缴费 + if (payCycleMonths == 99) { + Map bill = createOneTimeBill(startTime, endTime, totalLeaseMonths, params, chargeType); + billList.add(bill); + return billList; } - return rents; + + // 周期缴费:月/季/半年 + return createCycleBills(startTime, endTime, isMonthLastDay, payCycleMonths, params, chargeType); } + // ======================== 【2】按年周期账单(版本1) ======================== - /** - * 生成租金账单 - * @param startTime 开始时间 - * @param endTime 结束时间 - * @param isMaxDay 是否每月最后一天 - * @param jfzqNum 缴费周期月 - * @param jsonObject 请求参数 - * @param jifeifs 计费方式 - * @return + /** + * 按年生成账单(版本1:按周期月数计算) */ - public List> getLeaseBillYers2(Calendar startTime, Calendar endTime, boolean isMaxDay, int jfzqNum, - JSONObject jsonObject,String jifeifs){ - System.out.println("生成账单的参数: " + startTime + ","+ endTime+"," + isMaxDay+"," + jfzqNum +","+ jsonObject.toString() +","+ jifeifs); - List> rents = new ArrayList<>(); - DateUtil dateUtil = new DateUtil(); -// 两个日期相差多少年 - Calendar calendar = Calendar.getInstance(); - calendar.setTime(startTime.getTime()); - int starYear = startTime.get(Calendar.YEAR); + public List> getLeaseBillYear1(Calendar startTime, Calendar endTime, boolean isMonthLastDay, + int payCycleMonths, JSONObject params, String chargeType) { + // ====================== 控制台打印:生成账单入参 ====================== + System.out.println("======================================"); + System.out.println("【按年方法1】生成账单参数开始"); + System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); + System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("是否每月最后一天:" + isMonthLastDay); + System.out.println("缴费周期(月):" + payCycleMonths); + System.out.println("计费方式:" + chargeType); + System.out.println("表单参数:" + params.toString()); + System.out.println("【按年方法1】生成账单参数结束"); + System.out.println("======================================"); + + return createCycleBills(startTime, endTime, isMonthLastDay, payCycleMonths, params, chargeType); + } + + // ======================== 【3】按自然年切割账单(版本2) ======================== + + /** + * 按自然年生成账单(版本2:按自然年12.31切割) + */ + public List> getLeaseBillYear2(Calendar startTime, Calendar endTime, boolean isMonthLastDay, + int payCycleMonths, JSONObject params, String chargeType) { + // ====================== 控制台打印:生成账单入参 ====================== + System.out.println("======================================"); + System.out.println("【按年方法2】生成账单参数开始"); + System.out.println("租赁开始时间:" + sdf.format(startTime.getTime())); + System.out.println("租赁结束时间:" + sdf.format(endTime.getTime())); + System.out.println("是否每月最后一天:" + isMonthLastDay); + System.out.println("缴费周期(月):" + payCycleMonths); + System.out.println("计费方式:" + chargeType); + System.out.println("表单参数:" + params.toString()); + System.out.println("【按年方法2】生成账单参数结束"); + System.out.println("======================================"); + + List> billList = new ArrayList<>(); + int startYear = startTime.get(Calendar.YEAR); int endYear = endTime.get(Calendar.YEAR); - int termNum = endYear-starYear+1; - float zlmjFloat = 0; - double zf = 0; - if("面积计费".equals(jifeifs)){ - String mjStr = jsonObject.getString("mj"); - zlmjFloat = Float.parseFloat(mjStr); - String mjzjStr = jsonObject.getString("mjzj"); - double mjzj = dateUtil.stringToNum(mjzjStr); - zf = mjzj*zlmjFloat; - }else if ("固定租金".equals(jifeifs)){ - zlmjFloat = 1; - String gdzjStr = jsonObject.getString("gdzj"); - double gdzj = dateUtil.stringToNum(gdzjStr); - zf = gdzj*zlmjFloat; + int totalYears = endYear - startYear + 1; + + Calendar tempStart = (Calendar) startTime.clone(); + Calendar yearBaseCal = (Calendar) tempStart.clone(); + + for (int i = 0; i < totalYears; i++) { + if (!tempStart.before(endTime)) break; + + Map bill = new HashMap<>(); + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.format(tempStart.getTime())); + + // 设置为当年最后一天:12月31日 + tempStart.set(Calendar.MONTH, 11); + tempStart.set(Calendar.DATE, 31); + + if (tempStart.before(endTime)) { + // 当前年度在结束时间之前 → 完整年度账单 + Calendar nextYearStart = (Calendar) tempStart.clone(); + nextYearStart.add(Calendar.DATE, 1); + + int monthCount = dateUtil.betweenMonthByTwoCalendar(yearBaseCal, nextYearStart); + double rent = calculateRent(monthCount, params, chargeType); + + bill.put(fieldDisplayNameService.getDisplayName("租费"), String.valueOf(rent)); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(tempStart.getTime())); + + yearBaseCal = (Calendar) tempStart.clone(); + } else { + // 最后一个年度 → 不足一年 + int monthCount = dateUtil.betweenMonthByTwoCalendar(yearBaseCal, endTime); + double rent = calculateRent(monthCount, params, chargeType); + + Calendar realEnd = (Calendar) endTime.clone(); + realEnd.add(Calendar.DATE, -1); + + bill.put(fieldDisplayNameService.getDisplayName("租费"), String.valueOf(rent)); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(realEnd.getTime())); } - for(int i = 0 ; i < termNum ; i ++) { - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { - Map rentMap = new HashMap(); -// 设置租费时间 - rentMap.put("开始日期", sdf.format(startTime.getTime())); - startTime.set(Calendar.MONTH, 11); - startTime.set(Calendar.DATE, 31); - if (startTime.getTime().getTime() < endTime.getTime().getTime()) { -// rentMap.put("期间月数-租金",jfzqNum+""); - startTime.add(Calendar.DAY_OF_MONTH, 1); - int qijianyueshu = dateUtil.betweenMonthByTwoCalendar(calendar, startTime); - startTime.add(Calendar.DAY_OF_MONTH, -1); -// rentMap.put("租费", (zf * qijianyueshu) + ""); - if ("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - }else{ - rentMap.put("租费", (zf * qijianyueshu) + ""); - } - rentMap.put("结束日期", sdf.format(startTime.getTime())); - calendar.set(Calendar.MONTH, 11); - calendar.set(Calendar.DATE, 31); - } else { - //两个日期相差多少月 - int qijianyueshu = dateUtil.betweenMonthByTwoCalendar(calendar, endTime); -// rentMap.put("期间月数-租金",qijianyueshu+""); -// rentMap.put("租费", (zf * qijianyueshu) + ""); - if ("固定租金".equals(jifeifs)){ - rentMap.put("租费", (zf * 1) + ""); - }else{ - rentMap.put("租费", (zf * qijianyueshu) + ""); - } - endTime.add(Calendar.DAY_OF_MONTH, -1); - rentMap.put("结束日期", sdf.format(endTime.getTime())); - } - startTime.add(Calendar.DAY_OF_MONTH, 1); - calendar.add(Calendar.DAY_OF_MONTH, 1); - if (isMaxDay) { - startTime.set(Calendar.DAY_OF_MONTH, startTime.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - rents.add(rentMap); + // 下一期开始时间 = 当前结束时间 + 1天 + tempStart.add(Calendar.DATE, 1); + // 👆 这里已经修复,删除了错误的 calendar.add(...) + + // 如果是月末模式,设置为当月最后一天 + if (isMonthLastDay) { + tempStart.set(Calendar.DATE, tempStart.getActualMaximum(Calendar.DATE)); } + + billList.add(bill); } - return rents; + + return billList; } -} + // ======================== 【核心工具方法】 ======================== + + /** + * 创建一次性缴费账单 + */ + private Map createOneTimeBill(Calendar startTime, Calendar endTime, int totalMonths, + JSONObject params, String chargeType) { + Map bill = new HashMap<>(); + double rent = calculateRent(totalMonths, params, chargeType); + + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.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("租费"), String.valueOf(rent)); + return bill; + } + + /** + * 创建周期缴费账单(月缴/季度/半年/年缴) + */ + private List> createCycleBills(Calendar startTime, Calendar endTime, boolean isMonthLastDay, + int payCycleMonths, JSONObject params, String chargeType) { + List> billList = new ArrayList<>(); + int totalLeaseMonths = dateUtil.betweenMonthByTwoCalendar(startTime, endTime); + + // 计算总缴费期数:向上取整 + int periodCount = totalLeaseMonths / payCycleMonths; + if (totalLeaseMonths % payCycleMonths != 0) { + periodCount++; + } + + Calendar tempStart = (Calendar) startTime.clone(); + + // 循环生成每一期账单 + for (int i = 0; i < periodCount; i++) { + if (!tempStart.before(endTime)) break; + + Map bill = new HashMap<>(); + bill.put(fieldDisplayNameService.getDisplayName("开始日期"), sdf.format(tempStart.getTime())); + + // 计算本期结束日 = 开始时间 + 周期月数 - 1天 + Calendar periodEnd = (Calendar) tempStart.clone(); + periodEnd.add(Calendar.MONTH, payCycleMonths); + periodEnd.add(Calendar.DATE, -1); + + if (periodEnd.before(endTime)) { + // 正常完整周期 + double rent = calculateRent(payCycleMonths, params, chargeType); + bill.put(fieldDisplayNameService.getDisplayName("租费"), String.valueOf(rent)); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(periodEnd.getTime())); + } else { + // 最后一期:不足一个缴费周期 + int realMonths = dateUtil.betweenMonthByTwoCalendar(tempStart, endTime); + double rent = calculateRent(realMonths, params, chargeType); + + Calendar realEnd = (Calendar) endTime.clone(); + realEnd.add(Calendar.DATE, -1); + + bill.put(fieldDisplayNameService.getDisplayName("租费"), String.valueOf(rent)); + bill.put(fieldDisplayNameService.getDisplayName("结束日期"), sdf.format(realEnd.getTime())); + } + + // 下一期开始时间 + tempStart = (Calendar) periodEnd.clone(); + tempStart.add(Calendar.DATE, 1); + + // 月末规则处理 + if (isMonthLastDay) { + tempStart.set(Calendar.DATE, tempStart.getActualMaximum(Calendar.DATE)); + } + + billList.add(bill); + } + + return billList; + } + + /** + * 统一租金计算逻辑(抽离重复代码) + * + * @param months 计费月数 + * @param params 表单参数 + * @param chargeType 计费方式 + * @return 计算后租金金额 + */ + private double calculateRent(int months, JSONObject params, String chargeType) { + double unitPrice = 0; + boolean isAreaCharge = "面积计费".equals(chargeType); + boolean isFixedRent = "固定租金".equals(chargeType); + + if (isAreaCharge) { + // 面积计费:租金 = 面积 × 每平单价 + double area = Double.parseDouble(params.getString("mj")); + double pricePerArea = dateUtil.stringToNum(params.getString("mjzj")); + unitPrice = area * pricePerArea; + } else if (isFixedRent) { + // 固定租金:直接取固定金额 + unitPrice = dateUtil.stringToNum(params.getString("gdzj")); + } + + // 固定租金不乘月数,其他计费方式 × 月数 + return isFixedRent ? unitPrice : unitPrice * months; + } +} \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_leasebill/spring/spring-dao.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_leasebill/spring/spring-dao.xml index 451b067..c86ff91 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_leasebill/spring/spring-dao.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_leasebill/spring/spring-dao.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js index 9d1d97e..739698d 100644 --- a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js +++ b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/leaseBillResources/js/openUnflow.js @@ -81,19 +81,19 @@ if(targetObj[key].display === "年缴费方案选项") { njiaofeifs = targetObj[key].showValue } - if(targetObj[key].display === "实租单价") { + if(targetObj[key].display === "租赁单价") { mjzj = targetObj[key].showValue } if(targetObj[key].display === "固定租金标准") { gdzj = targetObj[key].showValue } - if(targetObj[key].display === "计租开始日期") { + if(targetObj[key].display === "计租日期") { startDate = targetObj[key].showValue } if(targetObj[key].display === "合同截止日期") { endDate = targetObj[key].showValue } - if(targetObj[key].display === "租赁总面积") { + if(targetObj[key].display === "租赁面积") { mj = targetObj[key].showValue } if(targetObj[key].display === "账单编号") {