Переглянути джерело

add 增加脚本功能
del 拒绝delete请求访问

A17404李放 3 роки тому
батько
коміт
ab46fbded2

+ 2 - 2
coffee-common/src/main/java/com/coffee/common/config/CorsConfig.java

@@ -23,8 +23,8 @@ public class CorsConfig implements WebMvcConfigurer {
                 .allowedOriginPatterns("*")
                 .allowedOrigins("*")
                 //放行哪些请求方式
-//                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
-                .allowedMethods("*") //或者放行全部
+                .allowedMethods(new String[]{"GET", "POST", "PUT"})
+//                .allowedMethods("*") //或者放行全部
                 //放行哪些原始请求头部信息
                 .allowedHeaders("*")
                 //暴露哪些原始请求头部信息

+ 48 - 2
coffee-system/src/main/java/com/coffee/bus/controller/BusHospitalController.java

@@ -3,17 +3,24 @@ package com.coffee.bus.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaMode;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.coffee.bus.bean.Script;
 import com.coffee.bus.controller.vo.ExecScript;
 import com.coffee.bus.entity.BusHospitalEntity;
+import com.coffee.bus.hospital.HospitalManagerRegister;
+import com.coffee.bus.hospital.his.strategy.HisStrategyEnum;
 import com.coffee.bus.hospital.script.ScriptManager;
 import com.coffee.bus.service.LocalBusHospitalService;
 import com.coffee.common.crud.BaseService;
 import com.coffee.common.crud.controller.BaseCrudController;
+import com.coffee.common.exception.CustomException;
 import com.coffee.common.result.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
@@ -30,7 +37,7 @@ import org.springframework.web.bind.annotation.*;
 @Api(tags = "医院管理",description = "统一权限前缀(bus:hospital),例如新增bus:hospital:add")
 public class BusHospitalController extends BaseCrudController<BusHospitalEntity, String> {
     private final LocalBusHospitalService hospitalService;
-
+    private final HospitalManagerRegister hospitalManagerRegister;
     private final ScriptManager scriptManager;
 
     /**
@@ -61,11 +68,50 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
     }
 
     @PostMapping("/debug")
-    @ApiOperation(value = "执行解析脚本")
+    @SaCheckPermission("bus:hospital:script")
+    @ApiOperation(value = "执行解析脚本",notes = "医院必选,根据入参执行解析脚本,权限【bus:hospital:script】")
     public R debug(@RequestBody ExecScript execScript){
         return R.success( scriptManager.debug(execScript.getContent(),execScript.getInput()));
     }
 
+    @PostMapping("/draft/script")
+    @SaCheckPermission("bus:hospital:script")
+    @ApiOperation(value = "保存脚本草稿脚本",notes = "医院必选,保存脚本草稿脚本,权限【bus:hospital:script】")
+    public R draftScript(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @RequestBody Script script){
+        scriptManager.check(script.getContent(),script.getType());
+        hospitalService.update(new UpdateWrapper<BusHospitalEntity>().lambda().eq(BusHospitalEntity::getId,tenantId)
+                .set(BusHospitalEntity::getScript,script));
+        return R.success(true);
+    }
+
+    @PostMapping("/publish/script")
+    @SaCheckPermission("bus:hospital:script")
+    @ApiOperation(value = "发布脚本",notes = "医院必选,发布脚本,发布后即用该脚本解析his数据,权限【bus:hospital:script】")
+    public R publishScript(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId){
+        BusHospitalEntity hospital = hospitalService.getById(tenantId);
+        if (ObjectUtil.isNull(hospital.getScript())||StrUtil.isEmpty(hospital.getScript().getContent())) {
+            throw new CustomException("草稿脚本内容为空,发布失败");
+        }
+        hospitalService.update(new UpdateWrapper<BusHospitalEntity>().lambda().eq(BusHospitalEntity::getId,tenantId)
+                .set(BusHospitalEntity::getScript,hospital.getDraftScript()));
+        hospitalManagerRegister.refresh(tenantId,false,false,true);
+        return R.success(true);
+    }
+
+    @PostMapping("/strategy/{type}")
+    @SaCheckPermission("bus:hospital:strategy")
+    @ApiOperation(value = "His对接策略编辑",notes = "His对接策略编辑,权限【bus:hospital:strategy】")
+    public R editStrategy(@PathVariable("type")@ApiParam("接收his数据的策略, 0、无his 1(默认)、获取病人全部信息 2、获取病人部分信息 3、获取病人最新信息") Integer type,@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId){
+        HisStrategyEnum strategy = HisStrategyEnum.valueOf(type);
+        if(strategy==null){
+            throw new CustomException("所选策略不存在");
+        }
+        hospitalService.update(new UpdateWrapper<BusHospitalEntity>()
+                .lambda()
+                .eq(BusHospitalEntity::getId,tenantId)
+                .set(BusHospitalEntity::getStrategy,strategy));
+        return R.success(true);
+    }
 
 
     @PostMapping("/validate")

+ 5 - 1
coffee-system/src/main/java/com/coffee/bus/controller/vo/ExecScript.java

@@ -4,6 +4,9 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
 /**
  * @author lifang
  * @version 1.0.0
@@ -15,9 +18,10 @@ import lombok.Data;
 @ApiModel("脚本执行")
 public class ExecScript {
     @ApiModelProperty("脚本内容")
+    @NotBlank(message = "脚本内容不能为空")
     private String content;
     @ApiModelProperty("输入参数")
     private String input;
-
+    @ApiModelProperty("脚本类型")
     private String type;
 }

+ 8 - 35
coffee-system/src/main/java/com/coffee/bus/entity/BusHospitalEntity.java

@@ -72,9 +72,14 @@ public class BusHospitalEntity implements RecordModifierEntity, RecordCreationEn
     @TableField(typeHandler = FastjsonTypeHandler.class )
     private GeoPoint coordinate;
 
-    @TableField(typeHandler = FastjsonTypeHandler.class)
+    @ApiModelProperty("发布的脚本内容")
+    @TableField(typeHandler = FastjsonTypeHandler.class,updateStrategy = FieldStrategy.NEVER)
     private Script script;
 
+    @ApiModelProperty("草稿(编辑中的脚本内容)")
+    @TableField(typeHandler = FastjsonTypeHandler.class,updateStrategy = FieldStrategy.NEVER)
+    private Script draftScript;
+
     @ApiModelProperty("医院唯一编码,自动生成")
     @JsonIgnoreProperties(allowGetters = true)
     private String code;
@@ -85,43 +90,11 @@ public class BusHospitalEntity implements RecordModifierEntity, RecordCreationEn
     @ApiModelProperty("设备数量")
     private Integer deviceCount;
 
-    @ApiModelProperty("气泡报警数量")
-    private Integer bubbleCount;
-
-    @ApiModelProperty("堵塞报警数量")
-    private Integer jamCount;
-
-    @ApiModelProperty("极限报警数量")
-    private Integer limitCount;
-
-    @ApiModelProperty("未装药盒报警数量")
-    private Integer noBoxCount;
-
-    @ApiModelProperty("电机失控报警数量")
-    private Integer outOfControlCount;
-
-    @ApiModelProperty("镇痛不足提醒数量")
-    private Integer warnAnalgesicPoorCount;
-
-    @ApiModelProperty(" 不在服务区数量")
-    private Integer noSignalCount;
-
-    @ApiModelProperty(" 机械报警数量")
-    private Integer machineCount;
-
-    @ApiModelProperty("电量耗尽报警数量")
-    private Integer lowBatteryCount;
-
-    @ApiModelProperty("低输注报警数量")
-    private Integer lowestCount;
-
-    @ApiModelProperty("返厂维护报警数量")
-    private Integer maintainCount;
-
     @TableField(fill = FieldFill.INSERT)
     private String createBy;
 
-    @ApiModelProperty("接受his数据的策略, 1(默认)、获取病人全部信息 2、获取病人部分信息 3、获取病人最新信息")
+    @ApiModelProperty("接收his数据的策略, 1(默认)、获取病人全部信息 2、获取病人部分信息 3、获取病人最新信息")
+    @TableField(updateStrategy = FieldStrategy.NEVER)
     private HisStrategyEnum strategy;
 
     @TableField(fill = FieldFill.INSERT_UPDATE)

+ 2 - 2
coffee-system/src/main/java/com/coffee/bus/hospital/his/HisRequest.java

@@ -8,7 +8,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.springframework.web.context.request.async.DeferredResult;
-
+import java.util.*;
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.util.Date;
@@ -77,5 +77,5 @@ public class HisRequest implements Serializable {
      */
     @JsonIgnore
     @NotNull
-    private DeferredResult<R<BusClinicEntity>> result;
+    private List<DeferredResult<R<BusClinicEntity>>> result;
 }

+ 23 - 13
coffee-system/src/main/java/com/coffee/bus/hospital/his/HisScriptSession.java

@@ -33,6 +33,7 @@ import org.tio.core.Tio;
 import org.tio.core.utils.TioUtils;
 import org.tio.websocket.common.WsResponse;
 
+import javax.validation.constraints.NotNull;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
@@ -110,7 +111,7 @@ public class HisScriptSession {
                 .sync(true)
                 .timeout(timeout)
                 .timeUnit(unit)
-                .result(result)
+                .result(Arrays.asList(result))
                 .timestamp(new Date())
                 .build();
         sendRequest(channelContext,request);
@@ -147,7 +148,7 @@ public class HisScriptSession {
                 .sync(true)
                 .timeout(timeout)
                 .timeUnit(unit)
-                .result(result)
+                .result(Arrays.asList(result))
                 .timestamp(new Date())
                 .build();
         result.onTimeout(()->{
@@ -239,6 +240,7 @@ public class HisScriptSession {
      * @return void
      */
     private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+
     private void sendRequest(ChannelContext channelContext,HisRequest request){
         hisRequestMap.put(request.getMessageId(),request);
         Tio.send(channelContext, WsResponse.fromText(JSONUtil.toJsonStr(request),"utf-8"));
@@ -284,22 +286,30 @@ public class HisScriptSession {
                 Date requestTimestamp = hisRequest.getTimestamp();
                 long timeout = hisRequest.getTimeout();
                 TimeUnit timeUnit = hisRequest.getTimeUnit();
-                DeferredResult<R<BusClinicEntity>> result = hisRequest.getResult();
-                if (requestTimestamp.getTime()+timeUnit.toMillis(timeout)>responseTimestamp.getTime()) {
-                    log.warn("请求[{}]已超时,请求时间[{}],响应时间[{}],是否为同步请求[{}]",messageId,requestTimestamp,responseTimestamp,sync);
-                    if(sync){
-                        result.setErrorResult("响应超时");
-                        return;
-                    }
+                List<DeferredResult<R<BusClinicEntity>>> results = hisRequest.getResult();
+                if(CollectionUtil.isNotEmpty(results)){
+                    results.parallelStream().forEach(result->{
+                        if (requestTimestamp.getTime()+timeUnit.toMillis(timeout)>responseTimestamp.getTime()) {
+                            log.warn("请求[{}]已超时,请求时间[{}],响应时间[{}],是否为同步请求[{}]",messageId,requestTimestamp,responseTimestamp,sync);
+                            if(sync){
+                                result.setErrorResult("响应超时");
+                                return;
+                            }
+                        }
+                        //正常响应
+                        BusClinicEntity clinic = handle(Value.simple(hisResponse.getContext()).asString(), hisResponse.getPatientCode());
+                        result.setResult(R.success(clinic));
+                    });
                 }
-                //正常响应
-                BusClinicEntity clinic = handle(Value.simple(hisResponse.getContext()).asString(), hisResponse.getPatientCode());
-                result.setResult(R.success(clinic));
+
             }
         }else {
             if (hisRequest != null) {
                 log.warn("医院[{}]拉取信息失败,失败原因[{}]",hospitalId,hisResponse.getErrorMsg());
-                hisRequest.getResult().setResult(R.fail("更新失败,失败原因["+ hisResponse.getErrorMsg()+"]"));
+                 List<DeferredResult<R<BusClinicEntity>>> results = hisRequest.getResult();
+                if(CollectionUtil.isNotEmpty(results)){
+                    results.parallelStream().forEach(result-> result.setResult(R.fail("更新失败,失败原因["+ hisResponse.getErrorMsg()+"]")));
+                }
             }
         }
     }

+ 13 - 0
coffee-system/src/main/java/com/coffee/bus/hospital/his/strategy/HisStrategyEnum.java

@@ -23,4 +23,17 @@ public enum  HisStrategyEnum  implements IEnum<Integer> {
     private Integer value;
     private String text;
 
+    public static HisStrategyEnum valueOf(Integer value){
+        switch (value){
+            case 0:
+                return NONE;
+            case 1:
+                return ALL;
+            case 2:
+                return PART;
+            case 3:
+                return NEW;
+            default:return null;
+        }
+    }
 }

+ 12 - 4
coffee-system/src/main/java/com/coffee/bus/hospital/script/ExecuteResult.java

@@ -2,20 +2,28 @@ package com.coffee.bus.hospital.script;
 
 import cn.hutool.json.JSON;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.script.ScriptException;
 import java.util.function.Supplier;
 @Data
+@ApiModel("脚本执行结果")
 public class ExecuteResult {
+    @ApiModelProperty("脚本是否执行成功")
     private boolean success;
-
+    @ApiModelProperty("脚本输入参数成功")
+    private String input;
+    @ApiModelProperty("脚本输出")
     private JSON result;
-
+    @ApiModelProperty("错误消息")
     private String message;
-
+    @ApiModelProperty("错误类型")
+    @JsonIgnore
     private transient Exception exception;
-
+    @ApiModelProperty("脚本运行时间")
     private long useTime;
 
     public boolean isSuccess() {

+ 10 - 3
coffee-system/src/main/java/com/coffee/bus/hospital/script/PythonParse.java

@@ -1,10 +1,9 @@
 package com.coffee.bus.hospital.script;
 
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSON;
 import cn.hutool.json.JSONUtil;
+import com.coffee.common.exception.CustomException;
 import lombok.extern.slf4j.Slf4j;
 import org.python.core.*;
 import org.python.util.PythonInterpreter;
@@ -54,14 +53,22 @@ public class PythonParse implements ScriptParse {
         if(StrUtil.isEmpty(script)){
             return;
         }
-        interpreter.exec(Py.newStringUTF8(script));
+        try {
+            interpreter.exec(Py.newStringUTF8(script));
+        }catch (Exception e){
+            throw new CustomException("脚本错误,请检查后重试,"+e.toString());
+        }
         pyFunction = interpreter.get(functionName(), PyFunction.class);
+        if(pyFunction==null){
+            throw new CustomException("脚本不包含方法【{"+functionName()+"}】");
+        }
     }
 
     @Override
     public ExecuteResult exec(String param) {
         ExecuteResult executeResult = new ExecuteResult();
         try {
+            executeResult.setInput(param);
             long start = System.currentTimeMillis();
             PyObject result = pyFunction.__call__(Py.newStringUTF8(param));
             long end = System.currentTimeMillis();

+ 12 - 0
coffee-system/src/main/java/com/coffee/bus/hospital/script/ScriptManager.java

@@ -65,6 +65,18 @@ public class ScriptManager {
         return pythonParse.exec(input);
     }
 
+    /**
+     * 描述: 检查脚本是否编写正确
+     * @author lifang
+     * @date 2022/5/21 19:39
+     * @param script
+     * @param type
+     * @return void
+     */
+    public void check(String script,String type){
+        pythonParse.reset(script);
+    }
+
     public ScriptParse createScript(String scriptId ){
         return new PythonParse();
     }