diff --git a/src/main/java/com/qs/serve/common/framework/security/filter/SecurityRequestFilter.java b/src/main/java/com/qs/serve/common/framework/security/filter/SecurityRequestFilter.java index 7ff0120c..de5b6326 100644 --- a/src/main/java/com/qs/serve/common/framework/security/filter/SecurityRequestFilter.java +++ b/src/main/java/com/qs/serve/common/framework/security/filter/SecurityRequestFilter.java @@ -125,8 +125,11 @@ public class SecurityRequestFilter extends OncePerRequestFilter { private void tryDoSecurityAuthor(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String tenant = request.getHeader(GySysConst.TENANT_PROP); + if(!StringUtils.hasText(tenant)){ + tenant = "001"; + } String token = request.getHeader(GySysConst.AUTHORIZATION_PROP); - if(tenant!=null&&token!=null&&JwtUtils.verify(token)){ + if(token != null && JwtUtils.verify(token)){ String userId = JwtUtils.getUserId(token); AuthContextUtils.setTenant(tenant); if(SecurityContextHolder.getContext().getAuthentication()==null){ diff --git a/src/main/java/com/qs/serve/controller/WxSvcLoginApi.java b/src/main/java/com/qs/serve/controller/WxSvcLoginApi.java index 72eb7e5b..e146a522 100644 --- a/src/main/java/com/qs/serve/controller/WxSvcLoginApi.java +++ b/src/main/java/com/qs/serve/controller/WxSvcLoginApi.java @@ -16,17 +16,23 @@ import com.qs.serve.modules.sys.entity.SysUser; import com.qs.serve.modules.sys.mapper.SysTenantMapper; import com.qs.serve.modules.sys.service.SysUserService; import com.qs.serve.modules.wx.common.conf.WxCpConfig; +import com.qs.serve.modules.wx.entity.WxApp; import com.qs.serve.modules.wx.entity.WxUser; import com.qs.serve.modules.wx.entity.dto.WxLoginUser; +import com.qs.serve.modules.wx.service.WxAppService; import com.qs.serve.modules.wx.service.WxUserService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpOAuth2Service; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.WxCpUserService; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.cp.bean.WxCpAgentJsapiSignature; import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo; import me.chanjar.weixin.cp.bean.WxCpUser; +import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; import org.jetbrains.annotations.NotNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; @@ -58,7 +64,7 @@ public class WxSvcLoginApi { private final SysUserDetailsServiceImpl userDetailsService; private final SysTenantMapper sysTenantMapper; - + private final WxAppService wxAppService; private SysUserService sysUserService; /** @@ -83,6 +89,57 @@ public class WxSvcLoginApi { return R.ok(objectMap); } + /** + * 获取签名授权 + * @param url + * @param request + * @return + */ + @GetMapping("/getCpSignature") + public R getCpSignature(String url, HttpServletRequest request) { + AuthContextUtils.setTenant("001"); + String agentIdStr = request.getHeader("agentId"); + String appId = AuthContextUtils.getAppId(); + WxApp wxApp = wxAppService.getById(appId); + Integer agentId = Integer.parseInt(agentIdStr); + // 企业微信登录 + WxCpService wxCpService = new WxCpServiceImpl(); + WxCpDefaultConfigImpl config =new WxCpDefaultConfigImpl(); + config.setAgentId(agentId); + config.setCorpSecret(WxCpConfig.getSecret(agentId)); + config.setCorpId(wxApp.getId()); + wxCpService.setWxCpConfigStorage(config); + WxCpAgentJsapiSignature signature = null; + try { + signature = wxCpService.createAgentJsapiSignature(url); + } catch (WxErrorException e) { + log.warn("企业微信签名授权失败:appid{},agentId:{},{}",appId,agentId,e.getMessage()); + } + return R.ok(signature); + } + + /** + * 企业微信登录 + * @param wxLoginUser + * @param request + * @return + */ + @SysLog(title = "企业微信登录",biz = BizType.LOGIN,inter = InterType.API) + @PostMapping("/cp4Pc") + public R loginCompanyPc(@RequestBody @Valid WxLoginUser wxLoginUser, HttpServletRequest request){ + WxUser wxUser = null; + try { + wxUser = wxUserService.login(wxLoginUser,request); + } catch (Exception e) { + Assert.throwEx(e.getMessage()); + } + if(wxUser==null){ + Assert.throwEx(HttpCode.WX_ERR); + } + Map objectMap = genTokenInfo(request, wxUser); + return R.ok(objectMap.get("adminTokenInfo")); + } + /** * 小程序登陆(暂测试) * @param wxLoginUser diff --git a/src/main/java/com/qs/serve/modules/baz/controller/BazVisitInstanceController.java b/src/main/java/com/qs/serve/modules/baz/controller/BazVisitInstanceController.java index a38ede1a..d29bc0c0 100644 --- a/src/main/java/com/qs/serve/modules/baz/controller/BazVisitInstanceController.java +++ b/src/main/java/com/qs/serve/modules/baz/controller/BazVisitInstanceController.java @@ -23,6 +23,8 @@ import com.qs.serve.modules.baz.service.BazVisitInstanceService; import javax.validation.Valid; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 拜访模块 拜访实例 @@ -66,12 +68,26 @@ public class BazVisitInstanceController { public R> getList(BazVisitInstanceSo param){ BazVisitInstance query = CopierUtil.copy(param,new BazVisitInstance()); if(param.getQueryStartDate()!=null){ - query.setQueryEndDate(param.getQueryStartDate().atStartOfDay()); + query.setQueryStartDate(param.getQueryStartDate().atStartOfDay()); } if(param.getQueryEndDate()!=null){ query.setQueryEndDate(param.getQueryEndDate().atTime(23,59,59)); } List list = bazVisitInstanceService.selectBazVisitInstanceList(query); + + if(param.getLoadFlowList()!=null&¶m.getLoadFlowList().equals(1)){ + List ids = list.stream().map(BazVisitInstance::getId).collect(Collectors.toList()); + ids.add(-1L); + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.in(BazVisitInstanceFlow::getVisitInstanceId,ids); + List allFlowList = bazVisitInstanceFlowService.list(lqw); + Map> flowListGroupByVisitInstanceId = allFlowList.stream() + .collect(Collectors.groupingBy(BazVisitInstanceFlow::getVisitInstanceId)); + for (BazVisitInstance instance : list) { + List fl = flowListGroupByVisitInstanceId.get(instance.getId()); + instance.setFlowList(fl); + } + } return R.ok(list); } diff --git a/src/main/java/com/qs/serve/modules/baz/entity/so/BazVisitInstanceSo.java b/src/main/java/com/qs/serve/modules/baz/entity/so/BazVisitInstanceSo.java index 893f86d1..a9cf2208 100644 --- a/src/main/java/com/qs/serve/modules/baz/entity/so/BazVisitInstanceSo.java +++ b/src/main/java/com/qs/serve/modules/baz/entity/so/BazVisitInstanceSo.java @@ -70,5 +70,10 @@ public class BazVisitInstanceSo implements Serializable { @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private LocalDate queryEndDate; + /** + * 加载流程 0/1 + */ + private Integer loadFlowList; + } diff --git a/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java b/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java index 46f5988a..82dad4d8 100644 --- a/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java @@ -137,6 +137,12 @@ public class BirActivityCenterGoodsServiceImpl extends ServiceImpl> collectMap = activityCenterGoodsAllList.stream() .collect(Collectors.groupingBy(TbsActivityCenterGoods::getActivityId)); + //移除错误的历史记录 + LambdaQueryWrapper rmErrorActId = new LambdaQueryWrapper<>(); + rmErrorActId.notIn(BirActivityCenterGoods::getActivityId,collectMap.keySet()); + rmErrorActId.in(BirActivityCenterGoods::getCostApplyId,costApplyIds); + this.remove(rmErrorActId); + LambdaQueryWrapper supplierLqw = new LambdaQueryWrapper<>(); supplierLqw.in(BmsSupplier::getCode,activityCenterGoodsAllList.stream().map(TbsActivityCenterGoods::getSupplierCode).distinct().collect(Collectors.toList())); List bmsSupplierList = bmsSupplierMapper.selectList(supplierLqw); diff --git a/src/main/java/com/qs/serve/modules/biz/controller/BizVisitFormController.java b/src/main/java/com/qs/serve/modules/biz/controller/BizVisitFormController.java index c57ad2f8..b8c565c7 100644 --- a/src/main/java/com/qs/serve/modules/biz/controller/BizVisitFormController.java +++ b/src/main/java/com/qs/serve/modules/biz/controller/BizVisitFormController.java @@ -84,8 +84,8 @@ public class BizVisitFormController { //@PreAuthorize("hasRole('biz:visitForm:update')") public R updateById(@RequestBody @Valid BizVisitForm param){ BizVisitForm entity = CopierUtil.copy(param,new BizVisitForm()); - boolean result = bizVisitFormService.updateById(entity); - return R.isTrue(result); + bizVisitFormService.updateById(entity); + return R.ok(entity); } /** @@ -98,8 +98,8 @@ public class BizVisitFormController { //@PreAuthorize("hasRole('biz:visitForm:insert')") public R save(@RequestBody @Valid BizVisitForm param){ BizVisitForm entity = CopierUtil.copy(param,new BizVisitForm()); - boolean result = bizVisitFormService.save(entity); - return R.isTrue(result); + bizVisitFormService.save(entity); + return R.ok(entity); } /** diff --git a/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierController.java b/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierController.java index 31253baa..061f2cba 100644 --- a/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierController.java +++ b/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierController.java @@ -26,6 +26,7 @@ import com.qs.serve.modules.bms.mapper.BmsSupplierMapper; import com.qs.serve.modules.bms.service.*; import com.qs.serve.modules.his.entity.HisUserSupplier; import com.qs.serve.modules.his.service.HisUserSupplierService; +import com.qs.serve.modules.his.service.impl.HisUserSupplierServiceImpl; import com.qs.serve.modules.sys.entity.SysPostUser; import com.qs.serve.modules.sys.entity.SysUser; import com.qs.serve.modules.sys.entity.bo.SysRelateSuppliersParam; @@ -78,10 +79,21 @@ public class BmsSupplierController { private BmsSupplierMyController supplierMyController; private SysAttachService attachService; private BirBudgetTargetService birBudgetTargetService; - + private HisUserSupplierServiceImpl hisUserSupplierServiceImpl; private BmsSupplierMapper supplierMapper; + /** + * 临时方法,用于紧急修复用户直属负责的客户 + * @param userId + * @return + */ + @GetMapping("/initUserSupplier") + public R initUserSupplier(String userId){ + hisUserSupplierServiceImpl.rebuildOnlyOneUserSuppliers(userId); + return R.ok(); + } + @GetMapping("/queryList") public R> getQueryList(BmsSupplier param){ PageUtil.startPage(); @@ -132,7 +144,6 @@ public class BmsSupplierController { @PostMapping("/page") @PreAuthorize("hasRole('bms:supplier:query')") public R> getPage(@RequestBody BmsSupplier param){ - if(param.getLoadByCurrent()!=null && param.getLoadByCurrent().equals(2)){ BirBudgetTargetSo query = new BirBudgetTargetSo(); query.setLoadType(param.getType()); diff --git a/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierVisitAddressController.java b/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierVisitAddressController.java index 7b8b4f2a..b689a257 100644 --- a/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierVisitAddressController.java +++ b/src/main/java/com/qs/serve/modules/bms/controller/BmsSupplierVisitAddressController.java @@ -59,7 +59,6 @@ public class BmsSupplierVisitAddressController { private BazVisitFlowService bazVisitFlowService; private SysPostUserService sysPostUserService; - /** * 翻页查询,过滤当前用户负责数据 * @param param diff --git a/src/main/java/com/qs/serve/modules/bms/service/impl/BmsSupplierServiceImpl.java b/src/main/java/com/qs/serve/modules/bms/service/impl/BmsSupplierServiceImpl.java index 67636917..638f6dcb 100644 --- a/src/main/java/com/qs/serve/modules/bms/service/impl/BmsSupplierServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/bms/service/impl/BmsSupplierServiceImpl.java @@ -255,19 +255,21 @@ public class BmsSupplierServiceImpl extends ServiceImpl syncCusInvPrice(String cusCode){ - goodsCustomerPriceService.syncCustomerPrice(cusCode); + String[] cusCodes = new String[]{ + "12201136","11301012","11302001","11301049","13004001","11702036","11308005","13001023","11310014","11308002","11612024","11305012","12201124","11301040","12301063","13001029","11312001","11902042","12801062","11301013","11301044","10806002","11308003","13001035","11310028","19701066","11310010","11303001","13007001","11301057","11301011","11308006","10806003","11301021","11301054","11310013","11301050","12421050","11612021","10808024","12205028","13001032","11304012","11310037","12201126","11301059","19701067","11307007","13001028","13001024","11307002","11603062","13001027","12205010","12409006","11301041","11612022","11301051","11316001","11310012","11501215","11711117","13001033","12201128","11307008","11314006","11307001","11601075","11310036","11307003","11315003","11301004","11401172","11301042","11607009","11307004","13001026","11310040","11310016","11301048","12403127","11310030","13005001","11310035","11301052","13004003","11306001","13008002","12013047","11301008","11704028","10808019","11304010","11301047","13001025","11312003","11310033","13001034","11301010","11313001","11301043","11314004","11704026","11301053","11310001","13004002","11310018","11310031","11311003","11313003","11601072","12201125","11501213","11301003","11301055","13008001","12309078","11301002","13001030","12701006","11301045","11301058" + }; + for (String code : cusCodes) { + goodsCustomerPriceService.syncCustomerPrice(code); + } + return R.ok(); } diff --git a/src/main/java/com/qs/serve/modules/goods/entity/GoodsCategory.java b/src/main/java/com/qs/serve/modules/goods/entity/GoodsCategory.java index a840359d..d69e8151 100644 --- a/src/main/java/com/qs/serve/modules/goods/entity/GoodsCategory.java +++ b/src/main/java/com/qs/serve/modules/goods/entity/GoodsCategory.java @@ -33,6 +33,7 @@ public class GoodsCategory implements Serializable { private Integer enable; @NotBlank(message = "编码不能为空") + @TableField(condition = SqlCondition.LIKE) private String code; /** 父分类编号 */ @@ -40,6 +41,7 @@ public class GoodsCategory implements Serializable { /** 名称 */ @Length(max = 64,message = "名称长度不能超过16字") + @TableField(condition = SqlCondition.LIKE) private String name; /** 排序 */ diff --git a/src/main/java/com/qs/serve/modules/goods/service/impl/GoodsCustomerPriceServiceImpl.java b/src/main/java/com/qs/serve/modules/goods/service/impl/GoodsCustomerPriceServiceImpl.java index 188dec22..3f52a337 100644 --- a/src/main/java/com/qs/serve/modules/goods/service/impl/GoodsCustomerPriceServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/goods/service/impl/GoodsCustomerPriceServiceImpl.java @@ -177,10 +177,13 @@ public class GoodsCustomerPriceServiceImpl extends ServiceImpl cusPriceList = cusPriceMap.get(cusCode); List skuCodes = cusPriceList.stream().map(InventoryCusPrice::getInvCode).collect(Collectors.toList()); - try { - flushSupplierSkuPrices(cusCode, skuCodes); - } catch (Exception e) { - log.error("客户价格同步失败:{},skus:{}",cusCode,JsonUtil.objectToJson(skuCodes)); + List> skuCodesAsList = CollUtil.split(skuCodes,500); + for (List list : skuCodesAsList) { + try { + flushSupplierSkuPrices(cusCode, list); + } catch (Exception e) { + log.error("客户价格同步失败:{},skus:{}",cusCode,JsonUtil.objectToJson(list)); + } } } diff --git a/src/main/java/com/qs/serve/modules/his/service/impl/HisUserSupplierServiceImpl.java b/src/main/java/com/qs/serve/modules/his/service/impl/HisUserSupplierServiceImpl.java index 8ee43e9e..99d381e5 100644 --- a/src/main/java/com/qs/serve/modules/his/service/impl/HisUserSupplierServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/his/service/impl/HisUserSupplierServiceImpl.java @@ -151,6 +151,10 @@ public class HisUserSupplierServiceImpl extends ServiceImpl list = bmsSupplierService.selectSupplierList(param); @@ -160,7 +164,7 @@ public class HisUserSupplierServiceImpl extends ServiceImpl regionUserLqw = new LambdaQueryWrapper<>(); - regionUserLqw.eq(BmsRegionUser::getUserId,userId); + regionUserLqw.eq(BmsRegionUser::getUserId, userId); List regionUsers = regionUserService.list(regionUserLqw); List regionSaleIds = regionUsers.stream() .filter(a->a.getType().equals(0)) @@ -172,7 +176,7 @@ public class HisUserSupplierServiceImpl extends ServiceImpl saleRegionListByLevel = saleRegionsMap.get(level); List regionIds = saleRegionListByLevel.stream().map(BmsRegion::getId).collect(Collectors.toList()); - toHisUserSupplier(userSuppliers,0,regionIds,level,userId); + toHisUserSupplier(userSuppliers,0,regionIds,level, userId); } } List regionBizIds = regionUsers.stream() @@ -185,7 +189,7 @@ public class HisUserSupplierServiceImpl extends ServiceImpl region2List = saleRegionsMap.get(level); List region2Ids = region2List.stream().map(BmsRegion2::getId).collect(Collectors.toList()); - toHisUserSupplier(userSuppliers,1,region2Ids,level,userId); + toHisUserSupplier(userSuppliers,1,region2Ids,level, userId); } } if(userSuppliers.size()>0){ diff --git a/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java b/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java index 078679ab..e11dc961 100644 --- a/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java +++ b/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java @@ -12,12 +12,14 @@ 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.oms.common.OmsOrderCheckState; import com.qs.serve.modules.oms.entity.OmsOrderItem; import com.qs.serve.modules.oms.entity.bo.OmsCheckParam; import com.qs.serve.modules.oms.entity.bo.OmsSpuAssesInfoBo; import com.qs.serve.modules.oms.entity.bo.OmsUrgentParam; import com.qs.serve.modules.oms.entity.vo.OmsSpuAssesInfo; import com.qs.serve.modules.oms.service.OmsOrderItemService; +import com.qs.serve.modules.oms.service.OmsOrderOptionsService; import com.qs.serve.modules.sys.entity.SysUser; import com.qs.serve.modules.sys.service.SysUserService; import lombok.AllArgsConstructor; @@ -48,6 +50,7 @@ public class OmsOrderController { private OmsOrderService omsOrderService; private BmsSupplierAddressService bmsSupplierAddressService; + private OmsOrderOptionsService omsOrderOptionsService; private SysUserService sysUserService; private OmsOrderItemService omsOrderItemService; private BmsSupplierMapper bmsSupplierMapper; @@ -118,6 +121,9 @@ public class OmsOrderController { @SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.QUERY) public R getById(@PathVariable("id") String id){ OmsOrder omsOrder = omsOrderService.getById(id); + if(omsOrder.getOrderType().equals(3)&&omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Commiting.getCode())){ + omsOrderOptionsService.runCompensate(omsOrder.getId()+""); + } BmsSupplier supplier = bmsSupplierMapper.selectById(omsOrder.getSupplierId()); omsOrder.setSupplierInfo(supplier); return R.ok(omsOrder); diff --git a/src/main/java/com/qs/serve/modules/oms/controller/api/OmsOrderApi.java b/src/main/java/com/qs/serve/modules/oms/controller/api/OmsOrderApi.java index 033c16fd..b2bdbd8a 100644 --- a/src/main/java/com/qs/serve/modules/oms/controller/api/OmsOrderApi.java +++ b/src/main/java/com/qs/serve/modules/oms/controller/api/OmsOrderApi.java @@ -28,6 +28,7 @@ import com.qs.serve.modules.oms.entity.OmsOrderItem; import com.qs.serve.modules.oms.entity.bo.*; import com.qs.serve.modules.oms.entity.vo.OmsConfirmOrderResult; import com.qs.serve.modules.oms.service.OmsOrderItemService; +import com.qs.serve.modules.oms.service.OmsOrderOptionsService; import com.qs.serve.modules.oms.service.OmsOrderPart1Service; import com.qs.serve.modules.oms.service.OmsOrderService; import com.qs.serve.modules.seeyon.service.impl.SeeYonRequestBaseService; @@ -69,6 +70,7 @@ public class OmsOrderApi { private SeeYonRequestBaseService seeYonRequestBaseService; private GoodsImminentBatchMapper goodsImminentBatchMapper; private OmsOrderPart1Service omsOrderPart1Service; + private OmsOrderOptionsService omsOrderOptionsService; /** * 查询客户特殊加 @@ -310,6 +312,10 @@ public class OmsOrderApi { public R getById(@PathVariable("id") String id){ BmsSupplier supplier = AuthContextUtils.getCurrentSupplier(); OmsOrder omsOrder = omsOrderService.getById(id); + if(omsOrder.getOrderType().equals(3)&&omsOrder.getOrderCheckState().equals(OmsOrderCheckState.Commiting.getCode())){ + omsOrderOptionsService.runCompensate(omsOrder.getId()+""); + omsOrder = omsOrderService.getById(id); + } omsOrder.setBrandRuleInfo(goodsCategoryRuleService.getById(omsOrder.getBrandRuleId())); omsOrder.setAddressInfo(bmsSupplierAddressService.getById(omsOrder.getSupplierAddrId())); omsOrder.setSupplierInfo(bmsSupplierMapper.selectById(omsOrder.getSupplierId())); diff --git a/src/main/java/com/qs/serve/modules/oms/entity/OmsXltOrder.java b/src/main/java/com/qs/serve/modules/oms/entity/OmsXltOrder.java index 3756df0b..5fdcad64 100644 --- a/src/main/java/com/qs/serve/modules/oms/entity/OmsXltOrder.java +++ b/src/main/java/com/qs/serve/modules/oms/entity/OmsXltOrder.java @@ -30,6 +30,12 @@ public class OmsXltOrder implements Serializable { @TableId(type = IdType.ASSIGN_UUID) private String id; + /** + * 0->普通订单;1->赠品;2->试吃品;3->临期品 + */ + @TableField("orderType") + private Integer orderType; + /** 订单号 */ @NotBlank(message = "订单号不能为空") @Length(max = 100,message = "订单号长度不能超过100字") diff --git a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java index dee9728a..74ecb116 100644 --- a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java @@ -34,6 +34,7 @@ import com.qs.serve.modules.oms.service.OmsOrderService; import com.qs.serve.modules.oms.utils.OmsOrderUtil; import com.qs.serve.modules.seeyon.entity.BaseCreateCallbackBo; import com.qs.serve.modules.seeyon.service.SeeYonRequestService; +import com.qs.serve.modules.seeyon.service.impl.SeeYonRequestBaseService; import com.qs.serve.modules.sys.entity.SysUser; import com.qs.serve.modules.sys.service.SysUserService; import com.qs.serve.modules.tag.mapper.TagInfoMapper; @@ -82,6 +83,7 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService { private final GoodsSpuMapper goodsSpuMapper; private final GoodsCategoryMapper goodsCategoryMapper; private final SeeYonRequestService seeYonService; + private final SeeYonRequestBaseService seeYonRequestBaseService; @Override @Transactional(rollbackFor = Exception.class) @@ -252,7 +254,9 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService { List omsOrders = omsOrderService.list(new LambdaQueryWrapper() //临期品 .eq(OmsOrder::getOrderType,3) - .in(OmsOrder::getStatus,0,1) + //未下单 + .in(OmsOrder::getStatus,0) + //审批完成 .eq(OmsOrder::getOrderCheckState,OmsOrderCheckState.Finished.getCode()) ); log.warn("临期品同步到ERP,数量:{}",omsOrders.size()); @@ -267,7 +271,24 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService { List cateIds = goodsSpuList.stream().map(GoodsSpu::getCategoryLast).collect(Collectors.toList()); List categoryList = goodsCategoryMapper.selectBatchIds(cateIds); String bs = categoryList.stream().map(GoodsCategory::getName).collect(Collectors.joining(",")); - //写入到ERP中间表 + // 读取OA最新订单折扣 + R codeRs = seeYonRequestBaseService.getBase( + TbsSeeYonConst.OA_DATA_EXPIRE_ORDER_DR + omsOrder.getOrderSn() + ,"获取条款申请流水号"); + BigDecimal dr = null; + if(codeRs.getData()!=null){ + try { + dr = new BigDecimal(codeRs.getData().toString()); + omsOrder.setDiscountRate(dr); + } catch (Exception e) { + e.printStackTrace(); + } + } + if(dr==null){ + log.error("临期品订单,获取最新的折扣率失败,单号:{}",omsOrder.getOrderSn()); + continue; + } + // 写入到ERP中间表 omsOrderService.saveToErpOrder(omsOrder,orderItemList,bs,supplierAddress,bmsRegion); } } @@ -314,13 +335,15 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService { data.put("cdNumber", omsOrder.getCdOrderRemark()); data.put("remark", omsOrder.getRemark()); data.put("mainRemark", omsOrder.getRemark()); - // 折扣率 + // 折扣率(审批时修改) data.put("ext1", omsOrder.getDiscountRate()); - // 折扣最终金额 + // 申请时的总金额(审批时该金额不更新,非最终的合计金额) data.put("ext2", totalOrderAmt.multiply(omsOrder.getDiscountRate()) .divide(new BigDecimal("100"),2, RoundingMode.DOWN) ); + // 申请时的折扣率 + data.put("ext3",omsOrder.getDiscountRate()); return data; } diff --git a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java index 1f316936..33e0e74e 100644 --- a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderServiceImpl.java @@ -992,6 +992,7 @@ public class OmsOrderServiceImpl extends ServiceImpl i 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()); diff --git a/src/main/java/com/qs/serve/modules/tbs/common/TbsSeeYonConst.java b/src/main/java/com/qs/serve/modules/tbs/common/TbsSeeYonConst.java index 6286fced..e2623a92 100644 --- a/src/main/java/com/qs/serve/modules/tbs/common/TbsSeeYonConst.java +++ b/src/main/java/com/qs/serve/modules/tbs/common/TbsSeeYonConst.java @@ -107,6 +107,8 @@ public interface TbsSeeYonConst { String OA_USER_INFO = "/process/getUserByCode"; String OA_USER_LIST_1 = "/process/getUsersList"; + String OA_DATA_EXPIRE_ORDER_DR = "/process/data/expiredOrderDiscountRate/"; + /** 获取流水号 */ String API_FLOW_CODE_TODO = "/process/getTodoFlowCode?todoId="; diff --git a/src/main/java/com/qs/serve/modules/wx/service/impl/WxUserServiceImpl.java b/src/main/java/com/qs/serve/modules/wx/service/impl/WxUserServiceImpl.java index c08868aa..d417f869 100644 --- a/src/main/java/com/qs/serve/modules/wx/service/impl/WxUserServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/wx/service/impl/WxUserServiceImpl.java @@ -182,9 +182,11 @@ public class WxUserServiceImpl extends ServiceImpl impleme config.setCorpSecret(WxCpConfig.getSecret(agentId)); config.setCorpId(wxApp.getId()); wxCpService.setWxCpConfigStorage(config); + // 授权方式登录 WxCpOAuth2Service oauth2Service = wxCpService.getOauth2Service(); WxCpOauth2UserInfo cpOauth2UserInfo = null; + // 获取敏感信息 WxCpUserDetail wxCpUserDetail = null; WxCpUser wxCpUser = null; diff --git a/src/main/java/com/qs/serve/task/OmsTask.java b/src/main/java/com/qs/serve/task/OmsTask.java new file mode 100644 index 00000000..76172c6e --- /dev/null +++ b/src/main/java/com/qs/serve/task/OmsTask.java @@ -0,0 +1,31 @@ +package com.qs.serve.task; + +import com.qs.serve.modules.oms.service.OmsOrderOptionsService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * @author YenHex + * @since 2024/9/26 + */ +@Slf4j +@Component +@AllArgsConstructor +@ConditionalOnProperty(value = "project.task", havingValue = "true") +public class OmsTask { + + OmsOrderOptionsService omsOrderOptionsService; + + /** + * 同步临期品到调度系统的订单中间表 + * 每10分钟执行一次 + */ + @Scheduled(cron="0 0/10 * * * ?") + public void saveToErpOrder(){ + omsOrderOptionsService.syncToErp(); + } + +} diff --git a/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java new file mode 100644 index 00000000..e61614af --- /dev/null +++ b/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -0,0 +1,576 @@ +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 implements WxMpService, RequestHttp { + 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 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 execute(RequestExecutor executor, WxMpApiUrl url, E data) throws WxErrorException { + return this.execute(executor, url.getUrl(this.getWxMpConfigStorage()), data); + } + + /** + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求. + */ + @Override + public T execute(RequestExecutor 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 executeInternal(RequestExecutor 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 configStorages) { + this.setMultiConfigStorages(configStorages, configStorages.keySet().iterator().next()); + } + + @Override + public void setMultiConfigStorages(Map 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; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 18d6ec1e..0dd7005e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -23,6 +23,7 @@ project: - /portal/syKeyLogin - /bir/roiRate/test - /static/* + - /api/wx/login/getCpSignature - /web/* permits: #忽略登录 - /thirty/** #第三方接口 diff --git a/src/main/resources/mapper/bms/BmsSupplierMapper.xml b/src/main/resources/mapper/bms/BmsSupplierMapper.xml index 74039803..bf85a048 100644 --- a/src/main/resources/mapper/bms/BmsSupplierMapper.xml +++ b/src/main/resources/mapper/bms/BmsSupplierMapper.xml @@ -56,6 +56,9 @@ bms_supplier.`name`, bms_supplier.`code`, bms_supplier.`pid`, + bms_supplier.`open_time`, + bms_supplier.`stop_flag_date`, + bms_supplier.`cooperate_pause_flag_date`, bms_supplier.`parent_code`, bms_supplier.`user_id`, bms_supplier.`user_code`,