wangxy 3 giorni fa
parent
commit
6c3006882f
25 ha cambiato i file con 463 aggiunte e 47 eliminazioni
  1. 24 3
      fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java
  2. 60 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  3. 19 0
      fs-admin/src/main/java/com/fs/his/controller/LifeSaluteOrderController.java
  4. 46 0
      fs-admin/src/main/java/com/fs/web/controller/his/AiSipCallOutboundCdrAdminController.java
  5. 4 1
      fs-company/src/main/java/com/fs/company/controller/company/CompanyController.java
  6. 3 0
      fs-company/src/main/java/com/fs/company/controller/company/LifeSaluteOrderController.java
  7. 2 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  8. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseClearLogMapper.java
  9. 3 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  10. 16 11
      fs-service/src/main/java/com/fs/his/domain/LifeSaluteOrder.java
  11. 17 12
      fs-service/src/main/java/com/fs/his/dto/LifeSaluteOrderImportDTO.java
  12. 2 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  13. 0 15
      fs-service/src/main/java/com/fs/his/param/LifeSaluteOrderCreateParam.java
  14. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsFourDiagnosisRecordService.java
  15. 4 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  16. 18 0
      fs-service/src/main/java/com/fs/his/service/impl/FsFourDiagnosisRecordServiceImpl.java
  17. 86 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  18. 13 0
      fs-service/src/main/java/com/fs/his/service/impl/LifeSaluteOrderServiceImpl.java
  19. 54 0
      fs-service/src/main/java/com/fs/his/vo/FsUserWatchProjectVO.java
  20. 2 2
      fs-service/src/main/resources/application-config-druid-hdt.yml
  21. 11 0
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  22. 11 0
      fs-service/src/main/resources/mapper/course/FsUserCourseClearLogMapper.xml
  23. 16 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  24. 11 2
      fs-service/src/main/resources/mapper/his/LifeSaluteOrderMapper.xml
  25. 36 0
      fs-user-app/src/main/java/com/fs/app/controller/FourDiagnosisController.java

+ 24 - 3
fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java

@@ -9,13 +9,16 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyUserService;
+import com.fs.company.service.ICompanyRoleService;
 import com.fs.qw.dto.UserProjectDTO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -31,6 +34,9 @@ public class CompanyUserController extends BaseController
     @Autowired
     private ICompanyUserService companyUserService;
 
+    @Autowired
+    private ICompanyRoleService companyRoleService;
+
     /**
      * 查询企业员工信息列表
      */
