Browse Source

feat(order): 临时保存,销售订单异常

muti_db
Yen 7 months ago
parent
commit
daea0d068e
  1. 15
      src/main/java/com/qs/serve/common/config/MyBatisConfig.java
  2. 69
      src/main/java/com/qs/serve/common/framework/mybatis/handler/meta/TableNameAppendHandler.java
  3. 10
      src/main/java/com/qs/serve/common/framework/redis/RedisService.java
  4. 45
      src/main/java/com/qs/serve/modules/oms/common/OmsSaleYearUtil.java
  5. 60
      src/main/java/com/qs/serve/modules/oms/controller/OmsSaleOrderItemController.java
  6. 490
      src/main/java/com/qs/serve/modules/oms/controller/api/OmsSaleOrderApi.java
  7. 2
      src/main/java/com/qs/serve/modules/oms/mapper/OmsSaleOrderItemMapper.java
  8. 5
      src/main/java/com/qs/serve/modules/oms/mapper/OmsSaleOrderMapper.java
  9. 1
      src/main/java/com/qs/serve/modules/oms/service/OmsSaleOrderService.java
  10. 4
      src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java
  11. 6
      src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java
  12. 81
      src/main/java/com/qs/serve/modules/oms/service/impl/OmsSaleOrderServiceImpl.java
  13. 5
      src/main/java/com/qs/serve/modules/sys/service/impl/SysDeleteLogServiceImpl.java
  14. 12
      src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java
  15. 576
      src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
  16. 2
      src/main/resources/application-dev.yml
  17. 2
      src/main/resources/mapper/goods/GoodsImminentBatchMapper.xml

15
src/main/java/com/qs/serve/common/config/MyBatisConfig.java

