ソースを参照

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	fs-company/src/main/resources/application.yml
吴树波 2 ヶ月 前
コミット
7fa2c5f21f
46 ファイル変更665 行追加78 行削除
  1. 136 0
      fs-admin/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/store/controller/FsDepartmentController.java
  3. 1 1
      fs-admin/src/main/java/com/fs/store/controller/FsTestTempController.java
  4. 1 1
      fs-admin/src/main/java/com/fs/store/controller/FsVesselController.java
  5. 1 1
      fs-common/src/main/java/com/fs/common/utils/OrderUtils.java
  6. 2 2
      fs-company/src/main/java/com/fs/company/controller/CompanyUserController.java
  7. 149 0
      fs-company/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java
  8. 10 4
      fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java
  9. 7 0
      fs-service-system/src/main/java/com/fs/company/cache/ICompanyCacheService.java
  10. 15 0
      fs-service-system/src/main/java/com/fs/company/cache/impl/ICompanyCacheServiceImpl.java
  11. 1 1
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java
  12. 1 1
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  13. 2 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseLink.java
  14. 2 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseRealLink.java
  15. 8 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseTrafficLog.java
  16. 3 16
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseTrafficLogMapper.java
  17. 3 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  18. 18 4
      fs-service-system/src/main/java/com/fs/course/param/FsCourseTrafficLogParam.java
  19. 2 0
      fs-service-system/src/main/java/com/fs/course/param/FsUserCourseVideoAddKfUParam.java
  20. 2 0
      fs-service-system/src/main/java/com/fs/course/service/IFsCourseLinkService.java
  21. 1 0
      fs-service-system/src/main/java/com/fs/course/service/IFsCourseTrafficLogService.java
  22. 2 0
      fs-service-system/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java
  23. 35 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  24. 65 1
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseTrafficLogServiceImpl.java
  25. 11 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  26. 66 26
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  27. 5 0
      fs-service-system/src/main/java/com/fs/course/vo/FsCourseTrafficLogListVO.java
  28. 1 1
      fs-service-system/src/main/java/com/fs/oms/service/impl/OmsProductServiceImpl.java
  29. 8 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  30. 1 1
      fs-service-system/src/main/java/com/fs/store/mapper/FsDepartmentMapper.java
  31. 1 1
      fs-service-system/src/main/java/com/fs/store/mapper/FsFollowTempMapper.java
  32. 1 1
      fs-service-system/src/main/java/com/fs/store/mapper/FsTestTempMapper.java
  33. 1 1
      fs-service-system/src/main/java/com/fs/store/mapper/FsVesselMapper.java
  34. 1 1
      fs-service-system/src/main/java/com/fs/store/service/IFsDepartmentService.java
  35. 1 1
      fs-service-system/src/main/java/com/fs/store/service/IFsFollowTempService.java
  36. 1 1
      fs-service-system/src/main/java/com/fs/store/service/IFsTestTempService.java
  37. 1 1
      fs-service-system/src/main/java/com/fs/store/service/IFsVesselService.java
  38. 8 0
      fs-service-system/src/main/java/com/fs/store/service/cache/IFsUserCourseCacheService.java
  39. 9 0
      fs-service-system/src/main/java/com/fs/store/service/cache/impl/FsUserCourseCacheServiceImpl.java
  40. 1 1
      fs-service-system/src/main/java/com/fs/store/service/impl/FsDepartmentServiceImpl.java
  41. 1 1
      fs-service-system/src/main/java/com/fs/store/service/impl/FsFollowTempServiceImpl.java
  42. 1 1
      fs-service-system/src/main/java/com/fs/store/service/impl/FsTestTempServiceImpl.java
  43. 1 1
      fs-service-system/src/main/java/com/fs/store/service/impl/FsVesselServiceImpl.java
  44. 7 1
      fs-service-system/src/main/resources/mapper/course/FsCourseLinkMapper.xml
  45. 42 1
      fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml
  46. 28 4
      fs-user-app/src/main/java/com/fs/app/controller/CourseH5Controller.java

+ 136 - 0
fs-admin/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java

