Просмотр исходного кода

1.济世百康直播支付
2.九州在线药方审核

jzp 2 недель назад
Родитель
Сommit
d95a8dc2c8
40 измененных файлов с 2100 добавлено и 146 удалено
  1. 24 0
      fs-admin/src/main/java/com/fs/his/controller/FsDoctorController.java
  2. 8 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  3. 8 1
      fs-company/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  4. 2 0
      fs-live-app/src/main/java/com/fs/live/task/Task.java
  5. 13 4
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  6. 90 0
      fs-service/src/main/java/com/fs/fastgptApi/param/ChatImgParam.java
  7. 2 0
      fs-service/src/main/java/com/fs/fastgptApi/service/ChatService.java
  8. 90 0
      fs-service/src/main/java/com/fs/fastgptApi/service/Impl/ChatServiceImpl.java
  9. 26 0
      fs-service/src/main/java/com/fs/his/mapper/FsDoctorMapper.java
  10. 50 0
      fs-service/src/main/java/com/fs/his/param/DoctorPrescriptionImgLogParam.java
  11. 75 0
      fs-service/src/main/java/com/fs/his/param/DoctorPrescriptionParam.java
  12. 27 3
      fs-service/src/main/java/com/fs/his/service/IFsDoctorService.java
  13. 684 3
      fs-service/src/main/java/com/fs/his/service/impl/FsDoctorServiceImpl.java
  14. 8 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java
  15. 2 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java
  16. 28 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  17. 2 0
      fs-service/src/main/java/com/fs/hisStore/param/FsMyStoreOrderQueryParam.java
  18. 1 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreAfterSalesQueryParam.java
  19. 2 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  20. 1 1
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java
  21. 46 2
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  22. 2 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsMyStoreOrderListQueryVO.java
  23. 2 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesQueryVO.java
  24. 144 99
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  25. 1 0
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  26. 359 0
      fs-service/src/main/resources/mapper/his/FsDoctorMapper.xml
  27. 52 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreAfterSalesScrmMapper.xml
  28. 6 3
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  29. 1 1
      fs-service/src/main/resources/mapper/live/LiveWatchUserMapper.xml
  30. 8 0
      fs-user-app/src/main/java/com/fs/app/controller/AppBaseController.java
  31. 210 8
      fs-user-app/src/main/java/com/fs/app/controller/DoctorController.java
  32. 2 0
      fs-user-app/src/main/java/com/fs/app/controller/UserController.java
  33. 21 12
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java
  34. 2 2
      fs-user-app/src/main/java/com/fs/app/controller/store/PayScrmController.java
  35. 11 0
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java
  36. 16 0
      fs-user-app/src/main/java/com/fs/app/param/DoctorEditParam.java
  37. 14 0
      fs-user-app/src/main/java/com/fs/app/param/DoctorEditPwdParam.java
  38. 26 0
      fs-user-app/src/main/java/com/fs/app/param/DoctorLoginParam.java
  39. 2 0
      fs-user-app/src/main/java/com/fs/app/param/FsDoctorRegisterParam.java
  40. 32 5
      fs-user-app/src/main/java/com/fs/framework/aspectj/LogAspect.java

+ 24 - 0
fs-admin/src/main/java/com/fs/his/controller/FsDoctorController.java

@@ -63,6 +63,30 @@ public class FsDoctorController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 处方图片列表审核
+     * @param param
+     * @return
+     */
+    @PostMapping("/prescriptionList")
+    public TableDataInfo prescriptionList(@RequestBody DoctorPrescriptionImgLogParam param)
+    {
+        startPage();
+        List<DoctorPrescriptionImgLogParam> doctorList = fsDoctorService.selectPrescriptionLogList(param);
+        return getDataTable(doctorList);
+    }
+
+    /**
+     * 处方图片审核
+     * @param param
+     * @return
+     */
+    @PostMapping("/auditPrescription")
+    public AjaxResult auditPrescription(@RequestBody DoctorPrescriptionParam param)
+    {
+        return toAjax(fsDoctorService.updateFsDoctorPrescription(param));
+    }
+
     /**
      * 导出医生管理列表
      */

