Explorar el Código

Merge branch 'refs/heads/master' into 红德堂

ct hace 4 días
padre
commit
0e2c0ccf06

+ 24 - 0
fs-admin/src/main/java/com/fs/his/controller/FsCompanyDivItemController.java

@@ -1,6 +1,8 @@
 package com.fs.his.controller;
 
 import java.util.List;
+
+import com.fs.common.core.domain.R;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -68,6 +70,28 @@ public class FsCompanyDivItemController extends BaseController
         return AjaxResult.success(companyDivItemService.selectCompanyDivItemById(id));
     }
 
+    /**
+     * 分账确认
+     */
+    @PreAuthorize("@ss.hasPermi('his:divItem:confirm')")
+    @Log(title = "延迟分账确认", businessType = BusinessType.UPDATE)
+    @PostMapping("/confirm")
+    public R confirm(@RequestBody List<String> payCodes)
+    {
+        return companyDivItemService.confirmByPayCodes(payCodes);
+    }
+
+    /**
+     * 分账确认Scrm
+     */
+    @PreAuthorize("@ss.hasPermi('his:divItem:confirm')")
+    @Log(title = "延迟分账确认", businessType = BusinessType.UPDATE)
+    @PostMapping("/confirm")
+    public R confirmScrm(@RequestBody List<String> payCodes)
+    {
+        return companyDivItemService.confirmByPayCodesScrm(payCodes);
+    }
+
 //    /**
 //     * 新增分账明细
 //     */

+ 1 - 1
fs-company/src/main/java/com/fs/company/controller/course/qw/FsQwCourseWatchLogController.java

@@ -86,7 +86,7 @@ public class FsQwCourseWatchLogController extends BaseController
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         return getDataTable(list);
     }
