Browse Source

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

caoliqin 1 week ago
parent
commit
61abbad25b
33 changed files with 635 additions and 167 deletions
  1. 41 0
      fs-admin/src/main/java/com/fs/course/controller/CourseRedPacketStatisticsController.java
  2. 52 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  3. 7 0
      fs-company/src/main/java/com/fs/company/controller/qw/QwUserController.java
  4. 1 1
      fs-doctor-app/src/main/resources/application.yml
  5. 27 0
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  6. 36 0
      fs-service/src/main/java/com/fs/course/dto/CourseRedPacketStatisticsDTO.java
  7. 4 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseRedPacketLogMapper.java
  8. 38 0
      fs-service/src/main/java/com/fs/course/param/CourseRedPacketStatisticsParam.java
  9. 11 0
      fs-service/src/main/java/com/fs/course/service/CourseRedPacketStatisticsService.java
  10. 28 0
      fs-service/src/main/java/com/fs/course/service/impl/CourseRedPacketStatisticsServiceImpl.java
  11. 1 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  12. 5 0
      fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java
  13. 4 4
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  14. 152 68
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  15. 6 0
      fs-service/src/main/java/com/fs/qw/domain/QwFriendWelcome.java
  16. 1 0
      fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java
  17. 2 0
      fs-service/src/main/java/com/fs/qw/mapper/QwUserVideoMapper.java
  18. 7 0
      fs-service/src/main/java/com/fs/qw/param/QwFriendWelcomeParam.java
  19. 7 0
      fs-service/src/main/java/com/fs/qw/param/QwUserListParam.java
  20. 3 0
      fs-service/src/main/java/com/fs/qw/service/IQwUserVideoService.java
  21. 30 11
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  22. 4 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwUserVideoServiceImpl.java
  23. 1 0
      fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java
  24. 6 1
      fs-service/src/main/java/com/fs/qw/vo/QwFriendWelcomeVO.java
  25. 3 2
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempVoiceServiceImpl.java
  26. 10 0
      fs-service/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java
  27. 1 1
      fs-service/src/main/resources/application-druid-cqtyt-test.yml
  28. 10 13
      fs-service/src/main/resources/application-druid-cqtyt.yml
  29. 1 1
      fs-service/src/main/resources/application-druid-jnmy-test.yml
  30. 25 0
      fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml
  31. 76 34
      fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml
  32. 29 30
      fs-service/src/main/resources/mapper/hisStore/FsUserScrmMapper.xml
  33. 6 1
      fs-service/src/main/resources/mapper/qw/QwFriendWelcomeMapper.xml

+ 41 - 0
fs-admin/src/main/java/com/fs/course/controller/CourseRedPacketStatisticsController.java

@@ -0,0 +1,41 @@
+package com.fs.course.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.course.dto.CourseRedPacketStatisticsDTO;
+import com.fs.course.param.CourseRedPacketStatisticsParam;
+import com.fs.course.service.CourseRedPacketStatisticsService;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @description: 看客红包发送统计
+ * @author: Xgb
+ * @createDate: 2025/10/14
+ * @version: 1.0
+ */
+@RestController
+@RequestMapping("/course/courseRedPacketStatistics")
+public class CourseRedPacketStatisticsController extends BaseController {
+
+    @Autowired
+    private CourseRedPacketStatisticsService courseRedPacketStatisticsService;
+
+    @ApiModelProperty("看客红包发送统计")
+    @GetMapping("/list")
+    public R list(CourseRedPacketStatisticsParam param) {
+
+        startPage();
+        // 看客红包发送统计
+        List<CourseRedPacketStatisticsDTO> list = courseRedPacketStatisticsService.statistics(param);
+
+        return R.ok().put("data", new PageInfo<>(list));
+    }
+
+}

+ 52 - 0
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -28,9 +28,13 @@ import com.fs.erp.dto.ErpOrderResponse;
 import com.fs.erp.mapper.FsErpFinishPushMapper;
 import com.fs.erp.service.IErpOrderService;
 import com.fs.fastGpt.domain.FastGptEventTokenLog;
+import com.fs.fastGpt.domain.FastgptChatVoiceHomo;
 import com.fs.fastGpt.domain.FastgptEventLogTotal;
 import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
+import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
 import com.fs.fastGpt.service.IFastgptEventLogTotalService;
+import com.fs.fastgptApi.util.AudioUtils;
+import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.FsInquiryOrder;
@@ -51,6 +55,8 @@ import com.fs.im.service.IImService;
 import com.fs.qw.domain.QwCompany;
 import com.fs.qw.service.*;
 import com.fs.qwApi.service.QwApiService;