@ -4,10 +4,12 @@ import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.qs.serve.common.framework.mybatis.handler.SysMetaHandler; import com.qs.serve.common.framework.mybatis.handler.SysMetaHandler;
import com.qs.serve.common.framework.mybatis.handler.SysTenantHandler; import com.qs.serve.common.framework.mybatis.handler.SysTenantHandler;
import com.qs.serve.common.framework.mybatis.handler.meta.TableNameAppendHandler;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -27,6 +29,10 @@ public class MyBatisConfig {
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 多租户、乐观锁等配置拦截 // 多租户、乐观锁等配置拦截
interceptor.addInnerInterceptor(buildTenantHandler()); interceptor.addInnerInterceptor(buildTenantHandler());
// 添加动态表名插件
// DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
// dynamicTableNameInnerInterceptor.setTableNameHandler(tableNameAppendHandler());
// interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
// 添加防止全表更新与删除拦截器 // 添加防止全表更新与删除拦截器
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor; return interceptor;
@ -37,6 +43,15 @@ public class MyBatisConfig {
return new SysMetaHandler(); return new SysMetaHandler();
} }
// public TableNameAppendHandler tableNameAppendHandler(){
// TableNameAppendHandler tableNameAppendHandler = new TableNameAppendHandler(
// "oms_sale_order",
// "oms_sale_order_item"
// );
// return tableNameAppendHandler;
// }
public TenantLineInnerInterceptor buildTenantHandler(){ public TenantLineInnerInterceptor buildTenantHandler(){
String[] ignoreTable = new String[]{ String[] ignoreTable = new String[]{
"sys_user", "sys_user",

69
src/main/java/com/qs/serve/common/framework/mybatis/handler/meta/TableNameAppendHandler.java

@ -0,0 +1,69 @@
package com.qs.serve.common.framework.mybatis.handler.meta;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
/**
* 拓展表格名称
* @author YenHex
* @since 2024/12/26
*/
@Slf4j
public class TableNameAppendHandler implements TableNameHandler {
/**
* 用于记录哪些表可以使用该月份动态表名处理器即哪些表按月分表
*/
private List<String> tableNames;
/**
* 构造函数构造动态表名处理器的时候传递tableNames参数
* @param tableNames
*/
public TableNameAppendHandler(String ...tableNames) {
this.tableNames = Arrays.asList(tableNames);
}
/**
* 每个请求线程维护一个month数据避免多线程数据冲突所以使用ThreadLocal
*/
private static final ThreadLocal<String> APPEND_DATA = new ThreadLocal<>();
/**
* 设置请求线程的month数据
* @param name
*/
public static void setAppend(String name) {
APPEND_DATA.set(name);
}
/**
* 删除当前请求线程的month数据
*/
public static void removeCache() {
APPEND_DATA.remove();
}
/**
* 动态表名接口实现方法
* @param sql
* @param tableName
* @return
*/
@Override
public String dynamicTableName(String sql, String tableName) {
if (this.tableNames.contains(tableName) && APPEND_DATA.get() != null){
//表名增加月份后缀
return tableName + "_" + APPEND_DATA.get();
}else{
if(this.tableNames.contains(tableName)){
log.warn("APPEND_DATA is null, table is {}",tableName);
}
//表名原样返回
return tableName;
}
}
}

10
src/main/java/com/qs/serve/common/framework/redis/RedisService.java

@ -36,6 +36,16 @@ public class RedisService {
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;
public long nextId(String key) {
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
// 如果键不存在,则设置初始值为 "0"
if (!redisTemplate.hasKey(key)) {
valueOps.set(key, "0");
}
// 使用 INCR 命令递增计数器
return valueOps.increment(key);
}
/** /**
* 加锁 * 加锁
* @param theme * @param theme

45
src/main/java/com/qs/serve/modules/oms/common/OmsSaleYearUtil.java

@ -0,0 +1,45 @@
package com.qs.serve.modules.oms.common;
import com.qs.serve.common.framework.mybatis.handler.meta.TableNameAppendHandler;
import com.qs.serve.common.util.ServletUtils;
import com.qs.serve.common.util.StringUtils;
import lombok.experimental.UtilityClass;
import java.time.LocalDate;
/**
* @author YenHex
* @since 2024/12/16
*/
@UtilityClass
public class OmsSaleYearUtil {
/**
* 通过订单id设置年份订单id前缀是年份
* @param id
*/
public static void initByIdString(String id){
// 截取id前面4位数值当年份
if(StringUtils.hasText(id) && id.length()>=4){
setYear(id.substring(0,4));
}
}
/**
* 当前年份
*/
public static void currYear(){
setYear(LocalDate.now().getYear()+"");
}
/**
* 设置指定年份
* @param year
*/
public static void setYear(String year){
if(StringUtils.hasText(year)){
TableNameAppendHandler.setAppend(year);
}
}
}

60
src/main/java/com/qs/serve/modules/oms/controller/OmsSaleOrderItemController.java

@ -0,0 +1,60 @@
package com.qs.serve.modules.oms.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qs.serve.common.model.annotation.SysLog;
import com.qs.serve.common.model.dto.R;
import com.qs.serve.common.model.enums.BizType;
import com.qs.serve.common.model.enums.SystemModule;
import com.qs.serve.modules.oms.entity.OmsOrderItem;
import com.qs.serve.modules.oms.entity.OmsSaleOrderItem;
import com.qs.serve.modules.oms.service.OmsOrderItemService;
import com.qs.serve.modules.oms.service.OmsSaleOrderItemService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 订单模块 订单明细
* @author YenHex
* @since 2022-10-14
*/
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("oms/saleOrderItem")
public class OmsSaleOrderItemController {
private OmsSaleOrderItemService omsSaleOrderItemService;
/**
* 查询订单项
* @param orderId
* @return
*/
@GetMapping("/listByOrderId/{orderId}")
public R<List<OmsSaleOrderItem>> listByOrderId(@PathVariable("orderId")Long orderId){
LambdaQueryWrapper<OmsSaleOrderItem> lqw = new LambdaQueryWrapper<>();
lqw.eq(OmsSaleOrderItem::getOrderId,orderId);
List<OmsSaleOrderItem> list = omsSaleOrderItemService.list(lqw);
return R.ok(list);
}
/**
* 根据ID查询
* @param id
* @return
*/
@GetMapping("/getById/{id}")
@SysLog(module = SystemModule.BASE, title = "订单明细", biz = BizType.QUERY)
public R<OmsSaleOrderItem> getById(@PathVariable("id") String id){
OmsSaleOrderItem omsOrderItem = omsSaleOrderItemService.getById(id);
return R.ok(omsOrderItem);
}
}

490
src/main/java/com/qs/serve/modules/oms/controller/api/OmsSaleOrderApi.java

@ -0,0 +1,490 @@
package com.qs.serve.modules.oms.controller.api;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qs.serve.common.framework.mybatis.handler.meta.TableNameAppendHandler;
import com.qs.serve.common.model.annotation.SysLog;
import com.qs.serve.common.model.dto.PageVo;
import com.qs.serve.common.model.dto.R;
import com.qs.serve.common.model.dto.SimpleKeyValue;
import com.qs.serve.common.model.enums.BizType;
import com.qs.serve.common.model.enums.SystemModule;
import com.qs.serve.common.util.*;
import com.qs.serve.modules.bms.entity.BmsSupplier;
import com.qs.serve.modules.bms.entity.BmsSupplierAddress;
import com.qs.serve.modules.bms.mapper.BmsSupplierMapper;
import com.qs.serve.modules.bms.service.BmsSupplierAddressService;
import com.qs.serve.modules.goods.entity.GoodsCategory;
import com.qs.serve.modules.goods.entity.GoodsSku;
import com.qs.serve.modules.goods.entity.GoodsSpu;
import com.qs.serve.modules.goods.entity.dto.InventoryCusPrice;
import com.qs.serve.modules.goods.entity.so.InventoryCusPriceQuery;
import com.qs.serve.modules.goods.mapper.GoodsImminentBatchMapper;
import com.qs.serve.modules.goods.service.GoodsCategoryRuleService;
import com.qs.serve.modules.goods.service.GoodsCategoryService;
import com.qs.serve.modules.goods.service.GoodsSkuService;
import com.qs.serve.modules.goods.service.GoodsSpuService;
import com.qs.serve.modules.oms.common.OmsOrderCheckState;
import com.qs.serve.modules.oms.common.OmsSaleYearUtil;
import com.qs.serve.modules.oms.entity.OmsOrder;
import com.qs.serve.modules.oms.entity.OmsOrderItem;
import com.qs.serve.modules.oms.entity.OmsSaleOrder;
import com.qs.serve.modules.oms.entity.OmsSaleOrderItem;
import com.qs.serve.modules.oms.entity.bo.*;
import com.qs.serve.modules.oms.entity.vo.OmsConfirmOrderResult;
import com.qs.serve.modules.oms.mapper.OmsOrderMapper;
import com.qs.serve.modules.oms.mapper.OmsSaleOrderMapper;
import com.qs.serve.modules.oms.service.*;
import com.qs.serve.modules.seeyon.service.impl.SeeYonRequestBaseService;
import com.qs.serve.modules.sys.entity.SysUser;
import com.qs.serve.modules.sys.service.SysPostUserService;
import com.qs.serve.modules.sys.service.SysUserService;
import com.qs.serve.modules.tbs.common.TbsSeeYonConst;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;
/**
* API订单模块 订单
* @author YenHex
* @since 2022-10-14
*/
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/api/saleOrder")
public class OmsSaleOrderApi {
private BmsSupplierMapper bmsSupplierMapper;
private OmsSaleOrderService omsSaleOrderService;
private OmsSaleOrderMapper omsSaleOrderMapper;
private OmsSaleOrderItemService omsSaleOrderItemService;
private BmsSupplierAddressService bmsSupplierAddressService;
private SysUserService sysUserService;
private GoodsCategoryRuleService goodsCategoryRuleService;
private GoodsSpuService goodsSpuService;
private GoodsSkuService goodsSkuService;
private GoodsCategoryService goodsCategoryService;
private SysPostUserService postUserService;
private SeeYonRequestBaseService seeYonRequestBaseService;
private GoodsImminentBatchMapper goodsImminentBatchMapper;
private OmsSaleOrderPart1Service omsSaleOrderPart1Service;
private OmsSaleOrderOptionsService omsSaleOrderOptionsService;
/**
* 查询客户特殊加
* @param query
* @return
*/
@PostMapping("queryCusPrices")
public R<List<InventoryCusPrice>> queryCusPrices(@RequestBody InventoryCusPriceQuery query){
R<String> res = seeYonRequestBaseService.postBase(TbsSeeYonConst.ERP_CUS_INV_PRICE,query,"查询客户特殊价");
if(res.getStatus().equals(200)) {
List<InventoryCusPrice> inventoryCusPrices = JsonUtil.jsonToList(res.getData(), InventoryCusPrice.class);
return R.ok(inventoryCusPrices);
}
return R.ok();
}
/**
* 传入订单ID返回订单每一项的sku单价,在前端校验商品价格
* @param orderId
* @return 返回错误的价格商品
*/
@GetMapping("checkOrderPrice")
public R<List<InventoryCusPrice>> checkOrderPrice(String orderId){
List<OmsSaleOrderItem> orderItemList = omsSaleOrderItemService.list(new LambdaQueryWrapper<OmsSaleOrderItem>()
.eq(OmsSaleOrderItem::getOrderId,orderId));
OmsSaleOrder order = omsSaleOrderService.getById(orderId);
String cusCode = order.getSupplierCode();
List<String> skuCodes = orderItemList.stream().map(OmsSaleOrderItem::getSkuCode).collect(Collectors.toList());
InventoryCusPriceQuery query = new InventoryCusPriceQuery();
query.setCusCode(cusCode);
query.setInvCodes(skuCodes);
R<String> res = seeYonRequestBaseService.postBase(TbsSeeYonConst.ERP_CUS_INV_PRICE,query,"查询客户特殊价");
List<InventoryCusPrice> errList = new ArrayList<>();
if(res.getStatus().equals(200)){
List<InventoryCusPrice> inventoryCusPrices = JsonUtil.jsonToList(res.getData(), InventoryCusPrice.class);
for (InventoryCusPrice cusPrice : inventoryCusPrices) {
for (OmsSaleOrderItem orderItem : orderItemList) {
if(cusPrice.getCusCode().equals(orderItem.getSkuCode())&&cusPrice.getPrice().compareTo(cusPrice.getPrice())!=0){
errList.add(cusPrice);
}
}
}
}
return R.ok(errList);
}
/**
* 确认订单
* @param confirmOrder
* @return
*/
@PostMapping("/generateConfirmOrder")
public R<OmsConfirmOrderResult> confirmOrder(@RequestBody @Valid OmsOrderBo confirmOrder){
return R.ok(omsSaleOrderService.confirmOrder(confirmOrder));
}
/**
* 创建订单H5
* @param omsOrderBo
* @return
*/
@PostMapping("/createOrder")
public R<OmsSaleOrder> createOrderPC(@RequestBody @Valid OmsOrderBo omsOrderBo){
return R.ok(omsSaleOrderService.createOrder(omsOrderBo));
}
/**
* 修改草稿的订单
* @param param
* @return
*/
@PostMapping("/modifyOrder")
public R<OmsOrder> modifyOrder(@RequestBody @Valid OmsOrderModifyParam param){
omsSaleOrderService.modifyOrder(param);
return R.ok();
}
/**
* 创建订单(PC)
* @param omsOrderBo
* @return
*/
@PostMapping("/createOrderOnPC")
public R<OmsSaleOrder> createOrder(@RequestBody @Valid OmsOrderSkuBo omsOrderBo){
return R.ok(omsSaleOrderService.createOrderPc(omsOrderBo));
}
/**
* 取消订单
* @param omsOrderBo
* @return
*/
@PostMapping("/cancelOrder")
public R<?> cancelOrder(@RequestBody @Valid OmsCancelOrder omsOrderBo){
OmsSaleOrder omsOrder = omsSaleOrderService.getById(omsOrderBo.getOrderId());
if(omsOrder.getOrderType().equals(3)){
//临期品
if(omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Commiting.getCode())){
//请求OA中止流程
Assert.throwEx("审批完成后再试");
}else if (!omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Finished.getCode())){
Assert.throwEx("审批状态不支持取消操作");
}
}
//omsOrderService.checkMsOrderStatus(omsOrder);
if(omsOrder.getStatus().equals(0)||omsOrder.getStatus().equals(1)){
//去执行取消
omsSaleOrderService.cancelOrder(omsOrder.getOrderSn());
omsOrder.setStatus(6);
omsSaleOrderService.updateById(omsOrder);
// 取消审批完成的临期品订单
if (omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Finished.getCode())){
omsSaleOrderPart1Service.releaseInventory(omsOrder.getId());
}
return R.ok();
}
return R.error("取消订单失败");
}
/**
* 翻页查询
* @param param
* @return
*/
@GetMapping("/page")
public R<PageVo<OmsSaleOrder>> getPage(OmsSaleOrder param){
BmsSupplier supplier = AuthContextUtils.getCurrentSupplier();
param.setSupplierId(Long.parseLong(supplier.getId()));
PageUtil.startPage();
LambdaQueryWrapper<OmsSaleOrder> orderWrapper = new LambdaQueryWrapper<>(param);
List<OmsSaleOrder> list = omsSaleOrderService.list(orderWrapper);
this.buildOrderVoInfo(list);
return R.byPageHelperList(list);
}
/**
* 翻页查询(PC,我的业务订单)
* @param param
* @return
*/
@GetMapping("/page4pc")
public R<PageVo<OmsSaleOrder>> getPage4Pc(OmsSaleOrder param){
PageUtil.startPage();
LambdaQueryWrapper<OmsSaleOrder> orderWrapper = new LambdaQueryWrapper<>(param);
orderWrapper.eq(OmsSaleOrder::getUserId,AuthContextUtils.getSysUserId());
orderWrapper.eq(OmsSaleOrder::getOrderType,param.getOrderType()==null?0:param.getOrderType());
orderWrapper.orderByDesc(OmsSaleOrder::getId);
if(param.getCheckStartTime()!=null){
orderWrapper.ge(OmsSaleOrder::getCheckTime,param.getCheckStartTime().atStartOfDay());
}
if(param.getCheckEndTime()!=null){
orderWrapper.le(OmsSaleOrder::getCheckTime,param.getCheckEndTime().atTime(23,59,59));
}
List<OmsSaleOrder> list = omsSaleOrderService.list(orderWrapper);
this.buildOrderVoInfo(list);
return R.byPageHelperList(list);
}
private void buildOrderVoInfo(List<OmsSaleOrder> list) {
List<String> userIds = list.stream().map(OmsSaleOrder::getCheckUserId).collect(Collectors.toList());
List<SysUser> sysUserList = new ArrayList<>();
if(userIds.size()>0){
sysUserList = sysUserService.listByIds(userIds);
}
List<Long> addrIds = list.stream().map(OmsSaleOrder::getSupplierAddrId).collect(Collectors.toList());
addrIds.add(0L);
List<BmsSupplierAddress> supplierAddressList = bmsSupplierAddressService.listByIds(addrIds);
List<Long> orderIds = list.stream().map(OmsSaleOrder::getId).collect(Collectors.toList());
orderIds.add(0L);
LambdaQueryWrapper<OmsSaleOrderItem> lqw = new LambdaQueryWrapper<>();
lqw.in(OmsSaleOrderItem::getOrderId,orderIds);
List<OmsSaleOrderItem> allItems = omsSaleOrderItemService.list(lqw);
List<SimpleKeyValue<String>> rates = omsSaleOrderMapper.selectExpiredOrderRates();
Map<Long,List<OmsSaleOrderItem>> itemsMap = allItems.stream().collect(Collectors.groupingBy(OmsSaleOrderItem::getOrderId));
for (OmsSaleOrder order : list) {
if(order.getOrderType().equals(3)&&StringUtils.hasText(order.getOaRateId())){
for (SimpleKeyValue<String> rate : rates) {
if (rate.getValue().equals(order.getOaRateId())){
order.setDiscountRateInfo(rate);
}
}
}
omsSaleOrderService.checkMsOrderStatus(order);
for (BmsSupplierAddress address : supplierAddressList) {
if(order.getSupplierAddrId().equals(address.getId())){
order.setAddressInfo(address);
}
}
for (SysUser user : sysUserList) {
if(user.getId().equals(order.getCheckUserId())){
order.setCheckUserInfo(user.toSysUserVo());
}
}
order.setOrderItems(itemsMap.get(order.getId()));
}
}
/**
* 翻页查询(PC,我的业务订单)
* @param param
* @return
*/
@GetMapping("/pageUnder4pc")
public R<PageVo<OmsSaleOrder>> getPageUnder4Pc(OmsSaleOrder param){
String loginUserId = AuthContextUtils.getSysUserId();
List<String> userIds = postUserService.listByChildIds(loginUserId);
if(CollectionUtil.isEmpty(userIds)){
return R.byEmptyList();
}
PageUtil.startPage();
LambdaQueryWrapper<OmsSaleOrder> orderWrapper = new LambdaQueryWrapper<>(param);
orderWrapper.in(OmsSaleOrder::getUserId,userIds);
orderWrapper.orderByDesc(OmsSaleOrder::getId);
List<OmsSaleOrder> list = omsSaleOrderService.list(orderWrapper);
Set<Long> addrIds = list.stream().map(OmsSaleOrder::getSupplierAddrId).filter(Objects::nonNull).collect(Collectors.toSet());
List<BmsSupplierAddress> supplierAddressList = bmsSupplierAddressService.listByIds(addrIds);
Set<String> checkUserIds = list.stream().map(OmsSaleOrder::getCheckUserId).filter(Objects::nonNull).collect(Collectors.toSet());
List<SysUser> sysUsers = sysUserService.listByIds(checkUserIds);
Set<Long> orderIds = list.stream().map(OmsSaleOrder::getId).filter(Objects::nonNull).collect(Collectors.toSet());
LambdaQueryWrapper<OmsSaleOrderItem> lqw = new LambdaQueryWrapper<>();
lqw.in(OmsSaleOrderItem::getOrderId,orderIds);
List<OmsSaleOrderItem> items = omsSaleOrderItemService.list(lqw);
Map<Long,List<OmsSaleOrderItem>> orderItemMap = items.stream().collect(Collectors.groupingBy(OmsSaleOrderItem::getOrderId));
for (OmsSaleOrder order : list) {
if(order.getSupplierAddrId()!=null){
for (BmsSupplierAddress address : supplierAddressList) {
if(order.getSupplierAddrId().equals(address.getId())){
order.setAddressInfo(address);
}
}
}
for (SysUser sysUser : sysUsers) {
if(sysUser.getId().equals(order.getCheckUserId())){
order.setCheckUserInfo(sysUser.toSysUserVo());
break;
}
}
order.setOrderItems(orderItemMap.get(order.getId()));
}
return R.byPageHelperList(list);
}
/**
* 根据ID查询
* @param id
* @return
*/
@GetMapping("/getById/{id}")
@SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.QUERY)
public R<OmsSaleOrder> getById(@PathVariable("id") String id){
BmsSupplier supplier = AuthContextUtils.getCurrentSupplier();
OmsSaleOrder omsOrder = omsSaleOrderService.getById(id);
if(omsOrder.getOrderType().equals(3)&&omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Commiting.getCode())){
omsSaleOrderOptionsService.runCompensate(omsOrder.getId()+"");
omsOrder = omsSaleOrderService.getById(id);
}
// 关联折扣信息
if(StringUtils.hasText(omsOrder.getOaRateId())){
SimpleKeyValue obj = omsSaleOrderMapper.getExpiredRateInfo(omsOrder.getOaRateId());
omsOrder.setDiscountRateInfo(obj);
}
omsOrder.setBrandRuleInfo(goodsCategoryRuleService.getById(omsOrder.getBrandRuleId()));
omsOrder.setAddressInfo(bmsSupplierAddressService.getById(omsOrder.getSupplierAddrId()));
omsOrder.setSupplierInfo(bmsSupplierMapper.selectById(omsOrder.getSupplierId()));
if(omsOrder.getSupplierId().toString().equals(supplier.getId())){
LambdaQueryWrapper<OmsSaleOrderItem> lqw = new LambdaQueryWrapper<>();
lqw.eq(OmsSaleOrderItem::getOrderId,id);
List<OmsSaleOrderItem> list = omsSaleOrderItemService.list(lqw);
if(CollectionUtil.isNotEmpty(list)){
omsSaleOrderService.updateCusPrice(omsOrder.getSupplierCode(),list);
}
for (OmsSaleOrderItem orderItem : list) {
GoodsSpu goodsSpu = goodsSpuService.getById(orderItem.getSpuId());
GoodsCategory goodsCategory = goodsCategoryService.getById(goodsSpu.getCategoryLast());
orderItem.setCategoryInfo(goodsCategory);
orderItem.setSpuInfo(goodsSpu);
GoodsSku goodsSku = goodsSkuService.getById(orderItem.getSkuId());
if(goodsSku!=null){
orderItem.setSkuSpecialFlag(goodsSku.getSpecialFlag());
orderItem.setSkuBelong(goodsSku.getBelong());
orderItem.setSkuAddCode(goodsSku.getSkuAddCode());
}
if(orderItem.getSkuBatchId()!=null){
orderItem.setBatchInfo(goodsImminentBatchMapper.selectById(orderItem.getSkuBatchId()));
}
}
omsOrder.setOrderItems(list);
return R.ok(omsOrder);
}
return R.error();
}
/**
* 删除订单
* @param id
* @return
*/
//@DeleteMapping("/deleteById/{id}")
@SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.DELETE)
public R<?> deleteById(@PathVariable("id") String id){
BmsSupplier supplier = AuthContextUtils.getCurrentSupplier();
OmsSaleOrder omsOrder = omsSaleOrderService.getById(id);
if(omsOrder.getSupplierId().toString().equals(supplier.getId())){
boolean result = omsSaleOrderService.removeById(id);
return R.isTrue(result);
}
return R.error();
}
/**
* 创建报价单
* @param id
* @return
*/
@PostMapping("/buildPriceOrder/{id}/{amount}")
@SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.DELETE)
public R<?> buildPriceOrder(@PathVariable("id") String id,@PathVariable("amount") String amount){
omsSaleOrderService.buildPriceOrder(id,amount);
return R.ok();
}
/**
* 删除订单
* @param id
* @return
*/
@DeleteMapping("/deleteById/{id}")
@SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.DELETE)
public R<?> deleteById(@PathVariable("id") Long id){
OmsSaleOrder dbOmsOrder = omsSaleOrderService.getById(id);
if(!dbOmsOrder.getOrderCheckState().equals(OmsOrderCheckState.UnPublish.getCode())){
return R.error("审批状态不支持删除");
}
omsSaleOrderService.checkMsOrderStatus(dbOmsOrder);
if(dbOmsOrder.getStatus().equals(0)&&dbOmsOrder.getCheckState().equals(0)){
boolean result = omsSaleOrderService.removeById(id);
return R.isTrue(result);
}
return R.error("当前状态无法删除");
}
/**
* 创建临期品订单
* @param omsOrderBo
* @return
*/
@PostMapping("/createImminentOrder")
public R<OmsSaleOrder> createImminentOrder(@RequestBody @Valid OmsOrderImminentBo omsOrderBo){
return R.ok(omsSaleOrderService.modifyImminentOrder(omsOrderBo));
}
/**
* 修改临期品的订单
* @param param
* @return
*/
@PostMapping("/modifyImminentOrder")
public R<OmsOrder> modifyImminentOrder(@RequestBody @Valid OmsOrderImminentBo param){
omsSaleOrderService.modifyImminentOrder(param);
return R.ok();
}
/**
* 校验sku合法性
* @param verifySkuParam
* @return
*/
@PostMapping("/verifySku")
public R<?> verifySku(@RequestBody OmsVerifySkuParam verifySkuParam){
return R.ok(omsSaleOrderPart1Service.verifySku(verifySkuParam));
}
/**
* 复制订单
* @param orderId
* @return
*/
@PostMapping("/copyOrder/{orderId}")
public R<OmsSaleOrder> copyOrder(@PathVariable Long orderId){
return R.ok(omsSaleOrderPart1Service.copyOrder(orderId));
}
/**
* 获取临期品订单折扣率
* @return
*/
@GetMapping("/expiredOrderRates")
public R<?> getExpiredOrderRates(){
return R.ok(omsSaleOrderService.selectExpiredOrderRates());
}
}

