Parcourir la source

update 租户后台 课程管理新增目录,视频上传以及问题设置

ct il y a 1 semaine
Parent
commit
42e3cd753b

+ 53 - 68
fs-admin-saas/src/main/java/com/fs/course/controller/FsCourseQuestionBankController.java

@@ -51,27 +51,15 @@ public class FsCourseQuestionBankController extends BaseController
     public TableDataInfo list(FsCourseQuestionBank fsCourseQuestionBank)
     public TableDataInfo list(FsCourseQuestionBank fsCourseQuestionBank)
     {
     {
         startPage();
         startPage();
-        applyQuestionBankOwnerScope(fsCourseQuestionBank);
-        List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankList(fsCourseQuestionBank);
-        return getDataTable(list);
-    }
-
-    /**
-     * 课程配置开启「绑定创建人」时,按当前登录后台用户过滤题库归属
-     */
-    private void applyQuestionBankOwnerScope(FsCourseQuestionBank query) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        if (loginUser == null) {
-            return;
-        }
+        Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         String json = configService.selectConfigByKey("course.config");
-        if (ObjectUtil.isEmpty(json)) {
-            return;
-        }
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
-            query.setUserId(loginUser.getUserId());
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsCourseQuestionBank.setUserId(userId);
         }
         }
+        List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankList(fsCourseQuestionBank);
+        return getDataTable(list);
     }
     }
 
 
     /**
     /**
@@ -82,18 +70,17 @@ public class FsCourseQuestionBankController extends BaseController
     @GetMapping("/export")
     @GetMapping("/export")
     public AjaxResult export(FsCourseQuestionBank fsCourseQuestionBank)
     public AjaxResult export(FsCourseQuestionBank fsCourseQuestionBank)
     {
     {
-//        com.fs.framework.security.LoginUser loginUser = (com.fs.framework.security.LoginUser) tokenService.getLoginUser(ServletUtils.getRequest());
-//        Long userId = loginUser.getCompanyUser() != null ? loginUser.getCompanyUser().getUserId() : null;
-//        String json = configService.selectConfigByKey("course.config");
-//        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-//        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
-//            fsCourseQuestionBank.setUserId(userId);
-//        }
-//
-//        List<FsCourseQuestionBankImportDTO> list = fsCourseQuestionBankService.exportData(fsCourseQuestionBank);
-//        ExcelUtil<FsCourseQuestionBankImportDTO> util = new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
-//        return util.exportExcel(list, "题库数据");
-        throw new RuntimeException("未实现");
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsCourseQuestionBank.setUserId(userId);
+        }
+
+        List<FsCourseQuestionBankImportDTO> list = fsCourseQuestionBankService.exportData(fsCourseQuestionBank);
+        ExcelUtil<FsCourseQuestionBankImportDTO> util = new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
+        return util.exportExcel(list, "题库数据");
     }
     }
 
 
     @PreAuthorize("@ss.hasPermi('course:courseQuestionBank:exportFail')")
     @PreAuthorize("@ss.hasPermi('course:courseQuestionBank:exportFail')")
@@ -124,17 +111,16 @@ public class FsCourseQuestionBankController extends BaseController
     @PostMapping
     @PostMapping
     public AjaxResult add(@RequestBody FsCourseQuestionBank fsCourseQuestionBank)
     public AjaxResult add(@RequestBody FsCourseQuestionBank fsCourseQuestionBank)
     {
     {
-//        com.fs.framework.security.LoginUser loginUser = (com.fs.framework.security.LoginUser) tokenService.getLoginUser(ServletUtils.getRequest());
-//        fsCourseQuestionBank.setCreateBy(loginUser.getCompanyUser().getNickName());
-//        Long userId = loginUser.getCompanyUser().getUserId();
-//        String json = configService.selectConfigByKey("course.config");
-//        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-//        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
-//            fsCourseQuestionBank.setUserId(userId);
-//        }
-//
-//        return toAjax(fsCourseQuestionBankService.insertFsCourseQuestionBank(fsCourseQuestionBank));
-        throw new RuntimeException("未实现");
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fsCourseQuestionBank.setCreateBy(loginUser.getUser().getNickName());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsCourseQuestionBank.setUserId(userId);
+        }
+
+        return toAjax(fsCourseQuestionBankService.insertFsCourseQuestionBank(fsCourseQuestionBank));
     }
     }
 
 
     /**
     /**
@@ -171,34 +157,33 @@ public class FsCourseQuestionBankController extends BaseController
     @PostMapping("/importData")
     @PostMapping("/importData")
     public AjaxResult importData(MultipartFile file) throws Exception {
     public AjaxResult importData(MultipartFile file) throws Exception {
 
 
-//        ExcelUtil<FsCourseQuestionBankImportDTO> util =
-//                new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
-//        List<FsCourseQuestionBankImportDTO> list =
-//                util.importExcel(file.getInputStream());
-//
-//        com.fs.framework.security.LoginUser loginUser = (com.fs.framework.security.LoginUser) tokenService.getLoginUser(ServletUtils.getRequest());
-//        Long userId = loginUser.getCompanyUser().getUserId();
-//
-//        // 读取配置
-//        String json = configService.selectConfigByKey("course.config");
-//        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-//
-//        // 绑定状态控制 userId
-//        Long finalUserId = (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound())
-//                ? userId
-//                : null;
-//
-//        // 调用 service
-//        ImportResultDTO result =
-//                fsCourseQuestionBankService.importData(list, loginUser.getCompanyUser().getNickName(), finalUserId);
-//
-//        // 返回 message + failList
-//        Map<String, Object> resp = new HashMap<>();
-//        resp.put("message", result.buildResultMessage());
-//        resp.put("failList", result.getFailureList());
-//
-//        return AjaxResult.success(resp);
-        throw new RuntimeException("未实现");
+        ExcelUtil<FsCourseQuestionBankImportDTO> util =
+                new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
+        List<FsCourseQuestionBankImportDTO> list =
+                util.importExcel(file.getInputStream());
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+
+        // 读取配置
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+
+        // 绑定状态控制 userId
+        Long finalUserId = (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound())
+                ? userId
+                : null;
+
+        // 调用 service
+        ImportResultDTO result =
+                fsCourseQuestionBankService.importData(list, loginUser.getUser().getNickName(), finalUserId);
+
+        // 返回 message + failList
+        Map<String, Object> resp = new HashMap<>();
+        resp.put("message", result.buildResultMessage());
+        resp.put("failList", result.getFailureList());
+
+        return AjaxResult.success(resp);
     }
     }
 
 
     @GetMapping(value = "/getByIds")
     @GetMapping(value = "/getByIds")

+ 109 - 0
fs-admin-saas/src/main/java/com/fs/his/controller/FsCourseCouponController.java

@@ -0,0 +1,109 @@
+package com.fs.his.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.exception.CustomException;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.his.domain.FsCourseCoupon;
+import com.fs.his.service.IFsCourseCouponService;
+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 2026-05-13
+ */
+@RestController
+@RequestMapping("/his/courserCoupon")
+public class FsCourseCouponController extends BaseController
+{
+    @Autowired
+    private IFsCourseCouponService fsCourseCouponService;
+
+    /**
+     * 查询课程优惠券列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsCourseCoupon fsCourseCoupon)
+    {
+        startPage();
+        List<FsCourseCoupon> list = fsCourseCouponService.selectFsCourseCouponList(fsCourseCoupon);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出课程优惠券列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:export')")
+    @Log(title = "课程优惠券", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsCourseCoupon fsCourseCoupon)
+    {
+        List<FsCourseCoupon> list = fsCourseCouponService.selectFsCourseCouponList(fsCourseCoupon);
+        ExcelUtil<FsCourseCoupon> util = new ExcelUtil<FsCourseCoupon>(FsCourseCoupon.class);
+        return util.exportExcel(list, "课程优惠券数据");
+    }
+
+    /**
+     * 获取课程优惠券详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsCourseCouponService.selectFsCourseCouponById(id));
+    }
+
+    /**
+     * 新增课程优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:add')")
+    @Log(title = "课程优惠券", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsCourseCoupon fsCourseCoupon)
+    {
+        return toAjax(fsCourseCouponService.insertFsCourseCoupon(fsCourseCoupon));
+    }
+
+    /**
+     * 修改课程优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:edit')")
+    @Log(title = "课程优惠券", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsCourseCoupon fsCourseCoupon)
+    {
+        FsCourseCoupon c = fsCourseCouponService.selectFsCourseCouponById(fsCourseCoupon.getId());
+        long l = c.getRemainNumber() + fsCourseCoupon.getNumber() - c.getNumber();
+        if (l < 0) {
+            throw new CustomException("剩余卷不足");
+        }
+        fsCourseCoupon.setRemainNumber(l);
+        return toAjax(fsCourseCouponService.updateFsCourseCoupon(fsCourseCoupon));
+    }
+
+    /**
+     * 删除课程优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courserCoupon:remove')")
+    @Log(title = "课程优惠券", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsCourseCouponService.deleteFsCourseCouponByIds(ids));
+    }
+
+    @GetMapping("/options")
+    public AjaxResult selectFsCourseCouponOptions(){
+        return AjaxResult.success(fsCourseCouponService.selectFsCourseCouponOptions());
+    }
+}

+ 15 - 0
fs-service/src/main/java/com/fs/course/domain/FsUserCourseVideo.java

@@ -1,5 +1,6 @@
 package com.fs.course.domain;
 package com.fs.course.domain;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.annotation.Excel;
@@ -128,4 +129,18 @@ public class FsUserCourseVideo extends BaseEntity
     private String jobId;
     private String jobId;
 
 
     private String vid;
     private String vid;
+
+    /** 看课奖励类型(展示文案,可配置) */
+    private String rewardType;
+
+    /** 课程介绍图片URL */
+    private String courseIntroImg;
+
+    /**
+     * 课程优惠券ID
+     */
+    private Long courseCouponId;
+
+    @TableField(exist = false)
+    private Integer showProduct; //1不展示疗法,0展示疗法
 }
 }

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

