Browse Source

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

caoliqin 1 week ago
parent
commit
aab241076c
30 changed files with 629 additions and 179 deletions
  1. 34 0
      fs-admin/src/main/java/com/fs/task/FsCompanyTask.java
  2. 10 0
      fs-company-app/src/main/java/com/fs/app/controller/AppBaseController.java
  3. 85 2
      fs-company/src/main/java/com/fs/company/controller/qw/QwExternalContactController.java
  4. 17 0
      fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java
  5. 34 30
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/AsyncCourseWatchFinishService.java
  6. 5 0
      fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisQwSopController.java
  7. 165 0
      fs-qwhook/src/main/java/com/fs/app/controller/ApisQwSopController.java
  8. 5 1
      fs-qwhook/src/main/java/com/fs/app/controller/QwSopController.java
  9. 21 8
      fs-service/src/main/java/com/fs/company/mapper/CompanyUserRoleMapper.java
  10. 3 0
      fs-service/src/main/java/com/fs/company/service/ICompanyService.java
  11. 33 94
      fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  12. 5 0
      fs-service/src/main/java/com/fs/course/config/CourseConfig.java
  13. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseRedPacketLogMapper.java
  14. 9 1
      fs-service/src/main/java/com/fs/course/param/FsCourseSendRewardUParam.java
  15. 22 11
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  16. 7 2
      fs-service/src/main/java/com/fs/fastGpt/param/FastGptChatSessionParam.java
  17. 2 0
      fs-service/src/main/java/com/fs/fastGpt/service/IFastGptChatSessionService.java
  18. 16 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatSessionServiceImpl.java
  19. 28 23
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  20. 3 0
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  21. 23 0
      fs-service/src/main/java/com/fs/qw/service/AsyncQwAiChatSopService.java
  22. 80 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  23. 2 0
      fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java
  24. 1 0
      fs-service/src/main/resources/application-config-druid-nmgyt.yml
  25. 4 0
      fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml
  26. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java
  27. 7 2
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseQwController.java
  28. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/store/CourseH5ScrmController.java
  29. 2 2
      fs-user-app/src/main/java/com/fs/app/controller/store/CourseScrmController.java
  30. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/store/CourseWxH5ScrmController.java

+ 34 - 0
fs-admin/src/main/java/com/fs/task/FsCompanyTask.java

@@ -0,0 +1,34 @@
+package com.fs.task;
+
+import com.fs.company.service.ICompanyService;
+import com.fs.company.vo.RedPacketMoneyVO;
+import com.fs.course.mapper.FsCourseRedPacketLogMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@AllArgsConstructor
+@Component("companyTask")
+public class FsCompanyTask {
+
+    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
+    private ICompanyService companyService;
+
+    public void refreshCompanyMoney() {
+        LocalDateTime now = LocalDateTime.now();
+        // 获取上一个小时的开始时间
+        LocalDateTime startTime = now.minusHours(1)
+                .withMinute(0)
+                .withSecond(0);
+        // 获取上一个小时的结束时间
+        LocalDateTime endTime = startTime
+                .withMinute(59)
+                .withSecond(59);
+        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogHourseByCompany(startTime, endTime);
+        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
+            companyService.subtractCompanyMoneyHourse(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId(), startTime.toLocalTime(), endTime.toLocalTime());
+        }
+    }
+}

+ 10 - 0
fs-company-app/src/main/java/com/fs/app/controller/AppBaseController.java

@@ -13,6 +13,8 @@ import com.fs.his.service.IFsUserService;
 import io.jsonwebtoken.Claims;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.concurrent.TimeUnit;
+
 
 public class AppBaseController {
 	@Autowired
@@ -27,8 +29,16 @@ public class AppBaseController {
 	public Long getCompanyId() {
 		String headValue =  ServletUtils.getRequest().getHeader("APPToken");
 		Claims claims=jwtUtils.getClaimByToken(headValue);
+		if (ObjectUtil.isEmpty(claims)){
+			throw new FSException("未授权,请先登录!");
+		}
 		String userId = claims.getSubject().toString();
 		Long companyId =(Long)redisCache.getCacheObject("companyId:"+userId);
+		if (companyId==null){
+			CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(userId));
+			companyId = companyUser.getCompanyId();
+			redisCache.setCacheObject("companyId:" + companyUser.getUserId(), companyUser.getCompanyId(), 604800, TimeUnit.SECONDS);
+		}
 		return companyId;
 	}
 	public String getUserId()

+ 85 - 2
fs-company/src/main/java/com/fs/company/controller/qw/QwExternalContactController.java

@@ -21,6 +21,7 @@ import com.fs.crm.vo.CrmMyCustomerListQueryVO;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.his.service.IFsUserService;
+import com.fs.qw.domain.QwContactWay;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwTag;
 import com.fs.qw.param.*;
@@ -28,6 +29,7 @@ import com.fs.qw.service.*;
 import com.fs.qw.vo.QwExternalContactVO;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.qw.vo.QwUserDelLossLogVO;
+import com.fs.voice.utils.StringUtil;
 import com.github.pagehelper.PageHelper;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
@@ -79,6 +81,9 @@ public class QwExternalContactController extends BaseController
     @Autowired
     private CompanyDeptServiceImpl companyDeptService;
 
+    @Autowired
+    private IQwContactWayService qwContactWayService;
+
     /**
      * 查询企业微信客户列表
      */
@@ -86,8 +91,13 @@ public class QwExternalContactController extends BaseController
     @GetMapping("/list")
     public TableDataInfo list(QwExternalContactParam qwExternalContact)
     {
-        startPage();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+        QwContactWay qwContactWay=new QwContactWay();
+        qwContactWay.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);
+
+        startPage();
         qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
         List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
         list.forEach(item->{
@@ -105,11 +115,47 @@ public class QwExternalContactController extends BaseController
 
                 item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
             }
+
+            if (!StringUtil.strIsNullOrEmpty(item.getState()) && !wayList.isEmpty()) {
+                item.setState(item.getState()+"-"+getContactWayNameStream(item.getState(), wayList));
+            }
+
         });
 
         return getDataTable(list);
     }
 
+
+    public String getContactWayNameStream(String configStr, List<QwContactWay> wayList) {
+        if (configStr == null || wayList == null || wayList.isEmpty()) {
+            return null;
+        }
+
+        return wayList.stream()
+                .filter(way -> way.getId() != null &&
+                        way.getId().toString().equals(extractLastValue(configStr)))
+                .map(QwContactWay::getName)
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * 提取最后一个冒号后的值
+     */
+    private String extractLastValue(String input) {
+        if (input == null || input.isEmpty()) {
+            return null;
+        }
+
+        int lastColonIndex = input.lastIndexOf(":");
+        if (lastColonIndex == -1) {
+            return input;
+        }
+
+        return input.substring(lastColonIndex + 1);
+    }
+
+
     @GetMapping("/test")
     public AjaxResult test()
     {
@@ -154,6 +200,10 @@ public class QwExternalContactController extends BaseController
         qwExternalContact.setUserType(loginUser.getUser().getUserType());
         qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
 
+        QwContactWay qwContactWay=new QwContactWay();
+        qwContactWay.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);
+
         startPage();
         List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
         list.forEach(item->{
@@ -171,6 +221,11 @@ public class QwExternalContactController extends BaseController
 
                 item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
             }
+
+            if (!StringUtil.strIsNullOrEmpty(item.getState()) && !wayList.isEmpty()) {
+                item.setState(item.getState()+"-"+getContactWayNameStream(item.getState(), wayList));
+            }
+
         });
 
         return getDataTable(list);
