浏览代码

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
#	fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java
#	fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
caoliqin 2 月之前
父节点
当前提交
70573ea33e
共有 47 个文件被更改,包括 2832 次插入523 次删除
  1. 106 0
      fs-admin/src/main/java/com/fs/qw/controller/FsAppContactWayController.java
  2. 99 0
      fs-admin/src/main/java/com/fs/qw/controller/QwAppContactWayLogsController.java
  3. 106 0
      fs-admin/src/main/java/com/fs/qw/controller/QwCompanyController.java
  4. 126 0
      fs-admin/src/main/java/com/fs/qw/controller/QwInformationController.java
  5. 102 0
      fs-admin/src/main/java/com/fs/qw/controller/QwSopTempController.java
  6. 102 0
      fs-admin/src/main/java/com/fs/qw/controller/QwTagController.java
  7. 27 0
      fs-admin/src/main/java/com/fs/qw/controller/QwUserController.java
  8. 107 0
      fs-admin/src/main/java/com/fs/qw/controller/QwWorkLinkController.java
  9. 97 0
      fs-admin/src/main/java/com/fs/qw/controller/QwWorkLinkUserController.java
  10. 110 0
      fs-admin/src/main/java/com/fs/qw/controller/QwWorkUserController.java
  11. 54 0
      fs-admin/src/main/java/com/fs/qw/controller/SopUserLogsController.java
  12. 72 0
      fs-admin/src/main/java/com/fs/qw/controller/SopUserLogsInfoController.java
  13. 126 0
      fs-admin/src/main/java/com/fs/qw/qwTask/qwTask.java
  14. 3 3
      fs-admin/src/main/resources/application-dev.yml
  15. 3 3
      fs-company/src/main/resources/application-dev.yml
  16. 9 24
      fs-qw-api/src/main/resources/application-dev.yml
  17. 0 57
      fs-qw-api/src/main/resources/application-druid-bly.yml
  18. 0 91
      fs-qw-api/src/main/resources/application-druid.yml
  19. 64 17
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  20. 4 6
      fs-service-system/pom.xml
  21. 8 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
  22. 8 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java
  23. 10 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  24. 1 0
      fs-service-system/src/main/java/com/fs/course/config/CourseConfig.java
  25. 3 1
      fs-service-system/src/main/java/com/fs/course/config/RedPacketConfig.java
  26. 5 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseRealLink.java
  27. 109 84
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  28. 63 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtBarcodeDto.java
  29. 43 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtBaseResponseDTO.java
  30. 227 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtGoodsDto.java
  31. 408 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtSpecDto.java
  32. 19 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtStockDTO.java
  33. 37 0
      fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtStockRespDTO.java
  34. 120 0
      fs-service-system/src/main/java/com/fs/erp/service/impl/WdtErpGoodsServiceImpl.java
  35. 2 0
      fs-service-system/src/main/java/com/fs/his/param/WxSendRedPacketParam.java
  36. 5 0
      fs-service-system/src/main/java/com/fs/qw/param/QwAutoTagsRulesTags.java
  37. 229 226
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  38. 19 0
      fs-service-system/src/main/java/com/fs/sop/domain/QwSop.java
  39. 3 0
      fs-service-system/src/main/java/com/fs/sop/mapper/QwSopMapper.java
  40. 7 3
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java
  41. 10 0
      fs-service-system/src/main/java/com/fs/sop/vo/SopUserLogsVo.java
  42. 10 0
      fs-service-system/src/main/java/com/fs/store/domain/FsUser.java
  43. 8 0
      fs-service-system/src/main/java/com/fs/store/service/IFsStorePaymentService.java
  44. 7 4
      fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreCartServiceImpl.java
  45. 143 3
      fs-service-system/src/main/java/com/fs/store/service/impl/FsStorePaymentServiceImpl.java
  46. 10 0
      fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml
  47. 1 1
      fs-service-system/src/main/resources/mapper/sop/SopUserLogsMapper.xml

+ 106 - 0
fs-admin/src/main/java/com/fs/qw/controller/FsAppContactWayController.java

@@ -0,0 +1,106 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.FsAppContactWay;
+import com.fs.qw.service.IFsAppContactWayService;
+import com.fs.qw.vo.FsAppContactWayListVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * app客服活码上架Controller
+ *
+ * @author fs
+ * @date 2024-12-02
+ */
+@RestController
+@RequestMapping("/qw/appContactWay")
+public class FsAppContactWayController extends BaseController
+{
+    @Autowired
+    private IFsAppContactWayService fsAppContactWayService;
+
+    /**
+     * 查询app客服活码上架列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsAppContactWay fsAppContactWay)
+    {
+        startPage();
+        List<FsAppContactWayListVO> list = fsAppContactWayService.selectFsAppContactWayListVO(fsAppContactWay);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出app客服活码上架列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:export')")
+    @Log(title = "app客服活码上架", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsAppContactWay fsAppContactWay)
+    {
+        List<FsAppContactWay> list = fsAppContactWayService.selectFsAppContactWayList(fsAppContactWay);
+        ExcelUtil<FsAppContactWay> util = new ExcelUtil<FsAppContactWay>(FsAppContactWay.class);
+        return util.exportExcel(list, "app客服活码上架数据");
+    }
+
+    /**
+     * 获取app客服活码上架详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsAppContactWayService.selectFsAppContactWayById(id));
+    }
+
+    /**
+     * 新增app客服活码上架
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:add')")
+    @Log(title = "app客服活码上架", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsAppContactWay fsAppContactWay)
+    {
+        return toAjax(fsAppContactWayService.insertFsAppContactWay(fsAppContactWay));
+    }
+
+    /**
+     * 修改app客服活码上架
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:edit')")
+    @Log(title = "app客服活码上架", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsAppContactWay fsAppContactWay)
+    {
+        return toAjax(fsAppContactWayService.updateFsAppContactWay(fsAppContactWay));
+    }
+
+    /**
+     * 删除app客服活码上架
+     */
+    @PreAuthorize("@ss.hasPermi('qw:appContactWay:remove')")
+    @Log(title = "app客服活码上架", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsAppContactWayService.deleteFsAppContactWayByIds(ids));
+    }
+
+
+    @Log(title = "活码上架", businessType = BusinessType.UPDATE)
+    @PostMapping("/updateIsShow")
+    public AjaxResult updateIsShow(@RequestBody FsAppContactWay fsAppContactWay)
+    {
+        return toAjax(fsAppContactWayService.updateFsAppContactWay(fsAppContactWay));
+    }
+}

+ 99 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwAppContactWayLogsController.java