2
src/main/java/com/qs/serve/modules/oms/mapper/OmsSaleOrderItemMapper.java

@ -1,5 +1,6 @@
package com.qs.serve.modules.oms.mapper; package com.qs.serve.modules.oms.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qs.serve.modules.oms.entity.OmsSaleOrderItem; import com.qs.serve.modules.oms.entity.OmsSaleOrderItem;
@ -8,6 +9,7 @@ import com.qs.serve.modules.oms.entity.OmsSaleOrderItem;
* @author YenHex * @author YenHex
* @date 2022-10-14 * @date 2022-10-14
*/ */
@DS("qisheng")
public interface OmsSaleOrderItemMapper extends BaseMapper<OmsSaleOrderItem> { public interface OmsSaleOrderItemMapper extends BaseMapper<OmsSaleOrderItem> {
} }

5
src/main/java/com/qs/serve/modules/oms/mapper/OmsSaleOrderMapper.java

@ -1,5 +1,6 @@
package com.qs.serve.modules.oms.mapper; package com.qs.serve.modules.oms.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qs.serve.common.model.dto.SimpleKeyValue; import com.qs.serve.common.model.dto.SimpleKeyValue;
import com.qs.serve.modules.oms.entity.OmsSaleOrder; import com.qs.serve.modules.oms.entity.OmsSaleOrder;
@ -13,14 +14,18 @@ import java.util.List;
* @author YenHex * @author YenHex
* @date 2022-10-14 * @date 2022-10-14
*/ */
@DS("qisheng")
public interface OmsSaleOrderMapper extends BaseMapper<OmsSaleOrder> { public interface OmsSaleOrderMapper extends BaseMapper<OmsSaleOrder> {
@DS("crm_db")
@Select("SELECT rate FROM `ext_expire_order_rate` where oa_id = #{oaId} and del_flag = 0 ") @Select("SELECT rate FROM `ext_expire_order_rate` where oa_id = #{oaId} and del_flag = 0 ")
BigDecimal getExpiredOrderRates(String oaId); BigDecimal getExpiredOrderRates(String oaId);
@DS("crm_db")
@Select("SELECT oa_id as `value`,`name` as label,rate as value2 FROM `ext_expire_order_rate` where del_flag = 0 order by rate") @Select("SELECT oa_id as `value`,`name` as label,rate as value2 FROM `ext_expire_order_rate` where del_flag = 0 order by rate")
List<SimpleKeyValue<String>> selectExpiredOrderRates(); List<SimpleKeyValue<String>> selectExpiredOrderRates();
@DS("crm_db")
@Select("SELECT oa_id as `value`,`name` as label,rate as value2 FROM `ext_expire_order_rate` where del_flag = 0 and oa_id = #{oaId} ") @Select("SELECT oa_id as `value`,`name` as label,rate as value2 FROM `ext_expire_order_rate` where del_flag = 0 and oa_id = #{oaId} ")
SimpleKeyValue<String> getExpiredRateInfo(String oaId); SimpleKeyValue<String> getExpiredRateInfo(String oaId);

1
src/main/java/com/qs/serve/modules/oms/service/OmsSaleOrderService.java

@ -128,5 +128,6 @@ public interface OmsSaleOrderService extends IService<OmsSaleOrder> {
BmsSupplierAddress supplierAddress, BmsSupplierAddress supplierAddress,
BmsRegion bmsRegion); BmsRegion bmsRegion);
} }

