实物卡片同步设备定时任务

This commit is contained in:
zhangzhiguo 2025-11-21 09:32:54 +08:00
parent 694a0d61ef
commit bcafba7657
2 changed files with 586 additions and 69 deletions

View File

@ -35,7 +35,9 @@ import java.util.stream.Collectors;
/**
* 实物卡片同步设备定时任务
* 现在使用NewEquipmentCardTaskPlugin
*/
@Deprecated
public class EquipmentCardTaskPlugin extends AbstractTask {
private static final Log log = LogFactory.getLog(EquipmentCardTaskPlugin.class);
@ -217,14 +219,7 @@ public class EquipmentCardTaskPlugin extends AbstractTask {
eceq_equipment.set("zcgj_remark",remark);//备注
DynamicObjectCollection entrys = eceq_equipment.getDynamicObjectCollection("zcgj_entryentity");
QFilter qf = new QFilter("realcard.number", QCP.equals, number);
// if (entrys.size() > 0) {//若分录行数大于0 则取上月的
// for (int i = 0; i < entrys.size(); i++) {
// DynamicObject entry = entrys.get(i);
// long billnoid = entry.getLong("zcgj_debillno");
// qf.and(new QFilter("id", QCP.not_equals, billnoid));
//// entrys.removeIf(record -> isLastMonth(zcgjDebillno));//若属于上个月那就删除重新塞入
// }
// }
DynamicObjectCollection depresplitdetails = QueryServiceHelper.query("fa_depresplitdetail", "id,billno,period,splitdept,assentry.costcentrer,assentry.splitamount", new QFilter[]{qf});
log.info("前depresplitdetails:"+depresplitdetails.toArray().toString() + "长度:"+depresplitdetails.size());
Collections.sort(depresplitdetails , new Comparator<DynamicObject>(){
@ -238,26 +233,35 @@ public class EquipmentCardTaskPlugin extends AbstractTask {
}
});
log.info("后depresplitdetails:"+depresplitdetails.toArray().toString() + "长度:"+depresplitdetails.size());
entrys.clear();
DynamicObjectCollection dynamicObjectCollection = eceq_equipment.getDynamicObjectCollection("zcgj_entryentity");
Set<String> existPeriodData = new HashSet<>();
if (eceq_equipment.get("zcgj_assetnumber") != null && !dynamicObjectCollection.isEmpty()) {
existPeriodData = dynamicObjectCollection.stream().map(data -> data.getDynamicObject("zcgj_assperiod").getString("number")).collect(Collectors.toSet());
}
//entrys.clear();
for (int x = 0 ; x<depresplitdetails.size() ; x++) {
DynamicObject depresplitdetail = depresplitdetails.get(x);
long id = depresplitdetail.getLong("id");
DynamicObject loadSingle = BusinessDataServiceHelper.loadSingle("fa_depresplitdetail", new QFilter[]{new QFilter("id", QCP.equals, id)});
// String billnoid = loadSingle.getString("billno");
//String billnoid = loadSingle.getString("billno");
DynamicObject period = loadSingle.getDynamicObject("period");//折旧区间
DynamicObject splitdept = loadSingle.getDynamicObject("splitdept");//使用部门
DynamicObjectCollection assentry = loadSingle.getDynamicObjectCollection("assentry");
DynamicObject costcentrer = assentry.get(0).getDynamicObject("costcentrer");//成本中心
BigDecimal splitamount = assentry.get(0).getBigDecimal("splitamount");//分摊金额
DynamicObject addNew = new DynamicObject(entrys.getDynamicObjectType());
addNew.set("zcgj_debillno", id);
addNew.set("zcgj_assperiod", period);
addNew.set("zcgj_headusedept", splitdept);
addNew.set("zcgj_entrybillno", number);
addNew.set("zcgj_entryname", assetname);
addNew.set("zcgj_costcenter", costcentrer);
addNew.set("zcgj_shareamount", splitamount);
entrys.add(addNew);
String periodnumber = period.getString("number");
if(existPeriodData.isEmpty() || !existPeriodData.contains(periodnumber) ){
DynamicObject splitdept = loadSingle.getDynamicObject("splitdept");//使用部门
DynamicObjectCollection assentry = loadSingle.getDynamicObjectCollection("assentry");
DynamicObject costcentrer = assentry.get(0).getDynamicObject("costcentrer");//成本中心
BigDecimal splitamount = assentry.get(0).getBigDecimal("splitamount");//分摊金额
DynamicObject addNew = new DynamicObject(entrys.getDynamicObjectType());
addNew.set("zcgj_debillno", id);
addNew.set("zcgj_assperiod", period);
addNew.set("zcgj_headusedept", splitdept);
addNew.set("zcgj_entrybillno", number);
addNew.set("zcgj_entryname", assetname);
addNew.set("zcgj_costcenter", costcentrer);
addNew.set("zcgj_shareamount", splitamount);
addNew.set("zcgj_zjuseorg", eceq_equipment.getDynamicObject("useorg").getLong("id"));//使用组织
entrys.add(addNew);
}
}
SaveServiceHelper.save(new DynamicObject[]{eceq_equipment});
}
@ -380,49 +384,4 @@ public class EquipmentCardTaskPlugin extends AbstractTask {
return msg;
}
}
}
// DynamicObject[] depresplitdetails = BusinessDataServiceHelper.load("fa_depresplitdetail", "billno,period,splitdept,assentry.costcentrer,assentry.splitamount", new QFilter[]{qf});
// DataSet rows = QueryServiceHelper.queryDataSet(this.getClass().getName(), "fa_depresplitdetail", "id,billno,period,splitdept,assentry,assentry.costcentrer,assentry.splitamount",
// new QFilter[]{new QFilter("realcard.number", QCP.equals, number)}, "period.number DESC");
// DynamicObjectCollection depresplitdetails = ORM.create().toPlainDynamicObjectCollection(rows.copy());
// // 增强版比较器自动适配多种日期格式
// for (int i = 0; i < depresplitdetails.size(); i++) {
// DynamicObject item = depresplitdetails.get(i);
//// log.info("排序前 " + i + ": " + item.getDynamicObject("period").getString("number"));
// }
// Comparator<DynamicObject> smartComparator = (o1, o2) -> {
// DynamicObject p1 = o1.getDynamicObject("period");
// DynamicObject p2 = o2.getDynamicObject("period");
// // 空值处理
// if (p1 == null && p2 == null) return 0;
// if (p1 == null) return 1;
// if (p2 == null) return -1;
// String c1 = p1.getString("number");
// String c2 = p2.getString("number");
// if (c1 == null) c1 = "";
// if (c2 == null) c2 = "";
// // 尝试解析为年月
// for (String pattern : new String[]{"yyyyMM", "yyyy-MM", "yyyy/MM"}) {
// try {
// DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
// YearMonth ym1 = YearMonth.parse(c1, fmt);
// YearMonth ym2 = YearMonth.parse(c2, fmt);
// return ym2.compareTo(ym1); // 降序
// } catch (Exception ignored) {}
// }
// // 纯数字比较 "202301"
// try {
// int num1 = Integer.parseInt(c1);
// int num2 = Integer.parseInt(c2);
// return Integer.compare(num2, num1);
// } catch (NumberFormatException e) {
// return c2.compareTo(c1); // 字符串降序
// }
// };
// depresplitdetails.sort(smartComparator);
// for (int i = 0; i < depresplitdetails.size(); i++) {
// DynamicObject item = depresplitdetails.get(i);
// log.info("排序前 " + i + ": " + item.getDynamicObject("period").getString("number"));
// }
//按字段 menuindex 排序
}

