SalesDetaiServicelImpl.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. package com.emato.biz.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.emato.biz.util.OmsUtils;
  5. import com.emato.biz.domain.OperateLogDTO;
  6. import com.emato.biz.domain.OutRequest;
  7. import com.emato.biz.domain.mall.*;
  8. import com.emato.biz.domain.merchant.MerchantSecret;
  9. import com.emato.biz.exception.Assert;
  10. import com.emato.biz.mapper.mall.InventoryDataMapper;
  11. import com.emato.biz.mapper.mall.MallMngChangeMapper;
  12. import com.emato.biz.mapper.mall.SalesDetailMapper;
  13. import com.emato.biz.mapper.merchant.MerchantSecretMapper;
  14. import com.emato.biz.service.SignService;
  15. import com.emato.biz.service.mall.ISalesDetaiServicel;
  16. import com.emato.biz.util.DateUtil;
  17. import com.emato.biz.util.MatchUtil;
  18. import com.emato.common.core.Result;
  19. import com.emato.common.exception.ServiceException;
  20. import com.emato.common.utils.DateUtils;
  21. import com.emato.common.utils.StringUtils;
  22. import com.emato.common.utils.oms.response.ResultCodeEnum;
  23. import com.emato.common.utils.sign.Md5Utils;
  24. import com.emato.system.mapper.SysConfigMapper;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. import org.springframework.beans.BeanUtils;
  28. import org.springframework.beans.factory.annotation.Autowired;
  29. import org.springframework.stereotype.Service;
  30. import javax.annotation.Resource;
  31. import javax.servlet.http.HttpServletRequest;
  32. import java.sql.*;
  33. import java.util.ArrayList;
  34. import java.util.Date;
  35. import java.util.HashMap;
  36. import java.util.List;
  37. import java.util.Map;
  38. import java.util.stream.Collectors;
  39. /**
  40. * CW推送数据接口
  41. */
  42. @Service
  43. public class SalesDetaiServicelImpl implements ISalesDetaiServicel {
  44. private final Logger logger = LoggerFactory.getLogger(SalesDetaiServicelImpl.class);
  45. @Resource
  46. private InventoryDataMapper inventoryDataMapper;
  47. @Resource
  48. private MallMngChangeMapper mallMngChangeMapper;
  49. @Autowired
  50. private SysConfigMapper configMapper;
  51. @Resource
  52. private MerchantSecretMapper merchantSecretMapper;
  53. @Autowired
  54. private OmsUtils omsUtils;
  55. @Resource
  56. private SalesDetailMapper salesDetailMapper;
  57. @Autowired
  58. private SignService signService;
  59. /**
  60. * 记录请求日志
  61. *
  62. * @param reqData
  63. * @param merchantSn
  64. */
  65. @Override
  66. public void insertReqLog(String reqData, String merchantSn) {
  67. try {
  68. OperateLogDTO operateLogDTO = new OperateLogDTO();
  69. operateLogDTO.setReqData(reqData);
  70. operateLogDTO.setMerchSn(merchantSn);
  71. salesDetailMapper.insertSalesDataReqLog(operateLogDTO);
  72. } catch (Exception e) {
  73. logger.error("记录商户请求日志异常", e);
  74. throw new ServiceException("系统异常,请稍后再试!");
  75. }
  76. }
  77. /**
  78. * 获取销售数据
  79. *
  80. * @param outRequest
  81. * @return
  82. */
  83. @Override
  84. public Result getSalesDetailData(OutRequest outRequest) {
  85. try {
  86. logger.info("---------- 查询销售数据开始 ----------");
  87. logger.info("========== 电商请求 eccs 报文 =========> {}", outRequest);
  88. // 验签
  89. Assert.notTrue(!signService.verifySign(outRequest), ResultCodeEnum.SIGN_ERROR);
  90. // 转为请求类
  91. SalesDataReqVO reqVO = JSON.parseObject(outRequest.getData(), SalesDataReqVO.class);
  92. logger.debug("========== 解析后的请求数据 ==========> 【{}】", reqVO);
  93. // 分页页码
  94. String pageIndexStr = reqVO.getPageIndex();
  95. // 分页大小
  96. String pageSizeStr = reqVO.getPageSize();
  97. // 起始时间戳
  98. String startTimeTimeStamp = reqVO.getStarTime();
  99. // 起始时间戳
  100. String endTimeTimeStamp = reqVO.getEndTime();
  101. // 参数校验
  102. Assert.notNull(pageIndexStr, ResultCodeEnum.PARAM_ERROR_PAGE_INDEX_NOT_NULL);
  103. Assert.notNull(pageSizeStr, ResultCodeEnum.PARAM_ERROR_PAGE_SIZE_NOT_NULL);
  104. Assert.notTrue(!MatchUtil.isPositiveInteger(pageIndexStr), ResultCodeEnum.PARAM_ERROR_PAGE_INDEX_NOT_POS_INT);
  105. Assert.notTrue(!MatchUtil.isPositiveInteger(pageSizeStr), ResultCodeEnum.PARAM_ERROR_PAGE_SIZE_NOT_POS_INT);
  106. Assert.notTrue(!MatchUtil.isTimestamp(reqVO.getStarTime()), ResultCodeEnum.PARAM_ERROR_START_TIME_NOT_TIMES_STAMP);
  107. Assert.notTrue(!MatchUtil.isTimestamp(reqVO.getEndTime()), ResultCodeEnum.PARAM_ERROR_END_TIME_NOT_TIMES_STAMP);
  108. // 计算起始时间和结束时间相差多少小时,
  109. long hourBetweenTimesStamp = DateUtil.getHourBetweenTimesStamp(startTimeTimeStamp, endTimeTimeStamp);
  110. Assert.notTrue(hourBetweenTimesStamp > 24, ResultCodeEnum.TIME_INTERVAL_TOO_LARGE);
  111. // 分页大小
  112. int pageSize = Integer.parseInt(pageSizeStr);
  113. // 大于500就取500,否则取 pageSize
  114. pageSize = Math.min(pageSize, 500);
  115. int pageIndex = Integer.parseInt(pageIndexStr);
  116. // 小于1就取1,否则取 pageIndex
  117. pageIndex = Math.max(pageIndex, 1);
  118. pageIndex = (pageIndex - 1) * pageSize;
  119. // 格式化起始时间
  120. String startTime = DateUtil.dateFormat(startTimeTimeStamp, "yyyy-MM-dd HH:mm:ss");
  121. // 格式化结束时间
  122. String endTime = DateUtil.dateFormat(endTimeTimeStamp, "yyyy-MM-dd HH:mm:ss");
  123. // 设置查询条件
  124. reqVO.setOffset(pageIndex);
  125. reqVO.setLimit(pageSize);
  126. reqVO.setStarTime(startTime);
  127. reqVO.setEndTime(endTime);
  128. // 查询销售数据
  129. List<NewSystemFormatEntiy> salesDataList = salesDetailMapper.selectSalesDetailData(reqVO);
  130. Assert.notTrue(salesDataList.isEmpty(), ResultCodeEnum.NO_DATA);
  131. // 记录查询日志
  132. insertReqLog(JSON.toJSONString(outRequest), outRequest.getMerchId());
  133. // 将数据库数据转换为接口输出的数据格式
  134. List<SalesDataResVO> salesDataVOList = salesDataList.stream().map(salesData -> {
  135. SalesDataResVO resVO = new SalesDataResVO();
  136. BeanUtils.copyProperties(salesData, resVO);
  137. return resVO;
  138. }).collect(Collectors.toList());
  139. // 查询总记录数
  140. int total = salesDetailMapper.selectSalesDetailDataTotal(reqVO);
  141. // 组装返回数据
  142. Map<String, Object> resultMap = new HashMap<>();
  143. resultMap.put("rows", salesDataVOList);
  144. resultMap.put("total", total);
  145. logger.info("---------- 查询销售数据结束 ----------");
  146. return Result.success(resultMap);
  147. } catch (ServiceException se) {
  148. throw se;
  149. } catch (Exception e) {
  150. logger.error("外部商户获取销售数据异常 => ", e);
  151. throw new ServiceException("获取销售数据异常,请稍后再试!");
  152. }
  153. }
  154. /**
  155. * kmall向eccs系统推送数据
  156. * @param newSystemFormatEntiy
  157. * @return
  158. */
  159. @Override
  160. public int pushSalesDetaiServicel(NewSystemFormatEntiy newSystemFormatEntiy) {
  161. logger.debug("---------- Eccs 接收 Kmall 销售数据开始 ----------");
  162. int rows = 0;
  163. try {
  164. // 查询订单查看是否存在
  165. SalesDataReqVO reqVO = new SalesDataReqVO();
  166. reqVO.setOrderNo(newSystemFormatEntiy.getReceiptNo());
  167. reqVO.setEmatouCode(newSystemFormatEntiy.getEmatouCode());
  168. List<NewSystemFormatEntiy> salesDataList = salesDetailMapper.selectSalesDetailData(reqVO);
  169. if (salesDataList.isEmpty()) {
  170. // 如果不存在, 新增
  171. // 设置创建人和创建时间
  172. newSystemFormatEntiy.setCreateSn("admin");
  173. newSystemFormatEntiy.setCreateTime(new Date());
  174. rows = salesDetailMapper.insertSalesDetaiDate(newSystemFormatEntiy);
  175. }else {
  176. // 如果存在则修改
  177. // 设置修改人和修改时间
  178. newSystemFormatEntiy.setModerSn("admin");
  179. newSystemFormatEntiy.setModTime(new Date());
  180. rows = salesDetailMapper.updateSalesDetailData(newSystemFormatEntiy);
  181. }
  182. } catch (Exception e) {
  183. logger.error("Eccs 接收 Kmall 销售数据异常 => ", e);
  184. throw new ServiceException("Eccs 接收 Kmall 销售数据异常!");
  185. }
  186. logger.debug("---------- Eccs 接收 Kmall 销售数据结束 ----------");
  187. return rows;
  188. }
  189. /**
  190. * 外部商户系统查询订单销售数据
  191. * @param msg
  192. * @return
  193. */
  194. @Override
  195. public Result getSalesDetaiData(JSONObject msg, HttpServletRequest httpServletRequest) {
  196. try {
  197. logger.debug("---------- 处理商户获取销售明细::开始 ----------");
  198. //校验签名
  199. Map<String, Object> weChatMapSalesMsg = JSONObject.toJavaObject(msg, Map.class);
  200. //签名验证
  201. String strSign = weChatMapSalesMsg.get("sign").toString().trim();
  202. String merchId = weChatMapSalesMsg.get("merchId").toString().trim()==null?"":weChatMapSalesMsg.get("merchId").toString().trim();
  203. String timestamp = weChatMapSalesMsg.get("timestamp").toString().trim()==null?"":weChatMapSalesMsg.get("timestamp").toString().trim();
  204. // String str = configMapper.getConfigValue("salesdetai").trim();
  205. if(StringUtils.isEmpty(merchId)){
  206. return Result.error("900051","merchId为空");
  207. }
  208. // 改为使用密钥配置
  209. MerchantSecret merchantSecret = new MerchantSecret();
  210. merchantSecret.setMerchSn(merchId);
  211. List<MerchantSecret> merchantSecrets = merchantSecretMapper.selectMerchantSecretList(merchantSecret);
  212. if (null == merchantSecrets || merchantSecrets.isEmpty()) {
  213. return Result.error("900051","merchId参数错误");
  214. }
  215. MerchantSecret MerchantSecret_2 = merchantSecrets.get(0);
  216. String str = MerchantSecret_2.getMd5Salt();
  217. if(StringUtils.isEmpty(timestamp)){
  218. return Result.error("900051","timestamp为空");
  219. }
  220. String md5CheckCode = checkType(weChatMapSalesMsg.get("data").toString(), timestamp, str);
  221. logger.debug("--- getSalesDetaiData md5CheckCode:", md5CheckCode);
  222. if (!strSign.trim().equals(md5CheckCode)) {
  223. return Result.error("900052", "签名错误");
  224. }
  225. Map<String, Object> weSalesMsg = JSONObject.toJavaObject(JSON.parseObject(weChatMapSalesMsg.get("data").toString()), Map.class);
  226. String starTime = (String) weSalesMsg.get("starTime");
  227. String endTime = (String) weSalesMsg.get("endTime");
  228. Integer pageIndex = Integer.parseInt(weSalesMsg.get("pageIndex")+"");
  229. pageIndex = pageIndex <= 1 ? 1 : pageIndex;
  230. Integer pageSize = Integer.parseInt(weSalesMsg.get("pageSize")+"");
  231. pageSize = pageSize <= 0 ? 1 : pageSize;
  232. pageSize = pageSize >= 500 ? 500 : pageSize;
  233. weSalesMsg.put("starTime", DateUtils.getStrDate((String) weSalesMsg.get("starTime")));
  234. weSalesMsg.put("endTime",DateUtils.getStrDate((String)weSalesMsg.get("endTime")));
  235. if(pageIndex>500){
  236. return Result.error("900053","请求总数或时间区间过大");
  237. }
  238. pageIndex = (pageIndex - 1) * pageSize;
  239. weSalesMsg.put("offset", pageIndex);
  240. weSalesMsg.put("limit", pageSize);
  241. //记录调用参数接口日志
  242. long diff=(Long.parseLong(endTime) - Long.parseLong(starTime))/1000/60/60;
  243. if(diff<=24){
  244. pullQueryData(weChatMapSalesMsg);
  245. List<NewSystemFormatEntiy> list = mallMngChangeMapper.getSalesDetaiData(weSalesMsg);
  246. Integer total = mallMngChangeMapper.getTotalRecord(weSalesMsg);
  247. //desList = DesUtils.encode(JSON.toJSONString(list));
  248. if(list.size()==0){
  249. return Result.error("900054","该条件下无数据");
  250. }else{
  251. Map<String,Object> map = new HashMap<>();
  252. map.put("total",total);
  253. map.put("rows",list);
  254. logger.debug("---------- 处理商户获取销售明细::结束,处理成功 ----------");
  255. return Result.success(map);
  256. }
  257. }else{
  258. logger.debug("---------- 处理商户获取销售明细::结束,【900053】请求总数或时间区间过大 ----------");
  259. return Result.error("900053","请求总数或时间区间过大");
  260. }
  261. }catch (Exception e){
  262. logger.error("外部系统查询订单销售数据错误="+ JSON.toJSONString(msg),e);
  263. return Result.error("900051","参数错误");
  264. }
  265. }
  266. /**
  267. * 记录外部调用接口参数,时间和调用方
  268. * @param msg
  269. */
  270. private void pullQueryData(Map msg) {
  271. Map<String,Object> map = new HashMap<>();
  272. map.put("tranDirection",msg.get("merchId"));
  273. map.put("msg",msg.toString());
  274. mallMngChangeMapper.pullQueryData(map);
  275. }
  276. /**
  277. * 插入来源于oms的库存数据
  278. * @param inventoryDataVo
  279. */
  280. @Override
  281. public Result inserInventory(InventoryDataVo inventoryDataVo) {
  282. try{
  283. logger.error("插入来源于oms的库存数据");
  284. //查询是否存在该库存信息
  285. Integer checkStuts = inventoryDataMapper.queryOneInventory(inventoryDataVo);
  286. if(checkStuts>0){
  287. inventoryDataMapper.updateInventory(inventoryDataVo);
  288. }else{
  289. inventoryDataMapper.inserInventory(inventoryDataVo);
  290. }
  291. return Result.success();
  292. }catch (Exception e){
  293. logger.error("插入来源于oms的库存数据"+JSON.toJSONString(inventoryDataVo),e);
  294. return Result.error("1001","数据插入出错");
  295. }
  296. }
  297. /**
  298. * 查询库存数据提供给外部系统
  299. * @param msg
  300. * @param httpServletRequest
  301. * @return
  302. */
  303. @Override
  304. public Result queryInventory(JSONObject msg, HttpServletRequest httpServletRequest) {
  305. try{
  306. logger.debug("---------- 处理商户获取库存数据::开始 ----------");
  307. //校验签名
  308. Map<String, Object> weChatMapMsg = JSONObject.toJavaObject(msg, Map.class);
  309. //签名验证
  310. String strSign = weChatMapMsg.get("sign").toString().trim();
  311. String merchId = weChatMapMsg.get("merchId").toString().trim()==null?"":weChatMapMsg.get("merchId").toString().trim();
  312. String timestamp = weChatMapMsg.get("timestamp").toString().trim()==null?"":weChatMapMsg.get("timestamp").toString().trim();
  313. // String str = configMapper.getConfigValue("inventory");
  314. if(StringUtils.isEmpty(merchId)){
  315. return Result.error("900051","merchId为空");
  316. }
  317. // 改为使用密钥配置
  318. MerchantSecret merchantSecret = new MerchantSecret();
  319. merchantSecret.setMerchSn(merchId);
  320. List<MerchantSecret> merchantSecrets = merchantSecretMapper.selectMerchantSecretList(merchantSecret);
  321. if (null == merchantSecrets || merchantSecrets.isEmpty()) {
  322. return Result.error("900051","merchId参数错误");
  323. }
  324. MerchantSecret MerchantSecret_2 = merchantSecrets.get(0);
  325. String str = MerchantSecret_2.getMd5Salt();
  326. if(StringUtils.isEmpty(timestamp)){
  327. return Result.error("900051","timestamp为空");
  328. }
  329. String md5CheckCode = checkType(weChatMapMsg.get("data").toString(), timestamp, str);
  330. logger.debug("--- queryInventory md5CheckCode:", md5CheckCode);
  331. if (!strSign.trim().equals(md5CheckCode)) {
  332. return Result.error("900002", "签名错误");
  333. }
  334. Map<String, Object> weDtilMsg = JSONObject.toJavaObject(JSON.parseObject(weChatMapMsg.get("data").toString()), Map.class);
  335. Integer pageIndex = Integer.parseInt(weDtilMsg.get("pageIndex")+"");
  336. pageIndex = pageIndex <= 1 ? 1 : pageIndex;
  337. Integer pageSize = Integer.parseInt(weDtilMsg.get("pageSize")+"");
  338. pageSize = pageSize <= 0 ? 1 : pageSize;
  339. pageSize = pageSize >= 500 ? 500 : pageSize;
  340. pageIndex = (pageIndex-1)*pageSize;
  341. weChatMapMsg.put("offset", pageIndex);
  342. weChatMapMsg.put("limit", pageSize);
  343. weChatMapMsg.put("merchId", merchId);
  344. weChatMapMsg.put("sign", strSign);
  345. String merchSn = weDtilMsg.get("merchSn").toString().trim()==null?"":weDtilMsg.get("merchSn").toString().trim();
  346. if(merchSn.equals("")){
  347. return Result.error("900001","参数错误");
  348. }
  349. if(pageSize>3000){
  350. return Result.error("900003","请求数量过大");
  351. }
  352. pullQueryData(weChatMapMsg);
  353. // 数据查询
  354. //List<InventoryDataPushVo> list = inventoryDataMapper.getInventoryData(weChatMapMsg);
  355. // todo bug_2023-03-21 此处直接拉取的oms库,需要重新设计
  356. // todo bug_2023-03-21 虽然拉取数据存疑,但此处拉取出的数据向商户返回,其返回的字段与对外接口已经保持一致
  357. List<InventoryDataPushVo> list = getOmsData(weDtilMsg,weChatMapMsg);
  358. // todo bug_2023-03-21 total不正确
  359. Integer total = inventoryDataMapper.getInventoryTotal();
  360. if(list.size()==0){
  361. return Result.error("900004","该条件下无数据");
  362. }else{
  363. Map<String,Object> map = new HashMap<>();
  364. map.put("total",total);
  365. map.put("invTime",DateUtils.dateToStrLong(new Date()));
  366. map.put("rows",list);
  367. logger.debug("---------- 处理商户获取库存数据::结束,处理成功 ----------");
  368. return Result.success(map);
  369. }
  370. }catch (Exception e){
  371. logger.error("外部系统查询库存系统条件="+JSON.toJSONString(msg),e);
  372. return Result.error("900001","参数错误");
  373. }
  374. }
  375. //签名加密校验
  376. public String checkType(String data,String timestamp,String sekey) {
  377. String sign = sekey+"data" + data + "timestamp" + timestamp;
  378. return Md5Utils.encryption(sign);
  379. }
  380. public List<InventoryDataPushVo> getOmsData(Map<String, Object> weDtilMsg,Map<String, Object> weChatMapMsg){
  381. String driver=omsUtils.getOmsDriver();
  382. String user=omsUtils.getOmsUser();
  383. String password=omsUtils.getOmsPassword();
  384. String url=omsUtils.getOmsUrl();
  385. List<InventoryDataPushVo> inventoryDataPushVos = null;
  386. try{
  387. //加载数据库驱动
  388. Class.forName(driver);
  389. //连接数据库
  390. Connection conn = DriverManager.getConnection(url,user,password);
  391. //创建Statement对象
  392. Statement stmt = conn.createStatement();
  393. String sql = "SELECT wmsi.merch_sn,ppr.prod_barcode,ppr.prod_name,wmsi.shop_sn,wim.valid_num,wmsi.shop_inve FROM wb_inve_mng wim LEFT JOIN pd_product_record ppr ON wim.sku = ppr.sku LEFT JOIN wb_merch_shop_inve wmsi ON wim.sku = wmsi.sku WHERE ppr.is_record = 1 AND ppr.is_valid = 0 AND wim.inve_status = 0 AND wim.is_valid = 0 AND wmsi.is_valid = 0 AND wim.merch_sn='"+weDtilMsg.get("merchSn")+"' limit "+weChatMapMsg.get("offset")+","+weChatMapMsg.get("limit")+"";
  394. //建立结果集
  395. ResultSet rs = stmt.executeQuery(sql);
  396. inventoryDataPushVos =convertList(rs);
  397. //关闭结果集
  398. rs.close();
  399. //关闭Statement对象
  400. stmt.close();
  401. //关闭数据库
  402. conn.close();
  403. }catch(Exception e){
  404. logger.error("查询oms库存数据出错");
  405. }
  406. return inventoryDataPushVos;
  407. }
  408. private static List<InventoryDataPushVo> convertList(ResultSet rs) throws SQLException {
  409. List<InventoryDataPushVo> list = new ArrayList();
  410. while (rs.next()) {
  411. InventoryDataPushVo inventoryDataPushVo = new InventoryDataPushVo();
  412. inventoryDataPushVo.setBarcode(rs.getString("prod_barcode"));
  413. inventoryDataPushVo.setProductName(rs.getString("prod_name"));
  414. inventoryDataPushVo.setShopSn(rs.getString("shop_sn"));
  415. inventoryDataPushVo.setShopInvent(rs.getInt("shop_inve"));
  416. inventoryDataPushVo.seteMatou(rs.getInt("valid_num"));
  417. list.add(inventoryDataPushVo);
  418. }
  419. return list;
  420. }
  421. }