@@ -0,0 +1,99 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwAppContactWayLogs;
+import com.fs.qw.param.QwAppContactWayLogsParam;
+import com.fs.qw.service.IQwAppContactWayLogsService;
+import com.fs.qw.vo.QwAppContactWayLogsListVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 联系我日志Controller
+ *
+ * @author fs
+ * @date 2024-12-19
+ */
+@RestController
+@RequestMapping("/qw/qwAppContactWayLogs")
+public class QwAppContactWayLogsController extends BaseController
+{
+    @Autowired
+    private IQwAppContactWayLogsService qwAppContactWayLogsService;
+
+    /**
+     * 查询联系我日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwAppContactWayLogsParam qwAppContactWayLogs)
+    {
+        startPage();
+        List<QwAppContactWayLogsListVO> list = qwAppContactWayLogsService.selectQwAppContactWayLogsListVO(qwAppContactWayLogs);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出联系我日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:export')")
+    @Log(title = "联系我日志", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwAppContactWayLogsParam qwAppContactWayLogs)
+    {
+        List<QwAppContactWayLogsListVO> list = qwAppContactWayLogsService.selectQwAppContactWayLogsListVO(qwAppContactWayLogs);
+        ExcelUtil<QwAppContactWayLogsListVO> util = new ExcelUtil<QwAppContactWayLogsListVO>(QwAppContactWayLogsListVO.class);
+        return util.exportExcel(list, "联系我日志数据");
+    }
+
+    /**
+     * 获取联系我日志详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwAppContactWayLogsService.selectQwAppContactWayLogsById(id));
+    }
+
+    /**
+     * 新增联系我日志
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:add')")
+    @Log(title = "联系我日志", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwAppContactWayLogs qwAppContactWayLogs)
+    {
+        return toAjax(qwAppContactWayLogsService.insertQwAppContactWayLogs(qwAppContactWayLogs));
+    }
+
+    /**
+     * 修改联系我日志
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:edit')")
+    @Log(title = "联系我日志", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwAppContactWayLogs qwAppContactWayLogs)
+    {
+        return toAjax(qwAppContactWayLogsService.updateQwAppContactWayLogs(qwAppContactWayLogs));
+    }
+
+    /**
+     * 删除联系我日志
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwAppContactWayLogs:remove')")
+    @Log(title = "联系我日志", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwAppContactWayLogsService.deleteQwAppContactWayLogsByIds(ids));
+    }
+}

+ 106 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwCompanyController.java

@@ -0,0 +1,106 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwCompany;
+import com.fs.qw.service.IQwCompanyService;
+import com.fs.qw.vo.QwOptionsVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企微主体Controller
+ *
+ * @author fs
+ * @date 2024-10-09
+ */
+@RestController
+@RequestMapping("/qw/qwCompany")
+public class QwCompanyController extends BaseController
+{
+    @Autowired
+    private IQwCompanyService qwCompanyService;
+
+    /**
+     * 查询企微主体列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwCompany qwCompany)
+    {
+        startPage();
+        List<QwCompany> list = qwCompanyService.selectQwCompanyList(qwCompany);
+        return getDataTable(list);
+    }
+
+
+    @GetMapping("/all")
+    public R all()
+    {
+        List<QwOptionsVO> list = qwCompanyService.selectQwCompanyListOptionsVO();
+        return R.ok().put("data", list);
+    }
+    /**
+     * 导出企微主体列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:export')")
+    @Log(title = "企微主体", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwCompany qwCompany)
+    {
+        List<QwCompany> list = qwCompanyService.selectQwCompanyList(qwCompany);
+        ExcelUtil<QwCompany> util = new ExcelUtil<QwCompany>(QwCompany.class);
+        return util.exportExcel(list, "企微主体数据");
+    }
+
+    /**
+     * 获取企微主体详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwCompanyService.selectQwCompanyById(id));
+    }
+
+    /**
+     * 新增企微主体
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:add')")
+    @Log(title = "企微主体", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwCompany qwCompany)
+    {
+        return toAjax(qwCompanyService.insertQwCompany(qwCompany));
+    }
+
+    /**
+     * 修改企微主体
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:edit')")
+    @Log(title = "企微主体", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwCompany qwCompany)
+    {
+        return toAjax(qwCompanyService.updateQwCompany(qwCompany));
+    }
+
+    /**
+     * 删除企微主体
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwCompany:remove')")
+    @Log(title = "企微主体", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwCompanyService.deleteQwCompanyByIds(ids));
+    }
+}

+ 126 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwInformationController.java

@@ -0,0 +1,126 @@
+package com.fs.qw.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.TimeUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwInformation;
+import com.fs.qw.param.QwStatisticsParam;
+import com.fs.qw.service.IQwInformationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 信息流管理Controller
+ *
+ * @author fs
+ * @date 2024-11-11
+ */
+@RestController
+@RequestMapping("/qw/qwInformation")
+public class QwInformationController extends BaseController
+{
+    @Autowired
+    private IQwInformationService qwInformationService;
+
+    /**
+     * 查询信息流管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwInformation qwInformation)
+    {
+        startPage();
+        List<QwInformation> list = qwInformationService.selectQwInformationList(qwInformation);
+        return getDataTable(list);
+    }
+    @GetMapping("/statistics")
+    public R statistics(QwStatisticsParam param)
+    {
+//        List<QwWayStatisticsListVO> list= qwContactWayService.QwWayStatisticsListVO(param);
+        TimeUtils.TimeEntity timeEntity= TimeUtils.parseTime(param.getType().toString(),param.getStartTime(),param.getEndTime());
+        timeEntity.setCompanyId(param.getId());
+        Integer cycleNum = timeEntity.getCycleNum();
+        Integer beginTime = timeEntity.getBeginTime();
+        List<Integer> timeList = new ArrayList<>();
+        for (int i = 1; i <= cycleNum; i++) {
+            timeList.add(beginTime);
+            beginTime = TimeUtils.formatTime(beginTime);
+        }
+        List<JSONObject> jsonObjectList = qwInformationService.selectQwWayStatisticsCounts(timeEntity.toMap());
+        List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
+        List<Integer> addNum = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("addNum")).collect(Collectors.toList());
+        List<Integer> deleteNum = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("deleteNum")).collect(Collectors.toList());
+        List<Integer> num = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("num")).collect(Collectors.toList());
+        return R.ok().put("list",jsonObjectList).put("dates",dates).put("addNum",addNum).put("deleteNum",deleteNum).put("num",num);
+
+    }
+    /**
+     * 导出信息流管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:export')")
+    @Log(title = "信息流管理", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwInformation qwInformation)
+    {
+        List<QwInformation> list = qwInformationService.selectQwInformationList(qwInformation);
+        ExcelUtil<QwInformation> util = new ExcelUtil<QwInformation>(QwInformation.class);
+        return util.exportExcel(list, "信息流管理数据");
+    }
+
+    /**
+     * 获取信息流管理详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwInformationService.selectQwInformationById(id));
+    }
+
+    /**
+     * 新增信息流管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:add')")
+    @Log(title = "信息流管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwInformation qwInformation)
+    {
+        return toAjax(qwInformationService.insertQwInformation(qwInformation));
+    }
+
+    /**
+     * 修改信息流管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:edit')")
+    @Log(title = "信息流管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwInformation qwInformation)
+    {
+        qwInformation.setAddNum(null);
+        qwInformation.setNum(null);
+        qwInformation.setDeleteNum(null);
+        return toAjax(qwInformationService.updateQwInformation(qwInformation));
+    }
+
+    /**
+     * 删除信息流管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwInformation:remove')")
+    @Log(title = "信息流管理", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwInformationService.deleteQwInformationByIds(ids));
+    }
+}

+ 102 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwSopTempController.java

@@ -0,0 +1,102 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.sop.domain.QwSopTemp;
+import com.fs.sop.service.IQwSopTempService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * sop模板Controller
+ *
+ * @author fs
+ * @date 2024-09-26
+ */
+@RestController
+@RequestMapping("/qw/sopTemp")
+public class QwSopTempController extends BaseController
+{
+    @Autowired
+    private IQwSopTempService qwSopTempService;
+    /**
+     * 查询sop模板列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(QwSopTemp qwSopTemp)
+    {
+        startPage();
+        List<QwSopTemp> list = qwSopTempService.selectQwSopTempList(qwSopTemp);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出sop模板列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sopTemp:export')")
+    @Log(title = "sop模板", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwSopTemp qwSopTemp)
+    {
+        List<QwSopTemp> list = qwSopTempService.selectQwSopTempList(qwSopTemp);
+        ExcelUtil<QwSopTemp> util = new ExcelUtil<QwSopTemp>(QwSopTemp.class);
+        return util.exportExcel(list, "sop模板数据");
+    }
+
+    /**
+     * 获取sop模板详细信息
+     */
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(qwSopTempService.selectQwSopTempById(id));
+    }
+
+    /**
+     * 新增sop模板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sopTemp:add')")
+    @Log(title = "sop模板", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwSopTemp qwSopTemp)
+    {
+        return toAjax(qwSopTempService.insertQwSopTemp(qwSopTemp));
+    }
+
+    /**
+     * 修改sop模板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sopTemp:edit')")
+    @Log(title = "sop模板", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwSopTemp qwSopTemp)
+    {
+
+        SimpleDateFormat slf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        qwSopTemp.setUpdateTime(slf.format(new Date()));
+        return toAjax(qwSopTempService.updateQwSopTemp(qwSopTemp));
+    }
+
+    /**
+     * 删除sop模板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sopTemp:remove')")
+    @Log(title = "sop模板", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        ;
+//        qwSopTempService.deleteQwSopTempByIds(ids);
+        return toAjax(qwSopTempService.updateQwSopTempByIds(ids));
+    }
+}

+ 102 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwTagController.java

@@ -0,0 +1,102 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwTag;
+import com.fs.qw.param.QwTagParam;
+import com.fs.qw.service.IQwTagService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企微客户标签Controller
+ *
+ * @author fs
+ * @date 2024-06-20
+ */
+@RestController
+@RequestMapping("/qw/tag")
+public class QwTagController extends BaseController
+{
+    @Autowired
+    private IQwTagService qwTagService;
+    /**
+     * 查询企微客户标签列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(QwTag qwTag)
+    {
+        startPage();
+
+        List<QwTag> list = qwTagService.selectQwTagList(qwTag);
+        return getDataTable(list);
+    }
+
+    @PostMapping("/searchTags")
+    public TableDataInfo  searchTags(@RequestBody QwTagParam tagParam)
+    {
+        return getDataTable(qwTagService.searchTags(tagParam));
+    }
+    /**
+     * 导出企微客户标签列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:tag:export')")
+    @Log(title = "企微客户标签", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwTag qwTag)
+    {
+        List<QwTag> list = qwTagService.selectQwTagList(qwTag);
+        ExcelUtil<QwTag> util = new ExcelUtil<QwTag>(QwTag.class);
+        return util.exportExcel(list, "企微客户标签数据");
+    }
+
+    /**
+     * 获取企微客户标签详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:tag:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwTagService.selectQwTagById(id));
+    }
+
+    /**
+     * 新增企微客户标签
+     */
+    @PreAuthorize("@ss.hasPermi('qw:tag:add')")
+    @Log(title = "企微客户标签", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwTag qwTag)
+    {
+        return toAjax(qwTagService.insertQwTag(qwTag));
+    }
+
+    /**
+     * 修改企微客户标签
+     */
+    @PreAuthorize("@ss.hasPermi('qw:tag:edit')")
+    @Log(title = "企微客户标签", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwTag qwTag)
+    {
+        return toAjax(qwTagService.updateQwTag(qwTag));
+    }
+
+    /**
+     * 删除企微客户标签
+     */
+    @PreAuthorize("@ss.hasPermi('qw:tag:remove')")
+    @Log(title = "企微客户标签", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwTagService.deleteQwTagByIds(ids));
+    }
+}

+ 27 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwUserController.java

@@ -0,0 +1,27 @@
+package com.fs.qw.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.qw.service.IQwUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 企微用户Controller
+ *
+ * @author fs
+ * @date 2024-06-20
+ */
+@RestController
+@RequestMapping("/qw/user")
+public class QwUserController extends BaseController {
+    @Autowired
+    private IQwUserService qwUserService;
+
+    @GetMapping("/getQwUserAll")
+    public AjaxResult getQwUserAll(){
+        return AjaxResult.success(qwUserService.getQwUserAll());
+    }
+}

+ 107 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwWorkLinkController.java

@@ -0,0 +1,107 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwWorkLink;
+import com.fs.qw.service.IQwWorkLinkService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企微获客链接管理Controller
+ *
+ * @author fs
+ * @date 2025-01-10
+ */
+@RestController
+@RequestMapping("/qw/workLink")
+public class QwWorkLinkController extends BaseController
+{
+    @Autowired
+    private IQwWorkLinkService qwWorkLinkService;
+
+    /**
+     * 查询企微获客链接管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwWorkLink qwWorkLink)
+    {
+        startPage();
+        List<QwWorkLink> list = qwWorkLinkService.selectQwWorkLinkList(qwWorkLink);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询企微获客链接管理列表-不分页
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:listAll')")
+    @GetMapping("/listAll")
+    public AjaxResult listAll(QwWorkLink qwWorkLink)
+    {
+        List<QwWorkLink> qwWorkLinks = qwWorkLinkService.selectQwWorkLinkListAll(qwWorkLink);
+        return AjaxResult.success(qwWorkLinks);
+    }
+
+    /**
+     * 导出企微获客链接管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:export')")
+    @Log(title = "企微获客链接管理", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwWorkLink qwWorkLink)
+    {
+        List<QwWorkLink> list = qwWorkLinkService.selectQwWorkLinkList(qwWorkLink);
+        ExcelUtil<QwWorkLink> util = new ExcelUtil<QwWorkLink>(QwWorkLink.class);
+        return util.exportExcel(list, "企微获客链接管理数据");
+    }
+
+    /**
+     * 获取企微获客链接管理详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwWorkLinkService.selectQwWorkLinkById(id));
+    }
+
+    /**
+     * 新增企微获客链接管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:add')")
+    @Log(title = "企微获客链接管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwWorkLink qwWorkLink)
+    {
+        return toAjax(qwWorkLinkService.insertQwWorkLink(qwWorkLink));
+    }
+
+    /**
+     * 修改企微获客链接管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:edit')")
+    @Log(title = "企微获客链接管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwWorkLink qwWorkLink){
+        return toAjax(qwWorkLinkService.updateQwWorkLink(qwWorkLink));
+    }
+
+    /**
+     * 删除企微获客链接管理
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLink:remove')")
+    @Log(title = "企微获客链接管理", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwWorkLinkService.deleteQwWorkLinkByIds(ids));
+    }
+}

+ 97 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwWorkLinkUserController.java

@@ -0,0 +1,97 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwWorkLinkUser;
+import com.fs.qw.service.IQwWorkLinkUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企微获客链接用户关联Controller
+ *
+ * @author fs
+ * @date 2025-01-10
+ */
+@RestController
+@RequestMapping("/qw/workLinkUser")
+public class QwWorkLinkUserController extends BaseController
+{
+    @Autowired
+    private IQwWorkLinkUserService qwWorkLinkUserService;
+
+    /**
+     * 查询企微获客链接用户关联列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwWorkLinkUser qwWorkLinkUser)
+    {
+        startPage();
+        List<QwWorkLinkUser> list = qwWorkLinkUserService.selectQwWorkLinkUserList(qwWorkLinkUser);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出企微获客链接用户关联列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:export')")
+    @Log(title = "企微获客链接用户关联", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwWorkLinkUser qwWorkLinkUser)
+    {
+        List<QwWorkLinkUser> list = qwWorkLinkUserService.selectQwWorkLinkUserList(qwWorkLinkUser);
+        ExcelUtil<QwWorkLinkUser> util = new ExcelUtil<QwWorkLinkUser>(QwWorkLinkUser.class);
+        return util.exportExcel(list, "企微获客链接用户关联数据");
+    }
+
+    /**
+     * 获取企微获客链接用户关联详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwWorkLinkUserService.selectQwWorkLinkUserById(id));
+    }
+
+    /**
+     * 新增企微获客链接用户关联
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:add')")
+    @Log(title = "企微获客链接用户关联", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwWorkLinkUser qwWorkLinkUser)
+    {
+        return toAjax(qwWorkLinkUserService.insertQwWorkLinkUser(qwWorkLinkUser));
+    }
+
+    /**
+     * 修改企微获客链接用户关联
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:edit')")
+    @Log(title = "企微获客链接用户关联", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwWorkLinkUser qwWorkLinkUser)
+    {
+        return toAjax(qwWorkLinkUserService.updateQwWorkLinkUser(qwWorkLinkUser));
+    }
+
+    /**
+     * 删除企微获客链接用户关联
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workLinkUser:remove')")
+    @Log(title = "企微获客链接用户关联", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwWorkLinkUserService.deleteQwWorkLinkUserByIds(ids));
+    }
+}

+ 110 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwWorkUserController.java

@@ -0,0 +1,110 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwWorkUser;
+import com.fs.qw.service.IQwWorkUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企微获客添加的用户Controller
+ *
+ * @author fs
+ * @date 2025-01-10
+ */
+@RestController
+@RequestMapping("/qw/workUser")
+public class QwWorkUserController extends BaseController
+{
+    @Autowired
+    private IQwWorkUserService qwWorkUserService;
+
+    /**
+     * 查询企微获客添加的用户列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwWorkUser qwWorkUser)
+    {
+        startPage();
+        List<QwWorkUser> list = qwWorkUserService.selectQwWorkUserList(qwWorkUser);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出企微获客添加的用户列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:export')")
+    @Log(title = "企微获客添加的用户", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwWorkUser qwWorkUser)
+    {
+        List<QwWorkUser> list = qwWorkUserService.selectQwWorkUserList(qwWorkUser);
+        ExcelUtil<QwWorkUser> util = new ExcelUtil<QwWorkUser>(QwWorkUser.class);
+        return util.exportExcel(list, "企微获客添加的用户数据");
+    }
+
+    /**
+     * 获取企微获客添加的用户详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwWorkUserService.selectQwWorkUserById(id));
+    }
+
+    /**
+     * 新增企微获客添加的用户
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:add')")
+    @Log(title = "企微获客添加的用户", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwWorkUser qwWorkUser)
+    {
+        return toAjax(qwWorkUserService.insertQwWorkUser(qwWorkUser));
+    }
+
+    /**
+     * 修改企微获客添加的用户
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:edit')")
+    @Log(title = "企微获客添加的用户", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwWorkUser qwWorkUser)
+    {
+        return toAjax(qwWorkUserService.updateQwWorkUser(qwWorkUser));
+    }
+
+    /**
+     * 删除企微获客添加的用户
+     */
+    @PreAuthorize("@ss.hasPermi('qw:workUser:remove')")
+    @Log(title = "企微获客添加的用户", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwWorkUserService.deleteQwWorkUserByIds(ids));
+    }
+
+
+//    @GetMapping("/syncUsers")
+    public R syncUsers(){
+        qwWorkUserService.syncUsers();
+        return R.ok();
+    }
+//    @GetMapping("/uploadBd")
+    public R uploadBd(){
+        qwWorkUserService.uploadBd();
+        return R.ok();
+    }
+}

+ 54 - 0
fs-admin/src/main/java/com/fs/qw/controller/SopUserLogsController.java

@@ -0,0 +1,54 @@
+package com.fs.qw.controller;
+
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.qw.param.SopUserLogsVO;
+import com.fs.sop.params.SopUserLogsParam;
+import com.fs.sop.service.ISopUserLogsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * sopUserLogsController
+ *
+ * @author fs
+ * @date 2024-12-27
+ */
+@RestController
+@RequestMapping("/qwSop/sopUserLogs")
+public class SopUserLogsController extends BaseController
+{
+    @Autowired
+    private ISopUserLogsService sopUserLogsService;
+
+    /**
+     * 查询sopUserLogs列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(SopUserLogsParam sopUserLogs)
+    {
+        startPage();
+        List<SopUserLogsVO> list = sopUserLogsService.selectSopUserLogsList(sopUserLogs);
+        return getDataTable(list);
+    }
+
+
+    /**
+     * 获取sopUserLogs详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sop:list')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(sopUserLogsService.selectSopUserLogsById(id));
+    }
+
+}

+ 72 - 0
fs-admin/src/main/java/com/fs/qw/controller/SopUserLogsInfoController.java

@@ -0,0 +1,72 @@
+package com.fs.qw.controller;
+
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.sop.domain.SopUserLogsInfo;
+import com.fs.sop.params.SendUserLogsInfoMsgParam;
+import com.fs.sop.service.ISopUserLogsInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * sopUserLogsInfoController
+ *
+ * @author fs
+ * @date 2024-12-27
+ */
+@RestController
+@RequestMapping("/qwSop/sopUserLogsInfo")
+public class SopUserLogsInfoController extends BaseController
+{
+    @Autowired
+    private ISopUserLogsInfoService sopUserLogsInfoService;
+
+    /**
+     * 查询sopUserLogsInfo列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(SopUserLogsInfo sopUserLogsInfo)
+    {
+        startPage();
+        List<SopUserLogsInfo> list = sopUserLogsInfoService.selectSopUserLogsInfoList(sopUserLogsInfo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取sopUserLogsInfo详细信息
+     */
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(sopUserLogsInfoService.selectSopUserLogsInfoById(id));
+    }
+
+    /**
+     * 修改sopUserLogsInfo
+     */
+    @Log(title = "updateSopUserLogsInfo", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody SopUserLogsInfo sopUserLogsInfo)
+    {
+        return sopUserLogsInfoService.updateSopUserLogsInfoToTime(sopUserLogsInfo);
+    }
+
+    /**
+     * 一键群发sopUserLogsInfo
+     */
+    @PreAuthorize("@ss.hasPermi('qw:sopUserLogsInfo:msg')")
+    @Log(title = "sendMsgSopUserLogsInfo", businessType = BusinessType.INSERT,isSaveRequestData=false)
+    @PostMapping("/sendUserLogsInfoMsg")
+    public R sendUserLogsInfoMsg(@RequestBody SendUserLogsInfoMsgParam param)
+    {
+        return sopUserLogsInfoService.sendUserLogsInfoMsg(param);
+    }
+}

+ 126 - 0
fs-admin/src/main/java/com/fs/qw/qwTask/qwTask.java

@@ -0,0 +1,126 @@
+package com.fs.qw.qwTask;
+
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.qw.mapper.QwCompanyMapper;
+import com.fs.qw.service.IQwExternalContactService;
+import com.fs.qw.service.IQwGroupMsgService;
+import com.fs.qw.service.impl.QwUserServiceImpl;
+import com.fs.qw.vo.QwOptionsVO;
+import com.fs.sop.service.ISopUserLogsService;
+import com.fs.sop.service.impl.QwSopLogsServiceImpl;
+import com.fs.sop.service.impl.QwSopServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component("qwTask")
+public class qwTask {
+
+    @Autowired
+    private QwSopServiceImpl qwSopService;
+
+    @Autowired
+    private QwSopLogsServiceImpl qwSopLogsService;
+
+    @Autowired
+    private IQwGroupMsgService qwGroupMsgService;
+
+    @Autowired
+    private ISopUserLogsService sopUserLogsService;
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+    @Autowired
+    private QwUserServiceImpl qwUserServiceImpl;
+    @Autowired
+    QwCompanyMapper qwCompanyMapper;
+
+    @Autowired
+    private IFsUserCourseService iFsUserCourseService;
+
+    //正在使用
+    public void qwExternalContact()
+    {
+        qwExternalContactService.qwExternalContactSync();
+    }
+    public void syncQwUser()
+    {  List<QwOptionsVO> vos = qwCompanyMapper.selectQwCompanyListOptionsVO();
+        for (QwOptionsVO vo : vos) {
+            qwUserServiceImpl.syncQwUser(vo.getCorpId());
+        }
+
+    }
+    //正在使用
+    public void qwExternalContactAddAndDel()
+    {
+        qwExternalContactService.qwExternalContactSyncAddAndDel();
+    }
+    //正在使用
+    public void qwExternalContactSyncAddRedis()
+    {
+        qwExternalContactService.qwExternalContactSyncAddRedis();
+    }
+    //正在使用
+    public void qwExternalContactAddRedis()
+    {
+        qwExternalContactService.qwExternalContactAddRedis();
+    }
+    //正在使用
+    public void qwExternalContactAddAndDelByRedis()
+    {
+        qwExternalContactService.qwExternalContactAddAndDelByRedis();
+    }
+    //正在使用
+    public void qwExternalContactAddTag()
+    {
+        qwExternalContactService.qwExternalContactAddCourseTag();
+    }
+
+    /**
+    * 定时任务 将 qw_sop任务 符合条件的录入到sop_user_Logs(clickHouse)
+    */
+    public void qwCheckSopRuleTime()
+    {
+        qwSopService.checkSopRuleTime();
+    }
+
+    /**
+    * 定时任务 将 clickHouse的sopUserLogs(营期表)按每小时的巡回 录入clickHouse的qw_sop_logs(消息发送表)
+    */
+    public void selectSopUserLogsListByTime(){
+        sopUserLogsService.selectSopUserLogsListByTime();
+    }
+
+    /**
+    * 定时 发送 通过调用 企业微信接口 发送的 SOP 群发消息
+    */
+    public void SendQwApiSopLogTimer(){
+        qwSopLogsService.checkQwSopLogs();
+    }
+
+    /**
+    * 定时获取 通过调用 企业微信接口 发送的 SOP 客户群发消息 的反馈结果
+    */
+    public void GetQwApiSopLogResultTimer(){
+        qwSopLogsService.qwSopLogsResult();
+    }
+
+    /**
+    * 定时群发API接口的 客户/群 群发
+    */
+    public void sendQwGroupMsgTask(){
+        qwGroupMsgService.qwGroupMsgTask();
+    }
+
+    /**
+    *  定时更新 待发送中已经算过期了的不能发的消息
+    */
+    public void updateQwSopLogsBySendStatusTask(){
+        qwSopLogsService.updateQwSopLogsBySendStatus();
+    }
+
+    /**
+     * 2天跑一次 将 课程的封面 上传企业微信 并上传到redis
+     */
+
+}

+ 3 - 3
fs-admin/src/main/resources/application-dev.yml

@@ -83,9 +83,9 @@ spring:
             druid:
             druid:
                 # 主库数据源
                 # 主库数据源
                 master:
                 master:
-                    url: jdbc:mysql://42.194.245.189:3306/test_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: root
-                    password: YJF_2024
+                    url: jdbc:mysql://139.186.77.83:3306/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: Rtroot
+                    password: Rtroot
                 # 初始连接数
                 # 初始连接数
                 initialSize: 5
                 initialSize: 5
                 # 最小连接池数量
                 # 最小连接池数量

+ 3 - 3
fs-company/src/main/resources/application-dev.yml

@@ -81,9 +81,9 @@ spring:
             druid:
             druid:
                 # 主库数据源
                 # 主库数据源
                 master:
                 master:
-                    url: jdbc:mysql://42.194.245.189:3306/test_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: root
-                    password: YJF_2024
+                    url: jdbc:mysql://139.186.77.83:3306/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: Rtroot
+                    password: Rtroot
                 # 初始连接数
                 # 初始连接数
                 initialSize: 5
                 initialSize: 5
                 # 最小连接池数量
                 # 最小连接池数量

+ 9 - 24
fs-qw-api/src/main/resources/application-dev.yml

@@ -6,12 +6,10 @@ spring:
         host: localhost
         host: localhost
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
-        # 数据库索引
-        database: 0
         # 密码
         # 密码
         password:
         password:
         # 连接超时时间
         # 连接超时时间
-        timeout: 20s
+        timeout: 10s
         lettuce:
         lettuce:
             pool:
             pool:
                 # 连接池中的最小空闲连接
                 # 连接池中的最小空闲连接
@@ -23,33 +21,21 @@ spring:
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 max-wait: -1ms
                 max-wait: -1ms
     datasource:
     datasource:
-        clickhouse:
-            type: com.alibaba.druid.pool.DruidDataSource
-#            driverClassName: ru.yandex.clickhouse.ClickHouseDriver
-            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
-            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
-            username: default
-            password: rt2024
-            initialSize: 10
-            maxActive: 100
-            minIdle: 10
-            maxWait: 6000
         mysql:
         mysql:
             type: com.alibaba.druid.pool.DruidDataSource
             type: com.alibaba.druid.pool.DruidDataSource
             driverClassName: com.mysql.cj.jdbc.Driver
             driverClassName: com.mysql.cj.jdbc.Driver
             druid:
             druid:
                 # 主库数据源
                 # 主库数据源
                 master:
                 master:
-                    url: jdbc:mysql://42.194.245.189:3306/rt_fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: root
-                    password: YJF_2024
+                    url: jdbc:mysql://139.186.77.83:3306/ylrz_scrm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: Rtroot
+                    password: Rtroot
                 # 从库数据源
                 # 从库数据源
                 slave:
                 slave:
                     # 从数据源开关/默认关闭
                     # 从数据源开关/默认关闭
-                    enabled: false
-                    url:
-                    username:
-                    password:
+                    url: jdbc:mysql://139.186.77.83:3306/ylrz_scrm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: Rtroot
+                    password: Rtroot
                 # 初始连接数
                 # 初始连接数
                 initialSize: 5
                 initialSize: 5
                 # 最小连接池数量
                 # 最小连接池数量
@@ -77,8 +63,8 @@ spring:
                     allow:
                     allow:
                     url-pattern: /druid/*
                     url-pattern: /druid/*
                     # 控制台管理用户名和密码
                     # 控制台管理用户名和密码
-                    login-username: fs
-                    login-password: 123456
+                    login-username:
+                    login-password:
                 filter:
                 filter:
                     stat:
                     stat:
                         enabled: true
                         enabled: true
@@ -148,4 +134,3 @@ rocketmq:
         group: test-group
         group: test-group
         access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
         access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
         secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
         secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
-

+ 0 - 57
fs-qw-api/src/main/resources/application-druid-bly.yml

@@ -1,57 +0,0 @@
-# 数据源配置
-spring:
-    datasource:
-        type: com.alibaba.druid.pool.DruidDataSource
-        driverClassName: com.mysql.cj.jdbc.Driver
-        druid:
-            # 主库数据源
-            master:
-                url: jdbc:mysql://cq-cdb-95qvu08p.sql.tencentcdb.com:63998/fs_his_rt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                username: root
-                password: Rtyy_2023
-            # 从库数据源
-            slave:
-                # 从数据源开关/默认关闭
-                enabled: false
-                url:
-                username:
-                password:
-            # 初始连接数
-            initialSize: 5
-            # 最小连接池数量
-            minIdle: 10
-            # 最大连接池数量
-            maxActive: 20
-            # 配置获取连接等待超时的时间
-            maxWait: 60000
-            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-            timeBetweenEvictionRunsMillis: 60000
-            # 配置一个连接在池中最小生存的时间,单位是毫秒
-            minEvictableIdleTimeMillis: 300000
-            # 配置一个连接在池中最大生存的时间,单位是毫秒
-            maxEvictableIdleTimeMillis: 900000
-            # 配置检测连接是否有效
-            validationQuery: SELECT 1 FROM DUAL
-            testWhileIdle: true
-            testOnBorrow: false
-            testOnReturn: false
-            webStatFilter:
-                enabled: true
-            statViewServlet:
-                enabled: true
-                # 设置白名单,不填则允许所有访问
-                allow:
-                url-pattern: /druid/*
-                # 控制台管理用户名和密码
-                login-username: fs
-                login-password: 123456
-            filter:
-                stat:
-                    enabled: true
-                    # 慢SQL记录
-                    log-slow-sql: true
-                    slow-sql-millis: 1000
-                    merge-sql: true
-                wall:
-                    config:
-                        multi-statement-allow: true

+ 0 - 91
fs-qw-api/src/main/resources/application-druid.yml

@@ -1,91 +0,0 @@
-# 数据源配置
-spring:
-    # redis 配置
-    redis:
-        # 地址  localhost
-        host: 127.0.0.1
-        # 端口,默认为6379
-        port: 6379
-        # 数据库索引
-        database: 0
-        # 密码
-        password:
-        #        password:
-        # 连接超时时间
-        timeout: 10s
-        lettuce:
-            pool:
-                # 连接池中的最小空闲连接
-                min-idle: 0
-                # 连接池中的最大空闲连接
-                max-idle: 8
-                # 连接池的最大数据库连接数
-                max-active: 8
-                # #连接池最大阻塞等待时间(使用负值表示没有限制)
-                max-wait: -1ms
-    datasource:
-        clickhouse:
-            type: com.alibaba.druid.pool.DruidDataSource
-            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
-            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
-            username: rt_2024
-            password: Yzx_19860213
-            initialSize: 10
-            maxActive: 100
-            minIdle: 10
-            maxWait: 6000
-        mysql:
-            type: com.alibaba.druid.pool.DruidDataSource
-            driverClassName: com.mysql.cj.jdbc.Driver
-            druid:
-                # 主库数据源
-                master:
-                    url: jdbc:mysql://cq-cdb-95qvu08p.sql.tencentcdb.com:63998/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: root
-                    password: Rtyy_2023
-                # 从库数据源
-                slave:
-                    # 从数据源开关/默认关闭
-                    enabled: false
-                    url:
-                    username:
-                    password:
-                # 初始连接数
-                initialSize: 5
-                # 最小连接池数量
-                minIdle: 10
-                # 最大连接池数量
-                maxActive: 20
-                # 配置获取连接等待超时的时间
-                maxWait: 60000
-                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-                timeBetweenEvictionRunsMillis: 60000
-                # 配置一个连接在池中最小生存的时间,单位是毫秒
-                minEvictableIdleTimeMillis: 300000
-                # 配置一个连接在池中最大生存的时间,单位是毫秒
-                maxEvictableIdleTimeMillis: 900000
-                # 配置检测连接是否有效
-                validationQuery: SELECT 1 FROM DUAL
-                testWhileIdle: true
-                testOnBorrow: false
-                testOnReturn: false
-                webStatFilter:
-                    enabled: true
-                statViewServlet:
-                    enabled: true
-                    # 设置白名单,不填则允许所有访问
-                    allow:
-                    url-pattern: /druid/*
-                    # 控制台管理用户名和密码
-                    login-username: fs
-                    login-password: 123456
-                filter:
-                    stat:
-                        enabled: true
-                        # 慢SQL记录
-                        log-slow-sql: true
-                        slow-sql-millis: 1000
-                        merge-sql: true
-                    wall:
-                        config:
-                            multi-statement-allow: true

+ 64 - 17
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -2,10 +2,14 @@ package com.fs.app.taskService.impl;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.common.utils.BatchUtils;
 import com.fs.common.utils.BatchUtils;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyUserService;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.*;
 import com.fs.course.domain.*;
 import com.fs.course.mapper.FsCourseDomainNameMapper;
 import com.fs.course.mapper.FsCourseDomainNameMapper;
@@ -17,6 +21,7 @@ import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.QwSopRuleTimeVO;
 import com.fs.qw.vo.QwSopTempSetting;
 import com.fs.qw.vo.QwSopTempSetting;
@@ -78,6 +83,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private QwSopTagMapper qwSopTagMapper ;
     private QwSopTagMapper qwSopTagMapper ;
     @Autowired
     @Autowired
     private QwSopMapper sopMapper;
     private QwSopMapper sopMapper;
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
 
 
     @Autowired
     @Autowired
     private FsCourseWatchLogMapper fsCourseWatchLogMapper;
     private FsCourseWatchLogMapper fsCourseWatchLogMapper;
@@ -122,6 +129,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     @Autowired
     @Autowired
     private QwSopTempMapper qwSopTempMapper;
     private QwSopTempMapper qwSopTempMapper;
 
 
+    @Autowired
+    private ICompanyUserService companyUserService;
 
 
     @PostConstruct
     @PostConstruct
     public void init() {
     public void init() {
@@ -244,7 +253,35 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             return;
             return;
         }
         }
 
 
+        // 查询销售二级域名
+        Set<Long> ids = sopUserLogsVos.stream().map(s -> {
+            String[] userKey = s.getUserId().split("\\|");
+            if (userKey.length < 3) {
+                return null;
+            }
+            return Long.parseLong(userKey[1]);
+        }).filter(Objects::nonNull).collect(Collectors.toSet());
+        List<CompanyUser> companyUserList;
+        if (ids.isEmpty()) {
+            companyUserList = new ArrayList<>();
+        } else {
+            companyUserList = companyUserService.selectCompanyUserByIds(ids);
+        }
+
         Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
         Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
+                .peek(s -> {
+                    String[] userKey = s.getUserId().split("\\|");
+                    if (userKey.length < 3) {
+                        return;
+                    }
+
+                    // 销售ID
+                    Long companyUserId = Long.parseLong(userKey[1]);
+                    CompanyUser companyUser = companyUserList.stream().filter(cu -> Objects.equals(cu.getUserId(), companyUserId)).findFirst().orElse(null);
+                    if (Objects.nonNull(companyUser)) {
+                        s.setDomain(companyUser.getDomain());
+                    }
+                })
                 .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
                 .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
 
 
         log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
         log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
@@ -465,6 +502,25 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         userLogsInfo.setUserLogsId(logVo.getId());
                         userLogsInfo.setUserLogsId(logVo.getId());
 
 
                         List<SopUserLogsInfo> sopUserLogsInfos = sopUserLogsInfoMapper.selectSopUserLogsInfoList(userLogsInfo);
                         List<SopUserLogsInfo> sopUserLogsInfos = sopUserLogsInfoMapper.selectSopUserLogsInfoList(userLogsInfo);
+                        if(logVo.getIsRegister() == 1){
+                            List<Long> externalContactIdList = PubFun.listToNewList(sopUserLogsInfos, SopUserLogsInfo::getExternalId);
+                            List<QwExternalContact> list = qwExternalContactService.list(new QueryWrapper<QwExternalContact>().isNotNull("fs_user_id").in("id", externalContactIdList));
+                            Map<Long, QwExternalContact> map = PubFun.listToMapByGroupObject(list, QwExternalContact::getId);
+                            sopUserLogsInfos = sopUserLogsInfos.stream().filter(e -> map.containsKey(e.getExternalId())).collect(Collectors.toList());
+                        }
+
+
+                        // 获取fsUserId
+                        Set<Long> externalIds = sopUserLogsInfos.stream().map(SopUserLogsInfo::getExternalId).collect(Collectors.toSet());
+                        if (!externalIds.isEmpty()) {
+                            List<QwExternalContact> externalContactList = qwExternalContactService.list(Wrappers.<QwExternalContact>lambdaQuery().in(QwExternalContact::getId, externalIds));
+                            sopUserLogsInfos.forEach(s -> {
+                                QwExternalContact qwExternalContact = externalContactList.stream().filter(e -> Objects.equals(s.getExternalId(), e.getId())).findFirst().orElse(null);
+                                if (Objects.nonNull(qwExternalContact)) {
+                                    s.setFsUserId(qwExternalContact.getFsUserId());
+                                }
+                            });
+                        }
 
 
                         insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content);
                         insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content);
 
 
@@ -570,7 +626,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 Long fsUserId = contactId.getFsUserId();
                 Long fsUserId = contactId.getFsUserId();
                 QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId);
                 QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId);
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        type, qwUserId, companyUserId, companyId, externalId);
+                        type, qwUserId, companyUserId, companyId, externalId, fsUserId);
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
                 log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
             }
             }
@@ -622,14 +678,14 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
     private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       Long videoId, int type, String qwUserId,
                                       Long videoId, int type, String qwUserId,
-                                      String companyUserId, String companyId, String externalId) {
+                                      String companyUserId, String companyId, String externalId, Long fsUserId) {
         switch (type) {
         switch (type) {
             case 1:
             case 1:
                 handleNormalMessage(sopLogs, content,companyUserId);
                 handleNormalMessage(sopLogs, content,companyUserId);
                 break;
                 break;
             case 2:
             case 2:
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        qwUserId, companyUserId, companyId, externalId);
+                        qwUserId, companyUserId, companyId, externalId, fsUserId);
                 break;
                 break;
             case 3:
             case 3:
                 handleOrderMessage(sopLogs, content);
                 handleOrderMessage(sopLogs, content);
@@ -661,7 +717,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
     private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      Long videoId, String qwUserId, String companyUserId,
                                      Long videoId, String qwUserId, String companyUserId,
-                                     String companyId, String externalId) {
+                                     String companyId, String externalId, Long fsUserId) {
         // 深拷贝 Content 对象,避免使用 JSON
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
         if (clonedContent == null) {
@@ -684,7 +740,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             if ("1".equals(setting.getIsBindUrl())&&("3".equals(setting.getContentType())||"1".equals(setting.getContentType()))) {
             if ("1".equals(setting.getIsBindUrl())&&("3".equals(setting.getContentType())||"1".equals(setting.getContentType()))) {
                 addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
                 addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
                 String sortLink = generateShortLink(setting, logVo, sendTime, courseId, videoId,
                 String sortLink = generateShortLink(setting, logVo, sendTime, courseId, videoId,
-                        qwUserId, companyUserId, companyId, externalId);
+                        qwUserId, companyUserId, companyId, externalId, fsUserId);
                 if (StringUtils.isNotEmpty(sortLink)) {
                 if (StringUtils.isNotEmpty(sortLink)) {
                     if ("3".equals(setting.getContentType())) {
                     if ("3".equals(setting.getContentType())) {
                         setting.setLinkUrl(sortLink);
                         setting.setLinkUrl(sortLink);
@@ -725,7 +781,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
     private String generateShortLink(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
     private String generateShortLink(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
                                      Long courseId, Long videoId, String qwUserId,
                                      Long courseId, Long videoId, String qwUserId,
-                                     String companyUserId, String companyId, String externalId) {
+                                     String companyUserId, String companyId, String externalId, Long fsUserId) {
         // 获取缓存的配置
         // 获取缓存的配置
         CourseConfig config;
         CourseConfig config;
         synchronized(configLock) {
         synchronized(configLock) {
@@ -757,6 +813,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         courseMap.setCourseId(link.getCourseId());
         courseMap.setCourseId(link.getCourseId());
         courseMap.setQwExternalId(link.getQwExternalId());
         courseMap.setQwExternalId(link.getQwExternalId());
         courseMap.setLinkType(0);
         courseMap.setLinkType(0);
+        courseMap.setFsUserId(fsUserId);
 
 
         String courseJson = JSON.toJSONString(courseMap);
         String courseJson = JSON.toJSONString(courseMap);
         String realLinkFull = REAL_LINK_PREFIX + courseJson;
         String realLinkFull = REAL_LINK_PREFIX + courseJson;
@@ -777,17 +834,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         Date updateTime = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
         Date updateTime = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
         link.setUpdateTime(updateTime);
         link.setUpdateTime(updateTime);
 
 
-        // 从缓存中随机选择一个域名
-        FsCourseDomainName fsCourseDomainName;
-        if (cachedDomainNames == null || cachedDomainNames.isEmpty()) {
-            log.error("No domain names available for short link generation.");
-            return "";
-        }
-
-        int randomIndex = ThreadLocalRandom.current().nextInt(cachedDomainNames.size());
-        fsCourseDomainName = cachedDomainNames.get(randomIndex);
-
-        String sortLink = "https://" + fsCourseDomainName.getDomainName() + "/s/" + link.getLink();
+        String sortLink = "https://" + logVo.getDomain() + "/s/" + link.getLink();
         enqueueCourseLink(link);
         enqueueCourseLink(link);
         return sortLink;
         return sortLink;
     }
     }

+ 4 - 6
fs-service-system/pom.xml

@@ -16,11 +16,9 @@
     </description>
     </description>
 
 
     <properties>
     <properties>
-        <weixin-java-cp.version>4.4.0</weixin-java-cp.version>
-        <weixin-java-miniapp.version>4.4.0</weixin-java-miniapp.version>
-        <weixin-java-cp.version>4.4.0</weixin-java-cp.version>
-        <weixin-java-miniapp.version>4.4.0</weixin-java-miniapp.version>
-        <weixin-java-mp.version>4.4.0</weixin-java-mp.version>
+        <weixin-java-cp.version>4.7.0</weixin-java-cp.version>
+        <weixin-java-miniapp.version>4.7.0</weixin-java-miniapp.version>
+        <weixin-java-mp.version>4.7.0</weixin-java-mp.version>
     </properties>
     </properties>
     <dependencies>
     <dependencies>
         <!-- 通用工具-->
         <!-- 通用工具-->
@@ -89,7 +87,7 @@
         <dependency>
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-pay</artifactId>
             <artifactId>weixin-java-pay</artifactId>
-            <version>4.6.5.B</version>
+            <version>4.7.2.B</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <groupId>com.github.binarywang</groupId>

+ 8 - 0
fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java

@@ -15,6 +15,7 @@ import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 import org.apache.ibatis.annotations.Update;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.Set;
 
 
 /**
 /**
  * 物业公司管理员信息Mapper接口
  * 物业公司管理员信息Mapper接口
@@ -248,5 +249,12 @@ public interface CompanyUserMapper
     @Select("select * from company_user where company_id=#{companyId} and del_flag=0")
     @Select("select * from company_user where company_id=#{companyId} and del_flag=0")
     List<CompanyUser> selectCompanyUserByCompanyId(Long companyId);
     List<CompanyUser> selectCompanyUserByCompanyId(Long companyId);
 
 
+    /**
+     * 查询公司销售列表
+     * @param ids 销售ID集合
+     * @return  list
+     */
+    List<CompanyUser> selectCompanyUserByIds(Set<Long> ids);
+
     List<CompanyUser> selectAllCompanyUserByParentId(Long parentId);
     List<CompanyUser> selectAllCompanyUserByParentId(Long parentId);
 }
 }

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

@@ -12,6 +12,7 @@ import com.fs.his.vo.OptionsVO;;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.Set;
 
 
 /**
 /**
  * 物业公司管理员信息Service接口
  * 物业公司管理员信息Service接口
@@ -127,5 +128,12 @@ public interface ICompanyUserService {
 
 
     CompanyUser selectCompanyUserByUserId(Long userId);
     CompanyUser selectCompanyUserByUserId(Long userId);
 
 
+    /**
+     * 查询公司销售列表
+     * @param ids 销售ID集合
+     * @return  list
+     */
+    List<CompanyUser> selectCompanyUserByIds(Set<Long> ids);
+
     List<CompanyUser> selectAllCompanyUserByParentId(Long parentId);
     List<CompanyUser> selectAllCompanyUserByParentId(Long parentId);
 }
 }

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

