3 次代码提交 dbf863051c ... fce911041c

作者 SHA1 备注 提交日期
  ct fce911041c update:发送福袋,已经看课挂小黄车 3 天之前
  ct cfedba016a update:信息采集一对多 3 天之前
  ct ba464cde19 add:金牛卫建委推送 3 天之前
共有 27 个文件被更改,包括 964 次插入691 次删除
  1. 0 480
      fs-admin/src/main/java/com/fs/his/task/NetMedicalService.java
  2. 1 1
      fs-admin/src/main/java/com/fs/his/task/Task.java
  3. 1 0
      fs-company/src/main/java/com/fs/company/controller/store/FsUserInformationCollectionController.java
  4. 22 0
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  5. 4 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  6. 193 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  7. 11 0
      fs-service/src/main/java/com/fs/course/vo/newfs/FsUserCourseVideoDetailsVO.java
  8. 7 1
      fs-service/src/main/java/com/fs/his/domain/FsInquiryOrderDTO.java
  9. 3 0
      fs-service/src/main/java/com/fs/his/domain/FsUserInformationCollection.java
  10. 4 2
      fs-service/src/main/java/com/fs/his/mapper/FsUserInformationCollectionMapper.java
  11. 4 0
      fs-service/src/main/java/com/fs/his/param/FsUserInformationCollectionParam.java
  12. 1 0
      fs-service/src/main/java/com/fs/his/param/UserInformationDoctorType2Param.java
  13. 0 1
      fs-service/src/main/java/com/fs/his/service/IFsUserInformationCollectionService.java
  14. 250 7
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreSubOrderServiceImpl.java
  15. 13 15
      fs-service/src/main/java/com/fs/his/service/impl/FsUserInformationCollectionServiceImpl.java
  16. 19 0
      fs-service/src/main/java/com/fs/his/vo/FsUserInformationCollectionAllVO.java
  17. 1 1
      fs-service/src/main/java/com/fs/his/vo/FsUserInformationCollectionAndPatientVO.java
  18. 57 0
      fs-service/src/main/java/com/fs/wjw/dto/UploadConsultNewDto.java
  19. 90 0
      fs-service/src/main/java/com/fs/wjw/dto/UploadFurtherConsultNewDto.java
  20. 8 146
      fs-service/src/main/java/com/fs/wjw/dto/UploadRecipeNewDto.java
  21. 40 14
      fs-service/src/main/resources/mapper/his/FsUserInformationCollectionMapper.xml
  22. 1 0
      fs-user-app/src/main/java/com/fs/app/controller/CompanyUserController.java
  23. 19 0
      fs-user-app/src/main/java/com/fs/app/controller/CourseController.java
  24. 14 22
      fs-user-app/src/main/java/com/fs/app/controller/FsUserInformationCollectionController.java
  25. 55 0
      fs-user-app/src/main/java/com/fs/app/controller/LuckyBagController.java
  26. 63 1
      fs-user-app/src/main/java/com/fs/app/controller/WxMpController.java
  27. 83 0
      fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

+ 0 - 480
fs-admin/src/main/java/com/fs/his/task/NetMedicalService.java