@@ -63,7 +69,10 @@ public class CompanyUserController extends BaseController
     @GetMapping(value = "/{userId}")
     public AjaxResult getInfo(@PathVariable("userId") Long userId)
     {
-        return AjaxResult.success(companyUserService.selectCompanyUserById(userId));
+        CompanyUser user = companyUserService.selectCompanyUserById(userId);
+        AjaxResult ajax = AjaxResult.success(user);
+        ajax.put("roleIds", companyRoleService.selectRoleListByUserId(userId));
+        return ajax;
     }
 
     /**
@@ -78,7 +87,11 @@ public class CompanyUserController extends BaseController
         {
             return AjaxResult.error("新增用户'" + companyUser.getUserName() + "'失败,登录账号已存在");
         }
-        return toAjax(companyUserService.insertCompanyUser(companyUser));
+        encryptPasswordIfNeed(companyUser);
+        companyUser.setUserType("01");
+        companyUser.setIsAudit(1);
+        companyUser.setCreateTime(new Date());
+        return toAjax(companyUserService.insertUser(companyUser));
     }
 
     /**
@@ -89,7 +102,8 @@ public class CompanyUserController extends BaseController
     @PutMapping
     public AjaxResult edit(@RequestBody CompanyUser companyUser)
     {
-        return toAjax(companyUserService.updateCompanyUser(companyUser));
+        encryptPasswordIfNeed(companyUser);
+        return toAjax(companyUserService.updateUser(companyUser));
     }
 
     /**
@@ -139,6 +153,13 @@ public class CompanyUserController extends BaseController
         return  R.ok().put("data",list);
     }
 
+    private void encryptPasswordIfNeed(CompanyUser user) {
+        String password = user.getPassword();
+        if (password != null && password.length() <= 20) {
+            user.setPassword(SecurityUtils.encryptPassword(password));
+        }
+    }
+
     /**
      * 更换会员归属销售
      * @return

+ 60 - 0
fs-admin/src/main/java/com/fs/his/controller/FsUserController.java

@@ -260,6 +260,66 @@ public class FsUserController extends BaseController
         return getDataTable(list);
     }
 
+    @PreAuthorize("@ss.hasPermi('his:user:list')")
+    @GetMapping("/listWatchProject")
+    public TableDataInfo listWatchProject(FsUser fsUser) {
+        if (StringUtils.isNotEmpty(fsUser.getPhone())) {
+            fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        }
+        long total = fsUserService.selectUserWatchProjectCount(fsUser);
+        startPage();
+        List<FsUserWatchProjectVO> list = fsUserService.selectUserWatchProjectList(fsUser);
+        SysRole sysRole = isCheckPermission();
+        for (FsUserWatchProjectVO vo : list) {
+            if (vo.getPhone() != null && !vo.getPhone().isEmpty()) {
+                if (!(sysRole.getIsCheckPhone() == 1)) {
+                    if (vo.getPhone().length() > 11) {
+                        vo.setPhone(decryptPhoneMk(vo.getPhone()));
+                    } else {
+                        vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                    }
+                } else {
+                    if (vo.getPhone().length() > 11) {
+                        vo.setPhone(decryptPhone(vo.getPhone()));
+                    }
+                }
+            }
+        }
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(200);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list);
+        rspData.setTotal(total);
+        return rspData;
+    }
+
+    @PreAuthorize("@ss.hasPermi('his:user:export')")
+    @GetMapping("/exportWatchProject")
+    public AjaxResult exportWatchProject(FsUser fsUser) {
+        if (StringUtils.isNotEmpty(fsUser.getPhone())) {
+            fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        }
+        List<FsUserWatchProjectVO> list = fsUserService.selectUserWatchProjectList(fsUser);
+        SysRole sysRole = isCheckPermission();
+        for (FsUserWatchProjectVO vo : list) {
+            if (vo.getPhone() != null && !vo.getPhone().isEmpty()) {
+                if (!(sysRole.getIsCheckPhone() == 1)) {
+                    if (vo.getPhone().length() > 11) {
+                        vo.setPhone(decryptPhoneMk(vo.getPhone()));
+                    } else {
+                        vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                    }
+                } else {
+                    if (vo.getPhone().length() > 11) {
+                        vo.setPhone(decryptPhone(vo.getPhone()));
+                    }
+                }
+            }
+        }
+        ExcelUtil<FsUserWatchProjectVO> util = new ExcelUtil<>(FsUserWatchProjectVO.class);
+        return util.exportExcel(list, "无项目绑定会员数据");
+    }
+
     @PreAuthorize("@ss.hasPermi('his:user:export')")
     @GetMapping("/exportListProject")
     public AjaxResult exportListProject(FsUser fsUser)

+ 19 - 0
fs-admin/src/main/java/com/fs/his/controller/LifeSaluteOrderController.java

@@ -8,6 +8,8 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.his.domain.LifeSaluteOrder;
 import com.fs.his.dto.LifeSaluteOrderImportDTO;
@@ -31,6 +33,9 @@ public class LifeSaluteOrderController extends BaseController {
     @Autowired
     private ILifeSaluteOrderService lifeSaluteOrderService;
 
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
+
     /**
      * 分页查询生命礼赞订单列表
      *
@@ -139,6 +144,7 @@ public class LifeSaluteOrderController extends BaseController {
                         existing = copyImportDtoToOrder(orderDTO, existing);
                         existing.setId(existing.getId());
                         existing.setSenderAddress("西藏自治区昌都市丁青县协雄乡达恩仓藏医门诊");
+                        fillCompanyInfo(existing);
                         lifeSaluteOrderService.updateLifeSaluteOrder(existing);
                         if (StringUtils.isNotEmpty(existing.getWaybillNo()) && StringUtils.isNotEmpty(existing.getDeliveryCode()))
                         {
@@ -168,6 +174,7 @@ public class LifeSaluteOrderController extends BaseController {
                     }
                     order.setOrderNo(orderSn);
                     order.setSenderAddress("西藏自治区昌都市丁青县协雄乡达恩仓藏医门诊");
+                    fillCompanyInfo(order);
                     lifeSaluteOrderService.insertLifeSaluteOrder(order);
                     if (StringUtils.isNotEmpty(order.getWaybillNo()) && StringUtils.isNotEmpty(order.getDeliveryCode()))
                     {
@@ -190,6 +197,8 @@ public class LifeSaluteOrderController extends BaseController {
     private LifeSaluteOrder copyImportDtoToOrder(LifeSaluteOrderImportDTO dto, LifeSaluteOrder order)
     {
         order.setOrderNo(dto.getOrderNo());
+        order.setCompanyUserName(dto.getCompanyUserName());
+        order.setCompanyUserPhone(dto.getCompanyUserPhone());
         order.setMerchantOrderNo(dto.getMerchantOrderNo());
         order.setPlatformOrderNo(dto.getPlatformOrderNo());
         order.setPreWaybillNo(dto.getPreWaybillNo());
@@ -247,4 +256,14 @@ public class LifeSaluteOrderController extends BaseController {
         order.setOrderStatus(dto.getOrderStatus());
         return order;
     }
+
+    private void fillCompanyInfo(LifeSaluteOrder order) {
+        if (StringUtils.isNotEmpty(order.getCompanyUserPhone())) {
+            CompanyUser companyUser = companyUserMapper.selectCompanyUserByPhone(order.getCompanyUserPhone());
+            if (companyUser != null) {
+                order.setCompanyId(companyUser.getCompanyId());
+                order.setCompanyUserId(companyUser.getUserId());
+            }
+        }
+    }
 }

+ 46 - 0
fs-admin/src/main/java/com/fs/web/controller/his/AiSipCallOutboundCdrAdminController.java

@@ -0,0 +1,46 @@
+package com.fs.web.controller.his;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.aiSipCall.domain.AiSipCallOutboundCdr;
+import com.fs.aiSipCall.service.IAiSipCallOutboundCdrService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 外呼通话记录(总后台)Controller
+ *
+ * @author fs
+ * @date 2025-06-10
+ */
+@RestController
+@RequestMapping("/his/outboundCdr")
+public class AiSipCallOutboundCdrAdminController extends BaseController {
+
+    @Autowired
+    private IAiSipCallOutboundCdrService aiSipCallOutboundCdrService;
+
+    @PreAuthorize("@ss.hasPermi('his:outboundCdr:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(AiSipCallOutboundCdr cdr) {
+        startPage();
+        List<AiSipCallOutboundCdr> list = aiSipCallOutboundCdrService.selectAiSipCallOutboundCdrList(cdr);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('his:outboundCdr:export')")
+    @Log(title = "外呼通话记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(AiSipCallOutboundCdr cdr) {
+        List<AiSipCallOutboundCdr> list = aiSipCallOutboundCdrService.selectAiSipCallOutboundCdrList(cdr);
+        ExcelUtil<AiSipCallOutboundCdr> util = new ExcelUtil<>(AiSipCallOutboundCdr.class);
+        return util.exportExcel(list, "外呼通话记录");
+    }
+}

+ 4 - 1
fs-company/src/main/java/com/fs/company/controller/company/CompanyController.java

@@ -58,7 +58,10 @@ public class CompanyController extends BaseController
     {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Company company=companyService.selectCompanyById(loginUser.getCompany().getCompanyId());
-        return R.ok().put("data",company);
+        R r = R.ok().put("data", company);
+        r.put("userName", loginUser.getUser().getNickName());
+        r.put("userPhone", loginUser.getUser().getPhonenumber());
+        return r;
     }
 
 

+ 3 - 0
fs-company/src/main/java/com/fs/company/controller/company/LifeSaluteOrderController.java

@@ -41,6 +41,9 @@ public class LifeSaluteOrderController extends BaseController
         startPage();
         LoginUser loginUser = SecurityUtils.getLoginUser();
         lifeSaluteOrder.setCompanyId(loginUser.getCompany().getCompanyId());
+        if (!loginUser.getUser().isAdmin()) {
+            lifeSaluteOrder.setCompanyUserId(loginUser.getUser().getUserId());
+        }
         List<LifeSaluteOrder> list = lifeSaluteOrderService.selectLifeSaluteOrderList(lifeSaluteOrder);
         return getDataTable(list);
     }

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

