| @@ -149,6 +149,8 @@ public class ShiroConfig { | |||
| //商场初始化init | |||
| filterChainDefinitionMap.put("/wxProjectConfig/**", "anon"); | |||
| // filterChainDefinitionMap.put("/wxCoupon/goods/**", "anon"); | |||
| // //test | |||
| // filterChainDefinitionMap.put("/merchantPoi/spuSync", "anon"); | |||
| // filterChainDefinitionMap.put("/merchantPoi/spuGet", "anon"); | |||
| @@ -14,13 +14,10 @@ import com.iformall.domain.po.WxCouponPassword; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| 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 +26,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; | |||
| @@ -60,6 +58,8 @@ public class WxCouponController extends BaseController { | |||
| @Autowired | |||
| private WxMallService wxMallService; | |||
| @Autowired | |||
| private TtMerchantPoiService ttMerchantPoiService; | |||
| @Autowired | |||
| RedisLock redisLock; | |||
| @Autowired | |||
| @@ -543,4 +543,23 @@ public class WxCouponController extends BaseController { | |||
| return result; | |||
| } | |||
| @ApiOperation("根据类目获取商品模板") | |||
| @GetMapping("/goods/getTemplate") | |||
| @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) | |||
| @SystemControllerLog(description = "根据类目获取商品模板") | |||
| public ResultData getGoodsTemplate(Integer categoryId,Integer productType) { | |||
| logger.debug("[" + getIpAddr() + "] WxCouponController::getGoodsTemplate"); | |||
| if(productType == null){ | |||
| productType = 1; | |||
| } | |||
| try { | |||
| GoodsTemplateGet goodsTemplateGet = ttMerchantPoiService.getTtWebService(getTenantInfo()).getGoodsService().templateGet(categoryId, productType); | |||
| return new ResultData(goodsTemplateGet); | |||
| } catch (WxErrorException e) { | |||
| e.printStackTrace(); | |||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| package com.iformall.controller; | |||
| import com.alibaba.fastjson.JSON; | |||
| 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; | |||
| @@ -13,16 +15,22 @@ 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.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.utils.Constant; | |||
| import com.iformall.utils.MaUtil; | |||
| import com.iformall.utils.RedisLock; | |||
| import io.swagger.annotations.Api; | |||
| @@ -55,6 +63,9 @@ public class WxOrderController extends BaseController { | |||
| @Autowired | |||
| private WxCouponService wxCouponService; | |||
| @Autowired | |||
| private CUserServiceFactory cuserFactory; | |||
| @Autowired | |||
| private WxCUserBasicInfoService wxCUserBasicInfoService; | |||
| @@ -76,6 +87,9 @@ public class WxOrderController extends BaseController { | |||
| @Autowired | |||
| private OrderFactory orderFactory; | |||
| @Autowired | |||
| private MaUtil maUtil; | |||
| @Autowired | |||
| @Qualifier("couponDetailRedisTemplate") | |||
| RedisTemplate<String, WxCouponCVo> cdRedisTemplate; | |||
| @@ -144,6 +158,8 @@ public class WxOrderController extends BaseController { | |||
| @ApiOperation(value = "抖音支付2.0与下单回调推送订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") | |||
| @PostMapping("douyinPushOrder") | |||
| public Map<String,Object> douyinPushOrder(HttpServletRequest request) { | |||
| Map<String, Object> map = new HashMap(); | |||
| SignatureHeader header = new SignatureHeader(); | |||
| header.setTimeStamp(request.getHeader("Byte-Timestamp")); | |||
| header.setNonce(request.getHeader("Byte-Nonce-Str")); | |||
| @@ -154,27 +170,105 @@ public class WxOrderController extends BaseController { | |||
| String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); | |||
| logger.info("支付2.0预下单回调---body{}"+body); | |||
| Map<String, Object> map = new HashMap(); | |||
| map.put("err_no",1000); | |||
| map.put("err_tips","库存不足"); | |||
| return map; | |||
| JSONObject jsonObject = JSONObject.parseObject(body); | |||
| String app_id = jsonObject.getString("app_id"); | |||
| String open_id = jsonObject.getString("open_id"); | |||
| //验证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; | |||
| } | |||
| //验证用户 | |||
| Long memberId = null; | |||
| TtCUser cuser = (TtCUser) cuserFactory.getCUserService(EnumAppPlat.TOUTIAO).getByOpenId(open_id, appinfo.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; | |||
| } | |||
| // Long memberId; | |||
| // try { | |||
| // memberId = getMemberId(); | |||
| // } catch (Exception e) { | |||
| // return new ResultData(Result.ERROR,e.getMessage()); | |||
| // } | |||
| // | |||
| // List<PlatPushOrderSaveDto> list = new ArrayList<>(); | |||
| // PlatPushOrderSaveDto dto = new PlatPushOrderSaveDto(); | |||
| // /** | |||
| // * TODO 从抖音推送的订单中取信息,每个订单里面有extParam,用来放第三方平台匹配的参数信息 | |||
| // * 注意,wx_batch_order中要存allExtParam, wx_order,wx_coupon_order中存储每个订单的参数信息,需要自己根据总参数信息进行拆分 | |||
| // */ | |||
| // list.add(dto); | |||
| // String allExtParam = "[]"; | |||
| // return wxOrderService.platPushSaveOrder(false,EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,allExtParam,list,memberId,getPayWay(),getTenantInfo()); | |||
| try { | |||
| 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<PlatPushOrderSaveDto> list = new ArrayList<>(); | |||
| for (CreateOrderCallback.Good good:createOrderCallback.getGoods()) { | |||
| PlatPushOrderSaveDto dto = new PlatPushOrderSaveDto(); | |||
| dto.setCouponChannelId(Long.parseLong(good.getGoodsId())); | |||
| dto.setCount(good.getQuantity()); | |||
| dto.setExtParam(good.getItemOrderInfoList().toString()); | |||
| list.add(dto); | |||
| } | |||
| ResultData resultData = wxOrderService.platPushSaveOrder(false, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH, allExtParam.toString(), list, memberId, EnumPayWay.PAY_WAY_TT, getTenantInfo()); | |||
| if(resultData.code == 200){ | |||
| WxComposeOrder order = (WxComposeOrder) resultData.data; | |||
| Map<String, Object> data = new HashMap<>(); | |||
| data.put("out_order_no",order.getMainOrderId()); | |||
| data.put("order_entry_schema",getOrderEntrySchema(order.getMainOrderId())); | |||
| List<Map<String,Object>> goodsValid = new ArrayList<>(); | |||
| for (Long goodId:order.getCouponChannelMap().keySet()) { | |||
| Map<String,Object> goodsValidMap = new HashMap<>(); | |||
| goodsValidMap.put("goods_id",goodId.toString()); | |||
| WxCouponChannel couponChannel = order.getCouponChannelMap().get(goodId); | |||
| 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); | |||
| 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; | |||
| } | |||
| } | |||
| private Map<String,String> getOrderEntrySchema(Long batchOrderId){ | |||
| Map<String,String> map = new HashMap<>(); | |||
| map.put("path", Constant.mainPageUrl); | |||
| Map<String,Object> paramMap = new HashMap<>(); | |||
| paramMap.put("type","dt"); | |||
| paramMap.put("orderId",batchOrderId); | |||
| map.put("params", JSON.toJSONString(paramMap)); | |||
| return map; | |||
| } | |||
| @@ -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"); | |||
| @@ -0,0 +1,59 @@ | |||
| package com.iformall.controller.callback; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.iformall.controller.base.BaseController; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| 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()); | |||
| /** | |||
| * { | |||
| * "event": "verify_webhook", | |||
| * "client_key": "", | |||
| * "content": { | |||
| * "challenge": 12345 | |||
| * } | |||
| * } | |||
| */ | |||
| @PostMapping(value = "/notice") | |||
| @ResponseBody | |||
| public Map<String,Object> notice( @RequestBody Map<String, Object> parameterMap,HttpServletRequest request){ | |||
| logger.debug("[" + getIpAddr() + "] TtOrderCallbackController::notice"); | |||
| Map<String,Object> resultMap = new HashMap<>(); | |||
| // String body = ((BodyReaderHttpServletRequestWrapper) request).getBody(); | |||
| logger.info("抖音开放平台通知-----parameterMap{}"+parameterMap); | |||
| try { | |||
| String header = request.getHeader("X-Douyin-Signature"); | |||
| logger.info("抖音开放平台通知-----header.X-Douyin-Signature{}"+parameterMap); | |||
| // Map<String, Object> parameterMap = JSONObject.parseObject(body, Map.class); | |||
| String event = (String) parameterMap.get("event"); | |||
| logger.info("抖音开放平台通知-----event{}"+event); | |||
| String client_key = (String) parameterMap.get("client_key"); | |||
| logger.info("抖音开放平台通知-----client_key{}"+client_key); | |||
| JSONObject content = (JSONObject) parameterMap.get("content"); | |||
| logger.info("抖音开放平台通知-----content{}"+content.toString()); | |||
| String challenge = content.getString("challenge"); | |||
| logger.info("抖音开放平台通知-----content.challenge{}"+challenge); | |||
| resultMap.put("challenge",challenge); | |||
| return resultMap; | |||
| } catch (Exception e){ | |||
| logger.error(e.getMessage()); | |||
| resultMap.put("err_tips","error"); | |||
| return resultMap; | |||
| } | |||
| } | |||
| } | |||
| @@ -24,7 +24,7 @@ public class PlatPushOrderSaveDto implements Serializable { | |||
| Integer shippingType = 0;//EnumOrderShopingType【传入参数】配送类型 | |||
| UserBasicInfoAddress address;//【传入参数】配送地址 | |||
| String extParam;//【传入参数】json,额外的信息,可能每个平台不一样 | |||
| String extParam;//数组格式长度与数量一致(一个券一个订单时)【传入参数】json,额外的信息,可能每个平台不一样 | |||
| WxCoupon wxCoupon;//【非传入参数】。 | |||
| WxCouponChannel wxCouponChannel;//【非传入参数】。 | |||
| @@ -195,6 +195,32 @@ public class CreateOrderCallback implements Serializable { | |||
| @SerializedName(value = "goods_id_type") | |||
| private Integer goodsIdType; | |||
| /** | |||
| * 是 | |||
| * 商品item_order信息,详情见 item_order_info_list部分 | |||
| */ | |||
| @SerializedName(value = "item_order_info_list") | |||
| protected List<ItemOrderInfo> 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; | |||
| } | |||
| } | |||
| @@ -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<String, String> { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| protected RequestHttp<CloseableHttpClient, HttpHost> requestHttp; | |||
| public TtWebGoodsGetRequestExecutor(RequestHttp requestHttp) { | |||
| this.requestHttp = requestHttp; | |||
| } | |||
| @Override | |||
| public void execute(String uri, String data, ResponseHandler<String> 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; | |||
| } | |||
| } | |||
| @@ -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<String, String> { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| protected RequestHttp<CloseableHttpClient, HttpHost> requestHttp; | |||
| public TtWebGoodsPostRequestExecutor(RequestHttp requestHttp) { | |||
| this.requestHttp = requestHttp; | |||
| } | |||
| @Override | |||
| public void execute(String uri, String data, ResponseHandler<String> 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>")) { | |||
| // //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; | |||
| } | |||
| } | |||
| @@ -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<Product> 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<Product> 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 ; | |||
| } | |||
| @@ -110,4 +110,6 @@ public interface TtWebService { | |||
| */ | |||
| TtWebProductService getProductService(); | |||
| TtWebGoodsService getGoodsService(); | |||
| } | |||
| @@ -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<GoodsTemplateGet> baseResult = GSON.fromJson(result, | |||
| new TypeReference<BaseGoodsResult<GoodsTemplateGet>>(){}.getType()); | |||
| if(baseResult.isSuccess()){ | |||
| return baseResult.getData(); | |||
| }else{ | |||
| throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); | |||
| } | |||
| } | |||
| @Override | |||
| public List<Product> 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()){ | |||
| JsonObject object = (JsonObject) baseResult.getData(); | |||
| if(object != null){ | |||
| JsonObject product_draft_list = object.getAsJsonObject("product_draft_list"); | |||
| List<Product> list = GSON.fromJson(product_draft_list.toString(), | |||
| new TypeReference<List<Product>>() {}.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<ProductPage> baseResult = GSON.fromJson(result, | |||
| new TypeReference<BaseGoodsResult<ProductPage>>() {}.getType()); | |||
| if(baseResult.isSuccess()){ | |||
| return baseResult.getData(); | |||
| }else{ | |||
| throw new WxErrorException(WxError.builder().errorCode(baseResult.getErrCode()).errorMsg(baseResult.getErrMsg()).build()); | |||
| } | |||
| } | |||
| @Override | |||
| public List<Product> 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()){ | |||
| JsonObject object = (JsonObject) baseResult.getData(); | |||
| if(object != null){ | |||
| JsonObject product_online_list = object.getAsJsonObject("product_online_list"); | |||
| List<Product> list = GSON.fromJson(product_online_list.toString(), | |||
| new TypeReference<List<Product>>() {}.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<ProductPage> baseResult = GSON.fromJson(result, | |||
| new TypeReference<BaseGoodsResult<ProductPage>>() {}.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()){ | |||
| JsonObject data = (JsonObject) baseResult.getData(); | |||
| return GsonHelper.getString(data,"product_id"); | |||
| }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<String,Object> 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<String,Object> 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<String,Object> 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<String,Integer> 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()); | |||
| } | |||
| } | |||
| } | |||
| @@ -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<CloseableHttp | |||
| private TtWebShopMatchService shopMatchService = new TtWebShopMatchServiceImpl(this); | |||
| private TtWebProductService productService = new TtWebProductServiceImpl(this); | |||
| private TtWebGoodsServiceImpl goodService = new TtWebGoodsServiceImpl(this); | |||
| private int retrySleepMillis = 1000; | |||
| private int maxRetryTimes = 5; | |||
| @@ -198,7 +200,7 @@ public class TtWebServiceImpl implements TtWebService, RequestHttp<CloseableHttp | |||
| if (error.getErrorCode() == -1) { | |||
| int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | |||
| try { | |||
| log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||
| log.warn("系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||
| Thread.sleep(sleepMillis); | |||
| } catch (InterruptedException e1) { | |||
| Thread.currentThread().interrupt(); | |||
| @@ -294,4 +296,9 @@ public class TtWebServiceImpl implements TtWebService, RequestHttp<CloseableHttp | |||
| return this.productService; | |||
| } | |||
| @Override | |||
| public TtWebGoodsService getGoodsService() { | |||
| return this.goodService; | |||
| } | |||
| } | |||
| @@ -0,0 +1,90 @@ | |||
| package com.iformall.douyin.web.bean; | |||
| import com.google.gson.annotations.SerializedName; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| import java.io.Serializable; | |||
| /** | |||
| * 商品. | |||
| * | |||
| * @author thinsstar | |||
| */ | |||
| @Data | |||
| @NoArgsConstructor | |||
| public class BaseGoodsResult<T> 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<T> 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; | |||
| } | |||
| } | |||
| @@ -0,0 +1,82 @@ | |||
| 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> productAttrs; | |||
| /** | |||
| * SKU属性列表 | |||
| */ | |||
| @SerializedName(value = "sku_attrs") | |||
| private List<ProductAttrs> 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; | |||
| /** | |||
| * 属性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; | |||
| } | |||
| } | |||
| @@ -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<PoiStruct> poiList; | |||
| /** | |||
| * 商品属性KV | |||
| */ | |||
| @SerializedName(value = "attr_key_value_map") | |||
| private Map<String,String> 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<String,String> 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; | |||
| } | |||
| } | |||
| @@ -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<Product> productList; | |||
| } | |||
| @@ -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<Product.SkuStruct> skuList; | |||
| } | |||
| @@ -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.*; | |||
| @@ -2796,10 +2797,22 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| //券一个数量创建一个订单 | |||
| boolean isOneNumberOneOrder = orderAdapterService.isOneNumberOneOrder(); | |||
| if (isOneNumberOneOrder) { | |||
| JSONArray jsonArray = new JSONArray(); | |||
| if(StringUtils.isNotBlank(orderdto.getExtParam())){ | |||
| try{ | |||
| jsonArray = JSONArray.parseArray(orderdto.getExtParam()); | |||
| }catch(Exception e){ | |||
| logger.error(e.getMessage()); | |||
| } | |||
| } | |||
| for (int j = 0; j < orderdto.getCount(); j++) { | |||
| lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, | |||
| orderdto.isPress(),orderdto.getOrderGroupId(),orderdto.getFormId(),orderdto.getShippingType(),orderdto.getAddress(),orderdto.getExtParam(), | |||
| orderdto.getWxCouponChannel(), payWay); | |||
| String extParam = ""; | |||
| if(jsonArray != null && !jsonArray.isEmpty()){ | |||
| extParam = jsonArray.get(j).toString(); | |||
| } | |||
| 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(), | |||
| @@ -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<Long,WxCouponChannel> couponChannelMap; | |||
| private Map<Long,WxCoupon> couponMap; | |||
| } | |||
| @@ -49,7 +49,7 @@ public class SingleOrderAdapterService extends BaseBatchOrderAdapterService { | |||
| @Override | |||
| public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, | |||
| EnumPayWay payWay) { | |||
| return super.createDBMainOrder(tenantEntity,user, payment,null, 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}) | |||
| @@ -79,6 +79,7 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,List<OrderComposeSaveDto> orderSave,EnumPayWay payWay,EnumComposeOrder composeOrderType) { | |||
| int payment = 0; | |||
| Map<Long,WxCoupon> couponMap = new HashMap<Long,WxCoupon>(); | |||
| Map<Long,WxCouponChannel> couponChannelMap = new HashMap<Long,WxCouponChannel>(); | |||
| for (OrderComposeSaveDto ocsd : orderSave) { | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(ocsd.getSignleOrder().getCouponChannelId(),tenantEntity.getTenantId()); | |||
| @@ -88,15 +89,17 @@ 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); | |||
| 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<PlatPushOrderSaveDto> platPushOrderList,EnumPayWay payWay,EnumComposeOrder composeOrderType) { | |||
| int payment = 0; | |||
| Map<Long,WxCoupon> couponMap = new HashMap<Long,WxCoupon>(); | |||
| Map<Long,WxCouponChannel> couponChannelMap = new HashMap<Long,WxCouponChannel>(); | |||
| for (PlatPushOrderSaveDto ocsd : platPushOrderList) { | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(ocsd.getCouponChannelId(),tenantEntity.getTenantId()); | |||
| @@ -106,14 +109,16 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic | |||
| 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, allExtParam,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,String allExtParam,EnumPayWay payWay,EnumComposeOrder composeOrderType,Map<Long,WxCouponChannel> couponChannelMap) { | |||
| protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,String allExtParam,EnumPayWay payWay,EnumComposeOrder composeOrderType, | |||
| Map<Long,WxCouponChannel> couponChannelMap,Map<Long,WxCoupon> couponMap) { | |||
| //判断是否poi订单 | |||
| Integer isTtPoiOrder = null; | |||
| try{ | |||
| @@ -140,6 +145,9 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic | |||
| if (null != couponChannelMap) { | |||
| composeOrder.setCouponChannelMap(couponChannelMap); | |||
| } | |||
| if (null != couponMap){ | |||
| composeOrder.setCouponMap(couponMap); | |||
| } | |||
| return composeOrder; | |||
| } | |||
| @@ -39,7 +39,7 @@ public class CouponPackageOrderAdapterService extends BaseBatchOrderAdapterServi | |||
| @Override | |||
| public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, | |||
| EnumPayWay payWay) { | |||
| return super.createDBMainOrder(tenantEntity, user, payment,null, 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}) | |||
| @@ -40,7 +40,7 @@ public class MulityNumberOneOrderBatchOrderAdapterService extends BaseBatchOrder | |||
| @Override | |||
| public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, | |||
| EnumPayWay payWay) { | |||
| return super.createDBMainOrder(tenantEntity,user, payment, null, 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}) | |||
| @@ -39,7 +39,7 @@ public class OneNumberOneOrderBatchOrderAdapterService extends BaseBatchOrderAda | |||
| @Override | |||
| public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, | |||
| EnumPayWay payWay) { | |||
| return super.createDBMainOrder(tenantEntity,user, payment, null,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}) | |||