+import com.fs.sop.domain.QwSopTempVoice;
+import com.fs.sop.service.IQwSopTempVoiceService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.google.gson.Gson;
@@ -63,6 +69,7 @@ import org.springframework.stereotype.Component;
 
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Component("task")
@@ -165,6 +172,51 @@ public class Task {
     @Autowired
     private IFastgptEventLogTotalService fastgptEventLogTotalService;
 
+    @Autowired
+    private FastgptChatVoiceHomoMapper fastgptChatVoiceHomoMapper;
+    @Autowired
+    private IQwSopTempVoiceService qwSopTempVoiceService;
+
+    public static final String SOP_TEMP_VOICE_KEY = "sop:tempVoice";
+
+    /**
+     * 一键生成语音定时任务
+     */
+    public void ConsumerSopTempVoice() {
+        try {
+            Long newCompanyUserId = redisCache.popVoiceKey(SOP_TEMP_VOICE_KEY);
+            if(newCompanyUserId != null){
+                List<QwSopTempVoice> sopTempVoices = redisCache.getVoiceAllList(SOP_TEMP_VOICE_KEY + ":" +newCompanyUserId);
+                if(sopTempVoices != null && !sopTempVoices.isEmpty()) {
+                    try {
+                        for (QwSopTempVoice qwSopTempVoice : sopTempVoices) {
+                            try {
+                                AudioVO audioVO = new AudioVO();
+                                List<FastgptChatVoiceHomo> homos = fastgptChatVoiceHomoMapper.selectFastgptChatVoiceHomoList(new FastgptChatVoiceHomo());
+                                audioVO = AudioUtils.createUserUrlAndUrl(homos,qwSopTempVoice.getCompanyUserId(), qwSopTempVoice.getVoiceTxt());
+                                if (audioVO != null && audioVO.getWavUrl() != null && audioVO.getUrl() != null) {
+                                    qwSopTempVoice.setVoiceUrl(audioVO.getUrl());
+                                    qwSopTempVoice.setUserVoiceUrl(audioVO.getWavUrl());
+                                    qwSopTempVoice.setDuration(audioVO.getDuration());
+                                    qwSopTempVoice.setRecordType(1);
+                                    qwSopTempVoiceService.updateQwSopTempVoice(qwSopTempVoice);
+                                }
+                            } catch (Exception e) {
+
+                            }
+                        }
+                    } finally {
+                        redisCache.deleteObject(SOP_TEMP_VOICE_KEY + ":" + newCompanyUserId);
+                    }
+                }
+            }else{
+                log.info("没有需要生成的语音");
+            }
+        } catch (Exception e) {
+            log.error("生成语音定时任务执行异常", e);
+        }
+    }
+
     //统计ai事件埋点
     public void eventLogTotals() {
         // 判断是否是凌晨 00:00 - 00:59

+ 7 - 0
fs-company/src/main/java/com/fs/company/controller/qw/QwUserController.java

@@ -1,5 +1,6 @@
 package com.fs.company.controller.qw;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
@@ -392,6 +393,12 @@ public class QwUserController extends BaseController
         startPage();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         qwUser.setCompanyId(loginUser.getCompany().getCompanyId());
+        if (ObjectUtil.isNotEmpty(qwUser.getIsRemark())&&qwUser.getIsRemark().equals("1")){
+            qwUser.setCompanyUserId(loginUser.getUser().getUserId());
+        }else if (ObjectUtil.isNotEmpty(qwUser.getIsRemark())&&qwUser.getIsRemark().equals("2")){
+            qwUser.setDeptId(loginUser.getUser().getDeptId());
+            qwUser.setCorpId(null);
+        }
 
         List<QwUserVO> list = qwUserService.selectQwUserListVO(qwUser);
         return getDataTable(list);

+ 1 - 1
fs-doctor-app/src/main/resources/application.yml

@@ -6,4 +6,4 @@ server:
 spring:
   profiles:
 #    active: dev
-    active: druid-jnmy
+    active: dev-yjb

+ 27 - 0
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -16,10 +16,12 @@ import com.fs.his.service.IFsExpressService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
+import com.fs.qw.domain.QwUserVideo;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwUserService;
+import com.fs.qw.service.IQwUserVideoService;
 import com.fs.qw.service.IQwUserVoiceLogService;
 import com.fs.sop.mapper.QwSopLogsMapper;
 import com.fs.sop.mapper.SopUserLogsInfoMapper;
@@ -57,6 +59,8 @@ public class QwMsgController {
     @Autowired
     IQwUserService qwUserService;
     @Autowired
+    IQwUserVideoService qwUserVideoService;
+    @Autowired
     IQwUserVoiceLogService qwUserVoiceLogService;
     @Autowired
     IFsStoreOrderService fsStoreOrderService;
@@ -342,6 +346,29 @@ public class QwMsgController {
                     else if (wxWorkMessageDTO.getMsgtype() == 104){
                         content = wxWorkMessageDTO.getUrl();
                         log.info("id:{}, 用户发送表情"+content, id);
+                    }//视频号
+                    else if (wxWorkMessageDTO.getMsgtype()==141){
+                        QwUser qwUserByAppKey = qwUserMapper.selectQwUserById(id);
+                        if(qwUserByAppKey.getVideoGetStatus() != null && qwUserByAppKey.getVideoGetStatus() == 1){
+                            QwUserVideo qwUserVideo = qwUserVideoService.selectByObjectId(wxWorkMessageDTO.getObjectId(), qwUserByAppKey.getId());
+                            if(qwUserVideo == null){
+                                QwUserVideo userVideo=new QwUserVideo();
+                                userVideo.setSenderName(wxWorkMessageDTO.getSender_name());
+                                userVideo.setNickName(wxWorkMessageDTO.getNickname());
+                                userVideo.setObjectId(wxWorkMessageDTO.getObjectId());
+                                userVideo.setCoverUrl(wxWorkMessageDTO.getCover_url());
+                                userVideo.setThumbUrl(wxWorkMessageDTO.getThumb_url());
+                                userVideo.setAvatar(wxWorkMessageDTO.getAvatar());
+                                userVideo.setDesc(wxWorkMessageDTO.getDesc());
+                                userVideo.setUrl(wxWorkMessageDTO.getUrl());
+                                userVideo.setExtras(wxWorkMessageDTO.getExtras());
+                                userVideo.setObjectNonceId(wxWorkMessageDTO.getObjectNonceId());
+                                userVideo.setQwUserId(qwUserByAppKey.getId());
+                                userVideo.setCompanyUserId(qwUserByAppKey.getCompanyUserId());
+                                userVideo.setCompanyId(qwUserByAppKey.getCompanyId());
+                                qwUserVideoService.insertQwUserVideo(userVideo);
+                            }
+                        }
                     }
 
                     if (2000000000000000L-receiver>0){

+ 36 - 0
fs-service/src/main/java/com/fs/course/dto/CourseRedPacketStatisticsDTO.java

@@ -0,0 +1,36 @@
+package com.fs.course.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @description: 看客红包发送统计
+ * @author: Xgb
+ * @createDate: 2025/10/14
+ * @version: 1.0
+ */
+@Data
+public class CourseRedPacketStatisticsDTO {
+
+    // 公司名称
+    private String companyName;
+
+    // 员工姓名
+    private String nickName;
+
+    // 员工id
+    private Long companyUserId;
+
+    // 红包数
+    private Long redPacketNum;
+
+   // 红包总金额
+    private BigDecimal redPacketTotalMoney;
+
+
+
+
+}

+ 4 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseRedPacketLogMapper.java

@@ -6,6 +6,8 @@ import java.util.List;
 
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.domain.FsCourseRedPacketLog;
+import com.fs.course.dto.CourseRedPacketStatisticsDTO;
+import com.fs.course.param.CourseRedPacketStatisticsParam;
 import com.fs.course.param.FsCourseRedPacketLogParam;
 import com.fs.course.param.FsUserCourseOrderParam;
 import com.fs.course.vo.FsCourseRedPacketLogListPVO;
@@ -171,4 +173,6 @@ public interface FsCourseRedPacketLogMapper
     List<FsCourseRedPacketLog> selectFail(@Param("userId") Long userId);
 
     List<RedPacketMoneyVO> selectFsCourseRedPacketLogHourseByCompany(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
+
+    List<CourseRedPacketStatisticsDTO> statistics(CourseRedPacketStatisticsParam param);
 }

+ 38 - 0
fs-service/src/main/java/com/fs/course/param/CourseRedPacketStatisticsParam.java

@@ -0,0 +1,38 @@
+package com.fs.course.param;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.models.auth.In;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @description: 看客红包发送统计
+ * @author: Xgb
+ * @createDate: 2025/10/14
+ * @version: 1.0
+ */
+@Data
+public class CourseRedPacketStatisticsParam {
+
+    // 公司id
+    private Long companyId;
+
+    // 公司用户id
+    private Long companyUserId;
+
+    // 状态 状态 0 发送中  1  已发送  2余额不足待发送
+    private Integer status;
+
+    // 开始时间
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date startTime;
+
+    // 结束时间
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date endTime;
+
+
+
+
+}

+ 11 - 0
fs-service/src/main/java/com/fs/course/service/CourseRedPacketStatisticsService.java

@@ -0,0 +1,11 @@
+package com.fs.course.service;
+
+import com.fs.course.dto.CourseRedPacketStatisticsDTO;
+import com.fs.course.param.CourseRedPacketStatisticsParam;
+
+import java.util.List;
+
+
+public interface CourseRedPacketStatisticsService {
+    List<CourseRedPacketStatisticsDTO> statistics(CourseRedPacketStatisticsParam param);
+}

+ 28 - 0
fs-service/src/main/java/com/fs/course/service/impl/CourseRedPacketStatisticsServiceImpl.java

@@ -0,0 +1,28 @@
+package com.fs.course.service.impl;
+
+import com.fs.course.dto.CourseRedPacketStatisticsDTO;
+import com.fs.course.mapper.FsCourseRedPacketLogMapper;
+import com.fs.course.param.CourseRedPacketStatisticsParam;
+import com.fs.course.service.CourseRedPacketStatisticsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description: 看客红包统计
+ * @author: Xgb
+ * @createDate: 2025/10/14
+ * @version: 1.0
+ */
+@Service
+public class CourseRedPacketStatisticsServiceImpl implements CourseRedPacketStatisticsService {
+
+    @Autowired
+    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
+
+    @Override
+    public List<CourseRedPacketStatisticsDTO> statistics(CourseRedPacketStatisticsParam param) {
+        return fsCourseRedPacketLogMapper.statistics(param);
+    }
+}

+ 1 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -1414,6 +1414,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                     transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
                     redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
                     redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
+                    redPacketLog.setBatchId(transferBillsResult.getTransferBillNo());
                 }else {
                     redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
                     redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());

+ 5 - 0
fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java

@@ -97,6 +97,10 @@ public interface IFsStorePaymentService
 
     R sendRedPacketV3(WxSendRedPacketParam param);
 
+    R sendRedPacketLimit(WxSendRedPacketParam param);
+
+    R sendRedPacketDeduction(WxSendRedPacketParam param);
+
     String transferNotify(String notifyData, HttpServletRequest request);
 
     Boolean isEntityNull(FsStorePaymentParam fsStorePayment);
@@ -120,4 +124,5 @@ public interface IFsStorePaymentService
     R paymentByWxaCode(FsStorePaymentPayParam payment);
 
     R getWxaCodeByPayment(FsStorePaymentGetWxaCodeParam param);
+
 }

+ 4 - 4
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java

@@ -121,8 +121,8 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
     private JpushService jpushService;
     @Autowired
     IPayService payService;
-    @Autowired
-    SmsServiceImpl smsService;
+//    @Autowired
+//    SmsServiceImpl smsService;
     @Autowired
     private FsInquiryOrderMapper fsInquiryOrderMapper;
     @Autowired
@@ -908,7 +908,7 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
                 FsUser fsUser = fsUserService.selectFsUserByUserId(order.getUserId());
                 if (fsUser!=null&&fsUser.getPhone()!=null){
                     logger.info("医生接单发送短信:"+fsUser.getPhone()+patientDTO.getPatientName());
-                    smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "3");
+//                    smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "3");
                 }
 
             }
@@ -1044,7 +1044,7 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
                 FsUser fsUser = fsUserService.selectFsUserByUserId(order.getUserId());
                 if (fsUser!=null&&fsUser.getPhone()!=null){
                     logger.info("医生接单发送短信:"+fsUser.getPhone()+patientDTO.getPatientName());
-                    smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "3");
+//                    smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "3");
                 }
 
             }