@@ -183,8 +238,14 @@ public class QwExternalContactController extends BaseController
         if(qwExternalContact.getQwUserId()==null){
             return null;
         }
-        startPage();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+        QwContactWay qwContactWay=new QwContactWay();
+        qwContactWay.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);
+
+
+        startPage();
         qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
         List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
         list.forEach(item->{
@@ -202,6 +263,10 @@ public class QwExternalContactController extends BaseController
 
                 item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
             }
+
+            if (!StringUtil.strIsNullOrEmpty(item.getState()) && !wayList.isEmpty()) {
+                item.setState(item.getState()+"-"+getContactWayNameStream(item.getState(), wayList));
+            }
         });
 
         return getDataTable(list);
@@ -232,7 +297,13 @@ public class QwExternalContactController extends BaseController
         if (qwExternalContact.getCorpId()==null){
             return AjaxResult.success();
         }
+
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+        QwContactWay qwContactWay=new QwContactWay();
+        qwContactWay.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);
+
         qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
         List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
         list.forEach(item->{
@@ -250,6 +321,10 @@ public class QwExternalContactController extends BaseController
 
                 item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
             }
+
+            if (!StringUtil.strIsNullOrEmpty(item.getState()) && !wayList.isEmpty()) {
+                item.setState(item.getState()+"-"+getContactWayNameStream(item.getState(), wayList));
+            }
         });
         ExcelUtil<QwExternalContactVO> util = new ExcelUtil<QwExternalContactVO>(QwExternalContactVO.class);
         return util.exportExcel(list, "企业微信客户数据");
@@ -266,6 +341,10 @@ public class QwExternalContactController extends BaseController
         }
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
+        QwContactWay qwContactWay=new QwContactWay();
+        qwContactWay.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);
+
 
         List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
 
@@ -284,6 +363,10 @@ public class QwExternalContactController extends BaseController
 
                 item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
             }
+
+            if (!StringUtil.strIsNullOrEmpty(item.getState()) && !wayList.isEmpty()) {
+                item.setState(item.getState()+"-"+getContactWayNameStream(item.getState(), wayList));
+            }
         });
 
         ExcelUtil<QwExternalContactVO> util = new ExcelUtil<QwExternalContactVO>(QwExternalContactVO.class);

+ 17 - 0
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -8,6 +8,9 @@ import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.app.taskService.SopWxLogsService;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.vo.RedPacketMoneyVO;
+import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.param.newfs.FsUserCourseAddCompanyUserParam;
 import com.fs.course.service.*;
@@ -76,6 +79,10 @@ public class CommonController {
 
     @Autowired
     private IFsCourseLinkService courseLinkService;
+    @Autowired
+    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
+    @Autowired
+    private ICompanyService companyService;
 
     @Autowired
     private SopUserLogsMapper sopUserLogsMapper;
@@ -298,4 +305,14 @@ public class CommonController {
         }
         return R.ok();
     }
+    @GetMapping("/updateRedPack")
+    public R updateRedPack(String start , String end    ){
+        LocalDateTime startTime = DateUtil.parseLocalDateTime(start);
+        LocalDateTime endTime = DateUtil.parseLocalDateTime(end);
+        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogHourseByCompany(startTime, endTime);
+        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
+            companyService.subtractCompanyMoneyHourse(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId(), startTime.toLocalTime(), endTime.toLocalTime());
+        }
+        return R.ok();
+    }
 }

+ 34 - 30
fs-qw-task/src/main/java/com/fs/app/taskService/impl/AsyncCourseWatchFinishService.java