@@ -386,6 +386,16 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.selectCompanyUserByUserId(userId);
         return companyUserMapper.selectCompanyUserByUserId(userId);
     }
     }
 
 
+    /**
+     * 查询公司销售列表
+     * @param ids 销售ID集合
+     * @return  list
+     */
+    @Override
+    public List<CompanyUser> selectCompanyUserByIds(Set<Long> ids) {
+        return companyUserMapper.selectCompanyUserByIds(ids);
+    }
+
     @Override
     @Override
     public  List<CompanyUser> selectAllCompanyUserByParentId(Long parentId) {
     public  List<CompanyUser> selectAllCompanyUserByParentId(Long parentId) {
         return companyUserMapper.selectAllCompanyUserByParentId(parentId);
         return companyUserMapper.selectAllCompanyUserByParentId(parentId);

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

@@ -16,5 +16,6 @@ public class CourseConfig implements Serializable {
     private String realLinkDomainName;//真链域名
     private String realLinkDomainName;//真链域名
     private String courseDomainName;//链接域名
     private String courseDomainName;//链接域名
     private Integer rewardType; // 奖励类型 1红包 2积分
     private Integer rewardType; // 奖励类型 1红包 2积分
+    private Integer redPacketMode;//红包模式 1总公司 2销售公司
 
 
 }
 }

+ 3 - 1
fs-service-system/src/main/java/com/fs/course/config/RedPacketConfig.java

@@ -6,7 +6,9 @@ import java.io.Serializable;
 
 
 @Data
 @Data
 public class RedPacketConfig implements Serializable {
 public class RedPacketConfig implements Serializable {
-    private String appId;
+    private String appId;//公众号appId
+
+    private String miniappId;//小程序appId
     /**
     /**
      * 商户号.
      * 商户号.
      */
      */

+ 5 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseRealLink.java

@@ -29,4 +29,9 @@ public class FsCourseRealLink implements Serializable
 
 
     private Long linkId;
     private Long linkId;
 
 
+    /**
+     * 用户ID (fs_user表)
+     */
+    private Long fsUserId;
+
 }
 }

+ 109 - 84
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.course.service.impl;
 package com.fs.course.service.impl;
 
 
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.BeanCopyUtils;
@@ -561,110 +562,134 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Override
     @Override
     @Transactional
     @Transactional
     public R sendReward(FsCourseSendRewardUParam param) {
     public R sendReward(FsCourseSendRewardUParam param) {
+        // 获取用户信息
         FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
         FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
-        if (StringUtils.isEmpty(user.getMpOpenId())){
-            return R.error("未识别到领取信息");
-        }
+//        if (StringUtils.isEmpty(user.getMpOpenId())){
+//            return R.error("未识别到领取信息");
+//        }
         FsCourseWatchLog log = new FsCourseWatchLog();
         FsCourseWatchLog log = new FsCourseWatchLog();
 
 
-        //判断链接类型
-        if (param.getLinkType()!=null&&param.getLinkType()==1){
-            FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(),param.getUserId());
-            if (packetLog!=null){
+        // 根据链接类型判断是否已发放奖励
+        if (param.getLinkType() != null && param.getLinkType() == 1) {
+            FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
+            if (packetLog != null) {
                 return R.error("奖励已发放");
                 return R.error("奖励已发放");
             }
             }
-        }else {
-            log = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(),param.getVideoId(),param.getQwUserId(),param.getQwExternalId());
-            if (log==null){
+        } else {
+            log = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
+            if (log == null) {
                 return R.error("无记录");
                 return R.error("无记录");
             }
             }
-            if (log.getRewardType()!=null){
+            if (log.getRewardType() != null) {
                 return R.error("奖励已发放");
                 return R.error("奖励已发放");
             }
             }
         }
         }
 
 
+        // 获取视频信息
         FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
         FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
 
 
-        // 获取配置
+        // 获取配置信息
         String json = configService.selectConfigByKey("course.config");
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
 
 
-        //发放奖励
-        switch (config.getRewardType()){
-            //红包奖励
+        // 根据奖励类型发放不同奖励
+        switch (config.getRewardType()) {
+            // 红包奖励
             case 1:
             case 1:
-                BigDecimal amount = BigDecimal.ZERO;
-                FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(param.getVideoId(), param.getCompanyId());
-                WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
-
-                if (redPackage!=null){
-                    amount = redPackage.getRedPacketMoney();
-                }else if (video!=null){
-                    amount = new BigDecimal(video.getRedPacketMoney());
-                }
-                packetParam.setOpenId(user.getMpOpenId());
-                packetParam.setAmount(amount);
-                R sendRedPacket = paymentService.sendRedPacket(packetParam);
-                if (sendRedPacket.get("code").equals(200)){
-                    //添加红包记录
-                    FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
-                    redPacketLog.setCourseId(param.getCourseId());
-                    redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
-                    redPacketLog.setCompanyId(param.getCompanyId());
-                    redPacketLog.setUserId(param.getUserId());
-                    redPacketLog.setVideoId(param.getVideoId());
-                    redPacketLog.setStatus(0);
-                    redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null );
-                    redPacketLog.setCompanyUserId(param.getCompanyUserId());
-                    redPacketLog.setCreateTime(new Date());
-                    redPacketLog.setAmount(amount);
-                    redPacketLog.setWatchLogId(log.getLogId() !=null ? log.getLogId() : null);
-                    redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
-                    if (param.getLinkType()==null || param.getLinkType()==0){
-                        log.setRewardType(config.getRewardType());
-                        courseWatchLogMapper.updateFsCourseWatchLog(log);
-                    }
-                    return R.ok("奖励发放成功");
-                }else {
-                    return R.error("奖励发送失败,请联系客服");
-                }
-            //积分奖励
+                return sendRedPacketReward(param, user, log, video, config);
+            // 积分奖励
             case 2:
             case 2:
-                //增加积分
-                FsUser userMap=new FsUser();
-                userMap.setUserId(user.getUserId());
-//                userMap.setIntegral(user.getIntegral()+config.getAnswerIntegral());
-                fsUserMapper.updateFsUser(userMap);
-                FsUserIntegralLogs integralLogs = new FsUserIntegralLogs();
-//                integralLogs.setIntegral(config.getAnswerIntegral().longValue());
-                integralLogs.setUserId(user.getUserId());
-                integralLogs.setBalance(userMap.getIntegral());
-                integralLogs.setLogType(17);
-                integralLogs.setBusinessId(StringUtils.isNotEmpty(log.getLogId().toString()) ? log.getLogId().toString() : null);
-                integralLogs.setCreateTime(new Date());
-                fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
-                if (param.getLinkType()==null || param.getLinkType()==0 ){
-                    log.setRewardType(config.getRewardType());
-                    courseWatchLogMapper.updateFsCourseWatchLog(log);
-                    //转换红包
-                    FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
-                    redPacketLog.setCourseId(param.getCourseId());
-                    redPacketLog.setOutBatchNo(integralLogs.getId().toString());
-                    redPacketLog.setCompanyId(param.getCompanyId());
-                    redPacketLog.setUserId(param.getUserId());
-                    redPacketLog.setVideoId(param.getVideoId());
-                    redPacketLog.setStatus(1);
-                    redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null );
-                    redPacketLog.setCompanyUserId(param.getCompanyUserId());
-                    redPacketLog.setCreateTime(new Date());
-                    redPacketLog.setAmount(BigDecimal.valueOf(config.getAnswerIntegral()).divide(BigDecimal.valueOf(1000)));
-                    redPacketLog.setRemark("点播答题领取积分转");
-                    redPacketLog.setWatchLogId(log.getLogId() !=null ? log.getLogId() : null);
-                    redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
-                }
-                return R.ok("奖励发放成功");
+                return sendIntegralReward(user, log, config);
             default:
             default:
                 return R.error("参数错误!");
                 return R.error("参数错误!");
         }
         }
     }
     }