+ 152 - 68
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -3,9 +3,10 @@ package com.fs.his.service.impl;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
@@ -17,8 +18,6 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.annotation.DataScope;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
@@ -26,7 +25,6 @@ import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyConfigMapper;
@@ -39,19 +37,15 @@ import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
-import com.fs.course.config.CourseConfig;
 import com.fs.course.config.RedPacketConfig;
 import com.fs.course.domain.FsCourseRedPacketLog;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.service.IFsCourseRedPacketLogService;
 import com.fs.course.service.IFsUserCourseOrderService;
 import com.fs.course.service.IFsUserVipOrderService;
-import com.fs.erp.dto.ErpRefundUpdateRequest;
 import com.fs.his.domain.*;
 import com.fs.his.dto.PayConfigDTO;
 import com.fs.his.enums.PaymentMethodEnum;
 import com.fs.his.mapper.*;
-import com.fs.his.param.FsStoreOrderParam;
 import com.fs.his.param.FsStorePaymentParam;
 import com.fs.his.param.PayOrderParam;
 import com.fs.his.param.WxSendRedPacketParam;
@@ -77,7 +71,6 @@ import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
 import com.fs.tzBankPay.TzBankService.TzBankService;
-import com.fs.tzBankPay.TzBankService.TzBankServiceImpl.TzBankServiceImpl;
 import com.fs.tzBankPay.doman.*;
 import com.fs.ybPay.domain.CreateWxOrderResult;
 import com.fs.ybPay.domain.OrderResult;
@@ -85,45 +78,35 @@ import com.fs.ybPay.dto.OrderQueryDTO;
 import com.fs.ybPay.dto.RefundDTO;
 import com.fs.ybPay.dto.WxJspayDTO;
 import com.fs.ybPay.service.IPayService;
-import com.github.binarywang.wxpay.bean.merchanttransfer.TransferCreateRequest;
-import com.github.binarywang.wxpay.bean.merchanttransfer.TransferCreateResult;
 import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
 import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
 import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
-import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
 import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
 import com.github.binarywang.wxpay.bean.transfer.*;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.MerchantTransferService;
-import com.github.binarywang.wxpay.service.RedpackService;
 import com.github.binarywang.wxpay.service.TransferService;
 import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.service.impl.RedpackServiceImpl;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.google.gson.Gson;
 import com.hc.openapi.tool.fastjson.JSON;
-import com.wechat.pay.java.service.transferbatch.TransferBatchService;
-import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
-import me.chanjar.weixin.common.bean.WxJsapiSignature;
 import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.mp.api.WxMpService;
 import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.hc.core5.concurrent.CompletedFuture;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
@@ -137,6 +120,7 @@ import javax.servlet.http.HttpServletRequest;
  * @date 2023-08-11
  */
 @Service
+@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
 public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
@@ -207,10 +191,23 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     @Value("${enableRedPackAccount:0}")
     private String ENABLE_RED_PACK_ACCOUNT;
 
+    @Autowired
+    private ICompanyConfigService companyConfigService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private RedPacketLogMapper redPacketLogMapper;
+
     /**
      * 红包账户锁
      */
     private static final String REDPACKET_POOL_LOCK = "redpacket_pool_lock";
+    /**
+     * 红包锁
+     */
+    private static final String REDPACKET_LOCK = "redpacket_lock:%d";
 
     /**
      * 公司红包金额
@@ -222,6 +219,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
      */
     private static final String REDPACKET_USER_LIMIT = "redpacket_user_limit:%s:%d";
 