4
src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java

@ -119,8 +119,8 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService {
OmsOrderUtil.checkOrderItemValues(orderItemList); OmsOrderUtil.checkOrderItemValues(orderItemList);
//下单前规则拦截 //下单前规则拦截
GoodsCategoryRule categoryRule = goodsCategoryRuleMapper.selectById(omsOrder.getBrandRuleId()); //GoodsCategoryRule categoryRule = goodsCategoryRuleMapper.selectById(omsOrder.getBrandRuleId());
omsOrderService.handleCategoryRule(categoryRule, orderItemList); //omsOrderService.handleCategoryRule(categoryRule, orderItemList);
List<GoodsImminentBatch> imminentBatches = new ArrayList<>(); List<GoodsImminentBatch> imminentBatches = new ArrayList<>();
if (omsOrder.getOrderType().equals(3)) { if (omsOrder.getOrderType().equals(3)) {

6
src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java

@ -960,13 +960,13 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
buildSkuSpecPrice(supplier, orderItems, skuCodes); buildSkuSpecPrice(supplier, orderItems, skuCodes);
//拦截商品授权维度规则 //拦截商品授权维度规则
this.checkGoodsRule(supplier, orderItems); //this.checkGoodsRule(supplier, orderItems);
//拦截客户维度规则 //拦截客户维度规则
goodsRuleService.checkSkuCode(skuCodes, order.getSupplierId().toString(), true); //goodsRuleService.checkSkuCode(skuCodes, order.getSupplierId().toString(), true);
//拦截品类下单规则 //拦截品类下单规则
this.handleCategoryRule(categoryRule, orderItems); //this.handleCategoryRule(categoryRule, orderItems);
} }

81
src/main/java/com/qs/serve/modules/oms/service/impl/OmsSaleOrderServiceImpl.java

@ -1095,87 +1095,6 @@ public class OmsSaleOrderServiceImpl extends ServiceImpl<OmsSaleOrderMapper, Oms
SysUser sysUser = sysUserService.getById(omsOrder.getCreateBy()); SysUser sysUser = sysUserService.getById(omsOrder.getCreateBy());
//保存到临时表-主表 //保存到临时表-主表
LocalDateTime nowTime = LocalDateTime.now(); LocalDateTime nowTime = LocalDateTime.now();
OmsXltOrder xltOrder = new OmsXltOrder();
xltOrder.setId(IdUtil.getSnowFlakeId() + "");
xltOrder.setOrderType(omsOrder.getOrderType());
xltOrder.setDingDanHao(omsOrder.getOrderSn());
xltOrder.setShenQingRiQi(nowTime);
xltOrder.setKeHuBianHao(omsOrder.getSupplierCode());
xltOrder.setShouHuoDiZhi(supplierAddress.getDetail());
xltOrder.setRenYuanBianHao(omsOrder.getUserCode());
xltOrder.setCdOrderRemark(omsOrder.getCdOrderRemark());
xltOrder.setDiscountRate(omsOrder.getDiscountRate());
String remark = sysUser.getName() + "(" + sysUser.getMobile() + ")" + omsOrder.getRemark() + supplierAddress.getDetail();
if (remark.length() > 120) {
remark = remark.substring(0, 120);
}
xltOrder.setZhuYiShiXian(remark);
xltOrder.setXieRuShiJian(nowTime);
xltOrder.setChuLiShiJian(null);
xltOrder.setRowCreateDate(nowTime);
xltOrder.setRenYuanXingMing(omsOrder.getUserName());
xltOrder.setRenYuanDianHua(omsOrder.getUserPhone());
xltOrder.setXianZhiWeiDu("品牌");
xltOrder.setXianZhiWeiDuMingChen(brands);
xltOrder.setZhuangTai(0);
//状态:0未使用;1报价单;2销售订单
xltOrder.setStatus(0);
xltOrder.setTmsSysId(supplierAddress.getId() + "");
xltOrder.setEmpName(omsOrder.getUserName());
xltOrder.setCusCode(omsOrder.getSupplierCode());
xltOrder.setCusName(omsOrder.getSupplierName());
try {
String[] regions = bmsRegion.getPathNames().split("_");
if (regions.length > 1) {
xltOrder.setDealerProvince(regions[1]);
}
if (regions.length > 0) {
xltOrder.setDealerCity(regions[0]);
}
} catch (Exception e) {
log.warn("区域档案异常:{}",bmsRegion.getName());
}
xltOrder.setDealerArea(bmsRegion.getPathNames());
//保存到临时表-明细表
List<OmsXltOrderItem> xltOrderItemList = new ArrayList<>();
for (int i = 0; i < orderItemList.size(); i++) {
OmsSaleOrderItem orderItem = orderItemList.get(i);
OmsXltOrderItem xltOrderItem = new OmsXltOrderItem();
xltOrderItem.setId(xltOrder.getId() + "_" + (i + 1));
xltOrderItem.setDingDanID(xltOrder.getId());
xltOrderItem.setSpuCode(orderItem.getSpuCode());
boolean eq = orderItem.getSkuCode().equals(orderItem.getSpuCode());
if (!StringUtils.hasText(orderItem.getSkuCode()) || eq) {
GoodsSku sku = goodsSkuService.getById(orderItem.getSkuId());
GoodsSpu spu = goodsSpuService.getById(orderItem.getSpuId());
if (!sku.getSkuCode().equals(spu.getSpuCode())) {
Assert.throwEx("SKU【" + orderItem.getSpuCode() + "】存货缺失,请联系档案负责人");
}
}
xltOrderItem.setChanPinBianHao(orderItem.getSkuCode());
xltOrderItem.setChanPinDanWei(orderItem.getSkuUnit());
xltOrderItem.setDingHuoShuLiang(orderItem.getQuantity());
xltOrderItem.setDaZengShuLiang(BigDecimal.ZERO);
xltOrderItem.setChanPinYuanJia(orderItem.getMarketPrice());
xltOrderItem.setChanPinXianJia(orderItem.getSalesPrice());
xltOrderItem.setXieRuShiJian(nowTime);
xltOrderItem.setChuLiShiJian(null);
xltOrderItem.setRowCreateDate(nowTime);
if (omsOrder.getOrderType().equals(3)) {
String itemRm = orderItem.getRemark() == null ? "" : orderItem.getRemark();
xltOrderItem.setBeiZhu("批号[" + orderItem.getSkuBatchCode() + "]" + itemRm);
} else {
xltOrderItem.setBeiZhu(orderItem.getRemark());
}
xltOrderItem.setZhuangTai(0);
xltOrderItemList.add(xltOrderItem);
}
XltOrderDTO xltOrderDTO = new XltOrderDTO(xltOrder, xltOrderItemList);
//请求到中间服务保存
seeYonRequestBaseService.postBase(ERP_ORDER_CREATE, xltOrderDTO, "创建订单:" + xltOrder.getDingDanHao());
//更新订单 //更新订单
omsOrder.setStatus(1); omsOrder.setStatus(1);
omsOrder.setCheckTime(LocalDateTime.now()); omsOrder.setCheckTime(LocalDateTime.now());

5
src/main/java/com/qs/serve/modules/sys/service/impl/SysDeleteLogServiceImpl.java

@ -3,6 +3,7 @@ import java.time.LocalDateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.serve.common.model.dto.R;
import com.qs.serve.common.util.*; import com.qs.serve.common.util.*;
import com.qs.serve.modules.bir.consts.BirActivityCenterGoodsUtil; import com.qs.serve.modules.bir.consts.BirActivityCenterGoodsUtil;
import com.qs.serve.modules.bms.entity.BmsSupplier; import com.qs.serve.modules.bms.entity.BmsSupplier;
@ -83,9 +84,9 @@ public class SysDeleteLogServiceImpl extends ServiceImpl<SysDeleteLogMapper,SysD
costDeletion.setCacc(bookCode); costDeletion.setCacc(bookCode);
costDeletion.setVerificationCode(costApply.getCode()); costDeletion.setVerificationCode(costApply.getCode());
String rs = HttpUtil.doPost(url, JsonUtil.objectToJson(costDeletion),null); String rs = HttpUtil.doPost(url, JsonUtil.objectToJson(costDeletion),null);
R rsObj = JsonUtil.jsonToPojo(rs, R.class);
log.warn("【请求删除ERP费用】{},返回结果:{}",costApplyId,rs); log.warn("【请求删除ERP费用】{},返回结果:{}",costApplyId,rs);
if(!rs.contains("200")&&!rs.contains("核销档案不存在该编码")){ if(!rsObj.getStatus().equals(200)){
Assert.throwEx("远程删除失败:"+rs); Assert.throwEx("远程删除失败:"+rs);
} }

12
src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java

@ -367,14 +367,14 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
policyItemDto.setPolicyGoodsItemList(goodsItems); policyItemDto.setPolicyGoodsItemList(goodsItems);
//测试环境不进入生成 //测试环境不进入生成
if(!DevEnvironmentConfig.isDev()){ if(!DevEnvironmentConfig.isDev()){
String policySyncInvUrl = projectApisProperties.getPolicySyncInv(); //String policySyncInvUrl = projectApisProperties.getPolicySyncInv();
// String policySyncCateUrl = projectApisProperties.getPolicySyncCate(); String policySyncCateUrl = projectApisProperties.getPolicySyncCate();
String dataJson = JsonUtil.objectToJson(policyItemDto); String dataJson = JsonUtil.objectToJson(policyItemDto);
// //
String rs = HttpUtil.doPost(policySyncInvUrl, dataJson, null); // String rs = HttpUtil.doPost(policySyncInvUrl, dataJson, null);
log.debug("policySyncInvUrl:{}\n result:{}",policySyncInvUrl,rs); // log.debug("policySyncInvUrl:{}\n result:{}",policySyncInvUrl,rs);
// String rs2 = HttpUtil.doPost(policySyncCateUrl, dataJson, null); String rs2 = HttpUtil.doPost(policySyncCateUrl, dataJson, null);
// log.debug("policySyncCateUrl:{}\n result:{}",policySyncCateUrl,rs2); log.debug("policySyncCateUrl:{}\n result:{}",policySyncCateUrl,rs2);
//保存异步处理的 //保存异步处理的
//xiaoLuTonService.savePolicyItem(policyItemDto); //xiaoLuTonService.savePolicyItem(policyItemDto);

576
src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java

@ -1,576 +0,0 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.ToJson;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxNetCheckResult;
import me.chanjar.weixin.common.enums.TicketType;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.service.WxImgProcService;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.common.service.WxOcrService;
import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.DataUtils;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpShortKeyResult;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.enums.WxMpApiUrl;
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.CLEAR_QUOTA_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.FETCH_SHORTEN_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GEN_SHORTEN_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_CALLBACK_IP_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_CURRENT_AUTOREPLY_INFO_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_TICKET_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.NETCHECK_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.QRCONNECT_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.SEMANTIC_SEMPROXY_SEARCH_URL;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.SHORTURL_API_URL;
/**
* 基础实现类.
*
* @author someone
*/
@Slf4j
public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestHttp<H, P> {
protected WxSessionManager sessionManager = new StandardSessionManager();
@Getter
@Setter
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
@Getter
@Setter
private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this);
@Getter
@Setter
private WxMpMenuService menuService = new WxMpMenuServiceImpl(this);
@Getter
@Setter
private WxMpUserService userService = new WxMpUserServiceImpl(this);
@Getter
@Setter
private WxMpUserTagService userTagService = new WxMpUserTagServiceImpl(this);
@Getter
@Setter
private WxMpQrcodeService qrcodeService = new WxMpQrcodeServiceImpl(this);
@Getter
@Setter
private WxMpCardService cardService = new WxMpCardServiceImpl(this);
@Getter
@Setter
private WxMpStoreService storeService = new WxMpStoreServiceImpl(this);
@Getter
@Setter
private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this);
@Getter
@Setter
private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this);
@Getter
@Setter
private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this);
@Getter
@Setter
private final WxMpSubscribeMsgService subscribeMsgService = new WxMpSubscribeMsgServiceImpl(this);
@Getter
@Setter
private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this);
@Getter
@Setter
private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this);
@Getter
@Setter
private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this);
@Getter
@Setter
private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this);
@Getter
@Setter
private WxMpAiOpenService aiOpenService = new WxMpAiOpenServiceImpl(this);
@Getter
@Setter
private final WxMpWifiService wifiService = new WxMpWifiServiceImpl(this);
@Getter
@Setter
private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this);
@Getter
@Setter
private WxMpCommentService commentService = new WxMpCommentServiceImpl(this);
@Getter
@Setter
private WxOcrService ocrService = new WxMpOcrServiceImpl(this);
@Getter
@Setter
private WxImgProcService imgProcService = new WxMpImgProcServiceImpl(this);
@Getter
@Setter
private WxMpMerchantInvoiceService merchantInvoiceService = new WxMpMerchantInvoiceServiceImpl(this, this.cardService);
@Getter
@Setter
private WxMpGuideService guideService = new WxMpGuideServiceImpl(this);
@Getter
@Setter
private WxMpGuideBuyerService guideBuyerService = new WxMpGuideBuyerServiceImpl(this);
@Getter
@Setter
private WxMpGuideTagService guideTagService = new WxMpGuideTagServiceImpl(this);
@Getter
@Setter
private WxMpGuideMassedJobService guideMassedJobService = new WxMpGuideMassedJobServiceImpl(this);
@Getter
@Setter
private WxMpGuideMaterialService guideMaterialService = new WxMpGuideMaterialServiceImpl(this);
@Getter
@Setter
private WxOAuth2Service oAuth2Service = new WxMpOAuth2ServiceImpl(this);
@Getter
@Setter
private WxMpReimburseInvoiceService reimburseInvoiceService = new WxMpReimburseInvoiceServiceImpl(this);
@Getter
@Setter
private WxMpDraftService draftService = new WxMpDraftServiceImpl(this);
@Getter
@Setter
private WxMpFreePublishService freePublishService = new WxMpFreePublishServiceImpl(this);
private Map<String, WxMpConfigStorage> configStorageMap;
private int retrySleepMillis = 1000;
private int maxRetryTimes = 5;
@Override
public String genShorten(String longData, Integer expireSeconds) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("long_data", longData);
param.addProperty("expire_seconds", expireSeconds);
String responseContent = this.post(GEN_SHORTEN_URL, param.toString());
JsonObject tmpJsonObject = GsonParser.parse(responseContent);
return tmpJsonObject.get("short_key").getAsString();
}
@Override
public WxMpShortKeyResult fetchShorten(String shortKey) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("short_key", shortKey);
String responseContent = this.post(FETCH_SHORTEN_URL, param.toString());
return WxMpShortKeyResult.fromJson(responseContent);
}
@Override
public boolean checkSignature(String timestamp, String nonce, String signature) {
try {
return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce)
.equals(signature);
} catch (Exception e) {
log.warn("Checking signature failed, and the reason is :" + e.getMessage());
return false;
}
}
@Override
public String getTicket(TicketType type) throws WxErrorException {
return this.getTicket(type, false);
}
@Override
public String getTicket(TicketType type, boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
this.getWxMpConfigStorage().expireTicket(type);
}
if (this.getWxMpConfigStorage().isTicketExpired(type)) {
Lock lock = this.getWxMpConfigStorage().getTicketLock(type);
lock.lock();
try {
if (this.getWxMpConfigStorage().isTicketExpired(type)) {
String responseContent = execute(SimpleGetRequestExecutor.create(this),
GET_TICKET_URL.getUrl(this.getWxMpConfigStorage()) + type.getCode(), null);
JsonObject tmpJsonObject = GsonParser.parse(responseContent);
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
this.getWxMpConfigStorage().updateTicket(type, jsapiTicket, expiresInSeconds);
}
} finally {
lock.unlock();
}
}
return this.getWxMpConfigStorage().getTicket(type);
}
@Override
public String getJsapiTicket() throws WxErrorException {
return this.getJsapiTicket(false);
}
@Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
return this.getTicket(TicketType.JSAPI, forceRefresh);
}
@Override
public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException {
long timestamp = System.currentTimeMillis() / 1000;
String randomStr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false);
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
"noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId());
jsapiSignature.setTimestamp(timestamp);
jsapiSignature.setNonceStr(randomStr);
jsapiSignature.setUrl(url);
jsapiSignature.setSignature(signature);
return jsapiSignature;
}
@Override
public String getAccessToken() throws WxErrorException {
return getAccessToken(false);
}
@Override
public String shortUrl(String longUrl) throws WxErrorException {
if (longUrl.contains("&access_token=")) {
throw new WxErrorException("要转换的网址中存在非法字符{&access_token=}," +
"会导致微信接口报错,属于微信bug,请调整地址,否则不建议使用此方法!");
}
JsonObject o = new JsonObject();
o.addProperty("action", "long2short");
o.addProperty("long_url", longUrl);
String responseContent = this.post(SHORTURL_API_URL, o.toString());
return GsonParser.parse(responseContent).get("short_url").getAsString();
}
@Override
public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException {
String responseContent = this.post(SEMANTIC_SEMPROXY_SEARCH_URL, semanticQuery.toJson());
return WxMpSemanticQueryResult.fromJson(responseContent);
}
@Override
public String buildQrConnectUrl(String redirectUri, String scope, String state) {
return String.format(QRCONNECT_URL.getUrl(this.getWxMpConfigStorage()), this.getWxMpConfigStorage().getAppId(),
URIUtil.encodeURIComponent(redirectUri), scope, StringUtils.trimToEmpty(state));
}
@Override
public String[] getCallbackIP() throws WxErrorException {
String responseContent = this.get(GET_CALLBACK_IP_URL, null);
JsonObject tmpJsonObject = GsonParser.parse(responseContent);
JsonArray ipList = tmpJsonObject.get("ip_list").getAsJsonArray();
String[] ipArray = new String[ipList.size()];
for (int i = 0; i < ipList.size(); i++) {
ipArray[i] = ipList.get(i).getAsString();
}
return ipArray;
}
@Override
public WxNetCheckResult netCheck(String action, String operator) throws WxErrorException {
JsonObject o = new JsonObject();
o.addProperty("action", action);
o.addProperty("check_operator", operator);
String responseContent = this.post(NETCHECK_URL, o.toString());
return WxNetCheckResult.fromJson(responseContent);
}
@Override
public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException {
return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null));
}
@Override
public void clearQuota(String appid) throws WxErrorException {
JsonObject o = new JsonObject();
o.addProperty("appid", appid);
this.post(CLEAR_QUOTA_URL, o.toString());
}
@Override
public String get(String url, String queryParam) throws WxErrorException {
return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
}
@Override
public String get(WxMpApiUrl url, String queryParam) throws WxErrorException {
return this.get(url.getUrl(this.getWxMpConfigStorage()), queryParam);
}
@Override
public String post(String url, String postData) throws WxErrorException {
return execute(SimplePostRequestExecutor.create(this), url, postData);
}
@Override
public String post(WxMpApiUrl url, String postData) throws WxErrorException {
return this.post(url.getUrl(this.getWxMpConfigStorage()), postData);
}
@Override
public String post(WxMpApiUrl url, Object obj) throws WxErrorException {
return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
}
@Override
public String post(WxMpApiUrl url, JsonObject jsonObject) throws WxErrorException {
return this.post(url.getUrl(this.getWxMpConfigStorage()), jsonObject.toString());
}
@Override
public String post(String url, ToJson obj) throws WxErrorException {
return this.post(url, obj.toJson());
}
@Override
public String post(String url, JsonObject jsonObject) throws WxErrorException {
return this.post(url, jsonObject.toString());
}
@Override
public String post(String url, Object obj) throws WxErrorException {
return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
}
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, WxMpApiUrl url, E data) throws WxErrorException {
return this.execute(executor, url.getUrl(this.getWxMpConfigStorage()), data);
}
/**
* 向微信端发送请求在这里执行的策略是当发生access_token过期时才去刷新然后重新执行请求而不是全局定时请求.
*/
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
int retryTimes = 0;
do {
try {
return this.executeInternal(executor, uri, data, false);
} catch (WxErrorException e) {
WxError error = e.getError();
// -1 系统繁忙, 1000ms后重试
if (error.getErrorCode() == -1) {
// 判断是否已经超了最大重试次数
if (retryTimes + 1 > this.maxRetryTimes) {
log.warn("重试达到最大次数【{}】", maxRetryTimes);
//最后一次重试失败后,直接抛出异常,不再等待
throw new WxRuntimeException("微信服务端异常,超出重试次数");
}
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new WxRuntimeException(e1);
}
} else {
throw e;
}
}
} while (retryTimes++ < this.maxRetryTimes);
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
throw new WxRuntimeException("微信服务端异常,超出重试次数");
}
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh) throws WxErrorException {
E dataForLog = DataUtils.handleDataWithSecret(data);
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
String accessToken = getAccessToken(false);
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
try {
T result = executor.execute(uriWithAccessToken, data, WxType.MP);
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
lock.lock();
try {
if (StringUtils.equals(this.getWxMpConfigStorage().getAccessToken(), accessToken)) {
this.getWxMpConfigStorage().expireAccessToken();
}
} catch (Exception ex) {
this.getWxMpConfigStorage().expireAccessToken();
} finally {
lock.unlock();
}
if (this.getWxMpConfigStorage().autoRefreshToken() && !doNotAutoRefresh) {
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
//下一次不再自动重试
//当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
return this.executeInternal(executor, uri, data, true);
}
}
if (error.getErrorCode() != 0) {
log.warn("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
throw new WxErrorException(error, e);
}
return null;
} catch (IOException e) {
log.warn("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new WxErrorException(e);
}
}
@Override
public WxMpConfigStorage getWxMpConfigStorage() {
if (this.configStorageMap.size() == 1) {
// 只有一个公众号,直接返回其配置即可
return this.configStorageMap.values().iterator().next();
}
return this.configStorageMap.get(WxMpConfigStorageHolder.get());
}
protected String extractAccessToken(String resultContent) throws WxErrorException {
WxMpConfigStorage config = this.getWxMpConfigStorage();
WxError error = WxError.fromJson(resultContent, WxType.MP);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
return config.getAccessToken();
}
@Override
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) {
final String defaultMpId = wxConfigProvider.getAppId();
this.setMultiConfigStorages(ImmutableMap.of(defaultMpId, wxConfigProvider), defaultMpId);
}
@Override
public void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages) {
this.setMultiConfigStorages(configStorages, configStorages.keySet().iterator().next());
}
@Override
public void setMultiConfigStorages(Map<String, WxMpConfigStorage> configStorages, String defaultMpId) {
this.configStorageMap = Maps.newHashMap(configStorages);
WxMpConfigStorageHolder.set(defaultMpId);
this.initHttp();
}
@Override
public void addConfigStorage(String mpId, WxMpConfigStorage configStorages) {
synchronized (this) {
if (this.configStorageMap == null) {
this.setWxMpConfigStorage(configStorages);
} else {
WxMpConfigStorageHolder.set(mpId);
this.configStorageMap.put(mpId, configStorages);
}
}
}
@Override
public void removeConfigStorage(String mpId) {
synchronized (this) {
if (this.configStorageMap.size() == 1) {
this.configStorageMap.remove(mpId);
log.warn("已删除最后一个公众号配置:{},须立即使用setWxMpConfigStorage或setMultiConfigStorages添加配置", mpId);
return;
}
if (WxMpConfigStorageHolder.get().equals(mpId)) {
this.configStorageMap.remove(mpId);
final String defaultMpId = this.configStorageMap.keySet().iterator().next();
WxMpConfigStorageHolder.set(defaultMpId);
log.warn("已删除默认公众号配置,公众号【{}】被设为默认配置", defaultMpId);
return;
}
this.configStorageMap.remove(mpId);
}
}
@Override
public WxMpService switchoverTo(String mpId) {
if (this.configStorageMap.containsKey(mpId)) {
WxMpConfigStorageHolder.set(mpId);
return this;
}
throw new WxRuntimeException(String.format("无法找到对应【%s】的公众号配置信息,请核实!", mpId));
}
@Override
public boolean switchover(String mpId) {
if (this.configStorageMap.containsKey(mpId)) {
WxMpConfigStorageHolder.set(mpId);
return true;
}
log.error("无法找到对应【{}】的公众号配置信息,请核实!", mpId);
return false;
}
@Override
public void setRetrySleepMillis(int retrySleepMillis) {
this.retrySleepMillis = retrySleepMillis;
}
@Override
public void setMaxRetryTimes(int maxRetryTimes) {
this.maxRetryTimes = maxRetryTimes;
}
@Override
public RequestHttp getRequestHttp() {
return this;
}
@Override
public WxMpGuideService getGuideService() {
return this.guideService;
}
@Override
public void setGuideService(WxMpGuideService guideService) {
this.guideService = guideService;
}
}