+    
+    /**
+     * 发放红包奖励
+     * 
+     * @param param 请求参数
+     * @param user 用户信息
+     * @param log 观看日志
+     * @param video 视频信息
+     * @param config 配置信息
+     * @return 处理结果
+     */
+    private R sendRedPacketReward(FsCourseSendRewardUParam param, FsUser user, FsCourseWatchLog log, FsUserCourseVideo video, CourseConfig config) {
+        // 确定红包金额
+        BigDecimal amount = BigDecimal.ZERO;
+        FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(param.getVideoId(), param.getCompanyId());
+        
+        if (redPackage != null) {
+            amount = redPackage.getRedPacketMoney();
+        } else if (video != null) {
+            amount = new BigDecimal(video.getRedPacketMoney());
+        }
+        
+        // 准备发送红包参数
+        WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
+        packetParam.setOpenId(user.getMpOpenId());
+        // 来源是小程序切换openId
+        if (param.getSource() == 2) {
+            packetParam.setOpenId(user.getCourseMaOpenId());
+        }
+        packetParam.setAmount(amount);
+        packetParam.setSource(param.getSource());
+        
+        // 发送红包
+        R sendRedPacket = paymentService.sendRedPacket(packetParam);
+        if (sendRedPacket.get("code").equals(200)) {
+            // 添加红包记录
+            FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+            redPacketLog.setCourseId(param.getCourseId());
+            redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+            redPacketLog.setCompanyId(param.getCompanyId());
+            redPacketLog.setUserId(param.getUserId());
+            redPacketLog.setVideoId(param.getVideoId());
+            redPacketLog.setStatus(0);
+            redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
+            redPacketLog.setCompanyUserId(param.getCompanyUserId());
+            redPacketLog.setCreateTime(new Date());
+            redPacketLog.setAmount(amount);
+            redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
+            redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+            
+            // 更新观看记录的奖励类型
+            if (param.getLinkType() == null || param.getLinkType() == 0) {
+                log.setRewardType(config.getRewardType());
+                courseWatchLogMapper.updateFsCourseWatchLog(log);
+            }
+            return R.ok("奖励发放成功");
+        } else {
+            return R.error("奖励发送失败,请联系客服");
+        }
+    }
+    
+    /**
+     * 发放积分奖励
+     * 
+     * @param user 用户信息
+     * @param log 观看日志
+     * @param config 配置信息
+     * @return 处理结果
+     */
+    private R sendIntegralReward(FsUser user, FsCourseWatchLog log, CourseConfig config) {
+        // 更新用户积分
+        FsUser userMap = new FsUser();
+        userMap.setUserId(user.getUserId());
+        userMap.setIntegral(NumberUtil.add(user.getIntegral(), config.getAnswerIntegral()));
+        fsUserMapper.updateFsUser(userMap);
+        
+        // 记录积分日志
+        FsUserIntegralLogs integralLogs = new FsUserIntegralLogs();
+        integralLogs.setIntegral(new BigDecimal(config.getAnswerIntegral()));
+        integralLogs.setUserId(user.getUserId());
+        integralLogs.setBalance(userMap.getIntegral());
+        integralLogs.setLogType(17);
+        integralLogs.setBusinessId(StringUtils.isNotEmpty(log.getLogId().toString()) ? log.getLogId().toString() : null);
+        integralLogs.setCreateTime(new Date());
+        fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
+        
+        return R.ok("奖励发放成功");
+    }
 }
 }

