package com.slibra.business.service.impl; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Objects; import com.slibra.business.domain.AutoFeedback; import com.slibra.business.domain.TXinyiIndustry; import com.slibra.business.mapper.AutoFeedbackMapper; import com.slibra.business.mapper.TXinyiIndustryMapper; import com.slibra.business.res.SmartAdd; import com.slibra.business.service.IFrontService; import com.slibra.common.DecimalUtils; import com.slibra.common.utils.DateUtils; import com.slibra.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.slibra.business.mapper.TXinyiMedicineParamMapper; import com.slibra.business.domain.TXinyiMedicineParam; import com.slibra.business.service.ITXinyiMedicineParamService; import static com.slibra.common.constant.MyConstants.*; /** * 智能投药参数设置Service业务层处理 * * @author slibra * @date 2024-09-09 */ @Slf4j @Service public class TXinyiMedicineParamServiceImpl implements ITXinyiMedicineParamService { @Autowired private TXinyiMedicineParamMapper tXinyiMedicineParamMapper; @Autowired private TXinyiIndustryMapper xinyiIndustryMapper; @Autowired private IFrontService frontService; @Autowired private AutoFeedbackMapper autoFeedbackMapper; /** * 查询智能投药参数设置 * * @param id 智能投药参数设置主键 * @return 智能投药参数设置 */ @Override public TXinyiMedicineParam selectTXinyiMedicineParamById(Long id) { return tXinyiMedicineParamMapper.selectTXinyiMedicineParamById(id); } /** * 查询智能投药参数设置列表 * * @param tXinyiMedicineParam 智能投药参数设置 * @return 智能投药参数设置 */ @Override public List selectTXinyiMedicineParamList(TXinyiMedicineParam tXinyiMedicineParam) { //日期兜底处理 String timeBegin = tXinyiMedicineParam.getTimeBegin(); String timeEnd = tXinyiMedicineParam.getTimeEnd(); Date nowDate = DateUtils.getNowDate(); Date dayBefore7 = DateUtils.plusDate(-7, nowDate); if(StringUtils.isBlank(timeBegin)) tXinyiMedicineParam.setTimeBegin(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dayBefore7)); if(StringUtils.isBlank(timeEnd)) tXinyiMedicineParam.setTimeEnd(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, nowDate)); return tXinyiMedicineParamMapper.selectTXinyiMedicineParamList(tXinyiMedicineParam); } /** * 新增智能投药参数设置 * * @param tXinyiMedicineParam 智能投药参数设置 * @return 结果 */ @Override public int insertTXinyiMedicineParam(TXinyiMedicineParam tXinyiMedicineParam) { tXinyiMedicineParam.setCreateTime(DateUtils.getNowDate()); return tXinyiMedicineParamMapper.insertTXinyiMedicineParam(tXinyiMedicineParam); } /** * 修改智能投药参数设置 * * @param tXinyiMedicineParam 智能投药参数设置 * @return 结果 */ @Override public int updateTXinyiMedicineParam(TXinyiMedicineParam tXinyiMedicineParam) { tXinyiMedicineParam.setUpdateTime(DateUtils.getNowDate()); return tXinyiMedicineParamMapper.updateTXinyiMedicineParam(tXinyiMedicineParam); } /** * 批量删除智能投药参数设置 * * @param ids 需要删除的智能投药参数设置主键 * @return 结果 */ @Override public int deleteTXinyiMedicineParamByIds(Long[] ids) { return tXinyiMedicineParamMapper.deleteTXinyiMedicineParamByIds(ids); } /** * 删除智能投药参数设置信息 * * @param id 智能投药参数设置主键 * @return 结果 */ @Override public int deleteTXinyiMedicineParamById(Long id) { return tXinyiMedicineParamMapper.deleteTXinyiMedicineParamById(id); } @Override public TXinyiMedicineParam getLatestRecord() { TXinyiMedicineParam latestRecord = this.tXinyiMedicineParamMapper.getLatestRecord(); if (!Objects.isNull(latestRecord)) { TXinyiIndustry tXinyiIndustry = this.xinyiIndustryMapper.selectTXinyiIndustryNewest(); if (!Objects.isNull(tXinyiIndustry)) { latestRecord.setTytjTransientLL(DecimalUtils.getNLengthHalfUp(tXinyiIndustry.getSJTYJLY(), INT_4)); } //2024年09月14日11:02:12 有可能用户选择的是仪表或者化验,需要获取实时数据 //获取最新的实时数据 SmartAdd smartAdd = this.frontService.smartAddDataInfo(); if(!Objects.isNull(smartAdd)){ //获取对应的类型 Integer hycXsyType = latestRecord.getHycXsyType(); Integer qycAdType = latestRecord.getQycAdType(); Integer qycYxyType = latestRecord.getQycYxyType(); Integer jsCodType = latestRecord.getJsCodType(); Integer jsLlType = latestRecord.getJsLlType(); Integer jsTnType = latestRecord.getJsTnType(); if(!Objects.isNull(hycXsyType)){ if(1 == hycXsyType){//化验 latestRecord.setHycXsyOne(smartAdd.getHyXsyHYOne()); latestRecord.setHycXsyTwo(smartAdd.getHyXsyHYTwo()); }else if(2 == hycXsyType){//预测 latestRecord.setHycXsyOne(smartAdd.getHyXsyYCOne()); latestRecord.setHycXsyTwo(smartAdd.getHyXsyYCTwo()); } } if(!Objects.isNull(qycAdType) && 1 == qycAdType){//化验 latestRecord.setQycAdOne(smartAdd.getQyAdHYOne()); latestRecord.setQycAdTwo(smartAdd.getQyAdHYTwo()); } if(!Objects.isNull(qycYxyType) && 1 == qycYxyType){//化验 latestRecord.setQycYxyOne(smartAdd.getQyXsyHYOne()); latestRecord.setQycYxyTwo(smartAdd.getQyXsyHYTwo()); } if(!Objects.isNull(jsCodType)){ if(1 == jsCodType){//仪表 latestRecord.setJsCodOne(smartAdd.getJsCodYB()); latestRecord.setJsCodTwo(smartAdd.getJsCodYB()); }else if(2 == jsCodType){//化验 latestRecord.setJsCodOne(smartAdd.getJsCodHY()); latestRecord.setJsCodTwo(smartAdd.getJsCodHY()); } } if(!Objects.isNull(jsLlType) && 1 == jsLlType){//仪表 latestRecord.setJsLlOne(smartAdd.getJslYB()); latestRecord.setJsLlTwo(smartAdd.getJslYB()); } if(!Objects.isNull(jsTnType) && 1 == jsTnType){//仪表 latestRecord.setJsTnOne(smartAdd.getJsTnYB()); latestRecord.setJsTnTwo(smartAdd.getJsTnYB()); } } } //todo 调用组态,获取投加状态 latestRecord.setAddType(Math.random() < 0.5 ? 0 : 1); //2024年09月18日10:26:57 把实时的计算的碳源投加总量 和 瞬时加药量也返回 this.addExtra(latestRecord); return latestRecord; } private void addExtra(TXinyiMedicineParam latestRecord) { /*BigDecimal total = this.calculateMedicineByLastRecord(latestRecord); latestRecord.setMedicineAmount(total); BigDecimal yymd = latestRecord.getYymd(); if(!Objects.isNull(total) && !Objects.isNull(yymd) && yymd.compareTo(BigDecimal.ZERO) > 0){ latestRecord.setTytjTransientLL(DecimalUtils.getNLengthHalfUp(total.divide(yymd, NUMBER_SCALE_10, RoundingMode.HALF_UP).divide(BigDecimal_1000, NUMBER_SCALE_10, RoundingMode.HALF_UP), INT_3)); }*/ //2024年09月20日10:12:43 做个兜底处理,防止计算的结果是负数 BigDecimal val = this.calculateMedicineByLastRecord(latestRecord); if(!Objects.isNull(val) && val.compareTo(BigDecimal.ZERO) < 0){ log.info("计算得到的碳源投加量是负数,按0处理"); val = BigDecimal.ZERO; } latestRecord.setMedicineAmount(val); } /** * 2025年04月27日10:26:29 逻辑调整:以前此方法只返回计算的碳源投加的结果,现在改成: * 返回map:存放: * 1.计算结果 CALCULATE_VAL * 2.用户选择的采用的哪个池子投药 CHOOSE_POOL:0一池 1二池 2自动 3手动 * 3.真实的投药池子(自动的话,2选1)ADD_POOL:0一池 1二池 * 4.投加时间 这里不用,由定时任务处理。 * 5.创哥返回的控制系数 KZXS 自动就取最大值,非自动选哪个池子就返回哪个的 * 6.创哥返回的后反馈设定 HTFKSD 自动就取最大值,非自动选哪个池子就返回哪个的 * @param param * @return */ public HashMap calculateMedicineByLastRecord(TXinyiMedicineParam param) { HashMap map = new HashMap<>(); if (Objects.isNull(param)) { return map; } //2025年04月24日17:21:58 控制系数获取创哥预测的值,不再由用户主动输入 AutoFeedback autoFeedback1 = autoFeedbackMapper.selectAutoFeedbackLatestByPool(1); AutoFeedback autoFeedback2 = autoFeedbackMapper.selectAutoFeedbackLatestByPool(2); if(Objects.isNull(autoFeedback1) || Objects.isNull(autoFeedback2)){ log.error("获取创哥推荐的系数失败,无法计算"); return map; } BigDecimal htfksd1 = autoFeedback1.getBasePara(); BigDecimal htfksd2 = autoFeedback2.getBasePara(); BigDecimal kzxs1 = autoFeedback1.getCoef(); BigDecimal kzxs2 = autoFeedback2.getCoef(); //计算用到的值 Integer hycXsyType = param.getHycXsyType(); BigDecimal hycXsyOne = param.getHycXsyOne(); BigDecimal hycXsyTwo = param.getHycXsyTwo(); //2025年04月24日17:21:58 控制系数获取创哥预测的值,不再由用户主动输入 // BigDecimal htfksd = param.getHtfksd(); Integer qycAdType = param.getQycAdType(); BigDecimal qycAdOne = param.getQycAdOne(); BigDecimal qycAdTwo = param.getQycAdTwo(); Integer qycYxyType = param.getQycYxyType(); BigDecimal qycYxyOne = param.getQycYxyOne(); BigDecimal qycYxyTwo = param.getQycYxyTwo(); BigDecimal xzxs = param.getXzxs(); BigDecimal jzxs = param.getJzxs(); Integer jsLlType = param.getJsLlType(); BigDecimal jsLlOne = param.getJsLlOne(); BigDecimal jsLlTwo = param.getJsLlTwo(); BigDecimal slfpxs = param.getSlfpxs(); //2025年04月24日17:21:58 控制系数获取创哥预测的值,不再由用户主动输入 // BigDecimal kzxs = param.getKzxs(); Integer jsCodType = param.getJsCodType(); BigDecimal jsCodOne = param.getJsCodOne(); BigDecimal jsCodTwo = param.getJsCodTwo(); BigDecimal zhxs = param.getZhxs(); BigDecimal tydl = param.getTydl(); BigDecimal medicineAmount = param.getMedicineAmount();//手动需要 Integer type = param.getType();//0自动 1一号池 2二号池 3人工投放 BigDecimal yymd = param.getYymd(); BigDecimal sxps = param.getSxps(); //计算 if(!Objects.isNull(type)) { if(3 == type){ // return medicineAmount; map.put("CHOOSE_POOL", 3); map.put("ADD_POOL", null); map.put("CALCULATE_VAL", medicineAmount); map.put("HTFKSD", null); map.put("KZXS", null); return map; } //计算1号池的值 BigDecimal oneResult = this.getResultByDiff(hycXsyType, hycXsyOne, htfksd1, qycAdType, qycAdOne, qycYxyType, qycYxyOne, xzxs, jzxs, jsLlType, jsLlOne, slfpxs, kzxs1, jsCodType, jsCodOne, zhxs, tydl, "one", yymd, sxps); //计算二号池的值 BigDecimal twoResult = this.getResultByDiff(hycXsyType, hycXsyTwo, htfksd2, qycAdType, qycAdTwo, qycYxyType, qycYxyTwo, xzxs, jzxs, jsLlType, jsLlTwo, slfpxs, kzxs2, jsCodType, jsCodTwo, zhxs, tydl, "two", yymd, sxps); //判断,返回值 if(0 == type){ map.put("CHOOSE_POOL", 2); if(!Objects.isNull(oneResult) && !Objects.isNull(twoResult)){ if(oneResult.compareTo(twoResult) > 0){ map.put("ADD_POOL", 0); map.put("CALCULATE_VAL", oneResult); map.put("HTFKSD", htfksd1); map.put("KZXS", kzxs1); return map; }else{ map.put("ADD_POOL", 1); map.put("CALCULATE_VAL", twoResult); map.put("HTFKSD", htfksd2); map.put("KZXS", kzxs2); return map; } } } else if(1 == type) { map.put("CHOOSE_POOL", 0); map.put("ADD_POOL", 0); map.put("CALCULATE_VAL", oneResult); map.put("HTFKSD", htfksd1); map.put("KZXS", kzxs1); return map; }else if(2 == type){ map.put("CHOOSE_POOL", 1); map.put("ADD_POOL", 1); map.put("CALCULATE_VAL", twoResult); map.put("HTFKSD", htfksd2); map.put("KZXS", kzxs2); return map; } else { return map;//错误的配置 } } return map; } private BigDecimal getResultByDiff(Integer hycXsyType, BigDecimal hycXsyVal, BigDecimal htfksd, Integer qycAdType, BigDecimal qycAdVal, Integer qycYxyType, BigDecimal qycYxyVal, BigDecimal xzxs, BigDecimal jzxs, Integer jsLlType, BigDecimal jsLlVal, BigDecimal slfpxs, BigDecimal kzxs, Integer jsCodType, BigDecimal jsCodVal, BigDecimal zhxs, BigDecimal tydl, String whichCZ, BigDecimal yymd, BigDecimal sxps) { //2024年09月14日10:26:11 不同池子,根据不同类型,获取最新的数据,计算碳源投加量 //获取最新的实时数据 SmartAdd smartAdd = this.frontService.smartAddDataInfo(); if(!Objects.isNull(smartAdd)){ if("one".equals(whichCZ)){//一池 if(!Objects.isNull(hycXsyType)){ if(1 == hycXsyType){//化验 hycXsyVal = smartAdd.getHyXsyHYOne(); }else if(2 == hycXsyType){//预测 hycXsyVal = smartAdd.getHyXsyYCOne(); } } if(!Objects.isNull(qycAdType) && 1 == qycAdType){//化验 qycAdVal = smartAdd.getQyAdHYOne(); } if(!Objects.isNull(qycYxyType) && 1 == qycYxyType){//化验 qycYxyVal = smartAdd.getQyXsyHYOne(); } if(!Objects.isNull(jsCodType)){ if(1 == jsCodType){//仪表 jsCodVal = smartAdd.getJsCodYB(); }else if(2 == jsCodType){//化验 jsCodVal = smartAdd.getJsCodHY(); } } if(!Objects.isNull(jsLlType) && 1 == jsLlType){//仪表 jsLlVal = smartAdd.getJslYB(); } }else {//二池 if(!Objects.isNull(hycXsyType)){ if(1 == hycXsyType){//化验 hycXsyVal = smartAdd.getHyXsyHYTwo(); }else if(2 == hycXsyType){//预测 hycXsyVal = smartAdd.getHyXsyYCTwo(); } } if(!Objects.isNull(qycAdType) && 1 == qycAdType){//化验 qycAdVal = smartAdd.getQyAdHYTwo(); } if(!Objects.isNull(qycYxyType) && 1 == qycYxyType){//化验 qycYxyVal = smartAdd.getQyXsyHYTwo(); } if(!Objects.isNull(jsCodType)){ if(1 == jsCodType){//仪表 jsCodVal = smartAdd.getJsCodYB(); }else if(2 == jsCodType){//化验 jsCodVal = smartAdd.getJsCodHY(); } } if(!Objects.isNull(jsLlType) && 1 == jsLlType){//仪表 jsLlVal = smartAdd.getJslYB(); } } } //兜底处理 if(Objects.isNull(hycXsyVal)) hycXsyVal = BigDecimal.ZERO; if(Objects.isNull(htfksd)) htfksd = BigDecimal.ZERO; if(Objects.isNull(qycAdVal)) qycAdVal = BigDecimal.ZERO; if(Objects.isNull(qycYxyVal)) qycYxyVal = BigDecimal.ZERO; if(Objects.isNull(xzxs)) xzxs = BigDecimal.ZERO; if(Objects.isNull(jzxs)) jzxs = BigDecimal.ZERO; if(Objects.isNull(jsLlVal)) jsLlVal = BigDecimal.ZERO; if(Objects.isNull(slfpxs)) slfpxs = BigDecimal.ZERO; if(Objects.isNull(kzxs)) kzxs = BigDecimal.ZERO; if(Objects.isNull(jsCodVal)) jsCodVal = BigDecimal.ZERO; if(Objects.isNull(zhxs)) zhxs = BigDecimal.ZERO; if(Objects.isNull(tydl)) tydl = BigDecimal.ZERO; if(Objects.isNull(yymd) || yymd.compareTo(BigDecimal.ZERO) <= 0) return null;//除数不能为0 if(Objects.isNull(sxps)){ sxps = BigDecimal.ZERO; } //1)计算挟走量 BigDecimal xzl = (((BigDecimal_2.multiply(hycXsyVal).subtract(htfksd)).add(((qycAdVal.add(qycYxyVal)).multiply(xzxs).subtract(htfksd)))).multiply((jzxs.subtract(BigDecimal_1)))).multiply((jsLlVal.multiply(slfpxs))).divide(BigDecimal_1000, NUMBER_SCALE_4, RoundingMode.HALF_UP); log.info("挟走量是{}", xzl); //2)计算碳源投加总量 BigDecimal total = (xzl.multiply(kzxs).subtract((jsLlVal.multiply(slfpxs).multiply(jsCodVal).multiply(zhxs).divide(BigDecimal_1000, NUMBER_SCALE_4, RoundingMode.HALF_UP)))).divide(tydl, NUMBER_SCALE_4, RoundingMode.HALF_UP); log.info("碳源投加总量是{}", total); //2024年09月14日15:33:37 计算出来的结果太大,是几千,把第三步公式也加上 //计算加药流量 BigDecimal result = DecimalUtils.getNLengthHalfUp(total.divide(yymd, NUMBER_SCALE_10, RoundingMode.HALF_UP).divide(BigDecimal_1000, NUMBER_SCALE_10, RoundingMode.HALF_UP).multiply(sxps), INT_3); log.info("最终的加药流量是{}", result); return result; } /*public static void main(String[] args) { System.out.println(Math.random() < 0.5 ? 0 : 1); String strJson = "{\n" + " \"createBy\": \"test11\",\n" + " \"createTime\": \"2024-09-19 11:39:00\",\n" + " \"updateBy\": null,\n" + " \"updateTime\": null,\n" + " \"remark\": null,\n" + " \"id\": 29,\n" + " \"numberBeng\": 1,\n" + " \"type\": 2,\n" + " \"jsLlType\": 0,\n" + " \"jsLlOne\": 2815,\n" + " \"jsLlTwo\": 3,\n" + " \"jsCodType\": 0,\n" + " \"jsCodOne\": 179.78,\n" + " \"jsCodTwo\": 4,\n" + " \"hycXsyType\": 0,\n" + " \"hycXsyOne\": 12.29,\n" + " \"hycXsyTwo\": 5,\n" + " \"qycYxyType\": 0,\n" + " \"qycYxyOne\": 3.7,\n" + " \"qycYxyTwo\": 6,\n" + " \"qycAdType\": 0,\n" + " \"qycAdOne\": 9.41,\n" + " \"qycAdTwo\": 7,\n" + " \"jsTnType\": 0,\n" + " \"jsTnOne\": 46.31,\n" + " \"jsTnTwo\": 8,\n" + " \"htfksd\": 12,\n" + " \"jzxs\": 11.5,\n" + " \"xzxs\": 5,\n" + " \"kzxs\": 5.5,\n" + " \"slfpxs\": 4,\n" + " \"tydl\": 1.2,\n" + " \"zhxs\": 0.8,\n" + " \"sxps\": 4,\n" + " \"yymd\": 4,\n" + " \"zxqdll\": 1.02,\n" + " \"tdb\": 1.54,\n" + " \"medicineAmount\": 27.606,\n" + " \"delFlag\": 0,\n" + " \"revision\": null,\n" + " \"tytjTransientLL\": 0.0101,\n" + " \"addType\": 1,\n" + " \"timeBegin\": null,\n" + " \"timeEnd\": null\n" + "}"; TXinyiMedicineParam tXinyiMedicineParam = JSON.parseObject(strJson, TXinyiMedicineParam.class); System.out.println(calculateMedicineByLastRecord(tXinyiMedicineParam)); }*/ }