+
+
     /**
      * 查询支付明细
      *
@@ -525,18 +524,111 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         return fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
     }
 
-    @Autowired
-    private ICompanyConfigService companyConfigService;
 
-    @Autowired
-    private RedissonClient redissonClient;
-
-    @Autowired
-    private RedPacketLogMapper redPacketLogMapper;
     @Override
     @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
     public R sendRedPacket(WxSendRedPacketParam param) {
+        IFsStorePaymentService service = (IFsStorePaymentService) AopContext.currentProxy();
+
+        if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
+            return service.sendRedPacketDeduction(param);
+        } else {
+            return service.sendRedPacketLimit(param);
+        }
+    }
+
+
+    @Override
+    public R sendRedPacketLimit(WxSendRedPacketParam param){
+        FsUser user = param.getUser();
+
+        if(user == null) {
+            throw new IllegalArgumentException("[发送红包] 用户id为必传参数!");
+        }
+        Long userId = user.getUserId();
 
+        String key = String.format(REDPACKET_LOCK,userId);
+        RLock lock = redissonClient.getLock(key);
+
+        try{
+            boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
+
+            if (!locked) {
+                logger.error("获取锁失败");
+                return R.error("[红包领取] 系统繁忙,请重试!");
+            }
+
+
+            // 判断当前用户是否限流
+            String today = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
+            String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, userId);
+            Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);
+
+
+            // 首次领取
+            if(userCount == null) {
+                userCount = 0;
+                long expireSeconds = getExpireSeconds();
+                redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
+            }
+
+            if(userCount >= RED_PACKET_LIMIT_COUNT){
+                logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",userId);
+                return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
+            }
+
+            String json;
+            RedPacketConfig config = new RedPacketConfig();
+            // 根据红包模式获取配置
+            switch (param.getRedPacketMode()){
+                case 1:
+                    json = configService.selectConfigByKey("redPacket.config");
+                    config = JSONUtil.toBean(json, RedPacketConfig.class);
+                    break;
+                case 2:
+                    json = companyConfigService.selectRedPacketConfigByKey(param.getCompanyId());
+                    config = JSONUtil.toBean(json, RedPacketConfig.class);
+                    break;
+                default:
+                    throw new UnsupportedOperationException("当前红包模式不支持!");
+            }
+            //H5的用公众号的appid发,小程序的用小程序的appid来发
+            if (param.getSource()==2){
+                // 传参appId为空时,仍然使用配置里面的
+                String appId = StringUtils.isBlank(param.getAppId()) ? config.getMiniappId() : param.getAppId();
+                config.setAppId(appId);
+            }
+            logger.info("最终传参 {}",config);
+            //组合返回参数
+            R result = new R();
+            // 根据 isNew 判断使用哪种发红包方式
+            if (config.getIsNew() != null && config.getIsNew() == 1) {
+                result = sendRedPacketV3Internal(param, config);
+            } else {
+                result= sendRedPacketLegacyInternal(param, config);
+            }
+            result.put("mchId", config.getMchId());
+            result.put("isNew",config.getIsNew());
+            logger.info("红包返回:{}",result);
+
+            // 用户领取红包次数+1
+            redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
+            return result;
+        }catch (Exception e){
+            logger.error("领取红包失败原因:{}", ExceptionUtils.getFullStackTrace(e),e);
+            throw new RuntimeException(e);
+        }finally {
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+    }
+
+    /**
+     * 开启红包账户扣减-发红包
+     */
+    @Override
+    public R sendRedPacketDeduction(WxSendRedPacketParam param){
         //---------------发红包前先判断润天账户余额是否足够---------
         RLock lock = redissonClient.getLock(REDPACKET_POOL_LOCK);
         RedPacketLog redPacketLog = null;
@@ -558,8 +650,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             Long userId = user.getUserId();
 
             // 判断当前用户是否限流
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
-            String today = sdf.format(new Date());
+            String today = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
             String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, userId);
             Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);
 
@@ -577,37 +668,33 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             }
 
 
-            BigDecimal companyMoney = null;
-
-            if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
-
-                if(ObjectUtils.isNull(companyMoney)){
-                    SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("company.money");
-                    if(ObjectUtils.isNull(sysConfig)){
-                        throw new IllegalArgumentException("润天公司账户余额不能为空!请检查配置!");
-                    }
-                    String configValue = sysConfig.getConfigValue();
-                    companyMoney = new BigDecimal(configValue);
-                    logger.info("缓存公司余额为空,从数据库读取 companyMoney: {}",companyMoney);
-                }
+            BigDecimal companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
 
-                if (companyMoney.compareTo(BigDecimal.ZERO) <= 0) {
-                    logger.info("润天账户余额: {} 不足!", companyMoney);
-                    return R.error("[红包领取] 账户余额不足,请联系管理员!");
+            if(ObjectUtils.isNull(companyMoney)){
+                SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("company.money");
+                if(ObjectUtils.isNull(sysConfig)){
+                    throw new IllegalArgumentException("润天公司账户余额不能为空!请检查配置!");
                 }
+                String configValue = sysConfig.getConfigValue();
+                companyMoney = new BigDecimal(configValue);
+                logger.info("缓存公司余额为空,从数据库读取 companyMoney: {}",companyMoney);
+            }
 
-                redPacketLog = new RedPacketLog();
-                redPacketLog.setRedPacketMode(param.getRedPacketMode());
-                redPacketLog.setAmount(param.getAmount());
-                redPacketLog.setAppId(param.getAppId());
-                redPacketLog.setCompanyId(param.getCompanyId());
-                redPacketLog.setCreateTime(LocalDateTime.now());
-                redPacketLog.setUserId(userId);
-                redPacketLog.setAccBalanceBefore(companyMoney);
-                redPacketLog.setSource(param.getSource());
+            if (companyMoney.compareTo(BigDecimal.ZERO) <= 0) {
+                logger.info("润天账户余额: {} 不足!", companyMoney);
+                return R.error("[红包领取] 账户余额不足,请联系管理员!");
             }
 
+            redPacketLog = new RedPacketLog();
+            redPacketLog.setRedPacketMode(param.getRedPacketMode());
+            redPacketLog.setAmount(param.getAmount());
+            redPacketLog.setAppId(param.getAppId());
+            redPacketLog.setCompanyId(param.getCompanyId());
+            redPacketLog.setCreateTime(LocalDateTime.now());
+            redPacketLog.setUserId(userId);
+            redPacketLog.setAccBalanceBefore(companyMoney);
+            redPacketLog.setSource(param.getSource());
+
             String json;
             RedPacketConfig config = new RedPacketConfig();
             // 根据红包模式获取配置
@@ -620,6 +707,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
                     json = companyConfigService.selectRedPacketConfigByKey(param.getCompanyId());
                     config = JSONUtil.toBean(json, RedPacketConfig.class);
                     break;
+                default:
+                    throw new UnsupportedOperationException("当前红包模式不支持!");
             }
             //H5的用公众号的appid发,小程序的用小程序的appid来发
             if (param.getSource()==2){
@@ -640,20 +729,17 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             result.put("isNew",config.getIsNew());
             logger.info("红包返回:{}",result);
 
+            // 更新账户余额
+            logger.info("[更新账户余额] 当前余额{} 更新后余额{}",companyMoney.toPlainString(),companyMoney.subtract(amount).toPlainString());
 
-            if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                // 更新账户余额
-                logger.info("[更新账户余额] 当前余额{} 更新后余额{}",companyMoney.toPlainString(),companyMoney.subtract(amount).toPlainString());
+            companyMoney = companyMoney.subtract(amount);
+            redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
 
-                companyMoney = companyMoney.subtract(amount);
-                redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
+            redPacketLog.setAccBalanceAfter(companyMoney);
+            redPacketLog.setUpdateTime(LocalDateTime.now());
+            redPacketLog.setStatus(1);
 
 
-                redPacketLog.setAccBalanceAfter(companyMoney);
-                redPacketLog.setUpdateTime(LocalDateTime.now());
-                redPacketLog.setStatus(1);
-            }
-
             // 用户领取红包次数+1
             redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
 
@@ -1386,8 +1472,6 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         }
     }
 
-
-
     @Override
     public R paymentByWxaCode(FsStorePaymentPayParam param) {
         FsUser user = userMapper.selectFsUserById(param.getUserId());

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

@@ -45,6 +45,12 @@ public class QwFriendWelcome extends BaseEntity
     @Excel(name = "开启分时段之后的存储")
     private String daypartingItemlist;
 
+    /**
+     * 欢迎语标题
+     */
+    @Excel(name = "欢迎语标题")
+    private String welcomeTitle;
+
     /** 公司id */
     @Excel(name = "公司id")
     private Long companyId;

+ 1 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -206,6 +206,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
             "            <if test=\"qwUserName != null  and qwUserName != ''\"> and qu.qw_user_uame like concat( #{qwUserName}, '%') </if>\n" +
             "            <if test=\"companyUserId != null \"> and qu.company_user_id = #{companyUserId}</if>\n" +
             "            <if test=\"corpId != null \"> and qu.corp_id = #{corpId}</if>\n" +
+            "            <if test=\"deptId != null \"> and qd.dept_id = #{deptId}</if>\n" +
             "            <if test=\"status != null \"> and qu.status = #{status}</if>\n" +
             "            <if test=\"type != null and sendType !=null and type==2 and (sendType==2 or sendType==4 or sendType==11) \"> and qu.app_key IS NOT NULL  </if>\n" +
             "</script>"})