@@ -959,4 +959,6 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * 查询用户当日未完课的课程列表
      */
     List<TodayUnfinishedCourseVO> selectTodayUnfinishedCourseList(@Param("userId") Long userId);
+
+    List<Map<String, Object>> selectLatestWatchTimeByUserIds(@Param("userIds") List<Long> userIds);
 }

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

@@ -5,10 +5,13 @@ import com.fs.course.domain.FsUserCourseClearLog;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 public interface FsUserCourseClearLogMapper extends BaseMapper<FsUserCourseClearLog> {
 
     int insertFsUserCourseClearLog(FsUserCourseClearLog log);
 
     int batchInsertFsUserCourseClearLog(@Param("list") List<FsUserCourseClearLog> list);
+
+    List<Map<String, Object>> selectByUserIds(@Param("userIds") List<Long> userIds);
 }

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

@@ -1035,7 +1035,9 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
             }
 
             if(null != jsonObject && !jsonObject.isEmpty() && jsonObject.containsKey("url_link")){
-                return jsonObject.getString("url_link");
+                String urlLink = jsonObject.getString("url_link");
+                String mpUrlLink = urlLink.replace("https://wxaurl.cn/", "https://wxmpurl.cn/");
+                return "链接1:" + urlLink + "\n链接2:" + mpUrlLink;
             }
             
             if(jsonObject != null && jsonObject.containsKey("errcode")) {

+ 16 - 11
fs-service/src/main/java/com/fs/his/domain/LifeSaluteOrder.java

@@ -26,20 +26,27 @@ public class LifeSaluteOrder extends BaseEntity
 //    @Excel(name = "销售/员工ID")
     private Long companyUserId;
 
+
+
     /** 系统订单号 */
     @Excel(name = "系统订单号", type = Excel.Type.EXPORT)
     private String orderNo;
 
+    /** 销售姓名 */
+    @Excel(name = "销售姓名")
+    private String companyUserName;
+
+    /** 销售手机号 */
+    @Excel(name = "销售手机号")
+    private String companyUserPhone;
+
     /** 商家订单号 */
-    @Excel(name = "商家订单号")
     private String merchantOrderNo;
 
     /** 平台订单号 */
-    @Excel(name = "平台订单号")
     private String platformOrderNo;
 
     /** 预制运单号 */
-    @Excel(name = "预制运单号")
     private String preWaybillNo;
 
     /** 实际运单号 */
@@ -51,24 +58,22 @@ public class LifeSaluteOrder extends BaseEntity
     private String deliveryCode;
 
     /** 物流状态 */
-    @Excel(name = "物流状态")
+//    @Excel(name = "物流状态")
     private Integer deliveryStatus;
 
     /** 物流状态类型 */
-    @Excel(name = "物流状态类型")
+//    @Excel(name = "物流状态类型")
     private String deliveryType;
 
     /** 物流更新时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Excel(name = "物流更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+//    @Excel(name = "物流更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date deliveryUpdateTime;
 
     /** 处方编号 */
-    @Excel(name = "处方编号")
     private String prescriptionNo;
 
     /** 处方人姓名 */
-    @Excel(name = "处方人姓名")
     private String prescriptionName;
 
     /** 患者年龄 */
@@ -269,16 +274,16 @@ public class LifeSaluteOrder extends BaseEntity
     private String customInfo;
 
     /** 订单状态 */
-    @Excel(name = "订单状态", readConverterExp = "0=待处理,1=处理中,2=已完成,3=已取消")
+//    @Excel(name = "订单状态", readConverterExp = "0=待处理,1=处理中,2=已完成,3=已取消")
     private Integer orderStatus;
 
     /** 创建时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+//    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     /** 更新时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+//    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
 }

+ 17 - 12
fs-service/src/main/java/com/fs/his/dto/LifeSaluteOrderImportDTO.java

@@ -20,19 +20,24 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String orderNo;
 
     /** 商家订单号 */
-    @Excel(name = "商家订单号")
     private String merchantOrderNo;
 
     /** 平台订单号 */
-    @Excel(name = "平台订单号")
     private String platformOrderNo;
 
     /** 预制运单号 */
-    @Excel(name = "预制运单号")
     private String preWaybillNo;
 
+    /** 销售姓名 */
+    @Excel(name = "销售姓名")
+    private String companyUserName;
+
+    /** 销售手机号 */
+    @Excel(name = "销售手机号")
+    private String companyUserPhone;
+
     /** 实际运单号 */
-    @Excel(name = "运单号")
+    @Excel(name = "实际运单号")
     private String waybillNo;
 
     /** 快递公司编码 */
@@ -44,7 +49,7 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String senderName;
 
     /** 寄件人手机号 */
-    @Excel(name = "寄件人手机")
+    @Excel(name = "寄件人手机")
     private String senderMobile;
 
     /** 寄件人座机 */
@@ -68,7 +73,7 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String senderDistrict;
 
     /** 寄件详细地址 */
-    @Excel(name = "寄件地址")
+    @Excel(name = "寄件详细地址")
     private String senderAddress;
 
     /** 收件人姓名 */
@@ -76,7 +81,7 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String receiverName;
 
     /** 收件人手机号 */
-    @Excel(name = "收件人手机")
+    @Excel(name = "收件人手机")
     private String receiverMobile;
 
     /** 收件人座机 */
@@ -100,7 +105,7 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String receiverDistrict;
 
     /** 收件详细地址 */
-    @Excel(name = "收件地址")
+    @Excel(name = "收件详细地址")
     private String receiverAddress;
 
     /** 物品类型 */
@@ -168,7 +173,7 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private Integer isSignReturn;
 
     /** 代收货款金额 */
-    @Excel(name = "代收货款金额(元)")
+    @Excel(name = "代收货款金额")
     private BigDecimal codAmount;
 
     /** 京尊达 0 否 1 是 */
@@ -224,15 +229,15 @@ public class LifeSaluteOrderImportDTO extends BaseEntity
     private String customInfo;
 
     /** 患者年龄 */
-    @Excel(name = "年龄")
+    @Excel(name = "患者年龄")
     private Integer age;
 
     /** 患者性别 */
-    @Excel(name = "性别")
+    @Excel(name = "患者性别")
     private String sex;
 
     /** 病情描述 */
-    @Excel(name = "病情")
+    @Excel(name = "病情描述")
     private String illnessCondition;
 
     /** 订单状态 */

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

@@ -58,6 +58,8 @@ public interface FsUserMapper
      */
     public List<FsUser> selectFsUserList(FsUser fsUser);
 
+    List<FsUser> selectUsersWithoutProject(FsUser fsUser);
+
     public List<FsUserVO> selectFsUserVOList(@Param("maps") FsUser fsUser);
 
     /**

+ 0 - 15
fs-service/src/main/java/com/fs/his/param/LifeSaluteOrderCreateParam.java

@@ -20,24 +20,9 @@ public class LifeSaluteOrderCreateParam {
     /** 系统订单号 */
     private String orderNo;
 
-    /** 商家订单号 */
-    private String merchantOrderNo;
-
-    /** 平台订单号 */
-    private String platformOrderNo;
-
-    /** 预制运单号 */
-    private String preWaybillNo;
-
     /** 实际运单号 */
     private String waybillNo;
 
-    /** 处方编号 */
-    private String prescriptionNo;
-
-    /** 处方人姓名 */
-    private String prescriptionName;
-
     /** 患者年龄 */
     private Integer age;
 

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/IFsFourDiagnosisRecordService.java

@@ -16,4 +16,6 @@ public interface IFsFourDiagnosisRecordService {
     int deleteFsFourDiagnosisRecordByIds(Long[] ids);
 
     void receivePush(String json);
+
+    List<FsFourDiagnosisRecord> selectRecordsByUserId(Long userId);
 }

+ 4 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -250,6 +250,10 @@ public interface IFsUserService
 
     List<FsUserVO> selectFsUserVOListByProjectNew(FsUser fsUser);
 
+    List<FsUserWatchProjectVO> selectUserWatchProjectList(FsUser fsUser);
+
+    long selectUserWatchProjectCount(FsUser fsUser);
+
     void increaseIntegral(List<Long> longs, Long integral);
 
     HisFsUserVO getHisUserIntegralWithLogs(FsUser fsUser);

+ 18 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsFourDiagnosisRecordServiceImpl.java

@@ -5,8 +5,11 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.utils.DateUtils;
 import com.fs.his.domain.FsFourDiagnosisRecord;
 import com.fs.his.domain.FsFourDiagnosisReport;
+import com.fs.his.domain.FsUser;
 import com.fs.his.mapper.FsFourDiagnosisRecordMapper;
 import com.fs.his.mapper.FsFourDiagnosisReportMapper;
+import com.fs.his.mapper.FsUserMapper;
+import com.fs.his.utils.PhoneUtil;
 import com.fs.his.service.IFsFourDiagnosisRecordService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,6 +31,9 @@ public class FsFourDiagnosisRecordServiceImpl implements IFsFourDiagnosisRecordS
     @Autowired
     private FsFourDiagnosisReportMapper reportMapper;
 
+    @Autowired
+    private FsUserMapper fsUserMapper;
+
     @Override
     public FsFourDiagnosisRecord selectFsFourDiagnosisRecordById(Long id) {
         return mapper.selectFsFourDiagnosisRecordById(id);
@@ -151,4 +157,16 @@ public class FsFourDiagnosisRecordServiceImpl implements IFsFourDiagnosisRecordS
         record.setCreateTime(DateUtils.getNowDate());
         return record;
     }
+
+    @Override
+    public List<FsFourDiagnosisRecord> selectRecordsByUserId(Long userId) {
+        FsUser user = fsUserMapper.selectFsUserById(userId);
+        if (user == null || user.getPhone() == null || user.getPhone().isEmpty()) {
+            return java.util.Collections.emptyList();
+        }
+        String phone = user.getPhone().length() > 11 ? PhoneUtil.decryptPhone(user.getPhone()) : user.getPhone();
+        FsFourDiagnosisRecord query = new FsFourDiagnosisRecord();
+        query.setMobile(phone);
+        return mapper.selectFsFourDiagnosisRecordList(query);
+    }
 }

