Quellcode durchsuchen

Merge remote-tracking branch 'origin/master'

ct vor 1 Woche
Ursprung
Commit
00a1aea5fa
46 geänderte Dateien mit 1883 neuen und 596 gelöschten Zeilen
  1. 126 0
      fs-admin/src/main/java/com/fs/fastGpt/FastgptExtUserTagController.java
  2. 12 0
      fs-admin/src/main/java/com/fs/qw/controller/QwTagGroupController.java
  3. 23 1
      fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java
  4. 2 0
      fs-service/src/main/java/com/fs/aiTongueApi/config/AiTongueConfig.java
  5. 58 0
      fs-service/src/main/java/com/fs/aiTongueApi/domain/enums/TongueTypeEnums.java
  6. 14 0
      fs-service/src/main/java/com/fs/aiTongueApi/domain/inner/ConfidenceDataNew.java
  7. 14 0
      fs-service/src/main/java/com/fs/aiTongueApi/domain/inner/TongueInfo.java
  8. 3 0
      fs-service/src/main/java/com/fs/aiTongueApi/service/AiTongueService.java
  9. 187 2
      fs-service/src/main/java/com/fs/aiTongueApi/service/impl/AiTongueServiceImpl.java
  10. 2 2
      fs-service/src/main/java/com/fs/company/domain/CompanyUser.java
  11. 1 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyRoleMapper.java
  12. 4 0
      fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java
  13. 166 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  14. 17 350
      fs-service/src/main/java/com/fs/company/vo/CompanyUserImportVO.java
  15. 2 0
      fs-service/src/main/java/com/fs/company/vo/CompanyVO.java
  16. 1 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoRedPackageMapper.java
  17. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java
  18. 3 0
      fs-service/src/main/java/com/fs/course/vo/newfs/FsUserCourseVideoPageListVO.java
  19. 31 0
      fs-service/src/main/java/com/fs/fastGpt/domain/FastgptExtUserTag.java
  20. 67 0
      fs-service/src/main/java/com/fs/fastGpt/mapper/FastgptExtUserTagMapper.java
  21. 66 0
      fs-service/src/main/java/com/fs/fastGpt/service/IFastgptExtUserTagService.java
  22. 58 2
      fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  23. 145 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastgptExtUserTagServiceImpl.java
  24. 34 0
      fs-service/src/main/java/com/fs/fastGpt/vo/FastgptExtUserTagVO.java
  25. 3 0
      fs-service/src/main/java/com/fs/his/mapper/FsHealthTongueMapper.java
  26. 8 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  27. 3 0
      fs-service/src/main/java/com/fs/his/service/IFsHealthTongueService.java
  28. 60 57
      fs-service/src/main/java/com/fs/his/service/impl/FsHealthTongueServiceImpl.java
  29. 191 171
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  30. 71 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreProductScrm.java
  31. 2 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  32. 122 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreProductAddEditParam.java
  33. 5 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductListVO.java
  34. 5 0
      fs-service/src/main/java/com/fs/qw/param/QwExternalContactParam.java
  35. 5 0
      fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java
  36. 5 0
      fs-service/src/main/resources/mapper/company/CompanyRoleMapper.xml
  37. 2 0
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  38. 6 1
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoRedPackageMapper.xml
  39. 75 0
      fs-service/src/main/resources/mapper/fastGpt/FastgptExtUserTagMapper.xml
  40. 4 0
      fs-service/src/main/resources/mapper/his/FsHealthTongueMapper.xml
  41. 196 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  42. 78 2
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  43. 2 1
      fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml
  44. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/AdvController.java
  45. 0 2
      fs-user-app/src/main/java/com/fs/app/controller/CommonController.java
  46. 2 2
      fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

+ 126 - 0
fs-admin/src/main/java/com/fs/fastGpt/FastgptExtUserTagController.java

@@ -0,0 +1,126 @@
+package com.fs.fastGpt;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.fastGpt.vo.FastgptExtUserTagVO;
+import com.fs.framework.web.service.TokenService;
+import com.fs.qw.service.IQwCompanyService;
+import com.fs.qw.vo.QwOptionsVO;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.fastGpt.domain.FastgptExtUserTag;
+import com.fs.fastGpt.service.IFastgptExtUserTagService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 处理新客标签Controller
+ * 
+ * @author fs
+ * @date 2025-09-10
+ */
+@RestController
+@RequestMapping("/fastGpt/FastGptExtUserTag")
+public class FastgptExtUserTagController extends BaseController
+{
+    @Autowired
+    private IFastgptExtUserTagService fastgptExtUserTagService;
+
+
+    @Autowired
+    private IQwCompanyService qwCompanyService;
+
+
+    /**
+     * 查询处理新客标签列表
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FastgptExtUserTag fastgptExtUserTag)
+    {
+        startPage();
+        List<FastgptExtUserTag> list = fastgptExtUserTagService.selectFastgptExtUserTagList(fastgptExtUserTag);
+        return getDataTable(list);
+    }
+    @PreAuthorize("@ss.hasPermi('qw:externalContact:addTag')")
+    @Log(title = "添加标签", businessType = BusinessType.UPDATE)
+    @PostMapping("/addFastGptTagByCorpId")
+    public R addFastGptTagByCorpId(@RequestBody FastgptExtUserTagVO fastgptExtUserTag) {
+        return fastgptExtUserTagService.addFastGptTagByCorpId(fastgptExtUserTag);
+    }
+    @GetMapping("/getMyQwUserList")
+    public R getMyQwUserList()
+    {
+        List<QwOptionsVO> list = qwCompanyService.selectQwCompanyListOptionsVO();
+        return  R.ok().put("data",list);
+    }
+
+    /**
+     * 导出处理新客标签列表
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:export')")
+    @Log(title = "处理新客标签", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastgptExtUserTag fastgptExtUserTag)
+    {
+        List<FastgptExtUserTag> list = fastgptExtUserTagService.selectFastgptExtUserTagList(fastgptExtUserTag);
+        ExcelUtil<FastgptExtUserTag> util = new ExcelUtil<FastgptExtUserTag>(FastgptExtUserTag.class);
+        return util.exportExcel(list, "处理新客标签数据");
+    }
+
+    /**
+     * 获取处理新客标签详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fastgptExtUserTagService.selectFastgptExtUserTagById(id));
+    }
+
+    /**
+     * 新增处理新客标签
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:add')")
+    @Log(title = "处理新客标签", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastgptExtUserTag fastgptExtUserTag)
+    {
+        return toAjax(fastgptExtUserTagService.insertFastgptExtUserTag(fastgptExtUserTag));
+    }
+
+    /**
+     * 修改处理新客标签
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:edit')")
+    @Log(title = "处理新客标签", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastgptExtUserTag fastgptExtUserTag)
+    {
+        return toAjax(fastgptExtUserTagService.updateFastgptExtUserTag(fastgptExtUserTag));
+    }
+
+    /**
+     * 删除处理新客标签
+     */
+    @PreAuthorize("@ss.hasPermi('FastGptExtUserTag:FastGptExtUserTag:remove')")
+    @Log(title = "处理新客标签", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastgptExtUserTagService.deleteFastgptExtUserTagByIds(ids));
+    }
+}

+ 12 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwTagGroupController.java

@@ -38,4 +38,16 @@ public class QwTagGroupController extends BaseController
         List<QwTagGroupListVO> list = qwTagGroupService.selectQwTagGroupListVO(qwTagGroup);
         return getDataTable(list);
     }
+
+    /**
+     * 所有标签列表(无分页)
+     * @param qwTagGroup
+     * @return
+     */
+    @GetMapping("/getAllList")
+    public TableDataInfo getAllList(QwTagGroup qwTagGroup)
+    {
+        List<QwTagGroupListVO> list = qwTagGroupService.selectQwTagGroupListVO(qwTagGroup);
+        return getDataTable(list);
+    }
 }

+ 23 - 1
fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java

@@ -22,6 +22,7 @@ import com.fs.company.param.CompanyUserCodeParam;
 import com.fs.company.param.CompanyUserQwParam;
 import com.fs.company.service.*;
 import com.fs.company.utils.DomainUtil;
+import com.fs.company.vo.CompanyUserImportVO;
 import com.fs.company.vo.CompanyUserQwListVO;
 import com.fs.company.vo.CompanyUserVO;
 import com.fs.course.config.CourseConfig;
@@ -30,6 +31,7 @@ import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.service.TokenService;
 import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.his.vo.OptionsVO;
+import com.fs.hisStore.vo.FsStoreProductExportVO;
 import com.fs.im.service.OpenIMService;
 import com.fs.qw.domain.QwCompany;
 import com.fs.qw.service.IQwCompanyService;
@@ -139,7 +141,7 @@ public class CompanyUserController extends BaseController
         }
         return getDataTable(list);
     }
-    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
+    @Log(title = "用户管理导出", businessType = BusinessType.EXPORT)
     @PreAuthorize("@ss.hasPermi('company:user:export')")
     @GetMapping("/export")
     public AjaxResult export(CompanyUser user)
@@ -152,6 +154,26 @@ public class CompanyUserController extends BaseController
     }
 
 