+ 2 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwUserVideoMapper.java

@@ -72,4 +72,6 @@ public interface QwUserVideoMapper
      * @return 结果
      */
     public int deleteQwUserVideoByIds(Long[] ids);
+
+    QwUserVideo selectByObjectId(@Param("objectId") String objectId, @Param("id") Long id);
 }

+ 7 - 0
fs-service/src/main/java/com/fs/qw/param/QwFriendWelcomeParam.java

@@ -72,4 +72,11 @@ public class QwFriendWelcomeParam extends BaseEntity {
      */
     private String userType;
 
+    /**
+     * 欢迎语标题
+     * ALTER TABLE qw_friend_welcome ADD welcome_title varchar(100) NULL COMMENT '标题';
+     */
+    private String welcomeTitle;
+
+
 }

+ 7 - 0
fs-service/src/main/java/com/fs/qw/param/QwUserListParam.java

@@ -62,4 +62,11 @@ public class QwUserListParam {
      */
     private String userType;
 
+    /**
+     * 0:好友欢迎语
+     * 1:我的欢迎语
+     * 2、部门欢迎语
+     */
+    private String isRemark;
+
 }

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

@@ -62,4 +62,7 @@ public interface IQwUserVideoService
      * @return 结果
      */
     public int deleteQwUserVideoById(Long id);
+
+
+    QwUserVideo selectByObjectId(String objectId, Long id);
 }

+ 30 - 11
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -50,6 +50,7 @@ import com.fs.qwApi.domain.*;
 import com.fs.qwApi.domain.inner.*;
 import com.fs.qwApi.param.*;
 import com.fs.qwApi.service.QwApiService;
+import com.fs.repeat.vo.RepeatUploadVo;
 import com.fs.sop.domain.QwSop;
 import com.fs.sop.domain.SopUserLogs;
 import com.fs.sop.domain.SopUserLogsInfo;
@@ -2175,7 +2176,9 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 
     @Override
     public QwUser getQwUserByRedisForId(String qwUserId) {
-
+        if(qwUserId==null|| !qwUserId.isEmpty()){
+            return  null;
+        }
         String redisKey = "qwUserRdById:" + qwUserId;
 
         // 直接从Redis获取JSON字符串
@@ -2249,6 +2252,21 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 //            logger.error("重粉提交mq失败", e);
 //        }
 //        iAdHtmlClickLogService.upload(state, AdUploadType.ADD_WX, e -> finalQwExternalContact.setUploadAddWxStatus(1));
+        //重粉问题
+        try {
+            new Thread(() -> {
+                try {
+                    Thread.sleep(3000);
+                } catch (InterruptedException e) {
+                    logger.error("添加等待时长错误", e);
+                }
+                rocketMQTemplate.syncSend("repeat-upload", JSON.toJSONString(RepeatUploadVo.builder().type(0).externalUserId(externalUserID).build()));
+            }).start();
+        }catch (Exception e){
+            logger.error("重粉提交mq失败", e);
+        }
+
+
 
         //先入一次库
         if (isNewQwExternalContact) {
@@ -2604,8 +2622,9 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                 //渠道活码的标签
                                 List<String> wayTags = JSON.parseArray(wayId.getTags(), String.class);
                                 //总添加标签
-                                combinedTagsSet.addAll(wayTags);
-                                logger.info("渠道活码标签,{}===============", wayTags);
+//                                combinedTagsSet.addAll(wayTags);
+                                combinedTagsSet = new HashSet<>(wayTags);
+                                logger.info("渠道活码标签,{}===============,打的标签={}", wayTags,combinedTagsSet);
                             }
 
                             //总标签 转换回列表
@@ -2676,18 +2695,18 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                     }
                     if (wayId.getIsRemark() == 1) {
                         if (wayId.getRemarkStatus() == 1) {
-                            if (!StringUtil.strIsNullOrEmpty(tagRemark)){
-                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark()+"-"+tagRemark);
-                            }else {
+//                            if (!StringUtil.strIsNullOrEmpty(tagRemark)){
+//                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark()+"-"+tagRemark);
+//                            }else {
                                 qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark());
-                            }
+//                            }
 
                         } else {
-                            if (!StringUtil.strIsNullOrEmpty(tagRemark)){
-                                qwExternalContact.setRemark(tagRemark+"-"+wayId.getRemark() + "-" + externalContact.getName());
-                            }else {
+//                            if (!StringUtil.strIsNullOrEmpty(tagRemark)){
+//                                qwExternalContact.setRemark(tagRemark+"-"+wayId.getRemark() + "-" + externalContact.getName());
+//                            }else {
                                 qwExternalContact.setRemark(wayId.getRemark() + "-" + externalContact.getName());
-                            }
+//                            }
 
                         }
                     }

+ 4 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwUserVideoServiceImpl.java

@@ -100,4 +100,8 @@ public class QwUserVideoServiceImpl implements IQwUserVideoService
     {
         return qwUserVideoMapper.deleteQwUserVideoById(id);
     }
+    @Override
+    public QwUserVideo selectByObjectId(String objectId, Long id) {
+        return qwUserVideoMapper.selectByObjectId(objectId, id);
+    }
 }

+ 1 - 0
fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java

@@ -18,6 +18,7 @@ public class QwExternalContactVO {
     /**
     *  属于用户名称
     */
+    @Excel(name = "销售企微昵称")
     private String qwUserName;
 
     /**

+ 6 - 1
fs-service/src/main/java/com/fs/qw/vo/QwFriendWelcomeVO.java

@@ -10,7 +10,7 @@ import java.util.List;
 
 /**
  * 好友欢迎语对象 qw_friend_welcome
- * 
+ *
  * @author fs
  * @date 2024-07-20
  */
@@ -60,6 +60,11 @@ public class QwFriendWelcomeVO extends BaseEntity
     /** 分时段欢迎语 */
     private String daypartingItemlist;
 
+    /**
+     * 欢迎语标题
+     */
+    private String welcomeTitle;
+
     public List<QwUserVO> userSelectList;
 
 }

+ 3 - 2
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempVoiceServiceImpl.java

@@ -10,6 +10,7 @@ import com.fs.common.enums.DataSourceType;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
+import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.vo.CompanyQwUserByIdsVo;
 import com.fs.fastgptApi.util.AudioUtils;
@@ -46,7 +47,7 @@ public class QwSopTempVoiceServiceImpl extends ServiceImpl<QwSopTempVoiceMapper,
     private final IQwSopTempContentService qwSopTempContentService;
     private final QwSopMapper qwSopMapper;
     private final QwSopTempDayMapper qwSopTempDayMapper;
