在调用金蝶的webApi保存接口时,"Model"中的数据结构其实是挺烦的,字段太多了...而且还有对应的序号。个人利用对象反射的机制写了一个小的demo,使向金蝶发送数据的操作变得简单了一些。直接上代码吧
package com.at.mes.kinDee.save;
import at.kingdee.core.annotation.KingDee;
import com.at.framework.pojo.annotation.pojo.DTO;
import com.at.framework.pojo.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import lombok.*;
import java.util.List;
/**
* @author XIAO MI FENG
* @version mes_4.0 v
* Created with IntelliJ IDEA
* @date 2023-11-15 15:22
*/
@DTO
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SaveKinDeeProductionBomDTO对象", description = "保存金蝶生产用料单主档")
public class SaveKinDeeProductionBomDTO extends BaseDTO {
@KingDee(key = "FID", index = 0)
private Integer id;
@KingDee(key = "FBillNo", index = 1)
private String fBillNo;
@KingDee(key = "FEntity", index = 6)
private List<SaveKinDeeProductionBomDetailDTO> entity;
}
package com.at.mes.kinDee.save;
import at.kingdee.core.annotation.KingDee;
import com.at.framework.pojo.annotation.pojo.DTO;
import com.at.framework.pojo.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import lombok.*;
/**
* @author XIAO MI FENG
* @version mes_4.0 v
* Created with IntelliJ IDEA
* @date 2023-11-15 15:24
*/
@DTO
@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SaveKinDeeProductionBomDetailDTO对象", description = "保存金蝶生产用料单详情")
public class SaveKinDeeProductionBomDetailDTO extends BaseDTO {
@KingDee(key = "FEntryID", index = 0)
private Integer id;
/**
* 物料编码
*
**/
@KingDee(key = "FMaterialID2.FNumber", index = 6)
private String skuCode;
/**
* 子项类型
*
**/
@KingDee(key = "FMaterialType", index = 9)
private String materialType;
/**
* 偏置提前期单位
*
**/
@KingDee(key = "FTimeUnit2", index = 10)
private String timeUnit;
/**
* 用量类型
*
**/
@KingDee(key = "FDosageType", index = 11)
private String dosageType;
/**
* 应发数量
*
**/
@KingDee(key = "FMustQty", index = 12)
private String mustQty;
/**
* 发料方式
*
**/
@KingDee(key = "FIssueType", index = 28)
private String issueType;
/**
* 发料组织
*
**/
@KingDee(key = "FSupplyOrg.FNumber", index = 49)
private String supplyOrg;
/**
* 子项单位
*
**/
@KingDee(key = "FUnitID2.FNumber", index = 50)
private String unit;
/**
* 分子
*
**/
@KingDee(key = "FNumerator", index = 51)
private String numerator;
/**
* 预留类型
*
**/
@KingDee(key = "FReserveType", index = 52)
private String reserveType;
/**
* 超发控制方式
*
**/
@KingDee(key = "FOverControlMode", index = 53)
private String overControlMode;
public static SaveKinDeeProductionBomDetailDTO setProperty() {
SaveKinDeeProductionBomDetailDTO entityDTO = new SaveKinDeeProductionBomDetailDTO();
entityDTO.setTimeUnit("1");
entityDTO.setReserveType("1");
entityDTO.setDosageType("2");
entityDTO.setMaterialType("1");
entityDTO.setOverControlMode("1");
entityDTO.setSupplyOrg("100.07");
entityDTO.setIssueType("1");
return entityDTO;
}
}
上面的对象分别对应金蝶中生产用料清单和生产用料清单子项物料信息,使用@KingDee注解来标识金蝶webApi的字段名和位置,静态方法主要是保存时的一些必填项,可以忽略。
private Map<String, Object> getMap(Object obj) {
Map<String, Object> hashMap = new LinkedHashMap<>();
//利用反射获取@KIngDee与对应的值
Class<? extends Object> aClass = obj.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
List<Field> collect = Arrays.stream(declaredFields).sorted(((o1, o2) -> {
return o1.getAnnotation(KingDee.class).index() - o2.getAnnotation(KingDee.class).index();
})).collect(Collectors.toList());
for (Field t : collect) {
//获取原来的控制访问权限
boolean accessible = t.isAccessible();
//修改控制访问权限
t.setAccessible(true);
//获取KingDee的key,也就是map的key
KingDee annotation = t.getAnnotation(KingDee.class);
String key = annotation.key();
try {
//获取对应的值
Object value = t.get(obj);
if (ObjectUtil.isNotNull(value)) {
//如果KinDeeKey带有"."说明是多级
if (key.contains(ConstantUtil.Symbol.POINT)) {
//根据"."进行切割
String[] split = StringUtils.split(key, ConstantUtil.Symbol.POINT);
HashMap<String, Object> fnMap = new HashMap<>();
//进行封装
fnMap.put(split[1], value);
hashMap.put(split[0], fnMap);
} else {
//不是多级
//存入集合
//如果是集合或者对象类型
if (value instanceof List) {
//集合类型
List<Map<String, Object>> arrayList = new ArrayList<>();
((List<?>) value).forEach(k -> {
Map<String, Object> map = getMap(k);
arrayList.add(map);
});
value = arrayList;
} else if (value instanceof BaseBean) {
//对象类型
value = getMap(value);
}
hashMap.put(key, value);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//恢复控制访问权限
t.setAccessible(accessible);
}
return hashMap;
}
在对象定义好之后利用上面的方法转为map结构,最后再转JSON就可以向金蝶发送数据啦