以创建一个订单为例,先上结构与代码
控制层,web、webmobile、webapi:统一请求与响应参数标准为ApiRequest<T> 和ApiResponse<T>,每个Dto只对应前端请求页面数据,做到Controller与Facade数据分离;
@ResponseBody
@RequestMapping("create")
public ApiResponse<UtOrderResponseDto> create(@RequestBody ApiRequest<UtOrderRequestDto> request) {
UtOrderResponseDto orderResponseDto = null;
UtOrderRequestDto requestDto = request.getBody();
UtruckPlatformSubject utruckPlatformSubject = WebApiUtils.getSubject();
try {
ValidationResult validationResult = ValidatorUtil.validateEntity(requestDto);
if (validationResult.hasErrors()) {
return WebApiUtils.getFailApiResponse(validationResult.toString());
}
FacadeRequest<UtOrderRequestDto> facadeRequest = new FacadeRequest<>();
facadeRequest.setSubject(utruckPlatformSubject);
facadeRequest.setBody(requestDto);
facadeRequest.setOperDate(new Date());
orderResponseDto = utOrderFacade.createOrder(facadeRequest);
if (orderResponseDto == null) {
return WebApiUtils.getFailApiResponse(I18n.getMsg(M.FAIL_SAVE));
}
} catch (UtruckException e) {
LOG.error(e.getMessage(), e);
return WebApiUtils.getFailApiResponse(e.getMessage());
}
return WebApiUtils.getSuccessApiResponse(I18n.getMsg(M.RESPONSE_SUCCESS), orderResponseDto);
}
facade层:接收统一请求参FacadeRequest<T>返回控制层所需要的指定Dto,遇到异常统一回滚并抛给控制层处理;
允许自动注入其他业务的facade,biz进行业务处理
public UtOrderResponseDto createOrder(FacadeRequest<UtOrderRequestDto> facadeRequest) throws UtruckException {
UtOrderResponseDto responseDto = null;
UtOrderRequestDto requestDto = facadeRequest.getBody();
if (null == requestDto.getCreateShpDate()) {
throw new UtruckException(I18n.getMsg(M.ALL_PARAMS_INVALID, "开单时间", "null"));
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
if (requestDto.getCreateShpDate().getTime() > facadeRequest.getOperDate().getTime()) {
throw new UtruckException(I18n.getMsg(M.UT_ORDER_CREATESHIPDATE_ERROR,
df.format(requestDto.getCreateShpDate()), df.format(facadeRequest.getOperDate())));
}
UtruckPlatformSubject subject = facadeRequest.getSubject();
requestDto.setFsownerId(subject.getProfileId());
/**
* 获取订单对象
*/
UtOrderCreateDto createDto = getOrder(requestDto, subject);
UtOrder record = new UtOrder();
try {
PropertyUtils.copyProperties(record, createDto);
record.setCreatedTime(facadeRequest.getOperDate());
UtOrder order = utOrderBiz.createUtOrder(record);
if (order != null) {
responseDto = new UtOrderResponseDto();
responseDto.setOrderId(order.getOrderId());
responseDto.setOrderNo(order.getOrderNo());
}
this.saveUtOrderState(order, subject);
/**
* 是否存在短信接单
*/
this.sendLbsMessage(order, createDto.getIsLbs());
//创建保险订单
try {
UtCargoInsuranceDto insurance = requestDto.getInsurance();
if (null != insurance) {
LOG.debug("Creating insurance order for UtOrder: {}", responseDto.getOrderNo());
//调用创建保险订单的API
InsureOrderInfo insureInfo = insureService.createInsure(insurance,createDto,subject,facadeRequest.getOperDate());
//获取保险订单号以及保险费用,并保存
if (insureInfo != null) {
UtOrderInsurance insuranceRecord = this.getInsuranceData(insurance,insureInfo,createDto,subject,facadeRequest.getOperDate());
insuranceBiz.saveInsurance(insuranceRecord);
}else {
LOG.error("订单{}创建关联保单失败",responseDto.getOrderNo());
}
}
}catch (UtruckException e) {
LOG.error("订单{}创建关联保单失败",responseDto.getOrderNo());
}
// 语音任务插入
if (order.getBaseCarrierId() != null && order.getBaseCarrierId() > 0) {
UtOrder utOrder = ModelUtil.dtoToModel(order, UtOrder.class);
utOrder.setDriverId(order.getBaseCarrierId());
this.saveVoiceTask(utOrder, DC.UtOperTypeCd.SS, M.UT_VOICE_PICK_ORDER_TEMPLATE, subject);
}
// 微信模板消息推送
if (order.getDriverId() != null && order.getDriverId() > 0) {
FacadeRequest<Integer> openIdFacade = new FacadeRequest<>();
openIdFacade.setBody(order.getDriverId());
String openId = wechatFacade.getOpenId(openIdFacade);
LOG.info("WechatCreateOrderPushMsg:driverId:{},openId:{},orderInfo:{}", order.getDriverId(), openId,
JSONUtil.toJSON(order));
if (StringUtils.isNotEmpty(openId)) {
String firstData = I18n.getMsg(M.UT_WECHAT_ORDER_NOTIFY_FIRSTDATA);
JSONObject extDataObj = JSONObject.fromObject(order.getExtData());
JSONObject accountJsonObj = extDataObj.getJSONObject("account");
BigDecimal serviceFee = UtruckConstants.BIG_DECIMAL_0;
if (accountJsonObj.containsKey("serviceFee")) {
serviceFee = new BigDecimal(accountJsonObj.get("serviceFee").toString());
}
order.setTotalCharge(order.getTotalCharge().subtract(serviceFee));
Map<String, Map<String, String>> data = wechatMsgTemplateData(order, firstData);
FacadeRequest<UtWechatTemplateMsgRequestDto> templateFacadeRequest = new FacadeRequest<>();
UtWechatTemplateMsgRequestDto dto = new UtWechatTemplateMsgRequestDto();
dto.setData(data);
dto.setGlobalId(order.getGlobalId());
dto.setOpenId(openId);
String template_id = ConfigProperties.getInstance("weixin")
.getPropertyAsString("order_notify_template_id");
dto.setTemplate_id(template_id);
templateFacadeRequest.setBody(dto);
wechatFacade.sendUtWechatTemplateMsg(templateFacadeRequest);
}
}
/**
* 货主 或者 物流企业指派了 司机 经纪人 物流企业 需要推送消息给 司机 经纪人 物流企业
*/
if (order.getCarrierId() != null && order.getCarrierId() > 0) {
FacadeRequest<UtOrderPushInfo> pushFacadeRequest = new FacadeRequest<>();
pushFacadeRequest.setSubject(facadeRequest.getSubject());
List<Integer> profileIds = new ArrayList<>();
profileIds.add(order.getCarrierId());
UtOrderPushInfo orderPushInfo = this.getUtorderPushInfo(order, profileIds,
new UtOrderPushInfo(null, DC.UtMessageClass.O, true, M.UT_PUSH_MESSAGE_ORDER_TITLE,
DC.UtMessageRefType.S, M.UT_PUSH_MESSAGE_ORDER_NEW, M.UT_PUSH_MESSAGE_ORDER_NEW),
null, null);
pushFacadeRequest.setBody(orderPushInfo);
utMessageFacade.pushOrderMessage(pushFacadeRequest);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
LOG.error(e.getMessage(), e);
throw new UtruckException(e.getMessage());
}
return responseDto;
}
biz层:用于完成独立业务与数据库之间的数据操作任务,允许注入其它的biz对象以及mapper接口;
common层:不依赖其它任何jar包层,为整个项目提供实体类对象;
support层:提供和实现外部接口的调用;本层只负责对外部进行调用,对内部系统数据不做处理,public方法中所用的调用传参为common中的实体对象;
dal层:封装mapper接口与mapper.xml处理与数据库之间的交互,不处理任何逻辑问题;
ref-service-api:封装对外提供Dubbo服务接口,为外部提供jar包,但所有接口实现在发布单元webapi(内部采用普通web发布单元或者springboot)内完成;所用到的请求参数对象均写在本层,当在webapi中实现后需要转换为facade请求参去调用facade业务层进行下一步处理