@@ -62,40 +62,44 @@ public class AsyncCourseWatchFinishService {
         }
 
         rocketMQTemplate.asyncSend("course-finish-notes", JSON.toJSONString(finishLog),     new SendCallback() {
-            @Override public void onSuccess(SendResult sendResult) {}  // 空实现
+            @Override public void onSuccess(SendResult sendResult) {
+                log.info("推送完课打备注成功1:{},{}",JSON.toJSONString(finishLog),sendResult.getMsgId());
+            }  // 空实现
             @Override public void onException(Throwable e) {log.error("推送完课打备注失败1:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
         });
 
 
-        // 定义默认值
-         final Integer DEFAULT_SERVER_NUM = 99;
-
-        // 使用
-        Integer companyServerNum = Optional.ofNullable(qwCompany.getCompanyServerNum())
-                .orElse(DEFAULT_SERVER_NUM);
-        switch (companyServerNum){
-            case 1:
-                rocketMQTemplate.asyncSend("course-finish-notes", JSON.toJSONString(finishLog),     new SendCallback() {
-                    @Override public void onSuccess(SendResult sendResult) {}  // 空实现
-                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败1:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
-                });
-                break;
-            case 2:
-
-                rocketMQTemplate.asyncSend("course-finish-notesTwo", JSON.toJSONString(finishLog),     new SendCallback() {
-                    @Override public void onSuccess(SendResult sendResult) {}  // 空实现
-                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败2:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
-                });
-                break;
-            case 3:
-                rocketMQTemplate.asyncSend("course-finish-notesThree", JSON.toJSONString(finishLog),     new SendCallback() {
-                    @Override public void onSuccess(SendResult sendResult) {}  // 空实现
-                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败3:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
-                });
-                break;
-            default:
-                break;
-        }
+//        // 定义默认值
+//         final Integer DEFAULT_SERVER_NUM = 99;
+//
+//        // 使用
+//        Integer companyServerNum = Optional.ofNullable(qwCompany.getCompanyServerNum())
+//                .orElse(DEFAULT_SERVER_NUM);
+//        switch (companyServerNum){
+//            case 1:
+//                rocketMQTemplate.asyncSend("course-finish-notes", JSON.toJSONString(finishLog),     new SendCallback() {
+//                    @Override public void onSuccess(SendResult sendResult) {
+//                     log.info("推送完课打备注成功1:{},{}",JSON.toJSONString(finishLog),sendResult.getMsgId());
+//                     }  // 空实现
+//                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败1:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
+//                });
+//                break;
+//            case 2:
+//
+//                rocketMQTemplate.asyncSend("course-finish-notesTwo", JSON.toJSONString(finishLog),     new SendCallback() {
+//                    @Override public void onSuccess(SendResult sendResult) {}  // 空实现
+//                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败2:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
+//                });
+//                break;
+//            case 3:
+//                rocketMQTemplate.asyncSend("course-finish-notesThree", JSON.toJSONString(finishLog),     new SendCallback() {
+//                    @Override public void onSuccess(SendResult sendResult) {}  // 空实现
+//                    @Override public void onException(Throwable e) {log.error("推送完课打备注失败3:{},{}",JSON.toJSONString(finishLog),e.getMessage());}          // 空实现
+//                });
+//                break;
+//            default:
+//                break;
+//        }
 
 
     }

+ 5 - 0
fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisQwSopController.java

@@ -4,6 +4,7 @@ import com.fs.app.params.SopLogsEditParam;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.fastGpt.param.FastGptChatSessionParam;
 import com.fs.fastGpt.service.IFastGptChatSessionService;
 import com.fs.qw.domain.QwTagGroup;
 import com.fs.qw.param.SopMsgParam;
@@ -95,6 +96,10 @@ public class ApisQwSopController {
         return qwSopLogsService.deleteQwSopLogsByJsApi(param);
 
     }
+    @PostMapping("/artificialInfo")
+    public R artificialInfo(@RequestBody FastGptChatSessionParam sessionParam) {
+        return R.ok().put("type",fastGptChatSessionService.selectFastGptChatSessionArtificialType(sessionParam));
+    }
 
     @GetMapping("/getQwSopLogs")
     public R getQwSopLogs(SopMsgParam param) throws Exception {

+ 165 - 0
fs-qwhook/src/main/java/com/fs/app/controller/ApisQwSopController.java

@@ -0,0 +1,165 @@
+package com.fs.app.controller;
+
+import com.fs.app.params.SopLogsEditParam;
+import com.fs.common.BeanCopyUtils;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.fastGpt.param.FastGptChatSessionParam;
+import com.fs.fastGpt.service.IFastGptChatSessionService;
+import com.fs.qw.domain.QwTagGroup;
+import com.fs.qw.param.SopMsgParam;
+import com.fs.qw.param.sidebar.ExternalContactInfoParam;
+import com.fs.qw.param.sidebar.TagGroupListParam;
+import com.fs.qw.param.sidebar.TagGroupUpdateParam;
+import com.fs.qw.result.QwExternalContactByQwResult;
+import com.fs.qw.service.IQwExternalContactService;
+import com.fs.qw.service.IQwTagGroupService;
+import com.fs.qw.vo.QwTagGroupListVO;
+import com.fs.qw.vo.sidebar.ExternalContactInfoVO;
+import com.fs.qw.vo.sidebar.ExternalContactTagVO;
+import com.fs.sop.domain.QwSopLogs;
+import com.fs.sop.params.GetQwSopLogsByJsApiParam;
+import com.fs.sop.params.SendSopParamDetailsC;
+import com.fs.sop.service.IQwSopLogsService;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+
+@RestController
+@RequestMapping("/apis/app/qwSop")
+public class ApisQwSopController {
+
+    @Autowired
+    RedisCache redisCache;
+    @Autowired
+    IFastGptChatSessionService fastGptChatSessionService;
+    @Autowired
+    private IQwSopLogsService qwSopLogsService;
+
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+
+    @Autowired
+    private IQwTagGroupService qwTagGroupService;
+
+    /**
+     * 更新AI发送状态
+     */
+    @PostMapping("/updateQwSopLogs")
+    public R updateCourseSopLogs(@RequestBody SopLogsEditParam param){
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            QwSopLogs qwSopLogs=new QwSopLogs();
+            qwSopLogs.setId(param.getId());
+            qwSopLogs.setReceivingStatus(param.getReceivingStatus());
+            qwSopLogs.setSendStatus(param.getSendStatus());
+            qwSopLogs.setRealSendTime(sdf.format(new Date()));
+            qwSopLogs.setRemark(param.getRemark());
+            qwSopLogsService.updateQwSopLogsSendType(qwSopLogs);
+                return  R.ok();
+        }catch (Exception e){
+                return R.error("更新失败");
+            }
+
+    }
+
+    //主动获取发送信息
+    @PostMapping("/getQwSopLogsByJsApi")
+    public R getQwSopLogsByJsApi(@RequestBody GetQwSopLogsByJsApiParam param) {
+
+        SendSopParamDetailsC qwSopLogsByJsApi = qwSopLogsService.getQwSopLogsByJsApi(param);
+
+        return R.ok().put("data",qwSopLogsByJsApi);
+    }
+
+    //获取销售的某个联系人
+    @GetMapping("/getExternalContactByAppKey/{appKey}")
+    public R getExternalContactByAppKey(@PathVariable("appKey") String appKey) {
+
+        QwExternalContactByQwResult result=qwSopLogsService.getExternalContactByAppKey(appKey);
+
+        return R.ok().put("data",result);
+    }
+
+    //清除不是当前员工的 外部联系以及营期
+    @PostMapping("/deleteQwSopLogsByJsApi")
+    public R deleteQwSopLogsByJsApi(@RequestBody GetQwSopLogsByJsApiParam param) {
+
+        return qwSopLogsService.deleteQwSopLogsByJsApi(param);
+
+    }
+    @PostMapping("/artificialInfo")
+    public R artificialInfo(@RequestBody FastGptChatSessionParam sessionParam) {
+        return R.ok().put("type",fastGptChatSessionService.selectFastGptChatSessionArtificialType(sessionParam));
+    }
+
+    @GetMapping("/getQwSopLogs")
+    public R getQwSopLogs(SopMsgParam param) throws Exception {
+        //获取记录
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<QwSopLogs> list = qwSopLogsService.selectQwSopLogsListVO(param);
+        PageInfo<QwSopLogs> listPageInfo=new PageInfo<>(list);
+        return R.ok().put("data",listPageInfo);
+    }
+
+    @GetMapping("/externalContact")
+    @ApiOperation("获取侧边栏外部联系人信息")
+    public R getExternalContactInfo(@RequestParam(value = "qwExternalContactId") Long qwExternalContactId) {
+        ExternalContactInfoVO externalContactInfo = qwExternalContactService.getExternalContactInfo(qwExternalContactId);
+        return R.ok().put("data", externalContactInfo);
+    }
+
+
+    @GetMapping("/externalContact/tag")
+    @ApiOperation("获取侧边栏外部联系人标签")
+    public R getExternalContactTag(@RequestParam(value = "qwExternalContactId") Long qwExternalContactId) {
+        List<ExternalContactTagVO> tagList = qwExternalContactService.getExternalContactTag(qwExternalContactId);
+        return R.ok().put("data", tagList);
+    }
+
+    @PutMapping("/externalContact")
+    @ApiOperation("编辑外部联系人信息")
+    public R updateExternalContactInfo(@RequestBody ExternalContactInfoParam param) {
+        return qwExternalContactService.updateExternalContactInfo(param);
+    }
+
+    @GetMapping("/tagGroupList")
+    @ApiOperation("获取所有标签组和其下标签")
+    public R getTagGroupList(TagGroupListParam param) {
+        QwTagGroup qwTagGroup = new QwTagGroup();
+        BeanCopyUtils.copy(param, qwTagGroup);
+        qwTagGroup.setName(param.getTagName());
+
+        PageHelper.startPage(qwTagGroup.getPageNum(), qwTagGroup.getPageSize());
+        List<QwTagGroupListVO> list = qwTagGroupService.selectQwGroupTagList(qwTagGroup);
+
+        PageInfo<QwTagGroupListVO> result = new PageInfo<>(list);
+        return R.ok().put("data", result);
+    }
+
+//    @GetMapping("/searchTags")
+//    @ApiOperation("搜索标签-跟管理端保持一致")
+//    public R searchTagList(QwTagParam param) {
+//        List<QwTagGroupListVO> list = qwTagService.searchTags(param);
+//        return R.ok().put("data", list);
+//    }
+
+    @PutMapping("/externalContact/tag")
+    @ApiOperation("编辑标签")
+    public R updateExternalContactTag(@RequestBody TagGroupUpdateParam param) {
+        int i = qwExternalContactService.updateExternalContactTag(param);
+        if (i > 0) {
+            return R.ok();
+        }
+        return R.error();
+    }
+
+}

+ 5 - 1
fs-qwhook/src/main/java/com/fs/app/controller/QwSopController.java

@@ -1,6 +1,7 @@
 package com.fs.app.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.fastGpt.param.FastGptChatSessionParam;
 import com.fs.fastGpt.param.SendHookAIParam;
 import com.fs.fastGpt.service.IFastGptChatSessionService;
 import com.fs.qw.param.QwLoginParam;
@@ -69,7 +70,10 @@ public class QwSopController {
         return R.ok("已关闭");
     }
 
-
+    @PostMapping("/artificialInfo")
+    public R artificialInfo(@RequestBody FastGptChatSessionParam sessionParam) {
+        return R.ok().put("type",fastGptChatSessionService.selectFastGptChatSessionArtificialType(sessionParam));
+    }
     /**
      * 更新AI发送状态
      */

+ 21 - 8
fs-service/src/main/java/com/fs/company/mapper/CompanyUserRoleMapper.java

@@ -1,20 +1,33 @@
 package com.fs.company.mapper;
 
 import com.fs.company.domain.CompanyUserRole;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 import java.util.List;
 
 /**
  * 用户和角色关联Mapper接口
- * 
+ *
  * @author fs
  * @date 2021-05-25
  */
-public interface CompanyUserRoleMapper 
+public interface CompanyUserRoleMapper
 {
+    @Select("\n" +
+            "SELECT \n" +
+            "   cur.user_id\n" +
+            "FROM \n" +
+            "    company_user_role cur\n" +
+            "JOIN \n" +
+            "    company_role cr ON cur.role_id = cr.role_id and cr.role_key = 'admin'\n" +
+            "WHERE \n" +
+            "    cur.user_id = #{userId} " +
+            "LIMIT 1")
+    public Long companyUserIsAdmin(@Param("userId") Long userId);
     /**
      * 查询用户和角色关联
-     * 
+     *
      * @param userId 用户和角色关联ID
      * @return 用户和角色关联
      */
@@ -22,7 +35,7 @@ public interface CompanyUserRoleMapper
 
     /**
      * 查询用户和角色关联列表
-     * 
+     *
      * @param companyUserRole 用户和角色关联
      * @return 用户和角色关联集合
      */
@@ -30,7 +43,7 @@ public interface CompanyUserRoleMapper
 
     /**
      * 新增用户和角色关联
-     * 
+     *
      * @param companyUserRole 用户和角色关联
      * @return 结果
      */
@@ -38,7 +51,7 @@ public interface CompanyUserRoleMapper
 
     /**
      * 修改用户和角色关联
-     * 
+     *
      * @param companyUserRole 用户和角色关联
      * @return 结果
      */
@@ -46,7 +59,7 @@ public interface CompanyUserRoleMapper
 
     /**
      * 删除用户和角色关联
-     * 
+     *
      * @param userId 用户和角色关联ID
      * @return 结果
      */
@@ -54,7 +67,7 @@ public interface CompanyUserRoleMapper
 
     /**
      * 批量删除用户和角色关联
-     * 
+     *
      * @param userIds 需要删除的数据ID
      * @return 结果
      */

+ 3 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyService.java

@@ -1,6 +1,7 @@
 package com.fs.company.service;
 
 import java.math.BigDecimal;
+import java.time.LocalTime;
 import java.util.List;
 
 import com.fs.common.core.domain.R;
@@ -159,4 +160,6 @@ public interface ICompanyService
      * @return
      */
     List<CompanyUser> selectCompanyListByIds(String result);
+
+    void subtractCompanyMoneyHourse(BigDecimal money, Long companyId, LocalTime start, LocalTime end);
 }

+ 33 - 94
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -1,9 +1,11 @@
 package com.fs.company.service.impl;
 
 import java.math.BigDecimal;
+import java.time.LocalTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.core.domain.R;
@@ -820,10 +822,17 @@ public class CompanyServiceImpl implements ICompanyService
                 .collect(Collectors.toList());
     }
 