@@ -0,0 +1,136 @@
+package com.fs.course.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+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.course.domain.FsCourseTrafficLog;
+import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.service.IFsCourseTrafficLogService;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.course.vo.FsCourseTrafficLogListVO;
+import com.fs.his.vo.OptionsVO;
+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.time.LocalDateTime;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+
+/**
+ * 短链课程流量记录Controller
+ *
+ * @author fs
+ * @date 2024-10-31
+ */
+@RestController
+@RequestMapping("/course/courseTrafficLog")
+public class FsCourseTrafficLogController extends BaseController
+{
+    @Autowired
+    private IFsCourseTrafficLogService fsCourseTrafficLogService;
+
+    @Autowired
+    private IFsUserCourseService fsUserCourseMapper;
+    /**
+     * 查询短链课程流量记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsCourseTrafficLogParam param)
+    {
+        startPage();
+        if(ObjectUtils.isNotNull(param.getTime())){
+
+            YearMonth yearMonth = param.getTime();
+            LocalDateTime startOfMonth = yearMonth.atDay(1).atStartOfDay();
+
+            LocalDateTime startOfNextMonth = yearMonth.plusMonths(1).atDay(1).atStartOfDay()
+                    .minusDays(1).withHour(23).withMinute(59).withSecond(59);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+            param.setStartDate(startOfMonth.format(formatter));
+            param.setEndDate(startOfNextMonth.format(formatter));
+        }
+        List<FsCourseTrafficLogListVO> list = fsCourseTrafficLogService.selectTrafficNew(param);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出短链课程流量记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:export')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsCourseTrafficLogParam param)
+    {
+        if (param.getTime() != null) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+            String formattedDate = sdf.format(param.getTime());
+            String[] parts = formattedDate.split("-");
+            param.setYear(Integer.parseInt(parts[0]));
+            param.setMonth(Integer.parseInt(parts[1]));
+        }
+        List<FsCourseTrafficLogListVO> list = fsCourseTrafficLogService.selectTrafficByCompany(param);
+        ExcelUtil<FsCourseTrafficLogListVO> util = new ExcelUtil<FsCourseTrafficLogListVO>(FsCourseTrafficLogListVO.class);
+        return util.exportExcel(list, "短链课程流量记录数据");
+    }
+
+    /**
+     * 获取短链课程流量记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:query')")
+    @GetMapping(value = "/{logId}")
+    public AjaxResult getInfo(@PathVariable("logId") Long logId)
+    {
+        return AjaxResult.success(fsCourseTrafficLogService.selectFsCourseTrafficLogByLogId(logId));
+    }
+
+    /**
+     * 新增短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:add')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsCourseTrafficLog fsCourseTrafficLog)
+    {
+        return toAjax(fsCourseTrafficLogService.insertFsCourseTrafficLog(fsCourseTrafficLog));
+    }
+
+    /**
+     * 修改短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:edit')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsCourseTrafficLog fsCourseTrafficLog)
+    {
+        return toAjax(fsCourseTrafficLogService.updateFsCourseTrafficLog(fsCourseTrafficLog));
+    }
+
+    /**
+     * 删除短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:remove')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logIds}")
+    public AjaxResult remove(@PathVariable Long[] logIds)
+    {
+        return toAjax(fsCourseTrafficLogService.deleteFsCourseTrafficLogByLogIds(logIds));
+    }
+
+    @GetMapping("/courseList")
+    public R courseList()
+    {
+        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList();
+        return R.ok().put("list", optionsVOS);
+    }
+}

+ 1 - 1
fs-admin/src/main/java/com/fs/store/controller/FsDepartmentController.java

@@ -8,7 +8,7 @@ import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.store.domain.FsDepartment;
 import com.fs.store.service.IFsDepartmentService;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;

+ 1 - 1
fs-admin/src/main/java/com/fs/store/controller/FsTestTempController.java

@@ -8,7 +8,7 @@ import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.store.domain.FsTestTemp;
 import com.fs.store.service.IFsTestTempService;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;

+ 1 - 1
fs-admin/src/main/java/com/fs/store/controller/FsVesselController.java

@@ -9,7 +9,7 @@ import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.store.domain.FsVessel;
 import com.fs.store.service.IFsVesselService;
 import com.fs.store.vo.FsVesselListVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;

+ 1 - 1
fs-common/src/main/java/com/fs/common/utils/OrderUtils.java

@@ -27,7 +27,7 @@ public class OrderUtils extends Thread {
         }
         orderNum ++;
         long orderNo = Long.parseLong((date)) * 10000;
-        orderNo += orderNum;;
+        orderNo += orderNum;
         return orderNo+"";
     }
 

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

@@ -19,7 +19,7 @@ import com.fs.core.web.service.TokenService;
 import com.fs.course.config.CourseConfig;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import com.fs.system.service.ISysConfigService;
 import com.fs.system.vo.DictVO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -214,7 +214,7 @@ public class CompanyUserController extends BaseController
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
 
         // 生成二级域名
-        String subDomain =  DomainUtil.generateSubDomain(config.getCourseDomainName(), 6, String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
+        String subDomain =  "http://"+DomainUtil.generateSubDomain(config.getCourseDomainName(), 6, String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
 
         AjaxResult result = AjaxResult.success();
         result.put("data", subDomain);

+ 149 - 0
fs-company/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java

@@ -0,0 +1,149 @@
+package com.fs.course.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+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.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.core.security.LoginUser;
+import com.fs.core.web.service.TokenService;
+import com.fs.course.domain.FsCourseTrafficLog;
+import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.service.IFsCourseTrafficLogService;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.course.vo.FsCourseTrafficLogListVO;
+import com.fs.his.vo.OptionsVO;
+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.time.LocalDateTime;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+
+/**
+ * 短链课程流量记录Controller
+ *
+ * @author fs
+ * @date 2024-10-31
+ */
+@RestController
+@RequestMapping("/course/courseTrafficLog")
+public class FsCourseTrafficLogController extends BaseController
+{
+    @Autowired
+    private IFsCourseTrafficLogService fsCourseTrafficLogService;
+
+    @Autowired
+    private IFsUserCourseService fsUserCourseMapper;
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询短链课程流量记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsCourseTrafficLogParam param)
+    {
+        startPage();
+        if(ObjectUtils.isNotNull(param.getTime())){
+
+            YearMonth yearMonth = param.getTime();
+            LocalDateTime startOfMonth = yearMonth.atDay(1).atStartOfDay();
+
+            LocalDateTime startOfNextMonth = yearMonth.plusMonths(1).atDay(1).atStartOfDay()
+                    .minusDays(1).withHour(23).withMinute(59).withSecond(59);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+            param.setCompanyId( loginUser.getCompany().getCompanyId());
+
+            param.setStartDate(startOfMonth.format(formatter));
+            param.setEndDate(startOfNextMonth.format(formatter));
+        }
+        List<FsCourseTrafficLogListVO> list = fsCourseTrafficLogService.selectTrafficNew(param);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出短链课程流量记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:export')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsCourseTrafficLogParam param)
+    {
+        if (param.getTime() != null) {
+            YearMonth yearMonth = param.getTime();
+            LocalDateTime startOfMonth = yearMonth.atDay(1).atStartOfDay();
+
+            LocalDateTime startOfNextMonth = yearMonth.plusMonths(1).atDay(1).atStartOfDay()
+                    .minusDays(1).withHour(23).withMinute(59).withSecond(59);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+            param.setStartDate(startOfMonth.format(formatter));
+            param.setEndDate(startOfNextMonth.format(formatter));
+        }
+        List<FsCourseTrafficLogListVO> list = fsCourseTrafficLogService.selectTrafficByCompany(param);
+        ExcelUtil<FsCourseTrafficLogListVO> util = new ExcelUtil<FsCourseTrafficLogListVO>(FsCourseTrafficLogListVO.class);
+        return util.exportExcel(list, "短链课程流量记录数据");
+    }
+
+    /**
+     * 获取短链课程流量记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:query')")
+    @GetMapping(value = "/{logId}")
+    public AjaxResult getInfo(@PathVariable("logId") Long logId)
+    {
+        return AjaxResult.success(fsCourseTrafficLogService.selectFsCourseTrafficLogByLogId(logId));
+    }
+
+    /**
+     * 新增短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:add')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsCourseTrafficLog fsCourseTrafficLog)
+    {
+        return toAjax(fsCourseTrafficLogService.insertFsCourseTrafficLog(fsCourseTrafficLog));
+    }
+
+    /**
+     * 修改短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:edit')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsCourseTrafficLog fsCourseTrafficLog)
+    {
+        return toAjax(fsCourseTrafficLogService.updateFsCourseTrafficLog(fsCourseTrafficLog));
+    }
+
+    /**
+     * 删除短链课程流量记录
+     */
+    @PreAuthorize("@ss.hasPermi('course:courseTrafficLog:remove')")
+    @Log(title = "短链课程流量记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logIds}")
+    public AjaxResult remove(@PathVariable Long[] logIds)
+    {
+        return toAjax(fsCourseTrafficLogService.deleteFsCourseTrafficLogByLogIds(logIds));
+    }
+
+    @GetMapping("/courseList")
+    public R courseList()
+    {
+        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList();
+        return R.ok().put("list", optionsVOS);
+    }
+}

+ 10 - 4
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -6,10 +6,7 @@ import com.fs.app.taskService.SopLogsChatTaskService;
 import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.common.core.domain.R;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
-import com.fs.course.service.IFsCourseLinkService;
-import com.fs.course.service.IFsCourseWatchLogService;
-import com.fs.course.service.IFsUserVideoService;
-import com.fs.course.service.IHuaweiObsService;
+import com.fs.course.service.*;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.sop.mapper.QwSopLogsMapper;
@@ -146,6 +143,15 @@ public class CommonController {
     }
 
 
+    @Autowired
+    private IFsCourseWatchLogService courseWatchLogService;
+    @GetMapping("/del")
+    public R del(){
+        courseWatchLogService.del();
+        return R.ok();
+    }
+
+
     @Autowired
     private SopLogsChatTaskService sopLogsChatTaskService;
     @GetMapping("/test2")

+ 7 - 0
fs-service-system/src/main/java/com/fs/company/cache/ICompanyCacheService.java

@@ -14,4 +14,11 @@ public interface ICompanyCacheService {
      */
     public Company selectCompanyById(Long companyId);
 
+    /**
+     * 查询企业名称
+     *
+     * @param companyId 企业ID
+     * @return 企业名称
+     */
+    String selectCompanyNameById(Long companyId);
 }

+ 15 - 0
fs-service-system/src/main/java/com/fs/company/cache/impl/ICompanyCacheServiceImpl.java

@@ -21,8 +21,23 @@ public class ICompanyCacheServiceImpl implements ICompanyCacheService {
             .maximumSize(1000)
             .expireAfterWrite(3, TimeUnit.MINUTES)
             .build();
+    private static final Cache<Long, String> COMPANY_NAME_CACHE = Caffeine.newBuilder()
+            .maximumSize(1000)
+            .expireAfterWrite(3, TimeUnit.MINUTES)
+            .build();
     @Override
     public Company selectCompanyById(Long companyId) {
         return COMPANY_CACHE.get(companyId,e-> companyService.selectCompanyById(companyId));
     }
+
+    @Override
+    public String selectCompanyNameById(Long companyId) {
+        return COMPANY_NAME_CACHE.get(companyId, e-> {
+            Company company = companyService.selectCompanyById(companyId);
+            if(company == null){
+                return "";
+            }
+            return String.format("%s_%s",company.getCompanyName(),company.getCompanyId());
+        });
+    }
 }

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

@@ -11,7 +11,7 @@ import com.fs.company.vo.DocCompanyUserVO;
 import com.fs.his.vo.CitysAreaVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 import java.util.Map;

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

@@ -14,7 +14,7 @@ import com.fs.company.vo.*;
 import com.fs.his.vo.CitysAreaVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import com.fs.store.service.IFsCityService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseLink.java

@@ -56,4 +56,6 @@ public class FsCourseLink extends BaseEntity
 
 //    private String link_uuid;
 
+    private Integer isRoom;//是否发群
+
 }

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