+    @Log(title = "销售信息导入", businessType = BusinessType.IMPORT,isStoreLog = true,logParam = {"销售","信息导入"})
+    @PreAuthorize("@ss.hasPermi('company:user:import')")
+    @PostMapping("/importCompanyUser")
+    public AjaxResult importData(@RequestParam("file") MultipartFile file, boolean updateSupport) throws Exception
+    {
+        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
+        List<CompanyUserImportVO> list = util.importExcel(file.getInputStream());
+        String message = companyUserService.importCompanyUser(list, updateSupport);
+        return AjaxResult.success(message);
+    }
+
+
+    @GetMapping("/importTemplate")
+    public AjaxResult importTemplate()
+    {
+        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
+        return util.importTemplateExcel("销售数据");
+    }
+
+
 
     /**
      * 根据用户编号获取详细信息

+ 2 - 0
fs-service/src/main/java/com/fs/aiTongueApi/config/AiTongueConfig.java

@@ -5,4 +5,6 @@ public interface AiTongueConfig {
     String quanxiUrl="https://api.aikanshe.com/agency/quanxi";
     String checkTongue="https://api.aikanshe.com/agency/checkTongue";
     String appKey="";
+
+    String newCheckTongue="http://132.232.234.246:5056/api/detect";
 }

+ 58 - 0
fs-service/src/main/java/com/fs/aiTongueApi/domain/enums/TongueTypeEnums.java

@@ -0,0 +1,58 @@
+package com.fs.aiTongueApi.domain.enums;
+
+public enum TongueTypeEnums {
+
+    SheZhi_xianHong("SheZhi","01","主热证,可能是身体积热过多。舌尖红有芒刺表示心火上炎;"),
+    SheZhi_danBai("SheZhi","02","淡白舌而属于机体虚证、寒证之舌象。"),
+    SheZhi_danHong("SheZhi","03","为正常舌色或者疾病初期舌象。"),
+    SheZhi_zi("SheZhi","04","舌质带紫色,有可能是拍照原因。"),
+
+    TaiSe_huang("TaiSe","01","主里证、热证。舌苔灰黄而干燥,表示身体有内热,耗伤津液。"),
+    TaiSe_hui("TaiSe","02","主里证苔厚腻,为湿浊、痰饮。"),
+    TaiSe_bai("TaiSe","03","舌苔薄白为正常舌苔或表证初起。苔白而润滑,为里寒证;"),
+
+    Xing_boTuo("Xing","01","舌见剥落表示脏腑气阴不平衡。"),
+    Xing_chiHen("Xing","02","舌见齿痕表示脾虚或湿盛证。"),
+    Xing_lieWen("Xing","03","舌见裂纹提示脏腑阴血亏虚。"),
+
+    HouDu_hou("HouDu","01","厚"),
+    HouDu_bao("HouDu","02","薄");
+
+    private final String category;
+    private final String code;
+    private final String description;
+
+    TongueTypeEnums(String category, String code, String description) {
+        this.category = category;
+        this.code = code;
+        this.description = description;
+    }
+
+
+    public String getCategory() {
+        return category;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public static String fromCategoryAndCode(String category, String code) {
+        for (TongueTypeEnums type : TongueTypeEnums.values()) {
+            if (type.getCategory().equals(category) && type.getCode().equals(code)) {
+                return type.getDescription();
+            }
+        }
+        return null;
+    }
+
+
+
+
+}

+ 14 - 0
fs-service/src/main/java/com/fs/aiTongueApi/domain/inner/ConfidenceDataNew.java

@@ -0,0 +1,14 @@
+package com.fs.aiTongueApi.domain.inner;
+
+import lombok.Data;
+
+@Data
+public class ConfidenceDataNew {
+
+    private int sub; // 下标
+    private String label; // 类别
+    private String labelName; // 类别名称
+    private String val; // 置信度
+    private int[] xyxy; // 坐标 (没啥大用,凑凑数)
+
+}

+ 14 - 0
fs-service/src/main/java/com/fs/aiTongueApi/domain/inner/TongueInfo.java

@@ -0,0 +1,14 @@
+package com.fs.aiTongueApi.domain.inner;
+
+import lombok.Data;
+
+@Data
+public class TongueInfo {
+    private Long id;
+    private Integer botai;
+    private String houdu;
+    private String shemianName;
+    private String taiseName;
+    private String typeName;
+    private String typeJson;
+}

+ 3 - 0
fs-service/src/main/java/com/fs/aiTongueApi/service/AiTongueService.java

@@ -5,6 +5,7 @@ import com.fs.aiTongueApi.domain.QueryAiTongue;
 import com.fs.aiTongueApi.domain.QueryQuanXi;
 import com.fs.aiTongueApi.domain.inner.ConfidenceData;
 import com.fs.aiTongueApi.domain.inner.TongueData;
+import com.fs.his.domain.FsHealthTongue;
 
 public interface AiTongueService {
     AITongueResult<TongueData> getHistoryTongue(QueryAiTongue queryAiTongue);
@@ -12,4 +13,6 @@ public interface AiTongueService {
     AITongueResult<ConfidenceData> checkTongue(String url);
 
     AITongueResult<TongueData> quanXiTongue(QueryQuanXi queryQuanXi);
+
+    AITongueResult<FsHealthTongue> newCheckTongue(String tongueUrl);
 }

+ 187 - 2
fs-service/src/main/java/com/fs/aiTongueApi/service/impl/AiTongueServiceImpl.java

@@ -6,10 +6,13 @@ import com.fs.aiTongueApi.config.AiTongueConfig;
 import com.fs.aiTongueApi.domain.AITongueResult;
 import com.fs.aiTongueApi.domain.QueryAiTongue;
 import com.fs.aiTongueApi.domain.QueryQuanXi;
-import com.fs.aiTongueApi.domain.inner.ConfidenceData;
-import com.fs.aiTongueApi.domain.inner.TongueData;
+import com.fs.aiTongueApi.domain.enums.TongueTypeEnums;
+import com.fs.aiTongueApi.domain.inner.*;
 import com.fs.aiTongueApi.service.AiTongueService;
 import com.fs.common.utils.uuid.UUID;
+import com.fs.his.domain.FsHealthTongue;
+import com.fs.his.service.IFsHealthTongueService;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.hc.core5.net.URIBuilder;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -20,6 +23,8 @@ import org.apache.http.entity.StringEntity;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.io.InputStream;
@@ -27,9 +32,18 @@ import java.net.URI;
 import java.net.URL;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+@Slf4j
 @Service
 public class AiTongueServiceImpl implements AiTongueService {
 
+    @Autowired
+    private IFsHealthTongueService tongueService;
+
     @Override
     public AITongueResult<TongueData> getHistoryTongue(QueryAiTongue queryAiTongue) {
         queryAiTongue.setAppkey(AiTongueConfig.appKey);
@@ -108,6 +122,177 @@ public class AiTongueServiceImpl implements AiTongueService {
         return aiTongueResult;
     }
 
+    @Override
+    public AITongueResult<FsHealthTongue> newCheckTongue(String url) {
+        String s="";
+        try {
+            HttpClient httpClient = HttpClients.createDefault();
+            HttpPost httpPost = new HttpPost(AiTongueConfig.newCheckTongue);
+            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+            URL urlItem = new URL(url);
+            InputStream inputStream =urlItem.openStream();
+            // 添加文件或表单参数
+            builder.addBinaryBody("file", inputStream, ContentType.DEFAULT_BINARY, "图片.jpg");
+
+            HttpEntity multipart = builder.build();
+            httpPost.setEntity(multipart);
+            // 执行请求
+            HttpResponse response = httpClient.execute(httpPost);
+            String responseBody = EntityUtils.toString(response.getEntity());
+            log.info(responseBody);
+            s=responseBody;
+
+            AITongueResult<List<List<ConfidenceDataNew>>> aiTongueResult = JSON.parseObject(s, new TypeReference<AITongueResult<List<List<ConfidenceDataNew>>>>(){});
+            List<List<ConfidenceDataNew>> data = aiTongueResult.getData();
+            FsHealthTongue healthTongue = new FsHealthTongue();
+            if (data != null && !data.isEmpty()){
+                String boTaiDesc =  "舌未见剥落提示脏腑气充足,胃阴正常,气阴平衡。";
+                String chiHenDesc = "舌未见齿痕表示脾气正常。";
+                String lieWenDesc = "舌未见裂纹表示脏腑津液正常。";
+                String houDu;
+                TongueInfo tongueInfo = new TongueInfo();
+                for (int i = 0; i < 4; i++) {
+                    List<ConfidenceDataNew> confidenceDataNews = data.get(i);
+                    if (confidenceDataNews != null && !confidenceDataNews.isEmpty()){
+                        Optional<ConfidenceDataNew> oldestPerson = confidenceDataNews.stream()
+                                .max(Comparator.comparingDouble(p -> Double.parseDouble(p.getVal())));
+                        ConfidenceDataNew confidenceDataNew = oldestPerson.get();
+
+                        healthTongue.setTongueUrl(url);
+                        if(i == 0){
+                            switch (confidenceDataNew.getLabel()){
+                                case "01":
+                                    healthTongue.setShemianName("鲜红舌");
+                                    break;
+                                case "02":
+                                    healthTongue.setShemianName("淡白舌");
+                                    break;
+                                case "03":
+                                    healthTongue.setShemianName("淡红舌");
+                                    break;
+                                case "04":
+                                    healthTongue.setShemianName("紫舌");
+                                    break;
+                            }
+                            String sheZhi = TongueTypeEnums.fromCategoryAndCode("SheZhi", confidenceDataNew.getLabel());
+                            healthTongue.setShemianDesc(sheZhi);
+                            //设置舌质
+                            tongueInfo.setShemianName(healthTongue.getShemianName());
+                        }
+                        if(i == 1){
+                            switch (confidenceDataNew.getLabel()){
+                                case "01":
+                                    healthTongue.setTaiseName("黄苔");
+                                    break;
+                                case "02":
+                                    healthTongue.setTaiseName("灰苔");
+                                    break;
+                                case "03":
+                                    healthTongue.setTaiseName("白苔");
+                                    break;
+                            }
+                            String taiSe = TongueTypeEnums.fromCategoryAndCode("TaiSe", confidenceDataNew.getLabel());
+                            healthTongue.setTaiseDesc(taiSe);
+                            //设置苔色
+                            tongueInfo.setTaiseName(healthTongue.getTaiseName());
+                        }
+                        if(i == 2){
+                            switch (confidenceDataNew.getLabel()){
+                                case "01":
+                                    healthTongue.setBotai(1L);
+                                    String boTai = TongueTypeEnums.fromCategoryAndCode("Xing", "01");
+                                    healthTongue.setBotaiDesc(boTai);
+                                    //设置是否剥脱 0正常 1剥脱
+                                    tongueInfo.setBotai(1);
+
+                                    healthTongue.setChihen(0L);
+                                    healthTongue.setChihenDesc(chiHenDesc);
+                                    healthTongue.setLiewen(0);
+                                    healthTongue.setLiewenDesc(lieWenDesc);
+                                    break;
+                                case "02":
+                                    healthTongue.setBotai(0L);
+                                    healthTongue.setBotaiDesc(boTaiDesc);
+                                    //设置是否剥脱 0正常 1剥脱
+                                    tongueInfo.setBotai(0);
+
+                                    healthTongue.setChihen(1L);
+                                    String chiHen = TongueTypeEnums.fromCategoryAndCode("Xing", "02");
+                                    healthTongue.setChihenDesc(chiHen);
+                                    healthTongue.setLiewen(0);
+                                    healthTongue.setLiewenDesc(lieWenDesc);
+                                    break;
+                                case "03":
+                                    healthTongue.setBotai(0L);
+                                    healthTongue.setBotaiDesc(boTaiDesc);
+                                    //设置是否剥脱 0正常 1剥脱
+                                    tongueInfo.setBotai(0);
+
+                                    healthTongue.setChihen(0L);
+                                    healthTongue.setChihenDesc(chiHenDesc);
+                                    healthTongue.setLiewen(1);
+                                    String lieWen = TongueTypeEnums.fromCategoryAndCode("Xing", "03");
+                                    healthTongue.setLiewenDesc(lieWen);
+                                    break;
+                            }
+                        }
+                        if(i == 3){
+                            switch (confidenceDataNew.getLabel()){
+                                case "01":
+                                    //厚
+                                    houDu = TongueTypeEnums.fromCategoryAndCode("HouDu", "01");
+                                    break;
+                                default:
+                                    //薄
+                                    houDu = TongueTypeEnums.fromCategoryAndCode("HouDu", "02");
+                                    break;
+                            }
+                            //设置厚度
+                            tongueInfo.setHoudu(houDu);
+                        }
+
+                    }else{
+                        //形状相关的为空就将这几个值置为0(表示正常)
+                        if(i == 2){
+                            healthTongue.setBotai(0L);
+                            healthTongue.setBotaiDesc(boTaiDesc);
+                            //设置是否剥脱 0正常 1剥脱
+                            tongueInfo.setBotai(0);
+
+                            healthTongue.setChihen(0L);
+                            healthTongue.setChihenDesc(chiHenDesc);
+                            healthTongue.setLiewen(0);
+                            healthTongue.setLiewenDesc(lieWenDesc);
+                        }
+                    }
+                }
+
+                TongueInfo fastTongueInfo = tongueService.selectFsTongueInfo(tongueInfo);
+                if(fastTongueInfo != null && fastTongueInfo.getTypeName() != null){
+                    healthTongue.setTypeName(fastTongueInfo.getTypeName());
+                    healthTongue.setTypeJson(fastTongueInfo.getTypeJson());
+                    return getAiTongueResult(healthTongue,"40001","ok");
+                }
+                return getAiTongueResult(healthTongue,"40003","未检测到舌头,请按照要求查询拍照检测");
+            }
+            return getAiTongueResult(healthTongue,"40003","未能从服务器获取结果,请稍后再试");
+        } catch (Exception e) {
+            return getAiTongueResult(null,"40003","请求频繁,请稍后再试");
+        }
+    }
+
+    private static @NotNull AITongueResult<FsHealthTongue> getAiTongueResult(FsHealthTongue healthTongue, String code, String msg) {
+        AITongueResult<FsHealthTongue> result = new AITongueResult<>();
+        result.setData(healthTongue);
+        result.setCode(code);
+        meta meta = new meta();
+        meta.setCode(code);
+        meta.setMsg(msg);
+        meta.setTimestamp(String.valueOf(new Date()));
+        result.setMeta(meta);
+        return result;
+    }
+
 
     public  String sendPost(String url,Object param){
         HttpClient httpClient = HttpClients.createDefault();

+ 2 - 2
fs-service/src/main/java/com/fs/company/domain/CompanyUser.java

@@ -35,8 +35,8 @@ public class CompanyUser extends BaseEntity
 
     private String corpId;
 
-    /** 部门ID */
-    @Excel(name = "部门ID")
+    /** 部门编号 */
+    @Excel(name = "部门编号")
     private Long deptId;
 
     /** 用户账号 */

+ 1 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyRoleMapper.java

@@ -84,4 +84,5 @@ public interface CompanyRoleMapper
      * @return 角色信息
      * **/
     CompanyRole selectCompanyRoleByRoleKey(@Param("roleKey") String roleKey);
+    Long selectRolesByUserNameAndCompanyId(@Param("roleName") String roleName,@Param("companyId") Long companyId);
 }

+ 4 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -8,6 +8,7 @@ import com.fs.company.param.CompanyUserQwParam;
 import com.fs.company.vo.*;
 import com.fs.his.vo.CitysAreaVO;
 import com.fs.his.vo.OptionsVO;
+import com.fs.hisStore.vo.FsStoreProductExportVO;
 import com.fs.qw.dto.UserProjectDTO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwOptionsVO;
