zhangbin 1 year ago
parent
commit
0eb6b40fbe
23 changed files with 760 additions and 10 deletions
  1. 53 2
      xpgx-admin/src/main/java/com/miaxis/app/controller/wx/WxController.java
  2. 45 0
      xpgx-admin/src/main/java/com/miaxis/pc/controller/PcOrderInfoController.java
  3. 62 0
      xpgx-admin/src/main/java/com/miaxis/pc/controller/PcOrderSplitController.java
  4. 1 0
      xpgx-admin/src/main/resources/application-dev.yml
  5. 3 2
      xpgx-admin/src/main/resources/application-local.yml
  6. 1 0
      xpgx-admin/src/main/resources/application-prod.yml
  7. 87 0
      xpgx-service/src/main/java/com/miaxis/job/AppAdJob.java
  8. 14 0
      xpgx-service/src/main/java/com/miaxis/order/domain/OrderInfo.java
  9. 67 0
      xpgx-service/src/main/java/com/miaxis/order/domain/OrderSplit.java
  10. 18 0
      xpgx-service/src/main/java/com/miaxis/order/dto/OrderInfoProfitDto.java
  11. 2 0
      xpgx-service/src/main/java/com/miaxis/order/mapper/OrderInfoMapper.java
  12. 23 0
      xpgx-service/src/main/java/com/miaxis/order/mapper/OrderSplitMapper.java
  13. 2 0
      xpgx-service/src/main/java/com/miaxis/order/service/IOrderInfoService.java
  14. 25 0
      xpgx-service/src/main/java/com/miaxis/order/service/IOrderSplitService.java
  15. 21 0
      xpgx-service/src/main/java/com/miaxis/order/service/impl/OrderInfoServiceImpl.java
  16. 33 0
      xpgx-service/src/main/java/com/miaxis/order/service/impl/OrderSplitServiceImpl.java
  17. 60 0
      xpgx-service/src/main/java/com/miaxis/order/vo/OrderSplitVo.java
  18. 5 0
      xpgx-service/src/main/java/com/miaxis/wx/domain/WxOrder.java
  19. 2 2
      xpgx-service/src/main/java/com/miaxis/wx/dto/WxOrderDTO.java
  20. 5 1
      xpgx-service/src/main/java/com/miaxis/wx/service/IWxOrderService.java
  21. 188 3
      xpgx-service/src/main/java/com/miaxis/wx/service/impl/WxOrderServiceImpl.java
  22. 7 0
      xpgx-service/src/main/resources/mapper/order/OrderInfoMapper.xml
  23. 36 0
      xpgx-service/src/main/resources/mapper/order/OrderSplitMapper.xml

+ 53 - 2
xpgx-admin/src/main/java/com/miaxis/app/controller/wx/WxController.java

@@ -3,6 +3,8 @@ package com.miaxis.app.controller.wx;
 import com.alibaba.fastjson.JSONObject;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.miaxis.birthday.domain.BirthdayLog;
+import com.miaxis.birthday.service.IBirthdayLogService;
 import com.miaxis.common.config.WxpayConfig;
 import com.miaxis.common.constant.Constants;
 import com.miaxis.common.core.controller.BaseController;
@@ -14,6 +16,7 @@ import com.miaxis.common.utils.SecurityUtils;
 import com.miaxis.common.utils.ServletUtils;
 import com.miaxis.common.utils.ip.IpUtils;
 import com.miaxis.common.utils.uuid.CommonUtils;
+import com.miaxis.system.service.ISysConfigService;
 import com.miaxis.system.service.ISysDictDataService;
 import com.miaxis.wx.domain.WxOrder;
 import com.miaxis.wx.dto.WxOrderDTO;
