瀏覽代碼

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

caoliqin 4 天之前
父節點
當前提交
d7cb867d6e
共有 18 個文件被更改,包括 457 次插入64 次删除
  1. 107 24
      fs-admin/src/main/java/com/fs/qw/qwTask/qwTask.java
  2. 69 31
      fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java
  3. 34 0
      fs-qwhook/src/main/java/com/fs/app/controller/CommonController.java
  4. 2 2
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyBindServiceImpl.java
  5. 14 1
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreProductPackageScrm.java
  6. 1 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  7. 58 0
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  8. 3 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductPacketVO.java
  9. 3 0
      fs-service/src/main/java/com/fs/qw/mapper/QwCompanyMapper.java
  10. 94 0
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  11. 9 0
      fs-service/src/main/java/com/fs/qw/param/QwMandatoryRegistrParam.java
  12. 1 1
      fs-service/src/main/java/com/fs/qw/service/IQwCompanyService.java
  13. 6 0
      fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java
  14. 6 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwCompanyServiceImpl.java
  15. 14 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  16. 6 1
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductPackageScrmMapper.xml
  17. 3 2
      fs-service/src/main/resources/mapper/qw/QwUserMapper.xml
  18. 27 1
      fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

+ 107 - 24
fs-admin/src/main/java/com/fs/qw/qwTask/qwTask.java

@@ -4,6 +4,7 @@ import com.fs.course.service.IFsUserCourseService;
 import com.fs.qw.domain.QwIpadServerLog;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.param.QwMandatoryRegistrParam;
 import com.fs.qw.service.*;
 import com.fs.sop.service.impl.QwSopLogsServiceImpl;
 import com.fs.sop.service.impl.QwSopServiceImpl;