@@ -34,4 +34,6 @@ public class FsCourseRealLink implements Serializable
      */
     private Long fsUserId;
 
+    private Integer isRoom;
+
 }

+ 8 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseTrafficLog.java

@@ -47,10 +47,18 @@ public class FsCourseTrafficLog extends BaseEntity
     /** 公司id */
     @Excel(name = "公司id")
     private Long companyId;
+    private String companyName;
 
     /** 课程id */
     @Excel(name = "课程id")
     private Long courseId;
+    private String courseName;
+
+    /**
+     * 项目id
+     */
+    private Long project;
+    private String projectName;
 
 //    @JsonFormat(pattern = "yyyy-MM-dd")
 //    private Date time;

+ 3 - 16
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseTrafficLogMapper.java

@@ -63,26 +63,13 @@ public interface FsCourseTrafficLogMapper
      */
     public int deleteFsCourseTrafficLogByLogIds(Long[] logIds);
 
-    @Select({"<script> " +
-            "select c.company_name, SUM(l.internet_traffic) AS total_internet_traffic" +
-            ",DATE_FORMAT(l.create_time, '%Y-%m') AS `month`  from fs_course_traffic_log l " +
-            "left join company c on c.company_id = l.company_id " +
-            "where 1 = 1 " +
-            "<if test= 'maps.year != null '>" +
-            "and YEAR(l.create_time) = #{maps.year} " +
-            "</if>" +
-            "<if test= 'maps.month != null '>"+
-            "and MONTH(l.create_time) = #{maps.month} " +
-            "</if>" +
-            "<if test = ' maps.companyId !=null '> " +
-            "and l.company_id = #{maps.companyId} " +
-            "</if>" +
-            "group by l.company_id,`month` "+
-            "</script>"})
+
     List<FsCourseTrafficLogListVO> selectTrafficByCompany(@Param("maps") FsCourseTrafficLogParam param);
 
     @Select("select * from fs_course_traffic_log where uu_id = #{uuId}")
     FsCourseTrafficLog selectFsCourseTrafficLogByuuId(@Param("uuId") String uuId);
 
     void insertOrUpdateTrafficLog(FsCourseTrafficLog trafficLog);