+    @Autowired
+    private CompanyUserRoleMapper companyUserRoleMapper;
     @Override
     public List<DeptDataVO> getDeptData(Long companyId, Long currentCompanyUserId, Long currentDeptId) {
         List<DeptDataVO> result = new ArrayList<>();
 
+        Long isAdmin = companyUserRoleMapper.companyUserIsAdmin(currentCompanyUserId);
+        logger.info("当前用户 {} 是公司admin 返回公司所有部门树",currentDeptId);
+        if(isAdmin!=null){
+            return getDeptData(companyId);
+        }
         // 1. 获取所有部门数据
         List<CompanyDept> allCompanyDepts = companyDeptMapper.queryDeptDataAll();
 
@@ -1062,34 +1071,6 @@ public class CompanyServiceImpl implements ICompanyService
         return companyNode;
     }
 
-    /**
-     * 构建公司节点,包含其下属多级部门和用户
-     */
-    private DeptDataVO buildCompanyNode(Company company,
-                                        Map<Long, List<CompanyUser>> companyUserGroupByDeptId,
-                                        Map<Long, List<CompanyDept>> companyDeptGroupByCompanyId,
-                                        Map<Long, List<CompanyDept>> deptGroupByParentId,
-                                        Long currentDeptId,
-                                        Long currentCompanyUserId
-                                        ) {
-        DeptDataVO companyNode = new DeptDataVO();
-        companyNode.setLabel(company.getCompanyName());
-        companyNode.setId("company_"+company.getCompanyId());
-
-        // 获取公司下的顶级部门(parentId为null或为公司ID的部门)
-        List<CompanyDept> topLevelDepts = companyDeptGroupByCompanyId.get(company.getCompanyId());
-        if (topLevelDepts != null) {
-            topLevelDepts = topLevelDepts.stream()
-                    .filter(dept -> dept.getParentId() == null || dept.getParentId().equals(0L))
-                    .collect(Collectors.toList());
-        }
-
-        List<DeptDataVO> deptDataList = buildDeptTree(topLevelDepts, companyUserGroupByDeptId, deptGroupByParentId,currentDeptId,currentCompanyUserId);
-        companyNode.setChildren(deptDataList.isEmpty() ? null : deptDataList);
-
-        return companyNode;
-    }
-
     /**
      * 递归构建部门树
      */
