diff --git a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java index ae5031ad3..8723ad7cb 100644 --- a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java +++ b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java @@ -148,6 +148,10 @@ public class ShiroConfig { // filterChainDefinitionMap.put("/role/**", "corsFilter,token"); //商场初始化init // filterChainDefinitionMap.put("/wxProjectConfig/**", "anon"); +// filterChainDefinitionMap.put("/goodsCategory/**", "anon"); + + +// filterChainDefinitionMap.put("/wxCoupon/goods/**", "anon"); // //test // filterChainDefinitionMap.put("/merchantPoi/spuSync", "anon"); diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtGoodsCategoryController.java b/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtGoodsCategoryController.java new file mode 100644 index 000000000..d2d73ce16 --- /dev/null +++ b/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtGoodsCategoryController.java @@ -0,0 +1,38 @@ +package com.iformall.controller.basic; + + +import com.iformall.annotation.SystemControllerLog; +import com.iformall.annotation.TenantIgnore; +import com.iformall.common.ResultData; +import com.iformall.controller.base.BaseController; +import com.iformall.service.TtGoodsCategoryService; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + + +/** + * @author gongbiao + */ +@RestController +@RequestMapping("goodsCategory") +public class TtGoodsCategoryController extends BaseController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private TtGoodsCategoryService ttGoodsCategoryService; + + @TenantIgnore + @ApiOperation("分页列表接口") + @GetMapping("treeList") + @ApiImplicitParams({}) + @SystemControllerLog(description = "列表") + public ResultData treeList() { + logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::treeList"); + return new ResultData(ttGoodsCategoryService.findTreeList()); + } + +} diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtMerchantPoiController.java b/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtMerchantPoiController.java index b87223f2b..a36b9334c 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtMerchantPoiController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/basic/TtMerchantPoiController.java @@ -137,80 +137,80 @@ public class TtMerchantPoiController extends BaseController { return ttMerchantPoiService.supplierQuery(getTenantInfo(),id); } - @ApiOperation("获取商品可用的POI") - @GetMapping("/findPoi") - @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) - @SystemControllerLog(description = "查询") - public ResultData findPoi(Long couponChannelId) { - logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::findPoi"); - if(couponChannelId == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); - } - return ttMerchantPoiService.findPoi(getTenantInfo(),couponChannelId); - } - - @ApiOperation("商品同步") - @PostMapping("spuSync") - @SystemControllerLog(description = "商品同步") - public ResultData spuSync(@RequestBody Map param) { - logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuSync"); - String couponChannelIdStr = param.get("couponChannelId"); - Long couponChannelId = null; - try{ - couponChannelId = Long.parseLong(couponChannelIdStr); - }catch(Exception e){ - return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR); - } - if(couponChannelId == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); - } -// String merchantIdStr = param.get("merchantIds"); -// List merchantIds = new ArrayList<>(); +// @ApiOperation("获取商品可用的POI") +// @GetMapping("/findPoi") +// @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) +// @SystemControllerLog(description = "查询") +// public ResultData findPoi(Long couponChannelId) { +// logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::findPoi"); +// if(couponChannelId == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); +// } +// return ttMerchantPoiService.findPoi(getTenantInfo(),couponChannelId); +// } + +// @ApiOperation("商品同步") +// @PostMapping("spuSync") +// @SystemControllerLog(description = "商品同步") +// public ResultData spuSync(@RequestBody Map param) { +// logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuSync"); +// String couponChannelIdStr = param.get("couponChannelId"); +// Long couponChannelId = null; // try{ -// List strings = Arrays.asList(merchantIdStr.split(",")); -// merchantIds = strings.stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()); +// couponChannelId = Long.parseLong(couponChannelIdStr); // }catch(Exception e){ // return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR); // } -// if(merchantIds == null || merchantIds.size() == 0){ +// if(couponChannelId == null){ // return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); // } - return ttMerchantPoiService.spuSync(getTenantInfo(),couponChannelId,null); - } - - @ApiOperation("商品同步查询") - @GetMapping("spuGet") - @SystemControllerLog(description = "商品同步查询") - public ResultData spuGet(Long couponChannelId) { - logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuGet"); - if(couponChannelId == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); - } - return ttMerchantPoiService.spuGet(getTenantInfo(),couponChannelId); - } - - @ApiOperation("商品状态同步") - @PostMapping("spuStatusSync") - @SystemControllerLog(description = "商品状态同步") - public ResultData spuStatusSync(@RequestBody Map param) { - logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuStatusSync"); - Long couponChannelId = param.get("couponChannelId"); - if(couponChannelId == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); - } - return ttMerchantPoiService.spuStatusSync(getTenantInfo(),couponChannelId); - } - - @ApiOperation("商品库存同步") - @PostMapping("spuStockSync") - @SystemControllerLog(description = "商品库存同步") - public ResultData spuStockSync(@RequestBody Map param) { - logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuStockSync"); - Long couponChannelId = param.get("couponChannelId"); - if(couponChannelId == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); - } - return ttMerchantPoiService.spuStockSync(getTenantInfo(),couponChannelId); - } +//// String merchantIdStr = param.get("merchantIds"); +//// List merchantIds = new ArrayList<>(); +//// try{ +//// List strings = Arrays.asList(merchantIdStr.split(",")); +//// merchantIds = strings.stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()); +//// }catch(Exception e){ +//// return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR); +//// } +//// if(merchantIds == null || merchantIds.size() == 0){ +//// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); +//// } +// return ttMerchantPoiService.spuSync(getTenantInfo(),couponChannelId,null); +// } + +// @ApiOperation("商品同步查询") +// @GetMapping("spuGet") +// @SystemControllerLog(description = "商品同步查询") +// public ResultData spuGet(Long couponChannelId) { +// logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuGet"); +// if(couponChannelId == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); +// } +// return ttMerchantPoiService.spuGet(getTenantInfo(),couponChannelId); +// } +// +// @ApiOperation("商品状态同步") +// @PostMapping("spuStatusSync") +// @SystemControllerLog(description = "商品状态同步") +// public ResultData spuStatusSync(@RequestBody Map param) { +// logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuStatusSync"); +// Long couponChannelId = param.get("couponChannelId"); +// if(couponChannelId == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); +// } +// return ttMerchantPoiService.spuStatusSync(getTenantInfo(),couponChannelId); +// } +// +// @ApiOperation("商品库存同步") +// @PostMapping("spuStockSync") +// @SystemControllerLog(description = "商品库存同步") +// public ResultData spuStockSync(@RequestBody Map param) { +// logger.debug("[" + getIpAddr() + "] TtMerchantPoiController::spuStockSync"); +// Long couponChannelId = param.get("couponChannelId"); +// if(couponChannelId == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); +// } +// return ttMerchantPoiService.spuStockSync(getTenantInfo(),couponChannelId); +// } } diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/basic/WxProjectConfigController.java b/mallinkAdmin/src/main/java/com/iformall/controller/basic/WxProjectConfigController.java index e66bf133d..02ef82d4a 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/basic/WxProjectConfigController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/basic/WxProjectConfigController.java @@ -10,10 +10,13 @@ import com.iformall.controller.base.BaseController; import com.iformall.domain.po.*; import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.vo.WxWeappInfo; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.payv2.request.CallBackSettingsRequest; import com.iformall.enums.*; import com.iformall.service.*; import com.iformall.shiro.PasswordHelper; import com.iformall.utils.Constant; +import com.iformall.utils.MaUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; @@ -94,6 +97,9 @@ public class WxProjectConfigController extends BaseController { @Autowired private WechatWebProperties wechatWebProperties; + @Autowired + private MaUtil maUtil; + @Autowired @Qualifier("openRedisTemplate") RedisTemplate openRedisTemplate; @@ -774,4 +780,74 @@ public class WxProjectConfigController extends BaseController { } } + @ApiOperation("获取抖音支付2.0 回调接口配置") + @GetMapping("/ttcallback/query/settings") + @SystemControllerLog(description = "") + @TenantIgnore + public ResultData ttcallbackQuerySettings(String appid) { + logger.debug("[" + getIpAddr() + "] WxProjectConfigController::ttcallbackQuerySettings"); + try { + WxAppinfo appinfo = wxAppinfoService.getByAppId(appid); + if(appinfo == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到对应的小程序"); + } + if(!EnumAppPlat.TOUTIAO.getCode().equals(appinfo.getPlat()) || !EnumAppType.C.getCode().equals(appinfo.getType())){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"该小程序不支持"); + } + WxPayAccount payAccount = wxPayAccountService.getById(appinfo.getPayId()); + if(payAccount == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到对应的支付数据"); + } + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + CallBackSettingsRequest callBackSettingsRequest = ttPayService.querySettings(); + return new ResultData(callBackSettingsRequest); + }catch (Exception e){ + logger.error(e.getMessage(),e); + return new ResultData(ErrorCode.SYS_SERVER_ERROR); + } + } + + @ApiOperation("配置抖音支付2.0 回调接口") + @PostMapping("/ttcallback/settings") + @SystemControllerLog(description = "商场集团-更新") + @TenantIgnore + public ResultData ttcallbackSettings(@RequestBody Map map) { + logger.debug("[" + getIpAddr() + "] WxProjectConfigController::ttcallbackSettings"); + String appid = map.get("appid"); + String create_order_callback = map.get("create_order_callback"); + String refund_callback = map.get("refund_callback"); + String delivery_qrcode_redirect = map.get("delivery_qrcode_redirect"); + if(StringUtils.isBlank(appid) || StringUtils.isBlank(create_order_callback) + || StringUtils.isBlank(refund_callback)){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + try { + WxAppinfo appinfo = wxAppinfoService.getByAppId(appid); + if(appinfo == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到对应的小程序"); + } + if(!EnumAppPlat.TOUTIAO.getCode().equals(appinfo.getPlat()) || !EnumAppType.C.getCode().equals(appinfo.getType())){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"该小程序不支持"); + } + WxPayAccount payAccount = wxPayAccountService.getById(appinfo.getPayId()); + if(payAccount == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到对应的支付数据"); + } + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + CallBackSettingsRequest request = new CallBackSettingsRequest(); + request.setCreateOrderCallback(create_order_callback); + request.setRefundCallback(refund_callback); + request.setDeliveryQrcodeRedirect(delivery_qrcode_redirect); + boolean b = ttPayService.callbackSettings(request); + if(b){ + return new ResultData(); + }else{ + return new ResultData(ErrorCode.SYS_SERVER_ERROR); + } + }catch (Exception e){ + logger.error(e.getMessage(),e); + return new ResultData(ErrorCode.SYS_SERVER_ERROR); + } + } + } diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/TtCouponGoodsController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/TtCouponGoodsController.java new file mode 100644 index 000000000..74fefdbb1 --- /dev/null +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/TtCouponGoodsController.java @@ -0,0 +1,184 @@ +package com.iformall.controller.market; + +import com.iformall.annotation.SystemControllerLog; +import com.iformall.common.ErrorCode; +import com.iformall.common.ResultData; +import com.iformall.controller.base.BaseController; +import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.base.BaseEntity; +import com.iformall.domain.vo.TtCouponChannelVo; +import com.iformall.domain.vo.TtCouponVo; +import com.iformall.douyin.web.bean.GoodsTemplateGet; +import com.iformall.enums.*; +import com.iformall.service.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import me.chanjar.weixin.common.error.WxErrorException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + + +@RestController +@RequestMapping("ttgoods") +@Api(description = "抖音商品库") +public class TtCouponGoodsController extends BaseController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private WxCouponService wxCouponService; + + @Autowired + private TtCouponGoodsService ttCouponGoodsService; + + @Autowired + private TtMerchantPoiService ttMerchantPoiService; + + @Autowired + private TtGoodsCategoryService ttGoodsCategoryService; + + @ApiOperation("分页列表接口") + @GetMapping("couponList") + @ApiImplicitParams({ + @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), + @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) + @SystemControllerLog(description = "-列表") + public ResultData couponList(@ModelAttribute TtCouponVo ttCouponVo, Integer pageNum, Integer pageSize) { + logger.debug("[" + getIpAddr() + "] WxCouponController::couponList"); + if (ttCouponVo == null) ttCouponVo = new TtCouponVo(); + ttCouponVo.updateTenantInfo(getTenantInfo()); + ttCouponVo.setType(EnumCouponType.COUPON_DOUYIN.getCode()); + if(StringUtils.isNotBlank(ttCouponVo.getSortColumn())){ + String coryColumn = "c."+ttCouponVo.getSortColumns(); + ttCouponVo.setSortColumns(coryColumn); + ttCouponVo.setSortColumn(null); + }else{ + ttCouponVo.setSortColumns(BaseEntity.SortField.CCreateDate_DESC, BaseEntity.SortField.CId_DESC); + } + if (ttCouponVo.getStatus() != null && ttCouponVo.getStatus() == -1) + ttCouponVo.setStatus(null); + return ttCouponGoodsService.couponList(ttCouponVo, pageNum, pageSize); + } + + @ApiOperation("分页列表接口") + @GetMapping("channelList") + @ApiImplicitParams({ + @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), + @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) + @SystemControllerLog(description = "-列表") + public ResultData channelList(@ModelAttribute TtCouponChannelVo ttChannelVo, Integer pageNum, Integer pageSize) { + logger.debug("[" + getIpAddr() + "] WxCouponController::channelList"); + if (ttChannelVo == null) ttChannelVo = new TtCouponChannelVo(); + ttChannelVo.updateTenantInfo(getTenantInfo()); + ttChannelVo.setTargetAd(EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode()); + if(null == ttChannelVo.getSourceType()){ + ttChannelVo.setSourceType(EnumCouponSourceType.COUPONSource_Admin.getCode()); + } + + if(StringUtils.isNotBlank(ttChannelVo.getSortColumn())){ + String coryColumn = "cc."+ttChannelVo.getSortColumns(); + ttChannelVo.setSortColumns(coryColumn); + ttChannelVo.setSortColumn(null); + }else{ + ttChannelVo.setSortColumns(BaseEntity.SortField.CCUpdateDate_DESC); + } + + return ttCouponGoodsService.channelList(ttChannelVo, pageNum, pageSize); + } + + @ApiOperation("根据类目获取商品模板") + @GetMapping("getTemplate") + @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) + @SystemControllerLog(description = "根据类目获取商品模板") + public ResultData getGoodsTemplate(Long couponId,Integer categoryId,Integer productType) { + logger.debug("[" + getIpAddr() + "] WxCouponController::getGoodsTemplate"); + if(productType == null){ + productType = 1; + } + if(couponId == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + WxCoupon coupon = wxCouponService.getAttrsById(couponId, getTenantInfo().getTenantId()); + if(coupon == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + + try { + GoodsTemplateGet goodsTemplateGet = ttMerchantPoiService.getTtWebService(getTenantInfo()).getGoodsService().templateGet(categoryId, productType); + ttGoodsCategoryService.adminIsShow(goodsTemplateGet); + ttGoodsCategoryService.handTemplate(goodsTemplateGet,coupon); + return new ResultData(goodsTemplateGet); + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + + } + + @ApiOperation("提交审核") + @PostMapping("product/save") + @SystemControllerLog(description = "提交审核") + public ResultData productSave(@RequestBody WxCoupon wxCoupon) { + if (wxCoupon.getId() == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + WxCoupon coupon = wxCouponService.getById(wxCoupon.getId(), getTenantInfo().getTenantId()); + if(coupon == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + + try { + return ttCouponGoodsService.productSave(coupon); + } catch (Exception e) { + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + } + + @ApiOperation("实时查询审核状态") + @GetMapping("product/draft") + @SystemControllerLog(description = "实时查询审核状态") + public ResultData productDraft(Long id) { + if (id == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + return ttCouponGoodsService.productDraftGet(getTenantInfo(),id); + } + + @ApiOperation("实时查询线上商品状态") + @GetMapping("product/online") + @SystemControllerLog(description = "实时查询审核状态") + public ResultData productOnline(Long id) { + if (id == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + return ttCouponGoodsService.productOnlineGet(getTenantInfo(),id); + } + + @ApiOperation("实时同步上下架状态") + @GetMapping("product/operate") + @SystemControllerLog(description = "实时同步上下架状态") + public ResultData productOperate(Long id) { + if (id == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + + return ttCouponGoodsService.productOperate(getTenantInfo(),id); + } + + @ApiOperation("实时同步库存") + @GetMapping("product/stock/sync") + @SystemControllerLog(description = "实时同步库存") + public ResultData productStockSync(Long id) { + if (id == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + return ttCouponGoodsService.productStockSync(getTenantInfo(),id); + } + + + +} diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java index 22c79f62f..aabd2912f 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java @@ -52,6 +52,7 @@ public class WxCouponChannelController extends BaseController { @Autowired @Qualifier("objectCommonRedisTemplate") RedisTemplate redisTemplate; + @ApiOperation("分页列表接口") @GetMapping("list") @@ -98,6 +99,23 @@ public class WxCouponChannelController extends BaseController { return resultData; } + @ApiOperation("预审核上架") + @PostMapping("updateOnline") + @SystemControllerLog(description = "预审核上架") + public ResultData updateOnline(@RequestBody WxCouponChannel wxCouponChannel) { + wxCouponChannel.updateTenantInfo(getTenantInfo()); + if (wxCouponChannel.getId() == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + ResultData resultData = wxCouponChannelService.updateOnline(wxCouponChannel); + if(resultData.code == 200){ + CouponCacheUtils.removeCouponChannelCache(redisTemplate, wxCouponChannel.getId()); + CouponCacheUtils.removeDouyinLivePageCache(redisTemplate, wxCouponChannel.getTenantId(), null, null); + } + + return resultData; + } + @ApiOperation("根据id查询接口") diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java index 61b790b8c..9fe2ff85f 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java @@ -13,14 +13,12 @@ import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxCouponPassword; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.TtCouponVo; import com.iformall.domain.vo.WxCouponStatisVo; +import com.iformall.douyin.web.bean.GoodsTemplateGet; import com.iformall.enums.*; import com.iformall.mapper.WxCouponChannelMapper; -import com.iformall.service.WxCouponPasswordService; -import com.iformall.service.WxCouponService; -import com.iformall.service.WxFlowService; -import com.iformall.service.WxMallService; -import com.iformall.service.WxPayAccountService; +import com.iformall.service.*; import com.iformall.service.util.CouponCacheUtils; import com.iformall.utils.DateUtils; import com.iformall.utils.RedisLock; @@ -29,6 +27,7 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; +import me.chanjar.weixin.common.error.WxErrorException; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.lang3.StringUtils; @@ -227,6 +226,45 @@ public class WxCouponController extends BaseController { return result; } + @ApiOperation("根据id更新接口") + @PostMapping("continueAdd") + @SystemControllerLog(description = "继续添加") + public ResultData continueAdd(@RequestBody WxCoupon wxCoupon) { + logger.debug("[" + getIpAddr() + "] WxCouponController::update"); + if (wxCoupon.getId() == null) { + return new ResultData(ResultData.ERROR, "缺少id"); + } + if(wxCoupon.getProductType() == null || wxCoupon.getCategoryId() == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "缺少必要参数"); + } + + wxCoupon.updateTenantInfo(getTenantInfo()); + if(EnumDelFlag.YES.getCode().equals(wxCoupon.getIsDel())){ + WxCouponChannel query = new WxCouponChannel(); + query.updateTenantInfo(wxCoupon); + query.setCouponId(wxCoupon.getId()); + query.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode()); + if (CollectionUtils.isNotEmpty(wxCouponChannelMapper.findList(query))) { + return new ResultData(ResultData.ERROR, "有活动正在上架,请先下架。"); + } + } + + WxCoupon coupon = wxCouponService.getById(wxCoupon.getId(),wxCoupon.getTenantId()); + if (null == coupon) { + return new ResultData(ResultData.ERROR, "券未查询到。"+wxCoupon.getId()); + } + + coupon.setProductType(wxCoupon.getProductType()); + coupon.setCategoryId(wxCoupon.getCategoryId()); + coupon.setProductAttrs(wxCoupon.getProductAttrs()); + coupon.setSkuAttrs(wxCoupon.getSkuAttrs()); + + ResultData result = wxCouponService.updateTtProduct(coupon); + CouponCacheUtils.removeCouponCache(redisTemplate, wxCoupon.getId()); + CouponCacheUtils.removeCouponMerchantCache(redisTemplate, wxCoupon.getId()); + return result; + } + @ApiOperation("根据id更新库存及有效期接口") @PostMapping("updateStokeAndValidDate") @SystemControllerLog(description = "券投放-库存/有效期更新") diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponOrderController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponOrderController.java index fc4a16334..e32a132ef 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponOrderController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponOrderController.java @@ -123,7 +123,7 @@ public class WxCouponOrderController extends BaseController { wxCouponOrder.getMerchantName().isEmpty()) { wxCouponOrder.setMerchantName(null); } - wxCouponOrderService.exportData(wxCouponOrder, request, response); + wxCouponOrderService.exportData(false,wxCouponOrder, request, response); } } diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java index 940bd65ca..dacec16b8 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java @@ -7,24 +7,17 @@ import com.iformall.common.Result; import com.iformall.common.ResultData; import com.iformall.controller.base.BaseController; import com.iformall.domain.dto.OrderSaveDto; -import com.iformall.domain.po.WxCUser; -import com.iformall.domain.po.WxCUserBasicInfo; -import com.iformall.domain.po.WxCoupon; -import com.iformall.domain.po.WxCouponChannel; -import com.iformall.domain.po.WxOrder; +import com.iformall.domain.po.*; import com.iformall.domain.po.base.BaseEntity; import com.iformall.domain.vo.WxMerchantSubsidyVo; import com.iformall.domain.vo.WxOrderQueryVo; import com.iformall.enums.*; import com.iformall.exception.MallinkException; -import com.iformall.service.WxCUserBasicInfoService; -import com.iformall.service.WxCUserService; -import com.iformall.service.WxCouponChannelService; -import com.iformall.service.WxCouponService; -import com.iformall.service.WxOrderService; +import com.iformall.service.*; import com.iformall.service.order.OrderFactory; import com.iformall.service.order.entity.WxComposeOrder; +import com.iformall.utils.MaUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -54,6 +47,9 @@ public class WxOrderController extends BaseController { @Autowired private WxOrderService wxOrderService; + @Autowired + private WxPayOrderService wxPayOrderService; + @Autowired private WxCUserService wxCUserService; @@ -62,7 +58,7 @@ public class WxOrderController extends BaseController { @Autowired private WxCUserBasicInfoService wxCUserBasicInfoService; - + @Autowired OrderFactory orderFactory; @@ -193,7 +189,7 @@ public class WxOrderController extends BaseController { // 免费券 WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(EnumComposeOrder.SINGLE.getCode()).createDBMainOrder(coupon, user, 0, EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT); order = wxOrderService.saveFreeOrderForCoupon(new Date(),false,composeOrder,user, coupon, 1, - wxCouponChannel, orderSaveDto.getFormId(), null,EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT, + wxCouponChannel, orderSaveDto.getFormId(), null,null,EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT, EnumOrderShopingType.ONLINE_PURCHASE.getCode(),null); return new ResultData(order); } catch (MallinkException e) { @@ -268,4 +264,19 @@ public class WxOrderController extends BaseController { } + @ApiOperation("查看抖音订单状态") + @GetMapping("/ttorderQuery") + @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) + @SystemControllerLog(description = "订单管理-id查询") + public ResultData ttorderQuery(Long id) { + logger.debug("[" + getIpAddr() + "] WxOrderController::ttorderQuery"); +// WxBatchOrder wxBatchOrder = wxOrderService.getWxBatchOrder(getTenantInfo(), id); +// if(wxBatchOrder == null || !EnumPayWay.PAY_WAY_TT.getCode().equals(wxBatchOrder.getPayVendor())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(), "订单未找到或不支持"); +// } + return new ResultData(wxPayOrderService.ttorderQuery(getTenantInfo(),id)); + + } + + } diff --git a/mallinkAdmin/src/main/resources/db/migration/V2022052700002__push_order.sql b/mallinkAdmin/src/main/resources/db/migration/V2022052700002__push_order.sql new file mode 100644 index 000000000..f14800f59 --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V2022052700002__push_order.sql @@ -0,0 +1,303 @@ +ALTER TABLE wx_order_0 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_1 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_2 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_3 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_4 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_5 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_6 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_7 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_8 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_9 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_10 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_11 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_12 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_13 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_14 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_15 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_16 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_17 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_18 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_19 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_20 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_21 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_22 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_23 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_24 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_25 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_26 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_27 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_28 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_29 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_30 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_31 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_32 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_33 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_34 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_35 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_36 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_37 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_38 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_39 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_40 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_41 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_42 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_43 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_44 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_45 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_46 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_47 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_48 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_49 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_50 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_51 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_52 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_53 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_54 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_55 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_56 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_57 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_58 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_59 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_60 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_61 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_62 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_63 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_64 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_65 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_66 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_67 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_68 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_69 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_70 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_71 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_72 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_73 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_74 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_75 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_76 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_77 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_78 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_79 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_80 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_81 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_82 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_83 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_84 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_85 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_86 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_87 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_88 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_89 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_90 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_91 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_92 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_93 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_94 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_95 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_96 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_97 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_98 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_order_99 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; + +ALTER TABLE wx_coupon_order_0 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_1 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_2 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_3 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_4 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_5 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_6 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_7 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_8 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_9 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_10 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_11 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_12 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_13 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_14 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_15 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_16 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_17 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_18 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_19 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_20 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_21 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_22 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_23 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_24 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_25 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_26 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_27 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_28 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_29 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_30 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_31 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_32 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_33 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_34 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_35 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_36 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_37 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_38 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_39 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_40 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_41 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_42 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_43 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_44 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_45 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_46 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_47 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_48 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_49 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_50 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_51 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_52 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_53 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_54 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_55 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_56 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_57 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_58 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_59 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_60 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_61 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_62 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_63 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_64 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_65 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_66 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_67 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_68 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_69 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_70 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_71 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_72 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_73 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_74 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_75 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_76 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_77 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_78 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_79 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_80 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_81 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_82 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_83 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_84 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_85 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_86 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_87 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_88 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_89 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_90 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_91 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_92 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_93 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_94 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_95 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_96 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_97 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_98 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_coupon_order_99 ADD COLUMN `ext_param` VARCHAR(1000) COMMENT '额外参数,用于第三方平台'; + +ALTER TABLE wx_batch_order_0 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_1 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_2 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_3 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_4 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_5 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_6 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_7 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_8 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_9 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_10 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_11 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_12 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_13 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_14 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_15 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_16 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_17 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_18 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_19 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_20 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_21 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_22 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_23 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_24 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_25 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_26 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_27 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_28 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_29 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_30 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_31 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_32 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_33 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_34 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_35 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_36 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_37 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_38 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_39 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_40 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_41 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_42 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_43 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_44 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_45 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_46 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_47 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_48 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_49 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_50 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_51 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_52 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_53 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_54 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_55 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_56 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_57 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_58 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_59 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_60 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_61 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_62 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_63 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_64 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_65 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_66 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_67 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_68 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_69 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_70 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_71 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_72 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_73 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_74 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_75 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_76 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_77 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_78 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_79 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_80 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_81 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_82 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_83 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_84 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_85 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_86 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_87 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_88 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_89 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_90 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_91 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_92 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_93 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_94 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_95 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_96 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_97 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_98 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; +ALTER TABLE wx_batch_order_99 ADD COLUMN `ext_param` text COMMENT '额外参数,用于第三方平台'; + diff --git a/mallinkAdmin/src/main/resources/db/migration/V2022060700001__coupon_product.sql b/mallinkAdmin/src/main/resources/db/migration/V2022060700001__coupon_product.sql new file mode 100644 index 000000000..c7592f2d4 --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V2022060700001__coupon_product.sql @@ -0,0 +1,505 @@ +ALTER TABLE `mallink`.`tt_coupon_channel_poi` +ADD COLUMN `coupon_channel_id` bigint(20) NOT NULL AFTER `parent_tenant_id`; + + + +ALTER TABLE `mallink`.`wx_coupon_0` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_1` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_2` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_3` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_4` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_5` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_6` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_7` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_8` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_9` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_10` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_11` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_12` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_13` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_14` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_15` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_16` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_17` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_18` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_19` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_20` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_21` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_22` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_23` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_24` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_25` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_26` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_27` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_28` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_29` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_30` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_31` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_32` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_33` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_34` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_35` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_36` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_37` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_38` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_39` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_40` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_41` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_42` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_43` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_44` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_45` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_46` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_47` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_48` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_49` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_50` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_51` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_52` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_53` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_54` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_55` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_56` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_57` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_58` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_59` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_60` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_61` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_62` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_63` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_64` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_65` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_66` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_67` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_68` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_69` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_70` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_71` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_72` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_73` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_74` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_75` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_76` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_77` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_78` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_79` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_80` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_81` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_82` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_83` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_84` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_85` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_86` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_87` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_88` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_89` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_90` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_91` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_92` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_93` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_94` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_95` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_96` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_97` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_98` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; +ALTER TABLE `mallink`.`wx_coupon_99` +ADD COLUMN `product_type` tinyint(1) DEFAULT 1 COMMENT 'EnumTtProductType' AFTER `gift_list`, +ADD COLUMN `category_id` int(11) DEFAULT NULL COMMENT '商品类目' AFTER `product_type`, +ADD COLUMN `product_attrs` json COMMENT '商品动态属性' AFTER `category_id`, +ADD COLUMN `sku_attrs` json COMMENT 'sku动态属性' AFTER `product_attrs`; \ No newline at end of file diff --git a/mallinkAdmin/src/main/resources/db/migration/V2022061000001__banner_add.sql b/mallinkAdmin/src/main/resources/db/migration/V2022061000001__banner_add.sql new file mode 100644 index 000000000..79dbad18e --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V2022061000001__banner_add.sql @@ -0,0 +1,4 @@ +INSERT INTO `mallink`.`mall_permission`(`id`, `name`, `parent_id`, `available`, `permission`, `resource_type`, `module_color`, `module_color_num`, `url`, `icon`, `version_type`, `sort`) VALUES (676, '抖音宣传页', 605, 'Y', NULL, 1, NULL, NULL, 'ttxcList', NULL, 0, 671); + + +UPDATE `mallink`.`mall_sale_type` SET `menus` = '[1, 2, 4, 5, 6, 50, 105, 110, 201, 205, 202, 211, 212, 221, 222, 223, 251, 409, 410, 411, 416, 500, 502, 504, 505, 506, 507, 508, 511, 512, 521, 522, 523, 531, 532, 591, 592, 595, 602, 605, 606, 607, 610, 647, 671, 675, 676, 680, 711, 901, 902, 904, 907, 60702]' WHERE `id` = 11; diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxCouponOrderController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxCouponOrderController.java index 037b100e9..f7b08ce25 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxCouponOrderController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxCouponOrderController.java @@ -2,6 +2,7 @@ package com.iformall.controller; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.PageInfo; +import com.iformall.annotation.AuthIgnore; import com.iformall.annotation.RedisCache; import com.iformall.common.ErrorCode; import com.iformall.common.Result; @@ -35,6 +36,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + @RestController @RequestMapping("/api/couponOrder") @Api(description = "卡券相关接口") @@ -463,4 +467,43 @@ public class WxCouponOrderController extends BaseController { } return new ResultData(); } + + @ApiOperation(value = "B端核销列表链接") + @GetMapping("/getVerifiedExportUrl") + public ResultData getVerifiedExportUrl(@ModelAttribute WxCouponOrderBVo wxCouponOrder) { + //只有B端管理员才能操作这个 + WxMerchantBUser buser = this.getLoginBUser(); + WxMerchant merchantQ= new WxMerchant(); + merchantQ.updateTenantInfo(buser); + merchantQ.setId(buser.getMerchantId()); + WxMerchant merchant = wxMerchantService.findOne(merchantQ); + if (!(buser.getPhone().equals(merchant.getLinkPhone()))) { + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"只有商户管理员才能进行此操作"); + } + if (wxCouponOrder == null) wxCouponOrder = new WxCouponOrderBVo(); + wxCouponOrder.updateTenantInfo(getTenantInfo()); + StringBuffer sb = new StringBuffer("/api/couponOrder/unLogin/verifiedExport?verifyMerchantId=").append(buser.getMerchantId()) + .append("&tenantId="+wxCouponOrder.getTenantId()); + if (null != wxCouponOrder.getVerifyStartDate()) { + sb.append("&verifyStartDate=").append(wxCouponOrder.getVerifyStartDate()); + } + if (null != wxCouponOrder.getVerifyEndDate()) { + sb.append("&verifyEndDate=").append(wxCouponOrder.getVerifyEndDate()); + } + return new ResultData(sb.toString()); + + } + + @GetMapping("/unLogin/verifiedExport") + @AuthIgnore + public void verifiedExport(@ModelAttribute WxCouponOrderBVo wxCouponOrder, HttpServletRequest request, HttpServletResponse response) { + logger.debug("[" + getIpAddr() + "] WxCouponOrderController::exportData"); + if (wxCouponOrder == null) { + return; + } + wxCouponOrder.setStartDate(DateUtils.stringToDate("2022-01-01 00:00:00",DateUtils.DATE_TIME_PATTERN)); + wxCouponOrder.setEndDate(DateUtils.stringToDate("2122-01-01 00:00:00",DateUtils.DATE_TIME_PATTERN)); + wxCouponOrderService.exportData(true,wxCouponOrder, request, response); + } + } diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java index 0be1a6aa1..043ffc14d 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java @@ -110,7 +110,11 @@ public class WxCouponController extends BaseController { if (null == coupon) { return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannel找不到coupon" + couponChannelId); } - if(EnumCouponType.COUPON_GIFT.getCode().equals(coupon.getType())){ + WxCoupon attrsById = couponService.getAttrsById(couponChannel.getCouponId(), couponChannel.getTenantId()); + coupon.setProductAttrs(attrsById.getProductAttrs()); + coupon.setSkuAttrs(attrsById.getSkuAttrs()); + + if(EnumCouponType.COUPON_GIFT.getCode().equals(coupon.getType())){ WxCoupon couponQ = new WxCoupon(); couponQ.updateTenantInfo(coupon); List longs = JSON.parseArray(coupon.getGiftList(), Long.class); diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java index 51da9b028..7b12861ba 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java @@ -103,7 +103,7 @@ public class WxCouponPasswordController extends BaseController { try { WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(EnumComposeOrder.SINGLE.getCode()).createDBMainOrder(coupon, member, 0, payWay); WxOrder order = orderService.saveFreeOrderForCoupon(new Date(),false,composeOrder,member, coupon, 1, - null, formId, couponPassword.getId(),payWay, + null, formId, couponPassword.getId(),null,payWay, EnumOrderShopingType.ONLINE_PURCHASE.getCode(),null); } catch (MallinkException e) { setCouponPasswordStatus(couponPassword, EnumCouponPasswordStatus.getEnum(pwdStatus)); diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java index 58541a5da..dc1c0316d 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java @@ -1,6 +1,10 @@ package com.iformall.controller; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader; import com.github.pagehelper.PageInfo; import com.iformall.annotation.AuthIgnore; import com.iformall.annotation.TenantIgnore; @@ -10,20 +14,28 @@ import com.iformall.common.Result; import com.iformall.common.ResultData; import com.iformall.domain.dto.OrderComposeSaveDto; import com.iformall.domain.dto.OrderSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.domain.po.*; import com.iformall.domain.po.base.BaseEntity; import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.po.tt.TtCUser; import com.iformall.domain.vo.WxCouponCVo; import com.iformall.domain.vo.WxOrderCouponPressVo; import com.iformall.domain.vo.WxOrderCouponVo; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.result.CreateOrderCallback; import com.iformall.enums.*; import com.iformall.exception.MallinkException; +import com.iformall.interceptor.BodyReaderHttpServletRequestWrapper; import com.iformall.service.*; +import com.iformall.service.cuser.CUserServiceFactory; import com.iformall.service.order.OrderFactory; import com.iformall.service.order.entity.WxComposeOrder; import com.iformall.service.pay.entity.PayExtraParam; import com.iformall.utils.Constant; import com.iformall.utils.IPUtil; +import com.iformall.utils.MaUtil; import com.iformall.utils.RedisLock; import io.swagger.annotations.Api; @@ -38,10 +50,8 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import java.util.*; @RestController @RequestMapping("/api/order/") @@ -58,6 +68,9 @@ public class WxOrderController extends BaseController { @Autowired private WxCouponService wxCouponService; + @Autowired + private CUserServiceFactory cuserFactory; + @Autowired private WxCUserBasicInfoService wxCUserBasicInfoService; @@ -79,6 +92,9 @@ public class WxOrderController extends BaseController { @Autowired private OrderFactory orderFactory; + @Autowired + private MaUtil maUtil; + @Autowired @Qualifier("couponDetailRedisTemplate") RedisTemplate cdRedisTemplate; @@ -122,7 +138,7 @@ public class WxOrderController extends BaseController { } catch (Exception e) { return new ResultData(Result.ERROR,e.getMessage()); } - return wxOrderService.composeSaveOrder(false,EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,orderSaveDto,memberId,EnumPayWay.PAY_WAY_WECHAT,getTenantInfo()); + return wxOrderService.composeSaveOrder(false,EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,orderSaveDto,memberId,getPayWay(),getTenantInfo()); } @ApiOperation(value = "单个券单个订单,卡(分账导致无法批量下单)、拼团,砍价用", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") @@ -142,6 +158,208 @@ public class WxOrderController extends BaseController { list.add(dto); return wxOrderService.composeSaveOrder(false,EnumComposeOrder.SINGLE,list,memberId,getPayWay(),getTenantInfo()); } + + @AuthIgnore + @ApiOperation(value = "抖音支付2.0与下单回调推送订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") + @PostMapping("douyinPushOrder") + public Map douyinPushOrder(HttpServletRequest request) { + + Map map = new HashMap(); + + SignatureHeader header = new SignatureHeader(); + header.setTimeStamp(request.getHeader("Byte-Timestamp")); + header.setNonce(request.getHeader("Byte-Nonce-Str")); + header.setSigned(request.getHeader("Byte-Signature")); + + logger.info("支付2.0预下单回调---header{}"+header.toString()); + + String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); + logger.info("支付2.0预下单回调---body{}"+body); + try { + JSONObject jsonObject = JSONObject.parseObject(body); + String msg = jsonObject.getString("msg"); + + JSONObject msgObject = JSONObject.parseObject(msg); + String app_id = msgObject.getString("app_id"); + String open_id = msgObject.getString("open_id"); + //透传字段 + Map couponMap = new HashMap<>(); + try{ + String cp_extra = msgObject.getString("cp_extra"); + if(StringUtils.isBlank(cp_extra)){ + map.put("err_no",ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); + map.put("err_tips","缺少透传字段"); + return map; + } + couponMap = JSONObject.parseObject(cp_extra, Map.class); + }catch(Exception e){ + } + if(couponMap.isEmpty()){ + map.put("err_no",ErrorCode.SYS_PARAMETER_NOT_NULL.getCode()); + map.put("err_tips","透传字段格式不正确"); + return map; + } + + //验证app + WxAppinfo appinfo = wxAppinfoService.getByAppId(app_id); + if(appinfo == null || !EnumAppPlat.TOUTIAO.getCode().equals(appinfo.getPlat()) + || !EnumAppType.C.getCode().equals(appinfo.getType())){ + map.put("err_no",ErrorCode.APP_ID_NOT_FOUND.getCode()); + map.put("err_tips",ErrorCode.APP_ID_NOT_FOUND.getMessage()); + return map; + } + WxPayAccount payAccount = wxPayAccountService.getById(appinfo.getPayId()); + if(payAccount == null){ + map.put("err_no",ErrorCode.API_KEY_NOT_FOUND.getCode()); + map.put("err_tips","未找到支付配置"); + return map; + } + TenantEntity tenantEntity = new TenantEntity(); + tenantEntity.updateTenantInfo(appinfo); + //验证用户 + Long memberId = null; + TtCUser cuser = (TtCUser) cuserFactory.getCUserService(EnumAppPlat.TOUTIAO).getByOpenId(open_id, tenantEntity.getTenantId()); + if(cuser != null && cuser.getUserId() != null){ + memberId = cuser.getUserId(); + } + if(memberId == null){ + map.put("err_no",ErrorCode.USER_NOT_MEMBER.getCode()); + map.put("err_tips",ErrorCode.USER_NOT_MEMBER.getMessage()); + return map; + } + + + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + CreateOrderCallback createOrderCallback = ttPayService.parseOrderNotifyV2Result(body, header); + JSONObject allExtParam = new JSONObject(); + allExtParam.put("order_id",createOrderCallback.getOrderId()); + allExtParam.put("total_amount",createOrderCallback.getTotalAmount()); + allExtParam.put("discount",createOrderCallback.getDiscount()); + allExtParam.put("open_id",createOrderCallback.getOpenId()); + + List list = new ArrayList<>(); + for (CreateOrderCallback.Good good:createOrderCallback.getGoods()) { + PlatPushOrderSaveDto dto = new PlatPushOrderSaveDto(); + dto.setCouponChannelId(Long.parseLong(couponMap.get(good.getGoodsId()))); + dto.setCount(good.getQuantity()); + dto.setExtParam(JSON.toJSONString(good.getItemOrderInfoList())); + list.add(dto); + } + + ResultData resultData = wxOrderService.platPushSaveOrder(true, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH, allExtParam.toJSONString(), list, memberId, EnumPayWay.PAY_WAY_TT, tenantEntity); + logger.info("resultData{}"+JSON.toJSONString(resultData)); + if(resultData.code == 200){ + WxComposeOrder order = (WxComposeOrder) resultData.data; + Map data = new HashMap<>(); + data.put("out_order_no",order.getMainOrderId().toString()); +// data.put("pay_expire_seconds",300); + data.put("order_entry_schema",wxOrderService.getOrderEntrySchema(order.getMainOrderId())); +// List> goodsValid = new ArrayList<>(); +// for (Long couponChannelId:order.getCouponChannelMap().keySet()) { +// Map goodsValidMap = new HashMap<>(); +// WxCouponChannel couponChannel = order.getCouponChannelMap().get(couponChannelId); +// goodsValidMap.put("goods_id",couponChannel.getTtSpuId()); +// WxCoupon wxCoupon = order.getCouponMap().get(couponChannel.getCouponId()); +// if(EnumCouponValidType.BETWEEN_TWO_TIME.getCode().equals(wxCoupon.getValidType())){ +// goodsValidMap.put("valid_start_time",wxCoupon.getValidStartDate().getTime()); +// goodsValidMap.put("valid_end_time",wxCoupon.getValidEndDate().getTime()); +// }else{ +// goodsValidMap.put("valid_duration",(long)wxCoupon.getValidDays()*24*3600*1000); +// } +// goodsValid.add(goodsValidMap); +// } +// data.put("order_valid_time",goodsValid); + + map.put("data",data); + map.put("err_no",0); + map.put("err_tips",resultData.message); + logger.info("resultData{}"+JSON.toJSONString(map)); + return map; + }else{ + map.put("err_no",resultData.code); + map.put("err_tips",resultData.message); + return map; + } + + } catch (TtPayException e) { + logger.error(e.getMessage()); + map.put("err_no",ErrorCode.SYS_BEAN_EMPTY_PROPERTY_ERROR.getCode()); + map.put("err_tips",e.getMessage()); + return map; + } catch (Exception e){ + logger.error(e.getMessage()); + map.put("err_no",ErrorCode.SYS_SERVER_ERROR.getCode()); + map.put("err_tips",e.getMessage()); + return map; + } + } + +// @ApiOperation(value = "更新订单状态", notes = "{\"payOrderId\":\"string\",\"composeOrderId\":\"string\",\"status\":integer,\"reason\":\"string\"}") +// @PostMapping("/updatePayOrder") +// public ResultData updatePayOrder(@RequestBody Map paramMap) { +// logger.info("/api/pay/updatePayOrder" + paramMap.toString()); +// String orderIdStr = (String) paramMap.get("composeOrderId"); +// if (StringUtils.isBlank(orderIdStr)) { +// logger.info("orderId不能为空: " + paramMap.toString()); +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空"); +// } +// Long orderId = 0L; +// try { +// orderId = Long.valueOf(orderIdStr); +// } catch (NumberFormatException e) { +// logger.error("orderId参数不正确: " + paramMap.toString() + ", e:" + e.getMessage()); +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId参数不正确"); +// } +// +// WxBatchOrder batchOrder = wxOrderService.getWxBatchOrder(getTenantInfo(),orderId); +// if(batchOrder == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(), "未找到订单"); +// } +// +// WxPayOrder payOrder = new WxPayOrder(); +// payOrder.setOrderId(orderId); +// payOrder.updateTenantInfo(getTenantInfo()); +// payOrder.setPayVendor(getPayWay().getCode()); +// payOrder.setComposeOrder(batchOrder.getOrderType()); +// +// try { +// WxPayOrder byObj = wxPayOrderService.getByObj(payOrder); +// if(byObj != null){ +// return new ResultData(Result.SUCCESS, "支付状态更新成功"); +// }else{ +// +// +// WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(payOrder.getComposeOrder()).getComposeOrder(payOrder.getOrderId(), payOrder.getTenantId()); +// +// WxAppinfo appInfo = wxAppinfoService.getCAppInfo(payOrder, EnumPayWay.getEnum(payOrder.getPayVendor()).getPlat()); +// //WxCUser user = getUser(); +// //WxAppinfo appInfo = getAppInfo(user.getAppId()); +// if (null == appInfo) { +// return new ResultData(ErrorCode.PAY_ORDER_ERROR, "当前支付类型["+payOrder.getPayVendor()+"]找不到C端appInfo"); +// } +// WxPayAccount payAccount = wxPayAccountService.getById(appInfo.getPayId()); +// try { +// WxPayOrder wo = wxPayOrderService.handleWxOrderQuery(payOrder, composeOrder,appInfo, payAccount, IdWorker.get(),false); +// if (null != wo) { +// return new ResultData(Result.SUCCESS, "支付状态更新成功", composeOrder); +// } +// }catch(MallinkException e) { +// //已经同步了微信的支付状态,表示已经更新 +// return new ResultData(Result.SUCCESS, "支付状态更新成功", composeOrder); +// } +// +// return new ResultData(ErrorCode.PAY_ORDER_ERROR, "查询微信订单支付状态失败,请稍后!"); +// } +// } catch (MallinkException e) { +// logger.error("支付状态更新失败2: " + payOrder.toString() + ", e:" + e.getMessage(),e); +// return new ResultData(e.getErrorCode(), e.getMessage()); +// } catch (Exception e) { +// logger.error("支付状态更新失败3: " + payOrder.toString() + ", e:" + e.getMessage(),e); +// return new ResultData(ErrorCode.PAY_ORDER_ERROR, "支付状态更新失败3: " + payOrder.toString() + ", e:" + e.getMessage()); +// } +// } + + @ApiOperation(value = "取消订单", notes = "{\"orderId\":\"string\"}") @PostMapping("cancel") @@ -169,7 +387,6 @@ public class WxOrderController extends BaseController { if (null != payOrder) { WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(payOrder.getComposeOrder()).getComposeOrder(payOrder.getOrderId(), payOrder.getTenantId()); //查询微信订单状态并更新 - boolean hasCompleted = wxPayOrderService.hasCompleted(composeOrder,payOrder); if (!hasCompleted) { WxAppinfo appInfo = wxAppinfoService.getCAppInfo(payOrder, EnumPayWay.getEnum(payOrder.getPayVendor()).getPlat()); @@ -714,5 +931,25 @@ public class WxOrderController extends BaseController { // // return openId; // } + @AuthIgnore + @ApiOperation(value = "抖音支付2.0与退款回调推送订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") + @PostMapping("douyinRefundOrder") + public Map douyinRefundOrder(HttpServletRequest request) { + SignatureHeader header = new SignatureHeader(); + header.setTimeStamp(request.getHeader("Byte-Timestamp")); + header.setNonce(request.getHeader("Byte-Nonce-Str")); + header.setSigned(request.getHeader("Byte-Signature")); + + logger.info("支付2.0预下单回调---header{}"+header.toString()); + + String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); + logger.info("支付2.0预下单回调---body{}"+body); + + Map map = new HashMap(); + map.put("err_no",1001); + map.put("err_tips","未找到支付信息"); + return map; + + } } diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java index b1ff51f35..71e52a096 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java @@ -100,10 +100,11 @@ public class WxPayOrderController extends BaseController { return new ResultData(ErrorCode.USER_IS_NOT_MEMBER.getCode(), "暂未成为会员,请授权手机号"); } - return _create(orderIdStr,composeOrderType,user.getUserId(),getPayWay(),user.getAppId(),new PayExtraParam("openId",user.getOpenId()),request); + return _create(orderIdStr,composeOrderType,user.getUserId(),getPayWay(),user.getAppId(),new PayExtraParam("openId",user.getOpenId()),true,request); } - private ResultData _create(String orderIdStr,String composeOrderType,Long userId, EnumPayWay payWay,String appId,PayExtraParam parm,HttpServletRequest request) { + private ResultData _create(String orderIdStr,String composeOrderType,Long userId, EnumPayWay payWay, + String appId,PayExtraParam parm,boolean isCreatePay,HttpServletRequest request) { WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(userId,getFinalTenantId()); if ( null == wxCUserBasicInfo) { logger.error("会员用户不存在."+userId); @@ -128,7 +129,7 @@ public class WxPayOrderController extends BaseController { try { record.setIp(IPUtil.getIpAddr(request)); record.setComposeOrder(Integer.parseInt(composeOrderType)); - return wxPayOrderService.createPayOrder(appInfo, wxCUserBasicInfo, record, payWay,parm); + return wxPayOrderService.createPayOrder(appInfo, wxCUserBasicInfo, record, payWay,parm,isCreatePay); } catch (MallinkException e) { logger.error("payment wechat, order create error, req 2: " + record.toString() + ", e:" + e.getMessage(),e); return new ResultData(e.getErrorCode(), e.getMessage()); @@ -138,6 +139,30 @@ public class WxPayOrderController extends BaseController { } } + @RequestMapping(value = "/ttcreatev2", method = RequestMethod.POST) + public ResultData _ttcreatev2(@RequestBody Map paramMap, HttpServletRequest request) throws Exception { + logger.info("/api/pay/create" + paramMap.toString()); + String orderIdStr = paramMap.get("orderId"); + if (StringUtils.isBlank(orderIdStr)) { + logger.info("orderId不能为空: " + paramMap.toString()); + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空"); + } + + String composeOrderType = paramMap.get("composeOrderType"); + if (StringUtils.isBlank(composeOrderType)) { + logger.info("composeOrderType不能为空: " + paramMap.toString()); + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "composeOrderType不能为空"); + } + + CUser user = getCUser(); + if (!user.basicInfoIs()) { + logger.error("暂未成为会员,请授权手机号"); + return new ResultData(ErrorCode.USER_IS_NOT_MEMBER.getCode(), "暂未成为会员,请授权手机号"); + } + + return _create(orderIdStr,composeOrderType,user.getUserId(),getPayWay(),user.getAppId(),new PayExtraParam("openId",user.getOpenId()),false,request); + } + @ApiOperation(value = "更新支付订单状态", notes = "{\"payOrderId\":\"string\",\"composeOrderId\":\"string\",\"status\":integer,\"reason\":\"string\"}") @PostMapping("/updatePayOrder") public ResultData updatePayOrder(@RequestBody Map paramMap) { diff --git a/mallinkCallback/src/main/java/com/iformall/config/ShiroConfig.java b/mallinkCallback/src/main/java/com/iformall/config/ShiroConfig.java index 32334bcee..69f7b4c13 100644 --- a/mallinkCallback/src/main/java/com/iformall/config/ShiroConfig.java +++ b/mallinkCallback/src/main/java/com/iformall/config/ShiroConfig.java @@ -112,6 +112,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/alipay/notify/**", "anon"); filterChainDefinitionMap.put("/ttPay/notify/**", "anon"); + filterChainDefinitionMap.put("/ttweb/notify/**", "anon"); filterChainDefinitionMap.put("/jinmao/notify/**", "anon"); diff --git a/mallinkCallback/src/main/java/com/iformall/controller/callback/JinMaoController.java b/mallinkCallback/src/main/java/com/iformall/controller/callback/JinMaoController.java index 878632ae6..810d6a7f8 100644 --- a/mallinkCallback/src/main/java/com/iformall/controller/callback/JinMaoController.java +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/JinMaoController.java @@ -219,7 +219,7 @@ public class JinMaoController extends BaseController { try { inputStream = request.getInputStream(); String paramStr = IOUtils.toString(inputStream, "utf-8"); - logger.info("dfh heartBeat: {}",paramStr); +// logger.info("dfh heartBeat: {}",paramStr); if (StringUtils.isBlank(paramStr)) { generateHeartBeatResult(response,"unvalid param", "参数不能为空paramStr",currentTime); return ; diff --git a/mallinkCallback/src/main/java/com/iformall/controller/callback/TtPayController.java b/mallinkCallback/src/main/java/com/iformall/controller/callback/TtPayController.java index 015305307..5a7055528 100644 --- a/mallinkCallback/src/main/java/com/iformall/controller/callback/TtPayController.java +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/TtPayController.java @@ -2,25 +2,28 @@ package com.iformall.controller.callback; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader; import com.iformall.common.ErrorCode; import com.iformall.common.ResultData; import com.iformall.controller.base.BaseController; import com.iformall.domain.po.WxAppinfo; +import com.iformall.domain.po.WxBatchOrder; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.WxPayOrder; +import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.po.msg.FmInsideNotifyRefundSuccessMsg; import com.iformall.douyin.pay.DouYinPayHelper; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.payv2.result.CreateOrderCallback; import com.iformall.enums.*; import com.iformall.interceptor.BodyReaderHttpServletRequestWrapper; import com.iformall.mq.MqBaseProducer; -import com.iformall.service.WxAppinfoService; -import com.iformall.service.WxPayAccountService; -import com.iformall.service.WxPayOrderService; -import com.iformall.service.WxRefundOrderService; +import com.iformall.service.*; import com.iformall.service.order.OrderFactory; import com.iformall.service.order.entity.WxComposeOrder; import com.iformall.service.pay.PayServiceFactory; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; +import com.iformall.utils.MaUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -50,6 +54,9 @@ public class TtPayController extends BaseController { @Autowired private WxPayOrderService wxPayOrderService; + @Autowired + private WxOrderService wxOrderService; + @Autowired private OrderFactory orderFactory; @@ -59,6 +66,9 @@ public class TtPayController extends BaseController { @Autowired private MqBaseProducer mqBaseProducer; + @Autowired + private MaUtil maUtil; + /** * timestamp number Unix 时间戳,10 位,整型数 * nonce string 随机数 @@ -75,60 +85,119 @@ public class TtPayController extends BaseController { */ @PostMapping(value = "/orderPay") @ResponseBody - public Map createOrder( @RequestBody Map parameterMap){ + public Map createOrder( @RequestBody Map parameterMap,HttpServletRequest request){ logger.debug("[" + getIpAddr() + "] TtOrderCallbackController::orderPay"); Map resultMap = new HashMap<>(); // String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); - logger.info("抖音支付通知-----body{}"+parameterMap); +// Map parameterMap = JSONObject.parseObject(body, Map.class); + logger.info("抖音通知-----body{}"+parameterMap); try { - -// Map parameterMap = JSONObject.parseObject(body, Map.class); - - String timestamp = (String) parameterMap.get("timestamp"); - String nonce = (String) parameterMap.get("nonce"); -// {"appid":"tt9da4eb19029c2bb301","cp_orderno":"557490321114062848","cp_extra":"","way":"2","channel_no":"2021052622001418391405536769","channel_gateway_no":"12105260162116189897","payment_order_no":"2021052622001418391405536769","out_channel_order_no":"","total_amount":100} String msg = (String) parameterMap.get("msg"); String type = (String) parameterMap.get("type"); - String msgSignature = (String) parameterMap.get("msg_signature"); + String version = (String) parameterMap.get("version"); Map pMap = JSONObject.parseObject(msg, Map.class); - String appid = (String) pMap.get("appid"); - WxAppinfo appinfo = appinfoService.getByAppId(appid); - WxPayAccount payAccount = payAccountService.getById(appinfo.getPayId()); - Map paramMap = new HashMap<>(); - paramMap.put("token",payAccount.getNotifyToken()); - paramMap.put("timestamp",timestamp); - paramMap.put("nonce",nonce); - paramMap.put("msg",msg); - String sign = DouYinPayHelper.getTTBackSign(paramMap, "SHA1"); - if(!msgSignature.equalsIgnoreCase(sign)){ - resultMap.put("err_tips","error"); - return resultMap; + + String appid; + WxAppinfo appinfo; + WxPayAccount payAccount; + Boolean is2_0 = false; + + if(StringUtils.isNotBlank(version) && "2.0".equals(version)){//支付2.0 回调 + is2_0 = true; + String msgSignature = request.getHeader("Byte-Signature"); + String timestamp = request.getHeader("Byte-Timestamp"); + String nonce = request.getHeader("Byte-Nonce-Str"); + + appid = (String) pMap.get("app_id"); + appinfo = appinfoService.getByAppId(appid); + payAccount = payAccountService.getById(appinfo.getPayId()); + + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + String beforeSign = String.format("%s\n%s\n%s\n", + timestamp, + nonce, + JSON.toJSONString(parameterMap)); + boolean verify = ttPayService.getConfig().getVerifier().verify(beforeSign.getBytes(StandardCharsets.UTF_8), msgSignature); + if(!verify){ + logger.info("抖音通知(2.0)-----{}签名效验失败"); + resultMap.put("err_tips","error"); + return resultMap; + } + logger.info("抖音通知(2.0)-----{}签名效验成功"); + + + }else{ + String msgSignature = (String) parameterMap.get("msg_signature"); + String timestamp = (String) parameterMap.get("timestamp"); + String nonce = (String) parameterMap.get("nonce"); + + appid = (String) pMap.get("appid"); + appinfo = appinfoService.getByAppId(appid); + payAccount = payAccountService.getById(appinfo.getPayId()); + + Map paramMap = new HashMap<>(); + paramMap.put("token",payAccount.getNotifyToken()); + paramMap.put("timestamp",timestamp); + paramMap.put("nonce",nonce); + paramMap.put("msg",msg); + String sign = DouYinPayHelper.getTTBackSign(paramMap, "SHA1"); + if(!msgSignature.equalsIgnoreCase(sign)){ + logger.info("抖音通知-----{}签名效验失败"); + resultMap.put("err_tips","error"); + return resultMap; + } + logger.info("抖音通知-----{}签名效验成功"); + } + + if("payment".equals(type)){//支付回调 - String cp_orderno = (String) pMap.get("cp_orderno");//开发者传入订单号 + String out_order_no; + if(is2_0){ + out_order_no = (String)pMap.get("out_order_no"); + }else{ + out_order_no = (String) pMap.get("cp_orderno"); + } String way = (String) pMap.get("way");//2-支付宝,1-微信 - if (!StringUtils.isNotBlank(cp_orderno)) { + if (!StringUtils.isNotBlank(out_order_no)) { try { - Long payOrderId = Long.valueOf(cp_orderno); - WxPayOrder wxpayOrder = wxPayOrderService.getById(payOrderId, appinfo.getTenantId()); + Long orderId = Long.valueOf(out_order_no); + WxPayOrder wxpayOrder = wxPayOrderService.getById(orderId, appinfo.getTenantId()); + if(wxpayOrder == null){ + TenantEntity tenantEntity = new TenantEntity(); + tenantEntity.setTenantId(appinfo.getTenantId()); + tenantEntity.setParentTenantId(appinfo.getParentTenantId()); + WxBatchOrder batchOrder = wxOrderService.getWxBatchOrder(tenantEntity,orderId); + if(batchOrder == null){ + logger.error("未找到订单"+orderId); + } + } PayQueryAdapterResult queryResult = payServiceFactory.getPayAdapterService(wxpayOrder.getPayVendor()).queryPayStatus(wxpayOrder, appinfo, payAccount); if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() == queryResult.getCode()) { WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(wxpayOrder.getComposeOrder()).getComposeOrder(wxpayOrder.getOrderId(), wxpayOrder.getTenantId()); wxPayOrderService.handleSuccessOrder(wxpayOrder, composeOrder, queryResult, true,false); } } catch (NumberFormatException e) { - logger.error("payOrderId参数不正确: " + paramMap.toString() + ", e:" + e.getMessage()); + logger.error("payOrderId参数不正确: " + toString() + ", e:" + e.getMessage()); } } resultMap.put("err_no",0); resultMap.put("err_tips","success"); }else if("refund".equals(type)){//退款回调 - String cp_refundno = (String) pMap.get("cp_refundno"); - String status = (String) pMap.get("status"); - Integer refund_amount = (Integer) pMap.get("refund_amount"); + String cp_refundno,status; + Integer refund_amount; + if(is2_0){ + cp_refundno = (String) pMap.get("out_refund_no"); + status = (String) pMap.get("status"); + refund_amount = (Integer) pMap.get("refund_total_amount"); + }else{ + cp_refundno = (String) pMap.get("cp_refundno"); + status = (String) pMap.get("status"); + refund_amount = (Integer) pMap.get("refund_amount"); + } Map map = new HashMap<>(); map.put("appid",appid); @@ -150,6 +219,8 @@ public class TtPayController extends BaseController { resultMap.put("err_no",0); resultMap.put("err_tips","success"); + }else if("settle".equals(type)){ + } return resultMap; diff --git a/mallinkCallback/src/main/java/com/iformall/controller/callback/TtWebController.java b/mallinkCallback/src/main/java/com/iformall/controller/callback/TtWebController.java new file mode 100644 index 000000000..31397aaa4 --- /dev/null +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/TtWebController.java @@ -0,0 +1,123 @@ +package com.iformall.controller.callback; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.iformall.controller.base.BaseController; +import com.iformall.domain.po.TtCouponChannelPoi; +import com.iformall.domain.po.WxAppinfo; +import com.iformall.enums.EnumSpuSyncStatus; +import com.iformall.service.*; +import com.iformall.utils.DateUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +@RestController +@RequestMapping("/ttweb/notify") +public class TtWebController extends BaseController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private String fmExceptionEmails; + + @Autowired + private MailService mailService; + + @Autowired + private WxAppinfoService wxAppinfoService; + + @Autowired + private TtCouponGoodsService ttCouponGoodsService; + + /** + * { + * "event": "verify_webhook", + * "client_key": "", + * "content": { + * "challenge": 12345 + * } + * } + */ + @PostMapping(value = "/notice") + @ResponseBody + public Map notice( @RequestBody Map parameterMap,HttpServletRequest request){ + logger.debug("[" + getIpAddr() + "] TtOrderCallbackController::notice"); + logger.info("抖音开放平台通知-----{}"+JSON.toJSONString(parameterMap)); + Map resultMap = new HashMap<>(); + String event = (String) parameterMap.get("event"); + String client_key = (String) parameterMap.get("client_key"); + WxAppinfo appInfo = wxAppinfoService.getByAppId(client_key); + if(appInfo == null){ + resultMap.put("err_code",1000); + resultMap.put("err_tips","error"); + return resultMap; + } + + String header = request.getHeader("X-Douyin-Signature"); + String sha1gen = SHA1.gen(appInfo.getSecret(), JSON.toJSONString(parameterMap)); + //发邮件 + String[] receivers = fmExceptionEmails.split(","); + StringBuilder sb = new StringBuilder(); + sb.append(DateUtils.date2String(new Date())); + sb.append("\n"); + sb.append("抖音开放平台通知{}"+JSON.toJSONString(parameterMap)); + sb.append("\n"); + sb.append("sha1gen{}"+sha1gen); + sb.append("\n"); + sb.append("header{}"+header); + //发送邮件 + mailService.sendSimpleMail(receivers, "抖音开放平台通知", sb.toString()); + + + String content = (String) parameterMap.get("content"); + JSONObject jsonObject = JSON.parseObject(content); + if("verify_webhook".equals(event)){ + String challenge = jsonObject.getString("challenge"); +// String challenge = (String) content.get("challenge"); + resultMap.put("challenge",challenge); + return resultMap; + }else if("life_goods_audit".equals(event)){ + String product_id = jsonObject.getString("product_id"); + String reason = jsonObject.getString("reason"); + String status = jsonObject.getString("status"); +// String product_id = content.get("product_id").toString(); +// String reason = (String) content.get("reason"); +// String status = (String) content.get("status"); + + TtCouponChannelPoi couponChannelPoi = new TtCouponChannelPoi(); + couponChannelPoi.updateTenantInfo(appInfo); + couponChannelPoi.setSpuId(product_id); + if("FAIL".equals(status)){ + couponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_audit_rejection.getCode()); + couponChannelPoi.setLastStatusDesc(reason); + + }else if("PASS".equals(status)){ + couponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_audit_pass.getCode()); + couponChannelPoi.setLastStatusDesc(reason); + + }else{ + resultMap.put("err_code",1000); + resultMap.put("err_tips","error"); + return resultMap; + } + ttCouponGoodsService.handlerTtGoodsAudit(couponChannelPoi); + resultMap.put("err_code",0); + resultMap.put("err_tips","success"); + return resultMap; + } + + resultMap.put("err_code",1000); + resultMap.put("err_tips","error"); + return resultMap; + } + +} diff --git a/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java b/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java index 28fb57791..bd3c494f6 100644 --- a/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java +++ b/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java @@ -39,6 +39,8 @@ public class MqBaseConsumer { @Autowired private FmInsideOrderPushMsgServiceImpl fmInsideOrderPushMsgService; @Autowired + private FmInsideOrderPushDeliveryMsgServiceImpl fmInsideOrderPushDeliveryMsgServiceImpl; + @Autowired private FmInsideCLoginMsgServiceImpl fmInsideCLoginMsgService; @Autowired private MqBaseProducer mqBaseProducer; @@ -115,6 +117,11 @@ public class MqBaseConsumer { FmInsideOrderPushMsg msg = (FmInsideOrderPushMsg)JsonUtil.readValue(message,FmInsideOrderPushMsg.class); fmInsideOrderPushMsgService.send(msg); } + else if(EnumMsgRecordType.INSIDE_ORDER_PUSH_DELIVERY.getCode().equals(baseMsg.getMsgType())) { + // 内部消息 - 2.0核销同步 + FmInsideOrderPushMsg msg = (FmInsideOrderPushMsg)JsonUtil.readValue(message,FmInsideOrderPushMsg.class); + fmInsideOrderPushDeliveryMsgServiceImpl.send(msg); + } //else if(EnumMsgRecordType.INSIDE_NOTIFY_PAY_SUCCESS.getCode().equals(baseMsg.getMsgType())) { // 内部消息 - 微信支付通知 //FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg)JsonUtil.readValue(message,FmInsideNotifyPaySuccessMsg.class); diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/CouponExpiringSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/CouponExpiringSchedule.java index 10c4bd5eb..2dc3622d7 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/CouponExpiringSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/CouponExpiringSchedule.java @@ -68,13 +68,13 @@ public class CouponExpiringSchedule { wxCouponSendMapper.offExpiriedCouponSendByCouponStatus(mall.getTenantId()); - List ids = wxCouponChannelMapper.getExpiriedCouponChannelIdsByCouponStatus(mall.getTenantId()); + List couponIds = wxCouponChannelMapper.getExpiriedCouponIdsByCouponStatus(mall.getTenantId()); wxCouponChannelMapper.offExpiriedCouponChannelByCouponStatus(mall.getTenantId()); //同步poi - if(ids != null && ids.size() > 0){ - for (Long id: ids) { + if(couponIds != null && couponIds.size() > 0){ + for (Long couponId: couponIds) { try{ - wxCouponChannelService.spuStatusSync(mall,id); + wxCouponChannelService.spuStatusSyncByCoupon(mall,couponId); }catch(Exception e){ logger.error("send spuStatusSync error: " + e.getMessage()); } @@ -107,34 +107,34 @@ public class CouponExpiringSchedule { List malls = getMalls(); for (WxMall mall : malls) { try { - List ids = new ArrayList<>(); + List couponIds = new ArrayList<>(); - List id1s = wxCouponChannelMapper.getExpiriedCouponChannelIdsByEndTime(mall.getTenantId()); - if(id1s != null && id1s.size() > 0){ - ids.removeAll(id1s); - ids.addAll(id1s); + List couponId1s = wxCouponChannelMapper.getExpiriedCouponIdsByEndTime(mall.getTenantId()); + if(couponId1s != null && couponId1s.size() > 0){ + couponIds.removeAll(couponId1s); + couponIds.addAll(couponId1s); } wxCouponChannelMapper.offExpiriedCouponChannelByEndTime(mall.getTenantId()); - List id2s = wxCouponChannelMapper.getExpiriedCouponChannelIdsByValidDate(mall.getTenantId()); - if(id2s != null && id2s.size() > 0){ - ids.removeAll(id2s); - ids.addAll(id2s); + List couponId2s = wxCouponChannelMapper.getExpiriedCouponIdsByValidDate(mall.getTenantId()); + if(couponId2s != null && couponId2s.size() > 0){ + couponIds.removeAll(couponId2s); + couponIds.addAll(couponId2s); } wxCouponChannelMapper.offExpiriedCouponChannelByValidDate(mall.getTenantId()); - List id3s = wxCouponChannelMapper.getExpiriedCouponChannelIdsByCouponStatus(mall.getTenantId()); + List id3s = wxCouponChannelMapper.getExpiriedCouponIdsByCouponStatus(mall.getTenantId()); if(id3s != null && id3s.size() > 0){ - ids.removeAll(id3s); - ids.addAll(id3s); + couponIds.removeAll(id3s); + couponIds.addAll(id3s); } wxCouponChannelMapper.offExpiriedCouponChannelByCouponStatus(mall.getTenantId()); //同步poi - if(ids != null && ids.size() > 0){ - for (Long id: ids) { + if(couponIds != null && couponIds.size() > 0){ + for (Long couponId: couponIds) { try{ - wxCouponChannelService.spuStatusSync(mall,id); + wxCouponChannelService.spuStatusSyncByCoupon(mall,couponId); }catch(Exception e){ logger.error("send spuStatusSync error: " + e.getMessage()); } diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java index 5051d3e9e..f56dec4ef 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java @@ -353,7 +353,7 @@ public class OrderExpiringSchedule { wxOrderMapper.updateById(updateOrder); logger.info("券订单: " + order.getId() + " create at " + order.getCreateDate() + " expired at " + new Date()); - wxOrderService.sendInsideOrderPushMsg(order,order.getComposeOrderId()); +// wxOrderService.sendInsideOrderPushMsg(order,order.getComposeOrderId()); } diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/OrderRefundAuditSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderRefundAuditSchedule.java new file mode 100644 index 000000000..b095d7f6c --- /dev/null +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderRefundAuditSchedule.java @@ -0,0 +1,76 @@ +package com.iformall.schedule; + + +import com.iformall.domain.po.*; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.request.TtRefundAuditMsgRequest; +import com.iformall.enums.*; +import com.iformall.mapper.*; +import com.iformall.utils.MaUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class OrderRefundAuditSchedule { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + WxOrderMapper wxOrderMapper; + + @Autowired + WxAppinfoMapper wxAppinfoMapper; + + @Autowired + WxRefundOrderMapper wxRefundOrderMapper; + + @Autowired + WxPayAccountMapper wxPayAccountMapper; + + @Autowired + MaUtil maUtil; + + + private List getAppInfos() { + WxAppinfo appinfo =new WxAppinfo(); + appinfo.setPlat(EnumAppPlat.TOUTIAO.getCode()); + appinfo.setType(EnumAppType.C.getCode()); + return wxAppinfoMapper.findList(appinfo); + } + + @Scheduled(cron = "0 */10 * * * *?") // 每10分钟检查一次 + //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 + public void merchantAuditCallback() { + logger.info("退款自动审核start"); + List appInfos = getAppInfos(); + for (WxAppinfo appinfo : appInfos) { + WxRefundOrder refundOrder = new WxRefundOrder(); + refundOrder.updateTenantInfo(appinfo); + refundOrder.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); + List list = wxRefundOrderMapper.findList(refundOrder); + if(list != null && list.size() > 0){ + WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + for (WxRefundOrder order:list) { + try { + TtRefundAuditMsgRequest request = new TtRefundAuditMsgRequest(); + request.setOutRefundNo(order.getId().toString()); + request.setRefundAuditStatus(1); + ttPayService.merchantAuditCallback(request); + } catch (TtPayException e) { + e.printStackTrace(); + } + } + + } + + } + } + + +} \ No newline at end of file diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java index df5236caf..6ab6e7c0f 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java @@ -42,8 +42,8 @@ public class SharingOrderRedoSchedule { } @Async - @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨02:00分账重试 -// @Scheduled(cron = "0 0 0/1 * * ?") // 测试 +// @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨02:00分账重试 + @Scheduled(cron = "0 0/10 * * * ?") // 测试 public void sharingOrderResultSchedule() { List malls = getMalls(); for (WxMall mall: malls) { diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderResultSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderResultSchedule.java index 953dc805f..55efd27fb 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderResultSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderResultSchedule.java @@ -35,8 +35,8 @@ public class SharingOrderResultSchedule { } @Async - @Scheduled(cron = "0 15 0 * * ?") // 每天凌晨3:00更新分账结果 - //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 +// @Scheduled(cron = "0 15 0 * * ?") // 每天凌晨3:00更新分账结果 + @Scheduled(cron = "* */15 * * * ?") // 测试10秒中一次 public void sharingOrderResultSchedule() { List malls = getMalls(); for (WxMall mall: malls) { diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/TtMerchantPoiSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/TtMerchantPoiSchedule.java index af09e3eb8..eb5268081 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/TtMerchantPoiSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/TtMerchantPoiSchedule.java @@ -59,21 +59,21 @@ public class TtMerchantPoiSchedule { // } // } - @Async - @Scheduled(cron = "0 0 */1 * * *?") // 每小时检查一次 - public void supplierQueryTaskSchedule() { - TtCouponChannelPoi ttCouponChannelPoi = new TtCouponChannelPoi(); - ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); - List list = ttCouponChannelPoiMapper.findList(ttCouponChannelPoi); - if(list != null && list.size() > 0){ - for (TtCouponChannelPoi poi:list) { - try{ - ttMerchantPoiService.spuGet(poi,poi.getId()); - }catch(Exception e){ - logger.error("查询商品同步任务失败"); - } - } - } - } +// @Async +// @Scheduled(cron = "0 0 */1 * * *?") // 每小时检查一次 +// public void supplierQueryTaskSchedule() { +// TtCouponChannelPoi ttCouponChannelPoi = new TtCouponChannelPoi(); +// ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); +// List list = ttCouponChannelPoiMapper.findList(ttCouponChannelPoi); +// if(list != null && list.size() > 0){ +// for (TtCouponChannelPoi poi:list) { +// try{ +// ttMerchantPoiService.spuGet(poi,poi.getId()); +// }catch(Exception e){ +// logger.error("查询商品同步任务失败"); +// } +// } +// } +// } } \ No newline at end of file diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/TtOrderPushErrorSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/TtOrderPushErrorSchedule.java index d91f80c46..78dddb7a4 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/TtOrderPushErrorSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/TtOrderPushErrorSchedule.java @@ -24,13 +24,13 @@ public class TtOrderPushErrorSchedule { private WxOrderService wxOrderService; @Async - @Scheduled(cron = "0 0 1 * * ?") + @Scheduled(cron = "0 0 */2 * * ?") public void OrderPushErrorTaskSchedule() { List orderPushErrors = ttOrderPushErrorMapper.findList(new TtOrderPushError()); if(orderPushErrors != null && orderPushErrors.size() > 0){ for (TtOrderPushError error:orderPushErrors) { try{ - wxOrderService.sendInsideOrderPushMsg(error,error.getId()); + wxOrderService.sendInsideOrderPushDeliveryMsg(error,null,error.getId()); }catch(Exception e){ logger.error("订单同步重试error"); } diff --git a/mallinkService/src/main/java/com/iformall/domain/dto/PlatPushOrderSaveDto.java b/mallinkService/src/main/java/com/iformall/domain/dto/PlatPushOrderSaveDto.java new file mode 100644 index 000000000..04d4a6edb --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/dto/PlatPushOrderSaveDto.java @@ -0,0 +1,32 @@ +package com.iformall.domain.dto; + +import lombok.Data; +import java.io.Serializable; + +import com.iformall.domain.po.UserBasicInfoAddress; +import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.WxCouponChannel; + +@Data +public class PlatPushOrderSaveDto implements Serializable { + + private static final long serialVersionUID = 1L; + + Long couponChannelId;//【传入参数】渠道商品编号,对饮我们系统的编号 + + int count;//【传入参数】购买数量 + + Long orderGroupId;//【传入参数】拼团主订单号 + + boolean isPress = false;//【传入参数】,是否砍价 + String formId ; //【传入参数】,非必传 + + Integer shippingType = 0;//EnumOrderShopingType【传入参数】配送类型 + UserBasicInfoAddress address;//【传入参数】配送地址 + + String extParam;//数组格式长度与数量一致(一个券一个订单时)【传入参数】json,额外的信息,可能每个平台不一样 + + WxCoupon wxCoupon;//【非传入参数】。 + WxCouponChannel wxCouponChannel;//【非传入参数】。 + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/TtCouponChannelPoi.java b/mallinkService/src/main/java/com/iformall/domain/po/TtCouponChannelPoi.java index cdd8c0eba..03866d5ab 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/TtCouponChannelPoi.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/TtCouponChannelPoi.java @@ -17,11 +17,15 @@ import java.util.Date; @EqualsAndHashCode(callSuper = true) public class TtCouponChannelPoi extends TenantEntity { - protected Long id;//coupon_channel_id + protected Long id;//coupon_id + + @io.swagger.annotations.ApiModelProperty(value="couponChannelId",name="couponChannelId") + private Long couponChannelId; @io.swagger.annotations.ApiModelProperty(value="spuId",name="spuId") private String spuId; + //该字段状态更新不及时,不作为业务使用 @io.swagger.annotations.ApiModelProperty(value="状态:0-审核中,1-上架,2-下架,3-审核拒绝 4-审核通过",name="status") private Integer status; diff --git a/mallinkService/src/main/java/com/iformall/domain/po/TtGoodsCategory.java b/mallinkService/src/main/java/com/iformall/domain/po/TtGoodsCategory.java new file mode 100644 index 000000000..70ca2606b --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/TtGoodsCategory.java @@ -0,0 +1,29 @@ +package com.iformall.domain.po; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.iformall.domain.po.base.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; +import java.util.List; + +@TableName(value = "tt_goods_category") +@Data +@EqualsAndHashCode(callSuper = true) +public class TtGoodsCategory extends BaseEntity { + + protected Integer id; + + @io.swagger.annotations.ApiModelProperty(value="",name="name") + private String name; + + @io.swagger.annotations.ApiModelProperty(value="",name="parentId") + private Integer parentId; + + @TableField(exist = false) + protected List child; + + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxBatchOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/WxBatchOrder.java index f96e0d7fd..a00ce763a 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxBatchOrder.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxBatchOrder.java @@ -1,5 +1,8 @@ package com.iformall.domain.po; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.iformall.domain.po.base.TenantEntity; @@ -42,6 +45,9 @@ public class WxBatchOrder extends TenantEntity { @io.swagger.annotations.ApiModelProperty(value = "EnumYesOrNo是否抖音poi订单", name = "isTtPoiOrder") private Integer isTtPoiOrder; + + @io.swagger.annotations.ApiModelProperty(value = "额外参数,总参数", name = "extParam") + private String extParam; @TableField(exist = false) @io.swagger.annotations.ApiModelProperty(value = "订单集合", name = "orders") @@ -56,4 +62,15 @@ public class WxBatchOrder extends TenantEntity { return null; } + public Object getExpParamValue(String key) { + if (StringUtils.isBlank(extParam)) { + return null; + } + JSONObject o = JSON.parseObject(extParam); + if (null == o ) { + return null; + } + return o.get(key); + } + } diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCoupon.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCoupon.java index c9c7340cf..4cd44e360 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCoupon.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCoupon.java @@ -1,10 +1,12 @@ package com.iformall.domain.po; +import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.iformall.common.SortColumn; import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.vo.WxCouponStatisVo; +import com.iformall.douyin.web.bean.GoodsTemplateGet; import com.iformall.enums.EnumCouponType; import com.iformall.enums.EnumValidStatus; import com.iformall.utils.Constant; @@ -14,6 +16,7 @@ import cn.afterturn.easypoi.excel.annotation.Excel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; @@ -237,9 +240,60 @@ public class WxCoupon extends TenantEntity { @io.swagger.annotations.ApiModelProperty(value="富文本内容",name="html") private String html; - //List String @io.swagger.annotations.ApiModelProperty(value="卷包内容",name="giftList") private String giftList; + + @io.swagger.annotations.ApiModelProperty(value="EnumTtProductType",name="productType") + private Integer productType; + + @io.swagger.annotations.ApiModelProperty(value="tt_goods_category",name="categoryId") + private Integer categoryId; + + @io.swagger.annotations.ApiModelProperty(value="JSON",name="productAttrs") + private String productAttrs; + + @TableField(exist = false) + private Map productAttrKeyValueMap; + + public Map getProductAttrKeyValueMap(){ + Map productAttrKeyValueMap = new HashMap<>(); + if(StringUtils.isNotBlank(productAttrs)){ + try{ + List productAttrs = JSONObject.parseArray(this.productAttrs, GoodsTemplateGet.ProductAttrs.class); + for (GoodsTemplateGet.ProductAttrs attr:productAttrs) { + if(StringUtils.isNotBlank(attr.getData())){ + productAttrKeyValueMap.put(attr.getKey(),attr.getData()); + } + } + }catch(Exception e){ + } + + } + return productAttrKeyValueMap; + } + + @io.swagger.annotations.ApiModelProperty(value="JSON",name="skuAttrs") + private String skuAttrs; + + @TableField(exist = false) + private Map skuAttrKeyValueMap; + + public Map getSkuAttrKeyValueMap(){ + Map skuAttrKeyValueMap = new HashMap<>(); + if(StringUtils.isNotBlank(skuAttrs)){ + try{ + List skuAttrs = JSONObject.parseArray(this.skuAttrs, GoodsTemplateGet.ProductAttrs.class); + for (GoodsTemplateGet.ProductAttrs attr:skuAttrs) { + if(StringUtils.isNotBlank(attr.getData())){ + skuAttrKeyValueMap.put(attr.getKey(),attr.getData()); + } + } + }catch(Exception e){ + } + + } + return skuAttrKeyValueMap; + } @TableField(exist = false) private List giftCouponList; diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponOrder.java index 61d7a5292..ea550a2e6 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponOrder.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponOrder.java @@ -1,5 +1,8 @@ package com.iformall.domain.po; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; @@ -83,6 +86,21 @@ public class WxCouponOrder extends TenantEntity { @io.swagger.annotations.ApiModelProperty(value="补贴",name="subsidy") private Integer subsidy; + + @io.swagger.annotations.ApiModelProperty(value="额外参数,用于第三方平台",name="extParam") + private String extParam; + + public Object getExpParamValue(String key) { + if (StringUtils.isBlank(extParam)) { + return null; + } + JSONObject o = JSON.parseObject(extParam); + if (null == o ) { + return null; + } + return o.get(key); + } + @TableField(exist = false) private String couponName; diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java b/mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java index 413c1d7f6..c4fa93c1f 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java @@ -346,6 +346,10 @@ public class WxMerchant extends TenantEntity { @TableField(exist = false) private String addr; + @io.swagger.annotations.ApiModelProperty(value=" supplierExtId",name="supplierExtId") + @TableField(exist = false) + private String supplierExtId; + @io.swagger.annotations.ApiModelProperty(value="ttPoi",name="ttPoi") @TableField(exist = false) private String ttPoi; diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/WxOrder.java index 9feeede8c..2ee93600a 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxOrder.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxOrder.java @@ -1,6 +1,10 @@ package com.iformall.domain.po; import cn.afterturn.easypoi.excel.annotation.Excel; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.iformall.common.SortColumn; @@ -119,6 +123,19 @@ public class WxOrder extends TenantEntity { @io.swagger.annotations.ApiModelProperty(value="父订单编号",name="parentOrderId") private Long parentOrderId; + @io.swagger.annotations.ApiModelProperty(value="额外参数,用于第三方平台",name="extParam") + private String extParam; + + public Object getExpParamValue(String key) { + if (StringUtils.isBlank(extParam)) { + return null; + } + JSONObject o = JSON.parseObject(extParam); + if (null == o ) { + return null; + } + return o.get(key); + } @TableField(exist = false) protected List couponIds; diff --git a/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideOrderPushMsg.java b/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideOrderPushMsg.java index 3423fbe04..de0ce14d8 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideOrderPushMsg.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideOrderPushMsg.java @@ -12,4 +12,7 @@ public class FmInsideOrderPushMsg extends BaseMsg{ @io.swagger.annotations.ApiModelProperty(value = "", name = "composeOrderId") private Long batchOrderId; + @io.swagger.annotations.ApiModelProperty(value = "", name = "couponOrderId") + private Long couponOrderId; + } diff --git a/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideProductPushMsg.java b/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideProductPushMsg.java index 36941991c..49605fece 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideProductPushMsg.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideProductPushMsg.java @@ -10,8 +10,8 @@ import lombok.ToString; @EqualsAndHashCode(callSuper = true) public class FmInsideProductPushMsg extends BaseMsg{ - @io.swagger.annotations.ApiModelProperty(value = "卷Id", name = "couponChannelId") - private Long couponChannelId; + @io.swagger.annotations.ApiModelProperty(value = "卷Id", name = "couponId") + private Long couponId; @io.swagger.annotations.ApiModelProperty(value = "同步类型", name = "syncType") private EnumPushType syncType; diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponChannelVo.java b/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponChannelVo.java new file mode 100644 index 000000000..797de8b5c --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponChannelVo.java @@ -0,0 +1,41 @@ +package com.iformall.domain.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.WxCouponChannel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * Created by syf on 2018/8/22. + */ +@JsonIgnoreProperties(value = {"handler"}) +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class TtCouponChannelVo extends WxCouponChannelVo implements Serializable { + private static final long serialVersionUID = 1L; + + @io.swagger.annotations.ApiModelProperty(value="spuId",name="spuId") + private String spuId; + + @io.swagger.annotations.ApiModelProperty(value="状态:0-审核中,1-上架,2-下架,3-审核拒绝 4-审核通过",name="poiStatus") + private Integer poiStatus; + + @io.swagger.annotations.ApiModelProperty(value="描述",name="statusDesc") + private String statusDesc; + + @io.swagger.annotations.ApiModelProperty(value="状态:0-审核中,1-上架,2-下架,3-审核拒绝 4-审核通过",name="lastStatus") + private Integer lastStatus; + + @io.swagger.annotations.ApiModelProperty(value="描述",name="lastStatusDesc") + private String lastStatusDesc; + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponVo.java b/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponVo.java new file mode 100644 index 000000000..a583d30cf --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/vo/TtCouponVo.java @@ -0,0 +1,34 @@ +package com.iformall.domain.vo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.iformall.domain.po.WxCoupon; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class TtCouponVo extends WxCoupon implements Serializable { + private static final long serialVersionUID = 1L; + + @io.swagger.annotations.ApiModelProperty(value="couponChannelId",name="couponChannelId") + private Long couponChannelId; + + @io.swagger.annotations.ApiModelProperty(value="spuId",name="spuId") + private String spuId; + + @io.swagger.annotations.ApiModelProperty(value="状态:0-审核中,1-上架,2-下架,3-审核拒绝 4-审核通过",name="poiStatus") + private Integer poiStatus; + + @io.swagger.annotations.ApiModelProperty(value="描述",name="statusDesc") + private String statusDesc; + + @io.swagger.annotations.ApiModelProperty(value="状态:0-审核中,1-上架,2-下架,3-审核拒绝 4-审核通过",name="lastStatus") + private Integer lastStatus; + + @io.swagger.annotations.ApiModelProperty(value="描述",name="lastStatusDesc") + private String lastStatusDesc; +} diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderBVo.java b/mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderBVo.java index 34f65d7cc..ab0343d1d 100644 --- a/mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderBVo.java +++ b/mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderBVo.java @@ -220,6 +220,8 @@ public class WxCouponOrderBVo extends WxCouponOrder { @Excel(name = "核销商户", width = 50, orderNum = "4") @TableField(exist = false) private String verifyMerchantName; + @TableField(exist = false) + private Long verifyMerchantId; @TableField(exist = false) private Long floor; diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/WxMerchantVo.java b/mallinkService/src/main/java/com/iformall/domain/vo/WxMerchantVo.java index 9d62e49f4..fbd2c1ed0 100644 --- a/mallinkService/src/main/java/com/iformall/domain/vo/WxMerchantVo.java +++ b/mallinkService/src/main/java/com/iformall/domain/vo/WxMerchantVo.java @@ -101,6 +101,10 @@ public class WxMerchantVo extends TenantEntity { @io.swagger.annotations.ApiModelProperty(value = "置顶时间", name = "topTime") private Date topTime; + @io.swagger.annotations.ApiModelProperty(value=" supplierExtId",name="supplierExtId") + @TableField(exist = false) + private String supplierExtId; + @io.swagger.annotations.ApiModelProperty(value="ttPoi",name="ttPoi") @TableField(exist = false) private String ttPoi; @@ -132,6 +136,7 @@ public class WxMerchantVo extends TenantEntity { this.linkLinePhone = m.getLinkLinePhone(); this.topTime = m.getTopTime(); this.addr = m.getAddr(); + this.supplierExtId = m.getSupplierExtId(); this.ttPoi = m.getTtPoi(); this.longitude = m.getLongitude(); this.latitude = m.getLatitude(); diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/DouYinPayHelper.java b/mallinkService/src/main/java/com/iformall/douyin/pay/DouYinPayHelper.java index 779de588d..3d687fb31 100644 --- a/mallinkService/src/main/java/com/iformall/douyin/pay/DouYinPayHelper.java +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/DouYinPayHelper.java @@ -6,7 +6,6 @@ import java.security.NoSuchAlgorithmException; import java.util.*; import com.iformall.common.ErrorCode; -import com.iformall.douyin.pay.enums.AppAddSubMerchantUrlType; import com.iformall.douyin.pay.orderQuery.QueryMerchantResult; import com.iformall.douyin.pay.orderQuery.QueryRefundResult; import com.iformall.douyin.pay.orderQuery.QuerySettleResult; @@ -22,7 +21,6 @@ import com.iformall.utils.HttpUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import springfox.documentation.spring.web.json.Json; /** * 抖音小程序支付 @@ -356,48 +354,52 @@ public class DouYinPayHelper { public static void main(String[] args) { //测试 // String mcuid = "70777649963225930610";//商户号 - String appid = "ttef6599d8705b49b101"; - String salt = "G8DdHfRcEPXB8kHQsnpVWvhLfMC7MZQ72aweTei8";//支付密钥 +// String appid = "ttef6599d8705b49b101"; +// String salt = "G8DdHfRcEPXB8kHQsnpVWvhLfMC7MZQ72aweTei8";//支付密钥 //生产 // String mcuid = "69739487619282066230"; -// String appid = "tt8183f73e1ebb053701"; -// String salt = "rtQwyvhZHMuMYrY6GBm8DnhvEu0fuJUVHYS2KP6P"; + String appid = "ttc0cdb6705ff345f301"; + String salt = "FhGHClzfdDEPW6Cq4hw2GyoynJbpeq6wLQyM5iub"; - AppAddSubMerchant appAddSubMerchant = new AppAddSubMerchant(); - appAddSubMerchant.setAppId("ttef6599d8705b49b101"); - appAddSubMerchant.setSalt("G8DdHfRcEPXB8kHQsnpVWvhLfMC7MZQ72aweTei8"); - appAddSubMerchant.setSubMerchantId("666438479039619072"); - appAddSubMerchant.setUrlType(2); - AppAddSubMerchantResult appAddSubMerchantResult = appAddSubMerchant(appAddSubMerchant); - System.out.println(appAddSubMerchantResult.toString()); +// AppAddSubMerchant appAddSubMerchant = new AppAddSubMerchant(); +// appAddSubMerchant.setAppId("ttef6599d8705b49b101"); +// appAddSubMerchant.setSalt("G8DdHfRcEPXB8kHQsnpVWvhLfMC7MZQ72aweTei8"); +// appAddSubMerchant.setSubMerchantId("666438479039619072"); +// appAddSubMerchant.setUrlType(2); +// AppAddSubMerchantResult appAddSubMerchantResult = appAddSubMerchant(appAddSubMerchant); +// System.out.println(appAddSubMerchantResult.toString()); // Settle settle = new Settle(); // settle.setAppId(appid); // settle.setSalt(salt); ///** -// * {"settle_params":"[{\"amount\":19,\"merchant_uid\":\"69798058370993871733\"}]", -// * "settle_desc":"客户提现。", -// * "sign":"94fa5f559880870f2fda53c67b236a3f", -// * "out_settle_no":"572578660822212608", -// * "out_order_no":"572308600038809600", -// * "app_id":"tt9da4eb19029c2bb301"} +// * {settle_params=[{"amount":6859,"merchant_uid":"70878359464980830803"}], +// * settle_desc=自主完结分账, sign=9acc782f9196bb45823fdbe7e14b24df, +// * out_settle_no=687210710707761152, +// * out_order_no=687209074036342784, app_id=ttc0cdb6705ff345f301} +// * response:{"err_no":6006,"err_tips":"其他分账方分账比例超限","settle_no":""} +// * +// * request:{settle_params=[{"amount":6900,"merchant_uid":"70878359464980830803"}], +// * settle_desc=自主完结分账, sign=d3541104ea0a6234f96ea753aa514f7c, +// * out_settle_no=687210746524631040, out_order_no=687208992638238720, app_id=ttc0cdb6705ff345f301} +// * response:{"err_no":6006,"err_tips":"其他分账方分账比例超限","settle_no":""} // */ -// settle.setOutSettleNo("57257866081118888"); -// settle.setOutOrderNo("613967802405908480"); +// settle.setOutSettleNo("687210746524631040"); +// settle.setOutOrderNo("687208992638238720"); // settle.setSettleDesc("手动处理。"); // List list = new ArrayList<>(); // Map settleParams = new HashMap<>(); -// settleParams.put("merchant_uid",mcuid); -// settleParams.put("amount",5); +// settleParams.put("merchant_uid","70878359464980830803"); +// settleParams.put("amount",6859); // list.add(settleParams); // settle.setSettleParams(JSON.toJSONString(list)); // SettleResult settle1 = settle(settle); // System.out.println(settle1.toString()); -// QuerySettleResult querySettleResult = settleQuery(appid, salt, "57257866081118888", null); -// System.out.println(querySettleResult.toString()); + QuerySettleResult querySettleResult = settleQuery(appid, salt, "687210746524631040", null); + System.out.println(querySettleResult.toString()); // OrderQueryResult orderQueryResult = orderQuery(appid, salt, "613879951804915712", null); // System.out.println(orderQueryResult.toString()); diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/ProfitSharingV2Service.java b/mallinkService/src/main/java/com/iformall/douyin/pay/ProfitSharingV2Service.java new file mode 100644 index 000000000..2468d6a96 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/ProfitSharingV2Service.java @@ -0,0 +1,48 @@ +package com.iformall.douyin.pay; + +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.request.ProfitSharingRequest; +import com.iformall.douyin.payv2.result.ProfitSharingResult; + +/** + * 支付V2-资金应用-分账 + * https://bytedance.feishu.cn/docx/doxcnj21j74jHyXEq6Ybg3AzOxh + * @author pg 2021-6-23 + * @date 2021-6-23 + */ +public interface ProfitSharingV2Service { + + /** + *
+   * 请求分账API
+   * 接口简介
+   * 一笔订单完成后,开发者可以通过分账接口将这笔订单产生的资金结算给各个分账方。
+   * - 结算规则统一为核销D+3;
+   *   - CPS订单比较特殊,统一结算规则是核销D+3
+   *   - 结算规则为核销D+3,表示订单到达“终态”3天后可以分账,“终态”表示所有的券/商品已核销或已退款
+   * - 如对上述结算规则有特殊需求,请联系对应行业经理(餐饮@Xinru Chen 酒旅@Jie Zhou @Yuekai Zhao 到综@Yankai Ouyang )
+   * - 若分账失败,请参考文档进行自查分账失败如何自查
+   * 核销D+3
+   * - 例如用户的一笔订单买了5张团购券,其中3张先核销,剩余2张再退款,最终退款完成的时间就是订单到达终态的时间。订单到达终态3天后,则可以发起分账
+   *
+   * 返回 小程序分账id,系统会确保不超过64个字节(数字+ASCII)
+   *
+   */
+  String profitSharing(ProfitSharingRequest request) throws TtPayException;
+
+  /**
+   * 
+   * 查询分账接口
+   * out_order_no string 否 开发者交易订单id,长度<64byte,数字ASCII字符
+   * out_settle_no string 否 开发者分账单id,长度<64byte,数字、ASCII字符
+   * order_id string 否 抖音开平侧订单id,长度<64byte,数字、ASCII
+   * settle_id string 否 抖音开平侧分账单id,长度<64byte,数字、ASCII
+   * - 查询优先级: settle_id > order_id > out_settle_no > out_order_no,4个参数选填一个
+   *   - 例如:请求填写了settle_id和order_id,服务只会按settle_id来查询,忽略order_id
+   *   - 如果未查询到结果,会返回空数组
+   * - 注意:对于担保交易和交易1.0的订单,如果需要根据order_id/out_order_no查询订单的分账记录,建议使用order_id(抖音开平侧支付单id查询),若使用out_order_no可能存在查询不到的情况
+   *
+   */
+  ProfitSharingResult getProfitSharingResult(String out_settle_no) throws TtPayException;
+
+}
diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/TtPayService.java b/mallinkService/src/main/java/com/iformall/douyin/pay/TtPayService.java
new file mode 100644
index 000000000..0a0a70c70
--- /dev/null
+++ b/mallinkService/src/main/java/com/iformall/douyin/pay/TtPayService.java
@@ -0,0 +1,201 @@
+package com.iformall.douyin.pay;
+
+import com.github.binarywang.wxpay.bean.WxPayApiData;
+import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
+import com.iformall.douyin.pay.exception.TtPayException;
+import com.iformall.douyin.payv2.config.TtPayConfig;
+import com.iformall.douyin.payv2.request.*;
+import com.iformall.douyin.payv2.result.*;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+
+
+/**
+ * 
+ * 支付相关接口.
+ * Created by Binary Wang on 2016/7/28.
+ * 
+ * + */ +public interface TtPayService { + + /** + * 获取微信支付请求url前缀,沙箱环境可能不一样. + * + * @return the pay base url + */ + String getPayBaseUrl(); + + + /** + * 发送post请求,得到响应字符串. + * + * @param url 请求地址 + * @param requestStr 请求信息 + * @return 返回请求结果字符串 string + * @throws TtPayException the tt pay exception + */ + String postV2(String url, String requestStr) throws TtPayException; + + /** + * 发送post请求,得到响应字符串. + * + * @param url 请求地址 + * @param httpPost 请求信息 + * @return 返回请求结果字符串 string + * @throws TtPayException the tt pay exception + */ + String postV2(String url, HttpPost httpPost) throws TtPayException; + + /** + * 发送http请求,得到响应字符串. + * + * @param url 请求地址 + * @param httpRequest 请求信息,可以是put,post,get,delete等请求 + * @return 返回请求结果字符串 string + * @throws TtPayException the tt pay exception + */ + String requestV2(String url, HttpRequestBase httpRequest) throws TtPayException; + + /** + * 发送get V2请求,得到响应字符串. + * + * @param url 请求地址 + * @return 返回请求结果字符串 string + * @throws TtPayException the tt pay exception + */ + String getV2(String url) throws TtPayException; + + /** + * 获取分账服务类. + * + * @return the ent pay service + */ + ProfitSharingV2Service getProfitSharingV2Service(); + + + /** + * 2.1 交易回调设置接口 + */ + boolean callbackSettings(CallBackSettingsRequest settings) throws TtPayException; + + + /** + * 2.2 查询交易回调设置接口 + */ + CallBackSettingsRequest querySettings() throws TtPayException; + + + /** + * 解析预下单回调 + * + */ + CreateOrderCallback parseOrderNotifyV2Result(String notifyData, SignatureHeader header) throws TtPayException; + + + /** + * 交易系统2.0模版下单依赖入口前端js-api,如果用户没有更新抖音,就没法使用模版下单,开发者可用该接口替用户发起下单,开发者发起的下单流程则不会有预下单回调,当低版本减少后,会下掉该接口,请不要应用于其它场景,否则会影响业务(对于poi商品,目前只支持团购券) + * @param request + * @return + * @throws TtPayException + */ + TtPayUnifiedOrderV2Result createOrderV2(TtPayUnifiedOrderV2Request request) throws TtPayException; + + + + /** + *
+   * 5. 订单信息接口
+   */
+  TtPayOrderQueryV2Result queryOrderV2(String orderId, String outOrderNo) throws TtPayException;
+
+  /**
+   * 
+   * 5. 订单信息接口
+   */
+  TtPayOrderQueryV2Result queryOrderV2(TtPayOrderQueryV2Request request) throws TtPayException;
+
+  /**
+   * 
+   * 5. cps订单信息接口
+   */
+  TtPayCpsOrderQueryV2Result queryCpsOrderV2(String orderId, String outOrderNo) throws TtPayException;
+
+  /**
+   * 推送核销状态(非闭环核销)
+   */
+  boolean pushDelivery(TtOrderPushDeliveryRequest request) throws TtPayException;
+
+
+  /**
+   * 获取配置.
+   *
+   * @return the config
+   */
+  TtPayConfig getConfig();
+
+  /**
+   * 设置配置对象.
+   *
+   * @param config the config
+   */
+  void setConfig(TtPayConfig config);
+
+  /**
+   * 
+   * 开发者可用该接口替用户发起退款,开发者发起的退款流程则不会有退款申请回调。
+   * - 过期自动退说明
+   *   - 过期自动退的退款被拒绝退款后,不会再次发起。
+   *   - 在交易系统2.0产生的订单,如果用户购买的商品是过期退商品,交易系统2.0会自动发起退款,创建退款单,退款流程和用户发起退款流程相同。
+   *   - 发起过期自动退条件
+   *     - 非POI 商品
+   *       - 前端传入合法的商品过期时间
+   *       - 前端传入的goodsLabels中包含过期退标签
+   *     - POI 商品
+   *       - POI 商品设置了过期时间
+   *       - POI 商品的 sub_title包含过期退标签
+   *   - 旧订单系统不会自动发起过期自动退,仍需开发者处理。
+   *     - 过期自动退的退款单由系统创建,因此 退款申请回调和状态通知回调 cp_extra 会是空值。
+   * - 外部退款单号说明
+   *   - 已经在担保支付或者交易1.0使用过的外部退款单号,请不要在交易2.0使用,当交易2.0系统发现该外部退款单号已经在担保支付或者交易1.0创建过退款单号时,会拒绝创建退款单。
+   *   - 已经升级到交易2.0的接口之后,不支持再降级使用交易1.0,否则产生的后果由开发者承担。
+   */
+  TtPayRefundV2Result refundV2(TtPayRefundV2Request request) throws TtPayException;
+
+  /**
+   * 5. 退款申请回调
+   * 当用户从交易的模板组件发起退款后,抖音开平交易系统会给向开发者的服务发起请求,用于通知开发者用户发起退款,开发者响应时需要返回必填的信息。
+   * 注意
+   * - 退款单的创建是在退款申请回调之前,退款申请回调请求开发者服务失败,也不会在C端展示错误,退款申请回调请求失败后会进行重试。
+   * - 请务必确保退款申请回调请求能按照正确的格式和参数要求返回。
+   * - 请求返回的外部退款单号也务必确保在同一小程序内不会重复,否则也会被认为请求失败。
+   * - 开发者返回的err_no 不为 0 也会认为请求失败,会进行重试,请确保请求成功,有拒绝退款的场景请在退款审核阶段拒绝退款。
+   * - 如果一直请求开发者服务失败,退款单将无法被推进到退款审核阶段,请务必确保响应无问题。
+   * - 退款申请回调务必做好幂等处理,相同的系统退款单号重复请求应当被视为相同的一次退款。
+   *
+   */
+  RefundOrderCallback refundOrderNotifyV2Result(String notifyData, SignatureHeader header) throws TtPayException;
+
+  /**
+   * 退款审核结果同步
+   * @param request
+   * @return
+   * @throws TtPayException
+   */
+  boolean merchantAuditCallback(TtRefundAuditMsgRequest request) throws TtPayException;
+
+  /**
+   * 
+   * 查询退款
+   *
+   */
+  TtPayRefundQueryV2Result refundQueryV2(TtPayRefundQueryV2Request request) throws TtPayException;
+
+  /**
+   * 获取微信请求数据,方便接口调用方获取处理.
+   *
+   * @return the wx api data
+   */
+  WxPayApiData getWxApiData();
+
+}
diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/exception/TtPayException.java b/mallinkService/src/main/java/com/iformall/douyin/pay/exception/TtPayException.java
new file mode 100644
index 000000000..c73d12b21
--- /dev/null
+++ b/mallinkService/src/main/java/com/iformall/douyin/pay/exception/TtPayException.java
@@ -0,0 +1,216 @@
+package com.iformall.douyin.pay.exception;
+
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.google.common.base.Joiner;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 
+ * 支付异常结果类
+ * Created by Binary Wang on 2017-6-6.
+ * 
+ * + * @author BinaryWang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class TtPayException extends Exception { + + private static final long serialVersionUID = -1246675502834889819L; + /** + * 自定义错误讯息. + */ + private String customErrorMsg; + /** + * 返回状态码. + */ + private String returnCode; + /** + * 返回信息. + */ + private String returnMsg; + + /** + * 业务结果. + */ + private String resultCode; + + /** + * 错误代码. + */ + private String errCode; + + /** + * 错误代码描述. + */ + private String errCodeDes; + + /** + * 微信支付返回的结果xml字符串. + */ + private String xmlString; + + /** + * Instantiates a new Wx pay exception. + * + * @param customErrorMsg the custom error msg + */ + public TtPayException(String customErrorMsg) { + super(customErrorMsg); + this.customErrorMsg = customErrorMsg; + } + + /** + * Instantiates a new Wx pay exception. + * + * @param customErrorMsg the custom error msg + * @param tr the tr + */ + public TtPayException(String customErrorMsg, Throwable tr) { + super(customErrorMsg, tr); + this.customErrorMsg = customErrorMsg; + } + + private TtPayException(Builder builder) { + super(builder.buildErrorMsg()); + returnCode = builder.returnCode; + returnMsg = builder.returnMsg; + resultCode = builder.resultCode; + errCode = builder.errCode; + errCodeDes = builder.errCodeDes; + xmlString = builder.xmlString; + } + + /** + * 通过BaseWxPayResult生成异常对象. + * + * @param payBaseResult the pay base result + * @return the wx pay exception + */ + public static TtPayException from(BaseWxPayResult payBaseResult) { + return TtPayException.newBuilder() + .xmlString(payBaseResult.getXmlString()) + .returnMsg(payBaseResult.getReturnMsg()) + .returnCode(payBaseResult.getReturnCode()) + .resultCode(payBaseResult.getResultCode()) + .errCode(payBaseResult.getErrCode()) + .errCodeDes(payBaseResult.getErrCodeDes()) + .build(); + } + + /** + * New builder builder. + * + * @return the builder + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * The type Builder. + */ + public static final class Builder { + private String returnCode; + private String returnMsg; + private String resultCode; + private String errCode; + private String errCodeDes; + private String xmlString; + + private Builder() { + } + + /** + * Return code builder. + * + * @param returnCode the return code + * @return the builder + */ + public Builder returnCode(String returnCode) { + this.returnCode = returnCode; + return this; + } + + /** + * Return msg builder. + * + * @param returnMsg the return msg + * @return the builder + */ + public Builder returnMsg(String returnMsg) { + this.returnMsg = returnMsg; + return this; + } + + /** + * Result code builder. + * + * @param resultCode the result code + * @return the builder + */ + public Builder resultCode(String resultCode) { + this.resultCode = resultCode; + return this; + } + + /** + * Err code builder. + * + * @param errCode the err code + * @return the builder + */ + public Builder errCode(String errCode) { + this.errCode = errCode; + return this; + } + + /** + * Err code des builder. + * + * @param errCodeDes the err code des + * @return the builder + */ + public Builder errCodeDes(String errCodeDes) { + this.errCodeDes = errCodeDes; + return this; + } + + /** + * Xml string builder. + * + * @param xmlString the xml string + * @return the builder + */ + public Builder xmlString(String xmlString) { + this.xmlString = xmlString; + return this; + } + + /** + * Build wx pay exception. + * + * @return the wx pay exception + */ + public TtPayException build() { + return new TtPayException(this); + } + + /** + * Build error msg string. + * + * @return the string + */ + public String buildErrorMsg() { + return Joiner.on(",").skipNulls().join( + returnCode == null ? null : String.format("返回代码:[%s]", returnCode), + returnMsg == null ? null : String.format("返回信息:[%s]", returnMsg), + resultCode == null ? null : String.format("结果代码:[%s]", resultCode), + errCode == null ? null : String.format("错误代码:[%s]", errCode), + errCodeDes == null ? null : String.format("错误详情:[%s]", errCodeDes), + xmlString == null ? null : "返回的原始报文:\n" + xmlString + ); + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/impl/BaseTtPayServiceImpl.java b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/BaseTtPayServiceImpl.java new file mode 100644 index 000000000..c7a8779bc --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/BaseTtPayServiceImpl.java @@ -0,0 +1,255 @@ +package com.iformall.douyin.pay.impl; + +import com.alibaba.fastjson.TypeReference; +import com.github.binarywang.wxpay.bean.WxPayApiData; +import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.v3.util.AesUtils; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.iformall.douyin.pay.ProfitSharingV2Service; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.config.TtPayConfig; +import com.iformall.douyin.payv2.request.*; +import com.iformall.douyin.payv2.result.*; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.util.*; + +/** + *
+ *  支付接口请求抽象实现类
+ * Created by Binary Wang on 2017-7-8.
+ * 
+ * + * @author Binary Wang + */ +public abstract class BaseTtPayServiceImpl implements TtPayService { + private static final String TOTAL_FUND_COUNT = "资金流水总笔数"; + /** + * The Log. + */ + final Logger log = LoggerFactory.getLogger(this.getClass()); + + private static final Gson GSON = new GsonBuilder().create(); + /** + * The constant wxApiData. + */ + static ThreadLocal wxApiData = new ThreadLocal<>(); + + private ProfitSharingV2Service profitSharingV2Service = new ProfitSharingV2ServiceImpl(this); + + /** + * The Config. + */ + protected TtPayConfig config; + + @Override + public ProfitSharingV2Service getProfitSharingV2Service() { + return profitSharingV2Service; + } + + @Override + public TtPayConfig getConfig() { + return this.config; + } + + @Override + public void setConfig(TtPayConfig config) { + this.config = config; + } + + @Override + public String getPayBaseUrl() { + return this.getConfig().getPayBaseUrl(); + } + + @Override + public boolean callbackSettings(CallBackSettingsRequest request) throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/settings", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, BaseTtPayResult.class); + if(baseTtPayResult.isSuccess()){ + return true; + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public CallBackSettingsRequest querySettings() throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/query_settings", this.getPayBaseUrl()); + String response = this.postV2(url,""); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public CreateOrderCallback parseOrderNotifyV2Result(String notifyData, SignatureHeader header) throws TtPayException { + if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { + throw new TtPayException("非法请求,头部信息验证失败"); + } + OriginNotifyResponse response = GSON.fromJson(notifyData, OriginNotifyResponse.class); + try { + CreateOrderCallback createOrderCallback = GSON.fromJson(response.getMsg(), CreateOrderCallback.class); + return createOrderCallback; + } catch (Exception e) { + throw new TtPayException("解析报文异常!", e); + } + } + + /** + * 校验通知签名 + * + * @param header 通知头信息 + * @param data 通知数据 + * @return true:校验通过 false:校验不通过 + */ + private boolean verifyNotifySign(SignatureHeader header, String data) { + String beforeSign = String.format("%s\n%s\n%s\n", + header.getTimeStamp(), + header.getNonce(), + data); + return this.getConfig().getVerifier().verify( + beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned()); + } + + @Override + public TtPayUnifiedOrderV2Result createOrderV2(TtPayUnifiedOrderV2Request request) throws TtPayException{ + String url = String.format("%s/api/apps/trade/v2/create_order", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public TtPayOrderQueryV2Result queryOrderV2(String orderId, String outOrderNo) throws TtPayException { + TtPayOrderQueryV2Request request = new TtPayOrderQueryV2Request(); + request.setOutOrderNo(StringUtils.trimToNull(outOrderNo)); + request.setOrderId(StringUtils.trimToNull(orderId)); + return this.queryOrderV2(request); + } + + @Override + public TtPayOrderQueryV2Result queryOrderV2(TtPayOrderQueryV2Request request) throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/query_order", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + public TtPayCpsOrderQueryV2Result queryCpsOrderV2(String orderId, String outOrderNo) throws TtPayException{ + String url = String.format("%s/api/apps/trade/v2/query_cps", this.getPayBaseUrl()); + TtPayOrderQueryV2Request request = new TtPayOrderQueryV2Request(); + request.setOutOrderNo(StringUtils.trimToNull(outOrderNo)); + request.setOrderId(StringUtils.trimToNull(orderId)); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + + @Override + public boolean pushDelivery(TtOrderPushDeliveryRequest request) throws TtPayException{ + String url = String.format("%s/api/apps/trade/v2/push_delivery", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, BaseTtPayResult.class); + if(baseTtPayResult.isSuccess()){ + return true; + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + + } + + @Override + public TtPayRefundV2Result refundV2(TtPayRefundV2Request request) throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/create_refund", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public RefundOrderCallback refundOrderNotifyV2Result(String notifyData, SignatureHeader header) throws TtPayException { + if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) { + throw new TtPayException("非法请求,头部信息验证失败"); + } + OriginNotifyResponse response = GSON.fromJson(notifyData, OriginNotifyResponse.class); + try { + RefundOrderCallback refundOrderCallback = GSON.fromJson(response.getMsg(), RefundOrderCallback.class); + return refundOrderCallback; + } catch (Exception e) { + throw new TtPayException("解析报文异常!", e); + } + } + + @Override + public boolean merchantAuditCallback(TtRefundAuditMsgRequest request) throws TtPayException{ + String url = String.format("%s/api/apps/trade/v2/merchant_audit_callback", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, BaseTtPayResult.class); + if(baseTtPayResult.isSuccess()){ + return true; + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public TtPayRefundQueryV2Result refundQueryV2(TtPayRefundQueryV2Request request) throws TtPayException{ + String url = String.format("%s/api/apps/trade/v2/query_refund", this.getPayBaseUrl()); + String response = this.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(response, + new TypeReference>(){}.getType()); + if(baseTtPayResult.isSuccess()){ + return baseTtPayResult.getData(); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + + @Override + public WxPayApiData getWxApiData() { + try { + return wxApiData.get(); + } finally { + //一般来说,接口请求会在一个线程内进行,这种情况下,每个线程get的会是之前所存入的数据, + // 但以防万一有同一线程多次请求的问题,所以每次获取完数据后移除对应数据 + wxApiData.remove(); + } + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/impl/ProfitSharingV2ServiceImpl.java b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/ProfitSharingV2ServiceImpl.java new file mode 100644 index 000000000..534ad0700 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/ProfitSharingV2ServiceImpl.java @@ -0,0 +1,76 @@ +package com.iformall.douyin.pay.impl; + +import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.iformall.douyin.pay.ProfitSharingV2Service; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.auth.Verifier; +import com.iformall.douyin.payv2.request.ProfitSharingRequest; +import com.iformall.douyin.payv2.result.BaseTtPayResult; +import com.iformall.douyin.payv2.result.ProfitSharingResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.util.json.GsonHelper; + +import java.nio.charset.StandardCharsets; + +/** + * 支付V2-资金应用-分账Service + * + * @author pg 2021-6-23 + * @version 1.0 + */ +@Slf4j +@RequiredArgsConstructor +public class ProfitSharingV2ServiceImpl implements ProfitSharingV2Service { + private static final Gson GSON = new GsonBuilder().create(); + private final TtPayService payService; + + @Override + public String profitSharing(ProfitSharingRequest request) throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/create_settle", this.payService.getPayBaseUrl()); + String result = this.payService.postV2(url, GSON.toJson(request)); + BaseTtPayResult baseTtPayResult = GSON.fromJson(result, BaseTtPayResult.class); + if(baseTtPayResult.isSuccess()){ + Object data = baseTtPayResult.getData(); + JsonObject asJsonObject = GSON.toJsonTree(data).getAsJsonObject(); + return GsonHelper.getString(asJsonObject,"settle_id"); + }else{ + throw new TtPayException(baseTtPayResult.getErrTips()); + } + } + + @Override + public ProfitSharingResult getProfitSharingResult(String out_settle_no) throws TtPayException { + String url = String.format("%s/api/apps/trade/v2/query_settle", this.payService.getPayBaseUrl()); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("out_settle_no",out_settle_no); + String result = this.payService.postV2(url,jsonObject.toString()); + return GSON.fromJson(result, ProfitSharingResult.class); + } + + + + /** + * 校验通知签名 + * + * @param header 通知头信息 + * @param data 通知数据 + * @return true:校验通过 false:校验不通过 + */ + private boolean verifyNotifySign(SignatureHeader header, String data) throws TtPayException { + String beforeSign = String.format("%s\n%s\n%s\n", + header.getTimeStamp(), + header.getNonce(), + data); + Verifier verifier = this.payService.getConfig().getVerifier(); + if (verifier == null) { + throw new TtPayException("检验对象为空"); + } + return verifier.verify( + beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned()); + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceApacheHttpImpl.java b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceApacheHttpImpl.java new file mode 100644 index 000000000..0eeef429e --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceApacheHttpImpl.java @@ -0,0 +1,155 @@ +package com.iformall.douyin.pay.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.iformall.douyin.pay.exception.TtPayException; +import me.chanjar.weixin.common.util.json.GsonParser; +import org.apache.http.HttpStatus; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + + +/** + *
+ * 支付请求实现类,apache httpclient实现.
+ * Created by Binary Wang on 2016/7/28.
+ * 
+ * + */ +public class TtPayServiceApacheHttpImpl extends BaseTtPayServiceImpl { + + @Override + public String postV2(String url, String requestStr) throws TtPayException { + CloseableHttpClient httpClient = this.createApiV2HttpClient(); + HttpPost httpPost = this.createHttpPost(url, requestStr); + httpPost.addHeader("Accept", "application/json"); + httpPost.addHeader("Content-Type", "application/json"); + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + //v3已经改为通过状态码判断200 204 成功 + int statusCode = response.getStatusLine().getStatusCode(); + //post方法有可能会没有返回值的情况 + String responseString; + if (response.getEntity() == null) { + responseString = null; + } else { + responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + } + if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) { + this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); + return responseString; + } else { + //有错误提示信息返回 + JsonObject jsonObject = GsonParser.parse(responseString); + throw convertException(jsonObject); + } + } catch (Exception e) { + this.log.error("\n【请求地址】:{}\n【请求数据】:{}\n【异常信息】:{}", url, requestStr, e.getMessage()); + throw (e instanceof TtPayException) ? (TtPayException) e : new TtPayException(e.getMessage(), e); + } finally { + httpPost.releaseConnection(); + } + + + } + + @Override + public String postV2(String url, HttpPost httpPost) throws TtPayException { + return this.requestV2(url, httpPost); + } + + @Override + public String requestV2(String url, HttpRequestBase httpRequest) throws TtPayException { + httpRequest.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) + .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) + .setSocketTimeout(this.getConfig().getHttpTimeout()) + .build()); + + CloseableHttpClient httpClient = this.createApiV2HttpClient(); + try (CloseableHttpResponse response = httpClient.execute(httpRequest)) { + //v3已经改为通过状态码判断200 204 成功 + int statusCode = response.getStatusLine().getStatusCode(); + //post方法有可能会没有返回值的情况 + String responseString; + if (response.getEntity() == null) { + responseString = null; + } else { + responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + } + if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) { + this.log.info("\n【请求地址】:{}\n【响应数据】:{}", url, responseString); + return responseString; + } else { + //有错误提示信息返回 + JsonObject jsonObject = GsonParser.parse(responseString); + throw convertException(jsonObject); + } + } catch (Exception e) { + this.log.error("\n【请求地址】:{}\n【异常信息】:{}", url, e.getMessage()); + throw (e instanceof TtPayException) ? (TtPayException) e : new TtPayException(e.getMessage(), e); + } finally { + httpRequest.releaseConnection(); + } + } + + @Override + public String getV2(String url) throws TtPayException { + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader("Accept", "application/json"); + httpGet.addHeader("Content-Type", "application/json"); + return this.requestV2(url.toString(), httpGet); + } + + + private CloseableHttpClient createApiV2HttpClient() throws TtPayException { + CloseableHttpClient apiV3HttpClient = this.getConfig().getApiV2HttpClient(); + if (null == apiV3HttpClient) { + return this.getConfig().initApiV2HttpClient(); + } + return apiV3HttpClient; + } + + private StringEntity createEntry(String requestStr) { + try { + return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)); + } catch (UnsupportedEncodingException e) { + //cannot happen + this.log.error(e.getMessage(), e); + return null; + } + } + + private HttpPost createHttpPost(String url, String requestStr) { + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(this.createEntry(requestStr)); + + httpPost.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) + .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) + .setSocketTimeout(this.getConfig().getHttpTimeout()) + .build()); + + return httpPost; + } + + private TtPayException convertException(JsonObject jsonObject) { + //todo 这里考虑使用新的适用于V2的异常 + JsonElement codeElement = jsonObject.get("code"); + String code = codeElement == null ? null : codeElement.getAsString(); + String message = jsonObject.get("message").getAsString(); + TtPayException ttPayException = new TtPayException(message); + ttPayException.setErrCode(code); + ttPayException.setErrCodeDes(message); + return ttPayException; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceImpl.java b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceImpl.java new file mode 100644 index 000000000..aa137ba85 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/pay/impl/TtPayServiceImpl.java @@ -0,0 +1,11 @@ +package com.iformall.douyin.pay.impl; + +/** + *
+ * 支付接口请求实现类,默认使用Apache HttpClient实现
+ * Created by Binary Wang on 2017-7-8.
+ * 
+ * + */ +public class TtPayServiceImpl extends TtPayServiceApacheHttpImpl { +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/CertificatesVerifier.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/CertificatesVerifier.java new file mode 100644 index 000000000..dcbfd0389 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/CertificatesVerifier.java @@ -0,0 +1,72 @@ +package com.iformall.douyin.payv2.auth; + +import com.iformall.douyin.payv2.util.PemUtils; +import me.chanjar.weixin.common.error.WxRuntimeException; + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Base64; + +public class CertificatesVerifier implements Verifier { + + private PublicKey apiKey; + + public CertificatesVerifier(PublicKey apiKey) { + this.apiKey = apiKey; + } + + @Override + public boolean verify(byte[] message, String signature) { + try { + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initVerify(this.apiKey); + sign.update(message); + return sign.verify(Base64.getDecoder().decode(signature.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException e) { + throw new WxRuntimeException("当前Java环境不支持SHA256withRSA", e); + } catch (SignatureException e) { + throw new WxRuntimeException("签名验证过程发生了错误", e); + } catch (InvalidKeyException e) { + throw new WxRuntimeException("无效的证书", e); + } + } + +// public static void main(String[] args) { +// String pubKey = "-----BEGIN PUBLIC KEY-----\n" + +// "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv8jSFriZ6l5vv0xVcpFJ\n" + +// "NxihPh3j6tVKrU2FBythCstyr/CwdpAp9AGXvcaW2x2kKiOMXXaRDo6OysjggsxK\n" + +// "5hh1fWDE3ML4Wi5tfAV64pvj8wn5XeHXGKtXcKD/ASQmUGnMKI0g8i2REm3Q7gzy\n" + +// "JH35URh+tU8wI2v8mDY9OCZ7Hmu8ImW3pibyYRYK0CEpa31+65gVaTeoaPlqTKR0\n" + +// "rwgxZM5nFcXxGtiTsH0O1GAJBqWpyVeOqH19vEVB/bROEb21bf65ZYhac2Z1lzWq\n" + +// "MW+/4knIDg6EH3/xZWFPPwAFZgpfkSQES/twPkN/59cZ8SfTwJ84k/KUOApvkihM\n" + +// "uQIDAQAB\n" + +// "-----END PUBLIC KEY-----"; +// String timestamp = "1653906762"; +// String nonce = "pztVmu9EhPgCv9Dvw31t68U9WhMcLXCb"; +// String httpBody = "{\"err_no\":0,\"data\":{\"create_order_callback\":\"https://ctest.malls.iformall.com/C/api/order/douyinPushOrder\",\"refund_callback\":\"https://ctest.malls.iformall.com/C/api/order/douyinRefundOrder\",\"delivery_qrcode_redirect\":\"\"},\"resp_extra\":{\"logid\":\"202205301832420101581160381B3C09C0\"},\"err_tips\":\"success\"}"; +// String signStr = "pZEQga7EpGI+NXEznLNZROViIBxwWaofnlstthQsu8MZiuTRUtool2SQhfLHkXwYzj5O8yj+luTbFUrhTfX+BzvcR3+fGrqMtgqGWp86a1hAg4e4pvoTHd5PAxUGRDb/gGxPoxLDgrS6cLKusdGi6mmwJbERveD9ThNV1RQGQo/BM3BeImr3fYdJ/ZU67iVkP6SEWkqRiEJhnQMaavy/B4LK3xI0A5BhWlGbhGUIqumLT903tIOhofXGA6PQJbDiU38J5EtMj/Z7l6+IXtbA/KO0IWbIZ96KFs6e8ZE6H18Xn7b0J7KDTjTelMt7iXczrLU2/e3QEcfn2/7+7DIRMQ=="; +// +// StringBuffer buffer = new StringBuffer(); +// buffer.append(timestamp).append("\n"); +// buffer.append(nonce).append("\n"); +// buffer.append(httpBody).append("\n"); +// try { +// Signature sign = Signature.getInstance("SHA256withRSA"); +// sign.initVerify(PemUtils.loadPublicKey(new ByteArrayInputStream(pubKey.getBytes("utf-8")))); +// sign.update(buffer.toString().getBytes(StandardCharsets.UTF_8)); +// boolean verify = sign.verify(Base64.getDecoder().decode(signStr.getBytes(StandardCharsets.UTF_8))); +// System.out.println("-------"+verify); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } catch (SignatureException e) { +// e.printStackTrace(); +// } catch (InvalidKeyException e) { +// e.printStackTrace(); +// } +// } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/PrivateKeySigner.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/PrivateKeySigner.java new file mode 100644 index 000000000..7f46f9218 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/PrivateKeySigner.java @@ -0,0 +1,35 @@ +package com.iformall.douyin.payv2.auth; + +import me.chanjar.weixin.common.error.WxRuntimeException; + +import java.security.*; +import java.util.Base64; + +public class PrivateKeySigner implements Signer { + private String certificateSerialNumber; + + private PrivateKey privateKey; + + public PrivateKeySigner(String serialNumber, PrivateKey privateKey) { + this.certificateSerialNumber = serialNumber; + this.privateKey = privateKey; + } + + @Override + public SignatureResult sign(byte[] message) { + try { + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initSign(privateKey); + sign.update(message); + + return new SignatureResult( + Base64.getEncoder().encodeToString(sign.sign()), certificateSerialNumber); + } catch (NoSuchAlgorithmException e) { + throw new WxRuntimeException("当前Java环境不支持SHA256withRSA", e); + } catch (SignatureException e) { + throw new WxRuntimeException("签名计算失败", e); + } catch (InvalidKeyException e) { + throw new WxRuntimeException("无效的私钥", e); + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Signer.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Signer.java new file mode 100644 index 000000000..0d8156eb0 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Signer.java @@ -0,0 +1,15 @@ +package com.iformall.douyin.payv2.auth; + +public interface Signer { + SignatureResult sign(byte[] message); + + class SignatureResult { + String sign; + String certificateSerialNumber; + + public SignatureResult(String sign, String serialNumber) { + this.sign = sign; + this.certificateSerialNumber = serialNumber; + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayCredentials.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayCredentials.java new file mode 100644 index 000000000..cc83b4e95 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayCredentials.java @@ -0,0 +1,91 @@ +package com.iformall.douyin.payv2.auth; + +import com.iformall.douyin.payv2.util.Credentials; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.client.methods.HttpRequestWrapper; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; + +@Slf4j +public class TtPayCredentials implements Credentials { + private static final String SYMBOLS = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static final SecureRandom RANDOM = new SecureRandom(); + protected String appId; + protected Signer signer; + + public TtPayCredentials(String appId, Signer signer) { + this.appId = appId; + this.signer = signer; + } + + public String getAppId() { + return appId; + } + + protected long generateTimestamp() { + return System.currentTimeMillis() / 1000; + } + + protected String generateNonceStr() { + char[] nonceChars = new char[32]; + for (int index = 0; index < nonceChars.length; ++index) { + nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + return new String(nonceChars); + } + + @Override + public final String getSchema() { + return "SHA256-RSA2048"; + } + + @Override + public final String getToken(HttpRequestWrapper request) throws IOException { + String nonceStr = generateNonceStr(); + long timestamp = generateTimestamp(); + + String message = buildMessage(nonceStr, timestamp, request); + log.info("authorization message=[{}]", message); + +// System.out.println("message---------------------------"+message); + + Signer.SignatureResult signature = signer.sign(message.getBytes(StandardCharsets.UTF_8)); + + String token = "appid=\"" + getAppId() + "\"," + + "nonce_str=\"" + nonceStr + "\"," + + "timestamp=\"" + timestamp + "\"," + + "key_version=\"" + signature.certificateSerialNumber + "\"," + + "signature=\"" + signature.sign + "\""; + log.info("authorization token=[{}]", token); + +// System.out.println("token---------------------------"+token); + + return token; + } + + protected final String buildMessage(String nonce, long timestamp, HttpRequestWrapper request) + throws IOException { + URI uri = request.getURI(); + String canonicalUrl = uri.getRawPath(); + if (uri.getQuery() != null) { + canonicalUrl += "?" + uri.getRawQuery(); + } + + String body = ""; + // PATCH,POST,PUT + body = EntityUtils.toString(((HttpEntityEnclosingRequest) request).getEntity(),StandardCharsets.UTF_8); + + return request.getRequestLine().getMethod() + "\n" + + canonicalUrl + "\n" + + timestamp + "\n" + + nonce + "\n" + + body + "\n"; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayValidator.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayValidator.java new file mode 100644 index 000000000..07414a20e --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/TtPayValidator.java @@ -0,0 +1,55 @@ +package com.iformall.douyin.payv2.auth; + +import com.iformall.douyin.payv2.util.Validator; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.entity.ContentType; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; + +@Slf4j +public class TtPayValidator implements Validator { + private Verifier verifier; + + public TtPayValidator(Verifier verifier) { + this.verifier = verifier; + } + + @Override + public final boolean validate(CloseableHttpResponse response) throws IOException { + if (!ContentType.APPLICATION_JSON.getMimeType().equals(ContentType.parse(String.valueOf(response.getFirstHeader("Content-Type").getValue())).getMimeType())) { + return true; + } + + Header sign = response.getFirstHeader("Byte-Signature"); + Header timestamp = response.getFirstHeader("Byte-Timestamp"); + Header nonce = response.getFirstHeader("Byte-Nonce-Str"); + + // todo: check timestamp + if (timestamp == null || nonce == null || sign == null) { + return false; + } + + String message = buildMessage(response); + return verifier.verify(message.getBytes("utf-8"), sign.getValue()); + } + + protected final String buildMessage(CloseableHttpResponse response) throws IOException { + String timestamp = response.getFirstHeader("Byte-Timestamp").getValue(); + String nonce = response.getFirstHeader("Byte-Nonce-Str").getValue(); + + String body = getResponseBody(response); + return timestamp + "\n" + + nonce + "\n" + + body + "\n"; + } + + protected final String getResponseBody(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + + return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : ""; + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Verifier.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Verifier.java new file mode 100644 index 000000000..fc3dfa1cb --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/auth/Verifier.java @@ -0,0 +1,6 @@ +package com.iformall.douyin.payv2.auth; + +public interface Verifier { + boolean verify(byte[] message, String signature); + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/config/TtPayConfig.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/config/TtPayConfig.java new file mode 100644 index 000000000..2a130ef35 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/config/TtPayConfig.java @@ -0,0 +1,179 @@ +package com.iformall.douyin.payv2.config; + +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.auth.CertificatesVerifier; +import com.iformall.douyin.payv2.auth.TtPayValidator; +import com.iformall.douyin.payv2.auth.Verifier; +import com.iformall.douyin.payv2.util.PemUtils; +import com.iformall.douyin.payv2.util.TtPayV2HttpClientBuilder; +import jodd.util.ResourcesUtil; +import lombok.Data; +import lombok.SneakyThrows; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.impl.client.CloseableHttpClient; +import java.io.*; +import java.net.URL; +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * 支付配置 + * + * @author Binary Wang + */ +@Data +public class TtPayConfig { + private static final String DEFAULT_PAY_BASE_URL = "https://developer.toutiao.com"; + private static final String PROBLEM_MSG = "证书文件【%s】有问题,请核实!"; + private static final String NOT_FOUND_MSG = "证书文件【%s】不存在,请核实!"; + + /** + * 支付接口请求地址域名部分. + */ + private String payBaseUrl = DEFAULT_PAY_BASE_URL; + + /** + * http请求连接超时时间. + */ + private int httpConnectionTimeout = 5000; + + /** + * http请求数据读取等待时间. + */ + private int httpTimeout = 10000; + + /** + * appid. + */ + private String appId; + + /** + * apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径. + */ + private String privateKeyPath; + + /** + * api 秘钥值. + */ + private String apiKey; + + private Verifier verifier; + + @SneakyThrows + public Verifier getVerifier() { + if (verifier == null) { + //当改对象为null时,初始化api v3的请求头 + initApiV2HttpClient(); + } + return verifier; + } + + /** + * apiV2 证书序列号值 + */ + private String certSerialNo; + + private CloseableHttpClient apiV2HttpClient; + /** + * 私钥信息 + */ + private PrivateKey privateKey; + + /** + * 返回所设置的微信支付接口请求地址域名. + * + * @return 微信支付接口请求地址域名 + */ + public String getPayBaseUrl() { + if (StringUtils.isEmpty(this.payBaseUrl)) { + return DEFAULT_PAY_BASE_URL; + } + + return this.payBaseUrl; + } + + + /** + * 初始化api v2请求头 自动签名验签 + * + * @return org.apache.http.impl.client.CloseableHttpClient + * @author doger.wang + **/ + public CloseableHttpClient initApiV2HttpClient() throws TtPayException { + String privateKeyPath = this.getPrivateKeyPath(); + String apiKey = this.getApiKey(); + if (StringUtils.isBlank(privateKeyPath)) { + throw new TtPayException("请确保privateKeyPath已设置"); + } + if (StringUtils.isBlank(apiKey)) { + throw new TtPayException("请确保apiKey值已设置"); + } + InputStream keyInputStream = this.loadConfigInputStream(privateKeyPath); + try { + PrivateKey privateKey = PemUtils.loadPrivateKey(keyInputStream); + PublicKey publicKey = PemUtils.loadPublicKey(new ByteArrayInputStream(apiKey.getBytes("utf-8"))); + CertificatesVerifier certificatesVerifier = new CertificatesVerifier(publicKey); + + CloseableHttpClient httpClient = TtPayV2HttpClientBuilder.create() + .withAppId(appId, certSerialNo, privateKey) + .withValidator(new TtPayValidator(certificatesVerifier)) + .build(); + this.apiV2HttpClient = httpClient; + this.privateKey = privateKey; + this.verifier = certificatesVerifier; + + return httpClient; + } catch (Exception e) { + throw new TtPayException("v2请求构造异常!", e); + } + } + + /** + * 从配置路径 加载配置 信息(支持 classpath、本地路径、网络url) + * @param configPath 配置路径 + * @return + * @throws TtPayException + */ + private InputStream loadConfigInputStream(String configPath) throws TtPayException { + InputStream inputStream; + final String prefix = "classpath:"; + String fileHasProblemMsg = String.format(PROBLEM_MSG, configPath); + String fileNotFoundMsg = String.format(NOT_FOUND_MSG, configPath); + if (configPath.startsWith(prefix)) { + String path = RegExUtils.removeFirst(configPath, prefix); + if (!path.startsWith("/")) { + path = "/" + path; + } + try { + inputStream = ResourcesUtil.getResourceAsStream(path); + if (inputStream == null) { + throw new TtPayException(fileNotFoundMsg); + } + } catch (Exception e) { + throw new TtPayException(fileNotFoundMsg, e); + } + } else if (configPath.startsWith("http://") || configPath.startsWith("https://")) { + try { + inputStream = new URL(configPath).openStream(); + if (inputStream == null) { + throw new TtPayException(fileNotFoundMsg); + } + } catch (IOException e) { + throw new TtPayException(fileNotFoundMsg, e); + } + } else { + try { + File file = new File(configPath); + if (!file.exists()) { + throw new TtPayException(fileNotFoundMsg); + } + + inputStream = new FileInputStream(file); + } catch (IOException e) { + throw new TtPayException(fileHasProblemMsg, e); + } + } + return inputStream; + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/CallBackSettingsRequest.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/CallBackSettingsRequest.java new file mode 100644 index 000000000..354f5b552 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/CallBackSettingsRequest.java @@ -0,0 +1,35 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class CallBackSettingsRequest implements Serializable { + private static final long serialVersionUID = -1L; + /** + * https回调地址,预下单请求地址,长度限制<=512字节 + */ + @SerializedName(value = "create_order_callback") + private String createOrderCallback; + /** + * https回调地址,退款请求地址,长度限制<=512字节 + */ + @SerializedName(value = "refund_callback") + private String refundCallback; + /** + * https回调地址,长度限制<=256字节。闭环核销方案核销组件上展示的二维码所对应的跳转地址。开发者可使用这个参数设置app_id维度的订单跳转链接。 + */ + @SerializedName(value = "delivery_qrcode_redirect") + private String deliveryQrcodeRedirect; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/ProfitSharingRequest.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/ProfitSharingRequest.java new file mode 100644 index 000000000..196bc02b2 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/ProfitSharingRequest.java @@ -0,0 +1,67 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 请求分账API请求实体 + * + * @author pg + * @date 2021-6-24 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class ProfitSharingRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 开发者侧订单id,长度限制<64字节 + */ + @SerializedName("out_order_no") + private String outOrderNo; + + /** + * 开发者侧分账单id,分账请求的唯一标识,长度限制<64字节 + */ + @SerializedName("out_settle_no") + private String outSettleNo; + + /** + * 分账描述,长度<512字节 + */ + @SerializedName("settle_desc") + private String settleDesc; + + /** + * 其他分账方(除卖家之外的),json字符串,长度<512字节 + * - 示例,"[{\"merchant_uid\":\"分账方商户号1\",\"amount\":100}]" + * merchant_uid string 是 + * 进件商户id(除了卖家以外的其他分账方) + * amount int64 是 + * 分账金额,单位[分],amount>0 + */ + @SerializedName("settle_params") + private String settleParams; + + /** + * 透传字段,开发者自定义,<=2048字节,不支持二进制 + */ + @SerializedName("cp_extra") + private String cpExtra; + + /** + * 分账结果通知地址,必须是https类型, + * 若不填,默认使用在开发者平台-担保交易配置页面设置的回调地址 + */ + @SerializedName("notify_url") + private String notifyUrl; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtOrderPushDeliveryRequest.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtOrderPushDeliveryRequest.java new file mode 100644 index 000000000..8affbef19 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtOrderPushDeliveryRequest.java @@ -0,0 +1,73 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 订单推送核销状态请求对象
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtOrderPushDeliveryRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 开发者服务交易单号
+   * 
+ */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + *
+   * out_order_no所关联的需要核销的商品单信息,详细结构见下表。可使用此参数指定核销整单中的特定商品单。
+   * 长度<=100
+   * 注意:只有待使用状态的商品单才能核销,已核销、正退款或已退款的将返回错误。
+   * 
+ */ + @SerializedName(value = "item_order_list") + private List itemOrderList; + + /** + * 是否整单核销。此参数设为true则将out_order_no的所有商品单核销。use_all和item_list必须有一个有效值,要么整单核销,要么指定商品单核销。 + * 注意:此参数设为true时只有out_order_no的所有商品单都为待使用状态才能成功核销,如果有商品单状态不对将导致不能整单核销,会返回错误。 + */ + @SerializedName(value = "use_all") + private Boolean useAll; + + /** + * 核销的商铺poi信息,详细结构见下表,最多1024个字节。 + * 注意:此字段为json string + * poi_info 结构,poi商品必填所有字段(强校验),小程序商品也尽量传入(不校验) + * shop_name string poi商品必填 + * 核销店铺名称,参考商铺同步接口中的店铺名称(name) + * ext_valid_shop_id string poi商品必填 + * 核销门店的外部店铺id,参考商铺同步接口中的接入方店铺id(supplier_ext_id) + * valid_poi_id_str string poi商品必填 + * 核销门店对应的抖音poi_id,参考商铺同步接口中的抖音poi id(poi_id) + */ + @SerializedName(value = "poi_info") + private String poiInfo; + + + @Data + @NoArgsConstructor + public static class ItemOrder implements Serializable { + private static final long serialVersionUID = 1L; + + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayOrderQueryV2Request.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayOrderQueryV2Request.java new file mode 100644 index 000000000..4a6196a86 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayOrderQueryV2Request.java @@ -0,0 +1,38 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *
+ * 订单查询请求对象
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtPayOrderQueryV2Request implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 抖音开平内部交易订单号,长度<64byte,开发者在接收到抖音开平发起的下单交易回调请求的时候,由抖音开平传递给开发者服务,开发者必须确保将该id与自己平台生成的交易单号进行唯一关联
+   * 
+ */ + @SerializedName(value = "order_id") + private String orderId; + + /** + *
+   * 开发者系统生成的订单号,与抖音开平交易单号order_id唯一关联,长度<64byte
+   * 
+ */ + @SerializedName(value = "out_order_no") + private String outOrderNo; +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundQueryV2Request.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundQueryV2Request.java new file mode 100644 index 000000000..5af00d555 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundQueryV2Request.java @@ -0,0 +1,36 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 微信支付-申请退款请求参数
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtPayRefundQueryV2Request implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 抖音开平内部交易退款单号,长度<= 64byte,开发者必须确保将该id与自己平台生成的交易单号进行唯一关联 + */ + @SerializedName(value = "refund_id") + private String refund_id; + + /** + * 开发者系统生成的退款单号,与抖音开平退款单号refund_id 唯一关联,长度<= 64byte + */ + @SerializedName(value = "out_refund_no") + private String outRefundNo; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundV2Request.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundV2Request.java new file mode 100644 index 000000000..968e7cc77 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayRefundV2Request.java @@ -0,0 +1,107 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 申请退款请求参数
+ * 
+ * + * @author + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtPayRefundV2Request implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 是 + * 开发者侧订单号,长度 <= 64 byte + */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + * 是 + * 开发者侧退款单号,长度 <= 64 byte + */ + @SerializedName(value = "out_refund_no") + private String outRefundNo; + + /** + * 否 + * 开发者自定义透传字段,不支持二进制,长度 <= 2048 byte + */ + @SerializedName(value = "cp_extra") + private String cpExtra; + + /** + * 是 + * 退款单的跳转的schema + */ + @SerializedName(value = "order_entry_schema") + private PageEntry orderEntrySchema; + + /** + * 否 + * 退款结果通知地址,必须是https类型, + * 若不填,默认使用在开发者平台-担保交易配置页面设置的退款回调地址 + */ + @SerializedName(value = "notify_url") + private String notifyUrl; + + /** + * 否(新订单发起退款必传) + * + * 需要发起退款的商品单信息(新订单发起退款必传) + */ + @SerializedName(value = "item_order_detail") + private List itemOrderDetail; + + /** + * 否(旧订单发起退款必传) + * 退款总金额 (旧订单发起退款必传) + */ + @SerializedName(value = "refund_total_amount") + private Integer refundTotalAmount; + + @Data + @NoArgsConstructor + public static class PageEntry implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 路径 没有前导的“/” + */ + @SerializedName(value = "path") + private String path; + + /** + * 参数 自定义的json结构 + */ + @SerializedName(value = "params") + private String params; + + } + + + @Data + @NoArgsConstructor + public static class OrderDetail implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 商品单号,参见前文"对于重要id字段的说明" + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayUnifiedOrderV2Request.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayUnifiedOrderV2Request.java new file mode 100644 index 000000000..c24e50a9f --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtPayUnifiedOrderV2Request.java @@ -0,0 +1,456 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 统一下单请求参数对象.
+ * 参考文档:https://bytedance.feishu.cn/docx/doxcna1ALcy90AGMNdGLoALBeIH#doxcnUUemGYgUYECi8n92wMQQke
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtPayUnifiedOrderV2Request implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 商品信息,详情见 goods_list说明 + */ + @SerializedName(value = "goods_list") + protected List goodsList; + + /** + * 是 + * 订单总价,单位(分) + */ + @SerializedName(value = "total_amount") + private Integer totalAmount; + + /** + * 否 + * 用户手机号 + */ + @SerializedName(value = "phone_num") + private String phoneNum; + + /** + * 否 + * 用户姓名 + */ + @SerializedName(value = "contact_name") + private String contactName; + + /** + * 否 + * 下单备注信息,长度 <= 2048byte + */ + @SerializedName(value = "extra") + private String extra; + + /** + * 是 + * 用户OpenID + */ + @SerializedName(value = "open_id") + private String openId; + + /** + * 否 + * 支付结果通知地址,必须是https类型。若不填,默认使用在开发者平台-担保交易配置页面设置的支付回调地址 + */ + @SerializedName(value = "pay_notify_url") + private String payNotifyUrl; + + /** + * 是 + * 开发者的单号,长度 <= 64 byte + */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + * 否 + * 支付超时时间,单位秒,例如300表示300秒后过期;不传或传0会使用默认值300 + */ + @SerializedName(value = "pay_expire_seconds") + private Integer payExpireSeconds; + + /** + * 是 + * 订单详情页 + */ + @SerializedName(value = "order_entry_schema") + private PageEntry orderEntrySchema; + + /** + * 否 + * 开发者自定义透传字段,不支持二进制,长度 <= 2048 byte + */ + @SerializedName(value = "cp_extra") + private PageEntry cpExtra; + + /** + * 否 + * 折扣金额,单位(分) + */ + @SerializedName(value = "discount_amount") + private Integer discountAmount; + + /** + * 否 + * 营销算价结果信息, + */ + @SerializedName(value = "price_calculation_detail") + private PriceDetail priceCalculationDetail; + + + + @Data + @NoArgsConstructor + public static class Good implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 否 + * - 非poi商品必传 + * 商品图片链接,长度 <= 512 byte + */ + @SerializedName(value = "goods_image") + private String goodsImage; + + /** + * 否 + * - 非poi商品必传 + * 商品标题/商品名称,长度 <= 256 byte + */ + @SerializedName(value = "goods_title") + private String goodsTitle; + + /** + * 否 + * - 非poi商品必传 + * 商品标签,最多设置三个标签,例如:随时退|免预约|提前3日预约 (“|”是中文类型),详见type的合法值 + */ + @SerializedName(value = "labels") + private String labels; + + /** + * 否 + * 使用规则,如 “周一至周日可用”、“周一至周五可用”、“非节假日可用”,默认“周一至周日可用” + */ + @SerializedName(value = "date_rule") + private String dateRule; + + /** + * 否 + * - 非poi商品必传 + * 商品价格,单位(分) + */ + @SerializedName(value = "price") + private Integer price; + + /** + * 是 + * 商品数量 + */ + @SerializedName(value = "quantity") + private Integer quantity; + + /** + * 是 + * 商品id + */ + @SerializedName(value = "goods_id") + private String goodsId; + + /** + * 是 + * 商品id类别,poi商品传 1,非poi商品传 2 + */ + @SerializedName(value = "goods_id_type") + private Integer goodsIdType; + + /** + * 否 + * 商品详情页 + */ + @SerializedName(value = "goods_page") + private PageEntry goodsPage; + + /** + * 否 + * - 非poi商品必传 + * 券的有效期,注意: + * 1. 非poi商品必传,poi商品会从poi库里查询有效期信息,不会使用开发者传的数据 + * 2. 如果是非poi商品,每个goods_id都要传券的有效期信息,否则会下单失败 + */ + @SerializedName(value = "order_valid_time") + private OrderValid orderValidTime; + + /** + * 否 + * 折扣金额,单位(分) + */ + @SerializedName(value = "discount_amount") + private Integer discountAmount; + + } + + + @Data + @NoArgsConstructor + public static class PageEntry implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 路径 没有前导的“/” + */ + @SerializedName(value = "path") + private String path; + + /** + * 参数 自定义的json结构 + */ + @SerializedName(value = "params") + private String params; + + } + + @Data + @NoArgsConstructor + public static class OrderValid implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 券的有效期开始时间,单位毫秒,须大于0 + */ + @SerializedName(value = "valid_start_time") + private Long validStartTime; + + /** + * 券的有效期结束时间,单位毫秒,须大于0,且须大于valid_start_time和当前时间 + */ + @SerializedName(value = "valid_end_time") + private Long validEndTime; + + /** + * 1. 券的相对有效时间,单位毫秒,须大于0 + * 2. 与组合,至少回传一个,否则会下单失败 + * 3. 都合法优先使用组合 + * 4. 当valid_duration 有效时,券的有效期开始时间 S=订单支付完成时间,券的有效期结束时间 E=1天 + 向下按天截断(S+valid_duration) + * eg:valid_duration = 86400000ms(一天) S = 2021.1.1 6:00 E = 2021.1.3 00:00 + */ + @SerializedName(value = "valid_duration") + private Long validDuration; + + } + + @Data + @NoArgsConstructor + public static class PriceDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 算价类型,1-商户单维度,item单价格我们按分摊比例计算, + * 2-item单维度,item单价格由开发者计算 + */ + @SerializedName(value = "calculation_type") + private Integer calculationType; + + /** + * 商品算价结果 + */ + @SerializedName(value = "goods_discount_detail") + private List goodsDiscountDetail; + + /** + * 商品算价结果 + */ + @SerializedName(value = "order_discount_detail") + private OrderDiscountDetail order_discount_detail; + + /** + * 商品算价结果 + */ + @SerializedName(value = "item_discount_detail") + private List item_discount_detail; + + } + + @Data + @NoArgsConstructor + public static class GoodsDiscountDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 商品id,此处为课程id,注意这里是string类型 + */ + @SerializedName(value = "goods_id") + private String goodsId; + + /** + * 是 + * 购买数量 + */ + @SerializedName(value = "quantity") + private Integer quantity; + + /** + * 是 + * 商品总价,单位:分 + */ + @SerializedName(value = "total_amount") + private Integer totalAmount; + + /** + * 是 + * 该商品总优惠金额,该商品的实付金额=total_amount-discount_amount + */ + @SerializedName(value = "discountAmount") + private Integer discountAmount; + + /** + * 营销明细 + */ + @SerializedName(value = "marketing_detail") + private List marketingDetail; + + } + + @Data + @NoArgsConstructor + public static class OrderDiscountDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 订单维度总优惠金额,单位: 分 + */ + @SerializedName(value = "order_total_discount_amount") + private Integer orderTotalDiscountAmount; + + /** + * 是 + * 商品(sku)维度总优惠金额,单位: 分 + */ + @SerializedName(value = "goods_total_discount_amount") + private Integer goodsTotalDiscountAmount; + + /** + * 营销明细 + */ + @SerializedName(value = "marketing_detail") + private List marketingDetail; + + } + + @Data + @NoArgsConstructor + public static class ItemDiscountDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 商品id,此处为课程id,注意这里是string类型 + */ + @SerializedName(value = "goods_id") + private String goodsId; + + /** + * 是 + * 商品总价,单位:分 + */ + @SerializedName(value = "total_amount") + private Integer totalAmount; + + /** + * 是 + * 该商品总优惠金额,该商品的实付金额=total_amount-discount_amount + */ + @SerializedName(value = "discountAmount") + private Integer discountAmount; + + /** + * 营销明细 + */ + @SerializedName(value = "marketing_detail") + private List marketingDetail; + + } + + @Data + @NoArgsConstructor + public static class MarketingDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 营销id(用户身份id,优惠券id,积分id或者活动id) + */ + @SerializedName(value = "id") + private String id; + + /** + * 是 + * + * 营销类型: + * 1: 用户身份 + * 2: 优惠券 + * 3: 积分(暂不开放) + * 4: 活动 + */ + @SerializedName(value = "type") + private Integer type; + + /** + * 是 + * 该营销策略优惠金额,单位: 分 + */ + @SerializedName(value = "discountAmount") + private Integer discountAmount; + + /** + * 营销名称 + */ + @SerializedName(value = "title") + private String title; + + /** + * 营销备注 + */ + @SerializedName(value = "note") + private String note; + + /** + * 优惠范围 + */ + @SerializedName(value = "discount_range") + private Integer discountRange; + + /** + * 营销子类型 + */ + @SerializedName(value = "subtype") + private String subtype; + + /** + * 不同type含义不同,若type=3,value则为积分值 + */ + @SerializedName(value = "value") + private Integer value; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtRefundAuditMsgRequest.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtRefundAuditMsgRequest.java new file mode 100644 index 000000000..f5429273b --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/request/TtRefundAuditMsgRequest.java @@ -0,0 +1,64 @@ +package com.iformall.douyin.payv2.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 订单推送核销状态请求对象
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtRefundAuditMsgRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 开发者侧退款单号 + */ + @SerializedName(value = "out_refund_no") + private String outRefundNo; + + /** + * 审核状态,1-同意退款 2-不同意退款 + */ + @SerializedName(value = "refund_audit_status") + private Integer refundAuditStatus; + + /** + * 不同意退款信息(不同意退款时必填),长度 <= 512 byte + */ + @SerializedName(value = "deny_message") + private String denyMessage; + + /** + * 核销的商铺poi信息,详细结构见下表,最多1024个字节。 + * shop_name string poi商品必填 + * 核销店铺名称,参考商铺同步接口中的店铺名称(name) + * ext_valid_shop_id string poi商品必填 + * 核销门店的外部店铺id,参考商铺同步接口中的接入方店铺id(supplier_ext_id) + * valid_poi_id_str string poi商品必填 + * 核销门店对应的抖音poi_id,参考商铺同步接口中的抖音poi id(poi_id) + */ + @SerializedName(value = "poi_info") + private Boolean poiInfo; + + + @Data + @NoArgsConstructor + public static class ItemOrder implements Serializable { + private static final long serialVersionUID = 1L; + + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/BaseTtPayResult.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/BaseTtPayResult.java new file mode 100644 index 000000000..ecb3395a3 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/BaseTtPayResult.java @@ -0,0 +1,55 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; + +/** + *
+ * 结果共用属性类.
+ * Created by Binary Wang on 2016-10-24.
+ * 
+ * + */ +@Data +@NoArgsConstructor +public class BaseTtPayResult implements Serializable { + + /** + * 返回状态码. + */ + @SerializedName("err_no") + protected Integer errNo; + + public boolean isSuccess() { + return errNo.intValue() == 0; + } + /** + * 返回信息. + */ + @SerializedName("err_tips") + protected String errTips; + + @SerializedName("data") + private T data; + + /** + * Gets logger. + * + * @return the logger + */ + protected Logger getLogger() { + return LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String toString() { + return WxGsonBuilder.create().toJson(this); + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/CreateOrderCallback.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/CreateOrderCallback.java new file mode 100644 index 000000000..f7aa1b86f --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/CreateOrderCallback.java @@ -0,0 +1,226 @@ +package com.iformall.douyin.payv2.result; + +import cn.binarywang.wx.miniapp.bean.WxMaGetLiveInfo; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 结果通知. + * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class CreateOrderCallback implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 是 + * 抖音开平侧生成的订单号 + */ + @SerializedName(value = "order_id") + private String orderId; + + /** + * 是 + * 商品信息,详情见 goods参数 部分 + */ + @SerializedName(value = "goods") + private List goods; + + /** + * 是 + * 订单总价格,单位[分] + * 用户实付金额=total_amount-discount + */ + @SerializedName(value = "total_amount") + private Integer totalAmount; + + /** + * 是 + * 订单折扣,单位[分] + */ + @SerializedName(value = "discount") + private Integer discount; + + /** + * 否 + * 预下单时开发者定义的透传信息 + */ + @SerializedName(value = "cp_extra") + private String cpExtra; + + /** + * 是 + * 订单创建时间,13位时间戳,毫秒 + */ + @SerializedName(value = "create_order_time") + private Long createOrderTime; + + /** + * 是 + * 用户OpenID + */ + @SerializedName(value = "open_id") + private String openId; + + /** + * 否 + * 用户手机号 + */ + @SerializedName(value = "phone_num") + private String phoneNum; + + /** + * 否 + * 联系人姓名 + */ + @SerializedName(value = "contact_name") + private String contactName; + + /** + * 是 + * 小程序id + */ + @SerializedName(value = "app_id") + private String appId; + + /** + * 否 + * 用户的 UnionID + */ + @SerializedName(value = "union_id") + private String unionId; + + /** + * 是 + * 核销类型,开平告知此订单是否可走闭环核销判断结果。 + * 0-非闭环核销,开发者自行处理券码生成及展示,通过push_delivery接口推送核销状态,1-闭环核销,开平负责生券,开发者使用核销组件展示,使用验券准备和验券接口核销。 + */ + @SerializedName(value = "delivery_type") + private Integer deliveryType; + + @Data + @NoArgsConstructor + public static class Good implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是 + * 商品图片链接 + */ + @SerializedName(value = "img_url") + private String imgUrl; + + /** + * 是 + * 商品标题 + */ + @SerializedName(value = "title") + private String title; + + /** + * 是 + * 商品副标题 + */ + @SerializedName(value = "sub_title") + private String subTitle; + + /** + * 是 + * + * 商品标签,对应poi多门店SPU同步的sub_title,例如:随时退|免预约|提前3日预约 (“|”是中文类型) + */ + @SerializedName(value = "labels") + private String labels; + + /** + * 是 + * 券的可用时间(目前仅用于展示),例如:“周一至周五可用”、“非节假日可用” + */ + @SerializedName(value = "date_rule") + private String dateRule; + + /** + * 是 + * 商品原价,单位[分] + */ + @SerializedName(value = "origin_price") + private Integer originPrice; + + /** + * 是 + * 商品去掉折扣后的单价,单位[分] + */ + @SerializedName(value = "price") + private Integer price; + + /** + * 是 + * 购买的商品数量 + */ + @SerializedName(value = "quantity") + private Integer quantity; + + /** + * 否 + * 对应门店的Poi ID + */ + @SerializedName(value = "poi_id") + private String poiId; + + /** + * 是 + * 商品id + */ + @SerializedName(value = "goods_id") + private String goodsId; + + /** + * 是 + * item_order_id列表,id个数与quantity一致 + */ + @SerializedName(value = "item_order_id_list") + private List itemOrderIdList; + + /** + * 是 + * 商品id类别,1:poi商品,2:非poi商品 + */ + @SerializedName(value = "goods_id_type") + private Integer goodsIdType; + + /** + * 是 + * 商品item_order信息,详情见 item_order_info_list部分 + */ + @SerializedName(value = "item_order_info") + protected List itemOrderInfoList; + + } + + @Data + @NoArgsConstructor + public static class ItemOrderInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * item单id + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + /** + * 商品优惠后价格 + */ + @SerializedName(value = "price") + private Integer price; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/OriginNotifyResponse.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/OriginNotifyResponse.java new file mode 100644 index 000000000..aa9e338f3 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/OriginNotifyResponse.java @@ -0,0 +1,32 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +public class OriginNotifyResponse implements Serializable { + + private static final long serialVersionUID = 1L; + + @SerializedName(value = "msg") + private String msg; + + /** + * 枚举值: + * pre_create_order 预下单回调 + * pre_create_refund 退款审核回调 + */ + @SerializedName(value = "type") + private String type; + + /** + * 固定值:"2.0" callback版本,用于开发者识别回调参数的变更 + */ + @SerializedName(value = "version") + private String version; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/ProfitSharingResult.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/ProfitSharingResult.java new file mode 100644 index 000000000..f3d47906f --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/ProfitSharingResult.java @@ -0,0 +1,112 @@ +package com.iformall.douyin.payv2.result; + + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 请求分账API返回的分账结果实体 + * + * @author pg + * @date 2021-6-24 + */ +@Data +public class ProfitSharingResult implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 返回状态码. + */ + @SerializedName("err_no") + protected Integer errNo; + + public boolean isSuccess() { + return errNo.intValue() == 0; + } + /** + * 返回信息. + */ + @SerializedName("err_tips") + protected String errTips; + + /** + * 订单的分账结果 + */ + @SerializedName("data") + private List data; + + @Data + public static class Receiver implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 开发者交易订单id,长度<=64byte,数字、ASCII字符组成 + */ + @SerializedName("out_order_no") + private String outOrderNo; + + /** + * 开发者分账单id,长度<=64byte,数字、ASCII字符组成 + */ + @SerializedName("out_settle_no") + private String outSettleNo; + + /** + * 小程序侧交易订单id,长度<=64byte,数字、ASCII字符组成 + */ + @SerializedName("order_id") + private String orderId; + + /** + * 小程序侧分账单id,长度<=64byte,数字、ASCII字符组成 + */ + @SerializedName("settle_id") + private String settleId; + + /** + * 分账金额,单位[分] + */ + @SerializedName("settle_amount") + private Integer settleAmount; + + /** + * 分账状态:INIT,PROCESSING,SUCCESS,FAIL + */ + @SerializedName("settle_status") + private String settleStatus; + + /** + * 分账详情,如“商户号ABC-分成金额(分)100” + */ + @SerializedName("settle_detail") + private String settleDetail; + + /** + * 分账时间,13位时间戳,毫秒 + */ + @SerializedName("settle_time") + private Long settleTime; + + /** + * 手续费,单位[分] + */ + @SerializedName("rake") + private Integer rake; + + /** + * 佣金,单位[分] + */ + @SerializedName("commission") + private Integer commission; + + /** + * 透传字段,开发者自定义,<=2048字节,不支持二进制数据 + */ + @SerializedName("cp_extra") + private String cpExtra; + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/RefundOrderCallback.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/RefundOrderCallback.java new file mode 100644 index 000000000..37a6ed17f --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/RefundOrderCallback.java @@ -0,0 +1,138 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 结果通知. + * + * @author + */ +@Data +@NoArgsConstructor +public class RefundOrderCallback implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 小程序的appid + */ + @SerializedName(value = "app_id") + private String appId; + + /** + * 用户openid + */ + @SerializedName(value = "open_id") + private String openId; + + /** + * 抖音开平侧退款单号 + */ + @SerializedName(value = "refund_id") + private String refundId; + + /** + * 抖音开平侧订单号 + */ + @SerializedName(value = "order_id") + private String orderId; + + /** + * 开发者侧订单号 + */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + * 退款总金额,单位[分] + */ + @SerializedName(value = "refund_total_amount") + private Integer refundTotalAmount; + + /** + * 退款审核的最后期限,超过该期限无需商家审核,自动退款,13位时间戳,毫秒 + */ + @SerializedName(value = "refund_audit_deadline") + private Long refundAuditDeadline; + + /** + * 退款创建时间,13位时间戳,毫秒 + */ + @SerializedName(value = "create_refund_time") + private Long createRefundTime; + + /** + * 退款来源:1-用户发起退款 3-过期自动退 + */ + @SerializedName(value = "refund_source") + private Integer refundSource; + + /** + * cp 自定义字段,不支持二进制,长度 <= 2048byte + */ + @SerializedName(value = "cp_extra") + private String cpExtra; + + /** + * 退款原因,退款原因有多个 + */ + @SerializedName(value = "refund_reason") + private List refundReason; + + /** + *退款补充说明 + */ + @SerializedName(value = "refund_description") + private String refundDescription; + + /** + * 退款商品单信息 (新系统订单退款必填) + */ + @SerializedName(value = "refund_item_detail") + private RefundItemDetail refundItemDetail; + + + @Data + @NoArgsConstructor + public static class RefundItemDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 用户需要退款多少个商品单 + */ + @SerializedName(value = "item_order_quantity") + private Integer itemOrderQuantity; + + /** + * 本次退款的商品单列表 + */ + @SerializedName(value = "item_order_detail") + private List itemOrderDetail; + + } + + @Data + @NoArgsConstructor + public static class ItemOrderDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 用户需要退款多少个商品单 + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + /** + * 用户需要退款多少个商品单 + */ + @SerializedName(value = "refund_amount") + private Integer refundAmount; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayCpsOrderQueryV2Result.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayCpsOrderQueryV2Result.java new file mode 100644 index 000000000..e990914f7 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayCpsOrderQueryV2Result.java @@ -0,0 +1,304 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ *  查询CPS订单 返回结果对象
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class TtPayCpsOrderQueryV2Result implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 抖音开平侧订单号 + */ + @SerializedName(value = "order_id") + private String orderId; + + /** + * 开发者侧订单号,与order_id一一对应 + */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + *cps订单支付相关信息 + */ + @SerializedName(value = "payment_info") + private PaymentInfo paymentInfo; + + /** + *cps相关信息 + */ + @SerializedName(value = "cps_info") + private CpsInfo cpsInfo; + + /** + *cps订单已退款记录信息 + * - refund_info字段结构(只展示已退款记录,退款失败和退款中不展示) + */ + @SerializedName(value = "refund_info") + private RefundInfo refundInfo; + + /** + *cps订单已核销记录信息 + * - delivery_info字段结构(只展示已核销记录) + */ + @SerializedName(value = "delivery_info") + private DeliveryInfo deliveryInfo; + + @Data + @NoArgsConstructor + public static class PaymentInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 订单实际支付金额,单位[分] + */ + @SerializedName(value = "total_fee") + private Integer totalFee; + + /** + * 订单状态, + * INIT 初始状态 + * PROCESS 订单处理中 + * SUCCESS:成功 + * FAIL:失败 + * TIMEOUT:用户超时未支付 + */ + @SerializedName(value = "order_status") + private String orderStatus; + + /** + * 支付时间,格式:2021-12-12 00:00:00 + */ + @SerializedName(value = "pay_time") + private String payTime; + + /** + * 支付渠道枚举,1:微信,2:支付宝 + */ + @SerializedName(value = "pay_channel") + private Integer payChannel; + + /** + * 渠道支付单号,如微信的支付单号 + */ + @SerializedName(value = "channel_pay_id") + private String channelPayId; + + /** + * 卖家商户号id + */ + @SerializedName(value = "seller_uid") + private String sellerUid; + + /** + * 预下单时开发者定义的透传信息 + */ + @SerializedName(value = "cp_extra") + private String cpExtra; + + /** + * 结果描述信息,如失败原因 + */ + @SerializedName(value = "message") + private String message; + } + + @Data + @NoArgsConstructor + public static class CpsInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 订单总佣金,单位分 + */ + @SerializedName(value = "total_commission_amount") + private Integer totalCommissionAmount; + + /** + * 订单状态, + * INIT 初始状态 + * PROCESS 订单处理中 + * SUCCESS:成功 + * FAIL:失败 + * TIMEOUT:用户超时未支付 + */ + @SerializedName(value = "cps_item_list") + private List cps_item_list; + } + + @Data + @NoArgsConstructor + public static class CpsItem implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 分佣比例,万分位 + */ + @SerializedName(value = "commission_rate") + private Integer commissionRate; + + /** + * 分佣用户ID + */ + @SerializedName(value = "commission_user_id") + private Long commissionUserId; + + /** + * 佣金,单位分 + */ + @SerializedName(value = "commission_amount") + private Integer commissionAmount; + + /** + * 分佣类型,1 短视频, 2 直播间 + */ + @SerializedName(value = "source_type") + private Integer sourceType; + + /** + * 短视频/直播间ID + */ + @SerializedName(value = "item_id") + private Long itemId; + + /** + * 售价,单位分 + */ + @SerializedName(value = "sell_amount") + private Integer sellAmount; + + /** + * cps订单状态,交易系统2.0为子单状态 + * 0-未支付, + * 1-已支付(待使用); + * 2-已退款(不分佣); + * 3-已核销(已分佣) + */ + @SerializedName(value = "status") + private Integer status; + + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } + + @Data + @NoArgsConstructor + public static class RefundInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 订单退款总金额,单位分,没有已退款记录,为0 + */ + @SerializedName(value = "total_refund_amount") + private Integer total_refund_amount; + + /** + * 分佣用户ID + */ + @SerializedName(value = "refund_items") + private List refund_items; + + } + + @Data + @NoArgsConstructor + public static class RefundItem implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 开发者系统生成的退款单号,与抖音开平退款单号refund_id 唯一关联 + */ + @SerializedName(value = "out_refund_no") + private String outRefundNo; + + /** + * 退款金额,单位[分] + */ + @SerializedName(value = "refund_amount") + private Integer refundAmount; + + /** + * 显示退款状态,默认“已退款” + */ + @SerializedName(value = "refundStatus") + private String refundStatus; + + /** + * 退款时间,13位毫秒时间戳,只有已退款才有退款时间 + */ + @SerializedName(value = "refunded_at") + private Long refunded_at; + + /** + * 抖音开平侧的商品单号,只存在交易2.0系统 + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } + + @Data + @NoArgsConstructor + public static class DeliveryInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 订单核销总金额,单位分,没有核销记录,为0 + */ + @SerializedName(value = "total_delivery_amount") + private Integer totalDeliveryAmount; + + /** + * 分佣用户ID + */ + @SerializedName(value = "delivery_items") + private List deliveryItems; + + } + + @Data + @NoArgsConstructor + public static class DeliveryItem implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 核销金额,单位[分] + */ + @SerializedName(value = "delivery_amount") + private Integer deliveryAmount; + + /** + * 显示核销状态,默认“已核销” + */ + @SerializedName(value = "delivery_status") + private String deliveryStatus; + + /** + * 退款时间,13位毫秒时间戳,只有已退款才有退款时间 + */ + @SerializedName(value = "delivery_at") + private Long deliveryAt; + + /** + * 抖音开平侧的商品单号,只存在交易2.0系统 + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayOrderQueryV2Result.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayOrderQueryV2Result.java new file mode 100644 index 000000000..b6d23e911 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayOrderQueryV2Result.java @@ -0,0 +1,119 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import io.swagger.models.auth.In; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ *  查询订单 返回结果对象
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class TtPayOrderQueryV2Result implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 抖音开平侧订单号 + */ + @SerializedName(value = "order_id") + private String orderId; + + /** + * 开发者侧订单号,与order_id一一对应 + */ + @SerializedName(value = "out_order_no") + private String outOrderNo; + + /** + * 已退款金额,单位[分] + */ + @SerializedName(value = "refund_amount") + private Integer refundAmount; + + /** + * 已分账金额,单位[分] + */ + @SerializedName(value = "settle_amount") + private Integer settleAmount; + + /** + * 订单实际支付金额,单位[分] + */ + @SerializedName(value = "total_fee") + private Integer totalFee; + + /** + * 订单状态, + * INIT 初始状态 + * PROCESS 订单处理中 + * SUCCESS:成功 + * FAIL:失败 + * TIMEOUT:用户超时未支付 + */ + @SerializedName(value = "order_status") + private String orderStatus; + + /** + * 支付时间,格式:2021-12-12 00:00:00 + */ + @SerializedName(value = "pay_time") + private String payTime; + + /** + * 支付渠道枚举,1:微信,2:支付宝 + */ + @SerializedName(value = "pay_channel") + private Integer payChannel; + + /** + * 渠道支付单号,如微信的支付单号 + */ + @SerializedName(value = "channel_pay_id") + private String channelPayId; + + /** + * 卖家商户号id + */ + @SerializedName(value = "seller_uid") + private String sellerUid; + + /** + * 视频id + */ + @SerializedName(value = "item_id") + private String itemId; + + /** + * 预下单时开发者定义的透传信息 + */ + @SerializedName(value = "cp_extra") + private String cpExtra; + + /** + * 结果描述信息,如失败原因 + */ + @SerializedName(value = "message") + private String message; + /** + * 担保支付单id + */ + @SerializedName(value = "payment_order_id") + private String paymentOrderId; + + /** + * 订单核销类型: + * 0-非闭环核销,开发者自行处理券码生成及展示,通过push_delivery接口推送核销状态。 + * 1-闭环核销,开平负责生券,开发者使用核销组件展示,使用验券准备和验券接口核销。 + */ + @SerializedName(value = "delivery_type") + private Integer deliveryType; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundQueryV2Result.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundQueryV2Result.java new file mode 100644 index 000000000..5b09f1cae --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundQueryV2Result.java @@ -0,0 +1,121 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 退款返回结果.
+ * 
+ * + * @author + */ +@Data +@NoArgsConstructor +public class TtPayRefundQueryV2Result implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 系统退款单号,开放平台生成的退款单号 + */ + @SerializedName(value = "refund_id") + private String refundId; + + /** + * 开发者系统生成的退款单号,与抖音开平退款单号refund_id 唯一关联 + */ + @SerializedName(value = "out_refund_no") + private String outRefundNo; + + /** + * 退款金额,单位[分] + */ + @SerializedName(value = "refund_total_amount") + private Integer refundTotalAmount; + + /** + * 退款状态 + * 退款中- PROCESSING,已退款- SUCCESS,退款失败- FAIL + */ + @SerializedName(value = "refund_status") + private String refundStatus; + + /** + * 退款时间,13位毫秒时间戳,只有已退款才有退款时间 + */ + @SerializedName(value = "refund_at") + private Long refundAt; + + /** + * 退款结果信息,非商家拒绝退款导致的退款失败,可以通过该字段了解退款失败原因 + */ + @SerializedName(value = "message") + private String message; + + /** + * 系统订单信息,开放平台生成的订单号 + */ + @SerializedName(value = "order_id") + private String orderId; + + /** + * 商品单信息 (新系统订单退款才有的信息) + */ + @SerializedName(value = "item_order_detail") + private List itemOrderDetail; + + /** + * 退款审核信息(在新系统发起的退款单才有) + */ + @SerializedName(value = "merchant_audit_detail") + private MerchantAuditDetail merchantAuditDetail; + + + @Data + @NoArgsConstructor + public static class itemOrderDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 抖音开平侧的商品单号 + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + /** + * 该商品单退款金额,单位[分] + */ + @SerializedName(value = "refund_amount") + private Integer refundAmount; + + } + + @Data + @NoArgsConstructor + public static class MerchantAuditDetail implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 退款审核的最后期限,过期无需审核,自动退款,13位unix时间戳,精度:毫秒 + */ + @SerializedName(value = "refund_audit_deadline") + private Long refundAuditDeadline; + + /** + * 退款审核状态 + * INIT-初始化 TOAUDIT-待审核 AGREE-同意 DENY-拒绝 OVERTIME-超时未审核自动同意 + */ + @SerializedName(value = "audit_status") + private String auditStatus; + + /** + * 不同意退款信息(不同意退款时必填),长度 <= 512 byte + */ + @SerializedName(value = "deny_message") + private String denyMessage; + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundV2Result.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundV2Result.java new file mode 100644 index 000000000..f04760030 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayRefundV2Result.java @@ -0,0 +1,33 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 申请退款返回结果.
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class TtPayRefundV2Result implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * 抖音开放平台交易系统内部退款单号 + */ + @SerializedName(value = "refund_id") + private String refundId; + + /** + * 退款审核的最后期限,过期无需审核,自动退款,13位unix时间戳,精度:毫秒 + */ + @SerializedName(value = "refund_audit_deadline") + private Long refundAuditDeadline; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayUnifiedOrderV2Result.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayUnifiedOrderV2Result.java new file mode 100644 index 000000000..dc669e2a1 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/result/TtPayUnifiedOrderV2Result.java @@ -0,0 +1,99 @@ +package com.iformall.douyin.payv2.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 统一下单请求参数对象.
+ * 
+ * + * @author thinsstar + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +public class TtPayUnifiedOrderV2Result implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 是 + * 抖音开平侧生成的订单号 + */ + @SerializedName(value = "order_id") + protected String orderId; + /** + * 是 + * 开发者系统生成的订单号 + */ + @SerializedName(value = "out_order_no") + protected String outOrderNo; + /** + * 是 + * 吊起收银台的支付订单号 + */ + @SerializedName(value = "pay_order_id") + protected String payOrderId; + /** + * 是 + * 吊起收银台的token + */ + @SerializedName(value = "pay_order_token") + protected String payOrderToken; + + /** + * 是 + * 商品item_order信息,详情见 item_order_info_list部分 + */ + @SerializedName(value = "item_order_info_list") + protected List itemOrderInfoList; + + @Data + @NoArgsConstructor + public static class ItemOrderInfo implements Serializable { + private static final long serialVersionUID = 1L; + + @SerializedName(value = "goods_id") + private String goodsId; + + /** + * 是 + * item_order_id列表,id个数与下单时对应goods_id的quantity一致 + */ + @SerializedName(value = "item_order_id_list") + private List itemOrderIdList; + + /** + * 是 + * 商品item_order详细信息,详情见 item_order_detail部分 + */ + @SerializedName(value = "item_order_detail") + private List itemOrderDetail; + + } + + @Data + @NoArgsConstructor + public static class ItemOrderDetail implements Serializable { + private static final long serialVersionUID = -1L; + + /** + * item单id + */ + @SerializedName(value = "item_order_id") + private String itemOrderId; + + /** + * 商品优惠后价格 + */ + @SerializedName(value = "price") + private Integer price; + } + + + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Credentials.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Credentials.java new file mode 100644 index 000000000..0021a68bd --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Credentials.java @@ -0,0 +1,12 @@ +package com.iformall.douyin.payv2.util; + +import org.apache.http.client.methods.HttpRequestWrapper; + +import java.io.IOException; + +public interface Credentials { + + String getSchema(); + + String getToken(HttpRequestWrapper request) throws IOException; +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/util/PemUtils.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/PemUtils.java new file mode 100644 index 000000000..3a217eeea --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/PemUtils.java @@ -0,0 +1,89 @@ +package com.iformall.douyin.payv2.util; + +import me.chanjar.weixin.common.error.WxRuntimeException; +import sun.misc.BASE64Decoder; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class PemUtils { + + public static PrivateKey loadPrivateKey(InputStream inputStream) { + try { + ByteArrayOutputStream array = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + array.write(buffer, 0, length); + } + + String privateKey = array.toString("utf-8") + .replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate( + new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))); + } catch (NoSuchAlgorithmException e) { + throw new WxRuntimeException("当前Java环境不支持RSA", e); + } catch (InvalidKeySpecException e) { + throw new WxRuntimeException("无效的密钥格式"); + } catch (IOException e) { + throw new WxRuntimeException("无效的密钥"); + } + } + + public static X509Certificate loadCertificate(InputStream inputStream) { + try { + CertificateFactory cf = CertificateFactory.getInstance("X509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream); + cert.checkValidity(); + return cert; + } catch (CertificateExpiredException e) { + throw new WxRuntimeException("证书已过期", e); + } catch (CertificateNotYetValidException e) { + throw new WxRuntimeException("证书尚未生效", e); + } catch (CertificateException e) { + throw new WxRuntimeException("无效的证书", e); + } + } + + public static PublicKey loadPublicKey(InputStream inputStream) { + + try { + ByteArrayOutputStream array = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + array.write(buffer, 0, length); + } + + String publicKey = array.toString("utf-8") + .replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replaceAll("\\s+", ""); + + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePublic( + new X509EncodedKeySpec(new BASE64Decoder().decodeBuffer(publicKey))); + + } catch (NoSuchAlgorithmException e) { + throw new WxRuntimeException("当前Java环境不支持RSA", e); + } catch (InvalidKeySpecException e) { + throw new WxRuntimeException("无效的密钥格式"); + } catch (IOException e) { + throw new WxRuntimeException("无效的密钥"); + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/util/SignatureExec.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/SignatureExec.java new file mode 100644 index 000000000..9179bf670 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/SignatureExec.java @@ -0,0 +1,81 @@ +package com.iformall.douyin.payv2.util; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpExecutionAware; +import org.apache.http.client.methods.HttpRequestWrapper; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.entity.BufferedHttpEntity; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.execchain.ClientExecChain; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; + +public class SignatureExec implements ClientExecChain { + final ClientExecChain mainExec; + final Credentials credentials; + final Validator validator; + + SignatureExec(Credentials credentials, Validator validator, ClientExecChain mainExec) { + this.credentials = credentials; + this.validator = validator; + this.mainExec = mainExec; + } + + protected HttpEntity newRepeatableEntity(HttpEntity entity) throws IOException { + byte[] content = EntityUtils.toByteArray(entity); + ByteArrayEntity newEntity = new ByteArrayEntity(content); + newEntity.setContentEncoding(entity.getContentEncoding()); + newEntity.setContentType(entity.getContentType()); + + return newEntity; + } + + protected void convertToRepeatableResponseEntity(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + if (entity != null && !entity.isRepeatable()) { + response.setEntity(newRepeatableEntity(entity)); + } + } + + protected void convertToRepeatableRequestEntity(HttpRequestWrapper request) throws IOException { + if (request instanceof HttpEntityEnclosingRequest) { + HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); + if (entity != null) { + ((HttpEntityEnclosingRequest) request).setEntity(new BufferedHttpEntity(entity)); + } + } + } + + @Override + public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request, + HttpClientContext context, HttpExecutionAware execAware) throws IOException, HttpException { + return executeWithSignature(route, request, context, execAware); + } + + private CloseableHttpResponse executeWithSignature(HttpRoute route, HttpRequestWrapper request, + HttpClientContext context, HttpExecutionAware execAware) throws IOException, HttpException { + // 添加认证信息 + request.addHeader("Byte-Authorization", + credentials.getSchema() + " " + credentials.getToken(request)); + + // 执行 + CloseableHttpResponse response = mainExec.execute(route, request, context, execAware); + + // 对成功应答验签 + StatusLine statusLine = response.getStatusLine(); + if (statusLine.getStatusCode() >= 200 && statusLine.getStatusCode() < 300) { + convertToRepeatableResponseEntity(response); + if (!validator.validate(response)) { + throw new HttpException("应答的支付签名验证失败"); + } + } + return response; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/util/TtPayV2HttpClientBuilder.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/TtPayV2HttpClientBuilder.java new file mode 100644 index 000000000..fde3552e7 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/TtPayV2HttpClientBuilder.java @@ -0,0 +1,70 @@ +package com.iformall.douyin.payv2.util; + +import com.iformall.douyin.payv2.auth.*; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.execchain.ClientExecChain; + +import java.security.PrivateKey; +import java.security.PublicKey; + +public class TtPayV2HttpClientBuilder extends HttpClientBuilder { + private Credentials credentials; + private Validator validator; + + static final String OS = System.getProperty("os.name") + "/" + System.getProperty("os.version"); + static final String VERSION = System.getProperty("java.version"); + + private TtPayV2HttpClientBuilder() { + super(); + + String userAgent = String.format( + "WechatPay-Apache-HttpClient/%s (%s) Java/%s", + getClass().getPackage().getImplementationVersion(), + OS, + VERSION == null ? "Unknown" : VERSION); + setUserAgent(userAgent); + } + + public static TtPayV2HttpClientBuilder create() { + return new TtPayV2HttpClientBuilder(); + } + + public TtPayV2HttpClientBuilder withAppId(String appId, String serialNo, PrivateKey privateKey) { + this.credentials = + new TtPayCredentials(appId, new PrivateKeySigner(serialNo, privateKey)); + return this; + } + + public TtPayV2HttpClientBuilder withCredentials(Credentials credentials) { + this.credentials = credentials; + return this; + } + + public TtPayV2HttpClientBuilder withPublicKey(PublicKey publicKey) { + this.validator = new TtPayValidator(new CertificatesVerifier(publicKey)); + return this; + } + + public TtPayV2HttpClientBuilder withValidator(Validator validator) { + this.validator = validator; + return this; + } + + @Override + public CloseableHttpClient build() { + if (credentials == null) { + throw new IllegalArgumentException("缺少身份认证信息"); + } + if (validator == null) { + throw new IllegalArgumentException("缺少签名验证信息"); + } + + return super.build(); + } + + @Override + protected ClientExecChain decorateProtocolExec(final ClientExecChain requestExecutor) { + return new SignatureExec(this.credentials, this.validator, requestExecutor); + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Validator.java b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Validator.java new file mode 100644 index 000000000..465d706f6 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/payv2/util/Validator.java @@ -0,0 +1,9 @@ +package com.iformall.douyin.payv2.util; + +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.io.IOException; + +public interface Validator { + boolean validate(CloseableHttpResponse response) throws IOException; +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsGetRequestExecutor.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsGetRequestExecutor.java new file mode 100644 index 000000000..2c610be23 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsGetRequestExecutor.java @@ -0,0 +1,108 @@ +package com.iformall.douyin.web.api; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.ResponseHandler; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * . + * + * @author ecoolper + * @date 2017/5/4 + */ +public class TtWebGoodsGetRequestExecutor implements RequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected RequestHttp requestHttp; + + public TtWebGoodsGetRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + @Override + public void execute(String uri, String data, ResponseHandler handler, WxType wxType) throws WxErrorException, IOException { + handler.handle(this.execute(uri, data, wxType)); + } + + @Override + public String execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { + + String access_token = handleUrl(uri); + if(StringUtils.isBlank(access_token)){ + WxError wxError = WxError.fromJson("{\n" + + " \"description\": \"未找到access_token\",\n" + + " \"error_code\": -1\n" + + " }"); + throw new WxErrorException(wxError); + } + + if (queryParam != null) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") ? queryParam : '&' + queryParam; + } + + HttpGet httpGet = new HttpGet(uri); + httpGet.addHeader("Content-Type","application/json"); + httpGet.addHeader("access-token",access_token); + logger.info("get请求地址uri{}"+uri); + logger.info("header-----access_token{}"+access_token); + + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpGet.setConfig(config); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + logger.info("response{}"+responseContent); + return responseContent; +// JSONObject jsonObject = JSON.parseObject(responseContent); +// JSONObject data = jsonObject.getJSONObject("data"); +// WxError error = WxError.fromJson(data.toJSONString()); +// if (error.getErrorCode() != 0) { +// throw new WxErrorException(error); +// } +// return data.toString(); + } finally { + httpGet.releaseConnection(); + } + } + + //去除链接中access_token 并返回 + private String handleUrl(String url){ + String access_token = null; + Pattern pXM = Pattern.compile("access_token=([^&]*)"); + Matcher mXM = pXM.matcher(url); + int i = 0; + while (mXM.find()) { + i++; + access_token = mXM.group(1); + } + if(i > 1){ + return null; + } +// url = url.replaceAll("&?access_token=[^&]*",""); + return access_token; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsPostRequestExecutor.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsPostRequestExecutor.java new file mode 100644 index 000000000..f42e7b460 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsPostRequestExecutor.java @@ -0,0 +1,117 @@ +package com.iformall.douyin.web.api; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.ResponseHandler; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * . + * + * @author ecoolper + * @date 2017/5/4 + */ +public class TtWebGoodsPostRequestExecutor implements RequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + protected RequestHttp requestHttp; + + public TtWebGoodsPostRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + @Override + public void execute(String uri, String data, ResponseHandler handler, WxType wxType) + throws WxErrorException, IOException { + handler.handle(this.execute(uri, data, wxType)); + } + + @Override + public String execute(String uri, String postEntity, WxType wxType) throws WxErrorException, IOException { + + String access_token = handleUrl(uri); + if(StringUtils.isBlank(access_token)){ + WxError wxError = WxError.fromJson("{\n" + + " \"description\": \"未找到access_token\",\n" + + " \"error_code\": -1\n" + + " }"); + throw new WxErrorException(wxError); + } + + HttpPost httpPost = new HttpPost(uri); + httpPost.addHeader("Content-Type","application/json"); + httpPost.addHeader("access-token",access_token); + logger.info("post请求地址uri{}"+uri); + logger.info("header-----access_token{}"+access_token); + logger.info("请求参数{}"+postEntity); + + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + if (postEntity != null) { + StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); + entity.setContentType("application/json; charset=utf-8"); + httpPost.setEntity(entity); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + logger.info("response{}"+responseContent); + if (responseContent.isEmpty()) { + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); + } + return responseContent; + +// if (responseContent.startsWith("")) { +// //xml格式输出直接返回 +// return responseContent; +// } +// JSONObject jsonObject = JSON.parseObject(responseContent); +// JSONObject data = jsonObject.getJSONObject("data"); +// WxError error = WxError.fromJson(data.toJSONString()); +// if (error.getErrorCode() != 0) { +// throw new WxErrorException(error); +// } +// return data.toString(); + } finally { + httpPost.releaseConnection(); + } + } + + //去除链接中access_token 并返回 + private String handleUrl(String url){ + String access_token = null; + Pattern pXM = Pattern.compile("access_token=([^&]*)"); + Matcher mXM = pXM.matcher(url); + int i = 0; + while (mXM.find()) { + i++; + access_token = mXM.group(1); + } + if(i > 1){ + return null; + } +// url = url.replaceAll("&?access_token=[^&]*",""); + return access_token; + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsService.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsService.java new file mode 100644 index 000000000..03f9c60d4 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebGoodsService.java @@ -0,0 +1,144 @@ +package com.iformall.douyin.web.api; + + +import com.iformall.douyin.web.bean.*; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.List; + +/** + * 接入商品库 + * + * @author + */ +public interface TtWebGoodsService { + + /** + *1 查询商品模板 + */ + String TEMPLATE_GET = "/life/goods/template/get/"; + /** + *2 查询商品草稿数据 + */ + String PRODUCT_DRAFT_GET = "/life/goods/product/draft/get/"; + /** + *3 查询商品草稿数据列表 + */ + String PRODUCT_DRAFT_LIST = "/life/goods/product/draft/list/"; + /** + *4 查询商品线上数据 + */ + String PRODUCT_ONLINE_GET = "/life/goods/product/online/get/"; + /** + *5 查询商品线上数据列表 + */ + String PRODUCT_ONLINE_LIST = "/life/goods/product/online/list/"; + /** + *6 创建/更新商品 + */ + String PRODUCT_SAVE = "/life/goods/product/save/"; + /** + *7 免审修改团购活动 + */ + String PRODUCT_FREE_AUDIT = "/life/goods/product/free_audit"; + /** + *8 创建/更新多SKU商品的SKU列表(团购/代金券不用对接这个接口) + */ + String SKU_BATCH_SAVE = "/life/goods/sku/batch_save/"; + /** + *9 上下架商品 + */ + String PRODUCT_OPERATE = "/life/goods/product/operate/"; + /** + *10 同步库存 + */ + String STOCK_SYNC = "/life/goods/stock/sync/"; + + /** + * - 查询商品模板,创建商品时的属性列表需与该接口保持一致,否则无法识别 + * category_id int TRUE 行业类目;详细见;商品类目表 https://bytedance.feishu.cn/docx/doxcnn02OUCTiKjpmzFR6ItdTye + * product_type int TRUE 商品类型 商品类型 1-团购 11-代金券 + */ + GoodsTemplateGet templateGet(Integer category_id,Integer product_type) throws WxErrorException; + + /** + * - 使用商品ID或外部商品ID查询商品草稿 + * - 处于新建审核中、修改审核中、或审核成功、失败的数据可以通过该接口查询到 + * - 一次最多查询10个草稿数据 + * product_ids string TRUE 商品ID列表(逗号分隔) + * out_ids string TRUE 外部商品ID列表(逗号分隔) + */ + List productDraftGet(String product_ids, String out_ids) throws WxErrorException ; + + /** + * - 查询本client_key(或绑定的账号)对应的商品草稿列表 + * - 处于审核中、或审核成功、失败的数据可以通过该接口查询到 + * cursor string FALSE 第一页不传,之后用前一次返回的next_cursor传入进行翻页 + * count int FALSE 分页数量,不传默认为5 + * status int FALSE 过滤草稿状态,10-审核中 12-审核失败 1-审核通过 + * + */ + ProductPage productDraftListGet(String cursor,Integer count,Integer status) throws WxErrorException ; + + /** + * - - 使用商品ID或外部商品ID查询商品线上数据 + * - 线上数据是指:通过审核后可以被用户看到的数据,包括在线、下线状态的数据 + * product_ids string TRUE 商品ID列表(逗号分隔) + * out_ids string TRUE 外部商品ID列表(逗号分隔) + */ + List productOnlineGet(String product_ids, String out_ids) throws WxErrorException ; + + /** + * - 查询本client_key(或绑定的账号)对应的商品线上列表 + * - 处于在线、下线、封禁状态的数据可以通过该接口查询到 + * cursor string FALSE 第一页不传,之后用前一次返回的next_cursor传入进行翻页 + * count int FALSE 分页数量,不传默认为5 + * status int FALSE 过滤在线状态 1-在线 2-下线 3-封禁 + * + */ + ProductPage productOnlineListGet(String cursor,Integer count,Integer status) throws WxErrorException ; + + /** + * - 创建或更新商品 + * - 对于同一服务商,相同的out_id会被认为是同一商品,重复创建会被覆盖 + * - 商品和SKU属性,需要通过模板获取 + * return - product_id 创建/更新商品成功后产生,与老接口spu_id一致 + */ + String productSave(Product product) throws WxErrorException ; + + /** + * - 免审修改团购活动 + * product_id string TRUE 商品id (商品id或商品外部id 选其一) + * out_id string TRUE 商品外部id (商品id或商品外部id 选其一) + * sold_end_time int64 FALSE 售卖结束时间 + * stock_qty int64 FALSE 总库存 + */ + boolean productFreeAudit(String productId,String outId,Long soldEndTime,Integer stockQty) throws WxErrorException ; + + /** + * 创建/更新多SKU商品的SKU列表(团购/代金券不用对接这个接口) + * + * @return + */ + boolean skuBatchSave(ProductSku sku) throws WxErrorException ; + + /** + * 上下架商品 + * product_id string TRUE 商品id(若有第三方id可不传) + * out_id string TRUE 商品第三方id + * op_type int64 TRUE 1-上线 2-下线 + * @return + */ + boolean productOperate(String product_id,String out_id,Integer op_type) throws WxErrorException ; + + /** + * 同步库存 + * product_id string TRUE 商品id(若有第三方id可不传) + * out_id string TRUE 商品第三方id + * stock StockStruct TRUE 库存信息 + * - limit_type int TRUE 库存上限类型,为2时stock_qty和avail_qty字段无意义 1-有限库存 2-无限库存 + * - stock_qty int TRUE 总库存,limit_type=2时无意义 + */ + boolean stockSync(String product_id,String out_id,Integer stock) throws WxErrorException ; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebService.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebService.java index 7f33598fe..e7f6538db 100644 --- a/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebService.java +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/TtWebService.java @@ -110,4 +110,6 @@ public interface TtWebService { */ TtWebProductService getProductService(); + TtWebGoodsService getGoodsService(); + } diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebGoodsServiceImpl.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebGoodsServiceImpl.java new file mode 100644 index 000000000..80c6d6799 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebGoodsServiceImpl.java @@ -0,0 +1,254 @@ +package com.iformall.douyin.web.api.impl; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.iformall.common.ErrorCode; +import com.iformall.douyin.pay.exception.TtPayException; +import com.iformall.douyin.payv2.request.CallBackSettingsRequest; +import com.iformall.douyin.payv2.result.BaseTtPayResult; +import com.iformall.douyin.web.api.*; +import com.iformall.douyin.web.bean.*; +import com.iformall.exception.MallinkException; +import lombok.AllArgsConstructor; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.json.GsonHelper; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * + */ +@AllArgsConstructor +public class TtWebGoodsServiceImpl implements TtWebGoodsService { + + private static final Gson GSON = new GsonBuilder().create(); + + private TtWebService service; + + + @Override + public GoodsTemplateGet templateGet(Integer category_id, Integer product_type) throws WxErrorException { + TtWebGoodsGetRequestExecutor getExecutor = new TtWebGoodsGetRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.TEMPLATE_GET; + String param = "category_id=" + category_id + + "&product_type=" + product_type; + String result = this.service.execute(getExecutor, apiUrl, param); + BaseGoodsResult baseResult = GSON.fromJson(result, + new TypeReference>(){}.getType()); + if(baseResult.isSuccess()){ + return baseResult.getData(); + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public List productDraftGet(String product_ids, String out_ids) throws WxErrorException { + TtWebGoodsGetRequestExecutor getExecutor = new TtWebGoodsGetRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_DRAFT_GET; + String param = "" ; + if(StringUtils.isNotBlank(product_ids)){ + param = "product_ids=" + product_ids; + }else if(StringUtils.isNotBlank(out_ids)){ + param = "out_ids=" + out_ids; + } + String result = this.service.execute(getExecutor, apiUrl, param); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + Map map = (Map) baseResult.getData(); + if(map != null){ + Object product_draft_list = map.get("product_draft_list"); + List list = GSON.fromJson(GSON.toJson(product_draft_list), + new TypeReference>() {}.getType()); + return list; + } + return null; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public ProductPage productDraftListGet(String cursor, Integer count, Integer status) throws WxErrorException { + TtWebGoodsGetRequestExecutor getExecutor = new TtWebGoodsGetRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_DRAFT_LIST; + String param = "" ; + if(count == null){ + param = "count=" + 5; + }else{ + param = "count=" + count; + } + if(StringUtils.isNotBlank(cursor)){ + param += "&cursor=" + cursor; + } + if(status != null){ + param += "&status=" + status; + } + String result = this.service.execute(getExecutor, apiUrl, param); + BaseGoodsResult baseResult = GSON.fromJson(result, + new TypeReference>() {}.getType()); + if(baseResult.isSuccess()){ + return baseResult.getData(); + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public List productOnlineGet(String product_ids, String out_ids) throws WxErrorException { + TtWebGoodsGetRequestExecutor getExecutor = new TtWebGoodsGetRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_ONLINE_GET; + String param = "" ; + if(StringUtils.isNotBlank(product_ids)){ + param = "product_ids=" + product_ids; + }else if(StringUtils.isNotBlank(out_ids)){ + param = "out_ids=" + out_ids; + } + String result = this.service.execute(getExecutor, apiUrl, param); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + Map map = (Map) baseResult.getData(); + if(map != null){ + Object product_online_list = map.get("product_online_list"); + List list = GSON.fromJson(GSON.toJson(product_online_list), + new TypeReference>() {}.getType()); + return list; + } + return null; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public ProductPage productOnlineListGet(String cursor, Integer count, Integer status) throws WxErrorException { + TtWebGoodsGetRequestExecutor getExecutor = new TtWebGoodsGetRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_ONLINE_LIST; + String param = "" ; + if(count == null){ + param = "count=" + 5; + }else{ + param = "count=" + count; + } + if(StringUtils.isNotBlank(cursor)){ + param += "&cursor=" + cursor; + } + if(status != null){ + param += "&status=" + status; + } + String result = this.service.execute(getExecutor, apiUrl, param); + BaseGoodsResult baseResult = GSON.fromJson(result, + new TypeReference>() {}.getType()); + if(baseResult.isSuccess()){ + return baseResult.getData(); + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public String productSave(Product product) throws WxErrorException { + TtWebGoodsPostRequestExecutor postExecutor = new TtWebGoodsPostRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_SAVE; + String result = this.service.execute(postExecutor, apiUrl, GSON.toJson(product)); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + Map map = (Map) baseResult.getData(); + return map.get("product_id").toString(); + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public boolean productFreeAudit(String productId, String outId, Long soldEndTime, Integer stockQty) throws WxErrorException { + TtWebGoodsPostRequestExecutor postExecutor = new TtWebGoodsPostRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_FREE_AUDIT; + Map map = new HashMap<>(); + if(StringUtils.isNotBlank(productId)){ + map.put("product_id",productId); + }else if(StringUtils.isNotBlank(outId)){ + map.put("out_id",outId); + } + if(soldEndTime != null){ + map.put("sold_end_time",soldEndTime); + } + if(stockQty != null){ + map.put("stock_qty",stockQty); + } + String result = this.service.execute(postExecutor, apiUrl, GSON.toJson(map)); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + return true; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public boolean skuBatchSave(ProductSku sku) throws WxErrorException { + TtWebGoodsPostRequestExecutor postExecutor = new TtWebGoodsPostRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.SKU_BATCH_SAVE; + String result = this.service.execute(postExecutor, apiUrl, GSON.toJson(sku)); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + return true; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public boolean productOperate(String product_id, String out_id, Integer op_type) throws WxErrorException { + TtWebGoodsPostRequestExecutor postExecutor = new TtWebGoodsPostRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.PRODUCT_OPERATE; + Map map = new HashMap<>(); + if(StringUtils.isNotBlank(product_id)){ + map.put("product_id",product_id); + }else if(StringUtils.isNotBlank(out_id)){ + map.put("out_id",out_id); + } + map.put("op_type",op_type); + String result = this.service.execute(postExecutor, apiUrl, GSON.toJson(map)); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + return true; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } + + @Override + public boolean stockSync(String product_id, String out_id, Integer stock) throws WxErrorException { + TtWebGoodsPostRequestExecutor postExecutor = new TtWebGoodsPostRequestExecutor(this.service.getRequestHttp()); + String apiUrl = this.service.getTtWebConfig().getApiBegin().getPrefix() + this.STOCK_SYNC; + Map map = new HashMap<>(); + if(StringUtils.isNotBlank(product_id)){ + map.put("product_id",product_id); + }else if(StringUtils.isNotBlank(out_id)){ + map.put("out_id",out_id); + } + Map stockStruct = new HashMap<>(); + if(stock == null || stock < 0){ + stockStruct.put("limit_type",2); + }else{ + stockStruct.put("limit_type",1); + stockStruct.put("stock_qty",stock); + } + map.put("stock",stockStruct); + String result = this.service.execute(postExecutor, apiUrl, GSON.toJson(map)); + BaseGoodsResult baseResult = GSON.fromJson(result, BaseGoodsResult.class); + if(baseResult.isSuccess()){ + return true; + }else{ + throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebServiceImpl.java b/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebServiceImpl.java index 0b7b5b14a..1d9e81ad2 100644 --- a/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/douyin/web/api/impl/TtWebServiceImpl.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.google.gson.JsonParser; +import com.iformall.douyin.web.api.TtWebGoodsService; import com.iformall.douyin.web.api.TtWebProductService; import com.iformall.douyin.web.api.TtWebService; import com.iformall.douyin.web.api.TtWebShopMatchService; @@ -51,6 +52,7 @@ public class TtWebServiceImpl implements TtWebService, RequestHttp implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * + */ + @SerializedName(value = "base") + private BaseResult base; + + public Integer getErrCode() { + if(base.getGatewayCode().intValue() != 0){ + return base.getGatewayCode(); + }else if(base.getBizCode().intValue() != 0){ + return base.getBizCode(); + } + return 0; + } + + public boolean isSuccess() { + if(base.getGatewayCode().intValue() == 0 + && base.getBizCode().intValue() == 0){ + return true; + } + return false; + } + + public String getErrMsg() { + if(base.getGatewayCode().intValue() != 0){ + return base.getGatewayMsg(); + }else if(base.getBizCode().intValue() != 0){ + return base.getBizMsg(); + } + return ""; + } + + @SerializedName(value = "data") + private T data; + + + @Data + @NoArgsConstructor + public class BaseResult implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 请求日志ID + */ + @SerializedName(value = "log_id") + private String logId; + /** + * 网关状态码 + */ + @SerializedName(value = "gateway_code") + private Integer gatewayCode; + /** + * 网关状态信息 + */ + @SerializedName(value = "gateway_msg") + private String gatewayMsg; + /** + * 业务状态码 + */ + @SerializedName(value = "biz_code") + private Integer bizCode; + /** + * 业务状态信息 + */ + @SerializedName(value = "biz_msg") + private String bizMsg; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/bean/GoodsTemplateGet.java b/mallinkService/src/main/java/com/iformall/douyin/web/bean/GoodsTemplateGet.java new file mode 100644 index 000000000..0f8c0e633 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/bean/GoodsTemplateGet.java @@ -0,0 +1,91 @@ +package com.iformall.douyin.web.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 结果通知. + * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class GoodsTemplateGet implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 商品属性列表 + */ + @SerializedName(value = "product_attrs") + private List productAttrs; + + /** + * SKU属性列表 + */ + @SerializedName(value = "sku_attrs") + private List skuAttrs; + + @Data + @NoArgsConstructor + public static class ProductAttrs implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 属性描述 + */ + @SerializedName(value = "desc") + private String desc; + + /** + * 是否列表 + */ + @SerializedName(value = "is_multi") + private Boolean isMulti; + + /** + * 是否必填 + */ + @SerializedName(value = "is_required") + private Boolean isRequired; + + /** + * 是否展示 + */ + @SerializedName(value = "is_show") + private Boolean isShow; + + /** + * 属性key + */ + @SerializedName(value = "key") + private String key; + + /** + * 属性名称 + */ + @SerializedName(value = "name") + private String name; + + /** + * 属性类型 + */ + @SerializedName(value = "value_demo") + private String valueDemo; + + /** + * 属性样例 + */ + @SerializedName(value = "value_type") + private String valueType; + + @SerializedName(value = "data") + private String data; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/bean/Product.java b/mallinkService/src/main/java/com/iformall/douyin/web/bean/Product.java new file mode 100644 index 000000000..177c9ab8a --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/bean/Product.java @@ -0,0 +1,252 @@ +package com.iformall.douyin.web.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 商品. + * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class Product implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 草稿状态 10-审核中 12-审核失败 1-审核通过 + */ + @SerializedName(value = "draft_status") + private Integer draftStatus; + + /** + * 审核失败原因 + */ + @SerializedName(value = "audit_msg") + private String auditMsg; + + /** + * 在线状态 1-在线 2-下线 3-封禁 + */ + @SerializedName(value = "online_status") + private Integer onlineStatus; + + /** + * 商品 + */ + @SerializedName(value = "product") + private ProductStruct product; + + /** + * 商品 + */ + @SerializedName(value = "sku") + private SkuStruct sku; + + @Data + @NoArgsConstructor + public static class ProductStruct implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 商品Id + * 创建时不必填写,更新时如有out_id可不填写 + */ + @SerializedName(value = "product_id") + private String productId; + /** + * 外部商品id + */ + @SerializedName(value = "out_id") + private String outId; + /** + * 商品名 + */ + @SerializedName(value = "product_name") + private String productName; + /** + * 品类全名,保存时不必填写 + */ + @SerializedName(value = "category_full_name") + private String categoryFullName; + /** + * 品类id + */ + @SerializedName(value = "category_id") + private Integer categoryId; + /** + * 商品类型 1-团购 11-代金券 + */ + @SerializedName(value = "product_type") + private Integer productType; + /** + * 业务线 1-闭环自研开发者 3-直连服务商 5-小程序 + */ + @SerializedName(value = "biz_line") + private Integer bizLine; + /** + * 商家名 + */ + @SerializedName(value = "account_name") + private String accountName; + /** + * 售卖开始时间 + */ + @SerializedName(value = "sold_start_time") + private Long soldStartTime; + /** + * 售卖结束时间 + */ + @SerializedName(value = "sold_end_time") + private Long soldEndTime; + /** + * 创建时间,保存时不必填写 + */ + @SerializedName(value = "create_time") + private Long createTime; + /** + * 更新时间,保存时不必填写 + */ + @SerializedName(value = "update_time") + private Long updateTime; + /** + * 第三方跳转链接,小程序商品必填 + */ + @SerializedName(value = "out_url") + private String outUrl; + /** + * 店铺列表 + */ + @SerializedName(value = "poi_list") + private List poiList; + + /** + * 商品属性KV + */ + @SerializedName(value = "attr_key_value_map") + private Map attrKeyValueMap; + + } + + @Data + @NoArgsConstructor + public static class PoiStruct implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 接入方店铺id,保存时必传 + */ + @SerializedName(value = "supplier_ext_id") + private String supplierExtId; + + /** + * poi id,保存时不必填写 + */ + @SerializedName(value = "poi_id") + private Long poiId; + + /** + * 店铺id,保存时不必填写 + */ + @SerializedName(value = "supplier_id") + private Long supplierId; + + } + + @Data + @NoArgsConstructor + public static class SkuStruct implements Serializable { + private static final long serialVersionUID = 1L; + /** + * sku id,创建时不必填写 + */ + @SerializedName(value = "sku_id") + private String skuId; + /** + * 接入方店铺id,保存时必传 + */ + @SerializedName(value = "sku_name") + private String skuName; + /** + * 原价,团购创建时可不填,会根据商品搭配计算原价 + */ + @SerializedName(value = "origin_amount") + private Integer originAmount; + /** + * 实际支付价格 + */ + @SerializedName(value = "actual_amount") + private Integer actualAmount; + /** + * 库存信息 + */ + @SerializedName(value = "stock") + private StockStruct stock; + /** + * 第三方id + */ + @SerializedName(value = "out_sku_id") + private String outSkuId; + /** + * 状态 1-在线 -1-删除 + */ + @SerializedName(value = "status") + private Integer status; + + /** + * sku属性KV + */ + @SerializedName(value = "attr_key_value_map") + private Map attrKeyValueMap; + + } + + @Data + @NoArgsConstructor + public static class StockStruct implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 库存上限类型, + * 为2时stock_qty和avail_qty字段无意义 + * 1-有限库存 2-无限库存 + */ + @SerializedName(value = "limit_type") + private Integer limitType; + /** + * 总库存, + * limit_type=2时无意义 + */ + @SerializedName(value = "stock_qty") + private Integer stockQty; + /** + * 可用库存, + * limit_type=2时无意义, + * 始终保证stock_qty=avail_qty+frozen_qty+sold_qty + */ + @SerializedName(value = "avail_qty") + private Integer availQty; + /** + * 冻结库存,保存SKU时不填 + */ + @SerializedName(value = "frozen_qty") + private Integer frozenQty; + /** + * 售卖库存, 退款回滚,保存SKU时不填 + */ + @SerializedName(value = "sold_qty") + private Integer soldQty; + /** + * 销量,退款不回滚,保存SKU时不填 + */ + @SerializedName(value = "sold_count") + private Integer soldCount; + + } + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductPage.java b/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductPage.java new file mode 100644 index 000000000..014048edb --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductPage.java @@ -0,0 +1,40 @@ +package com.iformall.douyin.web.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 商品. + * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class ProductPage implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 用于查询下一页 + */ + @SerializedName(value = "next_cursor") + private String nextCursor; + + /** + * 是否还有下一页 + */ + @SerializedName(value = "has_more") + private boolean hasMore; + + /** + * 商品 + */ + @SerializedName(value = "product_list") + private List productList; + +} diff --git a/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductSku.java b/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductSku.java new file mode 100644 index 000000000..184b26794 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/douyin/web/bean/ProductSku.java @@ -0,0 +1,40 @@ +package com.iformall.douyin.web.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 商品. + * + * @author thinsstar + */ +@Data +@NoArgsConstructor +public class ProductSku implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 商品Id + * 创建时不必填写,更新时如有out_id可不填写 + */ + @SerializedName(value = "product_id") + private String productId; + /** + * 外部商品id + */ + @SerializedName(value = "out_id") + private String outId; + + /** + * 商品 + */ + @SerializedName(value = "sku_list") + private List skuList; + +} diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelStatus.java b/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelStatus.java index 3cf00a521..e8283dceb 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelStatus.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelStatus.java @@ -7,8 +7,12 @@ public enum EnumCouponChannelStatus { // 0-草稿/待生效;1-已生效/已发布/已投放;2-已下架; + STATUS_BEFORE(-1, "预上线"),//审核用 + STATUS_THROW_IN(0, "已上架"), STATUS_TAKE_OFFF(1, "已下架"), + + STATUS_AFTER(2, "作废"), ; public static EnumCouponChannelStatus getEnum(Integer code) { diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java b/mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java index 0188072e3..c59c7279b 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java @@ -25,6 +25,8 @@ public enum EnumMsgRecordType { INSIDE_PRODUCT_PUSH(109, "商品状态或库存同步"), MALL_COO_USER_PUSH(110, "猫酷同步会员"), + + INSIDE_ORDER_PUSH_DELIVERY(200, "2.0核销同步"), ; public static EnumMsgRecordType getEnum(Integer code) { diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumPushType.java b/mallinkService/src/main/java/com/iformall/enums/EnumPushType.java index 9989176bf..fdbae5e68 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumPushType.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumPushType.java @@ -5,10 +5,11 @@ package com.iformall.enums; */ public enum EnumPushType { - // 1-B端, 2-C端, 3-服务号, 4-订阅号 + // SPU_STATUS_SYNC(1, "同步状态"), SPU_STOCK_SYNC(2, "同步库存"), + SPU_FREE_AUDIT_SYNC(3, "免审修改"), ; public static EnumPushType getEnum(Integer code) { diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumSpuSyncStatus.java b/mallinkService/src/main/java/com/iformall/enums/EnumSpuSyncStatus.java index 537553ae3..43de3788a 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumSpuSyncStatus.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumSpuSyncStatus.java @@ -11,6 +11,7 @@ public enum EnumSpuSyncStatus { sync_pull_off(2, "下架"), sync_audit_rejection(3, "审核拒绝"), sync_audit_pass(4, "审核通过"), + sync_audit_disable(5, "封禁"), ; public static EnumSpuSyncStatus getEnum(Integer code) { diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumTtProductType.java b/mallinkService/src/main/java/com/iformall/enums/EnumTtProductType.java new file mode 100644 index 000000000..570b5d3f3 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/enums/EnumTtProductType.java @@ -0,0 +1,52 @@ +package com.iformall.enums; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Stormeye on 2018/08/09. + */ +public enum EnumTtProductType { + + //1 : 团购套餐 + //3 : 预售券 + //4 : 日历房 + //5 : 门票 + //7 : 旅行跟拍 + //8 : 一日游 + //11 : 代金券 + PRODUCT_TUANGOU(1, "团购套餐"), + PRODUCT_YUSHOU(3, "预售券"), + PRODUCT_RILI(4, "日历房"),//没用 + PRODUCT_MENGPIAO(5, "门票"), + PRODUCT_LVPAI(7, "旅行跟拍"), + PRODUCT_YIRIYOU(8, "一日游"), + PRODUCT_DAIJIN(11, "代金券"), + ; + + public static EnumTtProductType getEnum(Integer code) { + for (EnumTtProductType value : values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + + private Integer code; + private String message; + + EnumTtProductType(Integer code, String message) { + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + + public String getMessage() { + return message; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/TtCouponChannelPoiMapper.java b/mallinkService/src/main/java/com/iformall/mapper/TtCouponChannelPoiMapper.java index 019934e66..5c8e02be6 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/TtCouponChannelPoiMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/TtCouponChannelPoiMapper.java @@ -13,4 +13,10 @@ public interface TtCouponChannelPoiMapper extends CommonMapper findIdList(TtCouponChannelPoi record); Integer getPoiPutOnCount(@Param("tenantId")String tenantId, @Param("ids")List ids); + + int updateBySpuId(TtCouponChannelPoi couponChannelPoi); + + TtCouponChannelPoi selectById(@Param("tenantId")String tenantId,@Param("id")Long id); + + TtCouponChannelPoi selectByChannelId(@Param("tenantId")String tenantId,@Param("couponChannelId")Long couponChannelId); } diff --git a/mallinkService/src/main/java/com/iformall/mapper/TtGoodsCategoryMapper.java b/mallinkService/src/main/java/com/iformall/mapper/TtGoodsCategoryMapper.java new file mode 100644 index 000000000..4f8088b5e --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/mapper/TtGoodsCategoryMapper.java @@ -0,0 +1,13 @@ +package com.iformall.mapper; + +import com.iformall.common.CommonMapper; +import com.iformall.domain.po.TtGoodsCategory; +import com.iformall.domain.po.WxSubBusiness; + +import java.util.List; + +public interface TtGoodsCategoryMapper extends CommonMapper { + + List findListAll(); + +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java index 6f1b56785..ed4ad3011 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java @@ -5,6 +5,7 @@ import com.iformall.common.CommonMapper; import com.iformall.domain.po.WxTopic; import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.po.WxCouponChannel; +import com.iformall.domain.vo.TtCouponChannelVo; import org.apache.ibatis.annotations.Param; public interface WxCouponChannelMapper extends CommonMapper { @@ -25,13 +26,13 @@ public interface WxCouponChannelMapper extends CommonMapper getExpiriedCouponChannelIdsByEndTime(@Param("tenantId")String tenantId);//同步poi状态 + List getExpiriedCouponIdsByEndTime(@Param("tenantId")String tenantId);//同步poi状态 void offExpiriedCouponChannelByEndTime(@Param("tenantId")String tenantId); - List getExpiriedCouponChannelIdsByValidDate(@Param("tenantId")String tenantId);//同步poi状态 + List getExpiriedCouponIdsByValidDate(@Param("tenantId")String tenantId);//同步poi状态 void offExpiriedCouponChannelByValidDate(@Param("tenantId")String tenantId); - List getExpiriedCouponChannelIdsByCouponStatus(@Param("tenantId")String tenantId);//同步poi状态 + List getExpiriedCouponIdsByCouponStatus(@Param("tenantId")String tenantId);//同步poi状态 void offExpiriedCouponChannelByCouponStatus(@Param("tenantId")String tenantId); void offExpiriedCouponChannel2ByEndTime(@Param("tenantId")String tenantId); @@ -50,14 +51,6 @@ public interface WxCouponChannelMapper extends CommonMapper newfindCList(WxCouponChannel wxCouponChannel); List liveHomeList(WxCouponChannel wxCouponChannel); - - /** - * 查询已同步的上架卷的Id - * @param tenantId - * @param id - * @return - */ - List getPoiProductIdList(@Param("tenantId")String tenantId, @Param("couponId")Long couponId); Integer reduceChannelStock(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("number")Integer number); @@ -72,4 +65,5 @@ public interface WxCouponChannelMapper extends CommonMapper batGetPriceAndStock(@Param("ids")List ids,@Param("tenantId")String tenantId); + List ttChannelList(TtCouponChannelVo ttChannelVo); } diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java index 6e5f61e64..c24a5d863 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java @@ -4,6 +4,7 @@ import java.util.*; import com.iformall.common.CommonMapper; import com.iformall.domain.po.WxTopic; import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.TtCouponVo; import com.iformall.domain.vo.WxCouponCVo; import com.iformall.domain.vo.WxCouponStatisVo; import org.apache.ibatis.annotations.Param; @@ -30,6 +31,8 @@ public interface WxCouponMapper extends CommonMapper { List findSendCouponIds(@Param("expired")Integer expired,@Param("tenantId")String tenantId); WxCoupon selectById(@Param("id")Long id,@Param("tenantId")String tenantId); + + WxCoupon getAttrsById(@Param("id")Long id, @Param("tenantId")String tenantId); WxCoupon getPriceAndStock(@Param("id")Long id,@Param("tenantId")String tenantId); List batchGetPriceAndStock(@Param("ids")List ids,@Param("tenantId")String tenantId); @@ -118,4 +121,6 @@ public interface WxCouponMapper extends CommonMapper { List newfindCList(WxCoupon couponQ); List findIdsListHasConditons(WxCoupon couponQ); + + List ttCouponList(TtCouponVo ttCouponVo); } diff --git a/mallinkService/src/main/java/com/iformall/service/TtCouponGoodsService.java b/mallinkService/src/main/java/com/iformall/service/TtCouponGoodsService.java new file mode 100644 index 000000000..553ae9407 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/TtCouponGoodsService.java @@ -0,0 +1,29 @@ +package com.iformall.service; + +import com.iformall.common.ResultData; +import com.iformall.domain.po.TtCouponChannelPoi; +import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.TtCouponChannelVo; +import com.iformall.domain.vo.TtCouponVo; + +public interface TtCouponGoodsService { + + ResultData couponList(TtCouponVo ttCouponVo, Integer pageNum, Integer pageSize); + + ResultData channelList(TtCouponChannelVo ttChannelVo, Integer pageNum, Integer pageSize); + + ResultData productSave(WxCoupon coupon) throws Exception; + + int handlerTtGoodsAudit(TtCouponChannelPoi couponChannelPoi); + + ResultData productDraftGet(TenantEntity tenantEntity,Long id); + + ResultData productOnlineGet(TenantEntity tenantEntity,Long id); + + ResultData productOperate(TenantEntity tenantInfo, Long id); + + ResultData productStockSync(TenantEntity tenantInfo, Long id); + + ResultData productFreeAudit(TenantEntity tenantInfo, Long id); +} diff --git a/mallinkService/src/main/java/com/iformall/service/TtGoodsCategoryService.java b/mallinkService/src/main/java/com/iformall/service/TtGoodsCategoryService.java new file mode 100644 index 000000000..4366fa472 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/TtGoodsCategoryService.java @@ -0,0 +1,36 @@ +package com.iformall.service; + +import com.iformall.domain.po.TtGoodsCategory; +import com.iformall.domain.po.WxCoupon; +import com.iformall.douyin.web.bean.GoodsTemplateGet; + +import java.util.List; + +public interface TtGoodsCategoryService { + + /** + * 根据实体查询列表 + * + * @param + * @return + */ + List findTreeList(); + + + /** + * A端是否显示处理 + */ + void adminIsShow(GoodsTemplateGet temp); + + + /** + * 处理回显 + * @param temp + */ + void handTemplate(GoodsTemplateGet temp, WxCoupon coupon); + + /** + * 处理系统属性和默认属性 + */ + void handDefaultAttr(WxCoupon coupon,List productAttrs,List skuAttrs); +} diff --git a/mallinkService/src/main/java/com/iformall/service/TtMerchantPoiService.java b/mallinkService/src/main/java/com/iformall/service/TtMerchantPoiService.java index 2baa3490a..b6887ae9c 100644 --- a/mallinkService/src/main/java/com/iformall/service/TtMerchantPoiService.java +++ b/mallinkService/src/main/java/com/iformall/service/TtMerchantPoiService.java @@ -43,14 +43,14 @@ public interface TtMerchantPoiService { TtWebService getTtWebService(TenantEntity tenantInfo); - ResultData findPoi(TenantEntity tenantInfo, Long couponChannelId); +// ResultData findPoi(TenantEntity tenantInfo, Long couponChannelId); - ResultData spuSync(TenantEntity tenantInfo, Long couponChannelId,List merchantIds); +// ResultData spuSync(TenantEntity tenantInfo, Long couponChannelId,List merchantIds); - ResultData spuGet(TenantEntity tenantInfo, Long couponChannelId); +// ResultData spuGet(TenantEntity tenantInfo, Long couponChannelId); - ResultData spuStatusSync(TenantEntity tenantInfo, Long couponChannelId); +// ResultData spuStatusSync(TenantEntity tenantInfo, Long couponChannelId); - ResultData spuStockSync(TenantEntity tenantInfo, Long couponChannelId); +// ResultData spuStockSync(TenantEntity tenantInfo, Long couponChannelId); } diff --git a/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java b/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java index bc66a3a06..335b5907d 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java @@ -5,7 +5,9 @@ import com.iformall.common.ResultData; import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.po.WxCoupon; import com.iformall.domain.po.WxCouponChannel; +import com.iformall.domain.vo.TtCouponChannelVo; import com.iformall.domain.vo.WxCouponCVo; +import com.iformall.domain.vo.WxCouponChannelAddVo; import com.iformall.domain.vo.WxCouponChannelVo; import java.util.Date; @@ -44,7 +46,7 @@ public interface WxCouponChannelService { */ ResultData saveOrUpdate(WxCouponChannel record); - void spuStatusSync(TenantEntity tenantEntity,Long id); + void spuStatusSyncByCoupon(TenantEntity tenantEntity,Long couponId); /** * 创建二维码 @@ -53,6 +55,8 @@ public interface WxCouponChannelService { ResultData addBatch(String type,String[] ids, String[] channelId, TenantEntity tenantEntity, Date showBeginTime, Date beginTime, Date endTime,Integer channelPrice,Integer channelStock); + WxCouponChannelAddVo addCouponChannel(Long couponid, Integer channelId, TenantEntity tenantEntity, Date showBeginTime, Date beginTime, Date endTime, Integer channelPrice, Integer channelStock); + void updateStatusByCouponId(Long couponId,TenantEntity tenantEntity,int status); ResultData change(WxCouponChannel wxCouponChannel); @@ -74,4 +78,8 @@ public interface WxCouponChannelService { List getPriceAndStock(TenantEntity tenantEntity,List couponChannelIds); ResultData getCouponChannelPoi(TenantEntity tenantInfo, Long id); + + PageInfo ttChannelList(TtCouponChannelVo ttChannelVo, Integer pageNum, Integer pageSize); + + ResultData updateOnline(WxCouponChannel wxCouponChannel); } diff --git a/mallinkService/src/main/java/com/iformall/service/WxCouponOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxCouponOrderService.java index 554abc34f..5ee0ce87e 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxCouponOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxCouponOrderService.java @@ -196,7 +196,7 @@ public interface WxCouponOrderService { ResultData queryCardStatus(WxCouponOrder wxCouponOrder); - void exportData(WxCouponOrderBVo wxCouponOrder, HttpServletRequest request, HttpServletResponse response); + void exportData(boolean cUserEntry,WxCouponOrderBVo wxCouponOrder, HttpServletRequest request, HttpServletResponse response); /** * B端-收银台-支持优惠券 diff --git a/mallinkService/src/main/java/com/iformall/service/WxCouponService.java b/mallinkService/src/main/java/com/iformall/service/WxCouponService.java index f0a7d0e4e..59eb94372 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxCouponService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxCouponService.java @@ -7,15 +7,16 @@ import javax.servlet.http.HttpServletResponse; import com.github.pagehelper.PageInfo; import com.iformall.common.ResultData; +import com.iformall.domain.po.TtCouponChannelPoi; import com.iformall.domain.po.WxCoupon; import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.TtCouponVo; import com.iformall.domain.vo.WxCouponCVo; import com.iformall.domain.vo.WxCouponStatisVo; import com.iformall.domain.vo.WxMerchantVo; public interface WxCouponService { - ResultData list(TenantEntity tenantEntity,WxCoupon wxCoupon, Integer pageNum, Integer pageSize); List list(WxCoupon wxCoupon); @@ -79,12 +80,16 @@ public interface WxCouponService { WxCouponCVo getVoById(Long id,String tenantId); WxCouponCVo getVoStatusById(Long id,String tenantId); + + WxCoupon getAttrsById(Long couponId, String tenantId); /** * 保存或更新实体 * * @param record */ ResultData saveOrUpdate(WxCoupon record); + + ResultData updateTtProduct(WxCoupon wxCoupon); /** * 更新实体 * @@ -269,5 +274,5 @@ public interface WxCouponService { Map getCouponMap(List couponIds, TenantEntity tenantEntity); List getCouponMerchantList(TenantEntity tenantInfo, Long couponId); - + } diff --git a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java index dc5d323de..6ec6392c9 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java @@ -8,9 +8,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.github.pagehelper.PageInfo; +import com.iformall.common.ErrorCode; import com.iformall.common.ResultData; import com.iformall.domain.dto.OrderComposeSaveDto; import com.iformall.domain.dto.OrderSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.domain.po.*; import com.iformall.domain.po.base.TenantEntity; import com.iformall.domain.vo.WxCouponSendVo; @@ -211,12 +213,12 @@ public interface WxOrderService { // 2. 创建免费订单, 领取 couponOrder WxOrder saveFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder, WxCUserBasicInfo user, WxCoupon coupon, int couponNumber, - WxCouponChannel couponChannel, String formId, Long couponPasswordId, EnumPayWay payWay, + WxCouponChannel couponChannel, String formId, Long couponPasswordId,String extParam, EnumPayWay payWay, Integer shippingType, UserBasicInfoAddress address); // 3. 创建有价订单 - WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,WxCouponChannel couponChannel, - OrderComposeSaveDto orderdto,EnumPayWay payWay); + WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber, + boolean isPressOrder,Long orderGroupId,String formId,Integer shippinType,UserBasicInfoAddress address,String extParam,WxCouponChannel couponChannel,EnumPayWay payWay); /** * 下订单成功后处理 @@ -244,9 +246,14 @@ public interface WxOrderService { //ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity); ResultData composeSaveOrder(boolean allowUnPayOrder,EnumComposeOrder composeOrderType,List composeOrderSaveDto,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity); + + //平台推送订单,如抖音支付2.0 + ResultData platPushSaveOrder(boolean allowUnPayOrder,EnumComposeOrder composeOrderType,String allExtParam,List platPushOrderList,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity); void sendInsideOrderPushMsg(TenantEntity tenantEntity,Long composeOrderId); + void sendInsideOrderPushDeliveryMsg(TenantEntity tenantEntity,Long composeOrderId,Long couponOrderId); + PageInfo listGoodsCAsPage(WxOrder wxOrder, Integer pageNum, Integer pageSize); PageInfo listBatchOrderAsPage(WxOrder wxOrder, Integer pageNum, Integer pageSize); @@ -254,4 +261,8 @@ public interface WxOrderService { WxBatchOrder batchOrderDetail(WxBatchOrder border); void cancelOrderBatchOrder(WxBatchOrder border,WxPayOrder payOrder); + + WxBatchOrder getWxBatchOrder(TenantEntity tenantInfo, Long orderId); + + Map getOrderEntrySchema(Long mainOrderId); } diff --git a/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java index 2d8b13c63..4031e7032 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java @@ -3,6 +3,7 @@ package com.iformall.service; import java.util.*; import com.github.pagehelper.PageInfo; +import com.iformall.common.ErrorCode; import com.iformall.common.IdWorker; import com.iformall.common.ResultData; import com.iformall.domain.po.WxAppinfo; @@ -13,6 +14,7 @@ import com.iformall.domain.po.WxMerchantBUser; import com.iformall.domain.po.WxOrder; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.WxPayOrder; +import com.iformall.domain.po.base.TenantEntity; import com.iformall.enums.EnumComposeOrder; import com.iformall.enums.EnumPayShare; import com.iformall.enums.EnumPayWay; @@ -34,7 +36,10 @@ public interface WxPayOrderService { * @param payWay * @return */ - ResultData createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user, WxPayOrder record, EnumPayWay payWay,PayExtraParam params); + ResultData createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user, WxPayOrder record, EnumPayWay payWay,PayExtraParam params,boolean isCreatePay); + + PayAdapterResult createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user,WxPayOrder record,WxComposeOrder composeOrder, + String productName, EnumPayWay payWay,PayExtraParam params,boolean isCreatePay); /** * 刷卡支付订单 @@ -157,4 +162,11 @@ public interface WxPayOrderService { boolean hasCompleted(WxComposeOrder composeOrder, WxPayOrder payOrder); + + /** + * 只douyin查询,不做任何操作 + * @param wxBatchOrder + * @return + */ + PayQueryAdapterResult ttorderQuery(TenantEntity tenantInfo, Long id); } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/TtCouponGoodsServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/TtCouponGoodsServiceImpl.java new file mode 100644 index 000000000..1655761c7 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/impl/TtCouponGoodsServiceImpl.java @@ -0,0 +1,426 @@ +package com.iformall.service.impl; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.iformall.common.ErrorCode; +import com.iformall.common.IdWorker; +import com.iformall.common.ResultData; +import com.iformall.domain.po.*; +import com.iformall.domain.po.base.BaseEntity; +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.*; +import com.iformall.douyin.web.api.TtWebService; +import com.iformall.douyin.web.bean.Product; +import com.iformall.enums.*; +import com.iformall.mapper.*; +import com.iformall.service.*; +import com.iformall.utils.Constant; +import me.chanjar.weixin.common.error.WxErrorException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; + + +@Service +public class TtCouponGoodsServiceImpl implements TtCouponGoodsService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + WxCouponMapper wxCouponMapper; + + @Autowired + WxCouponService wxCouponService; + + @Autowired + WxCouponChannelMapper wxCouponChannelMapper; + + @Autowired + WxCouponChannelService wxCouponChannelService; + + @Autowired + private TtMerchantPoiService ttMerchantPoiService; + + @Autowired + TtCouponChannelPoiMapper ttCouponChannelPoiMapper; + + @Autowired + WxAppinfoService wxAppinfoService; + + @Override + public ResultData couponList(TtCouponVo ttCouponVo, Integer pageNum, Integer pageSize) { + PageInfo pageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> wxCouponMapper.ttCouponList(ttCouponVo)); + List couponList = pageInfo.getList(); + + if(!couponList.isEmpty()){ + List ids = couponList.stream().map(p -> p.getId()).collect(toList()); + WxCouponChannel wxCouponChannel = new WxCouponChannel(); + wxCouponChannel.updateTenantInfo(ttCouponVo); + wxCouponChannel.setCouponIds(ids); + wxCouponChannel.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode()); + //上架状态 + List list = wxCouponChannelMapper.findList(wxCouponChannel); + if (!list.isEmpty()) { + Map> groupBy = list.stream().collect(Collectors.groupingBy(WxCouponChannel::getCouponId)); + for (TtCouponVo temp : couponList) { + if (groupBy.get(temp.getId()) != null) { + List channels = new ArrayList<>(); + for (WxCouponChannel tempchannel : groupBy.get(temp.getId())) { + if (!channels.contains(tempchannel.getTargetAd())) { + channels.add(tempchannel.getTargetAd()); + } + } + String sss = JSON.toJSONString(channels); + temp.setChannels(sss); + } else { + temp.setChannels(""); + } + + } + } else { + for (TtCouponVo temp : couponList) { + temp.setChannels(""); + } + + } + } + return new ResultData(pageInfo); + } + + @Override + public ResultData channelList(TtCouponChannelVo ttChannelVo, Integer pageNum, Integer pageSize) { + PageInfo ttCouponChannelVoPageInfo = wxCouponChannelService.ttChannelList(ttChannelVo, pageNum, pageSize); + return new ResultData(ttCouponChannelVoPageInfo); + } + + @Override + @Transactional(isolation=Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public ResultData productSave(WxCoupon coupon) throws Exception { + WxCoupon ttattrs = wxCouponService.getAttrsById(coupon.getId(), coupon.getTenantId()); + if(ttattrs.getProductType() == null || ttattrs.getCategoryId() == null + || ttattrs.getProductAttrKeyValueMap().isEmpty() + || ttattrs.getSkuAttrKeyValueMap().isEmpty()){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"该券缺少必要属性"); + } + if(coupon.getStatus() != EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode()) { + return new ResultData(ErrorCode.COUPON_ORDER_IS_INVALID); + } + + //获取门店 + List couponMerchantList = wxCouponService.getCouponMerchantList(coupon, coupon.getId()); + List poiList = new ArrayList(); + for (WxMerchantVo mvo:couponMerchantList){ + if(StringUtils.isNotBlank(mvo.getSupplierExtId())){ + Product.PoiStruct poiStruct = new Product.PoiStruct(); + poiStruct.setSupplierExtId(mvo.getSupplierExtId()); + poiList.add(poiStruct); + } + } + if(poiList.isEmpty()){ + return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND.getCode(),"未找到poi门店"); + } + + //查询是否有上架的 + WxCouponChannel wxCouponChannelQuery = new WxCouponChannel(); + wxCouponChannelQuery.updateTenantInfo(coupon); + wxCouponChannelQuery.setCouponId(coupon.getId()); + wxCouponChannelQuery.setTargetAd(EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode()); + wxCouponChannelQuery.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode()); + List wxCouponChannels = wxCouponChannelMapper.findList(wxCouponChannelQuery); + if(wxCouponChannels.size() > 0){ + return new ResultData(ErrorCode.COUPON_CHANNEL_IS_EXISTED); + } + //预审核的作废掉 重新投放 + wxCouponChannelQuery.setStatus(EnumCouponChannelStatus.STATUS_BEFORE.getCode()); + WxCouponChannel updCouponChannel = new WxCouponChannel(); + updCouponChannel.setStatus(EnumCouponChannelStatus.STATUS_AFTER.getCode()); + updCouponChannel.setUpdateDate(new Date()); + wxCouponChannelMapper.update(updCouponChannel,new QueryWrapper<>(wxCouponChannelQuery)); + //投放预审核 + WxCouponChannel wxCouponChannel = new WxCouponChannel(); + final IdWorker idWorker = IdWorker.get(); + wxCouponChannel.setId(idWorker.nextId()); + wxCouponChannel.updateTenantInfo(coupon); + wxCouponChannel.setShowBeginTime(new Date()); +// wxCouponChannel.setBeginTime(new Date()); + wxCouponChannel.setEndTime(coupon.getValidEndDate()); + wxCouponChannel.setStatus(EnumCouponChannelStatus.STATUS_BEFORE.getCode()); + wxCouponChannel.setCouponId(coupon.getId()); + wxCouponChannel.setType(coupon.getType()); + wxCouponChannel.setTargetAd(EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode()); + wxCouponChannel.setBusiness(coupon.getBusiness()); + wxCouponChannel.setSubBusiness(coupon.getSubBusiness()); + wxCouponChannel.setTitle(coupon.getTitle()); + wxCouponChannelMapper.insert(wxCouponChannel); + + //提交审核 + try { + + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(coupon); + Product product = new Product(); + Product.ProductStruct prostruct = new Product.ProductStruct(); + prostruct.setOutId(coupon.getId().toString()); + prostruct.setProductName(coupon.getTitle()); + prostruct.setCategoryId(ttattrs.getCategoryId()); + prostruct.setProductType(ttattrs.getProductType()); + prostruct.setBizLine(5);//默认小程序 + prostruct.setAccountName(couponMerchantList.get(0).getMerchantName()); + // prostruct.setSoldStartTime(); + // prostruct.setSoldEndTime(); + prostruct.setOutUrl(getGoodsEntrySchema(coupon,wxCouponChannel.getId())); + + prostruct.setPoiList(poiList); + prostruct.setAttrKeyValueMap(ttattrs.getProductAttrKeyValueMap()); + product.setProduct(prostruct); + + Product.SkuStruct skuStruct = new Product.SkuStruct(); + skuStruct.setSkuName(coupon.getTitle()); + skuStruct.setOriginAmount(coupon.getPrice()); + skuStruct.setActualAmount(coupon.getSalePrice()); + Product.StockStruct stockStruct = new Product.StockStruct(); + stockStruct.setLimitType(1); + stockStruct.setStockQty(coupon.getInventory()); + skuStruct.setStock(stockStruct); + skuStruct.setStatus(1); + skuStruct.setAttrKeyValueMap(ttattrs.getSkuAttrKeyValueMap()); + product.setSku(skuStruct); + + String productId = ttWebService.getGoodsService().productSave(product); + + if(StringUtils.isBlank(productId)){ + throw new Exception("未获取到抖音商品product_id"); + } + + WxCouponChannel updCC = new WxCouponChannel(); + updCC.setId(wxCouponChannel.getId()); + updCC.updateTenantInfo(wxCouponChannel); + wxCouponChannel.setTtSpuId(productId); + wxCouponChannelMapper.updateById(wxCouponChannel); + + syncCouponChannelPoi(coupon,wxCouponChannel.getId(),productId); + + return new ResultData(); + + } catch (WxErrorException e) { + throw new Exception(e.getMessage()); +// logger.error(e.getMessage()); +// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } catch (Exception e){ + throw e; +// logger.error(e.getMessage()); +// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + } + + @Override + public int handlerTtGoodsAudit(TtCouponChannelPoi couponChannelPoi) { + return ttCouponChannelPoiMapper.updateBySpuId(couponChannelPoi); + } + + @Override + public ResultData productDraftGet(TenantEntity tenantEntity,Long id) { + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantEntity.getTenantId(),id); + if(ttCouponChannelPoi == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"该券未提交审核"); + } + try { + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(ttCouponChannelPoi); + List products = ttWebService.getGoodsService().productDraftGet(null, ttCouponChannelPoi.getId().toString()); + if(products.size() > 0){ + Product product = products.get(0); + if(product.getDraftStatus().intValue() == 12 && !EnumSpuSyncStatus.sync_audit_rejection.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_audit_rejection.getCode()); + ttCouponChannelPoi.setLastStatusDesc(product.getAuditMsg()); + ttCouponChannelPoi.setUpdateDate(new Date()); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + + }else if(product.getDraftStatus().intValue() == 1 && !EnumSpuSyncStatus.sync_audit_pass.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_audit_pass.getCode()); + ttCouponChannelPoi.setLastStatusDesc(""); + ttCouponChannelPoi.setUpdateDate(new Date()); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + } + + return new ResultData(product); + }else{ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到审核数据"); + } + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),e.getMessage()); + } + } + + @Override + public ResultData productOnlineGet(TenantEntity tenantEntity,Long id) { + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantEntity.getTenantId(),id); + if(ttCouponChannelPoi == null){ + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"该券未提交审核"); + } + try { + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(ttCouponChannelPoi); + List products = ttWebService.getGoodsService().productOnlineGet(null, ttCouponChannelPoi.getId().toString()); + if(products.size() > 0){ + Product product = products.get(0); + if(product.getOnlineStatus().intValue() == 1 && !EnumSpuSyncStatus.sync_put_on.getCode().equals(ttCouponChannelPoi.getStatus())){ + ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_put_on.getCode()); + ttCouponChannelPoi.setUpdateDate(new Date()); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + }else if(product.getOnlineStatus().intValue() == 2 && !EnumSpuSyncStatus.sync_pull_off.getCode().equals(ttCouponChannelPoi.getStatus())){ + ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_pull_off.getCode()); + ttCouponChannelPoi.setUpdateDate(new Date()); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + }else if(product.getOnlineStatus().intValue() == 3 && !EnumSpuSyncStatus.sync_audit_disable.getCode().equals(ttCouponChannelPoi.getStatus())){ + ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_audit_disable.getCode()); + ttCouponChannelPoi.setUpdateDate(new Date()); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + } + return new ResultData(product); + }else{ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到在线数据"); + } + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),e.getMessage()); + } + } + + @Override + public ResultData productOperate(TenantEntity tenantInfo, Long id) { + WxCoupon wxCoupon = wxCouponMapper.selectById(id, tenantInfo.getTenantId()); + if(wxCoupon == null || EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode().equals(wxCoupon.getStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未找到或已作废"); + } + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantInfo.getTenantId(),id); + if(ttCouponChannelPoi == null || !EnumSpuSyncStatus.sync_audit_pass.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未提交审核或审核未通过"); + } + //查询上架 + //op_type int64 TRUE 1-上线 2-下线 + Integer op_type = 2; + WxCouponChannel wxCouponChannelQuery = new WxCouponChannel(); + wxCouponChannelQuery.updateTenantInfo(wxCoupon); + wxCouponChannelQuery.setCouponId(wxCoupon.getId()); + wxCouponChannelQuery.setTargetAd(EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode()); + wxCouponChannelQuery.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode()); + List wxCouponChannels = wxCouponChannelMapper.findList(wxCouponChannelQuery); + if(wxCouponChannels.size() > 0){ + op_type = 1; + } + + try { + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(ttCouponChannelPoi); + boolean b = ttWebService.getGoodsService().productOperate(null,wxCoupon.getId().toString(),op_type); + if(b){ + return new ResultData(); + }else{ + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); + } + + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),e.getMessage()); + } + } + + @Override + public ResultData productStockSync(TenantEntity tenantInfo, Long id) { + WxCoupon wxCoupon = wxCouponMapper.selectById(id, tenantInfo.getTenantId()); + if(wxCoupon == null || EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode().equals(wxCoupon.getStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未找到或已作废"); + } + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantInfo.getTenantId(),id); + if(ttCouponChannelPoi == null || !EnumSpuSyncStatus.sync_audit_pass.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未提交审核或审核未通过"); + } + try { + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(ttCouponChannelPoi); + boolean b = ttWebService.getGoodsService().stockSync(null,wxCoupon.getId().toString(),wxCoupon.getInventory()); + if(b){ + return new ResultData(); + }else{ + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); + } + + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),e.getMessage()); + } + } + + @Override + public ResultData productFreeAudit(TenantEntity tenantInfo, Long id) { + WxCoupon wxCoupon = wxCouponMapper.selectById(id, tenantInfo.getTenantId()); + if(wxCoupon == null || EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode().equals(wxCoupon.getStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未找到或已作废"); + } + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantInfo.getTenantId(),id); + if(ttCouponChannelPoi == null || !EnumSpuSyncStatus.sync_audit_pass.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未提交审核或审核未通过"); + } + try { + TtWebService ttWebService = ttMerchantPoiService.getTtWebService(ttCouponChannelPoi); + boolean b = ttWebService.getGoodsService().productFreeAudit(null,wxCoupon.getId().toString(), + null,wxCoupon.getInventory()); + if(b){ + return new ResultData(); + }else{ + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"修改失败"); + } + + } catch (WxErrorException e) { + e.printStackTrace(); + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),e.getMessage()); + } + } + + private void syncCouponChannelPoi(WxCoupon coupon,Long couponChannelId,String productId){ + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(coupon.getTenantId(),coupon.getId()); + Date date = new Date(); + if(ttCouponChannelPoi != null){ + ttCouponChannelPoi.setCouponChannelId(couponChannelId); + ttCouponChannelPoi.setSpuId(productId); +// ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); + ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); + ttCouponChannelPoi.setLastStatusDesc(""); + ttCouponChannelPoi.setUpdateDate(date); + ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); + }else{ + ttCouponChannelPoi = new TtCouponChannelPoi(); + ttCouponChannelPoi.setId(coupon.getId()); + ttCouponChannelPoi.updateTenantInfo(coupon); + ttCouponChannelPoi.setCouponChannelId(couponChannelId); + ttCouponChannelPoi.setSpuId(productId); +// ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); + ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); + ttCouponChannelPoi.setCreateDate(date); + ttCouponChannelPoi.setUpdateDate(date); + ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); + } + } + + private String getGoodsEntrySchema(TenantEntity tenantEntity,Long couponChannelId){ + WxAppinfo cAppInfo = wxAppinfoService.getCAppInfo(tenantEntity, EnumAppPlat.TOUTIAO); + Map map = new HashMap<>(); + map.put("app_id",cAppInfo.getAppId()); + map.put("path", Constant.mainPageUrl); + Map paramMap = new HashMap<>(); + paramMap.put("type","cd"); + paramMap.put("couponChannelId",couponChannelId); + map.put("params",JSON.toJSONString(paramMap)); + return JSON.toJSONString(map); + } + +} diff --git a/mallinkService/src/main/java/com/iformall/service/impl/TtGoodsCategoryServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/TtGoodsCategoryServiceImpl.java new file mode 100644 index 000000000..e4e54deac --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/impl/TtGoodsCategoryServiceImpl.java @@ -0,0 +1,448 @@ +package com.iformall.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.iformall.domain.po.TtGoodsCategory; +import com.iformall.domain.po.WxCoupon; +import com.iformall.douyin.web.bean.GoodsTemplateGet; +import com.iformall.enums.EnumCouponValidType; +import com.iformall.mapper.TtGoodsCategoryMapper; +import com.iformall.service.TtGoodsCategoryService; +import com.iformall.utils.DateUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class TtGoodsCategoryServiceImpl implements TtGoodsCategoryService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + TtGoodsCategoryMapper ttGoodsCategoryMapper; + + @Override + public List findTreeList() { + List listAll = ttGoodsCategoryMapper.findListAll(); + List topList = new ArrayList(); + for (TtGoodsCategory category:listAll) { + if(category.getParentId().intValue() == 0){ + category.setChild(getChild(listAll,category.getId())); + topList.add(category); + } + } + return topList; + } + + + private List getChild(List listAll,Integer parentId){ + List childList = new ArrayList(); + + for(TtGoodsCategory entity : listAll){ + if(parentId.equals(entity.getParentId())){ + entity.setChild(getChild(listAll,entity.getId())); + childList.add(entity); + } + } + + return childList; + } + + private List getProductAdminIsNotShowKey(){ + List keyList = new ArrayList<>(); + keyList.add("appointment"); //预约信息 默认不可预约 + keyList.add("auto_renew"); //是否开启自动延期 默认不开启 +// keyList.add("bring_out_meal"); //是否可以外带餐食 默认否 +// keyList.add("can_no_use_date");//不可使用日期 默认无 + keyList.add("customer_reserved_info");//留资规则 非必填 +// keyList.add("description_rich_text");//其他说明信息 非必填 +// keyList.add("detail_image_list");//长图 非必填 +// keyList.add("dishes_image_list");//菜品图 非必填 + keyList.add("EntryType");//入口类型 默认 2:小程序 + keyList.add("environment_image_list");//环境图 对应详情图 +// keyList.add("free_pack");//是否可以打包 默认否 +// keyList.add("FrontCategoryTag");//前台品类标签 非必填 + keyList.add("image_list");//封面图 对应系统商品图----------------------- + keyList.add("IndustryType");//商品行业类型 非必填 + keyList.add("IsConfirmImme");//是否立即确认 非必填 + keyList.add("MpResourceID");//小程序资源id 非必填 + keyList.add("MpSettleType");//小程序分账类型 非必填 +// keyList.add("Notification");//使用规则 对应系统的使用须知-------无法对应 +// keyList.add("private_room");//是否可以使用包间 + keyList.add("real_name_info");//实名信息 非必填 +// keyList.add("RecommendWord");//推荐语 非必填 +// keyList.add("rec_person_num");//建议使用人数 +// keyList.add("rec_person_num_max");//最多使用人数 + keyList.add("RefundPolicy");//退款政策 + keyList.add("refund_need_merchant_confirm");//退款是否需商家审核 默认否 +// keyList.add("show_channel");//投放渠道 默认1-不限制 + keyList.add("SortWeight");//排序权重 非必填 +// keyList.add("superimposed_discounts");//可以享受店内其他优惠 + keyList.add("TagList");//标签列表 非必填 + keyList.add("use_date");//使用日期 对应券有效期 + keyList.add("use_time");//使用时间 默认全天可用 + return keyList; + } + + private List getSkuAttrAdminIsNotShowKey(){ + List keyList = new ArrayList<>(); + keyList.add("code_source_type"); //券码生成方式 默认2 +// keyList.add("commodity"); //菜品搭配 + keyList.add("limit_rule");//限制购买 对应系统限购 + keyList.add("market_price");//市场价 对应原价 非必填 + keyList.add("settle_type");//收款方式1-总店结算 2-分店结算 ------待测试 + keyList.add("use_type");//团购使用方式 默认1 + return keyList; + } + + /** + * 去除默认值和系统自由属性 + * @param temp + * @return + */ + @Override + public void adminIsShow(GoodsTemplateGet temp) { + for (GoodsTemplateGet.ProductAttrs attr: temp.getProductAttrs()) { + if(getProductAdminIsNotShowKey().contains(attr.getKey())){ + attr.setIsShow(false); + }else{ + attr.setIsShow(true); + } + } + for (GoodsTemplateGet.ProductAttrs attr: temp.getSkuAttrs()) { + if(getSkuAttrAdminIsNotShowKey().contains(attr.getKey())){ + attr.setIsShow(false); + }else{ + attr.setIsShow(true); + } + } + } + + @Override + public void handTemplate(GoodsTemplateGet temp, WxCoupon coupon) { + if(!coupon.getProductAttrKeyValueMap().isEmpty()){ + for (GoodsTemplateGet.ProductAttrs attr: temp.getProductAttrs()) { + String value = coupon.getProductAttrKeyValueMap().get(attr.getKey()); + if(StringUtils.isNotBlank(value)){ + attr.setData(value); + } + } + } + if(!coupon.getSkuAttrKeyValueMap().isEmpty()){ + for (GoodsTemplateGet.ProductAttrs attr: temp.getSkuAttrs()) { + String value = coupon.getSkuAttrKeyValueMap().get(attr.getKey()); + if(StringUtils.isNotBlank(value)){ + attr.setData(value); + } + } + } + } + + @Override + public void handDefaultAttr(WxCoupon coupon, List productAttrs, List skuAttrs) { + for (GoodsTemplateGet.ProductAttrs attr: productAttrs) { + //预约信息 默认不可预约 + if("appointment".equals(attr.getKey())){ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("need_appointment",false); + jsonObject.put("ahead_day_num",0); + attr.setData(jsonObject.toJSONString()); + } + //是否开启自动延期 默认不开启 + else if("auto_renew".equals(attr.getKey())){ + attr.setData("false"); + } + //是否可以外带餐食 默认否------页面填写 +// else if("bring_out_meal".equals(attr.getKey())){ +// attr.setValue("false"); +// } + //不可使用日期 默认不开启 +// else if("can_no_use_date".equals(attr.getKey())){ +// JSONObject jsonObject = new JSONObject(); +// jsonObject.put("enable",false); +// attr.setData(jsonObject.toJSONString()); +// } + + /** + * 留资规则 ---暂无 + * "struct CustomerReservedInfoStruct { + * 1: required bool allow //是否留资 + * 2: optional bool allow_tel //可以留电话 + * 3: optional bool allow_name // 可以留姓名 + * 4: optional bool allow_identity // 可以留身份证 + * 5: optional bool require_for_tel //手机号是否必传 【默认非必传】 + * 10: optional bool need_for_all // 是否每张券都需要留资 + * }" + */ +// else if("customer_reserved_info".equals(attr.getKey())){ +// JSONObject jsonObject = new JSONObject(); +// +// attr.setValue(jsonObject.toJSONString()); +// } + + /** + * 其他说明信息 默认无------页面填写 + * "enum OtherNoteTypeEnum { + * TEXT = 1 // 文本 + * IMG = 2 // 图片 + * } + * + * struct NoteStruct { + * 1: optional OtherNoteTypeEnum note_type + * 2: optional string content + * }" + */ +// else if("description_rich_text".equals(attr.getKey())){ +// JSONArray jsonArray = new JSONArray(); +// +// attr.setValue(jsonArray.toJSONString()); +// } + /** + * 长图 默认无------页面填写 + * "struct ImageStruct { + * 1: optional string name + * 3: optional string url + * }" + */ +// else if("detail_image_list".equals(attr.getKey())){ +// JSONArray jsonArray = new JSONArray(); +// +// attr.setValue(jsonArray.toJSONString()); +// } + /** + * 菜品图 默认无------页面填写 + * "struct ImageStruct { + * 1: optional string name + * 3: optional string url + * }" + */ +// else if("dishes_image_list".equals(attr.getKey())){ +// JSONArray jsonArray = new JSONArray(); +// +// attr.setValue(jsonArray.toJSONString()); +// } + //入口类型 默认小程序 1:H5 2:小程序 3:抖音 4:lynx + else if("EntryType".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("2"); + } + } + /** + * 环境图 默认无------对应详情图 + * "struct ImageStruct { + * 1: optional string name + * 3: optional string url + * }" + */ + else if("environment_image_list".equals(attr.getKey())){ + JSONArray jsonArray = new JSONArray(); + List strings = JSONArray.parseArray(coupon.getDetailPicture(), String.class); + if(strings != null && strings.size() > 0){ + for (String url: strings) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("url",url); + jsonArray.add(jsonObject); + } + } + attr.setData(jsonArray.toJSONString()); + } + //是否可以打包 默认不开启-------页面填写 + else if("free_pack".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("false"); + } + } + /** + * 前台品类标签 ----页面填写 + * - 门票 + * - 项目 + * - 团购 + * - 一日游 + * - 多日游 + * - 旅行跟拍 + * - 含房套餐 + * - 美食套餐 + * - 美食单品 + * - 单景区门票 + * - 单景区套票 + * - 多景区联票 + * - 游玩项目票 + * - 门店项目票 + * - 门店服务 + * - 代金券 + * - 日历房 + * - 单房型 + * - 其他 + * - 测试 + */ +// else if("FrontCategoryTag".equals(attr.getKey())){ +// JSONArray jsonArray = new JSONArray(); +// jsonArray.add() +// attr.setValue(jsonArray.toJSONString()); +// } + /** + * 封面图 系统对应 + * "struct ImageStruct { + * 1: optional string name + * 3: optional string url + * }" + */ + else if("image_list".equals(attr.getKey())){ + JSONArray jsonArray = new JSONArray(); + List strings = JSONArray.parseArray(coupon.getCoverPicture(), String.class); + if(strings != null && strings.size() > 0){ + for (String url: strings) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("url",url); + jsonArray.add(jsonObject); + } + } + attr.setData(jsonArray.toJSONString()); + } + /** + * 商品行业类型(IndustryType)的枚举 -- 默认无 + * 传指定的中文字符串: + * - 门票 + * - 一日游 + * - 多日游 + * - 旅拍 + * - 其他 + */ +// else if("IndustryType".equals(attr.getKey())){ +// attr.setValue(); +// } + //是否立即确认 默认无 +// else if("IsConfirmImme".equals(attr.getKey())){ +// attr.setValue("false"); +// } + //小程序资源id 默认无 +// else if("MpResourceID".equals(attr.getKey())){ +// attr.setValue(""); +// } + //小程序分账类型 默认无 +// else if("MpSettleType".equals(attr.getKey())){ +// attr.setValue(""); +// } + //使用规则 页面填写 +// else if("Notification".equals(attr.getKey())){ +// attr.setValue("[]"); +// } + //是否可以使用包间 页面填写 + else if("private_room".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("false"); + } + } + //实名信息 默认无 +// else if("real_name_info".equals(attr.getKey())){ +// JSONObject jsonObject = new JSONObject(); +// jsonObject.put("enable",false); +// jsonObject.put("scene",0); +// attr.setData(jsonObject.toJSONString()); +// } + //推荐语 默认无 页面填写 +// else if("RecommendWord".equals(attr.getKey())){ +// attr.setData(""); +// } + //建议使用人数 页面填写 +// else if("rec_person_num".equals(attr.getKey())){ +// attr.setData(""); +// } + //最多使用人数 页面填写 +// else if("rec_person_num_max".equals(attr.getKey())){ +// attr.setData(""); +// } + //退款政策 默认1 1-允许退款 2-不可退款 3-有条件退 + else if("RefundPolicy".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("1"); + } + } + //退款是否需商家审核 默认false + else if("refund_need_merchant_confirm".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("false"); + } + } + //投放渠道 默认1 1-不限制 2-仅直播间可见 ----页面填写 + else if("show_channel".equals(attr.getKey())){ + if(StringUtils.isBlank(attr.getData())){ + attr.setData("1"); + } + } + //排序权重 默认无 +// else if("SortWeight".equals(attr.getKey())){ +// attr.setData("1"); +// } + //可以享受店内其他优惠 ----页面填写 +// else if("superimposed_discounts".equals(attr.getKey())){ +// attr.setData("false"); +// } + //标签列表 默认无 +// else if("TagList".equals(attr.getKey())){ +// attr.setData(""); +// } + //小程序提单页跳转 默认无 +// else if("trade_url".equals(attr.getKey())){ +// attr.setData(""); +// } + //使用日期 ----对应券有效期 + else if("use_date".equals(attr.getKey())){ + JSONObject jsonObject = new JSONObject(); + if(EnumCouponValidType.BETWEEN_TWO_TIME.getCode().equals(coupon.getValidType())){ + jsonObject.put("use_date_type",1); + jsonObject.put("use_start_date",DateUtils.date2String(coupon.getValidStartDate(),"yyyy-MM-dd")); + jsonObject.put("use_end_date",DateUtils.date2String(coupon.getValidEndDate(),"yyyy-MM-dd")); + }else if(EnumCouponValidType.DAYS_AFTER_RECEIVING.getCode().equals(coupon.getValidType())){ + jsonObject.put("use_date_type",2); + jsonObject.put("day_duration",coupon.getValidDays()); + } + + attr.setData(jsonObject.toJSONString()); + } + //使用日期 ----默认全天 + else if("use_time".equals(attr.getKey())){ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("use_time_type",1); + attr.setData(jsonObject.toJSONString()); + } + + } + + for (GoodsTemplateGet.ProductAttrs attr: skuAttrs) { + //券码生成方式 默认2 1-抖音码 2-三方码 3-预导码 + if("code_source_type".equals(attr.getKey())){ + attr.setData("2"); + } + //菜品搭配 页面填写 + else if("commodity".equals(attr.getKey())){ + + } + //限制购买 系统对应 + else if("limit_rule".equals(attr.getKey())){ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("is_limit",true); + jsonObject.put("total_buy_num",coupon.getUseLimitQuantity()); + attr.setData(jsonObject.toJSONString()); + } + //市场价 系统对应 非必填 +// else if("market_price".equals(attr.getKey())){ +// attr.setData(coupon.getPrice().toString()); +// } + //收款方式 测试一下1-总店结算 2-分店结算 + else if("settle_type".equals(attr.getKey())){ + attr.setData("1"); + } + //团购使用方式 1-到店核销 + else if("use_type".equals(attr.getKey())){ + attr.setData("1"); + } + + } + } + +} diff --git a/mallinkService/src/main/java/com/iformall/service/impl/TtMerchantPoiServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/TtMerchantPoiServiceImpl.java index 4490a9dfa..852d2cf2e 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/TtMerchantPoiServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/TtMerchantPoiServiceImpl.java @@ -505,45 +505,45 @@ public class TtMerchantPoiServiceImpl implements TtMerchantPoiService { return ttWebService; } - @Override - public ResultData findPoi(TenantEntity tenantInfo, Long couponChannelId) { - WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); - if(couponChannel == null || !EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到上架卷数据"); - } - if(!EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode().equals(couponChannel.getTargetAd())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"只有投放在列表的卷才能进行同步poi"); - } - WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); - if(coupon == null || !EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode().equals(coupon.getStatus())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到可投放的卷"); - } - if(!EnumCouponType.getSpuSyncType().contains(coupon.getType())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"卷类型不支持同步poi"); - } -// List list = new ArrayList<>(); -// TtMerchantPoi merchantPoi = ttMerchantPoiMapper.selectById(Long.parseLong(tenantInfo.getTenantId())); -//// TtMerchantPoi merchantPoi = ttMerchantPoiMapper.selectById(Long.parseLong("1038")); -// list.add(merchantPoi); - - List merchantIds = wxCouponMerchantMapper.findMerchantIdListByProduct(coupon.getId(), tenantInfo.getTenantId()); - if(merchantIds == null || merchantIds.size() == 0 ){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到门店"); - } - - TtMerchantPoi poi = new TtMerchantPoi(); - poi.updateTenantInfo(tenantInfo); - poi.setIds(merchantIds); - poi.setMatchStatus(EnumSupplierMathStatus.match_success.getCode()); - poi.setSyncStatus(EnumSupplierSyncStatus.sync_success.getCode()); - List poiList = ttMerchantPoiMapper.findList(poi); - if(poiList != null && merchantIds.size() == poiList.size()){ - return new ResultData(poiList); - }else{ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该商品店铺与poi门店不匹配"); - } - - } +// @Override +// public ResultData findPoi(TenantEntity tenantInfo, Long couponChannelId) { +// WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); +// if(couponChannel == null || !EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到上架卷数据"); +// } +// if(!EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode().equals(couponChannel.getTargetAd())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"只有投放在列表的卷才能进行同步poi"); +// } +// WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); +// if(coupon == null || !EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode().equals(coupon.getStatus())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到可投放的卷"); +// } +// if(!EnumCouponType.getSpuSyncType().contains(coupon.getType())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"卷类型不支持同步poi"); +// } +//// List list = new ArrayList<>(); +//// TtMerchantPoi merchantPoi = ttMerchantPoiMapper.selectById(Long.parseLong(tenantInfo.getTenantId())); +////// TtMerchantPoi merchantPoi = ttMerchantPoiMapper.selectById(Long.parseLong("1038")); +//// list.add(merchantPoi); +// +// List merchantIds = wxCouponMerchantMapper.findMerchantIdListByProduct(coupon.getId(), tenantInfo.getTenantId()); +// if(merchantIds == null || merchantIds.size() == 0 ){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到门店"); +// } +// +// TtMerchantPoi poi = new TtMerchantPoi(); +// poi.updateTenantInfo(tenantInfo); +// poi.setIds(merchantIds); +// poi.setMatchStatus(EnumSupplierMathStatus.match_success.getCode()); +// poi.setSyncStatus(EnumSupplierSyncStatus.sync_success.getCode()); +// List poiList = ttMerchantPoiMapper.findList(poi); +// if(poiList != null && merchantIds.size() == poiList.size()){ +// return new ResultData(poiList); +// }else{ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该商品店铺与poi门店不匹配"); +// } +// +// } private void updateWebAccessToken(WxAppinfo appinfo, TtWebService ttWebService) { try { @@ -565,386 +565,386 @@ public class TtMerchantPoiServiceImpl implements TtMerchantPoiService { } } - @Override - public ResultData spuSync(TenantEntity tenantInfo, Long couponChannelId, List merchantIds) { - WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); - if(couponChannel == null || !EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到上架卷数据"); - } - if(!EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode().equals(couponChannel.getTargetAd())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"只有投放在列表的卷才能进行同步poi"); - } - WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); - if(coupon == null || !EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode().equals(coupon.getStatus())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到可投放的卷"); - } - if(!EnumCouponType.getSpuSyncType().contains(coupon.getType())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"卷类型不支持同步poi"); - } - List couponMerchantIds = wxCouponMerchantMapper.findMerchantIdListByProduct(coupon.getId(), tenantInfo.getTenantId()); - if(couponMerchantIds == null || couponMerchantIds.size() == 0 ){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到门店"); - } - - TtMerchantPoi poi = new TtMerchantPoi(); - poi.updateTenantInfo(tenantInfo); - poi.setIds(couponMerchantIds); - poi.setMatchStatus(EnumSupplierMathStatus.match_success.getCode()); - poi.setSyncStatus(EnumSupplierSyncStatus.sync_success.getCode()); - List poiList = ttMerchantPoiMapper.findList(poi); - if(poiList == null || poiList.isEmpty()){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到匹配的poi"); - } -// List collect = poiList.stream().map(p -> p.getId()).collect(Collectors.toList()); - - String spuId = spuSync(coupon,couponChannel,couponMerchantIds); - if(StringUtils.isBlank(spuId)){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"同步失败"); - } - WxCouponChannel ccUpd = new WxCouponChannel(); - ccUpd.setId(couponChannel.getId()); - ccUpd.updateTenantInfo(couponChannel); - ccUpd.setTtSpuId(spuId); - ccUpd.setUpdateDate(new Date()); - wxCouponChannelMapper.updateById(ccUpd); - - syncCouponChannelPoi(ccUpd); - return new ResultData(); - } - - private void syncCouponChannelPoi(WxCouponChannel ccUpd){ - TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(ccUpd.getId()); - if(ttCouponChannelPoi != null){ - ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); - ttCouponChannelPoi.setLastStatusDesc(""); - ttCouponChannelPoi.setUpdateDate(ccUpd.getUpdateDate()); - ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); - }else{ - ttCouponChannelPoi = new TtCouponChannelPoi(); - ttCouponChannelPoi.setId(ccUpd.getId()); - ttCouponChannelPoi.updateTenantInfo(ccUpd); - ttCouponChannelPoi.setSpuId(ccUpd.getTtSpuId()); - ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); - ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); - ttCouponChannelPoi.setCreateDate(ccUpd.getUpdateDate()); - ttCouponChannelPoi.setUpdateDate(ccUpd.getUpdateDate()); - ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); - } - } - - private String spuSync(WxCoupon coupon,WxCouponChannel couponChannel, List merchantIds){ - TtSpuSync spuSync = new TtSpuSync(); - spuSync.setEntryInfo(getEntryInfo(couponChannel)); -// spuSync.setFrontCategoryTag();//前台品类标签 -// spuSync.setRecommendWord();//推荐语,5~20个字 -// spuSync.setSortWeight();//排序权重,按降序排列 - List collect = merchantIds.stream().map(merchantId -> merchantId.toString()).collect(Collectors.toList()); - spuSync.setSupplierExtIdList(collect); - spuSync.setPrice(coupon.getSalePrice()); - spuSync.setSpuExtId(couponChannel.getId().toString()); - spuSync.setImageList(JSONArray.parseArray(coupon.getCoverPicture(),String.class)); -// spuSync.setMpSettletype();//小程序结算类型 1-包销 2-代销 - spuSync.setOriginPrice(coupon.getPrice()); -// spuSync.setTakeRate();//商品的抽佣率,万分数 - spuSync.setAttribute(getAttribute(coupon,couponChannel)); -// spuSync.setHighlights(getHighlights(coupon)); - spuSync.setName(coupon.getTitle()); -// spuSync.setOrderDependsOnDate(false);//下单是否依赖日期 - spuSync.setSpuType(91);//spu类型号,1-日历房,30-酒店民宿预售券,90-门票,91-团购券 - if(EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ - spuSync.setStatus(1); - }else{ - spuSync.setStatus(2); - } - spuSync.setStock(coupon.getRemainInventory()); - - String spuId = null; - try { - spuId = getTtWebService(coupon).getProductService().spuSync(spuSync); - } catch (WxErrorException e) { - logger.error("发起商品同步error"+e.getMessage()); - throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); - } - return spuId; - } +// @Override +// public ResultData spuSync(TenantEntity tenantInfo, Long couponChannelId, List merchantIds) { +// WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); +// if(couponChannel == null || !EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到上架卷数据"); +// } +// if(!EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode().equals(couponChannel.getTargetAd())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"只有投放在列表的卷才能进行同步poi"); +// } +// WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); +// if(coupon == null || !EnumCouponStatus.COUPON_STATUS_THROW_IN.getCode().equals(coupon.getStatus())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到可投放的卷"); +// } +// if(!EnumCouponType.getSpuSyncType().contains(coupon.getType())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"卷类型不支持同步poi"); +// } +// List couponMerchantIds = wxCouponMerchantMapper.findMerchantIdListByProduct(coupon.getId(), tenantInfo.getTenantId()); +// if(couponMerchantIds == null || couponMerchantIds.size() == 0 ){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到门店"); +// } +// +// TtMerchantPoi poi = new TtMerchantPoi(); +// poi.updateTenantInfo(tenantInfo); +// poi.setIds(couponMerchantIds); +// poi.setMatchStatus(EnumSupplierMathStatus.match_success.getCode()); +// poi.setSyncStatus(EnumSupplierSyncStatus.sync_success.getCode()); +// List poiList = ttMerchantPoiMapper.findList(poi); +// if(poiList == null || poiList.isEmpty()){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未查询到匹配的poi"); +// } +//// List collect = poiList.stream().map(p -> p.getId()).collect(Collectors.toList()); +// +// String spuId = spuSync(coupon,couponChannel,couponMerchantIds); +// if(StringUtils.isBlank(spuId)){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"同步失败"); +// } +// WxCouponChannel ccUpd = new WxCouponChannel(); +// ccUpd.setId(couponChannel.getId()); +// ccUpd.updateTenantInfo(couponChannel); +// ccUpd.setTtSpuId(spuId); +// ccUpd.setUpdateDate(new Date()); +// wxCouponChannelMapper.updateById(ccUpd); +// +// syncCouponChannelPoi(ccUpd); +// return new ResultData(); +// } + +// private void syncCouponChannelPoi(WxCouponChannel ccUpd){ +// TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(ccUpd.getTenantId(),ccUpd.getId()); +// if(ttCouponChannelPoi != null){ +// ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); +// ttCouponChannelPoi.setLastStatusDesc(""); +// ttCouponChannelPoi.setUpdateDate(ccUpd.getUpdateDate()); +// ttCouponChannelPoiMapper.updateById(ttCouponChannelPoi); +// }else{ +// ttCouponChannelPoi = new TtCouponChannelPoi(); +// ttCouponChannelPoi.setId(ccUpd.getId()); +// ttCouponChannelPoi.updateTenantInfo(ccUpd); +// ttCouponChannelPoi.setSpuId(ccUpd.getTtSpuId()); +// ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); +// ttCouponChannelPoi.setLastStatus(EnumSpuSyncStatus.sync_auditing.getCode()); +// ttCouponChannelPoi.setCreateDate(ccUpd.getUpdateDate()); +// ttCouponChannelPoi.setUpdateDate(ccUpd.getUpdateDate()); +// ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); +// } +// } + +// private String spuSync(WxCoupon coupon,WxCouponChannel couponChannel, List merchantIds){ +// TtSpuSync spuSync = new TtSpuSync(); +// spuSync.setEntryInfo(getEntryInfo(couponChannel)); +//// spuSync.setFrontCategoryTag();//前台品类标签 +//// spuSync.setRecommendWord();//推荐语,5~20个字 +//// spuSync.setSortWeight();//排序权重,按降序排列 +// List collect = merchantIds.stream().map(merchantId -> merchantId.toString()).collect(Collectors.toList()); +// spuSync.setSupplierExtIdList(collect); +// spuSync.setPrice(coupon.getSalePrice()); +// spuSync.setSpuExtId(couponChannel.getId().toString()); +// spuSync.setImageList(JSONArray.parseArray(coupon.getCoverPicture(),String.class)); +//// spuSync.setMpSettletype();//小程序结算类型 1-包销 2-代销 +// spuSync.setOriginPrice(coupon.getPrice()); +//// spuSync.setTakeRate();//商品的抽佣率,万分数 +// spuSync.setAttribute(getAttribute(coupon,couponChannel)); +//// spuSync.setHighlights(getHighlights(coupon)); +// spuSync.setName(coupon.getTitle()); +//// spuSync.setOrderDependsOnDate(false);//下单是否依赖日期 +// spuSync.setSpuType(91);//spu类型号,1-日历房,30-酒店民宿预售券,90-门票,91-团购券 +// if(EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ +// spuSync.setStatus(1); +// }else{ +// spuSync.setStatus(2); +// } +// spuSync.setStock(coupon.getRemainInventory()); +// +// String spuId = null; +// try { +// spuId = getTtWebService(coupon).getProductService().spuSync(spuSync); +// } catch (WxErrorException e) { +// logger.error("发起商品同步error"+e.getMessage()); +// throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +// } +// return spuId; +// } //__________________________________商品同步_______________________________________________ //获取入口信息 - private JsonObject getEntryInfo(WxCouponChannel couponChannel){ - JsonObject object = new JsonObject(); - object.addProperty("entry_type",2);//入口类型(1:H5,2:抖音小程序,3:抖音链接) - JsonObject miniApp = new JsonObject(); - miniApp.addProperty("params",couponChannel.getTtparams()); - miniApp.addProperty("path",couponChannel.getTtPath()); - WxAppinfo appInfo = wxAppinfoService.getCAppInfo(couponChannel, EnumAppPlat.TOUTIAO); - miniApp.addProperty("app_id",appInfo.getAppId()); - object.add("entry_miniApp",miniApp); - return object; - } - - //获取SPU属性字段 - private JsonObject getAttribute(WxCoupon coupon,WxCouponChannel couponChannel){ +// private JsonObject getEntryInfo(WxCouponChannel couponChannel){ // JsonObject object = new JsonObject(); - JsonObject productObjuct = new JsonObject(); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - productObjuct.addProperty("groupon_valid_start",dateFormat.format(couponChannel.getShowBeginTime()));//团购售卖时间开始 - // todo 要求必传, 可能为空 - productObjuct.addProperty("groupon_valid_end",dateFormat.format(coupon.getValidEndDate()));//******* - - productObjuct.addProperty("order_limit",coupon.getUseLimitQuantity());//单个用户购买数量限制 - if(EnumCouponValidType.BETWEEN_TWO_TIME.getCode().equals(coupon.getValidType())){ - productObjuct.addProperty("order_valid_start",dateFormat.format(coupon.getValidStartDate())); - productObjuct.addProperty("order_valid_end",dateFormat.format(coupon.getValidEndDate())); - }else if(EnumCouponValidType.DAYS_AFTER_RECEIVING.getCode().equals(coupon.getValidType())){ - productObjuct.addProperty("post_purchase_day",coupon.getValidDays()); - } - //todo 商家客服电话 目前传的广场的客服电话 联系人广场名称 - WxMall mall = wxMallMapper.getByTenantId(coupon.getTenantId()); - JsonArray phoneArray = new JsonArray(); - phoneArray.add(mall.getServicePhone()); - productObjuct.add("service_phone",phoneArray); - productObjuct.addProperty("contact_name",mall.getName()); - - //todo 团购须知 要求格式 标题加类容 是否二选一 待测试 - JsonArray notificationArray = new JsonArray(); -// for ( : ) { - JsonObject contentObject = new JsonObject(); - contentObject.addProperty("title","");//标题 - contentObject.addProperty("content",coupon.getRemark());//内容 - notificationArray.add(contentObject); -// } - productObjuct.add("notification",notificationArray); - if(EnumCouponContentType.HTML.getCode().equals(coupon.getContentType())){ - productObjuct.addProperty("notification_rich_text",coupon.getHtml()); - } - productObjuct.addProperty("sub_title",coupon.getSubTitle()); - - //todo 团购详情 要求必传, 待测试 - if(StringUtils.isNotBlank(coupon.getItemGroup())){ - JsonArray groupArray = new JsonParser().parse(coupon.getItemGroup()).getAsJsonArray(); - productObjuct.add("pay_item_groups",groupArray); - } -// JsonArray groupArray = new JsonArray(); -// for ( : ) { -// JsonObject groupObject = new JsonObject(); -// groupObject.addProperty("group_name","标题");//标题 -// JsonArray itemArray = new JsonArray(); //菜品 -// for (:) { -// JsonObject itemObject = new JsonObject(); -// itemObject.addProperty("name","菜名"); -// itemObject.addProperty("count","数量"); -// itemObject.addProperty("price","价格"); -// itemArray.add(itemObject); -// } -// groupObject.add("item_list",itemArray); -// groupArray.add(groupObject); -// } -// productObjuct.add("pay_item_groups",groupArray); - - //使用日期规则 -// JsonObject dateRuleObject = new JsonObject(); -// JsonObject unDateObject = new JsonObject();//不可用日期 -// JsonArray dateArray = new JsonArray();//日期列表,格式yyyy-mm-dd,最多传100个 -// JsonArray weekDayArray = new JsonArray();//星期列表,1-7代表周一到周天,[1,2]代表周一周二不可用 -// unDateObject.add("date_list",dateArray); -// unDateObject.add("weekday_list",weekDayArray); -// dateRuleObject.add("unavailable_date",unDateObject); -// productObjuct.add("date_rule",dateRuleObject); - - return productObjuct; - } - - //商品亮点标签 - private JsonArray getHighlights(WxCoupon coupon){ - JsonArray array = new JsonArray(); -// for (:) { -// JsonObject object = new JsonObject(); -// object.addProperty("content",);//介绍,字符串长度<=5 -// object.addProperty("priority",);//优先级,数字越小优先级越高 -// array.add(object); +// object.addProperty("entry_type",2);//入口类型(1:H5,2:抖音小程序,3:抖音链接) +// JsonObject miniApp = new JsonObject(); +// miniApp.addProperty("params",couponChannel.getTtparams()); +// miniApp.addProperty("path",couponChannel.getTtPath()); +// WxAppinfo appInfo = wxAppinfoService.getCAppInfo(couponChannel, EnumAppPlat.TOUTIAO); +// miniApp.addProperty("app_id",appInfo.getAppId()); +// object.add("entry_miniApp",miniApp); +// return object; +// } +// +// //获取SPU属性字段 +// private JsonObject getAttribute(WxCoupon coupon,WxCouponChannel couponChannel){ +//// JsonObject object = new JsonObject(); +// JsonObject productObjuct = new JsonObject(); +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// productObjuct.addProperty("groupon_valid_start",dateFormat.format(couponChannel.getShowBeginTime()));//团购售卖时间开始 +// // todo 要求必传, 可能为空 +// productObjuct.addProperty("groupon_valid_end",dateFormat.format(coupon.getValidEndDate()));//******* +// +// productObjuct.addProperty("order_limit",coupon.getUseLimitQuantity());//单个用户购买数量限制 +// if(EnumCouponValidType.BETWEEN_TWO_TIME.getCode().equals(coupon.getValidType())){ +// productObjuct.addProperty("order_valid_start",dateFormat.format(coupon.getValidStartDate())); +// productObjuct.addProperty("order_valid_end",dateFormat.format(coupon.getValidEndDate())); +// }else if(EnumCouponValidType.DAYS_AFTER_RECEIVING.getCode().equals(coupon.getValidType())){ +// productObjuct.addProperty("post_purchase_day",coupon.getValidDays()); // } - return array; - } +// //todo 商家客服电话 目前传的广场的客服电话 联系人广场名称 +// WxMall mall = wxMallMapper.getByTenantId(coupon.getTenantId()); +// JsonArray phoneArray = new JsonArray(); +// phoneArray.add(mall.getServicePhone()); +// productObjuct.add("service_phone",phoneArray); +// productObjuct.addProperty("contact_name",mall.getName()); +// +// //todo 团购须知 要求格式 标题加类容 是否二选一 待测试 +// JsonArray notificationArray = new JsonArray(); +//// for ( : ) { +// JsonObject contentObject = new JsonObject(); +// contentObject.addProperty("title","");//标题 +// contentObject.addProperty("content",coupon.getRemark());//内容 +// notificationArray.add(contentObject); +//// } +// productObjuct.add("notification",notificationArray); +// if(EnumCouponContentType.HTML.getCode().equals(coupon.getContentType())){ +// productObjuct.addProperty("notification_rich_text",coupon.getHtml()); +// } +// productObjuct.addProperty("sub_title",coupon.getSubTitle()); +// +// //todo 团购详情 要求必传, 待测试 +// if(StringUtils.isNotBlank(coupon.getItemGroup())){ +// JsonArray groupArray = new JsonParser().parse(coupon.getItemGroup()).getAsJsonArray(); +// productObjuct.add("pay_item_groups",groupArray); +// } +//// JsonArray groupArray = new JsonArray(); +//// for ( : ) { +//// JsonObject groupObject = new JsonObject(); +//// groupObject.addProperty("group_name","标题");//标题 +//// JsonArray itemArray = new JsonArray(); //菜品 +//// for (:) { +//// JsonObject itemObject = new JsonObject(); +//// itemObject.addProperty("name","菜名"); +//// itemObject.addProperty("count","数量"); +//// itemObject.addProperty("price","价格"); +//// itemArray.add(itemObject); +//// } +//// groupObject.add("item_list",itemArray); +//// groupArray.add(groupObject); +//// } +//// productObjuct.add("pay_item_groups",groupArray); +// +// //使用日期规则 +//// JsonObject dateRuleObject = new JsonObject(); +//// JsonObject unDateObject = new JsonObject();//不可用日期 +//// JsonArray dateArray = new JsonArray();//日期列表,格式yyyy-mm-dd,最多传100个 +//// JsonArray weekDayArray = new JsonArray();//星期列表,1-7代表周一到周天,[1,2]代表周一周二不可用 +//// unDateObject.add("date_list",dateArray); +//// unDateObject.add("weekday_list",weekDayArray); +//// dateRuleObject.add("unavailable_date",unDateObject); +//// productObjuct.add("date_rule",dateRuleObject); +// +// return productObjuct; +// } +// +// //商品亮点标签 +// private JsonArray getHighlights(WxCoupon coupon){ +// JsonArray array = new JsonArray(); +//// for (:) { +//// JsonObject object = new JsonObject(); +//// object.addProperty("content",);//介绍,字符串长度<=5 +//// object.addProperty("priority",);//优先级,数字越小优先级越高 +//// array.add(object); +//// } +// return array; +// } //_________________________________________________________________________________ - @Override - public ResultData spuGet(TenantEntity tenantInfo, Long couponChannelId) { - WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); - if(couponChannel == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); - } - if(StringUtils.isBlank(couponChannel.getTtSpuId())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); - } - TtSpuGet spuGet = new TtSpuGet(); - spuGet.setSpuExtId(couponChannel.getId().toString()); - spuGet.setNeedSpuDraft(true); - spuGet.setSpuDraftcount(3); - try { - TtSpuGetResult spuGetResult = getTtWebService(tenantInfo).getProductService().spuGet(spuGet); - handSyncCouponChannelPoi(tenantInfo,spuGetResult); - //处理一下数据 - Map map = new HashMap<>(); - if(spuGetResult.getSpuDetail() != null){//线上数据 - TtSpuSync spuDetail = spuGetResult.getSpuDetail(); - map.put("spuDetail",handSpuSync(spuDetail)); - } - if(spuGetResult.getSpuDraft() != null && spuGetResult.getSpuDraft().size() > 0){//最近一次审核数据 - TtSpuSync spuDraft = spuGetResult.getSpuDraft().get(0); - map.put("spuDraft",handSpuSync(spuDraft)); - } - return new ResultData(map); - } catch (WxErrorException e) { - logger.error("couponChannelId:"+couponChannelId +" 多门店SPU信息查询error "+e.getMessage()); - return new ResultData(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); - } - } - - private void handSyncCouponChannelPoi(TenantEntity tenantInfo,TtSpuGetResult spuGetResult){ - Date now = new Date(); - TtSpuSync spuDetail = spuGetResult.getSpuDetail(); - if(spuDetail != null && StringUtils.isNotBlank(spuDetail.getSpuId()) && StringUtils.isNotBlank(spuDetail.getSpuExtId()) - && spuDetail.getStatus() != null){ - TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(Long.parseLong(spuDetail.getSpuExtId())); - if(ttCouponChannelPoi != null && !spuDetail.getStatus().equals(ttCouponChannelPoi.getStatus())){ - TtCouponChannelPoi ccPoi = new TtCouponChannelPoi(); - ccPoi.setId(ttCouponChannelPoi.getId()); - ccPoi.setStatus(spuDetail.getStatus()); - ccPoi.setStatusDesc(spuDetail.getStatusDesc()); - ccPoi.setUpdateDate(now); - ttCouponChannelPoiMapper.updateById(ccPoi); - }else if(ttCouponChannelPoi == null){ - ttCouponChannelPoi = new TtCouponChannelPoi(); - ttCouponChannelPoi.setId(Long.parseLong(spuDetail.getSpuExtId())); - ttCouponChannelPoi.updateTenantInfo(tenantInfo); - ttCouponChannelPoi.setSpuId(spuDetail.getSpuId()); - ttCouponChannelPoi.setStatus(spuDetail.getStatus()); - ttCouponChannelPoi.setStatusDesc(spuDetail.getStatusDesc()); - ttCouponChannelPoi.setCreateDate(now); - ttCouponChannelPoi.setUpdateDate(now); - ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); - } - } - List spuDraftList = spuGetResult.getSpuDraft(); - if(spuDraftList != null && spuDraftList.size() > 0){ - TtSpuSync spuDraft = spuDraftList.get(0); - if(spuDraft != null && StringUtils.isNotBlank(spuDraft.getSpuId()) && StringUtils.isNotBlank(spuDraft.getSpuExtId()) - && spuDraft.getStatus() != null){ - TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(Long.parseLong(spuDraft.getSpuExtId())); - if(ttCouponChannelPoi != null && !spuDraft.getStatus().equals(ttCouponChannelPoi.getStatus())){ - TtCouponChannelPoi ccPoi = new TtCouponChannelPoi(); - ccPoi.setId(ttCouponChannelPoi.getId()); - ccPoi.setLastStatus(spuDraft.getStatus()); - ccPoi.setLastStatusDesc(spuDraft.getStatusDesc()); - ccPoi.setUpdateDate(now); - ttCouponChannelPoiMapper.updateById(ccPoi); - }else if(ttCouponChannelPoi == null){ - ttCouponChannelPoi = new TtCouponChannelPoi(); - ttCouponChannelPoi.setId(Long.parseLong(spuDraft.getSpuExtId())); - ttCouponChannelPoi.updateTenantInfo(tenantInfo); - ttCouponChannelPoi.setSpuId(spuDraft.getSpuId()); - ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); - ttCouponChannelPoi.setLastStatus(spuDraft.getStatus()); - ttCouponChannelPoi.setLastStatusDesc(spuDraft.getStatusDesc()); - ttCouponChannelPoi.setCreateDate(now); - ttCouponChannelPoi.setUpdateDate(now); - ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); - } - } - } - } - - private Map handSpuSync(TtSpuSync spuSync){ - Map map = new HashMap<>(); - map.put("id",spuSync.getSpuExtId()); - map.put("spu_id",spuSync.getSpuId()); - map.put("image_list",spuSync.getImageList()); - map.put("name",spuSync.getName()); - if(spuSync.getAttribute() != null){ - JsonObject attribute = spuSync.getAttribute(); - JsonArray pay_item_groups = attribute.getAsJsonArray("pay_item_groups"); - map.put("pay_item_groups",pay_item_groups.toString()); - JsonArray notification = attribute.getAsJsonArray("notification"); - map.put("notification",notification.toString()); - map.put("order_limit", GsonHelper.getString(attribute, "order_limit")); - //售卖有效期 - map.put("groupon_valid_start", GsonHelper.getString(attribute, "groupon_valid_start")); - map.put("groupon_valid_end", GsonHelper.getString(attribute, "groupon_valid_end")); - //卷有效期 - map.put("order_valid_start", GsonHelper.getString(attribute, "order_valid_start")); - map.put("order_valid_end", GsonHelper.getString(attribute, "order_valid_end")); - - } - - map.put("price",spuSync.getPrice()); - map.put("origin_price",spuSync.getOriginPrice()); - map.put("stock",spuSync.getStock()); - map.put("status",spuSync.getStatus()); - map.put("status_desc",spuSync.getStatusDesc()); - return map; - } - - @Override - public ResultData spuStatusSync(TenantEntity tenantInfo, Long couponChannelId) { - WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); - if(couponChannel == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); - } - if(StringUtils.isBlank(couponChannel.getTtSpuId())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); - } - TtSpuStatusSync statusSync = new TtSpuStatusSync(); - List ids = new ArrayList<>(); - ids.add(couponChannel.getId().toString()); - statusSync.setSpuExtIdList(ids); - if(EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ - statusSync.setStatus(1); - }else{ - statusSync.setStatus(2); - } - try { - TtSpuStatusSync statusSyncResult = getTtWebService(tenantInfo).getProductService().spuStatusSync(statusSync); - if(statusSyncResult.getSpuExtIdList() != null && statusSyncResult.getSpuExtIdList().containsAll(ids)){ - return new ResultData(); - } - } catch (WxErrorException e) { - logger.error("couponChannelId:"+couponChannelId +" 多门店SPU状态同步error "+e.getMessage()); - throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); -// return new ResultData(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); - } - throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); -// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); - } - - @Override - public ResultData spuStockSync(TenantEntity tenantInfo, Long couponChannelId) { - WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); - if(couponChannel == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); - } - if(StringUtils.isBlank(couponChannel.getTtSpuId())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); - } - WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); - if(coupon == null){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到卷数据"); - } - TtSpuStockSync stockSync = new TtSpuStockSync(); - stockSync.setSpuExtId(couponChannel.getId().toString()); - stockSync.setStock(coupon.getRemainInventory()); - try { - boolean syncResult = getTtWebService(tenantInfo).getProductService().spuStockUpdate(stockSync); - if(syncResult){ - return new ResultData(); - } - } catch (WxErrorException e) { - logger.error("couponChannelId:"+couponChannelId +" 多门店SPU状态同步error "+e.getMessage()); - throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +// @Override +// public ResultData spuGet(TenantEntity tenantInfo, Long couponChannelId) { +// WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); +// if(couponChannel == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); +// } +// if(StringUtils.isBlank(couponChannel.getTtSpuId())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); +// } +// TtSpuGet spuGet = new TtSpuGet(); +// spuGet.setSpuExtId(couponChannel.getId().toString()); +// spuGet.setNeedSpuDraft(true); +// spuGet.setSpuDraftcount(3); +// try { +// TtSpuGetResult spuGetResult = getTtWebService(tenantInfo).getProductService().spuGet(spuGet); +// handSyncCouponChannelPoi(tenantInfo,spuGetResult); +// //处理一下数据 +// Map map = new HashMap<>(); +// if(spuGetResult.getSpuDetail() != null){//线上数据 +// TtSpuSync spuDetail = spuGetResult.getSpuDetail(); +// map.put("spuDetail",handSpuSync(spuDetail)); +// } +// if(spuGetResult.getSpuDraft() != null && spuGetResult.getSpuDraft().size() > 0){//最近一次审核数据 +// TtSpuSync spuDraft = spuGetResult.getSpuDraft().get(0); +// map.put("spuDraft",handSpuSync(spuDraft)); +// } +// return new ResultData(map); +// } catch (WxErrorException e) { +// logger.error("couponChannelId:"+couponChannelId +" 多门店SPU信息查询error "+e.getMessage()); // return new ResultData(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); - } - throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); -// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); - } +// } +// } +// +// private void handSyncCouponChannelPoi(TenantEntity tenantInfo,TtSpuGetResult spuGetResult){ +// Date now = new Date(); +// TtSpuSync spuDetail = spuGetResult.getSpuDetail(); +// if(spuDetail != null && StringUtils.isNotBlank(spuDetail.getSpuId()) && StringUtils.isNotBlank(spuDetail.getSpuExtId()) +// && spuDetail.getStatus() != null){ +// TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantInfo.getTenantId(),Long.parseLong(spuDetail.getSpuExtId())); +// if(ttCouponChannelPoi != null && !spuDetail.getStatus().equals(ttCouponChannelPoi.getStatus())){ +// TtCouponChannelPoi ccPoi = new TtCouponChannelPoi(); +// ccPoi.setId(ttCouponChannelPoi.getId()); +// ccPoi.setStatus(spuDetail.getStatus()); +// ccPoi.setStatusDesc(spuDetail.getStatusDesc()); +// ccPoi.setUpdateDate(now); +// ttCouponChannelPoiMapper.updateById(ccPoi); +// }else if(ttCouponChannelPoi == null){ +// ttCouponChannelPoi = new TtCouponChannelPoi(); +// ttCouponChannelPoi.setId(Long.parseLong(spuDetail.getSpuExtId())); +// ttCouponChannelPoi.updateTenantInfo(tenantInfo); +// ttCouponChannelPoi.setSpuId(spuDetail.getSpuId()); +// ttCouponChannelPoi.setStatus(spuDetail.getStatus()); +// ttCouponChannelPoi.setStatusDesc(spuDetail.getStatusDesc()); +// ttCouponChannelPoi.setCreateDate(now); +// ttCouponChannelPoi.setUpdateDate(now); +// ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); +// } +// } +// List spuDraftList = spuGetResult.getSpuDraft(); +// if(spuDraftList != null && spuDraftList.size() > 0){ +// TtSpuSync spuDraft = spuDraftList.get(0); +// if(spuDraft != null && StringUtils.isNotBlank(spuDraft.getSpuId()) && StringUtils.isNotBlank(spuDraft.getSpuExtId()) +// && spuDraft.getStatus() != null){ +// TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(tenantInfo.getTenantId(),Long.parseLong(spuDraft.getSpuExtId())); +// if(ttCouponChannelPoi != null && !spuDraft.getStatus().equals(ttCouponChannelPoi.getStatus())){ +// TtCouponChannelPoi ccPoi = new TtCouponChannelPoi(); +// ccPoi.setId(ttCouponChannelPoi.getId()); +// ccPoi.setLastStatus(spuDraft.getStatus()); +// ccPoi.setLastStatusDesc(spuDraft.getStatusDesc()); +// ccPoi.setUpdateDate(now); +// ttCouponChannelPoiMapper.updateById(ccPoi); +// }else if(ttCouponChannelPoi == null){ +// ttCouponChannelPoi = new TtCouponChannelPoi(); +// ttCouponChannelPoi.setId(Long.parseLong(spuDraft.getSpuExtId())); +// ttCouponChannelPoi.updateTenantInfo(tenantInfo); +// ttCouponChannelPoi.setSpuId(spuDraft.getSpuId()); +// ttCouponChannelPoi.setStatus(EnumSpuSyncStatus.sync_auditing.getCode()); +// ttCouponChannelPoi.setLastStatus(spuDraft.getStatus()); +// ttCouponChannelPoi.setLastStatusDesc(spuDraft.getStatusDesc()); +// ttCouponChannelPoi.setCreateDate(now); +// ttCouponChannelPoi.setUpdateDate(now); +// ttCouponChannelPoiMapper.insert(ttCouponChannelPoi); +// } +// } +// } +// } +// +// private Map handSpuSync(TtSpuSync spuSync){ +// Map map = new HashMap<>(); +// map.put("id",spuSync.getSpuExtId()); +// map.put("spu_id",spuSync.getSpuId()); +// map.put("image_list",spuSync.getImageList()); +// map.put("name",spuSync.getName()); +// if(spuSync.getAttribute() != null){ +// JsonObject attribute = spuSync.getAttribute(); +// JsonArray pay_item_groups = attribute.getAsJsonArray("pay_item_groups"); +// map.put("pay_item_groups",pay_item_groups.toString()); +// JsonArray notification = attribute.getAsJsonArray("notification"); +// map.put("notification",notification.toString()); +// map.put("order_limit", GsonHelper.getString(attribute, "order_limit")); +// //售卖有效期 +// map.put("groupon_valid_start", GsonHelper.getString(attribute, "groupon_valid_start")); +// map.put("groupon_valid_end", GsonHelper.getString(attribute, "groupon_valid_end")); +// //卷有效期 +// map.put("order_valid_start", GsonHelper.getString(attribute, "order_valid_start")); +// map.put("order_valid_end", GsonHelper.getString(attribute, "order_valid_end")); +// +// } +// +// map.put("price",spuSync.getPrice()); +// map.put("origin_price",spuSync.getOriginPrice()); +// map.put("stock",spuSync.getStock()); +// map.put("status",spuSync.getStatus()); +// map.put("status_desc",spuSync.getStatusDesc()); +// return map; +// } + +// @Override +// public ResultData spuStatusSync(TenantEntity tenantInfo, Long couponChannelId) { +// WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); +// if(couponChannel == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); +// } +// if(StringUtils.isBlank(couponChannel.getTtSpuId())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); +// } +// TtSpuStatusSync statusSync = new TtSpuStatusSync(); +// List ids = new ArrayList<>(); +// ids.add(couponChannel.getId().toString()); +// statusSync.setSpuExtIdList(ids); +// if(EnumCouponChannelStatus.STATUS_THROW_IN.getCode().equals(couponChannel.getStatus())){ +// statusSync.setStatus(1); +// }else{ +// statusSync.setStatus(2); +// } +// try { +// TtSpuStatusSync statusSyncResult = getTtWebService(tenantInfo).getProductService().spuStatusSync(statusSync); +// if(statusSyncResult.getSpuExtIdList() != null && statusSyncResult.getSpuExtIdList().containsAll(ids)){ +// return new ResultData(); +// } +// } catch (WxErrorException e) { +// logger.error("couponChannelId:"+couponChannelId +" 多门店SPU状态同步error "+e.getMessage()); +// throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +//// return new ResultData(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +// } +// throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); +//// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); +// } + +// @Override +// public ResultData spuStockSync(TenantEntity tenantInfo, Long couponChannelId) { +// WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(couponChannelId, tenantInfo.getTenantId()); +// if(couponChannel == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到卷数据"); +// } +// if(StringUtils.isBlank(couponChannel.getTtSpuId())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该券未同步poi"); +// } +// WxCoupon coupon = wxCouponMapper.selectById(couponChannel.getCouponId(), tenantInfo.getTenantId()); +// if(coupon == null){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"未找到卷数据"); +// } +// TtSpuStockSync stockSync = new TtSpuStockSync(); +// stockSync.setSpuExtId(couponChannel.getId().toString()); +// stockSync.setStock(coupon.getRemainInventory()); +// try { +// boolean syncResult = getTtWebService(tenantInfo).getProductService().spuStockUpdate(stockSync); +// if(syncResult){ +// return new ResultData(); +// } +// } catch (WxErrorException e) { +// logger.error("couponChannelId:"+couponChannelId +" 多门店SPU状态同步error "+e.getMessage()); +// throw new MallinkException(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +//// return new ResultData(ErrorCode.MSG_METHOD_REQUEST_ERROR.getCode(),e.getMessage()); +// } +// throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); +//// return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"同步失败"); +// } } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCampaignServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCampaignServiceImpl.java index 2231e832d..701ea5ad5 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCampaignServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCampaignServiceImpl.java @@ -176,7 +176,7 @@ public class WxCampaignServiceImpl implements WxCampaignService { } //type 为固定格式才会有券的信息 才会有投放的问题 - couponInject(wxCampaign); +// couponInject(wxCampaign); return new ResultData(Result.SUCCESS,"操作成功"); } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java index e238863e5..0c67948d1 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java @@ -12,10 +12,7 @@ import com.iformall.domain.po.WxCoupon; import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxMall; import com.iformall.domain.po.msg.FmInsideProductPushMsg; -import com.iformall.domain.vo.WxCouponCVo; -import com.iformall.domain.vo.WxCouponChannelAddVo; -import com.iformall.domain.vo.WxCouponChannelVo; -import com.iformall.domain.vo.WxMerchantVo; +import com.iformall.domain.vo.*; import com.iformall.enums.*; import com.iformall.exception.MallinkException; import com.iformall.mapper.*; @@ -160,19 +157,17 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { wxCardInfoMapper.updateTransferStatusByCouponId(orignal.getCouponId()); //浮层下架 wxFloatingLayerMapper.updateStatus(orignal.getCouponId()); + + try{ + spuStatusSyncByCoupon(orignal,orignal.getCouponId()); + }catch(Exception e){ + logger.error("send spuStatusSync error: " + e.getMessage()); + } } } record.setUpdateDate(new Date()); wxCouponChannelMapper.updateById(record); - if(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode().equals(record.getStatus())){ - try{ - spuStatusSync(record,record.getId()); - }catch(Exception e){ - logger.error("send spuStatusSync error: " + e.getMessage()); - } - } - } //清除缓存 @@ -181,12 +176,12 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { } @Override - public void spuStatusSync(TenantEntity tenantEntity, Long id) { + public void spuStatusSyncByCoupon(TenantEntity tenantEntity, Long couponId) { FmInsideProductPushMsg productPush = new FmInsideProductPushMsg(); productPush.setDelayTimeLevel(3); productPush.setMsgType(EnumMsgRecordType.INSIDE_PRODUCT_PUSH.getCode()); productPush.updateTenantInfo(tenantEntity); - productPush.setCouponChannelId(id); + productPush.setCouponId(couponId); productPush.setSyncType(EnumPushType.SPU_STATUS_SYNC); logger.info(">>>>>>>>>>>send FmInsideProductPushMsg :"+productPush); mqBaseProducer.sendMessage(productPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); @@ -307,24 +302,6 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { } } - private void spuStatusSyncByCoupon(TenantEntity tenantEntity, Long couponId){ - - List couponChannelIds = wxCouponChannelMapper.getPoiProductIdList(tenantEntity.getTenantId(),couponId); - if(couponChannelIds != null && couponChannelIds.size() > 0){ - for (Long couponChannelId:couponChannelIds) { - FmInsideProductPushMsg productPush = new FmInsideProductPushMsg(); - productPush.setDelayTimeLevel(3); - productPush.setMsgType(EnumMsgRecordType.INSIDE_PRODUCT_PUSH.getCode()); - productPush.updateTenantInfo(tenantEntity); - productPush.setCouponChannelId(couponChannelId); - productPush.setSyncType(EnumPushType.SPU_STATUS_SYNC); - logger.info(">>>>>>>>>>>send FmInsideProductPushMsg :"+productPush); - mqBaseProducer.sendMessage(productPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); - } - } - - } - @Override public ResultData change(WxCouponChannel record) { Long couponId = 0L; @@ -546,6 +523,7 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { return false; } + @Override public WxCouponChannelAddVo addCouponChannel(Long couponid,Integer channelId, TenantEntity tenantEntity,Date showBeginTime,Date beginTime,Date endTime,Integer channelPrice,Integer channelStock){ WxCouponChannelAddVo vo = new WxCouponChannelAddVo(); @@ -603,10 +581,12 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { // 投放渠道 if(channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_LIST.getCode()) || // 列表 + channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_CARD.getCode()) || // 卡频道 channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_PRESS.getCode()) || // 砍价 channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_ORDER_GROUP.getCode()) || // 拼团 channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_CREDIT.getCode()) || // 积分商城 + channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_DOUYIN_LIST.getCode()) || channelId.equals(EnumCouponChannelType.COUPON_CHANNEL_ID_WXLIVE_LIST.getCode()) //微信直播列表 ){ // 默认投放结束时间为有效时间之后 @@ -794,14 +774,52 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { @Override public ResultData getCouponChannelPoi(TenantEntity tenantInfo, Long id) { - TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectById(id); + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectByChannelId(tenantInfo.getTenantId(),id); if(ttCouponChannelPoi != null && ttCouponChannelPoi.getStatus() != null && ttCouponChannelPoi.getStatus().intValue() > 0){ return new ResultData(ttCouponChannelPoi); } return new ResultData(ErrorCode.SYS_NULLPOINTER_ERROR.getCode(),"未找到可用的数据"); } - @Override + @Override + public PageInfo ttChannelList(TtCouponChannelVo ttChannelVo, Integer pageNum, Integer pageSize) { + handleCouponIds(ttChannelVo); + if(ttChannelVo.getId() != null && ttChannelVo.getId().equals(-999L)){ + return new PageInfo(); + } + PageInfo pageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> wxCouponChannelMapper.ttChannelList(ttChannelVo)); + List list = pageInfo.getList(); + + if(list != null && !list.isEmpty()){ + List couponIds = list.stream().map(cc -> cc.getCouponId()).collect(Collectors.toList()); + Map couponMap = wxCouponService.getCouponMap(couponIds,ttChannelVo); + for (TtCouponChannelVo ccv:list) { + ccv.setWxCoupon(couponMap.get(ccv.getCouponId())); + } + } + return pageInfo; + } + + @Override + public ResultData updateOnline(WxCouponChannel wxCouponChannel) { + TtCouponChannelPoi ttCouponChannelPoi = ttCouponChannelPoiMapper.selectByChannelId(wxCouponChannel.getTenantId(),wxCouponChannel.getId()); + if(ttCouponChannelPoi == null || !EnumSpuSyncStatus.sync_audit_pass.getCode().equals(ttCouponChannelPoi.getLastStatus())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"该商品未提交审核或审核未通过"); + } + Date date = new Date(); + WxCouponChannel updChannel = new WxCouponChannel(); + updChannel.setId(wxCouponChannel.getId()); + updChannel.updateTenantInfo(wxCouponChannel); + updChannel.setStatus(EnumCouponChannelStatus.STATUS_THROW_IN.getCode()); + updChannel.setTtSpuId(ttCouponChannelPoi.getSpuId()); + updChannel.setShowBeginTime(date); + updChannel.setBeginTime(date); + updChannel.setUpdateDate(date); + wxCouponChannelMapper.updateById(updChannel); + return new ResultData(); + } + + @Override public WxCouponChannel getPriceAndStock(TenantEntity tenantEntity, Long couponChannelId) { return wxCouponChannelMapper.getPriceAndStock(couponChannelId, tenantEntity.getTenantId()); } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java index fc77a6117..99532230c 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java @@ -832,12 +832,12 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { retPageInfo.setPageSize(pageSize); retPageInfo.setPages(pageInfo.getPages()); retPageInfo.setTotal(pageInfo.getTotal()); - retPageInfo.setList(handleQueryResult(pageInfo.getList(), wxCouponOrderBVo)); + retPageInfo.setList(handleQueryResult(false,pageInfo.getList(), wxCouponOrderBVo)); return new ResultData(retPageInfo); } - private List handleQueryResult(List list,TenantEntity tenantEntity) { + private List handleQueryResult(boolean cUserEntry,List list,TenantEntity tenantEntity) { if (null != list && list.size() > 0) { @@ -984,8 +984,13 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { WxCUserBasicInfo basicInfo = cUserMap.get(co.getCUserId()); if (null != basicInfo) { - co.setcuserPhone(basicInfo.getPhone()); - co.setUserNickName(basicInfo.getNickName()); + if (!cUserEntry) { + co.setcuserPhone(basicInfo.getPhone()); + co.setUserNickName(basicInfo.getNickName()); + }else { + co.setcuserPhone("保密"); + co.setUserNickName("保密"); + } } Long bMechantId = co.getBMerchantId(); @@ -1155,18 +1160,24 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { } //核销商户 - String verifyMerchantName = StringUtils.trimToNull(wxCouponOrder.getVerifyMerchantName()); - if (null != verifyMerchantName) { - WxMerchant merchantQ2 = new WxMerchant(); - merchantQ2.updateTenantInfo(wxCouponOrder); - merchantQ2.setName(verifyMerchantName); - List merchantIds = wxMerchantMapper.findIdList(merchantQ2); - if (null == merchantIds || merchantIds.size() <= 0 ){ - //throw new MallinkException(ErrorCode.USER_IS_EMPTY.getCode(),"核销商户名称查询不到商户记录."); - wxCouponOrder.setId(-999L); - return; - } + if (null != wxCouponOrder.getVerifyMerchantId()) { + List merchantIds = new ArrayList(); + merchantIds.add(wxCouponOrder.getVerifyMerchantId()) ; wxCouponOrder.setBMerchantIdList(merchantIds); + }else { + String verifyMerchantName = StringUtils.trimToNull(wxCouponOrder.getVerifyMerchantName()); + if (null != verifyMerchantName) { + WxMerchant merchantQ2 = new WxMerchant(); + merchantQ2.updateTenantInfo(wxCouponOrder); + merchantQ2.setName(verifyMerchantName); + List merchantIds = wxMerchantMapper.findIdList(merchantQ2); + if (null == merchantIds || merchantIds.size() <= 0 ){ + //throw new MallinkException(ErrorCode.USER_IS_EMPTY.getCode(),"核销商户名称查询不到商户记录."); + wxCouponOrder.setId(-999L); + return; + } + wxCouponOrder.setBMerchantIdList(merchantIds); + } } } @@ -1188,14 +1199,14 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { } @Override - public void exportData(WxCouponOrderBVo wxCouponOrder, HttpServletRequest request, HttpServletResponse response) { + public void exportData(boolean cUserEntry,WxCouponOrderBVo wxCouponOrder, HttpServletRequest request, HttpServletResponse response) { String filename = "券订单"; if(EnumCouponType.COUPON_DISTRIBUTION.getCode().equals(wxCouponOrder.getCouponType())){ filename = "商品订单"; } handleWxCouponOrderBVoQueryParam(wxCouponOrder); List list = wxCouponOrderMapper.findListOfAdmin(wxCouponOrder); - List bolist = handleQueryResult(list,wxCouponOrder); + List bolist = handleQueryResult(cUserEntry,list,wxCouponOrder); excelService.exportCsv(bolist, null, filename, WxCouponOrderBVo.class, filename + ".csv", response, false); } @@ -1675,8 +1686,9 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { try { //如果是抖音支付 只能单次分账 if(EnumPayWay.PAY_WAY_TT.getCode().equals(payWay) && mulityShare){ - logger.error("抖音支付 只能单次分账: "); - return; + mulityShare = false; +// logger.error("抖音支付 只能单次分账: "); +// return; } WxPayOrder wxPayOrder = new WxPayOrder(); // Long orderId = couponOrder.getOrderId(); @@ -2823,7 +2835,7 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { retPageInfo.setPageSize(pageSize); retPageInfo.setPages(pageInfo.getPages()); retPageInfo.setTotal(pageInfo.getTotal()); - retPageInfo.setList(handleQueryResult(pageInfo.getList(), record)); + retPageInfo.setList(handleQueryResult(false,pageInfo.getList(), record)); return retPageInfo; } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java index d7d31067c..4de080f0b 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java @@ -19,6 +19,7 @@ import com.iformall.domain.vo.*; import com.iformall.domain.vo.excel.WxCardData; import com.iformall.domain.vo.excel.WxCouponData; import com.iformall.domain.vo.excel.WxPressData; +import com.iformall.douyin.web.bean.GoodsTemplateGet; import com.iformall.enums.*; import com.iformall.exception.MallinkException; import com.iformall.mapper.*; @@ -123,6 +124,13 @@ public class WxCouponServiceImpl implements WxCouponService { @Autowired WxProfitSharingReceiverMapper wxProfitSharingReceiverMapper; + @Autowired + private TtGoodsCategoryService ttGoodsCategoryService; + + + @Autowired + WxAppinfoService wxAppinfoService; + @Autowired private MqBaseProducer mqBaseProducer; @@ -189,6 +197,7 @@ public class WxCouponServiceImpl implements WxCouponService { } return new ResultData(page); } + @Override public List list(WxCoupon wxCoupon){ @@ -288,6 +297,11 @@ public class WxCouponServiceImpl implements WxCouponService { return wxCouponCVo; } + @Override + public WxCoupon getAttrsById(Long id, String tenantId) { + return wxCouponMapper.getAttrsById(id,tenantId); + } + private Long parseMerchantId(JSONObject merchantParam){ return Long.valueOf(merchantParam.getString("id")); @@ -349,16 +363,16 @@ public class WxCouponServiceImpl implements WxCouponService { if (StringUtils.isNotEmpty(record.getSubsidyNumStr())) { record.setSubsidyNum(new BigDecimal(record.getSubsidyNumStr()).multiply(new BigDecimal(100)).intValue()); } - if (EnumCouponType.COUPON_DOUYIN.getCode().equals(record.getType())){ - if(StringUtils.isBlank(record.getItemGroup())){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"团购详情不能为"); - } - try{ - JSON.parseArray(record.getItemGroup()); - }catch(Exception e){ - return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"团购详情格式不正确"); - } - } +// if (EnumCouponType.COUPON_DOUYIN.getCode().equals(record.getType())){ +// if(StringUtils.isBlank(record.getItemGroup())){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"团购详情不能为"); +// } +// try{ +// JSON.parseArray(record.getItemGroup()); +// }catch(Exception e){ +// return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"团购详情格式不正确"); +// } +// } if (StringUtils.isBlank(record.getCoverPicture())) { List strList = new ArrayList(); if (StringUtils.isNotBlank(record.getCoverImg())) { @@ -642,6 +656,47 @@ public class WxCouponServiceImpl implements WxCouponService { return new ResultData(record.getId()); } + @Override + public ResultData updateTtProduct(WxCoupon record) { + if(StringUtils.isBlank(record.getProductAttrs()) || StringUtils.isBlank(record.getSkuAttrs())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); + } + try{ + List productAttrs = JSONObject.parseArray(record.getProductAttrs(), GoodsTemplateGet.ProductAttrs.class); + List skuAttrs = JSONObject.parseArray(record.getSkuAttrs(), GoodsTemplateGet.ProductAttrs.class); + ttGoodsCategoryService.handDefaultAttr(record,productAttrs,skuAttrs); + for (GoodsTemplateGet.ProductAttrs attr:productAttrs) { + attr.setIsShow(null); + if(attr.getIsRequired() && StringUtils.isBlank(attr.getData())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"product属性" +attr.getName()+" 为空"); + } + } + record.setProductAttrs(JSONObject.toJSONString(productAttrs)); + for (GoodsTemplateGet.ProductAttrs attr:skuAttrs) { + attr.setIsShow(null); + if(attr.getIsRequired() && StringUtils.isBlank(attr.getData())){ + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"sku属性 "+attr.getName()+" 为空"); + } + } + record.setSkuAttrs(JSONObject.toJSONString(skuAttrs)); + }catch(Exception e){ + logger.error(e.getMessage(),e); + return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR); + } + WxCoupon coupon = new WxCoupon(); + coupon.setId(record.getId()); + coupon.updateTenantInfo(record); + coupon.setProductType(record.getProductType()); + coupon.setCategoryId(record.getCategoryId()); + coupon.setProductAttrs(record.getProductAttrs()); + coupon.setSkuAttrs(record.getSkuAttrs()); + coupon.setUpdateDate(new Date()); + wxCouponMapper.updateById(coupon); + //清空缓存 + clearCache(record); + return new ResultData(record.getId()); + } + /** * 清除c端首页券列表缓存 @@ -926,7 +981,12 @@ public class WxCouponServiceImpl implements WxCouponService { if(ret != 1) { throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "数据库更新数量错误"); } - //todo 更新库存后同步 + // 免审修改 + try{ + spuFreeAuditSync(wxCoupon,wxCoupon.getId()); + }catch(Exception e){ + logger.error("send spuStockSync error: " + e.getMessage()); + } // 5. 更新coupon channel 有效期 if(wxCoupon.getValidType().equals(EnumCouponValidType.BETWEEN_TWO_TIME.getCode())) { @@ -965,11 +1025,11 @@ public class WxCouponServiceImpl implements WxCouponService { if (num == 0) { throw new MallinkException(ErrorCode.ORDER_SAVE_ERR); } - try{ - spuStockSync(tenantEntity,id); - }catch(Exception e){ - logger.error("send spuStockSync error: " + e.getMessage()); - } +// try{ +// spuStockSync(tenantEntity,id); +// }catch(Exception e){ +// logger.error("send spuStockSync error: " + e.getMessage()); +// } } @Override @@ -979,14 +1039,14 @@ public class WxCouponServiceImpl implements WxCouponService { if (num == 0) { throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); } - try{ - spuStockSync(tenantEntity,id); - }catch(Exception e){ - logger.error("send spuStockSync error: " + e.getMessage()); - } +// try{ +// spuStockSync(tenantEntity,id); +// }catch(Exception e){ +// logger.error("send spuStockSync error: " + e.getMessage()); +// } } - private void spuStockSync(TenantEntity tenantEntity,Long id){ + private void spuStockSync(TenantEntity tenantEntity,Long couponId){ // new Thread(() -> { // //1秒之后同步poi // try { @@ -995,19 +1055,36 @@ public class WxCouponServiceImpl implements WxCouponService { // logger.error("sleep error: " + e.getMessage()); // } - List couponChannelIds = wxCouponChannelMapper.getPoiProductIdList(tenantEntity.getTenantId(),id); - if(couponChannelIds != null && couponChannelIds.size() > 0){ - for (Long couponChannelId:couponChannelIds) { - FmInsideProductPushMsg productPush = new FmInsideProductPushMsg(); - productPush.setDelayTimeLevel(3); - productPush.setMsgType(EnumMsgRecordType.INSIDE_PRODUCT_PUSH.getCode()); - productPush.updateTenantInfo(tenantEntity); - productPush.setCouponChannelId(couponChannelId); - productPush.setSyncType(EnumPushType.SPU_STOCK_SYNC); - logger.info(">>>>>>>>>>>send FmInsideProductPushMsg :"+productPush); - mqBaseProducer.sendMessage(productPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); - } - } + FmInsideProductPushMsg productPush = new FmInsideProductPushMsg(); + productPush.setDelayTimeLevel(3); + productPush.setMsgType(EnumMsgRecordType.INSIDE_PRODUCT_PUSH.getCode()); + productPush.updateTenantInfo(tenantEntity); + productPush.setCouponId(couponId); + productPush.setSyncType(EnumPushType.SPU_STOCK_SYNC); + logger.info(">>>>>>>>>>>send FmInsideProductPushMsg :"+productPush); + mqBaseProducer.sendMessage(productPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); + +// }).start(); + + } + + private void spuFreeAuditSync(TenantEntity tenantEntity,Long couponId){ +// new Thread(() -> { +// //1秒之后同步poi +// try { +// Thread.currentThread().sleep(1000); +// } catch (Exception e) { +// logger.error("sleep error: " + e.getMessage()); +// } + + FmInsideProductPushMsg productPush = new FmInsideProductPushMsg(); + productPush.setDelayTimeLevel(3); + productPush.setMsgType(EnumMsgRecordType.INSIDE_PRODUCT_PUSH.getCode()); + productPush.updateTenantInfo(tenantEntity); + productPush.setCouponId(couponId); + productPush.setSyncType(EnumPushType.SPU_FREE_AUDIT_SYNC); + logger.info(">>>>>>>>>>>send FmInsideProductPushMsg :"+productPush); + mqBaseProducer.sendMessage(productPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); // }).start(); @@ -1137,5 +1214,4 @@ public class WxCouponServiceImpl implements WxCouponService { return merchantList; } - } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java index a16db4d29..7d0d3c061 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java @@ -1331,6 +1331,7 @@ public class WxMerchantServiceImpl implements WxMerchantService { TtMerchantPoi poi = poiMap.get(m.getId()); if(null != poi){ m.setAddr(poi.getAddress()); + m.setSupplierExtId(poi.getSupplierExtId()); m.setTtPoi(poi.getPoiId()); m.setLongitude(poi.getLongitude()); m.setLatitude(poi.getLatitude()); @@ -1399,6 +1400,7 @@ public class WxMerchantServiceImpl implements WxMerchantService { vo.setShopVoList(merchantShopVoList.get(vo.getId())); } vo.setAddr(m.getAddr()); + vo.setSupplierExtId(m.getSupplierExtId()); vo.setTtPoi(m.getTtPoi()); vo.setLongitude(m.getLongitude()); vo.setLatitude(m.getLatitude()); diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java index 8815a1149..83d055df8 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java @@ -16,6 +16,7 @@ import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.alibaba.fastjson.JSONArray; import com.google.common.collect.Lists; import com.iformall.common.Result; import com.iformall.domain.po.*; @@ -33,6 +34,8 @@ import com.iformall.service.order.entity.WxComposeOrder; import com.iformall.service.order.util.OrderHelper; import com.iformall.service.pay.PayServiceFactory; +import com.iformall.service.pay.entity.PayExtraParam; +import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.utils.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -57,6 +60,7 @@ import com.iformall.common.IdWorker; import com.iformall.common.ResultData; import com.iformall.domain.dto.OrderComposeSaveDto; import com.iformall.domain.dto.OrderSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.domain.dto.WxSharingOrderDto; import com.iformall.domain.po.base.TenantEntity; import com.iformall.exception.MallinkException; @@ -912,7 +916,7 @@ public class WxOrderServiceImpl implements WxOrderService { * * @param user * @param coupon - * @param couponIdStr + * @param */ @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public StockReduceResult stockReduce(boolean allowUnPayOrder,WxCUserBasicInfo user, WxCoupon coupon, WxCouponChannel couponChannel,int number) { @@ -1342,6 +1346,7 @@ public class WxOrderServiceImpl implements WxOrderService { couponOrder.setAutoRefund(coupon.getAutoRefund()); couponOrder.setOrderId(order.getId()); couponOrder.setExpiredTime(valid_date); + couponOrder.setExtParam(order.getExtParam()); if (null != merchantId) { couponOrder.setSendMerchantId(merchantId); } @@ -2263,10 +2268,10 @@ public class WxOrderServiceImpl implements WxOrderService { logger.error("订单状态更新失败, e:" + e.getMessage(),e); throw new MallinkException(ErrorCode.ORDER_UPDATE_ERR); } - if(ret == 1){ - //订单同步 - sendInsideOrderPushMsg(oldOrder,oldOrder.getComposeOrderId()); - } +// if(ret == 1){ +// //订单同步 +// sendInsideOrderPushMsg(oldOrder,oldOrder.getComposeOrderId()); +// } return ret; } @@ -2765,6 +2770,82 @@ public class WxOrderServiceImpl implements WxOrderService { @Autowired @Qualifier("cUserBasicInfoRedisTemplate") RedisTemplate cUserBasicInfoRedisTemplate; + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public WxComposeOrder savePlatPushOrderForCoupon(TenantEntity tenantEntity,boolean allowUnPayOrder,EnumComposeOrder composeOrderType, + WxCUserBasicInfo user,String allExtParam,List platPushOrderList,EnumPayWay payWay) throws Exception { + WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); + // 防止同一用户重复下单,1秒内 + String key = new StringBuilder().append("savePlatPushOrder:").append(user.getId()).toString(); + boolean hasKey = cUserBasicInfoRedisTemplate.hasKey(key); + if (hasKey) { + logger.error("用户正在下单,请求异常返回,user: {} " + JSON.toJSONString(user)); + throw new MallinkException(ErrorCode.SYS_REPEAT_SUBMIT_EXCEPTION); + } + cUserBasicInfoRedisTemplate.opsForValue().set(key, user, 1000, TimeUnit.MILLISECONDS); + + OrderAdapterService orderAdapterService = orderFactory.getOrderAdapterService(composeOrderType.getCode()); + //从这里开始,就需要锁住渠道的价格,不能修改 + WxComposeOrder composeOrder = orderAdapterService.createDBMainOrderByPushOrder(tenantEntity,user, allExtParam,platPushOrderList, payWay); + Date orderDate = new Date(); + WxOrder lastOrder = null; + WxCoupon lastCoupon = null; + for (int i = 0 ; i < platPushOrderList.size(); i ++) { + PlatPushOrderSaveDto orderdto = platPushOrderList.get(i); + lastCoupon = orderdto.getWxCoupon(); + + Map couponChannelMap = composeOrder.getCouponChannelMap(); + Long couponChannelId = orderdto.getCouponChannelId(); + WxCouponChannel couponChannel = couponChannelMap.get(couponChannelId); + orderdto.setWxCouponChannel(couponChannel); + + //券一个数量创建一个订单 + boolean isOneNumberOneOrder = orderAdapterService.isOneNumberOneOrder(); + if (isOneNumberOneOrder) { + JSONArray jsonArray = new JSONArray(); + if(StringUtils.isNotBlank(orderdto.getExtParam())){ + logger.info("orderdto.getExtParam()---------------------------"+orderdto.getExtParam()); + try{ + jsonArray = JSONArray.parseArray(orderdto.getExtParam()); + }catch(Exception e){ + logger.error(e.getMessage()); + } + } + for (int j = 0; j < orderdto.getCount(); j++) { + String extParam = ""; + if(jsonArray != null && !jsonArray.isEmpty()){ + extParam = jsonArray.get(j).toString(); + } + logger.info("extParam---------------------------"+extParam); + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, + orderdto.isPress(),orderdto.getOrderGroupId(),orderdto.getFormId(),orderdto.getShippingType(),orderdto.getAddress(),extParam, + orderdto.getWxCouponChannel(), payWay); + } + }else { + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), orderdto.getCount(), + orderdto.isPress(),orderdto.getOrderGroupId(),orderdto.getFormId(),orderdto.getShippingType(),orderdto.getAddress(),orderdto.getExtParam(), + orderdto.getWxCouponChannel(), payWay); + } + } + //如果没有orderId,则用lastOrder的信息 + if (EnumComposeOrder.isSingle(composeOrderType.getCode())) { + composeOrder.setSingleOrder(lastOrder); + } + WxPayOrder record = new WxPayOrder(); + record.updateTenantInfo(tenantEntity); + record.setOrderId(composeOrder.getMainOrderId()); + record.setComposeOrder(composeOrder.getComposeOrderType()); + record.setOpenId((String) composeOrder.getMainOrder().getExpParamValue("open_id")); + String productName = orderAdapterService.getPayProductName(lastCoupon); + WxAppinfo cAppInfo = wxAppinfoService.getCAppInfo(tenantEntity, payWay.getPlat()); + PayAdapterResult payResult = wxPayOrderService.createPayOrder(cAppInfo, user, record,composeOrder,productName, payWay, new PayExtraParam("openId",record.getOpenId()),false); + if(payResult.isSuccess()){ + return composeOrder; + }else{ + throw new Exception(payResult.getMsg()); + } + } + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public WxComposeOrder saveOrderForCoupon(TenantEntity tenantEntity,boolean allowUnPayOrder,EnumComposeOrder composeOrderType,WxCUserBasicInfo user,List orderSave,EnumPayWay payWay) { @@ -2795,10 +2876,14 @@ public class WxOrderServiceImpl implements WxOrderService { boolean isOneNumberOneOrder = orderAdapterService.isOneNumberOneOrder(); if (isOneNumberOneOrder) { for (int j = 0; j < orderdto.getCount(); j++) { - lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, orderdto, payWay); + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, + orderdto.getSignleOrder().isPressOrder(),orderdto.getSignleOrder().getOrderGroupId(),orderdto.getSignleOrder().getFormId(), + orderdto.getShippingType(),orderdto.getAddress(),null,orderdto.getWxCouponChannel(), payWay); } }else { - lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), orderdto.getCount(), orderdto, payWay); + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), orderdto.getCount(), + orderdto.getSignleOrder().isPressOrder(),orderdto.getSignleOrder().getOrderGroupId(),orderdto.getSignleOrder().getFormId(), + orderdto.getShippingType(),orderdto.getAddress(),null,orderdto.getWxCouponChannel(), payWay); } } //如果没有orderId,则用lastOrder的信息 @@ -2809,15 +2894,15 @@ public class WxOrderServiceImpl implements WxOrderService { } @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public WxOrder handleSaveOrderForCouponSingle(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user,WxCoupon coupon,int perCouponNumber,OrderComposeSaveDto orderdto,EnumPayWay payWay) { + public WxOrder handleSaveOrderForCouponSingle(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user,WxCoupon coupon,int perCouponNumber, + boolean isPressOrder,Long orderGroupId,String formId,Integer shippinType,UserBasicInfoAddress address,String extParam,WxCouponChannel couponChannel,EnumPayWay payWay) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); // 是否砍价 WxOrder order = null; - WxCouponChannel couponChannel = orderdto.getWxCouponChannel(); - if (checkCouponIsFree(coupon,couponChannel,orderdto.getShippingType())) { + if (checkCouponIsFree(coupon,couponChannel,shippinType)) { // 免费券 order = proxy.saveFreeOrderForCoupon(orderDate,allowUnPayOrder,composeOrder,user, coupon,perCouponNumber,couponChannel, - orderdto.getSignleOrder().getFormId(),null,payWay,orderdto.getShippingType(),orderdto.getAddress()); + formId,null,extParam,payWay,shippinType,address); if (order != null) { // 6. 下订单完成,发送内部消息 // 下订单完成,发送内部消息 @@ -2830,7 +2915,8 @@ public class WxOrderServiceImpl implements WxOrderService { } } else { // 有价券 - order = proxy.saveNoFreeOrderForCoupon(orderDate,allowUnPayOrder,composeOrder,user, orderdto.getWxCoupon(),perCouponNumber,couponChannel,orderdto,payWay); + order = proxy.saveNoFreeOrderForCoupon(orderDate,allowUnPayOrder,composeOrder,user, coupon,perCouponNumber,isPressOrder, + orderGroupId,formId,shippinType,address,extParam,couponChannel,payWay); } // couponActionLog // try { @@ -2869,7 +2955,7 @@ public class WxOrderServiceImpl implements WxOrderService { @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) @Override public WxOrder saveFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber, - WxCouponChannel couponChannel, String formId, Long couponPasswordId,EnumPayWay payWay, + WxCouponChannel couponChannel, String formId, Long couponPasswordId,String extParam,EnumPayWay payWay, Integer shippingType, UserBasicInfoAddress address) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); @@ -2910,6 +2996,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setPayment(0); record.setFormId(formId); record.setOrderGroupId(0L); + record.setExtParam(extParam);; record.setShippingType(shippingType); if(EnumOrderShopingType.DISTRIBUTION.getCode().equals(shippingType)){ @@ -2936,7 +3023,8 @@ public class WxOrderServiceImpl implements WxOrderService { @Override @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,WxCouponChannel couponChannel,OrderComposeSaveDto orderdto,EnumPayWay payWay) { + public WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber, + boolean isPressOrder,Long orderGroupId,String formId,Integer shippinType,UserBasicInfoAddress address,String extParam,WxCouponChannel couponChannel,EnumPayWay payWay) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); // 3. 减库存操作。所有的订单都跟减库存操作时的订单详情保持一致 @@ -2970,22 +3058,22 @@ public class WxOrderServiceImpl implements WxOrderService { Long orderNumber; // 4.1 价格 渠道/券 WxComposeChildOrderPrice price = orderFactory.getOrderAdapterService(composeOrder.getComposeOrderType()) - .getChildCouponOrderPrice(orderdto,coupon,couponChannel, orderdto.getSignleOrder().isPressOrder(), orderdto.getSignleOrder().getOrderGroupId(), couponNumber); + .getChildCouponOrderPrice(shippinType,coupon,couponChannel, isPressOrder, orderGroupId, couponNumber); - Integer orderStatus = OrderHelper.getOrderStatusWxCoupon(coupon, orderdto.getSignleOrder().getOrderGroupId()); + Integer orderStatus = OrderHelper.getOrderStatusWxCoupon(coupon, orderGroupId); // 4.2 保存订单 WxOrder record = new WxOrder(); record.setType(orderType); record.setPayVendor(payWay.getCode()); - record.setCouponChannelId(orderdto.getSignleOrder().getCouponChannelId()); - record.setOrderGroupId(orderdto.getSignleOrder().getOrderGroupId()); - record.setFormId(orderdto.getSignleOrder().getFormId()); + record.setCouponChannelId(couponChannel.getId()); + record.setOrderGroupId(orderGroupId); + record.setFormId(formId); record.setPayment(price.getRealPayMent()); - record.setShippingType(orderdto.getShippingType()); - if(EnumOrderShopingType.DISTRIBUTION.getCode().equals(orderdto.getShippingType())){ + record.setShippingType(shippinType); + if(EnumOrderShopingType.DISTRIBUTION.getCode().equals(shippinType)){ record.setFreightPrice(coupon.getFreightPrice()); - record.setShippingAddress(JSON.toJSONString(orderdto.getAddress())); + record.setShippingAddress(JSON.toJSONString(address)); } record.setOrderStatus(orderStatus); @@ -2997,14 +3085,15 @@ public class WxOrderServiceImpl implements WxOrderService { //} record.setCouponNumber(couponNumber); + record.setExtParam(extParam);; try { - orderNumber = proxy.saveNoFreeOrder(orderDate,record, user, coupon, orderdto.getSignleOrder().isPressOrder()); + orderNumber = proxy.saveNoFreeOrder(orderDate,record, user, coupon, isPressOrder); } catch (Exception e) { logger.error("保存订单:" + e.getMessage(),e); throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]订单保存错误,"+e.getMessage()); } - if (orderdto.getSignleOrder().isPressOrder()) { + if (isPressOrder) { // 5. 第一次砍价 try { proxy.firstPress(orderDate,record, user, coupon, orderNumber); @@ -3315,7 +3404,8 @@ public class WxOrderServiceImpl implements WxOrderService { for ( int i =0 ; i< composeOrderSaveDto.size(); i++ ) { OrderComposeSaveDto ocsd = composeOrderSaveDto.get(i); - WxCoupon coupon = singleOrderCheck(ocsd.getSignleOrder(),ocsd.getCount(),wxCUserBasicInfo,payWay,tenantEntity,i+1,singleProduct); + WxCoupon coupon = singleOrderCheck(ocsd.getSignleOrder().getCouponChannelId(),ocsd.getSignleOrder().getOrderGroupId(),ocsd.getCount(), + wxCUserBasicInfo,payWay,tenantEntity,i+1,singleProduct); ocsd.setWxCoupon(coupon); } WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); @@ -3338,6 +3428,50 @@ public class WxOrderServiceImpl implements WxOrderService { } } + + @Override + public ResultData platPushSaveOrder(boolean allowUnPayOrder,EnumComposeOrder composeOrderType,String allExtParam,List platPushOrderList,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity) { + try { + if (null == platPushOrderList || platPushOrderList.size() <= 0 ) { + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"无商品信息"); + } + + WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,tenantEntity.getFinalTenantId()); + if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { + logger.info("会员权益被锁定:cUserId:" + cUserId); + return new ResultData(ErrorCode.MEMBER_IS_LOCKED); + } + + boolean singleProduct = false; + if (platPushOrderList.size() == 1) { + singleProduct = true; + } + + for ( int i =0 ; i< platPushOrderList.size(); i++ ) { + PlatPushOrderSaveDto ocsd = platPushOrderList.get(i); + WxCoupon coupon = singleOrderCheck(ocsd.getCouponChannelId(),ocsd.getOrderGroupId(),ocsd.getCount(),wxCUserBasicInfo,payWay,tenantEntity,i+1,singleProduct); + ocsd.setWxCoupon(coupon); + } + WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); + try { + WxComposeOrder order = proxy.savePlatPushOrderForCoupon(tenantEntity,allowUnPayOrder,composeOrderType,wxCUserBasicInfo, allExtParam,platPushOrderList, payWay); + return new ResultData(order); + } catch (MallinkException e) { + logger.error("saveOrderForCoupon error.",e); + throw new MallinkException(e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + logger.error("saveOrderForCoupon error.",e); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(), e.getMessage()); + } + + }catch(MallinkException me) { + return new ResultData(me.getErrorCode(),me.getMessage()); + }catch(Exception e) { + logger.error("composeSaveOrder error.",e); + return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + + } @Override public void sendInsideOrderPushMsg(TenantEntity tenantEntity,Long composeOrderId) { @@ -3355,6 +3489,22 @@ public class WxOrderServiceImpl implements WxOrderService { } + @Override + public void sendInsideOrderPushDeliveryMsg(TenantEntity tenantEntity, Long composeOrderId,Long couponOrderId) { + try{ + FmInsideOrderPushMsg orderPush = new FmInsideOrderPushMsg(); + orderPush.setDelayTimeLevel(5); + orderPush.setMsgType(EnumMsgRecordType.INSIDE_ORDER_PUSH_DELIVERY.getCode()); + orderPush.updateTenantInfo(tenantEntity); + orderPush.setBatchOrderId(composeOrderId); + orderPush.setCouponOrderId(couponOrderId); + logger.info(">>>>>>>>>>>send sendInsideOrderPushMsg :"+orderPush); + mqBaseProducer.sendMessage(orderPush, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); + }catch(Exception e){ + logger.info(">>>>>>>>>>>send sendInsideOrderPushMsg : error"+e.getMessage()); + } + } + //TODO 待优化重做 @Override public PageInfo listGoodsCAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { @@ -3439,6 +3589,22 @@ public class WxOrderServiceImpl implements WxOrderService { } + @Override + public WxBatchOrder getWxBatchOrder(TenantEntity tenantInfo, Long orderId) { + return wxBatchOrderMapper.selectById(orderId,tenantInfo.getTenantId()); + } + + @Override + public Map getOrderEntrySchema(Long mainOrderId) { + Map map = new HashMap<>(); + map.put("path", Constant.mainPageUrl); + Map paramMap = new HashMap<>(); + paramMap.put("type","dt"); + paramMap.put("orderId",mainOrderId); + map.put("params", JSON.toJSONString(paramMap)); + return map; + } + private Map> getBatchOrderMap(TenantEntity tenantEntity,List batchOrderIds){ WxOrder recordQ = new WxOrder(); recordQ.updateTenantInfo(tenantEntity); @@ -3459,26 +3625,25 @@ public class WxOrderServiceImpl implements WxOrderService { // } - private WxCoupon singleOrderCheck(OrderSaveDto orderSaveDto,int productCount,WxCUserBasicInfo wxCUserBasicInfo,EnumPayWay payWay,TenantEntity tenantEntity,int curindex,boolean singleProduct) { - logger.info("OrderSave: " + orderSaveDto); + private WxCoupon singleOrderCheck(Long couponChannelId,Long orderGroupId,int productCount,WxCUserBasicInfo wxCUserBasicInfo,EnumPayWay payWay,TenantEntity tenantEntity,int curindex,boolean singleProduct) { String premsg = ""; if (singleProduct) { premsg = "此券"; }else { premsg = "第["+curindex+"]张券"; } - if (orderSaveDto.getCouponChannelId() == null) { + if (couponChannelId == null) { throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), premsg+"couponChannelId不能为空"); } - WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(orderSaveDto.getCouponChannelId(),tenantEntity.getTenantId()); + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannelId,tenantEntity.getTenantId()); if (wxCouponChannel == null) { - logger.error("couponChannelId find error, " + orderSaveDto.getCouponChannelId()); + logger.error("couponChannelId find error, " + couponChannelId); throw new MallinkException(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF.getCode(),premsg+"投放渠道不存在"); } if (!singleProduct) { premsg = premsg+"【"+wxCouponChannel.getTitle()+"】"; } - couponChannelCheck(orderSaveDto, wxCouponChannel,premsg); + couponChannelCheck(wxCouponChannel,premsg); WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(),wxCouponChannel.getTenantId()); if (null == coupon) { @@ -3499,7 +3664,7 @@ public class WxOrderServiceImpl implements WxOrderService { WxCouponCVo wxCouponCVo = null; - String key = "cc:" + orderSaveDto.getCouponChannelId(); + String key = "cc:" + couponChannelId; ValueOperations operations = cdRedisTemplate.opsForValue(); // 缓存 boolean hasKey = cdRedisTemplate.hasKey(key); @@ -3508,7 +3673,7 @@ public class WxOrderServiceImpl implements WxOrderService { wxCouponCVo = operations.get(key); } else { // 游戏没有入缓存,需要从数据库中读取 - wxCouponCVo = wxCouponChannelService.findDetailVo(orderSaveDto.getCouponChannelId(),wxCouponChannel.getTenantId(),false); + wxCouponCVo = wxCouponChannelService.findDetailVo(couponChannelId,wxCouponChannel.getTenantId(),false); if (wxCouponCVo != null) { // 游戏优化,进缓存 cdRedisTemplate.opsForValue().set(key, wxCouponCVo, 3600, TimeUnit.SECONDS); @@ -3565,7 +3730,7 @@ public class WxOrderServiceImpl implements WxOrderService { couponUserCheck(wxCUserBasicInfo, wxCouponCVo,premsg); - Long couponId = orderSaveDto.getCouponId() == null ? wxCouponChannel.getCouponId() : orderSaveDto.getCouponId(); + Long couponId = wxCouponChannel.getCouponId(); if (couponId == null) { logger.error("couponChannelId或者couponId不能为空"); throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), premsg+"couponChannelId或者couponId不能为空"); @@ -3582,14 +3747,14 @@ public class WxOrderServiceImpl implements WxOrderService { if (!checkCouponIsFree(coupon,wxCouponChannel,null)) { // 有价,拼团检查 - if (isOrderGroup(orderSaveDto.getOrderGroupId())) { - checkOrderGroup(wxCUserBasicInfo, orderSaveDto.getOrderGroupId(),coupon,premsg); + if (isOrderGroup(orderGroupId)) { + checkOrderGroup(wxCUserBasicInfo, orderGroupId,coupon,premsg); } } return coupon; } - private void couponChannelCheck(OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel,String premsg) { + private void couponChannelCheck(WxCouponChannel wxCouponChannel,String premsg) { if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { Date now = new Date(); if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) { diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 8e44300b1..27b89b520 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -12,6 +12,7 @@ import com.iformall.common.Result; import com.iformall.common.ResultData; import com.iformall.domain.po.*; import com.iformall.domain.po.base.TenantEntity; +import com.iformall.douyin.payv2.result.TtPayOrderQueryV2Result; import com.iformall.enums.*; import com.iformall.exception.MallinkException; import com.iformall.mapper.*; @@ -32,6 +33,8 @@ import com.iformall.service.pay.service.pay.PayAdapterService; import com.iformall.service.pay.service.pay.entity.CreateUser; import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; +import com.iformall.service.pay.service.share.PayShareAdapterService; +import com.iformall.service.pay.service.share.entity.PayShareCalculateAmount; import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; import com.iformall.utils.*; import org.apache.commons.lang3.StringUtils; @@ -128,14 +131,14 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { @Override public void handleSuccessOrder(WxPayOrder oldRecord,WxComposeOrder composeOrder,PayQueryAdapterResult queryResult,boolean isScheduleTask,boolean isOneChildOrder) { Date curDate = new Date(); - if (oldRecord.getPayOrderStatus() != EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { - WxPayOrderServiceImpl proxy = (WxPayOrderServiceImpl) AopContext.currentProxy(); - //因为此处是处理订单支付成功了但是订单状态为未支付成功的异常状态,库存不应该再扣减 - //更新wxPayOrder - oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); + if(oldRecord.getPayOrderStatus() != EnumPayStatus.PAY_STATUS_SUCCESS.getCode()){ + WxPayOrderServiceImpl proxy = (WxPayOrderServiceImpl) AopContext.currentProxy(); + //因为此处是处理订单支付成功了但是订单状态为未支付成功的异常状态,库存不应该再扣减 + //更新wxPayOrder + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); oldRecord.setTtPayWay(queryResult.getWay()); - String timEndStr = queryResult.getEndTimeStr(); - Date timeEnd = null; + String timEndStr = queryResult.getEndTimeStr(); + Date timeEnd = null; try { timeEnd = Utility.getDateFromString(timEndStr); } catch (ParseException e) { @@ -147,39 +150,38 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { String transactionId = queryResult.getTransactionId(); oldRecord.setTransactionId(transactionId); oldRecord.setUpdateTime(curDate); - wxPayOrderMapper.updateById(oldRecord); - - if (!EnumComposeOrder.isSingle(composeOrder.getComposeOrderType())) { - //如果是组合订单的单独处理。如定时处理的单个订单 - if (isOneChildOrder) { - //处理其他信息 - try { - proxy.handleOrderPaySingleOrderSuccess(composeOrder.getSingleOrder(),oldRecord, transactionId,isScheduleTask); - }catch(Exception e) { - throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); - } - }else { - List orderList = orderFactory.getOrderAdapterService(composeOrder.getComposeOrderType()).getChildOrders(composeOrder, oldRecord.getTenantId()); - for (WxOrder o : orderList) { - try { - proxy.handleOrderPaySingleOrderSuccess(o,oldRecord, transactionId, isScheduleTask); - }catch(Exception e) { - logger.error("handleSuccessOrder error.",e); - } - } - } - }else { - //处理其他信息 - try { - proxy.handleOrderPaySingleOrderSuccess(composeOrder.getSingleOrder(),oldRecord, transactionId,isScheduleTask); - }catch(Exception e) { - throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); - } - } - //订单同步消息 - wxOrderService.sendInsideOrderPushMsg(composeOrder,composeOrder.getMainOrderId()); + wxPayOrderMapper.updateById(oldRecord); - } + if (!EnumComposeOrder.isSingle(composeOrder.getComposeOrderType())) { + //如果是组合订单的单独处理。如定时处理的单个订单 + if (isOneChildOrder) { + //处理其他信息 + try { + proxy.handleOrderPaySingleOrderSuccess(composeOrder.getSingleOrder(),oldRecord, transactionId,isScheduleTask); + }catch(Exception e) { + throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + }else { + List orderList = orderFactory.getOrderAdapterService(composeOrder.getComposeOrderType()).getChildOrders(composeOrder, oldRecord.getTenantId()); + for (WxOrder o : orderList) { + try { + proxy.handleOrderPaySingleOrderSuccess(o,oldRecord, transactionId, isScheduleTask); + }catch(Exception e) { + logger.error("handleSuccessOrder error.",e); + } + } + } + }else { + //处理其他信息 + try { + proxy.handleOrderPaySingleOrderSuccess(composeOrder.getSingleOrder(),oldRecord, transactionId,isScheduleTask); + }catch(Exception e) { + throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); + } + } + //订单同步消息 +// wxOrderService.sendInsideOrderPushMsg(composeOrder,composeOrder.getMainOrderId()); + } } @@ -227,7 +229,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } @Override - public ResultData createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user, WxPayOrder record, EnumPayWay payWay,PayExtraParam params) { + public ResultData createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user, WxPayOrder record, EnumPayWay payWay,PayExtraParam params,boolean isCreatePay) { /* * 如果是组合订单(非拼团、砍价),则结算按照主订单来结算。 * //如果是组合订单,则wxPayOrder对应的是WxcomposeOrder.为了兼容之前的,需要把支付相关信息也保存到子订单里面去 @@ -246,9 +248,9 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { lastCoupon = checkSinglePayOrder(o, user, payWay); } String productName = orderAdapterService.getPayProductName(lastCoupon); - PayAdapterResult payResult = createPayOrder(appInfo, user, record,composeOrder,productName, payWay, params); + PayAdapterResult payResult = createPayOrder(appInfo, user, record,composeOrder,productName, payWay, params,isCreatePay); if (payResult.isSuccess()) { - wxOrderService.sendInsideOrderPushMsg(composeOrder,composeOrder.getMainOrderId()); +// wxOrderService.sendInsideOrderPushMsg(composeOrder,composeOrder.getMainOrderId()); return new ResultData(Result.SUCCESS,"创建支付单成功",payResult.getData()); }else { return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), payResult.getMsg(), payResult.getData()); @@ -320,8 +322,9 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } return wxCoupon; } - - private PayAdapterResult createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user,WxPayOrder record,WxComposeOrder composeOrder,String productName, EnumPayWay payWay,PayExtraParam params) { + @Override + public PayAdapterResult createPayOrder(WxAppinfo appInfo, WxCUserBasicInfo user,WxPayOrder record,WxComposeOrder composeOrder, + String productName, EnumPayWay payWay,PayExtraParam params,boolean isCreatePay) { IdWorker idworker = IdWorker.get(); EnumPayShare isShare = EnumPayShare.NO; @@ -368,11 +371,14 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } }else { { + // 3.1 创建支付订单 - Long id = idworker.nextId(); - if (null == id || id.longValue() <=0) { - throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付流水号生成失败!new payorder:"+record.getOrderId()+",id:"+id); - } +// Long id = idworker.nextId(); +// if (null == id || id.longValue() <=0) { +// throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付流水号生成失败!new payorder:"+record.getOrderId()+",id:"+id); +// } + + Long id = record.getOrderId();//支付订单号=订单号 record.setId(id); record.updateTenantInfo(composeOrder); @@ -390,20 +396,22 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { record.setShare(isShare.getCode()); record.setComposeOrder(composeOrder.getComposeOrderType()); if (isShare == EnumPayShare.YES) { + PayShareAdapterService payShareServie = payServiceFactory.getPayShareAdapterService(payWay.getCode()); + + PayShareCalculateAmount recordShareAmount = payShareServie.calculateAmount(record.getPayAmount(), payAccount); // 分账金额 - int mallCharge = OrderHelper.getMallCharge(record.getPayAmount(), payAccount); - Integer share_amount = record.getPayAmount() - mallCharge; + Integer share_amount = recordShareAmount.getShareAmount(); record.setShareAmount(share_amount); - record.setRateAmount(OrderHelper.getRateAmount(record.getPayAmount(),mallCharge, payAccount)); + record.setRateAmount(recordShareAmount.getRateAmount()); //设置子订单分账金额 Map childShares = new HashMap(); OrderAdapterService orderAdapterService = orderFactory.getOrderAdapterService(composeOrder.getComposeOrderType()); List orderList = orderAdapterService.getChildOrders(composeOrder, appInfo.getTenantId()); if(null != orderList && orderList.size() > 0) { for (WxOrder o : orderList) { - int orderMallCharge = OrderHelper.getMallCharge(o.getPayment(), payAccount); - Integer orderShareAmount = o.getPayment() - orderMallCharge; - Integer orderRateAmount = OrderHelper.getRateAmount(o.getPayment(),orderMallCharge, payAccount); + PayShareCalculateAmount oShareAmount = payShareServie.calculateAmount(o.getPayment(), payAccount); + Integer orderShareAmount = oShareAmount.getShareAmount(); + Integer orderRateAmount = oShareAmount.getRateAmount(); childShares.put(String.valueOf(o.getId()), new WxComposeChildOrderShare(o.getPayment(), orderShareAmount, orderRateAmount)); } record.setChildOrderShare(JSON.toJSONString(childShares)); @@ -417,6 +425,14 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } } } + if(!isCreatePay){ + PayAdapterResult par = new PayAdapterResult(); + par.setSuccess(true); + Map map = new HashMap<>(); + map.put("outOrderNo",record.getOrderId().toString()); + par.setData(map); + return par; + } logger.debug("wxPayRecord md5 before:"+record.toString()); String beforemd5 = HashUtil.md5(record.toString()); @@ -981,6 +997,19 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { return false; } + @Override + public PayQueryAdapterResult ttorderQuery(TenantEntity tenantInfo, Long id) { + WxAppinfo appInfo = wxAppinfoService.getCAppInfo(tenantInfo,EnumAppPlat.TOUTIAO); + WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + WxPayOrder payOrder = new WxPayOrder(); + payOrder.setPayOrderNo(id.toString()); + try { + return payServiceFactory.getPayAdapterService(EnumPayWay.PAY_WAY_TT.getCode()).queryPayStatus(payOrder, appInfo, payAccount); + } catch (Exception e) { + return new PayQueryAdapterResult(ErrorCode.SYS_SERVER_ERROR.getCode(), e.getMessage(),EnumPayWay.PAY_WAY_TT.getCode(),null,null,null); + } + } + @Override @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) @@ -1361,7 +1390,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { }else if(list != null && list.size() > 1){ throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); } - throw new MallinkException(ErrorCode.PAY_ORDER_NOT_FOUND); + return null; } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java index ec5b2079e..9905d0c79 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java @@ -261,54 +261,6 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); } - -// final IdWorker idWorker = IdWorker.get(); -// Long refundOrderId = idWorker.nextId(); -// -// Date currentDate = new Date(); -// -// WxBatchOrder order =new WxBatchOrder(); -// order.setId(idWorker.nextId()); -// order.setCUserId(wxOrder.getCUserId()); -// order.updateTenantInfo(wxCouponOrder); -// order.setPayment(wxOrder.getPayment()); -// order.setPayVendor(wxOrder.getPayVendor()); -// order.setOrderType(wxOrder.getComposeOrderType()); -// order.setCreateDate(new Date()); -// wxBatchOrderMapper.insert(order); -// // 创建 refund Order -// WxOrder rOrder = new WxOrder(); -// rOrder.setId(refundOrderId); -// rOrder.updateTenantInfo(wxCouponOrder); -// rOrder.setOrderNumber(wxOrder.getOrderNumber()); // 退款订单填写支付订单orderNumber -// rOrder.setProductId(wxOrder.getProductId()); -// rOrder.setType(EnumOrderType.COUPON.getCode()); -// rOrder.setPayVendor(wxOrder.getPayVendor()); -// rOrder.setCUserId(wxOrder.getCUserId()); -// if (payType == EnumPayType.PAY_B_REFUND) { -// rOrder.setDetail("["+bUser.getId()+"]B端管理员操作退款"); //B端发起退款后存B端用户ID在此 -// }else if (payType == EnumPayType.PAY_ADMIN_REFUND) { -// rOrder.setDetail("["+aUserId+"]A端管理员操作退款"); -// } else if (payType == EnumPayType.PAY_AUTO_REFUND) { -// rOrder.setDetail("auto端发起退款"); -// } else { -// rOrder.setDetail("自己发起退款"); -// } -// rOrder.setPaymentType(payType.getCode()); -// rOrder.setPayment(wxOrder.getPayment()); -// rOrder.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_REFUND.getCode()); -// rOrder.setCreateDate(currentDate); -// rOrder.setUpdateDate(currentDate); -// rOrder.setComposeOrderId(order.getId()); -// rOrder.setComposeOrderType(wxOrder.getComposeOrderType()); -// rOrder.setCouponNumber(wxOrder.getCouponNumber()); -// try { -// wxOrderMapper.insert(rOrder); -// } catch (Exception e) { -// logger.error("退款订单保存出错: " + e.getMessage(),e); -// throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "退款订单保存出错"); -// } - for (WxCouponOrder wxCouponOrder:couponOrderList) { // 更改 couponOrder 状态 if (wxCouponOrder.getCouponType().equals(EnumCouponType.CARD_MULTIMCH.getCode())) { diff --git a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCouponVerifyMsgServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCouponVerifyMsgServiceImpl.java index 8b7967063..8427d040e 100644 --- a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCouponVerifyMsgServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCouponVerifyMsgServiceImpl.java @@ -48,8 +48,8 @@ public class FmInsideCouponVerifyMsgServiceImpl implements MsgSendService { logger.error("门店未找到: " + msg.getMerchantId()); throw new MallinkException(ErrorCode.USER_IS_EMPTY.getCode(), "门店未找到" + msg.getMerchantId()); } - - orderService.sendInsideOrderPushMsg(couponOrder,couponOrder.getComposeOrderId()); + orderService.sendInsideOrderPushDeliveryMsg(couponOrder,null,couponOrder.getId()); +// orderService.sendInsideOrderPushMsg(couponOrder,couponOrder.getComposeOrderId()); couponOrderService.actionAfterVerify(couponOrder, merchant); } diff --git a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderPushDeliveryMsgServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderPushDeliveryMsgServiceImpl.java new file mode 100644 index 000000000..e1b57f58b --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderPushDeliveryMsgServiceImpl.java @@ -0,0 +1,141 @@ +package com.iformall.service.msg.impl; + +import com.alibaba.fastjson.JSONObject; +import com.iformall.common.ErrorCode; +import com.iformall.common.ResultData; +import com.iformall.domain.po.*; +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.po.msg.BaseMsg; +import com.iformall.domain.po.msg.FmInsideOrderPushMsg; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.payv2.request.TtOrderPushDeliveryRequest; +import com.iformall.enums.*; +import com.iformall.exception.MallinkException; +import com.iformall.mapper.TtCUserMapper; +import com.iformall.mapper.TtOrderPushErrorMapper; +import com.iformall.mapper.WxPayOrderMapper; +import com.iformall.service.*; +import com.iformall.service.msg.MsgSendService; +import com.iformall.service.pay.PayServiceFactory; +import com.iformall.service.pay.service.pay.entity.PayAdapterResult; +import com.iformall.utils.MaUtil; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * + * @author Stormeye Wu + * @date 2019/5/10 + */ +@Service +public class FmInsideOrderPushDeliveryMsgServiceImpl implements MsgSendService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private WxAppinfoService wxAppinfoService; + + @Autowired + private WxPayAccountService wxPayAccountService; + + @Autowired + private WxCouponOrderService wxCouponOrderService; + + @Autowired + private WxOrderService wxOrderService; + + @Autowired + private WxMerchantService wxMerchantService; + + @Autowired + private TtMerchantPoiService ttMerchantPoiService; + + @Autowired + private MaUtil maUtil; + + @Autowired + private TtOrderPushErrorMapper ttOrderPushErrorMapper; + + + + @Override + public void send(BaseMsg baseMsg) throws Exception{ + FmInsideOrderPushMsg msg = (FmInsideOrderPushMsg)baseMsg; + + try{ + Thread.currentThread().sleep(1000);//延时秒 + }catch(Exception e){} + + TenantEntity tenantEntity = new TenantEntity(); + tenantEntity.setTenantId(msg.getTenantId()); + tenantEntity.setParentTenantId(msg.getParentTenantId()); + + try{ + WxCouponOrder couponOrder = wxCouponOrderService.getById(msg.getCouponOrderId(), tenantEntity.getTenantId()); + if(EnumCouponOrderStatus.COUPON_ORDER_USED.getCode().equals(couponOrder.getCouponOrderStatus()) + && EnumPayWay.PAY_WAY_TT.getCode().equals(couponOrder.getPayVendor())){ + WxOrder order = wxOrderService.getById(couponOrder.getOrderId(), tenantEntity.getTenantId()); + String itemOrderId = (String) order.getExpParamValue("itemOrderId"); + WxMerchant merchant = wxMerchantService.getById(couponOrder.getBMerchantId()); + String shop_name = merchant.getName(); + String ext_valid_shop_id = couponOrder.getBMerchantId().toString(); + TtMerchantPoi poi = ttMerchantPoiService.getById(couponOrder.getBMerchantId()); + + + WxAppinfo appinfo = wxAppinfoService.getCAppInfo(tenantEntity,EnumPayWay.PAY_WAY_TT.getPlat()); + WxPayAccount payAccount = wxPayAccountService.getById(appinfo.getPayId()); + TtPayService ttPayService = maUtil.getTtPayService(appinfo, payAccount); + + TtOrderPushDeliveryRequest request = new TtOrderPushDeliveryRequest(); + request.setOutOrderNo(order.getComposeOrderId().toString()); + List itemOrderList = new ArrayList<>(); + TtOrderPushDeliveryRequest.ItemOrder itemOrder = new TtOrderPushDeliveryRequest.ItemOrder(); + itemOrder.setItemOrderId(itemOrderId); + itemOrderList.add(itemOrder); + request.setItemOrderList(itemOrderList); + JSONObject poiInfo = new JSONObject(); + poiInfo.put("shop_name",shop_name); + poiInfo.put("ext_valid_shop_id",ext_valid_shop_id); + if(poi != null){ + poiInfo.put("valid_poi_id_str",poi.getPoiId()); + } + request.setPoiInfo(poiInfo.toJSONString()); + boolean b = ttPayService.pushDelivery(request); + if(b){ + ttOrderPushErrorMapper.deleteById(msg.getCouponOrderId()); + } + } + }catch(Exception e){ + TtOrderPushError pushError = new TtOrderPushError(); + pushError.setId(msg.getCouponOrderId()); + pushError.updateTenantInfo(tenantEntity); + pushError.setErrMsg(e.getMessage()); + saveOrUpdate(pushError); + } + + } + + private void saveOrUpdate(TtOrderPushError pushError){ + Date now = new Date(); + TtOrderPushError pushError1 = ttOrderPushErrorMapper.selectById(pushError.getId()); + if(pushError1 != null){ + pushError1.setErrMsg(pushError.getErrMsg()); + pushError1.setUpdateDate(now); + ttOrderPushErrorMapper.updateById(pushError1); + }else{ + pushError.setCreateDate(now); + pushError.setUpdateDate(now); + ttOrderPushErrorMapper.insert(pushError); + } + } + + + + +} diff --git a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderRefundMsgServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderRefundMsgServiceImpl.java index 24c6cbc94..2d93dabd5 100644 --- a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderRefundMsgServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideOrderRefundMsgServiceImpl.java @@ -31,20 +31,10 @@ public class FmInsideOrderRefundMsgServiceImpl implements MsgSendService { @Autowired private WxCUserBasicInfoService userService; - @Autowired - private WxCouponService couponService; - - @Autowired - private WxCouponOrderService couponOrderService; - - @Autowired - private WxCouponChannelService couponChannelService; - - @Override public void send(BaseMsg baseMsg) throws Exception{ FmInsideOrderRefundMsg msg = (FmInsideOrderRefundMsg)baseMsg; - + WxOrder order = orderService.getById(msg.getOrderId(),msg.getTenantId()); if(order == null) { logger.error("订单未找到: " + msg.getOrderId()); diff --git a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideProductPushMsgServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideProductPushMsgServiceImpl.java index ceecd8398..6cefce384 100644 --- a/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideProductPushMsgServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideProductPushMsgServiceImpl.java @@ -3,6 +3,8 @@ package com.iformall.service.msg.impl; import com.iformall.domain.po.msg.BaseMsg; import com.iformall.domain.po.msg.FmInsideProductPushMsg; import com.iformall.enums.EnumPushType; +import com.iformall.service.TtCouponGoodsService; +import com.iformall.service.TtGoodsCategoryService; import com.iformall.service.TtMerchantPoiService; import com.iformall.service.msg.MsgSendService; import org.slf4j.Logger; @@ -23,14 +25,21 @@ public class FmInsideProductPushMsgServiceImpl implements MsgSendService { @Autowired private TtMerchantPoiService poiService; + @Autowired + private TtCouponGoodsService ttCouponGoodsService; + @Override public void send(BaseMsg baseMsg) throws Exception{ FmInsideProductPushMsg msg = (FmInsideProductPushMsg)baseMsg; if(EnumPushType.SPU_STATUS_SYNC.equals(msg.getSyncType())){ - poiService.spuStatusSync(msg.getTenantInfo(),msg.getCouponChannelId()); + ttCouponGoodsService.productOperate(msg.getTenantInfo(),msg.getCouponId()); +// poiService.spuStatusSync(msg.getTenantInfo(),msg.getCouponId()); }else if(EnumPushType.SPU_STOCK_SYNC.equals(msg.getSyncType())){ - poiService.spuStockSync(msg.getTenantInfo(),msg.getCouponChannelId()); + ttCouponGoodsService.productOperate(msg.getTenantInfo(),msg.getCouponId()); +// poiService.spuStockSync(msg.getTenantInfo(),msg.getCouponId()); + }else if(EnumPushType.SPU_FREE_AUDIT_SYNC.equals(msg.getSyncType())){ + ttCouponGoodsService.productFreeAudit(msg.getTenantInfo(),msg.getCouponId()); } } diff --git a/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java index 5168a097f..cf274a2e9 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java @@ -4,6 +4,7 @@ import java.util.Date; import java.util.List; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.domain.po.*; import com.iformall.domain.po.base.TenantEntity; import com.iformall.enums.EnumPayWay; @@ -20,6 +21,9 @@ public interface OrderAdapterService { WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,EnumPayWay payWay); + //第三方平台推送过来的订单 + WxComposeOrder createDBMainOrderByPushOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,String allExtParam,List platPushOrderList,EnumPayWay payWay); + /** * 获取支付时商品名称,供服务商API使用 * @param lastCoupon @@ -39,6 +43,7 @@ public interface OrderAdapterService { * @return */ WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber); + WxComposeChildOrderPrice getChildCouponOrderPrice(Integer shippingType,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber); /** * 计算每一个子订单的补贴 diff --git a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java index 9ed64d1ba..c50584453 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java +++ b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java @@ -1,8 +1,10 @@ package com.iformall.service.order.entity; +import java.util.List; import java.util.Map; import com.iformall.domain.po.WxBatchOrder; +import com.iformall.domain.po.WxCoupon; import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxOrder; import com.iformall.domain.po.base.TenantEntity; @@ -34,5 +36,7 @@ public class WxComposeOrder extends TenantEntity{ private WxBatchOrder mainOrder;//真正的主订单对象,批量下单时才有 private Map couponChannelMap; + + private Map couponMap; } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java index ec369460c..c6477f0d0 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java @@ -14,6 +14,7 @@ import org.springframework.transaction.annotation.Transactional; import com.iformall.common.IdWorker; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.enums.EnumComposeOrder; import com.iformall.enums.EnumOrderShopingType; import com.iformall.enums.EnumPayWay; @@ -48,7 +49,14 @@ public class SingleOrderAdapterService extends BaseBatchOrderAdapterService { @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.SINGLE,null); + return super.createDBMainOrder(tenantEntity,user, payment,null, payWay, EnumComposeOrder.SINGLE,null,null); + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + @Override + public WxComposeOrder createDBMainOrderByPushOrder(TenantEntity tenantEntity, WxCUserBasicInfo user,String allExtParam, + List platPushOrderList, EnumPayWay payWay) { + return super.createDBMainOrderForPushOrders(tenantEntity, user, allExtParam,platPushOrderList, payWay, EnumComposeOrder.SINGLE); } @Override @@ -88,6 +96,4 @@ public class SingleOrderAdapterService extends BaseBatchOrderAdapterService { return lastCoupon.getTitle(); } - - } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java index 6b7ab73ec..4b5517a55 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java @@ -13,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional; import com.iformall.common.ErrorCode; import com.iformall.common.IdWorker; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.domain.po.WxBatchOrder; import com.iformall.domain.po.WxCUserBasicInfo; import com.iformall.domain.po.WxCoupon; @@ -60,18 +61,25 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic @Override public WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber) { + return getChildCouponOrderPrice(orderdto.getShippingType(),coupon,couponChannel,isPress,orderGroupId,couponNumber); + } + + @Override + public WxComposeChildOrderPrice getChildCouponOrderPrice(Integer shippingType,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber) { Integer perPrice = OrderHelper.getCouponPerPayment(coupon,couponChannel, isPress, orderGroupId); Integer freightPrice = 0; //在线配送加上运费 - if (EnumOrderShopingType.DISTRIBUTION.getCode().equals(orderdto.getShippingType())) { + if (EnumOrderShopingType.DISTRIBUTION.getCode().equals(shippingType)) { freightPrice = coupon.getFreightPrice(); } return new WxComposeChildOrderPrice(perPrice, couponNumber, freightPrice, coupon.getId()); } + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,List orderSave,EnumPayWay payWay,EnumComposeOrder composeOrderType) { int payment = 0; + Map couponMap = new HashMap(); Map couponChannelMap = new HashMap(); for (OrderComposeSaveDto ocsd : orderSave) { WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(ocsd.getSignleOrder().getCouponChannelId(),tenantEntity.getTenantId()); @@ -81,14 +89,36 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic boolean isPress = ocsd.getSignleOrder().isPressOrder(); WxComposeChildOrderPrice price = getChildCouponOrderPrice(ocsd,ocsd.getWxCoupon(),wxCouponChannel, isPress, ocsd.getSignleOrder().getOrderGroupId(), ocsd.getCount()); payment = payment+price.getRealPayMent(); + couponMap.put(ocsd.getWxCoupon().getId(),ocsd.getWxCoupon()); + couponChannelMap.put(wxCouponChannel.getId(), wxCouponChannel); + } + + return createDBMainOrder(tenantEntity, user, payment, null,payWay, composeOrderType,couponChannelMap,couponMap); + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + protected WxComposeOrder createDBMainOrderForPushOrders(TenantEntity tenantEntity,WxCUserBasicInfo user,String allExtParam,List platPushOrderList,EnumPayWay payWay,EnumComposeOrder composeOrderType) { + int payment = 0; + Map couponMap = new HashMap(); + Map couponChannelMap = new HashMap(); + for (PlatPushOrderSaveDto ocsd : platPushOrderList) { + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(ocsd.getCouponChannelId(),tenantEntity.getTenantId()); + if (null == wxCouponChannel) { + throw new MallinkException(ErrorCode.MSG_INSIDE_ERROR.getCode(),"渠道不存在:"+ocsd.getCouponChannelId()); + } + boolean isPress = ocsd.isPress(); + WxComposeChildOrderPrice price = getChildCouponOrderPrice(ocsd.getShippingType(),ocsd.getWxCoupon(),wxCouponChannel, isPress, ocsd.getOrderGroupId(), ocsd.getCount()); + payment = payment+price.getRealPayMent(); + couponMap.put(ocsd.getWxCoupon().getId(),ocsd.getWxCoupon()); couponChannelMap.put(wxCouponChannel.getId(), wxCouponChannel); } - return createDBMainOrder(tenantEntity, user, payment, payWay, composeOrderType,couponChannelMap); + return createDBMainOrder(tenantEntity, user, payment, allExtParam,payWay, composeOrderType,couponChannelMap,couponMap); } @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,EnumPayWay payWay,EnumComposeOrder composeOrderType,Map couponChannelMap) { + protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,String allExtParam,EnumPayWay payWay,EnumComposeOrder composeOrderType, + Map couponChannelMap,Map couponMap) { //判断是否poi订单 Integer isTtPoiOrder = null; try{ @@ -108,12 +138,17 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic order.setOrderType(composeOrderType.getCode()); order.setIsTtPoiOrder(isTtPoiOrder); order.setCreateDate(new Date()); + order.setExtParam(allExtParam); wxBatchOrderMapper.insert(order); WxComposeOrder composeOrder = new WxComposeOrder(order.getId(), composeOrderType.getCode(), payment); + composeOrder.setMainOrder(order); composeOrder.updateTenantInfo(tenantEntity); if (null != couponChannelMap) { composeOrder.setCouponChannelMap(couponChannelMap); } + if (null != couponMap){ + composeOrder.setCouponMap(couponMap); + } return composeOrder; } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java index c4ebb524e..ca65e2447 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.service.order.entity.WxComposeOrder; /** * 券包批量下单 @@ -38,7 +39,14 @@ public class CouponPackageOrderAdapterService extends BaseBatchOrderAdapterServi @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity, user, payment, payWay, EnumComposeOrder.PACKAGECOUPON,null); + return super.createDBMainOrder(tenantEntity, user, payment,null, payWay, EnumComposeOrder.PACKAGECOUPON,null,null); + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + @Override + public WxComposeOrder createDBMainOrderByPushOrder(TenantEntity tenantEntity, WxCUserBasicInfo user,String allExtParam, + List platPushOrderList, EnumPayWay payWay) { + return super.createDBMainOrderForPushOrders(tenantEntity, user, allExtParam, platPushOrderList, payWay, EnumComposeOrder.PACKAGECOUPON); } @Override @@ -73,6 +81,4 @@ public class CouponPackageOrderAdapterService extends BaseBatchOrderAdapterServi return "[券包]"+lastCoupon.getTitle(); } - - } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java index 541e7490e..3955a3a61 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java @@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.enums.EnumComposeOrder; import com.iformall.enums.EnumPayWay; import com.iformall.service.order.entity.WxComposeOrder; @@ -39,9 +40,17 @@ public class MulityNumberOneOrderBatchOrderAdapterService extends BaseBatchOrder @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH,null); + return super.createDBMainOrder(tenantEntity,user, payment, null, payWay, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH,null,null); } + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + @Override + public WxComposeOrder createDBMainOrderByPushOrder(TenantEntity tenantEntity, WxCUserBasicInfo user,String allExtParam, + List platPushOrderList, EnumPayWay payWay) { + return super.createDBMainOrderForPushOrders(tenantEntity, user, allExtParam, platPushOrderList, payWay, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH); + } + + @Override public WxComposeOrder getComposeOrder(Long mainOrderId, String tenantId) { return super.getComposeOrder(mainOrderId, tenantId, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH); @@ -61,6 +70,5 @@ public class MulityNumberOneOrderBatchOrderAdapterService extends BaseBatchOrder return "批量支付商品"; } - } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java index abed93602..c145eda7c 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java @@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.iformall.domain.dto.OrderComposeSaveDto; +import com.iformall.domain.dto.PlatPushOrderSaveDto; import com.iformall.enums.EnumComposeOrder; import com.iformall.enums.EnumPayWay; import com.iformall.service.order.entity.WxComposeOrder; @@ -38,7 +39,14 @@ public class OneNumberOneOrderBatchOrderAdapterService extends BaseBatchOrderAda @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,null); + return super.createDBMainOrder(tenantEntity,user, payment, null,payWay, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,null,null); + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + @Override + public WxComposeOrder createDBMainOrderByPushOrder(TenantEntity tenantEntity, WxCUserBasicInfo user,String allExtParam, + List platPushOrderList, EnumPayWay payWay) { + return super.createDBMainOrderForPushOrders(tenantEntity, user, allExtParam,platPushOrderList, payWay, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH); } @Override @@ -62,5 +70,7 @@ public class OneNumberOneOrderBatchOrderAdapterService extends BaseBatchOrderAda } + + } diff --git a/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java b/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java index 7a4df1b73..8639a4c3f 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java +++ b/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java @@ -50,19 +50,38 @@ public class OrderHelper { return orderStatus; } - //分账金额,扣掉商场设置的手续费率 + //分账金额,扣掉商场设置的手续费率,默认取最小整数,不四舍五入 public static int getMallCharge(Integer payment,WxPayAccount payAccount) { int iChargeFee = PayUtils.getPayRate(payment, payAccount.getRate(), false); return iChargeFee; } + //分账金额,扣掉商场设置的手续费率,是否四舍五入 + public static int getMallCharge(Integer payment,WxPayAccount payAccount,boolean round) { + int iChargeFee = PayUtils.getPayRate(payment, payAccount.getRate(), round); + return iChargeFee; + } - //费率差,微信、支付宝交易的费率. iChargeFee:商场扣掉的手续费 - public static Integer getRateAmount(Integer payment,int mallCharge, WxPayAccount payAccount) { + public static void main(String[] args) { + System.out.println(getMallCharge(null, null)); + } + + //微信、支付宝交易的手续费. + public static int getRealRateAmount(Integer payment,WxPayAccount payAccount) { if(payAccount.getRealRate() != null) { int iRealChargeFee = PayUtils.getPayRate(payment, payAccount.getRealRate(), true); - if(mallCharge > iRealChargeFee) { - return mallCharge - iRealChargeFee; - } + return iRealChargeFee; + } + return -1; + } + + //费率差. iChargeFee:商场扣掉的手续费 + public static Integer getRateAmount(Integer payment,int mallCharge, WxPayAccount payAccount) { + int iRealChargeFee = getRealRateAmount(payment, payAccount); + if (iRealChargeFee < 0) { + return null; + } + if(mallCharge > iRealChargeFee) { + return mallCharge - iRealChargeFee; } return null; } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/BaseTtPayAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/BaseTtPayAdapterService.java index 49631c36e..daef8701c 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/BaseTtPayAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/BaseTtPayAdapterService.java @@ -1,12 +1,16 @@ package com.iformall.service.pay.service.pay.douyin; +import com.iformall.common.ErrorCode; import com.iformall.domain.po.WxAppinfo; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.WxPayOrder; import com.iformall.douyin.miniapp.api.TtMaService; import com.iformall.douyin.pay.DouYinPayHelper; +import com.iformall.douyin.pay.TtPayService; import com.iformall.douyin.pay.orderQuery.OrderQueryResult; +import com.iformall.douyin.payv2.result.TtPayOrderQueryV2Result; import com.iformall.enums.EnumPayStatus; +import com.iformall.exception.MallinkException; import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; import com.iformall.utils.MaUtil; @@ -21,14 +25,43 @@ import java.io.File; @Slf4j public class BaseTtPayAdapterService { + @Autowired + protected MaUtil maUtil; + protected PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) throws Exception { - OrderQueryResult orderQueryResult = DouYinPayHelper.orderQuery(appInfo.getAppId(), payAccount.getApiKey(), oldRecord.getPayOrderNo(), null); - int code = DouYinPayHelper.getPayStatusFromOrderQueryResult(orderQueryResult,oldRecord.getPayOrderNo()); - PayQueryAdapterResult result = new PayQueryAdapterResult(code, EnumPayStatus.getEnum(code).getMessage(),orderQueryResult.getWay(), orderQueryResult,oldRecord.getTransactionId(),orderQueryResult.getPayTime()); + TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); + TtPayOrderQueryV2Result ttPayOrderQueryV2Result = ttPayService.queryOrderV2(null, oldRecord.getPayOrderNo()); + int code = getPayStatusFromOrderQueryResult(ttPayOrderQueryV2Result); + PayQueryAdapterResult result = new PayQueryAdapterResult(code, EnumPayStatus.getEnum(code).getMessage(), + ttPayOrderQueryV2Result.getPayChannel(), ttPayOrderQueryV2Result,ttPayOrderQueryV2Result.getPaymentOrderId(),ttPayOrderQueryV2Result.getPayTime()); + +// OrderQueryResult orderQueryResult = DouYinPayHelper.orderQuery(appInfo.getAppId(), payAccount.getApiKey(), oldRecord.getPayOrderNo(), null); +// int code = DouYinPayHelper.getPayStatusFromOrderQueryResult(orderQueryResult,oldRecord.getPayOrderNo()); +// PayQueryAdapterResult result = new PayQueryAdapterResult(code, EnumPayStatus.getEnum(code).getMessage(),orderQueryResult.getWay(), orderQueryResult,oldRecord.getTransactionId(),orderQueryResult.getPayTime()); return result; } + private int getPayStatusFromOrderQueryResult(TtPayOrderQueryV2Result result){ + if(result == null){ + return EnumPayStatus.PAY_STATUS_ORDER_NOT_EXISTS.getCode(); + } + String orderStatus = result.getOrderStatus(); + if(StringUtils.isBlank(orderStatus)){ + return EnumPayStatus.PAY_STATUS_FAIL.getCode(); + }else if("PROCESS".equals(orderStatus)){ + return EnumPayStatus.PAY_STATUS_WAIT.getCode(); + }else if("SUCCESS".equals(orderStatus)){ + return EnumPayStatus.PAY_STATUS_SUCCESS.getCode(); + }else if("FAIL".equals(orderStatus)){ + return EnumPayStatus.PAY_STATUS_FAIL.getCode(); + }else if("TIMEOUT".equals(orderStatus)){ + return EnumPayStatus.PAY_STATUS_FAIL.getCode(); + } + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询抖音支付状态失败"+result.getOutOrderNo()); + } + + protected int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception { return statusObject.getCode(); } @@ -46,8 +79,7 @@ public class BaseTtPayAdapterService { return new PayAdapterResult(true, "订单撤销成功", null, null); } - @Autowired - protected MaUtil maUtil; + protected File getQrCode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws WxErrorException { TtMaService ttappService = maUtil.getTtMaService(appinfo); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/miniApp/TtMiniAppPayAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/miniApp/TtMiniAppPayAdapterService.java index 28c2e97e6..0e22e1abf 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/miniApp/TtMiniAppPayAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/douyin/miniApp/TtMiniAppPayAdapterService.java @@ -8,8 +8,11 @@ import com.iformall.domain.vo.WxMerchantVo; import com.iformall.domain.vo.WxOrderCouponVo; import com.iformall.douyin.miniapp.api.TtMaService; import com.iformall.douyin.pay.DouYinPayHelper; +import com.iformall.douyin.pay.TtPayService; import com.iformall.douyin.pay.preOrder.CreatePreOrderResult; import com.iformall.douyin.pay.preOrder.DouYinCreatePreOrder; +import com.iformall.douyin.payv2.request.TtPayUnifiedOrderV2Request; +import com.iformall.douyin.payv2.result.TtPayUnifiedOrderV2Result; import com.iformall.enums.*; import com.iformall.mapper.TtMerchantPoiMapper; import com.iformall.mapper.WxAppinfoMapper; @@ -21,6 +24,7 @@ import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; import com.iformall.utils.Constant; import com.iformall.utils.DateUtils; +import com.iformall.utils.MaUtil; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.json.WxGsonBuilder; @@ -42,36 +46,49 @@ public class TtMiniAppPayAdapterService extends BaseTtPayAdapterService implemen @Autowired private TtMerchantPoiMapper ttMerchantPoiMapper; + @Autowired + private MaUtil maUtil; + @Override public PayAdapterResult pay(WxPayAccount payAccount, WxPayOrder record,WxComposeOrder composeOrder,String productName,EnumPayShare isShare,WxAppinfo appInfo,Date currentDate, PayExtraParam params) throws Exception { - DouYinCreatePreOrder preOrder = new DouYinCreatePreOrder(); - preOrder.setAppId(appInfo.getAppId()); - preOrder.setSercrect(appInfo.getSecret()); - preOrder.setSalt(payAccount.getApiKey()); - preOrder.setOutOrderNo(record.getPayOrderNo()); - preOrder.setTotalAmount(composeOrder.getPayment()); - preOrder.setSubject(productName); - preOrder.setBody(productName); - preOrder.setValidTime(30*60); -// preOrder.setNotifyUrl();//回调地址 -// preOrder.setThirdpartyId();//第三方服务商ID -// preOrder.setStoreId(record.getStoreId()); - CreatePreOrderResult preOrderResult = DouYinPayHelper.createPreOrder(preOrder); - if(preOrderResult.isSuccess()){ -// record.setPrepayId(preOrderResult.getOrderId()); - record.setTransactionId(preOrderResult.getOrderId()); - }else{ - record.setFailReason(preOrderResult.getMsg()); - } - record.setUpdateTime(new Date()); + throw new Exception("请升级抖音版本"); + + // 新下单接口 +// TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); +// TtPayUnifiedOrderV2Request request = new TtPayUnifiedOrderV2Request(); +// +// +// TtPayUnifiedOrderV2Result result = ttPayService.createOrderV2(request); - PayAdapterResult par = new PayAdapterResult(); - par.setSuccess(preOrderResult.isSuccess()); - par.setMsg(preOrderResult.getMsg()); - par.setTransactionId(preOrderResult.getOrderId()); - par.setData(preOrderResult); - return par; +// DouYinCreatePreOrder preOrder = new DouYinCreatePreOrder(); +// preOrder.setAppId(appInfo.getAppId()); +// preOrder.setSercrect(appInfo.getSecret()); +// preOrder.setSalt(payAccount.getApiKey()); +// preOrder.setOutOrderNo(record.getPayOrderNo()); +// preOrder.setTotalAmount(composeOrder.getPayment()); +// preOrder.setSubject(productName); +// preOrder.setBody(productName); +// preOrder.setValidTime(30*60); +//// preOrder.setNotifyUrl();//回调地址 +//// preOrder.setThirdpartyId();//第三方服务商ID +//// preOrder.setStoreId(record.getStoreId()); +// CreatePreOrderResult preOrderResult = DouYinPayHelper.createPreOrder(preOrder); +// +// if(preOrderResult.isSuccess()){ +//// record.setPrepayId(preOrderResult.getOrderId()); +// record.setTransactionId(preOrderResult.getOrderId()); +// }else{ +// record.setFailReason(preOrderResult.getMsg()); +// } +// record.setUpdateTime(new Date()); +// +// PayAdapterResult par = new PayAdapterResult(); +// par.setSuccess(preOrderResult.isSuccess()); +// par.setMsg(preOrderResult.getMsg()); +// par.setTransactionId(preOrderResult.getOrderId()); +// par.setData(preOrderResult); +// return par; } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java index 2383fa92f..df2ba9179 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java @@ -1,15 +1,17 @@ package com.iformall.service.pay.service.refund.douyin; +import com.alibaba.fastjson.JSON; import com.iformall.common.ErrorCode; -import com.iformall.domain.po.WxAppinfo; -import com.iformall.domain.po.WxPayAccount; -import com.iformall.domain.po.WxPayOrder; -import com.iformall.domain.po.WxRefundOrder; +import com.iformall.domain.po.*; import com.iformall.douyin.pay.DouYinPayHelper; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; import com.iformall.douyin.pay.orderQuery.QueryRefundResult; import com.iformall.douyin.pay.preOrder.CreateRefund; import com.iformall.douyin.pay.preOrder.CreateRefundResult; +import com.iformall.douyin.payv2.request.TtPayRefundV2Request; +import com.iformall.douyin.payv2.result.TtPayRefundV2Result; import com.iformall.enums.EnumPayType; import com.iformall.enums.EnumPayWay; import com.iformall.enums.EnumRefundStatus; @@ -18,46 +20,89 @@ import com.iformall.mapper.WxAppinfoMapper; import com.iformall.mapper.WxPayAccountMapper; import com.iformall.mapper.WxPayOrderMapper; import com.iformall.mapper.WxRefundOrderMapper; +import com.iformall.service.WxOrderService; import com.iformall.service.pay.service.refund.RefundPayAdapterService; import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; +import com.iformall.utils.Constant; +import com.iformall.utils.MaUtil; import com.iformall.utils.XmlUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; @Slf4j @Service public class TtRefundAdapterService implements RefundPayAdapterService{ + + @Autowired + MaUtil maUtil; + + @Autowired + WxOrderService wxOrderService; @Override public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { - CreateRefund createRefund = new CreateRefund(); - createRefund.setAppId(appInfo.getAppId()); - createRefund.setSalt(payAccount.getApiKey()); - createRefund.setOutOrderNo(payOrder.getPayOrderNo()); - createRefund.setOutRefundNo(String.valueOf(record.getId())); - if (payType == EnumPayType.PAY_B_REFUND) { - createRefund.setReason("B端商户退款"); - } else if (payType == EnumPayType.PAY_ADMIN_REFUND) { - createRefund.setReason("管理端商户退款"); - } else if (payType == EnumPayType.PAY_AUTO_REFUND) { - createRefund.setReason("超期自动退款"); - } else if (payType == EnumPayType.PAY_C_REFUND){ - createRefund.setReason("用户自己退款"); - } - createRefund.setRefundAmount(record.getRefundFee()); - CreateRefundResult refund = DouYinPayHelper.createRefund(createRefund); - if(refund.isSuccess()){ - return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", refund); - }else{ - return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),refund.getMsg(),refund); + try { + TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); + TtPayRefundV2Request request = new TtPayRefundV2Request(); + request.setOutOrderNo(payOrder.getPayOrderNo()); + request.setOutRefundNo(record.getId().toString()); + TtPayRefundV2Request.PageEntry pageEntry = new TtPayRefundV2Request.PageEntry(); + pageEntry.setPath(Constant.mainPageUrl); + Map paramMap = new HashMap<>(); + paramMap.put("type","dt"); + paramMap.put("orderId",payOrder.getId()); + pageEntry.setParams(JSON.toJSONString(paramMap)); + request.setOrderEntrySchema(pageEntry); + WxOrder order = wxOrderService.getById(record.getOrderId(), appInfo.getTenantId()); + if(StringUtils.isBlank(order.getExtParam())){ + request.setRefundTotalAmount(order.getPayment()); + }else{ + List list = new ArrayList<>(); + TtPayRefundV2Request.OrderDetail orderDetail = new TtPayRefundV2Request.OrderDetail(); + String itemOrderId = (String) order.getExpParamValue("itemOrderId"); + orderDetail.setItemOrderId(itemOrderId); + list.add(orderDetail); + request.setItemOrderDetail(list); + } + + TtPayRefundV2Result result1 = ttPayService.refundV2(request); + record.setRefundId(result1.getRefundId()); +// record.setRefundVendor(payOrder.getTtPayWay()); + return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", result1); + + } catch (TtPayException e) { + e.printStackTrace(); + return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),e.getMessage(),null); } + +// CreateRefund createRefund = new CreateRefund(); +// createRefund.setAppId(appInfo.getAppId()); +// createRefund.setSalt(payAccount.getApiKey()); +// createRefund.setOutOrderNo(payOrder.getPayOrderNo()); +// createRefund.setOutRefundNo(String.valueOf(record.getId())); +// if (payType == EnumPayType.PAY_B_REFUND) { +// createRefund.setReason("B端商户退款"); +// } else if (payType == EnumPayType.PAY_ADMIN_REFUND) { +// createRefund.setReason("管理端商户退款"); +// } else if (payType == EnumPayType.PAY_AUTO_REFUND) { +// createRefund.setReason("超期自动退款"); +// } else if (payType == EnumPayType.PAY_C_REFUND){ +// createRefund.setReason("用户自己退款"); +// } +// createRefund.setRefundAmount(record.getRefundFee()); +// +// CreateRefundResult refund = DouYinPayHelper.createRefund(createRefund); +// if(refund.isSuccess()){ +// return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", refund); +// }else{ +// return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),refund.getMsg(),refund); +// } } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java index d65cc639e..bf2bdda3d 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java @@ -12,6 +12,7 @@ import com.iformall.enums.EnumProfitSharingOrderType; import com.iformall.enums.EnumProfitSharingReceiverType; import com.iformall.exception.MallinkException; import com.iformall.service.pay.service.share.entity.ShareAccountResult; +import com.iformall.service.pay.service.share.entity.PayShareCalculateAmount; import com.iformall.service.pay.service.share.entity.PayShareQueryResult; import com.iformall.service.pay.service.share.entity.PayShareResult; import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; @@ -34,6 +35,11 @@ public interface PayShareAdapterService { */ public Integer getProfitSharingType(); + /** + * 计算商场分账金额和实际费率金额 + */ + public PayShareCalculateAmount calculateAmount(Integer payAmount,WxPayAccount payAccount); + /** * 无分账接收方分账 ,钱直接分给小程序方 调用API分账 * @param appInfo diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/douyin/TtPayShareService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/douyin/TtPayShareService.java index 21d87b673..e65094ec5 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/douyin/TtPayShareService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/douyin/TtPayShareService.java @@ -6,17 +6,25 @@ import com.alibaba.fastjson.JSONObject; import com.iformall.common.ErrorCode; import com.iformall.domain.po.*; import com.iformall.douyin.pay.DouYinPayHelper; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.exception.TtPayException; import com.iformall.douyin.pay.orderQuery.QuerySettleResult; import com.iformall.douyin.pay.preOrder.Settle; import com.iformall.douyin.pay.preOrder.SettleResult; +import com.iformall.douyin.payv2.request.ProfitSharingRequest; +import com.iformall.douyin.payv2.result.ProfitSharingResult; import com.iformall.enums.*; import com.iformall.exception.MallinkException; +import com.iformall.service.order.util.OrderHelper; import com.iformall.service.pay.service.share.PayShareBaseAdapterService; +import com.iformall.service.pay.service.share.entity.PayShareCalculateAmount; import com.iformall.service.pay.service.share.entity.PayShareQueryResult; import com.iformall.service.pay.service.share.entity.PayShareResult; import com.iformall.service.pay.service.share.entity.ShareAccountResult; import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; +import com.iformall.utils.MaUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -28,6 +36,9 @@ import java.util.Map; @Service public class TtPayShareService extends PayShareBaseAdapterService{ + @Autowired + MaUtil maUtil; + @Override public Integer getSubsidyType() { return EnumMerchantSubsidyType.DOUYIN.getCode(); @@ -37,74 +48,132 @@ public class TtPayShareService extends PayShareBaseAdapterService{ public Integer getProfitSharingType() { return EnumProfitSharingType.PROFIT_SHARING_TYPE_DOUYIN.getCode(); } + + @Override + public PayShareCalculateAmount calculateAmount(Integer payAmount, WxPayAccount payAccount) { + int mallCharge = OrderHelper.getMallCharge(payAmount, payAccount,true); + Integer realRateAmount = OrderHelper.getRealRateAmount(payAmount, payAccount); + return new PayShareCalculateAmount(payAmount,mallCharge,realRateAmount); + } @Override public PayShareResult noReciverShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,Integer amount) { - Settle settle = new Settle(); - settle.setAppId(appInfo.getAppId()); - settle.setSalt(payAccount.getApiKey()); - settle.setOutSettleNo(record.getId().toString()); - settle.setOutOrderNo(record.getOrderId().toString()); - settle.setSettleDesc("自主完结分账"); -// if(order.getSettlementAmount() != null && order.getSettlementAmount().intValue() > 0){ -// List list = new ArrayList<>(); -// Map settleParams = new HashMap<>(); -// settleParams.put("merchant_uid",merchantUid); -// settleParams.put("amount",order.getPayment()-order.getSettlementAmount()); -// list.add(settleParams); -// settle.setSettleParams(JSON.toJSONString(list)); -// } - SettleResult settleResult = DouYinPayHelper.settle(settle); - - if (settleResult.isSuccess()) { - return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); - }else{ - return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),settleResult.getMsg(), null,null); + try { + TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); + ProfitSharingRequest request = new ProfitSharingRequest(); + request.setOutOrderNo(record.getOrderId().toString()); + request.setOutSettleNo(record.getId().toString()); + request.setSettleDesc("mall_reciver_share"); + String settleId = ttPayService.getProfitSharingV2Service().profitSharing(request); + return new PayShareResult(true, null,"success", null,settleId); + } catch (TtPayException e) { + e.printStackTrace(); + return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),e.getMessage(), null,null); } + + +// Settle settle = new Settle(); +// settle.setAppId(appInfo.getAppId()); +// settle.setSalt(payAccount.getApiKey()); +// settle.setOutSettleNo(record.getId().toString()); +// settle.setOutOrderNo(record.getOrderId().toString()); +// settle.setSettleDesc("自主完结分账"); +//// if(order.getSettlementAmount() != null && order.getSettlementAmount().intValue() > 0){ +//// List list = new ArrayList<>(); +//// Map settleParams = new HashMap<>(); +//// settleParams.put("merchant_uid",merchantUid); +//// settleParams.put("amount",order.getPayment()-order.getSettlementAmount()); +//// list.add(settleParams); +//// settle.setSettleParams(JSON.toJSONString(list)); +//// } +// SettleResult settleResult = DouYinPayHelper.settle(settle); +// +// if (settleResult.isSuccess()) { +// return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); +// }else{ +// return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),settleResult.getMsg(), null,null); +// } } @Override public PayShareResult haveReciversShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,JSONArray receivers,EnumProfitSharingOrderType shareType ) throws MallinkException { - - Settle settle = new Settle(); - settle.setAppId(appInfo.getAppId()); - settle.setSalt(payAccount.getApiKey()); - settle.setOutSettleNo(record.getId().toString()); - settle.setOutOrderNo(record.getOrderId().toString()); - settle.setSettleDesc("自主完结分账"); - - List list = new ArrayList<>(); - for (Object o: receivers) { - JSONObject jo = (JSONObject) o; - Map settleParams = new HashMap<>(); - settleParams.put("merchant_uid",jo.getString("account")); - settleParams.put("amount",jo.getInteger("amount")); - list.add(settleParams); + try { + TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); + ProfitSharingRequest request = new ProfitSharingRequest(); + request.setOutOrderNo(record.getOrderId().toString()); + request.setOutSettleNo(record.getId().toString()); + request.setSettleDesc("merchant_reciver_share"); + List list = new ArrayList<>(); + for (Object o: receivers) { + JSONObject jo = (JSONObject) o; + Map settleParams = new HashMap<>(); + settleParams.put("merchant_uid",jo.getString("account")); + settleParams.put("amount",jo.getInteger("amount")); + list.add(settleParams); + } + request.setSettleParams(JSON.toJSONString(list)); + String settleId = ttPayService.getProfitSharingV2Service().profitSharing(request); + return new PayShareResult(true, null,"success", null,settleId); + } catch (TtPayException e) { + e.printStackTrace(); + return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),e.getMessage(), null,null); } - settle.setSettleParams(JSON.toJSONString(list)); - SettleResult settleResult = DouYinPayHelper.settle(settle); - - if (settleResult.isSuccess()) { - return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); - }else{ - return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),settleResult.getMsg(), null,null); - } +// Settle settle = new Settle(); +// settle.setAppId(appInfo.getAppId()); +// settle.setSalt(payAccount.getApiKey()); +// settle.setOutSettleNo(record.getId().toString()); +// settle.setOutOrderNo(record.getOrderId().toString()); +// settle.setSettleDesc("自主完结分账"); +// +// List list = new ArrayList<>(); +// for (Object o: receivers) { +// JSONObject jo = (JSONObject) o; +// Map settleParams = new HashMap<>(); +// settleParams.put("merchant_uid",jo.getString("account")); +// settleParams.put("amount",jo.getInteger("amount")); +// list.add(settleParams); +// } +// +// settle.setSettleParams(JSON.toJSONString(list)); +// SettleResult settleResult = DouYinPayHelper.settle(settle); +// +// if (settleResult.isSuccess()) { +// return new PayShareResult(true, null,"success", settleResult,settleResult.getSettleNo()); +// }else{ +// return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),settleResult.getMsg(), null,null); +// } } @Override public PayShareQueryResult shareQuery(WxAppinfo appInfo, WxPayAccount payAccount, WxProfitSharingOrder record) throws MallinkException { - - QuerySettleResult querySettleResult = DouYinPayHelper.settleQuery(appInfo.getAppId(), payAccount.getApiKey(), record.getId().toString(), null); - if(querySettleResult != null){ - if(querySettleResult.getSettleStatus().equals("SUCCESS")){ - return new PayShareQueryResult(true, 5, "success",querySettleResult, null); - }else if(querySettleResult.getSettleStatus().equals("FAIL")){ - return new PayShareQueryResult(true, 6, "fail",querySettleResult, null); + try { + TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); + ProfitSharingResult profitSharingResult = ttPayService.getProfitSharingV2Service().getProfitSharingResult(record.getId().toString()); + if(profitSharingResult.isSuccess()){ + ProfitSharingResult.Receiver receiver = profitSharingResult.getData().get(0); + if("SUCCESS".equals(receiver.getSettleStatus())){ + return new PayShareQueryResult(true, 5, "success",receiver, null); + } else if("FAIL".equals(receiver.getSettleStatus())){ + return new PayShareQueryResult(true, 6, "fail",receiver, null); + } } + throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), profitSharingResult.getErrTips()); + } catch (TtPayException e) { + e.printStackTrace(); + throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), e.getMessage()); } - throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), querySettleResult.getMsg()); + +// QuerySettleResult querySettleResult = DouYinPayHelper.settleQuery(appInfo.getAppId(), payAccount.getApiKey(), record.getId().toString(), null); +// if(querySettleResult != null){ +// if(querySettleResult.getSettleStatus().equals("SUCCESS")){ +// return new PayShareQueryResult(true, 5, "success",querySettleResult, null); +// }else if(querySettleResult.getSettleStatus().equals("FAIL")){ +// return new PayShareQueryResult(true, 6, "fail",querySettleResult, null); +// } +// } +// throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), querySettleResult.getMsg()); } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareCalculateAmount.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareCalculateAmount.java new file mode 100644 index 000000000..ff0bd0e8d --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareCalculateAmount.java @@ -0,0 +1,27 @@ +package com.iformall.service.pay.service.share.entity; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class PayShareCalculateAmount implements Serializable{ + + private static final long serialVersionUID = -3701322871877301001L; + + private Integer payAmount; + private Integer mallCharge;//商场拿走的钱 + private Integer realRateAmount;//平台手续费 + + //分账的钱 + public Integer getShareAmount() { + return payAmount - mallCharge; + } + + //费率差 + public Integer getRateAmount() { + return mallCharge - realRateAmount; + } +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java index 3f1937f17..52222012d 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java @@ -39,9 +39,11 @@ import com.iformall.pay.WxProfitSharingFinishP; import com.iformall.pay.WxProfitSharingP; import com.iformall.pay.WxProfitSharingQueryP; import com.iformall.pay.WxProfitSharingReceiverP; +import com.iformall.service.order.util.OrderHelper; import com.iformall.service.pay.service.share.PayShareAdapterService; import com.iformall.service.pay.service.share.PayShareBaseAdapterService; import com.iformall.service.pay.service.share.entity.ShareAccountResult; +import com.iformall.service.pay.service.share.entity.PayShareCalculateAmount; import com.iformall.service.pay.service.share.entity.PayShareQueryResult; import com.iformall.service.pay.service.share.entity.PayShareResult; import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; @@ -71,6 +73,13 @@ public class WxPayShareService extends PayShareBaseAdapterService{ public Integer getProfitSharingType() { return EnumProfitSharingType.PROFIT_SHARING_TYPE_WECHAT.getCode(); } + + @Override + public PayShareCalculateAmount calculateAmount(Integer payAmount, WxPayAccount payAccount) { + int mallCharge = OrderHelper.getMallCharge(payAmount, payAccount); + Integer realRateAmount = OrderHelper.getRealRateAmount(payAmount, payAccount); + return new PayShareCalculateAmount(payAmount,mallCharge,realRateAmount); + } @Override public PayShareResult noReciverShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,Integer amount) { @@ -444,7 +453,7 @@ public class WxPayShareService extends PayShareBaseAdapterService{ } return null; } - + // public static void main(String[] args) { // System.out.println(queryOrderShareAmount("1511925291","4200001516202205010431149938","XHZfpVA0NzoXgLEjsujctUTcyj8Zur2C")); // //System.out.println(test("1511925291", "1604439800", "wxed2f44705544b892", "4200001455202205127949391954", "XHZfpVA0NzoXgLEjsujctUTcyj8Zur2C", "684670745960046592", "D:\\apiclient_cert.p12")); diff --git a/mallinkService/src/main/java/com/iformall/sms/aliyun/AliyunSMS.java b/mallinkService/src/main/java/com/iformall/sms/aliyun/AliyunSMS.java index fd313e741..aa78f7516 100644 --- a/mallinkService/src/main/java/com/iformall/sms/aliyun/AliyunSMS.java +++ b/mallinkService/src/main/java/com/iformall/sms/aliyun/AliyunSMS.java @@ -317,7 +317,7 @@ public class AliyunSMS implements SMSExcutor { e.getErrCode(), e.getMessage(), e.getRequestId(), e.getErrMsg(), e.getErrorType()); } QuerySmsTemplateRequest request = new QuerySmsTemplateRequest(); - request.setTemplateCode("SMS_239312983"); + request.setTemplateCode("SMS_243451989"); DefaultAcsClient acsClient = new DefaultAcsClient(profile); QuerySmsTemplateResponse response = null; diff --git a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java index f38626ef4..124d3ec73 100644 --- a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java @@ -16,6 +16,9 @@ import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import com.iformall.douyin.pay.TtPayService; +import com.iformall.douyin.pay.impl.TtPayServiceImpl; +import com.iformall.douyin.payv2.config.TtPayConfig; import com.iformall.douyin.web.api.TtWebService; import com.iformall.douyin.web.api.impl.TtWebServiceImpl; import com.iformall.douyin.web.config.TtWebDefaultConfigImpl; @@ -42,6 +45,7 @@ public class MaUtil { private static Map payServiceMap = new ConcurrentHashMap(); + private static Map ttpayServiceMap = new ConcurrentHashMap(); private static Map wxMaServiceMap = new ConcurrentHashMap(); private static Map wxMaAppServiceKeyMap = new ConcurrentHashMap(); @@ -119,6 +123,28 @@ public class MaUtil { return service; } + public TtPayService getTtPayService(WxAppinfo appinfo, WxPayAccount payAccount) { + TtPayConfig config = new TtPayConfig(); + config.setAppId(appinfo.getAppId()); + + config.setPrivateKeyPath(payAccount.getPrivateKeyPath());//apiclient_key.pem 平台私钥 + config.setCertSerialNo(payAccount.getCertSerialNo());//平台私钥序列号 + config.setApiKey(payAccount.getApiV3Key());//平台私钥 + + TtPayService service = ttpayServiceMap.get(appinfo.getAppId()); + if ( null == service ) { + synchronized("getTtPayServiceBlock"+appinfo.getAppId()) { + service = ttpayServiceMap.get(appinfo.getAppId()); + if (null == service) { + service = new TtPayServiceImpl(); + service.setConfig(config); + ttpayServiceMap.put(appinfo.getAppId(), service); + } + } + } + return service; + } + private TtMaService getTtappService(WxAppinfo appinfo) { WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); config.setAppid(appinfo.getAppId()); diff --git a/mallinkService/src/main/java/com/iformall/utils/PayUtils.java b/mallinkService/src/main/java/com/iformall/utils/PayUtils.java index 10133e3b1..225aabb1b 100755 --- a/mallinkService/src/main/java/com/iformall/utils/PayUtils.java +++ b/mallinkService/src/main/java/com/iformall/utils/PayUtils.java @@ -23,8 +23,7 @@ public class PayUtils { Double dPayRate = 1.0D * payAmount * rate / 10000; long dChargeFee = Math.round(dPayRate); return Long.valueOf(dChargeFee).intValue(); - } - else if(payAmount > dBaseAmount.intValue()) { + }else if(payAmount > dBaseAmount.intValue()) { // 大于基础分,不小于他的最小整数 Double dChargeFee = Math.ceil(payAmount * 1.0D * rate / 10000); return dChargeFee.intValue(); @@ -35,6 +34,10 @@ public class PayUtils { return Long.valueOf(dChargeFee).intValue(); } } + + public static void main(String[] args) { + System.out.println(getPayRate(990, 7001, true)); + } /* public static void main(String[] args) { diff --git a/mallinkService/src/main/java/com/iformall/utils/Utility.java b/mallinkService/src/main/java/com/iformall/utils/Utility.java index 89ef682b6..879a09333 100644 --- a/mallinkService/src/main/java/com/iformall/utils/Utility.java +++ b/mallinkService/src/main/java/com/iformall/utils/Utility.java @@ -538,6 +538,11 @@ public final class Utility { return sdf.parse(timeEnd); } + public static Date getDateTtFromString(String timeEnd) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return sdf.parse(timeEnd); + } + public static String getOrderNo() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = sdf.format(new Date()); diff --git a/mallinkService/src/main/resources/mapper/TtCouponChannelPoiMapper.xml b/mallinkService/src/main/resources/mapper/TtCouponChannelPoiMapper.xml index 9992266bd..0644c4589 100644 --- a/mallinkService/src/main/resources/mapper/TtCouponChannelPoiMapper.xml +++ b/mallinkService/src/main/resources/mapper/TtCouponChannelPoiMapper.xml @@ -5,6 +5,7 @@ + @@ -18,7 +19,7 @@ - `id`,`tenant_id`,`parent_tenant_id`,`spu_id`, + `id`,`tenant_id`,`parent_tenant_id`,`coupon_channel_id`,`spu_id`, `status`,`status_desc`,`last_status`,`last_status_desc`, `create_date`,`update_date` @@ -37,6 +38,10 @@ and `parent_tenant_id` = #{parentTenantId} + + and `coupon_channel_id` = #{couponChannelId} + + and `spu_id` = #{spuId} @@ -65,6 +70,20 @@ from tt_coupon_channel_poi + + + + + + + update tt_coupon_channel_poi set update_date = now() + ,`status` = #{status} + ,`last_status` = #{statusDesc} + ,`last_status` = #{lastStatus} + ,`last_status_desc` = #{lastStatusDesc} + where `spu_id` = #{spuId} + + diff --git a/mallinkService/src/main/resources/mapper/TtGoodsCategoryMapper.xml b/mallinkService/src/main/resources/mapper/TtGoodsCategoryMapper.xml new file mode 100644 index 000000000..5e094496c --- /dev/null +++ b/mallinkService/src/main/resources/mapper/TtGoodsCategoryMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + `id`,`name`,`parent_id` + + + + where 1 = 1 + + + and `id` = #{id} + + + + and `name` like concat('%', #{name},'%') + + + + and `parent_id` = #{parentId} + + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + + + + diff --git a/mallinkService/src/main/resources/mapper/WxBatchOrderMapper.xml b/mallinkService/src/main/resources/mapper/WxBatchOrderMapper.xml index bde2fa25a..cc12a7cbb 100644 --- a/mallinkService/src/main/resources/mapper/WxBatchOrderMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxBatchOrderMapper.xml @@ -7,15 +7,16 @@ + - + - `id`,`tenant_id`,`parent_tenant_id`,`c_user_id`,`payment`,`pay_vendor`,`order_type`,`is_tt_poi_order`,`create_date`,`update_date` + `id`,`tenant_id`,`parent_tenant_id`,`c_user_id`,`payment`,`ext_param`,`pay_vendor`,`order_type`,`is_tt_poi_order`,`create_date`,`update_date` diff --git a/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml b/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml index cd9e02f86..26ae13e33 100644 --- a/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml @@ -192,10 +192,9 @@ - + select distinct coupon_id from wx_coupon_channel where status = 0 and tenant_id = #{tenantId} and end_time < now() - and `tt_spu_id` is not null @@ -203,11 +202,10 @@ where status = 0 and tenant_id = #{tenantId} and end_time < now() - + select distinct cc.coupon_id from wx_coupon_channel cc, wx_coupon c where cc.coupon_id = c.id and c.valid_type = 1 and c.valid_end_date < now() and cc.status = 0 and cc.tenant_id = #{tenantId} - and cc.`tt_spu_id` is not null @@ -215,11 +213,10 @@ where cc.status = 0 and cc.tenant_id = #{tenantId} and cc.coupon_id = c.id and c.valid_type = 1 and c.valid_end_date < now() - + select distinct cc.coupon_id from wx_coupon_channel cc, wx_coupon c where cc.coupon_id = c.id and c.status = 1 and cc.status = 0 and cc.tenant_id = #{tenantId} - and cc.`tt_spu_id` is not null @@ -359,14 +356,6 @@ order by ${sortColumns} - - - update wx_coupon_channel SET channel_stock = channel_stock - #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null and channel_stock - #{number} >= 0 @@ -400,4 +389,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mallinkService/src/main/resources/mapper/WxCouponMapper.xml b/mallinkService/src/main/resources/mapper/WxCouponMapper.xml index 9aeace5e7..7c801549f 100644 --- a/mallinkService/src/main/resources/mapper/WxCouponMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCouponMapper.xml @@ -55,6 +55,8 @@ + + @@ -113,7 +115,7 @@ c.`valid_type`,c.`valid_start_date`,c.`valid_end_date`,c.pick_start_date,c.pick_end_date,c.`valid_days`,c.`detail`,c.`price`,c.tail_price,c.orig_price,c.`unit`,c.`remain_inventory`,c.`inventory`, c.`remark`,c.`status`,c.`create_date`,c.`update_date`,c.`business`,c.`sub_business`,c.`support_transfer`,c.`subsidy_num`,c.`subsidy_type`, c.`press_limit_num`, c.`press_limit_hours`, c.`auto_refund`,c.`credit_price`,c.`credit_refund`,c.`put_apply_status`,c.`stock_apply_status`,c.`cancle_apply_status`, - c.`conditions`,c.approval_type,c.content_type,c.source_type,c.password_support,c.gift_list + c.`conditions`,c.approval_type,c.content_type,c.source_type,c.password_support,c.gift_list,c.product_type,c.category_id @@ -324,6 +326,19 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml b/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml index 2a74d8e21..fd3709e64 100644 --- a/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml @@ -30,6 +30,7 @@ + @@ -40,7 +41,7 @@ `id`,`tenant_id`,`parent_tenant_id`,`coupon_id`,`coupon_type`,`c_user_id`,`owner_id`,`b_user_id`,`b_merchant_id`,`order_id`,`expired_time`,`coupon_order_status`,`create_date`,`update_date`,`coupon_price`, `auto_refund`, `verify_type`,`verify_remark`,`pay_vendor`,`send_merchant_id`,`send_merchant_user_id`,`compose_order_type`,`compose_order_id`,`parent_coupon_order_id`,`coupon_number`, - `freight_price`,`shipping_type`,`shipping_address`,`shipping_status`,`delivery_info`,`subsidy` + `freight_price`,`shipping_type`,`shipping_address`,`shipping_status`,`delivery_info`,`subsidy`,`ext_param` @@ -161,7 +162,7 @@ select co.id,co.tenant_id,co.parent_tenant_id,co.coupon_id,co.coupon_type,co.c_user_id,co.owner_id,co.b_user_id,co.b_merchant_id,co.order_id,co.expired_time, co.coupon_order_status,co.create_date,co.update_date,co.coupon_price,co.verify_type,co.verify_remark,co.pay_vendor, - co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info` + co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.ext_param from wx_coupon_order co where co.tenant_id = #{tenantId} @@ -698,7 +699,7 @@ select co.id,co.tenant_id,co.parent_tenant_id,co.coupon_id,co.coupon_type,co.c_user_id,co.owner_id,co.b_user_id,co.b_merchant_id, co.order_id,co.expired_time,co.coupon_order_status,co.create_date,co.update_date,co.coupon_price,co.verify_type,co.verify_remark, co.pay_vendor, - co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.subsidy + co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.subsidy,co.ext_param FROM wx_coupon_order co where co.id = #{id} and co.tenant_id = #{tenantId} @@ -792,7 +793,7 @@ select co.id,co.tenant_id,co.parent_tenant_id,co.coupon_id,co.coupon_type,co.c_user_id,co.owner_id,co.b_user_id,co.b_merchant_id, co.order_id,co.expired_time,co.coupon_order_status,co.create_date,co.update_date,co.coupon_price,co.verify_type,co.verify_remark, co.pay_vendor, - co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info` + co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.ext_param FROM wx_coupon_order co where co.`tenant_id` = #{tenantId} @@ -857,7 +858,7 @@ select co.id,co.tenant_id,co.parent_tenant_id,co.coupon_id,co.coupon_type,co.c_user_id,co.owner_id,co.b_user_id,co.b_merchant_id, co.order_id,co.expired_time,co.coupon_order_status,co.create_date,co.update_date,co.coupon_price,co.verify_type,co.verify_remark,co.pay_vendor, - co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info` + co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.ext_param from wx_coupon_order co where co.coupon_order_status = '1' and co.tenant_id = #{tenantId} @@ -896,7 +897,7 @@ select co.id,co.tenant_id,co.parent_tenant_id,co.coupon_id,co.coupon_type,co.c_user_id,co.owner_id,co.b_user_id,co.b_merchant_id,co.order_id,co.expired_time,co.coupon_order_status,co.create_date,co.update_date,co.coupon_price,co.verify_type,co.verify_remark,co.pay_vendor, - co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info` + co.`freight_price`,co.`shipping_type`,co.`shipping_address`,co.`shipping_status`,co.`delivery_info`,co.ext_param from wx_coupon_order co where co.id = #{id} and co.tenant_id = #{tenantId} @@ -944,7 +945,7 @@ select o.id,o.order_number,o.tenant_id,o.parent_tenant_id,o.c_user_id,o.coupon_channel_id,o.product_id,o.payment_type,o.payment,o.payment_time,o.order_status,o.create_date,o.update_date, - o.compose_order_type,o.compose_order_id,o.`coupon_number`,o.`freight_price`,o.`shipping_type`,o.`shipping_address`,o.parent_order_id + o.compose_order_type,o.compose_order_id,o.`coupon_number`,o.`freight_price`,o.`shipping_type`,o.`shipping_address`,o.parent_order_id,o.ext_param from wx_order o where o.order_status in (0,1,2,3,4,5) @@ -360,7 +361,7 @@