@@ -744,4 +744,5 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      */
      */
     List<FsCourseReportVO> selectWatchStatistics(FsCourseWatchLogStatisticsListParam param);
     List<FsCourseReportVO> selectWatchStatistics(FsCourseWatchLogStatisticsListParam param);
 
 
+    FsCourseWatchLog getWatchLogByFsUserAndPeriodId(@Param("videoId") Long videoId, @Param("fsUserId") Long fsUserId, @Param("companyUserId") Long companyUserId, @Param("periodId") Long periodId);
 }
 }

+ 58 - 0
fs-service/src/main/java/com/fs/his/domain/FsCourseCoupon.java

@@ -0,0 +1,58 @@
+package com.fs.his.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 课程优惠券对象 fs_course_coupon
+ *
+ * @author fs
+ * @date 2026-05-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsCourseCoupon extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 有效期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "有效期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date limitTime;
+
+    /** 数量 */
+    @Excel(name = "数量")
+    private Long number;
+
+    /** 剩余数量 */
+    @Excel(name = "剩余数量")
+    private Long remainNumber;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long status;
+
+    /** 领取后有效期 */
+    @Excel(name = "领取后有效期")
+    private Long limitDay;
+
+    /** 有效期类别 1 过期时间 2 领取后有效期 */
+    @Excel(name = "有效期类别 1 过期时间 2 领取后有效期")
+    private Long limitType;
+
+    /** 每人可领取数量 */
+    @Excel(name = "每人可领取数量")
+    private Long limitCount;
+
+    /** 标题 */
+    @Excel(name = "标题")
+    private String title;
+
+
+}