+ 63 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtBarcodeDto.java

@@ -0,0 +1,63 @@
+package com.fs.erp.dto.wdt;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 条码信息 DTO
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ErpWdtBarcodeDto {
+
+    /**
+     * 货品ID
+     */
+    @JsonProperty("goods_id")
+    private String goodsId;
+
+    /**
+     * 规格ID
+     */
+    @JsonProperty("spec_id")
+    private String specId;
+
+    /**
+     * 条码信息
+     */
+    @JsonProperty("barcode")
+    private String barcode;
+
+    /**
+     * target_id的类型 1普通规格 2组合装
+     */
+    @JsonProperty("type")
+    private String type;
+
+    /**
+     * 是否为主条码 0 否 1 是
+     */
+    @JsonProperty("is_master")
+    private String isMaster;
+
+    /**
+     * 扫码一次对应出库数量
+     */
+    @JsonProperty("out_target_num")
+    private String outTargetNum;
+
+    /**
+     * 扫码一次对应入库货品数量
+     */
+    @JsonProperty("target_num")
+    private String targetNum;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonProperty("modified")
+    private String modified;
+}

+ 43 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtBaseResponseDTO.java

@@ -0,0 +1,43 @@
+package com.fs.erp.dto.wdt;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * Base API Response Structure
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ErpWdtBaseResponseDTO {
+
+    /**
+     * 状态码:0表示成功,其他表示失败
+     */
+    @JsonProperty("code")
+    private Integer code;
+
+    /**
+     * 错误描述
+     */
+    @JsonProperty("message")
+    private String message;
+
+    /**
+     * 符合条件的数据条数,用来分页 当page_no = 0时返回
+     */
+    @JsonProperty("total_count")
+    private Integer totalCount;
+
+    /**
+     * 货品节点列表
+     */
+    @JsonProperty("goods_list")
+    private List<ErpWdtGoodsDto> goodsList;
+
+}

+ 227 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtGoodsDto.java