+
+    List<FsCourseTrafficLogListVO> selectTrafficNew(FsCourseTrafficLogParam param);
 }

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

@@ -307,4 +307,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * @return  count
      */
     int countByMap(@Param("params") Map<String, Object> params);
+
+    @Select("select log_id from fs_course_watch_log where create_time < '2025-03-01'")
+    List<Long> selectFsCourseWatchLogByLastmonth();
 }

+ 18 - 4
fs-service-system/src/main/java/com/fs/course/param/FsCourseTrafficLogParam.java

@@ -1,16 +1,30 @@
 package com.fs.course.param;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
-import java.util.Date;
+import java.time.YearMonth;
 
 @Data
 public class FsCourseTrafficLogParam {
 
-    @JsonFormat(pattern = "yyyy-MM")
-    private Date time;
+    @DateTimeFormat(pattern = "yyyy-MM")
+    private YearMonth time;
+    /**
+     * 公司id
+     */
     private Long companyId;
     private Integer year;
     private Integer month;
+    /**
+     * 项目id
+     */
+    private Long project;
+    /**
+     * 课程id
+     */
+    private Long courseId;
+
+    private String startDate;
+    private String endDate;
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/param/FsUserCourseVideoAddKfUParam.java

@@ -57,4 +57,6 @@ public class FsUserCourseVideoAddKfUParam implements Serializable {
 
     private Long linkId;
 
+    private Integer isRoom;
+
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsCourseLinkService.java

@@ -76,4 +76,6 @@ public interface IFsCourseLinkService
 
     R createLinkByMiniApp(FsCourseLinkCreateParam param);
 
+    R createRoomLinkUrl(FsCourseLinkCreateParam param);
+
 }

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

@@ -63,4 +63,5 @@ public interface IFsCourseTrafficLogService
 
 
     List<FsCourseTrafficLogListVO> selectTrafficByCompany(FsCourseTrafficLogParam param);
+    List<FsCourseTrafficLogListVO> selectTrafficNew(FsCourseTrafficLogParam param);
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java

@@ -113,4 +113,6 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
      * @return  count
      */
     int countByMap(Map<String, Object> params);
+
+    void del();
 }

+ 35 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -195,6 +195,41 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
         return R.error("短链生成失败!");
     }
 