+ 58 - 0
fs-service/src/main/java/com/fs/his/domain/FsCourseCouponUser.java

@@ -0,0 +1,58 @@
+package com.fs.his.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 用户看课优惠券对象 fs_course_coupon_user
+ *
+ * @author fs
+ * @date 2026-05-13
+ */
+@Data
+public class FsCourseCouponUser {
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 优惠券id */
+    @Excel(name = "优惠券id")
+    private Long couponId;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 有效期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "有效期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date limitTime;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date startTime;
+
+    /** 核销状态 0-未核销 1-已核销 */
+    @Excel(name = "核销状态 0-未核销 1-已核销")
+    private Integer status;
+
+    /**
+     * 看课记录ID
+     */
+    private Long logId;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** 更新时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+}

+ 66 - 0
fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponMapper.java

@@ -0,0 +1,66 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsCourseCoupon;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 课程优惠券Mapper接口
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+public interface FsCourseCouponMapper extends BaseMapper<FsCourseCoupon>{
+    /**
+     * 查询课程优惠券
+     * 
+     * @param id 课程优惠券主键
+     * @return 课程优惠券
+     */
+    FsCourseCoupon selectFsCourseCouponById(Long id);
+
+    /**
+     * 查询课程优惠券列表
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 课程优惠券集合
+     */
+    List<FsCourseCoupon> selectFsCourseCouponList(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 新增课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    int insertFsCourseCoupon(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 修改课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    int updateFsCourseCoupon(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 删除课程优惠券
+     * 
+     * @param id 课程优惠券主键
+     * @return 结果
+     */
+    int deleteFsCourseCouponById(Long id);
+
+    /**
+     * 批量删除课程优惠券
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsCourseCouponByIds(Long[] ids);
+
+    @Select("SELECT id,title FROM fs_course_coupon WHERE `status` = 1")
+    List<FsCourseCoupon> selectFsCourseCouponOptions();
+}

+ 77 - 0
fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponUserMapper.java

@@ -0,0 +1,77 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsCourseCouponUser;
+import com.fs.his.vo.CourseCouponUserListUVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 用户看课优惠券Mapper接口
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+public interface FsCourseCouponUserMapper extends BaseMapper<FsCourseCouponUser>{
+    /**
+     * 查询用户看课优惠券
+     * 
+     * @param id 用户看课优惠券主键
+     * @return 用户看课优惠券
+     */
+    FsCourseCouponUser selectFsCourseCouponUserById(Long id);
+
+    /**
+     * 查询用户看课优惠券列表
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 用户看课优惠券集合
+     */
+    List<FsCourseCouponUser> selectFsCourseCouponUserList(FsCourseCouponUser fsCourseCouponUser);
+
+    /**
+     * 新增用户看课优惠券
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 结果
+     */
+    int insertFsCourseCouponUser(FsCourseCouponUser fsCourseCouponUser);
+
+    /**
+     * 修改用户看课优惠券
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 结果
+     */
+    int updateFsCourseCouponUser(FsCourseCouponUser fsCourseCouponUser);
+
+    /**
+     * 删除用户看课优惠券
+     * 
+     * @param id 用户看课优惠券主键
+     * @return 结果
+     */
+    int deleteFsCourseCouponUserById(Long id);
+
+    /**
+     * 批量删除用户看课优惠券
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsCourseCouponUserByIds(Long[] ids);
+
+    @Select("SELECT count(*) FROM fs_course_coupon_user WHERE user_id = #{userId}  AND coupon_id = #{couponId}")
+    Integer selectCountByUserIdAndCouponId(@Param("userId") Long userId,@Param("couponId") Long couponId);
+
+    @Select("SELECT * FROM fs_course_coupon_user WHERE log_id = #{logId}")
+    FsCourseCouponUser selectByLogId(@Param("logId") Long logId);
+    @Select("SELECT cu.*,c.title couponName \n" +
+            "FROM `fs_course_coupon_user` cu \n" +
+            "LEFT JOIN fs_course_coupon c ON cu.coupon_id = c.id \n" +
+            "WHERE cu.user_id = #{param.userId} \n" +
+            "AND cu.`status` = #{param.status}")
+    List<CourseCouponUserListUVO> selectCourseCouponUserList(@Param("param") FsCourseCouponUser fsCourseCouponUser);
+}

+ 21 - 0
fs-service/src/main/java/com/fs/his/param/CourseFinishRewardParam.java

@@ -0,0 +1,21 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+@Data
+public class CourseFinishRewardParam {
+
+    private Long companyId;
+
+    private Long periodId;
+
+    private Long userId;
+
+    private Long videoId;
+
+    private Long companyUserId;
+
+    private Long qwUsrId;
+
+    private Long qwExternalId;
+}

+ 73 - 0
fs-service/src/main/java/com/fs/his/service/IFsCourseCouponService.java

@@ -0,0 +1,73 @@
+package com.fs.his.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.FsCourseCoupon;
+
+import java.util.List;
+
+/**
+ * 课程优惠券Service接口
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+public interface IFsCourseCouponService extends IService<FsCourseCoupon>{
+    /**
+     * 查询课程优惠券
+     * 
+     * @param id 课程优惠券主键
+     * @return 课程优惠券
+     */
+    FsCourseCoupon selectFsCourseCouponById(Long id);
+
+    /**
+     * 查询课程优惠券列表
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 课程优惠券集合
+     */
+    List<FsCourseCoupon> selectFsCourseCouponList(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 新增课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    int insertFsCourseCoupon(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 修改课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    int updateFsCourseCoupon(FsCourseCoupon fsCourseCoupon);
+
+    /**
+     * 批量删除课程优惠券
+     * 
+     * @param ids 需要删除的课程优惠券主键集合
+     * @return 结果
+     */
+    int deleteFsCourseCouponByIds(Long[] ids);
+
+    /**
+     * 删除课程优惠券信息
+     * 
+     * @param id 课程优惠券主键
+     * @return 结果
+     */
+    int deleteFsCourseCouponById(Long id);
+
+    List<FsCourseCoupon> selectFsCourseCouponOptions();
+
+    /**
+     * 发送课程优惠券
+     * @param videoId 小节Id
+     * @param userId 用户Id
+     */
+    R sendAutoCourseCoupon(Long videoId, Long userId,Long companyId,Long qwUserId,Long qwExternalId);
+    R sendCourseCoupon(Long videoId, Long userId,Long companyId,Long periodId,Long companyUserId);
+}

+ 383 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponServiceImpl.java

@@ -0,0 +1,383 @@
+package com.fs.his.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.DateUtils;
+import com.fs.course.domain.FsCourseWatchLog;
+import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.course.mapper.FsUserCourseVideoMapper;
+import com.fs.course.mapper.FsUserCourseVideoRedPackageMapper;
+import com.fs.his.domain.FsCourseCoupon;
+import com.fs.his.domain.FsCourseCouponUser;
+import com.fs.his.mapper.FsCourseCouponMapper;
+import com.fs.his.mapper.FsCourseCouponUserMapper;
+import com.fs.his.param.CourseFinishRewardParam;
+import com.fs.his.service.IFsCourseCouponService;
+import com.fs.his.vo.CourseFinishRewardVO;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 课程优惠券Service业务层处理
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+@Service
+public class FsCourseCouponServiceImpl extends ServiceImpl<FsCourseCouponMapper, FsCourseCoupon> implements IFsCourseCouponService {
+
+    @Autowired
+    private FsCourseCouponUserMapper courseCouponUserMapper;
+
+    @Autowired
+    private FsUserCourseVideoMapper userCourseVideoMapper;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private FsUserCourseVideoRedPackageMapper fsUserCourseVideoRedPackageMapper;
+
+    @Autowired
+    private FsCourseWatchLogMapper courseWatchLogMapper;
+    /**
+     * 查询课程优惠券
+     * 
+     * @param id 课程优惠券主键
+     * @return 课程优惠券
+     */
+    @Override
+    public FsCourseCoupon selectFsCourseCouponById(Long id)
+    {
+        return baseMapper.selectFsCourseCouponById(id);
+    }
+
+    /**
+     * 查询课程优惠券列表
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 课程优惠券
+     */
+    @Override
+    public List<FsCourseCoupon> selectFsCourseCouponList(FsCourseCoupon fsCourseCoupon)
+    {
+        return baseMapper.selectFsCourseCouponList(fsCourseCoupon);
+    }
+
+    /**
+     * 新增课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    @Override
+    public int insertFsCourseCoupon(FsCourseCoupon fsCourseCoupon)
+    {
+        fsCourseCoupon.setCreateTime(DateUtils.getNowDate());
+        fsCourseCoupon.setRemainNumber(fsCourseCoupon.getNumber());
+        return baseMapper.insertFsCourseCoupon(fsCourseCoupon);
+    }
+
+    /**
+     * 修改课程优惠券
+     * 
+     * @param fsCourseCoupon 课程优惠券
+     * @return 结果
+     */
+    @Override
+    public int updateFsCourseCoupon(FsCourseCoupon fsCourseCoupon)
+    {
+        fsCourseCoupon.setUpdateTime(DateUtils.getNowDate());
+        return baseMapper.updateFsCourseCoupon(fsCourseCoupon);
+    }
+
+    /**
+     * 批量删除课程优惠券
+     * 
+     * @param ids 需要删除的课程优惠券主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsCourseCouponByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsCourseCouponByIds(ids);
+    }
+
+    /**
+     * 删除课程优惠券信息
+     * 
+     * @param id 课程优惠券主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsCourseCouponById(Long id)
+    {
+        return baseMapper.deleteFsCourseCouponById(id);
+    }
+
+    @Override
+    public List<FsCourseCoupon> selectFsCourseCouponOptions() {
+        return baseMapper.selectFsCourseCouponOptions();
+    }
+
+    //自动
+    @Override
+    @Transactional
+    public R sendAutoCourseCoupon(Long videoId, Long userId,Long companyId,Long qwUserId,Long qwExternalId) {
+        CourseFinishRewardParam param = new CourseFinishRewardParam();
+        param.setVideoId(videoId);
+        param.setUserId(userId);
+        param.setCompanyId(companyId);
+        param.setQwUsrId(qwUserId);
+        param.setQwExternalId(qwExternalId);
+        return sendCoupon(param,1);
+//        CourseFinishRewardVO rewardVO = new CourseFinishRewardVO();
+//        rewardVO.setTag(0);
+//        String couponName = null;
+//
+//        boolean isSend = true;
+//        //课程小节信息
+//        FsUserCourseVideo courseVideo = userCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+//        if (courseVideo == null) {
+//            return R.error("课程小节不存在");
+//        }
+//        if (courseVideo.getCourseCouponId() == null){
+//            //没用优惠券直接返回
+//            return R.ok().put("data", rewardVO);
+//        }
+//
+//        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideo(userId, videoId, qwUserId.toString(), qwExternalId);
+//        if (log == null){
+//            return R.error("请先观看课程");
+//        }
+//        FsCourseCouponUser selectByLogId = courseCouponUserMapper.selectByLogId(log.getLogId());
+//        if (selectByLogId != null) {
+//            return R.ok().put("data", rewardVO);
+//        }
+//        //优惠券
+//        FsCourseCoupon fsCourseCoupon = baseMapper.selectFsCourseCouponById(courseVideo.getCourseCouponId());
+//        if (fsCourseCoupon != null) {
+//            if (fsCourseCoupon.getStatus() != 1) {
+//                isSend = false;
+//            }
+//            if (fsCourseCoupon.getRemainNumber() <= 0) {
+//                isSend = false;
+//            }
+//            //用户领取优惠券总数
+//            Integer count = courseCouponUserMapper.selectCountByUserIdAndCouponId(userId, courseVideo.getCourseCouponId());
+//            if (count >= fsCourseCoupon.getLimitCount()) {
+//                isSend = false;
+//            }
+//        } else {
+//            isSend = false;
+//        }
+//
+//        if (isSend) {
+//            //发放优惠券
+//            FsCourseCouponUser couponUser = new FsCourseCouponUser();
+//            couponUser.setCouponId(courseVideo.getCourseCouponId());
+//            couponUser.setUserId(userId);
+//            couponUser.setStartTime(new Date());
+//            couponUser.setLimitTime(fsCourseCoupon.getLimitTime());
+//            couponUser.setCreateTime(new Date());
+//            couponUser.setLogId(log.getLogId());
+//            int i = courseCouponUserMapper.insertFsCourseCouponUser(couponUser);
+//
+//            //返回的优惠券名称
+//            couponName = fsCourseCoupon.getTitle();
+//            if (i > 0) {
+//                FsCourseCoupon coupon = new FsCourseCoupon();
+//                coupon.setId(courseVideo.getCourseCouponId());
+//                coupon.setRemainNumber(fsCourseCoupon.getRemainNumber() - 1);
+//                baseMapper.updateFsCourseCoupon(coupon);
+//            }
+//            rewardVO.setCouponName(couponName);
+//            rewardVO.setTag(1);
+//            return R.ok().put("data",rewardVO);
+//        } else {
+//            return R.ok().put("data",rewardVO);
+//        }
+    }
+
+    //手动
+    @Transactional
+    @Override
+    public R sendCourseCoupon(Long videoId, Long userId,Long companyId,Long periodId,Long companyUserId) {
+        CourseFinishRewardParam param = new CourseFinishRewardParam();
+        param.setVideoId(videoId);
+        param.setUserId(userId);
+        param.setCompanyId(companyId);
+        param.setPeriodId(periodId);
+        param.setCompanyUserId(companyUserId);
+        return sendCoupon(param,2);
+//        CourseFinishRewardVO rewardVO = new CourseFinishRewardVO();
+//        rewardVO.setTag(0);
+//        String couponName;
+//
+//        boolean isSend = true;
+//        //课程小节信息
+//        FsUserCourseVideo courseVideo = userCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+//        if (courseVideo == null) {
+//            return R.error("课程小节不存在");
+//        }
+//
+//        if (courseVideo.getCourseCouponId() == null){
+//            //没用优惠券直接返回
+//            return R.ok().put("data", rewardVO);
+//        }
+//
+//        FsCourseWatchLog log = courseWatchLogMapper.getWatchLogByFsUserAndPeriodId(videoId, userId, companyUserId, periodId);
+//        if (log == null) {
+//            return R.error("请先观看课程");
+//        }
+//        FsCourseCouponUser selectByLogId = courseCouponUserMapper.selectByLogId(log.getLogId());
+//        if (selectByLogId != null) {
+//            return R.ok().put("data", rewardVO);
+//        }
+//
+//        //优惠券
+//        FsCourseCoupon fsCourseCoupon = baseMapper.selectFsCourseCouponById(courseVideo.getCourseCouponId());
+//        if (fsCourseCoupon != null) {
+//            if (fsCourseCoupon.getStatus() != 1) {
+//                isSend = false;
+//            }
+//            if (fsCourseCoupon.getRemainNumber() <= 0) {
+//                isSend = false;
+//            }
+//            //用户领取优惠券总数
+//            Integer count = courseCouponUserMapper.selectCountByUserIdAndCouponId(userId, courseVideo.getCourseCouponId());
+//            if (count >= fsCourseCoupon.getLimitCount()) {
+//                isSend = false;
+//            }
+//        } else {
+//            isSend = false;
+//        }
+//
+//        if (isSend) {
+//            //发放优惠券
+//            FsCourseCouponUser couponUser = new FsCourseCouponUser();
+//            couponUser.setCouponId(courseVideo.getCourseCouponId());
+//            couponUser.setUserId(userId);
+//            couponUser.setStartTime(new Date());
+//            couponUser.setLimitTime(fsCourseCoupon.getLimitTime());
+//            couponUser.setCreateTime(new Date());
+//            couponUser.setLogId(log.getLogId());
+//            int i = courseCouponUserMapper.insertFsCourseCouponUser(couponUser);
+//
+//            //返回的优惠券名称
+//            couponName = fsCourseCoupon.getTitle();
+//            if (i > 0) {
+//                FsCourseCoupon coupon = new FsCourseCoupon();
+//                coupon.setId(courseVideo.getCourseCouponId());
+//                coupon.setRemainNumber(fsCourseCoupon.getRemainNumber() - 1);
+//                baseMapper.updateFsCourseCoupon(coupon);
+//            }
+//            rewardVO.setCouponName(couponName);
+//            rewardVO.setTag(1);
+//            return R.ok().put("data",rewardVO);
+//        } else {
+//            return R.ok().put("data", rewardVO);
+//        }
+////        // 获取配置信息
+////        String json = configService.selectConfigByKey("course.config");
+////        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+////        Integer rewardType = config.getRewardType();
+////
+////        if (rewardType == 1) {
+////            FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(videoId,companyId,periodId);
+////            if (redPackage != null && redPackage.getRedPacketMoney() != null) {
+////                amount = redPackage.getRedPacketMoney();
+////            } else if (courseVideo.getRedPacketMoney() != null) {
+////                amount = courseVideo.getRedPacketMoney();
+////            }
+////        }
+////        if (rewardType == 2) {
+////            integral = config.getAnswerIntegral();
+////        }
+    }
+
+    /**
+     * 发送看课优惠券
+     * @param param 优惠券参数
+     * @param type 1 自动 2 手动
+     * @return 结果
+     */
+    private R sendCoupon(CourseFinishRewardParam param,Integer type){
+        CourseFinishRewardVO rewardVO = new CourseFinishRewardVO();
+        //默认不弹窗
+        rewardVO.setTag(0);
+        //默认发送优惠券
+        boolean isSend = true;
+        //课程小节信息
+        FsUserCourseVideo courseVideo = userCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
+        if (courseVideo == null) {
+            return R.error("课程小节不存在");
+        }
+
+        if (courseVideo.getCourseCouponId() == null){
+            //没用优惠券直接返回
+            return R.ok().put("data", rewardVO);
+        }
+        FsCourseWatchLog log = null;
+        if (type == 1) {
+            log = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUsrId().toString(), param.getQwExternalId());
+        } else {
+            log = courseWatchLogMapper.getWatchLogByFsUserAndPeriodId(param.getVideoId(), param.getUserId(), param.getCompanyUserId(), param.getPeriodId());
+        }
+        if (log == null) {
+            return R.error("请先观看课程");
+        }
+
+        FsCourseCouponUser selectByLogId = courseCouponUserMapper.selectByLogId(log.getLogId());
+        if (selectByLogId != null) {
+            return R.ok().put("data", rewardVO);
+        }
+
+        //优惠券
+        FsCourseCoupon fsCourseCoupon = baseMapper.selectFsCourseCouponById(courseVideo.getCourseCouponId());
+        if (fsCourseCoupon != null) {
+            if (fsCourseCoupon.getStatus() != 1) {
+                isSend = false;
+            }
+            if (fsCourseCoupon.getRemainNumber() <= 0) {
+                isSend = false;
+            }
+            //用户领取优惠券总数
+            Integer count = courseCouponUserMapper.selectCountByUserIdAndCouponId(param.getUserId(), courseVideo.getCourseCouponId());
+            if (count >= fsCourseCoupon.getLimitCount()) {
+                isSend = false;
+            }
+        } else {
+            isSend = false;
+        }
+
+        if (isSend) {
+            //发放优惠券
+            FsCourseCouponUser couponUser = new FsCourseCouponUser();
+            couponUser.setCouponId(courseVideo.getCourseCouponId());
+            couponUser.setUserId(param.getUserId());
+            couponUser.setStartTime(new Date());
+            couponUser.setLimitTime(fsCourseCoupon.getLimitTime());
+            couponUser.setCreateTime(new Date());
+            couponUser.setLogId(log.getLogId());
+            int i = courseCouponUserMapper.insertFsCourseCouponUser(couponUser);
+
+            if (i > 0) {
+                FsCourseCoupon coupon = new FsCourseCoupon();
+                coupon.setId(courseVideo.getCourseCouponId());
+                coupon.setRemainNumber(fsCourseCoupon.getRemainNumber() - 1);
+                baseMapper.updateFsCourseCoupon(coupon);
+            }
+            //返回的优惠券名称
+            rewardVO.setCouponName(fsCourseCoupon.getTitle());
+            rewardVO.setTag(1);
+        }
+        return R.ok().put("data",rewardVO);
+    }
+}

+ 38 - 0
fs-service/src/main/java/com/fs/his/vo/CourseCouponUserListUVO.java

@@ -0,0 +1,38 @@
+package com.fs.his.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class CourseCouponUserListUVO {
+    private Long id;
+
+    /** 优惠券id */
+    private Long couponId;
+
+    /** 用户id */
+    private Long userId;
+
+    /** 有效期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date limitTime;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date startTime;
+
+    /** 核销状态 0-未核销 1-已核销 */
+    private Integer status;
+
+    /**
+     * 看课记录ID
+     */
+    private Long logId;
+
+    /**
+     * 优惠券名称
+     */
+    private String couponName;
+}

+ 18 - 0
fs-service/src/main/java/com/fs/his/vo/CourseFinishRewardVO.java

@@ -0,0 +1,18 @@
+package com.fs.his.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CourseFinishRewardVO {
+
+    private String couponName;
+
+    private BigDecimal redPacketMoney;
+
+    private Integer integral;
+
+    //0-不弹窗 1-弹窗
+    private Integer tag;
+}

+ 16 - 0
fs-service/src/main/resources/db/tenant-initTable.sql

@@ -18567,3 +18567,19 @@ ALTER TABLE company_user ADD COLUMN mp_subscribed INT(1) DEFAULT 0 COMMENT '是
 
 
 SET
 SET
 FOREIGN_KEY_CHECKS = 1;
 FOREIGN_KEY_CHECKS = 1;
+
+DROP TABLE IF EXISTS `fs_course_coupon`;
+CREATE TABLE `fs_course_coupon` (
+                                    `id` bigint NOT NULL AUTO_INCREMENT,
+                                    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+                                    `limit_time` datetime DEFAULT NULL COMMENT '有效期',
+                                    `number` int DEFAULT NULL COMMENT '数量',
+                                    `remain_number` int DEFAULT '0' COMMENT '剩余数量',
+                                    `status` int DEFAULT NULL COMMENT '状态',
+                                    `update_time` datetime DEFAULT NULL COMMENT '修改时间',
+                                    `limit_day` int DEFAULT '1' COMMENT '领取后有效期',
+                                    `limit_type` int DEFAULT '1' COMMENT '有效期类别 1 过期时间 2 领取后有效期',
+                                    `limit_count` int DEFAULT NULL COMMENT '每人可领取数量',
+                                    `title` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '标题',
+                                    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='课程优惠券';

+ 32 - 0
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -1200,4 +1200,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </choose>
         </choose>
         ORDER BY accessCount desc
         ORDER BY accessCount desc
     </select>
     </select>
+    <select id="getWatchLogByFsUserAndPeriodId" resultType="com.fs.course.domain.FsCourseWatchLog">
+        SELECT
+        log_id,
+        user_id,
+        video_id,
+        log_type,
+        create_time,
+        update_time,
+        duration,
+        company_user_id,
+        company_id,
+        course_id,
+        send_type,
+        reward_type,
+        last_heartbeat_time,
+        sop_id,
+        finish_time,
+        send_finish_msg,
+        camp_period_time,
+        period_id
+        FROM
+        fs_course_watch_log
+        WHERE
+        send_type = 1
+        AND video_id = #{videoId}
+        AND user_id = #{fsUserId}
+        AND company_user_id = #{companyUserId}
+        <if test="periodId != null">
+            and period_id = #{periodId}
+        </if>
+        order by log_id desc limit 1
+    </select>
 </mapper>
 </mapper>

+ 99 - 0
fs-service/src/main/resources/mapper/his/FsCourseCouponMapper.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsCourseCouponMapper">
+    
+    <resultMap type="FsCourseCoupon" id="FsCourseCouponResult">
+        <result property="id"    column="id"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="limitTime"    column="limit_time"    />
+        <result property="number"    column="number"    />
+        <result property="remainNumber"    column="remain_number"    />
+        <result property="status"    column="status"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="limitDay"    column="limit_day"    />
+        <result property="limitType"    column="limit_type"    />
+        <result property="limitCount"    column="limit_count"    />
+        <result property="title"    column="title"    />
+    </resultMap>
+
+    <sql id="selectFsCourseCouponVo">
+        select id, create_time, limit_time, number, remain_number, status, update_time, limit_day, limit_type, limit_count, title from fs_course_coupon
+    </sql>
+
+    <select id="selectFsCourseCouponList" parameterType="FsCourseCoupon" resultMap="FsCourseCouponResult">
+        <include refid="selectFsCourseCouponVo"/>
+        <where>  
+            <if test="limitTime != null "> and limit_time = #{limitTime}</if>
+            <if test="number != null "> and number = #{number}</if>
+            <if test="remainNumber != null "> and remain_number = #{remainNumber}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="limitDay != null "> and limit_day = #{limitDay}</if>
+            <if test="limitType != null "> and limit_type = #{limitType}</if>
+            <if test="limitCount != null "> and limit_count = #{limitCount}</if>
+            <if test="title != null  and title != ''"> and title = #{title}</if>
+        </where>
+    </select>
+    
+    <select id="selectFsCourseCouponById" parameterType="Long" resultMap="FsCourseCouponResult">
+        <include refid="selectFsCourseCouponVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertFsCourseCoupon" parameterType="FsCourseCoupon" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_course_coupon
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="createTime != null">create_time,</if>
+            <if test="limitTime != null">limit_time,</if>
+            <if test="number != null">number,</if>
+            <if test="remainNumber != null">remain_number,</if>
+            <if test="status != null">status,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="limitDay != null">limit_day,</if>
+            <if test="limitType != null">limit_type,</if>
+            <if test="limitCount != null">limit_count,</if>
+            <if test="title != null">title,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="createTime != null">#{createTime},</if>
+            <if test="limitTime != null">#{limitTime},</if>
+            <if test="number != null">#{number},</if>
+            <if test="remainNumber != null">#{remainNumber},</if>
+            <if test="status != null">#{status},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="limitDay != null">#{limitDay},</if>
+            <if test="limitType != null">#{limitType},</if>
+            <if test="limitCount != null">#{limitCount},</if>
+            <if test="title != null">#{title},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsCourseCoupon" parameterType="FsCourseCoupon">
+        update fs_course_coupon
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="limitTime != null">limit_time = #{limitTime},</if>
+            <if test="number != null">number = #{number},</if>
+            <if test="remainNumber != null">remain_number = #{remainNumber},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="limitDay != null">limit_day = #{limitDay},</if>
+            <if test="limitType != null">limit_type = #{limitType},</if>
+            <if test="limitCount != null">limit_count = #{limitCount},</if>
+            <if test="title != null">title = #{title},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsCourseCouponById" parameterType="Long">
+        delete from fs_course_coupon where id = #{id}
+    </delete>
+
+    <delete id="deleteFsCourseCouponByIds" parameterType="String">
+        delete from fs_course_coupon where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 88 - 0
fs-service/src/main/resources/mapper/his/FsCourseCouponUserMapper.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsCourseCouponUserMapper">
+    
+    <resultMap type="FsCourseCouponUser" id="FsCourseCouponUserResult">
+        <result property="id"    column="id"    />
+        <result property="couponId"    column="coupon_id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="limitTime"    column="limit_time"    />
+        <result property="startTime"    column="start_time"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="status"    column="status"    />
+        <result property="logId"    column="log_id"    />
+    </resultMap>
+
+    <sql id="selectFsCourseCouponUserVo">
+        select id, coupon_id, user_id, limit_time, start_time, create_time, update_time, status, log_id from fs_course_coupon_user
+    </sql>
+
+    <select id="selectFsCourseCouponUserList" parameterType="FsCourseCouponUser" resultMap="FsCourseCouponUserResult">
+        <include refid="selectFsCourseCouponUserVo"/>
+        <where>  
+            <if test="couponId != null "> and coupon_id = #{couponId}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="limitTime != null "> and limit_time = #{limitTime}</if>
+            <if test="startTime != null "> and start_time = #{startTime}</if>
+            <if test="status != null "> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectFsCourseCouponUserById" parameterType="Long" resultMap="FsCourseCouponUserResult">
+        <include refid="selectFsCourseCouponUserVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertFsCourseCouponUser" parameterType="FsCourseCouponUser" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_course_coupon_user
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="couponId != null">coupon_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="limitTime != null">limit_time,</if>
+            <if test="startTime != null">start_time,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="status != null">status,</if>
+            <if test="logId != null">log_id,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="couponId != null">#{couponId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="limitTime != null">#{limitTime},</if>
+            <if test="startTime != null">#{startTime},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="status != null">#{status},</if>
+            <if test="logId != null">#{logId},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsCourseCouponUser" parameterType="FsCourseCouponUser">
+        update fs_course_coupon_user
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="couponId != null">coupon_id = #{couponId},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="limitTime != null">limit_time = #{limitTime},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="logId != null">log_id = #{logId},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsCourseCouponUserById" parameterType="Long">
+        delete from fs_course_coupon_user where id = #{id}
+    </delete>
+
+    <delete id="deleteFsCourseCouponUserByIds" parameterType="String">
+        delete from fs_course_coupon_user where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>