-    private final ICompanyUserService companyUserService;
+    private final CompanyUserMapper companyUserMapper;
     private final QwSopTempVoiceMapper qwSopTempVoiceMapper;
     /**
      * 查询模板对应的销售语音文件
@@ -177,7 +178,7 @@ public class QwSopTempVoiceServiceImpl extends ServiceImpl<QwSopTempVoiceMapper,
             return;
         }
         List<Long> qwUserIdList = sopList.stream().flatMap(e -> Arrays.stream(e.getQwUserIds().split(","))).distinct().filter(StringUtils::isNotEmpty).map(Long::parseLong).collect(Collectors.toList());
-        List<CompanyQwUserByIdsVo> companyUserList = companyUserService.selectCompanyQwUserByIds(qwUserIdList);
+        List<CompanyQwUserByIdsVo> companyUserList = companyUserMapper.selectCompanyQwUserByIds(qwUserIdList);
         if (companyUserList.isEmpty()) {
             log.info("sop任务里面的销售为空跳过生成");
             qwSopTempDayMapper.updateVoice(dayId);

+ 10 - 0
fs-service/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java

@@ -33,4 +33,14 @@ public class WxWorkMessageDTO {
     // 语音
     private String voice_id;
     private Integer voice_size;
+
+    // 视频号
+    String objectId;//视频号ID
+    String nickname;//标题
+    String thumb_url;//视频号封面
+    String cover_url;//视频号切图
+    String avatar;//视频号头像
+    String desc;//视频号描述
+    String extras;//视频号扩展字段
+    String objectNonceId;//视频号扩展字段
 }

+ 1 - 1
fs-service/src/main/resources/application-druid-cqtyt-test.yml

@@ -11,7 +11,7 @@ spring:
         # 数据库索引
         database: 0
         # 密码
-#        password: Ylrz_c123232014^$
+        password:
         # 连接超时时间
         timeout: 20s
         lettuce:

+ 10 - 13
fs-service/src/main/resources/application-druid-cqtyt.yml

@@ -8,12 +8,10 @@ spring:
         host: r-2zexagt5g4z7arviu5.redis.rds.aliyuncs.com
         # 端口,默认为6379
         port: 6379
-        # 数据库索引
-        database: 0
         # 密码
         password: Ylrz_c123232014^$
         # 连接超时时间
-        timeout: 20s
+        timeout: 30s
         lettuce:
             pool:
                 # 连接池中的最小空闲连接
@@ -24,17 +22,8 @@ spring:
                 max-active: 8
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 max-wait: -1ms
+        database: 0
     datasource:
-        #        clickhouse:
-        #            type: com.alibaba.druid.pool.DruidDataSource
-        #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
-        #            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
-        #            username: rt_2024
-        #            password: Yzx_19860213
-        #            initialSize: 10
-        #            maxActive: 100
-        #            minIdle: 10
-        #            maxWait: 6000
         mysql:
             type: com.alibaba.druid.pool.DruidDataSource
             driverClassName: com.mysql.cj.jdbc.Driver
@@ -142,6 +131,14 @@ spring:
                     wall:
                         config:
                             multi-statement-allow: true
+redisson:
+    config: |
+        singleServerConfig:
+          address: "redis://r-2zexagt5g4z7arviu5.redis.rds.aliyuncs.com:6379"
+          password: "Ylrz_c123232014^$"
+          database: 0
+        checkKeysEventsConfig: false
+
 rocketmq:
     name-server: rmq-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
     producer:

+ 1 - 1
fs-service/src/main/resources/application-druid-jnmy-test.yml

@@ -41,7 +41,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://120.46.174.121:2345/fs_his_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    url: jdbc:mysql://120.46.174.121:2345/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: root
                     password: Ylrztek250218!3@.
                 # 从库数据源

+ 25 - 0
fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml

@@ -182,4 +182,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectFsCourseRedPacketLogHourseByCompany" resultType="com.fs.company.vo.RedPacketMoneyVO">
         SELECT a.company_id, SUM(amount) as money  FROM fs_course_red_packet_log a WHERE a.create_time &gt;= #{startTime} AND a.create_time &lt;= #{endTime} GROUP BY a.company_id
     </select>
+    <!-- 看客红包统计   -->
+    <select id="statistics" resultType="com.fs.course.dto.CourseRedPacketStatisticsDTO">
+       select c.company_name,cu.nick_name,pl.company_user_id,cu.company_id,sum(pl.amount) as redPacketTotalMoney,count(pl.log_id) as redPacketNum from fs_course_red_packet_log pl
+           left join  company_user cu on pl.company_user_id = cu.user_id
+       left join company c on cu.company_id=c.company_id
+       <where>
+           <if test="companyId != null">
+               and cu.company_id = #{companyId}
+           </if>
+           <if test="companyUserId != null">
+               and pl.company_user_id = #{companyUserId}
+           </if>
+            <if test="status != null">
+               and pl.status = #{status}
+           </if>
+           <if test="startTime != null">
+               and date_format(pl.create_time,'%Y-%m-%d') &gt;= date_format(#{startTime},'%Y-%m-%d')
+           </if>
+            <if test="endTime != null">
+               and date_format(pl.create_time,'%Y-%m-%d') &lt;= date_format(#{endTime},'%Y-%m-%d')
+           </if>
+       </where>
+       group by pl.company_user_id order by c.company_name
+    </select>
+
 </mapper>

+ 76 - 34
fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml

@@ -522,39 +522,52 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="(maps.companyUserNickName != null and maps.companyUserNickName !='') or (maps.params.dataScope!=null) ">
             LEFT JOIN  company_user cu on cu.user_id=so.company_user_id
         </if>
+        <if test="maps.coursePlaySourceConfigId != null">
+            LEFT JOIN (
+            SELECT
+            sp.*,
+            ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
+            FROM fs_store_payment sp
+            WHERE sp.business_code IS NOT NULL
+            ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
+            LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id
+        </if>
 
         where so.is_del=0
-        <if test="maps.packageSecondName != null and maps.packageSecondName != '' ">
+        <if test="maps.packageSecondName != null and maps.packageSecondName != ''">
             and so.package_second_name like concat('%', #{maps.packageSecondName}, '%')
         </if>
-        <if test="maps.storeId != null ">
+        <if test="maps.storeId != null">
             and so.store_id = #{maps.storeId}
         </if>
+        <if test="maps.coursePlaySourceConfigId != null">
+            and csc.id = #{maps.coursePlaySourceConfigId}
+        </if>
         <if test="maps.orderCodes != null  and maps.orderCodes.size > 0">
             and so.order_code in
             <foreach collection="maps.orderCodes" item="orderCode" open="(" close=")" separator=",">
                 #{orderCode}
             </foreach>
         </if>
-        <if test="maps.orderCode != null and maps.orderCode != ''">
+        <if test="maps.orderCode != null  and maps.orderCode != ''">
             and so.order_code = #{maps.orderCode}
         </if>
-        <if test="maps.prescribeCode != null and maps.prescribeCode != ''">
+        <if test="maps.prescribeCode != null  and maps.prescribeCode != ''">
             and p.prescribe_code = #{maps.prescribeCode}
         </if>
-        <if test="maps.userName != null and maps.userName != ''">
+        <if test="maps.userName != null  and maps.userName != ''">
             and so.user_name like concat('%', #{maps.userName}, '%')
         </if>
-        <if test="maps.userPhone != null and maps.userPhone != ''">
+        <if test="maps.userPhone != null  and maps.userPhone != ''">
             and so.user_phone = #{maps.userPhone}
         </if>
         <if test="maps.userId != null ">
             and so.user_id = #{maps.userId}
         </if>
-        <if test="maps.isFirst != null ">
+        <if test="maps.isFirst != null">
             and so.is_first = #{maps.isFirst}
         </if>
-        <if test="maps.status != null  and maps.status != 6">
+        <if test="maps.status != null and maps.status != 6">
             and so.status = #{maps.status}
         </if>
         <if test="maps.status == 6">
@@ -562,9 +575,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             and (
             so.store_id in (select store_id from fs_store where delivery_type=2 or delivery_type=1)
             )
-            and  (so.extend_order_id is null or so.extend_order_id like '')
+            and  (so.extend_order_id is null or  so.extend_order_id like '')
         </if>
-        <if test="maps.deliverySn != null and maps.deliverySn != ''">
+        <if test="maps.source != null">
+            and so.source = #{maps.source}
+        </if>
+        <if test="maps.deliverySn != null  and maps.deliverySn != ''">
             and so.delivery_sn = #{maps.deliverySn}
         </if>
         <if test="maps.prescribeId != null">
@@ -615,7 +631,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="maps.tuieTime != null">
             and DATE(so.tui_money_time) &lt;= DATE(#{maps.tuieTime})
         </if>
-        <if test="maps.companyUserNickName != null and maps.companyUserNickName !='' ">
+        <if test="maps.companyUserNickName != null and  maps.companyUserNickName !=''">
             and cu.nick_name like concat( #{maps.companyUserNickName}, '%')
         </if>
         <if test="maps.companyIds != null and  maps.companyIds.size >0">
@@ -624,69 +640,69 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 #{companyId}
             </foreach>
         </if>
-        <if test='maps.companyId != null and maps.companyId != "-1" '>
-            and so.company_id = #{maps.companyId}
+        <if test="maps.companyId != null and  maps.companyId != -1">
+            and so.company_id =#{maps.companyId}
         </if>
-        <if test='maps.companyId == "-1"'>
+        <if test="maps.companyId == -1">
             and so.company_id is null
         </if>
-        <if test='maps.deliveryStatus != null '>
+        <if test="maps.deliveryStatus != null">
             and so.delivery_status =#{maps.deliveryStatus}
         </if>
-        <if test='maps.customerId != null '>
+        <if test="maps.customerId != null">
             and so.customer_id =#{maps.customerId}
         </if>
-        <if test='maps.deliveryPayStatus != null '>
+        <if test="maps.deliveryPayStatus != null">
             and so.delivery_pay_status =#{maps.deliveryPayStatus}
         </if>
-        <if test='maps.tuiMoneyStatus != null '>
+        <if test="maps.tuiMoneyStatus != null">
             and so.tui_money_status =#{maps.tuiMoneyStatus}
         </if>
-        <if test='maps.deptId != null '>
+        <if test="maps.deptId != null">
             AND (so.dept_id = #{maps.deptId} OR so.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{maps.deptId}, ancestors) ))
         </if>
-        <if test='maps.packageName != null and maps.packageName != "" '>
+        <if test="maps.packageName != null and maps.packageName != ''">
             and so.package_name like concat('%', #{maps.packageName}, '%')
         </if>
-        <if test='maps.payType != null '>
+        <if test="maps.payType != null">
             and so.pay_type IN
-            <foreach collection="maps.payType.split(',') "  item='item' index='index'  open='(' separator=',' close=')'>
+            <foreach collection="maps.payType.split(',')" item="item" index="index" open="(" close=")" separator=",">
                 #{item}
             </foreach>
         </if>
-        <if test='maps.scheduleId != null and  maps.scheduleId != "-1" '>
+        <if test="maps.scheduleId != null  and  maps.scheduleId != -1">
             and so.schedule_id IN
-            <foreach collection="maps.scheduleId.split(',') "  item='item' index='index'  open='(' separator=',' close=')'>
+            <foreach collection="maps.scheduleId.split(',')" item="item" index="index" open="(" close=")" separator=",">
                 #{item}
             </foreach>
         </if>
-        <if test='maps.scheduleId == "-1" '>
+        <if test="maps.scheduleId == -1">
             and so.schedule_id is null
         </if>
-        <if test='maps.orderBuyType != null and  maps.orderBuyType != "-1" '>
+        <if test="maps.orderBuyType != null and maps.orderBuyType != -1">
             and so.order_buy_type IN
-            <foreach collection="maps.orderBuyType.split(',') "  item='item' index='index'  open='(' separator=',' close=')'>
+            <foreach collection="maps.orderBuyType.split(',')" item="item" index="index" open="(" close=")" separator=",">
                 #{item}
             </foreach>
         </if>
-        <if test='maps.orderBuyType == "-1" '>
+        <if test="maps.orderBuyType == -1">
             and so.order_buy_type is null
         </if>
-        <if test='maps.orderChannel == "-1" '>
+        <if test="maps.orderChannel == -1">
             and so.order_channel is null
         </if>
-        <if test='maps.orderChannel != null and  maps.orderChannel != "-1" '>
+        <if test="maps.orderChannel != null and maps.orderChannel != -1">
             and so.order_channel IN
-            <foreach collection="maps.orderChannel.split(',') "  item='item' index='index'  open='(' separator=',' close=')'>
+            <foreach collection="maps.orderChannel.split(',')" item="item" index="index" open="(" close=")" separator=",">
                 #{item}
             </foreach>
         </if>
-        <if test='maps.qwSubject == "-1"'>
+        <if test="maps.qwSubject == -1">
             and so.qw_subject is null
         </if>
-        <if test='maps.qwSubject != null and  maps.qwSubject != "-1" '>
+        <if test="maps.qwSubject != null and maps.qwSubject != -1">
             and so.qw_subject IN
-            <foreach collection="maps.qwSubject.split(',') "  item='item' index='index'  open='(' separator=',' close=')'>
+            <foreach collection="maps.qwSubject.split(',')" item="item" index="index" open="(" close=")" separator=",">
                 #{item}
             </foreach>
         </if>
@@ -1639,6 +1655,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_doctor d ON so.doctor_id= d.doctor_id
         LEFT JOIN company_user cu on cu.user_id=so.company_user_id
         LEFT JOIN fs_store_order_df df on df.order_id=so.order_id
+        <if test="maps.coursePlaySourceConfigId != null">
+            LEFT JOIN (
+            SELECT
+            sp.*,
+            ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
+            FROM fs_store_payment sp
+            WHERE sp.business_code IS NOT NULL
+            ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
+            LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id
+        </if>
         <where>
             <if test="maps.packageSecondName != null and maps.packageSecondName != ''">
                 and so.package_second_name like concat('%', #{maps.packageSecondName}, '%')
@@ -1646,6 +1672,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.storeId != null">
                 and so.store_id = #{maps.storeId}
             </if>
+            <if test="maps.coursePlaySourceConfigId != null">
+                and csc.id = #{maps.coursePlaySourceConfigId}
+            </if>
             <if test="maps.orderCodes != null  and maps.orderCodes.size > 0">
                 and so.order_code in
                 <foreach collection="maps.orderCodes" item="orderCode" open="(" close=")" separator=",">
@@ -1837,6 +1866,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_doctor d ON so.doctor_id= d.doctor_id
         LEFT JOIN company_user cu on cu.user_id=so.company_user_id
         LEFT JOIN fs_store_order_df df on df.order_id=so.order_id
+        <if test="maps.coursePlaySourceConfigId != null">
+            LEFT JOIN (
+            SELECT
+            sp.*,
+            ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
+            FROM fs_store_payment sp
+            WHERE sp.business_code IS NOT NULL
+            ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
+            LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id
+        </if>
         <where>
             <if test="maps.packageSecondName != null and maps.packageSecondName != ''">
                 and so.package_second_name like concat('%', #{maps.packageSecondName}, '%')
@@ -1844,6 +1883,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.storeId != null">
                 and so.store_id = #{maps.storeId}
             </if>
+            <if test="maps.coursePlaySourceConfigId != null">
+                and csc.id = #{maps.coursePlaySourceConfigId}
+            </if>
             <if test="maps.orderCodes != null  and maps.orderCodes.size > 0">
                 and so.order_code in
                 <foreach collection="maps.orderCodes" item="orderCode" open="(" close=")" separator=",">

+ 29 - 30
fs-service/src/main/resources/mapper/hisStore/FsUserScrmMapper.xml

@@ -515,49 +515,48 @@
     <update id="updateFsUser" parameterType="FsUserScrm">
         update fs_user
         <trim prefix="SET" suffixOverrides=",">
-            <if test="username != null">username = #{username},</if>
-            <if test="password != null">password = #{password},</if>
-            <if test="realName != null">real_name = #{realName},</if>
-            <if test="birthday != null">birthday = #{birthday},</if>
-            <if test="idCard != null">id_card = #{idCard},</if>
-            <if test="remark != null">remark = #{remark},</if>
+            <if test="nickName != null">nick_name = #{nickName},</if>
             <if test="nickname != null">nickname = #{nickname},</if>
             <if test="avatar != null">avatar = #{avatar},</if>
             <if test="phone != null">phone = #{phone},</if>
-            <if test="createTime != null">create_time = #{createTime},</if>
-            <if test="updateTime != null">update_time = #{updateTime},</if>
-            <if test="lastIp != null">last_ip = #{lastIp},</if>
-            <if test="nowMoney != null">now_money = #{nowMoney},</if>
-            <if test="brokeragePrice != null">brokerage_price = #{brokeragePrice},</if>
             <if test="integral != null">integral = #{integral},</if>
             <if test="signNum != null">sign_num = #{signNum},</if>
             <if test="status != null">status = #{status},</if>
-            <if test="level != null">level = #{level},</if>
-            <if test="spreadUserId != null">spread_user_id = #{spreadUserId},</if>
-            <if test="spreadTime != null">spread_time = #{spreadTime},</if>
-            <if test="userType != null and userType != ''">user_type = #{userType},</if>
-            <if test="isPromoter != null">is_promoter = #{isPromoter},</if>
-            <if test="payCount != null">pay_count = #{payCount},</if>
-            <if test="spreadCount != null">spread_count = #{spreadCount},</if>
-            <if test="addres != null and addres != ''">addres = #{addres},</if>
+            <if test="tuiUserId != null">tui_user_id = #{tuiUserId},</if>
+            <if test="tuiTime != null">tui_time = #{tuiTime},</if>
+            <if test="tuiUserCount != null">tui_user_count = #{tuiUserCount},</if>
             <if test="maOpenId != null">ma_open_id = #{maOpenId},</if>
             <if test="mpOpenId != null">mp_open_id = #{mpOpenId},</if>
             <if test="unionId != null">union_id = #{unionId},</if>
             <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="userCode != null">user_code = #{userCode},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="lastIp != null">last_ip = #{lastIp},</if>
+            <if test="balance != null">balance = #{balance},</if>
+            <if test="integralStatus != null">integral_status = #{integralStatus},</if>
+            <if test="isBuy != null">is_buy = #{isBuy},</if>
+            <if test="password != null">password = #{password},</if>
+            <if test="jpushId != null">jpush_id = #{jpushId},</if>
+            <if test="isVip != null">is_vip = #{isVip},</if>
+            <if test="vipStartDate != null">vip_start_date = #{vipStartDate},</if>
+            <if test="vipEndDate != null">vip_end_date = #{vipEndDate},</if>
+            <if test="vipLevel != null">vip_level = #{vipLevel},</if>
+            <if test="vipStatus != null">vip_status = #{vipStatus},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="storeOpenId != null">store_open_id = #{storeOpenId},</if>
+            <if test="isPush != null">is_push = #{isPush},</if>
+            <if test="isIndividuationPush != null">is_individuation_push = #{isIndividuationPush},</if>
             <if test="isWeixinAuth != null">is_weixin_auth = #{isWeixinAuth},</if>
-            <if test="companyId != null">company_id = #{companyId},</if>
-            <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
-            <if test="registerDate != null">register_date = #{registerDate},</if>
-            <if test="registerCode != null">register_code = #{registerCode},</if>
+            <if test="loginDevice != null">login_device = #{loginDevice},</if>
             <if test="source != null">source = #{source},</if>
-            <if test="userCode != null">user_code = #{userCode},</if>
-            <if test="isShow != null">is_show = #{isShow},</if>
-            <if test="qwExtId != null">qw_ext_id = #{qwExtId},</if>
             <if test="isAddQw != null">is_add_qw = #{isAddQw},</if>
-            <!--<if test="qwRepeat != null">qw_repeat = #{qwRepeat},</if>
-            <if test="userRepeat != null">user_repeat = #{userRepeat},</if>
-            <if test="payOrder != null">pay_order = #{payOrder},</if>
-            <if test="isBecomeMember != null">is_become_member = #{isBecomeMember},</if>-->
+            <if test="courseMaOpenId != null">course_ma_open_id = #{courseMaOpenId},</if>
+            <if test="parentId != null">parent_id = #{parentId},</if>
+            <if test="qwExtId != null">qw_ext_id = #{qwExtId},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
         </trim>
         where user_id = #{userId}
     </update>

+ 6 - 1
fs-service/src/main/resources/mapper/qw/QwFriendWelcomeMapper.xml

@@ -16,10 +16,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="corpId"    column="corp_id"    />
+        <result property="welcomeTitle"    column="welcome_title"    />
     </resultMap>
 
     <sql id="selectQwFriendWelcomeVo">
-        select id, qw_user_ids,corp_id, is_send_msg, welcome_text, attachments, is_dayparting, dayparting_ItemList, company_id, create_time, update_time from qw_friend_welcome
+        select id, qw_user_ids,corp_id,welcome_title, is_send_msg, welcome_text, attachments, is_dayparting, dayparting_ItemList, company_id, create_time, update_time from qw_friend_welcome
     </sql>
 
     <select id="selectQwFriendWelcomeListVO" parameterType="QwFriendWelcome" resultMap="QwFriendWelcomeResult">
@@ -33,6 +34,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null "> and create_time = #{createTime}</if>
             <if test="corpId != null "> and corp_id = #{corpId}</if>
             <if test="updateTime != null "> and update_time = #{updateTime}</if>
+            <if test="welcomeTitle != null "> and welcome_title = #{welcomeTitle}</if>
         </where>
     </select>
 
@@ -77,6 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <insert id="insertQwFriendWelcomeVO" parameterType="QwFriendWelcome" useGeneratedKeys="true" keyProperty="id">
         insert into qw_friend_welcome
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="welcomeTitle != null">welcome_title,</if>
             <if test="qwUserIds != null">qw_user_ids,</if>
             <if test="isSendMsg != null">is_send_msg,</if>
             <if test="welcomeText != null">welcome_text,</if>
@@ -91,6 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="corpId != null">corp_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="welcomeTitle != null">#{welcomeTitle},</if>
             <if test="qwUserIds != null">#{qwUserIds},</if>
             <if test="isSendMsg != null">#{isSendMsg},</if>
             <if test="welcomeText != null">#{welcomeText},</if>
@@ -109,6 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <update id="updateQwFriendWelcome" parameterType="QwFriendWelcome">
         update qw_friend_welcome
         <trim prefix="SET" suffixOverrides=",">
+            <if test="welcomeTitle != null">welcome_title = #{welcomeTitle},</if>
             <if test="qwUserIds != null">qw_user_ids = #{qwUserIds},</if>
             <if test="isSendMsg != null">is_send_msg = #{isSendMsg},</if>
             <if test="welcomeText != null">welcome_text = #{welcomeText},</if>