+    @Override
+    public R createRoomLinkUrl(FsCourseLinkCreateParam param) {
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        FsCourseLink link = new FsCourseLink();
+        BeanUtils.copyProperties(param,link);
+        link.setLinkType(0);
+        link.setIsRoom(1);
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link,courseMap);
+        // 将实体类对象转换为 JSON 字符串
+        String course = JSON.toJSONString(courseMap);
+        link.setRealLink(realLink+course);
+        String randomString = generateRandomString();
+        link.setLink(randomString);
+        link.setCreateTime(new Date());
+        Integer expireDays = 0;
+        if (param.getDays() == null || param.getDays() == 0){
+            expireDays = config.getVideoLinkExpireDate();
+        }else {
+            expireDays = param.getDays();
+        }
+        // 设置过期时间
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(link.getCreateTime());
+        calendar.add(Calendar.DAY_OF_MONTH, expireDays);
+        link.setUpdateTime(calendar.getTime());
+        if (fsCourseLinkMapper.insertFsCourseLink(link)>0){
+            String domainName = getDomainName(param.getCompanyUserId(), config);
+            String sortLink = domainName + "/s/" + link.getLink();
+            return R.ok("短链生成").put("url",sortLink);
+        }
+        return R.error("短链生成失败!");
+    }
+
     @Override
     public R createLinkUrlWc(FsCourseLinkCreateParam param) {
 

+ 65 - 1
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseTrafficLogServiceImpl.java

@@ -1,9 +1,16 @@
 package com.fs.course.service.impl;
 
+import java.util.Collections;
 import java.util.List;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.DictUtils;
+import com.fs.company.cache.ICompanyCacheService;
 import com.fs.course.param.FsCourseTrafficLogParam;
 import com.fs.course.vo.FsCourseTrafficLogListVO;
+import com.fs.store.service.cache.IFsUserCourseCacheService;
+import com.hc.openapi.tool.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.course.mapper.FsCourseTrafficLogMapper;
@@ -21,6 +28,10 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
 {
     @Autowired
     private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
+    @Autowired
+    private ICompanyCacheService companyCacheService;
+    @Autowired
+    private IFsUserCourseCacheService fsUserCourseCacheService;
 
     /**
      * 查询短链课程流量记录
@@ -43,7 +54,32 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
     @Override
     public List<FsCourseTrafficLog> selectFsCourseTrafficLogList(FsCourseTrafficLog fsCourseTrafficLog)
     {
-        return fsCourseTrafficLogMapper.selectFsCourseTrafficLogList(fsCourseTrafficLog);
+        List<FsCourseTrafficLog> fsCourseTrafficLogs = fsCourseTrafficLogMapper.selectFsCourseTrafficLogList(fsCourseTrafficLog);
+
+        for (FsCourseTrafficLog log : fsCourseTrafficLogs) {
+            if(ObjectUtils.isNotNull(log.getProject())){
+                String sysCourseProject = DictUtils.getDictLabel("sys_course_project", String.valueOf(log.getProject()));
+                if(StringUtils.isNotBlank(sysCourseProject)){
+                    log.setProjectName(sysCourseProject);
+                }
+            }
+
+            if(ObjectUtils.isNotNull(log.getCompanyId())){
+                String companyName = companyCacheService.selectCompanyNameById(log.getCompanyId());
+                if(StringUtils.isNotBlank(companyName)){
+                    log.setCompanyName(companyName);
+                }
+            }
+
+            if(ObjectUtils.isNotNull(log.getCourseId())){
+                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(log.getCourseId());
+                if(StringUtils.isNotBlank(courseName)){
+                    log.setCourseName(courseName);
+                }
+            }
+        }
+
+        return fsCourseTrafficLogs;
     }
 
     /**
@@ -99,4 +135,32 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
     public List<FsCourseTrafficLogListVO> selectTrafficByCompany(FsCourseTrafficLogParam param) {
         return fsCourseTrafficLogMapper.selectTrafficByCompany(param);
     }
+
+    @Override
+    public List<FsCourseTrafficLogListVO> selectTrafficNew(FsCourseTrafficLogParam param) {
+        List<FsCourseTrafficLogListVO> fsCourseTrafficLogListVOS = fsCourseTrafficLogMapper.selectTrafficNew(param);
+        for (FsCourseTrafficLogListVO log : fsCourseTrafficLogListVOS) {
+            if (ObjectUtils.isNotNull(log.getProject())) {
+                String sysCourseProject = DictUtils.getDictLabel("sys_course_project", String.valueOf(log.getProject()));
+                if (StringUtils.isNotBlank(sysCourseProject)) {
+                    log.setProjectName(sysCourseProject);
+                }
+            }
+
+            if (ObjectUtils.isNotNull(log.getCompanyId())) {
+                String companyName = companyCacheService.selectCompanyNameById(log.getCompanyId());
+                if (StringUtils.isNotBlank(companyName)) {
+                    log.setCompanyName(companyName);
+                }
+            }
+
+            if (ObjectUtils.isNotNull(log.getCourseId())) {
+                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(log.getCourseId());
+                if (StringUtils.isNotBlank(courseName)) {
+                    log.setCourseName(courseName);
+                }
+            }
+        }
+        return fsCourseTrafficLogListVOS;
+    }
 }

+ 11 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -750,4 +750,15 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         // 记录全部更新完成
         log.info("所有日志更新完成,总日志数量: {}", logs.size());
     }
+
+
+    @Override
+    public void del() {
+        List<Long> logIds = fsCourseWatchLogMapper.selectFsCourseWatchLogByLastmonth();
+        processDelCourseLogs(logIds);
+    }
+
+    private void processDelCourseLogs(List<Long> logIds) {
+
+    }
 }

+ 66 - 26
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.course.service.impl;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
@@ -39,6 +40,7 @@ import com.fs.qwApi.Result.QwAddContactWayResult;
 import com.fs.qwApi.param.QwAddContactWayParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.sop.mapper.QwSopLogsMapper;
+import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.fs.system.service.ISysConfigService;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
 import org.slf4j.Logger;
@@ -321,13 +323,61 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
         //用户不存在唤起重新授权
         if (fsUser==null){
-            return R.error(504,"");
+            return R.error(504,"未授权");
         }
-        String nickName = "微信用户";
-        if (fsUser.getNickname() != null && fsUser.getNickname().contains(nickName)) {
-            return R.error(504,"");
+
+        String msg = "<div style=\"color: red;margin-bottom: 15px;font-weight: bold;\">本课程为会员独享<br>请长按二维码</div>\n" +
+                "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
+
+        Integer isRoom = param.getIsRoom();
+
+        // 处理逻辑
+        if (isRoom == null || isRoom == 0) {
+            // 当 isRoom 为 null 或 0 时走 handleExt
+            return handleExt(param,msg);
+        } else if (isRoom == 1) {
+            // 当 isRoom 为 1 时走 handleRoom
+            return handleRoom(param,fsUser);
+        } else {
+            // 非法参数
+            logger.warn("非法参数 isRoom: {}", isRoom);
+            return R.error("参数错误!");
         }
 
+    }
+
+    private R handleRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
+        if (user.getQwExtId()==null){
+            return R.error("未注册");
+        }
+        param.setQwExternalId(user.getQwExtId());
+        //查询是否有添加客服
+        QwExternalContact externalContact = qwExternalContactMapper.selectQwExternalContactById(param.getQwExternalId());
+        if (externalContact==null){
+            return R.error("客户不存在!");
+        }
+        if (!externalContact.getQwUserId().equals(param.getUserId())){
+            return R.error("无权限观看,添加群主非本群主");
+        }
+        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(param.getQwExternalId(), param.getVideoId(),param.getQwUserId());
+        if (log==null){
+            createWatchLog(param);
+        }
+        return R.ok();
+    }
+
+    private void createWatchLog(FsUserCourseVideoAddKfUParam param) {
+        FsCourseWatchLog log = new FsCourseWatchLog();
+        BeanUtils.copyProperties(param,log);
+        log.setQwExternalContactId(param.getQwExternalId());
+        log.setSendType(2);
+        log.setDuration(0L);
+        log.setCreateTime(new Date());
+        log.setLogType(0);
+        courseWatchLogMapper.insertFsCourseWatchLog(log);
+    }
+
+    private R handleExt(FsUserCourseVideoAddKfUParam param,String msg){
         if (param.getLinkType()!=null&&param.getLinkType()==1){
             if (param.getLinkId()!=null){
                 // 从数据库中查找短链对应的真实链接
@@ -350,12 +400,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             return R.error("链接过期");
         }
 
-        String msg = "<div style=\"color: red;margin-bottom: 15px;font-weight: bold;\">本课程为会员独享<br>请长按二维码</div>\n" +
-                "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
+
 
         FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(param.getQwExternalId(), param.getVideoId(),param.getQwUserId());
         if (log==null ){
-            logger.info("");
             return addCustomerService(param.getQwUserId(),msg);
         }
 
@@ -371,12 +419,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             return addCustomerService(param.getQwUserId(),msg);
         }
 
-        //如果客户状态为正常或流失且无接替记录,才生成可以看课,不然加好友
-//        if (externalContact.getStatus() != 0 && externalContact.getStatus() != 2 && externalContact.getStatus() != 3){
-//        if (externalContact.getStatus()==4){
-//            return addCustomerService(param.getQwUserId(),msg);
-//        }
-
         //判断外部联系人有没有绑定userId
         if (externalContact.getFsUserId()!=null){
             //有客户有小程序id  但 登录的小程序id和根据外部联系人id查出来的小程序id不一致
@@ -389,13 +431,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             }
 
             //看课记录中userId为0绑定userId
-            if (log.getUserId()==null||log.getUserId().equals(0L)){
+            if (log.getUserId()==null||log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())){
                 log.setUserId(param.getUserId());
             }
-            //看课记录不为已完课时 改为看课中
-//            if (log.getLogType()!=2){
-//                log.setLogType(1);
-//            }
             log.setUpdateTime(new Date());
             courseWatchLogMapper.updateFsCourseWatchLog(log);
             return R.ok();
@@ -407,26 +445,20 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             contact.setFsUserId(param.getUserId());
             qwExternalContactMapper.updateQwExternalContact(contact);
             FsUser user = new FsUser();
-            user.setUserId(fsUser.getUserId());
+            user.setUserId(param.getUserId());
             user.setIsAddQw(1);
             fsUserMapper.updateFsUser(user);
 
             //绑定上之后 更新观看记录
             //看课记录中userId为0绑定userId
-            if (log.getUserId()==null||log.getUserId().equals(0L)){
+            if (log.getUserId()==null||log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())){
                 log.setUserId(param.getUserId());
             }
-            //看课记录不为已完课时 改为看课中
-//            if (log.getLogType()!=2){
-//                log.setLogType(1);
-//            }
 
             log.setUpdateTime(new Date());
             courseWatchLogMapper.updateFsCourseWatchLog(log);
             return R.ok();
         }
-
-
     }
 
     private R addCustomerService(String qwUserById,String msg){
@@ -471,6 +503,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
 
+    @Autowired
+    private IFsUserCourseCacheService fsUserCourseCacheService;
     @Transactional
     @Override
     public R getInternetTraffic(FsUserCourseVideoFinishUParam param) {
@@ -496,6 +530,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             if (StringUtils.isNotEmpty(trafficLog.getUuId())) {
                 // 直接插入或更新
 //                logger.error("zyp \n【插入或更新流量】:{}",trafficLog);
+                if(ObjectUtils.isNotNull(trafficLog.getCourseId())) {
+                    FsUserCourse course = fsUserCourseCacheService.selectFsUserCourseByCourseId(trafficLog.getCourseId());
+                    if(ObjectUtils.isNotNull(course)){
+                        trafficLog.setProject(course.getProject());
+                    }
+                }
                 fsCourseTrafficLogMapper.insertOrUpdateTrafficLog(trafficLog);
             }
         } catch (Exception e) {

+ 5 - 0
fs-service-system/src/main/java/com/fs/course/vo/FsCourseTrafficLogListVO.java

@@ -14,6 +14,11 @@ import java.io.Serializable;
 public class FsCourseTrafficLogListVO implements Serializable
 {
     private String companyName;
+    private Long companyId;
+    private String courseName;
+    private Long courseId;
+    private String projectName;
+    private Long project;
 
     private Long totalInternetTraffic;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/oms/service/impl/OmsProductServiceImpl.java

@@ -24,7 +24,7 @@ import com.fs.oms.mapper.OmsProductMapper;
 import com.fs.oms.param.OmsProductAddEditParam;
 import com.fs.oms.service.IOmsProductService;
 import com.fs.oms.vo.OmsProductExportVO;
-import com.fs.oms.vo.OmsProductListVO;;
+import com.fs.oms.vo.OmsProductListVO;
 import com.fs.oms.vo.OmsDetailVO;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;

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

@@ -2702,6 +2702,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                 } catch (Exception e) {
                     logger.error("欢迎语生成短链失败:", e);
                 }
+            }else if ("link".equals(att.getMsgtype()) && att.getLink().getIsFixed()==1 ) {
+
+                if (config != null) {
+                    att.getLink().setUrl(config.getRegisterDomainName()+registerLink+qwExternalId);
+                }else {
+                    logger.error("企业配置信息为空:发送注册链接失败");
+                }
+
             }
             //小程序
             if ("miniprogram".equals(att.getMsgtype())

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/mapper/FsDepartmentMapper.java

@@ -1,7 +1,7 @@
 package com.fs.store.mapper;
 
 import com.fs.store.domain.FsDepartment;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Select;
 
 import java.util.List;

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/mapper/FsFollowTempMapper.java

@@ -1,7 +1,7 @@
 package com.fs.store.mapper;
 
 import com.fs.store.domain.FsFollowTemp;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Select;
 
 import java.util.List;

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/mapper/FsTestTempMapper.java

@@ -1,7 +1,7 @@
 package com.fs.store.mapper;
 
 import com.fs.store.domain.FsTestTemp;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Select;
 
 import java.util.List;

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/mapper/FsVesselMapper.java

@@ -4,7 +4,7 @@ import com.fs.store.domain.FsVessel;
 import com.fs.store.param.FsVesselListUParam;
 import com.fs.store.vo.FsVesselListUVO;
 import com.fs.store.vo.FsVesselListVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsDepartmentService.java

@@ -1,7 +1,7 @@
 package com.fs.store.service;
 
 import com.fs.store.domain.FsDepartment;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsFollowTempService.java

@@ -1,7 +1,7 @@
 package com.fs.store.service;
 
 import com.fs.store.domain.FsFollowTemp;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsTestTempService.java

@@ -1,7 +1,7 @@
 package com.fs.store.service;
 
 import com.fs.store.domain.FsTestTemp;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsVesselService.java

@@ -4,7 +4,7 @@ import com.fs.store.domain.FsVessel;
 import com.fs.store.param.FsVesselListUParam;
 import com.fs.store.vo.FsVesselListUVO;
 import com.fs.store.vo.FsVesselListVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 

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

@@ -10,4 +10,12 @@ public interface IFsUserCourseCacheService {
      * @return 课程
      */
     public FsUserCourse selectFsUserCourseByCourseId(Long courseId);
+
+    /**
+     * 查询课程名称
+     *
+     * @param courseId 课程主键
+     * @return 课程名称
+     */
+    public String selectCourseNameByCourseId(Long courseId);
 }

+ 9 - 0
fs-service-system/src/main/java/com/fs/store/service/cache/impl/FsUserCourseCacheServiceImpl.java

@@ -21,8 +21,17 @@ public class FsUserCourseCacheServiceImpl implements IFsUserCourseCacheService {
             .maximumSize(1000)
             .expireAfterWrite(1, TimeUnit.MINUTES)
             .build();
+    private static final Cache<Long, String> COURSE_ID_AND_NAME = Caffeine.newBuilder()
+            .maximumSize(1000)
+            .expireAfterWrite(1, TimeUnit.MINUTES)
+            .build();
     @Override
     public FsUserCourse selectFsUserCourseByCourseId(Long courseId) {
         return FS_USER_COURSE_CACHE.get(courseId,e-> fsUserCourseService.selectFsUserCourseByCourseId(courseId));
     }
+
+    @Override
+    public String selectCourseNameByCourseId(Long courseId) {
+        return COURSE_ID_AND_NAME.get(courseId, e-> fsUserCourseService.selectFsUserCourseByCourseId(courseId).getCourseName());
+    }
 }

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/impl/FsDepartmentServiceImpl.java

@@ -5,7 +5,7 @@ import com.fs.common.utils.DateUtils;
 import com.fs.store.domain.FsDepartment;
 import com.fs.store.mapper.FsDepartmentMapper;
 import com.fs.store.service.IFsDepartmentService;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/impl/FsFollowTempServiceImpl.java

@@ -5,7 +5,7 @@ import com.fs.common.utils.DateUtils;
 import com.fs.store.domain.FsFollowTemp;
 import com.fs.store.mapper.FsFollowTempMapper;
 import com.fs.store.service.IFsFollowTempService;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/impl/FsTestTempServiceImpl.java

@@ -6,7 +6,7 @@ import com.fs.common.utils.DateUtils;
 import com.fs.store.domain.FsTestTemp;
 import com.fs.store.mapper.FsTestTempMapper;
 import com.fs.store.service.IFsTestTempService;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/service/impl/FsVesselServiceImpl.java

@@ -8,7 +8,7 @@ import com.fs.store.param.FsVesselListUParam;
 import com.fs.store.service.IFsVesselService;
 import com.fs.store.vo.FsVesselListUVO;
 import com.fs.store.vo.FsVesselListVO;
-import com.fs.his.vo.OptionsVO;;
+import com.fs.his.vo.OptionsVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 

+ 7 - 1
fs-service-system/src/main/resources/mapper/course/FsCourseLinkMapper.xml

@@ -18,10 +18,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="courseId"    column="course_id"    />
         <result property="qwExternalId"    column="qw_external_id"    />
         <result property="linkType"    column="link_type"    />
+        <result property="isRoom"    column="is_room"    />
     </resultMap>
 
     <sql id="selectFsCourseLinkVo">
-        select link_id, link, real_link,link_type, create_time, update_time, company_id, company_user_id, qw_user_id, video_id, corp_id, course_id ,qw_external_id  from fs_course_link
+        select link_id, is_room,link, real_link,link_type, create_time, update_time, company_id, company_user_id, qw_user_id, video_id, corp_id, course_id ,qw_external_id  from fs_course_link
     </sql>
 
     <select id="selectFsCourseLinkList" parameterType="FsCourseLink" resultMap="FsCourseLinkResult">
@@ -60,6 +61,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseId != null">course_id,</if>
             <if test="qwExternalId != null">qw_external_id,</if>
             <if test="linkType != null">link_type,</if>
+            <if test="isRoom != null">is_room,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="link != null">#{link},</if>
@@ -74,6 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseId != null">#{courseId},</if>
             <if test="qwExternalId != null">#{qwExternalId},</if>
             <if test="linkType != null">#{linkType},</if>
+            <if test="isRoom != null">#{isRoom},</if>
          </trim>
     </insert>
 
@@ -97,6 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                         <if test="item.courseId != null">course_id,</if>
                         <if test="item.qwExternalId != null">qw_external_id,</if>
                         <if test="item.linkType != null">link_type,</if>
+                        <if test="item.isRoom != null">is_room,</if>
                     </if>
                 </foreach>
             </if>
@@ -116,6 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 <if test="item.courseId != null">#{item.courseId},</if>
                 <if test="item.qwExternalId != null">#{item.qwExternalId},</if>
                 <if test="item.linkType != null">#{item.linkType},</if>
+                <if test="item.isRoom != null">#{item.isRoom},</if>
             </trim>)
             </foreach>
         </trim>
