| @@ -102,6 +102,7 @@ public class ShiroConfig { | |||
| filterChainDefinitionMap.put("/wechat/login", "anon"); // 微信第三方登录callback | |||
| filterChainDefinitionMap.put("/wechat/callback", "anon"); // 微信网页登录回调 | |||
| filterChainDefinitionMap.put("/wechat/weChatUserLogin", "anon"); // 微信第三方登录 | |||
| // 验证码 | |||
| filterChainDefinitionMap.put("/captcha.jpg", "anon"); | |||
| // 官网 | |||
| @@ -116,7 +117,7 @@ public class ShiroConfig { | |||
| filterChainDefinitionMap.put("/wxMallApply/sendvalidationcode", "anon"); | |||
| // 补发消息 | |||
| filterChainDefinitionMap.put("/msgrecord/resendMsg", "anon"); | |||
| filterChainDefinitionMap.put("/wxCoupon/updateStokeAndValidDate", "anon"); | |||
| // static files | |||
| filterChainDefinitionMap.put("/css/**", "anon"); | |||
| @@ -145,6 +146,8 @@ public class ShiroConfig { | |||
| filterChainDefinitionMap.put("/version", "anon"); | |||
| filterChainDefinitionMap.put("/wxDeviceScreenAd/**", "anon"); | |||
| // filterChainDefinitionMap.put("/role/**", "corsFilter,token"); | |||
| //商场初始化init | |||
| filterChainDefinitionMap.put("/wxProjectConfig/**", "anon"); | |||
| //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 | |||
| @@ -66,7 +66,6 @@ public class BaseController { | |||
| public TenantEntity getTenantInfo(){ | |||
| Session session = SecurityUtils.getSubject().getSession(); | |||
| String tenantId = (String)session.getAttribute(UserSession.tenantId); | |||
| TenantEntity tenantEntity = new TenantEntity(){{ | |||
| setTenantId(tenantId); | |||
| }}; | |||
| @@ -0,0 +1,39 @@ | |||
| package com.iformall.controller.basic; | |||
| import com.iformall.annotation.SystemControllerLog; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.controller.base.BaseController; | |||
| import com.iformall.service.WxProjectConfigService; | |||
| 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.*; | |||
| @RestController | |||
| @RequestMapping("wxProjectConfig") | |||
| public class WxProjectConfigController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| private WxProjectConfigService wxProjectConfigService; | |||
| @ApiOperation("添加商场基础数据") | |||
| @GetMapping(value = "/init/{id}") | |||
| @SystemControllerLog(description = "商场基础数据") | |||
| public ResultData init(@PathVariable Long id) { | |||
| logger.debug("[" + getIpAddr() + "] WxProjectConfigController::init"); | |||
| try { | |||
| wxProjectConfigService.initProjectConfig(id); | |||
| return new ResultData(); | |||
| }catch (Exception e){ | |||
| logger.error(e.getMessage(),e); | |||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR); | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ import com.iformall.service.WxCouponPasswordService; | |||
| import com.iformall.service.WxCouponService; | |||
| import com.iformall.service.WxFlowService; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.RedisLock; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| @@ -46,6 +48,8 @@ public class WxCouponController extends BaseController { | |||
| private WxCouponChannelMapper wxCouponChannelMapper; | |||
| @Autowired | |||
| private WxFlowService wxFlowService; | |||
| @Autowired | |||
| RedisLock redisLock; | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("list") | |||
| @@ -95,7 +99,7 @@ public class WxCouponController extends BaseController { | |||
| if (resultData.code != 200) { | |||
| return resultData; | |||
| } | |||
| redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); | |||
| //启动投放审批 | |||
| if(wxCoupon.getFlowParams() !=null && wxCoupon.getFlowParams().size()>0) { | |||
| wxCoupon.getFlowParams().put("businessId",wxCoupon.getId()); | |||
| @@ -124,7 +128,7 @@ public class WxCouponController extends BaseController { | |||
| return new ResultData(ResultData.ERROR, "有活动正在上架,请先下架。"); | |||
| } | |||
| } | |||
| redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); | |||
| //启动审批流 | |||
| if (wxCoupon.getFlowParams() != null && wxCoupon.getFlowParams().size() > 0) { | |||
| logger.info("------coupon.update().businessType:"+wxCoupon.getFlowParams().get("businessType")); | |||
| @@ -139,6 +143,7 @@ public class WxCouponController extends BaseController { | |||
| wxCoupon.setPutApplyStatus(EnumRentContractAppStatus.APPLYING.getCode()); | |||
| } | |||
| } | |||
| return wxCouponService.saveOrUpdate(wxCoupon); | |||
| } | |||
| @@ -246,7 +251,9 @@ public class WxCouponController extends BaseController { | |||
| updateCoupon.setStockApplyStatus(EnumRentContractAppStatus.APPLYING.getCode()); | |||
| updateCoupon.setUpdateDate(new Date()); | |||
| wxCouponService.update(updateCoupon); | |||
| redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); | |||
| } else { | |||
| redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); | |||
| return wxCouponService.updateCouponStockAndEndTime(wxCoupon); | |||
| } | |||
| @@ -411,6 +411,7 @@ public class HomeController extends BaseController { | |||
| @GetMapping("/version") | |||
| public ResultData version() { | |||
| logger.debug("[" + getIpAddr() + "] HomeController::version"); | |||
| logger.info(">>>>>>>>>>>>>"+version); | |||
| return new ResultData(version); | |||
| } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true&allowMultiQueries=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true&allowMultiQueries=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -26,7 +27,7 @@ spring: | |||
| #date-format: yyyy-MM-dd HH:mm:ss | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -72,6 +73,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| flyway: | |||
| enabled: false | |||
| @@ -92,7 +98,7 @@ wechat: | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -21,22 +21,22 @@ spring: | |||
| cache-names: redis_cache #缓存的名字(可以不指定) | |||
| redis: | |||
| time-to-live: 60000ms #很重要,缓存的有效时间,以便缓存的过期(单位为毫秒) | |||
| rocketmq: | |||
| nameServer: 202.165.179.86:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| rabbitmq: | |||
| host: 202.165.179.86 | |||
| port: 5672 | |||
| username: guest | |||
| password: guest | |||
| publisher-confirms: true | |||
| virtual-host: / | |||
| # rocketmq: | |||
| # nameServer: 202.165.179.86:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # rabbitmq: | |||
| # host: 202.165.179.86 | |||
| # port: 5672 | |||
| # username: guest | |||
| # password: guest | |||
| # publisher-confirms: true | |||
| # virtual-host: / | |||
| # FLOWABLE | |||
| flowable: | |||
| async-executor-activate: false | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -25,7 +26,7 @@ spring: | |||
| #date-format: yyyy-MM-dd HH:mm:ss | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -71,6 +72,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| @@ -84,12 +90,12 @@ jasypt: | |||
| wechat: | |||
| open: | |||
| componentAppId: "wx897e4673286c915d" | |||
| componentSecret: "cdfdfda65c45689beb6766c4c427eed2" | |||
| componentAppId: "wxdfc8fb4e62d6b52b" | |||
| componentSecret: "98daa62b316dd6feabaad708327ce233" | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -12,15 +12,15 @@ spring: | |||
| date-format: yyyy-MM-dd HH:mm:ss | |||
| time-zone: GMT+8 | |||
| default-property-inclusion: non_null | |||
| rocketmq: | |||
| nameServer: 127.0.0.1:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| # rocketmq: | |||
| # nameServer: 127.0.0.1:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # MybatisPlus | |||
| mybatis-plus: | |||
| @@ -1,12 +1,14 @@ | |||
| package com.iformall; | |||
| import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; | |||
| import org.mybatis.spring.annotation.MapperScan; | |||
| import org.rocketmq.starter.annotation.EnableRocketMQ; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.EnableAspectJAutoProxy; | |||
| import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; | |||
| /** | |||
| * @author chenkx | |||
| @@ -16,6 +18,7 @@ import org.springframework.context.annotation.Bean; | |||
| @MapperScan(basePackages = {"com.iformall.mapper"}) | |||
| @EnableEncryptableProperties | |||
| @EnableRocketMQ | |||
| @EnableAspectJAutoProxy(exposeProxy = true) | |||
| public class CApplication { | |||
| @Value("${fm.exception}") | |||
| @@ -64,6 +64,7 @@ public class RedisCacheAspect { | |||
| if (StringUtils.isBlank(token)) { | |||
| token = request.getParameter("token"); | |||
| } | |||
| log.info("token>>>>>>>>>>>>>>>"+token); | |||
| String tenantId; | |||
| WxCUser wxCUser = null ; | |||
| if(StringUtils.isNotBlank(token)) { | |||
| @@ -1,11 +1,23 @@ | |||
| package com.iformall.controller; | |||
| import java.util.Date; | |||
| import java.util.Map; | |||
| import org.apache.commons.collections.map.HashedMap; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.ModelAttribute; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.annotation.RedisCache; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.base.BaseEntity; | |||
| import com.iformall.domain.po.WxCouponChannel; | |||
| import com.iformall.domain.po.WxMerchant; | |||
| import com.iformall.domain.po.base.BaseEntity; | |||
| import com.iformall.domain.vo.WxCouponChannelVo; | |||
| import com.iformall.enums.EnumCouponChannelActivityStatus; | |||
| import com.iformall.enums.EnumCouponChannelStatus; | |||
| @@ -13,21 +25,11 @@ import com.iformall.enums.EnumCouponChannelType; | |||
| import com.iformall.enums.EnumCouponStatus; | |||
| import com.iformall.service.WxCouponChannelService; | |||
| import com.iformall.service.WxMerchantService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.apache.commons.collections.map.HashedMap; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.ModelAttribute; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import java.util.Date; | |||
| import java.util.Map; | |||
| @RestController | |||
| @RequestMapping("/api/wxCouponChannel") | |||
| @@ -41,6 +43,7 @@ public class WxCouponChannelController extends BaseController { | |||
| @Autowired | |||
| private WxMerchantService wxMerchantService; | |||
| @RedisCache(expireTime = 100) | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("list") | |||
| @ApiImplicitParams({ | |||
| @@ -98,7 +101,7 @@ public class WxCouponChannelController extends BaseController { | |||
| } | |||
| } | |||
| @RedisCache | |||
| @RedisCache(expireTime = 100) | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("change") | |||
| public ResultData change(@ModelAttribute WxCouponChannel wxCouponChannel) { | |||
| @@ -31,6 +31,7 @@ import com.iformall.service.WxCouponChannelService; | |||
| import com.iformall.service.WxCouponService; | |||
| import com.iformall.service.WxMerchantService; | |||
| import com.iformall.utils.Constant; | |||
| import com.iformall.utils.RedisLock; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| @@ -103,6 +104,7 @@ public class WxCouponController extends BaseController { | |||
| } | |||
| // end of 更新状态 | |||
| updateActivityStatus(wxCouponCVo); | |||
| return new ResultData(wxCouponCVo); | |||
| } | |||
| @@ -78,7 +78,7 @@ public class WxCouponOrderController extends BaseController { | |||
| else | |||
| wxCouponOrder.setSortColumns(BaseEntity.SortField.UpdateDate_DESC, BaseEntity.SortField.Id_DESC); | |||
| PageInfo<WxCouponOrderCVo> page = wxCouponOrderService.listCUserVoAsPage(wxCouponOrder, pageNum, pageSize); | |||
| PageInfo<WxCouponOrderCVo> page = wxCouponOrderService.listCUserVoAsPageOptimize(wxCouponOrder, pageNum, pageSize); | |||
| Date now = new Date(); | |||
| page.getList().stream().forEach(co->{ | |||
| @@ -18,6 +18,8 @@ import com.iformall.service.WxCouponChannelService; | |||
| import com.iformall.service.WxCouponService; | |||
| import com.iformall.service.WxOrderService; | |||
| import com.iformall.utils.Constant; | |||
| import com.iformall.utils.RedisLock; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| @@ -56,6 +58,9 @@ public class WxOrderController extends BaseController { | |||
| @Autowired | |||
| @Qualifier("couponDetailRedisTemplate") | |||
| RedisTemplate<String, WxCouponCVo> cdRedisTemplate; | |||
| @Autowired | |||
| RedisLock redisLock; | |||
| @ApiOperation(value = "下订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") | |||
| @PostMapping("save") | |||
| @@ -79,6 +84,21 @@ public class WxOrderController extends BaseController { | |||
| return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||
| } | |||
| WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId()); | |||
| if (null == coupon) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||
| } | |||
| //判断是否是拼团订单,如果是拼团订单,判断现在进行中的,和已完成的数量是否超出券的限制 | |||
| if (coupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode())) { | |||
| int ordercount = wxOrderService.countUserCouponGroupOrder(user.getId(),coupon.getId()); | |||
| if (ordercount>=coupon.getUseLimitQuantity()) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF.getCode(),"您当前此券的有效拼团数量达到券的限购次数。"); | |||
| } | |||
| } | |||
| WxCouponCVo wxCouponCVo = null; | |||
| String key = "cc:" + orderSaveDto.getCouponChannelId(); | |||
| @@ -100,6 +120,12 @@ public class WxOrderController extends BaseController { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 | |||
| boolean hascache = redisLock.hasCouponStockCache(wxCouponCVo.getCouponId()); | |||
| if (!hascache) { | |||
| redisLock.setCouponStock(wxCouponCVo.getCouponId(), coupon.getRemainInventory()); | |||
| } | |||
| resultData = couponUserCheck(user, wxCouponCVo); | |||
| if (resultData != null) return resultData; | |||
| @@ -112,14 +138,6 @@ public class WxOrderController extends BaseController { | |||
| boolean isPress = orderSaveDto.getPress() != null ? orderSaveDto.getPress() : false; | |||
| try { | |||
| WxCoupon coupon = wxCouponService.getById(couponId); | |||
| if (coupon == null) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||
| } | |||
| WxOrder order = wxOrderService.saveOrderForCoupon(user, coupon, orderSaveDto, isPress); | |||
| return new ResultData(order); | |||
| } catch (MallinkException e) { | |||
| @@ -1,30 +1,49 @@ | |||
| package com.iformall.controller; | |||
| import java.util.Map; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| 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.GetMapping; | |||
| import org.springframework.web.bind.annotation.ModelAttribute; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RequestMethod; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxCUser; | |||
| import com.iformall.domain.po.WxCUserBasicInfo; | |||
| import com.iformall.domain.po.WxCoupon; | |||
| import com.iformall.domain.po.WxOrder; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.WxPayOrder; | |||
| import com.iformall.enums.EnumCreditLockedStatus; | |||
| import com.iformall.enums.EnumOrderStatus; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.WxCUserBasicInfoService; | |||
| import com.iformall.service.WxCouponService; | |||
| import com.iformall.service.WxOrderService; | |||
| import com.iformall.service.WxPayAccountService; | |||
| import com.iformall.service.WxPayOrderService; | |||
| import com.iformall.utils.IPUtil; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| 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.*; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.util.Map; | |||
| @RestController | |||
| @RequestMapping("/api/pay") | |||
| @@ -40,8 +59,15 @@ public class WxPayOrderController extends BaseController { | |||
| @Autowired | |||
| private WxCUserBasicInfoService wxCUserBasicInfoService; | |||
| @ApiOperation(value = "发起微信小程序支付订单", notes = "{\"orderId\":\"string\"}") | |||
| @Autowired | |||
| private WxPayAccountService wxPayAccountService; | |||
| @Autowired | |||
| private WxCouponService wxCouponService; | |||
| //@ApiOperation(value = "发起微信小程序支付订单", notes = "{\"orderId\":\"string\"}") | |||
| @RequestMapping(value = "/create", method = RequestMethod.POST) | |||
| public ResultData _create(@RequestBody Map<String, String> paramMap, HttpServletRequest request) throws Exception { | |||
| logger.info("/api/pay/create" + paramMap.toString()); | |||
| @@ -69,7 +95,6 @@ public class WxPayOrderController extends BaseController { | |||
| } | |||
| WxPayOrder record = new WxPayOrder(); | |||
| record.setOrderId(orderId); | |||
| try { | |||
| record.setIp(IPUtil.getIpAddr(request)); | |||
| return wxPayOrderService.createPayOrder(appInfo, user, record, EnumPayWay.PAY_WAY_WECHAT); | |||
| @@ -121,24 +146,64 @@ public class WxPayOrderController extends BaseController { | |||
| payOrder.setPayOrderStatus(status); | |||
| payOrder.setFailReason(reasonStr); | |||
| WxOrder order = null; | |||
| try { | |||
| //有价券支付成功 | |||
| if (status.equals(EnumPayStatus.PAY_STATUS_SUCCESS.getCode())) { | |||
| // 前端提示支付成功, 不作为支付成功标志,只检查支付订单状态 | |||
| // 有价券不走update, callback更新 | |||
| if (payOrderId<=0) { | |||
| logger.error("/api/pay/updatePayOrder error : payOrderId不能为空: " + paramMap.toString()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "payOrderId非法"+payOrderId+"[payOrderIdStr:"+payOrderIdStr+"]"); | |||
| } | |||
| payOrder = wxPayOrderService.getById(payOrderId); | |||
| if (payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_SUCCESS.getCode())) { | |||
| order = wxOrderService.getById(orderId); | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功", order); | |||
| } else { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "支付状态未知,请等待!!"); | |||
| if (null == payOrder) { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "未查询到payOrder."); | |||
| } | |||
| WxOrder order = wxOrderService.getById(orderId); | |||
| if (null == order) { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "未查询到Order["+orderId+"]."); | |||
| } | |||
| WxCoupon wxCoupon = wxCouponService.getById(order.getProductId()); | |||
| if (null == wxCoupon) { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "未查询到优惠券[orderId:"+orderId+"]."); | |||
| } | |||
| //拼团的订单,如果查询到是拼团待付款的,则重新查询是否已经真的支付,其他的直接返回订单信息 | |||
| if (wxPayOrderService.isOrderGroupCoupon(payOrder, wxCoupon)) { | |||
| if (order.getOrderStatus()!=EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()) { | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功", order); | |||
| } | |||
| }else { | |||
| //非拼团的订单,支付成功,关闭订单,撤销支付订单,支付转退款的,直接返回订单信息,其他需要查询真实支付状态 | |||
| if (payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_SUCCESS.getCode())|| | |||
| payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_CLOSE.getCode())|| | |||
| payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_REVERSE.getCode())|| | |||
| payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_REFUND.getCode())) { | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功", order); | |||
| } | |||
| } | |||
| //查询微信订单状态并更新 | |||
| WxCUser user = getUser(); | |||
| WxAppinfo appInfo = getAppInfo(user.getAppId()); | |||
| if (null == appInfo) { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "当前用户appId["+user.getAppId()+"]找不到appInfo"); | |||
| } | |||
| WxPayAccount payAccount = wxPayAccountService.getById(appInfo.getPayId()); | |||
| try { | |||
| WxPayOrder wo = wxPayOrderService.handleWxOrderQuery(payOrder, order, appInfo, payAccount, IdWorker.get(),false); | |||
| if (null != wo) { | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功", order); | |||
| } | |||
| }catch(MallinkException e) { | |||
| //已经同步了微信的支付状态,表示已经更新 | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功", order); | |||
| } | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "查询微信订单支付状态失败,请稍后!"); | |||
| } else if (status.equals(EnumPayStatus.PAY_STATUS_FAIL.getCode())) { | |||
| // 有价券支付失败 | |||
| wxPayOrderService.handlePayOrderFail(payOrder, EnumPayStatus.PAY_STATUS_FAIL.getCode()); | |||
| } | |||
| } | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功"); | |||
| } catch (MallinkException e) { | |||
| logger.error("支付状态更新失败2: " + payOrder.toString() + ", e:" + e.getMessage()); | |||
| @@ -147,7 +147,7 @@ public class WxPressOrderController extends BaseController { | |||
| return new ResultData(ErrorCode.COUPON_PRESS_HAD_FINISHED); | |||
| } | |||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| if (!redisLock.lock(orderIdStr, timeStr)) { | |||
| logger.error("此砍价订单被锁定, orderId: " + orderIdStr); | |||
| @@ -136,7 +136,7 @@ public class WxUserGrantController extends BaseController { | |||
| @PostMapping("/login") | |||
| @ApiOperation(value = "用户登录", notes = "{\"appId\":\"string\",\"code\":\"string\",\"scene\":\"string\",\"sceneAddress\":\"string\",\"latitude\":\"string\",\"longitude\":\"string\",\"systemInfo\":\"string\"}") | |||
| public ResultData userLogin(@RequestBody Map<String, String> map) { | |||
| logger.debug(map.toString()); | |||
| logger.info("dologin >>>>>>>>>>>>>>>>>"+map.toString()); | |||
| Map resultMap = new HashMap(); | |||
| @@ -199,6 +199,11 @@ public class WxUserGrantController extends BaseController { | |||
| try { | |||
| WxMaJscode2SessionResult session = wxMaService.jsCode2SessionInfo(code); | |||
| logger.info("sessionResult: " + session); | |||
| if (null != session) { | |||
| logger.info("sessionResultDetail: [openid]" + session.getOpenid()+",[sessionkey]"+session.getSessionKey()+",[unionid]"+session.getUnionid()); | |||
| } | |||
| //获取会话密钥(session_key) | |||
| session_key = session.getSessionKey(); | |||
| openId = session.getOpenid(); | |||
| @@ -29,6 +29,9 @@ public class AuthorizationInterceptor extends HandlerInterceptorAdapter { | |||
| @Override | |||
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |||
| System.out.println(" requesturi......"+request.getRequestURL()); | |||
| AuthIgnore annotation; | |||
| if(handler instanceof HandlerMethod) { | |||
| annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class); | |||
| @@ -0,0 +1,175 @@ | |||
| package com.iformall.utils; | |||
| import net.sourceforge.pinyin4j.PinyinHelper; | |||
| import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; | |||
| import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; | |||
| import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; | |||
| import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType; | |||
| import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.util.ResourceUtils; | |||
| import javax.imageio.ImageIO; | |||
| import java.awt.*; | |||
| import java.awt.image.BufferedImage; | |||
| import java.io.ByteArrayInputStream; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.File; | |||
| import java.io.InputStream; | |||
| import java.time.LocalDateTime; | |||
| import java.time.format.DateTimeFormatter; | |||
| import java.util.Locale; | |||
| public class ImgIdeaUtil { | |||
| private static final Logger logger = LoggerFactory.getLogger(ImgIdeaUtil.class); | |||
| //模板图片 | |||
| private static final String imgTempPath = "imgTemp/gertificate.jpg"; | |||
| //字体路径 | |||
| private static final String fontPath = "opt/HWLS.TTF"; | |||
| /** | |||
| * 生成图片证书 | |||
| * @return | |||
| */ | |||
| public static byte[] imgGertificate(String name, String englishName, LocalDateTime date){ | |||
| if(StringUtils.isBlank(name)){ | |||
| logger.error("名字为空,无法生成证书"); | |||
| return null; | |||
| } | |||
| if(name.length() == 2){ | |||
| name = name.replaceAll("(\\S)", "$0 "); | |||
| } | |||
| if(StringUtils.isBlank(englishName)){ | |||
| englishName = getUpEname(name); | |||
| } | |||
| if(date == null){ | |||
| date = LocalDateTime.now(); | |||
| } | |||
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dMMM yyyy", Locale.UK); | |||
| String dateFormat = date.format(formatter); | |||
| try { | |||
| InputStream backImgUrl = ClassLoader.getSystemResourceAsStream(imgTempPath); | |||
| //InputStream backImgUrl = ImgIdeaUtil.class.getClassLoader().getResourceAsStream(imgTempPath); | |||
| Font font = Font.createFont(Font.TRUETYPE_FONT, ResourceUtils.getFile("classpath:"+fontPath)); | |||
| BufferedImage backImg = ImageIO.read(backImgUrl); | |||
| Graphics g = backImg.getGraphics(); | |||
| //图片加中文名 | |||
| Font fTxtBottomName = font.deriveFont(Font.PLAIN, 170); | |||
| //Font fTxtBottomName = new Font("华文隶书", Font.PLAIN, 170); | |||
| FontMetrics metricsName = g.getFontMetrics(fTxtBottomName); | |||
| int xName = (backImg.getWidth() - metricsName.stringWidth(name)) / 2; | |||
| Color myColorTxtBottomName = Color.BLACK; //颜色 | |||
| g.setColor(myColorTxtBottomName); | |||
| g.setFont(fTxtBottomName); | |||
| g.drawString(name, xName , 1150);//g.drawString(文字, x 位置, y 位置); | |||
| //图片加英文名 | |||
| Font fTxtBottomEname = font.deriveFont(Font.PLAIN, 120); | |||
| //Font fTxtBottomEname = new Font("华文隶书", Font.PLAIN, 120); | |||
| FontMetrics metricsEname = g.getFontMetrics(fTxtBottomEname); | |||
| int xEname = (backImg.getWidth() - metricsEname.stringWidth(englishName)) / 2; | |||
| Color myColorTxtBottomEname = Color.BLACK; | |||
| g.setColor(myColorTxtBottomEname); | |||
| g.setFont(fTxtBottomEname); | |||
| g.drawString(englishName, xEname, 1300); | |||
| //图片加日期 | |||
| Font fTxtBottomDate = font.deriveFont(Font.PLAIN, 90); | |||
| //Font fTxtBottomDate = new Font("华文隶书", Font.PLAIN, 90); | |||
| Color myColorTxtBottomDate = Color.BLACK; | |||
| g.setColor(myColorTxtBottomDate); | |||
| g.setFont(fTxtBottomDate); | |||
| g.drawString(dateFormat, 440, 2100); | |||
| //调这个方法就是开始这个整合 (可以多张图片,多个文字整合成一张图片,只有把他们放在这方法里面就行) | |||
| g.dispose(); | |||
| ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
| ImageIO.write(backImg, "png", out); | |||
| return out.toByteArray(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| logger.error("生成证书异常", e.getMessage()); | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * //姓、名的第一个字母需要为大写 | |||
| * @param name | |||
| * @return | |||
| */ | |||
| public static String getUpEname(String name) { | |||
| char[] strs = name.toCharArray(); | |||
| String newname = null; | |||
| if (strs.length == 2) { | |||
| newname = toUpCase(getEname("" + strs[0])) + " " + toUpCase(getEname("" + strs[1])); | |||
| } else if (strs.length == 3){ | |||
| newname = toUpCase(getEname("" + strs[0])) + " " | |||
| + toUpCase(getEname("" + strs[1] + strs[2])); | |||
| }else if (strs.length == 4){ | |||
| newname = toUpCase(getEname("" + strs[0] + strs[1])) + " " | |||
| + toUpCase(getEname("" + strs[2] + strs[3])); | |||
| } else{ | |||
| newname = toUpCase(getEname(name)); | |||
| } | |||
| return newname; | |||
| } | |||
| /** | |||
| * //将中文转换为英文 | |||
| * @param name | |||
| * @return | |||
| */ | |||
| public static String getEname(String name){ | |||
| HanyuPinyinOutputFormat pyFormat = new HanyuPinyinOutputFormat(); | |||
| pyFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); | |||
| pyFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); | |||
| pyFormat.setVCharType(HanyuPinyinVCharType.WITH_V); | |||
| String s = ""; | |||
| try { | |||
| s = PinyinHelper.toHanyuPinyinString(name, pyFormat, ""); | |||
| } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { | |||
| badHanyuPinyinOutputFormatCombination.printStackTrace(); | |||
| } | |||
| return s; | |||
| } | |||
| /** | |||
| * 首字母大写 | |||
| * @param str | |||
| * @return | |||
| */ | |||
| private static String toUpCase(String str) { | |||
| StringBuffer newstr = new StringBuffer(); | |||
| newstr.append((str.substring(0, 1)).toUpperCase()).append( | |||
| str.substring(1, str.length())); | |||
| return newstr.toString(); | |||
| } | |||
| // public static void main(String[] args) { | |||
| // String serverUploadImgUrl = "C:/Users/xiaohu/Desktop/img"; // 图片保存路径 | |||
| // try { | |||
| // byte[] bytes = imgGertificate("郑方元", null, null); | |||
| // ByteArrayInputStream bais = new ByteArrayInputStream(bytes); | |||
| // BufferedImage bi1 =ImageIO.read(bais); | |||
| // | |||
| // ImageIO.write(bi1, "png", new File(serverUploadImgUrl+"/0.png")); | |||
| // | |||
| // } catch (Exception e) { | |||
| // e.printStackTrace(); | |||
| // } | |||
| // System.out.println("结束"); | |||
| // } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -26,7 +27,7 @@ spring: | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -71,6 +72,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| @@ -80,12 +86,12 @@ aws: | |||
| wechat: | |||
| open: | |||
| componentAppId: "wx897e4673286c915d" | |||
| componentSecret: "cdfdfda65c45689beb6766c4c427eed2" | |||
| componentAppId: "wxdfc8fb4e62d6b52b" | |||
| componentSecret: "98daa62b316dd6feabaad708327ce233" | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -12,15 +12,15 @@ spring: | |||
| date-format: yyyy-MM-dd HH:mm:ss | |||
| time-zone: GMT+8 | |||
| default-property-inclusion: non_null | |||
| rocketmq: | |||
| nameServer: 127.0.0.1:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| # rocketmq: | |||
| # nameServer: 127.0.0.1:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # MybatisPlus | |||
| mybatis-plus: | |||
| @@ -55,58 +55,64 @@ public class WxPayController extends BaseController { | |||
| @ResponseBody | |||
| public String _payNotify(HttpServletRequest request) throws IOException, JDOMException { | |||
| logger.info("[" +getIpAddr() + "]微信支付回调"); | |||
| InputStream inStream = request.getInputStream(); | |||
| ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); | |||
| byte[] buffer = new byte[1024]; | |||
| int len = 0; | |||
| while ((len = inStream.read(buffer)) != -1) { | |||
| outSteam.write(buffer, 0, len); | |||
| } | |||
| String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); | |||
| logger.info(resultxml); | |||
| outSteam.close(); | |||
| inStream.close(); | |||
| Map<String, String> paramMap = null; | |||
| try { | |||
| paramMap = WxPayment.xmlToMap(resultxml); | |||
| logger.info("微信支付回调, notify, param: " + paramMap.toString() ); | |||
| String response = wxPayOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||
| logger.info("微信支付回调, notify success, req : " + resultxml); | |||
| return response; | |||
| } catch (BizMessageException e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap<>(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (MallinkException e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap<>(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (Exception e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "SUCCESS"); | |||
| resultMap.put("return_msg", "OK"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| // InputStream inStream = request.getInputStream(); | |||
| // ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); | |||
| // byte[] buffer = new byte[1024]; | |||
| // int len = 0; | |||
| // while ((len = inStream.read(buffer)) != -1) { | |||
| // outSteam.write(buffer, 0, len); | |||
| // } | |||
| // String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); | |||
| // logger.info(resultxml); | |||
| // | |||
| // outSteam.close(); | |||
| // inStream.close(); | |||
| // | |||
| // Map<String, String> paramMap = null; | |||
| // | |||
| // try { | |||
| // paramMap = WxPayment.xmlToMap(resultxml); | |||
| // logger.info("微信支付回调, notify, param: " + paramMap.toString() ); | |||
| // String response = wxPayOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||
| // logger.info("微信支付回调, notify success, req : " + resultxml); | |||
| // return response; | |||
| // } catch (BizMessageException e) { | |||
| // if (paramMap == null) { | |||
| // logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| // } else { | |||
| // logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| // } | |||
| // SortedMap resultMap = new TreeMap<>(); | |||
| // resultMap.put("return_code", "FAIL"); | |||
| // resultMap.put("return_msg", e.getMessage()); | |||
| // return XmlUtil.getRequestXml(resultMap); | |||
| // } catch (MallinkException e) { | |||
| // if (paramMap == null) { | |||
| // logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| // } else { | |||
| // logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| // } | |||
| // SortedMap resultMap = new TreeMap<>(); | |||
| // resultMap.put("return_code", "FAIL"); | |||
| // resultMap.put("return_msg", e.getMessage()); | |||
| // return XmlUtil.getRequestXml(resultMap); | |||
| // } catch (Exception e) { | |||
| // if (paramMap == null) { | |||
| // logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| // } else { | |||
| // logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| // } | |||
| // SortedMap resultMap = new TreeMap(); | |||
| // resultMap.put("return_code", "FAIL"); | |||
| // resultMap.put("return_msg", e.getMessage()); | |||
| // return XmlUtil.getRequestXml(resultMap); | |||
| // } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -26,7 +27,7 @@ spring: | |||
| #date-format: yyyy-MM-dd HH:mm:ss | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -73,6 +74,12 @@ spring: | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| bucketName: iformall-net | |||
| @@ -90,7 +97,7 @@ wechat: | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -21,22 +21,22 @@ spring: | |||
| cache-names: redis_cache #缓存的名字(可以不指定) | |||
| redis: | |||
| time-to-live: 60000ms #很重要,缓存的有效时间,以便缓存的过期(单位为毫秒) | |||
| rocketmq: | |||
| nameServer: 202.165.179.86:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| rabbitmq: | |||
| host: 202.165.179.86 | |||
| port: 5672 | |||
| username: guest | |||
| password: guest | |||
| publisher-confirms: true | |||
| virtual-host: / | |||
| # rocketmq: | |||
| # nameServer: 202.165.179.86:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # rabbitmq: | |||
| # host: 202.165.179.86 | |||
| # port: 5672 | |||
| # username: guest | |||
| # password: guest | |||
| # publisher-confirms: true | |||
| # virtual-host: / | |||
| aop: | |||
| proxy-target-class: true | |||
| auto: true | |||
| @@ -41,7 +41,9 @@ public class MqBaseConsumer { | |||
| private FmInsideNotifyPaySuccessMsgServiceImpl fmInsideNotifyPaySuccessMsgService; | |||
| @Autowired | |||
| private FmInsideNotifyRefundSuccessMsgServiceImpl fmInsideNotifyRefundSuccessMsgService; | |||
| @Autowired | |||
| UpdateCouponStockMsgServiceImpl updateCouponStockMsgService; | |||
| public void doMessage(String message) { | |||
| @@ -95,10 +97,15 @@ public class MqBaseConsumer { | |||
| // 内部消息 - 微信退款通知 | |||
| FmInsideNotifyRefundSuccessMsg msg = (FmInsideNotifyRefundSuccessMsg)JsonUtil.readValue(message,FmInsideNotifyRefundSuccessMsg.class); | |||
| fmInsideNotifyRefundSuccessMsgService.send(msg); | |||
| } else if (EnumMsgRecordType.COUPON_STOCK.getCode().equals(baseMsg.getMsgType())) { | |||
| UpdateCouponStockMsg msg = (UpdateCouponStockMsg)JsonUtil.readValue(message,UpdateCouponStockMsg.class); | |||
| updateCouponStockMsgService.send(msg); | |||
| } | |||
| baseMsg.setMsgStatus(EnumMsgRecordStatus.CONSUME_SUCC.getCode()); | |||
| wxMsgRecordMapper.updateByBaseMsg(baseMsg); | |||
| //baseMsg.setMsgStatus(EnumMsgRecordStatus.CONSUME_SUCC.getCode()); | |||
| //wxMsgRecordMapper.updateByBaseMsg(baseMsg); | |||
| }catch (Throwable e){ | |||
| log.error("consum received error: ", e); | |||
| /** | |||
| try { | |||
| log.error("consum received error: ", e); | |||
| baseMsg.setStatusMessage(e.getMessage()); | |||
| @@ -124,7 +131,7 @@ public class MqBaseConsumer { | |||
| } | |||
| }catch (Throwable e1){ | |||
| log.error("更新db状态error: ", e1); | |||
| } | |||
| }*/ | |||
| } | |||
| } | |||
| @@ -0,0 +1,79 @@ | |||
| package com.iformall.mq.impl; | |||
| import java.util.Properties; | |||
| import javax.annotation.PostConstruct; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.context.annotation.Profile; | |||
| import org.springframework.stereotype.Service; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.aliyun.openservices.ons.api.Action; | |||
| import com.aliyun.openservices.ons.api.ConsumeContext; | |||
| import com.aliyun.openservices.ons.api.Consumer; | |||
| import com.aliyun.openservices.ons.api.Message; | |||
| import com.aliyun.openservices.ons.api.MessageListener; | |||
| import com.aliyun.openservices.ons.api.ONSFactory; | |||
| import com.aliyun.openservices.ons.api.PropertyKeyConst; | |||
| import com.aliyun.openservices.ons.api.bean.ConsumerBean; | |||
| import com.iformall.enums.EnumMsgMqTopic; | |||
| import com.iformall.mq.MQConfig; | |||
| import com.iformall.mq.MqBaseConsumer; | |||
| import com.iformall.utils.JsonUtil; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| @Slf4j | |||
| @Service | |||
| @Profile(MQConfig.Impl.ALIYUN_ROCKET_MQ) | |||
| public class AliyunRocketMqConsumer extends MqBaseConsumer { | |||
| @Value("${spring.aliyunRocketmq.accessKeyId}") | |||
| private String accessKeyId; | |||
| @Value("${spring.aliyunRocketmq.accessKeySecret}") | |||
| private String accessKeySecret; | |||
| @Value("${spring.aliyunRocketmq.groupId}") | |||
| private String groupId; | |||
| @Value("${spring.aliyunRocketmq.namesrvAddr}") | |||
| private String namesrvAddr; | |||
| @PostConstruct | |||
| public void init() { | |||
| for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { | |||
| Properties properties = new Properties(); | |||
| // 您在控制台创建的 Group ID | |||
| properties.put(PropertyKeyConst.GROUP_ID, topic.getGroupId()); | |||
| // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||
| properties.put(PropertyKeyConst.AccessKey, accessKeyId); | |||
| // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||
| properties.put(PropertyKeyConst.SecretKey, accessKeySecret); | |||
| // 设置 TCP 接入域名,到控制台的实例基本信息中查看 | |||
| properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); | |||
| // 集群订阅方式(默认) | |||
| // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING); | |||
| // 广播订阅方式 | |||
| // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING); | |||
| Consumer consumer = ONSFactory.createConsumer(properties); | |||
| consumer.subscribe(topic.getCode(), "*", new MessageListener() { //订阅多个 Tag | |||
| public Action consume(Message message, ConsumeContext context) { | |||
| try { | |||
| System.out.println("Receive: " + message); | |||
| doMessage(new String(message.getBody())); | |||
| return Action.CommitMessage; | |||
| }catch(Exception e) { | |||
| log.error("AliyunRocketMqConsumer error:",e); | |||
| return Action.ReconsumeLater; | |||
| } | |||
| } | |||
| }); | |||
| consumer.start(); | |||
| log.info(" aliyunrocketMq consumer start success! "+JSON.toJSONString(consumer)); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -27,7 +28,7 @@ spring: | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -71,6 +72,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| @@ -85,7 +91,7 @@ wechat: | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -21,22 +21,22 @@ spring: | |||
| cache-names: redis_cache #缓存的名字(可以不指定) | |||
| redis: | |||
| time-to-live: 60000ms #很重要,缓存的有效时间,以便缓存的过期(单位为毫秒) | |||
| rocketmq: | |||
| nameServer: 127.0.0.1:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| rabbitmq: | |||
| host: 202.165.179.86 | |||
| port: 5672 | |||
| username: guest | |||
| password: guest | |||
| publisher-confirms: true | |||
| virtual-host: / | |||
| # rocketmq: | |||
| # nameServer: 127.0.0.1:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # rabbitmq: | |||
| # host: 202.165.179.86 | |||
| # port: 5672 | |||
| # username: guest | |||
| # password: guest | |||
| # publisher-confirms: true | |||
| # virtual-host: / | |||
| # MybatisPlus | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -25,7 +26,7 @@ spring: | |||
| #date-format: yyyy-MM-dd HH:mm:ss | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -71,6 +72,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| @@ -89,7 +95,7 @@ wechat: | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.EnableAspectJAutoProxy; | |||
| import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
| /** | |||
| @@ -18,6 +20,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
| @EnableSwagger2 | |||
| @EnableRocketMQ | |||
| @EnableEncryptableProperties | |||
| @EnableAspectJAutoProxy(exposeProxy = true) | |||
| public class ScheduleApplication { | |||
| @Value("${fm.exception}") | |||
| @@ -25,9 +25,6 @@ public class HomeController { | |||
| @Autowired | |||
| private MqBaseProducer mqBaseProducer; | |||
| @Autowired | |||
| private RabbitMqMessageProducer rabbitMqMessageProducer; | |||
| @ApiOperation("获取后端版本号") | |||
| @GetMapping("/version") | |||
| @@ -13,6 +13,7 @@ import com.iformall.service.WxRefundOrderService; | |||
| import com.iformall.utils.DateUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.aop.framework.AopContext; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.scheduling.annotation.Scheduled; | |||
| import org.springframework.stereotype.Component; | |||
| @@ -51,11 +52,13 @@ public class CouponOrderExpiringSchedule { | |||
| // @Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 | |||
| public void couponOrderExpiringSchedule() { | |||
| CouponOrderExpiringSchedule proxy = (CouponOrderExpiringSchedule) AopContext.currentProxy(); | |||
| List<WxCouponOrder> list = wxCouponOrderMapper.findExpiredFreeCouponOrderByValidDate(); | |||
| list.stream().forEach(co -> { | |||
| // 券过期,更改状态及库存退回 | |||
| try { | |||
| couponOrderExpire(co, true); | |||
| proxy.couponOrderExpire(co, true); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| @@ -64,31 +67,25 @@ public class CouponOrderExpiringSchedule { | |||
| } | |||
| @Scheduled(cron = "0 5 0 * * ?") // 每天凌晨00:05 | |||
| @Scheduled(cron = "0 0/2 * * * ?") // 每天凌晨00:05 | |||
| // @Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 | |||
| public void couponOrderRefundSchedule() { | |||
| List<WxCouponOrder> list = wxCouponOrderMapper.findExpiredCouponOrderByValidDate(); | |||
| CouponOrderExpiringSchedule proxy = (CouponOrderExpiringSchedule) AopContext.currentProxy(); | |||
| list.stream().forEach(co -> { | |||
| // 券过期,更改状态及库存退回 | |||
| try { | |||
| couponOrderExpire(co, false); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| // 退款 | |||
| try { | |||
| couponOrderExpireRefund(co, true); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| refund(co,proxy); | |||
| }); | |||
| } | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void refund(WxCouponOrder order,CouponOrderExpiringSchedule proxy) { | |||
| // 券过期,更改状态及库存退回 | |||
| proxy.couponOrderExpire(order, false); | |||
| // 退款 | |||
| proxy.couponOrderExpireRefund(order, true); | |||
| } | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void couponOrderExpire(WxCouponOrder co, boolean bStockBack) { | |||
| @@ -112,13 +109,14 @@ public class CouponOrderExpiringSchedule { | |||
| } | |||
| } | |||
| private void couponOrderExpireRefund(WxCouponOrder co, boolean bStockBack) { | |||
| public void couponOrderExpireRefund(WxCouponOrder co, boolean bStockBack) { | |||
| // 非储值卡, 可以退款 | |||
| if(!co.getCouponType().equals(EnumCouponType.CARD_MULTIMCH.getCode()) | |||
| && !co.getAutoRefund().equals(EnumCouponAutoRefund.UNSUPPORTED.getCode())) { | |||
| WxAppinfo appinfo = new WxAppinfo(); | |||
| appinfo.updateTenantInfo(co); | |||
| appinfo.setType(EnumAppType.B.getCode()); | |||
| //appinfo.setType(EnumAppType.B.getCode()); | |||
| appinfo.setType(EnumAppType.C.getCode()); | |||
| appinfo = wxAppinfoMapper.findList(appinfo).get(0); | |||
| Date limitDate = DateUtils.getTimeAfterDays(360, co.getCreateDate()); | |||
| @@ -1,33 +1,45 @@ | |||
| package com.iformall.schedule; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.aop.framework.AopContext; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.scheduling.annotation.Scheduled; | |||
| import org.springframework.stereotype.Component; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxCUser; | |||
| import com.iformall.domain.po.WxOrder; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.WxPayOrder; | |||
| import com.iformall.enums.EnumAppType; | |||
| import com.iformall.enums.EnumOrderStatus; | |||
| import com.iformall.enums.EnumOrderType; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.enums.EnumRefundStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.WxAppinfoMapper; | |||
| import com.iformall.mapper.WxCUserMapper; | |||
| import com.iformall.mapper.WxCouponMapper; | |||
| import com.iformall.mapper.WxOrderGroupMapper; | |||
| import com.iformall.mapper.WxOrderMapper; | |||
| import com.iformall.mapper.WxPayAccountMapper; | |||
| import com.iformall.mapper.WxPayOrderMapper; | |||
| import com.iformall.service.WxAppinfoService; | |||
| import com.iformall.service.WxOrderService; | |||
| import com.iformall.service.WxPayOrderService; | |||
| import com.iformall.service.WxRefundOrderService; | |||
| import com.iformall.service.helper.WxPayOrderServiceHelper; | |||
| import com.iformall.utils.DateUtils; | |||
| 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 org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @Component | |||
| public class OrderExpiringSchedule { | |||
| @@ -53,8 +65,23 @@ public class OrderExpiringSchedule { | |||
| @Autowired | |||
| WxCouponMapper wxCouponMapper; | |||
| @Scheduled(cron = "0 */5 * * * *?") // 每5分钟检查一次 | |||
| @Autowired | |||
| WxPayOrderMapper wxPayOrderMapper; | |||
| @Autowired | |||
| WxCUserMapper wxCUserMapper; | |||
| @Autowired | |||
| WxAppinfoService wxAppinfoService; | |||
| @Autowired | |||
| WxPayAccountMapper wxPayAccountMapper; | |||
| @Autowired | |||
| WxPayOrderService wxPayOrderService; | |||
| @Scheduled(cron = "0 */2 * * * *?") // 每5分钟检查一次 | |||
| //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 | |||
| public void orderExpireSchedule() { | |||
| @@ -62,13 +89,16 @@ public class OrderExpiringSchedule { | |||
| Date curDate = new Date(); | |||
| Date expireDate = new Date(curDate.getTime() - NORMAL_TIME_OUT ); | |||
| //直接调用不会触发事务,spring事务基于AOP代理 | |||
| OrderExpiringSchedule proxy = (OrderExpiringSchedule) AopContext.currentProxy(); | |||
| // 券相关订单, 15分钟未支付, 订单过期 | |||
| dateMap.put("type", EnumOrderType.COUPON.getCode()); | |||
| dateMap.put("endDate", expireDate); | |||
| List<WxOrder> orderCoupons = wxOrderMapper.findListOfUnpaidOrderByDate(dateMap); | |||
| orderCoupons.stream().forEach( o -> { | |||
| try { | |||
| orderExpired(o); | |||
| proxy.orderExpired(o,true); | |||
| } catch (Exception e) { | |||
| logger.error("券过期失败" + e.getMessage()); | |||
| } | |||
| @@ -82,7 +112,7 @@ public class OrderExpiringSchedule { | |||
| List<WxOrder> orderPresss = wxOrderMapper.findListOfCompleteUnPaidPressOrderByDate(dateMap); | |||
| orderPresss.stream().forEach( o -> { | |||
| try { | |||
| orderPressExpired(o, true); | |||
| proxy.orderPressExpired(o, true,true); | |||
| } catch (Exception e) { | |||
| logger.error("砍价券支付过期失败" + e.getMessage()); | |||
| } | |||
| @@ -93,7 +123,7 @@ public class OrderExpiringSchedule { | |||
| orderPresss = wxOrderMapper.findListOfUnpaidPressOrderByDate(dateMap); | |||
| orderPresss.stream().forEach( o -> { | |||
| try { | |||
| orderPressExpired(o, false); | |||
| proxy.orderPressExpired(o, false,true); | |||
| } catch (Exception e) { | |||
| logger.error("砍价券过期失败" +e.getMessage()); | |||
| } | |||
| @@ -105,7 +135,7 @@ public class OrderExpiringSchedule { | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { | |||
| try { | |||
| orderGroupExpired((WxOrder) o); | |||
| proxy.orderGroupExpired((WxOrder) o,true); | |||
| } catch (Exception e) { | |||
| logger.error("拼团取消失败" + e.getMessage()); | |||
| } | |||
| @@ -117,7 +147,7 @@ public class OrderExpiringSchedule { | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_OVERTIME.getCode()); | |||
| wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { | |||
| try { | |||
| returnMoney((WxOrder) o); | |||
| proxy.expiredAndReturnMoney((WxOrder) o,false); | |||
| } catch (Exception e) { | |||
| logger.error("拼团过期退款失败" + e.getMessage()); | |||
| } | |||
| @@ -128,7 +158,7 @@ public class OrderExpiringSchedule { | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_CANCEL.getCode()); | |||
| wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { | |||
| try { | |||
| returnMoney((WxOrder) o); | |||
| proxy.returnMoney((WxOrder) o); | |||
| } catch (Exception e) { | |||
| logger.error("拼团券下架退款失败" + e.getMessage()); | |||
| } | |||
| @@ -138,18 +168,75 @@ public class OrderExpiringSchedule { | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); | |||
| wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { | |||
| try { | |||
| returnMoney((WxOrder) o); | |||
| proxy.expiredAndReturnMoney((WxOrder) o,true); | |||
| } catch (Exception e) { | |||
| logger.error("参团失败退款失败" + e.getMessage()); | |||
| } | |||
| }); | |||
| //无需查询付款状态的订单-退款,回滚库存 | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_SCHEDU_REFUND.getCode()); | |||
| wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { | |||
| try { | |||
| proxy.expiredAndReturnMoney((WxOrder) o,false); | |||
| } catch (Exception e) { | |||
| logger.error("参团失败退款失败" + e.getMessage()); | |||
| } | |||
| }); | |||
| } | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void orderExpired(WxOrder order) { | |||
| public void expiredAndReturnMoney(WxOrder wxOrder,boolean checkRealPay) { | |||
| orderGroupExpired(wxOrder,checkRealPay); | |||
| returnMoney(wxOrder); | |||
| } | |||
| public boolean wxPaySuccess(WxOrder order) { | |||
| WxPayOrder payOrderq = new WxPayOrder(); | |||
| payOrderq.setOrderId(order.getId()); | |||
| List<WxPayOrder> payorderlist = wxPayOrderMapper.findList(payOrderq); | |||
| if (null == payorderlist || payorderlist.size() <=0 ) { | |||
| return false; | |||
| } | |||
| WxPayOrder wxpayOrder = payorderlist.get(0); | |||
| if (null == wxpayOrder) { | |||
| return false; | |||
| } | |||
| WxCUser user = wxCUserMapper.selectById(wxpayOrder.getCUserId()); | |||
| //找不到用户,问题单,不能删 | |||
| if (null == user) { | |||
| return true; | |||
| } | |||
| WxAppinfo appInfo = wxAppinfoService.getByAppId(user.getAppId()); | |||
| //找不到appInfo,问题单,不能删 | |||
| if(appInfo == null) { | |||
| return true; | |||
| } | |||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | |||
| //找不到appInfo,问题单,不能删 | |||
| if (null == payAccount) { | |||
| return true; | |||
| } | |||
| Map<String, String> retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(wxpayOrder, order, appInfo, payAccount); | |||
| int status = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, wxpayOrder.getPayOrderNo()); | |||
| //如果是支付成功,则更新信息 | |||
| if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() == status) { | |||
| wxPayOrderService.handleSuccessOrder(wxpayOrder, order, retMap,true); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void orderExpired(WxOrder order,boolean checkRealPay) { | |||
| if (checkRealPay) { | |||
| if (wxPaySuccess(order)) { | |||
| return; | |||
| } | |||
| } | |||
| // 库存退回 | |||
| wxOrderService.stockBack(order); | |||
| @@ -167,7 +254,13 @@ public class OrderExpiringSchedule { | |||
| } | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void orderPressExpired(WxOrder order, boolean payExpired) { | |||
| public void orderPressExpired(WxOrder order, boolean payExpired,boolean checkRealPay) { | |||
| if (checkRealPay) { | |||
| if (wxPaySuccess(order)) { | |||
| return; | |||
| } | |||
| } | |||
| Date curDate = new Date(); | |||
| WxOrder updateOrder = new WxOrder(); | |||
| updateOrder.setId(order.getId()); | |||
| @@ -187,8 +280,14 @@ public class OrderExpiringSchedule { | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void orderGroupExpired(WxOrder order) { | |||
| Date curDate = new Date(); | |||
| public void orderGroupExpired(WxOrder order,boolean checkRealPay) { | |||
| if (checkRealPay) { | |||
| if (wxPaySuccess(order)) { | |||
| return; | |||
| } | |||
| } | |||
| Date curDate = new Date(); | |||
| WxOrder updateOrder = new WxOrder(); | |||
| updateOrder.setId(order.getId()); | |||
| updateOrder.updateTenantInfo(order); | |||
| @@ -205,7 +304,10 @@ public class OrderExpiringSchedule { | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void returnMoney(WxOrder order) { | |||
| //支付成功的才退款 | |||
| if (!wxPaySuccess(order)) { | |||
| return; | |||
| } | |||
| //获取APP信息 | |||
| WxAppinfo appinfo = new WxAppinfo(); | |||
| appinfo.updateTenantInfo(order); | |||
| @@ -1,9 +1,10 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| include: aliyunRocketMQ | |||
| #include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| url: jdbc:mysql://zc349w82qvn56ftl5e64-rw4rm.rwlb.rds.aliyuncs.com:3306/mallink?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&useAffectedRows=true | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(IKH7HxMZwIqMttMc9+QsqWa1KMsJvTs4) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| @@ -27,7 +28,7 @@ spring: | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -71,6 +72,11 @@ spring: | |||
| publisher-confirms: true | |||
| publisher-returns: false | |||
| virtual-host: / | |||
| aliyunRocketmq: | |||
| accessKeyId: "LTAI4G7ixY4AhvM35F8o3W3V" | |||
| accessKeySecret: "VfWqGb83qIQrS9us45utskl8itd7ry" | |||
| groupId: "GID_P_1" | |||
| namesrvAddr: "http://MQ_INST_1796289517488555_Bcqaq2is.cn-beijing.mq-internal.aliyuncs.com:8080" | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| @@ -85,7 +91,7 @@ wechat: | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| host: 101.201.103.81 | |||
| port: 6379 | |||
| password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) | |||
| timeout: 3600 | |||
| @@ -21,22 +21,22 @@ spring: | |||
| cache-names: redis_cache #缓存的名字(可以不指定) | |||
| redis: | |||
| time-to-live: 60000ms #很重要,缓存的有效时间,以便缓存的过期(单位为毫秒) | |||
| rocketmq: | |||
| nameServer: 127.0.0.1:9876 | |||
| producer: | |||
| retry-times-when-send-async-failed: 0 | |||
| send-msg-timeout: 300000 | |||
| compress-msg-body-over-howmuch: 4096 | |||
| max-message-size: 4194304 | |||
| retry-another-broker-when-not-store-ok: false | |||
| retry-times-when-send-failed: 2 | |||
| rabbitmq: | |||
| host: 127.0.0.1 | |||
| port: 5672 | |||
| username: guest | |||
| password: guest | |||
| publisher-confirms: true | |||
| virtual-host: / | |||
| # rocketmq: | |||
| # nameServer: 127.0.0.1:9876 | |||
| # producer: | |||
| # retry-times-when-send-async-failed: 0 | |||
| # send-msg-timeout: 300000 | |||
| # compress-msg-body-over-howmuch: 4096 | |||
| # max-message-size: 4194304 | |||
| # retry-another-broker-when-not-store-ok: false | |||
| # retry-times-when-send-failed: 2 | |||
| # rabbitmq: | |||
| # host: 127.0.0.1 | |||
| # port: 5672 | |||
| # username: guest | |||
| # password: guest | |||
| # publisher-confirms: true | |||
| # virtual-host: / | |||
| # MybatisPlus | |||
| @@ -25,6 +25,13 @@ | |||
| <artifactId>dozer</artifactId> | |||
| <version>5.5.1</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.aliyun.openservices</groupId> | |||
| <artifactId>ons-client</artifactId> | |||
| <version>1.8.4.Final</version> | |||
| </dependency> | |||
| </dependencies> | |||
| </project> | |||
| @@ -76,7 +76,7 @@ public class IdWorker { | |||
| } | |||
| private IdWorker() { | |||
| String ipAddr = ""; | |||
| String ipAddr = "192.168.1.1"; | |||
| try { | |||
| ipAddr = IPUtil.getLocalHostLANAddress().getHostAddress(); | |||
| } catch (UnknownHostException e) { | |||
| @@ -121,7 +121,6 @@ public class IdWorker { | |||
| */ | |||
| public synchronized long nextId() { | |||
| long timestamp = timeGen(); | |||
| //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 | |||
| if (timestamp < lastTimestamp) { | |||
| throw new RuntimeException( | |||
| @@ -141,7 +140,6 @@ public class IdWorker { | |||
| else { | |||
| sequence = 0L; | |||
| } | |||
| //上次生成ID的时间截 | |||
| lastTimestamp = timestamp; | |||
| @@ -16,6 +16,8 @@ import java.util.Date; | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class WxCardInfo extends TenantEntity { | |||
| private static final long serialVersionUID = 2974374593127477999L; | |||
| @Excel(name = "卡号", width = 20, orderNum = "1") | |||
| @io.swagger.annotations.ApiModelProperty(value="主键ID-与coupon_order_id一致",name="id") | |||
| protected Long id; | |||
| @@ -58,5 +60,11 @@ public class WxCardInfo extends TenantEntity { | |||
| @io.swagger.annotations.ApiModelProperty(value = "是否支持转送(0:不支持,1支持)", name = "supportTransfer") | |||
| private Integer supportTransfer; | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value="查询-开始时间",name="startdate") | |||
| protected Date startdate; | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value="查询-结束时间",name="enddate") | |||
| protected Date enddate; | |||
| } | |||
| @@ -1,6 +1,8 @@ | |||
| package com.iformall.domain.po; | |||
| import com.baomidou.mybatisplus.annotation.IdType; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.baomidou.mybatisplus.annotation.TableId; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import com.iformall.domain.po.base.BaseEntity; | |||
| @@ -17,6 +19,7 @@ import java.util.List; | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class WxMall extends BaseEntity { | |||
| @TableId(type= IdType.AUTO) | |||
| protected Long id; | |||
| @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId") | |||
| @@ -24,6 +24,8 @@ public class WxMallBuilding extends TenantEntity { | |||
| private Long mallId; | |||
| @io.swagger.annotations.ApiModelProperty(value="楼座名",name="name") | |||
| private String name; | |||
| @io.swagger.annotations.ApiModelProperty(value="楼座名",name="buildingName") | |||
| private String buildingName; | |||
| @io.swagger.annotations.ApiModelProperty(value="楼层数",name="floorNumber") | |||
| private Integer floorNumber; | |||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createDate") | |||
| @@ -0,0 +1,113 @@ | |||
| package com.iformall.domain.po; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import com.iformall.domain.po.base.BaseEntity; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.math.BigDecimal; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| @TableName(value = "wx_project_config") | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class WxProjectConfig extends BaseEntity { | |||
| protected Long id; | |||
| @io.swagger.annotations.ApiModelProperty(value="商场名",name="name") | |||
| private String name; | |||
| @io.swagger.annotations.ApiModelProperty(value="国家",name="country") | |||
| private String country; | |||
| @io.swagger.annotations.ApiModelProperty(value="省",name="province") | |||
| private String province; | |||
| @io.swagger.annotations.ApiModelProperty(value="城市",name="city") | |||
| private String city; | |||
| @io.swagger.annotations.ApiModelProperty(value="地址",name="addr") | |||
| private String addr; | |||
| @io.swagger.annotations.ApiModelProperty(value="总面积",name="totalArea") | |||
| private BigDecimal totalArea; | |||
| @io.swagger.annotations.ApiModelProperty(value="营业面积",name="operatingArea") | |||
| private BigDecimal operatingArea; | |||
| @io.swagger.annotations.ApiModelProperty(value="停车场面积",name="parkArea") | |||
| private BigDecimal parkArea; | |||
| @io.swagger.annotations.ApiModelProperty(value="车位数",name="parkPlaceNumber") | |||
| private Integer parkPlaceNumber; | |||
| @io.swagger.annotations.ApiModelProperty(value="电话",name="servicePhone") | |||
| private String servicePhone; | |||
| @io.swagger.annotations.ApiModelProperty(value="商场图标",name="imgUrl") | |||
| private String imgUrl; | |||
| @io.swagger.annotations.ApiModelProperty(value="商场图标-H",name="imgUrlH") | |||
| private String imgUrlH; | |||
| //1(全能版)、2(营销版,除了合同,账单功能),3.速享版(营销版加3个月限制) | |||
| @io.swagger.annotations.ApiModelProperty(value="",name="saleType") | |||
| private Integer saleType; | |||
| @io.swagger.annotations.ApiModelProperty(value="商场楼座",name="mallBuilding") | |||
| private String mallBuilding; | |||
| @io.swagger.annotations.ApiModelProperty(value="微信商户号/特约服务商号",name="mchId") | |||
| private String mchId; | |||
| @io.swagger.annotations.ApiModelProperty(value="微信服务商号",name="subMchId") | |||
| private String subMchId; | |||
| @io.swagger.annotations.ApiModelProperty(value="支付密钥",name="apiKey") | |||
| private String apiKey; | |||
| // @io.swagger.annotations.ApiModelProperty(value="微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)",name="notifyUrl") | |||
| // private String notifyUrl; | |||
| // @io.swagger.annotations.ApiModelProperty(value="证书本地存放位置",name="certPath") | |||
| // private String certPath; | |||
| @io.swagger.annotations.ApiModelProperty(value="手续费(万分之几,默认60)",name="rate") | |||
| private Integer rate; | |||
| @io.swagger.annotations.ApiModelProperty(value="实际手续费(万分之几,默认60)",name="realRate") | |||
| private Integer realRate; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序ID(B端)",name="appIdB") | |||
| private String appIdB; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序ID(C端)",name="appIdC") | |||
| private String appIdC; | |||
| @io.swagger.annotations.ApiModelProperty(value="公众号ID",name="parentAppId") | |||
| private String parentAppId; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序名(B端)",name="appNameB") | |||
| private String appNameB; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序名(C端)",name="appNameC") | |||
| private String appNameC; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序secret(B端)",name="appSecretB") | |||
| private String appSecretB; | |||
| @io.swagger.annotations.ApiModelProperty(value="小程序secret(C端)",name="appSecretC") | |||
| private String appSecretC; | |||
| @io.swagger.annotations.ApiModelProperty(value="授权方头像(B端)",name="headImgB") | |||
| private String headImgB; | |||
| @io.swagger.annotations.ApiModelProperty(value="授权方头像(C端)",name="headImgC") | |||
| private String headImgC; | |||
| @io.swagger.annotations.ApiModelProperty(value="二维码图片的URL(B端)",name="qrcodeUrlB") | |||
| private String qrcodeUrlB; | |||
| @io.swagger.annotations.ApiModelProperty(value="二维码图片的URL(C端)",name="qrcodeUrlC") | |||
| private String qrcodeUrlC; | |||
| @io.swagger.annotations.ApiModelProperty(value="微信开放平台appid",name="openAppid") | |||
| private String openAppid; | |||
| @io.swagger.annotations.ApiModelProperty(value="B端当前版本号",name="currentVersionB") | |||
| private String currentVersionB; | |||
| @io.swagger.annotations.ApiModelProperty(value="C端当前版本号",name="currentVersionC") | |||
| private String currentVersionC; | |||
| @io.swagger.annotations.ApiModelProperty(value="A端管理员帐号",name="usernameA") | |||
| private String usernameA; | |||
| @io.swagger.annotations.ApiModelProperty(value="A端管理员密码",name="password") | |||
| private String password; | |||
| @io.swagger.annotations.ApiModelProperty(value="A端管理员名称",name="nameA") | |||
| private String nameA; | |||
| @io.swagger.annotations.ApiModelProperty(value="联系电话",name="phone") | |||
| private String phone; | |||
| @io.swagger.annotations.ApiModelProperty(value="销售类型",name="delType") | |||
| private Integer delType; | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| package com.iformall.domain.po.msg; | |||
| import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import lombok.ToString; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| /** | |||
| * 更新券库存消息 | |||
| * @author Stormeye | |||
| * @date 2019/4/9 13:55 | |||
| */ | |||
| @Data | |||
| @ToString(callSuper = true) | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class UpdateCouponStockMsg extends BaseMsg { | |||
| private static final long serialVersionUID = 223232132183760321L; | |||
| public static final String OPERATE_TYPE_INCREASE = "increase"; | |||
| public static final String OPERATE_TYPE_DECREASE = "decrease"; | |||
| @io.swagger.annotations.ApiModelProperty(value="券Id",name="couponId") | |||
| private Long couponId; | |||
| @io.swagger.annotations.ApiModelProperty(value="更新数量",name="number") | |||
| private long number; | |||
| @io.swagger.annotations.ApiModelProperty(value="操作类型 1-增加库存 ,2-减少库存",name="operateType") | |||
| private String operateType; | |||
| } | |||
| @@ -104,12 +104,4 @@ public class WxCardVo extends WxCardInfo { | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value="卡状态",name="statusStr") | |||
| protected String statusStr; | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value="查询-开始时间",name="startdate") | |||
| private Date startdate; | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value="查询-结束时间",name="enddate") | |||
| private Date enddate; | |||
| } | |||
| @@ -9,7 +9,7 @@ import java.util.Map; | |||
| public enum EnumCacheKey { | |||
| C_INDEX_PAGE_LIST(0, "couponChannelList_"), | |||
| COUPON_STOCK(1,"couponStock_") | |||
| ; | |||
| private static Map<Integer,EnumCacheKey> map = new HashMap<Integer,EnumCacheKey>(); | |||
| static { | |||
| @@ -4,7 +4,8 @@ package com.iformall.enums; | |||
| * Created by luozukai | |||
| */ | |||
| public enum EnumMsgMqTopic { | |||
| DEFAULT("topic-1", "默认"), | |||
| DEFAULT("topic-1","GID_P_1", "默认"), | |||
| STOCK("stock","GID_P_2","库存"), | |||
| ; | |||
| public static EnumMsgMqTopic getEnum(String code) { | |||
| @@ -18,10 +19,12 @@ public enum EnumMsgMqTopic { | |||
| private String code; | |||
| private String message; | |||
| private String groupId; | |||
| EnumMsgMqTopic(String code, String message) { | |||
| EnumMsgMqTopic(String code, String groupId,String message) { | |||
| this.code = code; | |||
| this.message = message; | |||
| this.groupId = groupId; | |||
| } | |||
| public String getCode() { | |||
| @@ -31,4 +34,12 @@ public enum EnumMsgMqTopic { | |||
| public String getMessage() { | |||
| return message; | |||
| } | |||
| public String getGroupId() { | |||
| return groupId; | |||
| } | |||
| public void setGroupId(String groupId) { | |||
| this.groupId = groupId; | |||
| } | |||
| } | |||
| @@ -17,6 +17,7 @@ public enum EnumMsgRecordType { | |||
| INSIDE_C_LOGIN(102, "C端用户登录"), | |||
| INSIDE_NOTIFY_PAY_SUCCESS(103, "微信支付回调"), | |||
| INSIDE_NOTIFY_REFUND_SUCCESS(104, "微信退款回调"), | |||
| COUPON_STOCK(105, "券库存更新"), | |||
| ; | |||
| public static EnumMsgRecordType getEnum(Integer code) { | |||
| @@ -23,9 +23,9 @@ public enum EnumOrderStatus { | |||
| ORDER_STATUS_COOPERATING_CANCEL(13, "拼团失败"), | |||
| ORDER_STATUS_COOPERATING_FAILD(14, "参团失败"), | |||
| ORDER_STATUS_COOPERATING_UNPAID(15, "拼团待付款"),//占库存 | |||
| ORDER_STATUS_COOPERATING_BREAK(16, "拼团取消") | |||
| ORDER_STATUS_COOPERATING_BREAK(16, "拼团取消"), | |||
| ORDER_STATUS_COOPERATING_SCHEDU_REFUND(99,"订单定时状态-需要返款和回滚库存,无需再次查询真实支付状态") | |||
| ; | |||
| public static EnumOrderStatus getEnum(Integer code) { | |||
| for (EnumOrderStatus value : values()) { | |||
| if (value.getCode().equals(code)) { | |||
| @@ -11,5 +11,7 @@ public interface WxCardInfoMapper extends CommonMapper<WxCardInfo, Long> { | |||
| List<WxCardVo> findVoList(WxCardVo wxCardVo); | |||
| void updateTransferStatusByCouponId(Long couponId); | |||
| List<WxCardInfo> findList(WxCardInfo wxCardInfo); | |||
| } | |||
| @@ -20,7 +20,7 @@ public interface WxCouponMapper extends CommonMapper<WxCoupon, Long> { | |||
| WxCouponCVo findVoDetail(@Param("id")Long id); | |||
| WxCouponCVo findVoStatusDetail(@Param("id")Long id); | |||
| Integer reduceInventory(@Param("id")Long id,@Param("number")Integer number,@Param("remainInventory")Integer remainInventory); | |||
| Integer reduceInventory(@Param("id")Long id,@Param("number")Integer number); | |||
| Integer backInventory(@Param("id")Long id, @Param("number")Integer number,@Param("remainInventory")Integer remainInventory); | |||
| @@ -39,7 +39,10 @@ public interface WxCouponOrderMapper extends CommonMapper<WxCouponOrder, Long> { | |||
| List<WxCouponOrderBVo> findListOfOrderedByDateForBUser(Map dateMap); | |||
| List<WxCouponOrderBVo> findListOfVerifiedByDateForBUser(Map dateMap); | |||
| List<WxCouponOrderCVo> findListOfCUser(WxCouponOrder wxCouponOrder); | |||
| //@Deprecated | |||
| //List<WxCouponOrderCVo> findListOfCUser(WxCouponOrder wxCouponOrder); | |||
| List<WxCouponOrderCVo> findListOfCUserOptimize(WxCouponOrder wxCouponOrder); | |||
| WxCouponOrderCVo findDetailOfCUser(@Param("id")Long id); | |||
| WxCouponOrderCVo findSimpleDetailOfCUser(@Param("id")Long id); | |||
| List<WxCouponOrderBVo> findListOfAdmin(WxCouponOrderBVo wxCouponOrder); | |||
| @@ -8,6 +8,9 @@ import java.util.List; | |||
| * @author luozukai | |||
| */ | |||
| public interface WxFlowConfigMapper extends CommonMapper<WxFlowConfig, Long> { | |||
| void wxFlowConfigInit(String initSql); | |||
| List<WxFlowConfig> findList(WxFlowConfig wxFlowConfig); | |||
| /** | |||
| @@ -6,11 +6,8 @@ import com.iformall.domain.po.WxMsgValidationcodeModel; | |||
| public interface WxMsgValidationcodeModelMapper extends CommonMapper<WxMsgValidationcodeModel, String> { | |||
| List<WxMsgValidationcodeModel> findList(WxMsgValidationcodeModel wxMsgValidationcodeModel); | |||
| void wxMsgValidationcodeModelInit(String initSql); | |||
| List<WxMsgValidationcodeModel> findList(WxMsgValidationcodeModel wxMsgValidationcodeModel); | |||
| } | |||
| @@ -0,0 +1,10 @@ | |||
| package com.iformall.mapper; | |||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| public interface WxProjectConfigMapper extends BaseMapper<WxProjectConfig> { | |||
| } | |||
| @@ -4,5 +4,6 @@ public class MQConfig { | |||
| public static class Impl { | |||
| public static final String RABBIT_MQ = "rabbitMQ"; | |||
| public static final String ROCKET_MQ = "rocketMQ"; | |||
| public static final String ALIYUN_ROCKET_MQ = "aliyunRocketMQ"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,123 @@ | |||
| package com.iformall.mq.impl; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import javax.annotation.PostConstruct; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.context.annotation.Profile; | |||
| import org.springframework.stereotype.Service; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.aliyun.openservices.ons.api.Message; | |||
| import com.aliyun.openservices.ons.api.ONSFactory; | |||
| import com.aliyun.openservices.ons.api.Producer; | |||
| import com.aliyun.openservices.ons.api.PropertyKeyConst; | |||
| import com.aliyun.openservices.ons.api.SendResult; | |||
| import com.iformall.domain.po.msg.BaseMsg; | |||
| import com.iformall.enums.EnumMsgMqTopic; | |||
| import com.iformall.mq.MQConfig; | |||
| import com.iformall.mq.MqBaseProducer; | |||
| import com.iformall.utils.JsonUtil; | |||
| /** | |||
| * @Auther: zfy 阿里云rocketmq | |||
| * @Date: 2019-01-31 | |||
| * @Description: RocketMQ消息生产者 | |||
| */ | |||
| @Service | |||
| @Profile(MQConfig.Impl.ALIYUN_ROCKET_MQ) | |||
| public class AliyunRocketMqMessageProducer implements MqBaseProducer { | |||
| private final Logger log = LoggerFactory.getLogger(this.getClass()); | |||
| @Value("${spring.aliyunRocketmq.accessKeyId}") | |||
| private String accessKeyId; | |||
| @Value("${spring.aliyunRocketmq.accessKeySecret}") | |||
| private String accessKeySecret; | |||
| @Value("${spring.aliyunRocketmq.groupId}") | |||
| private String groupId; | |||
| @Value("${spring.aliyunRocketmq.namesrvAddr}") | |||
| private String namesrvAddr; | |||
| //@Autowired | |||
| //private WxMsgRecordMapper wxMsgRecordMapper; | |||
| //@Autowired | |||
| //private WxMsgRecordService wxMsgRecordService; | |||
| private static Map<String,Producer> producerMap = null; | |||
| @PostConstruct | |||
| public void init() { | |||
| producerMap = new HashMap<String,Producer>(); | |||
| for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { | |||
| Properties properties = new Properties(); | |||
| properties.setProperty(PropertyKeyConst.GROUP_ID, topic.getGroupId()); | |||
| // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||
| properties.put(PropertyKeyConst.AccessKey,accessKeyId); | |||
| // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||
| properties.put(PropertyKeyConst.SecretKey, accessKeySecret); | |||
| //设置发送超时时间,单位毫秒 | |||
| properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000"); | |||
| // 设置 TCP 接入域名,到控制台的实例基本信息中查看 | |||
| properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); | |||
| Producer producer = ONSFactory.createProducer(properties); | |||
| // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 | |||
| producer.start(); | |||
| log.info("aliyunrocketmq producer info :"+JSON.toJSONString(producer)); | |||
| producerMap.put(topic.getCode(), producer); | |||
| } | |||
| } | |||
| @Override | |||
| public void sendMessage(BaseMsg data, String topic, String tags, String keys) { | |||
| Producer producer = producerMap.get(topic); | |||
| if (null == producer) { | |||
| log.error("topic :"+topic+" has no AliyunRocketMqMessageProducer."); | |||
| return; | |||
| } | |||
| if (producer.isClosed()) { | |||
| producer.start(); | |||
| } | |||
| //循环发送消息 | |||
| Message msg = new Message( // | |||
| // Message 所属的 Topic | |||
| topic, | |||
| // Message Tag 可理解为 Gmail 中的标签,对消息进行再归类,方便 Consumer 指定过滤条件在 MQ 服务器过滤 | |||
| tags, | |||
| // Message Body 可以是任何二进制形式的数据, MQ 不做任何干预, | |||
| // 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式 | |||
| JsonUtil.obj2Json(data).getBytes()); | |||
| // 设置代表消息的业务关键属性,请尽可能全局唯一。 | |||
| // 以方便您在无法正常收到消息情况下,可通过阿里云服务器管理控制台查询消息并补发 | |||
| // 注意:不设置也不会影响消息正常收发 | |||
| msg.setKey(keys); | |||
| try { | |||
| SendResult sendResult = producer.send(msg); | |||
| // 同步发送消息,只要不抛异常就是成功 | |||
| if (sendResult != null) { | |||
| System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMessageId()); | |||
| } | |||
| } | |||
| catch (Exception e) { | |||
| // 消息发送失败,需要进行重试处理,可重新发送这条消息或持久化这条数据进行补偿处理 | |||
| System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic()); | |||
| e.printStackTrace(); | |||
| } | |||
| // 在应用退出前,销毁 Producer 对象 | |||
| // 注意:如果不销毁也没有问题 | |||
| //producer.shutdown(); | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.vo.MallUserInfoVo; | |||
| @@ -14,6 +15,15 @@ import java.util.Set; | |||
| public interface MallUserInfoService { | |||
| /** | |||
| * MallUserInfo初始化 | |||
| * 返回id | |||
| * @param tenantId | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| Long MallUserInfoInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| //// -------------------- Login ----------------------- //// | |||
| /** | |||
| * 根据用户名查询用户对象 | |||
| @@ -2,6 +2,7 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| @@ -10,6 +11,17 @@ import java.util.List; | |||
| public interface WxAppinfoService { | |||
| /** | |||
| * WxAppinfo初始化 | |||
| * --- 小程序开通后,填写此数据,并设置域名及业务域名等 | |||
| * @param tenantId | |||
| * @param payId | |||
| * @param payBillId | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| void wxAppinfoInit(String tenantId, Long payId, Long payBillId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -2,12 +2,30 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxAuthorizerInfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.vo.WxWeappInfo; | |||
| import java.util.List; | |||
| public interface WxAuthorizerInfoService { | |||
| /** | |||
| * WxAuthorizerInfo初始化 | |||
| * | |||
| * @param tenantId | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| void wxAuthorizerInfoInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * wx_weapp_ext_set初始化 | |||
| * | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| void wxWeappExtSetInit(WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -109,13 +109,20 @@ public interface WxCouponOrderService { | |||
| ResultData listOnDateAsPage(Long bUserId, String date, Integer pageIndex, Integer pageSize, boolean isVerified); | |||
| /** | |||
| * C用户查券list | |||
| *@deprecated | |||
| * @param record C端用户 | |||
| */ | |||
| //PageInfo<WxCouponOrderCVo> listCUserVoAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize); | |||
| /** | |||
| * C用户查券list | |||
| * | |||
| * @param record C端用户 | |||
| */ | |||
| PageInfo<WxCouponOrderCVo> listCUserVoAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize); | |||
| PageInfo<WxCouponOrderCVo> listCUserVoAsPageOptimize(WxCouponOrder record, Integer pageIndex, Integer pageSize); | |||
| /** | |||
| * C用户查券详情 | |||
| @@ -5,6 +5,13 @@ import com.iformall.domain.po.WxCouponSendConfig; | |||
| public interface WxCouponSendConfigService { | |||
| /** | |||
| * 初始化WxCouponSendConfig | |||
| * @param tenantId | |||
| * @return | |||
| */ | |||
| void wxCouponSendConfigInit(String tenantId); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -214,7 +214,7 @@ public interface WxCouponService { | |||
| * @param number 减少数量 | |||
| * @param remainInventory 当前库存 | |||
| */ | |||
| void reduceRemainInventory(Long id, Integer number, Integer remainInventory); | |||
| void reduceRemainInventory(Long id, Integer number); | |||
| /** | |||
| * 库存退回 | |||
| @@ -16,6 +16,13 @@ import java.util.Map; | |||
| * 流程审批服务 | |||
| */ | |||
| public interface WxFlowService { | |||
| /** | |||
| * wx_flow_config初始化 | |||
| * @param tenantId | |||
| */ | |||
| void wxFlowConfigInit(String tenantId); | |||
| WxFlowModel getModelByType(int flowType,TenantEntity tenantEntity); | |||
| /** | |||
| @@ -9,6 +9,15 @@ import com.iformall.domain.po.WxMallFloor; | |||
| public interface WxMallBuildingService { | |||
| /** | |||
| * WxMallBuilding初始化 | |||
| * | |||
| * @param tenantId | |||
| * @param mallBuildingJSONstr {"A座":"B2层,B1层,1层,2层,3层,4层","B座":"1层,2层,3层"} | |||
| * @return | |||
| */ | |||
| void wxMallBuildingInit(String tenantId,String mallBuildingJSONstr); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -1,6 +1,7 @@ | |||
| package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.WxMall; | |||
| @@ -8,6 +9,15 @@ import java.util.List; | |||
| public interface WxMallService { | |||
| /** | |||
| * 根据WxProjectConfig初始化WxMall | |||
| * 返回TenantId | |||
| * | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| String wxMallInit(WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -62,5 +72,4 @@ public interface WxMallService { | |||
| @Deprecated | |||
| WxMall getByTenantIdExt(String id); | |||
| } | |||
| @@ -2,17 +2,27 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxMsgConfig; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import java.util.List; | |||
| public interface WxMsgConfigService { | |||
| /** | |||
| * WxMsgConfig初始化 | |||
| * | |||
| * @param tenantId | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| void WxMsgConfigInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| * @param record | |||
| * @param offset | |||
| * @param limit | |||
| * @param pageIndex | |||
| * @param pageSize | |||
| * @return | |||
| */ | |||
| PageInfo<WxMsgConfig> listAsPage(WxMsgConfig record, Integer pageIndex, Integer pageSize); | |||
| @@ -3,15 +3,24 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxMsgValidationcodeModel; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| public interface WxMsgValidationcodeModelService { | |||
| /** | |||
| * wx_msg_validationcode_model 初始化 | |||
| * | |||
| * @param tenantId | |||
| * @return | |||
| */ | |||
| void wxMsgValidationcodeModelInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| * @param record | |||
| * @param offset | |||
| * @param limit | |||
| * @param pageIndex | |||
| * @param pageSize | |||
| * @return | |||
| */ | |||
| PageInfo<WxMsgValidationcodeModel> listAsPage(WxMsgValidationcodeModel record, Integer pageIndex, Integer pageSize); | |||
| @@ -15,7 +15,7 @@ import java.util.Map; | |||
| */ | |||
| public interface WxOrderGroupService { | |||
| void createOrderGroup(WxOrder order, WxCoupon wxCoupon); | |||
| void createOrderGroup(WxOrder order, WxCoupon wxCoupon,boolean isScheduleTask); | |||
| ResultData queryRemainOne(WxOrderGroup wxOrderGroup, Long userId); | |||
| @@ -32,5 +32,5 @@ public interface WxOrderGroupService { | |||
| List<WxOrderGroup> findList(WxOrderGroup group); | |||
| PageInfo<WxOrderGroupMarketing> queryOrderGroupMarketingList(WxOrderGroupMarketing marketing, Integer pageNum, Integer pageSize); | |||
| } | |||
| @@ -226,5 +226,10 @@ public interface WxOrderService { | |||
| * H5支付后, 券再注入 | |||
| */ | |||
| Long saveOuterOrderForCoupon(WxCUser user, WxCoupon coupon, Long couponChannelId, String formId, Long couponPasswordId); | |||
| int countGroupOrder(Long groupId,boolean ignoreUnPay); | |||
| int countUserCouponGroupOrder(Long cuserId,Long couponId); | |||
| } | |||
| @@ -2,9 +2,18 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxPark; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| public interface WxParkService { | |||
| /** | |||
| * WxPark初始化 | |||
| * | |||
| * @param tenantId | |||
| * @return | |||
| */ | |||
| void wxParkInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -1,11 +1,21 @@ | |||
| package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| public interface WxPayAccountBillService { | |||
| /** | |||
| * --- 特殊商户号开通后,填写此数据 | |||
| * WxPayAccountBill初始化 | |||
| * 返回id | |||
| * @param wxPayAccount | |||
| * @return | |||
| */ | |||
| Long wxPayAccountInit(WxPayAccount wxPayAccount); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -2,9 +2,20 @@ package com.iformall.service; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| public interface WxPayAccountService { | |||
| /** | |||
| * --- 特殊商户号开通后,填写此数据 | |||
| * WxPayAccount初始化 | |||
| * | |||
| * @param tenantId | |||
| * @param wxProjectConfig | |||
| * @return | |||
| */ | |||
| WxPayAccount wxPayAccountInit(String tenantId, WxProjectConfig wxProjectConfig); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -3,15 +3,23 @@ package com.iformall.service; | |||
| import java.util.*; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxCUser; | |||
| import com.iformall.domain.po.WxCoupon; | |||
| 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.enums.EnumPayWay; | |||
| public interface WxPayOrderService { | |||
| public void handleSuccessOrder(WxPayOrder oldRecord,WxOrder order,Map<String, String> retMap,boolean isScheduleTask); | |||
| public WxPayOrder handleWxOrderQuery(WxPayOrder oldRecord,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount,IdWorker idworker,boolean repeatPay); | |||
| /** | |||
| * 创建支付订单 | |||
| * | |||
| @@ -137,6 +145,8 @@ public interface WxPayOrderService { | |||
| * @param id | |||
| */ | |||
| void deleteById(Long id); | |||
| public boolean isOrderGroupCoupon(WxPayOrder record, WxCoupon wxCoupon); | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| package com.iformall.service; | |||
| public interface WxProjectConfigService { | |||
| /** | |||
| * 根据wx_project_config数据生成初始化商户数据 | |||
| * | |||
| * @param id | |||
| */ | |||
| void initProjectConfig(Long id); | |||
| } | |||
| @@ -9,12 +9,21 @@ import java.util.List; | |||
| public interface WxQuestionService { | |||
| /** | |||
| * wx_question 初始化 | |||
| * | |||
| * @param tenantId | |||
| * @param questionJson | |||
| * @return | |||
| */ | |||
| void wxQuestionInit(String tenantId, String questionJson); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| * @param record | |||
| * @param offset | |||
| * @param limit | |||
| * @param pageIndex | |||
| * @param pageSize | |||
| * @return | |||
| */ | |||
| PageInfo<WxQuestion> listAsPage(WxQuestion record, Integer pageIndex, Integer pageSize); | |||
| @@ -9,6 +9,13 @@ import java.util.List; | |||
| public interface WxScoreRulesService { | |||
| /** | |||
| * 积分成长值设置wx_score_rules 初始化 | |||
| * @param tenantId | |||
| * @return | |||
| */ | |||
| void wxScoreRulesInit(String tenantId); | |||
| /** | |||
| * 获取租户的ScoreRules | |||
| * @param tenantEntity | |||
| @@ -5,6 +5,14 @@ import com.iformall.domain.po.WxTemplateMsg; | |||
| public interface WxTemplateMsgService { | |||
| /** | |||
| * wx_template_msg 初始化 | |||
| * 设置核销成功通知,核销失败通知 | |||
| * @param tenantId | |||
| * @return | |||
| */ | |||
| void wxTemplateMsgInit(String tenantId); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -0,0 +1,160 @@ | |||
| package com.iformall.service.helper; | |||
| import java.util.Date; | |||
| import java.util.Map; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| 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.enums.EnumOrderStatus; | |||
| import com.iformall.enums.EnumPayEndFrom; | |||
| import com.iformall.enums.EnumPayMode; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.pay.WxPay; | |||
| import com.iformall.pay.WxPayOrderQ; | |||
| import com.iformall.pay.WxPayOrderSQ; | |||
| import com.iformall.pay.WxPayment; | |||
| import com.iformall.utils.BeanUtils; | |||
| import com.iformall.utils.Utility; | |||
| public class WxPayOrderServiceHelper { | |||
| private static final Logger logger = LoggerFactory.getLogger(WxPayOrderServiceHelper.class); | |||
| /** | |||
| * 微信订单是否可以支付 | |||
| */ | |||
| public static Map<String, String> wxOrderPayStatusMap(WxPayOrder record,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount) { | |||
| if (record == null) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "wxPayOrder is null."); | |||
| } | |||
| if (StringUtils.isBlank(record.getPayOrderNo())) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "payOrderNo not found"); | |||
| } | |||
| if (order == null) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "Order not found"); | |||
| } | |||
| String response = wechatPayOrderQuery(appInfo, record,payAccount); | |||
| logger.info("pay order query, " + record.toString() + ", response: " + response); | |||
| try { | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| return returnMap; | |||
| }catch(Exception e) { | |||
| logger.error("wx payQuery xmlToMap error:response:["+response+"]",e); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "wx payQuery xmlToMap error"); | |||
| } | |||
| } | |||
| public static int getPayStatusFromMap(Map<String, String> returnMap,String payOrderNo) { | |||
| String return_code = returnMap.get("return_code"); | |||
| if ("SUCCESS".equalsIgnoreCase(return_code)) { | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String trade_state = returnMap.get("trade_state"); | |||
| //SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销(刷卡支付),USERPAYING--用户支付中,PAYERROR--支付失败(其他原因,如银行返回失败) | |||
| if ("SUCCESS".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_SUCCESS.getCode(); | |||
| }else if ("REFUND".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_REFUND.getCode(); | |||
| }else if ("NOTPAY".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_NOTPAY.getCode(); | |||
| }else if ("CLOSED".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_CLOSE.getCode(); | |||
| }else if ("REVOKED".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_REVERSE.getCode(); | |||
| }else if ("USERPAYING".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_WAIT.getCode(); | |||
| }else if ("PAYERROR".equals(trade_state)) { | |||
| return EnumPayStatus.PAY_STATUS_FAIL.getCode(); | |||
| } | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态非法["+trade_state+"]"+payOrderNo); | |||
| }else { | |||
| String errCode = returnMap.get("err_code"); | |||
| String errCodeDes = returnMap.get("err_code_des"); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态失败["+errCode+":"+errCodeDes+"]"+payOrderNo); | |||
| } | |||
| } else { | |||
| String return_msg = returnMap.get("return_msg"); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态失败"+return_msg); | |||
| } | |||
| } | |||
| public static int wxOrderPayStatus(WxPayOrder record,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount) { | |||
| Map<String, String> returnMap = wxOrderPayStatusMap(record,order,appInfo,payAccount); | |||
| return getPayStatusFromMap(returnMap,record.getPayOrderNo()); | |||
| } | |||
| public static String wechatPayOrderQuery(WxAppinfo appInfo, WxPayOrder record ,WxPayAccount payAccount) { | |||
| if (payAccount == null) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "WxPayAccount not found"); | |||
| } | |||
| // get payAccount | |||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||
| // 普通商户号模式 | |||
| WxPayOrderQ payOrderQ = new WxPayOrderQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payOrderQ.setAppid(appInfo.getAppId()); | |||
| payOrderQ.setMch_id(payAccount.getMchId()); | |||
| payOrderQ.setNonce_str(noncestr); | |||
| if (StringUtils.isNotBlank(record.getTransactionId())) { | |||
| payOrderQ.setTransaction_id(record.getTransactionId()); | |||
| } else { | |||
| payOrderQ.setOut_trade_no(record.getPayOrderNo()); | |||
| } | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payOrderQ); | |||
| payOrderQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payOrderQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } else { | |||
| // 服务商模式 | |||
| WxPayOrderSQ payOrderSQ = new WxPayOrderSQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payOrderSQ.setAppid(appInfo.getParentAppId()); | |||
| payOrderSQ.setSub_appid(appInfo.getAppId()); | |||
| payOrderSQ.setMch_id(payAccount.getMchId()); | |||
| payOrderSQ.setSub_mch_id(payAccount.getSubMchId()); | |||
| payOrderSQ.setNonce_str(noncestr); | |||
| if (StringUtils.isNotBlank(record.getTransactionId())) { | |||
| payOrderSQ.setTransaction_id(record.getTransactionId()); | |||
| } else { | |||
| payOrderSQ.setOut_trade_no(record.getPayOrderNo()); | |||
| } | |||
| payOrderSQ.setSign_type("HMAC-SHA256"); | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payOrderSQ); | |||
| payOrderSQ.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payOrderSQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -8,19 +8,15 @@ 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.MallPermission; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.domain.po.MallUserRole; | |||
| import com.iformall.domain.po.WxMsgValidationcode; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.vo.MallUserInfoVo; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.MallPermissionMapper; | |||
| import com.iformall.mapper.MallUserInfoMapper; | |||
| import com.iformall.mapper.MallUserRoleMapper; | |||
| import com.iformall.mapper.WxMsgValidationcodeMapper; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.service.MallRoleService; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import com.iformall.service.WxMallService; | |||
| import com.iformall.utils.PasswordHelper; | |||
| import org.apache.commons.collections.CollectionUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| @@ -43,9 +39,18 @@ public class MallUserInfoServiceImpl implements MallUserInfoService { | |||
| @Autowired | |||
| MallUserRoleMapper userRoleMapper; | |||
| @Autowired | |||
| MallRoleMapper mallRoleMapper; | |||
| @Autowired | |||
| MallUserRoleMapper mallUserRoleMapper; | |||
| @Autowired | |||
| MallPermissionMapper mallPermissionMapper; | |||
| @Autowired | |||
| MallRolePermissionMapper mallRolePermissionMapper; | |||
| @Autowired | |||
| WxMsgValidationcodeMapper wxMsgValidationcodeMapper; | |||
| @@ -163,6 +168,45 @@ public class MallUserInfoServiceImpl implements MallUserInfoService { | |||
| mallUserInfoMapper.deleteById(id); | |||
| } | |||
| @Override | |||
| public Long MallUserInfoInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| //创建帐号 | |||
| MallUserInfo mallUserInfo = new MallUserInfo(); | |||
| mallUserInfo.setTenantId(tenantId); | |||
| mallUserInfo.setUsername(wxProjectConfig.getUsernameA()); | |||
| mallUserInfo.setName(wxProjectConfig.getName()); | |||
| mallUserInfo.setPassword(wxProjectConfig.getPassword()); | |||
| new PasswordHelper().encryptPassword(mallUserInfo); | |||
| mallUserInfo.setCreateTime(new Date()); | |||
| mallUserInfo.setStatus(1); | |||
| mallUserInfo.setIsAdmin(1); | |||
| mallUserInfo.setPhone(wxProjectConfig.getPhone()); | |||
| mallUserInfoMapper.insert(mallUserInfo); | |||
| //创建角色 | |||
| MallRole mallRole = new MallRole(); | |||
| mallRole.setTenantId(tenantId); | |||
| mallRole.setName("系统管理员"); | |||
| mallRole.setAvailable("0"); | |||
| mallRoleMapper.insert(mallRole); | |||
| //给角色赋权限 | |||
| MallPermission mallPermission=new MallPermission(); | |||
| List<MallPermission> list = mallPermissionMapper.findList(mallPermission); | |||
| for(MallPermission m : list){ | |||
| MallRolePermission mallRolePermission = new MallRolePermission(); | |||
| mallRolePermission.setTenantId(tenantId); | |||
| mallRolePermission.setRoleId(mallRole.getId()); | |||
| mallRolePermission.setPermissionId(m.getId()); | |||
| mallRolePermissionMapper.insert(mallRolePermission); | |||
| } | |||
| //给帐号加角色 | |||
| MallUserRole mallUserRole = new MallUserRole(); | |||
| //mallUserRole.setId(idWorker.nextId()); | |||
| mallUserRole.setUid(mallUserInfo.getId()); | |||
| mallUserRole.setRoleId(mallRole.getId()); | |||
| mallUserRoleMapper.insert(mallUserRole); | |||
| return mallUserInfo.getId(); | |||
| } | |||
| @Override | |||
| public MallUserInfo getByUsername(String username) { | |||
| return mallUserInfoMapper.selectByUserName(username); | |||
| @@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.enums.EnumAppType; | |||
| import com.iformall.mapper.WxAppinfoMapper; | |||
| @@ -41,6 +42,30 @@ public class WxAppinfoServiceImpl implements WxAppinfoService { | |||
| return wxAppinfoMapper.findByAppId(appId); | |||
| } | |||
| @Override | |||
| public void wxAppinfoInit(String tenantId, Long payId, Long payBillId, WxProjectConfig wxProjectConfig) { | |||
| WxAppinfo wxAppinfo = new WxAppinfo(); | |||
| wxAppinfo.setTenantId(tenantId); | |||
| wxAppinfo.setType(1); | |||
| wxAppinfo.setAppId(wxProjectConfig.getAppIdB()); | |||
| wxAppinfo.setParentAppId(wxProjectConfig.getParentAppId()); | |||
| wxAppinfo.setName(wxProjectConfig.getAppNameB()); | |||
| wxAppinfo.setSecret(wxProjectConfig.getAppSecretB()); | |||
| wxAppinfo.setPayId(payId); | |||
| wxAppinfo.setPayBillId(payBillId); | |||
| wxAppinfoMapper.insert(wxAppinfo); | |||
| wxAppinfo = new WxAppinfo(); | |||
| wxAppinfo.setTenantId(tenantId); | |||
| wxAppinfo.setType(2); | |||
| wxAppinfo.setAppId(wxProjectConfig.getAppIdC()); | |||
| wxAppinfo.setParentAppId(wxProjectConfig.getParentAppId()); | |||
| wxAppinfo.setName(wxProjectConfig.getAppNameC()); | |||
| wxAppinfo.setSecret(wxProjectConfig.getAppSecretC()); | |||
| wxAppinfo.setPayId(payId); | |||
| wxAppinfo.setPayBillId(payBillId); | |||
| wxAppinfoMapper.insert(wxAppinfo); | |||
| } | |||
| @Override | |||
| public PageInfo<WxAppinfo> listAsPage(WxAppinfo record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxAppinfoMapper.findList(record)); | |||
| @@ -6,6 +6,7 @@ import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxAuthorizerInfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.WxWeappExtSet; | |||
| import com.iformall.domain.vo.WxWeappInfo; | |||
| import com.iformall.enums.EnumAppType; | |||
| @@ -37,6 +38,81 @@ public class WxAuthorizerInfoServiceImpl implements WxAuthorizerInfoService { | |||
| WxAppinfoMapper appinfoMapper; | |||
| @Override | |||
| public void wxAuthorizerInfoInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| WxAuthorizerInfo wxAuthorizerInfo = new WxAuthorizerInfo(); | |||
| wxAuthorizerInfo.setTenantId(tenantId); | |||
| wxAuthorizerInfo.setType(1); | |||
| wxAuthorizerInfo.setAuthorizerAppid(wxProjectConfig.getAppIdB()); | |||
| wxAuthorizerInfo.setHeadImg(wxProjectConfig.getHeadImgB()); | |||
| wxAuthorizerInfo.setQrcodeUrl(wxProjectConfig.getQrcodeUrlB()); | |||
| wxAuthorizerInfo.setCreateTime(new Date()); | |||
| wxAuthorizerInfo.setUpdateTime(new Date()); | |||
| wxAuthorizerInfo.setAuthorizationStatus(0);//授权状态,0为已授权,1为已取消授权 | |||
| wxAuthorizerInfo.setAuthTime(new Date()); | |||
| wxAuthorizerInfo.setBaseStatus(0);//微信基础版本设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setBaseTime(new Date()); | |||
| wxAuthorizerInfo.setDomainStatus(0);//服务器域名设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setDomainTime(new Date()); | |||
| wxAuthorizerInfo.setWebdomainStatus(0);//服务器业务域名设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setWebdomainTime(new Date()); | |||
| wxAuthorizerInfo.setCurrentVersion(wxProjectConfig.getCurrentVersionB()); | |||
| wxAuthorizerInfo.setCurrentDesc(wxProjectConfig.getCurrentVersionB()); | |||
| wxAuthorizerInfo.setReleaseTime(new Date()); | |||
| wxAuthorizerInfo.setOpenAppid(wxProjectConfig.getOpenAppid()); | |||
| wxAuthorizerInfo.setBindOpenTime(new Date()); | |||
| wxAuthorizerInfo.setRefreshToken(""); | |||
| wxAuthorizerInfo.setAccessToken(""); | |||
| authorizerInfoMapper.insert(wxAuthorizerInfo); | |||
| wxAuthorizerInfo = new WxAuthorizerInfo(); | |||
| wxAuthorizerInfo.setTenantId(tenantId); | |||
| wxAuthorizerInfo.setType(2); | |||
| wxAuthorizerInfo.setAuthorizerAppid(wxProjectConfig.getAppIdC()); | |||
| wxAuthorizerInfo.setHeadImg(wxProjectConfig.getHeadImgC()); | |||
| wxAuthorizerInfo.setQrcodeUrl(wxProjectConfig.getQrcodeUrlC()); | |||
| wxAuthorizerInfo.setCreateTime(new Date()); | |||
| wxAuthorizerInfo.setUpdateTime(new Date()); | |||
| wxAuthorizerInfo.setAuthorizationStatus(0);//授权状态,0为已授权,1为已取消授权 | |||
| wxAuthorizerInfo.setAuthTime(new Date()); | |||
| wxAuthorizerInfo.setBaseStatus(0);//微信基础版本设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setBaseTime(new Date()); | |||
| wxAuthorizerInfo.setDomainStatus(0);//服务器域名设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setDomainTime(new Date()); | |||
| wxAuthorizerInfo.setWebdomainStatus(0);//服务器业务域名设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setWebdomainTime(new Date()); | |||
| wxAuthorizerInfo.setTemplateStatus(0);//模板设置状态,0为已设置,1为设置失败 | |||
| wxAuthorizerInfo.setTemplateTime(new Date()); | |||
| wxAuthorizerInfo.setCurrentVersion(wxProjectConfig.getCurrentVersionC()); | |||
| wxAuthorizerInfo.setCurrentDesc(wxProjectConfig.getCurrentVersionC()); | |||
| wxAuthorizerInfo.setReleaseTime(new Date()); | |||
| wxAuthorizerInfo.setOpenAppid(wxProjectConfig.getOpenAppid()); | |||
| wxAuthorizerInfo.setBindOpenTime(new Date()); | |||
| wxAuthorizerInfo.setRefreshToken(""); | |||
| wxAuthorizerInfo.setAccessToken(""); | |||
| authorizerInfoMapper.insert(wxAuthorizerInfo); | |||
| } | |||
| @Override | |||
| public void wxWeappExtSetInit(WxProjectConfig wxProjectConfig) { | |||
| WxWeappExtSet wxWeappExtSet = new WxWeappExtSet(); | |||
| wxWeappExtSet.setAppId(wxProjectConfig.getAppIdB()); | |||
| wxWeappExtSet.setType(1); | |||
| wxWeappExtSet.setExtJson("{}"); | |||
| wxWeappExtSet.setReleaseJson("{}"); | |||
| wxWeappExtSet.setCreateDate(new Date()); | |||
| wxWeappExtSet.setUpdateDate(new Date()); | |||
| weappExtSetMapper.insert(wxWeappExtSet); | |||
| wxWeappExtSet = new WxWeappExtSet(); | |||
| wxWeappExtSet.setAppId(wxProjectConfig.getAppIdC()); | |||
| wxWeappExtSet.setType(2); | |||
| wxWeappExtSet.setExtJson("{}"); | |||
| wxWeappExtSet.setReleaseJson("{}"); | |||
| wxWeappExtSet.setCarSupport(0); | |||
| wxWeappExtSet.setCreateDate(new Date()); | |||
| wxWeappExtSet.setUpdateDate(new Date()); | |||
| weappExtSetMapper.insert(wxWeappExtSet); | |||
| } | |||
| @Override | |||
| public PageInfo<WxAuthorizerInfo> listAsPage(WxAuthorizerInfo record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> authorizerInfoMapper.findList(record)); | |||
| @@ -231,10 +231,16 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService { | |||
| return new ResultData(resultMap); | |||
| } | |||
| //@Override | |||
| //public PageInfo<WxCouponOrderCVo> listCUserVoAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize) { | |||
| // | |||
| // return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponOrderMapper.findListOfCUser(record)); | |||
| //} | |||
| @Override | |||
| public PageInfo<WxCouponOrderCVo> listCUserVoAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize) { | |||
| public PageInfo<WxCouponOrderCVo> listCUserVoAsPageOptimize(WxCouponOrder record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponOrderMapper.findListOfCUser(record)); | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponOrderMapper.findListOfCUserOptimize(record)); | |||
| } | |||
| @Override | |||
| @@ -4,6 +4,7 @@ import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxCouponSendConfig; | |||
| import com.iformall.enums.EnumCouponSendSendType; | |||
| import com.iformall.mapper.WxCouponSendConfigMapper; | |||
| import com.iformall.service.WxCouponSendConfigService; | |||
| import org.slf4j.Logger; | |||
| @@ -22,6 +23,23 @@ public class WxCouponSendConfigServiceImpl implements WxCouponSendConfigService | |||
| WxCouponSendConfigMapper wxCouponSendConfigMapper; | |||
| @Override | |||
| public void wxCouponSendConfigInit(String tenantId) { | |||
| WxCouponSendConfig wxCouponSendConfig = new WxCouponSendConfig(); | |||
| wxCouponSendConfig.setTenantId(tenantId); | |||
| wxCouponSendConfig.setValue(0);//默认停用 | |||
| wxCouponSendConfig.setCreateTime(new Date()); | |||
| wxCouponSendConfig.setUpdateTime(new Date()); | |||
| for (EnumCouponSendSendType value : EnumCouponSendSendType.values()) { | |||
| wxCouponSendConfig.setId(null); | |||
| if (value.getCode() > 1) { | |||
| wxCouponSendConfig.setSendType(value.getCode()); | |||
| wxCouponSendConfig.setRemark( value.getMessage() + "开关"); | |||
| wxCouponSendConfigMapper.insert(wxCouponSendConfig); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public PageInfo<WxCouponSendConfig> listAsPage(WxCouponSendConfig record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponSendConfigMapper.findList(record)); | |||
| @@ -181,7 +181,7 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||
| } | |||
| //更新库存 | |||
| wxCouponService.reduceRemainInventory(wxCouponOfDb.getId(), merchantLnventory, wxCouponOfDb.getRemainInventory()); | |||
| wxCouponService.reduceRemainInventory(wxCouponOfDb.getId(), merchantLnventory); | |||
| } | |||
| @Override | |||
| @@ -726,8 +726,8 @@ public class WxCouponServiceImpl implements WxCouponService { | |||
| @Override | |||
| @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) | |||
| public void reduceRemainInventory(Long id, Integer number, Integer remainInventory) { | |||
| int num = wxCouponMapper.reduceInventory(id, number, remainInventory); | |||
| public void reduceRemainInventory(Long id, Integer number) { | |||
| int num = wxCouponMapper.reduceInventory(id, number); | |||
| if (num == 0) { | |||
| throw new MallinkException(ErrorCode.ORDER_SAVE_ERR); | |||
| } | |||
| @@ -47,6 +47,7 @@ import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import java.lang.reflect.Field; | |||
| import java.text.DateFormat; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| @@ -99,6 +100,38 @@ public class WxFlowServiceImpl implements WxFlowService { | |||
| @Qualifier("couponChannelRedisTemplate") | |||
| RedisTemplate<String, PageInfo<WxCouponChannelVo>> cdRedisTemplate; | |||
| @Override | |||
| public void wxFlowConfigInit(String tenantId) { | |||
| DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||
| String nowTimestr = format.format(new Date()); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| Long id1 = idWorker.nextId(); | |||
| Long id2 = idWorker.nextId(); | |||
| Long id3 = idWorker.nextId(); | |||
| String initSql = "insert into `mallink`.`wx_flow_config` ( `id`, `parent_id`, `tenant_id`, `name`, `type`, `model_id`, `create_date`, `update_date`, `sort`) values " + | |||
| " ( '" + id1 + "', '0', '" + tenantId + "', '营销审批', '0', '0', '" + nowTimestr + "', '" + nowTimestr + "', '3')," + | |||
| " ( '" + id2 + "', '0', '" + tenantId + "', '合同审批', '0', '0', '" + nowTimestr + "', '" + nowTimestr + "', '1')," + | |||
| " ( '" + id3 + "', '0', '" + tenantId + "', '账单审批', '0', '0', '" + nowTimestr + "', '" + nowTimestr + "', '2')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id1 + "', '" + tenantId + "', '拼团审批', '11', '0', '" + nowTimestr + "', '" + nowTimestr + "', '3')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id1 + "', '" + tenantId + "', '有价券审批', '9', '0', '" + nowTimestr + "', '" + nowTimestr + "', '1')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id1 + "', '" + tenantId + "', '卡审批', '10', '0', '" + nowTimestr + "', '" + nowTimestr + "', '2')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id1 + "', '" + tenantId + "', '砍价审批', '12', '0', '" + nowTimestr + "', '" + nowTimestr + "', '4')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位租金+物业合同签约', '19', '0', '" + nowTimestr + "', '" + nowTimestr + "', '11')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺租金+物业合同终止', '18', '0', '" + nowTimestr + "', '" + nowTimestr + "', '10')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺物业合同签约', '13', '0', '" + nowTimestr + "', '" + nowTimestr + "', '5')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺租金+物业合同签约', '17', '0', '" + nowTimestr + "', '" + nowTimestr + "', '9')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位物业合同签约', '15', '0', '" + nowTimestr + "', '" + nowTimestr + "', '7')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位物业合同终止', '16', '0', '" + nowTimestr + "', '" + nowTimestr + "', '8')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位租金+物业合同终止', '20', '0', '" + nowTimestr + "', '" + nowTimestr + "', '12')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺物业合同终止', '14', '0', '" + nowTimestr + "', '" + nowTimestr + "', '6')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺租金合同终止', '6', '0', '" + nowTimestr + "', '" + nowTimestr + "', '3')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位租金合同签约', '5', '0', '" + nowTimestr + "', '" + nowTimestr + "', '2')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '多经点位租金合同终止', '7', '0', '" + nowTimestr + "', '" + nowTimestr + "', '4')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id2 + "', '" + tenantId + "', '商铺租金合同签约', '4', '0', '" + nowTimestr + "', '" + nowTimestr + "', '1')," + | |||
| " ( '" + idWorker.nextId() + "', '" + id3 + "', '" + tenantId + "', '账单应收金额变更', '8', '0', '" + nowTimestr + "', '" + nowTimestr + "', '1');"; | |||
| wxFlowConfigMapper.wxFlowConfigInit(initSql); | |||
| } | |||
| /** | |||
| * 获取流程key | |||
| * @param flowType | |||
| @@ -1,35 +1,77 @@ | |||
| package com.iformall.service.impl; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.dto.WxMallBuildingFloorDto; | |||
| import com.iformall.domain.po.WxMall; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.WxMallBuilding; | |||
| import com.iformall.domain.po.WxMallFloor; | |||
| import com.iformall.mapper.WxMallBuildingMapper; | |||
| import com.iformall.mapper.WxMallFloorMapper; | |||
| import com.iformall.service.WxMallBuildingService; | |||
| import com.iformall.service.WxMallService; | |||
| import com.iformall.utils.Constant; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.util.Date; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.stream.Collectors; | |||
| @Service | |||
| public class WxMallBuildingServiceImpl implements WxMallBuildingService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| WxMallService wxMallService; | |||
| @Autowired | |||
| WxMallBuildingMapper wxMallBuildingMapper; | |||
| @Autowired | |||
| WxMallFloorMapper wxMallFloorMapper; | |||
| @Override | |||
| public void wxMallBuildingInit(String tenantId, String mallBuildingJSONstr) { | |||
| WxMall byTenantId = wxMallService.getByTenantId(tenantId); | |||
| JSONObject obj= JSON.parseObject(mallBuildingJSONstr); | |||
| Iterator it =obj.entrySet().iterator(); | |||
| while (it.hasNext()) { | |||
| Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next(); | |||
| String[] split = entry.getValue().replace(",",",").split(","); | |||
| WxMallBuilding wxMallBuilding = new WxMallBuilding(); | |||
| wxMallBuilding.setTenantId(tenantId); | |||
| wxMallBuilding.setMallId(byTenantId.getId()); | |||
| wxMallBuilding.setBuildingName(entry.getKey()); | |||
| wxMallBuilding.setFloorNumber(split.length); | |||
| wxMallBuilding.setCreateDate(new Date()); | |||
| wxMallBuilding.setUpdateDate(new Date()); | |||
| wxMallBuildingMapper.insert(wxMallBuilding); | |||
| for (String cha:split) { | |||
| WxMallFloor wxMallFloor = new WxMallFloor(); | |||
| wxMallFloor.setTenantId(tenantId); | |||
| wxMallFloor.setMallId(byTenantId.getId()); | |||
| wxMallFloor.setBuildingId(wxMallBuilding.getId()); | |||
| wxMallFloor.setFloorName(cha); | |||
| //默认图片---------------------------------------------------- | |||
| wxMallFloor.setBackgroundImg("https://s3.cn-northwest-1.amazonaws.com.cn/iformall-net/789/9eea8e0e-15ea-4be0-a43d-31e2e9d8db8c.jpg"); | |||
| wxMallFloor.setCreateDate(new Date()); | |||
| wxMallFloor.setUpdateDate(new Date()); | |||
| wxMallFloorMapper.insert(wxMallFloor); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public PageInfo<WxMallBuilding> listAsPage(WxMallBuilding record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMallBuildingMapper.findList(record)); | |||
| @@ -3,6 +3,7 @@ package com.iformall.service.impl; | |||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.WxMall; | |||
| import com.iformall.domain.po.WxMallBuilding; | |||
| @@ -43,6 +44,43 @@ public class WxMallServiceImpl implements WxMallService { | |||
| @Qualifier("mallRedisTemplate") | |||
| RedisTemplate<String, WxMall> mallRedisTemplate; | |||
| @Override | |||
| public String wxMallInit(WxProjectConfig wxProjectConfig) { | |||
| WxMall wxMall = new WxMall(); | |||
| wxMall.setTenantId("-1"); | |||
| wxMall.setName(wxProjectConfig.getName()); | |||
| wxMall.setGroup(wxProjectConfig.getName());//无用 | |||
| wxMall.setCountry(wxProjectConfig.getCountry()); | |||
| wxMall.setProvince(wxProjectConfig.getProvince()); | |||
| wxMall.setCity(wxProjectConfig.getCity()); | |||
| wxMall.setAddr(wxProjectConfig.getAddr()); | |||
| wxMall.setTotalArea(wxProjectConfig.getTotalArea()); | |||
| wxMall.setOperatingArea(wxProjectConfig.getTotalArea());//无用 | |||
| wxMall.setParkArea(wxProjectConfig.getParkArea()); | |||
| wxMall.setParkPlaceNumber(wxProjectConfig.getParkPlaceNumber()); | |||
| wxMall.setServicePhone(wxProjectConfig.getServicePhone()); | |||
| wxMall.setImgUrl(wxProjectConfig.getImgUrl()); | |||
| wxMall.setImgUrlH(wxProjectConfig.getImgUrlH()); | |||
| String weapNote = "{\"carpage\": {\"desc\": \"分享个停车小程序,希望你喜欢\", \"title\": \"" | |||
| + wxProjectConfig.getName() | |||
| + "\"}, \"firstpage\": {\"desc\": \"分享个小程序,希望你喜欢\", \"title\": \"" | |||
| + wxProjectConfig.getName() | |||
| + "\"}}"; | |||
| wxMall.setWeapNote(weapNote); | |||
| //(1(全能版)、2(营销版,除了合同,账单功能),3.速享版(营销版加3个月限制)分别什么意思) | |||
| wxMall.setSaleType(wxProjectConfig.getSaleType()); | |||
| wxMall.setBusinessHours("[]"); | |||
| wxMall.setIntroduction(""); | |||
| wxMall.setImg(""); | |||
| wxMallMapper.insert(wxMall); | |||
| wxMall.setTenantId(wxMall.getId().toString()); | |||
| wxMallMapper.updateById(wxMall); | |||
| return wxMall.getTenantId(); | |||
| } | |||
| @Override | |||
| public PageInfo<WxMall> listAsPage(WxMall record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMallMapper.findList(record)); | |||
| @@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxMsgConfig; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.mapper.WxMsgConfigMapper; | |||
| import com.iformall.service.WxMsgConfigService; | |||
| import org.slf4j.Logger; | |||
| @@ -20,6 +21,36 @@ public class WxMsgConfigServiceImpl implements WxMsgConfigService { | |||
| WxMsgConfigMapper wxMsgConfigMapper; | |||
| @Override | |||
| public void WxMsgConfigInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| WxMsgConfig wxMsgConfig = new WxMsgConfig(); | |||
| wxMsgConfig.setTenantId(tenantId); | |||
| wxMsgConfig.setSecret("7305150347587283553aa8898e7dbf20"); | |||
| wxMsgConfig.setPublickey("MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvh8j/zagfxQdnSh5OIic\\r" + | |||
| "\\nMzN+MuRuWQJPjgu4Gza4+gX3j5Ln2xNDBOTjpwyuLBjh/JcBd1cGO3lAaKCwcaix\\r" + | |||
| "\\nsmhTq56wVXXUMgDiAChu4ud8FSvRc8G8tdZAirKVAIi3NW+/pYgpWBs/0wnF8hz4\\r" + | |||
| "\\n8no4pyJHl9Jc1LH3VNIMz8vqzKUPc4ack4pFUXlcNj6C+sBlaurmI4/vwLqNxBGs\\r" + | |||
| "\\n7/zyM7dv6oy3DSU/Y1qBArM1YPjfL2dNun8rmtPgJvlPwXqA7uoHPwQ2Ym3aUn59\\r" + | |||
| "\\npkS7QI6IE8uuqNkfSte8BXLd2nIqPLFxLYLDmdll7eoyRblHcHqAYSj8stK6StC7\\r" + | |||
| "\\nDNryNKEjTEwbgf9trUI0uvF1pfgTy2gpclnY69FtD/m0+FvLyorMq+nmBqYMjka5\\r" + | |||
| "\\nK0txDQJPOa7gsi//uXd/cJW2SAXY9MSO1AfMi8Xq/YKRQzN9FW5iapskXFHca7uX\\r" + | |||
| "\\ng5NhH7flr6DW+QInFlpoN6WIEAuDF1aj4O49Ikm3WxwhTqnvEkdSCfivpYQkp9Sh\\r" + | |||
| "\\n4kQ/SQdxuT7VX+Nz6k+uMx2z4cySk33bHi0KoHbA9QFGg/54Qd0+eU4qZnd4mrgh\\r" + | |||
| "\\nhH7/QQhL7Z9eF1U5UPrsHq2Vq3rEnN+tYQ26AuKeU8vzTxBrC/SxC6C/SMFt3f/Y\\r" + | |||
| "\\nnuFh1UnNJZleZwyQt+ZdGO0CAwEAAQ=="); | |||
| wxMsgConfig.setBid("465565"); | |||
| wxMsgConfig.setRecharge((long) 0); | |||
| wxMsgConfig.setRemains((long) 100000); | |||
| wxMsgConfig.setTotal((long) 100000); | |||
| wxMsgConfig.setAccount("15626593768"); | |||
| wxMsgConfig.setReminderstatus(0); | |||
| wxMsgConfig.setNotifyurl("https://admin.malls.iformall.com/wxMsgCallback/receivemsg/" + tenantId); | |||
| wxMsgConfig.setModelnotifyurl("https://admin.malls.iformall.com/wxMsgCallback/receivemodel/" + tenantId); | |||
| wxMsgConfig.setVerifynotifyurl("https://admin.malls.iformall.com/wxMsgCallback/receiveverifymodel/" + tenantId); | |||
| wxMsgConfig.setAppid(wxProjectConfig.getAppIdB()); | |||
| wxMsgConfigMapper.insert(wxMsgConfig); | |||
| } | |||
| @Override | |||
| public PageInfo<WxMsgConfig> listAsPage(WxMsgConfig record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMsgConfigMapper.findList(record)); | |||
| @@ -9,6 +9,7 @@ import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxMsgConfig; | |||
| import com.iformall.domain.po.WxMsgValidationcodeModel; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.enums.EnumMsgModelStatus; | |||
| import com.iformall.enums.EnumVerifyCode; | |||
| import com.iformall.mapper.WxMsgConfigMapper; | |||
| @@ -20,6 +21,8 @@ import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.text.DateFormat; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| @Service | |||
| @@ -32,6 +35,52 @@ public class WxMsgValidationcodeModelServiceImpl implements WxMsgValidationcodeM | |||
| @Autowired | |||
| WxMsgConfigMapper wxMsgConfigMapper; | |||
| @Override | |||
| public void wxMsgValidationcodeModelInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||
| String nowTimestr = format.format(new Date()); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| String initSql = "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`) values " + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '2', '代办通知', '" + wxProjectConfig.getName() + "', '{userName}提交了一个合同待您审批,电脑登陆{page} 查看您的待办。', '" + nowTimestr + "', '1', '0', '226', null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '3', '审批通知', '" + wxProjectConfig.getName() + "', '{userName}同意编号{contract}的合同审批,已呈送至{toUserName},登录{page}查看审批进度。', '" + nowTimestr + "', '1', '0', '227', null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '4', '通过审批通知', '" + wxProjectConfig.getName() + "', '编号{contract}的合同已通过审批,请登录{page} 跟进后续工作。', '" + nowTimestr + "', '1', '0', '228', null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '5', '驳回通知', '" + wxProjectConfig.getName() + "', '编号{contract}的合同审批被驳回,请登录{page} 查看审批明细。', '" + nowTimestr + "', '1', '0', '229', null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '6', '验证码', '" + wxProjectConfig.getName() + "', '{s6}(动态验证码),请在1分钟内填写', '" + nowTimestr + "', '1', '1', '115', null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '7', '账单待缴模板', '" + wxProjectConfig.getName() + "', '您当期的待缴账单为{price}元,截止日期为{date} ,请登录{app}小程序查看账单并交费。', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '8', '账单欠缴模板', '" + wxProjectConfig.getName() + "', '截止今日您的账单共计欠缴{price}元,请登录{app}小程序查看账单并交费。', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '9', '场景投放', '" + wxProjectConfig.getName() + "', '亲爱的vip,悄悄地送您一张{title},请到{app}微信小程序中使用吧!', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '11', '商户分账账户新增通知商户', '" + wxProjectConfig.getName() + "', '您于{time}提交了{merchant}商户的收款账户[{account}]绑定,后续销售分成及营销补贴将存入该账户', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '13', '商户分账账户变更通知商户', '" + wxProjectConfig.getName() + "', '您于{time}将{merchant}商户的收款账户变更为[{account}],后续销售分成及营销补贴将存入该账户', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '14', '商户分账账户不使用回执', '" + wxProjectConfig.getName() + "', '商管已同意[{account}]作为{merchant}商户的收款账户。后续的销售分成及营销补贴将存入此账户', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '15', '商户分账账户使用回执', '" + wxProjectConfig.getName() + "', '商管拒绝将[{account}]作为{merchant}商户的收款账户。如有疑问请联系商管', '" + nowTimestr + "', '1', '0', null, null)," + | |||
| " ( '" + idWorker.nextId() + "', '" + tenantId + "', '16', '商户分账账户删除提醒', '" + wxProjectConfig.getName() + "', '{merchant}商户的收款账户[{account}]于{time}取消绑定,营销活动与销售分成将无法正常进行,请尽快绑定新收款账户', '" + nowTimestr + "', '1', '0', null, null);" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| "values ( '" + idWorker.nextId() + "', '" + tenantId + "', '10', '审批通过通知', '富茂', " + | |||
| " '<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <script> document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + \\'px\\';</script>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;padding:0 40px;\\\" src=\\\"https://s3.cn-northwest-1.amazonaws.com.cn/iformall-net/cimg/changrong-logo.png\\\"/>\\n </header>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding:56px 55px 0;\\\">审批通过通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding: 36px 55px;\\\">编号<span>{contract}</span>的{bustype}已经审批通过,请登录<a href=\\\"{page}\\\">{page}</a>跟进后续工作</div>\\n </div>\\n </div>\\n</body>\\n\\n</html>', " + | |||
| " '" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| "values ( '" + idWorker.nextId() + "', '" + tenantId + "', '11', '待缴账单通知', '富茂', " + | |||
| " '<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <style>\\n *{\\n margin: 0;\\n padding: 0;\\n }\\n </style>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;margin-left: 40px;\\\" src=\\\"{bg}\\\"/>\\n </header>\\n <content>\\n <div style=\\\"background: #fff;padding-bottom: 40px;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding-top: 56px;padding-left: 55px;\\\">待缴账单通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding:36px 55px 0;\\\">您当前的待缴账单为<span style=\\\"font-weight:400;color:rgba(200,89,98,1);margin:0 10px;\\\">{price}</span>元,截止日期为<span>{date}</span>请登录<span>您的商户端</span>小程序查看账单并缴费</div>\\n </div>\\n <div style=\\\"height: auto;width: 100%;line-height: 40px; background: rgba(245,245,245,1);padding: 30px 0;\\\">\\n <div style=\\\"overflow: hidden;\\\">\\n <span style=\\\"display: block; font-size:18px;width:80px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">租金账单</span>\\n <div style=\\\"margin: 0 5%;width:90%;overflow: hidden;\\\">\\n <div style=\\\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">账单类型</div>\\n <div style=\\\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">账单金额(元)</div>\\n <div style=\\\"width: 33.3%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">缴费时间</div>\\n </div>\\n {billList}\\n </div>\\n </div>\\n <div style=\\\"background: #fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold; font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;margin-top: 26px;margin-left: 55px;padding-top: 56px;\\\">遇到问题?</div>\\n <div style=\\\"overflow: hidden;line-height: 60px;padding-bottom: 40px;\\\">\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">请联系商管负责人:</span>\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 25px;\\\"><span>{linkName}</span><span style=\\\"margin-left: 16px; font-family:MicrosoftYaHei;font-weight:400;color:rgba(64,103,139,1);\\\">{linkPhone}</span></span>\\n </div>\\n </div>\\n </content>\\n </div>\\n</body>\\n\\n</html>'," + | |||
| " '" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| "values ( '" + idWorker.nextId() + "', '" + tenantId + "', '12', '审批通知', '富茂', " + | |||
| "'<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <script> document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + \\'px\\';</script>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;padding:0 40px;\\\" src=\\\"{bg}\\\"/>\\n </header>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding:56px 55px 0;\\\">审批通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding: 36px 55px;\\\"><span>{userName}</span>同意编号<span>{contract}</span>的{bustype}审批,已呈送<span>{toUserName},</span>请登录<a href=\\\"{page}\\\">{page}</a>查看审批进度</div>\\n </div>\\n </div>\\n</body>\\n\\n</html>', " + | |||
| "'" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| "values ( '" + idWorker.nextId() + "', '" + tenantId + "', '13', '欠缴账单通知', '富茂', " + | |||
| " '<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <style>\\n *{\\n margin: 0;\\n padding: 0;\\n }\\n </style>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;margin-left: 40px;\\\" src=\\\"{bg}\\\"/>\\n </header>\\n <content>\\n <div style=\\\"background: #fff;padding-bottom: 40px;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding: 56px 55px 0;\\\">欠缴账单通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding: 36px 55px 0;\\\">您当前的欠缴账单为<span style=\\\"font-weight:400;color:rgba(200,89,98,1);margin:0 10px;\\\">{price}</span>元,截止日期为<span>{date}</span>请登录<span>您的商户端</span>小程序查看账单并缴费</div>\\n </div>\\n <div style=\\\"height: auto;width: 100%;line-height: 40px; background: rgba(245,245,245,1);padding: 30px 0;\\\">\\n <div style=\\\"overflow: hidden;\\\">\\n <span style=\\\"display: block; font-size:18px;width:80px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">租金账单</span>\\n <div style=\\\"margin: 0 5%;width:90%;overflow: hidden;font-size:14px;\\\">\\n <div style=\\\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">账单类型</div>\\n <div style=\\\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">账单金额(元)</div>\\n <div style=\\\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">缴费时间</div>\\n <div style=\\\"width: 25%;float: left;height: 60px;line-height: 60px;text-align: center;font-family:MicrosoftYaHei;color:rgba(85,85,85,1);\\\">逾期天数</div>\\n </div>\\n {billList}\\n </div>\\n </div>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold; font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;margin-top: 26px;margin-left: 55px;padding-top: 56px;\\\">遇到问题?</div>\\n <div style=\\\"overflow: hidden;line-height: 60px;padding-bottom: 40px;\\\">\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">请联系商管负责人:</span>\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 25px;\\\"><span>{linkName}</span><span style=\\\"margin-left: 16px; font-family:MicrosoftYaHei;font-weight:400;color:rgba(64,103,139,1);\\\">{linkPhone}</span></span>\\n </div>\\n </div>\\n </content>\\n </div>\\n</body>\\n\\n</html>'," + | |||
| "'" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| " values ( '" + idWorker.nextId() + "', '" + tenantId + "', '14', '待办通知', '富茂'," + | |||
| " '<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <style>\\n *{\\n margin: 0;\\n padding: 0;\\n }\\n </style>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;margin-left: 40px;\\\" src=\\\"{bg}\\\"/>\\n </header>\\n <content>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding: 56px 55px 0;\\\">待办通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding: 36px 55px 40px;\\\"><span>{name}</span><span>提交了一个{bustype}待您审批,电脑登录</span><a href=\\\"{page}\\\" target=\\\"_blank\\\">{page}</a>查看您的待办</div>\\n </div>\\n <div style=\\\"height: auto;width: 100%;line-height: 40px; background: rgba(245,245,245,1);padding: 30px 0;\\\">\\n <div style=\\\"overflow: hidden;\\\">\\n <div style=\\\"float: left;font-size:18px;width:cale(20%-55px);font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">申请时间:</div>\\n <div style=\\\"float: left;font-size:18px;width:cale(80%-55px);font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 55px;\\\">{applyTime}</div>\\n </div>\\n <div style=\\\"overflow: hidden;\\\">\\n <div style=\\\"float: left;font-size:18px;width:cale(20%-55px);font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">申请进度:</div>\\n <div style=\\\"float: left;width:cale(80%-55px);margin-left: 55px;\\\">\\n \\n {taskList}\\n </div>\\n </div>\\n </div>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;margin-top: 26px;padding: 56px 55px 0;\\\">遇到问题?</div>\\n <div style=\\\"overflow: hidden;line-height: 60px;padding-bottom: 40px;\\\">\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">请联系申请人:</span>\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 25px;\\\"><span>{linkName}</span><span style=\\\"margin-left: 16px; font-family:MicrosoftYaHei;font-weight:400;color:rgba(64,103,139,1);\\\">{linkPhone}</span></span>\\n </div>\\n </div>\\n </content>\\n </div>\\n</body>\\n\\n</html>'," + | |||
| " '" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');" + | |||
| "insert into `mallink`.`wx_msg_validationcode_model` ( `id`, `tenant_id`, `type`, `name`, `signature`, `content`, `createtime`, `status`, `minutes`, `model_id`, `email_bg_img`)" + | |||
| " values ( '" + idWorker.nextId() + "', '" + tenantId + "', '15', '驳回通知', '富茂', " + | |||
| " '<!DOCTYPE html>\\n<html>\\n\\n<head>\\n <meta charset=\\\"utf-8\\\">\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0\\\">\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"initial-scale=1.0, user-scalable=no\\\" />\\n <meta name=\\\"renderer\\\" content=\\\"webkit\\\">\\n <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge,chrome=1\\\">\\n <title>富茂审批邮件</title>\\n <title></title>\\n <style>\\n *{\\n margin: 0;\\n padding: 0;\\n }\\n </style>\\n</head>\\n\\n<body>\\n <div id=\\\"box\\\" style=\\\"padding:80px 20%;background:#E9E7E7;min-height:100vh;\\\">\\n <header style=\\\"height:140px;width:100%;display:flex;background:rgba(31,47,62,1);border-radius:15px 15px 0px 0px;\\\">\\n <img style=\\\"height:auto;width:292px;display:flex;align-self: center;justify-content: center;margin-left: 40px;\\\" src=\\\"{bg}\\\"/>\\n </header>\\n <content>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding: 56px 55px 0;\\\">审批通过通知</div>\\n <div style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);padding:36px 55px 40px;\\\">编号<span>{contract}</span>的{bustype}审批被驳回,请登录<a href=\\\"{page}\\\">{page}</a>查看审批明细</div>\\n </div>\\n <div style=\\\"height: auto;width: 100%;line-height: 40px; background: rgba(245,245,245,1);padding: 30px 0;\\\">\\n <div style=\\\"overflow: hidden;\\\">\\n <span style=\\\"display: block;float: left; font-size:18px;width:80px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">驳回人:</span>\\n <span style=\\\"display: block;float: left; width:calc(100% - 240px);font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 55px;\\\">{name}</span>\\n </div>\\n <div style=\\\"overflow: hidden;\\\">\\n <span style=\\\"display: block;float: left; font-size:18px;width:80px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">驳回原因:</span>\\n <span style=\\\"display: block;float: left;width:calc(100% - 240px); font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 55px;\\\">{remark}</span>\\n </div>\\n </div>\\n <div style=\\\"background:#fff;\\\">\\n <div style=\\\"font-size:26px;font-family:MicrosoftYaHei-Bold;font-weight:bold;color:rgba(85,85,85,1);line-height: 32px;padding: 56px 55px 0;margin-top: 26px;\\\">遇到问题?</div>\\n <div style=\\\"overflow: hidden;line-height: 60px;padding-bottom: 40px;\\\">\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(153,153,153,1);margin-left: 55px;\\\">请联系驳回人:</span>\\n <span style=\\\"font-size:18px;font-family:MicrosoftYaHei;font-weight:400;color:rgba(85,85,85,1);margin-left: 25px;\\\"><span>{linkName}</span><span style=\\\"margin-left: 16px; font-family:MicrosoftYaHei;font-weight:400;color:rgba(64,103,139,1);\\\">{linkPhone}</span></span>\\n </div>\\n </div>\\n </content>\\n </div>\\n</body>\\n\\n</html>'," + | |||
| " '" + nowTimestr + "', '1', null, '500', '" + wxProjectConfig.getImgUrlH() + "');"; | |||
| wxMsgValidationcodeModelMapper.wxMsgValidationcodeModelInit(initSql); | |||
| } | |||
| @Override | |||
| public PageInfo<WxMsgValidationcodeModel> listAsPage(WxMsgValidationcodeModel record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMsgValidationcodeModelMapper.findList(record)); | |||
| @@ -34,8 +34,6 @@ import java.util.stream.Collectors; | |||
| public class WxOrderGroupServiceImpl implements WxOrderGroupService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| private final Long notOrderGroupId = 0L; | |||
| private final int endPeople = 0; | |||
| @Autowired | |||
| WxOrderGroupMapper wxOrderGroupMapper; | |||
| @@ -67,29 +65,67 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { | |||
| @Autowired | |||
| WxCouponChannelMapper wxCouponChannelMapper; | |||
| private int updateOrderGroup(WxOrderGroup wxOrderGroup,WxOrder order, WxCoupon wxCoupon) { | |||
| //锁住人数 | |||
| long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| boolean grouppeopleLock = redisLock.lock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); | |||
| if (!grouppeopleLock) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团锁定失败,请稍后再试。"); | |||
| } | |||
| //此处拼团数量应从订单总数查询,支付成功的就算一个,没支付成功的不算 | |||
| int ordercount = wxOrderService.countGroupOrder(order.getOrderGroupId(),true); | |||
| Integer remainPeople = wxCoupon.getPressLimitNum()-ordercount-1; | |||
| //Integer remainPeople = wxOrderGroup.getRemainPeople()-1; | |||
| wxOrderGroup.setStatus(remainPeople <= 0 ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); | |||
| wxOrderGroup.setUpdateDate(new Date()); | |||
| wxOrderGroup.setRemainPeople(remainPeople); | |||
| logger.info("非首次拼团,更新拼团信息, 剩余人数-1"); | |||
| int row = wxOrderGroupMapper.updateOrderGroup(wxOrderGroup); | |||
| if (row != 1) { | |||
| //错误,更新状态,定时任务会发起退款,回滚库存 | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| wxOrderMapper.updateById(order); | |||
| redisLock.unlock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团失败,将稍后退款."); | |||
| }else { | |||
| redisLock.unlock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); | |||
| } | |||
| return remainPeople; | |||
| } | |||
| @Override | |||
| @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) | |||
| public void createOrderGroup(WxOrder order, WxCoupon wxCoupon) { | |||
| public void createOrderGroup(WxOrder order, WxCoupon wxCoupon,boolean isScheduleTask) { | |||
| Long orderGroupId = order.getOrderGroupId(); | |||
| //查看是否首次拼团,orderGroupId不等于0代表不是首次拼团,因为第二个加入的拼团者肯定有团单号 | |||
| if (!orderGroupId.equals(notOrderGroupId)) { | |||
| if (!orderGroupId.equals(0L)) { | |||
| // 非首次拼团 | |||
| // 参与拼团 | |||
| WxOrderGroup wxOrderGroup = wxOrderGroupMapper.selectById(orderGroupId); | |||
| if(wxOrderGroup.getRemainPeople() < endPeople + 1) { | |||
| logger.info(">>>>>>>>>>>>参团失败 修改订单状态后定时退款 团单号" + orderGroupId); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); | |||
| if (null == wxOrderGroup) { | |||
| //错误,更新状态,定时任务会发起退款,回滚库存 | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| wxOrderMapper.updateById(order); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"WxOrderGroup is null."+orderGroupId); | |||
| } | |||
| Integer remainPeople = wxOrderGroup.getRemainPeople()-1; | |||
| wxOrderGroup.setStatus(remainPeople == endPeople ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); | |||
| wxOrderGroup.setUpdateDate(new Date()); | |||
| logger.info("非首次拼团,更新拼团信息, 剩余人数-1"); | |||
| int row = wxOrderGroupMapper.updateOrderGroup(wxOrderGroup); | |||
| if (row != 1) { | |||
| logger.info(">>>>>>>>>>>>参团失败 修改订单状态后定时退款 团单号" + orderGroupId); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); | |||
| if(wxOrderGroup.getRemainPeople()<1) { | |||
| //如果是定时任务处理订单时候补程序发现拼团已满,则此时发起退款,回滚库存, 不能设置为未付款,回引起死循环 | |||
| if(isScheduleTask) { | |||
| //错误,更新状态,定时任务会发起退款,回滚库存,到此结束 | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_SCHEDU_REFUND.getCode()); | |||
| wxOrderMapper.updateById(order); | |||
| //此处不要抛出异常,会导致事务回滚,状态写不上 | |||
| return; | |||
| }else { | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| wxOrderMapper.updateById(order); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团人数已满,将稍后退款。"); | |||
| } | |||
| } | |||
| int remainPeople = updateOrderGroup(wxOrderGroup,order,wxCoupon); | |||
| // 更新订单信息 | |||
| order.setOrderStatus(wxOrderGroup.getStatus()); | |||
| order.setPressEndDate(wxOrderGroup.getExpiredDate()); | |||
| @@ -100,7 +136,7 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { | |||
| logger.error("更新订单信息失败", e); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); | |||
| } | |||
| if (remainPeople == endPeople) { | |||
| if (remainPeople == 0) { | |||
| actionAfterOrderGroupSuccess(order, orderGroupId); | |||
| } | |||
| } else { | |||
| @@ -233,7 +269,7 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { | |||
| if (orderTemp == null) { | |||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); | |||
| } | |||
| if (orderTemp.getOrderGroupId().equals(notOrderGroupId)) { | |||
| if (orderTemp.getOrderGroupId().equals(0L)) { | |||
| return new ResultData(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); | |||
| } | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(orderTemp.getCouponChannelId()); | |||
| @@ -376,4 +412,5 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,7 +1,34 @@ | |||
| package com.iformall.service.impl; | |||
| import java.math.BigDecimal; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.ArrayList; | |||
| import java.util.Calendar; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.Objects; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.stream.Collectors; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Qualifier; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| @@ -10,34 +37,99 @@ import com.iformall.common.IdWorker; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.dto.OrderSaveDto; | |||
| import com.iformall.domain.dto.WxSharingOrderDto; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxCUser; | |||
| import com.iformall.domain.po.WxCardInfo; | |||
| import com.iformall.domain.po.WxCoupon; | |||
| import com.iformall.domain.po.WxCouponChannel; | |||
| import com.iformall.domain.po.WxCouponMerchant; | |||
| import com.iformall.domain.po.WxCouponOrder; | |||
| import com.iformall.domain.po.WxCouponPassword; | |||
| import com.iformall.domain.po.WxCouponSend; | |||
| import com.iformall.domain.po.WxCreditHistory; | |||
| import com.iformall.domain.po.WxMerchant; | |||
| import com.iformall.domain.po.WxMerchantBUser; | |||
| import com.iformall.domain.po.WxOrder; | |||
| import com.iformall.domain.po.WxOrderGroup; | |||
| import com.iformall.domain.po.WxOrderPress; | |||
| 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.FmInsideOrderSuccessMsg; | |||
| import com.iformall.domain.vo.*; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.domain.po.msg.UpdateCouponStockMsg; | |||
| import com.iformall.domain.vo.WxCouponSendVo; | |||
| import com.iformall.domain.vo.WxMerchantVo; | |||
| import com.iformall.domain.vo.WxOrderCouponPressVo; | |||
| import com.iformall.domain.vo.WxOrderCouponVo; | |||
| import com.iformall.domain.vo.WxOrderPayExpVo; | |||
| import com.iformall.domain.vo.WxOrderPayVo; | |||
| import com.iformall.domain.vo.WxOrderQueryVo; | |||
| import com.iformall.enums.EnumAssignTagsTrigger; | |||
| import com.iformall.enums.EnumCacheKey; | |||
| import com.iformall.enums.EnumCouponChannelStatus; | |||
| import com.iformall.enums.EnumCouponConditionType; | |||
| import com.iformall.enums.EnumCouponMerchantStatus; | |||
| import com.iformall.enums.EnumCouponOrderStatus; | |||
| import com.iformall.enums.EnumCouponPasswordStatus; | |||
| import com.iformall.enums.EnumCouponPasswordSupport; | |||
| import com.iformall.enums.EnumCouponSendSendType; | |||
| import com.iformall.enums.EnumCouponSendType; | |||
| import com.iformall.enums.EnumCouponStatus; | |||
| import com.iformall.enums.EnumCouponTransfer; | |||
| import com.iformall.enums.EnumCouponType; | |||
| import com.iformall.enums.EnumMerchantStatus; | |||
| import com.iformall.enums.EnumMerchantType; | |||
| import com.iformall.enums.EnumMsgMqKey; | |||
| import com.iformall.enums.EnumMsgMqTag; | |||
| import com.iformall.enums.EnumMsgMqTopic; | |||
| import com.iformall.enums.EnumMsgRecordType; | |||
| import com.iformall.enums.EnumOrderPressType; | |||
| import com.iformall.enums.EnumOrderStatus; | |||
| import com.iformall.enums.EnumOrderType; | |||
| import com.iformall.enums.EnumPayShare; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.enums.EnumPayType; | |||
| import com.iformall.enums.EnumProfitSharingOrderType; | |||
| import com.iformall.enums.EnumScoreType; | |||
| import com.iformall.enums.EnumUserType; | |||
| import com.iformall.enums.EnumValidStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.mapper.WxAppinfoMapper; | |||
| import com.iformall.mapper.WxCUserBasicInfoMapper; | |||
| import com.iformall.mapper.WxCUserMapper; | |||
| import com.iformall.mapper.WxCardInfoMapper; | |||
| import com.iformall.mapper.WxCouponChannelMapper; | |||
| import com.iformall.mapper.WxCouponMapper; | |||
| import com.iformall.mapper.WxCouponMerchantMapper; | |||
| import com.iformall.mapper.WxCouponOrderMapper; | |||
| import com.iformall.mapper.WxCouponPasswordMapper; | |||
| import com.iformall.mapper.WxMallMapper; | |||
| import com.iformall.mapper.WxMerchantBUserMapper; | |||
| import com.iformall.mapper.WxMerchantMapper; | |||
| import com.iformall.mapper.WxOrderGroupMapper; | |||
| import com.iformall.mapper.WxOrderMapper; | |||
| import com.iformall.mapper.WxOrderPressMapper; | |||
| import com.iformall.mapper.WxPayAccountMapper; | |||
| import com.iformall.mapper.WxPayOrderMapper; | |||
| import com.iformall.mq.MqBaseProducer; | |||
| import com.iformall.service.*; | |||
| import com.iformall.utils.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Qualifier; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.math.BigDecimal; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.stream.Collectors; | |||
| import com.iformall.service.ExcelService; | |||
| import com.iformall.service.WxAppinfoService; | |||
| import com.iformall.service.WxCUserService; | |||
| import com.iformall.service.WxCUserTagsService; | |||
| import com.iformall.service.WxCouponActionLogService; | |||
| import com.iformall.service.WxCouponSendService; | |||
| import com.iformall.service.WxCreditHistoryService; | |||
| import com.iformall.service.WxMsgLimitService; | |||
| import com.iformall.service.WxOrderService; | |||
| import com.iformall.service.WxPayOrderService; | |||
| import com.iformall.service.WxProfitSharingOrderService; | |||
| import com.iformall.service.WxScoreRulesService; | |||
| import com.iformall.utils.Constant; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.PayUtils; | |||
| import com.iformall.utils.PressUtils; | |||
| import com.iformall.utils.RedisLock; | |||
| import com.iformall.utils.Utility; | |||
| @Service | |||
| public class WxOrderServiceImpl implements WxOrderService { | |||
| @@ -414,7 +506,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| * @param wxCouponSendVo | |||
| */ | |||
| private void stockMerchantReduce(WxCUser user, WxCoupon coupon, String couponIdStr, WxCouponSendVo wxCouponSendVo) { | |||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| // 库存加锁 | |||
| if (!redisLock.lock(couponIdStr, timeStr)) { | |||
| @@ -479,94 +571,165 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| } | |||
| } | |||
| /** | |||
| * 减库存 | |||
| * | |||
| * @param user | |||
| * @param coupon | |||
| * @param couponIdStr | |||
| */ | |||
| private void stockReduce(WxCUser user, WxCoupon coupon, String couponIdStr) { | |||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| // 库存加锁 | |||
| if (!redisLock.lock(couponIdStr, timeStr)) { | |||
| logger.error("此券被锁定, couponId: " + couponIdStr); | |||
| throw new MallinkException(ErrorCode.TOO_MANY_REQUEST); | |||
| } | |||
| // 检查 优惠券 库存 | |||
| if (coupon.getRemainInventory() <= 0) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| logger.error("此券库存为0, couponId: " + couponIdStr); | |||
| throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); | |||
| } | |||
| int count = 0; | |||
| // 有价券 | |||
| if (coupon.getSalePrice() > 0) { | |||
| // 检查是否未支付订单 | |||
| try { | |||
| count = getUserOrderCount(user, coupon); | |||
| } catch (Exception e) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count > 0) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| logger.error("此券有未支付的订单, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_UNPAID); | |||
| } | |||
| } | |||
| //检查拼团中的数量 | |||
| try { | |||
| count = getUserOrderGroupCount(user, coupon); | |||
| } catch (Exception e) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count >= coupon.getUseLimitQuantity()) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); | |||
| } | |||
| // 检查用户已购买数量 | |||
| try { | |||
| count = getUserCouponOrderCount(user, coupon); | |||
| } catch (Exception e) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count >= coupon.getUseLimitQuantity()) { | |||
| //解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); | |||
| } | |||
| try { | |||
| // 减库存 | |||
| int num = wxCouponMapper.reduceInventory(coupon.getId(), 1, coupon.getRemainInventory()); | |||
| if (num <= 0) { | |||
| logger.error("此券减库存失败, couponId: " + couponIdStr); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| } | |||
| } catch (RuntimeException e) { | |||
| logger.error("此券减库存失败, couponId: " + couponIdStr); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| } finally { | |||
| // 解锁 | |||
| redisLock.unlock(couponIdStr, timeStr); | |||
| } | |||
| } | |||
| * 减库存 | |||
| * | |||
| * @param user | |||
| * @param coupon | |||
| * @param couponIdStr | |||
| */ | |||
| private void stockReduce(WxCUser user, WxCoupon coupon, String couponIdStr) { | |||
| long redisStock = redisLock.getCouponStock(Long.parseLong(couponIdStr)); | |||
| if (redisStock<=0) { | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券库存已为零!"); | |||
| } | |||
| // 检查 优惠券 库存 | |||
| if (coupon.getRemainInventory() <= 0) { | |||
| throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); | |||
| } | |||
| int count = 0; | |||
| // 有价券 | |||
| if (coupon.getSalePrice() > 0) { | |||
| // 检查是否未支付订单 | |||
| try { | |||
| count = getUserOrderCount(user, coupon); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count > 0) { | |||
| logger.error("此券有未支付的订单, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_UNPAID); | |||
| } | |||
| } | |||
| //检查拼团中的数量 | |||
| try { | |||
| count = getUserOrderGroupCount(user, coupon); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count >= coupon.getUseLimitQuantity()) { | |||
| logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); | |||
| } | |||
| // 检查用户已购买数量 | |||
| try { | |||
| count = getUserCouponOrderCount(user, coupon); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| if (count >= coupon.getUseLimitQuantity()) { | |||
| logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| } | |||
| try { | |||
| //减库存,从redis中取,然后发mq消息同步到数据库 | |||
| long stock = redisLock.decrease(EnumCacheKey.COUPON_STOCK.getMessage()+coupon.getId(), 1); | |||
| if (stock < 0 ) { | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券库存已为零!"); | |||
| } | |||
| UpdateCouponStockMsg msg = new UpdateCouponStockMsg(); | |||
| msg.setCouponId(coupon.getId()); | |||
| msg.setNumber(1); | |||
| msg.setOperateType(UpdateCouponStockMsg.OPERATE_TYPE_DECREASE); | |||
| msg.setMsgType(EnumMsgRecordType.COUPON_STOCK.getCode()); | |||
| mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.STOCK.getCode(), "*", "decrease_stock_"+coupon.getId()); | |||
| } catch (RuntimeException e) { | |||
| logger.error("此券减库存失败, couponId: " + couponIdStr,e); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),e.getMessage()); | |||
| } | |||
| } | |||
| // /** | |||
| // * 减库存 | |||
| // * | |||
| // * @param user | |||
| // * @param coupon | |||
| // * @param couponIdStr | |||
| // */ | |||
| // private void stockReduce(WxCUser user, WxCoupon coupon, String couponIdStr) { | |||
| // long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| // String timeStr = String.valueOf(time); | |||
| // // 库存加锁 | |||
| // if (!redisLock.lock(couponIdStr, timeStr)) { | |||
| // logger.error("此券被锁定, couponId: " + couponIdStr); | |||
| // throw new MallinkException(ErrorCode.TOO_MANY_REQUEST); | |||
| // } | |||
| // | |||
| // // 检查 优惠券 库存 | |||
| // if (coupon.getRemainInventory() <= 0) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // logger.error("此券库存为0, couponId: " + couponIdStr); | |||
| // throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); | |||
| // } | |||
| // | |||
| // int count = 0; | |||
| // // 有价券 | |||
| // if (coupon.getSalePrice() > 0) { | |||
| // // 检查是否未支付订单 | |||
| // try { | |||
| // count = getUserOrderCount(user, coupon); | |||
| // } catch (Exception e) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // throw new MallinkException(ErrorCode.DB_FAIL); | |||
| // } | |||
| // if (count > 0) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // logger.error("此券有未支付的订单, couponId: " + couponIdStr + ", count: " + count); | |||
| // throw new MallinkException(ErrorCode.ORDER_UNPAID); | |||
| // } | |||
| // } | |||
| // //检查拼团中的数量 | |||
| // try { | |||
| // count = getUserOrderGroupCount(user, coupon); | |||
| // } catch (Exception e) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // throw new MallinkException(ErrorCode.DB_FAIL); | |||
| // } | |||
| // if (count >= coupon.getUseLimitQuantity()) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| // throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); | |||
| // } | |||
| // | |||
| // // 检查用户已购买数量 | |||
| // try { | |||
| // count = getUserCouponOrderCount(user, coupon); | |||
| // } catch (Exception e) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // throw new MallinkException(ErrorCode.DB_FAIL); | |||
| // } | |||
| // if (count >= coupon.getUseLimitQuantity()) { | |||
| // //解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); | |||
| // throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); | |||
| // } | |||
| // | |||
| // try { | |||
| // // 减库存 | |||
| // int num = wxCouponMapper.reduceInventory(coupon.getId(), 1); | |||
| // if (num <= 0) { | |||
| // logger.error("此券减库存失败, couponId: " + couponIdStr); | |||
| // throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| // } | |||
| // } catch (RuntimeException e) { | |||
| // logger.error("此券减库存失败, couponId: " + couponIdStr); | |||
| // throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| // } finally { | |||
| // // 解锁 | |||
| // redisLock.unlock(couponIdStr, timeStr); | |||
| // } | |||
| // } | |||
| @Override | |||
| public void stockBack(WxOrder updateOrder) { | |||
| @@ -575,7 +738,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| Long couponId = updateOrder.getProductId(); | |||
| String couponIdStr = "" + couponId; | |||
| //加锁 | |||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| if (!redisLock.lock(couponIdStr, timeStr)) { | |||
| @@ -600,8 +763,9 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| int num = wxCouponMapper.backInventory(coupon.getId(), 1, coupon.getRemainInventory()); | |||
| if (num <= 0) { | |||
| logger.error("此券加库存失败, couponId: " + couponIdStr); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券couponId:["+couponIdStr+"]库存回滚失败,更新记录条数小于等于0."); | |||
| } | |||
| redisLock.increase(EnumCacheKey.COUPON_STOCK.getMessage()+coupon.getId(), 1); | |||
| } catch (Exception e) { | |||
| logger.error("数据库更新失败,库存+1失败, e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "库存恢复失败"); | |||
| @@ -843,87 +1007,101 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| if (coupon.getType().equals(EnumCouponType.CARD_MULTIMCH.getCode())) { | |||
| isCard = true; | |||
| } | |||
| // TODO Stormeye 检查是否已经生成券, 微信回调并发问题 | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| WxCouponOrder couponOrder = new WxCouponOrder(); | |||
| couponOrder.setId(idWorker.nextId()); | |||
| couponOrder.updateTenantInfo(order); | |||
| couponOrder.setCouponId(order.getProductId()); | |||
| couponOrder.setCouponType(coupon.getType()); | |||
| couponOrder.setCUserId(user.getId()); | |||
| couponOrder.setOwnerId(user.getId()); | |||
| couponOrder.setAutoRefund(coupon.getAutoRefund()); | |||
| couponOrder.setOrderId(order.getOrderNumber()); | |||
| couponOrder.setExpiredTime(valid_date); | |||
| if (!isCard) { | |||
| couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode()); | |||
| } else { | |||
| couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_USING.getCode()); | |||
| //TODO 如果orderId已经存在,则不再添加 | |||
| WxCouponOrder couponOrderQ = new WxCouponOrder(); | |||
| couponOrderQ.setOrderId(order.getId()); | |||
| WxCouponOrder couponOrder = null; | |||
| List<WxCouponOrder> couponorderlist = wxCouponOrderMapper.findList(couponOrderQ); | |||
| if (null != couponorderlist && couponorderlist.size() > 0 ) { | |||
| couponOrder = couponorderlist.get(0); | |||
| }else { | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| couponOrder = new WxCouponOrder(); | |||
| couponOrder.setId(idWorker.nextId()); | |||
| couponOrder.updateTenantInfo(order); | |||
| couponOrder.setCouponId(order.getProductId()); | |||
| couponOrder.setCouponType(coupon.getType()); | |||
| couponOrder.setCUserId(user.getId()); | |||
| couponOrder.setOwnerId(user.getId()); | |||
| couponOrder.setAutoRefund(coupon.getAutoRefund()); | |||
| couponOrder.setOrderId(order.getOrderNumber()); | |||
| couponOrder.setExpiredTime(valid_date); | |||
| if (!isCard) { | |||
| couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode()); | |||
| } else { | |||
| couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_USING.getCode()); | |||
| } | |||
| couponOrder.setCreateDate(curr); | |||
| couponOrder.setUpdateDate(curr); | |||
| couponOrder.setCouponPrice(order.getPayment()); | |||
| wxCouponOrderMapper.insert(couponOrder); | |||
| } | |||
| couponOrder.setCreateDate(curr); | |||
| couponOrder.setUpdateDate(curr); | |||
| couponOrder.setCouponPrice(order.getPayment()); | |||
| wxCouponOrderMapper.insert(couponOrder); | |||
| /// 储值卡信息添加 | |||
| if (isCard) { | |||
| Integer fee = 0; | |||
| WxCardInfo cardInfo = new WxCardInfo(); | |||
| cardInfo.setId(couponOrder.getId()); | |||
| cardInfo.updateTenantInfo(order); | |||
| cardInfo.setCouponId(order.getProductId()); | |||
| cardInfo.setAmount(coupon.getPrice()); | |||
| cardInfo.setSaleAmount(coupon.getSalePrice()); | |||
| cardInfo.setRemainingAmount(coupon.getPrice()); | |||
| if (!coupon.checkIsFree()) { | |||
| // 有价卡 | |||
| cardInfo.setTransactionId(payOrder.getTransactionId()); | |||
| if (payOrder.getShareAmount() != null) { | |||
| // 开启分账 | |||
| fee = payOrder.getPayAmount() - payOrder.getShareAmount(); | |||
| cardInfo.setShareFeeAmount(payOrder.getShareAmount()); | |||
| cardInfo.setRemainingShareFeeAmount(payOrder.getShareAmount()); | |||
| cardInfo.setRateAmount(payOrder.getRateAmount()); | |||
| } else { | |||
| // 未开启分账 | |||
| fee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRate(), false); | |||
| Integer shareAmount = payOrder.getPayAmount() - fee; | |||
| cardInfo.setShareFeeAmount(shareAmount); | |||
| cardInfo.setRemainingShareFeeAmount(shareAmount); | |||
| if (payAccount.getRealRate() != null) { | |||
| int iRealChargeFee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRealRate(), true); | |||
| if (fee > iRealChargeFee) { | |||
| cardInfo.setRateAmount(fee - iRealChargeFee); | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| // 免费卡 | |||
| cardInfo.setShareFeeAmount(0); | |||
| cardInfo.setRemainingShareFeeAmount(0); | |||
| cardInfo.setRateAmount(0); | |||
| if (coupon.getPasswordSupport().equals(EnumCouponPasswordSupport.SUPPORTED.getCode())) { | |||
| WxCouponPassword updateCPwd = new WxCouponPassword(); | |||
| updateCPwd.setId(couponPasswordId); | |||
| updateCPwd.setCardId(cardInfo.getId()); | |||
| updateCPwd.setStatus(EnumCouponPasswordStatus.USED.getCode()); | |||
| couponPasswordMapper.updateById(updateCPwd); | |||
| } | |||
| } | |||
| cardInfo.setServiceFeeAmount(fee); | |||
| cardInfo.setCreateDate(curr); | |||
| cardInfo.setUpdateDate(curr); | |||
| cardInfo.setSupportTransfer(coupon.getSupportTransfer()); | |||
| //检查卡是否下架,如果是,不可转赠 | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(order.getCouponChannelId()); | |||
| if (wxCouponChannel != null && wxCouponChannel.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())) { | |||
| cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); | |||
| } | |||
| wxCardInfoMapper.insert(cardInfo); | |||
| //判断该transctionId是否已经存在,如果存在,则不添加 | |||
| WxCardInfo cardInfoq = new WxCardInfo(); | |||
| cardInfoq.setTransactionId(payOrder.getTransactionId()); | |||
| List<WxCardInfo> cardInfoList = wxCardInfoMapper.findList(cardInfoq); | |||
| if (null != cardInfoList && cardInfoList.size() > 0) { | |||
| //do nothing | |||
| }else { | |||
| Integer fee = 0; | |||
| WxCardInfo cardInfo = new WxCardInfo(); | |||
| cardInfo.setId(couponOrder.getId()); | |||
| cardInfo.updateTenantInfo(order); | |||
| cardInfo.setCouponId(order.getProductId()); | |||
| cardInfo.setAmount(coupon.getPrice()); | |||
| cardInfo.setSaleAmount(coupon.getSalePrice()); | |||
| cardInfo.setRemainingAmount(coupon.getPrice()); | |||
| if (!coupon.checkIsFree()) { | |||
| // 有价卡 | |||
| cardInfo.setTransactionId(payOrder.getTransactionId()); | |||
| if (payOrder.getShareAmount() != null) { | |||
| // 开启分账 | |||
| fee = payOrder.getPayAmount() - payOrder.getShareAmount(); | |||
| cardInfo.setShareFeeAmount(payOrder.getShareAmount()); | |||
| cardInfo.setRemainingShareFeeAmount(payOrder.getShareAmount()); | |||
| cardInfo.setRateAmount(payOrder.getRateAmount()); | |||
| } else { | |||
| // 未开启分账 | |||
| fee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRate(), false); | |||
| Integer shareAmount = payOrder.getPayAmount() - fee; | |||
| cardInfo.setShareFeeAmount(shareAmount); | |||
| cardInfo.setRemainingShareFeeAmount(shareAmount); | |||
| if (payAccount.getRealRate() != null) { | |||
| int iRealChargeFee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRealRate(), true); | |||
| if (fee > iRealChargeFee) { | |||
| cardInfo.setRateAmount(fee - iRealChargeFee); | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| // 免费卡 | |||
| cardInfo.setShareFeeAmount(0); | |||
| cardInfo.setRemainingShareFeeAmount(0); | |||
| cardInfo.setRateAmount(0); | |||
| if (coupon.getPasswordSupport().equals(EnumCouponPasswordSupport.SUPPORTED.getCode())) { | |||
| WxCouponPassword updateCPwd = new WxCouponPassword(); | |||
| updateCPwd.setId(couponPasswordId); | |||
| updateCPwd.setCardId(cardInfo.getId()); | |||
| updateCPwd.setStatus(EnumCouponPasswordStatus.USED.getCode()); | |||
| couponPasswordMapper.updateById(updateCPwd); | |||
| } | |||
| } | |||
| cardInfo.setServiceFeeAmount(fee); | |||
| cardInfo.setCreateDate(curr); | |||
| cardInfo.setUpdateDate(curr); | |||
| cardInfo.setSupportTransfer(coupon.getSupportTransfer()); | |||
| //检查卡是否下架,如果是,不可转赠 | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(order.getCouponChannelId()); | |||
| if (wxCouponChannel != null && wxCouponChannel.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())) { | |||
| cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); | |||
| } | |||
| wxCardInfoMapper.insert(cardInfo); | |||
| } | |||
| } | |||
| return couponOrder; | |||
| } | |||
| @@ -1151,6 +1329,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| orderSuccess.setOrderId(updateOrder.getId()); | |||
| orderSuccess.setCUserId(user.getId()); | |||
| orderSuccess.setCouponId(coupon.getId()); | |||
| logger.info(">>>>>>>>>>>send sendInsideOrderSuccessMsg :"+orderSuccess); | |||
| mqBaseProducer.sendMessage(orderSuccess, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); | |||
| } | |||
| @@ -1179,6 +1358,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| jo = JSONObject.parseObject(coupon.getConditions()); | |||
| } catch (Exception e) { | |||
| logger.error("购买券条件判断错误:ID=" + coupon.getId() + e.getMessage()); | |||
| e.printStackTrace(); | |||
| } | |||
| if (jo != null) { | |||
| if (jo.getIntValue("type") == EnumCouponConditionType.NEW_MEMBER.getCode()) { | |||
| @@ -1716,6 +1896,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| throw new MallinkException(ErrorCode.SYS_REPEAT_SUBMIT_EXCEPTION); | |||
| } | |||
| cUserTokenRedisTemplate.opsForValue().set(key, user, 1000, TimeUnit.MILLISECONDS); | |||
| order = saveFreeOrderForCoupon(user, coupon, orderSaveDto.getCouponChannelId(), orderSaveDto.getFormId(), null); | |||
| if (order != null) { | |||
| // 6. 下订单完成,发送内部消息 | |||
| @@ -1944,7 +2125,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| // 2. 拼团检查 | |||
| if (isOrderGroup(orderGroupId)) { | |||
| checkOrderGroup(user, orderGroupId); | |||
| checkOrderGroup(user, orderGroupId,coupon); | |||
| } | |||
| String couponIdStr = String.valueOf(coupon.getId()); | |||
| // 3. 减库存操作 | |||
| @@ -2075,16 +2256,27 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| return orderNumber; | |||
| } | |||
| private void checkOrderGroup(WxCUser user, Long orderGroupId) { | |||
| private void checkOrderGroup(WxCUser user, Long orderGroupId,WxCoupon coupon) { | |||
| WxOrderGroup group = wxOrderGroupMapper.selectById(orderGroupId); | |||
| if (group.getStatus().equals(EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode())) { | |||
| logger.error("下订单拼团人数已满>>>" + orderGroupId); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED); | |||
| } | |||
| if (group.getRemainPeople()<=0) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED.getCode(),"下单人数已满"); | |||
| } | |||
| //判断拼团人数是否已经超出限制 | |||
| int groupCount = countGroupOrder(orderGroupId,true); | |||
| if (groupCount>=coupon.getPressLimitNum()) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED.getCode(),"下单人数超出优惠券人数限制!"); | |||
| } | |||
| WxOrder order = new WxOrder(); | |||
| order.setOrderGroupId(group.getId()); | |||
| order.setCUserId(user.getId()); | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| //order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| long count = wxOrderMapper.selectCount(new QueryWrapper(order)); | |||
| if (count > 0) { | |||
| logger.error("重复的拼团>>>" + orderGroupId); | |||
| @@ -2096,5 +2288,32 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| return orderGroupId != null && !orderGroupId.equals(0L); | |||
| } | |||
| @Override | |||
| public int countGroupOrder(Long groupId,boolean ignoreUnPay) { | |||
| WxOrder query = new WxOrder(); | |||
| query.setOrderGroupId(groupId); | |||
| List<Integer> statusS = new ArrayList<Integer>(); | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode()); | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()); | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode()); | |||
| if (!ignoreUnPay) { | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); | |||
| } | |||
| query.setStatusS(statusS); | |||
| return wxOrderMapper.countList(query); | |||
| } | |||
| @Override | |||
| public int countUserCouponGroupOrder(Long cuserId, Long couponId) { | |||
| WxOrder query = new WxOrder(); | |||
| query.setCUserId(cuserId); | |||
| query.setProductId(couponId); | |||
| List<Integer> statusS = new ArrayList<Integer>(); | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()); | |||
| statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode()); | |||
| query.setStatusS(statusS); | |||
| return wxOrderMapper.countList(query); | |||
| } | |||
| } | |||
| @@ -3,8 +3,11 @@ package com.iformall.service.impl; | |||
| import java.util.*; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxMall; | |||
| import com.iformall.domain.po.WxPark; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.mapper.WxParkMapper; | |||
| import com.iformall.service.WxMallService; | |||
| import com.iformall.service.WxParkService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| @@ -19,6 +22,25 @@ public class WxParkServiceImpl implements WxParkService { | |||
| @Autowired | |||
| WxParkMapper wxParkMapper; | |||
| @Autowired | |||
| WxMallService wxMallService; | |||
| @Override | |||
| public void wxParkInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| WxMall byTenantId = wxMallService.getByTenantId(tenantId); | |||
| WxPark wxPark = new WxPark(); | |||
| wxPark.setVendorParams("{}"); | |||
| wxPark.setCreateDate(new Date()); | |||
| wxPark.setUpdateDate(new Date()); | |||
| wxPark.setAddr(wxProjectConfig.getName()); | |||
| wxPark.setTenantId(tenantId); | |||
| wxPark.setNumber(byTenantId.getParkPlaceNumber()); | |||
| wxPark.setVendorType(0); | |||
| wxPark.setParkId("0"); | |||
| wxPark.setEntryExit(1); | |||
| wxPark.setStopFee(""); | |||
| wxParkMapper.insert(wxPark); | |||
| } | |||
| @Override | |||
| public PageInfo<WxPark> listAsPage(WxPark record, Integer pageIndex, Integer pageSize) { | |||
| @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| import com.iformall.mapper.WxBillPropertyMapper; | |||
| @@ -28,6 +29,23 @@ public class WxPayAccountBillServiceImpl implements WxPayAccountBillService { | |||
| @Autowired | |||
| WxBillPropertyMapper wxBillPropertyMapper; | |||
| @Override | |||
| public Long wxPayAccountInit(WxPayAccount wxPayAccount) { | |||
| WxPayAccountBill wxPayAccountBill = new WxPayAccountBill(); | |||
| wxPayAccountBill.setTenantId(wxPayAccount.getTenantId()); | |||
| wxPayAccountBill.setMchId(wxPayAccount.getMchId()); | |||
| wxPayAccountBill.setSubMchId(wxPayAccount.getSubMchId()); | |||
| wxPayAccountBill.setApiKey(wxPayAccount.getApiKey()); | |||
| wxPayAccountBill.setNotifyUrl(wxPayAccount.getNotifyUrl()); | |||
| wxPayAccountBill.setCertPath(wxPayAccount.getCertPath()); | |||
| wxPayAccountBill.setType(wxPayAccount.getType()); | |||
| wxPayAccountBill.setShare(!(wxPayAccount.getShare() == 0)); | |||
| wxPayAccountBill.setRate(wxPayAccount.getRate()); | |||
| wxPayAccountBill.setRealRate(wxPayAccount.getRealRate()); | |||
| wxPayAccountBillMapper.insert(wxPayAccountBill); | |||
| return wxPayAccountBill.getId(); | |||
| } | |||
| @Override | |||
| public PageInfo<WxPayAccountBill> listAsPage(WxPayAccountBill record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxPayAccountBillMapper.findList(record)); | |||
| @@ -3,6 +3,7 @@ package com.iformall.service.impl; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.WxProjectConfig; | |||
| import com.iformall.mapper.WxPayAccountMapper; | |||
| import com.iformall.service.WxPayAccountService; | |||
| import org.slf4j.Logger; | |||
| @@ -19,6 +20,25 @@ public class WxPayAccountServiceImpl implements WxPayAccountService { | |||
| WxPayAccountMapper wxPayAccountMapper; | |||
| @Override | |||
| public WxPayAccount wxPayAccountInit(String tenantId, WxProjectConfig wxProjectConfig) { | |||
| WxPayAccount wxPayAccount = new WxPayAccount(); | |||
| wxPayAccount.setTenantId(tenantId); | |||
| wxPayAccount.setMchId(wxProjectConfig.getMchId()); | |||
| wxPayAccount.setSubMchId(wxProjectConfig.getSubMchId()); | |||
| wxPayAccount.setApiKey(wxProjectConfig.getApiKey()); | |||
| //默认------------------------------------------------------------- | |||
| wxPayAccount.setNotifyUrl("https://admin.malls.iformall.com/wxPay/notify"); | |||
| wxPayAccount.setCertPath("/opt/iformall/service/apiclient_cert.p12"); | |||
| //---------------------------------------------------------------- | |||
| wxPayAccount.setType(1);//0:普通商户模式, 1:服务商模式(默认服务商模式) | |||
| wxPayAccount.setShare(0);//0: 未分账,1:分账(默认不分账) | |||
| wxPayAccount.setRate(wxProjectConfig.getRate()); | |||
| wxPayAccount.setRealRate(wxProjectConfig.getRealRate()); | |||
| wxPayAccountMapper.insert(wxPayAccount); | |||
| return wxPayAccount; | |||
| } | |||
| @Override | |||
| public PageInfo<WxPayAccount> listAsPage(WxPayAccount record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxPayAccountMapper.findList(record)); | |||
| @@ -17,10 +17,12 @@ import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.pay.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.service.helper.WxPayOrderServiceHelper; | |||
| import com.iformall.utils.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.aop.framework.AopContext; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| @@ -33,6 +35,9 @@ import java.util.*; | |||
| public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| WxPayOrderServiceImpl wxPayOrderServiceImpl; | |||
| @Autowired | |||
| WxAppinfoMapper wxAppinfoMapper; | |||
| @@ -113,9 +118,108 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| "\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||
| "\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"reason\":\"请检查XML参数格式是否正确\"}}"); | |||
| //方法必须为public AopContext.currentProxy() | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| @Override | |||
| public void handleSuccessOrder(WxPayOrder oldRecord,WxOrder order,Map<String, String> retMap,boolean isScheduleTask) { | |||
| Date curDate = new Date(); | |||
| if (oldRecord.getPayOrderStatus() != EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { | |||
| //因为此处是处理订单支付成功了但是订单状态为未支付成功的异常状态,库存不应该再扣减 | |||
| //更新wxPayOrder | |||
| oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); | |||
| String timEndStr = retMap.get("time_end"); | |||
| Date timeEnd = null; | |||
| try { | |||
| timeEnd = Utility.getDateFromString(timEndStr); | |||
| } catch (ParseException e) { | |||
| logger.error("解析timeEnd失败"); | |||
| timeEnd = new Date(); | |||
| } | |||
| oldRecord.setPayTimeEnd(timeEnd); | |||
| oldRecord.setPayEndFrom(EnumPayEndFrom.QUERY.getCode()); | |||
| String transactionId = retMap.get("transaction_id"); | |||
| oldRecord.setTransactionId(transactionId); | |||
| oldRecord.setUpdateTime(curDate); | |||
| wxPayOrderMapper.updateById(oldRecord); | |||
| //处理其他信息 | |||
| WxCoupon wxCoupon = wxCouponMapper.selectById(order.getProductId()); | |||
| if(wxCoupon != null) { | |||
| if (isOrderGroupCoupon(oldRecord, wxCoupon)) { | |||
| // 如果是Coupon是拼团, 创建拼团信息, 不创建COUPON_ORDER | |||
| try { | |||
| wxOrderGroupService.createOrderGroup(order, wxCoupon,isScheduleTask); | |||
| } catch (Exception e) { | |||
| logger.error("参团失败" + e.getMessage()); | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); | |||
| order.setUpdateDate(new Date()); | |||
| wxOrderMapper.updateById(order); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); | |||
| } | |||
| } else { | |||
| // 普通券, 修改订单状态 | |||
| try { | |||
| wxOrderService.couponOrderSuccess(order); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "订单更新"); | |||
| } | |||
| // 下订单完成,发送内部消息 | |||
| try { | |||
| wxOrderService.sendOrderSuccessActionMsg(order); | |||
| } catch (Exception e) { | |||
| logger.error("内部消息发送失败: " + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.MSG_INSIDE_ERROR); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public WxPayOrder handleWxOrderQuery(WxPayOrder oldRecord,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount,IdWorker idworker,boolean repeatPay) { | |||
| Map<String, String> retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(oldRecord, order, appInfo, payAccount); | |||
| int wxpaystatus = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, oldRecord.getPayOrderNo()); | |||
| //Map<String, String> retMap = new HashMap<String, String>(); | |||
| //retMap.put("time_end","2020-6-18 10:48:20"); | |||
| //retMap.put("transaction_id","asdasdasdasdasd"); | |||
| //int wxpaystatus = EnumPayStatus.PAY_STATUS_SUCCESS.getCode(); | |||
| if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode()==wxpaystatus) { | |||
| //直接调用不会触发事务,spring事务基于AOP代理 | |||
| WxPayOrderServiceImpl proxy = (WxPayOrderServiceImpl) AopContext.currentProxy(); | |||
| proxy.handleSuccessOrder(oldRecord,order,retMap,false); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_EXIST.getCode(),"该订单已经支付,请勿重复支付!"); | |||
| }else if (EnumPayStatus.PAY_STATUS_REFUND.getCode()==wxpaystatus) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_REFUND.getCode(),"该订单已经退款,无法支付!"); | |||
| }else if (EnumPayStatus.PAY_STATUS_CLOSE.getCode()==wxpaystatus) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_CLOSED.getCode(),"该订单已经关闭,无法支付!"); | |||
| }else if (EnumPayStatus.PAY_STATUS_REVERSE.getCode()==wxpaystatus) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_REVERSE.getCode(),"该订单已撤销,无法支付!"); | |||
| }else if (EnumPayStatus.PAY_STATUS_WAIT.getCode()==wxpaystatus) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单支付中,请勿重复支付!"); | |||
| }else if (EnumPayStatus.PAY_STATUS_NOTPAY.getCode()==wxpaystatus || EnumPayStatus.PAY_STATUS_FAIL.getCode()==wxpaystatus) { | |||
| //支付调用,支付遇到问题,可以重复支付 | |||
| if (repeatPay) { | |||
| if (oldRecord.getPayOrderStatus()!=EnumPayStatus.PAY_STATUS_WAIT.getCode()) { | |||
| oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| int sqlRow0 =wxPayOrderMapper.updateById(oldRecord); | |||
| if (sqlRow0 != 1) { | |||
| logger.error("pay order update error: " + oldRecord.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| } | |||
| } | |||
| return oldRecord; | |||
| } | |||
| return null; | |||
| } | |||
| @Override | |||
| public ResultData createPayOrder(WxAppinfo appInfo, WxCUser user, WxPayOrder record, EnumPayWay payWay) { | |||
| final IdWorker idworker = IdWorker.get(); | |||
| IdWorker idworker = IdWorker.get(); | |||
| EnumPayShare isShare = EnumPayShare.NO; | |||
| @@ -134,11 +238,19 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| WxOrder orderParams = new WxOrder(); | |||
| orderParams.setOrderGroupId(order.getOrderGroupId()); | |||
| orderParams.setCUserId(user.getId()); | |||
| orderParams.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()); | |||
| int count = wxOrderMapper.selectCount(new QueryWrapper(orderParams)); | |||
| if (count > 0) { | |||
| logger.error("重复的拼团>>>" + order); | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_ATTEND); | |||
| List<WxOrder> olist = wxOrderMapper.findList(orderParams); | |||
| if (olist == null || olist.size() <=0 ) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"未查询到参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); | |||
| } | |||
| if (olist.size() != 1) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团订单多条[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); | |||
| } | |||
| WxOrder orderq = olist.get(0); | |||
| if (null == orderq) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"未查询到参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); | |||
| } | |||
| if (orderq.getOrderStatus()==EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()) { | |||
| throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_ATTEND.getCode(),"不能重复参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); | |||
| } | |||
| } | |||
| @@ -180,82 +292,121 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| isShare = EnumPayShare.YES; | |||
| } | |||
| // 1.5 检查是否有已支付订单 | |||
| { | |||
| WxPayOrder payOrderParams = new WxPayOrder(); | |||
| payOrderParams.setOrderId(order.getId()); | |||
| payOrderParams.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); | |||
| QueryWrapper<WxPayOrder> queryWrapper = new QueryWrapper<>(); | |||
| queryWrapper.setEntity(payOrderParams); | |||
| int count = wxPayOrderMapper.selectCount(queryWrapper); | |||
| if (count > 0) { | |||
| logger.error("已支付>>>" + order); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); | |||
| } | |||
| } | |||
| // // 1.5 检查是否有已支付订单 | |||
| // { | |||
| // WxPayOrder payOrderParams = new WxPayOrder(); | |||
| // payOrderParams.setOrderId(order.getId()); | |||
| // payOrderParams.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); | |||
| // QueryWrapper<WxPayOrder> queryWrapper = new QueryWrapper<>(); | |||
| // queryWrapper.setEntity(payOrderParams); | |||
| // int count = wxPayOrderMapper.selectCount(queryWrapper); | |||
| // if (count > 0) { | |||
| // logger.error("已支付>>>" + order); | |||
| // throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); | |||
| // } | |||
| // } | |||
| // | |||
| // /*设置进入分账,待分账时再判断是否存在对应的分账账户 | |||
| // // 1.5 check 分账 receive | |||
| // if (isShare == EnumPayShare.YES) { | |||
| // WxProfitSharingReceiver receiver = new WxProfitSharingReceiver(); | |||
| // receiver.setMerchantId(order.getMerchantId()); | |||
| // List<WxProfitSharingReceiver> merList = wxProfitSharingReceiverMapper.findList(receiver); | |||
| // if (merList.size() > 0) { | |||
| // isShare = EnumPayShare.YES; | |||
| // } else { | |||
| // isShare = EnumPayShare.NO; | |||
| // } | |||
| // } | |||
| // */ | |||
| // | |||
| // //支付中的订单, 都是已经点过支付的订单,要等微信通知更新,不能再操作。 | |||
| // record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| // List<WxPayOrder> list = wxPayOrderMapper.findList(record); | |||
| // if (list.size() > 0) { | |||
| // logger.error("支付状态等待微信同步中>>>" + order); | |||
| // throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付状态等待微信同步中"); | |||
| // // 3.0 已有支付订单,关闭之前的 | |||
| // //payOrderClose(appInfo, list.get(0)); | |||
| // } | |||
| /*设置进入分账,待分账时再判断是否存在对应的分账账户 | |||
| // 1.5 check 分账 receive | |||
| if (isShare == EnumPayShare.YES) { | |||
| WxProfitSharingReceiver receiver = new WxProfitSharingReceiver(); | |||
| receiver.setMerchantId(order.getMerchantId()); | |||
| List<WxProfitSharingReceiver> merList = wxProfitSharingReceiverMapper.findList(receiver); | |||
| if (merList.size() > 0) { | |||
| isShare = EnumPayShare.YES; | |||
| } else { | |||
| isShare = EnumPayShare.NO; | |||
| } | |||
| } | |||
| */ | |||
| // 2. check 是否有支付中订单 | |||
| Date currentDate = new Date(); | |||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| List<WxPayOrder> list = wxPayOrderMapper.findList(record); | |||
| String payOrderNo = ""; | |||
| if (list.size() > 0) { | |||
| // 3.0 已有支付订单,关闭之前的 | |||
| payOrderClose(appInfo, list.get(0)); | |||
| //一个订单只有一条支付记录。 | |||
| WxPayOrder orderq = new WxPayOrder(); | |||
| orderq.setOrderId(record.getOrderId()); | |||
| List<WxPayOrder> list = wxPayOrderMapper.findList(orderq); | |||
| WxPayOrder oldRecord = null; | |||
| if (null != list && list.size() > 0) { | |||
| oldRecord = list.get(0); | |||
| } | |||
| { | |||
| // 3.1 创建支付订单 | |||
| Long id = idworker.nextId(); | |||
| payOrderNo = String.valueOf(id); | |||
| record.setId(id); | |||
| record.updateTenantInfo(order); | |||
| record.setCUserId(user.getId()); | |||
| record.setCreateTime(currentDate); | |||
| record.setUpdateTime(currentDate); | |||
| record.setPayTimeStart(currentDate); | |||
| record.setPayTimeEnd(currentDate); | |||
| // 支付单号 | |||
| record.setPayOrderNo(payOrderNo); | |||
| record.setPayAmount(order.getPayment()); | |||
| record.setPayVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); | |||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| record.setShare(isShare.getCode()); | |||
| if (isShare == EnumPayShare.YES) { | |||
| // 分账金额 | |||
| int iChargeFee = PayUtils.getPayRate(record.getPayAmount(), payAccount.getRate(), false); | |||
| Integer share_amount = record.getPayAmount() - iChargeFee; | |||
| record.setShareAmount(share_amount); | |||
| if(payAccount.getRealRate() != null) { | |||
| int iRealChargeFee = PayUtils.getPayRate(record.getPayAmount(), payAccount.getRealRate(), true); | |||
| if(iChargeFee > iRealChargeFee) { | |||
| record.setRateAmount(iChargeFee - iRealChargeFee); | |||
| } | |||
| } | |||
| } | |||
| int sqlRow = wxPayOrderMapper.insert(record); | |||
| if (sqlRow != 1) { | |||
| logger.error("pay order insert error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| if (null != oldRecord) { | |||
| //如果是已经支付成功,则不能再次支付。如果是支付中的,也不能再次支付,等待微信同步结果 | |||
| if (oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { | |||
| logger.error("已支付>>>" + order); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); | |||
| //如果是支付中的,则调用微信接口查询支付状态 | |||
| }else if (oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_WAIT.getCode()) { | |||
| record = handleWxOrderQuery(oldRecord,order,appInfo,payAccount,idworker,true); | |||
| if (null == record) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单微信查询支付状态失败!"); | |||
| } | |||
| //如果是支付错误,可以重新支付 | |||
| }else if(oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_FAIL.getCode()|| | |||
| oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_NOTPAY.getCode()) { | |||
| oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| int sqlRow0 = wxPayOrderMapper.updateById(oldRecord); | |||
| if (sqlRow0 != 1) { | |||
| logger.error("pay order update error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| record = oldRecord; | |||
| }else { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单状态不允许支付!"); | |||
| } | |||
| }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); | |||
| } | |||
| record.setId(id); | |||
| record.updateTenantInfo(order); | |||
| record.setCUserId(user.getId()); | |||
| record.setCreateTime(currentDate); | |||
| record.setUpdateTime(currentDate); | |||
| record.setPayTimeStart(currentDate); | |||
| record.setPayTimeEnd(currentDate); | |||
| // 支付单号 | |||
| record.setPayOrderNo(String.valueOf(id)); | |||
| record.setPayAmount(order.getPayment()); | |||
| record.setPayFrom(payWay.getCode()); | |||
| record.setPayVendor(payWay.getCode()); | |||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); | |||
| record.setShare(isShare.getCode()); | |||
| if (isShare == EnumPayShare.YES) { | |||
| // 分账金额 | |||
| int iChargeFee = PayUtils.getPayRate(record.getPayAmount(), payAccount.getRate(), false); | |||
| Integer share_amount = record.getPayAmount() - iChargeFee; | |||
| record.setShareAmount(share_amount); | |||
| if(payAccount.getRealRate() != null) { | |||
| int iRealChargeFee = PayUtils.getPayRate(record.getPayAmount(), payAccount.getRealRate(), true); | |||
| if(iChargeFee > iRealChargeFee) { | |||
| record.setRateAmount(iChargeFee - iRealChargeFee); | |||
| } | |||
| } | |||
| } | |||
| int sqlRow = wxPayOrderMapper.insert(record); | |||
| if (sqlRow != 1) { | |||
| logger.error("pay order insert error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| } | |||
| } | |||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||
| // 统一下单 普通商户模式 | |||
| String noncestr = Utility.generate32UUID(); | |||
| @@ -281,7 +432,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | |||
| logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| returnMap.put("payOrderId", payOrderNo); | |||
| returnMap.put("payOrderId", String.valueOf(record.getId())); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String prepay_id = returnMap.get("prepay_id"); | |||
| @@ -361,7 +512,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderSP)); | |||
| logger.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| returnMap.put("payOrderId", payOrderNo); | |||
| returnMap.put("payOrderId", String.valueOf(record.getId())); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String prepay_id = returnMap.get("prepay_id"); | |||
| @@ -411,8 +562,10 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| } | |||
| } | |||
| } catch (RuntimeException e) { | |||
| logger.error("createwxpayorder error:",e); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error("createwxpayorder error:",e); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| @@ -635,65 +788,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| } | |||
| } | |||
| private String wechatPayOrderQuery(WxAppinfo appInfo, WxPayOrder record) { | |||
| // get payAccount | |||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | |||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||
| // 普通商户号模式 | |||
| WxPayOrderQ payOrderQ = new WxPayOrderQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payOrderQ.setAppid(appInfo.getAppId()); | |||
| payOrderQ.setMch_id(payAccount.getMchId()); | |||
| payOrderQ.setNonce_str(noncestr); | |||
| if (StringUtils.isNotBlank(record.getTransactionId())) { | |||
| payOrderQ.setTransaction_id(record.getTransactionId()); | |||
| } else { | |||
| payOrderQ.setOut_trade_no(record.getPayOrderNo()); | |||
| } | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payOrderQ); | |||
| payOrderQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payOrderQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } else { | |||
| // 服务商模式 | |||
| WxPayOrderSQ payOrderSQ = new WxPayOrderSQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payOrderSQ.setAppid(appInfo.getParentAppId()); | |||
| payOrderSQ.setSub_appid(appInfo.getAppId()); | |||
| payOrderSQ.setMch_id(payAccount.getMchId()); | |||
| payOrderSQ.setSub_mch_id(payAccount.getSubMchId()); | |||
| payOrderSQ.setNonce_str(noncestr); | |||
| if (StringUtils.isNotBlank(record.getTransactionId())) { | |||
| payOrderSQ.setTransaction_id(record.getTransactionId()); | |||
| } else { | |||
| payOrderSQ.setOut_trade_no(record.getPayOrderNo()); | |||
| } | |||
| payOrderSQ.setSign_type("HMAC-SHA256"); | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payOrderSQ); | |||
| payOrderSQ.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payOrderSQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 微信订单查询 | |||
| */ | |||
| @@ -719,7 +813,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record); | |||
| String response = wechatPayOrderQuery(appInfo, record); | |||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | |||
| String response = WxPayOrderServiceHelper.wechatPayOrderQuery(appInfo, record,payAccount); | |||
| logger.info("pay order query, " + record.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| @@ -1289,7 +1384,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| if (isOrderGroupCoupon(record, wxCoupon)) { | |||
| // 如果是Coupon是拼团, 创建拼团信息, 不创建COUPON_ORDER | |||
| try { | |||
| wxOrderGroupService.createOrderGroup(order, wxCoupon); | |||
| wxOrderGroupService.createOrderGroup(order, wxCoupon,false); | |||
| } catch (Exception e) { | |||
| logger.error("参团失败" + e.getMessage()); | |||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); | |||
| @@ -1316,7 +1411,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| } | |||
| } | |||
| private boolean isOrderGroupCoupon(WxPayOrder record, WxCoupon wxCoupon) { | |||
| @Override | |||
| public boolean isOrderGroupCoupon(WxPayOrder record, WxCoupon wxCoupon) { | |||
| return wxCoupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode()) && wxCoupon.getSalePrice().equals(record.getPayAmount()); | |||
| } | |||
| @@ -1617,7 +1713,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| // 回调未返回,主动检查支付订单状态 | |||
| try { | |||
| record.setPayOrderNo(String.valueOf(record.getId())); | |||
| String response = wechatPayOrderQuery(appInfo, record); | |||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | |||
| String response = WxPayOrderServiceHelper.wechatPayOrderQuery(appInfo, record,payAccount); | |||
| logger.info("pay order query, " + record.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| @@ -0,0 +1,133 @@ | |||
| package com.iformall.service.impl; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONArray; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.utils.PasswordHelper; | |||
| 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.Transactional; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| @Service | |||
| public class WxProjectConfigServiceImpl implements WxProjectConfigService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| WxProjectConfigMapper wxProjectConfigMapper; | |||
| @Autowired | |||
| WxMallService wxMallService; | |||
| @Autowired | |||
| WxCouponSendConfigService wxCouponSendConfigService; | |||
| @Autowired | |||
| WxMallBuildingService wxMallBuildingService; | |||
| @Autowired | |||
| WxPayAccountService wxPayAccountService; | |||
| @Autowired | |||
| WxPayAccountBillService wxPayAccountBillService; | |||
| @Autowired | |||
| WxAppinfoService wxAppinfoService; | |||
| @Autowired | |||
| WxAuthorizerInfoService wxAuthorizerInfoService; | |||
| @Autowired | |||
| MallUserInfoService mallUserInfoService; | |||
| @Autowired | |||
| MallRoleService mallRoleService; | |||
| @Autowired | |||
| WxMsgConfigService wxMsgConfigService; | |||
| @Autowired | |||
| WxParkService wxParkService; | |||
| @Autowired | |||
| WxScoreRulesService wxScoreRulesService; | |||
| @Autowired | |||
| WxTemplateMsgService wxTemplateMsgService; | |||
| @Autowired | |||
| WxQuestionService wxQuestionService; | |||
| @Autowired | |||
| WxMsgValidationcodeModelService wxMsgValidationcodeModelService; | |||
| @Autowired | |||
| WxFlowService wxFlowService; | |||
| @Override | |||
| @Transactional | |||
| public void initProjectConfig(Long id) { | |||
| WxProjectConfig wxProjectConfig = wxProjectConfigMapper.selectById(id); | |||
| if(wxProjectConfig!=null && wxProjectConfig.getDelType()<10000){ | |||
| // 1. wx_mall 商场 | |||
| String tenantId = wxMallService.wxMallInit(wxProjectConfig); | |||
| // 2. wx_coupon_send_config | |||
| wxCouponSendConfigService.wxCouponSendConfigInit(tenantId); | |||
| // 3. wx_mall_building 商场楼座 | |||
| wxMallBuildingService.wxMallBuildingInit(tenantId,wxProjectConfig.getMallBuilding()); | |||
| //# --- 特殊商户号开通后,填写此数据 | |||
| //# 5. wx_pay_account | |||
| WxPayAccount wxPayAccount = wxPayAccountService.wxPayAccountInit(tenantId,wxProjectConfig); | |||
| //# --- 特殊商户号开通后,填写此数据 | |||
| //# 6. wx_pay_account_bill | |||
| Long payBillId = wxPayAccountBillService.wxPayAccountInit(wxPayAccount); | |||
| //# --- 小程序开通后,填写此数据,并设置域名及业务域名等 | |||
| //# 7. wx_appinfo | |||
| wxAppinfoService.wxAppinfoInit(tenantId,wxPayAccount.getId(),payBillId,wxProjectConfig); | |||
| wxAuthorizerInfoService.wxAuthorizerInfoInit(tenantId,wxProjectConfig); | |||
| wxAuthorizerInfoService.wxWeappExtSetInit(wxProjectConfig); | |||
| // 9. mall_user_info | |||
| // 10. mall_role | |||
| // 11. mall_role_permission | |||
| //# 12. mall_user_role | |||
| Long mallUserInfoId = mallUserInfoService.MallUserInfoInit(tenantId, wxProjectConfig); | |||
| //# 13. wx_msg_config | |||
| wxMsgConfigService.WxMsgConfigInit(tenantId, wxProjectConfig); | |||
| //# ETCP 设置完后再填写此数据 | |||
| //# 14. wx_park | |||
| wxParkService.wxParkInit(tenantId, wxProjectConfig); | |||
| //# 积分成长值设置wx_score_rules | |||
| wxScoreRulesService.wxScoreRulesInit(tenantId); | |||
| //# 17. wx_template_msg | |||
| //# 设置核销成功通知,核销失败通知 | |||
| wxTemplateMsgService.wxTemplateMsgInit(tenantId); | |||
| //# 18. wx_wiwide_info -- 迈外迪 服务商后台设置商户(点击获取商户bid),再找迈外迪初始化,收到激活邮件激活后,再在数据库中插入此数据 | |||
| //# 数据格式如下 | |||
| //# szld1086@iformall | |||
| //# 1391054397 | |||
| //# wuguoqiang@iformall.com | |||
| // # 19. wx_question | |||
| logger.info("wx_question---------------------init--start"); | |||
| String questionJson = "[{\"flag\": \"single\", \"title\": \"请问您的职业是?\", \"answers\": [{\"id\": \"59\", \"name\": \"学生\"}, {\"id\": \"60\", \"name\": \"上班族\"}, {\"id\": \"61\", \"name\": \"企业高管\"}, {\"id\": \"62\", \"name\": \"个体户\"}, {\"id\": \"63\", \"name\": \"自由职业\"}, {\"id\": \"64\", \"name\": \"其他\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"请问您目前的学历是?\", \"answers\": [{\"id\": \"34\", \"name\": \"高中\"}, {\"id\": \"35\", \"name\": \"大专\"}, {\"id\": \"36\", \"name\": \"本科\"}, {\"id\": \"37\", \"name\": \"硕士及以上\"}, {\"id\": \"38\", \"name\": \"博士及以上\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"请问您是如何到达商场的?\", \"answers\": [{\"id\": \"127\", \"name\": \"走路\"}, {\"id\": \"128\", \"name\": \"乘车\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"请问您和父母一起居住吗?\", \"answers\": [{\"id\": \"65\", \"name\": \"不是,我已租房\"}, {\"id\": \"66\", \"name\": \"是,我已购房\"}, {\"id\": \"67\", \"name\": \"不是,我和室友住宿舍\"}]}," | |||
| + "{\"flag\": \"multi\", \"title\": \"请问您的孩子愿意与您一起?\", \"answers\": [{\"id\": \"57\", \"name\": \"逛街\"}, {\"id\": \"57\", \"name\": \"玩乐\"}, {\"id\": \"57\", \"name\": \"阅读\"}, {\"id\": \"55\", \"name\": \"我还没有宝宝\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"主人,您结婚了吗?\", \"answers\": [{\"id\": \"56\", \"name\": \"结婚啦\"}, {\"id\": \"55\", \"name\": \"还没有哦\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"您是?\", \"answers\": [{\"id\": \"42\", \"name\": \"贫下中农\"}, {\"id\": \"43\", \"name\": \"小康家庭\"}, {\"id\": \"44\", \"name\": \"中产家庭\"}, {\"id\": \"45\", \"name\": \"富裕家庭\"}]}," | |||
| + "{\"flag\": \"single\", \"title\": \"请问您是?\", \"answers\": [{\"id\": \"104\", \"name\": \"实惠型消费\"}, {\"id\": \"105\", \"name\": \"享乐型消费\"}, {\"id\": \"106\", \"name\": \"品质型消费\"}]}," | |||
| + "{\"flag\": \"multi\", \"title\": \"请问您喜欢哪种口味的食物?\", \"answers\": [{\"id\": \"92\", \"name\": \"轻餐\"}, {\"id\": \"93\", \"name\": \"小吃快餐\"}, {\"id\": \"94\", \"name\": \"西餐\"}, {\"id\": \"95\", \"name\": \"日料中餐甜点\"}, {\"id\": \"96\", \"name\": \"火锅\"}]}," | |||
| + "{\"flag\": \"multi\", \"title\": \"请问您的爱好是?\", \"answers\": [{\"id\": \"121\", \"name\": \"时尚\"}, {\"id\": \"122\", \"name\": \"旅游\"}, {\"id\": \"123\", \"name\": \"运动\"}, {\"id\": \"124\", \"name\": \"电玩\"}, {\"id\": \"125\", \"name\": \"看书\"}, {\"id\": \"126\", \"name\": \"其他\"}]}]"; | |||
| wxQuestionService.wxQuestionInit(tenantId,questionJson); | |||
| //# 20. wx_msg_validationcode_model, 数据重新一下 | |||
| wxMsgValidationcodeModelService.wxMsgValidationcodeModelInit(tenantId, wxProjectConfig); | |||
| //wx_flow_config | |||
| wxFlowService.wxFlowConfigInit(tenantId); | |||
| //初始化成功 删除标记 | |||
| wxProjectConfig.setDelType(10000); | |||
| wxProjectConfigMapper.updateById(wxProjectConfig); | |||
| }else { | |||
| logger.info("------数据已初始化"); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| package com.iformall.service.impl; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONArray; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.IdWorker; | |||
| @@ -31,6 +33,18 @@ public class WxQuestionServiceImpl implements WxQuestionService { | |||
| @Autowired | |||
| WxQuestionLogMapper wxQuestionLogMapper; | |||
| @Override | |||
| public void wxQuestionInit(String tenantId, String questionJson) { | |||
| WxQuestion wxQuestion = new WxQuestion(); | |||
| wxQuestion.setTenantId(tenantId); | |||
| JSONArray jsonObject = JSON.parseArray(questionJson); | |||
| for (Object object : jsonObject) { | |||
| wxQuestion.setId(null); | |||
| wxQuestion.setContent(object.toString()); | |||
| wxQuestionMapper.insert(wxQuestion); | |||
| } | |||
| } | |||
| @Override | |||
| public PageInfo<WxQuestion> listAsPage(WxQuestion record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxQuestionMapper.findList(record)); | |||