StartChargeCmd.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. package com.java110.common.cmd.chargeMachine;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.java110.common.charge.IChargeCore;
  5. import com.java110.core.annotation.Java110Cmd;
  6. import com.java110.core.annotation.Java110Transactional;
  7. import com.java110.core.context.ICmdDataFlowContext;
  8. import com.java110.core.event.cmd.Cmd;
  9. import com.java110.core.event.cmd.CmdEvent;
  10. import com.java110.core.factory.GenerateCodeFactory;
  11. import com.java110.dto.account.AccountDto;
  12. import com.java110.dto.accountDetail.AccountDetailDto;
  13. import com.java110.dto.chargeMachine.ChargeMachineDto;
  14. import com.java110.dto.chargeMachineOrder.ChargeMachineOrderDto;
  15. import com.java110.dto.chargeMachinePort.ChargeMachinePortDto;
  16. import com.java110.dto.chargeRuleFee.ChargeRuleFeeDto;
  17. import com.java110.dto.couponPropertyPoolConfig.CouponPropertyPoolConfigDto;
  18. import com.java110.dto.couponPropertyUser.CouponPropertyUserDto;
  19. import com.java110.dto.user.UserDto;
  20. import com.java110.intf.acct.IAccountInnerServiceSMO;
  21. import com.java110.intf.acct.ICouponPropertyPoolConfigV1InnerServiceSMO;
  22. import com.java110.intf.acct.ICouponPropertyUserDetailV1InnerServiceSMO;
  23. import com.java110.intf.acct.ICouponPropertyUserV1InnerServiceSMO;
  24. import com.java110.intf.common.*;
  25. import com.java110.intf.user.IUserV1InnerServiceSMO;
  26. import com.java110.po.accountDetail.AccountDetailPo;
  27. import com.java110.po.chargeMachineOrder.ChargeMachineOrderPo;
  28. import com.java110.po.chargeMachineOrderAcct.ChargeMachineOrderAcctPo;
  29. import com.java110.po.chargeMachinePort.ChargeMachinePortPo;
  30. import com.java110.po.couponPropertyUser.CouponPropertyUserPo;
  31. import com.java110.utils.exception.CmdException;
  32. import com.java110.utils.lock.DistributedLock;
  33. import com.java110.utils.util.Assert;
  34. import com.java110.utils.util.DateUtil;
  35. import com.java110.utils.util.StringUtil;
  36. import com.java110.vo.ResultVo;
  37. import org.springframework.beans.factory.annotation.Autowired;
  38. import java.math.BigDecimal;
  39. import java.text.ParseException;
  40. import java.util.Calendar;
  41. import java.util.List;
  42. /**
  43. * 充电桩开始充电 处理类
  44. * <p>
  45. * add by wuxw 2023-03-09
  46. */
  47. @Java110Cmd(serviceCode = "chargeMachine.startCharge")
  48. public class StartChargeCmd extends Cmd {
  49. @Autowired
  50. private IChargeMachineV1InnerServiceSMO chargeMachineV1InnerServiceSMOImpl;
  51. @Autowired
  52. private IChargeMachinePortV1InnerServiceSMO chargeMachinePortV1InnerServiceSMOImpl;
  53. @Autowired
  54. private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;
  55. @Autowired
  56. private IAccountInnerServiceSMO accountInnerServiceSMOImpl;
  57. @Autowired
  58. private IChargeCore chargeCoreImpl;
  59. @Autowired
  60. private IChargeMachineOrderV1InnerServiceSMO chargeMachineOrderV1InnerServiceSMOImpl;
  61. @Autowired
  62. private IChargeMachineOrderAcctV1InnerServiceSMO chargeMachineOrderAcctV1InnerServiceSMOImpl;
  63. @Autowired
  64. private ICouponPropertyUserV1InnerServiceSMO couponPropertyUserV1InnerServiceSMOImpl;
  65. @Autowired
  66. private ICouponPropertyUserDetailV1InnerServiceSMO couponPropertyUserDetailV1InnerServiceSMOImpl;
  67. @Autowired
  68. private ICouponPropertyPoolConfigV1InnerServiceSMO couponPropertyPoolConfigV1InnerServiceSMOImpl;
  69. @Autowired
  70. private IChargeRuleFeeV1InnerServiceSMO chargeRuleFeeV1InnerServiceSMOImpl;
  71. @Override
  72. public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
  73. Assert.hasKeyAndValue(reqJson, "communityId", "未包含小区信息");
  74. Assert.hasKeyAndValue(reqJson, "machineId", "未包含充电桩");
  75. Assert.hasKeyAndValue(reqJson, "portId", "未包含插槽");
  76. Assert.hasKeyAndValue(reqJson, "duration", "未包含充电时长"); // 999 为按量充电
  77. String userId = context.getReqHeaders().get("user-id");
  78. Assert.hasLength(userId, "用户不存在");
  79. //查询充电桩设备信息
  80. ChargeMachineDto chargeMachineDto = new ChargeMachineDto();
  81. chargeMachineDto.setCommunityId(reqJson.getString("communityId"));
  82. chargeMachineDto.setMachineId(reqJson.getString("machineId"));
  83. List<ChargeMachineDto> chargeMachineDtos = chargeMachineV1InnerServiceSMOImpl.queryChargeMachines(chargeMachineDto);
  84. Assert.listOnlyOne(chargeMachineDtos, "充电桩 不存在");
  85. // todo 插槽是否空闲
  86. ChargeMachinePortDto chargeMachinePortDto = new ChargeMachinePortDto();
  87. chargeMachinePortDto.setMachineId(reqJson.getString("machineId"));
  88. chargeMachinePortDto.setPortId(reqJson.getString("portId"));
  89. chargeMachinePortDto.setState(ChargeMachinePortDto.STATE_FREE);
  90. List<ChargeMachinePortDto> chargeMachinePortDtos = chargeMachinePortV1InnerServiceSMOImpl.queryChargeMachinePorts(chargeMachinePortDto);
  91. Assert.listOnlyOne(chargeMachinePortDtos, "插槽忙线");
  92. double duration = reqJson.getDoubleValue("duration");
  93. if (duration == 999) {
  94. duration = 10;
  95. }
  96. ChargeRuleFeeDto chargeRuleFeeDto = new ChargeRuleFeeDto();
  97. chargeRuleFeeDto.setRuleId(chargeMachineDtos.get(0).getRuleId());
  98. chargeRuleFeeDto.setCommunityId(chargeMachineDtos.get(0).getCommunityId());
  99. List<ChargeRuleFeeDto> chargeRuleFeeDtos = chargeRuleFeeV1InnerServiceSMOImpl.queryChargeRuleFees(chargeRuleFeeDto);
  100. if (chargeRuleFeeDtos == null || chargeRuleFeeDtos.size() < 1) {
  101. throw new CmdException("未设置充值收费");
  102. }
  103. reqJson.put("durationPrice",chargeRuleFeeDtos.get(chargeRuleFeeDtos.size()-1).getDurationPrice());
  104. BigDecimal payMoneyDec = new BigDecimal(Double.parseDouble(chargeRuleFeeDtos.get(chargeRuleFeeDtos.size()-1).getDurationPrice()));
  105. double payMoney = payMoneyDec.multiply(new BigDecimal(duration)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
  106. UserDto userDto = new UserDto();
  107. userDto.setUserId(userId);
  108. List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);
  109. Assert.listOnlyOne(userDtos, "用户不存在");
  110. AccountDto accountDto = new AccountDto();
  111. accountDto.setLink(userDtos.get(0).getTel());
  112. accountDto.setAcctType(AccountDto.ACCT_TYPE_CASH);
  113. accountDto.setObjType(AccountDto.OBJ_TYPE_PERSON);
  114. accountDto.setPartId(reqJson.getString("communityId"));
  115. List<AccountDto> accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
  116. if (accountDtos == null || accountDtos.size() < 1) {
  117. throw new CmdException("请先充值,账户金额不足");
  118. }
  119. if (Double.parseDouble(accountDtos.get(0).getAmount()) < payMoney) {
  120. throw new CmdException("账户金额不足,无法支付" + duration + "小时费用,请先充值");
  121. }
  122. reqJson.put("acctId", accountDtos.get(0).getAcctId());
  123. if (!reqJson.containsKey("couponIds") || StringUtil.isEmpty(reqJson.getString("couponIds"))) {
  124. return;
  125. }
  126. for (String couponId : reqJson.getString("couponIds").split(",")) {
  127. CouponPropertyUserDto couponPropertyUserDto = new CouponPropertyUserDto();
  128. couponPropertyUserDto.setCouponId(couponId);
  129. couponPropertyUserDto.setToType(CouponPropertyUserDto.TO_TYPE_CHARGE);
  130. couponPropertyUserDto.setState(CouponPropertyUserDto.STATE_WAIT);
  131. List<CouponPropertyUserDto> couponPropertyUserDtos = couponPropertyUserV1InnerServiceSMOImpl.queryCouponPropertyUsers(couponPropertyUserDto);
  132. if (couponPropertyUserDtos == null || couponPropertyUserDtos.size() < 1) {
  133. throw new CmdException("优惠券不存在");
  134. }
  135. if (!"Y".equals(couponPropertyUserDtos.get(0).getIsExpire())) {
  136. throw new CmdException("优惠券已过期");
  137. }
  138. }
  139. }
  140. @Override
  141. @Java110Transactional
  142. public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
  143. String userId = context.getReqHeaders().get("user-id");
  144. UserDto userDto = new UserDto();
  145. userDto.setUserId(userId);
  146. List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);
  147. Assert.listOnlyOne(userDtos, "用户不存在");
  148. ChargeMachineDto chargeMachineDto = new ChargeMachineDto();
  149. chargeMachineDto.setCommunityId(reqJson.getString("communityId"));
  150. chargeMachineDto.setMachineId(reqJson.getString("machineId"));
  151. List<ChargeMachineDto> chargeMachineDtos = chargeMachineV1InnerServiceSMOImpl.queryChargeMachines(chargeMachineDto);
  152. double duration = reqJson.getDoubleValue("duration");
  153. String durationType = IChargeCore.CHARGE_TYPE_HOURS;
  154. double durationHours = duration;
  155. if (duration == 999) {
  156. durationType = IChargeCore.CHARGE_TYPE_ENERGY;
  157. durationHours = 10;
  158. }
  159. ChargeMachinePortDto chargeMachinePortDto = new ChargeMachinePortDto();
  160. chargeMachinePortDto.setMachineId(reqJson.getString("machineId"));
  161. chargeMachinePortDto.setPortId(reqJson.getString("portId"));
  162. chargeMachinePortDto.setState(ChargeMachinePortDto.STATE_FREE);
  163. List<ChargeMachinePortDto> chargeMachinePortDtos = chargeMachinePortV1InnerServiceSMOImpl.queryChargeMachinePorts(chargeMachinePortDto);
  164. String orderId = GenerateCodeFactory.getGeneratorId("11");
  165. //调用充电桩充电
  166. ResultVo resultVo = chargeCoreImpl.startCharge(chargeMachineDtos.get(0), chargeMachinePortDtos.get(0), durationType, durationHours, orderId);
  167. if (resultVo.getCode() != ResultVo.CODE_OK) {
  168. context.setResponseEntity(ResultVo.createResponseEntity(resultVo));
  169. return;
  170. }
  171. // todo 修改端口状态
  172. ChargeMachinePortPo chargeMachinePortPo = new ChargeMachinePortPo();
  173. chargeMachinePortPo.setPortId(chargeMachinePortDtos.get(0).getPortId());
  174. chargeMachinePortPo.setCommunityId(chargeMachinePortDtos.get(0).getCommunityId());
  175. chargeMachinePortPo.setState(ChargeMachinePortDto.STATE_WORKING);
  176. chargeMachinePortV1InnerServiceSMOImpl.updateChargeMachinePort(chargeMachinePortPo);
  177. // todo 生成 充电订单
  178. ChargeMachineOrderPo chargeMachineOrderPo = new ChargeMachineOrderPo();
  179. chargeMachineOrderPo.setAmount("0");
  180. chargeMachineOrderPo.setOrderId(orderId);
  181. chargeMachineOrderPo.setPortId(chargeMachinePortDtos.get(0).getPortId());
  182. chargeMachineOrderPo.setPersonName(userDtos.get(0).getName());
  183. chargeMachineOrderPo.setMachineId(chargeMachineDtos.get(0).getMachineId());
  184. chargeMachineOrderPo.setAcctDetailId(reqJson.getString("acctId"));
  185. chargeMachineOrderPo.setPersonId(userId);
  186. chargeMachineOrderPo.setChargeHours(reqJson.getString("duration"));
  187. chargeMachineOrderPo.setStartTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  188. chargeMachineOrderPo.setDurationPrice(reqJson.getString("durationPrice"));
  189. Calendar calendar = Calendar.getInstance();
  190. if (duration == 999) {
  191. calendar.add(Calendar.HOUR, 10);
  192. } else {
  193. calendar.add(Calendar.HOUR, reqJson.getIntValue("duration"));
  194. }
  195. chargeMachineOrderPo.setEndTime(DateUtil.getFormatTimeString(calendar.getTime(), DateUtil.DATE_FORMATE_STRING_A));
  196. chargeMachineOrderPo.setState(ChargeMachineOrderDto.STATE_DOING);
  197. chargeMachineOrderPo.setPersonTel(userDtos.get(0).getTel());
  198. chargeMachineOrderPo.setCommunityId(chargeMachineDtos.get(0).getCommunityId());
  199. chargeMachineOrderPo.setEnergy("1");
  200. int flag = chargeMachineOrderV1InnerServiceSMOImpl.saveChargeMachineOrder(chargeMachineOrderPo);
  201. if (flag < 1) {
  202. chargeCoreImpl.stopCharge(chargeMachineDtos.get(0), chargeMachinePortDtos.get(0));
  203. throw new CmdException("充电失败");
  204. }
  205. resultVo.setData(orderId);
  206. double couponDurationHours = 0.0;
  207. //扣款
  208. if (reqJson.containsKey("couponIds") && !StringUtil.isEmpty(reqJson.getString("couponIds"))) {
  209. //todo 优惠券抵扣
  210. couponDurationHours = withholdCoupon(reqJson, chargeMachineDtos, orderId);
  211. }
  212. if (durationHours - couponDurationHours > 0) {
  213. // todo 3.0 账户扣款
  214. withholdAccount(reqJson, chargeMachineDtos, orderId, durationHours, couponDurationHours);
  215. }
  216. context.setResponseEntity(ResultVo.createResponseEntity(resultVo));
  217. }
  218. /**
  219. * 优惠券抵扣
  220. *
  221. * @param reqJson
  222. * @param chargeMachineDtos
  223. * @param orderId
  224. */
  225. private double withholdCoupon(JSONObject reqJson, List<ChargeMachineDto> chargeMachineDtos, String orderId) {
  226. int flag;
  227. double hours = 0;
  228. String couponNames = "";
  229. for (String couponId : reqJson.getString("couponIds").split(",")) {
  230. String requestId = DistributedLock.getLockUUID();
  231. String key = this.getClass().getSimpleName() + reqJson.getString("couponId");
  232. try {
  233. CouponPropertyUserDto couponPropertyUserDto = new CouponPropertyUserDto();
  234. couponPropertyUserDto.setCouponId(couponId);
  235. couponPropertyUserDto.setToType(CouponPropertyUserDto.TO_TYPE_CHARGE);
  236. couponPropertyUserDto.setState(CouponPropertyUserDto.STATE_WAIT);
  237. List<CouponPropertyUserDto> couponPropertyUserDtos = couponPropertyUserV1InnerServiceSMOImpl.queryCouponPropertyUsers(couponPropertyUserDto);
  238. int stock = Integer.parseInt(couponPropertyUserDtos.get(0).getStock());
  239. CouponPropertyUserPo couponPropertyUserPo = new CouponPropertyUserPo();
  240. couponPropertyUserPo.setCouponId(couponPropertyUserDtos.get(0).getCouponId());
  241. couponPropertyUserPo.setCommunityId(couponPropertyUserDtos.get(0).getCommunityId());
  242. couponPropertyUserPo.setStock((stock - 1) + "");
  243. if (stock == 1) {
  244. couponPropertyUserPo.setState(CouponPropertyUserDto.STATE_FINISH);
  245. }
  246. flag = couponPropertyUserV1InnerServiceSMOImpl.updateCouponPropertyUser(couponPropertyUserPo);
  247. if (flag < 1) {
  248. throw new CmdException("核销失败");
  249. }
  250. couponNames += ("优惠券名称:" + couponPropertyUserDtos.get(0).getCouponName() + ",优惠券编号:" + couponId + ";");
  251. CouponPropertyPoolConfigDto couponPropertyPoolConfigDto = new CouponPropertyPoolConfigDto();
  252. couponPropertyPoolConfigDto.setCouponId(couponPropertyUserDtos.get(0).getCppId());
  253. couponPropertyPoolConfigDto.setColumnKey("hours");
  254. List<CouponPropertyPoolConfigDto> couponPropertyPoolConfigDtos = couponPropertyPoolConfigV1InnerServiceSMOImpl.queryCouponPropertyPoolConfigs(couponPropertyPoolConfigDto);
  255. Assert.listOnlyOne(couponPropertyPoolConfigDtos, "未包含优惠券配置信息");
  256. double value = Double.parseDouble(couponPropertyPoolConfigDtos.get(0).getColumnValue());
  257. hours += value;
  258. } finally {
  259. DistributedLock.releaseDistributedLock(requestId, key);
  260. }
  261. }
  262. hours = Math.ceil(hours);
  263. ChargeMachineOrderAcctPo chargeMachineOrderAcctPo = new ChargeMachineOrderAcctPo();
  264. chargeMachineOrderAcctPo.setAcctDetailId("-1");
  265. chargeMachineOrderAcctPo.setAmount(reqJson.getString("durationPrice"));
  266. chargeMachineOrderAcctPo.setCmoaId(GenerateCodeFactory.getGeneratorId("11"));
  267. chargeMachineOrderAcctPo.setOrderId(orderId);
  268. chargeMachineOrderAcctPo.setAcctId(reqJson.getString("acctId"));
  269. chargeMachineOrderAcctPo.setStartTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  270. chargeMachineOrderAcctPo.setEndTime(DateUtil.getAddHoursStringA(DateUtil.getCurrentDate(), new Double(hours).intValue()));
  271. chargeMachineOrderAcctPo.setRemark("优惠券抵扣," + couponNames);
  272. chargeMachineOrderAcctPo.setCommunityId(chargeMachineDtos.get(0).getCommunityId());
  273. chargeMachineOrderAcctPo.setEnergy("0");
  274. chargeMachineOrderAcctV1InnerServiceSMOImpl.saveChargeMachineOrderAcct(chargeMachineOrderAcctPo);
  275. return hours;
  276. }
  277. /**
  278. * 账户抵扣
  279. *
  280. * @param reqJson
  281. * @param chargeMachineDtos
  282. * @param orderId
  283. */
  284. private void withholdAccount(JSONObject reqJson, List<ChargeMachineDto> chargeMachineDtos, String orderId, double durationHours, double couponDurationHours) {
  285. AccountDto accountDto = new AccountDto();
  286. accountDto.setAcctId(reqJson.getString("acctId"));
  287. List<AccountDto> accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
  288. double amount = 0.0;
  289. BigDecimal durationPrice = new BigDecimal(Double.parseDouble(reqJson.getString("durationPrice")));
  290. if (couponDurationHours > 0) {
  291. durationPrice = durationPrice.multiply(new BigDecimal(durationHours - couponDurationHours)).setScale(2, BigDecimal.ROUND_HALF_UP);
  292. amount = durationPrice.doubleValue();
  293. } else {
  294. durationPrice = durationPrice.multiply(new BigDecimal(durationHours)).setScale(2, BigDecimal.ROUND_HALF_UP);
  295. amount = durationPrice.doubleValue();
  296. }
  297. AccountDetailPo accountDetailPo = new AccountDetailPo();
  298. accountDetailPo.setAcctId(accountDtos.get(0).getAcctId());
  299. accountDetailPo.setObjId(accountDtos.get(0).getObjId());
  300. accountDetailPo.setObjType(accountDtos.get(0).getObjType());
  301. accountDetailPo.setAmount(amount + "");
  302. accountDetailPo.setDetailId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailId));
  303. accountInnerServiceSMOImpl.withholdAccount(accountDetailPo);
  304. ChargeMachineOrderAcctPo chargeMachineOrderAcctPo = new ChargeMachineOrderAcctPo();
  305. chargeMachineOrderAcctPo.setAcctDetailId(accountDetailPo.getDetailId());
  306. chargeMachineOrderAcctPo.setAmount(amount + "");
  307. chargeMachineOrderAcctPo.setCmoaId(GenerateCodeFactory.getGeneratorId("11"));
  308. chargeMachineOrderAcctPo.setOrderId(orderId);
  309. chargeMachineOrderAcctPo.setAcctId(accountDtos.get(0).getAcctId());
  310. if (couponDurationHours > 0) {
  311. chargeMachineOrderAcctPo.setStartTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  312. } else {
  313. chargeMachineOrderAcctPo.setStartTime(DateUtil.getAddHoursStringA(DateUtil.getCurrentDate(), new Double(Math.ceil(couponDurationHours)).intValue()));
  314. }
  315. chargeMachineOrderAcctPo.setEndTime(DateUtil.getAddHoursStringA(DateUtil.getCurrentDate(), new Double(Math.ceil(durationHours)).intValue()));
  316. chargeMachineOrderAcctPo.setRemark("账户扣款");
  317. chargeMachineOrderAcctPo.setCommunityId(chargeMachineDtos.get(0).getCommunityId());
  318. chargeMachineOrderAcctPo.setEnergy("0");
  319. chargeMachineOrderAcctPo.setDurationPrice(reqJson.getString("durationPrice"));
  320. chargeMachineOrderAcctV1InnerServiceSMOImpl.saveChargeMachineOrderAcct(chargeMachineOrderAcctPo);
  321. }
  322. }