View File

@ -0,0 +1,558 @@
package zcgj.zcdev.zcdev.pr.task;
import com.alibaba.excel.util.StringUtils;
import kd.bos.algo.DataSet;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.coderule.service.cache.CodeRuleCache;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperateErrorInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 实物卡片同步设备定时任务已优化判空与性能
*/
public class NewEquipmentCardTaskPlugin extends AbstractTask {
private static final Log log = LogFactory.getLog(NewEquipmentCardTaskPlugin.class);
@Override
public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
// 1. 收集 assetcat.number避免 NPE使用泛型
Set<String> strings = new HashSet<>();
DynamicObject[] equipmenttype = BusinessDataServiceHelper.load(
"zcgj_equipmenttype",
"number,zcgj_assetcat",
new QFilter[]{new QFilter("zcgj_assetcat.number", QCP.is_notnull, "")}
);
if (equipmenttype != null) {
for (DynamicObject dynamicObject : equipmenttype) {
if (dynamicObject == null) continue;
DynamicObject zcgjAssetcat = dynamicObject.getDynamicObject("zcgj_assetcat");
String number = safeGetString(zcgjAssetcat, "number");
if (!isEmpty(number)) {
strings.add(number);
}
}
}
// 2. 获取组织及其下属组织
QFilter filterOrgId = new QFilter("number", QCP.equals, "10006431"); // 中材矿山建设有限公司 (建议配置化)
DynamicObject adminOrg = BusinessDataServiceHelper.loadSingle("bos_org", "number,name,fullname", new QFilter[]{filterOrgId});
if (adminOrg == null) {
log.error("未找到组织10006431任务终止");
return;
}
long orgId = adminOrg.getLong("id");
List<Long> orgIds = new ArrayList<>(1);
orgIds.add(orgId);
List<Long> subOrgIds = OrgUnitServiceHelper.getAllSubordinateOrgs(1L, orgIds, true);
if (subOrgIds == null) subOrgIds = Collections.emptyList();
Set<Long> orgSer = new HashSet<>(subOrgIds);
// 3. 查询资产卡片
QFilter qFilter = new QFilter("assetcat.number", QCP.in, strings);
QFilter qFilter2 = new QFilter("assetunit.id", QCP.in, orgSer);
QFilter qFilter3 = new QFilter("bizstatus", QCP.not_equals, "DELETE");
DynamicObject[] realcards = BusinessDataServiceHelper.load(
"fa_asset_card",
"zcgj_costcenter,headusedept,finentry,assetcat,number,assetname,model,realaccountdate," +
"assetunit,supplier,zcgj_platenumber,unit,zcgj_manufacturer,zcgj_prodate,storeplace,creator,createtime,modifier,modifytime,auditdate,auditor,finentry.fin_originalval,finentry.fin_preresidualval," +
"finentry.fin_depredamount,finentry.fin_preusingamount,finentry.fin_accumdepre,finentry.fin_networth,remark,assetamount",
new QFilter[]{qFilter, qFilter2, qFilter3}
);
int realcardsLen = (realcards == null ? 0 : realcards.length);
log.info("同步的实物数量有 " + realcardsLen);
StringBuilder totalErrorBuilder = new StringBuilder();
if (realcards == null || realcardsLen == 0) {
return;
}
// 提前缓存一些重复查询的结果按需
// 遍历每个实物卡片进行同步
for (DynamicObject realcard : realcards) {
if (realcard == null) continue;
String number = safeGetString(realcard, "number"); // 资产编码
DynamicObject assetcat = realcard.getDynamicObject("assetcat"); // 资产类别
String assetname = safeGetString(realcard, "assetname"); // 资产名称
log.info("同步的实物卡片为 " + number + " " + assetname);
// 基本字段都做了 null 安全读取
String model = safeGetString(realcard, "model");
Date realaccountdate = realcard.getDate("realaccountdate");
DynamicObject assetunit = realcard.getDynamicObject("assetunit");
DynamicObject supplier = realcard.getDynamicObject("supplier");
String platenumber = safeGetString(realcard, "zcgj_platenumber");
DynamicObject unit = realcard.getDynamicObject("unit");
String manufacturer = safeGetString(realcard, "zcgj_manufacturer");
Date prodate = realcard.getDate("zcgj_prodate");
DynamicObject storeplace = realcard.getDynamicObject("storeplace");
DynamicObject headusedept = realcard.getDynamicObject("headusedept");
DynamicObject zcgj_costcenter = realcard.getDynamicObject("zcgj_costcenter");
BigDecimal assetamount = safeGetBigDecimal(realcard, "assetamount");
String remark = safeGetString(realcard, "remark");
DynamicObjectCollection finentrys = realcard.getDynamicObjectCollection("finentry");//财务卡片分录
// 存放地点 fulladdress做了 loadSingle 后的 null 校验
String fulladdress = null;
if (storeplace != null) {
Long spId = storeplace.getLong("id");
if (spId != null) {
DynamicObject storeplaceinfo = BusinessDataServiceHelper.loadSingle("fa_storeplace", new QFilter[]{new QFilter("id", QCP.equals, spId)});
if (storeplaceinfo != null) {
fulladdress = safeGetString(storeplaceinfo, "fulladdress");
}
}
}
DynamicObject creator = realcard.getDynamicObject("creator");
Date createtime = realcard.getDate("createtime");
DynamicObject modifier = realcard.getDynamicObject("modifier");
Date modifytime = realcard.getDate("modifytime");
DynamicObject auditor = realcard.getDynamicObject("auditor");
Date auditdate = realcard.getDate("auditdate");
// 创建或更新 eceq_equipment_card 对象
DynamicObject equipmentcard = ORM.create().newDynamicObject("eceq_equipment_card");
// 时间文本修正了 format 的用法
String timeText;
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
timeText = format.format(new Date());
}
// 检查已有设备卡片
DynamicObject eceq_equipment_card = null;
if (!isEmpty(number)) {
eceq_equipment_card = BusinessDataServiceHelper.loadSingle("eceq_equipment_card", new QFilter[]{new QFilter("zcgj_assetnumber", QCP.equals, number)});
}
if (eceq_equipment_card != null) {
equipmentcard.set("id", eceq_equipment_card.getLong("id"));
String cardString = safeGetString(eceq_equipment_card, "number");
if (!isEmpty(cardString)) {
equipmentcard.set("number", cardString);
} else {
equipmentcard.set("number", getCodeRule(equipmentcard, "53BT+ZJB86=L"));
}
} else {
equipmentcard.set("number", getCodeRule(equipmentcard, "53BT+ZJB86=L"));
}
// 基本属性赋值保持原业务字段
equipmentcard.set("billno", timeText);
equipmentcard.set("status", "C");
equipmentcard.set("billstatus", "C");
equipmentcard.set("enable", "1");
equipmentcard.set("property", "OWN");
equipmentcard.set("name", assetname);
equipmentcard.set("modelnum", model);
equipmentcard.set("indate", realaccountdate);
equipmentcard.set("org", assetunit);
equipmentcard.set("equipstatus", "FREE");
equipmentcard.set("project", null);
equipmentcard.set("useorg", null);
equipmentcard.set("supplier", supplier);
equipmentcard.set("carnumber", platenumber);
equipmentcard.set("enginenumber", null);
equipmentcard.set("framenumber", null);
equipmentcard.set("unit", unit);
equipmentcard.set("power", null);
equipmentcard.set("manufacturer", manufacturer);
equipmentcard.set("proddate", prodate);
equipmentcard.set("storageplace", fulladdress);
equipmentcard.set("creator", creator);
equipmentcard.set("createtime", createtime);
equipmentcard.set("modifier", modifier);
equipmentcard.set("modifytime", modifytime);
equipmentcard.set("auditor", auditor);
equipmentcard.set("auditdate", auditdate);
equipmentcard.set("zcgj_assetnumber", number);
equipmentcard.set("zcgj_headusedepts", headusedept);
equipmentcard.set("zcgj_costcenters", zcgj_costcenter);
equipmentcard.set("zcgj_assetcat", assetcat);
equipmentcard.set("zcgj_assetamount", assetamount);
equipmentcard.set("zcgj_remark", remark);
// 处理财务卡片分录改进一次加载 fin_card 并取 depredamount 最大的记录
BigDecimal finOriginalval = BigDecimal.ZERO;
BigDecimal fin_preusingamount = BigDecimal.ZERO;
BigDecimal fin_depredamount = BigDecimal.ZERO;
BigDecimal fin_preresidualval = BigDecimal.ZERO;
BigDecimal fin_accumdepre = BigDecimal.ZERO;
BigDecimal fin_networth = BigDecimal.ZERO;
if (finentrys != null && !finentrys.isEmpty() && !isEmpty(number)) {
DynamicObject[] fincards = BusinessDataServiceHelper.load("fa_card_fin",
"id,originalval,preusingamount,depredamount,preresidualval,accumdepre,networth",
new QFilter[]{new QFilter("number", QCP.equals, number)});
if (fincards != null && fincards.length > 0) {
DynamicObject best = null;
BigDecimal maxDep = new BigDecimal(-1);
for (DynamicObject fincard : fincards) {
if (fincard == null) continue;
BigDecimal dep = safeGetBigDecimal(fincard, "depredamount");
if (dep.compareTo(maxDep) > 0) {
maxDep = dep;
best = fincard;
}
}
if (best != null) {
finOriginalval = safeGetBigDecimal(best, "originalval");
fin_preusingamount = safeGetBigDecimal(best, "preusingamount");
fin_depredamount = safeGetBigDecimal(best, "depredamount");
fin_preresidualval = safeGetBigDecimal(best, "preresidualval");
fin_accumdepre = safeGetBigDecimal(best, "accumdepre");
fin_networth = safeGetBigDecimal(best, "networth");
equipmentcard.set("zcgj_networth", fin_networth);
equipmentcard.set("zcgj_accumdepre", fin_accumdepre);
equipmentcard.set("zcgj_depredamount", fin_depredamount);
equipmentcard.set("zcgj_preresidualval", fin_preresidualval);
equipmentcard.set("zcgj_preusingamount", fin_preusingamount);
equipmentcard.set("unitprice", finOriginalval);
}
}
}
// 保存或更新 equipmentcard
if (eceq_equipment_card != null) {
// 更新
SaveServiceHelper.update(equipmentcard);
} else {
OperationResult result = OperationServiceHelper.executeOperate("save", "eceq_equipment_card", new DynamicObject[]{equipmentcard}, null);
String operationResultErrorInfo = getOperationResultErrorInfos(result);
if (!isEmpty(operationResultErrorInfo)) {
totalErrorBuilder.append(number).append(": ").append(operationResultErrorInfo).append(System.lineSeparator());
log.error(number + assetname + " 报错信息为:" + operationResultErrorInfo);
}
}
// 同步到 eceq_equipinfo存在则更新
DynamicObject eceq_equipment = null;
if (!isEmpty(number)) {
eceq_equipment = BusinessDataServiceHelper.loadSingle("eceq_equipinfo", new QFilter[]{new QFilter("zcgj_assetnumber", QCP.equals, number)});
}
if (eceq_equipment != null) {
// 更新字段与原逻辑保持一致
eceq_equipment.set("zcgj_assetnumber", number);
eceq_equipment.set("zcgj_headusedepts", headusedept);
eceq_equipment.set("zcgj_costcenters", zcgj_costcenter);
eceq_equipment.set("zcgj_networth", fin_networth);
eceq_equipment.set("zcgj_accumdepre", fin_accumdepre);
eceq_equipment.set("zcgj_depredamount", fin_depredamount);
eceq_equipment.set("zcgj_preresidualval", fin_preresidualval);
eceq_equipment.set("zcgj_preusingamount", fin_preusingamount);
eceq_equipment.set("zcgj_unitprice", finOriginalval);
eceq_equipment.set("org", assetunit);
// eceq_equipment.set("equipstatus","FREE"); // 保持原注释更新设备时不更新设备状态
eceq_equipment.set("project", null);
eceq_equipment.set("zcgj_assetcat", assetcat);
eceq_equipment.set("zcgj_assetamount", assetamount);
eceq_equipment.set("zcgj_remark", remark);
// 处理折旧分摊明细优化减少重复 loadSingle
DynamicObjectCollection entrys = eceq_equipment.getDynamicObjectCollection("zcgj_entryentity");
QFilter qf = new QFilter("realcard.number", QCP.equals, number);
/*DynamicObjectCollection depresplitdetails = QueryServiceHelper.query(
"fa_depresplitdetail",
"id,billno,period,splitdept,assentry.costcentrer,assentry.splitamount",
new QFilter[]{qf}
);*/
DynamicObject[] depresplitdetailsArray = BusinessDataServiceHelper.load(
"fa_depresplitdetail",
"id,billno,period,splitdept,assentry.costcentrer,assentry.splitamount",
new QFilter[]{qf}
);
List<DynamicObject> depresplitdetails = new ArrayList<>(Arrays.asList(depresplitdetailsArray));
int beforeSize = depresplitdetailsArray.length;
log.info("前depresplitdetails length: " + beforeSize);
// depresplitdetails 转为 List 并按 period.number 降序排序避免每次 compare 时重复 DB 查询
if (depresplitdetails.size() > 1) {
List<DynamicObject> tmp = new ArrayList<>(depresplitdetails.size());
for (DynamicObject d : depresplitdetails) {
tmp.add(d);
}
tmp.sort((o1, o2) -> {
String p1 = safeNestedString(o1, "period", "number");
String p2 = safeNestedString(o2, "period", "number");
if (p1 == null && p2 == null) return 0;
if (p1 == null) return 1;
if (p2 == null) return -1;
return p2.compareTo(p1); // 降序
});
// 清空并重新加入排好序的项保持类型为 DynamicObjectCollection
depresplitdetails.clear();
depresplitdetails.addAll(tmp);
}
int afterSize = depresplitdetails.size();
log.info("后depresplitdetails length: " + afterSize);
// 计算已存在的 period number 集合避免重复添加
Set<String> existPeriodData = new HashSet<>();
DynamicObjectCollection dynamicObjectCollection = eceq_equipment.getDynamicObjectCollection("zcgj_entryentity");
if (eceq_equipment.get("zcgj_assetnumber") != null && dynamicObjectCollection != null && !dynamicObjectCollection.isEmpty()) {
for (DynamicObject data : dynamicObjectCollection) {
if (data == null) continue;
DynamicObject period = data.getDynamicObject("zcgj_assperiod");
String pn = safeGetString(period, "number");
if (!isEmpty(pn)) existPeriodData.add(pn);
}
}
// 遍历 depresplitdetails避免再次调用 loadSingle
if (!depresplitdetails.isEmpty()) {
for (DynamicObject depresplitdetail : depresplitdetails) {
if (depresplitdetail == null) continue;
// 直接使用已查询到的对象不再 loadSingle
DynamicObject period = depresplitdetail.getDynamicObject("period");
String periodnumber = safeGetString(period, "number");
if (isEmpty(periodnumber)) continue;
if (existPeriodData.isEmpty() || !existPeriodData.contains(periodnumber)) {
DynamicObject splitdept = depresplitdetail.getDynamicObject("splitdept");
DynamicObjectCollection assentry = depresplitdetail.getDynamicObjectCollection("assentry");
if (assentry == null || assentry.isEmpty()) continue;
DynamicObject firstAss = assentry.get(0);
DynamicObject costcentrer = (firstAss == null) ? null : firstAss.getDynamicObject("costcentrer");
BigDecimal splitamount = (firstAss == null) ? BigDecimal.ZERO : safeGetBigDecimal(firstAss, "splitamount");
DynamicObject addNew = new DynamicObject(entrys.getDynamicObjectType());
addNew.set("zcgj_debillno", depresplitdetail.getLong("id"));
addNew.set("zcgj_assperiod", period);
addNew.set("zcgj_headusedept", splitdept);
addNew.set("zcgj_entrybillno", number);
addNew.set("zcgj_entryname", assetname);
addNew.set("zcgj_costcenter", costcentrer);
addNew.set("zcgj_shareamount", splitamount);
// useorg 可能为 DynamicObject null做安全处理
Object useorgObj = eceq_equipment.get("useorg");
if (useorgObj instanceof DynamicObject) {
DynamicObject useorgDo = (DynamicObject) useorgObj;
Long useorgId = useorgDo.getLong("id");
addNew.set("zcgj_zjuseorg", useorgId);
} else if (useorgObj instanceof Long) {
addNew.set("zcgj_zjuseorg", (Long) useorgObj);
}
entrys.add(addNew);
}
}
}
// 保存 eceq_equipment
SaveServiceHelper.save(new DynamicObject[]{eceq_equipment});
}
// 每次循环可选打印或记录累计错误但不要频繁 println改用日志
if (totalErrorBuilder.length() > 0) {
log.warn("当前累计报错(部分示例): " + (totalErrorBuilder.length() > 400 ? totalErrorBuilder.substring(0, 400) + "..." : totalErrorBuilder.toString()));
}
} // end for realcards
if (totalErrorBuilder.length() > 0) {
log.error("总报错信息为:\n" + totalErrorBuilder.toString());
}
} // end execute
/**
* 判断给定字符串是否为空null 空字符串
*/
private static boolean isEmpty(String s) {
return s == null || s.trim().isEmpty();
}
/**
* 安全读取 DynamicObject String 字段
*/
private static String safeGetString(DynamicObject obj, String prop) {
if (obj == null) return null;
try {
Object v = obj.get(prop);
return v == null ? null : v.toString();
} catch (Exception e) {
return null;
}
}
/**
* 安全读取 DynamicObject BigDecimal 字段
*/
private static BigDecimal safeGetBigDecimal(DynamicObject obj, String prop) {
if (obj == null) return BigDecimal.ZERO;
try {
BigDecimal v = obj.getBigDecimal(prop);
return (v == null) ? BigDecimal.ZERO : v;
} catch (Exception e) {
return BigDecimal.ZERO;
}
}
/**
* 安全获取嵌套字段例如 period.number
*/
private static String safeNestedString(DynamicObject obj, String nestedField, String prop) {
if (obj == null) return null;
try {
DynamicObject nested = obj.getDynamicObject(nestedField);
return safeGetString(nested, prop);
} catch (Exception e) {
return null;
}
}
public static boolean isLastMonth(String dateStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
try {
LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);
LocalDateTime now = LocalDateTime.now();
YearMonth lastMonth = YearMonth.from(now.minusMonths(1));
LocalDateTime firstDay = lastMonth.atDay(1).atStartOfDay();
LocalDateTime lastDay = lastMonth.atEndOfMonth().atTime(23, 59, 59);
return !dateTime.isBefore(firstDay) && !dateTime.isAfter(lastDay);
} catch (DateTimeParseException e) {
log.error("日期格式错误: " + e.getMessage());
return false;
}
}
// 安全解析年月
private YearMonth parseYearMonth(String code, DateTimeFormatter fmt) {
if (code == null || code.isEmpty()) {
return YearMonth.of(1900, 1); // 返回最小值
}
try {
return YearMonth.parse(code, fmt);
} catch (DateTimeParseException e) {
log.warn("parseYearMonth failed for '" + code + "', returning minimal YearMonth", e);
return YearMonth.of(1900, 1);
}
}
// 自动检测日期格式的辅助方法
private DateTimeFormatter detectFormat(String code1, String code2) {
String[] patterns = {
"yyyyMM", "yyyy-MM", "yyyy/MM",
"yyyy年MM月", "MM-yyyy", "MM/yyyy"
};
for (String pattern : patterns) {
try {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
if (!isEmpty(code1)) YearMonth.parse(code1, fmt);
if (!isEmpty(code2)) YearMonth.parse(code2, fmt);
return fmt;
} catch (Exception ignored) {
}
}
return DateTimeFormatter.ofPattern("yyyyMM");
}
/**
* 获取编码规则生成编码修复空判断
*/
public static String getCodeRule(DynamicObject data, String number) {
String archivebillno = null;
DynamicObject coderule = BusinessDataServiceHelper.loadSingle("bos_coderule", "id", new QFilter[]{new QFilter("number", QCP.equals, number)});
if (coderule != null) {
try {
String id = coderule.getString("id");
if (!isEmpty(id)) {
CodeRuleInfo codeRule = CodeRuleCache.reloadCodeRuleById(id);
if (codeRule != null) {
archivebillno = CodeRuleServiceHelper.getNumber(codeRule, data);
}
}
} catch (Exception e) {
log.warn("reloadCodeRuleById failed: " + e.getMessage(), e);
}
}
if (isEmpty(archivebillno)) {
try {
DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject("eceq_equipment_card");
CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(dynamicObject.getDataEntityType().getName(), dynamicObject, null);
if (codeRule != null) {
archivebillno = CodeRuleServiceHelper.getNumber(codeRule, dynamicObject);
}
} catch (Exception e) {
log.warn("getCodeRule fallback failed: " + e.getMessage(), e);
}
}
if (archivebillno == null) archivebillno = "";
log.info("生成的设备编号为 " + archivebillno);
return archivebillno;
}
/**
* 获取操作错误信息更健壮的空安全处理
*/
private String getOperationResultErrorInfos(OperationResult operationResult) {
if (operationResult == null) return StringUtils.EMPTY;
if (operationResult.isSuccess()) {
return StringUtils.EMPTY;
}
List<IOperateInfo> errorInfos = operationResult.getAllErrorOrValidateInfo();
int successCount = (operationResult.getSuccessPkIds() == null ? 0 : operationResult.getSuccessPkIds().size());
int errorCount = (errorInfos == null ? 0 : errorInfos.size());
int size = errorCount + successCount;
if (size > 1 && errorInfos != null && !errorInfos.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(5, errorInfos.size()); i++) {
IOperateInfo info = errorInfos.get(i);
if (info != null) {
sb.append(info.getMessage());
if (i < Math.min(5, errorInfos.size()) - 1) sb.append("; ");
}
}
return sb.toString();
} else if (errorInfos != null && !errorInfos.isEmpty()) {
OperateErrorInfo errorInfo = (OperateErrorInfo) errorInfos.get(0);
String msg = errorInfo.getMessage() == null ? "" : errorInfo.getMessage();
return msg;
} else {
String msg = operationResult.getMessage() == null ? "" : operationResult.getMessage();
return msg;
}
}
}