@@ -0,0 +1,227 @@
+package com.fs.erp.dto.wdt;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 货品节点 (SPU) DTO
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ErpWdtGoodsDto {
+
+    /**
+     * 货品ID (货品表主键)
+     */
+    @JsonProperty("goods_id")
+    private Integer goodsId;
+
+    /**
+     * 货品编号 (代表SPU所有属性的唯一编号)
+     */
+    @JsonProperty("goods_no")
+    private String goodsNo;
+
+    /**
+     * 货品名称
+     */
+    @JsonProperty("goods_name")
+    private String goodsName;
+
+    /**
+     * 简称
+     */
+    @JsonProperty("short_name")
+    private String shortName;
+
+    /**
+     * 货品别名
+     */
+    @JsonProperty("alias")
+    private String alias;
+
+    /**
+     * 货品类别 0:其它, 1:销售货品, 2:原材料, 3:包装物, 4:周转材料, 5:虚拟商品, 6:固定资产,7:保修配件 8:虚拟代发货品
+     */
+    @JsonProperty("goods_type")
+    private Integer goodsType; // tinyint mapped to Integer
+
+    /**
+     * 规格数
+     */
+    @JsonProperty("spec_count")
+    private Integer specCount;
+
+    /**
+     * 拼音
+     */
+    @JsonProperty("pinyin")
+    private String pinyin;
+
+    /**
+     * 品牌编号
+     */
+    @JsonProperty("brand_no")
+    private String brandNo;
+
+    /**
+     * 品牌名称
+     */
+    @JsonProperty("brand_name")
+    private String brandName;
+
+    /**
+     * 备注
+     */
+    @JsonProperty("remark")
+    private String remark;
+
+    /**
+     * 自定义属性1
+     */
+    @JsonProperty("prop1")
+    private String prop1;
+
+    /**
+     * 自定义属性2
+     */
+    @JsonProperty("prop2")
+    private String prop2;
+
+    /**
+     * 自定义属性3
+     */
+    @JsonProperty("prop3")
+    private String prop3;
+
+    /**
+     * 自定义属性4
+     */
+    @JsonProperty("prop4")
+    private String prop4;
+
+    /**
+     * 自定义属性5
+     */
+    @JsonProperty("prop5")
+    private String prop5;
+
+    /**
+     * 自定义属性6
+     */
+    @JsonProperty("prop6")
+    private String prop6;
+
+    /**
+     * 产地
+     */
+    @JsonProperty("origin")
+    private String origin;
+
+    /**
+     * 分类id
+     */
+    @JsonProperty("class_id")
+    private String classId;
+
+    /**
+     * 分类名称
+     */
+    @JsonProperty("class_name")
+    private String className;
+
+    /**
+     * 品牌ID
+     */
+    @JsonProperty("brand_id")
+    private String brandId;
+
+    /**
+     * 基本单位id
+     */
+    @JsonProperty("unit")
+    private String unit;
+
+    /**
+     * 辅助单位id
+     */
+    @JsonProperty("aux_unit")
+    private String auxUnit;
+
+    /**
+     * 标记
+     */
+    @JsonProperty("flag_id")
+    private String flagId;
+
+    /**
+     * 属性
+     */
+    @JsonProperty("properties")
+    private String properties;
+
+    /**
+     * 版本号,用来检查同时修改的
+     */
+    @JsonProperty("version_id")
+    private String versionId;
+
+    /**
+     * 最后修改时间 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("modified")
+    private String modified; // Keep as String for direct mapping
+
+    /**
+     * 创建时间 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("created")
+    private String created; // Keep as String for direct mapping
+
+    /**
+     * 基本单位名称
+     */
+    @JsonProperty("unit_name")
+    private String unitName;
+
+    /**
+     * 辅助单位名称
+     */
+    @JsonProperty("aux_unit_name")
+    private String auxUnitName;
+
+    /**
+     * 标记名称
+     */
+    @JsonProperty("flag_name")
+    private String flagName;
+
+    /**
+     * 创建时间 (ERP客户端需升级至V2.3.8.6及以上版本可获取此字段) 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("goods_created")
+    private String goodsCreated; // Keep as String
+
+    /**
+     * 最后修改时间 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("goods_modified")
+    private String goodsModified; // Keep as String
+
+    /**
+     * 是否已删除: 0:未删除 >0代表已删除
+     */
+    @JsonProperty("deleted")
+    private Integer deleted;
+
+    /**
+     * 单品节点列表 (SKU)
+     */
+    @JsonProperty("spec_list")
+    private List<ErpWdtSpecDto> specList;
+}

+ 408 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtSpecDto.java

@@ -0,0 +1,408 @@
+package com.fs.erp.dto.wdt;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 单品节点 (SKU) DTO
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ErpWdtSpecDto {
+
+    /**
+     * 规格ID
+     */
+    @JsonProperty("spec_id")
+    private String specId;
+
+    /**
+     * 商家编码 (代表单品(SKU)所有属性的唯一编号)
+     */
+    @JsonProperty("spec_no")
+    private String specNo;
+
+    /**
+     * 规格码
+     */
+    @JsonProperty("spec_code")
+    private String specCode;
+
+    /**
+     * 主条码,单品下如果有多个条码,会随机返回其中一条条码
+     */
+    @JsonProperty("barcode")
+    private String barcode;
+
+    /**
+     * 规格名称
+     */
+    @JsonProperty("spec_name")
+    private String specName;
+
+    /**
+     * 货品ID
+     */
+    @JsonProperty("goods_id")
+    private Integer goodsId;
+
+    /**
+     * 最低价
+     */
+    @JsonProperty("lowest_price")
+    private BigDecimal lowestPrice;
+
+    /**
+     * 零售价
+     */
+    @JsonProperty("retail_price")
+    private BigDecimal retailPrice;
+
+    /**
+     * 批发价
+     */
+    @JsonProperty("wholesale_price")
+    private BigDecimal wholesalePrice;
+
+    /**
+     * 会员价
+     */
+    @JsonProperty("member_price")
+    private BigDecimal memberPrice;
+
+    /**
+     * 市场价
+     */
+    @JsonProperty("market_price")
+    private BigDecimal marketPrice;
+
+    /**
+     * 自定义价格1
+     */
+    @JsonProperty("custom_price1")
+    private BigDecimal customPrice1;
+
+    /**
+     * 自定义价格2
+     */
+    @JsonProperty("custom_price2")
+    private BigDecimal customPrice2;
+
+    /**
+     * 销售积分
+     */
+    @JsonProperty("sale_score")
+    private Integer saleScore;
+
+    /**
+     * 打包积分
+     */
+    @JsonProperty("pack_score")
+    private Integer packScore;
+
+    /**
+     * 拣货积分
+     */
+    @JsonProperty("pick_score")
+    private Integer pickScore;
+
+    /**
+     * 有效期天数 (保质期)
+     */
+    @JsonProperty("validity_days")
+    private Integer validityDays;
+
+    /**
+     * 最佳销售天数
+     */
+    @JsonProperty("sales_days")
+    private Integer salesDays;
+
+    /**
+     * 最佳收获天数
+     */
+    @JsonProperty("receive_days")
+    private Integer receiveDays;
+
+    /**
+     * 重量
+     */
+    @JsonProperty("weight")
+    private BigDecimal weight;
+
+    /**
+     * 长(CM)
+     */
+    @JsonProperty("length")
+    private BigDecimal length;
+
+    /**
+     * 宽(CM)
+     */
+    @JsonProperty("width")
+    private BigDecimal width;
+
+    /**
+     * 高(CM)
+     */
+    @JsonProperty("height")
+    private BigDecimal height;
+
+    /**
+     * 是否启用序列号 0不启用序列号 1强序列号 2弱序列号
+     */
+    @JsonProperty("is_sn_enable")
+    private Integer isSnEnable; // tinyint mapped to Integer
+
+    /**
+     * 是否允许负库存 0(不允许负库存);1(允许负库存)
+     */
+    @JsonProperty("is_allow_neg_stock")
+    private Integer isAllowNegStock; // tinyint mapped to Integer
+
+    /**
+     * 是否出库不验货 0(出库不验货);1(出库必须验货)
+     */
+    @JsonProperty("is_not_need_examine")
+    private Integer isNotNeedExamine; // tinyint mapped to Integer
+
+    /**
+     * 是否允许0成本 0(不允许0成本);1(允许0成本)
+     */
+    @JsonProperty("is_zero_cost")
+    private Integer isZeroCost; // tinyint mapped to Integer
+
+    /**
+     * 是否允许低于成本价 0(不允许低于成本价);1(允许低于成本价)
+     */
+    @JsonProperty("is_lower_cost")
+    private Integer isLowerCost; // tinyint mapped to Integer
+
+    /**
+     * 是否航空禁运 0(航空不禁运) 1(航空禁运)
+     */
+    @JsonProperty("is_not_use_air")
+    private Integer isNotUseAir; // tinyint mapped to Integer
+
+    /**
+     * 税率
+     */
+    @JsonProperty("tax_rate")
+    private BigDecimal taxRate;
+
+    /**
+     * 大件类别 0非大件1普通大件2独立大件
+     */
+    @JsonProperty("large_type")
+    private Integer largeType; // tinyint mapped to Integer
+
+    /**
+     * 备注
+     */
+    @JsonProperty("remark")
+    private String remark;
+
+    /**
+     * 创建时间 格式:YYYY-MM-DD HH:MM:SS
+     */
+    @JsonProperty("spec_created")
+    private String specCreated; // Keep as String
+
+    /**
+     * 最后修改时间 格式:YYYY-MM-DD HH:MM:SS
+     */
+    @JsonProperty("spec_modified")
+    private String specModified; // Keep as String
+
+    /**
+     * 自定义1
+     */
+    @JsonProperty("prop1")
+    private String prop1;
+
+    /**
+     * 自定义2
+     */
+    @JsonProperty("prop2")
+    private String prop2;
+
+    /**
+     * 自定义3
+     */
+    @JsonProperty("prop3")
+    private String prop3;
+
+    /**
+     * 自定义4
+     */
+    @JsonProperty("prop4")
+    private String prop4;
+
+    /**
+     * 自定义5
+     */
+    @JsonProperty("prop5")
+    private String prop5;
+
+    /**
+     * 自定义6
+     */
+    @JsonProperty("prop6")
+    private String prop6;
+
+    /**
+     * 图片url
+     */
+    @JsonProperty("img_url")
+    private String imgUrl;
+
+    /**
+     * 关联税务表税务编码
+     */
+    @JsonProperty("tax_code_id")
+    private String taxCodeId;
+
+    /**
+     * 是否启用同一批次出库 0,不使用同一批次,1,使用同一批次
+     */
+    @JsonProperty("is_single_batch")
+    private Integer isSingleBatch; // tinyint mapped to Integer
+
+    /**
+     * 水洗标
+     */
+    @JsonProperty("washing_label")
+    private String washingLabel;
+
+    /**
+     * 基本单位
+     */
+    @JsonProperty("unit")
+    private String unit;
+
+    /**
+     * 辅助单位
+     */
+    @JsonProperty("aux_unit")
+    private String auxUnit;
+
+    /**
+     * 标记
+     */
+    @JsonProperty("flag_id")
+    private String flagId;
+
+    /**
+     * 图片在外部空间的key 比如说 云盘的一个 外链
+     */
+    @JsonProperty("img_key")
+    private String imgKey;
+
+    /**
+     * 条码个数
+     */
+    @JsonProperty("barcode_count")
+    private Integer barcodeCount; // smallint mapped to Integer
+
+    /**
+     * 平台货品数量(不包含删除的)
+     */
+    @JsonProperty("plat_spec_count")
+    private Integer platSpecCount; // smallint mapped to Integer
+
+    /**
+     * sn自增数
+     */
+    @JsonProperty("postfix_val")
+    private String postfixVal;
+
+    /**
+     * 最后日期 格式:yyyy-MM-dd
+     */
+    @JsonProperty("last_date")
+    private String lastDate; // Keep as String (Date type)
+
+    /**
+     * 补货方式 0持续补货 1不补货 2低于警戒库存补货
+     */
+    @JsonProperty("replenish_type")
+    private Integer replenishType;
+
+    /**
+     * 是否畅销 0非畅销 1畅销
+     */
+    @JsonProperty("is_popular")
+    private Integer isPopular;
+
+    /**
+     * 备注换货匹配码
+     */
+    @JsonProperty("replace_no")
+    private String replaceNo;
+
+    /**
+     * 单品标记二进制位 1同款备注换货虚拟规格 2是否在备注换货界面展示 4递交自动生成货品
+     */
+    @JsonProperty("spec_mask")
+    private String specMask;
+
+    /**
+     * 同款备注换货--虚拟货品换货比例
+     */
+    @JsonProperty("replace_proportion")
+    private String replaceProportion;
+
+    /**
+     * 扩展字段
+     */
+    @JsonProperty("extra_3")
+    private String extra3;
+
+    /**
+     * 税务编码
+     */
+    @JsonProperty("tax_code")
+    private String taxCode;
+
+    /**
+     * 最后修改时间 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("modified")
+    private String modified; // Keep as String
+
+    /**
+     * 创建时间 格式:yyyy-MM-dd HH:mm:ss
+     */
+    @JsonProperty("created")
+    private String created; // Keep as String
+
+    /**
+     * 基本单位名称
+     */
+    @JsonProperty("spec_unit_name")
+    private String specUnitName;
+
+    /**
+     * 辅助单位名称
+     */
+    @JsonProperty("spec_aux_unit_name")
+    private String specAuxUnitName;
+
+    /**
+     * 是否已删除:0:未删除 >0代表已删除
+     */
+    @JsonProperty("deleted")
+    private Integer deleted;
+
+    /**
+     * 条码列表
+     */
+    @JsonProperty("barcode_list")
+    private List<ErpWdtBarcodeDto> barcodeList;
+}

+ 19 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtStockDTO.java

@@ -0,0 +1,19 @@
+package com.fs.erp.dto.wdt;
+
+import lombok.Data;
+
+@Data
+public class ErpWdtStockDTO {
+    /**
+     * sku
+     */
+    private String sepc_no;
+    /**
+     * 库存量
+     */
+    private String stock_num;
+    /**
+     * 可用库存量
+     */
+    private String avaliable_num;
+}