@@ -1134,72 +1115,6 @@ public class CompanyServiceImpl implements ICompanyService
 
         return result;
     }
-    /**
-     * 递归构建部门树
-     */
-    /**
-     *
-     * @param depts
-     * @param companyUserGroupByDeptId
-     * @param deptGroupByParentId
-     * @param currentDeptId 当前部门id
-     * @param currentCompanyUserId 当前销售id
-     * @return
-     */
-    private List<DeptDataVO> buildDeptTree(List<CompanyDept> depts,
-                                           Map<Long, List<CompanyUser>> companyUserGroupByDeptId,
-                                           Map<Long, List<CompanyDept>> deptGroupByParentId,
-                                           Long currentDeptId,
-                                           Long currentCompanyUserId) {
-        if (depts == null || depts.isEmpty()) {
-            return new ArrayList<>();
-        }
-
-        List<DeptDataVO> result = new ArrayList<>();
-
-        for (CompanyDept dept : depts) {
-            DeptDataVO deptNode = new DeptDataVO();
-            deptNode.setLabel(dept.getDeptName());
-            deptNode.setId("dept_"+dept.getDeptId());
-
-            List<DeptDataVO> children = new ArrayList<>();
-
-            // 1. 添加子部门(递归)
-            List<CompanyDept> childDepts = deptGroupByParentId.get(dept.getDeptId());
-            if (childDepts != null && !childDepts.isEmpty()) {
-                List<DeptDataVO> childDeptNodes = buildDeptTree(childDepts, companyUserGroupByDeptId, deptGroupByParentId);
-                children.addAll(childDeptNodes);
-            }
-
-            // 2. 添加部门下的用户
-            List<CompanyUser> deptUsers = companyUserGroupByDeptId.get(dept.getDeptId());
-            if (deptUsers != null && !deptUsers.isEmpty()) {
-                for (CompanyUser user : deptUsers) {
-                    // 如果是销售当前部门,不显示同级其他销售
-                    if(ObjectUtils.equals(dept.getDeptId(),currentDeptId)) {
-                        if(ObjectUtils.equals(user.getUserId(),currentCompanyUserId)) {
-                            DeptDataVO userNode = new DeptDataVO();
-                            userNode.setLabel(user.getNickName()+"_"+user.getUserName());
-                            userNode.setId("user_"+user.getUserId());
-                            userNode.setChildren(null);
-                            children.add(userNode);
-                        }
-                    } else {
-                        DeptDataVO userNode = new DeptDataVO();
-                        userNode.setLabel(user.getNickName()+"_"+user.getUserName());
-                        userNode.setId("user_"+user.getUserId());
-                        userNode.setChildren(null);
-                        children.add(userNode);
-                    }
-                }
-            }
-
-            deptNode.setChildren(children.isEmpty() ? null : children);
-            result.add(deptNode);
-        }
-
-        return result;
-    }
 
     @Override
     @Transactional
@@ -1333,4 +1248,28 @@ public class CompanyServiceImpl implements ICompanyService
     public List<CompanyUser> selectCompanyListByIds(String result) {
         return companyMapper.selectCompanyListByIds(result);
     }
+    @Override
+    @Transactional
+    public void subtractCompanyMoneyHourse(BigDecimal money, Long companyId, LocalTime start, LocalTime end) {
+        if(companyId!=null&&companyId>0){
+            Company company=companyMapper.selectCompanyByIdForUpdate(companyId);
+            if(company!=null){
+                logger.info("每个小时扣除红包金额:{}", money);
+                company.setMoney(company.getMoney().subtract(money));
+                companyMapper.updateCompany(company);
+                CompanyMoneyLogs log=new CompanyMoneyLogs();
+                log.setCompanyId(company.getCompanyId());
+                if(end != null && start.getHour() != end.getHour()){
+                    log.setRemark("扣除"+start.getHour() + "到" + end.getHour() +"点红包金额");
+                }else{
+                    log.setRemark("扣除"+start.getHour()+"点红包金额");
+                }
+                log.setMoney(money.multiply(new BigDecimal(-1)));
+                log.setLogsType(15);
+                log.setBalance(company.getMoney());
+                log.setCreateTime(new Date());
+                moneyLogsMapper.insertCompanyMoneyLogs(log);
+            }
+        }
+    }
 }

+ 5 - 0
fs-service/src/main/java/com/fs/course/config/CourseConfig.java