+ 8 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -762,10 +762,17 @@ public class FsStoreOrderScrmController extends BaseController {
                 if("恒春来".equals(cloudHostProper.getCompanyName())
                         && ObjectUtil.isNotEmpty(lastFourNumber = order.getVirtualPhone())){
                     if (lastFourNumber.contains("-")) {
-                        lastFourNumber = lastFourNumber.length() >= 4 ? lastFourNumber.substring(lastFourNumber.length() - 4) : lastFourNumber;
+                        String beforeDash = lastFourNumber.split("-")[0];
+                        lastFourNumber = beforeDash.length() >= 4 ? beforeDash.substring(beforeDash.length() - 4) : beforeDash;
                     }else{
                         lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                     }
+                    expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
+                    if(expressInfoDTO!=null && !expressInfoDTO.isSuccess()){
+                        lastFourNumber = StrUtil.sub(order.getVirtualPhone(), order.getVirtualPhone().length(), -4);
+                        expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
+                    }
+                    return R.ok().put("data",expressInfoDTO);
                 }
                 // 原逻辑
                 else if ((lastFourNumber = order.getUserPhone()).length() == 11) {

+ 8 - 1
fs-company/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -435,10 +435,17 @@ public class FsStoreOrderScrmController extends BaseController
                 if("恒春来".equals(cloudHostProper.getCompanyName())
                         && ObjectUtil.isNotEmpty(lastFourNumber = order.getVirtualPhone())){
                     if (lastFourNumber.contains("-")) {
-                        lastFourNumber = lastFourNumber.length() >= 4 ? lastFourNumber.substring(lastFourNumber.length() - 4) : lastFourNumber;
+                        String beforeDash = lastFourNumber.split("-")[0];
+                        lastFourNumber = beforeDash.length() >= 4 ? beforeDash.substring(beforeDash.length() - 4) : beforeDash;
                     }else{
                         lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                     }
+                    expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
+                    if(expressInfoDTO!=null && !expressInfoDTO.isSuccess()){
+                        lastFourNumber = StrUtil.sub(order.getVirtualPhone(), order.getVirtualPhone().length(), -4);
+                        expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
+                    }
+                    return R.ok().put("data",expressInfoDTO);
                 }
                 // 原逻辑
                 else if ((lastFourNumber = order.getUserPhone()).length() == 11) {

+ 2 - 0
fs-live-app/src/main/java/com/fs/live/task/Task.java

@@ -351,6 +351,8 @@ public class Task {
                     lotteryVo.setPrizeLevel(liveLotteryProductListVo.getPrizeLevel());
                     lotteryVo.setProductName(liveLotteryProductListVo.getProductName());
                     lotteryVo.setProductId(liveLotteryProductListVo.getProductId());
+                    //设置中奖记录id
+                    lotteryVo.setRecordId(record.getId());
                     lotteryVos.add(lotteryVo);
                 }
             }

+ 13 - 4
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -341,14 +341,23 @@ public class QwMsgController {
                         WxwSpeechToTextEntityDTO ste = new WxwSpeechToTextEntityDTO();
                         ste.setMsgid(wxWorkMessageDTO.getMsg_id());
                         ste.setUuid(wxWorkMsgResp.getUuid());
+
                         WxWorkResponseDTO<WxwSpeechToTextEntityRespDTO> dto = wxWorkService.SpeechToTextEntity(ste, serverId);
                         System.out.println(dto);
-                        if(dto.getErrcode() != 0 || Objects.isNull(dto.getData()) || StringUtils.isBlank(dto.getData().getText())){
+
+                        int maxRetries = 3;
+                        int retryCount = 0;
+
+                        while((dto.getErrcode() != 0 || Objects.isNull(dto.getData()) || StringUtils.isBlank(dto.getData().getText()))
+                                && retryCount < maxRetries) {
                             try {
-                                TimeUnit.SECONDS.sleep(2); // 阻塞2秒
+                                TimeUnit.SECONDS.sleep(1);
+                                retryCount++;
+                                log.info("id:{}, 语音转换第{}次重试", id, retryCount);
                             } catch (InterruptedException e) {
-                                Thread.currentThread().interrupt(); // 处理中断异常
-                                log.info("id:{}, 第一次语音转换失败", id);
+                                Thread.currentThread().interrupt();
+                                log.info("id:{}, 语音转换等待被中断", id);
+                                break;
                             }
                             dto = wxWorkService.SpeechToTextEntity(ste, serverId);
                         }

+ 90 - 0
fs-service/src/main/java/com/fs/fastgptApi/param/ChatImgParam.java

@@ -0,0 +1,90 @@
+package com.fs.fastgptApi.param;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+* 对话接口
+*/
+@Data
+public class ChatImgParam {
+
+    /**
+    * 聊天id
+    */
+    private String chatId;
+
+    //知识库id
+//    private String dataId;
+//    private String datasetId;
+
+    /**
+    * 是否开启 stream模式 (stream模式下会通过event进行区分/非stream模式结果保存在responseData)
+    */
+    private Boolean stream;
+
+    /**
+    * 是否返回中间值(模块状态,响应的完整结果等)
+    */
+    private Boolean detail;
+
+
+    /**
+    * 模块变量,一个对象,会替换模块中,输入框内容里的{{key}}
+    */
+    private Variables variables;
+
+    /**
+    * 聊天信息(对话框)
+    */
+    private List<Message> messages;
+
+
+    @Data
+    public static class Variables {
+        //客户的id?
+        private String uid;
+        /**
+        * 客户名称
+        */
+        private String name;
+
+    }
+
+
+    @Data
+    public static class Message {
+        //知识库id
+        private String dataId;
+//        private String datasetId;
+
+        /**
+        *  问题
+        */
+        private List<content> content;
+        /**
+        * 用户权限
+         * 字段用来定义消息的发送者角色,具体包括三种选择:system、user、和 assistant。
+         *
+         * system(系统):通常用于设置聊天的上下文或者提供系统级别的指示和配置信息。
+         * user(用户):代表实际的用户输入,即用户向聊天系统提出的问题或者发起的对话内容。
+         * assistant(助手):代表智能助手的回复或者动作,是模型根据用户输入给出的响应。
+        */
+        private String role;
+
+        @Data
+        public static class content {
+            private String type;
+            private String text;
+            private ImageUrl image_url;
+        }
+
+        @Data
+        public static class ImageUrl {
+            private String url;
+        }
+
+    }
+
+}

+ 2 - 0
fs-service/src/main/java/com/fs/fastgptApi/service/ChatService.java

@@ -2,6 +2,7 @@ package com.fs.fastgptApi.service;
 
 
 import com.fs.common.core.domain.R;
+import com.fs.fastgptApi.param.ChatImgParam;
 import com.fs.fastgptApi.param.ChatParam;
 
 /**
@@ -13,4 +14,5 @@ public interface ChatService {
     * 发起对话
     */
     R initiatingTakeChat(ChatParam param,String url,String appKey);
+    R initiatingTakeChatNew(ChatImgParam param, String url, String appKey);
 }

+ 90 - 0
fs-service/src/main/java/com/fs/fastgptApi/service/Impl/ChatServiceImpl.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.core.domain.R;
 import com.fs.fastgptApi.config.FastGptApiConfig;
+import com.fs.fastgptApi.param.ChatImgParam;
 import com.fs.fastgptApi.param.ChatParam;
 import com.fs.fastgptApi.result.ChatDetailFStreamFResult;
 import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
@@ -116,6 +117,95 @@ public class ChatServiceImpl implements ChatService {
         return null;
     }
 
+    @Override
+    public R initiatingTakeChatNew(ChatImgParam param, String url, String appKey) {
+
+        String json = HttpUtil.sendPost(param, url+FastGptApiConfig.completionsUrl, appKey);
+
+        JSONObject jsonObject = JSON.parseObject(json);
+
+        // 判断是否有回应消息
+        if(jsonObject.containsKey("choices")){
+            // 获取消息列表
+            JSONArray choices = jsonObject.getJSONArray("choices");
+            // 回复消息不为空
+            if(!choices.isEmpty()){
+                // 判断是否转人工
+                if(JSON.parseObject(choices.get(0).toString()).getJSONObject("message").getString("content").contains("【转人工】")){
+                    jsonObject.put("artificial", true);
+                }
+                if(JSON.parseObject(choices.get(0).toString()).getJSONObject("message").getString("content").contains("FunctionCallBegin")){
+                    jsonObject.put("artificial", true);
+                }
+                if(JSON.parseObject(choices.get(0).toString()).getJSONObject("message").getString("content").contains("【长对话】")){
+                    jsonObject.put("longText", true);
+                }
+
+
+
+                // 替换AI回复里面的所有的【】包括里面的字符串
+                List<JSONObject> list = choices.stream().map(e -> {
+                    JSONObject result = JSON.parseObject(e.toString());
+                    JSONObject message = result.getJSONObject("message");
+                    message.put("content", message.getString("content"));
+                    return result;
+                }).collect(Collectors.toList());
+                jsonObject.put("choices", list);
+            }
+        }
+        // 判断是否匹配知识库逻辑
+        if(jsonObject.containsKey("responseData")){
+            // 遍历查找主对话框
+            JSONArray responseData = jsonObject.getJSONArray("responseData");
+            // 筛选出主对话框里面的信息,里面的historyPreview是匹配信息
+            responseData.stream().filter(e -> "主对话框".equals(JSON.parseObject(e.toString()).getString("moduleName"))).findFirst().ifPresent(e -> {
+                // 进入方法证明以及查找主对话框
+                JSONObject eJson = JSON.parseObject(e.toString());
+                // 如果主对话框里面信息为空则不处理
+                if(!eJson.containsKey("historyPreview") || StringUtils.isEmpty(eJson.getString("historyPreview"))) return;
+                // 循环里面的所有数据
+                JSONArray historyPreview = eJson.getJSONArray("historyPreview");
+                // 判断是否包含未匹配信息  -> true:未匹配到知识库  false:已匹配到知识库
+                boolean knowledge = historyPreview.stream().anyMatch(h -> {
+                    JSONObject hJson = JSON.parseObject(h.toString());
+                    return hJson.getString("value").contains("<Data>\n\n</Data>");
+                });
+                // 之所以取反,是为了后面实体类方便查看
+                jsonObject.put("knowledge", !knowledge);
+            });
+        }
+
+
+        if (jsonObject.containsKey("code") && !("200".equals(jsonObject.getString("code")))) {
+            return R.error().put("data", JSON.parseObject(json, KnowledgeBaseResult.class));
+        }
+        if (!param.getDetail() && !param.getStream()){
+
+            ChatDetailFStreamFResult result = jsonObject.toJavaObject(ChatDetailFStreamFResult.class);
+
+            return R.ok().put("data", result);
+        }
+        // flase true 的方式不建议(即stream流的方式),都是输出完才返回,没意义
+        if (!param.getDetail() && param.getStream()){
+
+//            ChatDetailFStreamTResult result = jsonObject.toJavaObject(ChatDetailFStreamTResult.class);
+
+            return R.ok().put("data", json);
+        }
+
+        if (param.getDetail()&&!param.getStream()){
+            ChatDetailTStreamFResult result = jsonObject.toJavaObject(ChatDetailTStreamFResult.class);
+            return R.ok().put("data", result);
+        }
+
+        // true true 的方式不建议(即stream流的方式),都是输出完才返回,没意义
+        if (param.getDetail()&&param.getStream()){
+
+            return R.ok().put("data", json);
+        }
+        return null;
+    }
+
 
 
 

+ 26 - 0
fs-service/src/main/java/com/fs/his/mapper/FsDoctorMapper.java

@@ -5,6 +5,8 @@ import java.util.Map;
 
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsDoctor;
+import com.fs.his.param.DoctorPrescriptionImgLogParam;
+import com.fs.his.param.DoctorPrescriptionParam;
 import com.fs.his.param.FsDoctorListUParam;
 import com.fs.his.param.FsDoctorParam;
 import com.fs.his.vo.*;
@@ -223,4 +225,28 @@ public interface FsDoctorMapper
      */
     List<FsDoctorListUVO> getFsDoctorListUVOListByIds(@Param("doctorIds") List<Long> doctorIds);
     String selectDoctorNameByIds(@Param("doctorIds") String doctorIds);
+
+    Integer selectFsDoctorPrescriptionByCode(@Param("code") String prescriptionCode);
+
+    int insertFsDoctorPrescription(DoctorPrescriptionParam processResult);
+
+    int insertFsDoctorPrescriptionImgLog(DoctorPrescriptionImgLogParam imgLogParam);
+
+    List<DoctorPrescriptionImgLogParam> selectFsDoctorPrescribeImgByDoctorId(DoctorPrescriptionImgLogParam imgLogParam);
+
+    int updateFsDoctorPrescriptionImgLog(DoctorPrescriptionImgLogParam param1);
+
+    List<DoctorPrescriptionImgLogParam> selectAllPrescriptionImgList(@Param("doctorId") String doctorId,@Param("param") DoctorPrescriptionImgLogParam param);
+
+    DoctorPrescriptionParam selectPrescriptionImgInfo(@Param("id") Long prescriptionId);
+
+    int updateFsDoctorPrescription(DoctorPrescriptionParam processResult);
+
+    int updateFsDoctorPrescriptionByLogId(DoctorPrescriptionParam param);
+
+    DoctorPrescriptionParam selectPrescriptionImgInfoByLogId(@Param("logId") Long logId);
+
+    DoctorPrescriptionImgLogParam selectFsDoctorPrescribeImgById(@Param("id") Long imgLogId);
+
+    List<DoctorPrescriptionImgLogParam> selectPrescriptionLogList(@Param("param") DoctorPrescriptionImgLogParam param);
 }

+ 50 - 0
fs-service/src/main/java/com/fs/his/param/DoctorPrescriptionImgLogParam.java

@@ -0,0 +1,50 @@
+package com.fs.his.param;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class DoctorPrescriptionImgLogParam extends BaseEntity {
+
+    @Excel(name = "ID")
+    private Long id;
+
+    @Excel(name = "医生id")
+    private Long doctorId;
+
+    @Excel(name = "医生名称")
+    private String doctorName;
+
+    @Excel(name = "图片链接")
+    private String url;
+
+    /**
+     *  状态 0上传成功 1解析成功 2解析失败 3解析中
+     */
+    @Excel(name = "状态 0上传成功 1解析成功 2解析失败 3解析中")
+    private Integer status;
+
+    @Excel(name = "是否删除")
+    private Integer isDel;
+
+    @Excel(name = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "处方信息对象")
+    private DoctorPrescriptionParam prescription;
+
+    @ApiModelProperty(value = "医生信息对象")
+    private FsDoctorParam doctorInfo;
+
+    @ApiModelProperty(value = "页码,默认为1")
+    private Integer pageNum =1;
+    @ApiModelProperty(value = "页大小,默认为10")
+    private Integer pageSize = 10;
+    @ApiModelProperty(value = "开始时间")
+    private String beginTime;
+    @ApiModelProperty(value = "结束时间")
+    private String endTime;
+
+}

+ 75 - 0
fs-service/src/main/java/com/fs/his/param/DoctorPrescriptionParam.java

@@ -0,0 +1,75 @@
+package com.fs.his.param;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class DoctorPrescriptionParam extends BaseEntity {
+
+    @Excel(name = "ID")
+    private Long id;
+
+    @Excel(name = "是否解析")
+    private Integer isParse;
+
+    @Excel(name = "处方编号")
+    private String prescriptionCode;
+
+    @Excel(name = "年龄")
+    private Integer age;
+
+    @Excel(name = "性别",readConverterExp = "1=男,2=女,0=未知")
+    private Integer sex;
+
+    @NotNull(message = "处方图片不能为空")
+    private String prescriptionImg;
+
+    @Excel(name = "处方信息")
+    private String prescriptionInfo;
+
+    @Excel(name = "主诉")
+    private String chiefComplaint;
+
+    @Excel(name = "现病史")
+    private String historyOfPresentIllness;
+
+    @Excel(name = "既往史")
+    private String pastMedicalHistory;
+
+    @Excel(name = "个人史")
+    private String personalHistory;
+
+    @Excel(name = "婚育史")
+    private String obstetricHistory;
+
+    @Excel(name = "家族史")
+    private String familyHistory;
+
+    @Excel(name = "建议")
+    private String suggest;
+
+    /**
+     * 状态 0=待完善、1=已创建、2=待提交、3=待审核、4=审核通过、5=审核驳回、6=已完成
+     */
+    @Excel(name = "状态",readConverterExp = "状态 0=待完善、1=已创建、2=待提交、3=待审核、4=审核通过、5=审核驳回、6=已完成")
+    private Integer status;
+
+    private Integer isDel;
+
+    @Excel(name = "医生ID")
+    private Long doctorId;
+
+    @Excel(name = "日志ID")
+    private Long logId;
+
+    /*@Excel(name = "备注")
+    private String remark;*/
+
+
+
+
+}

+ 27 - 3
fs-service/src/main/java/com/fs/his/service/IFsDoctorService.java

@@ -1,10 +1,10 @@
 package com.fs.his.service;
 
+import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsDoctor;
-import com.fs.his.param.FsDoctorListUParam;
-import com.fs.his.param.FsDoctorParam;
-import com.fs.his.param.FsUpdateFollowParam;
+import com.fs.his.param.*;
 import com.fs.his.vo.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 import java.util.Map;
@@ -115,4 +115,28 @@ public interface IFsDoctorService
      * 查询医生选择列表
      */
     List<FsDoctorChooseVO> getChooseDoctorListByMap(Map<String, Object> params);
+
+    R uploadPrescriptionImg(MultipartFile file,String doctorId);
+
+    R cleanPrescriptionImg(String doctorId);
+
+    R selectPrescriptionImgList(String doctorId, DoctorPrescriptionImgLogParam param);
+
+    R selectPrescriptionImgInfo(Long prescriptionId);
+
+    R cleanPrescriptionImgSecond(Long prescriptionId);
+
+    R uploadPrescriptionImg(MultipartFile file, Long logId);
+
+    R deletePrescription(Long imgLogId, Long doctorId);
+
+    R cleanPrescriptionImgOne(Long imgLogId);
+
+    R savePrescriptionInfo(DoctorPrescriptionParam param);
+
+    R commitPrescriptionInfo(DoctorPrescriptionParam param);
+
+    List<DoctorPrescriptionImgLogParam> selectPrescriptionLogList(DoctorPrescriptionImgLogParam param);
+
+    int updateFsDoctorPrescription(DoctorPrescriptionParam param);
 }

+ 684 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsDoctorServiceImpl.java

@@ -3,20 +3,23 @@ package com.fs.his.service.impl;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.common.core.domain.R;
 import com.fs.common.enums.ImTypeEnum;
 import com.fs.common.exception.CustomException;
+import com.fs.common.exception.file.OssException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.sign.Md5Utils;
+import com.fs.fastgptApi.param.ChatImgParam;
+import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
+import com.fs.fastgptApi.service.ChatService;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.mapper.FsDoctorMapper;
 import com.fs.his.mapper.FsFollowMapper;
 import com.fs.his.mapper.FsFollowTempMapper;
 import com.fs.his.mapper.FsStoreOrderMapper;
-import com.fs.his.param.FsDoctorListUParam;
-import com.fs.his.param.FsDoctorParam;
-import com.fs.his.param.FsUpdateFollowParam;
+import com.fs.his.param.*;
 import com.fs.his.service.IFsDoctorService;
 import com.fs.his.service.IFsPrescribeService;
 import com.fs.his.utils.ConfigUtil;
@@ -32,12 +35,16 @@ import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
 import com.google.zxing.WriterException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.imageio.ImageIO;
 import java.awt.*;
@@ -78,6 +85,9 @@ public class FsDoctorServiceImpl implements IFsDoctorService
     @Autowired
     private OpenIMService openIMService;
 
+    @Autowired
+    private ChatService chatService;
+
     /**
      * 查询医生管理
      *
@@ -551,4 +561,675 @@ public class FsDoctorServiceImpl implements IFsDoctorService
         return fsDoctorMapper.getChooseDoctorListByMap(params);
     }
 
+    /**
+     * 上传处方图片
+     * @param file
+     * @param doctorId
+     * @return
+     */
+    @Override
+    public R uploadPrescriptionImg(MultipartFile file, String doctorId) {
+        if (file == null) {
+            return R.error("请选择要上传的文件");
+        }
+
+        return uploadSingleFile(file, doctorId);
+
+    }
+
+    /*//上传处方图片
+    @Override
+    public R uploadPrescriptionImg(MultipartFile[] files, String doctorId) {
+        if (files == null || files.length == 0) {
+            return R.error("请选择要上传的文件");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        int total = files.length;
+        int successCount = 0;
+        int failCount = 0;
+
+        for (MultipartFile file : files) {
+            Map<String, Object> resultMap = uploadSingleFile(file, doctorId);
+            resultList.add(resultMap);
+
+            if ("success".equals(resultMap.get("status"))) {
+                successCount++;
+            } else {
+                failCount++;
+            }
+        }
+
+        return R.ok()
+                .put("total", total)
+                .put("successCount", successCount)
+                .put("failCount", failCount)
+                .put("data", resultList);
+    }*/
+
+    private R uploadSingleFile(MultipartFile file, String doctorId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String fileName = file.getOriginalFilename();
+        resultMap.put("name", fileName);
+
+        try {
+            //validateFile(file, fileName);
+
+            CloudStorageService storage = OSSFactory.build();
+            String suffix = getFileSuffix(fileName);
+            String url = storage.uploadSuffix(file.getBytes(), suffix);
+
+            DoctorPrescriptionImgLogParam imgLogParam = new DoctorPrescriptionImgLogParam();
+            boolean saveSuccess = savePrescriptionLog(imgLogParam,url, doctorId);
+
+            if (saveSuccess) {
+                resultMap.put("id", imgLogParam.getId());
+                resultMap.put("url", url);
+                return R.ok().put("result",resultMap).put("msg", "图片上传成功!");
+            } else {
+                resultMap.put("id", imgLogParam.getId());
+                resultMap.put("url", "");
+                return R.error().put("result",resultMap).put("msg", "保存记录失败!");
+            }
+        } catch (OssException e) {
+            log.error("图片格式或内容校验失败:{}", fileName, e);
+            resultMap.put("url", "");
+            return R.error().put("result",resultMap).put("msg", e.getMessage());
+        } catch (IOException e) {
+            log.error("读取文件失败:{}", fileName, e);
+            resultMap.put("url", "");
+            return R.error().put("result",resultMap).put("msg", "文件读取失败!");
+        } catch (Exception e) {
+            log.error("图片上传失败:{}", fileName, e);
+            resultMap.put("url", "");
+            resultMap.put("msg", "");
+            return R.error().put("result",resultMap).put("msg", "图片上传失败!");
+        }
+    }
+
+    private void validateFile(MultipartFile file, String fileName) throws OssException {
+        if (file.isEmpty()) {
+            throw new OssException("上传文件不能为空");
+        }
+
+        if (fileName == null || fileName.isEmpty()) {
+            throw new OssException("文件名不能为空");
+        }
+
+        String suffix = getFileSuffix(fileName).toLowerCase();
+        if (!isValidImageType(suffix)) {
+            throw new OssException("只支持上传图片格式(jpg、png、gif、bmp)");
+        }
+
+        long fileSize = file.getSize();
+        if (fileSize > 10 * 1024 * 1024) {
+            throw new OssException("文件大小不能超过10MB");
+        }
+    }
+
+    private String getFileSuffix(String fileName) {
+        int lastDotIndex = fileName.lastIndexOf(".");
+        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
+            return fileName.substring(lastDotIndex);
+        }
+        return "";
+    }
+
+    private boolean isValidImageType(String suffix) {
+        return ".jpg".equals(suffix) || ".jpeg".equals(suffix)
+                || ".png".equals(suffix) || ".gif".equals(suffix)
+                || ".bmp".equals(suffix) || ".webp".equals(suffix);
+    }
+
+    private boolean savePrescriptionLog(DoctorPrescriptionImgLogParam imgLogParam,String url, String doctorId) {
+        try {
+            imgLogParam.setDoctorId(Long.parseLong(doctorId));
+            imgLogParam.setUrl(url);
+            imgLogParam.setStatus(0);
+
+            int insertResult = fsDoctorMapper.insertFsDoctorPrescriptionImgLog(imgLogParam);
+
+            if (insertResult != 1) {
+                log.error("插入处方图片日志失败,doctorId: {}, url: {}", doctorId, url);
+                return false;
+            }
+
+            DoctorPrescriptionParam prescriptionParam = new DoctorPrescriptionParam();
+            prescriptionParam.setPrescriptionImg(url);
+            prescriptionParam.setDoctorId(Long.parseLong(doctorId));
+            prescriptionParam.setIsParse(0);
+            prescriptionParam.setStatus(0);
+            prescriptionParam.setLogId(imgLogParam.getId());
+
+            int prescriptionResult = fsDoctorMapper.insertFsDoctorPrescription(prescriptionParam);
+
+            if (prescriptionResult != 1) {
+                log.error("插入处方记录失败,logId: {}, url: {}", imgLogParam.getId(), url);
+                return false;
+            }
+
+            return true;
+        } catch (NumberFormatException e) {
+            log.error("医生ID格式错误:{}", doctorId, e);
+            return false;
+        } catch (Exception e) {
+            log.error("保存处方记录异常,doctorId: {}, url: {}", doctorId, url, e);
+            return false;
+        }
+    }
+
+
+    /**
+     * 解析处方图片
+     */
+    @Override
+    public R cleanPrescriptionImg(String doctorId) {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        DoctorPrescriptionImgLogParam imgLogParam = new DoctorPrescriptionImgLogParam();
+        imgLogParam.setDoctorId(Long.parseLong(doctorId));
+        imgLogParam.setStatus(1);
+        List<DoctorPrescriptionImgLogParam> paramList = fsDoctorMapper.selectFsDoctorPrescribeImgByDoctorId(imgLogParam);
+
+        if (paramList == null || paramList.isEmpty()) {
+            return R.error("请先上传能解析的图片")
+                    .put("data", resultList);
+        }
+
+        int total = paramList.size();
+        int successCount = 0;
+        int failCount = 0;
+
+        for (DoctorPrescriptionImgLogParam logParam : paramList) {
+            Map<String, Object> resultMap = processSingleImage(logParam, doctorId);
+            resultList.add(resultMap);
+
+            if ((Boolean) resultMap.get("status")) {
+                successCount++;
+            } else {
+                failCount++;
+            }
+        }
+
+        return R.ok()
+                .put("total", total)
+                .put("successCount", successCount)
+                .put("failCount", failCount)
+                .put("data", resultList);
+    }
+
+    private Map<String, Object> processSingleImage(DoctorPrescriptionImgLogParam logParam, String doctorId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String url = logParam.getUrl();
+        resultMap.put("url", url);
+
+        DoctorPrescriptionImgLogParam updateParam = new DoctorPrescriptionImgLogParam();
+        updateParam.setId(logParam.getId());
+        updateParam.setStatus(3);
+        updateParam.setRemark("图像解析中...");
+        fsDoctorMapper.updateFsDoctorPrescriptionImgLog(updateParam);
+
+        try {
+            DoctorPrescriptionParam processResult = imageProcess(url, doctorId);
+            processResult.setLogId(logParam.getId());
+
+            if (processResult.getIsParse() != 1 || processResult.getPrescriptionCode() == null) {
+                updateParam.setStatus(2);
+                updateParam.setRemark("图像解析失败,请重新上传!");
+                resultMap.put("status", false);
+                resultMap.put("result", "图像解析失败,请重新上传!");
+            } else {
+                Integer existCount = fsDoctorMapper.selectFsDoctorPrescriptionByCode(processResult.getPrescriptionCode());
+                if (existCount >= 1) {
+                    updateParam.setStatus(2);
+                    updateParam.setRemark("处方单号已存在,请重新上传!");
+                    resultMap.put("status", false);
+                    resultMap.put("result", "处方单号已存在,请重新上传!");
+                } else {
+                    boolean saveSuccess = savePrescription(processResult, logParam.getId());
+                    if (saveSuccess) {
+                        updateParam.setStatus(1);
+                        updateParam.setRemark("解析成功");
+                        resultMap.put("status", true);
+                        resultMap.put("result", processResult);
+                    } else {
+                        updateParam.setStatus(2);
+                        updateParam.setRemark("保存失败,请重新解析!");
+                        resultMap.put("status", false);
+                        resultMap.put("result", "保存失败,请重新解析!");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            updateParam.setStatus(2);
+            updateParam.setRemark("处理异常:" + e.getMessage());
+            resultMap.put("status", false);
+            resultMap.put("result", "处理异常,请稍后重试!");
+        }
+
+        fsDoctorMapper.updateFsDoctorPrescriptionImgLog(updateParam);
+        return resultMap;
+    }
+
+    private boolean savePrescription(DoctorPrescriptionParam processResult, Long logId) {
+        DoctorPrescriptionParam existingParam = fsDoctorMapper.selectPrescriptionImgInfoByLogId(logId);
+
+        if (existingParam != null) {
+            processResult.setId(existingParam.getId());
+            processResult.setStatus(0);
+            return fsDoctorMapper.updateFsDoctorPrescription(processResult) > 0;
+        } else {
+            processResult.setStatus(0);
+            return fsDoctorMapper.insertFsDoctorPrescription(processResult) > 0;
+        }
+    }
+
+
+    @Override
+    public R selectPrescriptionImgList(String doctorId, DoctorPrescriptionImgLogParam param) {
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<DoctorPrescriptionImgLogParam> param1 = fsDoctorMapper.selectAllPrescriptionImgList(doctorId,param);
+        return R.ok().put("result",new PageInfo<>(param1));
+    }
+
+    @Override
+    public R selectPrescriptionImgInfo(Long imgLogId) {
+        DoctorPrescriptionParam param = fsDoctorMapper.selectPrescriptionImgInfoByLogId(imgLogId);
+        return R.ok().put("result",param);
+    }
+
+    @Override
+    public R cleanPrescriptionImgSecond(Long prescriptionId) {
+        if (prescriptionId == null) {
+            return R.error("处方ID不能为空");
+        }
+
+        DoctorPrescriptionParam param = fsDoctorMapper.selectPrescriptionImgInfo(prescriptionId);
+        if (param == null) {
+            return R.error("未找到对应的处方记录");
+        }
+
+        String url = param.getPrescriptionImg();
+        if (url == null || url.isEmpty()) {
+            return R.error("处方图片不存在");
+        }
+
+        Map<String, Object> resultMap = reprocessPrescriptionImage(param, url);
+        return R.ok().put("data", resultMap);
+    }
+
+    private Map<String, Object> reprocessPrescriptionImage(DoctorPrescriptionParam prescriptionParam, String url) {
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("url", url);
+
+        DoctorPrescriptionImgLogParam logUpdateParam = new DoctorPrescriptionImgLogParam();
+        logUpdateParam.setId(prescriptionParam.getLogId());
+
+        try {
+            DoctorPrescriptionParam processResult = imageProcess(url, String.valueOf(prescriptionParam.getDoctorId()));
+
+            if (processResult.getIsParse() != 1 || processResult.getPrescriptionCode() == null) {
+                updateLogStatus(logUpdateParam, 2, "图像解析失败,请重新上传!");
+                resultMap.put("status", false);
+                resultMap.put("result", "图像解析失败,请重新上传!");
+            } else {
+                handleParsedPrescription(processResult, logUpdateParam, resultMap);
+            }
+        } catch (Exception e) {
+            log.error("重新解析处方图片失败,prescriptionId: {}", prescriptionParam.getId(), e);
+            updateLogStatus(logUpdateParam, 2, "解析异常:" + e.getMessage());
+            resultMap.put("status", false);
+            resultMap.put("result", "解析异常,请稍后重试!");
+        }
+
+        return resultMap;
+    }
+
+    private void handleParsedPrescription(DoctorPrescriptionParam processResult,
+                                          DoctorPrescriptionImgLogParam logUpdateParam,
+                                          Map<String, Object> resultMap) {
+        Integer existCount = fsDoctorMapper.selectFsDoctorPrescriptionByCode(processResult.getPrescriptionCode());
+        DoctorPrescriptionParam param = fsDoctorMapper.selectPrescriptionImgInfoByLogId(logUpdateParam.getId());
+        boolean status = param != null && !processResult.getPrescriptionCode().equals(param.getPrescriptionCode()) && param.getIsDel() == 0;
+        if (existCount >= 1 && status) {
+            updateLogStatus(logUpdateParam, 2, "处方单号已存在,请重新上传!");
+            resultMap.put("status", false);
+            resultMap.put("result", "处方单号已存在,请重新上传!");
+        } else {
+            processResult.setLogId(logUpdateParam.getId());
+            resultMap.put("status", true);
+            resultMap.put("result", processResult);
+
+            /*boolean saveSuccess = saveNewPrescription(processResult);
+            if (saveSuccess) {
+                updateLogStatus(logUpdateParam, 1, "解析成功");
+                resultMap.put("status", true);
+                resultMap.put("result", processResult);
+            } else {
+                updateLogStatus(logUpdateParam, 2, "保存失败,请重新解析!");
+                resultMap.put("status", false);
+                resultMap.put("result", "保存失败,请重新解析!");
+            }*/
+        }
+    }
+
+    private boolean saveNewPrescription(DoctorPrescriptionParam processResult) {
+        try {
+            processResult.setStatus(0);
+            int updated = fsDoctorMapper.updateFsDoctorPrescriptionByLogId(processResult);
+            return updated > 0;
+        } catch (Exception e) {
+            log.error("保存新处方记录失败,处方号: {}", processResult.getPrescriptionCode(), e);
+            return false;
+        }
+    }
+
+    @Override
+    public R uploadPrescriptionImg(MultipartFile file, Long logId) {
+        if (file == null || file.isEmpty()) {
+            return R.error("上传文件不能为空");
+        }
+
+        if (logId == null) {
+            return R.error("日志ID不能为空");
+        }
+
+
+        Map<String, Object> resultMap = uploadAndUpdateSingleFile(file, logId);
+
+        if ("success".equals(resultMap.get("status"))) {
+            return R.ok().put("data", resultMap);
+        } else {
+            return R.error((String) resultMap.get("message")).put("data", resultMap);
+        }
+    }
+
+    private Map<String, Object> uploadAndUpdateSingleFile(MultipartFile file, Long logId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String fileName = file.getOriginalFilename();
+        resultMap.put("name", fileName);
+
+        try {
+            validateFile(file, fileName);
+
+            CloudStorageService storage = OSSFactory.build();
+            String suffix = getFileSuffix(fileName);
+            String url = storage.uploadSuffix(file.getBytes(), suffix);
+
+            boolean updateSuccess = updatePrescriptionWithNewImage(url, logId);
+
+            if (updateSuccess) {
+                resultMap.put("id", logId);
+                resultMap.put("status", "success");
+                resultMap.put("url", url);
+                resultMap.put("message", "图片上传成功!");
+            } else {
+                resultMap.put("id", 0);
+                resultMap.put("status", "error");
+                resultMap.put("url", "");
+                resultMap.put("message", "更新记录失败!");
+            }
+        } catch (OssException e) {
+            log.error("图片格式或内容校验失败:{}", fileName, e);
+            resultMap.put("id", 0);
+            resultMap.put("status", "error");
+            resultMap.put("url", "");
+            resultMap.put("message", e.getMessage());
+        } catch (IOException e) {
+            log.error("读取文件失败:{}", fileName, e);
+            resultMap.put("id", 0);
+            resultMap.put("status", "error");
+            resultMap.put("url", "");
+            resultMap.put("message", "文件读取失败!");
+        } catch (Exception e) {
+            log.error("图片上传失败:{}", fileName, e);
+            resultMap.put("id", 0);
+            resultMap.put("status", "error");
+            resultMap.put("url", "");
+            resultMap.put("message", "图片上传失败!");
+        }
+
+        return resultMap;
+    }
+
+    private boolean updatePrescriptionWithNewImage(String url, Long logId) {
+        try {
+            DoctorPrescriptionImgLogParam imgLogParam = new DoctorPrescriptionImgLogParam();
+            imgLogParam.setUrl(url);
+            imgLogParam.setId(logId);
+
+            int logUpdateResult = fsDoctorMapper.updateFsDoctorPrescriptionImgLog(imgLogParam);
+            if (logUpdateResult != 1) {
+                log.error("更新处方图片日志失败,logId: {}, url: {}", logId, url);
+                return false;
+            }
+
+            DoctorPrescriptionParam prescriptionParam = new DoctorPrescriptionParam();
+            prescriptionParam.setPrescriptionImg(url);
+            prescriptionParam.setLogId(logId);
+            prescriptionParam.setIsParse(0);
+
+            int prescriptionUpdateResult = fsDoctorMapper.updateFsDoctorPrescriptionByLogId(prescriptionParam);
+            if (prescriptionUpdateResult < 1) {
+                log.error("更新处方记录失败,logId: {}, url: {}", logId, url);
+                return false;
+            }
+
+            return true;
+        } catch (Exception e) {
+            log.error("更新处方记录异常,logId: {}, url: {}", logId, url, e);
+            return false;
+        }
+    }
+
+    private void updateLogStatus(DoctorPrescriptionImgLogParam logParam, Integer status, String remark) {
+        logParam.setStatus(status);
+        logParam.setRemark(remark);
+        fsDoctorMapper.updateFsDoctorPrescriptionImgLog(logParam);
+    }
+
+
+    // 自定义图片处理方法
+    private DoctorPrescriptionParam imageProcess(String url,String doctorId) {
+        ChatImgParam param=new ChatImgParam();
+        param.setChatId(doctorId);
+        param.setStream(false);
+        param.setDetail(true);
+        List<ChatImgParam.Message> messageList=new ArrayList<ChatImgParam.Message>();
+        ChatImgParam.Message message = new ChatImgParam.Message();
+        message.setRole("user");
+        List<ChatImgParam.Message.content> contents = new ArrayList<>();
+
+        ChatImgParam.Message.content content = new ChatImgParam.Message.content();
+        content.setType("text");
+        content.setText("请根据提示词识别图片内容");
+        contents.add(content);
+
+        //设置上传的图片
+        ChatImgParam.Message.content contentImg = new ChatImgParam.Message.content();
+        contentImg.setType("image_url");
+        ChatImgParam.Message.ImageUrl imageUrl = new ChatImgParam.Message.ImageUrl();
+        imageUrl.setUrl(url);
+        contentImg.setImage_url(imageUrl);
+        contents.add(contentImg);
+
+        message.setContent(contents);
+        messageList.add(message);
+        param.setMessages(messageList);
+
+        R r = chatService.initiatingTakeChatNew(param, "http://129.28.170.206:3000/api", "fastgpt-t3Z1s8Lb6pKMILsSNUHDCOZ4PWgcRlwcWJT7DvrxtvqJfyZbEyWLqS8Up");
+        if(!r.get("code").equals(200)){
+            DoctorPrescriptionParam doctorPrescriptionParam = new DoctorPrescriptionParam();
+            doctorPrescriptionParam.setIsParse(0);
+            return doctorPrescriptionParam;
+        }
+        ChatDetailTStreamFResult result=(ChatDetailTStreamFResult)r.get("data");
+
+        String contentKh = result.getChoices().get(0).getMessage().getContent();
+        System.out.println("模型解析图片结果:"+contentKh);
+        Gson gson = new Gson();
+        DoctorPrescriptionParam fromJson = gson.fromJson(contentKh, DoctorPrescriptionParam.class);
+        fromJson.setPrescriptionImg(url);
+        fromJson.setDoctorId(Long.parseLong(doctorId));
+        return fromJson;
+    }
+
+    @Override
+    @Transactional
+    public R deletePrescription(Long imgLogId, Long doctorId) {
+        DoctorPrescriptionParam param = fsDoctorMapper.selectPrescriptionImgInfoByLogId(imgLogId);
+        if(param == null || param.getId()==null){
+            return R.error("未找到对应的处方记录");
+        }
+        Long prescriptionId = param.getId();
+
+        if (doctorId == null) {
+            return R.error("医生ID不能为空");
+        }
+
+        DoctorPrescriptionParam prescription = fsDoctorMapper.selectPrescriptionImgInfo(prescriptionId);
+        if (prescription == null) {
+            return R.error("未找到对应的处方记录");
+        }
+
+        if (!prescription.getDoctorId().equals(doctorId)) {
+            return R.error("无权删除该处方记录");
+        }
+
+        if (prescription.getIsDel() != null && prescription.getIsDel() == 1) {
+            return R.error("该处方已被删除");
+        }
+
+        Integer status = prescription.getStatus();
+        if (status != null && (status == 3 || status == 4 || status == 6)) {
+            String statusMsg = getStatusDescription(status);
+            return R.error("当前处方状态为" + statusMsg + ",不允许删除");
+        }
+
+        try {
+            DoctorPrescriptionParam updateParam = new DoctorPrescriptionParam();
+            updateParam.setId(prescriptionId);
+            updateParam.setIsDel(1);
+            int prescriptionResult = fsDoctorMapper.updateFsDoctorPrescription(updateParam);
+
+            if (prescriptionResult <= 0) {
+                log.error("软删除处方记录失败,prescriptionId: {}", prescriptionId);
+                return R.error("删除处方记录失败");
+            }
+
+            if (prescription.getLogId() != null) {
+                DoctorPrescriptionImgLogParam logUpdateParam = new DoctorPrescriptionImgLogParam();
+                logUpdateParam.setId(prescription.getLogId());
+                logUpdateParam.setIsDel(1);
+                int logResult = fsDoctorMapper.updateFsDoctorPrescriptionImgLog(logUpdateParam);
+
+                if (logResult <= 0) {
+                    log.warn("更新处方图片日志状态失败,logId: {}", prescription.getLogId());
+                }
+            }
+
+            log.info("成功删除处方记录,prescriptionId: {}, doctorId: {}", prescriptionId, doctorId);
+            return R.ok("删除成功");
+        } catch (Exception e) {
+            log.error("删除处方记录异常,prescriptionId: {}", prescriptionId, e);
+            throw new RuntimeException("删除处方记录失败");
+        }
+    }
+
+    @Override
+    public R cleanPrescriptionImgOne(Long imgLogId) {
+        DoctorPrescriptionParam param = fsDoctorMapper.selectPrescriptionImgInfoByLogId(imgLogId);
+        if(param == null || param.getId()==null){
+            return R.error("未找到对应的处方记录");
+        }
+        return this.cleanPrescriptionImgSecond(param.getId());
+    }
+
+    @Override
+    public R savePrescriptionInfo(DoctorPrescriptionParam param) {
+        Map<String, Object> resultMap = new HashMap<>();
+        Integer existCount = fsDoctorMapper.selectFsDoctorPrescriptionByCode(param.getPrescriptionCode());
+        DoctorPrescriptionParam paramDb = fsDoctorMapper.selectPrescriptionImgInfoByLogId(param.getId());
+        boolean status1 = paramDb != null && !param.getPrescriptionCode().equals(paramDb.getPrescriptionCode()) && paramDb.getIsDel() == 0;
+        if (existCount >= 1 && status1) {
+            DoctorPrescriptionImgLogParam imgLogParam = new DoctorPrescriptionImgLogParam();
+            imgLogParam.setId(param.getLogId());
+            updateLogStatus(imgLogParam, 2, "处方单号已存在,请重新上传!");
+            resultMap.put("status", false);
+            resultMap.put("result", "处方单号已存在,请重新上传!");
+        }
+
+        Integer status = param.getStatus();
+        if(status == 0){
+            int i = fsDoctorMapper.updateFsDoctorPrescriptionByLogId(param);
+            if(i <= 0){
+                resultMap.put("msg", "暂存处方信息失败");
+                return R.error().put("result", resultMap);
+            }
+            resultMap.put("msg", "暂存处方信息成功");
+            return R.ok().put("result", resultMap);
+        }else if(status == 1){
+            if(param.getPrescriptionCode() == null){
+                resultMap.put("msg", "处方单号未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getAge() == null){
+                resultMap.put("msg", "年龄未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getSex() == null){
+                resultMap.put("msg", "性别未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getChiefComplaint() == null){
+                resultMap.put("msg", "主诉未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getHistoryOfPresentIllness() == null){
+                resultMap.put("msg", "现病史未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getSuggest() == null){
+                resultMap.put("msg", "医生建议未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            if(param.getPrescriptionInfo() == null){
+                resultMap.put("msg", "处方信息未填,请重新上传!");
+                return R.error().put("result", resultMap);
+            }
+            fsDoctorMapper.updateFsDoctorPrescriptionByLogId(param);
+            resultMap.put("msg", "保存处方信息成功");
+            return R.ok().put("result", resultMap);
+        }
+        return null;
+    }
+
+    @Override
+    public R commitPrescriptionInfo(DoctorPrescriptionParam param) {
+        int i = fsDoctorMapper.updateFsDoctorPrescriptionByLogId(param);
+        boolean status = i > 0;
+        return R.ok().put("success", status);
+    }
+
+    @Override
+    public List<DoctorPrescriptionImgLogParam> selectPrescriptionLogList(DoctorPrescriptionImgLogParam param) {
+        return fsDoctorMapper.selectPrescriptionLogList(param);
+    }
+
+    @Override
+    public int updateFsDoctorPrescription(DoctorPrescriptionParam param) {
+        return fsDoctorMapper.updateFsDoctorPrescriptionByLogId(param);
+    }
+
+    private String getStatusDescription(Integer status) {
+        switch (status) {
+            case 3:
+                return "待审核";
+            case 4:
+                return "审核通过";
+            case 6:
+                return "已完成";
+            default:
+                return "状态" + status;
+        }
+    }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -3,7 +3,9 @@ package com.fs.hisStore.domain;
 import java.math.BigDecimal;
 import java.util.Date;
 
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
@@ -21,6 +23,7 @@ public class FsStoreOrderScrm extends BaseEntity
     private static final long serialVersionUID = 1L;
 
     /** 订单ID */
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     /** 订单号 */
@@ -203,6 +206,8 @@ public class FsStoreOrderScrm extends BaseEntity
     private String itemJson;
 
     // 直播订单类型:2
+    /**订单类型(0商城,2直播,3点播,5直播中奖,6秒杀,7限时折扣)
+     */
     private Integer orderType;
 
     private Long packageId;
@@ -420,4 +425,7 @@ public class FsStoreOrderScrm extends BaseEntity
     /** 产品是否标记不分润(不入库;分佣流程传参,佣金按 0 入账并仍写公司流水) */
     @TableField(exist = false)
     private Boolean noCommission;
+
+    //直播间id
+    private Long liveId;
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -327,4 +327,6 @@ public interface FsStoreAfterSalesScrmMapper
     @Select("SELECT s.*, s.reason_level1_text AS reasonValue1, s.reason_level2_text AS reasonValue2 " +
             "FROM fs_store_after_sales_scrm s WHERE s.id = #{id}")
     FsStoreAfterSalesScrm selectFsStoreAfterSalesByIdForDetail(@Param("id") Long id);
+
+    List<FsStoreAfterSalesQueryVO> selectFsStoreAfterSalesListQueryNew(@Param("maps") FsStoreAfterSalesQueryParam storeAfterSalesParam);
 }

+ 28 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java

@@ -479,7 +479,7 @@ public interface FsStoreOrderScrmMapper
     List<FsPromotionOrderVO> selectFsPromotionOrderListVO(@Param("maps")FsStoreOrderParam param);
 
     @Select({"<script> " +
-            "select o.id,o.order_code,o.item_json,o.pay_price,o.status,o.is_package,o.package_json,o.delivery_id,o.finish_time,o.company_id,o.company_user_id  from fs_store_order_scrm o  " +
+            "select o.id,o.order_code,o.item_json,o.pay_price,o.status,o.is_package,o.package_json,o.delivery_id,o.finish_time,o.company_id,o.company_user_id,o.live_id  from fs_store_order_scrm o  " +
             "where o.is_del=0 and o.is_sys_del=0 " +
             "<if test = 'maps.status != null and maps.status != \"\"     '> " +
             "and o.status =#{maps.status} " +
@@ -1557,6 +1557,33 @@ public interface FsStoreOrderScrmMapper
      */
     @Select("SELECT * FROM fs_store_order_scrm WHERE status = 0 AND paid = 0 AND create_time < DATE_SUB(NOW(), INTERVAL #{unPayTime} MINUTE)")
     List<FsStoreOrderScrm> selectUnpayTimeoutOrderList(@Param("unPayTime") Integer unPayTime);
+    @Select({"<script> " +
+            "select o.id,o.order_code,o.item_json,o.pay_price,o.status,o.is_package,o.package_json,o.delivery_id,o.finish_time,o.company_id,o.company_user_id,o.live_id  from fs_store_order_scrm o  " +
+            "where o.is_del=0 and o.is_sys_del=0 " +
+            "<if test = 'maps.status != null and maps.status != \"\"     '> " +
+            "and o.status =#{maps.status} " +
+            "</if>" +
+            "<if test = 'maps.keyword != null and  maps.keyword !=\"\"    '> " +
+            "and o.order_code like CONCAT('%',#{maps.keyword},'%') " +
+            "</if>" +
+            "<if test = 'maps.deliveryStatus != null     '> " +
+            "and o.delivery_status =#{maps.deliveryStatus} " +
+            "</if>" +
+            "<if test = 'maps.liveId == null '> " +
+            "and o.live_id is null " +
+            "</if>" +
+            "<if test = 'maps.liveId != null and maps.liveId == 0 '> " +
+            "and o.live_id is not null " +
+            "</if>" +
+            "<if test = 'maps.userId != null     '> " +
+            "and o.user_id=#{maps.userId} " +
+            "</if>" +
+            "<if test = 'maps.appId != null and  maps.appId !=\"\"    '> " +
+            "and o.app_id =#{maps.appId} " +
+            "</if>" +
+            " order by o.id desc "+
+            "</script>"})
+    List<FsMyStoreOrderListQueryVO> selectFsMyStoreOrderListVONew(@Param("maps")FsMyStoreOrderQueryParam param);
 
     @Select("SELECT status FROM fs_store_order_scrm WHERE id = #{orderId}")
     FsStoreOrderScrm selectStatusById(@Param("orderId") Long orderId);

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsMyStoreOrderQueryParam.java

@@ -16,4 +16,6 @@ public class FsMyStoreOrderQueryParam extends BaseQueryParam implements Serializ
     private Integer deliveryStatus;
     @ApiModelProperty(value = "当前的appid")
     private String appId;
+    @ApiModelProperty(value = "直播间ID,null表示查询商城订单,0表示查询直播订单")
+    private Long liveId;
 }

+ 1 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreAfterSalesQueryParam.java

@@ -11,5 +11,6 @@ public class FsStoreAfterSalesQueryParam extends BaseQueryParam implements Seria
 
     private Integer status;
     private Long userId;
+    private Long liveId;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -416,6 +416,8 @@ public interface IFsStoreOrderScrmService
 
     R zfbPayment(FsStoreOrderDoPayParam param);
 
+    List<FsMyStoreOrderListQueryVO> selectFsMyStoreOrderListVONew(FsMyStoreOrderQueryParam param);
+
 //    R getExpressMulti(FsStoreOrder order);
 
     R sendExpressInfoToWx(@PathVariable Long orderId);

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -626,7 +626,7 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
 
     @Override
     public List<FsStoreAfterSalesQueryVO> selectFsStoreAfterSalesListQuery(FsStoreAfterSalesQueryParam storeAfterSalesParam) {
-        List<FsStoreAfterSalesQueryVO>  list=fsStoreAfterSalesMapper.selectFsStoreAfterSalesListQuery(storeAfterSalesParam);
+        List<FsStoreAfterSalesQueryVO>  list=fsStoreAfterSalesMapper.selectFsStoreAfterSalesListQueryNew(storeAfterSalesParam);
         for(FsStoreAfterSalesQueryVO vo:list){
             FsStoreAfterSalesItemScrm map=new FsStoreAfterSalesItemScrm();
              map.setStoreAfterSalesId(vo.getId());

+ 46 - 2
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -3719,21 +3719,27 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     public R syncExpress(FsStoreOrderExpressEditParam param) {
         FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
         String lastFourNumber = "";
+        ExpressInfoDTO dto = null;
         if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue()) || order.getDeliverySn().equals(ShipperCodeEnum.ZTO.getValue())) {
             if("恒春来".equals(cloudHostProper.getCompanyName())
                     && ObjectUtil.isNotEmpty(lastFourNumber = order.getVirtualPhone())){
                 if (lastFourNumber.contains("-")) {
-                    lastFourNumber = lastFourNumber.length() >= 4 ? lastFourNumber.substring(lastFourNumber.length() - 4) : lastFourNumber;
+                    String beforeDash = lastFourNumber.split("-")[0];
+                    lastFourNumber = beforeDash.length() >= 4 ? beforeDash.substring(beforeDash.length() - 4) : beforeDash;
                 }else{
                     lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                 }
+                dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
+                if(dto!=null && !dto.isSuccess()){
+                    lastFourNumber = StrUtil.sub(order.getVirtualPhone(), order.getVirtualPhone().length(), -4);
+                }
             }
             // 原逻辑
             else if ((lastFourNumber = order.getUserPhone()).length() == 11) {
                 lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
             }
         }
-        ExpressInfoDTO dto = expressService.getExpressInfo(order.getOrderCode(), order.getDeliverySn(), order.getDeliveryId(), lastFourNumber);
+        dto = expressService.getExpressInfo(order.getOrderCode(), order.getDeliverySn(), order.getDeliveryId(), lastFourNumber);
         if (dto == null || dto.getState() == null || dto.getStateEx() == null) {
             return null;
         }
@@ -7209,6 +7215,44 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return R.error();
     }
 
+    @Override
+    public List<FsMyStoreOrderListQueryVO> selectFsMyStoreOrderListVONew(FsMyStoreOrderQueryParam param) {
+        List<FsMyStoreOrderListQueryVO> list = fsStoreOrderMapper.selectFsMyStoreOrderListVONew(param);
+        for (FsMyStoreOrderListQueryVO vo : list) {
+//          List<FsStoreOrderItemVO> items=fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(vo.getId());
+//          vo.setItems(items);
+            if (StringUtils.isNotEmpty(vo.getItemJson())) {
+                JSONArray jsonArray = JSONUtil.parseArray(vo.getItemJson());
+                List<FsStoreOrderItemVO> items = JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
+                if (items.size() > 0) {
+                    vo.setItems(items);
+                }
+            }
+            //处理是否可以申请售后
+            vo.setIsAfterSales(0);
+            if (vo.getStatus().equals(OrderInfoEnum.STATUS_3.getValue())) {
+                //已完成订单
+                vo.setIsAfterSales(1);
+                if (vo.getFinishTime() != null) {
+                    String json = configService.selectConfigByKey("store.config");
+                    StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+                    if (storeConfig.getStoreAfterSalesDay() != null && storeConfig.getStoreAfterSalesDay() > 0) {
+                        //判断完成时间是否超过指定时间
+                        Calendar calendar = new GregorianCalendar();
+                        calendar.setTime(vo.getFinishTime());
+                        calendar.add(calendar.DATE, storeConfig.getStoreAfterSalesDay()); //把日期往后增加一天,整数  往后推,负数往前移动
+                        if (calendar.getTime().getTime() < new Date().getTime()) {
+                            vo.setIsAfterSales(0);
+                        }
+                    }
+                }
+            } else if (vo.getStatus() == 1 || vo.getStatus() == 2) {
+                vo.setIsAfterSales(1);
+            }
+        }
+        return list;
+    }
+
 
     /**
      * 综合参数

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsMyStoreOrderListQueryVO.java

@@ -47,5 +47,7 @@ public class FsMyStoreOrderListQueryVO implements Serializable
 
     private List<FsStoreOrderItemVO> items;
 
+    private Long liveId;
+
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesQueryVO.java

@@ -87,6 +87,8 @@ public class FsStoreAfterSalesQueryVO implements Serializable
 
     private String packageJson;
 
+    private Long liveId;
+
 
     List<FsStoreAfterSalesItemScrm> items;
 

+ 144 - 99
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -2181,88 +2181,140 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         // 更改店铺库存
         fsStoreProduct.setStock(fsStoreProduct.getStock() - Integer.parseInt(liveOrder.getTotalNum()));
         fsStoreProduct.setSales(fsStoreProduct.getSales() + Integer.parseInt(liveOrder.getTotalNum()));
-        fsStoreProductScrmMapper.incStockDecSales(Long.valueOf("-" + liveOrder.getTotalNum()), fsStoreProduct.getProductId());
+        fsStoreProductScrmMapper.incStockDecSales(Long.valueOf(liveOrder.getTotalNum()), fsStoreProduct.getProductId());
         // 更新直播间库存
         goods.setStock(goods.getStock() - Integer.parseInt(liveOrder.getTotalNum()));
         goods.setSales(goods.getSales() + Integer.parseInt(liveOrder.getTotalNum()));
         liveGoodsMapper.updateLiveGoods(goods);
 
+        // 复制到商城订单
+        FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
+        copyLiveToStore(liveOrder, storeOrder);
+        storeOrder.setLiveId(liveOrder.getLiveId());
+        storeOrder.setCartId(liveOrder.getCartId());
+
         //判断是否是三种特定产品
+        String storeHouseCode;
         if (fsStoreProduct.getProductId() != null && (fsStoreProduct.getProductId().equals(3168L)
                 || fsStoreProduct.getProductId().equals(3184L)
                 || fsStoreProduct.getProductId().equals(3185L))) {
-            liveOrder.setStoreHouseCode("YDSP001");
+            storeHouseCode = "YDSP001";
         } else {
-            liveOrder.setStoreHouseCode("CQDS001");
+            storeHouseCode = "CQDS001";
         }
 
+        storeOrder.setStoreHouseCode(storeHouseCode);
+
         LiveUserFirstEntry liveUserFirstEntry = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveOrder.getLiveId(), Long.parseLong(liveOrder.getUserId()));
-        liveOrder.setCompanyId(liveUserFirstEntry.getCompanyId());
-        liveOrder.setCompanyUserId(liveUserFirstEntry.getCompanyUserId());
-        liveOrder.setTuiUserId(liveUserFirstEntry.getCompanyUserId());
+        if (ObjectUtil.isNotEmpty(liveUserFirstEntry)) {
+            storeOrder.setCompanyId(liveUserFirstEntry.getCompanyId());
+            storeOrder.setCompanyUserId(liveUserFirstEntry.getCompanyUserId());
+            storeOrder.setTuiUserId(liveUserFirstEntry.getCompanyUserId());
+        }
 
         String orderSn = SnowflakeUtil.nextIdStr();
         log.info("订单生成:" + orderSn);
-        liveOrder.setOrderCode(orderSn);
+        storeOrder.setOrderCode(orderSn);
         BigDecimal totalPrice = fsStoreProduct.getPrice().multiply(new BigDecimal(liveOrder.getTotalNum()));
-        // 直播不需要服务费 0915 1735 左
-//        String config=configService.selectConfigByKey("store.config");
-//        StoreConfig storeConfig= JSONUtil.toBean(config,StoreConfig.class);
-//        BigDecimal serviceFee=new BigDecimal(0);
-//        if(storeConfig.getServiceFee()!=null){
-//            if(liveOrder.getCompanyUserId()==null||liveOrder.getCompanyUserId()==0){
-//                serviceFee=storeConfig.getServiceFee();
-//            }
-//        }
-//        payPrice = payPrice.add(serviceFee);
+
         // 生成
         BigDecimal deliveryMoney = handleDeliveryMoney(liveOrder);
         if (deliveryMoney.compareTo(BigDecimal.valueOf(-1)) == 0) {
             return R.error("偏远地区暂不可购买");
         }
         totalPrice = totalPrice.add(deliveryMoney);
-        liveOrder.setDiscountMoney(totalPrice);
+        BigDecimal discountMoney = BigDecimal.ZERO;
+
+        // 设置商城订单字段(按照 createOrder 的逻辑)
+        storeOrder.setUserId(Long.parseLong(liveOrder.getUserId()));
+        storeOrder.setTotalNum(Long.parseLong(liveOrder.getTotalNum()));
+        storeOrder.setTotalPrice(totalPrice);
+        storeOrder.setTotalPostage(deliveryMoney);
+        storeOrder.setPayPostage(deliveryMoney);
+        storeOrder.setPayDelivery(deliveryMoney);
+        storeOrder.setCouponPrice(discountMoney);
+        storeOrder.setDeductionPrice(BigDecimal.ZERO);
+        storeOrder.setPaid(0);
+        storeOrder.setPayType(StringUtils.isEmpty(liveOrder.getPayType()) ? "1" :liveOrder.getPayType());
+        storeOrder.setUseIntegral(BigDecimal.ZERO);
+        storeOrder.setBackIntegral(BigDecimal.ZERO);
+        storeOrder.setGainIntegral(BigDecimal.ZERO);
+        storeOrder.setCost(BigDecimal.ZERO);
+        storeOrder.setIsChannel(1);
+        storeOrder.setShippingType(1);
+        storeOrder.setCreateTime(new Date());
+        storeOrder.setIsPrescribe(0);
+        storeOrder.setOrderType(5);
+        storeOrder.setStatus(OrderInfoEnum.STATUS_0.getValue());
+        storeOrder.setLiveId(liveOrder.getLiveId());
+
+        // 获取配置
+        String json = configService.selectConfigByKey("store.config");
+        StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+        if (config != null && config.getServiceFee() != null) {
+            storeOrder.setServiceFee(config.getServiceFee());
+        }
 
-        fsStoreProduct.setCost(BigDecimal.ZERO);
-        liveOrder.setItemJson(JSON.toJSONString(fsStoreProduct));
-        liveOrder.setCreateTime(new Date());
-        liveOrder.setUpdateTime(new Date());
-        liveOrder.setPayDelivery(deliveryMoney);
-        liveOrder.setPayPostage(deliveryMoney);
-        liveOrder.setProductId(fsStoreProduct.getProductId());
-        liveOrder.setStatus(OrderInfoEnum.STATUS_0.getValue());
-        liveOrder.setPayType("1");
-        liveOrder.setTotalPrice(totalPrice);
-        liveOrder.setPayMoney(BigDecimal.ZERO);
         try {
-            if (baseMapper.insertLiveOrder(liveOrder) > 0) {
-                liveUserLotteryRecord.setOrderId(liveOrder.getOrderId());
-                liveUserLotteryRecord.setOrderStatus(liveOrder.getStatus());
-                liveUserLotteryRecordMapper.updateLiveUserLotteryRecord(liveUserLotteryRecord);
-                LiveOrderItemDTO dto = new LiveOrderItemDTO();
-                dto.setImage(fsStoreProduct.getImage());
-                dto.setSku(String.valueOf(fsStoreProduct.getStock()));
-                if (StringUtils.isEmpty(fsStoreProduct.getBarCode())) {
-                    FsStoreProductAttrValueScrm fsStoreProductAttrValue = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueByProductId(fsStoreProduct.getProductId()).stream().filter(attr -> StringUtils.isNotEmpty(attr.getBarCode())).findFirst().orElse(null);
-                    if (fsStoreProductAttrValue != null) {
-                        dto.setBarCode(fsStoreProductAttrValue.getBarCode());
-                    }
+            int i = fsStoreOrderScrmMapper.insertFsStoreOrder(storeOrder);
+            if (i > 0) {
+
+                // 保存订单明细
+                FsStoreCartDTO fsStoreCartDTO = new FsStoreCartDTO();
+                fsStoreCartDTO.setProductId(fsStoreProduct.getProductId());
+                fsStoreCartDTO.setPrice(attrValue != null ? attrValue.getPrice() : fsStoreProduct.getPrice());
+                fsStoreCartDTO.setSku(attrValue != null ? (attrValue.getSku() != null ? attrValue.getSku() : "") : "");
+                fsStoreCartDTO.setProductName(fsStoreProduct.getProductName());
+                fsStoreCartDTO.setNum(Integer.parseInt(liveOrder.getTotalNum()));
+                fsStoreCartDTO.setImage(fsStoreProduct.getImage());
+
+                if (attrValue != null) {
+                    fsStoreCartDTO.setBarCode(attrValue.getBarCode());
+                    fsStoreCartDTO.setGroupBarCode(attrValue.getGroupBarCode());
+                }
+
+                FsStoreOrderItemScrm orderItem = new FsStoreOrderItemScrm();
+                orderItem.setOrderId(storeOrder.getId());
+                orderItem.setOrderCode(orderSn);
+                orderItem.setProductId(fsStoreProduct.getProductId());
+                orderItem.setProductAttrValueId(attrValue != null ? attrValue.getId() : null);
+                orderItem.setJsonInfo(JSONUtil.toJsonStr(fsStoreCartDTO));
+                orderItem.setNum(Integer.parseInt(liveOrder.getTotalNum()));
+                orderItem.setIsAfterSales(0);
+                orderItem.setIsPrescribe(0);
+                fsStoreOrderItemScrmMapper.insertFsStoreOrderItem(orderItem);
+
+                // 更新订单的 itemJson
+                List<FsStoreOrderItemScrm> listOrderItem = new ArrayList<>();
+                listOrderItem.add(orderItem);
+                String itemJson = JSONUtil.toJsonStr(listOrderItem);
+                storeOrder.setItemJson(itemJson);
+                fsStoreOrderScrmMapper.updateFsStoreOrder(storeOrder);
+
+                // 添加订单日志
+                orderStatusService.create(storeOrder.getId(), OrderLogEnum.CREATE_ORDER.getValue(),
+                        OrderLogEnum.CREATE_ORDER.getDesc());
+
+                // 设置直播订单的 orderId 为商城订单的 id
+
+                // 加入redis,24小时自动取消
+                String redisKey = StoreConstants.REDIS_ORDER_OUTTIME_UNPAY + storeOrder.getId();
+                if (config != null && config.getUnPayTime() != null && config.getUnPayTime() > 0) {
+                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
                 } else {
-                    dto.setBarCode(fsStoreProduct.getBarCode());
+                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
                 }
-                dto.setPrice(fsStoreProduct.getPrice());
-                dto.setProductName(fsStoreProduct.getProductName());
-                dto.setNum(Long.valueOf(liveOrder.getTotalNum()));
 
-                LiveOrderItem liveOrderItem = new LiveOrderItem();
-                liveOrderItem.setOrderCode(liveOrder.getOrderCode());
-                liveOrderItem.setOrderId(liveOrder.getOrderId());
-                liveOrderItem.setProductId(liveOrder.getProductId());
-                liveOrderItem.setNum(Long.valueOf(liveOrder.getTotalNum()));
-                liveOrderItem.setJsonInfo(JSON.toJSONString(dto));
-                liveOrderItemMapper.insertLiveOrderItem(liveOrderItem);
                 redisCache.deleteObject("orderKey:" + liveOrder.getOrderKey());
-                return R.ok("下单成功").put("order", liveOrder);
+                //添加支付到期时间
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(storeOrder.getCreateTime());
+                if (config != null && config.getUnPayTime() != null) {
+                    calendar.add(Calendar.MINUTE, config.getUnPayTime());
+                }
+                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                String payLimitTime = format.format(calendar.getTime());
+                return R.ok("下单成功").put("order", storeOrder).put("payLimitTime", payLimitTime);
             } else {
                 return R.error("订单创建失败");
             }
@@ -3168,8 +3220,10 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         String appId = liveOrder.getAppId();
         Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
         try {
-            liveOrder = baseMapper.selectLiveOrderByOrderId(String.valueOf(orderId));
-            if (liveOrder == null || !liveOrder.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())) {
+            // 查询商城订单
+            FsStoreOrderScrm storeOrder = fsStoreOrderScrmService.selectFsStoreOrderById(orderId);
+
+            if (storeOrder == null || !storeOrder.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())) {
                 throw new CustomException("当前订单未找到或者订单状态不为待支付! orderId:" + orderId);
             }
             // 设置appId
@@ -3178,9 +3232,6 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             }
             FsUserScrm user = userMapper.selectFsUserById(Long.valueOf(liveOrder.getUserId()));
             if (user == null) return R.error("用户不存在");
-//            String json = configService.selectConfigByKey("store.pay");
-//            String json = configService.selectConfigByKey("his.pay");
-//            FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
             FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(appId);
             if (fsCoursePlaySourceConfig == null) {
                 throw new CustomException("未找到appId对应的小程序配置: " + appId);
@@ -3196,56 +3247,49 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             if (StringUtils.isEmpty(payCode)) {
                 return R.error("订单生成失败,请重试");
             }
-            LiveOrderPayment storePayment = liveOrderPaymentMapper.selectByBuissnessId(liveOrder.getOrderId());
-            storePayment.setAppId(liveOrder.getAppId());
-            if (storePayment != null) {
-                storePayment.setStatus(1);
-                liveOrderPaymentMapper.updateLiveOrderPayment(storePayment);
-            } else {
-                storePayment = new LiveOrderPayment();
-                storePayment.setStatus(1);
+
+            // 查询商城支付记录
+            List<FsStorePaymentScrm> paymentList = fsStorePaymentScrmMapper.selectFsStorePaymentByOrderId(orderId);
+            if (paymentList != null && !paymentList.isEmpty()) {
+                // 检查是否有已支付的支付记录
+                for (FsStorePaymentScrm storePayment : paymentList) {
+                    if (storePayment != null) {
+                        storePayment.setStatus(1);
+                        storePayment.setAppId(liveOrder.getAppId());
+                        storePayment.setPaymentId(storePayment.getPaymentId());
+                        storePayment.setPayTime(new Date());
+                        fsStorePaymentScrmMapper.updateFsStorePayment(storePayment);
+                    }
+                }
+            }else{
+                FsStorePaymentScrm storePayment = new FsStorePaymentScrm();
+                storePayment.setCompanyId(storeOrder.getCompanyId());
+                storePayment.setCompanyUserId(storeOrder.getCompanyUserId());
                 storePayment.setPayMode(merchantAppConfig.getMerchantType());
-                storePayment.setBusinessCode(liveOrder.getOrderCode());
+                storePayment.setStatus(1);
                 storePayment.setPayCode(payCode);
-                storePayment.setPayMoney(liveOrder.getPayMoney());
-//                storePayment.setPayMoney(new BigDecimal("0.01"));
+                storePayment.setPayMoney(storeOrder.getPayMoney());
                 storePayment.setCreateTime(new Date());
                 storePayment.setPayTypeCode("weixin");
-                storePayment.setBusinessType(5);
-                storePayment.setRemark("直播商品订单支付");
-                storePayment.setOpenId(user.getMaOpenId());
+                storePayment.setBusinessType(9);
+                storePayment.setRemark("直播订单支付");
+                storePayment.setOpenId(user.getRealName());
                 storePayment.setUserId(user.getUserId());
-                storePayment.setBusinessId(liveOrder.getOrderId().toString());
-                storePayment.setAppId(appId);
+                storePayment.setBusinessOrderId(storeOrder.getId().toString());
+                storePayment.setOrderId(storeOrder.getId());
+                storePayment.setAppId(fsCoursePlaySourceConfig.getAppid() == null ? "" : fsCoursePlaySourceConfig.getAppid());
                 storePayment.setMerConfigId(merchantAppConfig.getId());
-                liveOrderPaymentMapper.insertLiveOrderPayment(storePayment);
-            }
-
-            if (storePayment != null) {
-                if (storePayment.getStatus().equals(0)) {
-                    LiveOrderPayment paymentMap = new LiveOrderPayment();
-                    paymentMap.setPaymentId(storePayment.getPaymentId());
-                    paymentMap.setStatus(1);
-                    paymentMap.setPayTime(new Date());
-                    liveOrderPaymentMapper.updateLiveOrderPayment(paymentMap);
-                }
-            } else {
-                log.info("支付单号不存在:" + payCode);
-                throw new CustomException("当前支付记录未找到!");
-            }
-            if (liveOrder.getStatus() != 1) {
-                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                return R.error("当前订单未找到或者订单状态不为待支付!");
+                storePayment.setBusinessCode(storeOrder.getOrderCode());
+                fsStorePaymentScrmMapper.insertFsStorePayment(storePayment);
             }
             //增加用户购买次数
-            userMapper.incPayCount(Long.valueOf(liveOrder.getUserId()));
+            userMapper.incPayCount(storeOrder.getUserId());
             //更新用户下单次数和累计成交总额
-            userMapper.updateUserOrderCountAndAmount(Long.valueOf(liveOrder.getUserId()), liveOrder.getPayMoney());
-
-            liveOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
-            liveOrder.setPayTime(LocalDateTime.now());
-            liveUserLotteryRecordMapper.updateOrderStatusByOrderId(liveOrder.getOrderId(), 2);
-            baseMapper.updateLiveOrder(liveOrder);
+            userMapper.updateUserOrderCountAndAmount(storeOrder.getUserId(), storeOrder.getPayMoney());
+            storeOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
+            storeOrder.setPayTime(new Date());
+            liveUserLotteryRecordMapper.updateOrderStatusByOrderId(storeOrder.getId(), 2);
+            fsStoreOrderScrmService.updateFsStoreOrder(storeOrder);
             return R.ok("支付成功");
         } catch (Exception e) {
             log.info("抽奖订单支付错误:" + e.getMessage());
@@ -4131,6 +4175,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         storeOrder.setCreateTime(new Date());
         storeOrder.setIsPrescribe(0);
         storeOrder.setOrderType(2);
+        storeOrder.setLiveId(liveOrder.getLiveId());
 
         // 获取配置
         String json = configService.selectConfigByKey("store.config");

+ 1 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -247,6 +247,7 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
             "            <if test=\"wayId != null  and wayId != ''\"> and  SUBSTRING_INDEX(ec.state, ':', -1) = #{wayId} </if>\n" +
             "            <if test=\"name != null  and name != ''\"> and ec.name like concat( #{name}, '%')</if>\n" +
             "            <if test=\"type != null \"> and ec.type = #{type}</if>\n" +
+            "            <if test=\"isReply != null \"> and ec.is_reply = #{isReply}</if>\n" +
             "            <if test=\"gender != null \"> and ec.gender = #{gender}</if>\n" +
             "            <if test=\"description != null  and description != ''\"> and ec.description = #{description}</if>\n" +
 

+ 359 - 0
fs-service/src/main/resources/mapper/his/FsDoctorMapper.xml

@@ -64,6 +64,64 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="gptRoleId"    column="gpt_role_id"    />
     </resultMap>
 
+    <resultMap type="com.fs.his.param.DoctorPrescriptionImgLogParam" id="DoctorPrescriptionImgLogResult">
+        <result property="id"    column="id"    />
+        <result property="doctorId"    column="doctor_id"    />
+        <result property="url"    column="url"    />
+        <result property="status"    column="status"    />
+        <result property="isDel"    column="is_del"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <association property="doctorInfo" javaType="com.fs.his.param.FsDoctorParam">
+            <result property="doctorId"    column="doctor_id"    />
+            <result property="doctorName"    column="doctor_name"    />
+            <result property="introduction"    column="introduction"    />
+            <result property="speciality"    column="speciality"    />
+            <result property="certificateCode"    column="certificate_code"    />
+            <result property="certificateImages"    column="certificate_images"    />
+            <result property="practiseCode"    column="practise_code"    />
+            <result property="practiseImages"    column="practise_images"    />
+            <result property="avatar"    column="avatar"    />
+            <result property="hospitalId"    column="hospital_id"    />
+            <result property="deptId"    column="dept_id"    />
+            <result property="position"    column="position"    />
+            <result property="tags"    column="tags"    />
+            <result property="status"    column="doctor_status"    />
+            <result property="pingStar"    column="ping_star"    />
+            <result property="orderNumber"    column="order_number"    />
+            <result property="mobile"    column="mobile"    />
+            <result property="doctorType"    column="doctor_type"    />
+            <result property="sex"    column="sex"    />
+            <result property="workStatus"    column="work_status"    />
+            <result property="isAudit"    column="is_audit"    />
+        </association>
+
+        <association property="prescription" javaType="com.fs.his.param.DoctorPrescriptionParam">
+            <result property="id"    column="prescription_id"    />
+            <result property="isParse"    column="is_parse"    />
+            <result property="prescriptionCode"    column="prescription_code"    />
+            <result property="age"    column="age"    />
+            <result property="sex"    column="patient_sex"    />
+            <result property="prescriptionImg"    column="prescription_img"    />
+            <result property="prescriptionInfo"    column="prescription_info"    />
+            <result property="chiefComplaint"    column="chief_complaint"    />
+            <result property="historyOfPresentIllness"    column="history_of_present_illness"    />
+            <result property="pastMedicalHistory"    column="past_medical_history"    />
+            <result property="personalHistory"    column="personal_history"    />
+            <result property="obstetricHistory"    column="obstetric_history"    />
+            <result property="familyHistory"    column="family_history"    />
+            <result property="suggest"    column="suggest"    />
+            <result property="status"    column="prescription_status"    />
+            <result property="doctorId"    column="prescription_doctor_id"    />
+            <result property="logId"    column="prescription_log_id"    />
+            <result property="isDel"    column="prescription_is_del"    />
+            <result property="createTime"    column="prescription_create_time"    />
+            <result property="updateTime"    column="prescription_update_time"    />
+            <result property="remark"    column="prescription_remark"    />
+        </association>
+    </resultMap>
+
     <sql id="selectFsDoctorVo">
         select doctor_id,is_agreement_prescribe_doctor,is_follow,is_show,audit_type,store_ids,gpt_role_id, package_ids,sort,doctor_card_url,prescribe_doctor_id,is_prescribe_doctor,doctor_name,is_accept,is_self, introduction, speciality, certificate_code, certificate_images, practise_code, practise_images, avatar, user_id, hospital_id, dept_id, balance, position, tags, create_time, update_time, status, remark, ping_star, order_number, speed, mobile, doctor_type, sex, bitthday, id_card, id_card_front_url, id_card_back_url, city_ids, province, city, district, is_tui, is_expert, work_status, is_audit, audit_time, price_json, account, password,sign_url,jpush_id,extract_json from fs_doctor
     </sql>
@@ -181,6 +239,195 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{doctorId}
         </foreach>
     </select>
+    <select id="selectFsDoctorPrescriptionByCode" resultType="java.lang.Integer">
+        select count(1) from fs_doctor_prescription_new where prescription_code = #{code} and is_del = 0
+    </select>
+
+    <select id="selectFsDoctorPrescribeImgByDoctorId"
+            resultType="com.fs.his.param.DoctorPrescriptionImgLogParam">
+        select id,doctor_id doctorId,url,status,remark from fs_doctor_prescription_img_log
+        where is_del = 0
+          <if test="doctorId != null">and doctor_id = #{doctorId}</if>
+          <if test="status != null">and status != #{status}</if>
+        order by id desc
+    </select>
+    <select id="selectAllPrescriptionImgList" resultMap="DoctorPrescriptionImgLogResult">
+        SELECT
+        l.id,
+        l.doctor_id,
+        l.url,
+        l.status,
+        l.is_del,
+        l.remark,
+        l.create_time,
+        l.update_time,
+        l.remark,
+        p.id AS prescription_id,
+        p.is_parse AS prescription_is_parse,
+        p.prescription_code AS prescription_code,
+        p.age AS prescription_age,
+        p.sex AS prescription_sex,
+        p.prescription_img AS prescription_img,
+        p.prescription_info AS prescription_info,
+        p.chief_complaint AS prescription_chief_complaint,
+        p.history_of_present_illness AS prescription_history_of_present_illness,
+        p.past_medical_history AS prescription_past_medical_history,
+        p.personal_history AS prescription_personal_history,
+        p.obstetric_history AS prescription_obstetric_history,
+        p.family_history AS prescription_family_history,
+        p.suggest AS prescription_suggest,
+        p.status AS prescription_status,
+        p.doctor_id AS prescription_doctor_id,
+        p.remark AS prescription_remark
+        FROM fs_doctor_prescription_img_log l
+        LEFT JOIN fs_doctor_prescription_new p ON l.id = p.log_id
+        WHERE l.is_del = 0
+        <if test="doctorId != null and doctorId != ''">
+            AND l.doctor_id = #{doctorId}
+        </if>
+        <if test="param.status != null and param.status != ''">
+            AND p.status = #{param.status}
+        </if>
+        ORDER BY l.id DESC
+    </select>
+
+    <select id="selectPrescriptionImgInfo" resultType="com.fs.his.param.DoctorPrescriptionParam">
+        SELECT
+        p.id,
+        p.doctor_id doctorId,
+        p.prescription_code prescriptionCode,
+        p.age,
+        p.sex,
+        p.chief_complaint,
+        p.history_of_present_illness historyOfPresentIllness,
+        p.past_medical_history pastMedicalHistory,
+        p.personal_history personalHistory,
+        p.obstetric_history obstetricHistory,
+        p.family_history familyHistory,
+        p.is_parse isParse,
+        p.prescription_info prescriptionInfo,
+        p.prescription_img prescriptionImg,
+        p.suggest suggest,
+        p.status,
+        p.log_id logId,p.remark remark
+        from fs_doctor_prescription_new p
+        where id = #{id}
+    </select>
+    <select id="selectPrescriptionImgInfoByLogId" resultType="com.fs.his.param.DoctorPrescriptionParam">
+        SELECT
+            p.id,
+            p.doctor_id doctorId,
+            p.prescription_code prescriptionCode,
+            p.age,
+            p.sex,
+            p.chief_complaint,
+            p.history_of_present_illness historyOfPresentIllness,
+            p.past_medical_history pastMedicalHistory,
+            p.personal_history personalHistory,
+            p.obstetric_history obstetricHistory,
+            p.family_history familyHistory,
+            p.is_parse isParse,
+            p.prescription_info prescriptionInfo,
+            p.prescription_img prescriptionImg,
+            p.suggest suggest,
+            p.status,
+            p.log_id logId,
+            p.is_del isDel,
+            p.remark remark
+        from fs_doctor_prescription_new p
+        where log_id = #{logId}
+    </select>
+    <select id="selectFsDoctorPrescribeImgById" resultType="com.fs.his.param.DoctorPrescriptionImgLogParam">
+        SELECT
+        id,
+        doctor_id doctorId,
+        url,
+        status,
+        is_del,
+        remark,
+        create_time,
+        update_time,
+        remark
+        FROM fs_doctor_prescription_img_log
+        WHERE id = #{id}
+    </select>
+    <select id="selectPrescriptionLogList" resultMap="DoctorPrescriptionImgLogResult">
+        SELECT
+        d1.id,
+        d1.doctor_id,
+        d1.url,
+        d1.status,
+        d1.is_del,
+        d1.remark,
+        d1.create_time,
+        d1.update_time,
+        d2.doctor_id,
+        d2.doctor_name,
+        d2.introduction,
+        d2.speciality,
+        d2.certificate_code,
+        d2.certificate_images,
+        d2.practise_code,
+        d2.practise_images,
+        d2.avatar,
+        d2.hospital_id,
+        d2.dept_id,
+        d2.position,
+        d2.tags,
+        d2.status AS doctor_status,
+        d2.ping_star,
+        d2.order_number,
+        d2.mobile,
+        d2.doctor_type,
+        d2.sex,
+        d2.work_status,
+        d2.is_audit,
+        d3.id AS prescription_id,
+        d3.is_parse,
+        d3.prescription_code,
+        d3.age,
+        d3.sex AS patient_sex,
+        d3.prescription_img,
+        d3.prescription_info,
+        d3.chief_complaint,
+        d3.history_of_present_illness,
+        d3.past_medical_history,
+        d3.personal_history,
+        d3.obstetric_history,
+        d3.family_history,
+        d3.suggest,
+        d3.status AS prescription_status,
+        d3.doctor_id AS prescription_doctor_id,
+        d3.log_id AS prescription_log_id,
+        d3.is_del AS prescription_is_del,
+        d3.create_time AS prescription_create_time,
+        d3.update_time AS prescription_update_time,
+        d3.remark AS prescription_remark
+        FROM fs_doctor_prescription_img_log d1
+        LEFT JOIN fs_doctor d2 ON d1.doctor_id = d2.doctor_id
+        LEFT JOIN fs_doctor_prescription_new d3 ON d1.id = d3.log_id
+        WHERE d1.is_del = 0 and d3.status > 2
+        <if test="param.doctorId != null">
+            AND d1.doctor_id = #{doctorId}
+        </if>
+        <if test="param.beginTime != null and param.beginTime != ''">
+            AND DATE(d1.create_time) &gt;= DATE(#{param.beginTime})
+        </if>
+        <if test="param.endTime != null and param.endTime != ''">
+            AND DATE(d1.create_time) &lt;= DATE(#{param.endTime})
+        </if>
+        <if test="param.doctorName != null and param.doctorName != null">
+            AND d2.doctor_name LIKE CONCAT('%', #{param.doctorName}, '%')
+        </if>
+        <if test="param.prescription != null and param.prescription.status != null and param.prescription.status != ''">
+            AND d3.status LIKE CONCAT('%', #{param.prescription.status}, '%')
+        </if>
+        <if test="param.prescription != null and param.prescription.prescriptionCode != null and param.prescription.prescriptionCode != ''">
+            AND d3.prescription_code LIKE CONCAT('%', #{param.prescription.prescriptionCode}, '%')
+        </if>
+        ORDER BY d1.id DESC
+    </select>
+
 
     <insert id="insertFsDoctor" parameterType="FsDoctor" useGeneratedKeys="true" keyProperty="doctorId">
         insert into fs_doctor
@@ -301,6 +548,59 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="gptRoleId != null">#{gptRoleId},</if>
          </trim>
     </insert>
+    <insert id="insertFsDoctorPrescription" parameterType="com.fs.his.param.DoctorPrescriptionParam" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_doctor_prescription_new
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="isParse != null">is_parse,</if>
+            <if test="prescriptionCode != null">prescription_code,</if>
+            <if test="age != null">age,</if>
+            <if test="sex != null">sex,</if>
+            <if test="prescriptionImg != null">prescription_img,</if>
+            <if test="prescriptionInfo != null">prescription_info,</if>
+            <if test="chiefComplaint != null">chief_complaint,</if>
+            <if test="historyOfPresentIllness != null">history_of_present_illness,</if>
+            <if test="pastMedicalHistory != null">past_medical_history,</if>
+            <if test="personalHistory != null">personal_history,</if>
+            <if test="obstetricHistory != null">obstetric_history,</if>
+            <if test="familyHistory != null">family_history,</if>
+            <if test="suggest != null">suggest,</if>
+            <if test="status != null">status,</if>
+            <if test="doctorId != null">doctor_id,</if>
+            <if test="logId != null">log_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="isParse != null">#{isParse},</if>
+            <if test="prescriptionCode != null">#{prescriptionCode},</if>
+            <if test="age != null">#{age},</if>
+            <if test="sex != null">#{sex},</if>
+            <if test="prescriptionImg != null">#{prescriptionImg},</if>
+            <if test="prescriptionInfo != null">#{prescriptionInfo},</if>
+            <if test="chiefComplaint != null">#{chiefComplaint},</if>
+            <if test="historyOfPresentIllness != null">#{historyOfPresentIllness},</if>
+            <if test="pastMedicalHistory != null">#{pastMedicalHistory},</if>
+            <if test="personalHistory != null">#{personalHistory},</if>
+            <if test="obstetricHistory != null">#{obstetricHistory},</if>
+            <if test="familyHistory != null">#{familyHistory},</if>
+            <if test="suggest != null">#{suggest},</if>
+            <if test="status != null">#{status},</if>
+            <if test="doctorId != null">#{doctorId},</if>
+            <if test="logId != null">#{logId},</if>
+        </trim>
+    </insert>
+    <insert id="insertFsDoctorPrescriptionImgLog" parameterType="com.fs.his.param.DoctorPrescriptionImgLogParam" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_doctor_prescription_img_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="doctorId != null">doctor_id,</if>
+            <if test="url != null">url,</if>
+            <if test="status != null">status,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="doctorId != null">#{doctorId},</if>
+            <if test="url != null">#{url},</if>
+            <if test="status != null">#{status},</if>
+        </trim>
+    </insert>
+
 
     <update id="updateFsDoctor" parameterType="FsDoctor">
         update fs_doctor
@@ -364,6 +664,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </trim>
         where doctor_id = #{doctorId}
     </update>
+    <update id="updateFsDoctorPrescriptionImgLog" parameterType="com.fs.his.param.DoctorPrescriptionImgLogParam">
+        update fs_doctor_prescription_img_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="doctorId != null">doctor_id = #{doctorId},</if>
+            <if test="url != null">url = #{url},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="isDel != null">is_del = #{isDel},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <update id="updateFsDoctorPrescription" parameterType="com.fs.his.param.DoctorPrescriptionParam">
+        update fs_doctor_prescription_new
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="isParse != null">is_parse = #{isParse},</if>
+            <if test="prescriptionCode != null">prescription_code = #{prescriptionCode},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="prescriptionImg != null">prescription_img = #{prescriptionImg},</if>
+            <if test="prescriptionInfo != null ">prescription_info = #{prescriptionInfo},</if>
+            <if test="chiefComplaint != null">chief_complaint = #{chiefComplaint},</if>
+            <if test="historyOfPresentIllness != null">history_of_present_illness = #{historyOfPresentIllness},</if>
+            <if test="pastMedicalHistory != null">past_medical_history = #{pastMedicalHistory},</if>
+            <if test="personalHistory != null">personal_history = #{personalHistory},</if>
+            <if test="obstetricHistory != null">obstetric_history = #{obstetricHistory},</if>
+            <if test="familyHistory != null">family_history = #{familyHistory},</if>
+            <if test="suggest != null">suggest = #{suggest},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="doctorId != null">doctor_id = #{doctorId},</if>
+            <if test="logId != null">log_id = #{logId},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where id = #{id}
+    </update>
+    <update id="updateFsDoctorPrescriptionByLogId">
+        update fs_doctor_prescription_new
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="isParse != null">is_parse = #{isParse},</if>
+            <if test="prescriptionCode != null">prescription_code = #{prescriptionCode},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="prescriptionImg != null">prescription_img = #{prescriptionImg},</if>
+            <if test="prescriptionInfo != null ">prescription_info = #{prescriptionInfo},</if>
+            <if test="chiefComplaint != null">chief_complaint = #{chiefComplaint},</if>
+            <if test="historyOfPresentIllness != null">history_of_present_illness = #{historyOfPresentIllness},</if>
+            <if test="pastMedicalHistory != null">past_medical_history = #{pastMedicalHistory},</if>
+            <if test="personalHistory != null">personal_history = #{personalHistory},</if>
+            <if test="obstetricHistory != null">obstetric_history = #{obstetricHistory},</if>
+            <if test="familyHistory != null">family_history = #{familyHistory},</if>
+            <if test="suggest != null">suggest = #{suggest},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="doctorId != null">doctor_id = #{doctorId},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where log_id = #{logId}
+    </update>
 
     <delete id="deleteFsDoctorByDoctorId" parameterType="Long">
         delete from fs_doctor where doctor_id = #{doctorId}

+ 52 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreAfterSalesScrmMapper.xml

@@ -69,6 +69,58 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectFsStoreAfterSalesVo"/>
         where id = #{id}
     </select>
+    <select id="selectFsStoreAfterSalesListQueryNew" resultType="com.fs.hisStore.vo.FsStoreAfterSalesQueryVO">
+        select a1.id,
+        a1.order_code,
+        a1.refund_amount,
+        a1.service_type,
+        a1.reasons,
+        a1.explains,
+        a1.explain_img,
+        a1.shipper_code,
+        a1.delivery_sn,
+        a1.delivery_name,
+        a1.status,
+        a1.sales_status,
+        a1.order_status,
+        a1.create_time,
+        a1.is_del,
+        a1.user_id,
+        a1.consignee,
+        a1.phone_number,
+        a1.address,
+        a1.company_id,
+        a1.company_user_id,
+        a1.is_package,
+        a1.package_json,
+        a1.reason_id1,
+        a1.reason_id2,
+        a1.reason_level1_text,
+        a1.reason_level2_text,
+        a1.audit_remark,
+        a1.audit_reason_name,
+        a2.live_id as liveId
+        from fs_store_after_sales_scrm a1
+        left join fs_store_order_scrm a2
+        on a1.order_code = a2.order_code
+        where 1=1
+        <if test="maps.status != null and maps.status == 1">
+            and a1.sales_status = 0
+        </if>
+        <if test="maps.status != null and maps.status == 2">
+            and a1.sales_status = 3
+        </if>
+        <if test="maps.liveId == null">
+            and a2.live_id is null
+        </if>
+        <if test="maps.liveId == 0">
+            and a2.live_id is not null
+        </if>
+        <if test="maps.userId != null">
+            and a1.user_id = #{maps.userId}
+        </if>
+        order by a1.create_time desc
+    </select>
 
     <insert id="insertFsStoreAfterSales" parameterType="FsStoreAfterSalesScrm" useGeneratedKeys="true" keyProperty="id">
         insert into fs_store_after_sales_scrm

+ 6 - 3
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -94,10 +94,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="virtualPhone"    column="virtual_phone"    />
         <result property="groupBuyId"    column="group_buy_id"    />
         <result property="shoppingPointsClaimed"    column="shopping_points_claimed"    />
+        <result property="liveId"    column="live_id"    />
     </resultMap>
 
     <sql id="selectFsStoreOrderVo">
-        select id, order_code,outer_oi_id,service_fee, extend_order_id,pay_order_id,bank_order_id, user_id,order_visit, real_name, user_phone, user_address, cart_id, freight_price, total_num, total_price, total_postage, pay_price, pay_postage,pay_delivery,pay_money, deduction_price, coupon_id, coupon_price, paid, pay_time, pay_type, create_time, update_time, status, refund_status, refund_reason_wap_img, refund_reason_wap_explain, refund_reason_time, refund_reason_wap, refund_reason, refund_price, delivery_sn, delivery_name, delivery_type, delivery_id, gain_integral, use_integral, pay_integral, back_integral, mark, is_del, remark, cost, verify_code, store_id, shipping_type, is_channel, is_remind, is_sys_del,is_prescribe,prescribe_id ,company_id,company_user_id,is_package,package_json,item_json,order_type,package_id,finish_time,delivery_status,delivery_pay_status,delivery_time,delivery_pay_time,delivery_pay_money,tui_money,tui_money_status,delivery_import_time,tui_user_id,tui_user_money_status,order_create_type,store_house_code,dept_id,is_edit_money,customer_id,is_pay_remain,delivery_send_time,certificates,schedule_id,backend_edit_product_type,video_id,course_id,project_id,period_id,virtual_phone,group_buy_id from fs_store_order_scrm
+        select id, order_code,outer_oi_id,service_fee, extend_order_id,pay_order_id,bank_order_id, user_id,order_visit, real_name, user_phone, user_address, cart_id, freight_price, total_num, total_price, total_postage, pay_price, pay_postage,pay_delivery,pay_money, deduction_price, coupon_id, coupon_price, paid, pay_time, pay_type, create_time, update_time, status, refund_status, refund_reason_wap_img, refund_reason_wap_explain, refund_reason_time, refund_reason_wap, refund_reason, refund_price, delivery_sn, delivery_name, delivery_type, delivery_id, gain_integral, use_integral, pay_integral, back_integral, mark, is_del, remark, cost, verify_code, store_id, shipping_type, is_channel, is_remind, is_sys_del,is_prescribe,prescribe_id ,company_id,company_user_id,is_package,package_json,item_json,order_type,package_id,finish_time,delivery_status,delivery_pay_status,delivery_time,delivery_pay_time,delivery_pay_money,tui_money,tui_money_status,delivery_import_time,tui_user_id,tui_user_money_status,order_create_type,store_house_code,dept_id,is_edit_money,customer_id,is_pay_remain,delivery_send_time,certificates,schedule_id,backend_edit_product_type,video_id,course_id,project_id,period_id,virtual_phone,group_buy_id,live_id from fs_store_order_scrm
     </sql>
 
     <select id="selectFsStoreOrderList" parameterType="FsStoreOrderScrm" resultMap="FsStoreOrderResult">
@@ -290,6 +291,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="projectId != null" >project_id,</if>
             <if test="periodId != null" >period_id,</if>
             <if test="groupBuyId != null" >group_buy_id,</if>
+            <if test="liveId != null" >live_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="orderCode != null and orderCode != ''">#{orderCode},</if>
@@ -382,6 +384,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="projectId != null" >#{projectId},</if>
             <if test="periodId != null" >#{periodId},</if>
             <if test="groupBuyId != null" >#{groupBuyId},</if>
+            <if test="liveId != null" >#{liveId},</if>
          </trim>
     </insert>
 
@@ -965,10 +968,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
         <!-- 时间条件 -->
         <if test="param.startDate != null">
-            AND DATE_FORMAT(fso.pay_time, '%Y-%m') >= DATE_FORMAT(#{param.startDate}, '%Y-%m')
+            AND DATE_FORMAT(fso.pay_time, '%Y-%m-%d') >= DATE_FORMAT(#{param.startDate}, '%Y-%m-%d')
         </if>
         <if test="param.endDate != null">
-            AND DATE_FORMAT(fso.pay_time, '%Y-%m') &lt;= DATE_FORMAT(#{param.endDate}, '%Y-%m')
+            AND DATE_FORMAT(fso.pay_time, '%Y-%m-%d') &lt;= DATE_FORMAT(#{param.endDate}, '%Y-%m-%d')
         </if>
 
         <!-- 商品和标签筛选(使用EXISTS避免重复计算) -->

+ 1 - 1
fs-service/src/main/resources/mapper/live/LiveWatchUserMapper.xml

@@ -212,7 +212,7 @@
     </select>
 
     <select id="selectLiveWatchAndRegisterUser" resultType="com.fs.live.domain.LiveWatchUser">
-        select a.*,fu.nickname as nick_name from (
+        select a.*,fu.nick_name as nickname from (
             select lws.* from live_watch_user lws 
             where live_id=#{params.liveId} and online = 0
             <if test="params.liveFlag != null "> and live_flag = #{params.liveFlag}</if>

+ 8 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppBaseController.java

@@ -28,6 +28,14 @@ public class AppBaseController {
 	@Autowired
     public RedisCache redisCache;
 
+	public String getDoctorId()
+	{
+		String headValue =  ServletUtils.getRequest().getHeader("APPToken");
+		Claims claims=jwtUtils.getClaimByToken(headValue);
+		String doctorId = claims.getSubject().toString();
+		return doctorId;
+	}
+
 	public String getUserId()
 	{
 		String headValue =  ServletUtils.getRequest().getHeader("APPToken");

+ 210 - 8
fs-user-app/src/main/java/com/fs/app/controller/DoctorController.java

@@ -2,16 +2,17 @@ package com.fs.app.controller;
 
 
 import com.fs.app.annotation.Login;
+ import com.fs.app.param.DoctorEditParam;
+import com.fs.app.param.DoctorEditPwdParam;
+import com.fs.app.param.DoctorLoginParam;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.sign.Md5Utils;
 import com.fs.his.domain.FsDepartment;
 import com.fs.his.domain.FsDoctor;
 import com.fs.his.domain.FsHospital;
 import com.fs.his.domain.FsUserDoctor;
-import com.fs.his.param.FsDoctorPingListUParam;
-import com.fs.his.param.FsDoctorListUParam;
-import com.fs.his.param.FsUserDoctorFollowUParam;
-import com.fs.his.param.FsUserDoctorListUParam;
+import com.fs.his.param.*;
 import com.fs.his.service.*;
 import com.fs.his.vo.FsDoctorListUVO;
 import com.fs.his.vo.FsDoctorPingUVO;
@@ -22,16 +23,17 @@ import io.jsonwebtoken.Claims;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.Synchronized;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 
 @Api("医生接口")
@@ -54,6 +56,206 @@ public class DoctorController extends  AppBaseController {
 
 
 
+    @ApiOperation("医生登陆")
+    @PostMapping("/login")
+    public R login(@Validated  @RequestBody DoctorLoginParam param) {
+        FsDoctor doctor=doctorService.selectFsDoctorByAccount(param.getAccount());
+        if(doctor==null||!doctor.getStatus().equals(1)){
+            return R.error("帐号不存在或已停用");
+        }
+        else{
+            if(StringUtils.isNotEmpty(param.getJpushId())){
+                FsDoctor doctorMap=new FsDoctor();
+                doctorMap.setDoctorId(doctor.getDoctorId());
+                doctorMap.setJpushId(param.getJpushId());
+                doctorService.updateFsDoctor(doctorMap);
+            }
+
+            if(!doctor.getDoctorType().equals(param.getType())){
+                return R.error("非法操作");
+            }
+            if(!Md5Utils.hash(param.getPassword()).equals(doctor.getPassword())){
+                return R.error("密码不正确");
+            }
+            String token = jwtUtils.generateToken(doctor.getDoctorId());
+            redisCache.setCacheObject("doctorToken:"+doctor.getDoctorId(),token,604800, TimeUnit.SECONDS);
+            Map<String,Object> map=new HashMap<>();
+            map.put("token",token);
+            map.put("doctor",doctor);
+            if(doctor.getDeptId()!=null){
+                FsDepartment department=departmentService.selectFsDepartmentByDeptId(doctor.getDeptId());
+                if(department!=null){
+                    map.put("deptName",department.getDeptName());
+                }
+                else{
+                    map.put("deptName","");
+                }
+            }
+            return R.ok(map);
+        }
+    }
+
+    @Login
+    @ApiOperation("获取医生信息")
+    @GetMapping("/getDoctorInfo")
+    public R getDoctorInfo(HttpServletRequest request){
+        try {
+            FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
+            FsHospital hospital=hospitalService.selectFsHospitalByHospitalId(doctor.getHospitalId());
+            FsDepartment department=departmentService.selectFsDepartmentByDeptId(doctor.getDeptId());
+
+            Map<String,Object> map=new HashMap<>();
+            map.put("doctor",doctor);
+            map.put("hospital",hospital);
+            map.put("department",department);
+            return R.ok(map);
+        } catch (Exception e){
+            return R.error("操作异常");
+        }
+    }
+
+    @Login
+    @ApiOperation("检测是否登录")
+    @GetMapping("/checkLogin")
+    public R checkLogin(HttpServletRequest request){
+        return R.ok("认证成功");
+    }
+
+
+    @Login
+    @ApiOperation("修改信息")
+    @PostMapping("/editDoctor")
+    public R editDoctor(@Validated @RequestBody DoctorEditParam param, HttpServletRequest request){
+        FsDoctor doctor=new FsDoctor();
+        doctor.setDoctorId(Long.parseLong(getDoctorId()));
+        doctor.setWorkStatus(param.getWorkStatus());
+        doctor.setPriceJson(param.getPriceJson());
+        doctor.setMobile(param.getMobile());
+        doctor.setSignUrl(param.getSignUrl());
+        doctorService.updateFsDoctor(doctor);
+        return R.ok("修改成功");
+    }
+
+    @Login
+    @ApiOperation("修改密码")
+    @PostMapping("/editPwd")
+    public R editPwd(@Validated @RequestBody DoctorEditPwdParam param, HttpServletRequest request){
+        FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
+        if(!Md5Utils.hash(param.getOldPassword()).equals(doctor.getPassword())){
+            return R.error("旧密码不正确");
+        }
+        FsDoctor map=new FsDoctor();
+        map.setDoctorId(Long.parseLong(getDoctorId()));
+        map.setPassword(Md5Utils.hash(param.getNewPassword()));
+        doctorService.updateFsDoctor(map);
+        return R.ok("修改成功");
+    }
+
+    @Login
+    @ApiOperation("批量上传处方图片")
+    @PostMapping("/uploadPrescriptionImgList")
+    public R uploadPrescriptionImgList(@RequestParam("file") MultipartFile file, HttpServletRequest request){
+        String doctorId = getDoctorId();
+        //String doctorId = "123";
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+
+        return doctorService.uploadPrescriptionImg(file,doctorId);
+    }
+
+    @Login
+    @ApiOperation("重新上传处方图片")
+    @PostMapping("/uploadPrescriptionImg")
+    public R uploadPrescriptionImg(@Validated @RequestParam("file") MultipartFile file,@RequestParam("logId")Long logId){
+        String doctorId = getDoctorId();
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+
+        return doctorService.uploadPrescriptionImg(file,logId);
+    }
+
+
+    @Login
+    @ApiOperation("批量处理解析处方图片")
+    @PostMapping("/cleanPrescriptionImg")
+    public R cleanPrescriptionImg(HttpServletRequest request){
+        String doctorId = getDoctorId();
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+
+        return doctorService.cleanPrescriptionImg(doctorId);
+    }
+
+    @ApiOperation("单次处理解析处方图片")
+    @PostMapping("/cleanPrescriptionImgOne")
+    public R cleanPrescriptionImgOne(@RequestParam("imgLogId")Long imgLogId){
+        return doctorService.cleanPrescriptionImgOne(imgLogId);
+    }
+
+    @ApiOperation("重新处理解析处方图片")
+    @PostMapping("/cleanPrescriptionImgSecond")
+    public R cleanPrescriptionImgSecond(@RequestParam("prescriptionId")Long prescriptionId){
+        return doctorService.cleanPrescriptionImgSecond(prescriptionId);
+    }
+
+    @Login
+    @ApiOperation("查看处方图片列表")
+    @PostMapping("/selectPrescriptionImgList")
+    public R selectPrescriptionImgList(@RequestBody DoctorPrescriptionImgLogParam param){
+        String doctorId = getDoctorId();
+        //String doctorId = "123";
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+
+        return doctorService.selectPrescriptionImgList(doctorId,param);
+    }
+
+    @ApiOperation("查看处方详情")
+    @PostMapping("/selectPrescriptionImgInfo")
+    public R selectPrescriptionImgInfo(@RequestParam("imgLogId")Long imgLogId){
+        return doctorService.selectPrescriptionImgInfo(imgLogId);
+    }
+
+
+    @Login
+    @ApiOperation("删除处方记录")
+    @PostMapping("/deletePrescription")
+    public R deletePrescription(@RequestParam("imgLogId") Long imgLogId){
+        String doctorId = getDoctorId();
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+        return doctorService.deletePrescription(imgLogId, Long.parseLong(doctorId));
+    }
+
+    @Login
+    @ApiOperation("保存/暂存处方信息")
+    @PostMapping("/savePrescriptionInfo")
+    public R savePrescriptionInfo(@RequestBody DoctorPrescriptionParam param){
+        String doctorId = getDoctorId();
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+        return doctorService.savePrescriptionInfo(param);
+    }
+
+    @Login
+    @ApiOperation("提交处方信息")
+    @PostMapping("/commitPrescriptionInfo")
+    public R commitPrescriptionInfo(@RequestBody DoctorPrescriptionParam param){
+        String doctorId = getDoctorId();
+        if(StringUtils.isEmpty(doctorId)){
+            return R.error("请先登录");
+        }
+        return doctorService.commitPrescriptionInfo(param);
+    }
+
+
+
     @GetMapping("/getDoctorList")
     @Cacheable(value = "getDoctorList", key = "#param")
     public R getDoctorList(FsDoctorListUParam param)

+ 2 - 0
fs-user-app/src/main/java/com/fs/app/controller/UserController.java

@@ -298,6 +298,8 @@ public class UserController extends  AppBaseController {
         doctor.setStatus(0);
         doctor.setBalance(new BigDecimal(0));
         doctor.setPriceJson("[{\"price\":1.00,\"type\":1},{\"price\":1.00,\"type\":2}]");
+        doctor.setPractiseCode(param.getPractiseCode());
+        doctor.setPractiseImages(param.getPractiseImages());
         if(doctorService.insertFsDoctor(doctor)>0){
             return R.ok("注册成功");
         }

+ 21 - 12
fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java

@@ -297,8 +297,11 @@ public class LiveOrderController extends AppBaseController
     @Log(title = "新增中奖订单", businessType = BusinessType.INSERT)
     @PostMapping("/createReward")
     @RepeatSubmit
-    public R createReward(@RequestBody LiveOrder liveOrder)
-    {
+    public R createReward(@RequestBody LiveOrder liveOrder,
+                          @RequestHeader(value = "AppId", required = false) String AppId){
+        if (AppId != null && !AppId.isEmpty()) {
+            liveOrder.setAppId(AppId);
+        }
         // 校验appId
         if (StringUtils.isEmpty(liveOrder.getAppId())) {
             return R.error("appId不能为空");
@@ -316,8 +319,11 @@ public class LiveOrderController extends AppBaseController
     @Log(title = "提交中奖订单", businessType = BusinessType.INSERT)
     @PostMapping("/payConfirmReward")
     @RepeatSubmit
-    public R payConfirmReward(@RequestBody LiveOrder liveOrder)
-    {
+    public R payConfirmReward(@RequestBody LiveOrder liveOrder,
+                              @RequestHeader(value = "AppId", required = false) String AppId){
+        if (AppId != null && !AppId.isEmpty()) {
+            liveOrder.setAppId(AppId);
+        }
         // 校验appId
         if (StringUtils.isEmpty(liveOrder.getAppId())) {
             return R.error("appId不能为空");
@@ -332,7 +338,11 @@ public class LiveOrderController extends AppBaseController
     @ApiOperation("创建订单")
     @PostMapping("/create")
     @RateLimiter(time = 10, count = 10000, msg = "当前下单的人比较多,请稍后再试")
-    public R create(@Validated @RequestBody LiveOrder param, HttpServletRequest request){
+    public R create(@Validated @RequestBody LiveOrder param,
+                    @RequestHeader(value = "AppId", required = false) String AppId){
+        if (AppId != null && !AppId.isEmpty()) {
+            param.setAppId(AppId);
+        }
         // 校验appId
         if (StringUtils.isEmpty(param.getAppId())) {
             return R.error("appId不能为空");
@@ -340,11 +350,7 @@ public class LiveOrderController extends AppBaseController
         String userId= getUserId();
         log.info("开始创建订单,登录用户id:{}", userId);
         param.setUserId(userId);
-        if(CloudHostUtils.hasCloudHostName("济世百康")){
-            return  orderService.createLiveOrder(param);
-        }else{
-            return orderService.createStoreOrder(param);
-        }
+         return orderService.createStoreOrder(param);
     }
     @Login
     @ApiOperation("创建订单测试")
@@ -377,8 +383,11 @@ public class LiveOrderController extends AppBaseController
     @ApiOperation("支付")
     @PostMapping("/pay")
     @Transactional
-    public R pay(HttpServletRequest request, @Validated @RequestBody LiveOrderPayParam param)
-    {
+    public R pay(HttpServletRequest request, @Validated @RequestBody LiveOrderPayParam param,
+                 @RequestHeader(value = "AppId", required = false) String AppId){
+        if (AppId != null && !AppId.isEmpty()) {
+            param.setAppId(AppId);
+        }
         // 校验appId
         if (StringUtils.isEmpty(param.getAppId())) {
             return R.error("appId不能为空");

+ 2 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/PayScrmController.java

@@ -82,10 +82,10 @@ public class PayScrmController {
             switch (order[0]) {
                 case "store":
                 case "live":
-                    if ("live".equals(order[0]) && CloudHostUtils.hasCloudHostName("济世百康")) {
+                    /*if ("live".equals(order[0]) && CloudHostUtils.hasCloudHostName("济世百康")) {
                         liveOrderService.payConfirm(1,null,order[1], o.getHf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                         break;
-                    }
+                    }*/
                     try {
                         HuiFuUtils.updateDivItem(order[1]);
                     } catch (Exception e) {

+ 11 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java

@@ -110,6 +110,17 @@ public class StoreOrderScrmController extends AppBaseController {
         return R.ok().put("data",listPageInfo);
     }
 
+    @Login
+    @ApiOperation("获取客户订单列表")
+    @GetMapping("/getCustomerStoreOrderList")
+    public R getCustomerStoreOrderList(FsMyStoreOrderQueryParam param, HttpServletRequest request){
+        PageHelper.startPage(param.getPage(), param.getPageSize());
+        param.setUserId(Long.parseLong(getUserId()));
+        List<FsMyStoreOrderListQueryVO> list=orderService.selectFsMyStoreOrderListVONew(param);
+        PageInfo<FsMyStoreOrderListQueryVO> listPageInfo=new PageInfo<>(list);
+        return R.ok().put("data",listPageInfo);
+    }
+
     @Login
     @ApiOperation("获取销售公司订单列表")
     @GetMapping("/getCompanyStoreOrderList")

+ 16 - 0
fs-user-app/src/main/java/com/fs/app/param/DoctorEditParam.java

@@ -0,0 +1,16 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class DoctorEditParam implements Serializable {
+    @NotNull(message = "工作状态不能为空")
+    private Integer workStatus;
+    @NotNull(message = "价格配置不能为空")
+    private String priceJson;
+    private String mobile;
+    private String signUrl;
+}

+ 14 - 0
fs-user-app/src/main/java/com/fs/app/param/DoctorEditPwdParam.java

@@ -0,0 +1,14 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class DoctorEditPwdParam implements Serializable {
+    @NotNull(message = "旧密码不能为空")
+    private String oldPassword;
+    @NotNull(message = "新密码不能为空")
+    private String newPassword;
+}

+ 26 - 0
fs-user-app/src/main/java/com/fs/app/param/DoctorLoginParam.java

@@ -0,0 +1,26 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class DoctorLoginParam implements Serializable {
+    @NotBlank(message = "帐号不能为空")
+    private String account;
+    @NotBlank(message = "密码不能为空")
+    private String password;
+    @NotNull(message = "类型不能为空")
+    private Integer type;//1医师 2药师
+    /**
+     * 验证码
+     */
+    private String code;
+    /**
+     * 唯一标识
+     */
+    private String uuid = "";
+    private String jpushId;
+}

+ 2 - 0
fs-user-app/src/main/java/com/fs/app/param/FsDoctorRegisterParam.java

@@ -96,4 +96,6 @@ public class FsDoctorRegisterParam implements Serializable {
 //    @Pattern(regexp="^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,}$",message="密码长度最少8位,由数字、大写字母、小写字母、特殊字符中的至少三种组成")
     private String password;
 
+    private String practiseCode;
+    private String practiseImages;
 }

+ 32 - 5
fs-user-app/src/main/java/com/fs/framework/aspectj/LogAspect.java

@@ -1,6 +1,7 @@
 package com.fs.framework.aspectj;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.app.interceptor.AuthorizationInterceptor;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.domain.model.LoginUser;
 import com.fs.common.enums.BusinessStatus;
@@ -85,8 +86,30 @@ public class LogAspect
                 return;
             }
 
-            // 获取当前的用户
-            LoginUser loginUser = SecurityUtils.getLoginUser();
+            // 获取当前的用户(优先从 Spring Security 获取,如果没有则从 request 属性获取)
+            LoginUser loginUser = null;
+            try {
+                loginUser = SecurityUtils.getLoginUser();
+            } catch (Exception ex) {
+                log.debug("从 SecurityContext 获取用户失败,尝试从 request 获取");
+            }
+
+            // 如果 Spring Security 中没有用户信息,尝试从 request 属性中获取(fs-user-app 模块的认证方式)
+            Long userId = null;
+            String username = null;
+
+            if (loginUser != null) {
+                userId = loginUser.getUserId();
+                username = loginUser.getUsername();
+            } else {
+                // 从 AuthorizationInterceptor 设置的 request 属性中获取 userId
+                HttpServletRequest request = ServletUtils.getRequest();
+                Object userIdObj = request.getAttribute(AuthorizationInterceptor.USER_KEY);
+                if (userIdObj instanceof Long) {
+                    userId = (Long) userIdObj;
+                    username = "user_" + userId; // 使用 userId 作为用户名
+                }
+            }
 
             // *========数据库日志=========*//
             SysOperLog operLog = new SysOperLog();
@@ -98,9 +121,13 @@ public class LogAspect
             operLog.setJsonResult(JSON.toJSONString(jsonResult));
 
             operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
-            if (loginUser != null)
-            {
-                operLog.setOperName(loginUser.getUsername());
+            // 设置操作用户
+            if (username != null) {
+                operLog.setOperName(username);
+            } else if (userId != null) {
+                operLog.setOperName("user_" + userId);
+            } else {
+                operLog.setOperName("anonymous");
             }
 
             if (e != null)