17 changed files with 712 additions and 673 deletions
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -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); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -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()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -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; |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue