Parcourir la source

Merge remote-tracking branch 'origin/master'

yuhongqi il y a 3 semaines
Parent
commit
649bad0a92

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

@@ -0,0 +1,111 @@
+package com.fs.his.controller;
+
+import java.util.List;
+
+import com.fs.common.exception.CustomException;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.his.domain.FsCourseCoupon;
+import com.fs.his.service.IFsCourseCouponService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 课程优惠券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));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/his/controller/FsCourseCouponUserController.java

@@ -0,0 +1,103 @@
+package com.fs.his.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.his.domain.FsCourseCouponUser;
+import com.fs.his.service.IFsCourseCouponUserService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户看课优惠券Controller
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+@RestController
+@RequestMapping("/his/courseCouponUser")
+public class FsCourseCouponUserController extends BaseController
+{
+    @Autowired
+    private IFsCourseCouponUserService fsCourseCouponUserService;
+
+    /**
+     * 查询用户看课优惠券列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsCourseCouponUser fsCourseCouponUser)
+    {
+        startPage();
+        List<FsCourseCouponUser> list = fsCourseCouponUserService.selectFsCourseCouponUserList(fsCourseCouponUser);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户看课优惠券列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:export')")
+    @Log(title = "用户看课优惠券", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsCourseCouponUser fsCourseCouponUser)
+    {
+        List<FsCourseCouponUser> list = fsCourseCouponUserService.selectFsCourseCouponUserList(fsCourseCouponUser);
+        ExcelUtil<FsCourseCouponUser> util = new ExcelUtil<FsCourseCouponUser>(FsCourseCouponUser.class);
+        return util.exportExcel(list, "用户看课优惠券数据");
+    }
+
+    /**
+     * 获取用户看课优惠券详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsCourseCouponUserService.selectFsCourseCouponUserById(id));
+    }
+
+    /**
+     * 新增用户看课优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:add')")
+    @Log(title = "用户看课优惠券", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsCourseCouponUser fsCourseCouponUser)
+    {
+        return toAjax(fsCourseCouponUserService.insertFsCourseCouponUser(fsCourseCouponUser));
+    }
+
+    /**
+     * 修改用户看课优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:edit')")
+    @Log(title = "用户看课优惠券", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsCourseCouponUser fsCourseCouponUser)
+    {
+        return toAjax(fsCourseCouponUserService.updateFsCourseCouponUser(fsCourseCouponUser));
+    }
+
+    /**
+     * 删除用户看课优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('his:courseCouponUser:remove')")
+    @Log(title = "用户看课优惠券", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsCourseCouponUserService.deleteFsCourseCouponUserByIds(ids));
+    }
+}

+ 43 - 2
fs-admin/src/main/java/com/fs/third/controller/WeizouController.java

@@ -34,7 +34,7 @@ public class WeizouController extends BaseController {
             return error("参数异常请核验参数");
         }
         fsStoreOrder.setOrderId(Long.valueOf((String) map.get("orderCode")));
-        fsStoreOrder.setOperator("微走发货同步");
+        fsStoreOrder.setOperator("-1");
 // 校验物流单号
         if (map.get("deliverySn") == null) {
             return error("参数异常请核验参数:deliverySn不能为空");
@@ -50,7 +50,48 @@ public class WeizouController extends BaseController {
             return error("参数异常请核验参数:deliveryName不能为空");
         }
         fsStoreOrder.setDeliveryName((String) map.get("deliveryName"));
+        return toAjax(fsStoreOrderService.sendGoodsWeizou(fsStoreOrder));
+    }
 
-        return toAjax(fsStoreOrderService.sendGoodsWeizou(fsStoreOrder, "微走发货同步"));
+    /**
+     * 更新快递订单
+     * @param map
+     * @return
+     */
+    @PostMapping("/cancelThirdParty")
+    public AjaxResult cancelThirdParty(@RequestBody Map map) {
+        String thirdPartySecret = (String) map.get("thirdPartySecret");
+        String s = decryptPhone(thirdPartySecret);
+        if (!s.equals("weizou_send_goods_call_back")) {
+            return error("认证失败,请核验参数");
+        }
+        FsStoreOrder fsStoreOrder = new FsStoreOrder();
+        if (map.get("orderCode") == null) {
+            return error("参数异常请核验参数");
+        }
+        fsStoreOrder.setOrderId(Long.valueOf((String) map.get("orderCode")));
+        //取消订单
+        if (map.get("operation") == null)return error("参数异常请核验参数:operator不能为空");
+        fsStoreOrder.setOperator((String) map.get("operation"));
+        return toAjax(fsStoreOrderService.sendGoodsWeizou(fsStoreOrder));
     }
+//    @PostMapping("/updateOrderLogisticsStatus")
+//    public AjaxResult updateOrderLogisticsStatus(@RequestBody Map map) {
+//        String thirdPartySecret = (String) map.get("thirdPartySecret");
+//        String s = decryptPhone(thirdPartySecret);
+//        if (!s.equals("weizou_send_goods_call_back")) {
+//            return error("认证失败,请核验参数");
+//        }
+//        FsStoreOrder fsStoreOrder = new FsStoreOrder();
+//        if (map.get("orderCode") == null) {
+//            return error("参数异常请核验参数");
+//        }
+//        fsStoreOrder.setOrderId(Long.valueOf((String) map.get("orderCode")));
+//        if (map.get("operation") == null)return error("参数异常请核验参数:operator不能为空");
+//        fsStoreOrder.setOperator((String) map.get("operation"));
+////        if (map.get("status") == null)return error("参数异常请核验参数:status不能为空");
+////        fsStoreOrder.setStatus((Integer) map.get("status"));
+//
+//        return toAjax(fsStoreOrderService.sendGoodsWeizou(fsStoreOrder, "微走更新物流状态"));
+//    }
 }