@@ -1,480 +0,0 @@
-package com.fs.his.task;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.file.PathUtil;
-import cn.hutool.core.util.IdcardUtil;
-import cn.hutool.http.HttpRequest;
-import cn.hutool.http.HttpResponse;
-import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.utils.file.ImageUtils;
-import com.fs.framework.interceptor.impl.SameUrlDataInterceptor;
-import com.fs.his.domain.FsInquiryOrderDTO;
-import com.fs.his.domain.FsPrescribeDrugDTO;
-import com.fs.his.dto.FsInquiryOrderPatientDTO;
-import com.fs.his.mapper.FsInquiryOrderMapper;
-import com.fs.his.mapper.FsPrescribeDrugMapper;
-import com.fs.his.param.FurtherConsultationParam;
-import com.fs.his.param.PrescriptionParam;
-import com.fs.his.service.IFsPrescribeService;
-import com.qiniu.util.Json;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-
-/**
- * 互联网医疗服务定时任务
- * 润天推送参考:每天从中午12点到下午17点,每个小时的整点执行一次
- */
-@Component("netMedicalService")
-@AllArgsConstructor
-@Slf4j
-public class NetMedicalService {
-
-    private final String prefix = "https://202.61.88.184:19200/";
-    private final String prescriptionPath = "wjw/upload/uploadRecipe";
-    private final String reconsultPath = "wjw/upload/uploadFurtherConsult";
-
-    private final IFsPrescribeService iFsPrescribeService;
-    private final FsPrescribeDrugMapper durgMapper;
-    private final FsInquiryOrderMapper inquiryOrderMapper;
-
-    public void uploadPrescription() {
-        log.info("互联网医疗服务定时任务启动,时间{}", LocalDateTime.now());
-
-        try {
-            // 1.抽取有生成电子处方and上传了首诊记录的数据
-            LocalDate today = LocalDate.now().minusDays(1);
-            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-            String date = today.format(formatter);
-
-            // 此任务准备在凌晨执行,上传前一天的电子处方。
-            List<Map<String, Object>> result = iFsPrescribeService.selectUploadDate("2025-09-21");//TODO:测试修改
-            log.info("查询到 {} 条待上传处方数据", result.size());
-
-            if (result.isEmpty()) {
-                log.info("没有需要上传的处方数据");
-                return;
-            }
-
-            List<PrescriptionParam> paramList = processPrescriptions(result);
-
-            uploadToRemoteService(paramList);
-
-        } catch (Exception e) {
-            log.error("上传处方任务执行失败", e);
-        }
-    }
-
-    /**
-     * 网络诊疗服务数据上传
-     * TODO:请求体太大,可能需要分批请求;
-     */
-    public void uploadReconsultDate() {
-        log.info("开始执行网络诊疗服务数据上传任务");
-
-        // 使用 DateTimeFormatter 替代 SimpleDateFormat
-        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-
-        LocalDate today = LocalDate.now().minusDays(1);
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        String date = today.format(formatter);
-
-        log.info("查询日期: {}", date);
-        List<FsInquiryOrderDTO> fsInquiryOrderDTOS = inquiryOrderMapper.selectNeedUploadData("2025-01-01");//TODO:测试修改
-        log.info("查询到需要上传的数据条数: {}", fsInquiryOrderDTOS.size());
-
-        ArrayList<FurtherConsultationParam> paramList = new ArrayList<>();
-        int successCount = 0;
-        int skipCount = 0;
-        int errorCount = 0;
-
-        for (int i = 0; i < fsInquiryOrderDTOS.size(); i++) {
-            FsInquiryOrderDTO fsInquiryOrder = fsInquiryOrderDTOS.get(i);
-            String orderSn = fsInquiryOrder.getOrderSn();
-
-            log.debug("正在处理第 {}/{} 条数据, 订单号: {}", i + 1, fsInquiryOrderDTOS.size(), orderSn);
-
-            try {
-                // 检查是否开具处方
-                int isPrescribe = iFsPrescribeService.selectPrescribeByinquiryOrderId(fsInquiryOrder.getOrderId());
-                log.debug("订单 {} 处方检查结果: {}", orderSn, isPrescribe > 0 ? "有处方" : "无处方");
-
-                String imageUrl = fsInquiryOrder.getReportImages();
-                if (imageUrl == null || imageUrl.trim().isEmpty()) {
-                    log.warn("订单 {} 报告图片URL为空,跳过处理", orderSn);
-                    skipCount++;
-                    continue;
-                }
-
-                log.debug("订单 {} 报告图片URL: {}", orderSn, imageUrl);
-
-                Integer supportedImageFormat = getSupportedImageFormat(imageUrl);
-                if (Objects.isNull(supportedImageFormat)) {
-                    log.warn("订单 {} 不支持的文件后缀,跳过处理,图片URL: {}", orderSn, imageUrl);
-                    skipCount++;
-                    continue;
-                }
-                log.debug("订单 {} 图片格式识别成功: {}", orderSn, supportedImageFormat);
-
-                byte[] image = ImageUtils.getImage(imageUrl);
-                if (image == null || image.length == 0) {
-                    log.warn("订单 {} 无法获取图片数据,图片URL: {}", orderSn, imageUrl);
-                    skipCount++;
-                    continue;
-                }
-                log.debug("订单 {} 成功获取图片数据,图片大小: {} bytes", orderSn, image.length);
-
-                String base64Image = Base64.getEncoder().encodeToString(image);
-                log.debug("订单 {} Base64编码完成,编码后长度: {}", orderSn, base64Image.length());
-
-                // 安全处理时间字段
-                String applyTime = formatDateTimeSafely(fsInquiryOrder.getCreateTime(), dateTimeFormatter);
-                String startTime = formatDateTimeSafely(fsInquiryOrder.getStartTime(), dateTimeFormatter);
-                String endTime = formatDateTimeSafely(fsInquiryOrder.getFinishTime(), dateTimeFormatter);
-                String uploadTime = LocalDateTime.now().format(dateTimeFormatter);//TODO:这个完成时间必须传,业务上判断是否需要未完结的复诊数据
-
-                if (applyTime == null || startTime == null || endTime == null) {
-                    log.warn("订单 {} 时间字段存在空值,跳过处理", orderSn);
-                    skipCount++;
-                    continue;
-                }
-
-                FurtherConsultationParam param = FurtherConsultationParam.builder()
-                        .thirdUniqueid(orderSn)
-                        .orgName(fsInquiryOrder.getHospitalName())
-                        .orgCode("组织结构代码")
-                        .channelName("平台名称")
-                        .section(fsInquiryOrder.getDeptName())
-                        .sectionCode(fsInquiryOrder.getDeptCode())
-                        .docName(fsInquiryOrder.getDoctorName())
-                        .certificateNum(fsInquiryOrder.getCertificateCode())
-                        .patientName(fsInquiryOrder.getPatientName())
-                        .patientAge(IdcardUtil.getAgeByIdCard(fsInquiryOrder.getIdCard()))
-                        .patientSex(fsInquiryOrder.getSex())
-                        .patientIdcardType(1)
-                        .patientIdcardNum(fsInquiryOrder.getIdCard())
-                        .furtherConsultNo(orderSn)
-                        .furtherConsulType(1)
-                        .medicalHistory(fsInquiryOrder.getSelfMedHistory())
-                        .furtherConsultApplyTime(applyTime)
-                        .furtherConsulStartTime(startTime)
-                        .furtherConsulEndTime(endTime)
-                        .furtherConsulIsReply(1)
-                        .feeType(1)
-                        .furtherConsultDiagnosis(fsInquiryOrder.getInquiryResult())
-                        .furtherConsultDiagnosisNo("复诊icd诊断编码")
-                        .furtherConsultPrice(fsInquiryOrder.getMoney().toBigInteger().doubleValue())
-                        .patientEvaluate(1)
-                        .complainInfo("")
-                        .disposeResult("")
-                        .isRiskWarn(1)
-                        .isPatientSign(1)
-                        .isPrescription(isPrescribe > 0 ? 1 : 0)
-                        .uploadTime(uploadTime)
-                        .consultDiagnosisType(supportedImageFormat)
-                        .consultOrg("首诊机构")
-                        .consultDiagnosis(base64Image)
-                        .cityId("")
-                        .isMark("1")
-                        .build();
-
-                paramList.add(param);
-                successCount++;
-                log.debug("订单 {} 参数构建完成,已添加到上传列表", orderSn);
-
-            } catch (Exception e) {
-                errorCount++;
-                log.error("处理订单 {} 时发生异常: {}", orderSn, e.getMessage(), e);
-            }
-        }
-
-        log.info("数据处理完成 - 成功: {}条, 跳过: {}条, 异常: {}条", successCount, skipCount, errorCount);
-
-        if (paramList.isEmpty()) {
-            log.info("没有需要上传的数据,任务结束");
-            return;
-        }
-
-        try {
-            String jsonParam = JSON.toJSONString(paramList);
-            log.info("准备上传数据,参数条数: {}", paramList.size());
-//            log.debug("请求参数JSON: {}", jsonParam);
-
-            String urlPath = prefix + reconsultPath;
-            log.info("请求URL: {}", urlPath);
-
-            HttpRequest post = HttpUtil.createPost(urlPath);
-            post.body(jsonParam, "application/json; charset=utf-8");
-
-            log.info("开始发送HTTP请求...");
-            long startTime = System.currentTimeMillis();
-            HttpResponse response = post.execute();
-            long endTime = System.currentTimeMillis();
-
-            log.info("HTTP请求完成,状态码: {}, 耗时: {}ms", response.getStatus(), endTime - startTime);
-
-            if (response.isOk()) {
-                String responseBody = response.body();
-                log.info("上传成功,响应内容: {}", responseBody);
-
-                // 可以在这里添加响应结果解析和业务逻辑判断
-                try {
-                    JSONObject responseJson = JSON.parseObject(responseBody);
-                    if (responseJson != null) {
-                        String code = responseJson.getString("status");
-                        String message = responseJson.getString("message");
-                        log.info("响应解析 - 状态码: {}, 消息: {}", code, message);
-                    }
-                } catch (Exception e) {
-                    log.warn("响应内容解析失败: {}", e.getMessage());
-                }
-            } else {
-                log.error("上传失败,状态码: {}, 响应内容: {}", response.getStatus(), response.body());
-            }
-
-        } catch (Exception e) {
-            log.error("数据上传过程中发生异常: {}", e.getMessage(), e);
-        }
-        log.info("网络诊疗服务数据上传任务执行完毕");
-    }
-
-    private List<PrescriptionParam> processPrescriptions(List<Map<String, Object>> prescriptions) {
-        List<PrescriptionParam> paramList = new ArrayList<>();
-
-        for (Map<String, Object> prescribe : prescriptions) {
-            try {
-                PrescriptionParam param = processSinglePrescription(prescribe);
-                if (param != null) {
-                    paramList.add(param);
-                }
-            } catch (Exception e) {
-                log.error("处理处方失败, prescribe_id: {}", prescribe.get("prescribe_id"), e);
-            }
-        }
-
-        log.info("成功处理 {} 个处方", paramList.size());
-        return paramList;
-    }
-
-    private PrescriptionParam processSinglePrescription(Map<String, Object> prescribe) {
-        Long prescribeId = Convert.toLong(prescribe.get("prescribe_id"));
-        if (prescribeId == null) {
-            log.warn("处方ID为空,跳过处理");
-            return null;
-        }
-
-        // 药品信息查询
-        List<FsPrescribeDrugDTO> drugs = durgMapper.selectDrugList(prescribeId);
-        if (drugs == null || drugs.isEmpty()) {
-            log.warn("处方 {} 没有药品信息,跳过处理", prescribeId);
-            return null;
-        }
-
-        // 计算总量
-        Double quantity = calculateTotalQuantity(drugs);
-        Double days = calculateTotalDays(drugs);
-
-        // 组装药品信息
-        Map<String, String> drugInfoMap = buildDrugInfoMap(drugs);
-
-        // 构建处方参数
-        return buildPrescriptionParam(prescribe, drugInfoMap, quantity, days);
-    }
-
-    private Double calculateTotalQuantity(List<FsPrescribeDrugDTO> drugs) {
-        return drugs.stream().map(FsPrescribeDrugDTO::getDrugNum).filter(Objects::nonNull).mapToDouble(Convert::toDouble).sum();
-    }
-
-    private Double calculateTotalDays(List<FsPrescribeDrugDTO> drugs) {
-        return drugs.stream().map(FsPrescribeDrugDTO::getUsageDays).filter(Objects::nonNull).mapToDouble(Convert::toDouble).sum();
-    }
-
-    private Map<String, String> buildDrugInfoMap(List<FsPrescribeDrugDTO> drugs) {
-        Map<String, String> resultMap = new HashMap<>();
-        resultMap.put("drugName", join(drugs, FsPrescribeDrugDTO::getDrugName));
-        resultMap.put("specification", join(drugs, FsPrescribeDrugDTO::getDrugSpec));
-        resultMap.put("frequency", join(drugs, FsPrescribeDrugDTO::getUsageFrequencyUnit));
-        resultMap.put("useMethod", join(drugs, FsPrescribeDrugDTO::getUsageMethod));
-        resultMap.put("usagePerUseUnit", join(drugs, FsPrescribeDrugDTO::getUsagePerUseUnit));
-        resultMap.put("drugCode", join(drugs, FsPrescribeDrugDTO::getBarCode));
-        resultMap.put("doseEachTime", join(drugs, FsPrescribeDrugDTO::getUsagePerUseCount)); // 修复类型
-        return resultMap;
-    }
-
-    private PrescriptionParam buildPrescriptionParam(Map<String, Object> prescribe, Map<String, String> drugInfoMap, Double quantity, Double days) {
-        return PrescriptionParam.builder()
-                .thirdUniqueid(getString(prescribe, "prescribe_code"))
-                .orgName(getString(prescribe, "hospital_name"))
-                .orgCode("机构编码") // TODO: 不晓得从哪取
-                .section(getString(prescribe, "dept_name"))
-                .sectionCode(getString(prescribe, "dept_code"))
-                .docName(getString(prescribe, "doctor_name"))
-                .docCertificateNum(getString(prescribe, "certificate_code"))
-                .pharmacistName(getString(prescribe, "doctor_drug_name"))
-                .pharmacistCertificateNum(getString(prescribe, "doctor_drug_code"))
-                .patientName(getString(prescribe, "patient_name"))
-                .patientSex(getString(prescribe, "patient_gender"))
-                .patientAge(getInteger(prescribe, "patient_age"))
-                .patientIdcardType(1)
-                .feeType(1)
-                .patientIdcardNum(getString(prescribe, "id_card"))
-                .recipeTime(getString(prescribe, "create_time"))
-                .reviewTime(getString(prescribe, "create_time"))
-                .recipeUnitPrice(getDouble(prescribe, "total_price"))
-                .drugName(drugInfoMap.get("drugName"))
-                .drugCode(drugInfoMap.get("drugCode"))
-                .drugCommonName(drugInfoMap.get("drugName"))
-                .specification(drugInfoMap.get("specification"))
-                .frequency(drugInfoMap.get("frequency"))
-                .usage(drugInfoMap.get("useMethod"))
-                .doseUnit(drugInfoMap.get("usagePerUseUnit"))
-                .doseEachTime(drugInfoMap.get("doseEachTime"))
-                .medicationDays(days)
-                .quantity(quantity)
-                .drugPackage("药品包装") // TODO: 不晓得去哪取
-                .recipeAllPrice(getDouble(prescribe, "total_price"))
-                .uploadTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
-                .recipeNo(getString(prescribe, "prescribe_code"))
-                .cityId("") // TODO: 没有对应字典
-                .build();
-    }
-
-    private void uploadToRemoteService(List<PrescriptionParam> paramList) {
-        if (paramList.isEmpty()) {
-            log.info("没有需要上传的数据");
-            return;
-        }
-
-        try {
-            String url = prefix + prescriptionPath;
-            log.info("开始上传 {} 个处方到: {}", paramList.size(), url);
-
-            HttpRequest post = HttpUtil.createPost(url);
-            String requestBody = JSON.toJSONString(paramList);
-            log.debug("上传数据: {}", requestBody);//很大一坨
-
-            post.body(requestBody);
-            HttpResponse response = post.execute();
-
-//            log.info("上传完成,响应状态: {}", response.getStatus());
-            log.info("响应内容: {}", JSON.toJSONString(response));
-
-        } catch (Exception e) {
-            log.error("上传处方数据到远程服务失败", e);
-            throw new RuntimeException("上传失败", e);
-        }
-    }
-
-    // 工具方法
-    private String getString(Map<String, Object> map, String key) {
-        Object value = map.get(key);
-        return value != null ? value.toString() : "";
-    }
-
-    private Integer getInteger(Map<String, Object> map, String key) {
-        try {
-            Object value = map.get(key);
-            return value != null ? Integer.valueOf(value.toString()) : 0;
-        } catch (NumberFormatException e) {
-            log.warn("字段 {} 转换整数失败, 使用默认值0", key);
-            return 0;
-        }
-    }
-
-    private Double getDouble(Map<String, Object> map, String key) {
-        try {
-            Object value = map.get(key);
-            return value != null ? Double.valueOf(value.toString()) : 0.0;
-        } catch (NumberFormatException e) {
-            log.warn("字段 {} 转换浮点数失败, 使用默认值0.0", key);
-            return 0.0;
-        }
-    }
-
-    private String join(List<FsPrescribeDrugDTO> drugs, Function<FsPrescribeDrugDTO, String> fieldExtractor) {
-        return drugs.stream().map(fieldExtractor).filter(Objects::nonNull).filter(str -> !str.trim().isEmpty()).collect(Collectors.joining("|"));
-    }
-
-    /**
-     * 获取图片格式(只支持jpg、png、bmp)
-     *
-     * @param imagePath 图片路径
-     * @return 图片格式(jpeg, png, bmp),如果不支持则返回null
-     */
-    public static Integer getSupportedImageFormat(String imagePath) {
-        if (imagePath == null || imagePath.trim().isEmpty()) {
-            return null;
-        }
-
-        // 处理URL参数
-        String cleanPath = imagePath.split("[?#]")[0];
-
-        // 获取扩展名
-        String extension = "";
-        int lastDotIndex = cleanPath.lastIndexOf('.');
-        if (lastDotIndex > 0 && lastDotIndex < cleanPath.length() - 1) {
-            extension = cleanPath.substring(lastDotIndex + 1).toLowerCase();
-        }
-
-        // 只支持三种格式
-        switch (extension) {
-            case "jpg":
-            case "jpeg":
-                return 2;
-            case "png":
-                return 3;
-            case "bmp":
-                return 4;
-            default:
-                return null; // 不支持的格式返回null
-        }
-    }
-
-    /**
-     * 安全格式化时间方法,处理各种时间类型
-     */
-    private String formatDateTimeSafely(Object dateTime, DateTimeFormatter formatter) {
-        if (dateTime == null) {
-            log.warn("时间字段为null");
-            return null;
-        }
-
-        try {
-            if (dateTime instanceof java.util.Date) {
-                // 转换 java.util.Date 到 LocalDateTime
-                Instant instant = ((java.util.Date) dateTime).toInstant();
-                return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).format(formatter);
-            } else if (dateTime instanceof java.sql.Timestamp) {
-                // 转换 java.sql.Timestamp 到 LocalDateTime
-                return ((java.sql.Timestamp) dateTime).toLocalDateTime().format(formatter);
-            } else if (dateTime instanceof LocalDateTime) {
-                // 直接格式化 LocalDateTime
-                return ((LocalDateTime) dateTime).format(formatter);
-            } else if (dateTime instanceof LocalDate) {
-                // 处理 LocalDate,添加时间部分
-                return ((LocalDate) dateTime).atStartOfDay().format(formatter);
-            } else {
-                log.warn("不支持的时间类型: {}", dateTime.getClass().getName());
-                return null;
-            }
-        } catch (Exception e) {
-            log.error("时间格式化失败: {}, 原始值: {}", e.getMessage(), dateTime);
-            return null;
-        }
-    }
-}