+ 37 - 0
fs-service-system/src/main/java/com/fs/erp/dto/wdt/ErpWdtStockRespDTO.java

@@ -0,0 +1,37 @@
+package com.fs.erp.dto.wdt;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class ErpWdtStockRespDTO implements Serializable {
+    /**
+     * 错误码,状态码:0表示成功,其他表示失败
+     */
+    @JsonProperty("code")
+    @NotNull
+    private Integer code;
+
+    /**
+     * 错误描述
+     */
+    @JsonProperty("message")
+    @NotNull
+    private String message;
+
+    /**
+     * 数据条数,只有,page_no = 0 时才返回的符合条件的数据总条数,用来分页
+     */
+    @JsonProperty("total_count")
+    private Integer totalCount;
+
+    /**
+     * 订单列表节点,响应参数的1级数据节点,包含当前页的订单及其明细的数据节点
+     */
+    @JsonProperty("stocks")
+    private List<ErpWdtStockDTO> stocks;
+}

+ 120 - 0
fs-service-system/src/main/java/com/fs/erp/service/impl/WdtErpGoodsServiceImpl.java

@@ -0,0 +1,120 @@
+package com.fs.erp.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.PropertyNamingStrategy;
+import com.alibaba.fastjson.parser.ParserConfig;
+import com.fs.erp.domain.ErpGoods;
+import com.fs.erp.domain.ErpGoodsStock;
+import com.fs.erp.dto.*;
+import com.fs.erp.dto.sdk.wangdian.api.WdtClient;
+import com.fs.erp.dto.wdt.*;
+import com.fs.erp.service.IErpGoodsService;
+import com.hc.openapi.tool.util.ObjectUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.http.util.Asserts;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+@Primary
+public class WdtErpGoodsServiceImpl implements IErpGoodsService {
+    @Autowired
+    private WdtClient client;
+
+    @Override
+    public BaseResponse addGoods(ErpGoods goods) {
+        return null;
+    }
+
+    @Override
+    public ErpGoodsQueryResponse getGoods(ErpGoodsQueryRequert param) {
+        Map<String,String> map = new HashMap<>();
+        map.put("spec_no",param.getCode());
+        Asserts.notBlank(param.getCode(),"barcode不能为空!");
+
+        try {
+            String response = client.execute("goods_query.php", map);
+            ParserConfig config = new ParserConfig();
+            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
+            ErpWdtBaseResponseDTO erpWdtBaseResponseDTO =
+                    JSON.parseObject(response, ErpWdtBaseResponseDTO.class, config);
+            if(ObjectUtils.equals(0, erpWdtBaseResponseDTO.getCode())){
+                List<ErpGoods> list = new ArrayList<>();
+
+                List<ErpWdtGoodsDto> goodsList = erpWdtBaseResponseDTO.getGoodsList();
+                for (ErpWdtGoodsDto goodsDto : goodsList) {
+                    ErpGoods erpGoods = new ErpGoods();
+                    erpGoods.setCode(param.getCode());
+                    erpGoods.setName(goodsDto.getGoodsName());
+                    erpGoods.setSimple_name(goodsDto.getShortName());
+                    erpGoods.setCategory_code(String.valueOf(goodsDto.getGoodsType()));
+                    List<ErpWdtSpecDto> specList = goodsDto.getSpecList();
+                    ErpWdtSpecDto erpWdtSpecDto = specList.get(0);
+
+                    // 市场价
+                    erpGoods.setCost_price(erpWdtSpecDto.getMarketPrice());
+                    // 零售价
+                    erpGoods.setSales_price(erpWdtSpecDto.getRetailPrice());
+                    list.add(erpGoods);
+                }
+
+                ErpGoodsQueryResponse erpGoodsQueryResponse = new ErpGoodsQueryResponse();
+                erpGoodsQueryResponse.setItems(list);
+                return erpGoodsQueryResponse;
+            } else {
+                log.info("获取erp商品失败! 错误原因: {}", JSON.toJSONString(erpWdtBaseResponseDTO));
+                throw new RuntimeException(erpWdtBaseResponseDTO.getMessage());
+            }
+
+        } catch (IOException e) {
+            log.info("获取erp商品失败! 错误原因: {}", ExceptionUtils.getStackTrace(e));
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    @Override
+    public ErpGoodsStockQueryResponse getGoodsStock(ErpGoodsStockQueryRequert param) {
+        String barcode = param.getBarcode();
+        Asserts.notBlank(barcode,"barcode不能为空!");
+
+        Map<String,String> map = new HashMap<>();
+        map.put("spec_no",barcode);
+        try {
+            String response = client.execute("stock_query.php", map);
+            ParserConfig config = new ParserConfig();
+            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
+            ErpWdtStockRespDTO erpWdtStockRespDTO = JSON.parseObject(response, ErpWdtStockRespDTO.class,config);
+            List<ErpGoodsStock> list = new ArrayList<>();
+            if(ObjectUtils.equals(0,erpWdtStockRespDTO.getCode())){
+                List<ErpWdtStockDTO> stocks = erpWdtStockRespDTO.getStocks();
+                for (ErpWdtStockDTO stock : stocks) {
+                    ErpGoodsStock erpGoodsStock = new ErpGoodsStock();
+                    erpGoodsStock.setBarcode(barcode);
+                    erpGoodsStock.setQty(stock.getStock_num());
+                    erpGoodsStock.setSalable_qty(stock.getAvaliable_num());
+                    list.add(erpGoodsStock);
+                }
+            } else {
+                log.info("获取erp库存失败! 错误原因: {}", JSON.toJSONString(erpWdtStockRespDTO));
+                throw new RuntimeException(erpWdtStockRespDTO.getMessage());
+            }
+            ErpGoodsStockQueryResponse erpGoodsStockQueryResponse = new ErpGoodsStockQueryResponse();
+            erpGoodsStockQueryResponse.setStocks(list);
+            return erpGoodsStockQueryResponse;
+        } catch (IOException e) {
+            log.info("获取erp库存失败! 错误原因: {}", ExceptionUtils.getStackTrace(e));
+            throw new RuntimeException(e);
+        }
+    }
+}
+

+ 2 - 0
fs-service-system/src/main/java/com/fs/his/param/WxSendRedPacketParam.java

@@ -14,5 +14,7 @@ public class WxSendRedPacketParam implements Serializable {
 
 
     private Long companyId;
     private Long companyId;
 
 
+    private Integer source=1;//来源 1:h5  2:看课小程序
+
 
 
 }
 }

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

@@ -2,14 +2,19 @@ package com.fs.qw.param;
 
 
 import lombok.Data;
 import lombok.Data;
 
 
+import java.time.LocalDate;
 import java.util.List;
 import java.util.List;
 
 
 @Data
 @Data
 public class QwAutoTagsRulesTags {
 public class QwAutoTagsRulesTags {
     private List<String> tags;
     private List<String> tags;
+    private List<LocalDate> date;
+    private LocalDate startDate;
+    private LocalDate endDate;
     private List<Integer> week;
     private List<Integer> week;
     private String startTime;
     private String startTime;
     private String endTime;
     private String endTime;
     private String remarks;
     private String remarks;
     private Integer isDay;
     private Integer isDay;
+    private Integer everyDay;
 }
 }

文件差异内容过多而无法显示
+ 229 - 226
fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java


+ 19 - 0
fs-service-system/src/main/java/com/fs/sop/domain/QwSop.java

@@ -1,5 +1,7 @@
 package com.fs.sop.domain;
 package com.fs.sop.domain;
 
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.annotation.Excel;
 import lombok.Data;
 import lombok.Data;
@@ -17,6 +19,7 @@ public class QwSop implements Serializable
 {
 {
 
 
     /** id */
     /** id */
+    @TableId(type = IdType.UUID)
     private String id;
     private String id;
 
 
     /** 规则名称 */
     /** 规则名称 */
@@ -91,4 +94,20 @@ public class QwSop implements Serializable
 
 
     private Integer courseDay;
     private Integer courseDay;
 
 
+
+    // 是否固定营期
+    private Integer isFixed;
+    // 是否只发送注册用户
+    private Integer isRegister;
+    // 进入营期打标签开始时间
+    private Integer startDayNum;
+    // 进入营期打标签结束时间
+    private Integer endDayNum;
+    // 添加的标签
+    private String addTags;
+    // 第几天开始发课
+    private Integer courseDateNum;
+    // 新课对话模板
+    private String newTemplateId;
+
 }
 }

+ 3 - 0
fs-service-system/src/main/java/com/fs/sop/mapper/QwSopMapper.java

@@ -360,4 +360,7 @@ public interface QwSopMapper extends BaseMapper<QwSop> {
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
     @Select("select * FROM qw_sop where is_rating = 1 and send_type in(2,3) and min_conversion_day is not null and max_conversion_day is not null order by create_time desc")
     @Select("select * FROM qw_sop where is_rating = 1 and send_type in(2,3) and min_conversion_day is not null and max_conversion_day is not null order by create_time desc")
     List<QwSop> selectQwSopByIsRatingNotNull();
     List<QwSop> selectQwSopByIsRatingNotNull();
+
+
+
 }
 }

+ 7 - 3
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java

@@ -1,7 +1,9 @@
 package com.fs.sop.service.impl;
 package com.fs.sop.service.impl;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.fs.common.annotation.DataSource;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
+import com.fs.common.enums.DataSourceType;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
@@ -149,12 +151,13 @@ public class QwSopServiceImpl implements IQwSopService
      * @return 结果
      * @return 结果
      */
      */
     @Override
     @Override
+    @DataSource(DataSourceType.SOP)
     public int insertQwSop(QwSop qwSop)
     public int insertQwSop(QwSop qwSop)
     {
     {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         qwSop.setCreateTime(sdf.format(new Date()));
         qwSop.setCreateTime(sdf.format(new Date()));
 
 
-        return qwSopMapper.insertQwSop(qwSop);
+        return qwSopMapper.insert(qwSop);
     }
     }
 
 
     /**
     /**
@@ -164,13 +167,14 @@ public class QwSopServiceImpl implements IQwSopService
      * @return 结果
      * @return 结果
      */
      */
     @Override
     @Override