@@ -137,6 +142,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseId != null">course_id = #{courseId},</if>
             <if test="qwExternalId != null">qw_external_id = #{qwExternalId},</if>
             <if test="linkType != null">link_type = #{linkType},</if>
+            <if test="isRoom != null">is_room = #{isRoom},</if>
         </trim>
         where link_id = #{linkId}
     </update>

+ 42 - 1
fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml

@@ -19,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsCourseTrafficLogVo">
-        select log_id, uu_id,user_id, video_id, create_time, qw_external_contact_id, internet_traffic, qw_user_id, company_user_id, company_id, course_id from fs_course_traffic_log
+        select log_id, uu_id,user_id, video_id, create_time, qw_external_contact_id, internet_traffic, qw_user_id, company_user_id, company_id, course_id, project from fs_course_traffic_log
     </sql>
 
     <select id="selectFsCourseTrafficLogList" parameterType="FsCourseTrafficLog" resultMap="FsCourseTrafficLogResult">
@@ -40,6 +40,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectFsCourseTrafficLogVo"/>
         where log_id = #{logId}
     </select>
+    <select id="selectTrafficByCompany" resultType="com.fs.course.vo.FsCourseTrafficLogListVO">
+        select c.company_name, SUM(l.internet_traffic) AS total_internet_traffic
+        ,DATE_FORMAT(l.create_time, '%Y-%m') AS `month`  from fs_course_traffic_log l
+        left join company c on c.company_id = l.company_id
+        where 1 = 1
+        <if test= 'maps.year != null '>
+            and YEAR(l.create_time) = #{maps.year}
+            </if>
+        <if test= 'maps.month != null '>
+            and MONTH(l.create_time) = #{maps.month}
+            </if>
+        <if test = ' maps.companyId !=null '>
+            and l.company_id = #{maps.companyId}
+            </if>
+        group by l.company_id,`month`
+
+    </select>
+    <select id="selectTrafficNew" resultType="com.fs.course.vo.FsCourseTrafficLogListVO">
+        select company_id,project,course_id,SUM(internet_traffic) AS total_internet_traffic
+        ,DATE_FORMAT(create_time, '%Y-%m') AS `month`  from fs_course_traffic_log
+        <where>
+            <if test="startDate != null and endDate != null">
+                and create_time between #{startDate} AND #{endDate}
+            </if>
+            <if test='companyId !=null'>
+                and company_id = #{companyId}
+            </if>
+            <if test="courseId != null">
+                and course_id = ${courseId}
+            </if>
+            <if test="project">
+                and project = ${project}
+            </if>
+        </where>
+        group by company_id,`month`,project,course_id
+    </select>
 
     <insert id="insertFsCourseTrafficLog" parameterType="FsCourseTrafficLog" useGeneratedKeys="true" keyProperty="logId">
         insert into fs_course_traffic_log