+ 1 - 1
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -1899,7 +1899,7 @@ public class Task {
         List<FsUser> fsUserList = fsUsers.stream().filter(Objects::nonNull)
                 .filter(fsUser -> {
                     String imName = userInfosMap.get("U" + fsUser.getUserId());
-                    return imName != null && !Objects.equals(fsUser.getNickName(), imName);
+                    return imName != null && !Objects.equals(fsUser.getNickname(), imName);
                 }).collect(Collectors.toList());
         log.info("名字对不上的用户集合:{}", fsUserList);
         requestImUpdate(adminToken, fsUserList);

+ 1 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsUserInformationCollectionController.java

@@ -93,6 +93,7 @@ public class FsUserInformationCollectionController extends BaseController
             return AjaxResult.error("用户未绑定该销售");
         }
         fsUserInformationCollection.setCompanyUserId(companyUserId);
+        fsUserInformationCollection.setIsTemplate(-1L);
         return AjaxResult.success(fsUserInformationCollectionService.insertFsUserInformationCollection(fsUserInformationCollection));
     }
 

+ 22 - 0
fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java

@@ -15,6 +15,7 @@ import com.fs.config.ai.AiHostProper;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.domain.LuckyBagCollectRecord;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.service.IFsCoursePlaySourceConfigService;
@@ -29,6 +30,7 @@ import com.fs.live.mapper.LiveWatchLogMapper;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwUserVideo;
+import com.fs.qw.mapper.LuckyBagCollectRecordMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwUserService;
@@ -41,6 +43,7 @@ import com.fs.sop.service.impl.QwSopLogsServiceImpl;
 import com.fs.wxwork.dto.*;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.json.JSONObject;
 import org.springframework.stereotype.Service;