@@ -62,6 +62,11 @@ public class CourseConfig implements Serializable {
      * 是否绑定
      */
     private Boolean isBound;
+
+    /**
+     * 是否显示企微二维码
+     */
+    private Boolean showQwCode;
     private Boolean dept;
     /**
      * 是否单销售观看(只能在第一次绑定的销售头上看课)

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

@@ -1,6 +1,7 @@
 package com.fs.course.mapper;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.List;
 
 import com.fs.company.vo.RedPacketMoneyVO;
@@ -168,4 +169,6 @@ public interface FsCourseRedPacketLogMapper
 
     @Select("SELECT * FROM fs_course_red_packet_log WHERE status = 0 and create_time > DATE_SUB(NOW(), INTERVAL 2 day) and company_user_id =#{userId}")
     List<FsCourseRedPacketLog> selectFail(@Param("userId") Long userId);
+
+    List<RedPacketMoneyVO> selectFsCourseRedPacketLogHourseByCompany(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
 }

+ 9 - 1
fs-service/src/main/java/com/fs/course/param/FsCourseSendRewardUParam.java

@@ -2,6 +2,8 @@ package com.fs.course.param;
 
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 /**
@@ -14,19 +16,25 @@ import java.io.Serializable;
 public class FsCourseSendRewardUParam implements Serializable
 {
     private Long userId;
+    @NotNull(message = "课程参数不能为空")
     private Long videoId;//小节Id
+    @NotBlank(message = "客服参数不能为空")
     private String qwUserId;
+    @NotNull(message = "客服参数不能为空")
     private Long companyUserId;
+    @NotNull(message = "经销商参数不能为空")
     private Long companyId;
+    @NotNull(message = "课程参数不能为空")
     private Long courseId;
     private String corpId;
     private Integer linkType;
+    @NotNull(message = "课程参数不能为空")
     private Long qwExternalId;
     private Integer source=1;//来源 1:h5  2:小程序
     private Integer isRoom;
     private Integer sendType;
     private Long periodId;
-
+    @NotBlank(message = "小程序参数不能为空")
     private String appId; //前端传来的小程序的appid
 
     private String code;

+ 22 - 11
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -758,7 +758,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
     private R addCustomerService(String qwUserById,String msg){
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         String contactWay = "";
+        if (ObjectUtils.isNotEmpty(config.getShowQwCode())&&!config.getShowQwCode()){
+            return R.error(400,msg).put("qrcode",contactWay);
+        }
         QwUser qwUser = qwUserMapper.selectQwUserById(Long.parseLong(qwUserById));
         if (qwUser==null){
             return R.error("客服不存在");
@@ -992,26 +997,31 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 //        if (StringUtils.isEmpty(user.getMpOpenId())){
 //            return R.error("未识别到领取信息");
 //        }
+        log.info("查询会员信息:{}", user);
         if (user.getStatus()==0){
             return R.error("会员被停用,无权限,请联系客服!");
         }
-        FsCourseWatchLog log = new FsCourseWatchLog();
+        FsCourseWatchLog watchLog = new FsCourseWatchLog();
 
         // 根据链接类型判断是否已发放奖励
-        log = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
-        if (log == null) {
+        watchLog = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
+        log.info("看课记录:{}", watchLog);
+        if (watchLog == null) {
             return R.error("无记录");
         }
-        if (log.getLogType() != 2) {
+        if (watchLog.getLogType() != 2) {
             return R.error("未完课");
         }
-        if (log.getRewardType() != null) {
+        if (watchLog.getRewardType() != null) {
             FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
+            log.info("课程红包:{}", packetLog);
             if(packetLog != null && packetLog.getStatus() == 1) {
                 return R.error("已领取该课程奖励,不可重复领取!");
             }
             if(packetLog != null && packetLog.getStatus() == 0) {
+                log.info("判断领取记录");
                 if(StringUtils.isNotEmpty(packetLog.getResult())){
+                    log.info("是否有结果");
                     R r = JSON.parseObject(packetLog.getResult(), R.class);
                     return r;
                 } else {
@@ -1029,22 +1039,22 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         // 获取配置信息
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-
+        log.info("奖励类型:{}", config.getRewardType());
         // 根据奖励类型发放不同奖励
         switch (config.getRewardType()) {
             // 红包奖励
             case 1:
-                return sendRedPacketReward(param, user, log, video, config);
+                return sendRedPacketReward(param, user, watchLog, video, config);
             // 积分奖励
             case 2:
-                return sendIntegralReward(param,user, log, config);
+                return sendIntegralReward(param,user, watchLog, config);
             // 红包+积分
             case 3:
-                R sendRed = sendRedPacketReward(param, user, log, video, config);
+                R sendRed = sendRedPacketReward(param, user, watchLog, video, config);
                 if (!Objects.equals(sendRed.get("code"), 200)) {
                     return sendRed;
                 }
-                return sendIntegralReward(param,user, log, config);
+                return sendIntegralReward(param,user, watchLog, config);
             default:
                 return R.error("参数错误!");
         }
@@ -1052,6 +1062,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     @Override
     public R sendRewardByFsUser(FsCourseSendRewardUParam param) {
+        log.info("进入用户判断");
         FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
         if (user == null){
             return R.error("未识别到用户信息");
@@ -1127,7 +1138,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
      * @return 处理结果
      */
     private R sendRedPacketReward(FsCourseSendRewardUParam param, FsUser user, FsCourseWatchLog log, FsUserCourseVideo video, CourseConfig config) {
-
+        logger.info("进入发放红包");
         // 确定红包金额
         BigDecimal amount = BigDecimal.ZERO;
         FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(param.getVideoId(), param.getCompanyId(), param.getPeriodId());

+ 7 - 2
fs-service/src/main/java/com/fs/fastGpt/param/FastGptChatSessionParam.java

@@ -35,8 +35,8 @@ public class FastGptChatSessionParam  extends BaseEntity {
     @Excel(name = "是否查看")
     private Long isLook;
 
-    /** 用户类型 1微信用户 2小程序用户 3销售用户 */
-    @Excel(name = "用户类型 1微信用户 2小程序用户 3销售用户")
+    /** 用户类型 1微信用户 2小程序用户 3客服用户 */
+    @Excel(name = "用户类型 1微信用户 2小程序用户 3客服用户")
     private Integer userType;
 
     /** 客户昵称 */
@@ -47,4 +47,9 @@ public class FastGptChatSessionParam  extends BaseEntity {
     private String qwUserName;
     private Integer isArtificial;
 
+    private Long qwExtId;
+    private String qwUserId;
+    private Integer overTime;
+    private String corpId;
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/fastGpt/service/IFastGptChatSessionService.java

@@ -78,4 +78,6 @@ public interface IFastGptChatSessionService
     void addAiMsgBySopByStatus(String id);
 
     void qwHookNotifyAddMsg(QwHookMsgVO msgVo);
+
+    Integer selectFastGptChatSessionArtificialType(FastGptChatSessionParam sessionParam);
 }

+ 16 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatSessionServiceImpl.java

@@ -36,6 +36,7 @@ import com.fs.qw.mapper.QwExternalContactInfoMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwContactWayService;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwJsApiService;
 import com.fs.qw.service.IQwUserService;
 import com.fs.qwApi.service.QwApiService;
@@ -81,6 +82,8 @@ public class FastGptChatSessionServiceImpl implements IFastGptChatSessionService
     @Autowired
     private QwExternalContactInfoMapper qwExternalContactInfoMapper;
     @Autowired
+    private IQwExternalContactService qwExternalContactService;
+    @Autowired
     private IFastGptRoleService roleService;
     @Autowired
     private ChatService chatService;
@@ -358,6 +361,19 @@ public class FastGptChatSessionServiceImpl implements IFastGptChatSessionService
             }
 
     }
+    @Override
+    public Integer selectFastGptChatSessionArtificialType(FastGptChatSessionParam sessionParam) {
+        QwUser qwUser = qwExternalContactService.getQwUserByRedis(sessionParam.getCorpId().trim(), sessionParam.getQwUserId().trim());
+        if(qwUser != null && qwUser.getId() != null){
+            FastGptChatSession chatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(sessionParam.getQwExtId(), qwUser.getId());
+            if(chatSession != null && chatSession.getIsArtificial() != null){
+                return chatSession.getIsArtificial();
+            }else{
+                return null;
+            }
+        }
+        return null;
+    }
 
     @Override
     public void qwHookNotifyAddMsg(QwHookMsgVO vo) {

+ 28 - 23
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -1853,29 +1853,34 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
 
         String[] address = order.getUserAddress().split(" ");
-        if (address.length < 3) {
-            String kdnAddress = fsUserAddressService.getKdnAddress(order.getUserAddress());
-            Map<String, Object> addDAta = (Map<String, Object>) JSON.parse(kdnAddress);
-            Map<String, String> add = (Map<String, String>) addDAta.get("Data");
-            erpOrder.setReceiver_province(add.get("ProvinceName"));
-            erpOrder.setReceiver_city(add.get("CityName"));
-            erpOrder.setReceiver_district(add.get("ExpAreaName"));
-            erpOrder.setReceiver_address(add.get("StreetName") + add.get("Address"));
-        } else {
-            erpOrder.setReceiver_province(address[0]);
-            erpOrder.setReceiver_city(address[1]);
-            erpOrder.setReceiver_district(address[2]);
-            //处理地址多空隔问题
-            if (address.length > 3) {
-                StringBuffer addrs = new StringBuffer();
-                for (int i = 3; i < address.length; i++) {
-                    addrs.append(address[i]);
-                }
-                erpOrder.setReceiver_address(addrs.toString());
-            } else if (address.length == 3) {
-                erpOrder.setReceiver_address(address[2]);
-            }
-        }
+      try{
+          if (address.length < 3) {
+              String kdnAddress = fsUserAddressService.getKdnAddress(order.getUserAddress());
+              Map<String, Object> addDAta = (Map<String, Object>) JSON.parse(kdnAddress);
+              Map<String, String> add = (Map<String, String>) addDAta.get("Data");
+              erpOrder.setReceiver_province(add.get("ProvinceName"));
+              erpOrder.setReceiver_city(add.get("CityName"));
+              erpOrder.setReceiver_district(add.get("ExpAreaName"));
+              erpOrder.setReceiver_address(add.get("StreetName") + add.get("Address"));
+          } else {
+              erpOrder.setReceiver_province(address[0]);
+              erpOrder.setReceiver_city(address[1]);
+              erpOrder.setReceiver_district(address[2]);
+              //处理地址多空隔问题
+              if (address.length > 3) {
+                  StringBuffer addrs = new StringBuffer();
+                  for (int i = 3; i < address.length; i++) {
+                      addrs.append(address[i]);
+                  }
+                  erpOrder.setReceiver_address(addrs.toString());
+              } else if (address.length == 3) {
+                  erpOrder.setReceiver_address(address[2]);
+              }
+          }
+      }catch (Exception e){
+          log.error("地址错误:{}",e);
+          throw new CustomException("地址格式不对请正确写入详细地址!!");
+      }
         erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("+", "加"));
         erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("\n", ""));
 