+ 78 - 0
fs-service/src/main/java/com/fs/enums/WeizouOrderExpressEnum.java

@@ -0,0 +1,78 @@
+package com.fs.enums;
+
+public enum WeizouOrderExpressEnum {
+
+    SEND_ORDER("-1","待发货"),
+
+    WAITING_PICKUP("1","待揽收"),
+
+    PICKED_UP("2","已揽收"),
+
+    IN_TRANSIT("3","运输中"),
+
+    DELIVERING("4","派送中"),
+
+    ABNORMAL("5","异常件"),
+
+    RETURNED("6","退回件"),
+
+    RETURNED_SIGNED("7","退回签收"),
+
+    FORWARDED("8","转寄件"),
+
+    CANCELLED("9","作废件"),
+
+    SIGNED("10","已签收"),
+
+    CANCELED("11","已取消");
+
+    private final String code;
+    private final String desc;
+
+    WeizouOrderExpressEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * 根据code获取枚举
+     */
+    public static WeizouOrderExpressEnum fromCode(String code) {
+        for (WeizouOrderExpressEnum status : values()) {
+            if (status.code.equals(code)) {
+                return status;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 根据code获取状态描述
+     */
+    public static String getDescByCode(String code) {
+        WeizouOrderExpressEnum status = fromCode(code);
+        return status != null ? status.desc : "未知状态";
+    }
+
+    /**
+     * 是否为终态
+     */
+    public boolean isFinal() {
+        return this == SIGNED || this == CANCELED;
+    }
+
+    /**
+     * 是否为异常状态
+     */
+    public boolean isAbnormal() {
+        return this == ABNORMAL || this == RETURNED;
+    }
+}

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

@@ -0,0 +1,58 @@
+package com.fs.his.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 课程优惠券对象 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;
+
+
+}

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

@@ -0,0 +1,47 @@
+package com.fs.his.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户看课优惠券对象 fs_course_coupon_user
+ *
+ * @author fs
+ * @date 2026-05-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsCourseCouponUser extends BaseEntity{
+
+    /** $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;
+
+
+}

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

@@ -0,0 +1,61 @@
+package com.fs.his.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsCourseCoupon;
+
+/**
+ * 课程优惠券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);
+}

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

@@ -0,0 +1,61 @@
+package com.fs.his.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsCourseCouponUser;
+
+/**
+ * 用户看课优惠券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);
+}

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

@@ -0,0 +1,61 @@
+package com.fs.his.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.his.domain.FsCourseCoupon;
+
+/**
+ * 课程优惠券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);
+}

+ 61 - 0
fs-service/src/main/java/com/fs/his/service/IFsCourseCouponUserService.java

@@ -0,0 +1,61 @@
+package com.fs.his.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.his.domain.FsCourseCouponUser;
+
+/**
+ * 用户看课优惠券Service接口
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+public interface IFsCourseCouponUserService extends IService<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 ids 需要删除的用户看课优惠券主键集合
+     * @return 结果
+     */
+    int deleteFsCourseCouponUserByIds(Long[] ids);
+
+    /**
+     * 删除用户看课优惠券信息
+     * 
+     * @param id 用户看课优惠券主键
+     * @return 结果
+     */
+    int deleteFsCourseCouponUserById(Long id);
+}

+ 1 - 1
fs-service/src/main/java/com/fs/his/service/IFsStoreOrderService.java

@@ -287,7 +287,7 @@ public interface IFsStoreOrderService
 
     void weizouPush(Long l) throws IOException;
 
-    int sendGoodsWeizou(FsStoreOrder fsStoreOrder, String opeName);
+    Integer sendGoodsWeizou(FsStoreOrder fsStoreOrder);
 
     BigDecimal selectPayPriceByYear(String userId);
 }

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

@@ -0,0 +1,95 @@
+package com.fs.his.service.impl;
+
+import java.util.List;
+import com.fs.common.utils.DateUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fs.his.mapper.FsCourseCouponMapper;
+import com.fs.his.domain.FsCourseCoupon;
+import com.fs.his.service.IFsCourseCouponService;
+
+/**
+ * 课程优惠券Service业务层处理
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+@Service
+public class FsCourseCouponServiceImpl extends ServiceImpl<FsCourseCouponMapper, FsCourseCoupon> implements IFsCourseCouponService {
+
+    /**
+     * 查询课程优惠券
+     * 
+     * @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);
+    }
+}

+ 94 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponUserServiceImpl.java

@@ -0,0 +1,94 @@
+package com.fs.his.service.impl;
+
+import java.util.List;
+import com.fs.common.utils.DateUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fs.his.mapper.FsCourseCouponUserMapper;
+import com.fs.his.domain.FsCourseCouponUser;
+import com.fs.his.service.IFsCourseCouponUserService;
+
+/**
+ * 用户看课优惠券Service业务层处理
+ * 
+ * @author fs
+ * @date 2026-05-13
+ */
+@Service
+public class FsCourseCouponUserServiceImpl extends ServiceImpl<FsCourseCouponUserMapper, FsCourseCouponUser> implements IFsCourseCouponUserService {
+
+    /**
+     * 查询用户看课优惠券
+     * 
+     * @param id 用户看课优惠券主键
+     * @return 用户看课优惠券
+     */
+    @Override
+    public FsCourseCouponUser selectFsCourseCouponUserById(Long id)
+    {
+        return baseMapper.selectFsCourseCouponUserById(id);
+    }
+
+    /**
+     * 查询用户看课优惠券列表
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 用户看课优惠券
+     */
+    @Override
+    public List<FsCourseCouponUser> selectFsCourseCouponUserList(FsCourseCouponUser fsCourseCouponUser)
+    {
+        return baseMapper.selectFsCourseCouponUserList(fsCourseCouponUser);
+    }
+
+    /**
+     * 新增用户看课优惠券
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 结果
+     */
+    @Override
+    public int insertFsCourseCouponUser(FsCourseCouponUser fsCourseCouponUser)
+    {
+        fsCourseCouponUser.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFsCourseCouponUser(fsCourseCouponUser);
+    }
+
+    /**
+     * 修改用户看课优惠券
+     * 
+     * @param fsCourseCouponUser 用户看课优惠券
+     * @return 结果
+     */
+    @Override
+    public int updateFsCourseCouponUser(FsCourseCouponUser fsCourseCouponUser)
+    {
+        fsCourseCouponUser.setUpdateTime(DateUtils.getNowDate());
+        return baseMapper.updateFsCourseCouponUser(fsCourseCouponUser);
+    }
+
+    /**
+     * 批量删除用户看课优惠券
+     * 
+     * @param ids 需要删除的用户看课优惠券主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsCourseCouponUserByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsCourseCouponUserByIds(ids);
+    }
+
+    /**
+     * 删除用户看课优惠券信息
+     * 
+     * @param id 用户看课优惠券主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsCourseCouponUserById(Long id)
+    {
+        return baseMapper.deleteFsCourseCouponUserById(id);
+    }
+}

+ 291 - 71
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -20,7 +20,10 @@ import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.*;
 import com.fs.common.utils.ip.IpUtils;
-import com.fs.company.domain.*;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyDept;
+import com.fs.company.domain.CompanyMoneyLogs;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyDivItemMapper;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
@@ -36,13 +39,15 @@ import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
+import com.fs.enums.WeizouOrderExpressEnum;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.dto.df.*;
 import com.fs.erp.service.IErpOrderService;
 import com.fs.erp.utils.WeizouApiClient;
-import com.fs.event.*;
-import com.fs.gtPush.service.uniPush2Service;
+import com.fs.event.TemplateBean;
+import com.fs.event.TemplateEvent;
+import com.fs.event.TemplateListenEnum;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.*;
@@ -54,9 +59,7 @@ import com.fs.his.service.*;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.*;
-import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
-import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
 import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.hisStore.param.FsStoreOrderRefundByProductParam;
@@ -66,8 +69,8 @@ import com.fs.hisapi.domain.ApiResponse;
 import com.fs.hisapi.param.CreateOrderParam;
 import com.fs.hisapi.param.RecipeDetailParam;
 import com.fs.hisapi.service.HisApiService;
-import com.fs.huifuPay.domain.*;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentDelaytransConfirmRequest;
+import com.fs.huifuPay.domain.HuiFuCreateOrder;
+import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.im.dto.*;
@@ -78,15 +81,15 @@ import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.service.impl.QwUserServiceImpl;
 import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.fs.system.service.ISysConfigService;
+import com.fs.tzBankPay.TzBankService.TzBankService;
 import com.fs.tzBankPay.doman.*;
 import com.fs.ybPay.domain.CreateWxOrderResult;
 import com.fs.ybPay.domain.OrderResult;
 import com.fs.ybPay.dto.OrderQueryDTO;
 import com.fs.ybPay.dto.WxJspayDTO;
 import com.fs.ybPay.service.IPayService;
-import com.fs.system.mapper.SysConfigMapper;
-import com.fs.system.service.ISysConfigService;
-import com.fs.tzBankPay.TzBankService.TzBankService;
 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.config.WxPayConfig;
@@ -125,6 +128,8 @@ import java.nio.charset.Charset;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -380,11 +385,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         //推送修改的互联网医院订单地址到聚水潭ERP
         try {
             pushOrderAddressToErp(fsStoreOrder);
-        }catch (Exception e){
+        } catch (Exception e) {
             log.error("修改互联网医院订单地址推送到聚水潭ERP失败,orderId: {}", fsStoreOrder.getOrderId(), e);
         }
         return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder);
     }
+
     /**
      * 推送修改订单的最新地址到 ERP
      *
@@ -1660,7 +1666,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
     @Override
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
-    public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type,String bankTransactionId,String bankSerialNo){
+    public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type, String bankTransactionId, String bankSerialNo) {
         try {
             FsStoreOrder order = null;
             if (type.equals(1)) {
@@ -3255,12 +3261,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         } else {
             appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-            if (StringUtils.isBlank(openId)){
+            if (StringUtils.isBlank(openId)) {
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                         .eq(FsUserWx::getFsUserId, param.getUserId())
                         .eq(FsUserWx::getAppId, appId);
                 FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-                if (Objects.nonNull(fsUserWx)){
+                if (Objects.nonNull(fsUserWx)) {
                     openId = fsUserWx.getOpenId();
                 }
             }
@@ -4627,11 +4633,28 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(l);
         if (order.getShippingType() != null && order.getShippingType() == 2)return;
         WeizouApiPushOrderParam param = new WeizouApiPushOrderParam();
-        param.setPaid(order.getIsPay()).setRealName(order.getUserName()).setPhone(order.getUserPhone())
+        param.setRealName(order.getUserName()).setPhone(order.getUserPhone().length() > 11 ? decryptPhone(order.getUserPhone()) : order.getUserPhone())
                 .setFreightPrice(order.getFreightPrice()).setExtendOrderId(order.getOrderId().toString())
-                .setPayType(order.getPayType()==1?"02":"04")
-                .setPaymentType(order.getPayType()==1?"01":"02").setDeliveryType("顺丰快递")
         ;
+        //全款
+        if (order.getPayType().equals(1)) {
+            param.setPaymentType("01").setPaid(1)
+                    .setPayType("02").setDeliveryType("顺丰快递")
+//                    .setPayType("01").setDeliveryType("邮政快递")
+            ;
+            //部分支付
+        } else if (order.getPayType().equals(2)) {
+            param.setPaymentType("02").setPaid(2).setPrecollection(order.getPayPrice())
+                    .setPayType("04").setDeliveryType("顺丰快递")
+//                    .setPayType("03").setDeliveryType("邮政快递")
+            ;
+            //未付款
+        } else if (order.getPayType().equals(3)) {
+            param.setPaymentType("02").setPaid(0)
+                    .setPayType("04").setDeliveryType("顺丰快递")
+//                    .setPayType("03").setDeliveryType("邮政快递")
+            ;
+        }
         //商品
         FsStoreOrderItem itemMap = new FsStoreOrderItem();
         itemMap.setOrderId(order.getOrderId());
@@ -4680,66 +4703,263 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         String s = WeizouApiClient.pushOrder(param);
         log.info("微走推送结果:{}",s);
     }
+    private static final int STATUS_PENDING_SHIPMENT = 2;
+    private static final int STATUS_SHIPPED = 3;
+    private static final int STATUS_TO_EVALUATED = 4;
+    private static final String OPERATOR_CANCEL = "0";
+    private static final String OPERATOR_UPDATE = "1";
+    private static final String LOG_TYPE_DELIVERY = "delivery_goods";
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
 
     @Override
-    public int sendGoodsWeizou(FsStoreOrder fsStoreOrder, String opeName) {
-        FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(fsStoreOrder.getOrderId());
-        if (order == null) throw new CustomException("订单不存在");
-        if (order.getStatus() == 2){
-            FsStoreOrder o1 = new FsStoreOrder();
-            o1.setOrderId(fsStoreOrder.getOrderId());
-            o1.setStatus(3);
-            o1.setUpdateTime(new DateTime());
-            o1.setDeliveryCode(fsStoreOrder.getDeliveryCode());
-            o1.setDeliveryName(fsStoreOrder.getDeliveryName());
-            o1.setDeliverySn(fsStoreOrder.getDeliverySn());
-            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            String dateString = formatter.format(new Date());
-            o1.setDeliveryTime(dateString);
-            int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
-            if (order.getCompanyId() != null) {
-                companyService.subtractCompanyMoney(order);
-            }
-            FsStoreOrderLogs Logs = new FsStoreOrderLogs();
-            Logs.setChangeMessage(opeName+" 订单发货");
-            Logs.setOrderId(fsStoreOrder.getOrderId());
-            Logs.setChangeTime(new DateTime());
-            Logs.setChangeType("delivery_goods");
-            Optional.ofNullable(fsStoreOrder.getOperator()).ifPresent(Logs::setOperator);
-            fsStoreOrderLogsMapper.insertFsStoreOrderLogs(Logs);
-            String lastFourNumber = "";
-            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
-                lastFourNumber = order.getUserPhone();
-                if (lastFourNumber.length() == 11) {
-                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-                }
-            }
-            expressService.subscribeEspress(order.getOrderCode(), fsStoreOrder.getDeliveryCode(), fsStoreOrder.getDeliverySn(), lastFourNumber);
-            return i;
+    public Integer sendGoodsWeizou(FsStoreOrder fsStoreOrder) {
+        // 1. 参数校验
+//        validateSendGoodsParams(fsStoreOrder, opeName);//controller处理了
+
+        // 2. 查询原始订单
+        FsStoreOrder originalOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderId(fsStoreOrder.getOrderId());
+        if (originalOrder == null) {
+            throw new CustomException("订单不存在");
+        }
+
+        // 3. 根据操作类型分发处理
+        if (OPERATOR_CANCEL.equals(fsStoreOrder.getOperator())) {
+            return processCancelDelivery(originalOrder, fsStoreOrder, "微走取消订单");
+        }
+        else if (WeizouOrderExpressEnum.SEND_ORDER.getCode().equals(fsStoreOrder.getOperator())){
+            return processNormalDelivery(originalOrder, fsStoreOrder, "微走发货同步订单单号更新");
         }else {
-            log.info("微走修改快递单号",fsStoreOrder.getDeliverySn());
-            FsStoreOrder o1 = new FsStoreOrder();
-            o1.setOrderId(fsStoreOrder.getOrderId());
-            o1.setDeliveryCode(fsStoreOrder.getDeliveryCode());
-            int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
-            FsStoreOrderLogs Logs = new FsStoreOrderLogs();
-            Logs.setChangeMessage(opeName+"订单单号更新");
-            Logs.setOrderId(fsStoreOrder.getOrderId());
-            Logs.setChangeTime(new DateTime());
-            Logs.setChangeType("delivery_goods");
-            Logs.setOperator("微走快递单号更新");
-            fsStoreOrderLogsMapper.insertFsStoreOrderLogs(Logs);
-            String lastFourNumber = "";
-            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
-                lastFourNumber = order.getUserPhone();
-                if (lastFourNumber.length() == 11) {
-                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+            return processUpdateDelivery(originalOrder, fsStoreOrder, "微走订单更新");        }
+    }
+
+    /**
+     * 处理订单状态更新//todo 到货后续业务逻辑需要对接
+     */
+    private int processUpdateDelivery(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder, String opeName) {
+        //微走有多个状态,需要分别记录
+        if (originalOrder.getStatus() == STATUS_SHIPPED) {
+            updateOrderToEvaluated(fsStoreOrder);
+        }
+
+        // 记录日志
+        log.info("微走快递送达, 订单号: {}",
+                fsStoreOrder.getOrderId());
+        return saveOrderLog(fsStoreOrder, WeizouOrderExpressEnum.getDescByCode(fsStoreOrder.getOperator()), opeName);
+    }
+    /**
+     * 处理取消发货
+     */
+    private int processCancelDelivery(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder, String opeName) {
+        // 待发货状态才更新订单状态
+        if (originalOrder.getStatus() == STATUS_PENDING_SHIPMENT) {
+            updateOrderToCancelled(fsStoreOrder);
+        }
+
+        // 调用退款服务
+//        SpringUtils.getBean(IFsStoreOrderScrmService.class).refundOrder(fsStoreOrder.getOrderId());//todo 推给售后
+
+        // 记录日志
+        log.info("微走取消发货, 订单号: {}",
+                fsStoreOrder.getOrderId());
+
+        return saveOrderLog(fsStoreOrder, fsStoreOrder.getOperator(), opeName);
+    }
+
+    /**
+     * 处理正常发货/修改快递
+     */
+    private int processNormalDelivery(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder, String opeName) {
+        int result;
+
+        if (originalOrder.getStatus() == STATUS_PENDING_SHIPMENT) {
+            // 待发货状态:执行发货操作
+            result = executeShipOrder(originalOrder, fsStoreOrder, opeName);
+        } else {
+            // 其他状态:只更新快递信息
+            result = updateDeliveryInfo(originalOrder, fsStoreOrder, opeName);
+        }
+
+        // 订阅快递信息(两种场景都需要)
+//        subscribeExpress(originalOrder, fsStoreOrder);//2026-3-20沟通后今正用微走接口调用的方式更新物流状态
+
+        return result;
+    }
+
+    /**
+     * 执行发货操作
+     */
+    private int executeShipOrder(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder, String opeName) {
+        // 1. 更新订单为已发货
+        FsStoreOrder updateOrder = buildShipOrderUpdate(fsStoreOrder);
+        int result = fsStoreOrderMapper.updateFsStoreOrder(updateOrder);
+
+        // 2. 处理公司扣款
+        if (originalOrder.getCompanyId() != null) {
+            companyService.subtractCompanyMoney(originalOrder);
+        }
+
+        // 3. 记录日志
+        String logMessage = opeName + " 订单发货";
+        saveOrderLog(fsStoreOrder, opeName, logMessage);
+
+        log.info("微走订单发货成功, 订单号: {}, 快递公司: {}, 快递单号: {}",
+                fsStoreOrder.getOrderId(),
+                fsStoreOrder.getDeliveryName(),
+                fsStoreOrder.getDeliverySn());
+
+        return result;
+    }
+
+    /**
+     * 更新快递信息
+     */
+    private int updateDeliveryInfo(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder, String opeName) {
+        // 1. 只更新快递相关信息
+        FsStoreOrder updateOrder = buildDeliveryInfoUpdate(fsStoreOrder);
+        int result = fsStoreOrderMapper.updateFsStoreOrder(updateOrder);
+
+        // 2. 记录日志
+        String logMessage = opeName + " 订单单号更新";
+        saveOrderLog(fsStoreOrder, opeName, logMessage);
+
+        log.info("微走修改快递单号, 订单号: {}, 新快递单号: {}",
+                fsStoreOrder.getOrderId(), fsStoreOrder.getDeliverySn());
+
+        return result;
+    }
+
+    /**
+     * 更新订单为已取消状态
+     */
+    private void updateOrderToCancelled(FsStoreOrder fsStoreOrder) {
+        FsStoreOrder updateOrder = new FsStoreOrder();
+        updateOrder.setOrderId(fsStoreOrder.getOrderId());
+        updateOrder.setStatus(STATUS_SHIPPED);
+        updateOrder.setUpdateTime(new DateTime());
+        updateOrder.setDeliveryTime(getCurrentDateTimeString());
+
+        fsStoreOrderMapper.updateFsStoreOrder(updateOrder);
+    }
+    /**
+     * 更新订单为待评价状态
+     */
+    private void updateOrderToEvaluated(FsStoreOrder fsStoreOrder) {
+        FsStoreOrder updateOrder = new FsStoreOrder();
+        updateOrder.setOrderId(fsStoreOrder.getOrderId());
+        updateOrder.setStatus(STATUS_TO_EVALUATED);
+        updateOrder.setUpdateTime(new DateTime());
+        updateOrder.setDeliveryTime(getCurrentDateTimeString());
+
+        fsStoreOrderMapper.updateFsStoreOrder(updateOrder);
+    }
+
+    /**
+     * 构建发货订单更新对象
+     */
+    private FsStoreOrder buildShipOrderUpdate(FsStoreOrder fsStoreOrder) {
+        FsStoreOrder updateOrder = new FsStoreOrder();
+        updateOrder.setOrderId(fsStoreOrder.getOrderId());
+        updateOrder.setStatus(STATUS_SHIPPED);
+        updateOrder.setUpdateTime(new DateTime());
+        updateOrder.setDeliveryCode(fsStoreOrder.getDeliveryCode());
+        updateOrder.setDeliveryName(fsStoreOrder.getDeliveryName());
+        updateOrder.setDeliverySn(fsStoreOrder.getDeliverySn());
+        updateOrder.setDeliveryTime(getCurrentDateTimeString());
+
+        return updateOrder;
+    }
+
+    /**
+     * 构建快递信息更新对象
+     */
+    private FsStoreOrder buildDeliveryInfoUpdate(FsStoreOrder fsStoreOrder) {
+        FsStoreOrder updateOrder = new FsStoreOrder();
+        updateOrder.setOrderId(fsStoreOrder.getOrderId());
+        updateOrder.setDeliveryCode(fsStoreOrder.getDeliveryCode());
+        updateOrder.setDeliveryName(fsStoreOrder.getDeliveryName());
+        updateOrder.setDeliverySn(fsStoreOrder.getDeliverySn());
+        updateOrder.setUpdateTime(new DateTime());
+        // 注意:这里不更新状态和发货时间
+
+        return updateOrder;
+    }
+
+    /**
+     * 保存订单日志
+     */
+    private int saveOrderLog(FsStoreOrder fsStoreOrder, String operator, String message) {
+        FsStoreOrderLogs logs = new FsStoreOrderLogs();
+        logs.setChangeMessage(message);
+        logs.setOrderId(fsStoreOrder.getOrderId());
+        logs.setChangeTime(new DateTime());
+        logs.setChangeType(LOG_TYPE_DELIVERY);
+        logs.setOperator(operator);
+
+        return fsStoreOrderLogsMapper.insertFsStoreOrderLogs(logs);
+    }
+
+    /**
+     * 订阅快递信息
+     */
+    private void subscribeExpress(FsStoreOrder originalOrder, FsStoreOrder fsStoreOrder) {
+        String lastFourNumber = "";
+
+        // 顺丰需要手机号后四位
+        if (ShipperCodeEnum.SF.getValue().equals(fsStoreOrder.getDeliveryCode())) {
+            lastFourNumber = getLastFourPhoneNumber(originalOrder.getUserPhone());
+        }
+
+        expressService.subscribeEspress(
+                originalOrder.getOrderCode(),
+                fsStoreOrder.getDeliveryCode(),
+                fsStoreOrder.getDeliverySn(),
+                lastFourNumber
+        );
+    }
+
+    /**
+     * 获取手机号后四位
+     */
+    private String getLastFourPhoneNumber(String phone) {
+        if (phone != null && phone.length() == 11) {
+            return phone.substring(7); // 索引7开始取后4位
+        }
+        return "";
+    }
+
+    /**
+     * 获取当前时间字符串
+     */
+    private String getCurrentDateTimeString() {
+        return LocalDateTime.now().format(DATE_TIME_FORMATTER);
+    }
+
+    /**
+     * 参数校验
+     */
+    private void validateSendGoodsParams(FsStoreOrder fsStoreOrder, String opeName) {
+        if (fsStoreOrder == null) {
+            throw new IllegalArgumentException("订单参数不能为空");
+        }
+        if (fsStoreOrder.getOrderId() == null) {
+            throw new IllegalArgumentException("订单ID不能为空");
+        }
+        if (opeName == null) {
+            throw new IllegalArgumentException("备注不能为空");
+        }
+
+        // 非取消操作需要校验快递信息
+        if (!OPERATOR_CANCEL.equals(fsStoreOrder.getOperator()) ) {
+            if (!OPERATOR_UPDATE.equals(fsStoreOrder.getOperator())){
+                if (fsStoreOrder.getDeliveryCode() == null) {
+                    throw new IllegalArgumentException("快递公司编码不能为空");
                 }
             }
-            expressService.subscribeEspress(order.getOrderCode(), fsStoreOrder.getDeliveryCode(), fsStoreOrder.getDeliverySn(), lastFourNumber);
-            return i;
+            if (fsStoreOrder.getDeliverySn() == null) {
+                throw new IllegalArgumentException("快递单号不能为空");
+            }
         }
-
     }
 
     @Override

+ 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>

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

@@ -0,0 +1,84 @@
+<?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"    />
+    </resultMap>
+
+    <sql id="selectFsCourseCouponUserVo">
+        select id, coupon_id, user_id, limit_time, start_time, create_time, update_time, status 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>
+         </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>
+         </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>
+        </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>