金蝶系统的数据控制
先说金蝶对数据的几个状态控制:
新增一个凭证还是基础数据也好,都需要经过(保存 -> 提交 -> 审核)
同样的,如果要删除一条记录,需要(反审核 -> 删除)

我们系统的数据,推送到金蝶系统中,就要经历上述的3个步骤
然后还要支持可以重复推送,那就要先去操作前面的反审核和删除
所以一个推送就包括了5个步骤, 一份数据,调用五次接口
接口规律抽象
我们自己的业务功能可以和金蝶系统的业务功能进行一个关联,所有业务都可以被抽象出来统一管理,例如:
推送员工信息,项目信息,财务报销单...等等
老板的意思是集中在一个功能里面做推送,所有业务都放在其中,对选中的记录进行推送

对于行为的抽象,我的理解只有两件事情
- 这个业务需要翻页查询
- 这个业务需要推送数据
于是我就定义了一个关于金蝶推送的行为接口,我更愿意称为一个“规范”
因为只有遵守规范的服务才能够正确的执行具体内容
package cn.hyite.amerp.system.push.manage.service;
import cn.hyite.amerp.system.push.kingdee.config.KingdeeApiSettings;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.Map;
/**
* 业务推送管理规范
* @author Cloud9
* @version 1.0
* @project amerp-server
* @date 2023年03月11日 15:16
*/
public interface PushManageService {
/* 业务标识 */
String businessIdent();
/* 翻页数据 */
IPage<? extends Object> getPushDataPage(String json);
/* 推送数据 */
Map<String, Object> pushData(Map<String, Object> pushParam, KingdeeApiSettings settings);
}
在仔细查看其中推送接口的描述后发现,除了保存接口,其它接口只需要提供编号参数即可
也就是说,除了保存接口,其它接口在封装参数的方法上还是一样的
所以这里又有第二层规范,关于推送数据的规范:
package cn.hyite.amerp.system.push.manage.service;
import java.io.Serializable;
/**
* 具体推送行为规范
* @author Cloud9
* @version 1.0
* @project amerp-server
* @date 2023年03月15日 14:15
*/
public interface PushStrategy {
/* 业务标识 */
String businessIdent();
/* 获取保存操作的JSON参数 */
String getSaveOperateFormJson(Serializable businessId);
/* 获取提交操作的JSON参数 */
String getSubmitOperateFormJson(Serializable businessId);
/* 获取审核操作的JSON参数 */
String getAuditOperateFormJson(Serializable businessId);
/* 获取反审核操作的JSON参数 */
String getUnAuditOperateFormJson(Serializable businessId);
/* 获取删除操作的JSON参数 */
String getDeleteOperateFormJson(Serializable businessId);
}
先解决页面翻页查询的问题:
每个业务实现翻页具体的逻辑,每个业务需要有自己唯一的业务标识

Controller控制器Bean只需要根据业务标识来知晓哪个服务Bean是具体要调用的
这是识别方法:
/**
* @author Cloud9
* @date 2023/3/11 15:47
* @description 通过Spring类型集中注入推送的服务对象,根据设置的业务标识获取对应实例
* @params [businessIdent]
* @return cn.hyite.amerp.system.push.manage.service.PushManageService
*/
private PushManageService getSpecificInstance(final String businessIdent) {
PushManageService pushManageService = pushManageServices.stream().filter(pm -> pm.businessIdent().equals(businessIdent)).findFirst().orElse(null);
Assert.isTrue(Objects.isNull(pushManageService), ResultMessage.CUSTOM_ERROR, "没有这个业务的推送管理Bean! [" + businessIdent + "]");
return pushManageService;
}
控制器通过Spring的自动装配@Autowired进行注入:
@Autowired private List<PushManageService> pushManageServices;
接口方法:
/**
* @author OnCloud9
* @date 2023/3/11 15:45
* @description 推送记录翻页查询
* @params [businessIdent, json]
* @return com.baomidou.mybatisplus.core.metadata.IPage<? extends java.lang.Object>
*/
@PostMapping("/{businessIdent}/page")
public PageResult<?> getPushDataPage(@PathVariable("businessIdent") final String businessIdent, @RequestBody final String json) {
/* 推送业务的服务实例是否存在 */
final PushManageService specificInstance = getSpecificInstance(businessIdent);
return PageResult.toPageResult(specificInstance.getPushDataPage(json));
}
解决推送问题:
1、之前组长写过一版,太复杂了,使用抽象类来耦合公共部分,抽象部分就用抽象方法调用,但是我们都知道Java对多继承是不支持的
一个类只能有一个父类,我的开发经验认为是不用抽象类继承,而是接口来实现,因为抽象类对业务理解是不友好的,限制了服务类的继承
基于这几点内容,我对组长的推送逻辑进行了一个重构,不用抽象类,改为【处理器Bean】来完成
处理器Bean提供推送方法完成