@@ -15,10 +16,14 @@ import com.fs.wxwork.service.WxWorkService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.time.Duration;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 @Component("qwTask")
 public class qwTask {
@@ -73,6 +78,10 @@ public class qwTask {
     private WxWorkService wxWorkService;
 
 
+    @Autowired
+    private IQwCompanyService iQwCompanyService;
+
+
     //正在使用
     public void qwExternalContact()
     {
@@ -240,37 +249,41 @@ public class qwTask {
      * 定时清除 占着茅坑不拉屎的ipad 账号
      */
     public void selectQwUserByUnbindIpad(){
+
+        //查询所有状态为 绑定了AI主机的
         List<QwUser> list = qwUserMapper.selectQwUserByTest();
         for (QwUser qwUser : list) {
             try {
-                Integer serverStatus = qwUser.getServerStatus();
+
                 Long serverId = qwUser.getServerId();
-                if (serverStatus==0){
-                    System.out.println("不需要解绑");
-                }
+
                 if (serverId==null){
                     System.out.println("serverId不存在");
+                }else {
+                    //没绑定销售 或者 已经离职
+                    if (qwUser.getStatus()==0 || qwUser.getIsDel()==2){
+
+                        updateIpadStatus(qwUser,serverId);
+                    }
+
+                    //绑定了销售-也绑定了ipad,但是长时间离线的(离线状态,无操作超过2天的,也自动解绑)
+                    if(qwUser.getCreateTime()!=null){
+                        Date createTime = qwUser.getCreateTime();
+                        Integer serverStatus = qwUser.getServerStatus();
+                        Integer ipadStatus = qwUser.getIpadStatus();
+
+                        boolean result = isCreateTimeMoreThanDaysWithOptional(createTime, 2);
+                        //大于2天 ,绑定了ipad,离线
+                        if(result && serverStatus==1 && ipadStatus==0){
+                            updateIpadStatus(qwUser,serverId);
+
+                        }
+                    }
+
+
                 }
-                QwUser u = new QwUser();
-                u.setId(qwUser.getId());
-                u.setServerId(null);
-                u.setServerStatus(0);
-                qwUserMapper.updateQwUser(u);
-                ipadServerService.addServer(serverId);
-                QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
-                qwIpadServerLog.setType(2);
-                qwIpadServerLog.setTilie("解绑");
-                qwIpadServerLog.setServerId(serverId);
-                qwIpadServerLog.setQwUserId(qwUser.getId());
-                qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
-                qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
-                qwIpadServerLog.setCreateTime(new Date());
-                qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
-                qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
-                WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
-                wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
-                wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
-                updateIpadStatus(qwUser.getId(),0);
+
+
             } catch (Exception e) {
                 System.out.println("解绑ipad报错"+e);
 
@@ -278,6 +291,41 @@ public class qwTask {
         }
     }
 
+    public void updateIpadStatus(QwUser qwUser,Long serverId){
+        QwUser u = new QwUser();
+        u.setId(qwUser.getId());
+        u.setServerId(null);
+        u.setServerStatus(0);
+        qwUserMapper.updateQwUser(u);
+        ipadServerService.addServer(serverId);
+        QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
+        qwIpadServerLog.setType(2);
+        qwIpadServerLog.setTilie("解绑");
+        qwIpadServerLog.setServerId(serverId);
+        qwIpadServerLog.setQwUserId(qwUser.getId());
+        qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
+        qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
+        qwIpadServerLog.setCreateTime(new Date());
+        qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
+        qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
+        WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
+        wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
+        wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
+        updateIpadStatus(qwUser.getId(),0);
+    }
+
+    public static boolean isCreateTimeMoreThanDaysWithOptional(Date createTime, int days) {
+        return Optional.ofNullable(createTime)
+                .map(time -> {
+                    LocalDateTime createDateTime = time.toInstant()
+                            .atZone(ZoneId.systemDefault())
+                            .toLocalDateTime();
+                    LocalDateTime now = LocalDateTime.now();
+                    Duration duration = Duration.between(createDateTime, now);
+                    return duration.toDays() > days;
+                })
+                .orElse(false); // 为null时返回false,可根据需求调整
+    }
 
     void updateIpadStatus(Long id ,Integer status){
         QwUser u = new QwUser();
@@ -286,4 +334,39 @@ public class qwTask {
         qwUserMapper.updateQwUser(u);
     }
 
+
+    /**
+     * 强制注册-2025-11-12 之后的 更新
+     */
+    public void QwExternalContactMandatoryRegistration(){
+        try {
+//            List<String> longs = qwExternalContactService.selectQwExternalContactMandatoryRegistration();
+            List<String> longs = iQwCompanyService.selectQwCompanyListFormCorpId();
+            longs.forEach(item->{
+                List<QwMandatoryRegistrParam> registrParamList = qwExternalContactService.selectQwExternalContactMandatoryRegistrationByIds(String.valueOf(item));
+
+                batchUpdateQwExternalContactMandatoryRegistration(registrParamList);
+
+            });
+        }catch (Exception e){
+
+        }
+
+    }
+
+
+    private void batchUpdateQwExternalContactMandatoryRegistration(List<QwMandatoryRegistrParam> registrParamList) {
+        // 定义批量插入的大小
+        int batchSize = 300;
+
+        // 循环处理外部用户 ID,每次处理批量大小的子集
+        for (int i = 0; i < registrParamList.size(); i += batchSize) {
+
+            int endIndex = Math.min(i + batchSize, registrParamList.size());
+            List<QwMandatoryRegistrParam> batchList = registrParamList.subList(i, endIndex);  // 获取当前批次的子集
+
+            qwExternalContactService.batchUpdateQwExternalContactMandatoryRegistration(batchList);
+
+        }
+    }
 }

+ 69 - 31
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -46,13 +46,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import com.fs.app.task.qwTask;
 
+import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 @Api("公共接口")
 @RestController
@@ -164,36 +163,39 @@ public class CommonController {
             List<QwUser> list = qwUserMapper.selectQwUserByTest();
             for (QwUser qwUser : list) {
                 try {
-                    Integer serverStatus = qwUser.getServerStatus();
-                    Long serverId = qwUser.getServerId();
-                    if (serverStatus==0){
-                        log.error("不需要解绑");
-                    }
+
+                     Long serverId = qwUser.getServerId();
+
                     if (serverId==null){
-                        log.error("serverId不存在");
+                        System.out.println("serverId不存在");
+                    }else {
+                        //没绑定销售 或者 已经离职
+                        if (qwUser.getStatus()==0 || qwUser.getIsDel()==2){
+
+                            updateIpadStatus(qwUser,serverId);
+                        }
+
+                        //绑定了销售-也绑定了ipad,但是长时间离线的(离线状态,无操作超过2天的,也自动解绑)
+                        if(qwUser.getUpdateTime()!=null){
+                            Date createTime = qwUser.getUpdateTime();
+                            Integer serverStatus = qwUser.getServerStatus();
+                            Integer ipadStatus = qwUser.getIpadStatus();
+
+                            boolean result = isCreateTimeMoreThanDaysWithOptional(createTime, 2);
+                            //大于2天 ,绑定了ipad,离线
+                            if(result && serverStatus==1 && ipadStatus==0){
+                                updateIpadStatus(qwUser,serverId);
+
+                            }
+                        }
+
+
                     }
-                    QwUser u = new QwUser();
-                    u.setId(qwUser.getId());
-                    u.setServerId(null);
-                    u.setServerStatus(0);
-                    qwUserMapper.updateQwUser(u);
-                    ipadServerService.addServer(serverId);
-                    QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
-                    qwIpadServerLog.setType(2);
-                    qwIpadServerLog.setTilie("解绑");
-                    qwIpadServerLog.setServerId(serverId);
-                    qwIpadServerLog.setQwUserId(qwUser.getId());
-                    qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
-                    qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
-                    qwIpadServerLog.setCreateTime(new Date());
-                    qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
-                    qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
-                    WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
-                    wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
-                    wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
-                    updateIpadStatus(qwUser.getId(),0);
+
+
                 } catch (Exception e) {
-                    log.error("解绑ipad报错",e);
+                    System.out.println("解绑ipad报错"+e);
+
                 }
             }
         } catch (Exception e) {
@@ -203,6 +205,42 @@ public class CommonController {
     }
 
 
+    public void updateIpadStatus(QwUser qwUser,Long serverId){
+        QwUser u = new QwUser();
+        u.setId(qwUser.getId());
+        u.setServerId(null);
+        u.setServerStatus(0);
+        qwUserMapper.updateQwUser(u);
+        ipadServerService.addServer(serverId);
+        QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
+        qwIpadServerLog.setType(2);
+        qwIpadServerLog.setTilie("解绑");
+        qwIpadServerLog.setServerId(serverId);
+        qwIpadServerLog.setQwUserId(qwUser.getId());
+        qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
+        qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
+        qwIpadServerLog.setCreateTime(new Date());
+        qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
+        qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
+        WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
+        wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
+        wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
+        updateIpadStatus(qwUser.getId(),0);
+    }
+
+    public static boolean isCreateTimeMoreThanDaysWithOptional(Date createTime, int days) {
+        return Optional.ofNullable(createTime)
+                .map(time -> {
+                    LocalDateTime createDateTime = time.toInstant()
+                            .atZone(ZoneId.systemDefault())
+                            .toLocalDateTime();
+                    LocalDateTime now = LocalDateTime.now();
+                    Duration duration = Duration.between(createDateTime, now);
+                    return duration.toDays() > days;
+                })
+                .orElse(false); // 为null时返回false,可根据需求调整
+    }
+
     void updateIpadStatus(Long id ,Integer status){
         QwUser u = new QwUser();
         u.setId(id);

+ 34 - 0
fs-qwhook/src/main/java/com/fs/app/controller/CommonController.java

@@ -17,6 +17,7 @@ import com.fs.his.service.IFsAppVersionService;
 import com.fs.qw.domain.*;
 import com.fs.qw.mapper.*;
 import com.fs.qw.param.QwConfigSignatureParam;
+import com.fs.qw.param.QwMandatoryRegistrParam;
 import com.fs.qw.service.*;
 import com.fs.qw.vo.QwHookAuthVO;
 import com.fs.qwApi.param.QwExternalContactHParam;
@@ -34,6 +35,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 @Api("公共接口")
@@ -93,6 +96,37 @@ public class CommonController {
     @Autowired
     private RocketMQTemplate rocketMQTemplate;
 
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+
+
+    @GetMapping("/MandatoryRegistration")
+    public R MandatoryRegistration() throws Exception {
+        List<String> longs = qwExternalContactService.selectQwExternalContactMandatoryRegistration();
+        longs.forEach(item->{
+            List<QwMandatoryRegistrParam> registrParamList = qwExternalContactService.selectQwExternalContactMandatoryRegistrationByIds(String.valueOf(item));
+
+            batchUpdateQwExternalContactMandatoryRegistration(registrParamList);
+
+        });
+        return R.ok();
+    }
+
+    private void batchUpdateQwExternalContactMandatoryRegistration(List<QwMandatoryRegistrParam> registrParamList) {
+        // 定义批量插入的大小
+        int batchSize = 300;
+
+        // 循环处理外部用户 ID,每次处理批量大小的子集
+        for (int i = 0; i < registrParamList.size(); i += batchSize) {
+
+            int endIndex = Math.min(i + batchSize, registrParamList.size());
+            List<QwMandatoryRegistrParam> batchList = registrParamList.subList(i, endIndex);  // 获取当前批次的子集
+
+            qwExternalContactService.batchUpdateQwExternalContactMandatoryRegistration(batchList);
+
+        }
+    }
+
     @PostMapping("/qwHookNotify")
     public R qwHookNotify(@RequestBody String body) {
         QwHookVO vo= JSONUtil.toBean(body,QwHookVO.class);

+ 2 - 2
fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyBindServiceImpl.java

@@ -152,8 +152,8 @@ public class FsUserCompanyBindServiceImpl extends ServiceImpl<FsUserCompanyBindM
                 }
             }
             if (qwExternalContact.getUserRepeat() == 0) {
-                Integer i = baseMapper.selectCount(new QueryWrapper<FsUserCompanyBind>().eq("fs_user_id", fsUserId).ne("company_user_id", companyUserId));
-                if (i > 0) {
+                Integer i = baseMapper.selectCount(new QueryWrapper<FsUserCompanyBind>().eq("fs_user_id", fsUserId));
+                if (i > 1) {
                     qwExternalContact.setUserRepeat(1);
                     qwExternalContactMapper.updateById(qwExternalContact);
                 }

+ 14 - 1
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreProductPackageScrm.java

@@ -9,7 +9,7 @@ import com.fs.hisStore.dto.StoreOrderProductDTO;
 
 /**
  * 商品组合套餐对象 fs_store_product_package
- * 
+ *
  * @author fs
  * @date 2022-07-14
  */
@@ -66,6 +66,11 @@ public class FsStoreProductPackageScrm extends BaseEntity
 
     private Integer status;
 
+
+
+    //套餐赠送积分
+    private Integer integral;
+
     List<StoreOrderProductDTO> productList;
 
     public Integer getStatus() {
@@ -211,4 +216,12 @@ public class FsStoreProductPackageScrm extends BaseEntity
     public void setProducts(String products) {
         this.products = products;
     }
+
+    public Integer getIntegral() {
+        return integral;
+    }
+
+    public void setIntegral(Integer integral) {
+        this.integral = integral;
+    }
 }

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -209,7 +209,7 @@ public interface FsStoreProductScrmMapper
             "        </foreach>\n" +
             "    </if>"+
             "<if test = 'maps.defaultOrder != null and maps.defaultOrder==\"desc\"  '> " +
-            "order by p.sort desc,product_id desc" +
+            "order by p.sort asc,product_id desc" +
             "</if>" +
             "<if test = 'maps.priceOrder != null and maps.priceOrder==\"desc\"   '> " +
             "order by p.price desc " +

+ 58 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -21,6 +21,7 @@ import com.fs.api.vo.ProductListVO;
 import com.fs.common.config.FSSysConfig;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.event.TemplateBean;
 import com.fs.common.event.TemplateEvent;
@@ -62,9 +63,12 @@ import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
 import com.fs.his.dto.FsStoreOrderItemDTO;
 import com.fs.his.enums.FsStoreOrderLogEnum;
 import com.fs.his.enums.FsStoreOrderStatusEnum;
+import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.mapper.*;
 import com.fs.his.param.FsStoreOrderSalesParam;
+import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.service.IFsPrescribeService;
+import com.fs.his.service.IFsUserIntegralLogsService;
 import com.fs.his.service.IFsUserWatchService;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.vo.FsInquiryOrderVO;
@@ -104,6 +108,7 @@ import com.fs.hisStore.domain.*;
 import com.fs.hisStore.enums.*;
 import com.fs.hisStore.service.*;
 import com.fs.system.service.ISysConfigService;
+import com.fs.system.service.ISysDictTypeService;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.wx.order.domain.FsWxExpressTask;
 import com.fs.wx.order.dto.*;
@@ -379,6 +384,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     @Autowired
     private IFsStoreCartScrmService fsStoreCartScrmService;
 
+    @Autowired
+    private ISysDictTypeService sysDictTypeService;
+    @Autowired
+    private IFsUserIntegralLogsService userIntegralLogsService;
+    @Autowired
+    private FsStoreProductPackageScrmMapper fsStoreProductPackageMapper;
+
     @PostConstruct
     public void initErpServiceMap() {
         erpServiceMap = new HashMap<>();
@@ -1820,6 +1832,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     companyService.addCompanyMoney(order);
                 }
             }
+            //套餐包赠送积分
+            try {
+                sendIntegral(order);
+            } catch (Exception e) {
+                log.error("赠送积分错误:{},订单号:{}", e.getMessage(), order.getOrderCode());
+            }
+
 
             FsErpConfig erpConfig = configUtil.getErpConfig();
             Integer erpType = erpConfig.getErpType();
@@ -1859,6 +1878,43 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
     }
 
+    /**
+     * 套餐包赠送积分
+     * @param order
+     */
+    private void sendIntegral(FsStoreOrderScrm order) {
+        //如果是套餐包赠送积分
+        Integer orderCreateType = order.getOrderCreateType();
+        Long packageId = order.getPackageId();
+        if (orderCreateType != null && order.getUserId() != null && packageId !=null) {
+            List<SysDictData> sysDictData = sysDictTypeService.selectDictDataByType("store_order_create_type");
+            if (sysDictData != null && !sysDictData.isEmpty()){
+                String dictValue = "";
+                for (SysDictData dictData : sysDictData) {
+                    String dictLabel = dictData.getDictLabel();
+                    if (StringUtils.isNotBlank(dictLabel) && "套餐".equals(dictLabel)){
+                        dictValue = dictData.getDictValue();
+                        break;
+                    }
+                    if (StringUtils.isNotBlank(dictValue)){
+                        //查询套餐赠送积分
+                        FsStoreProductPackageScrm fsStoreProductPackage = fsStoreProductPackageMapper.selectFsStoreProductPackageById(packageId);
+                        if (fsStoreProductPackage != null && fsStoreProductPackage.getIntegral() != null && fsStoreProductPackage.getIntegral()>0){
+                            //赠送积分
+                            FsUserAddIntegralTemplateParam integralTemplateParam = new FsUserAddIntegralTemplateParam();
+                            integralTemplateParam.setUserId(order.getUserId());
+                            integralTemplateParam.setLogType(FsUserIntegralLogTypeEnum.TYPE_2.getValue()); //消费获取积分
+                            integralTemplateParam.setBusinessId(order.getId().toString());
+                            integralTemplateParam.setPoints(fsStoreProductPackage.getIntegral());
+                            userIntegralLogsService.addIntegralTemplate(integralTemplateParam);
+                        }
+
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public BigDecimal selectFsStoreOrderByPayPriceCount(FsStoreOrderStatisticsParam param) {
         return fsStoreOrderMapper.selectFsStoreOrderByPayPriceCount(param);
@@ -2453,6 +2509,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 }
             }
         }
+        //退积分 todo
+
         orderStatusService.create(order.getId(), OrderLogEnum.REFUND_ORDER_SUCCESS.getValue(),
                 OrderLogEnum.REFUND_ORDER_SUCCESS.getDesc());
         if (order.getTuiUserId() != null && order.getTuiUserId() > 0) {

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductPacketVO.java

@@ -71,6 +71,9 @@ public class FsStoreProductPacketVO implements Serializable
     @Excel(name = "状态", dictType = "common_status")
     private Integer status;
 
+    @Excel(name = "赠送积分")
+    private Integer integral;
+
     List<StoreOrderProductDTO> productList;
 
 }

+ 3 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwCompanyMapper.java

@@ -76,4 +76,7 @@ public interface QwCompanyMapper
     List<QwOptionsVO> selectQwCompanyListOptionsVO(@Param("userId") Long userId, @Param("deptId") Long deptId);
 
     List<QwCompany> selectByCorpIds(@Param("corpIds") List<String> corpIds);
+
+    @Select("select DISTINCT corp_id from qw_company ")
+    List<String> selectQwCompanyListFormCorpId();
 }

+ 94 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -551,4 +551,98 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     List<QwExternalContact> getGroupChatUserByChatIdAndUserName(@Param("userId")String userId,@Param("userName")String userName,@Param("corpId") String corpId,@Param("chatId") String chatId);
     @Select("select * from qw_external_contact where unionid = #{unionID} order by create_time asc limit 1 ")
     QwExternalContact selectQwExternalByUnionID(String unionId);
+
+    @Select("<script> " +
+            "WITH contact_analysis AS (\n" +
+            "    SELECT \n" +
+            "        id,\n" +
+            "        external_user_id,\n" +
+            "        corp_id,\n" +
+            "        fs_user_id,\n" +
+            "        COUNT(CASE WHEN fs_user_id IS NOT NULL THEN 1 END) OVER (\n" +
+            "            PARTITION BY external_user_id, corp_id\n" +
+            "        ) as has_valid_fs_user,\n" +
+            "        COUNT(CASE WHEN fs_user_id IS NULL THEN 1 END) OVER (\n" +
+            "            PARTITION BY external_user_id, corp_id\n" +
+            "        ) as has_null_fs_user,\n" +
+            "        COUNT(*) OVER (\n" +
+            "            PARTITION BY external_user_id, corp_id\n" +
+            "        ) as total_records\n" +
+            "    FROM qw_external_contact\n" +
+            "    WHERE external_user_id IS NOT NULL \n" +
+            "          AND corp_id IS NOT NULL\n" +
+            "          AND create_time >='2025-10-01 00:00:00'\n" +
+            "     \n" +
+            "),\n" +
+            "filtered_contacts AS (\n" +
+            "    SELECT \n" +
+            "        id,\n" +
+            "        external_user_id,\n" +
+            "        corp_id,\n" +
+            "        fs_user_id\n" +
+            "    FROM contact_analysis\n" +
+            "    WHERE total_records >= 2\n" +
+            "        AND has_valid_fs_user >= 1\n" +
+            "        AND has_null_fs_user >= 1\n" +
+            "        AND fs_user_id IS NULL\n" +
+            ")\n" +
+            "SELECT \n" +
+            "    corp_id\n" +
+            "FROM filtered_contacts\n" +
+            "GROUP BY corp_id" +
+            "</script> ")
+    public List<String> selectQwExternalContactMandatoryRegistration();
+
+    @Select("<script>" +
+            "SELECT t1.id,t2.valid_fs_user_id as fs_user_id \n" +
+            "FROM qw_external_contact t1\n" +
+            "JOIN (\n" +
+            "    SELECT \n" +
+            "        external_user_id,\n" +
+            "        corp_id,\n" +
+            "        MAX(fs_user_id) as valid_fs_user_id\n" +
+            "    FROM qw_external_contact\n" +
+            "    WHERE external_user_id IS NOT NULL \n" +
+            "        AND corp_id IS NOT NULL \n" +
+            "        AND corp_id = #{corpId}\n" +
+            "        AND fs_user_id IS NOT NULL\n" +
+            "        AND create_time >='2025-10-01 00:00:00' \n" +
+            "    GROUP BY external_user_id, corp_id\n" +
+            ") t2 ON t1.external_user_id = t2.external_user_id \n" +
+            "    AND t1.corp_id = t2.corp_id\n" +
+            "JOIN (\n" +
+            "    SELECT \n" +
+            "        external_user_id,\n" +
+            "        corp_id\n" +
+            "    FROM qw_external_contact\n" +
+            "    WHERE external_user_id IS NOT NULL \n" +
+            "        AND corp_id IS NOT NULL \n" +
+            "        AND corp_id = #{corpId}\n" +
+            "        AND create_time >='2025-10-01 00:00:00' \n" +
+            "    GROUP BY external_user_id, corp_id\n" +
+            "    HAVING COUNT(*) >= 2\n" +
+            "        AND SUM(CASE WHEN fs_user_id IS NOT NULL THEN 1 ELSE 0 END) >= 1\n" +
+            "        AND SUM(CASE WHEN fs_user_id IS NULL THEN 1 ELSE 0 END) >= 1\n" +
+            ") t3 ON t1.external_user_id = t3.external_user_id \n" +
+            "    AND t1.corp_id = t3.corp_id\n" +
+            "WHERE t1.fs_user_id IS NULL\n" +
+            "    AND t1.corp_id = #{corpId}\n" +
+            "</script>")
+    public List<QwMandatoryRegistrParam> selectQwExternalContactMandatoryRegistrationByIds(@Param("corpId") String corpId);
+
+
+
+    @Update("<script>" +
+            "UPDATE qw_external_contact " +
+            "SET fs_user_id = CASE " +
+            "<foreach collection='map' item='item'>" +
+            "WHEN id = #{item.id} THEN #{item.fsUserId} " +
+            "</foreach>" +
+            "ELSE fs_user_id END " +
+            "WHERE id IN " +
+            "<foreach collection='map' item='item' open='(' separator=',' close=')'>" +
+            "#{item.id}" +
+            "</foreach>" +
+            "</script>")
+    public int batchUpdateQwExternalContactMandatoryRegistration(@Param("map") List<QwMandatoryRegistrParam> batchList);
 }

+ 9 - 0
fs-service/src/main/java/com/fs/qw/param/QwMandatoryRegistrParam.java

@@ -0,0 +1,9 @@
+package com.fs.qw.param;
+
+import lombok.Data;
+
+@Data
+public class QwMandatoryRegistrParam {
+    private Long id;
+    private Long fsUserId;
+}

+ 1 - 1
fs-service/src/main/java/com/fs/qw/service/IQwCompanyService.java

@@ -66,5 +66,5 @@ public interface IQwCompanyService
 
     List<QwOptionsVO> selectQwCompanyListOptionsVO(Long userId, Long deptId);
 
-
+    List<String>  selectQwCompanyListFormCorpId();
 }

+ 6 - 0
fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java

@@ -259,4 +259,10 @@ public interface IQwExternalContactService extends IService<QwExternalContact> {
     QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam);
 
     List<QwExternalContact> selectQwUserAndLevel(List<Long> qwUserIdList, List<String> levelList, boolean isReg);
+
+    List<String> selectQwExternalContactMandatoryRegistration();
+
+    List<QwMandatoryRegistrParam> selectQwExternalContactMandatoryRegistrationByIds(String corpId);
+
+    int batchUpdateQwExternalContactMandatoryRegistration(List<QwMandatoryRegistrParam> batchList);
 }

+ 6 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwCompanyServiceImpl.java

@@ -11,6 +11,7 @@ import com.fs.voice.utils.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -132,4 +133,9 @@ public class QwCompanyServiceImpl implements IQwCompanyService
     public List<QwOptionsVO> selectQwCompanyListOptionsVO(Long userId, Long deptId) {
         return qwCompanyMapper.selectQwCompanyListOptionsVO(userId, deptId);
     }
+
+    @Override
+    public List<String> selectQwCompanyListFormCorpId() {
+        return qwCompanyMapper.selectQwCompanyListFormCorpId();
+    }
 }

+ 14 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -5933,6 +5933,20 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         return list(queryCondition);
     }
 
+    @Override
+    public List<String> selectQwExternalContactMandatoryRegistration() {
+        return qwExternalContactMapper.selectQwExternalContactMandatoryRegistration();
+    }
+
+    @Override
+    public List<QwMandatoryRegistrParam> selectQwExternalContactMandatoryRegistrationByIds(String corpId) {
+        return qwExternalContactMapper.selectQwExternalContactMandatoryRegistrationByIds(corpId);
+    }
+
+    @Override
+    public int batchUpdateQwExternalContactMandatoryRegistration(List<QwMandatoryRegistrParam> batchList) {
+        return qwExternalContactMapper.batchUpdateQwExternalContactMandatoryRegistration( batchList);
+    }
     @Override
     public R getRepeat(RepeatParam param) {
         List<QwExternalContact> list = qwExternalContactMapper.selectList(new QueryWrapper<QwExternalContact>().eq("external_user_id", param.getExternalUserId()));

+ 6 - 1
fs-service/src/main/resources/mapper/hisStore/FsStoreProductPackageScrmMapper.xml

@@ -20,10 +20,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="cateId"    column="cate_id"    />
         <result property="sort"    column="sort"    />
         <result property="status"    column="status"    />
+        <result property="integral"    column="integral"    />
     </resultMap>
 
     <sql id="selectFsStoreProductPackageVo">
-        select package_id, title, descs, content, img_url,images, products, money, pay_money, company_id, dept_id,pay_type,limit_count,cate_id,sort,status from fs_store_product_package_scrm
+        select package_id, title, descs, content, img_url,images, products, money, pay_money, company_id,
+               dept_id,pay_type,limit_count,cate_id,sort,status,integral from fs_store_product_package_scrm
     </sql>
 
     <select id="selectFsStoreProductPackageList" parameterType="FsStoreProductPackageScrm" resultMap="FsStoreProductPackageResult">
@@ -70,6 +72,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="cateId != null">cate_id,</if>
             <if test="sort != null">sort,</if>
             <if test="status != null">status,</if>
+            <if test="integral != null">integral,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="packageId != null">#{packageId},</if>
@@ -88,6 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="cateId != null">#{cateId},</if>
             <if test="sort != null">#{sort},</if>
             <if test="status != null">#{status},</if>
+            <if test="integral != null">#{integral},</if>
          </trim>
     </insert>
 
@@ -109,6 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="cateId != null">cate_id = #{cateId},</if>
             <if test="sort != null">sort = #{sort},</if>
             <if test="status != null">status = #{status},</if>
+            <if test="integral != null">integral = #{integral},</if>
         </trim>
         where package_id = #{packageId}
     </update>

+ 3 - 2
fs-service/src/main/resources/mapper/qw/QwUserMapper.xml

@@ -34,10 +34,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="serverStatus"    column="server_status"    />
         <result property="isAuto"    column="is_auto"    />
         <result property="videoGetStatus"    column="video_get_status"    />
+        <result property="updateTime"    column="update_time"    />
     </resultMap>
 
     <sql id="selectQwUserVo">
-        select id,is_auto, video_get_status, qw_user_id,server_id,server_status,ipad_status,config_id,vid,uid,contact_way,app_key, qw_user_name, department, openid, company_id, company_user_id, corp_id, status, is_del, welcome_text, welcome_image, is_send_msg,app_key,qw_hook_id,fastGpt_role_id,login_status,tool_status,login_code_url,version from qw_user
+        select id,is_auto, video_get_status, qw_user_id,server_id,server_status,ipad_status,config_id,vid,uid,contact_way,app_key, qw_user_name, department, openid, company_id, company_user_id, corp_id, status, is_del, welcome_text, welcome_image, is_send_msg,app_key,qw_hook_id,fastGpt_role_id,login_status,tool_status,login_code_url,version,update_time from qw_user
         </sql>
 
     <select id="selectQwUserList" parameterType="QwUser" resultMap="QwUserResult">
@@ -306,7 +307,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectQwUserByTest" resultMap="QwUserResult">
         <include refid="selectQwUserVo"/>
-        where status = 0 and server_status = 1
+        where  server_status = 1
     </select>
 
 </mapper>

+ 27 - 1
fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

@@ -2,10 +2,14 @@ package com.fs.app.controller.store;
 
 
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.annotation.Login;
 import com.fs.app.controller.AppBaseController;
 import com.fs.app.vo.IndexVO;
 import com.fs.common.core.domain.R;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.his.config.AgreementConfig;
 import com.fs.hisStore.domain.*;
 import com.fs.hisStore.param.*;
@@ -57,13 +61,16 @@ public class IndexScrmController extends AppBaseController {
 	private IFsStoreCanvasScrmService storeCanvasService;
 	@Autowired
 	private ISysConfigService configService;
+	@Autowired
+	private IFsCoursePlaySourceConfigService coursePlaySourceConfigService;
+
 	@ApiOperation("获取首页数据")
 	@GetMapping("/getIndexData")
 	public R getIndexData(HttpServletRequest request){
 		List<FsArticleCateListQueryVO> articleCateList=articleCateService.selectFsArticleCateListQuery();
 		List<FsAdvListQueryVO> advList=advService.selectFsAdvListQuery(1);
 		List<FsStoreProductListQueryVO> newProductList=productService.selectFsStoreProductNewQuery(10);
-		List<FsStoreProductListQueryVO> hotProductList=productService.selectFsStoreProductHotQuery(10);
+		List<FsStoreProductListQueryVO> hotProductList=productService.selectFsStoreProductHotQuery(12);
 		IndexVO vo=IndexVO.builder().articleCateList(articleCateList).advList(advList).newProductList(newProductList).hotProductList(hotProductList).build();
 		return R.ok().put("data", vo);
 	}
@@ -287,5 +294,24 @@ public class IndexScrmController extends AppBaseController {
 		return R.ok().put("data",data);
 	}
 
+	/**
+	 * 获取小程序logo
+	 * @return
+	 */
+	@GetMapping("/getAppInfo")
+	public R getAppInfo(@RequestParam("appId") String appId)
+	{
+		Wrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
+				.eq(FsCoursePlaySourceConfig::getAppid, appId)
+				.eq(FsCoursePlaySourceConfig::getIsDel, 0)
+				.last("limit 1");
+		FsCoursePlaySourceConfig sourceConfig = coursePlaySourceConfigService.getOne(queryWrapper);
+		FsCoursePlaySourceConfig vo = new FsCoursePlaySourceConfig();
+		vo.setAppid(appId);
+		vo.setImg(sourceConfig.getImg());
+		vo.setName(sourceConfig.getName());
+		return R.ok().put("data",vo);
+	}
+
 
 }