+    @DataSource(DataSourceType.SOP)
     public R updateQwSop(QwSop qwSop)
     public R updateQwSop(QwSop qwSop)
     {
     {
 
 
         try {
         try {
 
 
             if (qwSop.getExpiryTime()!=null||qwSop.getIsRating()!=null){
             if (qwSop.getExpiryTime()!=null||qwSop.getIsRating()!=null){
-                qwSopMapper.updateQwSop(qwSop);
+                qwSopMapper.updateById(qwSop);
                 return R.ok("修改成功");
                 return R.ok("修改成功");
             }
             }
 
 
@@ -178,7 +182,7 @@ public class QwSopServiceImpl implements IQwSopService
                 return R.error("sop编号或模板编号不能为空");
                 return R.error("sop编号或模板编号不能为空");
             }
             }
 
 
-            int i = qwSopMapper.updateQwSop(qwSop);
+            int i = qwSopMapper.updateById(qwSop);
             if (i > 0) {
             if (i > 0) {
 
 
                     try {
                     try {

+ 10 - 0
fs-service-system/src/main/java/com/fs/sop/vo/SopUserLogsVo.java

@@ -29,4 +29,14 @@ public class SopUserLogsVo  {
      */
      */
     private Integer status;
     private Integer status;
 
 
+    /**
+     * 销售二级域名
+     */
+    private String domain;
+
+    // 是否固定营期
+    private Integer isFixed;
+    // 是否只发送注册用户
+    private Integer isRegister;
+
 }
 }

+ 10 - 0
fs-service-system/src/main/java/com/fs/store/domain/FsUser.java

@@ -137,6 +137,16 @@ public class FsUser extends BaseEntity
 
 
     private Integer isShow;//是否展示购买以及订单状态
     private Integer isShow;//是否展示购买以及订单状态
 
 
+    private String courseMaOpenId;//看课小程序openId
+
+    public String getCourseMaOpenId() {
+        return courseMaOpenId;
+    }
+
+    public void setCourseMaOpenId(String courseMaOpenId) {
+        this.courseMaOpenId = courseMaOpenId;
+    }
+
     public Integer getIsAddQw() {
     public Integer getIsAddQw() {
         return isAddQw;
         return isAddQw;
     }
     }

+ 8 - 0
fs-service-system/src/main/java/com/fs/store/service/IFsStorePaymentService.java

@@ -13,6 +13,8 @@ import com.fs.his.param.WxSendRedPacketParam;
 import com.fs.store.vo.FsStorePaymentStatisticsVO;
 import com.fs.store.vo.FsStorePaymentStatisticsVO;
 import com.fs.store.vo.FsStorePaymentVO;
 import com.fs.store.vo.FsStorePaymentVO;
 
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
 /**
  * 支付明细Service接口
  * 支付明细Service接口
  *
  *
@@ -100,4 +102,10 @@ public interface IFsStorePaymentService
     FsStorePayment selectFsStorePaymentByTradeNo(String tradeNo);
     FsStorePayment selectFsStorePaymentByTradeNo(String tradeNo);
 
 
     R sendRedPacket(WxSendRedPacketParam param);
     R sendRedPacket(WxSendRedPacketParam param);
+
+    R sendRedPacketV3(WxSendRedPacketParam param);
+
+    String transferNotify(String notifyData, HttpServletRequest request);
+
+    String v3TransferNotify(String notifyData, HttpServletRequest request);
 }
 }

+ 7 - 4
fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreCartServiceImpl.java

@@ -22,6 +22,7 @@ import com.fs.store.param.FsStoreCartDelParam;
 import com.fs.store.param.FsStoreCartNumParam;
 import com.fs.store.param.FsStoreCartNumParam;
 import com.fs.store.param.FsStoreCartParam;
 import com.fs.store.param.FsStoreCartParam;
 import com.fs.store.vo.FsStoreCartVO;
 import com.fs.store.vo.FsStoreCartVO;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import com.fs.store.domain.FsStoreCart;
 import com.fs.store.domain.FsStoreCart;
@@ -34,6 +35,7 @@ import com.fs.store.service.IFsStoreCartService;
  * @date 2022-03-21
  * @date 2022-03-21
  */
  */
 @Service
 @Service
+@Slf4j
 public class FsStoreCartServiceImpl implements IFsStoreCartService
 public class FsStoreCartServiceImpl implements IFsStoreCartService
 {
 {
     @Autowired
     @Autowired
@@ -135,7 +137,7 @@ public class FsStoreCartServiceImpl implements IFsStoreCartService
                     .isBuy(cartParam.getIsBuy())
                     .isBuy(cartParam.getIsBuy())
                     .build();
                     .build();
             storeCart.setCreateTime(new Date());
             storeCart.setCreateTime(new Date());
-//            checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+            checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
             fsStoreCartMapper.insertFsStoreCart(storeCart);
             fsStoreCartMapper.insertFsStoreCart(storeCart);
             return R.ok().put("id",storeCart.getId());
             return R.ok().put("id",storeCart.getId());
 
 
@@ -161,7 +163,7 @@ public class FsStoreCartServiceImpl implements IFsStoreCartService
                         .isBuy(0)
                         .isBuy(0)
                         .build();
                         .build();
                 storeCart.setCreateTime(new Date());
                 storeCart.setCreateTime(new Date());
-//                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
                 fsStoreCartMapper.insertFsStoreCart(storeCart);
                 fsStoreCartMapper.insertFsStoreCart(storeCart);
                 return R.ok().put("id",storeCart.getId());
                 return R.ok().put("id",storeCart.getId());
             }
             }
@@ -169,7 +171,7 @@ public class FsStoreCartServiceImpl implements IFsStoreCartService
                 storeCart=cart.get(0);
                 storeCart=cart.get(0);
                 storeCart.setCartNum(cartParam.getCartNum() + cart.get(0).getCartNum());
                 storeCart.setCartNum(cartParam.getCartNum() + cart.get(0).getCartNum());
                 storeCart.setUpdateTime(new Date());
                 storeCart.setUpdateTime(new Date());
-//                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
                 fsStoreCartMapper.updateFsStoreCart(storeCart);
                 fsStoreCartMapper.updateFsStoreCart(storeCart);
                 return R.ok().put("id",storeCart.getId());
                 return R.ok().put("id",storeCart.getId());
             }
             }
@@ -191,7 +193,7 @@ public class FsStoreCartServiceImpl implements IFsStoreCartService
     @Override
     @Override
     public R changeNum(long userId, FsStoreCartNumParam cartParam) {
     public R changeNum(long userId, FsStoreCartNumParam cartParam) {
         FsStoreCart cart=fsStoreCartMapper.selectFsStoreCartById(cartParam.getId());
         FsStoreCart cart=fsStoreCartMapper.selectFsStoreCartById(cartParam.getId());
-//        checkProductStock(cart.getProductId(),cart.getProductAttrValueId());
+        checkProductStock(cart.getProductId(),cart.getProductAttrValueId());
         cart.setCartNum(cartParam.getNumber());
         cart.setCartNum(cartParam.getNumber());
         cart.setUpdateTime(new Date());
         cart.setUpdateTime(new Date());
         fsStoreCartMapper.updateFsStoreCart(cart);
         fsStoreCartMapper.updateFsStoreCart(cart);
@@ -200,6 +202,7 @@ public class FsStoreCartServiceImpl implements IFsStoreCartService
 
 
     @Override
     @Override
     public void checkProductStock(Long productId, Long productAttrValueId) {
     public void checkProductStock(Long productId, Long productAttrValueId) {
+        log.info("检查库存 {} {}",productId,productAttrValueId);
         FsStoreProductAttrValue productAttrValue=valueMapper.selectFsStoreProductAttrValueById(productAttrValueId);
         FsStoreProductAttrValue productAttrValue=valueMapper.selectFsStoreProductAttrValueById(productAttrValueId);
         if(StringUtils.isEmpty(productAttrValue.getGroupBarCode())){
         if(StringUtils.isEmpty(productAttrValue.getGroupBarCode())){
             //单品
             //单品

+ 143 - 3
fs-service-system/src/main/java/com/fs/store/service/impl/FsStorePaymentServiceImpl.java

@@ -19,6 +19,7 @@ import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.course.config.RedPacketConfig;
 import com.fs.course.config.RedPacketConfig;
+import com.fs.course.service.IFsCourseRedPacketLogService;
 import com.fs.pay.pay.config.PayConfig;
 import com.fs.pay.pay.config.PayConfig;
 import com.fs.pay.pay.domain.CreateWxOrderResult;
 import com.fs.pay.pay.domain.CreateWxOrderResult;
 import com.fs.pay.pay.dto.WxJspayDTO;
 import com.fs.pay.pay.dto.WxJspayDTO;
@@ -38,14 +39,18 @@ import com.fs.pay.service.IPayService;
 import com.fs.pay.service.dto.CreatePayDTO;
 import com.fs.pay.service.dto.CreatePayDTO;
 import com.fs.pay.service.dto.PayDTO;
 import com.fs.pay.service.dto.PayDTO;
 import com.fs.pay.service.dto.TradeOrder;
 import com.fs.pay.service.dto.TradeOrder;
+import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
-import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest;
-import com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult;
+import com.github.binarywang.wxpay.bean.transfer.*;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.TransferService;
 import com.github.binarywang.wxpay.service.TransferService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -54,6 +59,8 @@ import com.fs.store.domain.FsStorePayment;
 import com.fs.store.service.IFsStorePaymentService;
 import com.fs.store.service.IFsStorePaymentService;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
 /**
  * 支付明细Service业务层处理
  * 支付明细Service业务层处理
  *
  *
@@ -63,7 +70,7 @@ import org.springframework.transaction.annotation.Transactional;
 @Service
 @Service
 public class FsStorePaymentServiceImpl implements IFsStorePaymentService
 public class FsStorePaymentServiceImpl implements IFsStorePaymentService
 {
 {
-
+    Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
     @Autowired
     private WxMaProperties properties;
     private WxMaProperties properties;
     @Autowired
     @Autowired
@@ -85,6 +92,9 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
     PayService ybPayService;
     PayService ybPayService;
     @Autowired
     @Autowired
     private ISysConfigService configService;
     private ISysConfigService configService;
+
+    @Autowired
+    private IFsCourseRedPacketLogService redPacketLogService;
     /**
     /**
      * 查询支付明细
      * 查询支付明细
      *
      *
@@ -384,4 +394,134 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
             return R.error("发送失败");
             return R.error("发送失败");
         }
         }
     }
     }
+
+
+    @Override
+    public String transferNotify(String notifyData, HttpServletRequest request) {
+        logger.info("zyp \n【收到转账回调】:{}",notifyData);
+        try {
+            String json = configService.selectConfigByKey("redPacket.config");
+            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
+            //创建微信订单
+            WxPayConfig payConfig = new WxPayConfig();
+            BeanUtils.copyProperties(config,payConfig);
+            WxPayService wxPayService = new WxPayServiceImpl();
+            wxPayService.setConfig(payConfig);
+            SignatureHeader signatureHeader = new SignatureHeader();
+            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
+            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
+            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
+            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
+            WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
+            logger.info("到零钱回调:{}",result.getResult());
+            if (result.getResult().getBatchStatus().equals("FINISHED")) {
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo());
+                logger.info("result:{}",r);
+                if (r.get("code").equals(200)){
+                    return WxPayNotifyResponse.success("处理成功");
+                }else {
+                    return WxPayNotifyResponse.fail("");
+                }
+            }else {
+                return WxPayNotifyResponse.fail("");
+            }
+        } catch (WxPayException e) {
+            logger.error("zyp \n【转账回调异常】:{}", e.getReturnMsg());
+            return WxPayNotifyResponse.fail(e.getMessage());
+        }
+    }
+
+    @Override
+    public R sendRedPacketV3(WxSendRedPacketParam param) {
+        String json = configService.selectConfigByKey("redPacket.config");
+        RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
+
+        //创建微信订单
+        WxPayConfig payConfig = new WxPayConfig();
+        BeanUtils.copyProperties(config,payConfig);
+        WxPayService wxPayService = new WxPayServiceImpl();
+        wxPayService.setConfig(payConfig);
+        TransferService transferService = wxPayService.getTransferService();
+
+        //商家转账请求
+        TransferBillsRequest request = new TransferBillsRequest();
+        request.setAppid(config.getAppId());
+        request.setOpenid(param.getOpenId());
+
+//        String code =  OrderCodeUtils.getH5RedPacketOrderSn();
+//        if(StringUtils.isEmpty(code)){
+//            return R.error("订单生成失败,请重试");
+//        }
+        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
+        request.setOutBillNo("fsCourse"+code);
+        //转账金额
+        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount()!=null ? param.getAmount().toString() : "0.1");
+        request.setTransferAmount(amount);
+        request.setTransferRemark("活动奖励");
+        //用户感知
+        request.setUserRecvPerception("活动奖励");
+        request.setNotifyUrl(config.getNotifyUrl());
+        request.setTransferSceneId("1000");
+        List<TransferBillsRequest.TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<>();
+        // 添加第一条数据
+        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
+        info1.setInfoType("活动名称");
+        info1.setInfoContent("新会员有礼");
+        transferSceneReportInfos.add(info1);
+
+        // 添加第二条数据
+        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
+        info2.setInfoType("奖励说明");
+        info2.setInfoContent("注册会员抽奖一等奖");
+        transferSceneReportInfos.add(info2);
+        request.setTransferSceneReportInfos(transferSceneReportInfos);
+
+        //发起商家转账API(新)
+        TransferBillsResult transferBillsResult=null;
+        try {
+            transferBillsResult = transferService.transferBills(request);
+            logger.info("商家转账支付完成:[msg:{}]",transferBillsResult);
+            return R.ok("发送红包成功").put("data",transferBillsResult);
+        } catch (WxPayException e) {
+            e.printStackTrace();
+            logger.info("商家转账支付失败:[msg:{}]",e.getMessage());
+            return R.error("发送失败");
+        }
+    }
+
+
+    @Override
+    public String v3TransferNotify(String notifyData, HttpServletRequest request) {
+        logger.info("zyp \n【收到转账回调】:{}",notifyData);
+        try {
+            String json = configService.selectConfigByKey("redPacket.config");
+            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
+            //创建微信订单
+            WxPayConfig payConfig = new WxPayConfig();
+            BeanUtils.copyProperties(config,payConfig);
+            WxPayService wxPayService = new WxPayServiceImpl();
+            wxPayService.setConfig(payConfig);
+            SignatureHeader signatureHeader = new SignatureHeader();
+            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
+            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
+            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
+            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
+            TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
+            logger.info("到零钱回调:{}",result.getResult());
+            if (result.getResult().getState().equals("SUCCESS")) {
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo());
+                logger.info("result:{}",r);
+                if (r.get("code").equals(200)){
+                    return WxPayNotifyResponse.success("处理成功");
+                }else {
+                    return WxPayNotifyResponse.fail("");
+                }
+            }else {
+                return WxPayNotifyResponse.fail("");
+            }
+        } catch (WxPayException e) {
+            logger.error("zyp \n【转账回调异常】:{}", e.getReturnMsg());
+            return WxPayNotifyResponse.fail(e.getMessage());
+        }
+    }
 }
 }

+ 10 - 0
fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml

@@ -328,6 +328,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         and b.voice_print_url is not null
         and b.voice_print_url is not null
     </select>
     </select>
 
 
+    <select id="selectCompanyUserByIds" resultType="com.fs.company.domain.CompanyUser">
+        select cu.*
+        from company_user cu
+        where cu.user_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+
+    </select>
+
 
 
     <resultMap type="com.fs.company.vo.CompanyUserVO" id="CompanyUserVOResult">
     <resultMap type="com.fs.company.vo.CompanyUserVO" id="CompanyUserVOResult">
         <result property="userId"    column="user_id"    />
         <result property="userId"    column="user_id"    />

+ 1 - 1
fs-service-system/src/main/resources/mapper/sop/SopUserLogsMapper.xml

@@ -158,7 +158,7 @@
 
 
 
 
     <select id="selectSopUserLogsListByTime" resultType="com.fs.sop.vo.SopUserLogsVo">
     <select id="selectSopUserLogsListByTime" resultType="com.fs.sop.vo.SopUserLogsVo">
-        select a.*,b.min_conversion_day,b.max_conversion_day,b.min_send,b.max_send from sop_user_logs a
+        select a.*,b.min_conversion_day,b.max_conversion_day,b.min_send,b.max_send,b.is_fixed,b.is_register from sop_user_logs a
         inner join qw_sop b on a.sop_id = b.id
         inner join qw_sop b on a.sop_id = b.id
         where a.start_time &lt;= Now() and a.status = 1 and b.send_type != 4 and b.status in (2,3)
         where a.start_time &lt;= Now() and a.status = 1 and b.send_type != 4 and b.status in (2,3)
     </select>
     </select>

部分文件因为文件数量过多而无法显示