@@ -70,7 +73,11 @@ public class WxController extends BaseController {
     @Autowired
     private ISysDictDataService dictDataService;
 
+    @Autowired
+    private ISysConfigService configService;
 
+    @Autowired
+    private IBirthdayLogService birthdayLogService;
 
 
     @Value("${xcx.appId}")
@@ -208,7 +215,47 @@ public class WxController extends BaseController {
     }
 
 
-
+    /**
+     * 微信小程序支付获取预订单id
+     */
+    @PostMapping(value = "/xcxPrepareOrder")
+    @ApiOperation("微信小程序支付下单")
+    public Response<JSONObject> xcxPrepareOrder(@RequestBody WxOrderDTO wxOrderDTO) throws Exception {
+        UserInfo userInfo = SecurityUtils.getLoginUser().getStudent();
+        String profitSharing = configService.selectConfigByKey("profit_sharing");
+        if (wxOrderDTO.getGoodsType() == 1) {
+            String baziPriceStr = configService.selectConfigByKey("bazi_price");
+            BirthdayLog birthdayLog = birthdayLogService.getById(wxOrderDTO.getGoodsId()); //记录ID
+            if(birthdayLog!=null && (birthdayLog.getIsPay()==1 || birthdayLog.getIsPay()==2)) {
+                throw new CustomException("您已支付此订单,退回上个页面,重新进入。");
+            }
+            //创建本地微信订单
+            WxOrder order = new WxOrder();
+            String orderCode = getOrderCode(userInfo.getId());
+            order.setGoodsId(birthdayLog.getId()); //八字记录ID
+            order.setGoodsName("人生报告");
+            order.setGoodsType(3);
+            order.setOutTradeNo(orderCode);
+            order.setUserId(userInfo.getId());
+            order.setXcxOpenid(userInfo.getXcxOpenid());
+            order.setAppOpenid(userInfo.getAppOpenid());
+            order.setGzhOpenid(userInfo.getGzhOpenid());
+            order.setUnionId(userInfo.getUnionId());
+            order.setPhoneType(wxOrderDTO.getPhoneType()); //手机类型 1:苹果 2:安卓
+            order.setForeType(wxOrderDTO.getForeType()); //前端类型 1:app 2:小程序 3:公众号
+            order.setTotal(Integer.parseInt(baziPriceStr));
+            if("1".equals(profitSharing)) {
+                order.setIsSharing(1); //分账
+            } else {
+                order.setIsSharing(0); //不分账
+            }
+            order.setOrderStatus(OrderStatusEnum.PROCESSING.getCode());
+            wxOrderService.save(order);
+            return Response.success(placeXcxWxOrder(order, "人生报告"));
+        } else {
+            throw new CustomException("请正确传入GoodsType。");
+        }
+    }
 
 
 
@@ -220,6 +267,8 @@ public class WxController extends BaseController {
      * @throws Exception
      */
     private JSONObject placeXcxWxOrder(WxOrder order, String goodsName) throws Exception {
+        String profitSharing = configService.selectConfigByKey("profit_sharing");
+
         HttpPost httpPost = initHttpPost(wxpayConfig.getV3JsUrl());
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         ObjectMapper objectMapper = new ObjectMapper();
@@ -231,6 +280,9 @@ public class WxController extends BaseController {
                 .put("out_trade_no", order.getOutTradeNo());
         rootNode.putObject("amount").put("total", order.getTotal());
         rootNode.putObject("payer").put("openid", order.getXcxOpenid());
+        if("1".equals(profitSharing)) {
+            rootNode.putObject("settle_info").put("profit_sharing", true);
+        }
         objectMapper.writeValue(bos, rootNode);
         httpPost.setEntity(new StringEntity(rootNode.toString(), "utf-8"));
         HttpResponse response = httpClient.execute(httpPost);
@@ -239,7 +291,6 @@ public class WxController extends BaseController {
             throw new CustomException(JSONObject.parseObject(bodyAsString).get("message").toString());
         }
         return getWxParamJson(bodyAsString,xcxAppId);
-
     }
 
 

+ 45 - 0
xpgx-admin/src/main/java/com/miaxis/pc/controller/PcOrderInfoController.java

@@ -13,6 +13,7 @@ import io.swagger.annotations.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
 import java.util.List;
 
 import static com.miaxis.common.utils.OrderCodeFactory.getOrderCode;
@@ -50,6 +51,50 @@ public class PcOrderInfoController extends BaseController {
         return toResponsePageInfo(list);
     }
 
+    /**
+     * 发起分账
+     */
+    @PutMapping(value = "/shareProfit/{outTradeNo}")
+    @ApiOperation("发起分账")
+    public Response<OrderInfo> shareProfit(
+            @ApiParam(name = "outTradeNo", value = "商户订单信息", required = true)
+            @PathVariable("outTradeNo") String outTradeNo) throws Exception {
+        OrderInfo orderInfo = orderInfoService.getByOutTradeNo(outTradeNo);
+
+        if (orderInfo.getTradeType()!=1) {
+            Response response = new Response(200, "非支付成功的订单,无法分账。");
+            return response;
+        }
+        if (orderInfo.getProfitSharing() != 1) {
+            Response response = new Response(200, "非待分账订单,无法分账。");
+            return response;
+        }
+
+        // 获取当前时间
+        Date currentDate = new Date();
+        // 添加5分钟
+        long fiveMinutesInMillis = 1 * 60 * 1000; // 5分钟的毫秒数
+        Date nowDate = new Date(currentDate.getTime() - fiveMinutesInMillis);
+
+        if (nowDate.compareTo(orderInfo.getSuccessTime()) < 0) {
+            Response response = new Response(200, "支付成功的订单,未满5分钟无法分账,请稍后操作。");
+            return response;
+        }
+
+        boolean addFlag = wxOrderService.wxAddFenZhang(orderInfo);
+        boolean flag = wxOrderService.wxProfitsharing(orderInfo);
+        if (flag && addFlag) {
+            Response response = new Response(200, "分账成功");
+            return response;
+        } else {
+            Response response = new Response(200, "分账失败,请联系管理员");
+            return response;
+        }
+
+    }
+
+
+
     /**
      * 获取订单信息详细信息
      */

+ 62 - 0
xpgx-admin/src/main/java/com/miaxis/pc/controller/PcOrderSplitController.java

@@ -0,0 +1,62 @@
+package com.miaxis.pc.controller;
+
+import com.miaxis.common.core.controller.BaseController;
+import com.miaxis.common.core.page.ResponsePageInfo;
+import com.miaxis.order.domain.OrderSplit;
+import com.miaxis.order.service.IOrderSplitService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.List;
+
+/**
+ * 【分账记录】Controller
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+@RestController
+@RequestMapping("/order/split")
+@Api(tags = {"【PC-分账记录】"})
+public class PcOrderSplitController extends BaseController {
+    @Autowired
+    private IOrderSplitService orderSplitService;
+
+    /**
+     * 查询分账记录列表
+     */
+    @GetMapping("/list")
+    @ApiOperation("查询分账记录列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "当前页码", dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "pageSize", value = "每页数据量", dataType = "int", paramType = "query", required = false),
+    })
+    public ResponsePageInfo<OrderSplit> list(@ModelAttribute OrderSplit orderSplit) {
+        startPage();
+        List<OrderSplit> list = orderSplitService.selectOrderSplitList(orderSplit);
+        return toResponsePageInfo(list);
+    }
+
+
+
+    /**
+     * 获取分账记录详细信息
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation("获取分账记录详细信息")
+    public Response<OrderSplit> getInfo(
+            @ApiParam(name = "id", value = "分账记录参数", required = true)
+            @PathVariable("id") Long id
+    ) {
+        return Response.success(orderSplitService.getById(id));
+    }
+     */
+
+}

+ 1 - 0
xpgx-admin/src/main/resources/application-dev.yml

@@ -110,6 +110,7 @@ gzh:
 
 # 小程序
 xcx:
+    mchId: 1639487489
     appId: wxd14b31479ff7bfbc
     appSecret: cd76422cbe9892505f78469dd08958b6
 

+ 3 - 2
xpgx-admin/src/main/resources/application-local.yml

@@ -103,6 +103,7 @@ gzh:
 
 # 小程序
 xcx:
+    mchId: 1639487489
     appId: wxd14b31479ff7bfbc
     appSecret: cd76422cbe9892505f78469dd08958b6
 
@@ -115,8 +116,8 @@ wxpay:
     merchantId: 1639487489
     serialNumber: 1304D67DC59D94217412C49E20D5B0E00A5A122D
     v3key: PIQKEpG1FEoBEELgv0GUxkUJKTkc0jGB
-    notifyUrl: https://1a0j71808.imdo.co/open-api/wx/notify/wxpay
-    notifyUrlRefund: https://1a0j71808.imdo.co/open-api/wx/notify/refund
+    notifyUrl: https://107j18o08.vicp.fun/open-api/wx/notify/wxpay
+    notifyUrlRefund: https://107j18o08.vicp.fun/open-api/wx/notify/refund
     #notifyUrl: https://1a0j71808.imdo.co/open-api/wx/notify/wxpay
     #notifyUrlRefund: https://1a0j71808.imdo.co/open-api/wx/notify/refund
 

+ 1 - 0
xpgx-admin/src/main/resources/application-prod.yml

@@ -106,6 +106,7 @@ gzh:
 
 # 小程序
 xcx:
+    mchId: 1639487489
     appId: wxd14b31479ff7bfbc
     appSecret: cd76422cbe9892505f78469dd08958b6
 

+ 87 - 0
xpgx-service/src/main/java/com/miaxis/job/AppAdJob.java

@@ -0,0 +1,87 @@
+package com.miaxis.job;
+
+import com.miaxis.common.core.domain.entity.SysDictData;
+import com.miaxis.order.domain.OrderInfo;
+import com.miaxis.order.service.IOrderInfoService;
+import com.miaxis.system.service.ISysDictDataService;
+import com.miaxis.wx.service.IWxOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Slf4j
+@Component
+public class AppAdJob {
+
+
+    @Autowired
+    private ISysDictDataService dictDataService;
+    @Autowired
+    private IWxOrderService wxOrderService;
+    @Autowired
+    private IOrderInfoService orderInfoService;
+
+
+
+   // @Scheduled(cron = "0 0 19 * * ?")
+    public void openAd()  {
+        log.info("--------打开广告!~---------------");
+        SysDictData splashAd = dictDataService.selectDictDataById(104l);
+        SysDictData nativeAd = dictDataService.selectDictDataById(105l);
+        SysDictData bannerAd = dictDataService.selectDictDataById(106l);
+
+        splashAd.setDictValue("1");
+        nativeAd.setDictValue("1");
+        bannerAd.setDictValue("1");
+        dictDataService.updateDictData(splashAd);
+        dictDataService.updateDictData(nativeAd);
+        dictDataService.updateDictData(bannerAd);
+
+    }
+
+
+  //  @Scheduled(cron = "0 30 7 * * ?")
+    public void closeAd()  {
+        log.info("--------关闭广告!~---------------");
+        SysDictData splashAd = dictDataService.selectDictDataById(104l);
+        SysDictData nativeAd = dictDataService.selectDictDataById(105l);
+        SysDictData bannerAd = dictDataService.selectDictDataById(106l);
+        splashAd.setDictValue("0");
+        nativeAd.setDictValue("0");
+        bannerAd.setDictValue("0");
+        dictDataService.updateDictData(splashAd);
+        dictDataService.updateDictData(nativeAd);
+        dictDataService.updateDictData(bannerAd);
+
+    }
+
+
+    //@Scheduled(cron = "0 30 6 * * ?")
+    public void closeAd2()  {
+        log.info("--------现在是6点半!~---------------");
+    }
+
+
+    //@Scheduled(cron = "0 0/5 * * * ?")
+    public void wxProfitsharing()  {
+        log.info("--------现在开始执行每1分钟一次的微信分帐!~---------------");
+
+        List<OrderInfo> orderInfoList = orderInfoService.selectOrderInfoByWaitProfit();
+        for (int i = 0; i < orderInfoList.size(); i++) {
+            OrderInfo orderInfo = orderInfoList.get(i);
+            try {
+                wxOrderService.wxAddFenZhang(orderInfo); //添加
+                wxOrderService.wxProfitsharing(orderInfo);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+
+
+    }
+
+
+}

+ 14 - 0
xpgx-service/src/main/java/com/miaxis/order/domain/OrderInfo.java

@@ -78,6 +78,13 @@ public class OrderInfo extends BaseBusinessEntity{
     @ApiModelProperty(value = "公众号openid")
     private String gzhOpenid;
 
+    /** 微信支付系统生成的订单号 */
+    @Excel(name = "微信支付系统生成的订单号")
+    @TableField("transaction_id")
+    @ApiModelProperty(value = "微信支付系统生成的订单号")
+    private String transactionId;
+
+
     /** 订单编号 */
     @Excel(name = "订单编号")
     @TableField("out_trade_no")
@@ -97,6 +104,13 @@ public class OrderInfo extends BaseBusinessEntity{
     @ApiModelProperty(value = "总金额")
     private Integer total;
 
+    /** 分账状态 0 不分帐 1待分账  2分账成功  3分账失败 */
+    @Excel(name = "分账状态")
+    @TableField("profit_sharing")
+    @ApiModelProperty(value = "分账状态 0 不分帐 1待分账  2分账成功  3分账失败")
+    private Integer profitSharing;
+
+
     /** 交易状态 1、支付成功2、支付失败*/
     @Excel(name = "交易状态 1、支付成功2、支付失败")
     @TableField("trade_type")

+ 67 - 0
xpgx-service/src/main/java/com/miaxis/order/domain/OrderSplit.java

@@ -0,0 +1,67 @@
+package com.miaxis.order.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.miaxis.common.annotation.Excel;
+import com.miaxis.common.core.domain.BaseBusinessEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 分账记录对象 order_split
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+@Data
+@TableName("order_split")
+@ApiModel(value = "OrderSplit", description = "分账记录对象 order_split")
+public class OrderSplit extends BaseBusinessEntity {
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    @TableId(value = "id")
+    @ApiModelProperty(value = "ID")
+    private Long id;
+
+    /** 商户内部分账订单ID */
+    @Excel(name = "商户内部分账订单ID")
+    @TableField("out_split_no")
+    @ApiModelProperty(value = "商户内部分账订单ID")
+    private String outSplitNo;
+
+    /** 商户内部订单ID */
+    @Excel(name = "商户内部订单ID")
+    @TableField("out_trade_no")
+    @ApiModelProperty(value = "商户内部订单ID")
+    private String outTradeNo;
+
+    /** 分账金额 */
+    @Excel(name = "分账金额")
+    @TableField("amount")
+    @ApiModelProperty(value = "分账金额")
+    private Integer amount;
+
+    /** 分账到openid或商户号 */
+    @Excel(name = "分账到openid或商户号")
+    @TableField("open_id")
+    @ApiModelProperty(value = "分账到openid或商户号")
+    private String openId;
+
+    /** 前端类型 1:app 2:小程序 3:公众号 */
+    @Excel(name = "前端类型 1:app 2:小程序 3:公众号")
+    @TableField("open_id_type")
+    @ApiModelProperty(value = "前端类型 1:app 2:小程序 3:公众号")
+    private Integer openIdType;
+
+
+    /** 描述 */
+    @Excel(name = "描述")
+    @TableField("description")
+    @ApiModelProperty(value = "描述")
+    private String description;
+
+
+}

+ 18 - 0
xpgx-service/src/main/java/com/miaxis/order/dto/OrderInfoProfitDto.java

@@ -0,0 +1,18 @@
+package com.miaxis.order.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OrderInfoProfitDto {
+    private static final long serialVersionUID = 1L;
+
+
+
+    @ApiModelProperty(value = "时间",required = true)
+    private String nowDate;
+
+
+
+
+}

+ 2 - 0
xpgx-service/src/main/java/com/miaxis/order/mapper/OrderInfoMapper.java

@@ -25,4 +25,6 @@ public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
 
 
     OrderInfo getByOutTradeNo(String outTradeNo);
+
+    List<OrderInfo> selectOrderInfoByWaitProfit(String nowDateStr);
 }

+ 23 - 0
xpgx-service/src/main/java/com/miaxis/order/mapper/OrderSplitMapper.java

@@ -0,0 +1,23 @@
+package com.miaxis.order.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.miaxis.order.domain.OrderSplit;
+
+import java.util.List;
+
+/**
+ * 分账记录Mapper接口
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+public interface OrderSplitMapper extends BaseMapper<OrderSplit> {
+    /**
+     * 查询分账记录列表
+     *
+     * @param orderSplit 分账记录
+     * @return 分账记录集合
+     */
+    public List<OrderSplit> selectOrderSplitList(OrderSplit orderSplit);
+
+}

+ 2 - 0
xpgx-service/src/main/java/com/miaxis/order/service/IOrderInfoService.java

@@ -29,4 +29,6 @@ public interface IOrderInfoService extends IService<OrderInfo> {
 
 
     OrderInfo getByOutTradeNo(String outTradeNo);
+
+    List<OrderInfo> selectOrderInfoByWaitProfit();
 }

+ 25 - 0
xpgx-service/src/main/java/com/miaxis/order/service/IOrderSplitService.java

@@ -0,0 +1,25 @@
+package com.miaxis.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.miaxis.order.domain.OrderSplit;
+
+import java.util.List;
+
+/**
+ * 分账记录Service接口
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+public interface IOrderSplitService extends IService<OrderSplit>{
+    /**
+     * 查询分账记录列表
+     *
+     * @param orderSplit 分账记录
+     * @return 分账记录集合
+     */
+     List<OrderSplit> selectOrderSplitList(OrderSplit orderSplit);
+
+
+
+}

+ 21 - 0
xpgx-service/src/main/java/com/miaxis/order/service/impl/OrderInfoServiceImpl.java

@@ -1,8 +1,10 @@
 package com.miaxis.order.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.miaxis.common.utils.DateUtils;
 import com.miaxis.order.domain.OrderInfo;
 import com.miaxis.order.dto.OrderInfoDto;
+import com.miaxis.order.dto.OrderInfoProfitDto;
 import com.miaxis.order.mapper.OrderInfoMapper;
 import com.miaxis.order.service.IOrderInfoService;
 import com.miaxis.wx.domain.WxOrder;
@@ -43,6 +45,8 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
         return orderInfoMapper.getByOutTradeNo(outTradeNo);
     }
 
+
+
     @Override
     public void writeVipDataToDb(WxOrder order, int payType) {
         long oneYearLong = 1000 * 60 * 60 * 24 * 365l;
@@ -71,6 +75,23 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
 
     }
 
+    @Override
+    public List<OrderInfo> selectOrderInfoByWaitProfit() {
+
+        // 获取当前时间
+        Date currentDate = new Date();
+        // 添加5分钟
+        long fiveMinutesInMillis = 1 * 60 * 1000; // 5分钟的毫秒数
+        Date nowDate = new Date(currentDate.getTime() - fiveMinutesInMillis);
+
+        OrderInfoProfitDto orderInfoProfitDto = new OrderInfoProfitDto();
+
+        String nowDateStr = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", nowDate);
+
+        orderInfoProfitDto.setNowDate(nowDateStr);
+        List<OrderInfo> orderList = orderInfoMapper.selectOrderInfoByWaitProfit(nowDateStr);
+        return orderList;
+    }
 
 
 }