@@ -89,6 +92,7 @@ public class IpadSendServer {
     private final IFsCoursePlaySourceConfigService playSourceConfigService;
     private final FsUserMapper fsUserMapper;
     private final FsUserCourseVideoMapper fsUserCourseVideoMapper;
+    private final LuckyBagCollectRecordMapper luckyBagCollectRecordMapper;
 
 
     private static final List<String> PROJECT_NAMES = Arrays.asList("济南联志健康", "北京存在文化","宽益堂");
@@ -727,6 +731,12 @@ public class IpadSendServer {
                     // 语音
                     sendWxVideo(vo, content);
                     break;
+                case "14":
+                    // 记录福袋发送记录
+                    addLuckyBagCollectRecord(vo, content,qwSopLogs);
+                    // 福袋
+                    sendMiniProgram(vo, content, miniMap,qwUser.getCompanyId());
+                    break;
                 case "99":
                     // 群发
                     sendTxtAtMsg(vo);
@@ -741,6 +751,18 @@ public class IpadSendServer {
             content.setSendRemarks("发送失败:" + e.getMessage());
         }
     }
+    private void addLuckyBagCollectRecord(BaseVo vo,QwSopCourseFinishTempSetting.Setting content,QwSopLogs qwSopLogs) {
+        try {
+            // 写入福袋发放记录
+            LuckyBagCollectRecord luckyBagCollectRecord = luckyBagCollectRecordMapper.selectLuckyBagCollectRecordById(Long.valueOf(content.getBusinessId()));
+            luckyBagCollectRecord.setSendTime(new Date());
+            luckyBagCollectRecord.setCollectType("0");
+            luckyBagCollectRecordMapper.updateLuckyBagCollectRecord(luckyBagCollectRecord);
+
+        }catch (Exception e){
+            log.error("ID:" + qwSopLogs.getId() + "-添加福袋记录失败", e);
+        }
+    }
 
     public void loginOut(QwUser user) {
         ipadSendUtils.loginOut(user.getUid(), user.getServerId());

+ 4 - 0
fs-service/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java

@@ -250,4 +250,8 @@ public interface IFsUserCourseVideoService extends IService<FsUserCourseVideo> {
     R createRoomMiniLinkByCourse(FsCourseLinkRoomNewParam param);
 
     void updateMediaPublishStatus(String vid);
+
+    R registerQwFsUserFinish(FsUserCourseVideoAddKfUParam param);
+
+    R registerQwFsUser(FsUserCourseVideoAddKfUParam param);
 }

+ 193 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.course.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
@@ -9,6 +10,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.constant.FsConstants;
 import com.fs.common.core.domain.R;
@@ -52,6 +56,7 @@ import com.fs.his.config.AppConfig;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserIntegralLogs;
 import com.fs.his.domain.FsUserWx;
+import com.fs.his.mapper.FsPackageMapper;
 import com.fs.his.mapper.FsUserIntegralLogsMapper;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.param.WxSendRedPacketParam;
@@ -60,6 +65,7 @@ import com.fs.his.service.IFsUserIntegralLogsService;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.ConfigUtil;
+import com.fs.his.vo.FsPackageListVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.im.service.OpenIMService;
 import com.fs.qw.domain.*;
@@ -269,6 +275,12 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
     @Autowired
     private IFsCourseLinkService linkService;
 
+    @Autowired
+    private FsDepVideoShowMapper fsDepVideoShowMapper;
+
+    @Autowired
+    private FsPackageMapper fsPackageMapper;
+
 
     /**
      * 查询课堂视频
@@ -2812,6 +2824,9 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         // 1、获取视频详情、问题详情
         ResponseResult<FsUserCourseVideoDetailsVO> videoDetails = this.getVideoDetails(param.getVideoId());
         FsUserCourseVideoDetailsVO courseVideoDetails = videoDetails.getData() != null ? videoDetails.getData() : null;
+        if(courseVideoDetails != null){
+            getGoodsAndShow(param.getVideoId(),courseVideoDetails);
+        }
 
         //课程logo
         if (param.getPeriodId() != null) {
@@ -2929,6 +2944,44 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         return ResponseResult.ok(vo);
     }
 
+    /**
+     * 小黄车商品和展示
+     */
+    private void getGoodsAndShow(Long videoId, FsUserCourseVideoDetailsVO vo) {
+        String show = fsDepVideoShowMapper.selectFsDepVideoShowByVideoId(videoId, null);
+        vo.setShowTreatment(ObjectUtil.isEmpty(show) ? "1" : show);
+
+        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+        String packageJson = courseVideo.getPackageJson();
+        if (StringUtils.isNotEmpty(packageJson)) {
+            List<String> packageIds = new ArrayList<>();
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode jsonNode = null;
+            try {
+                jsonNode = objectMapper.readTree(packageJson);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+            if (jsonNode.isArray()) {
+                for (JsonNode node : jsonNode) {
+                    String packageId = node.path("packageId").asText();
+                    if (StringUtils.isNotEmpty(packageId)) {
+                        packageIds.add(packageId);
+                    }
+                }
+                List<FsPackageListVO> fsPackageListVOS = new ArrayList<>();
+                if (!packageIds.isEmpty()) {
+                    fsPackageListVOS = fsPackageMapper.selectFsPackagesByIds(packageIds);
+                }else {
+                    fsPackageListVOS = new ArrayList<>();
+                }
+                vo.setTreatmentPackage(fsPackageListVOS);
+            }
+        }else {
+            vo.setTreatmentPackage(new ArrayList<>());
+        }
+    }
+
     /**
      * @Description: 是否看课中断
      * @Param:
@@ -4533,6 +4586,146 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         }
     }
 
+    @Override
+    public R registerQwFsUserFinish(FsUserCourseVideoAddKfUParam param) {// 查询用户
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
+
+        // 不能反401 前端会絮乱
+        // 用户不存在唤起重新授权
+        if (fsUser == null) {
+            return R.error("用户不存在");
+        }
+//        if (StringUtils.isNotEmpty(fsUser.getNickName())
+//                &&fsUser.getNickName().equals("微信用户")) {
+//            return R.error(409, "请重新登录用户!");
+//        }
+        if (fsUser.getStatus() != null && fsUser.getStatus() == 0) {
+            return R.error("会员被停用,无权限,请联系客服!");
+        }
+
+        // 处理群聊逻辑
+        if (param.getChatId() != null && StringUtils.isNotEmpty(param.getChatId())) {
+            QwGroupChat qwGroupChat = qwGroupChatMapper.selectQwGroupChatByChatId(param.getChatId());
+            if (qwGroupChat == null) {
+                logger.error("群聊不存在,chatId: {}", param.getChatId());
+                return R.error("群聊不存在!");
+            }
+
+            SopUserLogsInfo sopUserLogsInfo = new SopUserLogsInfo();
+            sopUserLogsInfo.setChatId(param.getChatId());
+            List<QwGroupChatUser> qwGroupChatUsers = qwGroupChatUserMapper.selectByChatId(sopUserLogsInfo);
+
+            if (qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()) {
+                logger.error("群聊用户为空,chatId: {}", param.getChatId());
+                return R.error("群聊用户为空!");
+            }
+
+            QwExternalContact qwExternalContact =
+                    qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+                            .eq("user_id", qwGroupChat.getOwner())
+                            .eq("fs_user_id", param.getUserId())
+                            .eq("corp_id", param.getCorpId())
+                            .eq("status",0));
+            if(null == qwExternalContact){
+                try{
+                    //修改成通过昵称匹配
+                    qwExternalContact =
+                            qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+                                    .eq("user_id", qwGroupChat.getOwner())
+                                    .eq("name", fsUser.getNickName())
+                                    .eq("corp_id", param.getCorpId())
+                                    .eq("status",0));
+                } catch(Exception e){
+                    log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{}",qwGroupChat.getOwner(),fsUser.getNickName(),param.getCorpId(),e);
+                }
+
+            }
+
+            if (qwExternalContact == null) {
+                return R.error("未查询到客户!");
+            }
+
+            QwExternalContact finalQwExternalContact = qwExternalContact;
+            if(qwGroupChatUsers.stream().noneMatch(e -> e.getUserId().equals(finalQwExternalContact.getExternalUserId()))){
+                log.error("客户不在群:{},里面:{}", qwGroupChat.getChatId(), qwExternalContact.getExternalUserId());
+                return R.error("客户不在群!");
+            }
+
+            logger.info("外部联系人数据:{}", qwExternalContact);
+
+            // 如果群在里面
+            if (qwExternalContact.getFsUserId() != null) {
+                // 有客户有小程序id,但登录的小程序id和根据外部联系人id查出来的小程序id不一致
+//                if (!qwExternalContact.getFsUserId().equals(param.getUserId())) {
+//                    logger.error("已注册,但绑定的userId,不一致param.getUserId{},qwExternalContact.getFsUserId(){}",param.getUserId(),qwExternalContact.getFsUserId());
+//                    return R.error("已注册!");
+//                }
+            }else {
+                // 未绑定
+                return R.error( "客户未绑定用户");
+            }
+
+
+        }else {
+            Long qwExternalId = param.getQwExternalId();
+
+            if (qwExternalId == null) {
+                return R.error("外部联系人ID不能为空");
+            }
+
+            // 查询外部联系人
+            QwExternalContact externalContact = qwExternalContactMapper.selectQwExternalContactById(qwExternalId);
+
+            // 如果查不出来客户信息,加好友
+            if (externalContact == null) {
+                return R.error("未查询到企微客户信息!");
+            }
+
+            if (externalContact.getFsUserId() != null) {
+                // 有客户有小程序id,但登录的小程序id和根据外部联系人id查出来的小程序id不一致
+//                if (!externalContact.getFsUserId().equals(param.getUserId())) {
+//                    logger.error("已注册,但绑定的userId,不一致param.getUserId{},qwExternalContact.getFsUserId(){}",param.getUserId(),externalContact.getFsUserId());
+//                    return R.error("已注册!");
+//                }
+            }else {
+                // 未绑定
+                return R.error( "客户未绑定用户");
+            }
+        }
+
+        return R.ok();
+    }
+
+    @Override
+    public R registerQwFsUser(FsUserCourseVideoAddKfUParam param) {
+        logger.info("zyp \n【判断添加客服】:{}", param);
+
+        // 参数校验
+        if (param == null) {
+            return R.error("参数不能为空");
+        }
+
+        // 查询用户
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
+
+        // 用户不存在唤起重新授权
+        if (fsUser == null) {
+            return R.error(401, "用户不存在");
+        }
+
+        if (fsUser.getStatus() != null && fsUser.getStatus() == 0) {
+            return R.error("会员被停用,无权限,请联系客服!");
+        }
+
+        // 处理群聊逻辑
+        if (param.getChatId() != null) {
+            return handleGroupChatLogic(param,fsUser);
+        }
+
+        // 处理普通外部联系人逻辑
+        return handleExternalContactLogic(param, fsUser);
+    }
+
 
     public void uploadSingleTaskWithRetry(FsVideoResource videoResource,Integer type) {
         int maxRetry = 3;

+ 11 - 0
fs-service/src/main/java/com/fs/course/vo/newfs/FsUserCourseVideoDetailsVO.java

@@ -1,5 +1,6 @@
 package com.fs.course.vo.newfs;
 
+import com.fs.his.vo.FsPackageListVO;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -39,4 +40,14 @@ public class FsUserCourseVideoDetailsVO {
     @ApiModelProperty(value = "题库内容")
     private List<FsUserVideoQuestionVO> questionBankList;
 
+    /**
+     * 疗法包套餐
+     */
+    private List<FsPackageListVO> treatmentPackage;
+
+    /**
+     * 疗法包展示
+     */
+    private String showTreatment;
+
 }

+ 7 - 1
fs-service/src/main/java/com/fs/his/domain/FsInquiryOrderDTO.java

@@ -6,14 +6,20 @@ import lombok.Data;
 public class FsInquiryOrderDTO extends FsInquiryOrder{
     private String json;
     private String doctorName;
+    private String drugDoctorName; //药师名称
+    private String practiseCode; //执业证编号(药师)
     private String hospitalName;
     private String deptCode;
     private String deptName;
-    private String certificateCode;
+    private String certificateCode; //资格证编号(医生)
     private String patientName;
     private String idCard;
     private String sex;
     private String selfMedHistory;
     private String inquiryResult;
     private String reportImages;
+    private String recipeTime; //处方日期,YYYY-MM-DD HH:mm:ss
+    private Integer prescribeType; //处方类型,1中药 2西药
+    private String reviewTime; //处方类型,1中药 2西药
+    private String packageJson; //套餐详情
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/domain/FsUserInformationCollection.java

@@ -115,4 +115,7 @@ public class FsUserInformationCollection extends BaseEntity{
     //药品订单id
     private Long storeOrderId;
 
+    private Long isTemplate; //是否是创建模板 0:否 1:是
+    private String userCommitment; //用户承诺
+
 }

+ 4 - 2
fs-service/src/main/java/com/fs/his/mapper/FsUserInformationCollectionMapper.java

@@ -5,7 +5,9 @@ import com.fs.his.domain.FsUserInformationCollection;
 import com.fs.his.dto.FsUserInformationCollectionDTO;
 import com.fs.his.param.FsUserInformationCollectionListDParam;
 import com.fs.his.param.UserInformationDoctorType2Param;
+import com.fs.his.vo.FsUserInformationCollectionAllVO;
 import com.fs.his.vo.FsUserInformationCollectionListDVO;
+import com.fs.his.vo.FsUserInformationCollectionVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
@@ -26,7 +28,8 @@ public interface FsUserInformationCollectionMapper extends BaseMapper<FsUserInfo
      */
     FsUserInformationCollection selectFsUserInformationCollectionById(Long id);
 
-    FsUserInformationCollection selectFsUserInformationCollectionByUserId(Long userId);
+    FsUserInformationCollectionAllVO selectFsUserInformationCollectionAllById(@Param("id") Long id);
+
 
     /**
      * 查询用户信息采集列表
@@ -70,7 +73,6 @@ public interface FsUserInformationCollectionMapper extends BaseMapper<FsUserInfo
      */
     int deleteFsUserInformationCollectionByIds(Long[] ids);
 
-    FsUserInformationCollection selectByUserId(Long userId);
     FsUserInformationCollection selectByOrderCode(String orderCode);
 
     @Select({"<script> " +

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

@@ -53,4 +53,8 @@ public class FsUserInformationCollectionParam {
     private Long doctorType2Id;
 
     private String packageOrderCode;
+
+    private Long isTemplate; //是否是创建模板 0:否 -1:是 如果不是模板 则存模板id
+
+    private String userCommitment; //用户承诺
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/UserInformationDoctorType2Param.java

@@ -13,4 +13,5 @@ public class UserInformationDoctorType2Param extends BaseParam implements Serial
     private Long doctorType;
     private Long doctorId;
     private Integer doctorConfirm;
+    private Long isTemplate;
 }

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

@@ -107,7 +107,6 @@ public interface IFsUserInformationCollectionService extends IService<FsUserInfo
     //自动退款
     void autoRefund(FsUserInformationCollection collection);
 
-    FsUserInformationCollectionVO getCollectionByUserId(Long userId);
 
     FsUserInformationCollectionDTO selectFsUserInformationCollectionDTOById(Long id);
 

+ 250 - 7
fs-service/src/main/java/com/fs/his/service/impl/FsStoreSubOrderServiceImpl.java

@@ -9,10 +9,16 @@ import java.util.*;
 import java.util.logging.Logger;
 
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.annotation.Log;
+import com.fs.common.utils.CloudHostUtils;
 import com.fs.common.utils.DateUtils;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
@@ -27,7 +33,11 @@ import com.fs.his.vo.FsStoreProductAttrVO;
 import com.fs.his.vo.FsStoreSubOrderListVO;
 import com.fs.his.vo.FsStoreSubOrderVO;
 import com.fs.his.vo.FsSubOrderResultVO;
+import com.fs.wjw.dto.UploadConsultNewDto;
+import com.fs.wjw.dto.UploadFurtherConsultNewDto;
+import com.fs.wjw.dto.UploadRecipeNewDto;
 import com.qcloud.cos.transfer.Copy;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.util.EntityUtils;
@@ -47,6 +57,7 @@ import org.apache.http.impl.client.HttpClients;
  * @date 2024-05-09
  */
 @Service
+@Slf4j
 public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
 {
     @Autowired
@@ -69,7 +80,8 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
     FsStoreProductMapper fsStoreProductMapper;
     @Autowired
     ConfigUtil configUtil;
-    org.slf4j.Logger logger= LoggerFactory.getLogger(getClass());
+    @Autowired
+    private FsDepartmentMapper departmentMapper;
     /**
      * 查询订单
      *
@@ -154,7 +166,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
         FsStoreOrder fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderId(orderId);
         if (fsStoreOrder!=null&&fsStoreOrder.getPrescribeId()!=null){
             FsPrescribe  fsPrescribe = fsPrescribeMapper.selectFsPrescribeByPrescribeId(fsStoreOrder.getPrescribeId());
-            logger.info("拆分处方:"+fsPrescribe);
+            log.info("拆分处方:"+fsPrescribe);
             if (fsPrescribe!=null){
                 FsPrescribeDrug q = new FsPrescribeDrug();
                 q.setPrescribeId(fsStoreOrder.getPrescribeId());
@@ -389,7 +401,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
                         sub.setSubOrderCode(IdUtil.getSnowflake(0, 0).nextIdStr());
                         sub.setDrugDoctorId(fsPrescribe.getDrugDoctorId());
                         fsStoreSubOrderMapper.insertFsStoreSubOrder(sub);
-                        logger.info("药师id:"+fsPrescribe.getDrugDoctorId());
+                        log.info("药师id:"+fsPrescribe.getDrugDoctorId());
                     }
                     FsStoreSubOrder sub = BeanCopyUtils.copy(fsStoreOrder, FsStoreSubOrder.class);
                     BigDecimal prodCostPrice = new BigDecimal("0");
@@ -509,7 +521,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
                     sub.setIcdCode(fsPrescribe.getIcdCode());
                     sub.setSubOrderCode(IdUtil.getSnowflake(0, 0).nextIdStr());
                     sub.setDrugDoctorId(fsPrescribe.getDrugDoctorId());
-                    logger.info("药师id:"+fsPrescribe.getDrugDoctorId());
+                    log.info("药师id:"+fsPrescribe.getDrugDoctorId());
                     fsStoreSubOrderMapper.insertFsStoreSubOrder(sub);
                 }
             }
@@ -519,6 +531,9 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
 
     @Override
     public FsSubOrderResultVO TuiFsStoreSubOrderByStoreOrder(Long orderId) {
+        if (CloudHostUtils.hasCloudHostName("金牛明医")){
+            return tuiFsStoreSubOrderByStoreOrderAndJN(orderId);
+        }
         FsSysConfig sysConfig = configUtil.getSysConfig();
         System.out.println(orderId);
         FsStoreSubOrder fsStoreSubOrder = fsStoreSubOrderMapper.selectFsStoreSubOrderBySubOrderId(orderId);
@@ -574,7 +589,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
             d.setDetailsUsage(fsStoreSubOrder.getDetailsUsage()!=null&&fsStoreSubOrder.getDetailsUsage()!=""?fsStoreSubOrder.getDetailsUsage():"无");
             d.setDetailsFrequencyStr(drug.getUsageFrequencyUnit()!=null&&drug.getUsageFrequencyUnit()!=""?drug.getUsageFrequencyUnit():"无");
             d.setDrugCommonCode(drug.getPrescribeCode()!=null&&drug.getPrescribeCode().trim().length()!=0?drug.getPrescribeCode():"无");
-            logger.info("国药准字:"+d.getDrugCommonCode());
+            log.info("国药准字:"+d.getDrugCommonCode());
             drugs.add(d);
         }
         param.setDrugList(drugs); // 药品列表
@@ -594,7 +609,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
                 // 获取响应状态
                 HttpEntity entity = response.getEntity();
                 String responseBody = EntityUtils.toString(entity);
-                logger.info(orderId+"上传处方返回:"+responseBody);
+                log.info(orderId+"上传处方返回:"+responseBody);
                 FsSubOrderResultVO fsSubOrderResultVO = JSON.parseObject(responseBody, FsSubOrderResultVO.class);
                 if (fsSubOrderResultVO.getCode()==1){
                     FsStoreSubOrder o = new FsStoreSubOrder();
@@ -606,7 +621,7 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
                     o.setSubOrderId(orderId);
                     o.setIsPush(2);
                     fsStoreSubOrderMapper.updateFsStoreSubOrder(o);
-                    logger.info(orderId+":上传处方错误:"+fsSubOrderResultVO+":"+param.getDoctorName());
+                    log.info(orderId+":上传处方错误:"+fsSubOrderResultVO+":"+param.getDoctorName());
                 }
                 return fsSubOrderResultVO;
             }
@@ -617,6 +632,234 @@ public class FsStoreSubOrderServiceImpl implements IFsStoreSubOrderService
         return null;
     }
 
+    private FsSubOrderResultVO tuiFsStoreSubOrderByStoreOrderAndJN(Long orderId){
+        FsStoreSubOrder fsStoreSubOrder = fsStoreSubOrderMapper.selectFsStoreSubOrderBySubOrderId(orderId);
+        FsSubOrderResultVO fsSubOrderResultVO = new FsSubOrderResultVO();
+
+        try {
+            //1.网络咨询服务数据上传-外部
+            FsDoctor fsDoctor = fsDoctorMapper.selectFsDoctorByDoctorId(fsStoreSubOrder.getDoctorId());
+            FsPatient fsPatient = fsPatientMapper.selectFsPatientByPatientId(fsStoreSubOrder.getPatientId());
+            FsDepartment department=departmentMapper.selectFsDepartmentByDeptId(fsDoctor.getDeptId());
+            String section = department.getDeptName();
+            String sectionCode = department.getDeptCode();
+            String thirdUniqueid = fsStoreSubOrder.getSubOrderId().toString();
+            String doctorName = fsDoctor.getDoctorName();
+            String sex = null;
+            if (fsPatient.getSex()==null) {
+                sex = "未知";
+            } else if (fsPatient.getSex() == 1){
+                sex = "男";
+            } else {
+                sex = "女";
+            }
+            String createDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fsStoreSubOrder.getCreateTime());
+            UploadConsultNewDto uploadConsultNewDto = UploadConsultNewDto.builder()
+                    .thirdUniqueid(thirdUniqueid)
+                    .uploadTime(DateUtils.getTime())
+                    .section(section)
+                    .sectionCode(sectionCode)
+                    .docName(doctorName)
+                    .certificateNum(fsDoctor.getCertificateCode())
+                    .patientName(fsStoreSubOrder.getPatientName())
+                    .patientAge(IdcardUtil.getAgeByIdCard(fsStoreSubOrder.getPatientIdcard()))
+                    .patientSex(sex)
+                    .patientIdcardType(1)
+                    .patientIdcardNum(fsStoreSubOrder.getPatientIdcard())
+                    .serviceType(1)
+                    .consultNo(thirdUniqueid)
+                    .consultType(1) //1、图文咨询 2语音咨询3、视频咨询
+                    .consultApplyTime(createDate)
+                    .consultStartTime(createDate)
+                    .consultEndTime(createDate)
+                    .feeType(1)
+                    .price(fsStoreSubOrder.getPayMoney())
+                    .isReply(1)
+                    .medicalHistory(fsStoreSubOrder.getDiagnosis())
+                    .build();
+            String consultJsonParam = JSON.toJSONString(uploadConsultNewDto);
+            if (!doRequest(consultJsonParam,consultPath)){
+                fsSubOrderResultVO.setCode(0);
+                return fsSubOrderResultVO;
+            }
+
+
+            //2.网络复诊服务数据上传-外部
+            UploadFurtherConsultNewDto uploadFurtherConsultNewDto = UploadFurtherConsultNewDto.builder()
+                    .thirdUniqueid(thirdUniqueid)
+                    .uploadTime(DateUtils.getTime())
+                    .section(section)
+                    .sectionCode(sectionCode)
+                    .docName(doctorName)
+                    .certificateNum(fsDoctor.getCertificateCode())
+                    .patientName(fsStoreSubOrder.getPatientName())
+                    .patientAge(IdcardUtil.getAgeByIdCard(fsStoreSubOrder.getPatientIdcard()))
+                    .patientSex(sex)
+                    .patientIdcardType(1)
+                    .patientIdcardNum(fsStoreSubOrder.getPatientIdcard())
+                    .furtherConsultNo(thirdUniqueid)
+                    .furtherConsulType(1)
+                    .medicalHistory(fsStoreSubOrder.getDiagnosis())
+                    .consultDiagnosisType(1)
+                    .consultDiagnosis(fsStoreSubOrder.getDiagnosis())
+                    .consultTime(DateUtils.addDateDays(30) +" " + DateUtils.getTime().split(" ")[1])
+                    .furtherConsultApplyTime(createDate)
+                    .furtherConsulStartTime(createDate)
+                    .furtherConsulEndTime(createDate)
+                    .furtherConsulIsReply(1)
+                    .feeType(1)
+                    .furtherConsultDiagnosis(fsStoreSubOrder.getDiagnosis())
+                    .furtherConsultDiagnosisNo(fsStoreSubOrder.getIcdCode())
+                    .furtherConsultPrice(fsStoreSubOrder.getPayMoney())
+                    .patientEvaluate(1)
+                    .isPrescription(1)//处方药
+                    .build();
+            String furtherJsonParam = JSON.toJSONString(uploadFurtherConsultNewDto);
+
+            if (!doRequest(furtherJsonParam,furtherPath)){
+                fsSubOrderResultVO.setCode(0);
+                return fsSubOrderResultVO;
+            }
+
+            String prescribeDrugJson = fsStoreSubOrder.getPrescribeDrugJson();
+            List<FsPrescribeDrug> fsPrescribeDrugs = JSON.parseArray(prescribeDrugJson, FsPrescribeDrug.class);
+            StringBuilder drugName = new StringBuilder();
+            StringBuilder drugCode = new StringBuilder();
+            StringBuilder drugCommonName = new StringBuilder();
+            StringBuilder specification = new StringBuilder();
+            StringBuilder frequency = new StringBuilder();
+            StringBuilder usage = new StringBuilder();
+            StringBuilder doseUnit = new StringBuilder();
+            StringBuilder doseEachTime = new StringBuilder();
+            StringBuilder medicationDays = new StringBuilder();
+            StringBuilder quantity = new StringBuilder();
+            StringBuilder drugPackage = new StringBuilder();
+            for (FsPrescribeDrug drug : fsPrescribeDrugs) {
+                drugName.append(drug.getDrugNum()).append("|");
+                drugCode.append(drug.getBarCode()).append("|");
+                drugCommonName.append(drug.getDrugNum()).append("|");
+                specification.append(drug.getDrugSpec()).append("|");
+                frequency.append(drug.getUsageFrequencyUnit()).append("|");
+                usage.append(drug.getUsageMethod()).append("|");
+                doseUnit.append(drug.getDrugUnit()).append("|");
+                doseEachTime.append(drug.getUsagePerUseCount()).append("|");
+                medicationDays.append(drug.getUsageDays()).append("|");
+                quantity.append(drug.getDrugNum()).append("|");
+                drugPackage.append(drug.getDrugImgUrl()).append("|");
+            }
+            //3.电子处方服务数据上传-外部
+            FsDoctor drugDoctor = fsDoctorMapper.selectFsDoctorByDoctorId(fsStoreSubOrder.getDrugDoctorId());
+            UploadRecipeNewDto uploadRecipeNewDto = UploadRecipeNewDto.builder()
+                    .thirdUniqueid(thirdUniqueid)
+                    .uploadTime(DateUtils.getTime())
+                    .section(section)
+                    .sectionCode(sectionCode)
+                    .docName(doctorName)
+                    .docCertificateNum(fsDoctor.getCertificateCode())
+                    .pharmacistName(drugDoctor.getDoctorName())
+                    .pharmacistOrg("成都金牛明医云联互联网医院有限公司")
+                    .pharmacistCertificateNum(drugDoctor.getPractiseCode()) //药师执业资格证号
+                    .furtherConsultNo(thirdUniqueid)
+                    .furtherConsultDiagnosis(fsStoreSubOrder.getDiagnosis())
+                    .patientName(fsStoreSubOrder.getPatientName())
+                    .patientAge(IdcardUtil.getAgeByIdCard(fsStoreSubOrder.getPatientIdcard()))
+                    .patientSex(sex)
+                    .patientIdcardType(1)
+                    .patientIdcardNum(fsStoreSubOrder.getPatientIdcard())
+                    .feeType(1)
+                    .medicalHistory(fsStoreSubOrder.getDiagnosis())
+                    .recipeTime(createDate)
+                    .recipeType(fsStoreSubOrder.getOrderType())
+                    .reviewTime(createDate)
+                    .recipeUnitPrice(fsStoreSubOrder.getPayMoney())
+                    .drugName(drugName.toString())
+                    .drugCode(drugCode.toString())
+                    .drugCommonName(drugCommonName.toString())
+                    .specification(specification.toString())
+                    .frequency(frequency.toString())
+                    .usage(usage.toString())
+                    .doseUnit(doseUnit.toString())
+                    .doseEachTime(doseEachTime.toString())
+                    .medicationDays(medicationDays.toString())
+                    .quantity(quantity.toString())
+                    .drugPackage(drugPackage.toString())
+                    .recipeAllPrice(fsStoreSubOrder.getPayMoney())
+                    .recipeNo(drugCode.toString())
+                    .build();
+            String reconsultJsonParam = JSON.toJSONString(uploadRecipeNewDto);
+
+            if (!doRequest(reconsultJsonParam,prescriptionPath)){
+                fsSubOrderResultVO.setCode(0);
+                return fsSubOrderResultVO;
+            }
+
+            FsStoreSubOrder o = new FsStoreSubOrder();
+            o.setSubOrderId(orderId);
+            o.setIsPush(1);
+            fsStoreSubOrderMapper.updateFsStoreSubOrder(o);
+            fsSubOrderResultVO.setCode(1);
+        } catch (Exception e) {
+            FsStoreSubOrder o = new FsStoreSubOrder();
+            o.setSubOrderId(orderId);
+            o.setIsPush(2);
+            fsStoreSubOrderMapper.updateFsStoreSubOrder(o);
+            log.info(orderId+":上传处方错误");
+            fsSubOrderResultVO.setCode(0);
+        }
+        return fsSubOrderResultVO;
+    }
+
+    /**
+     * 金牛卫健委请求
+     * @param jsonParam
+     * @param path
+     */
+
+    private final static String prefix = "https://api.myylhlwyy.com/";
+    private final static String consultPath = "supervision/supervision/uploadConsultNew";//网络咨询服务数据上传-外部
+    private final static String furtherPath = "supervision/supervision/uploadFurtherConsultNew";//网络复诊服务数据上传-外部
+    private final static String prescriptionPath = "supervision/supervision/uploadRecipeNew";//电子处方服务数据上传-外部
+    private boolean doRequest(String jsonParam,String path) {
+        String urlPath = prefix + path;
+        log.info("请求URL: {}", urlPath);
+
+        HttpRequest post = HttpUtil.createPost(urlPath);
+        post.body(jsonParam, "application/json; charset=utf-8");
+
+        log.info("开始发送HTTP请求...");
+        long requestStartTime = System.currentTimeMillis();
+        HttpResponse response = post.execute();
+        long requestEndTime = System.currentTimeMillis();
+
+        log.info("HTTP请求完成,状态码: {}, 耗时: {}ms", response.getStatus(), requestEndTime - requestStartTime);
+        if (response.isOk()) {
+            String responseBody = response.body();
+            log.info("上传成功,响应内容: {}", responseBody);
+
+            // 可以在这里添加响应结果解析和业务逻辑判断
+            try {
+                JSONObject responseJson = JSON.parseObject(responseBody);
+                if (responseJson != null) {
+                    String code = responseJson.getString("code");
+                    String message = responseJson.getString("message");
+                    String data = responseJson.getString("data");
+                    String requestId = responseJson.getString("requestId");
+                    log.info("响应解析 - 状态码: {}, 消息: {}", code, message);
+                    if ("200".equals(code)) {
+                        return  true;
+                    }
+                }
+                return false;
+            } catch (Exception e) {
+                log.warn("响应内容解析失败: {}", e.getMessage());
+                return false;
+            }
+        } else {
+            log.error("上传失败,状态码: {}, 响应内容: {}", response.getStatus(), response.body());
+            return false;
+        }
+    }
+
     @Override
     public List<Long> selectFsStoreSubOrderByNoPush() {
         return fsStoreSubOrderMapper.selectFsStoreSubOrderByNoPush();

+ 13 - 15
fs-service/src/main/java/com/fs/his/service/impl/FsUserInformationCollectionServiceImpl.java

@@ -557,6 +557,14 @@ public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserIn
             FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderId(fsPackageOrder.getStoreOrderId());
             fsStoreOrder.setDoctorType2Confirm(1);
             storeOrderService.updateFsStoreOrder(fsStoreOrder);
+            if (collection.getDoctorType2Confirm() == -1){
+                //拒绝 取消订单
+                FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
+                afterSalesParam.setOrderId(fsStoreOrder.getOrderId());
+                afterSalesParam.setReasons("药师审核拒绝改信息采集订单");
+                afterSalesParam.setOperator(fsDoctor.getDoctorName());
+                storeOrderService.afterSales(afterSalesParam);
+            }
             return R.ok();
         }
         return R.error("药师确认失败");
@@ -909,19 +917,7 @@ public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserIn
             throw new CustomException("退款请求失败" + refund.getResp_desc());
         }
     }
-    @Override
-    public FsUserInformationCollectionVO getCollectionByUserId(Long userId) {
-        FsUserInformationCollectionVO vo = new FsUserInformationCollectionVO();
-        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionByUserId(userId);
-        if (collection != null) {
-            vo.setAnswers(JSON.parseArray(collection.getJsonInfo(), AnswerVO.class));
-            //医生建议
-            if (collection.getDoctorAdvice() != null){
-                vo.setDoctorAdvice(collection.getDoctorAdvice());
-            }
-        }
-        return vo;
-    }
+
 
     @Override
     public FsUserInformationCollectionDTO selectFsUserInformationCollectionDTOById(Long id) {
@@ -935,7 +931,7 @@ public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserIn
 
     @Override
     public FsUserInformationCollectionAndPatientVO selectFsUserInformationCollectionVoById(Long id) {
-        FsUserInformationCollection info = baseMapper.selectFsUserInformationCollectionById(id);
+        FsUserInformationCollectionAllVO info = baseMapper.selectFsUserInformationCollectionAllById(id);
         FsUserInformationCollectionAndPatientVO vo = new FsUserInformationCollectionAndPatientVO();
         BeanUtils.copyProperties(info, vo);
         Long patientId = info.getPatientId();
@@ -1030,7 +1026,9 @@ public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserIn
         fsUserInformationCollection.setRemark(param.getRemark());
         fsUserInformationCollection.setPatientId(param.getPatientId());
         fsUserInformationCollection.setDoctorSign(param.getDoctorSign());
-        //获取医生信息
+        fsUserInformationCollection.setIsTemplate(param.getIsTemplate());
+        fsUserInformationCollection.setUserCommitment(param.getUserCommitment());
+        //获取销售信息
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
         if (companyUser == null) {
             throw new CustomException("销售不存在");

+ 19 - 0
fs-service/src/main/java/com/fs/his/vo/FsUserInformationCollectionAllVO.java

@@ -0,0 +1,19 @@
+package com.fs.his.vo;
+
+import com.fs.his.domain.FsUserInformationCollection;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class FsUserInformationCollectionAllVO extends FsUserInformationCollection {
+
+    private String doctorName;
+    private String doctorType2Name;
+    private String companyUserName;
+    private String packageName;
+    private String patientName;
+    private String patientIdCard;
+
+}

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

@@ -11,7 +11,7 @@ import java.util.Date;
 import java.util.List;
 
 @Data
-public class FsUserInformationCollectionAndPatientVO extends FsUserInformationCollection {
+public class FsUserInformationCollectionAndPatientVO extends FsUserInformationCollectionAllVO {
     private FsPatient patientInfo; //病人信息
     private Integer isPay;
     private Long storeOrderId;

+ 57 - 0
fs-service/src/main/java/com/fs/wjw/dto/UploadConsultNewDto.java

@@ -0,0 +1,57 @@
+package com.fs.wjw.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder
+public class UploadConsultNewDto {
+    /** 唯一标识,可以传主键ID,处方/问诊订单ID */
+    private String thirdUniqueid;
+    /** 上传时间,YYYY-MM-DD HH:mm:ss **/
+    private String uploadTime;
+    /** 科室名称 */
+    private String section;
+    /** 科室编码(三医监管),三医监管的和诊疗科目编码是一致: https://wenku.baidu.com/view/cbc1ff8e9b8fcc22bcd126fff705cc1754275f16.html*/
+    private String sectionCode;
+
+    /**姓名(医师、护师、技师)**/
+    private String docName;
+    /**执业资格证号 **/
+    private String certificateNum;
+    /**患者姓名 **/
+    private String patientName;
+    /**患者年龄 **/
+    private Integer patientAge;
+    /** 患者性别(男/女) **/
+    private String patientSex;
+    /**证件类型(1 身份证 2 护照) **/
+    private Integer patientIdcardType;
+    /**患者证件号码**/
+    private String patientIdcardNum;
+    /**服务类型(1网络咨询 2网络门诊),默认1 **/
+    private Integer serviceType;
+    /**网络咨询或网络门诊编号 **/
+    private String consultNo;
+
+    /**咨询类别(1、图文咨询 2语音咨询3、视频咨询) **/
+    private Integer consultType;
+    /**咨询申请时间,YYYY-MM-DD HH:mm:ss **/
+    private String consultApplyTime;
+    /** 咨询开始时间,YYYY-MM-DD HH:mm:ss **/
+    private String consultStartTime;
+    /**咨询结束时间,YYYY-MM-DD HH:mm:ss **/
+    private String consultEndTime;
+    /** 费别(1自费 2医保),默认1 **/
+    private Integer feeType;
+    /**咨询价格(元) **/
+    private BigDecimal price;
+
+    /**咨询是否回复(0未回复 1已回复) **/
+    private Integer isReply;
+
+    /**患者病史描述**/
+    private String medicalHistory;
+}

+ 90 - 0
fs-service/src/main/java/com/fs/wjw/dto/UploadFurtherConsultNewDto.java

@@ -0,0 +1,90 @@
+package com.fs.wjw.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder
+public class UploadFurtherConsultNewDto {
+    /** 唯一标识,可以传主键ID,处方/问诊订单ID */
+    private String thirdUniqueid;
+
+    /** 上传时间,YYYY-MM-DD HH:mm:ss */
+    private String uploadTime;
+
+    /** 科室名称 */
+    private String section;
+
+    /** 科室编码(三医监管),三医监管的和诊疗科目编码是一致: https://wenku.baidu.com/view/cbc1ff8e9b8fcc22bcd126fff705cc1754275f16.html*/
+    private String sectionCode;
+
+    /**姓名(医师、护师、技师)**/
+    private String docName;
+
+    /**执业资格证号 **/
+    private String certificateNum;
+    /**患者姓名 **/
+    private String patientName;
+
+    /**患者年龄 **/
+    private Integer patientAge;
+    /** 患者性别(男/女) **/
+    private String patientSex;
+
+    /**证件类型(1 身份证 2 护照) **/
+    private Integer patientIdcardType;
+    /**患者证件号码**/
+    private String patientIdcardNum;
+
+    /**网络复诊编号**/
+    private String furtherConsultNo;
+
+    /**复诊类别(1、图文诊疗 2语音诊疗3、视频诊疗)**/
+    private Integer furtherConsulType;
+
+    /**患者病史描述**/
+    private String medicalHistory;
+
+    /**首诊诊断类型(1文字,2图片jpg格式,3图片png格式,4图片bmp格式),默认1**/
+    private Integer consultDiagnosisType;
+
+    /**首诊诊断,传当前问诊诊断**/
+    private String consultDiagnosis;
+
+    /** 首诊时间,YYYY-MM-DD HH:mm:ss,传问诊时间 **/
+    private String consultTime;
+
+    /** 复诊申请时间,YYYY-MM-DD HH:mm:ss **/
+    private String furtherConsultApplyTime;
+
+    /** 复诊开始时间,YYYY-MM-DD HH:mm:ss **/
+    private String furtherConsulStartTime;
+
+    /** 复诊结束时间,YYYY-MM-DD HH:mm:ss **/
+    private String furtherConsulEndTime;
+
+    /** 复诊是否回复(0未回复 1已回复) **/
+    private Integer furtherConsulIsReply;
+
+    /** 费别(1自费 2医保),默认1 **/
+    private Integer feeType;
+
+    /** 复诊诊断(复诊患者在实体医院的诊断名称,如有多条,使用“|”进行分隔) **/
+    private String furtherConsultDiagnosis;
+
+    /** 复诊icd诊断编码 **/
+    private String furtherConsultDiagnosisNo;
+
+    /** 复诊价格(元) **/
+    private BigDecimal furtherConsultPrice;
+
+    /** 患者满意度(1-5,1代表非常满意,5代表非常不满意) **/
+    private Integer patientEvaluate;
+
+    /** 是否开具处方(0否 1是) **/
+    private Integer isPrescription;
+
+
+}

+ 8 - 146
fs-admin/src/main/java/com/fs/his/param/PrescriptionParam.java → fs-service/src/main/java/com/fs/wjw/dto/UploadRecipeNewDto.java

@@ -1,39 +1,18 @@
-package com.fs.his.param;
+package com.fs.wjw.dto;
 
 import lombok.Builder;
 import lombok.Data;
 
-/**
- * 电子处方信息上传请求参数
- */
+import java.math.BigDecimal;
+
 @Data
 @Builder
-public class PrescriptionParam {
-
-    /**
-     * 接口调用凭证
-     */
-    private String accessToken;
-
-    /**
-     * 第三方厂商标识
-     */
-    private String clientId;
-
+public class UploadRecipeNewDto {
     /**
      * 唯一标识,用于唯一确定某条记录,避免重复上传,一般传该条数据的主键
      */
     private String thirdUniqueid;
 
-    /**
-     * 机构名称
-     */
-    private String orgName;
-
-    /**
-     * 机构编码
-     */
-    private String orgCode;
 
     /**
      * 科室名称
@@ -105,25 +84,6 @@ public class PrescriptionParam {
      */
     private String patientIdcardNum;
 
-    /**
-     * 监护人姓名,患者年龄小于6岁需填此项
-     */
-    private String guardianName;
-
-    /**
-     * 监护人身份证,患者年龄小于6岁需填此项
-     */
-    private String guardianIdcardNum;
-
-    /**
-     * 陪伴医师姓名,患者年龄小于6岁需填此项
-     */
-    private String accompanyDocName;
-
-    /**
-     * 陪伴医师执业证号码,患者年龄小于6岁需填此项
-     */
-    private String accompanyCertificateNum;
 
     /**
      * 费别,1自费 2医保
@@ -153,7 +113,7 @@ public class PrescriptionParam {
     /**
      * 处方单价,单位:元
      */
-    private Double recipeUnitPrice;
+    private BigDecimal recipeUnitPrice;
 
     /**
      * 药品名称商品名,以|作为分隔,相同index位置的为一组数据
@@ -200,17 +160,12 @@ public class PrescriptionParam {
     /**
      * 用药天数
      */
-    private Double medicationDays;
-
-    /**
-     * 帖数
-     */
-    private Double packetNum;
+    private String medicationDays;
 
     /**
      * 数量
      */
-    private Double quantity;
+    private String quantity;
 
     /**
      * 药品包装
@@ -220,110 +175,17 @@ public class PrescriptionParam {
     /**
      * 处方总价,单位:元
      */
-    private Double recipeAllPrice;
-
-    /**
-     * 是否经过合理用药判断标志,0 否 1 是
-     */
-    private Integer isRationalDrugUse;
-
-    /**
-     * 合理用药审核结果
-     */
-    private String rationalDrugUseReason;
-
-    /**
-     * 配送单位,配送药企、医院药房发药或药店名称
-     */
-    private String deliveryOrg;
-
-    /**
-     * 核销方式,0 医院取药 1物流配送 2药店取药 3自动失效
-     */
-    private Integer cancelAfterVerifyWay;
-
-    /**
-     * 处方核销状态,0未核销 1已核销
-     */
-    private Integer cancelAfterVerifyStatus;
-
-    /**
-     * 处方核销时间,物流配送、医院药房发药或药店自购时间、自动失效时间
-     */
-    private String cancelAfterVerifyTime;
+    private BigDecimal recipeAllPrice;
 
-    /**
-     * 配送金额
-     */
-    private Double deliveryPrice;
 
     /**
      * 上传时间,格式:YYYY-MM-DD HH:mm:ss
      */
     private String uploadTime;
 
-    /**
-     * 医师ca签名订单id
-     */
-    private String docCaSignOrderId;
-
-    /**
-     * 医师ca签名值
-     */
-    private String docCaSign;
-
-    /**
-     * 医师ca签名时间,格式:YYYY-MM-DD HH:mm:ss
-     */
-    private String docCaSignTime;
-
-    /**
-     * 医师ca登录值
-     */
-    private String docCaLoginSign;
-
-    /**
-     * 医师ca登录时间,格式:YYYY-MM-DD HH:mm:ss
-     */
-    private String docCaLoginTime;
-
-    /**
-     * 药师ca签名订单id
-     */
-    private String pharmacistCaSignOrderId;
-
-    /**
-     * 药师ca签名值
-     */
-    private String pharmacistCaSign;
-
-    /**
-     * 药师ca签名时间,格式:YYYY-MM-DD HH:mm:ss
-     */
-    private String pharmacistCaSignTime;
-
-    /**
-     * 药师ca登录值
-     */
-    private String pharmacistCaLoginSign;
-
-    /**
-     * 药师ca登录时间,格式:YYYY-MM-DD HH:mm:ss
-     */
-    private String pharmacistCaLoginTime;
 
     /**
      * 医院处方编号
      */
     private String recipeNo;
-
-    /**
-     * 所在城市id(参考地区字段)
-     */
-    private String cityId;
-
-    /**
-     * 职称
-     */
-    private String jobTitle;
 }

+ 40 - 14
fs-service/src/main/resources/mapper/his/FsUserInformationCollectionMapper.xml

@@ -38,6 +38,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="doctorType2Confirm"    column="doctor_type2_confirm"    />
         <result property="doctorType2Sign"    column="doctor_type2_sign"    />
         <result property="storeOrderId"    column="store_order_id"    />
+        <result property="isTemplate"    column="is_template"    />
+        <result property="userCommitment"    column="user_commitment"    />
     </resultMap>
 
     <sql id="selectFsUserInformationCollectionVo">
@@ -45,12 +47,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              , doctor_confirm, create_time, update_time,doctor_id,company_user_id
              ,package_id,pay_type,amount,is_package,user_confirm2,package_order_code,package_order_id
              ,status,user_advice,doctor_advice,doctor_sign,doctor_confirm_time,sex,user_name,user_phone_four
-             ,allergy,remark,patient_id,doctor_type2_id,doctor_type2_confirm,doctor_type2_sign,store_order_id  from fs_user_information_collection
+             ,allergy,remark,patient_id,doctor_type2_id,doctor_type2_confirm,doctor_type2_sign,store_order_id,is_template,
+            user_commitment from fs_user_information_collection
     </sql>
 
     <select id="selectFsUserInformationCollectionList" parameterType="FsUserInformationCollection" resultMap="FsUserInformationCollectionResult">
         <include refid="selectFsUserInformationCollectionVo"/>
         <where>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
             <if test="questionId != null "> and question_id = #{questionId}</if>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="jsonInfo != null  and jsonInfo != ''"> and json_info = #{jsonInfo}</if>
@@ -59,6 +63,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageOrderId != null "> and package_order_id = #{packageOrderId}</if>
             <if test="storeOrderId != null "> and store_order_id = #{storeOrderId}</if>
             <if test="packageOrderCode != null and packageOrderCode !=''"> and package_order_code = #{packageOrderCode}</if>
+            <if test="isTemplate != null "> and is_template = #{isTemplate}</if>
+            <if test="isTemplate == null "> and is_template != -1</if>
+            <if test="userCommitment != null and userCommitment != ''"> and user_commitment like concat('%', #{userCommitment},'%')</if>
         </where>
         order by id desc
     </select>
@@ -68,15 +75,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where id = #{id}
     </select>
 
-    <select id="selectFsUserInformationCollectionByUserId" parameterType="Long" resultMap="FsUserInformationCollectionResult">
-        <include refid="selectFsUserInformationCollectionVo"/>
-        where user_id = #{userId}
-    </select>
-
-    <select id="selectByUserId" parameterType="Long" resultMap="FsUserInformationCollectionResult">
-        <include refid="selectFsUserInformationCollectionVo"/>
-        where user_id = #{userId}
-    </select>
 
     <select id="selectByOrderCode" parameterType="String" resultMap="FsUserInformationCollectionResult">
         <include refid="selectFsUserInformationCollectionVo"/>
@@ -102,17 +100,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 <if test="maps.doctorType2Confirm != null"> and fui.doctor_type2_confirm = #{maps.doctorType2Confirm}</if>
                 <if test="maps.packageOrderCode != null  and maps.packageOrderCode != ''"> and fui.package_order_code = #{maps.packageOrderCode}</if>
                 <if test="maps.patientName != null  and maps.patientName != ''"> and fp.patient_name like concat(#{maps.patientName},"%")</if>
+                <if test="maps.isTemplate != null "> and fui.is_template = #{maps.isTemplate}</if>
+                <if test="maps.isTemplate == null "> and is_template != -1</if>
         order by id desc
     </select>
     <select id="selectFsUserInformationCollectionByDoctorType1"
             resultType="com.fs.his.domain.FsUserInformationCollection">
         select fui.*,fp.patient_name as patientName from fs_user_information_collection fui left join fs_patient fp on fui.patient_id = fp.patient_id
-        <where>
-            <if test="maps.doctorId != null and maps.doctorId != ''"> and fui.doctor_id = #{maps.doctorId}</if>
+        where  fui.user_confirm = 1
+        <if test="maps.doctorId != null and maps.doctorId != ''"> and fui.doctor_id = #{maps.doctorId}</if>
             <if test="maps.doctorConfirm != null"> and fui.doctor_confirm = #{maps.doctorConfirm}</if>
             <if test="maps.packageOrderCode != null  and maps.packageOrderCode != ''"> and fui.package_order_code = #{maps.packageOrderCode}</if>
             <if test="maps.patientName != null  and maps.patientName != ''"> and fp.patient_name like concat(#{maps.patientName},"%")</if>
-        </where>
+            <if test="maps.isTemplate != null "> and fui.is_template = #{maps.isTemplate}</if>
+            <if test="maps.isTemplate == null "> and is_template != -1</if>
         order by id desc
     </select>
     <select id="selectFsUserInformationCollectionByOrderCode"
@@ -160,6 +161,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE fso.status > 1
         AND fuic.doctor_type2_confirm = 0
         AND fso.pay_time &lt;= NOW() - INTERVAL 1 HOUR
+        AND fuic.is_template != -1
         GROUP BY fuic.id
     </select>
     <select id="selectListByUserConfirmStatus" resultType="com.fs.his.domain.FsUserInformationCollection">
@@ -198,9 +200,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             fuic.doctor_type2_sign,
             fuic.store_order_id
         FROM fs_user_information_collection fuic
-        WHERE fuic.user_confirm = 1 AND fuic.doctor_confirm = 0 AND fuic.user_confirm_time &lt;= NOW() - INTERVAL 1 HOUR
+        WHERE fuic.user_confirm = 1 AND fuic.doctor_confirm = 0 AND fuic.user_confirm_time &lt;= NOW() - INTERVAL 1 HOUR AND fuic.is_template != -1
         GROUP BY fuic.id
     </select>
+    <select id="selectFsUserInformationCollectionAllById"
+            resultType="com.fs.his.vo.FsUserInformationCollectionAllVO">
+        select uic.id, uic.question_id, uic.user_id, uic.json_info, uic.user_confirm,uic.user_confirm_time
+             , uic.doctor_confirm, uic.create_time, uic.update_time,uic.doctor_id,uic.company_user_id
+             ,uic.package_id,uic.pay_type,uic.amount,uic.is_package,uic.user_confirm2,uic.package_order_code,uic.package_order_id
+             ,uic.status,uic.user_advice,uic.doctor_advice,uic.doctor_sign,uic.doctor_confirm_time,uic.sex,uic.user_name,uic.user_phone_four
+             ,uic.allergy,uic.remark,uic.patient_id,uic.doctor_type2_id,uic.doctor_type2_confirm,uic.doctor_type2_sign,
+              uic.store_order_id,uic.is_template,uic.user_commitment,
+              d1.doctor_name AS doctor_name ,d2.doctor_name AS doctor_type2_name,
+              cu.nick_name AS company_user_name,fp.package_name as package_name,fpa.patient_name AS patient_name,fpa.id_card AS patient_id_card
+        from fs_user_information_collection uic
+                 LEFT JOIN fs_doctor d1 ON uic.doctor_id = d1.doctor_id
+                 LEFT JOIN fs_doctor d2 ON uic.doctor_type2_id = d2.doctor_id
+                 LEFT JOIN company_user cu ON uic.company_user_id = cu.user_id
+                 LEFT JOIN fs_package fp ON uic.package_id = fp.package_id
+                 LEFT JOIN fs_patient fpa ON uic.patient_id = fpa.patient_id
+        where id = #{id}
+    </select>
 
     <insert id="insertFsUserInformationCollection" parameterType="FsUserInformationCollection" useGeneratedKeys="true" keyProperty="id">
         insert into fs_user_information_collection
@@ -237,6 +257,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="doctorType2Confirm != null">doctor_type2_confirm,</if>
             <if test="doctorType2Sign != null">doctor_type2_sign,</if>
             <if test="storeOrderId != null">store_order_id,</if>
+            <if test="isTemplate != null">is_template,</if>
+            <if test="userCommitment != null">user_commitment,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="questionId != null">#{questionId},</if>
@@ -271,6 +293,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="doctorType2Confirm != null">#{doctorType2Confirm},</if>
             <if test="doctorType2Sign != null">#{doctorType2Sign},</if>
             <if test="storeOrderId != null">#{storeOrderId},</if>
+            <if test="isTemplate != null">#{isTemplate},</if>
+            <if test="userCommitment != null">#{userCommitment},</if>
          </trim>
     </insert>
 
@@ -309,6 +333,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="doctorType2Confirm != null">doctor_type2_confirm = #{doctorType2Confirm},</if>
             <if test="doctorType2Sign != null">doctor_type2_sign = #{doctorType2Sign},</if>
             <if test="storeOrderId != null">store_order_id = #{storeOrderId},</if>
+            <if test="isTemplate != null">is_template = #{isTemplate},</if>
+            <if test="userCommitment != null and userCommitment != ''">user_commitment = #{userCommitment},</if>
         </trim>
         where id = #{id}
     </update>

+ 1 - 0
fs-user-app/src/main/java/com/fs/app/controller/CompanyUserController.java

@@ -450,6 +450,7 @@ public class CompanyUserController extends  AppBaseController {
 //        }
 
         fsUserInformationCollection.setCompanyUserId(companyUserId);
+        fsUserInformationCollection.setIsTemplate(-1L);
         Long id = fsUserInformationCollectionService.insertFsUserInformationCollection(fsUserInformationCollection);
         return id == null?R.error("新增失败"):R.ok().put("data",id);
     }

+ 19 - 0
fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

@@ -355,4 +355,23 @@ public class CourseController extends  AppBaseController{
         log.info("zyp \n【发放APP奖励】:{}",param);
         return courseVideoService.sendAppReward(param);
     }
+
+    @Login
+    @ApiOperation("判断是否注册")
+    @PostMapping("/registerQwFsUserFinish")
+    public R registerQwFsUserFinish(@RequestBody FsUserCourseVideoAddKfUParam param) {
+        Long userId = Long.parseLong(getUserId());
+        param.setUserId(userId);
+        return courseVideoService.registerQwFsUserFinish(param);
+    }
+
+
+    @Login
+    @ApiOperation("注册链接接口")
+    @PostMapping("/registerQwFsUser")
+    public R registerQwFsUser(@RequestBody FsUserCourseVideoAddKfUParam param) {
+        Long userId = Long.parseLong(getUserId());
+        param.setUserId(userId);
+        return courseVideoService.registerQwFsUser(param);
+    }
 }

+ 14 - 22
fs-user-app/src/main/java/com/fs/app/controller/FsUserInformationCollectionController.java

@@ -58,18 +58,18 @@ public class FsUserInformationCollectionController extends AppBaseController
         String userId = getUserId();
 
         long nowUserId = Long.parseLong(userId);
-        if (vo.getUserId()!=null){
-            if (vo.getUserId() != nowUserId) {
-                //先查询之前的订单
-                FsUserInformationCollection param = new FsUserInformationCollection();
-                param.setUserId(nowUserId);
-                param.setPackageId(vo.getPackageId());
-                param.setDoctorType2Confirm(0);
-                List<FsUserInformationCollection> list = fsUserInformationCollectionService.selectFsUserInformationCollectionList(param);
-                param.setUserConfirm(0);
-                if (!list.isEmpty()){
-                    return R.error(300,"有信息采集订单暂未完成").put("data",list.get(0));
-                }
+        Long isTemplate = vo.getIsTemplate();
+        if (isTemplate == -1){
+            //模板
+            //查询该用户是否有这个模板生成的信息采集
+            //先查询之前的订单
+            FsUserInformationCollection queryParam = new FsUserInformationCollection();
+            queryParam.setUserId(nowUserId);
+            queryParam.setIsTemplate(vo.getId());
+            List<FsUserInformationCollection> list = fsUserInformationCollectionService.selectFsUserInformationCollectionList(queryParam);
+            if (!list.isEmpty()){
+                return R.ok().put("data", list.get(0));
+            } else {
                 //一对多 创建新的用户采集
                 FsUserInformationCollectionParam info = new FsUserInformationCollectionParam();
                 FsUser fsUser = fsUserService.selectFsUserById(nowUserId);
@@ -87,19 +87,14 @@ public class FsUserInformationCollectionController extends AppBaseController
                 info.setPackageOrderCode(null);
                 info.setSex(fsUser.getSex());
                 info.setUserName(nickName);
-                info.setAllergy(null);
                 info.setPatientId(null);
-                info.setRemark(null);
                 List<AnswerVO> answerVOS = JSON.parseArray(vo.getJsonInfo(), AnswerVO.class);
-                for (AnswerVO answerVO : answerVOS) {
-                    answerVO.setValue(new ArrayList<>());
-                }
                 info.setAnswers(answerVOS);
+                info.setIsTemplate(vo.getId());
+                info.setUserCommitment(null);
                 Long newId = fsUserInformationCollectionService.insertFsUserInformationCollection(info);
                 vo = fsUserInformationCollectionService.selectFsUserInformationCollectionVoById(newId);
-                // return R.error("未查询您的采集信息!");
             }
-
         }
         if (vo.getDoctorConfirm() == 0){
             vo.setPackageId(null);
@@ -129,9 +124,6 @@ public class FsUserInformationCollectionController extends AppBaseController
             if (info.getUserId() != nowUserId){
                 return R.error("您没有修改信息的权限");
             }
-            if (!info.getUserId().equals(fsUserInformationCollection.getUserId())){
-                return R.error("用户id不能修改");
-            }
         } else {
             FsUser fsUser = fsUserService.selectFsUserById(nowUserId);
             String nickname = fsUser.getNickname();

+ 55 - 0
fs-user-app/src/main/java/com/fs/app/controller/LuckyBagController.java

@@ -0,0 +1,55 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.FsUser;
+import com.fs.his.param.FsReceiveLuckyBagParam;
+import com.fs.his.service.IFsUserService;
+import com.fs.qw.service.ILuckyBagService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @description: 福袋控制器 福袋信息 领取福袋
+ * @author: Xgb
+ * @createDate: 2025/11/20
+ * @version: 1.0
+ */
+@Api("福袋接口")
+@RestController
+@RequestMapping(value="/app/luckyBag")
+public class LuckyBagController extends  AppBaseController {
+
+
+    @Autowired
+    private ILuckyBagService luckyBagService;
+
+    @Autowired
+    private IFsUserService userService;
+
+    @ApiOperation("获取福袋详情信息")
+    @GetMapping("/getLuckyBagInfo")
+    public R getLuckyBagInfo(@RequestParam("recordId")Long recordId, HttpServletRequest request){
+        return luckyBagService.getLuckyBagInfoByRecordId(recordId);
+    }
+
+    @Login
+    @ApiOperation("领取福袋")
+    @PostMapping("/receiveLuckyBag")
+    public R receiveLuckyBag(@RequestBody FsReceiveLuckyBagParam param, HttpServletRequest request){
+
+        Long userId = Long.parseLong(getUserId());
+//        Long userId = param.getUserId();
+        FsUser user=userService.selectFsUserByUserId(userId);
+        param.setUserId(user.getUserId());
+        param.setUserName(user.getNickName());
+        return luckyBagService.receiveLuckyBag(param,user);
+
+    }
+
+
+}

+ 63 - 1
fs-user-app/src/main/java/com/fs/app/controller/WxMpController.java

@@ -46,7 +46,7 @@ import java.util.concurrent.TimeUnit;
 
 @RestController
 @RequestMapping("/app/wx/mp")
-public class WxMpController {
+public class WxMpController extends AppBaseController{
   Logger logger= LoggerFactory.getLogger(getClass());
   @Autowired
   private WxMpService wxMpService;
@@ -197,6 +197,68 @@ public class WxMpController {
 
     }
 
+  @ApiOperation("课程短链公众号登录")
+  @PostMapping("/mpByLogin")
+  @Transactional
+  public R mpByLogin( @RequestBody FsUserLoginByMpParam param) {
+
+    if (StringUtils.isBlank(param.getCode())) {
+      return R.error("code不存在");
+    }
+    try{
+      wxMpService.switchoverTo("wxd59797042932c49a");
+      WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
+      WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
+      WxMpUserService wxMpUserService = wxMpService.getUserService();
+      WxMpUser userInfo = wxMpUserService.userInfo(wxMpUser.getOpenid());
+//      if (!userInfo.getSubscribe()){
+//        return R.error("请关注公众号进行登录");
+//      }
+      FsUser user=userService.selectFsUserByUnionid(wxMpUser.getUnionId());
+      if(user!=null){
+        FsUser userMap=new FsUser();
+        userMap.setUserId(user.getUserId());
+        userMap.setNickName(wxMpUser.getNickname());
+        userMap.setAvatar(wxMpUser.getHeadImgUrl());
+        userMap.setMpOpenId(wxMpUser.getOpenid());
+        userMap.setUpdateTime(new DateTime());
+        userService.updateFsUser(userMap);
+      }
+      else{
+        //写入
+//        String code=genCode();
+        user=new FsUser();
+//        user.setPhone(code);
+        user.setNickName(wxMpUser.getNickname());
+        user.setAvatar(wxMpUser.getHeadImgUrl());
+        user.setStatus(1);
+        user.setSex(wxMpUser.getSex());
+        user.setMpOpenId(wxMpUser.getOpenid());
+        user.setUnionId(wxMpUser.getUnionId());
+        user.setCreateTime(new Date());
+        userService.insertFsUser(user);
+      }
+      String token = jwtUtils.generateToken(user.getUserId());
+      redisCache.setCacheObject("token:"+user.getUserId(),token,604800, TimeUnit.SECONDS);
+      Map<String,Object> map=new HashMap<>();
+      map.put("token",token);
+      map.put("user",user);
+      logger.info("zyp \n 【点播公众号登录】:{}",user.getUserId());
+      return R.ok(map);
+
+    }
+    catch (WxErrorException e){
+      if(e.getError().getErrorCode()==40163){
+        return R.error(40163,e.getError().getErrorMsg());
+      }
+      else{
+        return R.error("授权失败,"+e.getMessage());
+      }
+    }
+
+  }
+
+
 
 
 

+ 83 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

@@ -8,6 +8,7 @@ import cn.hutool.core.date.DateTime;
 import com.alibaba.fastjson.JSON;
 import com.fs.app.annotation.Login;
 import com.fs.app.annotation.UserOperationLog;
+import com.fs.app.param.FsUserLoginByMpParam;
 import com.fs.app.utils.JwtUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
@@ -460,4 +461,86 @@ public class WxUserController extends AppBaseController{
         return currentAppIds + "," + newAppId;
     }
 
+
+    @ApiOperation("处理用户与小程序的绑定")
+    @PostMapping("/handleFsUserWx")
+    public R handleFsUserWx(@RequestBody FsUserLoginByMpParam param) {
+
+        SysConfig sysConfig3 = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
+        List<CourseMaConfig> courseMaConfigs = JSON.parseArray(sysConfig3.getConfigValue(), CourseMaConfig.class);
+        if (courseMaConfigs.isEmpty()){
+            return R.error("小程序配置为空");
+        }
+        // 根据appId匹配配置
+        CourseMaConfig matchedConfig = courseMaConfigs.stream()
+                .filter(config -> param.getAppId().equals(config.getAppid()))
+                .findFirst()
+                .orElse(null);
+
+        if (matchedConfig == null) {
+            return R.error("未找到匹配的小程序配置");
+        }
+        return handleCourseLogin1(param,
+                () -> WxMaConfiguration.getMaService(matchedConfig.getAppid()),
+                matchedConfig.getName());
+
+//    final WxMaService wxService = WxMaConfiguration.getMaService(param.getAppId());
+//    try {
+//      //获取微信用户信息
+//      WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
+//
+//      FsUser user = userService.selectFsUserByUserId(param.getUserId());
+//      handleFsUserWx(user, param, session);
+//      return R.ok();
+//    } catch (WxErrorException e) {
+//      if (e.getError().getErrorCode() == 40163) {
+//        return R.error(40163, e.getError().getErrorMsg());
+//      } else {
+//        return R.error("获取用户信息失败," + e.getMessage());
+//      }
+//    }
+    }
+
+    private R handleCourseLogin1(FsUserLoginByMpParam param, Supplier<WxMaService> wxServiceSupplier, String logName) {
+        if (StringUtils.isBlank(param.getCode())) {
+            return R.error("code不存在");
+        }
+
+        try {
+            // 通过函数式接口获取不同的微信服务实例
+            final WxMaService wxService = wxServiceSupplier.get();
+            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
+            this.logger.info("获取{} Session:{}", logName, session);
+
+            FsUser user = userService.selectFsUserByUserId(param.getUserId());
+
+            handleFsUserWx(user, param,session);
+            return R.ok();
+        } catch (WxErrorException e) {
+            if (e.getError().getErrorCode() == 40163) {
+                return R.error(40163, e.getError().getErrorMsg());
+            } else {
+                return R.error("获取用户信息失败," + e.getMessage());
+            }
+        }
+    }
+
+    @Autowired
+    private IFsUserWxService fsUserWxService;
+    /**
+     * 处理用户与小程序的绑定
+     */
+    private void handleFsUserWx(FsUser user, FsUserLoginByMpParam param, WxMaJscode2SessionResult session) {
+        if (user == null) return;
+        FsUserWx fsUserWx = new FsUserWx();
+        fsUserWx.setType(1);
+        fsUserWx.setFsUserId(user.getUserId());
+        fsUserWx.setAppId(param.getAppId());
+        fsUserWx.setOpenId(session.getOpenid());
+        fsUserWx.setUnionId(session.getUnionid() != null ? session.getUnionid() : null);
+        fsUserWx.setCreateTime(new Date());
+        fsUserWx.setUpdateTime(new Date());
+        fsUserWxService.saveOrUpdateByUniqueKey(fsUserWx);
+    }
+
 }