+ 3 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -120,6 +120,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 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.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Async;
@@ -186,9 +187,11 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     private RedisCache redisCache;
 
     @Autowired
+    @Qualifier("redisTemplateForBigDecimal")
     private RedisTemplate<String,BigDecimal> redisTemplate;
 
     @Autowired
+    @Qualifier("redisTemplateForInteger")
     private RedisTemplate<String,Integer> redisTemplateInteger;
     /**
      * 红包领取数量限制 默认一个用户当天最多只能领取10个

+ 23 - 0
fs-service/src/main/java/com/fs/qw/service/AsyncQwAiChatSopService.java

@@ -12,7 +12,9 @@ import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.fastGpt.domain.FastGptChatReplaceWords;
 import com.fs.fastGpt.mapper.FastGptChatReplaceWordsMapper;
 import com.fs.qw.domain.QwCompany;
+import com.fs.qw.domain.QwExternalContactInfo;
 import com.fs.qw.domain.QwUser;
+import com.fs.qw.mapper.QwExternalContactInfoMapper;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.QwSopTempSetting;
 import com.fs.sop.domain.QwSopLogs;
@@ -82,6 +84,9 @@ public class AsyncQwAiChatSopService {
     @Autowired
     private IQwSopTempVoiceService sopTempVoiceService;
 
+    @Autowired
+    private QwExternalContactInfoMapper qwExternalContactInfoMapper;
+
     @Async("threadPoolTaskExecutor")
     public void executeQwAiChatSop(QwSopAutoByTags qwSopAutoByTags, String userID,
                                    QwUser qwUser, String externalUserID, String externalContactName,
@@ -320,4 +325,22 @@ public class AsyncQwAiChatSopService {
         }
     }
 
+    /**
+     * 在职转接 -AI用户信息 一起转
+     */
+    @Async("threadPoolTaskExecutor")
+    public void executeQwSopJobTransfer(Long externalContactId, Long externalId){
+        try {
+            QwExternalContactInfo contactInfo = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(externalContactId);
+            if (contactInfo != null) {
+                contactInfo.setExternalContactId(externalId);
+                qwExternalContactInfoMapper.insertQwExternalContactInfo(contactInfo);
+            }
+        }catch (Exception e){
+            log.error("在职转接-转接客户AI信息失败:{},{}",externalContactId,externalId,e);
+        }
+
+    }
+
+
 }

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

@@ -202,6 +202,9 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
     @Autowired
     private ISysDictTypeService dictTypeService;
 
+    @Autowired
+    private AsyncQwAiChatSopService asyncQwAiChatSopService;
+
 
     Logger logger = LoggerFactory.getLogger(getClass());
 
@@ -2183,6 +2186,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
     @Override
     public void insertQwExternalContactByExternalUserId(String externalUserID, String userID, Long companyId, String corpId, String state, String welcomeCode) throws ParseException {
 
+
+        String qwApiExternal=redisCache.getCacheObject("qwApiExternal:"+userID+":"+corpId+":"+externalUserID);
+        if (!StringUtil.strIsNullOrEmpty(qwApiExternal)){
+            return;
+        }else {
+            redisCache.setCacheObject("qwApiExternal:"+userID+":"+corpId+":"+externalUserID ,"1",10, TimeUnit.MINUTES);
+        }
+
         // 获取当前日期(只包含年月日)
         LocalDate currentDate = LocalDate.now();
         // 获取当前系统时间 (HH:mm)
@@ -2767,6 +2778,13 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                     //SOP规则
                     qwSopRuleTimeTools(qwSopRuleTimeVOS,userID,qwUser,corpId,externalUserID,externalContact.getName(),contact,currentDate,localTime,combinedTagsList);
                 }
+
+                //新客对话任务
+                Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                if (!sopAiChatByRedis){
+                    asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                            ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                }
                 //aiSop任务
 //                List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()){
@@ -3216,6 +3234,12 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                     //SOP规则
                     qwSopRuleTimeTools(qwSopRuleTimeVOS,contact.getUserId(),qwUser,contact.getCorpId(),contact.getExternalUserId(),contact.getName(),contact,currentDate,localTime,combinedTagsList);
                 }
+
+                Boolean sopAiChatByRedis = getSopAiChatByRedis(qwUser.getQwUserId(), qwUser.getCorpId(), contact.getExternalUserId());
+                if (!sopAiChatByRedis){
+                    asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,qwUser.getQwUserId(),qwUser, contact.getExternalUserId()
+                            ,contact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                }
 //                //aiSop任务
 //                List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()){