2
src/main/resources/application-dev.yml

@ -88,7 +88,7 @@ spring:
password: 123456 password: 123456
qisheng: qisheng:
url: jdbc:sqlserver://192.168.10.11:1433;DatabaseName=JSL_COST_QS url: jdbc:sqlserver://192.168.10.11:1433;DatabaseName=JSL_COST_QS_TEST
username: sa username: sa
password: JSL2282125 password: JSL2282125
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

2
src/main/resources/mapper/goods/GoodsImminentBatchMapper.xml

@ -43,7 +43,6 @@
and goods_spu.del_flag = 0 and goods_spu.del_flag = 0
<if test="query.filterFlag!=null and query.filterFlag == 1 "> <if test="query.filterFlag!=null and query.filterFlag == 1 ">
and goods_imminent_batch.end_date &gt;= now() and goods_imminent_batch.end_date &gt;= now()
and goods_sku.order_flag = 1
and goods_sku.`enable` = 1 and goods_sku.`enable` = 1
</if> </if>
<include refid="spuWherePart"></include> <include refid="spuWherePart"></include>
@ -84,7 +83,6 @@
</if> </if>
<if test="query.filterFlag!=null and query.filterFlag == 1 "> <if test="query.filterFlag!=null and query.filterFlag == 1 ">
and goods_imminent_batch.end_date &gt;= now() and goods_imminent_batch.end_date &gt;= now()
and goods_sku.order_flag = 1
and goods_sku.`enable` = 1 and goods_sku.`enable` = 1
</if> </if>
<include refid="spuWherePart"></include> <include refid="spuWherePart"></include>

Loading…
Cancel
Save