+ 33 - 0
xpgx-service/src/main/java/com/miaxis/order/service/impl/OrderSplitServiceImpl.java

@@ -0,0 +1,33 @@
+package com.miaxis.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.miaxis.order.domain.OrderSplit;
+import com.miaxis.order.mapper.OrderSplitMapper;
+import com.miaxis.order.service.IOrderSplitService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 分账记录Service业务层处理
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+@Service
+public class OrderSplitServiceImpl extends ServiceImpl<OrderSplitMapper, OrderSplit> implements IOrderSplitService {
+    @Autowired
+    private OrderSplitMapper orderSplitMapper;
+
+    /**
+     * 查询分账记录列表
+     *
+     * @param orderSplit 分账记录
+     * @return 分账记录
+     */
+    @Override
+    public List<OrderSplit> selectOrderSplitList(OrderSplit orderSplit){
+        return orderSplitMapper.selectOrderSplitList(orderSplit);
+    }
+}

+ 60 - 0
xpgx-service/src/main/java/com/miaxis/order/vo/OrderSplitVo.java

@@ -0,0 +1,60 @@
+package com.miaxis.order.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 分账记录对象 order_split
+ *
+ * @author miaxis
+ * @date 2024-01-31
+ */
+@Data
+public class OrderSplitVo {
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    @ApiModelProperty(value = "ID")
+    private Long id;
+
+    /** 商户内部分账订单ID */
+    @ApiModelProperty(value = "商户内部分账订单ID")
+    private String outSplitNo;
+
+
+    /** 商户内部订单ID */
+    @ApiModelProperty(value = "商户内部订单ID")
+    private String outTradeNo;
+
+
+    /** 分账金额 */
+    @ApiModelProperty(value = "分账金额")
+    private Integer amount;
+
+    /** 分账到openid或商户号 */
+    @ApiModelProperty(value = "分账到openid或商户号")
+    private String openId;
+
+    /** 前端类型 1:app 2:小程序 3:公众号 */
+    @ApiModelProperty(value = "前端类型 1:app 2:小程序 3:公众号")
+    private Integer openIdType;
+
+
+    /** 描述 */
+    @ApiModelProperty(value = "描述")
+    private String description;
+
+    /** 昵称 */
+    @ApiModelProperty(value = "昵称")
+    private String nickName;
+
+    /** 创建时间 */
+    @ApiModelProperty(value = "创建时间"  ,hidden = true)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+
+}