@@ -54,6 +90,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">company_id,</if>
             <if test="courseId != null">course_id,</if>
             <if test="uuId != null">uu_id,</if>
+            <if test="project != null">project,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="userId != null">#{userId},</if>
@@ -66,6 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">#{companyId},</if>
             <if test="courseId != null">#{courseId},</if>
             <if test="uuId != null">#{uuId},</if>
+            <if test="project != null">#{project},</if>
          </trim>
     </insert>
 
@@ -82,6 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">company_id,</if>
             <if test="courseId != null">course_id,</if>
             <if test="uuId != null">uu_id,</if>
+            <if test="project != null">project,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="userId != null">#{userId},</if>
@@ -94,6 +133,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">#{companyId},</if>
             <if test="courseId != null">#{courseId},</if>
             <if test="uuId != null">#{uuId},</if>
+            <if test="project != null">#{project},</if>
         </trim>
         on duplicate key update
         <trim suffixOverrides=",">
@@ -114,6 +154,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">company_id = #{companyId},</if>
             <if test="courseId != null">course_id = #{courseId},</if>
             <if test="uuId != null">uu_id = #{uuId},</if>
+            <if test="project != null">project = #{project},</if>
         </trim>
         where log_id = #{logId}
     </update>

+ 28 - 4
fs-user-app/src/main/java/com/fs/app/controller/CourseH5Controller.java