-    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsList')")
+    @PreAuthorize("@ss.hasPermi('qw:user:export')")
     @GetMapping("/statisticsExport")
     public AjaxResult statisticsExport(FsCourseWatchLogStatisticsListParam param)
     {

+ 17 - 0
fs-company/src/main/java/com/fs/company/controller/qw/SopUserLogsInfoController.java

@@ -10,7 +10,10 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.PubFun;
+import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
 import com.fs.qw.domain.QwGroupChatUser;
 import com.fs.qw.domain.QwTag;
 import com.fs.qw.mapper.QwTagMapper;
@@ -20,6 +23,7 @@ import com.fs.qw.param.SopExternalContactInfo;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwGroupChatUserService;
 import com.fs.qw.service.IQwTagService;
+import com.fs.qw.service.IQwUserService;
 import com.fs.sop.domain.SopUserLogsInfo;
 import com.fs.sop.params.BatchSopUserLogsInfoParam;
 import com.fs.sop.params.SendUserLogsInfoMsgParam;
@@ -62,6 +66,10 @@ public class SopUserLogsInfoController extends BaseController
     private IQwGroupChatUserService qwGroupChatUserService;
 
     private static final Gson GSON = new Gson();
+    @Autowired
+    private IQwUserService qwUserService;
+    @Autowired
+    private TokenService tokenService;
 
     /**
      * 查询sopUserLogsInfo列表
@@ -528,6 +536,15 @@ public class SopUserLogsInfoController extends BaseController
     @RepeatSubmit
     public R sendUserLogsInfoMsgSop(@RequestBody SendUserLogsInfoMsgParam param)
     {
+        if (param.getIsMine() != null && param.getIsMine() == 1) {
+            //我的sop
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+            //查询qwUserId
+            List<String> qwUserIds = qwUserService.selectQwUserListByCompanyUserId(loginUser.getUser().getUserId(), param.getCorpId());
+            if (qwUserIds != null && !qwUserIds.isEmpty()) {
+                param.setQwUserIds(qwUserIds);
+            }
+        }
         return sopUserLogsInfoService.sendUserLogsInfoMsgSop(param);
     }
 

+ 5 - 0
fs-service/src/main/java/com/fs/company/domain/CompanyDivItem.java

@@ -52,4 +52,9 @@ public class CompanyDivItem extends BaseEntity{
     private Integer isRefund;
 
 
+    /** 延迟交易状态: (实时分账 null) 0:未确认 1:已确认 */
+    @Excel(name = "是否退款 0否 1是")
+    private Integer delayStatus;
+
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyDivItemService.java

@@ -2,6 +2,7 @@ package com.fs.company.service;
 
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
 import com.fs.company.domain.CompanyDivItem;
 
 /**
@@ -62,4 +63,8 @@ public interface ICompanyDivItemService extends IService<CompanyDivItem>{
     CompanyDivItem selectCompanyDivItemByOrderCode(String orderCode);
 
     CompanyDivItem selectCompanyDivItemByPayCode(String payCode);
+
+    R confirmByPayCodes(List<String> payCodes);
+
+    R confirmByPayCodesScrm(List<String> payCodes);
 }

+ 19 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyDivItemServiceImpl.java

@@ -1,8 +1,11 @@
 package com.fs.company.service.impl;
 
 import java.util.List;
+
+import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.company.mapper.CompanyDivItemMapper;
@@ -101,4 +104,20 @@ public class CompanyDivItemServiceImpl extends ServiceImpl<CompanyDivItemMapper,
     public CompanyDivItem selectCompanyDivItemByPayCode(String payCode) {
         return baseMapper.selectCompanyDivItemByPayCode(payCode);
     }
+
+    @Override
+    public R confirmByPayCodes(List<String> payCodes) {
+        if (payCodes != null && !payCodes.isEmpty()) {
+            payCodes.forEach(HuiFuUtils::confirmByPayCode);
+        }
+        return R.ok();
+    }
+
+    @Override
+    public R confirmByPayCodesScrm(List<String> payCodes) {
+        if (payCodes != null && !payCodes.isEmpty()) {
+            payCodes.forEach(HuiFuUtils::confirmByPayCodeScrm);
+        }
+        return R.ok();
+    }
 }

+ 11 - 42
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -1300,48 +1300,17 @@ public class CompanyServiceImpl implements ICompanyService
         if(companyId!=null&&companyId>0){
             Company company=companyMapper.selectCompanyByIdForUpdate(companyId);
             if(company!=null){
-                String companyMoneyKey = FsConstants.COMPANY_MONEY_KEY + company.getCompanyId();
-                // 加锁,与看课发放红包的加锁保持一致
-                RLock lock = redissonClient.getLock(FsConstants.COMPANY_MONEY_LOCK + company.getCompanyId());
-                boolean lockAcquired = false;
-                try {
-                    lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
-                    if (lockAcquired) {
-                        BigDecimal redisMoney;
-                        // 获取当前余额
-                        String moneyStr = redisCache.getCacheObject(companyMoneyKey);
-                        if (StringUtils.isNotEmpty(moneyStr)) {
-                            redisMoney = new BigDecimal(moneyStr);
-                        } else {
-                            redisMoney = company.getMoney();
-                        }
-                        BigDecimal newMoney = redisMoney.add(money);
-                        logger.info("退回红包金额:"+money);
-                        company.setMoney(newMoney);
-                        companyMapper.updateCompany(company);
-                        CompanyMoneyLogs log=new CompanyMoneyLogs();
-                        log.setCompanyId(company.getCompanyId());
-                        log.setRemark("退回红包金额");
-                        log.setMoney(money);
-                        log.setLogsType(16);
-                        log.setBalance(newMoney);
-                        log.setCreateTime(new Date());
-                        moneyLogsMapper.insertCompanyMoneyLogs(log);
-
-                        redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
-                    }
-                } catch (Exception e) {
-                    logger.error("退回的红包同步增加到缓存和数据表,参数错误,请求异常,异常信息:{}", e.getMessage(), e);
-                } finally {
-                    if (lockAcquired && lock.isHeldByCurrentThread()) {
-                        try {
-                            lock.unlock();
-                        } catch (IllegalMonitorStateException e) {
-                            logger.warn("尝试释放非当前线程持有的锁: companyId:{}", company.getCompanyId());
-                        }
-                    }
-                }
-
+                logger.info("退回红包金额:"+money);
+                company.setMoney(company.getMoney().add(money));
+                companyMapper.updateCompany(company);
+                CompanyMoneyLogs log=new CompanyMoneyLogs();
+                log.setCompanyId(company.getCompanyId());
+                log.setRemark("退回红包金额");
+                log.setMoney(money);
+                log.setLogsType(16);
+                log.setBalance(company.getMoney());
+                log.setCreateTime(new Date());
+                moneyLogsMapper.insertCompanyMoneyLogs(log);
             }
         }
     }

+ 39 - 6
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -14,10 +14,8 @@ import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.*;
 import com.fs.common.utils.ip.IpUtils;
-import com.fs.company.domain.Company;
-import com.fs.company.domain.CompanyDept;
-import com.fs.company.domain.CompanyMoneyLogs;
-import com.fs.company.domain.CompanyUser;
+import com.fs.company.domain.*;
+import com.fs.company.mapper.CompanyDivItemMapper;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
 import com.fs.company.param.FsStoreStatisticsParam;
@@ -52,12 +50,14 @@ import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
 import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.hisStore.param.FsStoreOrderRefundByProductParam;
 import com.fs.hisStore.service.IFsStoreOrderLogsScrmService;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisapi.domain.ApiResponse;
 import com.fs.hisapi.param.CreateOrderParam;
 import com.fs.hisapi.param.RecipeDetailParam;
 import com.fs.hisapi.service.HisApiService;
-import com.fs.huifuPay.domain.HuiFuCreateOrder;
-import com.fs.huifuPay.domain.HuifuCreateOrderResult;
+import com.fs.huifuPay.domain.*;
+import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentDelaytransConfirmRequest;
+import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.im.dto.*;
 import com.fs.im.service.IImService;
@@ -285,6 +285,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     @Autowired
     private IFsUserWxService userWxService;
 
+    @Autowired
+    private CompanyDivItemMapper companyDivItemMapper;
+
     @Value("${express.omsCode}")
     private String expressOmsCode;
 
@@ -296,6 +299,8 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
     //ERP 类型到服务的映射
     private Map<Integer, IErpOrderService> erpServiceMap;
+
+    private IFsStoreOrderScrmService orderScrmService;
     @PostConstruct
     public void initErpServiceMap() {
         erpServiceMap = new HashMap<>();
@@ -643,6 +648,13 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
         fsUserWatchService.addUserWatch(order);
         int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
+        try {
+            if (i > 0){
+                HuiFuUtils.confirmByOrderCode(order.getOrderCode());
+            }
+        } catch (Exception e) {
+            log.error("延迟分账确认交易失败:{}", e.getMessage());
+        }
         fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
                 opeName + " " +FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
         return i;
@@ -2204,6 +2216,27 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
                     }
                 }
+
+                List<FsStoreOrderScrm> orders2 = orderScrmService.selectFsStoreOrderListByDeliveryId(dto.getLogisticCode());
+                if (orders != null) {
+                    for (FsStoreOrderScrm order : orders2) {
+                        logger.info("订单信息:" + JSONUtil.toJsonStr(order));
+                        logger.info("运单号:" + dto.getLogisticCode());
+                        if (order != null && (order.getDeliveryStatus()==null|| order.getDeliveryStatus()!= 3)) {
+                            FsStoreOrderScrm map = new FsStoreOrderScrm();
+                            map.setDeliveryStatus(Integer.parseInt(dto.getState()));
+                            map.setId(order.getId());
+                            map.setDeliveryType(dto.getStateEx());
+                            orderScrmService.updateFsStoreOrder(map);
+                            //如果是正常签收,更新订单状态
+                            if (dto.getState().equals("3") && (dto.getStateEx().equals("301") || dto.getStateEx().equals("302") || dto.getStateEx().equals("304") || dto.getStateEx().equals("311"))) {
+                                orderScrmService.finishOrder(order.getId());
+                            }
+
+                        }
+                    }
+                }
+
             }
             return ExpressResultDTO.success(sysConfig.getKdnId().trim());
         }

+ 27 - 0
fs-service/src/main/java/com/fs/huifuPay/domain/HuiFuConfirmOrder.java

@@ -0,0 +1,27 @@
+package com.fs.huifuPay.domain;
+
+import lombok.Data;
+
+@Data
+public class HuiFuConfirmOrder {
+//    T_JSAPI: 微信公众号
+//    T_MINIAPP: 微信小程序
+//    A_JSAPI: 支付宝JS
+//    A_NATIVE: 支付宝正扫
+//    U_NATIVE: 银联正扫
+//    U_JSAPI: 银联JS
+//    D_NATIVE: 数字人民币正扫
+//    T_H5:微信直连H5支付
+//    T_APP:微信APP支付(只支持直连)
+//    T_NATIVE:微信正扫(只支持直连)
+    String tradeType;
+    String reqSeqId;
+    String transAmt;
+    String goodsDesc;
+    String openid;
+    String appId; //多小程序支付
+    String acctSplitBunch; //公司分账参数
+    String delayAcctFlag; //延时交易 延迟分账需要
+    String orgReqSeqId; //原交易请求流水号
+    String orgReqDate; //原交易请求日期
+}

+ 30 - 1
fs-service/src/main/java/com/fs/huifuPay/sdk/opps/core/request/V2TradePaymentDelaytransConfirmRequest.java

@@ -27,6 +27,18 @@ public class V2TradePaymentDelaytransConfirmRequest extends BaseRequest {
     @JSONField(name = "huifu_id")
     private String huifuId;
 
+    /**
+     * 原交易请求流水号
+     */
+    @JSONField(name = "org_req_seq_id")
+    private String orgReqSeqId;
+
+    /**
+     * 原交易请求日期
+     */
+    @JSONField(name = "org_req_date")
+    private String orgReqDate;
+
     @Override
     public FunctionCodeEnum getFunctionCode() {
         return FunctionCodeEnum.V2_TRADE_PAYMENT_DELAYTRANS_CONFIRM;
@@ -35,10 +47,12 @@ public class V2TradePaymentDelaytransConfirmRequest extends BaseRequest {
     public V2TradePaymentDelaytransConfirmRequest() {
     }
 
-    public V2TradePaymentDelaytransConfirmRequest(String reqDate, String reqSeqId, String huifuId) {
+    public V2TradePaymentDelaytransConfirmRequest(String reqDate, String reqSeqId, String huifuId,String orgReqSeqId,String orgReqDate) {
         this.reqDate = reqDate;
         this.reqSeqId = reqSeqId;
         this.huifuId = huifuId;
+        this.orgReqSeqId = orgReqSeqId;
+        this.orgReqDate = orgReqDate;
     }
 
     public String getReqDate() {
@@ -65,4 +79,19 @@ public class V2TradePaymentDelaytransConfirmRequest extends BaseRequest {
         this.huifuId = huifuId;
     }
 
+    public String getOrgReqSeqId() {
+        return orgReqSeqId;
+    }
+
+    public void setOrgReqSeqId(String orgReqSeqId) {
+        this.orgReqSeqId = orgReqSeqId;
+    }
+
+    public String getOrgReqDate() {
+        return orgReqDate;
+    }
+
+    public void setOrgReqDate(String orgReqDate) {
+        this.orgReqDate = orgReqDate;
+    }
 }

+ 233 - 93
fs-service/src/main/java/com/fs/huifuPay/sdk/opps/core/utils/HuiFuUtils.java

@@ -2,6 +2,7 @@ package com.fs.huifuPay.sdk.opps.core.utils;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyDivItem;
@@ -15,129 +16,65 @@ import com.fs.his.domain.FsPackageOrder;
 import com.fs.his.domain.FsPayConfig;
 import com.fs.his.domain.FsStoreOrder;
 import com.fs.his.domain.FsStorePayment;
+import com.fs.his.mapper.FsStorePaymentMapper;
+import com.fs.hisStore.domain.FsStorePaymentScrm;
+import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
+import com.fs.huifuPay.domain.HuiFuConfirmOrder;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
+import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
+import com.fs.huifuPay.service.HuiFuService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.google.gson.Gson;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
 
 public class HuiFuUtils {
     private static ICompanyDivConfigService companyDivConfigService = SpringUtils.getBean(ICompanyDivConfigService.class);
     private static ICompanyDivItemService companyDivItemService = SpringUtils.getBean(ICompanyDivItemService.class);
+    private static FsStorePaymentMapper fsStorePaymentMapper = SpringUtils.getBean(FsStorePaymentMapper.class);
+    private static FsStorePaymentScrmMapper fsStorePaymentScrmMapper = SpringUtils.getBean(FsStorePaymentScrmMapper.class);
+    private static HuiFuService huiFuService = SpringUtils.getBean(HuiFuService.class);
 
     /**
-     *  处理分账
+     * 处理分账
+     *
      * @param huiFuCreateOrder
      * @param companyId
      */
     public static void doDiv(HuiFuCreateOrder huiFuCreateOrder, Long companyId) throws Exception {
         //默认汇付账户
-        SysConfigMapper sysConfigMapper= SpringUtils.getBean(SysConfigMapper.class);
+        SysConfigMapper sysConfigMapper = SpringUtils.getBean(SysConfigMapper.class);
         SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
         FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
         String defaultHuifuId = fsPayConfig.getHuifuId();
         //查询是否开启分账
-        if (companyId !=null){
+        if (companyId != null) {
 
             CompanyDivConfigVo configVo = companyDivConfigService.selectCompanyDivConfigByCompanyId(companyId);
-            if (configVo != null){
+            if (configVo != null) {
                 Integer divFlag = configVo.getDivFlag();
-                if (divFlag != null && divFlag == 1){
+                if (divFlag != null && divFlag == 1) {
                     //开启分账
                     //汇付传参
                     Map<String, Object> acctSplitBunchMap = new HashMap<>();
-                    List<Map<String,Object>> acctInfos = new ArrayList();
+                    List<Map<String, Object>> acctInfos = new ArrayList();
                     List<CompanyAcctInfo> acctInfoVos = configVo.getAcctInfos();
-                    if (acctInfoVos != null && !acctInfoVos.isEmpty()){
+                    if (acctInfoVos != null && !acctInfoVos.isEmpty()) {
                         String delayAcctFlag = configVo.getDelayAcctFlag();
                         String percentageFlag = configVo.getPercentageFlag();
-                        if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("N")){
+                        if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("N")) {
                             //实时分账
-                            if (StringUtils.isNotBlank(percentageFlag) && percentageFlag.equals("Y")){
-                                acctSplitBunchMap.put("percentage_flag","Y");
-                                Float total = 0f;
-                                //百分比分账
-                                for (CompanyAcctInfo acctInfo : acctInfoVos) {
-                                    Map<String, Object> map = new HashMap<>();
-                                    Float percentageDiv = acctInfo.getPercentageDiv();
-                                    if (percentageDiv == null || percentageDiv <= 0){
-                                        continue;
-                                    }
-                                    map.put("percentage_div", String.format("%.2f", percentageDiv));
-                                    if (percentageDiv > 100){
-                                        acctInfos = null;
-                                        break;
-                                    }
-                                    total = total + percentageDiv;
-                                    if (total>100){
-                                        acctInfos = null;
-                                        break;
-                                    }
-                                    if (StringUtils.isBlank(acctInfo.getAcctId())){
-                                        acctInfo.setAcctId(null);
-                                    }
-                                    map.put("huifu_id", acctInfo.getHuifuId());
-                                    acctInfos.add(map);
-                                }
-                                if (acctInfos != null && !acctInfos.isEmpty()){
-                                    Map<String, Object> defaultAccount = new HashMap<>();
-                                    defaultAccount.put("percentage_div", String.format("%.2f", 100f - total));
-                                    defaultAccount.put("huifu_id", defaultHuifuId);
-                                    acctInfos.add(defaultAccount);
-                                }
-
-
-                            } else {
-                                acctSplitBunchMap.put("percentage_flag","N");
-                                // 固定金额
-                                BigDecimal amtTotal = BigDecimal.ZERO;
-                                //支付金额
-                                BigDecimal initTotal = new BigDecimal(huiFuCreateOrder.getTransAmt()).setScale(2, RoundingMode.FLOOR);
-                                for (CompanyAcctInfo acctInfo : acctInfoVos) {
-                                    Map<String, Object> map = new HashMap<>();
-                                    BigDecimal divAmt = acctInfo.getDivAmt().setScale(2, RoundingMode.FLOOR);
-                                    if (divAmt.compareTo(BigDecimal.ZERO) <= 0){
-                                        continue;
-                                    }
-                                    map.put("div_amt",divAmt.toString());
-                                    amtTotal = amtTotal.add(divAmt);
-                                    if (amtTotal.compareTo(initTotal) > 0){
-                                        acctInfos = null;
-                                        break;
-                                    }
-                                    if (StringUtils.isBlank(acctInfo.getAcctId())){
-                                        acctInfo.setAcctId(null);
-                                    }
-                                    map.put("huifu_id", acctInfo.getHuifuId());
-                                    acctInfos.add(map);
-                                }
-                                if (acctInfos != null && !acctInfos.isEmpty()){
-                                    if (initTotal.compareTo(amtTotal)<0){
-                                        acctInfos = null;
-                                    } else {
-                                        Map<String, Object> defaultAccount = new HashMap<>();
-                                        defaultAccount.put("div_amt", String.valueOf(initTotal.subtract(amtTotal).setScale(2, RoundingMode.FLOOR)));
-                                        defaultAccount.put("huifu_id", defaultHuifuId);
-                                        acctInfos.add(defaultAccount);
-                                    }
-                                }
-
-                            }
-
-                            if (acctInfos != null){
-                                acctSplitBunchMap.put("is_clean_split", configVo.getIsCleanSplit());
-                                acctSplitBunchMap.put("acct_infos", acctInfos);
-                                huiFuCreateOrder.setAcctSplitBunch( JSON.toJSONString(acctSplitBunchMap));
-                            }
-                        } else if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("Y")){
+                            huiFuCreateOrder.setDelayAcctFlag("N");
+                            extractedDiv(huiFuCreateOrder, percentageFlag, acctSplitBunchMap, acctInfoVos, acctInfos, defaultHuifuId, configVo);
+                        } else if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("Y")) {
                             //延时分账 确认交易时传参
                             huiFuCreateOrder.setDelayAcctFlag("Y");
+                            extractedDiv(huiFuCreateOrder, percentageFlag, acctSplitBunchMap, acctInfoVos, acctInfos, defaultHuifuId, configVo);
                         }
 
                     }
@@ -146,20 +83,108 @@ public class HuiFuUtils {
         }
     }
 
+    private static void extractedDiv(HuiFuCreateOrder huiFuCreateOrder, String percentageFlag,
+                                     Map<String, Object> acctSplitBunchMap, List<CompanyAcctInfo> acctInfoVos,
+                                     List<Map<String, Object>> acctInfos, String defaultHuifuId, CompanyDivConfigVo configVo) {
+        if (StringUtils.isNotBlank(percentageFlag) && percentageFlag.equals("Y")) {
+            acctSplitBunchMap.put("percentage_flag", "Y");
+            Float total = 0f;
+            //百分比分账
+            for (CompanyAcctInfo acctInfo : acctInfoVos) {
+                Map<String, Object> map = new HashMap<>();
+                Float percentageDiv = acctInfo.getPercentageDiv();
+                if (percentageDiv == null || percentageDiv <= 0) {
+                    continue;
+                }
+                map.put("percentage_div", String.format("%.2f", percentageDiv));
+                if (percentageDiv > 100) {
+                    acctInfos = null;
+                    break;
+                }
+                total = total + percentageDiv;
+                if (total > 100) {
+                    acctInfos = null;
+                    break;
+                }
+                if (StringUtils.isBlank(acctInfo.getAcctId())) {
+                    acctInfo.setAcctId(null);
+                }
+                map.put("huifu_id", acctInfo.getHuifuId());
+                acctInfos.add(map);
+            }
+            if (acctInfos != null && !acctInfos.isEmpty()) {
+                Map<String, Object> defaultAccount = new HashMap<>();
+                defaultAccount.put("percentage_div", String.format("%.2f", 100f - total));
+                defaultAccount.put("huifu_id", defaultHuifuId);
+                acctInfos.add(defaultAccount);
+            }
+
+
+        } else {
+            acctSplitBunchMap.put("percentage_flag", "N");
+            // 固定金额
+            BigDecimal amtTotal = BigDecimal.ZERO;
+            //支付金额
+            BigDecimal initTotal = new BigDecimal(huiFuCreateOrder.getTransAmt()).setScale(2, RoundingMode.FLOOR);
+            for (CompanyAcctInfo acctInfo : acctInfoVos) {
+                Map<String, Object> map = new HashMap<>();
+                BigDecimal divAmt = acctInfo.getDivAmt().setScale(2, RoundingMode.FLOOR);
+                if (divAmt.compareTo(BigDecimal.ZERO) <= 0) {
+                    continue;
+                }
+                map.put("div_amt", divAmt.toString());
+                amtTotal = amtTotal.add(divAmt);
+                if (amtTotal.compareTo(initTotal) > 0) {
+                    acctInfos = null;
+                    break;
+                }
+                if (StringUtils.isBlank(acctInfo.getAcctId())) {
+                    acctInfo.setAcctId(null);
+                }
+                map.put("huifu_id", acctInfo.getHuifuId());
+                acctInfos.add(map);
+            }
+            if (acctInfos != null && !acctInfos.isEmpty()) {
+                if (initTotal.compareTo(amtTotal) < 0) {
+                    acctInfos = null;
+                } else {
+                    Map<String, Object> defaultAccount = new HashMap<>();
+                    defaultAccount.put("div_amt", String.valueOf(initTotal.subtract(amtTotal).setScale(2, RoundingMode.FLOOR)));
+                    defaultAccount.put("huifu_id", defaultHuifuId);
+                    acctInfos.add(defaultAccount);
+                }
+            }
+
+        }
+
+        if (acctInfos != null) {
+            acctSplitBunchMap.put("is_clean_split", configVo.getIsCleanSplit());
+            acctSplitBunchMap.put("acct_infos", acctInfos);
+            huiFuCreateOrder.setAcctSplitBunch(JSON.toJSONString(acctSplitBunchMap));
+        }
+    }
+
     public static void saveDivItem(HuiFuCreateOrder o, String orderCode, String payCode) {
         CompanyDivItem companyDivItem = new CompanyDivItem();
-        if (StringUtils.isNotBlank(o.getAcctSplitBunch())){
+        if (StringUtils.isNotBlank(o.getAcctSplitBunch())) {
             companyDivItem.setOrderCode(orderCode);
             companyDivItem.setPayCode(payCode);
             companyDivItem.setDetail(o.getAcctSplitBunch());
             companyDivItem.setIsRefund(0); //支付
-            companyDivItem.setIsDelay(0); //延迟分账
+            if (StringUtils.isNotBlank(o.getDelayAcctFlag()) && o.getDelayAcctFlag().equals("Y")) {
+                companyDivItem.setIsDelay(1); //延迟分账
+
+            } else {
+                companyDivItem.setIsDelay(0);
+                companyDivItem.setDelayStatus(0);
+            }
             companyDivItemService.insertCompanyDivItem(companyDivItem);
         }
     }
 
     /**
      * 回调修改分账明细状态
+     *
      * @param payCode
      */
     public static void updateDivItem(String payCode) {
@@ -172,7 +197,6 @@ public class HuiFuUtils {
     }
 
 
-
     /**
      * 处理分账退款
      *
@@ -180,7 +204,7 @@ public class HuiFuUtils {
      * @param payment
      * @param extendInfoMap
      */
-    public static CompanyDivItem doRefundDiv(BigDecimal payPrice,BigDecimal reMoney, FsStorePayment payment, Map<String, Object> extendInfoMap) {
+    public static CompanyDivItem doRefundDiv(BigDecimal payPrice, BigDecimal reMoney, FsStorePayment payment, Map<String, Object> extendInfoMap) {
         CompanyDivItem companyDivItem = null;
         companyDivItem = companyDivItemService.selectCompanyDivItemByPayCode(payment.getPayCode());
         if (companyDivItem != null) {
@@ -251,4 +275,120 @@ public class HuiFuUtils {
         return companyDivItem;
 
     }
+
+    public static void confirmByOrderCode(String orderCode) {
+        FsStorePayment queryParam = new FsStorePayment();
+        queryParam.setBusinessCode(orderCode);
+        queryParam.setStatus(1);
+        List<FsStorePayment> fsStorePayments = fsStorePaymentMapper.selectFsStorePaymentList(queryParam);
+        if (!fsStorePayments.isEmpty()) {
+            FsStorePayment fsStorePayment = fsStorePayments.get(0);
+            Integer businessType = fsStorePayment.getBusinessType();
+            String appId = fsStorePayment.getAppId();
+            Date payTime = fsStorePayment.getPayTime();
+            String payCode = fsStorePayment.getPayCode();
+            confirm(payCode, businessType, appId, payTime);
+        }
+    }
+
+    public static void confirmByPayCode(String payCode) {
+        FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
+        if (fsStorePayment == null){
+            confirmByPayCodeScrm(payCode);
+        } else {
+            Integer businessType = fsStorePayment.getBusinessType();
+            String appId = fsStorePayment.getAppId();
+            Date payTime = fsStorePayment.getPayTime();
+            confirm(payCode, businessType, appId, payTime);
+        }
+    }
+
+    public static void confirmByOrderCodeScrm(String orderCode) {
+        FsStorePaymentScrm queryParam = new FsStorePaymentScrm();
+        queryParam.setBusinessCode(orderCode);
+        queryParam.setStatus(1);
+        List<FsStorePaymentScrm> fsStorePayments = fsStorePaymentScrmMapper.selectFsStorePaymentList(queryParam);
+        if (!fsStorePayments.isEmpty()) {
+            FsStorePaymentScrm fsStorePayment = fsStorePayments.get(0);
+            Integer businessType = fsStorePayment.getBusinessType();
+            String appId = fsStorePayment.getAppId();
+            Date payTime = fsStorePayment.getPayTime();
+            String payCode = fsStorePayment.getPayCode();
+            confirm(payCode, businessType, appId, payTime);
+        }
+    }
+
+    public static void confirmByPayCodeScrm(String payCode) {
+        FsStorePaymentScrm fsStorePayment = fsStorePaymentScrmMapper.selectFsStorePaymentByPaymentCode(payCode);
+        if (fsStorePayment != null) {
+            Integer businessType = fsStorePayment.getBusinessType();
+            String appId = fsStorePayment.getAppId();
+            Date payTime = fsStorePayment.getPayTime();
+            confirm(payCode, businessType, appId, payTime);
+        }
+    }
+
+    private static void confirm(String payCode, Integer businessType, String appId,Date payTime) {
+        CompanyDivItem companyDivItem = companyDivItemService.selectCompanyDivItemByPayCode(payCode);
+        if (companyDivItem != null) {
+            if (companyDivItem.getIsDelay() != null && companyDivItem.getIsDelay() == 1) {
+                //延时分账 确认订单分账
+                HuiFuConfirmOrder confirmOrder = new HuiFuConfirmOrder();
+                String orgReqSeqId = payCode;
+                switch (businessType) {
+                    case 1:
+                        orgReqSeqId = "inquiry-" + orgReqSeqId;
+                        break;
+                    case 2:
+                        orgReqSeqId = "store-" + orgReqSeqId;
+                        break;
+                    case 3:
+                        orgReqSeqId = "package-" + orgReqSeqId;
+                        break;
+                    case 4:
+                        orgReqSeqId = "course-" + orgReqSeqId;
+                        break;
+                    case 5:
+                        orgReqSeqId = "appvip-" + orgReqSeqId;
+                        break;
+                    case 6:
+                        orgReqSeqId = "integral-" + orgReqSeqId;
+                        break;
+                    case 7:
+                        orgReqSeqId = "payment-" + orgReqSeqId;
+                        break;
+                }
+                confirmOrder.setOrgReqSeqId(orgReqSeqId);
+                confirmOrder.setOrgReqDate(DateUtils.parseDateToStr("yyyyMMdd", payTime));
+                confirmOrder.setAppId(appId);
+                HuiFuQueryOrderResult huiFuResult = huiFuService.delayTransConfirm(confirmOrder);
+                /**
+                 * {
+                 * 	"org_req_date": "20251111",
+                 * 	"resp_desc": "交易成功",
+                 * 	"trans_stat": "S",
+                 * 	"org_hf_seq_id": "002900TOP2A251111092843P250ac139c1400000",
+                 * 	"confirmed_amt": "0.02",
+                 * 	"hf_seq_id": "003500TOP3A251111101202P443ac13696f00000",
+                 * 	"org_mer_ord_id": "package-1988056235747835904",
+                 * 	"org_req_seq_id": "package-1988056235747835904",
+                 * 	"unconfirm_amt": "0.00",
+                 * 	"req_seq_id": "202511111011597366vxgcpozqvirxg",
+                 * 	"req_date": "20251111",
+                 * 	"resp_code": "00000000",
+                 * 	"acct_resp_desc": "成功",
+                 * 	"huifu_id": "6666000171179317",
+                 * 	"acct_split_bunch": "{\"acct_infos\":[{\"acct_id\":\"F13245119\",\"div_amt\":\"0.01\",\"huifu_id\":\"6666000181121137\",\"split_fee_acct_id\":\"F13245119\",\"split_fee_amt\":\"0.00\",\"split_fee_huifu_id\":\"6666000181121137\"},{\"acct_id\":\"F08847757\",\"div_amt\":\"0.01\",\"huifu_id\":\"6666000171179317\"}]}",
+                 * 	"acct_resp_code": "000"
+                 * }
+                 */
+                if (huiFuResult != null) {
+                    if ("00000000".equals(huiFuResult.getResp_code())) {
+                        companyDivItem.setDelayStatus(1);
+                        companyDivItemService.updateCompanyDivItem(companyDivItem);
+                    }
+                }
+            }
+        }
+    }
 }

+ 3 - 0
fs-service/src/main/java/com/fs/huifuPay/service/HuiFuService.java

@@ -36,4 +36,7 @@ public interface HuiFuService {
     /**余额支付退款查询**/
     acctPayRefundQueryResult acctPayRefundQuery(V2TradeAcctpaymentRefundQueryRequest request)throws Exception;
 
+    /**延迟分账 交易确认接口**/
+    HuiFuQueryOrderResult delayTransConfirm(HuiFuConfirmOrder request);
+
 }

+ 44 - 1
fs-service/src/main/java/com/fs/huifuPay/service/impl/HuiFuServiceImpl.java

@@ -70,7 +70,12 @@ public class HuiFuServiceImpl implements HuiFuService {
             // 禁用信用卡标记
             extendInfoMap.put("limit_pay_type", "NO_CREDIT");
             // 是否延迟交易
-            extendInfoMap.put("delay_acct_flag", "N");
+            if(StringUtils.isNotBlank(order.getDelayAcctFlag()) && order.getDelayAcctFlag().equals("Y")){
+                extendInfoMap.put("delay_acct_flag", "Y");
+            } else {
+                extendInfoMap.put("delay_acct_flag", "N");
+            }
+
             extendInfoMap.put("pay_scene", "02");
             if (StringUtils.isNotBlank(order.getAcctSplitBunch())){
                 extendInfoMap.put("acct_split_bunch", order.getAcctSplitBunch());
@@ -271,6 +276,44 @@ public class HuiFuServiceImpl implements HuiFuService {
         return result;
     }
 
+    @Override
+    public HuiFuQueryOrderResult delayTransConfirm(HuiFuConfirmOrder order){
+        HuiFuQueryOrderResult result =null;
+        try {
+            if (order.getAppId() != null) {
+                FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
+                FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(order.getAppId());
+                if (fsHfpayConfig != null) {
+                    //多汇付支付获取配置
+                    doInit(getMerConfig(fsHfpayConfig));
+                } else {
+                    //多小程序
+                    doInit(getMerConfig());
+                }
+            } else {
+                doInit(getMerConfig());
+            }
+            V2TradePaymentDelaytransConfirmRequest request = new V2TradePaymentDelaytransConfirmRequest();
+            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
+            request.setReqSeqId(SequenceTools.getReqSeqId32());
+            request.setOrgReqSeqId(order.getOrgReqSeqId()); //	原交易请求流水号
+            request.setOrgReqDate(order.getOrgReqDate()); //	原交易请求流水号
+
+            logger.info("汇付确认交易传参:"+JSON.toJSONString(request));
+            Map<String, Object> response = doExecute(request);
+            logger.info("汇付返回:"+response);
+            String jsonString = JSONObject.toJSONString(response);
+            logger.info("汇付返回:"+jsonString);
+            result = JSON.parseObject(jsonString, HuiFuQueryOrderResult.class);
+
+        }catch (Exception e){
+            logger.info("汇付确认交易失败 :"+e);
+            e.printStackTrace();
+            throw  new CustomException("汇付确认交易失败");
+        }
+        return result;
+    }
+
 
     public MerConfig getMerConfig(){
         SysConfigMapper sysConfigMapper= SpringUtils.getBean(SysConfigMapper.class);

+ 4 - 0
fs-service/src/main/java/com/fs/sop/mapper/SopUserLogsMapper.java

@@ -368,6 +368,10 @@ List<SopUserLogsVO> selectSopUserLogsGroupListByParam(@Param("maps") SopUserLogs
             "WHERE corp_id = #{param.corpId} " +
             "and sop_id in" +
             "<foreach  item='item' index='index' collection='param.sopIds' open='(' separator=',' close=')'> #{item}    </foreach>" +
+            "<if test=\"param.qwUserIds != null and param.qwUserIds.size > 0\">" +
+            "and qw_user_id in" +
+            "<foreach  item='item' index='index' collection='param.qwUserIds' open='(' separator=',' close=')'> #{item}    </foreach>" +
+            "</if>" +
             "</script>"})
     List<String> getSopUserLogsIds(@Param("param")SendUserLogsInfoMsgParam param);
 

+ 6 - 0
fs-service/src/main/java/com/fs/sop/params/SendUserLogsInfoMsgParam.java

@@ -2,6 +2,8 @@ package com.fs.sop.params;
 
 import lombok.Data;
 
+import java.util.List;
+
 /**
 * 一键群发
 */
@@ -30,4 +32,8 @@ public class SendUserLogsInfoMsgParam {
 
     private String sendTime;
 
+    private Integer isMine; //1:我的营期
+
+    private List<String> qwUserIds; //当isMine为1 需要查询该主体下该员工的营期
+
 }

+ 6 - 1
fs-service/src/main/resources/mapper/company/CompanyDivItemMapper.xml

@@ -19,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectCompanyDivItemVo">
-        select id, order_code, pay_code, detail,refund_detail,is_pay, is_delay, is_refund, create_time, update_time from company_div_item
+        select id, order_code, pay_code, detail,refund_detail,is_pay, is_delay, is_refund, create_time, update_time,delay_status from company_div_item
     </sql>
 
     <select id="selectCompanyDivItemList" parameterType="CompanyDivItem" resultMap="CompanyDivItemResult">
@@ -32,6 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isPay != null "> and is_pay = #{isPay}</if>
             <if test="isDelay != null "> and is_delay = #{isDelay}</if>
             <if test="isRefund != null "> and is_refund = #{isRefund}</if>
+            <if test="delayStatus != null "> and (delay_status = #{delayStatus} or delay_status is null)</if>
         </where>
         order by id desc
     </select>
@@ -61,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isRefund != null">is_refund,</if>
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
+            <if test="delayStatus != null">delay_status,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="orderCode != null and orderCode != ''">#{orderCode},</if>
@@ -72,6 +74,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isRefund != null">#{isRefund},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="delayStatus != null">#{delayStatus},</if>
          </trim>
     </insert>
 
@@ -87,6 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isRefund != null">is_refund = #{isRefund},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="delayStatus != null">update_time = #{delayStatus},</if>
         </trim>
         where id = #{id}
     </update>