+ 86 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -47,6 +47,7 @@ import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsUserCompanyUser;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.mapper.FsUserCompanyUserMapper;
+import com.fs.course.mapper.FsUserCourseClearLogMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.param.CourseAnalysisParam;
 import com.fs.course.param.newfs.FsUserCourseBeMemberParam;
@@ -91,6 +92,8 @@ import com.fs.store.vo.UserProjectPair;
 import com.fs.store.vo.h5.*;
 import com.fs.system.mapper.SysDictDataMapper;
 import com.fs.system.service.ISysConfigService;
+import com.fs.system.service.ISysDictTypeService;
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.watch.domain.WatchUser;
 import com.fs.watch.domain.vo.FsUserAndCompanyAndDoctorVo;
 import com.fs.watch.service.WatchUserService;
@@ -188,9 +191,16 @@ public class FsUserServiceImpl implements IFsUserService {
     private FsPatientMapper fsPatientMapper;
     @Autowired
     private FsCourseWatchLogMapper courseWatchLogMapper;
+
+    @Autowired
+    private FsUserCourseClearLogMapper userCourseClearLogMapper;
+
     @Autowired
     FsExportTaskMapper fsExportTaskMapper;
 
+    @Autowired
+    private ISysDictTypeService dictTypeService;
+
     @Autowired
     private FsUserCompanyUserMapper fsUserCompanyUserMapper;
 
@@ -1447,6 +1457,82 @@ public class FsUserServiceImpl implements IFsUserService {
         return list;
     }
 
+    @Override
+    public List<FsUserWatchProjectVO> selectUserWatchProjectList(FsUser fsUser) {
+        List<FsUser> users = fsUserMapper.selectUsersWithoutProject(fsUser);
+        if (users == null || users.isEmpty()) {
+            return new ArrayList<>();
+        }
+
+        List<Long> userIds = new ArrayList<>(users.size());
+        for (FsUser u : users) userIds.add(u.getUserId());
+
+        Map<String, String> projectDictMap = new HashMap<>();
+        List<SysDictData> projectDict = dictTypeService.selectDictDataByType("sys_course_project");
+        if (projectDict != null) {
+            for (SysDictData d : projectDict) projectDictMap.put(d.getDictValue(), d.getDictLabel());
+        }
+
+        Map<Long, FsUserWatchProjectVO> voMap = new HashMap<>(users.size() * 4 / 3);
+        for (FsUser u : users) {
+            FsUserWatchProjectVO vo = new FsUserWatchProjectVO();
+            vo.setUserId(u.getUserId());
+            vo.setNickName(u.getNickName());
+            vo.setPhone(u.getPhone());
+            vo.setLastAppLoginTime(u.getUpdateTime());
+            voMap.put(u.getUserId(), vo);
+        }
+
+        for (Map<String, Object> row : courseWatchLogMapper.selectLatestWatchTimeByUserIds(userIds)) {
+            FsUserWatchProjectVO vo = voMap.get(((Number) row.get("user_id")).longValue());
+            if (vo == null) continue;
+            int wt = ((Number) row.get("watch_type")).intValue();
+            if (wt == 1) vo.setLastAppWatchTime((Date) row.get("last_time"));
+            else if (wt == 2) vo.setLastMiniWatchTime((Date) row.get("last_time"));
+        }
+
+        for (Map<String, Object> row : userCourseClearLogMapper.selectByUserIds(userIds)) {
+            FsUserWatchProjectVO vo = voMap.get(((Number) row.get("user_id")).longValue());
+            if (vo == null) continue;
+
+            FsUserWatchProjectVO.ProjectRelation pr = new FsUserWatchProjectVO.ProjectRelation();
+            String cn = (String) row.get("company_name");
+            String cun = (String) row.get("company_user_name");
+            pr.setCompanyName(cn);
+            pr.setCompanyUserName(cun);
+            Object pidObj = row.get("project_id");
+            if (pidObj != null) {
+                Long pid = ((Number) pidObj).longValue();
+                pr.setProjectId(pid);
+                String pn = projectDictMap.get(String.valueOf(pid));
+                pr.setProjectName(pn);
+                if (pn != null) appendDictName(vo, "pn", pn);
+            }
+            if (cn != null) appendDictName(vo, "cn", cn);
+            if (cun != null) appendDictName(vo, "cun", cun);
+            if (vo.getProjectRelations() == null) vo.setProjectRelations(new ArrayList<>());
+            vo.getProjectRelations().add(pr);
+        }
+
+        return new ArrayList<>(voMap.values());
+    }
+
+    private void appendDictName(FsUserWatchProjectVO vo, String type, String val) {
+        if ("cn".equals(type)) {
+            vo.setCompanyNames(vo.getCompanyNames() == null ? val : vo.getCompanyNames() + "、" + val);
+        } else if ("cun".equals(type)) {
+            vo.setCompanyUserNames(vo.getCompanyUserNames() == null ? val : vo.getCompanyUserNames() + "、" + val);
+        } else if ("pn".equals(type)) {
+            vo.setProjectNames(vo.getProjectNames() == null ? val : vo.getProjectNames() + "、" + val);
+        }
+    }
+
+    @Override
+    public long selectUserWatchProjectCount(FsUser fsUser) {
+        List<FsUser> users = fsUserMapper.selectUsersWithoutProject(fsUser);
+        return users == null ? 0 : users.size();
+    }
+
     @Override
     public FsUserAndCompanyAndDoctorVo selectCompanyAndDoctor(Long userId) {
         return fsUserMapper.selectCompanyAndDoctor(userId);

+ 13 - 0
fs-service/src/main/java/com/fs/his/service/impl/LifeSaluteOrderServiceImpl.java

@@ -4,6 +4,8 @@ import com.fs.common.OrderUtils;
 import com.fs.common.core.domain.R;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyConfig;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.service.ICompanyConfigService;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.impl.CompanyServiceImpl;
@@ -46,6 +48,9 @@ public class LifeSaluteOrderServiceImpl implements ILifeSaluteOrderService {
     @Autowired
     private IFsExpressService expressService;
 
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
+
     /**
      * 根据主键查询生命礼赞订单
      *
@@ -126,6 +131,14 @@ public class LifeSaluteOrderServiceImpl implements ILifeSaluteOrderService {
         LifeSaluteOrder order = new LifeSaluteOrder();
         BeanUtils.copyProperties(param, order);
 
+        if (param.getCompanyUserId() != null) {
+            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
+            if (companyUser != null) {
+                order.setCompanyUserName(companyUser.getNickName());
+                order.setCompanyUserPhone(companyUser.getPhonenumber());
+            }
+        }
+
         if (order.getPackageCount() == null) {
             order.setPackageCount(1);
         }

+ 54 - 0
fs-service/src/main/java/com/fs/his/vo/FsUserWatchProjectVO.java

@@ -0,0 +1,54 @@
+package com.fs.his.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class FsUserWatchProjectVO {
+
+    @Excel(name = "会员ID")
+    private Long userId;
+
+    @Excel(name = "会员昵称")
+    private String nickName;
+
+    @Excel(name = "手机号")
+    private String phone;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date lastAppLoginTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "小程序看课时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date lastMiniWatchTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "APP看课时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date lastAppWatchTime;
+
+    private List<ProjectRelation> projectRelations;
+
+    @Excel(name = "经销商")
+    private String companyNames;
+
+    @Excel(name = "销售")
+    private String companyUserNames;
+
+    @Excel(name = "项目")
+    private String projectNames;
+
+    @Data
+    public static class ProjectRelation {
+        private Long projectId;
+        private String projectName;
+        private Long companyId;
+        private String companyName;
+        private Long companyUserId;
+        private String companyUserName;
+    }
+}

+ 2 - 2
fs-service/src/main/resources/application-config-druid-hdt.yml

@@ -104,8 +104,8 @@ wx_miniapp_temp:
 
 # 飞书
 feishu:
-  appId: "cli_a92ff75ce0785bc0"
-  appSecret: "DCQPW11pTY48zSdwAnqPwhJfihe0kP8G"
+  appId: "cli_aaa27d4aed395bee"
+  appSecret: "DYh8JVjwnoGT4p4ykHjK7AiA6AzH1x6e"
 
 # sip外呼配置
 sip:

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

@@ -2491,4 +2491,15 @@ FROM
         GROUP BY l.course_id
         ORDER BY l.create_time DESC
     </select>
+
+    <select id="selectLatestWatchTimeByUserIds" resultType="java.util.HashMap">
+        select user_id, watch_type, max(update_time) as last_time
+        from fs_course_watch_log
+        where user_id in
+        <foreach collection="userIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        and watch_type in (1, 2)
+        group by user_id, watch_type
+    </select>
 </mapper>

+ 11 - 0
fs-service/src/main/resources/mapper/course/FsUserCourseClearLogMapper.xml

@@ -30,4 +30,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </insert>
 
+    <select id="selectByUserIds" resultType="java.util.HashMap">
+        select l.user_id, l.project_id, l.company_id, l.company_user_id,
+               c.company_name, cu.nick_name as company_user_name
+        from fs_user_course_clear_log l
+        left join company c on c.company_id = l.company_id
+        left join company_user cu on cu.user_id = l.company_user_id
+        where l.user_id in
+        <foreach collection="userIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
 </mapper>

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

@@ -2763,4 +2763,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_user_course_period_days pd ON pd.id = l.period_days_id
     </select>
 
+    <select id="selectUsersWithoutProject" parameterType="FsUser" resultType="com.fs.his.domain.FsUser">
+        select u.*
+        from fs_user u
+        left join fs_user_company_user r on u.user_id = r.user_id
+        where r.user_id is null
+          and u.is_del = 0
+        <if test="nickName != null and nickName != ''">
+            and u.nick_name like concat('%', #{nickName}, '%')
+        </if>
+        <if test="phone != null and phone != ''">
+            and u.phone like concat('%', #{phone}, '%')
+        </if>
+        <if test="userId != null">
+            and u.user_id = #{userId}
+        </if>
+    </select>
 </mapper>

+ 11 - 2
fs-service/src/main/resources/mapper/his/LifeSaluteOrderMapper.xml

@@ -9,6 +9,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="id"    column="id"    />
         <result property="companyId"    column="company_id"    />
         <result property="companyUserId"    column="company_user_id"    />
+        <result property="companyUserName"    column="company_user_name"    />
+        <result property="companyUserPhone"    column="company_user_phone"    />
         <result property="orderNo"    column="order_no"    />
         <result property="merchantOrderNo"    column="merchant_order_no"    />
         <result property="platformOrderNo"    column="platform_order_no"    />
@@ -76,7 +78,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <!-- 生命礼赞订单基础查询列 -->
     <sql id="selectLifeSaluteOrderVo">
-        select id, company_id, company_user_id, order_no, merchant_order_no, platform_order_no, pre_waybill_no, waybill_no, delivery_code,
+        select id, company_id, company_user_id, company_user_name, company_user_phone,
+               order_no, merchant_order_no, platform_order_no, pre_waybill_no, waybill_no, delivery_code,
                delivery_status, delivery_type, delivery_update_time,
                prescription_no, prescription_name,
                age, sex, illness_condition,
@@ -97,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectLifeSaluteOrderVo"/>
         <where>
 <!--            <if test="companyId != null"> and company_id = #{companyId}</if>-->
-<!--            <if test="companyUserId != null"> and company_user_id = #{companyUserId}</if>-->
+            <if test="companyUserId != null"> and company_user_id = #{companyUserId}</if>
             <if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
             <if test="merchantOrderNo != null and merchantOrderNo != ''"> and merchant_order_no = #{merchantOrderNo}</if>
             <if test="platformOrderNo != null and platformOrderNo != ''"> and platform_order_no = #{platformOrderNo}</if>
@@ -151,6 +154,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="companyId != null">company_id,</if>
             <if test="companyUserId != null">company_user_id,</if>
+            <if test="companyUserName != null and companyUserName != ''">company_user_name,</if>
+            <if test="companyUserPhone != null and companyUserPhone != ''">company_user_phone,</if>
             <if test="orderNo != null and orderNo != ''">order_no,</if>
             <if test="merchantOrderNo != null and merchantOrderNo != ''">merchant_order_no,</if>
             <if test="platformOrderNo != null and platformOrderNo != ''">platform_order_no,</if>
@@ -217,6 +222,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="companyId != null">#{companyId},</if>
             <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="companyUserName != null and companyUserName != ''">#{companyUserName},</if>
+            <if test="companyUserPhone != null and companyUserPhone != ''">#{companyUserPhone},</if>
             <if test="orderNo != null and orderNo != ''">#{orderNo},</if>
             <if test="merchantOrderNo != null and merchantOrderNo != ''">#{merchantOrderNo},</if>
             <if test="platformOrderNo != null and platformOrderNo != ''">#{platformOrderNo},</if>
@@ -288,6 +295,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="SET" suffixOverrides=",">
             <if test="companyId != null">company_id = #{companyId},</if>
             <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="companyUserName != null and companyUserName != ''">company_user_name = #{companyUserName},</if>
+            <if test="companyUserPhone != null and companyUserPhone != ''">company_user_phone = #{companyUserPhone},</if>
             <if test="orderNo != null and orderNo != ''">order_no = #{orderNo},</if>
             <if test="merchantOrderNo != null and merchantOrderNo != ''">merchant_order_no = #{merchantOrderNo},</if>
             <if test="platformOrderNo != null and platformOrderNo != ''">platform_order_no = #{platformOrderNo},</if>

+ 36 - 0
fs-user-app/src/main/java/com/fs/app/controller/FourDiagnosisController.java

@@ -0,0 +1,36 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.FsFourDiagnosisRecord;
+import com.fs.his.service.IFsFourDiagnosisRecordService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 四诊仪检测记录Controller
+ *
+ * @author fs
+ * @date 2026-05-29
+ */
+@Api("四诊仪检测记录")
+@RestController
+@RequestMapping("/app/fourDiagnosis")
+public class FourDiagnosisController extends AppBaseController {
+
+    @Autowired
+    private IFsFourDiagnosisRecordService fourDiagnosisRecordService;
+
+    @Login
+    @ApiOperation("获取我的四诊仪检测记录")
+    @GetMapping("/myRecords")
+    public R myRecords() {
+        Long userId = Long.parseLong(getUserId());
+        List<FsFourDiagnosisRecord> list = fourDiagnosisRecordService.selectRecordsByUserId(userId);
+        return R.ok().put("data", list);
+    }
+}