@@ -53,6 +54,9 @@ public interface ICompanyUserService {
      */
     public int insertCompanyUser(CompanyUser companyUser);
 
+    String importCompanyUser(List<CompanyUserImportVO> list, boolean updateSupport);
+
+
     /**
      * 修改物业公司管理员信息
      *

+ 166 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -1,9 +1,12 @@
 package com.fs.company.service.impl;
 
+import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
+import com.fs.common.BeanCopyUtils;
 import com.fs.common.annotation.DataScope;
 import com.fs.common.constant.UserConstants;
+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;
@@ -23,6 +26,11 @@ import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.service.IFsCityService;
 import com.fs.his.vo.CitysAreaVO;
 import com.fs.his.vo.OptionsVO;
+import com.fs.hisStore.domain.FsStoreProductAttrScrm;
+import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.dto.ProductArrtDTO;
+import com.fs.hisStore.vo.FsStoreProductExportVO;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.dto.UserProjectDTO;
 import com.fs.qw.mapper.QwUserMapper;
@@ -43,6 +51,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -152,6 +161,163 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.insertCompanyUser(companyUser);
     }
 
+    @Override
+    public String importCompanyUser(List<CompanyUserImportVO> list, boolean updateSupport) {
+
+        if (com.fs.common.utils.StringUtils.isNull(list) || list.size() == 0)
+        {
+            throw new CustomException("导入销售信息不能为空!");
+        }
+        int successNum = 0;
+        int failureNum = 0;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder failureMsg = new StringBuilder();
+        for (CompanyUserImportVO importVO : list){
+            try
+            {
+                CompanyUser copy = BeanCopyUtils.copy(importVO, CompanyUser.class);
+
+                assert copy != null;
+
+                if (StringUtil.strIsNullOrEmpty(copy.getPassword())){
+                    throw new CustomException("密码不能为空");
+                }
+
+
+                if (!PatternUtils.checkPassword(copy.getPassword())) {
+                    throw new CustomException("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
+                }
+
+                if (copy.getCompanyId() == null){
+                    throw new CustomException("公司ID不能为空,且为数字!");
+                } else if (!String.valueOf(copy.getCompanyId()).matches("\\d+")) {
+                    throw new CustomException("公司ID必须为数字!");
+                }
+
+                if (copy.getDeptId() == null){
+                    throw new CustomException("部门编号不能为空,且为数字!");
+                } else if (!String.valueOf(copy.getDeptId()).matches("\\d+")) {
+                    throw new CustomException("部门编号必须为数字!");
+                }
+
+                if (StringUtil.strIsNullOrEmpty(copy.getPhonenumber())){
+                    throw new CustomException("手机号不能为空");
+                } else if (!copy.getPhonenumber().matches("\\d+")) {
+                    throw new CustomException("手机号必须为数字!");
+                }
+
+                if (StringUtil.strIsNullOrEmpty(copy.getAddressId())){
+                    throw new CustomException("区域不能为空");
+                } else if (!copy.getAddressId().matches("\\d+")) {
+                    throw new CustomException("区域ID必须为数字!");
+                }
+
+                Integer count=companyUserService.selectCompanyUserCountByCompanyId(copy.getCompanyId());
+                Company company=companyService.selectCompanyById(copy.getCompanyId());
+
+                if(count>company.getLimitUserCount()){
+                    throw new CustomException("销售公司的销售数量已达到上限!");
+                }
+
+                if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(copy.getUserName()))))
+                {
+                    throw new CustomException("新增用户'" + copy.getUserName() + "'失败,登录账号已存在");
+                }
+
+                if (StringUtil.strIsNullOrEmpty(copy.getNickName())){
+                    throw new CustomException("用户昵称不能为空");
+                }
+
+                if (StringUtil.strIsNullOrEmpty(importVO.getRoleString())){
+                    throw new CustomException("角色-不能为空");
+                }
+
+                try {
+                    String[] splitRoles = splitRoles(importVO.getRoleString());
+
+                    // 新增用户与岗位管理
+                    Set<Long> setList= new HashSet<>();
+
+                    for (String stringRole : splitRoles) {
+                        Long rolesId = roleMapper.selectRolesByUserNameAndCompanyId(stringRole, copy.getCompanyId());
+
+                        if (StringUtils.isNotNull(rolesId)) {
+                            setList.add(rolesId);
+                        }else {
+                            throw new CustomException("当前销售公司没有此角色");
+                        }
+                    }
+
+                    // 转换为 Long[]
+                    Long[] roleIds = setList.toArray(new Long[0]);
+                    copy.setRoleIds(roleIds);
+
+
+                }catch (Exception e){
+                    throw new CustomException("角色-格式不正确");
+                }
+
+
+
+                copy.setUserType("01");//一般用户
+                copy.setIsAudit(1);
+                copy.setPassword(SecurityUtils.encryptPassword(copy.getPassword()));
+                copy.setCreateTime(new Date());
+                copy.setStatus("0");
+
+                int rows = companyUserMapper.insertCompanyUser(copy);
+                if (rows>0){
+                    // 新增用户与角色管理
+                    insertUserRole(copy);
+                }else {
+                    throw new CustomException("新增用户'" + copy.getUserName() + "'失败");
+                }
+
+
+                successNum++;
+                successMsg.append("<br/>" + successNum + "、销售账号 " + copy.getUserName() + " 导入成功");
+            }
+            catch (Exception e)
+            {
+
+                failureNum++;
+                String msg = "<br/>" + failureNum + "、销售账号 " + importVO.getUserName()  + " 导入失败:";
+                failureMsg.append(msg + e.getMessage());
+            }
+
+        }
+        if (failureNum > 0)
+        {
+            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+            throw new CustomException(failureMsg.toString());
+        }
+        else
+        {
+            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+        }
+        return successMsg.toString();
+    }
+
+
+    public String[] splitRoles(String roleString) {
+        if (roleString == null || roleString.trim().isEmpty()) {
+            return new String[0];
+        }
+
+        // 预处理:替换中文标点,去除首尾空格
+        String processed = roleString
+                .replace(",", ",")
+                .replace(";", ";")
+                .replace("、", ",")
+                .trim();
+
+        // 分割并过滤空值
+        return Arrays.stream(processed.split("[,;\\s]+"))
+                .filter(s -> !s.isEmpty())
+                .map(String::trim)
+                .toArray(String[]::new);
+    }
+
     /**
      * 修改物业公司管理员信息
      *

+ 17 - 350
fs-service/src/main/java/com/fs/company/vo/CompanyUserImportVO.java

@@ -5,32 +5,24 @@ import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
 import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyRole;
+import lombok.Data;
 
 import java.util.Date;
 import java.util.List;
 
+@Data
 public class CompanyUserImportVO extends BaseEntity {
     private static final long serialVersionUID = 1L;
 
     /** 用户ID */
     private Long userId;
 
-    /** 公司ID */
-    @Excel(name = "公司ID")
+    /** 公司编号 */
+    @Excel(name = "公司编号")
     private Long companyId;
 
-    public String getCorpId() {
-        return corpId;
-    }
-
-    public void setCorpId(String corpId) {
-        this.corpId = corpId;
-    }
-
-    private String corpId;
-
-    /** 部门ID */
-    @Excel(name = "部门ID")
+    /** 部门编号 */
+    @Excel(name = "部门编号")
     private Long deptId;
 
     /** 用户账号 */
@@ -41,8 +33,7 @@ public class CompanyUserImportVO extends BaseEntity {
     @Excel(name = "用户昵称")
     private String nickName;
 
-    /** 用户类型(00系统用户) */
-    @Excel(name = "用户类型", readConverterExp = "0=0系统用户")
+    /** 用户类型(00管理员 01员工 ) */
     private String userType;
 
     /** 用户邮箱 */
@@ -54,13 +45,9 @@ public class CompanyUserImportVO extends BaseEntity {
     private String phonenumber;
 
     /** 用户性别(0男 1女 2未知) */
-    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
+    @Excel(name = "用户性别(0男 1女 2未知)", readConverterExp = "0=男,1=女,2=未知")
     private String sex;
 
-    /** 头像地址 */
-    @Excel(name = "头像地址")
-    private String avatar;
-
     /** 身份证号 */
     @Excel(name = "身份证号")
     private String idCard;
@@ -69,23 +56,24 @@ public class CompanyUserImportVO extends BaseEntity {
     @Excel(name = "密码")
     private String password;
 
+    /** 角色字符串 */
+    @Excel(name = "角色(多角色用逗号分割)")
+    private String roleString;
+
     /** 帐号状态(0正常 1停用) */
-    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
     private String status;
 
+    private String corpId;
+
     /** 删除标志(0代表存在 2代表删除) */
     private String delFlag;
 
+    /** 头像地址 */
+    private String avatar;
+
     private String qwUserId;
     private Integer qwStatus;
 
-    public String getIdCard() {
-        return idCard;
-    }
-
-    public void setIdCard(String idCard) {
-        this.idCard = idCard;
-    }
 
     /** 最后登录IP */
     private String loginIp;
@@ -111,9 +99,6 @@ public class CompanyUserImportVO extends BaseEntity {
     /** 角色组 */
     private Long[] roleIds;
 
-    /** 角色字符串 */
-    @Excel(name = "角色(多角色用逗号分割)")
-    private String roleString;
 
     /** 岗位组 */
     private Long[] postIds;
@@ -137,322 +122,4 @@ public class CompanyUserImportVO extends BaseEntity {
     /** 看课域名 */
     private String domain;
 
-    public String getDomain() {
-        return domain;
-    }
-
-    public void setDomain(String domain) {
-        this.domain = domain;
-    }
-
-    public String getAddressId() {
-        return addressId;
-    }
-
-    public void setAddressId(String addressId) {
-        this.addressId = addressId;
-    }
-
-    public String getVoicePrintUrl() {
-        return voicePrintUrl;
-    }
-
-    public void setVoicePrintUrl(String voicePrintUrl) {
-        this.voicePrintUrl = voicePrintUrl;
-    }
-
-    public String getCallerNo() {
-        return callerNo;
-    }
-
-    public void setCallerNo(String callerNo) {
-        this.callerNo = callerNo;
-    }
-
-    public String getJpushId() {
-        return jpushId;
-    }
-
-    public String getQwUserId() {
-        return qwUserId;
-    }
-
-    public void setQwUserId(String qwUserId) {
-        this.qwUserId = qwUserId;
-    }
-
-    public Integer getQwStatus() {
-        return qwStatus;
-    }
-
-    public void setQwStatus(Integer qwStatus) {
-        this.qwStatus = qwStatus;
-    }
-
-    public void setJpushId(String jpushId) {
-        this.jpushId = jpushId;
-    }
-
-    public String getQrCodeWeixin() {
-        return qrCodeWeixin;
-    }
-
-    public void setQrCodeWeixin(String qrCodeWeixin) {
-        this.qrCodeWeixin = qrCodeWeixin;
-    }
-
-    public String getQrCodeWecom() {
-        return qrCodeWecom;
-    }
-
-    public void setQrCodeWecom(String qrCodeWecom) {
-        this.qrCodeWecom = qrCodeWecom;
-    }
-
-    public String getOpenId() {
-        return openId;
-    }
-
-    public void setOpenId(String openId) {
-        this.openId = openId;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    public String getNickName() {
-        return nickName;
-    }
-
-
-    public void setNickName(String nickName) {
-        this.nickName = nickName;
-    }
-
-    public String getFirstchar() {
-        return firstchar;
-    }
-
-    public void setFirstchar(String firstchar) {
-        this.firstchar = firstchar;
-    }
-
-    public String getPostName() {
-        return postName;
-    }
-
-    public void setPostName(String postName) {
-        this.postName = postName;
-    }
-
-    public String getDeptName() {
-        return deptName;
-    }
-
-    public void setDeptName(String deptName) {
-        this.deptName = deptName;
-    }
-
-    public CompanyDept getDept() {
-        return dept;
-    }
-
-    public void setDept(CompanyDept dept) {
-        this.dept = dept;
-    }
-
-    public static long getSerialVersionUID() {
-        return serialVersionUID;
-    }
-
-    public boolean isAdmin()
-    {
-        return isAdmin(this.userType);
-    }
-
-    public static boolean isAdmin(String userType)
-    {
-        if(userType!=null&&(userType.equals("00") || userType.equals("02"))){
-            return true;
-        }
-        else return false;
-    }
-
-    public List<CompanyRole> getRoles() {
-        return roles;
-    }
-
-    public void setRoles(List<CompanyRole> roles) {
-        this.roles = roles;
-    }
-
-    public String getRoleString() {
-        return roleString;
-    }
-
-    public void setRoleString(String roleString) {
-        this.roleString = roleString;
-    }
-
-    public Long[] getRoleIds() {
-        return roleIds;
-    }
-
-    public void setRoleIds(Long[] roleIds) {
-        this.roleIds = roleIds;
-    }
-
-    public Long[] getPostIds() {
-        return postIds;
-    }
-
-    public void setPostIds(Long[] postIds) {
-        this.postIds = postIds;
-    }
-
-
-    public void setUserId(Long userId)
-    {
-        this.userId = userId;
-    }
-
-    public Long getUserId()
-    {
-        return userId;
-    }
-    public void setCompanyId(Long companyId)
-    {
-        this.companyId = companyId;
-    }
-
-    public Long getCompanyId()
-    {
-        return companyId;
-    }
-    public void setDeptId(Long deptId)
-    {
-        this.deptId = deptId;
-    }
-
-    public Long getDeptId()
-    {
-        return deptId;
-    }
-
-    public void setUserType(String userType)
-    {
-        this.userType = userType;
-    }
-
-    public String getUserType()
-    {
-        return userType;
-    }
-    public void setEmail(String email)
-    {
-        this.email = email;
-    }
-
-    public String getEmail()
-    {
-        return email;
-    }
-    public void setPhonenumber(String phonenumber)
-    {
-        this.phonenumber = phonenumber;
-    }
-
-    public String getPhonenumber()
-    {
-        return phonenumber;
-    }
-    public void setSex(String sex)
-    {
-        this.sex = sex;
-    }
-
-    public String getSex()
-    {
-        return sex;
-    }
-    public void setAvatar(String avatar)
-    {
-        this.avatar = avatar;
-    }
-
-    public String getAvatar()
-    {
-        return avatar;
-    }
-
-    public void setPassword(String password)
-    {
-        this.password = password;
-    }
-
-    public String getPassword()
-    {
-        return password;
-    }
-    public void setStatus(String status)
-    {
-        this.status = status;
-    }
-
-    public String getStatus()
-    {
-        return status;
-    }
-    public void setDelFlag(String delFlag)
-    {
-        this.delFlag = delFlag;
-    }
-
-    public String getDelFlag()
-    {
-        return delFlag;
-    }
-    public void setLoginIp(String loginIp)
-    {
-        this.loginIp = loginIp;
-    }
-
-    public String getLoginIp()
-    {
-        return loginIp;
-    }
-    public void setLoginDate(Date loginDate)
-    {
-        this.loginDate = loginDate;
-    }
-
-    public Date getLoginDate()
-    {
-        return loginDate;
-    }
-
-
-    public void setToken(String token)
-    {
-        this.token = token;
-    }
-
-    public String getToken()
-    {
-        return token;
-    }
-    public void setIsDel(Integer isDel)
-    {
-        this.isDel = isDel;
-    }
-
-    public Integer getIsDel()
-    {
-        return isDel;
-    }
 }

+ 2 - 0
fs-service/src/main/java/com/fs/company/vo/CompanyVO.java

@@ -79,6 +79,8 @@ public class CompanyVO implements Serializable
 
     private Integer limitUserCount;
 
+    private Integer maxPadNum;
+
     private Integer voiceCallerNumber;
     @Excel(name = "商务负责人")
     private String manager;

+ 1 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoRedPackageMapper.java

@@ -66,6 +66,7 @@ public interface FsUserCourseVideoRedPackageMapper
      * @return 结果
      */
     public int deleteFsUserCourseVideoRedPackageByIds(Long[] ids);
+    public int deleteFsUserCourseVideoRedPackageByVedioIds(Long[] ids);
     @Update("INSERT INTO fs_user_course_video_red_package (company_id, video_id, red_packet_money) " +
             "VALUES (#{companyId}, #{videoId}, #{redPacketMoney}) " +
             "ON DUPLICATE KEY UPDATE red_packet_money = VALUES(red_packet_money);")

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

@@ -133,7 +133,7 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
         if(!periodDayIds.isEmpty()){
             flag = fsUserCoursePeriodDaysMapper.updateBatchDelFlag(periodDayIds.toArray(new Long[0]),1);
             //删除红包记录
-            fsUserCourseVideoRedPackageMapper.updateBatchDelFlag(videoIds.toArray(new Long[0]),1);
+            fsUserCourseVideoRedPackageMapper.deleteFsUserCourseVideoRedPackageByVedioIds(videoIds.toArray(new Long[0]));
         }
         return flag;
     }

+ 3 - 0
fs-service/src/main/java/com/fs/course/vo/newfs/FsUserCourseVideoPageListVO.java

@@ -58,6 +58,9 @@ public class FsUserCourseVideoPageListVO extends BaseEntity {
     @ApiModelProperty(value = "营期id")
     private Long periodId;
 
+    @ApiModelProperty(value = "营期名称")
+    private String periodName;
+
     @ApiModelProperty(value = "营期课程ID")
     private Long id;
 

+ 31 - 0
fs-service/src/main/java/com/fs/fastGpt/domain/FastgptExtUserTag.java

@@ -0,0 +1,31 @@
+package com.fs.fastGpt.domain;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 处理新客标签对象 fastgpt_ext_user_tag
+ *
+ * @author fs
+ * @date 2025-09-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FastgptExtUserTag extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 标签id */
+    @Excel(name = "标签id")
+    private String tagId;
+
+    /** 企业id */
+    @Excel(name = "企业id")
+    private String corpId;
+
+
+
+}

+ 67 - 0
fs-service/src/main/java/com/fs/fastGpt/mapper/FastgptExtUserTagMapper.java

@@ -0,0 +1,67 @@
+package com.fs.fastGpt.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.fastGpt.domain.FastgptExtUserTag;
+import com.fs.fastGpt.vo.FastgptExtUserTagVO;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 处理新客标签Mapper接口
+ * 
+ * @author fs
+ * @date 2025-09-10
+ */
+public interface FastgptExtUserTagMapper extends BaseMapper<FastgptExtUserTag>{
+    /**
+     * 查询处理新客标签
+     * 
+     * @param id 处理新客标签主键
+     * @return 处理新客标签
+     */
+    FastgptExtUserTag selectFastgptExtUserTagById(Long id);
+
+    /**
+     * 查询处理新客标签列表
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 处理新客标签集合
+     */
+    List<FastgptExtUserTag> selectFastgptExtUserTagList(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 新增处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    int insertFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 修改处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    int updateFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 删除处理新客标签
+     * 
+     * @param id 处理新客标签主键
+     * @return 结果
+     */
+    int deleteFastgptExtUserTagById(Long id);
+
+    /**
+     * 批量删除处理新客标签
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFastgptExtUserTagByIds(Long[] ids);
+
+    int addFastGptTagByCorpId(@Param("data") FastgptExtUserTagVO fastgptExtUserTag);
+
+    List<FastgptExtUserTag> selectFastgptExtUserTagByIds(@Param("ids") Long[] ids);
+}

+ 66 - 0
fs-service/src/main/java/com/fs/fastGpt/service/IFastgptExtUserTagService.java

@@ -0,0 +1,66 @@
+package com.fs.fastGpt.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
+import com.fs.fastGpt.domain.FastgptExtUserTag;
+import com.fs.fastGpt.vo.FastgptExtUserTagVO;
+
+/**
+ * 处理新客标签Service接口
+ * 
+ * @author fs
+ * @date 2025-09-10
+ */
+public interface IFastgptExtUserTagService extends IService<FastgptExtUserTag>{
+    /**
+     * 查询处理新客标签
+     * 
+     * @param id 处理新客标签主键
+     * @return 处理新客标签
+     */
+    FastgptExtUserTag selectFastgptExtUserTagById(Long id);
+
+    /**
+     * 查询处理新客标签列表
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 处理新客标签集合
+     */
+    List<FastgptExtUserTag> selectFastgptExtUserTagList(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 新增处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    int insertFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 修改处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    int updateFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag);
+
+    /**
+     * 批量删除处理新客标签
+     * 
+     * @param ids 需要删除的处理新客标签主键集合
+     * @return 结果
+     */
+    int deleteFastgptExtUserTagByIds(Long[] ids);
+
+    /**
+     * 删除处理新客标签信息
+     * 
+     * @param id 处理新客标签主键
+     * @return 结果
+     */
+    int deleteFastgptExtUserTagById(Long id);
+
+    R addFastGptTagByCorpId(FastgptExtUserTagVO fastgptExtUserTag);
+
+}

+ 58 - 2
fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.fastGpt.service.impl;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.fs.common.annotation.Excel;
 import com.fs.common.config.FSConfig;
 import com.fs.common.core.domain.R;
@@ -161,6 +162,10 @@ public class AiHookServiceImpl implements AiHookService {
     @Autowired
     private IFastGptChatReplaceTextService fastGptChatReplaceTextService;
 
+    private static final String AI_REPLY = "AI_REPLY:";
+    private static final String AI_REPLY_TAG = "AI_REPLY_TAG:";
+
+
     /** Ai半小时未回复提醒 **/
     /**
      *
@@ -376,7 +381,7 @@ public class AiHookServiceImpl implements AiHookService {
         }
         if(user.getFastGptRoleId()==null){
             log.error("未绑定角色");
-            return R.ok();
+            return userIsReply(sender, uid, user);
         }
         Long serverId = user.getServerId();
         log.info("服务器id"+serverId);
@@ -388,7 +393,7 @@ public class AiHookServiceImpl implements AiHookService {
         //没用ai角色跳过
         if(role==null){
             log.error("没用ai角色跳过");
-            return R.ok();
+            return userIsReply(sender, uid, user);
         }
         String modeConfig=role.getModeConfigJson();
         //key不为空
@@ -598,6 +603,57 @@ public class AiHookServiceImpl implements AiHookService {
         return R.ok();
     }
 
+    /**
+     * 根据发送者id设置用户是否为首次回复
+     * @param sender 发送者id
+     * @param uid   企微用户的uuid
+     * @param user  企微用户信息
+     * @return
+     */
+    private @Nullable R userIsReply(Long sender, String uid, QwUser user) {
+        Long qwExternalContactId = redisCache.getCacheObject(AI_REPLY + sender);
+        if(qwExternalContactId == null){
+            WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
+            wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(sender));
+            wxWorkVid2UserIdDTO.setUuid(uid);
+            WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO, user.getServerId());
+            List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
+            if (data==null|| data.isEmpty()){
+                log.error("未获取到extId"+wxWorkVid2UserIdDTO);
+                return R.ok();
+            }
+            com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
+
+            QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(), user.getQwUserId());
+            if (qwExternalContacts==null){
+                log.error("没有外部联系人" + "user:" + user);
+                return R.ok();
+            }
+            List<String> oldCache = redisCache.getCacheObject(AI_REPLY_TAG + user.getCorpId());
+            if(oldCache != null && !oldCache.isEmpty()){
+                QwExternalContact qwExternalContact = new QwExternalContact();
+                if(qwExternalContacts.getTagIds() != null && !qwExternalContacts.getTagIds().isEmpty() && !"[]".equals(qwExternalContacts.getTagIds())){
+                    List<String> parsedTags = JSON.parseArray(qwExternalContacts.getTagIds(), String.class);
+                    if (parsedTags != null && !parsedTags.isEmpty()) {
+                        for (String parsedTag : oldCache) {
+                            if (!oldCache.contains(parsedTag)) {
+                                oldCache.add(parsedTag);
+                            }
+                        }
+                    }
+                    qwExternalContact.setTagIds(JSON.toJSONString(oldCache));
+                }else if("[]".equals(qwExternalContacts.getTagIds()) || qwExternalContacts.getTagIds() == null){
+                    qwExternalContact.setTagIds(JSON.toJSONString(oldCache));
+                }
+                qwExternalContact.setId(qwExternalContacts.getId());
+                qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
+            }
+            qwExternalContactMapper.updateQwExternalContactIsRePlyById(qwExternalContacts.getId());
+            redisCache.setCacheObject(AI_REPLY + sender,qwExternalContacts.getId());
+        }
+        return R.ok();
+    }
+
     /**
      * 通过用户发送的对话去查询用户是否为新客,是就删除sop,否就不做处理
      * @param user

+ 145 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastgptExtUserTagServiceImpl.java

@@ -0,0 +1,145 @@
+package com.fs.fastGpt.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.DateUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.fastGpt.vo.FastgptExtUserTagVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fs.fastGpt.mapper.FastgptExtUserTagMapper;
+import com.fs.fastGpt.domain.FastgptExtUserTag;
+import com.fs.fastGpt.service.IFastgptExtUserTagService;
+
+/**
+ * 处理新客标签Service业务层处理
+ * 
+ * @author fs
+ * @date 2025-09-10
+ */
+@Service
+public class FastgptExtUserTagServiceImpl extends ServiceImpl<FastgptExtUserTagMapper, FastgptExtUserTag> implements IFastgptExtUserTagService {
+
+    @Autowired
+    private FastgptExtUserTagMapper fastgptExtUserTagMapper;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    private static final String AI_REPLY_TAG = "AI_REPLY_TAG:";
+
+    /**
+     * 查询处理新客标签
+     * 
+     * @param id 处理新客标签主键
+     * @return 处理新客标签
+     */
+    @Override
+    public FastgptExtUserTag selectFastgptExtUserTagById(Long id)
+    {
+        return baseMapper.selectFastgptExtUserTagById(id);
+    }
+
+    /**
+     * 查询处理新客标签列表
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 处理新客标签
+     */
+    @Override
+    public List<FastgptExtUserTag> selectFastgptExtUserTagList(FastgptExtUserTag fastgptExtUserTag)
+    {
+        return baseMapper.selectFastgptExtUserTagList(fastgptExtUserTag);
+    }
+
+    /**
+     * 新增处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    @Override
+    public int insertFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag)
+    {
+        fastgptExtUserTag.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFastgptExtUserTag(fastgptExtUserTag);
+    }
+
+    /**
+     * 修改处理新客标签
+     * 
+     * @param fastgptExtUserTag 处理新客标签
+     * @return 结果
+     */
+    @Override
+    public int updateFastgptExtUserTag(FastgptExtUserTag fastgptExtUserTag)
+    {
+        return baseMapper.updateFastgptExtUserTag(fastgptExtUserTag);
+    }
+
+    /**
+     * 批量删除处理新客标签
+     * 
+     * @param ids 需要删除的处理新客标签主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastgptExtUserTagByIds(Long[] ids)
+    {
+        List<FastgptExtUserTag> fastgptExtUserTags = fastgptExtUserTagMapper.selectFastgptExtUserTagByIds(ids);
+        int i = baseMapper.deleteFastgptExtUserTagByIds(ids);
+        if(i > 0){
+            if(fastgptExtUserTags != null && !fastgptExtUserTags.isEmpty()){
+                String corpId = fastgptExtUserTags.get(0).getCorpId();
+                List<String> oldCache = redisCache.getCacheObject(AI_REPLY_TAG + corpId);
+                for (FastgptExtUserTag fastgptExtUserTag : fastgptExtUserTags) {
+                    if(fastgptExtUserTag != null && fastgptExtUserTag.getTagId() != null){
+                        if(oldCache != null && !oldCache.isEmpty()){
+                            oldCache.remove(fastgptExtUserTag.getTagId());
+                        }
+                    }
+                }
+                redisCache.setCacheObject(AI_REPLY_TAG + corpId,oldCache);
+            }
+        }
+        return i;
+    }
+
+    /**
+     * 删除处理新客标签信息
+     * 
+     * @param id 处理新客标签主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastgptExtUserTagById(Long id)
+    {
+        return baseMapper.deleteFastgptExtUserTagById(id);
+    }
+
+    @Override
+    public R addFastGptTagByCorpId(FastgptExtUserTagVO fastgptExtUserTag) {
+        int i = 0;
+        try {
+            i = fastgptExtUserTagMapper.addFastGptTagByCorpId(fastgptExtUserTag);
+        } catch (Exception e) {
+            return R.error("添加失败,存在重复的标签");
+        }
+        if(i > 0){
+            if(fastgptExtUserTag != null && fastgptExtUserTag.getTagIds() != null){
+                List<String> oldCache = redisCache.getCacheObject(AI_REPLY_TAG + fastgptExtUserTag.getCorpId());
+                if(oldCache != null && !oldCache.isEmpty()){
+                    oldCache.addAll(fastgptExtUserTag.getTagIds());
+                    redisCache.setCacheObject(AI_REPLY_TAG + fastgptExtUserTag.getCorpId(),oldCache);
+                }else{
+                    List<String> newCacheTagList = new ArrayList<>(fastgptExtUserTag.getTagIds());
+                    redisCache.setCacheObject(AI_REPLY_TAG + fastgptExtUserTag.getCorpId(),newCacheTagList);
+                }
+            }
+        }
+        return R.ok("添加成功");
+    }
+}

+ 34 - 0
fs-service/src/main/java/com/fs/fastGpt/vo/FastgptExtUserTagVO.java

@@ -0,0 +1,34 @@
+package com.fs.fastGpt.vo;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 处理新客标签对象 fastgpt_ext_user_tag
+ *
+ * @author fs
+ * @date 2025-09-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FastgptExtUserTagVO extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 标签id */
+    @Excel(name = "标签id")
+    private String tagId;
+
+    /** 企业id */
+    @Excel(name = "企业id")
+    private String corpId;
+
+    List<String> tagIds;
+
+
+}

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/FsHealthTongueMapper.java

@@ -2,6 +2,7 @@ package com.fs.his.mapper;
 
 import java.util.List;
 
+import com.fs.aiTongueApi.domain.inner.TongueInfo;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsHealthTongue;
 import com.fs.his.param.FsHealthTongueListUParam;
@@ -95,4 +96,6 @@ public interface FsHealthTongueMapper
     FsHealthTongueUVO selectFsHealthTongueUVOById(Long id);
 
     List<String> selectListByDateAndUserId(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("userId") Long userId);
+
+    TongueInfo selectFsTongueInfo(TongueInfo tongueInfo);
 }

+ 8 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -402,4 +402,12 @@ public interface FsUserMapper
 
     @Update("update fs_user set status = 0,phone = null,union_id = null,is_del = 1 where user_id = #{userId}")
     void removeUser(Long userId);
+
+
+    /**
+     * 统计用户相关数据(课程、答题、红包)
+     */
+    Map<String, Object> countUserStats(
+            UserStatisticsCommonParam param);
+
 }

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

@@ -2,6 +2,7 @@ package com.fs.his.service;
 
 import java.util.List;
 
+import com.fs.aiTongueApi.domain.inner.TongueInfo;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsHealthTongue;
 import com.fs.his.param.FsHealthTongueListUParam;
@@ -80,4 +81,6 @@ public interface IFsHealthTongueService
     FsHealthTongueUVO selectFsHealthTongueUVOById(Long id);
 
     Long selectFsHealthTongueAllCountByUserId(Long l);
+
+    TongueInfo selectFsTongueInfo(TongueInfo tongueInfo);
 }

+ 60 - 57
fs-service/src/main/java/com/fs/his/service/impl/FsHealthTongueServiceImpl.java

@@ -4,15 +4,18 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.aiTongueApi.domain.AITongueResult;
 import com.fs.aiTongueApi.domain.QueryQuanXi;
 import com.fs.aiTongueApi.domain.inner.TongueData;
+import com.fs.aiTongueApi.domain.inner.TongueInfo;
 import com.fs.aiTongueApi.service.AiTongueService;
 import com.fs.aiTongueApi.service.impl.AiTongueServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.spring.SpringUtils;
 import com.fs.his.param.FsHealthTongueListUParam;
 import com.fs.his.param.FsHealthTongueParam;
 import com.fs.his.param.FsHealthTongueUParam;
@@ -20,6 +23,8 @@ import com.fs.his.vo.FsHealthTongueListUVO;
 import com.fs.his.vo.FsHealthTongueListVO;
 import com.fs.his.vo.FsHealthTongueUVO;
 import com.qiniu.util.Json;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.his.mapper.FsHealthTongueMapper;
@@ -125,66 +130,59 @@ public class FsHealthTongueServiceImpl implements IFsHealthTongueService
     @Override
     public R insertFsHealthTongueByImgUrl(FsHealthTongueUParam param) {
 
-        QueryQuanXi queryQuanXi = new QueryQuanXi();
-        if (param.getName()!=null&&!param.getName().equals("")){
-            queryQuanXi.setName(param.getName());
-        }{
-            queryQuanXi.setName("匿名");
-        }
-        if (param.getAge()!=null){
-            queryQuanXi.setAge(param.getAge()+"");
-        }else {
-            queryQuanXi.setAge("55");
-        }
+        // 使用Redisson分布式锁保证高并发下的同步执行
+        RedissonClient redissonClient = SpringUtils.getBean(RedissonClient.class);
+        String lockKey = "tongueAnalysis:" + param.getUserId();
+        RLock lock = redissonClient.getLock(lockKey);
 
-        queryQuanXi.setFile(param.getTongueUrl());
-        if (param.getSex()!=null){
-            queryQuanXi.setMale(param.getSex()==1?"1":"0");
-        }else {
-            queryQuanXi.setMale("0");
-        }
+        try {
+            // 尝试获取锁,最多等待3秒,持有锁时间最多30秒
+            boolean isLocked = lock.tryLock(3,  30, TimeUnit.SECONDS);
+            if (!isLocked) {
+                return R.error("系统繁忙,请稍后再试");
+            }
+
+            // 检查用户使用频率限制(每天最多3次)
+            /*Long count = selectFsHealthTongueCountByUserId(param.getUserId());
+            if (count >= 5) {
+                return R.error("今日使用次数已达上限");
+            }*/
+
+            AITongueResult<FsHealthTongue> tongueDataAITongueResult = aiTongueService.newCheckTongue(param.getTongueUrl());
+            FsHealthTongue data = tongueDataAITongueResult.getData();
+
+            if (param.getName()!=null&&!param.getName().isEmpty()){
+                data.setName(param.getName());
+            }
 
-        AITongueResult<TongueData> tongueDataAITongueResult = aiTongueService.quanXiTongue(queryQuanXi);
-
-        if (tongueDataAITongueResult.getCode().equals("40001")){
-            FsHealthTongue fsHealthTongue = new FsHealthTongue();
-            fsHealthTongue.setAge(param.getAge());
-            fsHealthTongue.setPatientId(param.getPatientId());
-            fsHealthTongue.setName(param.getName());
-            fsHealthTongue.setSex(param.getSex());
-            fsHealthTongue.setStatus(0);
-            fsHealthTongue.setUserId(param.getUserId());
-            fsHealthTongue.setTongueUrl(param.getTongueUrl());
-            TongueData data = tongueDataAITongueResult.getData();
-            fsHealthTongue.setTongueId(data.getId());
-            fsHealthTongue.setCreateTime(new Date());
-            fsHealthTongue.setTypeName(data.getTypeName()+"质");
-
-            fsHealthTongue.setBotai(data.getBotai());
-            fsHealthTongue.setBotaiDesc(data.getBotaiDesc());
-            fsHealthTongue.setChihen(data.getChihen());
-            fsHealthTongue.setChihenDesc(data.getChihenDesc());
-            fsHealthTongue.setLiewen(data.getLiewen());
-            fsHealthTongue.setLiewenDesc(data.getLiewenDesc());
-            fsHealthTongue.setShemianName(data.getShemianName());
-            fsHealthTongue.setShemianDesc(data.getShemianDesc());
-            fsHealthTongue.setTaiseName(data.getTaiseName());
-            fsHealthTongue.setTaiseDesc(data.getTaiseDesc());
-            String json =fsHealthTongueMapper.selectTypeJSON();
-            String typeName = fsHealthTongue.getTypeName();
-            String itemTypeJSonValue="[]";
-            List<Map<String, Object>> itemTypeJsonList = (List<Map<String, Object>>) JSON.parse(json);
-            for (Map<String, Object> stringStringMap : itemTypeJsonList) {
-                String itemType = (String) stringStringMap.get("itemType");
-                if (itemType.equals(typeName)){
-                    itemTypeJSonValue= Json.encode(stringStringMap.get("item"));
-                }
+            if (param.getAge()!=null){
+                data.setAge(param.getAge());
+            }
+
+            if (param.getSex()!=null){
+                data.setSex(param.getSex());
+            }
+
+            if (tongueDataAITongueResult.getCode().equals("40001")){
+                data.setPatientId(param.getPatientId());
+                data.setStatus(0);
+                data.setUserId(param.getUserId());
+                data.setCreateTime(new Date());
+                fsHealthTongueMapper.insertFsHealthTongue(data);
+                return R.ok().put("data",data);
+            }else {
+                return R.error(tongueDataAITongueResult.getMeta().getMsg());
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return R.error("系统繁忙,请稍后再试");
+        } catch (Exception e) {
+            return R.error("系统异常,请稍后再试!");
+        } finally {
+            // 释放锁
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
             }
-            fsHealthTongue.setTypeJson(itemTypeJSonValue);
-            fsHealthTongueMapper.insertFsHealthTongue(fsHealthTongue);
-            return R.ok().put("data",fsHealthTongue);
-        }else {
-            return R.error(tongueDataAITongueResult.getMeta().getMsg());
         }
     }
 
@@ -207,4 +205,9 @@ public class FsHealthTongueServiceImpl implements IFsHealthTongueService
     public Long selectFsHealthTongueAllCountByUserId(Long id) {
         return fsHealthTongueMapper.selectFsHealthTongueAllCountByUserId(id);
     }
+
+    @Override
+    public TongueInfo selectFsTongueInfo(TongueInfo tongueInfo) {
+        return fsHealthTongueMapper.selectFsTongueInfo(tongueInfo);
+    }
 }

+ 191 - 171
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -6,6 +6,8 @@ import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -19,6 +21,7 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.param.LoginMaWxParam;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DictUtils;
@@ -103,9 +106,9 @@ import static com.fs.hisStore.enums.BillDetailEnum.CATEGORY_3;
  * @date 2023-06-07
  */
 @Service
-public class FsUserServiceImpl implements IFsUserService
-{
-    Logger logger= LoggerFactory.getLogger(getClass());;
+public class FsUserServiceImpl implements IFsUserService {
+    Logger logger = LoggerFactory.getLogger(getClass());
+    ;
     @Autowired
     private FsUserMapper fsUserMapper;
     @Autowired
@@ -155,6 +158,9 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Autowired
     private CompanyRoleMapper companyRoleMapper;
+
+    @Autowired
+    private RedisCache redisCache;
     @Autowired
     private IFsUserProjectTagService userProjectTagService;
 
@@ -177,8 +183,7 @@ public class FsUserServiceImpl implements IFsUserService
      * @return 用户
      */
     @Override
-    public FsUser selectFsUserByUserId(Long userId)
-    {
+    public FsUser selectFsUserByUserId(Long userId) {
         return fsUserMapper.selectFsUserByUserId(userId);
     }
 
@@ -194,8 +199,7 @@ public class FsUserServiceImpl implements IFsUserService
      * @return 用户
      */
     @Override
-    public List<FsUser> selectFsUserList(FsUser fsUser)
-    {
+    public List<FsUser> selectFsUserList(FsUser fsUser) {
         return fsUserMapper.selectFsUserList(fsUser);
     }
 
@@ -207,10 +211,9 @@ public class FsUserServiceImpl implements IFsUserService
      */
     @Override
     @Transactional
-    public int insertFsUser(FsUser fsUser)
-    {
+    public int insertFsUser(FsUser fsUser) {
         fsUser.setCreateTime(DateUtils.getNowDate());
-        if (StringUtils.isNotEmpty(fsUser.getPhone())){
+        if (StringUtils.isNotEmpty(fsUser.getPhone())) {
             fsUser.setPhone(encryptPhone(fsUser.getPhone()));
         }
         int i = fsUserMapper.insertFsUser(fsUser);
@@ -229,12 +232,11 @@ public class FsUserServiceImpl implements IFsUserService
      * @return 结果
      */
     @Override
-    public int updateFsUser(FsUser fsUser)
-    {
+    public int updateFsUser(FsUser fsUser) {
         fsUser.setUpdateTime(DateUtils.getNowDate());
-        if (fsUser.getPhone()!=null&&fsUser.getPhone().length()==11&&fsUser.getPhone().matches("\\d+")){
+        if (fsUser.getPhone() != null && fsUser.getPhone().length() == 11 && fsUser.getPhone().matches("\\d+")) {
             fsUser.setPhone(encryptPhone(fsUser.getPhone()));
-        }else {
+        } else {
             fsUser.setPhone(null);
         }
         return fsUserMapper.updateFsUser(fsUser);
@@ -247,8 +249,7 @@ public class FsUserServiceImpl implements IFsUserService
      * @return 结果
      */
     @Override
-    public int deleteFsUserByUserIds(Long[] userIds)
-    {
+    public int deleteFsUserByUserIds(Long[] userIds) {
         for (Long userId : userIds) {
             fsUserMapper.updateFsUserByUserId(userId);
         }
@@ -262,8 +263,7 @@ public class FsUserServiceImpl implements IFsUserService
      * @return 结果
      */
     @Override
-    public int deleteFsUserByUserId(Long userId)
-    {
+    public int deleteFsUserByUserId(Long userId) {
         return fsUserMapper.updateFsUserByUserId(userId);
     }
 
@@ -313,6 +313,7 @@ public class FsUserServiceImpl implements IFsUserService
     public List<FsUserExportListVO> selectFsUserExportListVO(FsUserParam fsUser) {
         return fsUserMapper.selectFsUserExportListVO(fsUser);
     }
+
     @Autowired
     private FsUserIntegralLogsMapper integralLogsMapper;
 
@@ -321,9 +322,9 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     @Transactional
-    public void addUserIntegral(BigDecimal payMoney,Long userId,Long orderId ,Integer orderType) {
-        String json =configService.selectConfigByKey("his.integral");
-        IntegralConfig config = JSONUtil.toBean(json,IntegralConfig.class);
+    public void addUserIntegral(BigDecimal payMoney, Long userId, Long orderId, Integer orderType) {
+        String json = configService.selectConfigByKey("his.integral");
+        IntegralConfig config = JSONUtil.toBean(json, IntegralConfig.class);
 
         int points = payMoney.intValue() * config.getIntegralRatio();
 
@@ -343,7 +344,7 @@ public class FsUserServiceImpl implements IFsUserService
     /**
      * 判断是否节气套餐包
      */
-    private boolean isSolarTerm(Long orderId ,Integer orderType) {
+    private boolean isSolarTerm(Long orderId, Integer orderType) {
         if (orderType == 2) {
             FsStoreOrder fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderId(orderId);
             if (Objects.nonNull(fsStoreOrder.getPackageId())) {
@@ -364,34 +365,34 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     @Transactional
-    public void followAddIntegral(Long userId,Long orderId) {
+    public void followAddIntegral(Long userId, Long orderId) {
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
-        if(fsUser!=null){
-            String json =configService.selectConfigByKey("his.integral");
-            IntegralConfig config= JSONUtil.toBean(json,IntegralConfig.class);
-            Integer todayTotalIntegral= integralLogsMapper.selectTodayTotalIntegral(config.getIntegralTypeByOneDay(),userId);
-            if (todayTotalIntegral==null){
-                todayTotalIntegral=0;
+        if (fsUser != null) {
+            String json = configService.selectConfigByKey("his.integral");
+            IntegralConfig config = JSONUtil.toBean(json, IntegralConfig.class);
+            Integer todayTotalIntegral = integralLogsMapper.selectTodayTotalIntegral(config.getIntegralTypeByOneDay(), userId);
+            if (todayTotalIntegral == null) {
+                todayTotalIntegral = 0;
             }
-            if (todayTotalIntegral!=null&&todayTotalIntegral>=config.getIntegralByOneDay()){
+            if (todayTotalIntegral != null && todayTotalIntegral >= config.getIntegralByOneDay()) {
                 return;
             }
-            Long integral = config.getIntegralFollow()+0L;
-                FsUser u = new FsUser();
-                u.setUserId(userId);
-                u.setIntegral(fsUser.getIntegral()+integral);
-                fsUserMapper.updateFsUser(u);
-                logger.info("用户{}获取积分{}",fsUser.getUserId(),integral);
-                //写入日志
-                FsUserIntegralLogs logs = new FsUserIntegralLogs();
-                logs.setIntegral(integral.longValue());
-                logs.setBusinessType(4);
-                logs.setUserId(userId);
-                logs.setBalance(u.getIntegral());
-                logs.setLogType(6);
-                logs.setBusinessId(orderId.toString());
-                logs.setCreateTime(new Date());
-                integralLogsMapper.insertFsUserIntegralLogs(logs);
+            Long integral = config.getIntegralFollow() + 0L;
+            FsUser u = new FsUser();
+            u.setUserId(userId);
+            u.setIntegral(fsUser.getIntegral() + integral);
+            fsUserMapper.updateFsUser(u);
+            logger.info("用户{}获取积分{}", fsUser.getUserId(), integral);
+            //写入日志
+            FsUserIntegralLogs logs = new FsUserIntegralLogs();
+            logs.setIntegral(integral.longValue());
+            logs.setBusinessType(4);
+            logs.setUserId(userId);
+            logs.setBalance(u.getIntegral());
+            logs.setLogType(6);
+            logs.setBusinessId(orderId.toString());
+            logs.setCreateTime(new Date());
+            integralLogsMapper.insertFsUserIntegralLogs(logs);
 
         }
     }
@@ -399,26 +400,26 @@ public class FsUserServiceImpl implements IFsUserService
     @Transactional
     public void subIntegral(Long userId) {
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
-        if(fsUser!=null&&fsUser.getIntegral()!=0){
+        if (fsUser != null && fsUser.getIntegral() != 0) {
             Long integral = fsUser.getIntegral();
             fsUser.setIntegral(0L);
             fsUserMapper.updateFsUser(fsUser);
-            logger.info("用户{}扣除积分{}",fsUser.getUserId(),0-integral);
+            logger.info("用户{}扣除积分{}", fsUser.getUserId(), 0 - integral);
             FsUserIntegralLogs logs = new FsUserIntegralLogs();
-            logs.setIntegral(0-integral);
+            logs.setIntegral(0 - integral);
             logs.setUserId(userId);
             logs.setBalance(0L);
             logs.setLogType(7);
             logs.setCreateTime(new Date());
             integralLogsMapper.insertFsUserIntegralLogs(logs);
-            }
-
         }
 
+    }
+
     @Override
     public FsUserFollowDoctorVO getUserFollowDoctorAndOrderId(Long userId) {
         FsUserFollowDoctorVO fsUserFollowDoctorVO = fsStoreOrderMapper.selectFsFollowDoctorIdByUserId(userId);
-        if (fsUserFollowDoctorVO!=null&&fsUserFollowDoctorVO.getFollowDoctorId()!=null){
+        if (fsUserFollowDoctorVO != null && fsUserFollowDoctorVO.getFollowDoctorId() != null) {
             Long followId = fsFollowMapper.selectFsFollowByStoreOrderId(fsUserFollowDoctorVO.getOrderId());
             fsUserFollowDoctorVO.setFollowId(followId);
         }
@@ -433,34 +434,34 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     @Transactional
-    public void subUserIntegral(Long userId,Long orderId ,Integer orderType) {
-            FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
-            if(fsUser!=null){
-                FsUserIntegralLogs maps=new FsUserIntegralLogs();
-                maps.setLogType(2);
-                maps.setBusinessType(orderType);
-                maps.setBusinessId(orderId.toString());
-                List<FsUserIntegralLogs> logsList=integralLogsMapper.selectFsUserIntegralLogsList(maps);
-                if(logsList.size()>0){
-                    for (FsUserIntegralLogs userLogs : logsList) {
-                        fsUser.setIntegral(fsUser.getIntegral()-userLogs.getIntegral());
-                        fsUserMapper.updateFsUser(fsUser);
-                        logger.info("用户{}扣除积分{}",fsUser.getUserId(),userLogs.getIntegral());
-                        //写入日志
-                        FsUserIntegralLogs logs = new FsUserIntegralLogs();
-                        logs.setIntegral(-logsList.get(0).getIntegral());
-                        logs.setUserId(userId);
-                        logs.setBalance(fsUser.getIntegral());
-                        logs.setBusinessType(orderType);
-                        logs.setLogType(4);
-                        logs.setBusinessId(orderId.toString());
-                        logs.setCreateTime(new Date());
-                        integralLogsMapper.insertFsUserIntegralLogs(logs);
-                    }
+    public void subUserIntegral(Long userId, Long orderId, Integer orderType) {
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
+        if (fsUser != null) {
+            FsUserIntegralLogs maps = new FsUserIntegralLogs();
+            maps.setLogType(2);
+            maps.setBusinessType(orderType);
+            maps.setBusinessId(orderId.toString());
+            List<FsUserIntegralLogs> logsList = integralLogsMapper.selectFsUserIntegralLogsList(maps);
+            if (logsList.size() > 0) {
+                for (FsUserIntegralLogs userLogs : logsList) {
+                    fsUser.setIntegral(fsUser.getIntegral() - userLogs.getIntegral());
+                    fsUserMapper.updateFsUser(fsUser);
+                    logger.info("用户{}扣除积分{}", fsUser.getUserId(), userLogs.getIntegral());
+                    //写入日志
+                    FsUserIntegralLogs logs = new FsUserIntegralLogs();
+                    logs.setIntegral(-logsList.get(0).getIntegral());
+                    logs.setUserId(userId);
+                    logs.setBalance(fsUser.getIntegral());
+                    logs.setBusinessType(orderType);
+                    logs.setLogType(4);
+                    logs.setBusinessId(orderId.toString());
+                    logs.setCreateTime(new Date());
+                    integralLogsMapper.insertFsUserIntegralLogs(logs);
                 }
-
             }
 
+        }
+
     }
 
     @Override
@@ -481,7 +482,7 @@ public class FsUserServiceImpl implements IFsUserService
         user.setIsVip(0);
         user.setVipStartDate(null);
         user.setVipEndDate(null);
-        if (fsUserMapper.updateFsUser(user)>0){
+        if (fsUserMapper.updateFsUser(user) > 0) {
             return R.ok("清除成功");
         }
         return R.error("清除vip失败");
@@ -529,7 +530,7 @@ public class FsUserServiceImpl implements IFsUserService
         map.put("tagName", "重粉");
         List<CompanyTag> companyTags = companyTagMapper.selectCompanyTagListByMap(map);
         Long tagId;
-        if(companyTags == null || companyTags.isEmpty()){
+        if (companyTags == null || companyTags.isEmpty()) {
             CompanyTag companyTag = new CompanyTag();
             companyTag.setCompanyId(param.getCompanyId());
             companyTag.setTag("重粉");
@@ -543,7 +544,7 @@ public class FsUserServiceImpl implements IFsUserService
         companyTagUserParam.setUserId(param.getUserId());
         companyTagUserParam.setTagIds(tagId.toString());
         List<CompanyTagUser> companyTagUsers = companyTagUserMapper.selectCompanyTagUserList(companyTagUserParam);
-        if(companyTagUsers == null || companyTagUsers.isEmpty()){
+        if (companyTagUsers == null || companyTagUsers.isEmpty()) {
             CompanyTagUser companyTagUser = new CompanyTagUser();
             companyTagUser.setUserId(param.getUserId());
             companyTagUser.setCompanyId(param.getCompanyId());
@@ -557,12 +558,12 @@ public class FsUserServiceImpl implements IFsUserService
     @Override
     public PageInfo<FsUserPageListVO> selectFsUserPageList(FsUserPageListParam param) {
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
-        if (companyUser!=null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             param.setUserId(0L);
             param.setCompanyId(companyUser.getCompanyId());
         }
         //筛选问题
-        if (StringUtils.isNotBlank(param.getCompanyUserId())){
+        if (StringUtils.isNotBlank(param.getCompanyUserId())) {
             param.setUserId(Long.valueOf(param.getCompanyUserId()));
         }
 
@@ -581,7 +582,7 @@ public class FsUserServiceImpl implements IFsUserService
         List<SysDictData> courseProject = dictDataMapper.selectDictDataByType("sys_course_project");
         for (FsUserPageListVO fsUserPageListVO : fsUserPageListVOS) {
             if (courseProject != null && !courseProject.isEmpty()) {
-                if (fsUserPageListVO.getProjectId() != null){
+                if (fsUserPageListVO.getProjectId() != null) {
                     // 项目
                     courseProject.stream()
                             .filter(c -> c.getDictValue().equals(fsUserPageListVO.getProjectId().toString()))
@@ -589,15 +590,15 @@ public class FsUserServiceImpl implements IFsUserService
                             .ifPresent(c -> fsUserPageListVO.setProjectName(c.getDictLabel()));
                 }
             }
-            if (StringUtils.isEmpty(fsUserPageListVO.getNickname())){
+            if (StringUtils.isEmpty(fsUserPageListVO.getNickname())) {
                 fsUserPageListVO.setNickname("用户暂未授权昵称");
             }
 
             //解密
-            if(fsUserPageListVO.getPhone() != null && fsUserPageListVO.getPhone() != ""){
-                if (fsUserPageListVO.getPhone().length()>11){
+            if (fsUserPageListVO.getPhone() != null && fsUserPageListVO.getPhone() != "") {
+                if (fsUserPageListVO.getPhone().length() > 11) {
                     fsUserPageListVO.setPhone(decryptPhoneMk(fsUserPageListVO.getPhone()));
-                }else {
+                } else {
                     fsUserPageListVO.setPhone(fsUserPageListVO.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
                 }
             }
@@ -611,7 +612,7 @@ public class FsUserServiceImpl implements IFsUserService
         String[] splitTag = tag.split(",");
         StringBuilder newTag = new StringBuilder();
         for (String s : splitTag) {
-            if(!"重粉".equals(s)){
+            if (!"重粉".equals(s)) {
                 newTag.append(s);
             }
         }
@@ -650,7 +651,7 @@ public class FsUserServiceImpl implements IFsUserService
     public TableDataInfo selectFsUserPageListNew(FsUserPageListParam param) {
         // 找出下级销售
         String companyUserId = param.getCompanyUserId();
-        if(StringUtils.isNotBlank(companyUserId)) {
+        if (StringUtils.isNotBlank(companyUserId)) {
             Long companyUser = Long.parseLong(companyUserId);
             Set<Long> userIds = companyUserCacheService.selectUserAllCompanyUserId(companyUser);
             if (userIds != null || userIds.size() <= 1) {
@@ -667,34 +668,34 @@ public class FsUserServiceImpl implements IFsUserService
         //获取会员的最新的看课状态和最后看课时间
         Set<Long> userIds = fsUserPageListVOS.stream().map(FsUserPageListVO::getUserId).collect(Collectors.toSet());
         List<FsUserLastCount> fsUserCourseCounts = Collections.emptyList();
-        if(!userIds.isEmpty()){
+        if (!userIds.isEmpty()) {
             fsUserCourseCounts = fsUserCourseCountMapper.selectUserLastCount(userIds);
         }
         Map<Long, FsUserLastCount> countMap = fsUserCourseCounts.stream().collect(Collectors.toMap(FsUserLastCount::getUserId, Function.identity()));
 
         for (FsUserPageListVO item : fsUserPageListVOS) {
-            if(item.getCompanyUserId() != null) {
+            if (item.getCompanyUserId() != null) {
                 String companyUserName = companyUserCacheService.selectCompanyUserNameUserById(item.getCompanyUserId());
-                if(companyUserName != null) {
+                if (companyUserName != null) {
                     item.setCompanyUserNickName(companyUserName);
                 }
             }
-            if(item.getPhone() != null) {
+            if (item.getPhone() != null) {
                 item.setPhone(ParseUtils.parsePhone(item.getPhone()));
             }
-            if(item.getStatus() != null) {
+            if (item.getStatus() != null) {
                 String userStatus = DictUtils.getDictLabel("user_status", String.valueOf(item.getStatus()));
-                if(StringUtils.isNotBlank(userStatus)){
+                if (StringUtils.isNotBlank(userStatus)) {
                     item.setStatusText(userStatus);
                 }
             }
-            if(item.getUserId() != null) {
+            if (item.getUserId() != null) {
                 FsUserCourseCount byUserId = fsUserCourseCountCacheService.findByUserId(item.getUserId());
-                if(byUserId != null) {
+                if (byUserId != null) {
                     item.setWatchCourseCount(byUserId.getWatchCourseCount());
                     item.setMissCourseCount(byUserId.getMissCourseCount());
                     item.setMissCourseStatus(byUserId.getMissCourseStatus());
-                    if(StringUtils.isNotEmpty(byUserId.getPartCourseCount())){
+                    if (StringUtils.isNotEmpty(byUserId.getPartCourseCount())) {
                         item.setPartCourseCount(new BigDecimal(byUserId.getPartCourseCount()).longValue());
                     }
 //                    item.setCourseCountStatus(byUserId.getStatus());
@@ -703,25 +704,25 @@ public class FsUserServiceImpl implements IFsUserService
                     item.setLastWatchDate(byUserId.getLastWatchDate());
                 }
                 FsUserLastCount fsUserCourseCount = countMap.get(item.getUserId());
-                if(fsUserCourseCount != null){
+                if (fsUserCourseCount != null) {
                     item.setCourseCountStatus(fsUserCourseCount.getStatus());
                 }
                 String userTagByUserId = companyTagCacheService
-                        .findUserTagByUserId(item.getUserId(),item.getCompanyUserId());
-                if(StringUtils.isNotEmpty(userTagByUserId)) {
+                        .findUserTagByUserId(item.getUserId(), item.getCompanyUserId());
+                if (StringUtils.isNotEmpty(userTagByUserId)) {
                     String[] split = userTagByUserId.split(",");
                     Set<String> tagNames = new HashSet<>();
                     for (String tag : split) {
-                        if(StringUtils.isNotBlank(tag)) {
+                        if (StringUtils.isNotBlank(tag)) {
                             Long tagL = Long.parseLong(tag);
                             CompanyTag companyTag = tagMap.get(tagL);
-                            if(companyTag != null) {
+                            if (companyTag != null) {
                                 tagNames.add(companyTag.getTag());
                             }
                         }
                     }
                     item.setTagIds(userTagByUserId);
-                    item.setTag(String.join(",",tagNames));
+                    item.setTag(String.join(",", tagNames));
                 }
 
                 // 是否宠粉
@@ -732,10 +733,10 @@ public class FsUserServiceImpl implements IFsUserService
             }
 
             // 解密
-            if(item.getPhone() != null && item.getPhone() != ""){
-                if (item.getPhone().length()>11){
+            if (item.getPhone() != null && item.getPhone() != "") {
+                if (item.getPhone().length() > 11) {
                     item.setPhone(decryptPhoneMk(item.getPhone()));
-                }else {
+                } else {
                     item.setPhone(item.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
                 }
             }
@@ -750,14 +751,15 @@ public class FsUserServiceImpl implements IFsUserService
         rspData.setTotal(this.selectFsUserCount(param));
         return rspData;
     }
+
     @Override
     public Long selectFsUserCount(FsUserPageListParam param) {
         return fsUserMapper.selectFsUserPageListCount(param);
     }
 
     @Override
-    public Long selectFsUserCount(int type,Long companyId,Long companyUserId) {
-        return fsUserMapper.selectFsUserCount(type,companyId,companyUserId);
+    public Long selectFsUserCount(int type, Long companyId, Long companyUserId) {
+        return fsUserMapper.selectFsUserCount(type, companyId, companyUserId);
     }
 
     @Override
@@ -775,7 +777,7 @@ public class FsUserServiceImpl implements IFsUserService
         // 判断是否是管理员
         Long companyId = null;
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             userId = 0L;
             companyId = companyUser.getCompanyId();
         }
@@ -798,13 +800,13 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public UserDetailsVO getUserDetails(Long userId, Long fsUserId, String dateTag, Long userCompanyId) {
-        UserDetailsVO countWatchCourse = fsUserMapper.getCountWatchCourse(userId, fsUserId, dateTag,userCompanyId);
+        UserDetailsVO countWatchCourse = fsUserMapper.getCountWatchCourse(userId, fsUserId, dateTag, userCompanyId);
         FsUserCompanyUser fsUserCompanyUser = userCompanyUserService.selectFsUserCompanyUserById(userCompanyId);
 
         UserDetailsVO countAnswer = fsUserMapper.getCountAnswer(fsUserCompanyUser.getCompanyUserId(), fsUserId, dateTag);
         UserDetailsVO countRedPacket = fsUserMapper.getCountRedPacket(fsUserCompanyUser.getCompanyUserId(), fsUserId, dateTag);
         UserDetailsVO vo = new UserDetailsVO();
-        if (countWatchCourse != null){
+        if (countWatchCourse != null) {
             BeanUtils.copyProperties(countWatchCourse, vo);
         }
         if (countRedPacket != null) {
@@ -830,7 +832,7 @@ public class FsUserServiceImpl implements IFsUserService
         // 判断是否是管理员
         Long companyId = null;
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             userId = 0L;
             companyId = companyUser.getCompanyId();
         }
@@ -851,12 +853,12 @@ public class FsUserServiceImpl implements IFsUserService
 
         // 判断是否是管理员
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             param.setUserId(0L);
         }
         //统计课程数据详情,在查询统计详情的时候需要显示
         Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetailsNew(param);
-        if(courseDetailsMap != null && courseDetailsMap.get("courseNum") != null && courseDetailsMap.get("videoNum") != null && courseDetailsMap.get("courseUserNum") != null){
+        if (courseDetailsMap != null && courseDetailsMap.get("courseNum") != null && courseDetailsMap.get("videoNum") != null && courseDetailsMap.get("courseUserNum") != null) {
             userStatisticsVO.setCourseNum(Integer.parseInt(courseDetailsMap.get("courseNum").toString()))
                     .setVideoNum(Integer.parseInt(courseDetailsMap.get("videoNum").toString()))
                     .setCourseUserNum(Integer.parseInt(courseDetailsMap.get("courseUserNum").toString()));
@@ -869,7 +871,7 @@ public class FsUserServiceImpl implements IFsUserService
 
         // 判断是否是管理员
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             param.setUserId(0L);
             param.setCompanyId(companyUser.getCompanyId());
         }
@@ -904,7 +906,7 @@ public class FsUserServiceImpl implements IFsUserService
 
         // 获取红包统计
         Map<String, Object> redPacketMap = fsUserMapper.countUserRedPacket(param);
-        if(redPacketMap != null && redPacketMap.get("redPacketNum") != null && redPacketMap.get("redPacketAmount") != null) {
+        if (redPacketMap != null && redPacketMap.get("redPacketNum") != null && redPacketMap.get("redPacketAmount") != null) {
             fsUserStatisticsVO.setRedPacketNum(Integer.parseInt(redPacketMap.get("redPacketNum").toString()))
                     .setRedPacketAmount(new BigDecimal(redPacketMap.get("redPacketAmount").toString()));
         }
@@ -917,15 +919,15 @@ public class FsUserServiceImpl implements IFsUserService
         // 判断是否是管理员
         Long companyId = null;
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             userId = 0L;
             companyId = companyUser.getCompanyId();
         }
-        if(type == 1){
+        if (type == 1) {
             //按完播率
             listVO = fsUserMapper.countUserRankingByComplete(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
-        if(type == 2){
+        if (type == 2) {
             //按正确率
             listVO = fsUserMapper.countUserRankingByRight(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
@@ -937,15 +939,15 @@ public class FsUserServiceImpl implements IFsUserService
         // 判断是否是管理员
         Long companyId = null;
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             userId = 0L;
             companyId = companyUser.getCompanyId();
         }
         List<FsCourseRankingVO> list = Collections.emptyList();
-        if(type == 1){
+        if (type == 1) {
             list = fsUserMapper.countCourseRankingByComplete(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
-        if(type == 2){
+        if (type == 2) {
             list = fsUserMapper.countCourseRankingByRight(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
 
@@ -956,7 +958,7 @@ public class FsUserServiceImpl implements IFsUserService
     public List<FsUserGraphicStatisticsVO> graphicStatistics(UserStatisticsCommonParam param) {
         FsUserStatisticsVO userStatistics = getUserStatistics(param);
         List<FsUserGraphicStatisticsVO> list = new ArrayList<>();
-        list.add(new FsUserGraphicStatisticsVO("观看人数",userStatistics.getCourseWatchNum(), userStatistics.getCourseWatchNum()));
+        list.add(new FsUserGraphicStatisticsVO("观看人数", userStatistics.getCourseWatchNum(), userStatistics.getCourseWatchNum()));
         list.add(new FsUserGraphicStatisticsVO("完播人数", userStatistics.getCourseCompleteNum(), userStatistics.getCourseCompleteNum()));
         list.add(new FsUserGraphicStatisticsVO("答题人数", userStatistics.getAnswerNum(), userStatistics.getAnswerNum()));
         list.add(new FsUserGraphicStatisticsVO("正确人数", userStatistics.getAnswerRightNum(), userStatistics.getAnswerRightNum()));
@@ -1010,7 +1012,7 @@ public class FsUserServiceImpl implements IFsUserService
             countVO.setRedPacketNum(redPacketVO.getRedPacketNum())
                     .setRedPacketAmount(redPacketVO.getRedPacketAmount() != null ? redPacketVO.getRedPacketAmount() : new BigDecimal(BigInteger.ZERO));
             countVO.setAnswerNum(answerVO.getAnswerNum()).setAnswerRightNum(answerVO.getAnswerRightNum())
-                    .setAnswerRightRate(answerVO.getAnswerRightRate()!=null ? answerVO.getAnswerRightRate() : new BigDecimal(BigInteger.ZERO));
+                    .setAnswerRightRate(answerVO.getAnswerRightRate() != null ? answerVO.getAnswerRightRate() : new BigDecimal(BigInteger.ZERO));
             allVO.setCountVO(countVO);
             return allVO;
         }).collect(Collectors.toList());
@@ -1021,7 +1023,7 @@ public class FsUserServiceImpl implements IFsUserService
         // 判断是否是管理员
         Long companyId = null;
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             companyUserId = String.valueOf(0);
             companyId = companyUser.getCompanyId();
         }
@@ -1039,25 +1041,25 @@ public class FsUserServiceImpl implements IFsUserService
     public ResponseResult<Boolean> becomeMember(FsUserCourseBeMemberParam param) {
         //查询用户
         FsUser fsUser = fsUserMapper.selectFsUserById(param.getUserId());
-        if (Objects.isNull(fsUser)){
-            return ResponseResult.fail(404,"当前用户信息不存在");
+        if (Objects.isNull(fsUser)) {
+            return ResponseResult.fail(404, "当前用户信息不存在");
         }
 
         //判断该销售是否存在
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
-        if (Objects.isNull(companyUser)){
-            return ResponseResult.fail(405,"销售不存在");
+        if (Objects.isNull(companyUser)) {
+            return ResponseResult.fail(405, "销售不存在");
         }
         // 通过字段值判断该销售是否允许注册会员
-        if(companyUser.getIsAllowedAllRegister() != null && companyUser.getIsAllowedAllRegister() == 0){
-            return ResponseResult.fail(407,"不允许注册会员,请联系管理员");
+        if (companyUser.getIsAllowedAllRegister() != null && companyUser.getIsAllowedAllRegister() == 0) {
+            return ResponseResult.fail(407, "不允许注册会员,请联系管理员");
         }
 
         // 逻辑调整:如果会员已经绑定了销售,直接提示,不添加重粉数据了-2025年6月16日14点53分
         // 逻辑调整:会员与销售的绑定关系通过中间表关联 /20250625 17:13
         FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), param.getProjectId());
-        if (Objects.nonNull(userCompanyUser) && !userCompanyUser.getCompanyUserId().equals(param.getCompanyUserId())){
-            return ResponseResult.fail(500,"该用户("+fsUser.getUserId() + ")已成为其他销售会员");
+        if (Objects.nonNull(userCompanyUser) && !userCompanyUser.getCompanyUserId().equals(param.getCompanyUserId())) {
+            return ResponseResult.fail(500, "该用户(" + fsUser.getUserId() + ")已成为其他销售会员");
         }
 
         // 特殊(需求设计:需要根据公司是否开启黑名单来设置会员初始化的状态)
@@ -1066,7 +1068,7 @@ public class FsUserServiceImpl implements IFsUserService
         int isDefaultBlack = company != null ? company.getFsUserIsDefaultBlack() : 0;
 
         // 添加关系表数据
-        if (Objects.isNull(userCompanyUser)){
+        if (Objects.isNull(userCompanyUser)) {
             int defaultStatus = isDefaultBlack == 1 ? 0 : 1;
             userCompanyUser = userCompanyUserService.bindRelationship(param.getUserId(), param.getProjectId(), companyUser.getCompanyId(), companyUser.getUserId(), defaultStatus);
         }
@@ -1082,7 +1084,7 @@ public class FsUserServiceImpl implements IFsUserService
 //        }
 
         //如果是设置了需要进入小黑屋,则需要返回提示,否则正常返回
-        if(isDefaultBlack == 1){
+        if (isDefaultBlack == 1) {
             return ResponseResult.fail(402, "已成功注册,待管理审核");
         }
         return ResponseResult.ok(Boolean.TRUE);
@@ -1095,28 +1097,28 @@ public class FsUserServiceImpl implements IFsUserService
         BeanUtils.copyProperties(fsUser, item);
         item.setNickname(fsUser.getNickName());
         Map<Long, CompanyTag> tagMap = companyTagCacheService.queryAllTagMap();
-        if(item.getPhone() != null) {
+        if (item.getPhone() != null) {
             item.setPhone(ParseUtils.parsePhone(item.getPhone()));
         }
         String userTagByUserId = null;
-        if (item.getUserId()!=null && item.getCompanyUserId() != null){
+        if (item.getUserId() != null && item.getCompanyUserId() != null) {
             userTagByUserId = companyTagCacheService
-                    .findUserTagByUserId(item.getUserId(),item.getCompanyUserId());
+                    .findUserTagByUserId(item.getUserId(), item.getCompanyUserId());
         }
-        if(StringUtils.isNotEmpty(userTagByUserId)) {
+        if (StringUtils.isNotEmpty(userTagByUserId)) {
             String[] split = userTagByUserId.split(",");
             Set<String> tagNames = new HashSet<>();
             for (String tag : split) {
-                if(StringUtils.isNotBlank(tag)) {
+                if (StringUtils.isNotBlank(tag)) {
                     Long tagL = Long.parseLong(tag);
                     CompanyTag companyTag = tagMap.get(tagL);
-                    if(companyTag != null) {
+                    if (companyTag != null) {
                         tagNames.add(companyTag.getTag());
                     }
                 }
             }
             item.setTagIds(userTagByUserId);
-            item.setTag(String.join(",",tagNames));
+            item.setTag(String.join(",", tagNames));
         }
         return item;
     }
@@ -1124,26 +1126,26 @@ public class FsUserServiceImpl implements IFsUserService
     @Override
     @Transactional
     public void addMoney(FsStoreOrderScrm order) {
-        FsUserBillScrm map=new FsUserBillScrm();
+        FsUserBillScrm map = new FsUserBillScrm();
         map.setCategory(CATEGORY_3.getValue());
         map.setBusinessId(order.getId().toString());
         map.setBillType(1);
-        List<FsUserBillScrm> list=billService.selectFsUserBillList(map);
-        if(list!=null&&list.size()>0){
-            for(FsUserBillScrm bill:list){
-                FsUser tuiUser= fsUserMapper.selectFsUserByIdForUpdate(bill.getUserId());
-                if(tuiUser!=null){
-                    FsUser tuiUserMap=new FsUser();
+        List<FsUserBillScrm> list = billService.selectFsUserBillList(map);
+        if (list != null && list.size() > 0) {
+            for (FsUserBillScrm bill : list) {
+                FsUser tuiUser = fsUserMapper.selectFsUserByIdForUpdate(bill.getUserId());
+                if (tuiUser != null) {
+                    FsUser tuiUserMap = new FsUser();
                     tuiUserMap.setUserId(tuiUser.getUserId());
                     tuiUserMap.setNowMoney(tuiUser.getNowMoney().add(new BigDecimal(bill.getNumber())));
                     tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(new BigDecimal(bill.getNumber())));
                     fsUserMapper.updateFsUser(tuiUserMap);
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),0, BillDetailEnum.TYPE_6.getDesc(),bill.getNumber().doubleValue(),tuiUserMap.getBrokeragePrice().doubleValue(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),bill.getNumber().doubleValue(),tuiUserMap.getNowMoney().doubleValue(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(), 0, BillDetailEnum.TYPE_6.getDesc(), bill.getNumber().doubleValue(), tuiUserMap.getBrokeragePrice().doubleValue(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(), 1, BillDetailEnum.TYPE_5.getDesc(), bill.getNumber().doubleValue(), tuiUserMap.getNowMoney().doubleValue(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
                 }
             }
         }
-        FsStoreOrderScrm orderMap=new FsStoreOrderScrm();
+        FsStoreOrderScrm orderMap = new FsStoreOrderScrm();
         orderMap.setId(order.getId());
         orderMap.setTuiUserMoneyStatus(1);
         storeOrderMapper.updateFsStoreOrder(orderMap);
@@ -1180,18 +1182,26 @@ public class FsUserServiceImpl implements IFsUserService
 
         // 判断是否是管理员
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
-        if (companyUser != null && companyUser.isAdmin()){
+        if (companyUser != null && companyUser.isAdmin()) {
             param.setUserId(0L);
             param.setCompanyId(companyUser.getCompanyId());
         }
-        // 获取课程统计
-        Map<String, Long> couserMap = fsUserMapper.countUserCourse2(param);
-        if (couserMap != null) {
-            fsUserStatisticsVO.setCourseWatchNum(couserMap.get("courseWatchNum").intValue()).setCourseCompleteNum(couserMap.get("courseCompleteNum").intValue());
 
-            if (couserMap.get("courseCompleteNum") != null && couserMap.get("courseWatchNum") > 0) {
-                int courseCompleteRate = BigDecimal.valueOf(couserMap.get("courseCompleteNum"))
-                        .divide(BigDecimal.valueOf(couserMap.get("courseWatchNum")), 2, RoundingMode.HALF_UP)
+
+        Map<String, Object> map = fsUserMapper.countUserStats(
+                param
+        );
+        // 获取课程统计
+//        Map<String, Long> courseMap = fsUserMapper.countUserCourse2(param);
+        if (map != null) {
+            fsUserStatisticsVO.setCourseWatchNum(Integer.valueOf(map.getOrDefault("courseWatchNum", 0L).toString()))
+                    .setCourseCompleteNum(Integer.valueOf(map.getOrDefault("courseCompleteNum", 0L).toString()));
+
+            Long completeNum = (Long) map.get("courseCompleteNum");
+            Long watchNum = (Long) map.get("courseWatchNum");
+            if (completeNum != null && watchNum != null && watchNum > 0) {
+                int courseCompleteRate = BigDecimal.valueOf(completeNum)
+                        .divide(BigDecimal.valueOf(watchNum), 2, RoundingMode.HALF_UP)
                         .multiply(BigDecimal.valueOf(100))
                         .intValue();
                 fsUserStatisticsVO.setCourseCompleteRate(courseCompleteRate);
@@ -1199,13 +1209,16 @@ public class FsUserServiceImpl implements IFsUserService
         }
 
         // 获取答题统计
-        Map<String, Long> answerMap = fsUserMapper.countUserAnswer(param);
-        if (answerMap != null) {
-            fsUserStatisticsVO.setAnswerNum(answerMap.get("answerNum").intValue()).setAnswerRightNum(answerMap.get("answerRightNum").intValue());
+//        Map<String, Long> answerMap = fsUserMapper.countUserAnswer(param);
+        if (map != null) {
+            Long answerRightNum = (Long) map.get("answerRightNum");
+            Long answerNum = (Long) map.get("answerNum");
 
-            if (answerMap.get("answerRightNum") != null && answerMap.get("answerNum") > 0) {
-                int answerCompleteRate = BigDecimal.valueOf(answerMap.get("answerRightNum"))
-                        .divide(BigDecimal.valueOf(answerMap.get("answerNum")), 2, RoundingMode.HALF_UP)
+            fsUserStatisticsVO.setAnswerNum(answerNum.intValue()).setAnswerRightNum(answerRightNum.intValue());
+
+            if (answerRightNum != null && answerNum != null && answerNum > 0) {
+                int answerCompleteRate = BigDecimal.valueOf(answerRightNum)
+                        .divide(BigDecimal.valueOf(answerNum), 2, RoundingMode.HALF_UP)
                         .multiply(BigDecimal.valueOf(100))
                         .intValue();
                 fsUserStatisticsVO.setAnswerRightRate(answerCompleteRate);
@@ -1213,13 +1226,18 @@ public class FsUserServiceImpl implements IFsUserService
         }
 
         // 获取红包统计
-        Map<String, Object> redPacketMap = fsUserMapper.countUserRedPacket(param);
-        if(redPacketMap != null && redPacketMap.get("redPacketNum") != null && redPacketMap.get("redPacketAmount") != null) {
-            fsUserStatisticsVO.setRedPacketNum(Integer.parseInt(redPacketMap.get("redPacketNum").toString()))
-                    .setRedPacketAmount(new BigDecimal(redPacketMap.get("redPacketAmount").toString()));
+//        Map<String, Object> redPacketMap = fsUserMapper.countUserRedPacket(param);
+        if (map != null) {
+            Object numObj = map.get("redPacketNum");
+            Object amtObj = map.get("redPacketAmount");
+            if (numObj != null && amtObj != null) {
+                fsUserStatisticsVO.setRedPacketNum(Integer.parseInt(numObj.toString()))
+                        .setRedPacketAmount(new BigDecimal(amtObj.toString()));
+            }
         }
         return fsUserStatisticsVO;
     }
+
     private static FsUserCompanyUser getFsUserCompanyUser(FsUserCourseBeMemberParam param, FsUser fsUser) {
         FsUserCompanyUser fsUserCompanyUser = new FsUserCompanyUser();
         // 判断是否绑定了销售,如果已绑定,则需要标识为重粉,且放黑名单
@@ -1233,10 +1251,12 @@ public class FsUserServiceImpl implements IFsUserService
         fsUserCompanyUser.setCompanyUserId(param.getCompanyUserId());
         return fsUserCompanyUser;
     }
+
     @Override
     public List<FsCompanyUserListQueryVO> selectFsCompanyUserListQuery(FsUser fsUser) {
         return fsUserMapper.selectFsCompanyUserListQuery(fsUser);
     }
+
     @Override
     public List<FsUser> getUserListLimit(FsUser fsUser) {
         return fsUserMapper.selectFsUserListLimit(fsUser);

+ 71 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreProductScrm.java

@@ -67,6 +67,9 @@ public class FsStoreProductScrm extends BaseEntity
     @Excel(name = "市场价")
     private BigDecimal otPrice;
 
+    @Excel(name = "市场价")
+    private BigDecimal agentPrice;
+
     /** 邮费 */
     @Excel(name = "邮费")
     private BigDecimal postage;
@@ -183,6 +186,74 @@ public class FsStoreProductScrm extends BaseEntity
     /** 指定企业 */
     private String companyIds;
 
+    /** 店铺ID */
+    @Excel(name = "店铺ID")
+    private Long storeId;
+
+    /** 药品展示图 */
+    @Excel(name = "药品展示图")
+    private String drugImage;
+
+    /** 药品注册证书编号 */
+    @Excel(name = "药品注册证书编号")
+    private String drugRegCertNo;
+
+    /** 通用名称 */
+    @Excel(name = "通用名称")
+    private String commonName;
+
+    /** 剂型 */
+    @Excel(name = "剂型")
+    private String dosageForm;
+
+    /** 单价 */
+    @Excel(name = "单价")
+    private String unitPrice;
+
+    /** 批号 */
+    @Excel(name = "批号")
+    private String batchNumber;
+
+    /** 上市许可持有人 */
+    @Excel(name = "上市许可持有人")
+    private String mah;
+
+    /** 上市许可持有人地址 */
+    @Excel(name = "上市许可持有人地址")
+    private String mahAddress;
+
+    /** 生产企业 */
+    @Excel(name = "生产企业")
+    private String manufacturer;
+
+    /** 生产企业地址 */
+    @Excel(name = "生产企业地址")
+    private String manufacturerAddress;
+
+    /** 功能主治 */
+    @Excel(name = "功能主治")
+    private String indications;
+
+    /** 用法用量 */
+    @Excel(name = "用法用量")
+    private String dosage;
+
+    /** 不良反应 */
+    @Excel(name = "不良反应")
+    private String adverseReactions;
+
+    /** 禁忌 */
+    @Excel(name = "禁忌")
+    private String contraindications;
+
+    /** 注意事项 */
+    @Excel(name = "注意事项")
+    private String precautions;
+
+    /** 审核状态(0未审核1审核通过2审核退回) */
+    @Excel(name = "审核状态(0未审核1审核通过2审核退回)")
+    private String isAudit;
+
     /**
      * 商品图片
      */

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

@@ -72,7 +72,8 @@ public interface FsStoreProductScrmMapper
      */
     public int deleteFsStoreProductByIds(Long[] productIds);
     @Select({"<script> " +
-            "select p.*,pc.cate_name  from fs_store_product_scrm p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id   " +
+            "select p.*,pc.cate_name, fs_store.store_name from fs_store_product_scrm p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id  " +
+            "left join fs_store on fs_store.store_id = p.store_id " +
             "where 1=1 " +
             "<if test = 'maps.productName != null and  maps.productName !=\"\"    '> " +
             "and p.product_name like CONCAT('%',#{maps.productName},'%') " +

+ 122 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreProductAddEditParam.java

@@ -1,5 +1,6 @@
 package com.fs.hisStore.param;
 
+import com.fs.common.annotation.Excel;
 import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
 import com.fs.hisStore.dto.ProductArrtDTO;
 import lombok.Data;
@@ -138,6 +139,127 @@ public class FsStoreProductAddEditParam implements Serializable
 
     private Integer tuiCateId;
 
+    /** 店铺ID */
+    @Excel(name = "店铺ID")
+    private Long storeId;
+
+    /** 药品展示图 */
+    @Excel(name = "药品展示图")
+    private String drugImage;
+
+    /** 药品注册证书编号 */
+    @Excel(name = "药品注册证书编号")
+    private String drugRegCertNo;
+
+    /** 通用名称 */
+    @Excel(name = "通用名称")
+    private String commonName;
+
+    /** 剂型 */
+    @Excel(name = "剂型")
+    private String dosageForm;
+
+    /** 单价 */
+    @Excel(name = "单价")
+    private String unitPrice;
+
+    /** 批号 */
+    @Excel(name = "批号")
+    private String batchNumber;
+
+    /** 上市许可持有人 */
+    @Excel(name = "上市许可持有人")
+    private String mah;
+
+    /** 上市许可持有人地址 */
+    @Excel(name = "上市许可持有人地址")
+    private String mahAddress;
+
+    /** 生产企业 */
+    @Excel(name = "生产企业")
+    private String manufacturer;
+
+    /** 生产企业地址 */
+    @Excel(name = "生产企业地址")
+    private String manufacturerAddress;
+
+    /** 功能主治 */
+    @Excel(name = "功能主治")
+    private String indications;
+
+    /** 用法用量 */
+    @Excel(name = "用法用量")
+    private String dosage;
+
+    /** 不良反应 */
+    @Excel(name = "不良反应")
+    private String adverseReactions;
+
+    /** 禁忌 */
+    @Excel(name = "禁忌")
+    private String contraindications;
+
+    /** 注意事项 */
+    @Excel(name = "注意事项")
+    private String precautions;
+
+    /** 审核状态(0未审核1审核通过2审核退回) */
+    @Excel(name = "审核状态(0未审核1审核通过2审核退回)")
+    private String isAudit;
+
+    /**
+     * 商品图片
+     */
+    @Excel(name = "商品图片")
+    private String imgUrl;
+
+    /**
+     * 轮播图
+     */
+    @Excel(name = "轮播图")
+    private String images;
+
+    /**
+     * 商品介绍
+     */
+    @Excel(name = "商品介绍")
+    private String productIntroduce;
+
+    /**
+     * 产品描述
+     */
+    @Excel(name = "产品描述")
+    private String desc;
+    /**
+     * 成本价
+     */
+    @Excel(name = "成本价")
+    private BigDecimal costPrice;
+
+    /**
+     * 浏览量
+     */
+    @Excel(name = "浏览量")
+    private Long views;
+
+    /**
+     * 产品二维码地址(用户小程序海报)
+     */
+    @Excel(name = "产品二维码地址(用户小程序海报)")
+    private String codeUrl;
+    /**
+     * 商品类型:1非处方 2处方
+     */
+    @Excel(name = "是否为处方药:1非处方 2处方")
+    private Integer isPrescribe;
+
+
+    /** 品牌 */
+    @Excel(name = "品牌")
+    private String brand;
+
+    private Integer isDrug;
+
     //属性项目
     private List<ProductArrtDTO> items;
     //sku结果集

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductListVO.java

@@ -78,4 +78,9 @@ public class FsStoreProductListVO  implements Serializable
      * 所属公司
      */
     private String companyName;
+
+    /**
+     * 所属店铺
+     */
+    private String storeName;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/qw/param/QwExternalContactParam.java

@@ -122,4 +122,9 @@ public class QwExternalContactParam {
      */
     private String userType;
 
+    /**
+     * 是否回复
+     */
+    private Integer isReply;
+
 }

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

@@ -117,4 +117,9 @@ public class QwExternalContactVO {
     private Long level;
     @Excel(name = "等级升降")
     private Long levelType;
+
+    /**
+     * 是否回复
+     */
+    private Integer isReply;
 }

+ 5 - 0
fs-service/src/main/resources/mapper/company/CompanyRoleMapper.xml

@@ -181,4 +181,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectCompanyRoleByRoleKey" resultType="com.fs.company.domain.CompanyRole">
         SELECT * FROM company_role WHERE del_flag=0 AND role_key = #{roleKey}
     </select>
+
+    <select id="selectRolesByUserNameAndCompanyId" resultType="Long">
+        select role_id from company_role where  del_flag = '0' and status = '0' and  role_name= #{roleName}  and company_id = #{companyId}
+    </select>
+
 </mapper>

+ 2 - 0
fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml

@@ -262,6 +262,7 @@
         video.course_sort,
         course.course_name,
         fcpd.period_id,
+        fcp.period_name,
         fcpd.id,
         if(ccut.start_date_time is null, fcpd.start_date_time, ccut.start_date_time) as startDateTime,
         if(ccut.end_date_time is null, fcpd.end_date_time, ccut.end_date_time) as endDateTime,
@@ -316,6 +317,7 @@
         video.course_sort,
         course.course_name,
         fcpd.period_id,
+        fcp.period_name,
         fcpd.start_date_time,
         fcpd.end_date_time,
         fcpd.last_join_time,

+ 6 - 1
fs-service/src/main/resources/mapper/course/FsUserCourseVideoRedPackageMapper.xml

@@ -63,7 +63,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{id}
         </foreach>
     </delete>
-
+    <delete id="deleteFsUserCourseVideoRedPackageByVedioIds" parameterType="String">
+        delete from fs_user_course_video_red_package where video_id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
     <!-- 批量查询匹配的红包数据 -->
     <select id="selectByParamsList" resultMap="FsUserCourseVideoRedPackageResult">
         select id, company_id, video_id, red_packet_money, period_id, data_type

+ 75 - 0
fs-service/src/main/resources/mapper/fastGpt/FastgptExtUserTagMapper.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.fastGpt.mapper.FastgptExtUserTagMapper">
+    
+    <resultMap type="FastgptExtUserTag" id="FastgptExtUserTagResult">
+        <result property="id"    column="id"    />
+        <result property="tagId"    column="tag_id"    />
+        <result property="corpId"    column="corp_id"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectFastgptExtUserTagVo">
+        select id, tag_id, corp_id, create_time from fastgpt_ext_user_tag
+    </sql>
+
+    <select id="selectFastgptExtUserTagList" parameterType="FastgptExtUserTag" resultMap="FastgptExtUserTagResult">
+        <include refid="selectFastgptExtUserTagVo"/>
+        <where>  
+            <if test="tagId != null  and tagId != ''"> and tag_id = #{tagId}</if>
+            <if test="corpId != null  and corpId != ''"> and corp_id = #{corpId}</if>
+        </where>
+    </select>
+    
+    <select id="selectFastgptExtUserTagById" parameterType="Long" resultMap="FastgptExtUserTagResult">
+        <include refid="selectFastgptExtUserTagVo"/>
+        where id = #{id}
+    </select>
+    <select id="selectFastgptExtUserTagByIds" resultType="com.fs.fastGpt.domain.FastgptExtUserTag">
+        <include refid="selectFastgptExtUserTagVo"/> where id in
+        <foreach item="id" collection="ids" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
+    <insert id="insertFastgptExtUserTag" parameterType="FastgptExtUserTag" useGeneratedKeys="true" keyProperty="id">
+        insert into fastgpt_ext_user_tag
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="tagId != null">tag_id,</if>
+            <if test="corpId != null">corp_id,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="tagId != null">#{tagId},</if>
+            <if test="corpId != null">#{corpId},</if>
+         </trim>
+    </insert>
+    <insert id="addFastGptTagByCorpId">
+        insert into fastgpt_ext_user_tag (tag_id, corp_id)
+        <foreach item="tagId" collection="data.tagIds" separator="," open="values ">
+            (#{tagId}, #{data.corpId})
+        </foreach>
+    </insert>
+
+    <update id="updateFastgptExtUserTag" parameterType="FastgptExtUserTag">
+        update fastgpt_ext_user_tag
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="tagId != null">tag_id = #{tagId},</if>
+            <if test="corpId != null">corp_id = #{corpId},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFastgptExtUserTagById" parameterType="Long">
+        delete from fastgpt_ext_user_tag where id = #{id}
+    </delete>
+
+    <delete id="deleteFastgptExtUserTagByIds" parameterType="String">
+        delete from fastgpt_ext_user_tag where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 4 - 0
fs-service/src/main/resources/mapper/his/FsHealthTongueMapper.xml

@@ -78,6 +78,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
         GROUP BY DATE(create_time)
     </select>
+    <select id="selectFsTongueInfo" resultType="com.fs.aiTongueApi.domain.inner.TongueInfo">
+        select botai,houdu,shemian_name shemianName,taise_name taiseName,type_name typeName,type_json typeJson from fs_tongue_info
+        where botai = #{botai} and houdu = #{houdu} and shemian_name = #{shemianName} and taise_name = #{taiseName}
+    </select>
 
     <insert id="insertFsHealthTongue" parameterType="FsHealthTongue" useGeneratedKeys="true" keyProperty="id">
         insert into fs_health_tongue

+ 196 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -1005,6 +1005,201 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         GROUP BY fcc.user_id, ucu.project_id
         ) AS complete_counts ) as courseCompleteNum
     </select>
+    <select id="countUserStats" resultType="Map">
+        SELECT
+        -- 观看人数
+        (
+        SELECT COUNT(DISTINCT l.user_id)
+        FROM fs_course_watch_log l
+        LEFT JOIN fs_user u ON u.user_id = l.user_id
+        LEFT JOIN company_user cu ON l.company_user_id = cu.user_id
+        <where>
+            l.log_type != 3 AND l.send_type = 1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND l.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND l.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND l.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND l.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND l.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND l.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS courseWatchNum,
+
+        -- 完成人数
+        (
+        SELECT COUNT(DISTINCT l.user_id)
+        FROM fs_course_watch_log l
+        LEFT JOIN fs_user u ON u.user_id = l.user_id
+        LEFT JOIN company_user cu ON l.company_user_id = cu.user_id
+        <where>
+            l.log_type = 2 AND l.send_type = 1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND l.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND l.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND l.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND l.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND l.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND l.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS courseCompleteNum,
+
+        -- 答题人数
+        (
+        SELECT COUNT(distinct a.user_id)
+        FROM fs_course_answer_logs a
+        LEFT JOIN fs_user u ON u.user_id = a.user_id
+        LEFT JOIN company_user cu ON cu.user_id = a.company_user_id
+        <where>
+            1=1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND a.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND a.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND a.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND a.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND a.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND a.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS answerNum,
+
+        -- 答对人数
+        (
+        SELECT COUNT(distinct a.user_id)
+        FROM fs_course_answer_logs a
+        LEFT JOIN fs_user u ON u.user_id = a.user_id
+        LEFT JOIN company_user cu ON cu.user_id = a.company_user_id
+        <where>
+            a.is_right = 1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND a.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND a.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND a.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND a.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND a.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND a.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS answerRightNum,
+
+        -- 红包数
+        (
+        SELECT COUNT(flog.log_id)
+        FROM fs_course_red_packet_log flog
+        LEFT JOIN fs_user u ON u.user_id = flog.user_id
+        LEFT JOIN company_user cu ON cu.user_id = flog.company_user_id
+        <where>
+            flog.status = 1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND flog.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND flog.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND flog.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND flog.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND flog.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND flog.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS redPacketNum,
+
+        -- 红包金额
+        (
+        SELECT IFNULL(SUM(flog.amount), 0)
+        FROM fs_course_red_packet_log flog
+        LEFT JOIN fs_user u ON u.user_id = flog.user_id
+        LEFT JOIN company_user cu ON cu.user_id = flog.company_user_id
+        <where>
+            flog.status = 1
+            <if test="userId != null and userId != 0 ">
+                AND (cu.user_id = #{userId} OR cu.parent_id = #{userId})
+            </if>
+            <if test="userId != null and userId == 0 ">
+                AND flog.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != '' ">
+                AND flog.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != '' ">
+                AND flog.video_id = #{videoId}
+            </if>
+            <if test="startTime != null and startTime != '' ">
+                AND flog.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != '' ">
+                AND flog.create_time &lt;= #{endTime}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND flog.company_user_id = #{companyUserId}
+            </if>
+        </where>
+        ) AS redPacketAmount
+    </select>
+
 
     <select id="countUserAnswer" resultType="Map">
         SELECT
@@ -1944,4 +2139,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             WHERE phonenumber = #{keywords}
         </if>
     </select>
+
 </mapper>

+ 78 - 2
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -6,8 +6,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <resultMap type="FsStoreProductScrm" id="FsStoreProductResult">
         <result property="productId"    column="product_id"    />
-        <result property="image"    column="image"    />
         <result property="video"    column="video"    />
+        <result property="image"    column="image"    />
         <result property="sliderImage"    column="slider_image"    />
         <result property="productName"    column="product_name"    />
         <result property="productInfo"    column="product_info"    />
@@ -17,6 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="price"    column="price"    />
         <result property="vipPrice"    column="vip_price"    />
         <result property="otPrice"    column="ot_price"    />
+        <result property="agentPrice"    column="agent_price"    />
         <result property="postage"    column="postage"    />
         <result property="unitName"    column="unit_name"    />
         <result property="sort"    column="sort"    />
@@ -49,10 +50,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="isDisplay"    column="is_display"    />
         <result property="tuiCateId"    column="tui_cate_id"    />
         <result property="companyIds"    column="company_ids"    />
+        <result property="storeId"    column="store_id"    />
+        <result property="isDrug"    column="is_drug"    />
+        <result property="drugImage"    column="drug_image"    />
+        <result property="drugRegCertNo"    column="drug_reg_cert_no"    />
+        <result property="commonName"    column="common_name"    />
+        <result property="dosageForm"    column="dosage_form"    />
+        <result property="unitPrice"    column="unit_price"    />
+        <result property="batchNumber"    column="batch_number"    />
+        <result property="mah"    column="mah"    />
+        <result property="mahAddress"    column="mah_address"    />
+        <result property="manufacturer"    column="manufacturer"    />
+        <result property="manufacturerAddress"    column="manufacturer_address"    />
+        <result property="indications"    column="indications"    />
+        <result property="dosage"    column="dosage"    />
+        <result property="adverseReactions"    column="adverse_reactions"    />
+        <result property="contraindications"    column="contraindications"    />
+        <result property="precautions"    column="precautions"    />
+        <result property="isAudit"    column="is_audit"    />
     </resultMap>
 
     <sql id="selectFsStoreProductVo">
-        select product_id, image,video, slider_image, product_name, product_info, keyword, bar_code, cate_id, price, vip_price, ot_price, postage, unit_name, sort, sales, stock, is_show, is_hot, is_benefit, is_best, is_new, description, create_time, update_time, is_postage, is_del, give_integral, cost, is_good, browse, code_path, temp_id, spec_type, is_integral, integral, product_type, prescribe_code, prescribe_spec, prescribe_factory, prescribe_name,is_display,tui_cate_id,company_ids from fs_store_product_scrm
+        select product_id, video, image, slider_image, product_name, product_info, keyword, bar_code, cate_id, price, vip_price, ot_price, agent_price, postage, unit_name, sort, sales, stock, is_show, is_hot, is_benefit, is_best, is_new, description, create_time, update_time, is_postage, is_del, give_integral, cost, is_good, browse, code_path, temp_id, spec_type, is_integral, integral, product_type, prescribe_code, prescribe_spec, prescribe_factory, prescribe_name, is_display, tui_cate_id, company_ids, store_id, is_drug, drug_image, drug_reg_cert_no, common_name, dosage_form, unit_price, batch_number, mah, mah_address, manufacturer, manufacturer_address, indications, dosage, adverse_reactions, contraindications, precautions, is_audit from fs_store_product_scrm
     </sql>
 
     <select id="selectFsStoreProductByProductId" parameterType="Long" resultMap="FsStoreProductResult">
@@ -136,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="price != null">price,</if>
             <if test="vipPrice != null">vip_price,</if>
             <if test="otPrice != null">ot_price,</if>
+            <if test="agentPrice != null">agent_price,</if>
             <if test="postage != null">postage,</if>
             <if test="unitName != null">unit_name,</if>
             <if test="sort != null">sort,</if>
@@ -168,6 +188,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDisplay != null">is_display,</if>
             <if test="tuiCateId != null">tui_cate_id,</if>
             <if test="companyIds != null and companyIds != ''">company_ids,</if>
+            <if test="storeId != null">store_id,</if>
+            <if test="isDrug != null">is_drug,</if>
+            <if test="drugImage != null">drug_image,</if>
+            <if test="drugRegCertNo != null">drug_reg_cert_no,</if>
+            <if test="commonName != null">common_name,</if>
+            <if test="dosageForm != null">dosage_form,</if>
+            <if test="unitPrice != null">unit_price,</if>
+            <if test="batchNumber != null">batch_number,</if>
+            <if test="mah != null">mah,</if>
+            <if test="mahAddress != null">mah_address,</if>
+            <if test="manufacturer != null">manufacturer,</if>
+            <if test="manufacturerAddress != null">manufacturer_address,</if>
+            <if test="indications != null">indications,</if>
+            <if test="dosage != null">dosage,</if>
+            <if test="adverseReactions != null">adverse_reactions,</if>
+            <if test="contraindications != null">contraindications,</if>
+            <if test="precautions != null">precautions,</if>
+            <if test="isAudit != null">is_audit,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="image != null and image != ''">#{image},</if>
@@ -181,6 +219,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="price != null">#{price},</if>
             <if test="vipPrice != null">#{vipPrice},</if>
             <if test="otPrice != null">#{otPrice},</if>
+            <if test="agentPrice != null">#{agentPrice},</if>
             <if test="postage != null">#{postage},</if>
             <if test="unitName != null">#{unitName},</if>
             <if test="sort != null">#{sort},</if>
@@ -213,6 +252,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDisplay != null">#{isDisplay},</if>
             <if test="tuiCateId != null">#{tuiCateId},</if>
             <if test="companyIds != null and companyIds != ''">#{companyIds},</if>
+            <if test="storeId != null">#{storeId},</if>
+            <if test="isDrug != null">#{isDrug},</if>
+            <if test="drugImage != null">#{drugImage},</if>
+            <if test="drugRegCertNo != null">#{drugRegCertNo},</if>
+            <if test="commonName != null">#{commonName},</if>
+            <if test="dosageForm != null">#{dosageForm},</if>
+            <if test="unitPrice != null">#{unitPrice},</if>
+            <if test="batchNumber != null">#{batchNumber},</if>
+            <if test="mah != null">#{mah},</if>
+            <if test="mahAddress != null">#{mahAddress},</if>
+            <if test="manufacturer != null">#{manufacturer},</if>
+            <if test="manufacturerAddress != null">#{manufacturerAddress},</if>
+            <if test="indications != null">#{indications},</if>
+            <if test="dosage != null">#{dosage},</if>
+            <if test="adverseReactions != null">#{adverseReactions},</if>
+            <if test="contraindications != null">#{contraindications},</if>
+            <if test="precautions != null">#{precautions},</if>
+            <if test="isAudit != null">#{isAudit},</if>
          </trim>
     </insert>
 
@@ -230,6 +287,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="price != null">price = #{price},</if>
             <if test="vipPrice != null">vip_price = #{vipPrice},</if>
             <if test="otPrice != null">ot_price = #{otPrice},</if>
+            <if test="agentPrice != null">agent_price = #{agentPrice},</if>
             <if test="postage != null">postage = #{postage},</if>
             <if test="unitName != null">unit_name = #{unitName},</if>
             <if test="sort != null">sort = #{sort},</if>
@@ -262,6 +320,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDisplay != null">is_display = #{isDisplay},</if>
             <if test="tuiCateId != null">tui_cate_id = #{tuiCateId},</if>
             <if test="companyIds != null and companyIds != ''">company_ids = #{companyIds},</if>
+            <if test="storeId != null">store_id = #{storeId},</if>
+            <if test="isDrug != null">is_drug = #{isDrug},</if>
+            <if test="drugImage != null">drug_image = #{drugImage},</if>
+            <if test="drugRegCertNo != null">drug_reg_cert_no = #{drugRegCertNo},</if>
+            <if test="commonName != null">common_name = #{commonName},</if>
+            <if test="dosageForm != null">dosage_form = #{dosageForm},</if>
+            <if test="unitPrice != null">unit_price = #{unitPrice},</if>
+            <if test="batchNumber != null">batch_number = #{batchNumber},</if>
+            <if test="mah != null">mah = #{mah},</if>
+            <if test="mahAddress != null">mah_address = #{mahAddress},</if>
+            <if test="manufacturer != null">manufacturer = #{manufacturer},</if>
+            <if test="manufacturerAddress != null">manufacturer_address = #{manufacturerAddress},</if>
+            <if test="indications != null">indications = #{indications},</if>
+            <if test="dosage != null">dosage = #{dosage},</if>
+            <if test="adverseReactions != null">adverse_reactions = #{adverseReactions},</if>
+            <if test="contraindications != null">contraindications = #{contraindications},</if>
+            <if test="precautions != null">precautions = #{precautions},</if>
+            <if test="isAudit != null">is_audit = #{isAudit},</if>
         </trim>
         where product_id = #{productId}
     </update>

+ 2 - 1
fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

@@ -43,10 +43,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="firstTime"    column="first_time"    />
         <result property="lastWatchTime"    column="last_watch_time"    />
         <result property="registerTime"    column="register_time"    />
+        <result property="isReply"    column="is_reply"    />
     </resultMap>
 
     <sql id="selectQwExternalContactVo">
-        select id,qw_user_id,register_time,state,way_id,stage_status,first_time,open_id,is_interact,level, unionid, user_id,transfer_time,loss_time,del_time,transfer_num, external_user_id,transfer_status,status,create_time, name, avatar, type, gender, remark, description, tag_ids, remark_mobiles, remark_corp_name, add_way, oper_userid, corp_id, company_id, company_user_id, customer_id, fs_user_id from qw_external_contact
+        select id,qw_user_id,register_time,state,way_id,stage_status,first_time,open_id,is_interact,level, unionid, user_id,transfer_time,loss_time,del_time,transfer_num, external_user_id,transfer_status,status,create_time, name, avatar, type, gender, remark, description, tag_ids, remark_mobiles, remark_corp_name, add_way, oper_userid, corp_id, company_id, company_user_id, customer_id, fs_user_id,is_reply from qw_external_contact
     </sql>
 
     <select id="selectQwExternalContactList" parameterType="QwExternalContact" resultMap="QwExternalContactResult">

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

@@ -26,7 +26,7 @@ public class AdvController {
 	@Autowired
 	private IFsAdvService advService;
 
-	@Cacheable(value="getAdvList", key="#map")
+//	@Cacheable(value="getAdvList", key="#map")
 	@ApiOperation("获取首页广告位")
 	@GetMapping("/getAdvList")
 	public R getAdvList(FsAdvUParam map){

+ 0 - 2
fs-user-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -603,6 +603,4 @@ public class CommonController {
 		return R.error("获取域名失败,请检查后台配置!");
 	}
 
-
-
 }

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

@@ -47,7 +47,7 @@ public class CourseController extends  AppBaseController{
     private IFsCourseSopAppLinkService courseSopAppLinkService;
 
 
-    @Cacheable(value="getCourseCate" )
+//    @Cacheable(value="getCourseCate" )
     @ApiOperation("获取分类")
     @GetMapping("/getCourseCate")
     public R getCourseCate(){
@@ -70,7 +70,7 @@ public class CourseController extends  AppBaseController{
             return R.error("操作异常");
         }
     }
-    @Cacheable(value = "getCourseList",key = "#param" )
+//    @Cacheable(value = "getCourseList",key = "#param" )
     @ApiOperation("课程列表")
     @GetMapping("/getCourseList")
     public R getCourseList(FsUserCourseListUParam param)