@@ -3398,6 +3422,15 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 
                         }
 
+                        try {
+
+                            asyncQwAiChatSopService.executeQwSopJobTransfer(transferLogVO.getExternalContactId(), logsInfoNew.getExternalId());
+
+                        }catch (Exception e){
+                            logger.error("在职转接-转接客户AI信息失败:{},{}",transferLogVO.getExternalContactId(),logsInfoNew.getExternalId(),e);
+                        }
+
+
                         //删除原员工对此客户的营期信息
                         sopUserLogsInfoMapper.deleteById(logsInfoOld.getId());
 
@@ -4976,6 +5009,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                 //SOP规则
                                                 qwSopRuleTimeTools(qwSopRuleTimeVOS, qwUserId, qwUser, corpId, ext, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                             }
+
+                                            //aiSop任务
+                                            Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                            if (!sopAiChatByRedis){
+                                                asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                        ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                            }
+
                                             //aiSop任务
 //                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                                            if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
@@ -5014,6 +5055,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                 //SOP规则
                                                 qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                             }
+
+                                            //aiSop任务
+                                            Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                            if (!sopAiChatByRedis){
+                                                asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                        ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                            }
+
 //                                            //aiSop任务
 //                                            logger.info("/n 传参:" + qwSopAutoByTags);
 //                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
@@ -5048,6 +5097,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                 //SOP规则
                                                 qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                             }
+
+                                            //新客对话任务
+                                            Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                            if (!sopAiChatByRedis){
+                                                asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                        ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                            }
+
 //                                            //aiSop任务
 //                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                                            if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
@@ -5264,6 +5321,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                         //SOP规则
                                                         qwSopRuleTimeTools(qwSopRuleTimeVOS, qwUserId, qwUser, corpId, ext, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                     }
+
+                                                    //aiSop任务
+                                                    Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                                    if (!sopAiChatByRedis){
+                                                        asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                                ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                                    }
+
                                                     //aiSop任务
 //                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
@@ -5295,6 +5360,13 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                         //SOP规则
                                                         qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                     }
+
+                                                    //aiSop任务
+                                                    Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                                    if (!sopAiChatByRedis){
+                                                        asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                                ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                                    }
                                                     //aiSop任务
 //                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
@@ -5322,6 +5394,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                                                         //SOP规则
                                                         qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                     }
+
+                                                    //aiSop任务
+                                                    Boolean sopAiChatByRedis = getSopAiChatByRedis(userID, corpId, externalUserID);
+                                                    if (!sopAiChatByRedis){
+                                                        asyncQwAiChatSopService.executeQwAiChatSop(qwSopAutoByTags,userID,qwUser,externalUserID
+                                                                ,externalContact.getName(),contact.getId(),contact.getFsUserId(),currentDate,localTime);
+                                                    }
+
                                                     //aiSop任务
 //                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
 //                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {

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

@@ -108,7 +108,9 @@ public class QwExternalContactVO {
     private Date registerTime;
     private Integer transferNum;
 
+    @Excel(name = "活码")
     private String state;
+
     private Long wayId;
     private String stageStatus;
     private String customerName;

+ 1 - 0
fs-service/src/main/resources/application-config-druid-nmgyt.yml

@@ -90,5 +90,6 @@ ipad:
 wx_miniapp_temp:
   pay_order_temp_id: V
   inquiry_temp_id: 9
+enableRedPackAccount: 1
 
 

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

@@ -178,4 +178,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         inner join fs_user fu on fu.user_id = fcrpl.user_id and date(fu.create_time) = CURDATE()
         where fcrpl.company_user_id = #{companyUserId}
     </select>
+
+    <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>
 </mapper>

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java

@@ -129,7 +129,7 @@ public class CourseFsUserController extends AppBaseController {
             Long userId = Long.parseLong(getUserId());
             param.setUserId(userId);
         }
-        logger.info("zyp \n【发放奖励】:{}",param);
+        logger.info("zyp \n【发放奖励】2:{}",param);
         return courseVideoService.sendRewardByFsUser(param);
     }
 

+ 7 - 2
fs-user-app/src/main/java/com/fs/app/controller/course/CourseQwController.java

@@ -2,6 +2,7 @@ package com.fs.app.controller.course;
 
 
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.app.annotation.Login;
 import com.fs.app.controller.AppBaseController;
 import com.fs.common.annotation.RepeatSubmit;
@@ -33,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -110,6 +112,9 @@ public class CourseQwController extends AppBaseController {
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         FsUserCourseVideoH5DVO course = courseService.selectFsUserCourseVideoH5DVOByVideoId(param.getVideoId());
         List<FsUserCourseVideoQuestionVO> questionVOList = new ArrayList<>();
+        if (ObjectUtils.isEmpty(course)){
+            return R.error("课堂视频对象不存在,请联系客服!");
+        }
         if (StringUtils.isNotEmpty(course.getQuestionBankId())){
             String[] questionIds = course.getQuestionBankId().split(",");
             for (String questionId : questionIds){
@@ -219,10 +224,10 @@ public class CourseQwController extends AppBaseController {
     @ApiOperation("发放奖励")
     @PostMapping("/sendReward")
     @RepeatSubmit
-    public R sendReward(@RequestBody FsCourseSendRewardUParam param)
+    public R sendReward(@RequestBody @Valid FsCourseSendRewardUParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        logger.info("【发放奖励】:{}",param);
+        logger.info("【发放奖励】3:{}",param);
         return courseVideoService.sendReward(param);
     }
 

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

@@ -159,7 +159,7 @@ public class CourseH5ScrmController extends AppBaseController {
     public R sendReward(@RequestBody FsCourseSendRewardUParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        logger.info("【发放奖励】:{}",param);
+        logger.info("【发放奖励】4:{}",param);
         return courseVideoService.sendReward(param);
     }
 

+ 2 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/CourseScrmController.java

@@ -437,7 +437,7 @@ public class CourseScrmController extends AppBaseController {
     public R sendReward(@RequestBody FsCourseSendRewardUParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        logger.info("zyp \n【发放奖励】:{}",param);
+        logger.info("zyp \n【发放奖励】5:{}",param);
         return courseVideoService.sendReward(param);
     }
 
@@ -552,7 +552,7 @@ public class CourseScrmController extends AppBaseController {
     @GetMapping("/sendRewardByTest")
     public R sendRewardByTest(@RequestBody Long userId)
     {
-        logger.info("zyp \n【发放奖励】:{}",userId);
+        logger.info("zyp \n【发放奖励】6:{}",userId);
         return  storePaymentService.sendRewardByTest(userId);
     }
 

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

@@ -121,7 +121,7 @@ public class CourseWxH5ScrmController extends AppBaseController {
     public R sendReward(@RequestBody FsCourseSendRewardUParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        logger.info("【发放奖励】:{}",param);
+        logger.info("【发放奖励】1:{}",param);
         return courseVideoService.sendRewardByFsUser(param);
     }