+ 5 - 0
xpgx-service/src/main/java/com/miaxis/wx/domain/WxOrder.java

@@ -193,5 +193,10 @@ public class WxOrder extends BaseBusinessEntity{
     private Integer foreType;
 
 
+    /** 是否分账 0不分账 1分账 */
+    @Excel(name = "是否分账 0不分账 1分账")
+    @TableField("is_sharing")
+    @ApiModelProperty(value = "是否分账 0不分账 1分账")
+    private Integer isSharing;
 
 }

+ 2 - 2
xpgx-service/src/main/java/com/miaxis/wx/dto/WxOrderDTO.java

@@ -9,10 +9,10 @@ public class WxOrderDTO {
 
 
 
-    @ApiModelProperty(value = "商品ID(考场ID)",required = true)
+    @ApiModelProperty(value = "商品ID",required = true)
     private Long goodsId;
 
-    @ApiModelProperty(value = "商品类型 1:考场 2:实物",required = true)
+    @ApiModelProperty(value = "商品类型 1:人生报告 ",required = true)
     private Long goodsType;
 
     @ApiModelProperty(value = "手机类型 1苹果 2安卓",required = true)

+ 5 - 1
xpgx-service/src/main/java/com/miaxis/wx/service/IWxOrderService.java

@@ -2,6 +2,7 @@ package com.miaxis.wx.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.miaxis.common.core.domain.entity.SysDictData;
+import com.miaxis.order.domain.OrderInfo;
 import com.miaxis.wx.domain.WxOrder;
 import com.miaxis.wx.dto.*;
 
@@ -12,8 +13,11 @@ import java.util.List;
 public interface IWxOrderService extends IService<WxOrder>{
 
 
-    WxOrder getByOutTradeNo(String outTradeNo);
+    boolean wxAddFenZhang(OrderInfo orderInfo) throws Exception;
+
+    boolean wxProfitsharing(OrderInfo orderInfo) throws  Exception;
 
+    WxOrder getByOutTradeNo(String outTradeNo);
 
     String wxwithdrawal(Integer amount) throws Exception;
 

+ 188 - 3
xpgx-service/src/main/java/com/miaxis/wx/service/impl/WxOrderServiceImpl.java

@@ -2,6 +2,7 @@ package com.miaxis.wx.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.wxpay.sdk.WXPay;
 import com.github.wxpay.sdk.WXPayConfig;
 import com.github.wxpay.sdk.WXPayConstants;
@@ -14,8 +15,14 @@ import com.miaxis.common.enums.OrderStatusEnum;
 import com.miaxis.common.exception.CustomException;
 import com.miaxis.common.utils.RSAUtils;
 import com.miaxis.common.utils.SecurityUtils;
+import com.miaxis.common.utils.StringUtils;
 import com.miaxis.common.utils.XmlUtil;
+import com.miaxis.order.domain.OrderInfo;
+import com.miaxis.order.domain.OrderSplit;
+import com.miaxis.order.service.IOrderInfoService;
+import com.miaxis.order.service.IOrderSplitService;
 import com.miaxis.system.service.ISysConfigService;
+import com.miaxis.system.service.ISysUserService;
 import com.miaxis.user.service.IUserInfoService;
 import com.miaxis.wx.domain.WxExtract;
 import com.miaxis.wx.domain.WxExtractBank;
@@ -36,6 +43,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -57,6 +65,15 @@ public class WxOrderServiceImpl extends ServiceImpl<WxOrderMapper, WxOrder> impl
     @Autowired
     private IWxExtractService wxExtractService;
 
+    @Autowired
+    private IOrderInfoService orderInfoService;
+
+    @Autowired
+    private IOrderSplitService orderSplitService;
+
+    @Autowired
+    private ISysUserService sysUserService;
+
     @Autowired
     private RSAUtils rsaUtils;
 
@@ -71,9 +88,142 @@ public class WxOrderServiceImpl extends ServiceImpl<WxOrderMapper, WxOrder> impl
     @Autowired
     private IWxExtractBankService wxExtractBankService;
 
-    @Value("${gzh.appid}")
-    private String appid;
+    @Value("${xcx.appId}")
+    private String xcxAppid;
+
+    @Value("${xcx.mchId}")
+    private String mchId;
+
+
+    @Override
+    @Transactional
+    public boolean wxAddFenZhang(OrderInfo orderInfo) throws Exception {
+        //查询上级
+        Map<String, Object> accountMap = getAccount(orderInfo);
+        String url = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver";
+
+        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
+        //用于签名
+        Map<String, String> sortMap = new TreeMap<String, String>();
+        sortMap.put("mch_id", mchId);
+        sortMap.put("appid", xcxAppid);
+        sortMap.put("nonce_str", nonceStr);
+        sortMap.put("sign_type", "HMAC-SHA256");
+        Map<String, String> receiverMap = new TreeMap<String, String>();
+        receiverMap.put("type", "PERSONAL_OPENID");
+
+        if (accountMap != null) {
+            String account = (String) accountMap.get("account");
+            if (StringUtils.isNotEmpty(account)) {  //如果存在上级,分给上给
+                receiverMap.put("account", account);
+            } else {                               //如果不存在上级,分给固定的
+                receiverMap.put("account", "o7N3j5XxUrgOKE4ulP-HseFpBCiM");
+            }
+        }
+
+        receiverMap.put("relation_type", "SERVICE_PROVIDER");  //合作合伙
+        ObjectMapper objectMapper = new ObjectMapper();
+        String receiverMapJson = objectMapper.writeValueAsString(receiverMap);
+        sortMap.put("receiver", receiverMapJson);
 
+        WXPayConfig config = new WxPayConfigImpl();
+        String sign = WXPayUtil.generateSignature(sortMap, config.getKey(), WXPayConstants.SignType.HMACSHA256);
+        sortMap.put("sign", sign);
+
+        WXPay pay = new WXPay(config);
+        String xmlStr = pay.requestWithoutCert(url, sortMap, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());
+
+        Map<String, String> resMap = XmlUtil.xmlToMap(xmlStr);
+        if (!"SUCCESS".equals(resMap.get("return_code")) || !"SUCCESS".equals(resMap.get("result_code"))) {
+            // throw new CustomException("微信添加分账出错");
+            log.info("微信添加分账出错");
+            log.info(resMap.toString());
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+
+
+    /**
+     * @return
+     * @throws Exception
+     */
+    @Override
+    @Transactional
+    public boolean wxProfitsharing(OrderInfo orderInfo) throws Exception {
+        String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing";
+        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
+        //用于签名
+        Map<String, String> sortMap = new TreeMap<String, String>();
+        sortMap.put("mch_id", mchId);
+        sortMap.put("appid", xcxAppid);
+        sortMap.put("nonce_str", nonceStr);
+        sortMap.put("sign_type", "HMAC-SHA256");
+        sortMap.put("transaction_id", orderInfo.getTransactionId());
+        String orderCode = getOrderCode(orderInfo.getUserId()); //商户分账单号
+        sortMap.put("out_order_no", orderCode);
+
+        //扣除手续费后
+        double commission = orderInfo.getTotal() * 0.01;
+        double total = orderInfo.getTotal() - commission;
+        int amount = (int) Math.floor(total * 0.3);
+        Map<String, Object> receiverMap = new TreeMap<String, Object>();
+        receiverMap.put("type", "PERSONAL_OPENID");
+
+        //获取上级
+        Map<String, Object> accountMap = getAccount(orderInfo);
+        String account = null;
+        Integer openIdType = null;
+        if (accountMap != null) {
+            account = (String) accountMap.get("account");
+            openIdType = (Integer) accountMap.get("openIdType");
+        }
+        if (StringUtils.isNotEmpty(account)) {  //如果存在上级,分给上给
+            receiverMap.put("account", account);
+        } else {                               //如果不存在上级,分给固定的
+            receiverMap.put("account", "o7N3j5XxUrgOKE4ulP-HseFpBCiM");
+        }
+
+        receiverMap.put("amount", amount);
+        receiverMap.put("description", "分到个人");  //合作合伙
+        ObjectMapper objectMapper = new ObjectMapper();
+        String receiverMapJson = objectMapper.writeValueAsString(receiverMap);
+        sortMap.put("receivers", receiverMapJson);
+
+        WXPayConfig config = new WxPayConfigImpl();
+        String sign = WXPayUtil.generateSignature(sortMap, config.getKey(), WXPayConstants.SignType.HMACSHA256);
+        sortMap.put("sign", sign);
+
+        WXPay pay = new WXPay(config);
+        String xmlStr = pay.requestWithCert(url, sortMap, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());
+        Map<String, String> resMap = XmlUtil.xmlToMap(xmlStr);
+        if (!"SUCCESS".equals(resMap.get("return_code")) || !"SUCCESS".equals(resMap.get("result_code"))) {
+            //throw new CustomException("微信分账出错");
+            log.info("微信分账出错");
+            log.info(resMap.toString());
+            orderInfo.setProfitSharing(3);
+            orderInfoService.updateById(orderInfo);
+            return false;
+        }
+        //更新成交订单表
+        orderInfo.setProfitSharing(2);
+        orderInfoService.updateById(orderInfo);
+
+        OrderSplit orderSplit = new OrderSplit();
+        orderSplit.setOutSplitNo(orderCode);
+        orderSplit.setOutTradeNo(orderInfo.getOutTradeNo());
+        orderSplit.setAmount(amount);
+        orderSplit.setOpenId(account);
+        if (openIdType!=null) {
+            orderSplit.setOpenIdType(openIdType);
+        } else {
+            orderSplit.setOpenIdType(2);
+        }
+        orderSplit.setDescription("分到个人");
+        return orderSplitService.save(orderSplit);
+    }
 
 
     @Override
@@ -92,7 +242,7 @@ public class WxOrderServiceImpl extends ServiceImpl<WxOrderMapper, WxOrder> impl
 //        }
 
         Map<String, String> sortMap = new TreeMap<String, String>();
-        sortMap.put("mch_appid",appid);
+        sortMap.put("mch_appid",xcxAppid);
         sortMap.put("mchid",wxpayConfig.getMerchantId());
         sortMap.put("nonce_str", RandomStringUtils.randomAlphanumeric(32));
         sortMap.put("partner_trade_no",getOrderCode(null));
@@ -193,5 +343,40 @@ public class WxOrderServiceImpl extends ServiceImpl<WxOrderMapper, WxOrder> impl
         return resMap.get("return_msg");
     }
 
+    /**
+     * 查询出上级unionId
+     *
+     * @param orderInfo
+     * @return
+     */
+    private Map<String, Object> getAccount(OrderInfo orderInfo) {
+        Map<String, Object> resultMap = new HashMap<String, Object>();
+
+        String account = null;
+        UserInfo userInfo = sysUserService.getStudentByUnionId(orderInfo.getUnionId());
+        UserInfo pUserInfo = null;
+        if (userInfo.getPUnionId() != null) {
+            pUserInfo = sysUserService.getStudentByUnionId(userInfo.getPUnionId());
+        }
+        if (pUserInfo != null) {
+            if (StringUtils.isNotEmpty(pUserInfo.getXcxOpenid())) {
+                account = pUserInfo.getXcxOpenid();
+                resultMap.put("account", account);
+                resultMap.put("openIdType", 2);
+            } else if (StringUtils.isNotEmpty(pUserInfo.getGzhOpenid())) {
+                account = pUserInfo.getGzhOpenid();
+                resultMap.put("account", account);
+                resultMap.put("openIdType", 3);
+            } else if (StringUtils.isNotEmpty(pUserInfo.getAppOpenid())) {
+                account = pUserInfo.getAppOpenid();
+                resultMap.put("account", account);
+                resultMap.put("openIdType", 1);
+            } else {
+                return null;
+            }
+        }
+        return resultMap;
+    }
+
 
 }

+ 7 - 0
xpgx-service/src/main/resources/mapper/order/OrderInfoMapper.xml

@@ -56,6 +56,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select * from order_info where out_trade_no =#{outTradeNo}
     </select>
 
+    <select id="selectOrderInfoByWaitProfit" resultType="com.miaxis.order.domain.OrderInfo">
+        select * from order_info where trade_type = 1 and profit_sharing = 1
+        <if test="nowDate != null"><!-- 开始时间检索 -->
+            and DATE_FORMAT(success_time,'%Y-%m-%d %H:%i:%S') <![CDATA[ <= ]]> #{nowDate}
+        </if>
+        order by success_time
+    </select>
 
 
 </mapper>

+ 36 - 0
xpgx-service/src/main/resources/mapper/order/OrderSplitMapper.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.miaxis.order.mapper.OrderSplitMapper">
+
+    <resultMap type="OrderSplit" id="OrderSplitResult">
+        <result property="id"    column="id"    />
+        <result property="outSplitNo"    column="out_split_no"    />
+        <result property="outTradeNo"    column="out_trade_no"    />
+        <result property="amount"    column="amount"    />
+        <result property="openId"    column="open_id"    />
+        <result property="description"    column="description"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectOrderSplitVo">
+        select * from order_split
+    </sql>
+
+
+    <select id="selectOrderSplitList" parameterType="OrderSplit" resultType="com.miaxis.order.vo.OrderSplitVo">
+        select s.*,u.nick_name from order_split s join user_info u on s.open_id = u.xcx_openid
+        or s.open_id = u.app_openid or s.open_id = u.gzh_openid
+        <where>
+            <if test="outSplitNo != null  and outSplitNo != ''"> and s.out_split_no = #{outSplitNo}</if>
+            <if test="outTradeNo != null  and outTradeNo != ''"> and s.out_trade_no = #{outTradeNo}</if>
+            <if test="amount != null "> s.and amount = #{amount}</if>
+            <if test="openId != null  and openId != ''"> and s.open_id = #{openId}</if>
+            <if test="description != null  and description != ''"> and s.description = #{description}</if>
+        </where>
+    </select>
+
+
+</mapper>