@@ -2,14 +2,15 @@ package com.fs.app.controller;
 
 
 import cn.hutool.json.JSONUtil;
+import com.fs.app.annotation.Login;
+import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCourseWatchLog;
+import com.fs.course.param.FsCourseQuestionAnswerUParam;
+import com.fs.course.param.FsCourseSendRewardUParam;
 import com.fs.course.param.FsUserCourseVideoFinishUParam;
-import com.fs.course.service.IFsCourseLinkService;
-import com.fs.course.service.IFsCourseWatchLogService;
-import com.fs.course.service.IFsUserCourseService;
-import com.fs.course.service.IFsUserCourseVideoService;
+import com.fs.course.service.*;
 import com.fs.course.vo.FsUserCourseVideoH5DVO;
 import com.fs.course.vo.FsUserCourseVideoH5VO;
 import com.fs.system.service.ISysConfigService;
@@ -41,6 +42,9 @@ public class CourseH5Controller extends  AppBaseController{
     @Autowired
     private IFsCourseWatchLogService courseWatchLogService;
 
+    @Autowired
+    private IFsCourseQuestionBankService questionBankService;
+
 
     @ApiOperation("h5课程简介")
     @GetMapping("/getH5CourseByVideoId")
@@ -117,6 +121,26 @@ public class CourseH5Controller extends  AppBaseController{
         return courseVideoService.getInternetTraffic(param);
     }
 
+    @ApiOperation("答题")
+    @PostMapping("/courseAnswer")
+    public R courseAnswer(@RequestBody FsCourseQuestionAnswerUParam param)
+    {
+        logger.info("zyp \n【答题】:{}",param.getQuestions());
+        if (param.getDuration()==null){
+            logger.info("zyp \n【未识别到时长】:{}",param.getUserId());
+        }
+        return questionBankService.courseAnswer(param);
+    }
+
+    @ApiOperation("发放奖励")
+    @PostMapping("/sendReward")
+    @RepeatSubmit
+    public R sendReward(@RequestBody FsCourseSendRewardUParam param)
+    {
+        logger.info("zyp \n【发放奖励】:{}",param);
+        return courseVideoService.sendReward(param);
+    }
+
     @PostMapping("/getErrMsg")
     public void getErrMsg(@RequestParam("msg") String msg) {
         logger.error("zyp \n【h5看课中途报错】:{}",msg);