wuyunfeng 1 سال پیش
کامیت
9ffd66cee1
100فایلهای تغییر یافته به همراه6916 افزوده شده و 0 حذف شده
  1. 4 0
      .gitignore
  2. 3 0
      build.sh
  3. 1 0
      id_file
  4. 92 0
      ncs-entrace-service/pom.xml
  5. 108 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/ConfigSwagger2.java
  6. 25 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/EntraceServiceApplication.java
  7. 49 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceRefBoardItemController.java
  8. 55 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceRefNursingMarkController.java
  9. 150 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceUniqueContentController.java
  10. 89 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardInformationController.java
  11. 160 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardItemConfigController.java
  12. 29 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardItemDisplayConfigController.java
  13. 57 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/DepartmentController.java
  14. 54 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/DoctorAdviceController.java
  15. 52 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/EmployeeController.java
  16. 86 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/ManualInputBoardItemConfigController.java
  17. 124 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/NursingMarkCategoryConfigController.java
  18. 93 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/NursingMarkOptionConfigController.java
  19. 69 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/PartTempBedController.java
  20. 64 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/PatientController.java
  21. 70 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/AdviceUniqueContentService.java
  22. 145 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/BoardItemConfigService.java
  23. 312 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/BoardItemService.java
  24. 51 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/DepartmentService.java
  25. 85 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/DoctorAdviceService.java
  26. 49 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/EmployeeService.java
  27. 68 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/ManualInputBoardItemService.java
  28. 300 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/NursingMarkCategoryService.java
  29. 267 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/PartTempBedService.java
  30. 83 0
      ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/PatientService.java
  31. 51 0
      ncs-entrace-service/src/main/resources/bootstrap.yml
  32. 42 0
      ncs-ms-feign/pom.xml
  33. 19 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/exception/CustomizedConfiguration.java
  34. 28 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/exception/FeignErrorDecoder.java
  35. 34 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceDepartmentFeignClient.java
  36. 33 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceDoctorAdviceFeignClient.java
  37. 35 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceEmployeeFeignClient.java
  38. 40 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntracePatientFeignClient.java
  39. 30 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceRefBoardItemFeignClient.java
  40. 33 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceRefNursingMarkFeignClient.java
  41. 59 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceUniqueContentFeignClient.java
  42. 63 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/BoardItemConfigFeignClient.java
  43. 36 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/DepartmentFeignClient.java
  44. 50 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/DoctorAdviceFeignClient.java
  45. 37 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/EmployeeFeignClient.java
  46. 39 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/ManualInputBoardItemConfigFeignClient.java
  47. 49 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/NursingMarkCategoryConfigFeignClient.java
  48. 45 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/NursingMarkOptionConfigFeignClient.java
  49. 49 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/PartTempBedFeignClient.java
  50. 52 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/PatientFeignClient.java
  51. 28 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/BoardItemDisplayConfigFeignClient.java
  52. 67 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/BoardItemFeignClient.java
  53. 30 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ClerkFeignClient.java
  54. 41 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/CustomerFeignClient.java
  55. 27 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/DeviceFeignClient.java
  56. 43 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/FrameFeignClient.java
  57. 45 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ManualInputBoardItemFeignClient.java
  58. 24 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/NursingMarkDisplayFeignClient.java
  59. 63 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/NursingMarkFeignClient.java
  60. 41 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ShopFeignClient.java
  61. 18 0
      ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/retryer/MyRetryer.java
  62. 125 0
      ncs-ms-framework/pom.xml
  63. 119 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/cache/Cache.java
  64. 139 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/cache/RedisCacheImpl.java
  65. 148 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/config/TaskSchedule.java
  66. 66 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/ApplicationContextHolder.java
  67. 89 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelArgumentResolver.java
  68. 45 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelModelAttributeMethodProcessor.java
  69. 71 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelRequestDataBinder.java
  70. 47 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/ThreadContextHolder.java
  71. 53 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/WdklRequestInterceptor.java
  72. 61 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/WebInterceptorConfigurer.java
  73. 46 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/CRUDBaseManager.java
  74. 34 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ColumnMeta.java
  75. 43 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DBRuntimeException.java
  76. 310 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DaoSupport.java
  77. 45 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DataMeta.java
  78. 21 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DoubleMapper.java
  79. 29 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DynamicField.java
  80. 17 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ISqlFileExecutor.java
  81. 20 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/IntegerMapper.java
  82. 24 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ObjectNotFoundException.java
  83. 138 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/Page.java
  84. 40 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/SqlMetaBuilder.java
  85. 21 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/StringMapper.java
  86. 21 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Column.java
  87. 17 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Id.java
  88. 17 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/NotDbField.java
  89. 17 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/PrimaryKeyField.java
  90. 21 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Table.java
  91. 58 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/AbstractCRUDBaseManagerImpl.java
  92. 669 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/DaoSupportImpl.java
  93. 36 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/FilterColumnMapRowMapper.java
  94. 25 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/IRowMapperColumnFilter.java
  95. 19 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/LowerCaseJdbcTemplate.java
  96. 36 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/MySqlColumnMapRowMapper.java
  97. 91 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/MySqlMetaBuilderImpl.java
  98. 51 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/OracleColumnMapRowMapper.java
  99. 42 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/SqlPaser.java
  100. 0 0
      ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/exception/ErrorMessage.java

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+/.idea/
+target
+*.iml
+*.class

+ 3 - 0
build.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+#build the jar
+mvn clean install -DskipTests

+ 1 - 0
id_file

@@ -0,0 +1 @@
+4300

+ 92 - 0
ncs-entrace-service/pom.xml

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ncs-ms</artifactId>
+        <groupId>com.wdklian</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ncs-entrace-service</artifactId>
+    <description>his对接数据统一入口服务,处理数据对接逻辑,通过调用open服务和system服务处理数据</description>
+    <version>1.0.0</version>
+    <dependencies>
+        <dependency>
+            <groupId>com.wdklian</groupId>
+            <artifactId>third-party-common</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-alibaba-commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <version>2.1.8.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>5.1.9.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.wdklian</groupId>
+            <artifactId>ncs-ms-feign</artifactId>
+            <version>1.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.7.10</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 108 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/ConfigSwagger2.java

@@ -0,0 +1,108 @@
+package com.wdklian.ncs.ms.entrace;
+
+
+import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
+import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
+import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
+import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
+import org.springframework.boot.actuate.endpoint.web.*;
+import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
+import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
+import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@Configuration
+@EnableSwagger2
+public class ConfigSwagger2 implements WebMvcConfigurer {
+    /**
+     * 创建RESTFUL API文档内容
+     * @return
+     */
+    @Bean
+    public Docket createRestApi(){
+        return new Docket(DocumentationType.SWAGGER_2)
+                //此处参数为ApiInfo对象
+                //指定构建api文档的详细信息的方法
+                .apiInfo(apiInfo())
+                .select()
+                //指定构建api接口的包路径-指定具体包路径
+//                .apis(RequestHandlerSelectors.basePackage("com.provider.controller"))
+                //指定构建api接口的包路径-此处为所有包(未指定)
+                .apis(RequestHandlerSelectors.any())
+                //访问路径下面的接口
+//                .paths(PathSelectors.any())
+//                .paths(PathSelectors.ant("/libai/**"))
+//                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                //可根据url路径设置那些请求加入文档,忽略哪些请求
+                .paths(PathSelectors.any())
+                .build()
+                //分组管理可以与哪个访问路径结合使用
+//                .groupName("用户管理")
+                ;
+    }
+
+    /**
+     * 创建API界面的基本信息
+     * @return 返回一个构建好的ApiInfo对象
+     */
+    private ApiInfo apiInfo(){
+        return new ApiInfoBuilder()
+                //界面标题
+                .title("维鼎康联his对接平台统一入口")
+                //接口描述
+                .description("后端API接口文档展示")
+                //联系方式,联系人-网址-邮箱
+                .contact(new Contact("WDKL", "http://www.wdklian.com", "service@wdklian.com"))
+                //版本信息
+                .version("1.0.0")
+                //证书描述
+                .license("访问主页")
+                //以上全部,开始构建
+                .build();
+    }
+
+    @Bean
+    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
+                                                                         ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
+                                                                         EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
+                                                                         WebEndpointProperties webEndpointProperties, Environment environment) {
+        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
+        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
+        allEndpoints.addAll(webEndpoints);
+        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
+        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
+        String basePath = webEndpointProperties.getBasePath();
+        EndpointMapping endpointMapping = new EndpointMapping(basePath);
+        boolean shouldRegisterLinksMapping =
+                webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath)
+                        || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
+        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
+                corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath),
+                shouldRegisterLinksMapping, null);
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+
+}

+ 25 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/EntraceServiceApplication.java

@@ -0,0 +1,25 @@
+package com.wdklian.ncs.ms.entrace;
+
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 15:50
+ * ${description}
+ */
+@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class})
+@ComponentScan(basePackages = "com.wdklian.ncs.ms",excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX,pattern = "com.wdklian.ncs.ms.common.service.*"))
+@EnableDiscoveryClient
+@EnableFeignClients(basePackages ="com.wdklian.ncs.ms.feignclient")
+public class EntraceServiceApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(EntraceServiceApplication.class,args);
+    }
+}

+ 49 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceRefBoardItemController.java

@@ -0,0 +1,49 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.AdviceRefBoardItemDO;
+import com.wdklian.ncs.ms.feignclient.open.AdviceRefBoardItemFeignClient;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@Slf4j
+@Api(description = "医嘱强制关联(手动设置匹配)看板条目", tags = "医嘱强制关联(手动设置匹配)看板条目")
+@RequestMapping("/advice-refer-board-item")
+@Validated
+public class AdviceRefBoardItemController {
+
+    @Autowired
+    private AdviceRefBoardItemFeignClient adviceRefBoardItemFeignClient;
+
+    @PostMapping(value = "/{part_id}/{item_name_md5}")
+    @ApiOperation(value = "设置看板条目匹配医嘱", response = AdviceRefBoardItemDO.class, responseContainer = "list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path")})
+    public List<AdviceRefBoardItemDO> addAdviceReferenceBoardItem(@RequestBody String[] adviceContentMd5s,
+                                                                  @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                                                  @PathVariable(name = "part_id") Integer partId) {
+        return this.adviceRefBoardItemFeignClient.addAdviceReferenceBoardItem(adviceContentMd5s, itemNameMd5, partId).getData();
+    }
+
+
+    @DeleteMapping(value = "/{part_id}/{item_name_md5}")
+    @ApiOperation(value = "取消看板条目匹配医嘱")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path")})
+    public Integer deleteAdviceReferenceBoardItem(@RequestBody String[] adviceContentMd5s,
+                                                  @PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId) {
+        return this.adviceRefBoardItemFeignClient.deleteAdviceReferenceBoardItem(adviceContentMd5s, itemNameMd5, partId).getData();
+    }
+
+
+}

+ 55 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceRefNursingMarkController.java

@@ -0,0 +1,55 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.AdviceRefNursingMarkOptionDO;
+import com.wdklian.ncs.ms.feignclient.open.AdviceRefNursingMarkFeignClient;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.List;
+
+@RestController
+@Slf4j
+@Api(description = "医嘱强制关联(手动设置匹配)护理项目", tags = "医嘱强制关联(手动设置匹配)护理项目")
+@RequestMapping("/advice-refer-nurse")
+@Validated
+@ApiIgnore
+public class AdviceRefNursingMarkController {
+
+    @Autowired
+    private AdviceRefNursingMarkFeignClient adviceRefNursingMarkFeignClient;
+
+    @PostMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    @ApiOperation(value = "设置医嘱匹配护理项目", response = AdviceRefNursingMarkOptionDO.class,responseContainer = "list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path")})
+    public List<AdviceRefNursingMarkOptionDO> addAdviceReferenceNurse(@RequestBody String[] adviceContentMd5s,
+                                                                      @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                                      @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                                                      @PathVariable(name = "part_id") Integer partId) {
+        return this.adviceRefNursingMarkFeignClient.addAdviceReferenceNurse(adviceContentMd5s, categoryNameMd5, itemNameMd5, partId).getData();
+    }
+
+    @DeleteMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    @ApiOperation(value = "取消医嘱匹配护理项目")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path")})
+    public Integer deleteMapping(@RequestBody String[] adviceContentMd5s,
+                                               @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                               @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                               @PathVariable(name = "part_id") Integer partId) {
+        return this.adviceRefNursingMarkFeignClient.deleteMapping(adviceContentMd5s, categoryNameMd5, itemNameMd5,partId).getData();
+    }
+
+
+}

+ 150 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/AdviceUniqueContentController.java

@@ -0,0 +1,150 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.AdviceUniqueContentDO;
+import com.wdklian.ncs.ms.entrace.service.AdviceUniqueContentService;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.GridParameterParser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+
+@RestController
+@Slf4j
+@Api(description = "医嘱内容去重数据", tags = "医嘱内容去重数据")
+@RequestMapping("/advice-unique-content")
+@Validated
+@ApiIgnore
+public class AdviceUniqueContentController {
+
+    @Autowired
+    private AdviceUniqueContentService adviceUniqueContentService;
+
+    @ApiOperation(value = "查询去重后护理项目可设置匹配HIS医嘱列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true),
+            @ApiImplicitParam(name = "item_name_md5", value = "分类条目名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @PostMapping("/{part_id}/{category_name_md5}/{item_name_md5}/page")
+    public Page listNurseOptionAvailable(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                         @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                         @PathVariable(name = "part_id") Integer partId,
+                                         @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                         @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                         HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listNurseOptionAvailable(gp, categoryNameMd5, itemNameMd5, partId);
+    }
+
+
+    @ApiOperation(value = "查询护理项目匹配的HIS医嘱列表,包括关键字匹配和手动添加匹配")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "床头屏医嘱分类名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true),
+            @ApiImplicitParam(name = "item_name_md5", value = "护理项目名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @PostMapping("/match/nurse-option/{part_id}/{category_name_md5}/{item_name_md5}/page")
+    public Page listNurseOptionMatch(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                     @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                     @PathVariable(name = "part_id") Integer partId,
+                                     @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                     @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                     HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listNurseOptionMatch(gp, categoryNameMd5, itemNameMd5, partId);
+    }
+
+
+    @ApiOperation(value = "查询去重后护理项目可设置匹配HIS医嘱列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true),
+            @ApiImplicitParam(name = "item_name_md5", value = "分类条目名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @PostMapping("/nurse-category/{part_id}/{category_id}/page")
+    public Page listNurseCategoryAvailable(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                           @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                           @PathVariable(name = "part_id") Integer partId,
+                                           @PathVariable(name = "category_id") Integer categoryId,
+                                           HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listNurseCategoryAvailable(gp, partId, categoryId);
+    }
+
+
+    @ApiOperation(value = "查询自动生成子项的护理分类匹配的HIS医嘱列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_id", value = "科室Id", required = true, dataType = "int", paramType = "path")
+    })
+    @PostMapping("/match/nurse-category/{part_id}/{category_id}/page")
+    public Page listNurseCategoryMatch(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                       @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                       @PathVariable(name = "part_id") Integer partId,
+                                       @PathVariable(name = "category_id") Integer categoryId,
+                                       HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listNurseCategoryMatch(gp, partId, categoryId);
+    }
+
+    @ApiOperation(value = "查询去重后电子白板条目可设置匹配HIS医嘱列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "item_name_md5", value = "电子白板条目名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @PostMapping("/{part_id}/{item_name_md5}/page")
+    public Page listBoardItemAvailable(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                       @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                       @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                       @PathVariable(name = "part_id") Integer partId,
+                                       HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listBoardItemAvailable(gp, itemNameMd5, partId);
+    }
+
+
+    @ApiOperation(value = "查询电子白板项目匹配的HIS医嘱列表,包括关键字匹配和手动添加匹配")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "item_name_md5", value = "电子白板条目名称MD5值,字符串0,代表没有选择条目", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @PostMapping("/match/board-item/{part_id}/{item_name_md5}/page")
+    public Page listBoardItemMatch(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                   @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                   @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                   @PathVariable(name = "part_id") Integer partId,
+                                   HttpServletRequest request) {
+        GridParameter gp = GridParameterParser.parse(AdviceUniqueContentDO.class, request.getParameterMap());
+        return this.adviceUniqueContentService.listBoardItemMatch(gp, itemNameMd5, partId);
+    }
+
+
+}

+ 89 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardInformationController.java

@@ -0,0 +1,89 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.vos.VChartPaitentQuantityVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.DoctorAdviceMapBoardItemVO;
+import com.wdklian.ncs.ms.entrace.service.BoardItemService;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.GridParameterParser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-16 11:32
+ * ${description}
+ */
+@RestController
+@Slf4j
+@Api(description = "看板项目内容", tags = "看板项目内容")
+@RequestMapping("/infomation-board-item")
+@Validated
+@ApiIgnore
+public class BoardInformationController {
+
+    @Autowired
+    BoardItemService boardItemService;
+
+    @Autowired
+    private BoardItemFeignClient boardItemFeignClient;
+
+    @ApiOperation(value = "查询自定义看板项数据及数据来源列表", response = DoctorAdviceMapBoardItemVO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "display_type", value = "显示方式(1、数据校验列表,2、工作台列表)", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "with_detail", value = "是否返回项目匹配明细(0-不返回,1-返回)", required = true, dataType = "int", paramType = "query")
+    })
+    @PostMapping("/{part_id}/{display_type}/page")
+    public Page listDataPage(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                             @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                             @ApiIgnore @NotNull(message = "是否返回项目匹配明细") Integer withDetail,
+                             @PathVariable("part_id") Integer partId,
+                             @PathVariable("display_type") Integer displayType,
+                             HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(BoardItemDO.class, request.getParameterMap());
+       // gp.setSqlSelect("select * from (select item.*,display.part_subscribe,display.dash_board_show,display.subscribe_order,display.dash_board_order from ncs_board_item item LEFT JOIN ncs_board_item_display display on md5(item.area_label)=display.item_name_md5 and item.part_id=display.part_id) as t\t");
+        return this.boardItemService.listDataPage(gp,withDetail,partId,displayType);
+    }
+
+
+    @GetMapping("/renew-part/{partid}")
+    @ApiOperation(value = "更新单个科室信息看板条目内容", notes = "返回有变化科室Id", response = Integer.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "partid", value = "科室主键", required = true, dataType = "int", paramType = "path")
+    })
+    public CommonResult renewPart(@NotNull(message = "科室主键不能为空")  @PathVariable("partid") Integer id) {
+        List<Integer> partIds = boardItemFeignClient.renewPartByPartId(id).getData();
+        return CommonResult.success(partIds);
+
+    }
+
+    @GetMapping("/part-patient-trend/{partId}")
+    @ApiOperation(value = "获取某科室下患者数量变化趋势图表数据", response = VChartPaitentQuantityVO.class,responseContainer = "list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "partId", value = "科室Id", dataType = "int", paramType = "path", required = true)
+    })
+    public List<VChartPaitentQuantityVO> getPartPatientTrend(@PathVariable Integer partId,String start,String end){
+        return boardItemService.getPartPatientTrend(partId,start,end);
+    }
+
+
+
+}

+ 160 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardItemConfigController.java

@@ -0,0 +1,160 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.BoardItemConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.BoardItemConfigVO;
+import com.wdklian.ncs.ms.entrace.service.BoardItemConfigService;
+import com.wdklian.ncs.ms.feignclient.open.BoardItemConfigFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.GridParameterParser;
+import com.wdklian.ncs.ms.framework.mvc.JsonResponse;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Api(description = "看板项目设置", tags = "看板项目设置")
+@RequestMapping("/board-item-config")
+@Validated
+@ApiIgnore
+public class BoardItemConfigController {
+
+
+    @Autowired
+    private BoardItemConfigFeignClient boardItemConfigFeignClient;
+
+    @Autowired
+    private BoardItemConfigService boardItemConfigService;
+
+    @ApiOperation(value = "查询自定义看板项目设定列表", response = BoardItemConfigVO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query")
+    })
+    @PostMapping("/page")
+    public Page<BoardItemConfigVO> list(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                        @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                        HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(BoardItemConfigDO.class, request.getParameterMap());
+        return this.boardItemConfigFeignClient.list(gp).getData();
+    }
+
+
+    @ApiOperation(value = "查询自定义看板项目设定列表", response = BoardItemConfigVO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "partId", value = "科室id", required = true, dataType = "int", paramType = "path")
+    })
+    @PostMapping("/{partId}/page")
+    public Page<BoardItemConfigVO> listPartPage(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                                                          @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                                                          @PathVariable Integer partId,
+                                                                          HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(BoardItemConfigDO.class, request.getParameterMap());
+        return this.boardItemConfigService.listPartPage(gp, partId);
+    }
+
+
+    @ApiOperation(value = "添加自定义看板项目设定", response = BoardItemConfigDO.class)
+    @PostMapping
+    public BoardItemConfigDO add(@Valid BoardItemConfigDO boardItemSettingDO) {
+        return  this.boardItemConfigFeignClient.add(boardItemSettingDO).getData();
+    }
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取单个自定义看板项信息", response = BoardItemConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public BoardItemConfigDO get(@PathVariable("id") Integer id) {
+        return this.boardItemConfigFeignClient.get(id).getData();
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改自定义看板项", response = BoardItemConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public BoardItemConfigDO edit(@Valid BoardItemConfigDO boardItemSettingDO, @PathVariable Integer id) {
+        return this.boardItemConfigFeignClient.edit(boardItemSettingDO, id).getData();
+
+    }
+
+    @DeleteMapping(value = "/{ids}")
+    @ApiOperation(value = "删除自定义看板项", response = CommonResult.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要删除的自定义看板项主键集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
+    public void delete(@PathVariable("ids") Integer[] ids) {
+        this.boardItemConfigFeignClient.delete(ids);
+    }
+
+    @GetMapping(value = "/forselect/{part_id}")
+    @ApiOperation(value = "获取所有看板条目项,做为下拉控件数据源", response = BoardItemConfigDO.class,responseContainer ="list" )
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室主键,-1为全院通用", required = true, dataType = "int", paramType = "path")})
+    public List<BoardItemConfigDO> getForSelect(@PathVariable(name = "part_id") Integer partId) {
+        return this.boardItemConfigFeignClient.getForSelect(partId).getData();
+    }
+
+
+    @PutMapping(value = "/keywords/{part_id}/{item_name_md5}")
+    @ApiOperation(value = "更新看板条目关键字", response = BoardItemConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "string", paramType = "path")})
+    public BoardItemConfigDO updateKeywords(@Valid BoardItemConfigDO itemSettingDO,
+                                                          @PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId) {
+        return this.boardItemConfigFeignClient.updateKeywords(itemSettingDO, itemNameMd5, partId).getData();
+    }
+
+
+    @GetMapping(value = "/{part_id}/{item_name_md5}")
+    @ApiOperation(value = "根据看板条目名称Md5获取条目", response = BoardItemConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "string", paramType = "path")})
+    public BoardItemConfigDO getModelByMd5(@PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId) {
+        return this.boardItemConfigFeignClient.getModelByMd5(itemNameMd5, partId).getData();
+    }
+
+    @GetMapping(value = "/{part_id}")
+    @ApiOperation(value = "根据科室Id获取看板条目设置列表", response = BoardItemConfigDO.class,responseContainer = "list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "string", paramType = "path")})
+    public List<BoardItemConfigDO> listPartBoardItemConfig(@PathVariable(name = "part_id") Integer partId) {
+        return this.boardItemConfigFeignClient.listPartBoardItemConfig(partId).getData();
+    }
+
+
+    @GetMapping(value = "/list-all")
+    @ApiOperation(value = "查询所有看板条目设置", response = BoardItemConfigDO.class,responseContainer = "list")
+    public List<BoardItemConfigDO> listAllBoardItemConfig() {
+        return this.boardItemConfigFeignClient.listAllBoardItemConfig().getData();
+    }
+
+
+    @ApiOperation(value = "应用床头屏医嘱设置到科室科室的护理参数配置上")
+    @PostMapping(value = "/apply/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id,-1为所有科室", required = true, dataType = "int", paramType = "path")})
+    public JsonResponse apply(@PathVariable("part_id") Integer partId) {
+        return this.boardItemConfigService.applyBoardItemConfig(partId);
+    }
+
+
+
+}

+ 29 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/BoardItemDisplayConfigController.java

@@ -0,0 +1,29 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.vos.BoardItemDisplayConfigVO;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemDisplayConfigFeignClient;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+@RestController
+@RequestMapping("/boarditem-display-config")
+@Api(description = "看板条目在系统中的显示设置API", tags = "看板条目在系统中的显示设置API")
+@ApiIgnore
+public class BoardItemDisplayConfigController {
+
+    @Autowired
+    private BoardItemDisplayConfigFeignClient boardItemDisplayConfigFeignClient;
+
+    @PostMapping
+    @ApiOperation(value = "更新设置", response = BoardItemDisplayConfigVO.class)
+    public BoardItemDisplayConfigVO edit(BoardItemDisplayConfigVO boardItemDisplayConfigVO) {
+        return this.boardItemDisplayConfigFeignClient.edit(boardItemDisplayConfigVO).getData();
+
+    }
+
+}

+ 57 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/DepartmentController.java

@@ -0,0 +1,57 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DepartmentDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.entrace.service.DepartmentService;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Validated
+@RequestMapping("/department")
+@Api(description = "科室信息同步", tags = "科室信息同步")
+public class DepartmentController {
+
+    @Autowired
+    private DepartmentService departmentService;
+
+    @PostMapping("/sync-list")
+    @ApiOperation(value = "同步科室列表", response = ShopDO.class, responseContainer = "list")
+    public List<ShopDO> syncDepartment(@RequestBody @NotEmpty(message = "科室列表不能为空") @Validated List<DepartmentDO> departments) {
+        return departmentService.saveDepartments(departments);
+    }
+
+    @PostMapping("/sync-single")
+    @ApiOperation(value = "同步单个科室信息", response = ShopDO.class)
+    public ShopDO syncSingleDepartment(@RequestBody @NotNull(message = "科室数据不能为null") DepartmentDO departmentDO) {
+
+        return departmentService.saveDepartment(departmentDO);
+
+    }
+
+    @GetMapping("/sync-single/{key}")
+    @ApiOperation(value = "根据his的科室主键更新呼叫系统科室信息", response = ShopDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "key", value = "科室主键", required = true, dataType = "String", paramType = "path")
+    })
+    public ShopDO syncDepartmentByKey(@PathVariable("key") @NotEmpty(message = "科室主键不能为空") String key) {
+        ShopDO shopDO = departmentService.syncSingleByKey(key);
+        return shopDO;
+
+    }
+
+
+}

+ 54 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/DoctorAdviceController.java

@@ -0,0 +1,54 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DoctorAdviceDO;
+import com.wdklian.ncs.ms.entrace.service.DoctorAdviceService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Validated
+@RequestMapping("/doctor-advice")
+@Api(description = "医嘱同步", tags = "医嘱同步")
+public class DoctorAdviceController {
+
+    @Autowired
+    private DoctorAdviceService doctorAdviceService;
+
+    @PostMapping("/sync-list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "doctoradvices", value = "医嘱列表", required = true, dataType = "List<DoctorAdviceDO>", paramType = "body")})
+    @ApiOperation(value = "批量新增或更新医嘱,返回更新成功的医嘱列表",response = DoctorAdviceDO.class,responseContainer = "list")
+    public List<DoctorAdviceDO> syncDoctorAdvice(@RequestBody @NotEmpty(message = "医嘱列表不能为空") @Validated List<DoctorAdviceDO> doctoradvices) {
+        return doctorAdviceService.saveDoctorAdvice(doctoradvices);
+    }
+
+    @PostMapping("/sync-single")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "doctoradvices", value = "医嘱列表", required = true, dataType = "DoctorAdviceDO", paramType = "body")})
+    @ApiOperation(value = "新增或更新单个医嘱信息,返回更新后的医嘱",response = DoctorAdviceDO.class)
+    public DoctorAdviceDO syncSingleDoctorAdvice(@RequestBody @NotNull(message = "医嘱数据不能为null") @Validated DoctorAdviceDO doctorAdvice) {
+        return doctorAdviceService.saveDoctorAdvice(doctorAdvice);
+    }
+
+    @DeleteMapping("/{his_keys}")
+    @ApiOperation(value = "批量删除医嘱",response = Integer.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "his_keys", value = "要删除医嘱的主键集合", required = true, example = "1,2,3",dataType = "String", paramType = "path", allowMultiple = true)})
+    public Integer deleteDoctorAdvice(@PathVariable(value = "his_keys") @NotEmpty(message = "医嘱主键不能为空") String[] hisKeys) {
+        return doctorAdviceService.deleteDoctorAdvice(hisKeys);
+    }
+
+
+
+}

+ 52 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/EmployeeController.java

@@ -0,0 +1,52 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.EmployeeDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ClerkDO;
+import com.wdklian.ncs.ms.entrace.service.EmployeeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Validated
+@RequestMapping("/employee")
+@Api(description = "职工信息同步", tags = "职工信息同步")
+public class EmployeeController {
+
+    @Autowired
+    private EmployeeService employeeService;
+
+    @PostMapping("/sync-list")
+    @ApiOperation(value = "新增或更新职员信息,返回更新成功的职员列表", response = EmployeeDO.class, responseContainer = "list")
+    public List<ClerkDO> syncEmployee(@RequestBody @NotEmpty(message = "职员列表不能为空") @Validated List<EmployeeDO> employees) {
+        return employeeService.saveEmployee(employees);
+    }
+
+    @PostMapping("/sync-single")
+    @ApiOperation(value = "新增或更新单个职员信息,返回更新成功的职员", response = EmployeeDO.class)
+    public ClerkDO syncSingleEmployee(@RequestBody @NotNull(message = "科室数据不能为null") @Validated EmployeeDO employee) {
+        return employeeService.saveEmployee(employee);
+    }
+
+    @GetMapping("/sync-single/{key}")
+    @ApiOperation(value = "通过职工主键,更新数据到呼叫系统", response = ClerkDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "key", value = "职工主键", required = true, dataType = "String", paramType = "path")
+    })
+    public ClerkDO syncSingleEmployeeByKey(@NotEmpty(message = "职工主键不能为空") @PathVariable("key") String key) {
+        ClerkDO clerkDO = employeeService.syncEmployeeByKey(key);
+        return clerkDO;
+    }
+
+
+}

+ 86 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/ManualInputBoardItemConfigController.java

@@ -0,0 +1,86 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.ManualInputBoardItemConfingDO;
+import com.wdklian.ncs.ms.entrace.service.ManualInputBoardItemService;
+import com.wdklian.ncs.ms.feignclient.open.ManualInputBoardItemConfigFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.GridParameterParser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+@RestController
+@Slf4j
+@Api(description = "看板项目设置", tags = "看板项目设置")
+@RequestMapping("/manual-input-board-item-config")
+@Validated
+@ApiIgnore
+public class ManualInputBoardItemConfigController {
+
+
+    @Autowired
+    private ManualInputBoardItemConfigFeignClient manualInputBoardItemConfigFeignClient;
+    @Autowired
+    private ManualInputBoardItemService manualInputBoardItemService;
+
+    @ApiOperation(value = "查询手动输入看板项目设定列表", response = ManualInputBoardItemConfingDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "partId", value = "科室id", required = true, dataType = "int", paramType = "path")
+    })
+    @PostMapping("/{part_id}/page")
+    public Page<ManualInputBoardItemConfingDO> listPartPage(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                                            @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                                            @PathVariable("part_id") Integer partId,
+                                                            HttpServletRequest request) {
+
+        GridParameter gp = GridParameterParser.parse(ManualInputBoardItemConfingDO.class, request.getParameterMap());
+        return this.manualInputBoardItemConfigFeignClient.listPartPage(gp, partId).getData();
+    }
+
+
+    @ApiOperation(value = "添加手动输入看板项目设定", response = ManualInputBoardItemConfingDO.class)
+    @PostMapping
+    public ManualInputBoardItemConfingDO add(@Valid ManualInputBoardItemConfingDO manualInputBoardItemSettingDO) {
+        return this.manualInputBoardItemService.add(manualInputBoardItemSettingDO);
+
+    }
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取单个手动输入看板项目信息", response = ManualInputBoardItemConfingDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public ManualInputBoardItemConfingDO get(@PathVariable("id") Integer id) {
+        return this.manualInputBoardItemConfigFeignClient.get(id).getData();
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改手动输入看板项目", response = ManualInputBoardItemConfingDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public ManualInputBoardItemConfingDO edit(@Valid ManualInputBoardItemConfingDO manualInputBoardItemSettingDO, @PathVariable("id") Integer id) {
+        return this.manualInputBoardItemService.edit(manualInputBoardItemSettingDO, id);
+    }
+
+    @DeleteMapping(value = "/{ids}")
+    @ApiOperation(value = "删除手动输入看板项目")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要删除的手动输入看板项目主键集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
+    public void delete(@PathVariable("ids") Integer[] ids) {
+        this.manualInputBoardItemService.delete(ids);
+    }
+
+
+}

+ 124 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/NursingMarkCategoryConfigController.java

@@ -0,0 +1,124 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkCategoryConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NurseCascaderVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NursingMarkCategoryConfigVO;
+import com.wdklian.ncs.ms.entrace.service.NursingMarkCategoryService;
+import com.wdklian.ncs.ms.feignclient.open.NursingMarkCategoryConfigFeignClient;
+import com.wdklian.ncs.ms.framework.mvc.JsonResponse;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Api(description = "护理信息分类设置", tags = "护理信息分类设置")
+@RequestMapping("/nursing-mark-category-config")
+@Validated
+@ApiIgnore
+public class NursingMarkCategoryConfigController {
+
+
+    @Autowired
+    private NursingMarkCategoryConfigFeignClient categoryConfigFeignClient;
+
+    @Autowired
+    private NursingMarkCategoryService nursingMarkCategoryService;
+
+    @ApiOperation(value = "添加分类设置", response = NursingMarkCategoryConfigDO.class)
+    @PostMapping
+    public NursingMarkCategoryConfigDO add(@Valid NursingMarkCategoryConfigDO categoryDO) {
+        return this.categoryConfigFeignClient.add(categoryDO).getData();
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改分类设置", response = NursingMarkCategoryConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public NursingMarkCategoryConfigDO edit(@Valid NursingMarkCategoryConfigDO categoryDO, @PathVariable Integer id) {
+        return this.categoryConfigFeignClient.edit(categoryDO, id).getData();
+    }
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除分类设置")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的护理主键集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
+    public Integer delete(@PathVariable Integer id) {
+
+        return this.categoryConfigFeignClient.delete(id).getData();
+
+    }
+
+    @ApiOperation(value = "查询科室所有分类配置", response = NursingMarkCategoryConfigVO.class, responseContainer = "List")
+    @PostMapping(value = "/list/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室主键", required = true, dataType = "int", paramType = "path")})
+    public List<NursingMarkCategoryConfigVO> list(@PathVariable("part_id") Integer partId) {
+        return this.nursingMarkCategoryService.list(partId);
+    }
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取单个护理分类设置信息", response = NursingMarkCategoryConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public NursingMarkCategoryConfigDO get(@PathVariable Integer id) {
+        return this.categoryConfigFeignClient.get(id).getData();
+    }
+
+
+    @ApiOperation(value = "查询科室护理标识可配置的分类选项级联选择列表", response = NurseCascaderVO.class, responseContainer = "List")
+    @GetMapping(value = "/cascader/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "int", paramType = "path")})
+    public List<NurseCascaderVO> cascader(@PathVariable("part_id") Integer partId) {
+        return this.categoryConfigFeignClient.cascader(partId).getData();
+    }
+
+    @ApiOperation(value = "查询自动生成子项目的分类设置", response = NurseCascaderVO.class, responseContainer = "List")
+    @GetMapping(value = "/auto-match-category/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "int", paramType = "path")})
+    public List<NursingMarkCategoryConfigDO> autoChildrenCategory(@PathVariable("part_id") Integer partId) {
+        return this.categoryConfigFeignClient.autoChildrenCategory(partId).getData();
+    }
+
+    @ApiOperation(value = "拷贝默认分类到科室", response = NurseCascaderVO.class, responseContainer = "List")
+    @PostMapping(value = "/copy-default/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "int", paramType = "path")})
+    public List copyDefault(@PathVariable("part_id") Integer partId,@RequestBody Integer[] categoryIds) {
+        return this.nursingMarkCategoryService.copyDefaultToPart(categoryIds,partId);
+    }
+
+    @ApiOperation(value = "强制拷贝默认分类到科室", response = NurseCascaderVO.class, responseContainer = "List")
+    @PostMapping(value = "/force-copy-default/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id", required = true, dataType = "int", paramType = "path")})
+    public List forceCopyDefault(@PathVariable("part_id") Integer partId,@RequestBody Integer[] categoryIds) {
+        return this.nursingMarkCategoryService.copyDefaultToPart(categoryIds,partId,true);
+    }
+
+    @ApiOperation(value = "强制拷贝默认分类到科室", response = NurseCascaderVO.class, responseContainer = "List")
+    @PostMapping(value = "/foce-copy-default")
+    public JsonResponse forceCopyDefaultToPart() {
+        return this.nursingMarkCategoryService.foceCopyDefaultToPart();
+    }
+
+
+    @ApiOperation(value = "应用护理信息到科室中")
+    @PostMapping(value = "/apply/{part_id}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室id,-1为所有科室", required = true, dataType = "int", paramType = "path")})
+    public JsonResponse apply(@PathVariable("part_id") Integer partId) {
+        return this.nursingMarkCategoryService.applyNurseConfig(partId);
+    }
+}

+ 93 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/NursingMarkOptionConfigController.java

@@ -0,0 +1,93 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkOptionConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NursingMarkOptionConfigVO;
+import com.wdklian.ncs.ms.feignclient.open.NursingMarkOptionConfigFeignClient;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2023-12-03 10:19
+ * ${description}
+ */
+@RestController
+@Slf4j
+@Api(description = "护理标识项目设置", tags = "护理标识项目设置")
+@RequestMapping("/nursing-mark-option-config")
+@Validated
+@ApiIgnore
+public class NursingMarkOptionConfigController {
+
+    @Autowired
+    private NursingMarkOptionConfigFeignClient optionConfigFeignClient;
+
+
+    @ApiOperation(value = "添加项目设置", response = NursingMarkOptionConfigDO.class)
+    @PostMapping
+    public NursingMarkOptionConfigDO add(@Valid NursingMarkOptionConfigDO itemSettingDO) {
+        return this.optionConfigFeignClient.add(itemSettingDO).getData();
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改项目设置", response = NursingMarkOptionConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public NursingMarkOptionConfigDO edit(@Valid NursingMarkOptionConfigDO itemSettingDO, @PathVariable("id") Integer id) {
+        return this.optionConfigFeignClient.edit(itemSettingDO, id).getData();
+    }
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除条目")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的护理主键集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
+    public void delete(@PathVariable("id") Integer id) {
+        this.optionConfigFeignClient.delete(id);
+    }
+
+
+    @PutMapping(value = "/keywords/{category_name_md5}/{item_name_md5}")
+    @ApiOperation(value = "更新条目关键字", response = NursingMarkOptionConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path")})
+    public NursingMarkOptionConfigDO updateKeywords(@Valid NursingMarkOptionConfigDO itemSettingDO, @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                    @PathVariable(name = "item_name_md5") String itemNameMd5) {
+        return this.optionConfigFeignClient.updateKeywords(itemSettingDO, categoryNameMd5, itemNameMd5).getData();
+
+    }
+
+    @GetMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    @ApiOperation(value = "根据类目名称Md5和条目名称Md5获取条目", response = NursingMarkOptionConfigDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_id", value = "科室Id", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "category_name_md5", value = "分类名称md5", required = true, dataType = "string", paramType = "path"),
+            @ApiImplicitParam(name = "item_name_md5", value = "条目名称md5", required = true, dataType = "string", paramType = "path")})
+    public NursingMarkOptionConfigDO getModelByCIMd5(@PathVariable(name = "part_id") Integer partId,
+                                                     @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                     @PathVariable(name = "item_name_md5") String itemNameMd5) {
+        return this.optionConfigFeignClient.getModelByCIMd5(partId, categoryNameMd5, itemNameMd5).getData();
+
+    }
+
+    @GetMapping(value = "/list-parts-option-config")
+    @ApiOperation(value = "根据科室id列表获取护理标识项目匹配设置列表", response = NursingMarkOptionConfigVO.class, responseContainer = "list")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "part_ids", value = "科室Id", required = true, dataType = "int", paramType = "body")
+    })
+    public List<NursingMarkOptionConfigVO> listNurseOptionConfigVOByPartIds(@RequestBody List<Integer> partIds) {
+        return this.optionConfigFeignClient.listNurseOptionConfigVOByPartIds(partIds).getData();
+    }
+
+
+}

+ 69 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/PartTempBedController.java

@@ -0,0 +1,69 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PartTempBedDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.PartTempBedVO;
+import com.wdklian.ncs.ms.entrace.service.PartTempBedService;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.GridParameterParser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+
+@RestController
+@Slf4j
+@Api(description = "科室临时床位", tags = "科室临时床位")
+@RequestMapping("/part-temp-bed")
+@Validated
+@ApiIgnore
+public class PartTempBedController {
+
+    @Autowired
+    private PartTempBedService partTempBedService;
+
+    @ApiOperation(value = "添加临时床位设置", response = PartTempBedDO.class)
+    @PostMapping
+    public PartTempBedDO add(PartTempBedDO partTempBedsDO) {
+        return this.partTempBedService.add(partTempBedsDO);
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改临时床位", response = PartTempBedDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")})
+    public PartTempBedDO edit(PartTempBedDO partTempBedsDO, @PathVariable("id") Integer id) {
+        return this.partTempBedService.edit(partTempBedsDO, id);
+    }
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除临时床位")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的主键", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
+    public void delete(@PathVariable("id") Integer id) {
+
+        this.partTempBedService.delete(id);
+    }
+
+    @ApiOperation(value = "分页查询临时床位数据")
+    @PostMapping(value = "/page")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query")})
+    public Page<PartTempBedVO> list(@ApiIgnore @NotNull(message = "页码不能为空") Integer pageNo,
+                                    @ApiIgnore @NotNull(message = "页容量") Integer pageSize,
+                                    HttpServletRequest request) {
+        GridParameter gp = GridParameterParser.parse(PartTempBedDO.class, request.getParameterMap());
+        return this.partTempBedService.list(gp);
+    }
+
+
+}

+ 64 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/controller/PatientController.java

@@ -0,0 +1,64 @@
+package com.wdklian.ncs.ms.entrace.controller;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.CustomerDO;
+import com.wdklian.ncs.ms.entrace.service.PatientService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@RestController
+@Slf4j
+@Validated
+@RequestMapping("/patient")
+@Api(description = "患者信息同步", tags = "患者信息同步")
+public class PatientController {
+
+    @Autowired
+    private PatientService patientService;
+
+    @PostMapping("/sync-list")
+    @ApiOperation(value = "新增或更新患者信息,返回更新成功的患者列表", response = PatientDO.class, responseContainer = "List")
+    public List<PatientDO> syncPatient(@RequestBody @NotEmpty(message = "患者列表不能为空") @Validated List<PatientDO> patients) {
+        return patientService.savePatient(patients);
+
+    }
+
+    @PostMapping("/sync-single")
+    @ApiOperation(value = "新增或更新单个患者信息,返回更新成功的患者", response = PatientDO.class)
+    public PatientDO syncSinglePatient(@RequestBody @NotNull(message = "患者数据不能为null") @Validated PatientDO patient) {
+        return patientService.savePatient(patient);
+    }
+
+
+    @GetMapping("/sync-single/{patient_key}")
+    @ApiOperation(value = "根据患者主键把患者同步到呼叫系统", response = PatientDO.class)
+    public PatientDO syncSinglePatientByKey(@PathVariable("patient_key") String patientKey) {
+        return patientService.syncPatientByKey(patientKey);
+    }
+
+    @PostMapping("/patient-out/{patient_key}")
+    @ApiOperation(value = "指定患者主键出院")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "patient_key", value = "患者主键", required = true, dataType = "String", paramType = "path")
+    })
+    public PatientDO patientOut(@NotEmpty(message = "患者主键不能为空") @PathVariable(value = "patient_key") String patientKey) {
+        return patientService.patientOut(patientKey);
+    }
+
+    @GetMapping("/sync-all")
+    @ApiOperation(value = "更新所有患者信息,his数据库转换到ncs库,仅对视图同步方式有效", response = CustomerDO.class)
+    public void syncAllPatient() {
+        patientService.syncAllPatient();
+    }
+
+}

+ 70 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/AdviceUniqueContentService.java

@@ -0,0 +1,70 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.common.pojo.PageShopParam;
+import com.wdklian.ncs.ms.feignclient.open.AdviceUniqueContentFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ShopFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * @author wuyunfeng
+ * 2024-01-16 09:45
+ * ${description}
+ */
+@Service
+@Slf4j
+public class AdviceUniqueContentService {
+
+    @Autowired
+    private ShopFeignClient shopFeignClient;
+
+    @Autowired
+    private AdviceUniqueContentFeignClient adviceUniqueContentFeignClient;
+
+
+    public Page listNurseOptionAvailable(GridParameter gp, String categoryNameMd5, String itemNameMd5, Integer partId) {
+        PageShopParam pageShopParam = getPageShopParam(gp, partId);
+        return this.adviceUniqueContentFeignClient.listNurseOptionAvailable(pageShopParam, categoryNameMd5, itemNameMd5).getData();
+    }
+
+    public Page listNurseOptionMatch(GridParameter gp, String categoryNameMd5, String itemNameMd5, Integer partId) {
+        PageShopParam pageShopParam = getPageShopParam(gp, partId);
+        return this.adviceUniqueContentFeignClient.listNurseOptionMatch(pageShopParam, categoryNameMd5, itemNameMd5).getData();
+    }
+
+    public Page listNurseCategoryAvailable(GridParameter gp, Integer partId, Integer categoryId) {
+        ShopDO shopDO = shopFeignClient.getPartById(partId).getData();
+        PageShopParam pageShopParam = new PageShopParam(gp, shopDO);
+        return this.adviceUniqueContentFeignClient.listNurseCategoryAvailable(pageShopParam, categoryId).getData();
+    }
+
+    public Page listNurseCategoryMatch(GridParameter gp, Integer partId, Integer categoryId) {
+        ShopDO shopDO = shopFeignClient.getPartById(partId).getData();
+        PageShopParam pageShopParam = new PageShopParam(gp, shopDO);
+        return this.adviceUniqueContentFeignClient.listNurseCategoryMatch(pageShopParam, categoryId).getData();
+    }
+
+    public Page listBoardItemAvailable(GridParameter gp, String itemNameMd5, Integer partId) {
+        PageShopParam pageShopParam = getPageShopParam(gp, partId);
+        return this.adviceUniqueContentFeignClient.listBoardItemAvailable(pageShopParam, itemNameMd5).getData();
+    }
+
+    private PageShopParam getPageShopParam(GridParameter gp, Integer partId) {
+        ShopDO shopDO = new ShopDO();
+        shopDO.setShopId(partId);
+        if (!partId.equals(-1)) {
+            shopDO = shopFeignClient.getPartById(partId).getData();
+        }
+        return new PageShopParam(gp, shopDO);
+    }
+
+    public Page listBoardItemMatch(GridParameter gp, String itemNameMd5, Integer partId) {
+        PageShopParam pageShopParam = getPageShopParam(gp, partId);
+        return this.adviceUniqueContentFeignClient.listBoardItemMatch(pageShopParam, itemNameMd5).getData();
+    }
+}

+ 145 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/BoardItemConfigService.java

@@ -0,0 +1,145 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.BoardItemConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.BoardItemConfigVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDisplayDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.common.enums.ShopTypeEnum;
+import com.wdklian.ncs.ms.feignclient.open.BoardItemConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemDisplayConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.NursingMarkFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ShopFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.database.annotation.Table;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.mvc.JsonResponse;
+import com.wdklian.ncs.ms.framework.util.BeanUtil;
+import com.wdklian.ncs.ms.framework.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 15:37
+ * ${description}
+ */
+@Service
+@Slf4j
+public class BoardItemConfigService {
+
+    @Autowired
+    private BoardItemConfigFeignClient boardItemConfigFeignClient;
+
+    @Autowired
+    private BoardItemDisplayConfigFeignClient displayConfigFeignClient;
+
+    @Autowired
+    private ShopFeignClient shopFeignClient;
+
+    @Autowired
+    private BoardItemFeignClient boardItemFeignClient;
+
+    @Autowired
+    private NursingMarkFeignClient nursingMarkFeignClient;
+
+    public Page<BoardItemConfigVO> listPartPage(GridParameter gp, Integer partId) {
+
+        Page<BoardItemConfigDO> pateData = this.boardItemConfigFeignClient.listPartPage(gp, partId).getData();
+        List<BoardItemDisplayDO> displayDOS = this.displayConfigFeignClient.listByPartId(partId).getData();
+        List<BoardItemConfigDO> data = pateData.getData();
+        List<BoardItemConfigVO> vodata = new ArrayList<>();
+        if (data.size() > 0) {
+            vodata = data.stream().map(p -> {
+                BoardItemConfigVO vo = new BoardItemConfigVO();
+                BeanUtil.copyProperties(p, vo);
+                BoardItemDisplayDO boardItemDisplayDO = displayDOS.stream().filter(k -> k.getItemNameMd5().equalsIgnoreCase(p.getItemNameMd5())).findFirst().orElse(null);
+                vo.setPartId(partId);
+                if (boardItemDisplayDO != null) {
+                    vo.setDashBoardShow(boardItemDisplayDO.getDashBoardShow());
+                    vo.setPartSubscribe(boardItemDisplayDO.getPartSubscribe());
+                    vo.setDashBoardOrder(boardItemDisplayDO.getDashBoardOrder());
+                    vo.setSubscribeOrder(boardItemDisplayDO.getSubscribeOrder());
+                } else {
+                    vo.setDashBoardShow(false);
+                    vo.setPartSubscribe(false);
+                }
+                return vo;
+            }).collect(Collectors.toList());
+        }
+        return new Page<BoardItemConfigVO>(pateData.getPageNo(), pateData.getDataTotal(), pateData.getPageSize(), vodata);
+    }
+
+    public JsonResponse applyBoardItemConfig(Integer partId) {
+        //要处理的科室列表
+        List<ShopDO> shops = new ArrayList<>();
+        if (partId.equals(-1)) {
+            shops.addAll(this.shopFeignClient.listShopByType(ShopTypeEnum.PART.value()).getData());
+        } else {
+            shops.add(this.shopFeignClient.getPartById(partId).getData());
+        }
+        List<BoardItemDO> boardItemDOS = this.boardItemFeignClient.listAll().getData();
+        List<BoardItemConfigDO> settingDOS = this.boardItemConfigFeignClient.listAllBoardItemConfig().getData();
+        List<String> clearDataSql = new ArrayList<>();
+
+        if(settingDOS!=null&&settingDOS.size()>0){
+
+            for (BoardItemConfigDO partItemDOSetting : settingDOS) {
+                for (ShopDO shop : shops) {
+                    String settingNameMd5s = settingDOS.stream().filter(p->!StringUtil.isEmpty(p.getItemNameMd5())&&(p.getForPartId().equals(-1)||p.getForPartId().equals(shop.getShopId()))).map(p->p.getItemNameMd5()).collect(Collectors.joining(","));
+                    if(partItemDOSetting.getForPartId().equals(-1)||partItemDOSetting.getForPartId().equals(shop.getShopId())) {
+                        List<BoardItemDO> partBoardItems = boardItemDOS.stream().filter(p -> p.getPartId() != null && p.getPartId().equals(shop.getShopId())).collect(Collectors.toList());
+
+                        this.syncBoardItems(partItemDOSetting, shop, partBoardItems);
+                    }
+                    //删除科室中存在但科室设置中不存在的项目
+                    String partClearDataSql = String.format("delete from "+BoardItemDO.class.getAnnotation(Table.class).name()+" where find_in_set(MD5(area_label),'%s')=0 and part_id =%d",settingNameMd5s,shop.getShopId());
+                    clearDataSql.add(partClearDataSql);
+                }
+            }
+            //删除配置中已经没有的项目
+            if(clearDataSql.size()>0){
+                this.nursingMarkFeignClient.batchUpdate(clearDataSql.toArray(new String[clearDataSql.size()]));
+            }
+        }else{ //配置全为空,删除所有自定义看板条目即可
+            for (ShopDO shop : shops) {
+                String partClearDataSql = String.format("delete from "+BoardItemDO.class.getAnnotation(Table.class).name()+" where part_id =%d",shop.getShopId());
+                clearDataSql.add(partClearDataSql);
+            }
+            //删除配置中已经没有的项目
+            if(clearDataSql.size()>0){
+                this.nursingMarkFeignClient.batchUpdate(clearDataSql.toArray(new String[clearDataSql.size()]));
+            }
+        }
+
+        return JsonResponse.successResponse(settingDOS);
+
+    }
+
+
+    private void syncBoardItems(BoardItemConfigDO partItemDOSetting, ShopDO shop, List<BoardItemDO> partBoardItems) {
+
+        BoardItemDO boardItemDO = partBoardItems.stream().filter(p -> !StringUtil.isEmpty(p.getAreaLabel()) && StringUtil.md5(p.getAreaLabel()).equalsIgnoreCase(partItemDOSetting.getItemNameMd5())).findFirst().orElse(null);
+        if(boardItemDO==null){
+            boardItemDO= new BoardItemDO();
+            boardItemDO.setPartId(shop.getShopId());
+            boardItemDO.setAreaLabel(partItemDOSetting.getItemName());
+            boardItemDO.setLabelGroupName(StringUtil.isEmpty(partItemDOSetting.getItemGroup())?"":partItemDOSetting.getItemGroup());
+            //把名称MD5作为条目标识,看板设计上有使用改标识
+            boardItemDO.setHisKeyval(partItemDOSetting.getItemNameMd5());
+            boardItemDO.setHisPartKeyval(!StringUtil.isEmpty(shop.getHisCode())?shop.getHisCode().trim():"");
+            this.boardItemFeignClient.add(boardItemDO);
+        }else{
+            boardItemDO.setLabelGroupName(StringUtil.isEmpty(partItemDOSetting.getItemGroup())?"":partItemDOSetting.getItemGroup());
+            boardItemDO.setHisPartKeyval(!StringUtil.isEmpty(shop.getHisCode())?shop.getHisCode().trim():"");
+            this.boardItemFeignClient.edit(boardItemDO,boardItemDO.getId());
+        }
+
+    }
+}

+ 312 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/BoardItemService.java

@@ -0,0 +1,312 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import cn.hutool.core.lang.ObjectId;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.wdklian.ncs.ms.common.entity.open.dos.BoardItemConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.DoctorAdviceMatchBoardItemVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.PatientDataVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.VChartPaitentQuantityVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDisplayDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.BoardItemDataVO;
+import com.wdklian.ncs.ms.common.entity.system.vos.CustomerFrameVO;
+import com.wdklian.ncs.ms.feignclient.open.BoardItemConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.open.PatientFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemDisplayConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.open.DoctorAdviceFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.CustomerFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ShopFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.util.BeanUtil;
+import com.wdklian.ncs.ms.framework.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.ListUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-16 11:34
+ * ${description}
+ */
+@Service
+@Slf4j
+public class BoardItemService {
+
+    @Autowired
+    private BoardItemFeignClient boardItemFeignClient;
+
+    @Autowired
+    private BoardItemDisplayConfigFeignClient displayConfigFeignClient;
+
+    @Autowired
+    private BoardItemConfigFeignClient boardItemConfigFeignClient;
+
+    @Autowired
+    private DoctorAdviceFeignClient doctorAdviceFeignClient;
+
+    @Autowired
+    private ShopFeignClient shopFeignClient;
+
+    @Autowired
+    private CustomerFeignClient customerFeignClient;
+
+    @Autowired
+    private PatientFeignClient patientFeignClient;
+
+
+    public Page listDataPage(GridParameter gp, Integer withDetail, Integer partId, Integer displayType) {
+        List<BoardItemDO> partBoardItems = this.boardItemFeignClient.listPartAll(partId).getData();
+        List<BoardItemDisplayDO> partDisplays = this.displayConfigFeignClient.listByPartId(partId).getData();
+        if (partBoardItems == null || partBoardItems.size() == 0 || partDisplays == null || partDisplays.size() == 0) {
+            return new Page(gp.getPageNo(), 0L, gp.getPageSize(), new ArrayList());
+        }
+        if (displayType.equals(1)) {
+            partDisplays = partDisplays.stream().filter(p -> p.getPartSubscribe()).collect(Collectors.toList());
+
+        } else {
+            partDisplays = partDisplays.stream().filter(p -> p.getDashBoardShow()).collect(Collectors.toList());
+        }
+        final List<BoardItemDisplayDO> displayConfigDOS = partDisplays;
+        List<DoctorAdviceMatchBoardItemVO> doctorAdviceMapBoardItems = new ArrayList<>();
+        List<String> partHisCodes = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date today = new Date();
+        //his数据患者状态信息
+        PatientDataVO todayPatients = patientFeignClient.getPatientData(sdf.format(today), sdf.format(today)).getData();
+        //在住院患者的主键
+        Set<String> hospitalizePatientKey = new HashSet<>();
+        if (withDetail > 0) {
+            ShopDO part = shopFeignClient.getPartById(partId).getData();
+            if (part != null) {
+                doctorAdviceMapBoardItems = this.doctorAdviceFeignClient.listAdviceReferenceBoardItem(Arrays.asList(part)).getData(); //this.doctorAdviceService.listAdviceReferenceBoardItem(hisCode,Arrays.asList(model));
+                partHisCodes = listPartsRefHisCode(Arrays.asList(part));
+
+            }
+        }
+        final List<String> partHisKey = partHisCodes;
+        if (todayPatients != null) {
+            //当前在院患者主键
+            hospitalizePatientKey = todayPatients.getHospitalized().stream().filter(p -> !StrUtil.isEmpty(p.getBedNo()) && partHisKey.contains(p.getPartKeyval())).map(p -> p.getKeyval()).collect(Collectors.toSet());
+        }
+        final Set<String> patientKeys = hospitalizePatientKey;
+        //查询出在院患者的匹配医嘱
+        final List<DoctorAdviceMatchBoardItemVO> doctorAdviceMap = doctorAdviceMapBoardItems.stream().filter(p -> StrUtil.isNotEmpty(p.getPatientKey()) && patientKeys.contains(p.getPatientKey())).collect(Collectors.toList());
+        List<CustomerFrameVO> hospitalizedBeds = customerFeignClient.getHospitalizedBeds(partId).getData();
+        List<BoardItemConfigDO> partBoardItemConfigDOS = boardItemConfigFeignClient.listPartBoardItemConfig(partId).getData();
+
+
+        List<BoardItemDataVO> collect = partBoardItems.stream().filter(p -> matchDisplay(displayConfigDOS, p)).map(p -> {
+            BoardItemDataVO vo = new BoardItemDataVO();
+            BeanUtil.copyProperties(p, vo);
+            BoardItemDisplayDO boardItemDisplayConfigDO = displayConfigDOS.stream().filter(d -> d.getItemName().equalsIgnoreCase(p.getAreaLabel())).findFirst().orElse(null);
+            if (boardItemDisplayConfigDO == null) {
+                vo.setDisplaySort(null);
+            } else {
+                if (displayType.equals(1)) {
+                    vo.setDisplaySort(boardItemDisplayConfigDO.getSubscribeOrder());
+                } else {
+                    vo.setDisplaySort(boardItemDisplayConfigDO.getDashBoardOrder());
+                }
+            }
+            BoardItemConfigDO configDO = partBoardItemConfigDOS.stream().filter(c -> c.getItemName().equalsIgnoreCase(p.getAreaLabel())).findFirst().orElse(null);
+            if (configDO != null) {
+                vo.setContainsKeywords(configDO.getContainsKeywords());
+                List<DoctorAdviceMatchBoardItemVO> matchAdvice = doctorAdviceMap.stream().filter(ap -> getDoctorAdviceMatchBoardItemSetting(ap, configDO)).sorted(Comparator.comparing(DoctorAdviceMatchBoardItemVO::getCustomerBedNo)).collect(Collectors.toList());
+                if (matchAdvice != null) {
+                    vo.setDoctorAdvices(matchAdvice);
+                } else {
+                    vo.setDoctorAdvices(new ArrayList<>());
+                }
+            }
+
+            //处理手动加入的床位数据展示
+            if (!StringUtil.isEmpty(p.getManualAddData())) {
+                //手动输入的床位列表
+                JSONArray manualBeds = JSON.parseArray(p.getManualAddData());
+                if (!manualBeds.isEmpty()) {
+                    List<DoctorAdviceMatchBoardItemVO> doctorAdvices = vo.getDoctorAdvices();
+                    List<String> adviceBeds = doctorAdvices.stream().map(d -> d.getCustomerBedNo()).collect(Collectors.toList());
+                    List<String> manualBedArr = manualBeds.stream().map(m -> m.toString()).collect(Collectors.toList());
+                    List<String> nomatchBeds = ListUtils.removeAll(manualBedArr, adviceBeds);
+                    if (nomatchBeds != null && nomatchBeds.size() > 0) {
+                        for (String nomatchBed : nomatchBeds) {
+                            DoctorAdviceMatchBoardItemVO dambiVO = new DoctorAdviceMatchBoardItemVO();
+                            dambiVO.setCustomerBedNo(nomatchBed);
+                            dambiVO.setAdviceContent("手工输入床位");
+//                                DoctorAdviceDO doctorAdviceDO = nomatchAdvices.stream().filter(p -> p.getCustomerBedNo().equalsIgnoreCase(nomatchBed)).findFirst().orElse(null);
+                            CustomerFrameVO customerFrameVO = hospitalizedBeds.stream().filter(cf -> !StringUtil.isEmpty(cf.getBedNo()) && cf.getBedNo().equalsIgnoreCase(nomatchBed)).findFirst().orElse(null);
+                            if (customerFrameVO != null) {
+                                dambiVO.setHisKey(customerFrameVO.getId().toString());
+                                dambiVO.setPatientName(customerFrameVO.getNamed());
+                            } else {
+                                dambiVO.setHisKey(ObjectId.next());
+                            }
+                            doctorAdvices.add(dambiVO);
+                        }
+                    }
+                }
+            }
+
+            return vo;
+        }).sorted(Comparator.comparing(BoardItemDataVO::getDisplaySort, Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());//未设置排序的排到最后
+
+
+        return new Page(gp.getPageNo(), (long) collect.size(), gp.getPageSize(), collect.stream().skip((gp.getPageNo() - 1) * gp.getPageSize()).limit(gp.getPageSize()).collect(Collectors.toList()));
+    }
+
+    private boolean matchDisplay(List<BoardItemDisplayDO> displayConfigDOS, BoardItemDO p) {
+        return displayConfigDOS.stream().anyMatch(d -> d.getItemName().equalsIgnoreCase(p.getAreaLabel()));
+    }
+
+
+    public boolean getDoctorAdviceMatchBoardItemSetting(DoctorAdviceMatchBoardItemVO advice, BoardItemConfigDO settingDO) {
+        if (advice == null || settingDO == null) {
+            return false;
+        }
+
+        if (StrUtil.isEmpty(settingDO.getContainsKeywords())) {
+            return false;
+        }
+        //手动选择项目
+        if (!StringUtil.isEmpty(advice.getManualMatchItemMd5()) && advice.getManualMatchItemMd5().equalsIgnoreCase(settingDO.getItemNameMd5())
+        ) {
+            return true;
+        }
+        JSONArray matchCondition = JSON.parseArray(settingDO.getContainsKeywords());
+        if (matchCondition.isEmpty()) { //空json数组
+            return false;
+        }
+        boolean result = false;
+        for (Object o : matchCondition) { //搜索包含的关键字
+            JSONObject conditon = JSON.parseObject(o.toString());
+            JSONArray containsKeywords = new JSONArray();
+            JSONArray excludeKeywords = new JSONArray();
+            if (conditon.containsKey("containKeywords")) {
+                containsKeywords = conditon.getJSONArray("containKeywords");
+                if (!containsKeywords.isEmpty()) {
+                    result = containsKeywords.stream().allMatch(p -> advice.getAdviceContent().toLowerCase().contains(p.toString().toLowerCase()));
+
+                }
+            }
+
+            if (conditon.containsKey("excludeKeywords") && result) { //关键字匹配成功后才需要看是否包含排除的关键字
+                excludeKeywords = conditon.getJSONArray("excludeKeywords");
+                if (!excludeKeywords.isEmpty()) {
+                    result = !excludeKeywords.stream().anyMatch(p -> advice.getAdviceContent().toLowerCase().contains(p.toString().toLowerCase()));
+
+                }
+            }
+
+
+            if (result) { //有匹配中的一组条件,中断循环
+                break;
+            }
+
+
+        }
+        return result;
+    }
+
+    private List<String> listPartsRefHisCode(List<ShopDO> shopDOS) {
+        List<String> refHisCodes = new ArrayList<>();
+        //对接了his的科室his科室主键集合
+        List<String> mainCodes = shopDOS.stream().filter(p -> StrUtil.isNotEmpty(p.getHisCode())).map(p -> p.getHisCode()).collect(Collectors.toList());
+        if (mainCodes != null && mainCodes.size() > 0) {
+            refHisCodes.addAll(mainCodes);
+        }
+        //附加his科室对接
+        List<String> attachHisCode = shopDOS.stream().filter(p -> StrUtil.isNotEmpty(p.getAttachHisCodes())).flatMap(p -> Stream.of(p.getAttachHisCodes().split(","))).collect(Collectors.toList());
+        if (!attachHisCode.isEmpty()) {
+            refHisCodes.addAll(attachHisCode);
+        }
+        List<String> sharedBedHisCode = shopDOS.stream().filter(p -> StrUtil.isNotEmpty(p.getSharedBedHisCodes())).flatMap(p -> Stream.of(p.getSharedBedHisCodes().split(","))).collect(Collectors.toList());
+        if (!sharedBedHisCode.isEmpty()) {
+            refHisCodes.addAll(sharedBedHisCode);
+        }
+        return refHisCodes;
+    }
+
+    public List<VChartPaitentQuantityVO> getPartPatientTrend(Integer partId, String start, String end) {
+
+        List<VChartPaitentQuantityVO> result = new ArrayList<>();
+//        List<ShopDO> shopDOS = shopManager.listByType(ShopTypeEnum.PART.value());
+//        ShopDO part = shopDOS.stream().filter(p -> p.getShopId().equals(partId)).findFirst().orElse(null);
+//
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        SimpleDateFormat sdfMd = new SimpleDateFormat("MM-dd");
+        try {
+            Date startDay = sdf.parse(start);
+            Date endDay = sdf.parse(end);
+            Calendar cld = Calendar.getInstance();
+            Date nextDay = startDay;
+            cld.setTime(startDay);
+            PatientDataVO patients = patientFeignClient.getPatientData(sdf.format(startDay), sdf.format(endDay)).getData();
+            ShopDO part = shopFeignClient.getPartById(partId).getData();
+            List<String> partHisCodes = new ArrayList<>();
+            if (part != null) {
+                partHisCodes = listPartsRefHisCode(Arrays.asList(part));
+
+            }
+            final List<String> hisCodes = partHisCodes;
+            if (patients == null) {
+                return result;
+            } else {
+                //查询本科室指定时间段内在院患者,如果本科室有与其他科室共享床位,需要排除住在其他科室的患者。
+                List<PatientDO> hospitalized = patients.getHospitalized();
+                List<PatientDO> inHospital = patients.getInHospital();
+                List<PatientDO> outHospital = patients.getOutHospital();
+                while (nextDay.before(endDay) || nextDay.compareTo(endDay) == 0) {
+
+                    final Date finalNextDay = nextDay;
+                    //入院时间小于等于当日时间且出院时间大于当日时间
+                    if (hospitalized != null) {
+                        List<PatientDO> nextDayIn = hospitalized.stream().filter(p -> StrUtil.isNotEmpty(p.getPartKeyval()) && hisCodes.contains(p.getPartKeyval()) &&
+                                (!StringUtil.isEmpty(p.getIndate()) && p.getIndate().compareToIgnoreCase(sdf.format(finalNextDay)) <= 0 && StringUtil.isEmpty(p.getOutdate()) ||
+                                        !StringUtil.isEmpty(p.getOutdate()) && p.getOutdate().compareToIgnoreCase(sdf.format(finalNextDay)) > 0)).collect(toList());
+                        result.add(new VChartPaitentQuantityVO(sdfMd.format(finalNextDay), nextDayIn.size(), "在院人数"));
+                    }
+                    if (outHospital != null) {
+                        List<PatientDO> dayOut = outHospital.stream().filter(p -> StrUtil.isNotEmpty(p.getPartKeyval()) && hisCodes.contains(p.getPartKeyval()) &&
+                                (!StringUtil.isEmpty(p.getOutdate()) && p.getOutdate().equalsIgnoreCase(sdf.format(finalNextDay)))).collect(toList());
+                        result.add(new VChartPaitentQuantityVO(sdfMd.format(finalNextDay), dayOut.size(), "出院人数"));
+
+                    }
+                    if (inHospital != null) {
+                        List<PatientDO> dayIn = inHospital.stream().filter(p -> StrUtil.isNotEmpty(p.getPartKeyval()) && hisCodes.contains(p.getPartKeyval()) &&
+                                (!StringUtil.isEmpty(p.getIndate()) && p.getIndate().equalsIgnoreCase(sdf.format(finalNextDay)))).collect(toList());
+                        result.add(new VChartPaitentQuantityVO(sdfMd.format(finalNextDay), dayIn.size(), "入院人数"));
+                        cld.add(Calendar.DATE, 1);
+                    }
+                    nextDay = cld.getTime();
+
+                }
+
+
+            }
+            return result;
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+
+    }
+}

+ 51 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/DepartmentService.java

@@ -0,0 +1,51 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DepartmentDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.feignclient.open.DepartmentFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ShopFeignClient;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 15:56
+ * ${description}
+ */
+@Service
+@Slf4j
+public class DepartmentService {
+
+    @Autowired
+    private DepartmentFeignClient departmentFeignClient;
+
+    @Autowired
+    private ShopFeignClient shopFeignClient;
+
+    public List<ShopDO> saveDepartments(List<DepartmentDO> departments) {
+        this.departmentFeignClient.saveDepartments(departments).getData();
+        List<ShopDO> data = this.shopFeignClient.syncDepartment(departments).getData();
+        return data;
+
+    }
+
+    public ShopDO saveDepartment(DepartmentDO departmentDO) {
+        DepartmentDO data = this.departmentFeignClient.saveSingleDepartment(departmentDO).getData();
+        ShopDO shopDO = this.shopFeignClient.syncSingleDepartment(departmentDO).getData();
+        return shopDO;
+    }
+
+
+    public ShopDO syncSingleByKey(String key) {
+        DepartmentDO departmentDO = this.departmentFeignClient.getDepartment(key).getData();
+        if (departmentDO == null) {
+            throw new ServiceException("找不到科室信息");
+        }
+        return this.shopFeignClient.syncSingleDepartment(departmentDO).getData();
+    }
+}

+ 85 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/DoctorAdviceService.java

@@ -0,0 +1,85 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import cn.hutool.core.util.StrUtil;
+import com.wdklian.ncs.ms.common.entity.open.dos.DoctorAdviceDO;
+import com.wdklian.ncs.ms.feignclient.open.AdviceUniqueContentFeignClient;
+import com.wdklian.ncs.ms.feignclient.open.DoctorAdviceFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.BoardItemFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.NursingMarkFeignClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 17:33
+ * ${description}
+ */
+@Service
+@Slf4j
+public class DoctorAdviceService {
+
+    @Autowired
+    private DoctorAdviceFeignClient doctorAdviceFeignClient;
+
+    @Autowired
+    private NursingMarkFeignClient nursingMarkFeignClient;
+
+    @Autowired
+    private BoardItemFeignClient boardItemFeignClient;
+
+    @Autowired
+    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    @Autowired
+    private AdviceUniqueContentFeignClient adviceUniqueContentFeignClient;
+
+    public List<DoctorAdviceDO> saveDoctorAdvice(List<DoctorAdviceDO> doctoradvices) {
+
+        List<DoctorAdviceDO> changedAdvices = this.doctorAdviceFeignClient.syncDoctorAdvice(doctoradvices).getData();
+        handleAdviceChange(changedAdvices);
+        //更新唯一条目
+        this.adviceUniqueContentFeignClient.updateAdviceUniqueContent(changedAdvices);
+        return changedAdvices;
+    }
+
+    public DoctorAdviceDO saveDoctorAdvice(DoctorAdviceDO doctorAdvice) {
+        DoctorAdviceDO changedAdvice = this.doctorAdviceFeignClient.syncSingleDoctorAdvice(doctorAdvice).getData();
+        if (changedAdvice != null && StrUtil.isNotEmpty(changedAdvice.getHisPartKey())) {
+            //这里无需得到执行结果,开启线程去执行
+            Runnable r = () -> {
+                //更新唯一条目
+                this.adviceUniqueContentFeignClient.updateAdviceUniqueContent(Arrays.asList(changedAdvice));
+                this.nursingMarkFeignClient.renewDepartByDepartKey(changedAdvice.getHisPartKey());
+                this.boardItemFeignClient.renewByDepartKey(changedAdvice.getHisPartKey());
+            };
+            threadPoolTaskExecutor.submit(r);
+        }
+        return changedAdvice;
+    }
+
+    public int deleteDoctorAdvice(String[] hisKeys) {
+
+        List<DoctorAdviceDO> deletedAdvices = this.doctorAdviceFeignClient.deleteDoctorAdvice(hisKeys).getData();
+        handleAdviceChange(deletedAdvices);
+
+        return 0;
+    }
+
+    private void handleAdviceChange(List<DoctorAdviceDO> changedAdvices) {
+        if (changedAdvices != null && changedAdvices.size() > 0) {//医嘱信息有变化,刷新有变化的科室的护理标识和看板条目内容
+            //这里无需得到执行结果,开启线程去执行
+            Runnable r = () -> {
+                List<String> adviceChangedDepartKeys = changedAdvices.stream().map(p -> p.getHisPartKey()).collect(Collectors.toList());
+                this.nursingMarkFeignClient.renewDepartNursingByHisPartKeys(adviceChangedDepartKeys);
+                this.boardItemFeignClient.renewDepartBoardItemByHisPartKeys(adviceChangedDepartKeys);
+            };
+            threadPoolTaskExecutor.submit(r);
+        }
+    }
+}

+ 49 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/EmployeeService.java

@@ -0,0 +1,49 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.EmployeeDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ClerkDO;
+import com.wdklian.ncs.ms.feignclient.open.EmployeeFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ClerkFeignClient;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:17
+ * ${description}
+ */
+@Service
+@Slf4j
+public class EmployeeService {
+
+    @Autowired
+    private EmployeeFeignClient employeeFeignClient;
+    @Autowired
+    private ClerkFeignClient clerkFeignClient;
+
+    public List<ClerkDO> saveEmployee(List<EmployeeDO> employees) {
+        this.employeeFeignClient.saveEmployeeList(employees).getData();
+        List<ClerkDO> clerkDOS = this.clerkFeignClient.syncEmployee(employees).getData();
+        return clerkDOS;
+    }
+
+    public ClerkDO saveEmployee(EmployeeDO employee) {
+
+        this.employeeFeignClient.saveEmployee(employee).getData();
+        ClerkDO clerkDO = this.clerkFeignClient.syncSingleEmployee(employee).getData();
+        return clerkDO;
+    }
+
+    public ClerkDO syncEmployeeByKey(String key) {
+        EmployeeDO employeeDO = this.employeeFeignClient.getEmployee(key).getData();
+        if (employeeDO == null) {
+            throw new ServiceException("不存在的职员!");
+        }
+        return this.clerkFeignClient.syncSingleEmployee(employeeDO).getData();
+
+    }
+}

+ 68 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/ManualInputBoardItemService.java

@@ -0,0 +1,68 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.ManualInputBoardItemConfingDO;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.ManualInputBoardItemDO;
+import com.wdklian.ncs.ms.feignclient.open.ManualInputBoardItemConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ManualInputBoardItemFeignClient;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 17:38
+ * ${description}
+ */
+@Service
+@Slf4j
+public class ManualInputBoardItemService {
+
+    @Autowired
+    private ManualInputBoardItemConfigFeignClient manualInputBoardItemConfigFeignClient;
+
+    @Autowired
+    private ManualInputBoardItemFeignClient manualInputBoardItemFeignClient;
+
+    public ManualInputBoardItemConfingDO add(ManualInputBoardItemConfingDO manualInputBoardItemSettingDO) {
+        ManualInputBoardItemConfingDO data = this.manualInputBoardItemConfigFeignClient.add(manualInputBoardItemSettingDO).getData();
+        ManualInputBoardItemDO manualInputBoardItemDO = new ManualInputBoardItemDO();
+        manualInputBoardItemDO.setItemName(data.getItemName());
+        manualInputBoardItemDO.setItemNameMd5(data.getItemNameMd5());
+        manualInputBoardItemDO.setPartId(data.getForPartId());
+        manualInputBoardItemDO.setRemark(data.getRemark());
+        this.manualInputBoardItemFeignClient.add(manualInputBoardItemDO);
+        return data;
+    }
+
+    public ManualInputBoardItemConfingDO edit(ManualInputBoardItemConfingDO manualInputBoardItemSettingDO, Integer id) {
+        ManualInputBoardItemConfingDO old = this.manualInputBoardItemConfigFeignClient.get(id).getData();
+        CommonResult<ManualInputBoardItemConfingDO> result = this.manualInputBoardItemConfigFeignClient.edit(manualInputBoardItemSettingDO, id);
+        if (result.getCode() == 200) {
+
+            ManualInputBoardItemDO manualInputBoardItemDO = this.manualInputBoardItemFeignClient.getPartItemByName(old.getForPartId(), old.getItemNameMd5()).getData();
+            if (manualInputBoardItemDO != null) {
+                manualInputBoardItemDO.setItemName(manualInputBoardItemSettingDO.getItemName());
+                manualInputBoardItemDO.setItemNameMd5(manualInputBoardItemSettingDO.getItemNameMd5());
+                manualInputBoardItemDO.setPartId(manualInputBoardItemSettingDO.getForPartId());
+                manualInputBoardItemDO.setRemark(manualInputBoardItemSettingDO.getRemark());
+                this.manualInputBoardItemFeignClient.edit(manualInputBoardItemDO, manualInputBoardItemDO.getId());
+            }
+        }
+        return result.getData();
+    }
+
+    public void delete(Integer[] ids) {
+
+        List<ManualInputBoardItemConfingDO> data = this.manualInputBoardItemConfigFeignClient.listByIds(ids).getData();
+        CommonResult result = this.manualInputBoardItemConfigFeignClient.delete(ids);
+        if (result.getCode() == 200) {
+            for (ManualInputBoardItemConfingDO datum : data) {
+                this.manualInputBoardItemFeignClient.deletePartItem(datum.getForPartId(), datum.getItemNameMd5());
+            }
+        }
+    }
+}

+ 300 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/NursingMarkCategoryService.java

@@ -0,0 +1,300 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import cn.hutool.core.lang.ObjectId;
+import cn.hutool.core.util.StrUtil;
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkCategoryConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkOptionConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NursingMarkCategoryConfigVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigDisplayDO;
+
+
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigOptionDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.common.enums.ShopTypeEnum;
+import com.wdklian.ncs.ms.feignclient.open.NursingMarkCategoryConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.open.NursingMarkOptionConfigFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.NursingMarkDisplayFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.NursingMarkFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.ShopFeignClient;
+import com.wdklian.ncs.ms.framework.database.annotation.Table;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import com.wdklian.ncs.ms.framework.mvc.JsonResponse;
+import com.wdklian.ncs.ms.framework.util.BeanUtil;
+import com.wdklian.ncs.ms.framework.util.DateUtil;
+import com.wdklian.ncs.ms.framework.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 15:24
+ * ${description}
+ */
+@Service
+@Slf4j
+public class NursingMarkCategoryService {
+
+    @Autowired
+    private NursingMarkCategoryConfigFeignClient categoryConfigFeignClient;
+
+    @Autowired
+    private NursingMarkOptionConfigFeignClient nursingMarkOptionConfigFeignClient;
+
+    @Autowired
+    private NursingMarkDisplayFeignClient nursingMarkDisplayFeignClient;
+
+    @Autowired
+    private ShopFeignClient shopFeignClient;
+
+    @Autowired
+    private NursingMarkFeignClient nursingMarkFeignClient;
+
+
+    public List<NursingMarkCategoryConfigVO> list(Integer partId) {
+        List<NursingMarkCategoryConfigVO> data = this.categoryConfigFeignClient.list(partId).getData();
+
+
+        if(data!=null&&data.size()>0){
+            List<NurseConfigDisplayDO> displayDOS = this.nursingMarkDisplayFeignClient.listByPartId(partId).getData();
+            for (NursingMarkCategoryConfigVO datum : data) {
+                NurseConfigDisplayDO nurseConfigDisplayDO = displayDOS.stream().filter(p -> !StrUtil.isEmpty(p.getConfigNameMd5()) && p.getConfigNameMd5().equalsIgnoreCase(datum.getNameMd5())).findFirst().orElse(null);
+                if (nurseConfigDisplayDO != null) {
+                    datum.setDashBoardShow(nurseConfigDisplayDO.getDashBoardShow());
+                } else {
+                    datum.setDashBoardShow(false);
+                }
+            }
+        }
+
+        return data;
+
+    }
+
+    public List copyDefaultToPart(Integer[] categoryIds, Integer partId) {
+        return this.copyDefaultToPart(categoryIds, partId, false);
+    }
+
+
+    public List copyDefaultToPart(Integer[] categoryIds, Integer partId, Boolean force) {
+        List<NursingMarkCategoryConfigVO> categoryConfigVOS = this.categoryConfigFeignClient.list(-1).getData();
+        List<NursingMarkCategoryConfigVO> partCategory = this.categoryConfigFeignClient.list(partId).getData();
+        for (NursingMarkCategoryConfigVO categoryConfigVO : categoryConfigVOS) {
+            if (ArrayUtils.contains(categoryIds, categoryConfigVO.getId())) {
+                NursingMarkCategoryConfigVO partSameName = partCategory.stream().filter(p -> StrUtil.isNotEmpty(p.getNameMd5()) && p.getNameMd5().equalsIgnoreCase(categoryConfigVO.getNameMd5())).findFirst().orElse(null);
+                if (!force && partSameName != null) {
+                    throw new ServiceException("科室中存在同名分类[" + categoryConfigVO.getCategoryName() + "],如需替换,请使用强制拷贝!");
+                }
+                if (partSameName != null) {
+                    this.categoryConfigFeignClient.delete(partSameName.getId());
+                }
+                NursingMarkCategoryConfigDO categoryConfigDO = new NursingMarkCategoryConfigDO();
+                BeanUtil.copyProperties(categoryConfigVO, categoryConfigDO);
+                categoryConfigDO.setForPartId(partId);
+                categoryConfigDO.setCopyFrom(categoryConfigVO.getId());
+                categoryConfigDO.setId(null);
+                NursingMarkCategoryConfigDO add = this.categoryConfigFeignClient.add(categoryConfigDO).getData();
+                List<NursingMarkOptionConfigDO> child = categoryConfigVO.getChild();
+                if (child != null && child.size() > 0) {
+                    for (NursingMarkOptionConfigDO nursingMarkOptionConfigDO : child) {
+                        NursingMarkOptionConfigDO optionConfigDO = new NursingMarkOptionConfigDO();
+                        BeanUtil.copyProperties(nursingMarkOptionConfigDO, optionConfigDO);
+                        optionConfigDO.setCategoryId(add.getId());
+                        optionConfigDO.setCopyFrom(nursingMarkOptionConfigDO.getId());
+                        optionConfigDO.setForPartId(partId);
+                        optionConfigDO.setId(null);
+                        this.nursingMarkOptionConfigFeignClient.add(optionConfigDO);
+                    }
+                }
+            }
+        }
+        return this.categoryConfigFeignClient.list(partId).getData();
+    }
+
+    public JsonResponse foceCopyDefaultToPart() {
+
+        List<NursingMarkCategoryConfigVO> categoryConfigVOS = this.categoryConfigFeignClient.list(-1).getData();
+        List<ShopDO> shopDOS = this.shopFeignClient.listShopByType(ShopTypeEnum.PART.value()).getData();
+
+        for (ShopDO shopDO : shopDOS) {
+            NursingMarkCategoryConfigDO categoryConfigDO = new NursingMarkCategoryConfigDO();
+            NursingMarkOptionConfigDO optionConfigDO = new NursingMarkOptionConfigDO();
+            List<NursingMarkCategoryConfigVO> partCategory = this.categoryConfigFeignClient.list(shopDO.getShopId()).getData();
+            for (NursingMarkCategoryConfigVO categoryConfigVO : categoryConfigVOS) {
+                NursingMarkCategoryConfigVO sameNameCategory = partCategory.stream().filter(p -> StrUtil.isNotEmpty(p.getNameMd5()) && p.getNameMd5().equalsIgnoreCase(categoryConfigVO.getNameMd5())).findFirst().orElse(null);
+                if (sameNameCategory != null && !categoryConfigVO.getId().equals(sameNameCategory.getCopyFrom())) { //存在同名分类,但不是从categoryConfigVO拷贝而来,删除这个项目及其子项
+                    this.categoryConfigFeignClient.delete(sameNameCategory.getId());
+                    partCategory.remove(sameNameCategory);
+                }
+                NursingMarkCategoryConfigVO copyFrom = partCategory.stream().filter(p -> p.getCopyFrom() != null && p.getCopyFrom().equals(categoryConfigVO.getId()) && p.getForPartId() != null && p.getForPartId().equals(shopDO.getShopId())).findFirst().orElse(null);
+                List<NursingMarkOptionConfigDO> copyChild = new ArrayList<>();
+                if (copyFrom != null) {
+                    copyChild = copyFrom.getChild();
+                    BeanUtil.copyProperties(copyFrom, categoryConfigDO);
+                    BeanUtil.copyProperties(categoryConfigVO, categoryConfigDO);
+                    categoryConfigDO.setCopyFrom(categoryConfigVO.getId());
+                    categoryConfigDO.setId(copyFrom.getId());
+                    categoryConfigDO.setForPartId(shopDO.getShopId());
+                    categoryConfigDO = this.categoryConfigFeignClient.edit(categoryConfigDO, categoryConfigDO.getId()).getData();
+                } else {
+                    BeanUtil.copyProperties(categoryConfigVO, categoryConfigDO);
+                    categoryConfigDO.setCopyFrom(categoryConfigVO.getId());
+                    categoryConfigDO.setForPartId(shopDO.getShopId());
+                    categoryConfigDO.setId(null);
+                    categoryConfigDO = this.categoryConfigFeignClient.add(categoryConfigDO).getData();
+
+                }
+                List<NursingMarkOptionConfigDO> child = categoryConfigVO.getChild();
+                if (child != null && child.size() > 0) {
+                    for (NursingMarkOptionConfigDO nursingMarkOptionConfigDO : child) {
+                        NursingMarkOptionConfigDO optionConfigDO1 = copyChild.stream().filter(p -> p.getCopyFrom() != null && p.getCopyFrom().equals(nursingMarkOptionConfigDO.getId()) && p.getForPartId() != null && p.getForPartId().equals(shopDO.getShopId())).findFirst().orElse(null);
+                        if (optionConfigDO1 == null) {
+
+                            BeanUtil.copyProperties(nursingMarkOptionConfigDO, optionConfigDO);
+                            optionConfigDO.setCategoryId(categoryConfigDO.getId());
+                            optionConfigDO.setCopyFrom(nursingMarkOptionConfigDO.getId());
+                            optionConfigDO.setForPartId(shopDO.getShopId());
+                            optionConfigDO.setId(null);
+                            this.nursingMarkOptionConfigFeignClient.add(optionConfigDO);
+                        } else {
+                            BeanUtil.copyProperties(optionConfigDO1, optionConfigDO);
+                            BeanUtil.copyProperties(nursingMarkOptionConfigDO, optionConfigDO);
+                            optionConfigDO.setId(optionConfigDO1.getId());
+                            optionConfigDO.setCopyFrom(nursingMarkOptionConfigDO.getId());
+                            optionConfigDO.setCategoryId(categoryConfigDO.getId());
+                            optionConfigDO.setForPartId(shopDO.getShopId());
+                            this.nursingMarkOptionConfigFeignClient.edit(optionConfigDO, optionConfigDO.getId());
+                        }
+
+                    }
+                }
+            }
+        }
+
+        return JsonResponse.successResponse();
+
+    }
+
+    public JsonResponse applyNurseConfig(Integer partId) {
+
+        List<NursingMarkCategoryConfigVO> list = this.categoryConfigFeignClient.listAll().getData();
+        //所有床头屏医嘱分类
+        List<NurseConfigDO> nurseConfigDOS = this.nursingMarkFeignClient.listAllNursingMark().getData();
+        //所有床头屏医嘱分类的选项
+        List<NurseConfigOptionDO> nurseConfigOptionDOS = this.nursingMarkFeignClient.listAllNursingMarkOption().getData();
+        //要处理的科室列表
+        List<ShopDO> shops = new ArrayList<>();
+        if (partId.equals(-1)) {
+            shops.addAll(this.shopFeignClient.listShopByType(ShopTypeEnum.PART.value()).getData());
+        } else {
+            shops.add(this.shopFeignClient.getPartById(partId).getData());
+        }
+
+        if (list.size() > 0) {
+            //删除已经在配置中不存在的床头屏医嘱分类
+            String deleteOptionsSqlTpl = "delete from " + NurseConfigOptionDO.class.getAnnotation(Table.class).name() + " where find_in_set(MD5(option_name),'%s')=0 and ncfg_id =%d";
+            List<String> clearOptionsSql = new ArrayList<>();
+
+            for (NursingMarkCategoryConfigVO screenAdviceCategoryVO : list) {
+                for (ShopDO shop : shops) {
+                    //删掉已存在的但是配置中没有的记录
+                    String categoryNamesMd5 = list.stream().filter(p -> p.getForPartId().equals(shop.getShopId())).map(p -> p.getNameMd5()).collect(Collectors.joining(","));
+                    if (screenAdviceCategoryVO.getForPartId().equals(shop.getShopId())) { //本科室的分类
+                        List<NurseConfigDO> partNurseConfigDOs = nurseConfigDOS.stream().filter(p -> p.getPartId().equals(shop.getShopId())).collect(Collectors.toList());
+                        List<NurseConfigOptionDO> partOptionDOS = nurseConfigOptionDOS.stream().filter(p -> p.getPartId().equals(shop.getShopId())).collect(Collectors.toList());
+                        //同步分类
+                        NurseConfigDO nurseConfigDO = this.syncPartScreenAdviceCategory(screenAdviceCategoryVO, shop, partNurseConfigDOs);
+                        List<NursingMarkOptionConfigDO> child = screenAdviceCategoryVO.getChild();
+                        if (!screenAdviceCategoryVO.getBoolAuto() && child != null && child.size() > 0) {
+                            List<NursingMarkOptionConfigDO> partScreenAdviceItemSettingDOs = child.stream().filter(p -> !StringUtil.isEmpty(p.getItemNameMd5()) && p.getForPartId().equals(shop.getShopId())).collect(Collectors.toList());
+                            String optionsNameMd5s = partScreenAdviceItemSettingDOs.stream().map(p -> p.getItemNameMd5()).collect(Collectors.joining(","));
+                            String formatSql = String.format(deleteOptionsSqlTpl, optionsNameMd5s, nurseConfigDO.getId());
+                            clearOptionsSql.add(formatSql);
+                            for (NursingMarkOptionConfigDO settingDO : partScreenAdviceItemSettingDOs) {
+                                this.syncPartScreenAdviceItem(settingDO, nurseConfigDO, partOptionDOS);
+                            }
+                        }
+                    }
+                    //删除配置中没有的分类,及其选项
+                    String sqlNurseConfigClear = " delete config,op from " + NurseConfigDO.class.getAnnotation(Table.class).name() + " as config left join " + NurseConfigOptionDO.class.getAnnotation(Table.class).name() + " as op on config.id=op.ncfg_id  where not find_in_set(MD5(config.config_name),'" + categoryNamesMd5 + "') and config.part_id =" + shop.getShopId();
+                    //反向删除找不到分类的项目,由于更新用户护理项时是删除重建,这里可以不删除用户护理项mapping记录
+                    String sqlNurseConfigOptionClear = "delete op from " + NurseConfigOptionDO.class.getAnnotation(Table.class).name() + " as op left join " + NurseConfigDO.class.getAnnotation(Table.class).name() + " as config on config.id=op.ncfg_id where config.id is null ";
+                    clearOptionsSql.add(sqlNurseConfigClear);
+                    clearOptionsSql.add(sqlNurseConfigOptionClear);
+
+                }
+            }
+            //清理已经不在设置中的分类和选项
+            if (clearOptionsSql.size() > 0) {
+                this.nursingMarkFeignClient.batchUpdate(clearOptionsSql.toArray(new String[clearOptionsSql.size()]));
+            }
+
+        } else { //清空配置
+            List<String> clearConfigSqls = new ArrayList<>();
+            for (ShopDO shop : shops) {
+                String sql = "delete config,op from " + NurseConfigDO.class.getAnnotation(Table.class).name() + " as config left join " + NurseConfigOptionDO.class.getAnnotation(Table.class).name() + " as op on config.id=op.ncfg_id where config.part_id =" + shop.getShopId();
+                clearConfigSqls.add(sql);
+            }
+            if (clearConfigSqls.size() > 0) {
+                this.nursingMarkFeignClient.batchUpdate(clearConfigSqls.toArray(new String[clearConfigSqls.size()]));
+            }
+        }
+        return JsonResponse.successResponse(list);
+    }
+
+    //应用指定科室的指定床头屏医嘱分类
+    private NurseConfigDO syncPartScreenAdviceCategory(NursingMarkCategoryConfigVO screenAdviceCategoryVO, ShopDO shop, List<NurseConfigDO> partNurseConfigDOs) {
+
+        NurseConfigDO nurseConfigDO = partNurseConfigDOs.stream().filter(p -> StringUtil.md5(p.getConfigName()).equalsIgnoreCase(screenAdviceCategoryVO.getNameMd5())).findFirst().orElse(null);
+        if (nurseConfigDO == null) {
+            nurseConfigDO = new NurseConfigDO();
+            nurseConfigDO.setPartId(shop.getShopId());
+            nurseConfigDO.setConfigName(screenAdviceCategoryVO.getCategoryName());
+            nurseConfigDO.setUnionId(ObjectId.next());
+            nurseConfigDO.setBoolCritical(screenAdviceCategoryVO.getCritical());
+            nurseConfigDO.setIndexNo(screenAdviceCategoryVO.getIndexNo());
+            nurseConfigDO.setDefaultColor(screenAdviceCategoryVO.getDefaultColor().replace("#", ""));
+            nurseConfigDO.setBoolManual(screenAdviceCategoryVO.getBoolManual());
+            nurseConfigDO= this.nursingMarkFeignClient.addNursingConfig(nurseConfigDO).getData();
+        } else {
+            nurseConfigDO.setBoolCritical(screenAdviceCategoryVO.getCritical());
+            nurseConfigDO.setIndexNo(screenAdviceCategoryVO.getIndexNo());
+            nurseConfigDO.setDefaultColor(screenAdviceCategoryVO.getDefaultColor().replace("#", ""));
+            nurseConfigDO.setSyncTime(DateUtil.getDateline());
+            nurseConfigDO.setBoolManual(screenAdviceCategoryVO.getBoolManual());
+            this.nursingMarkFeignClient.updateNursingConfig(nurseConfigDO, nurseConfigDO.getId());
+        }
+        return nurseConfigDO;
+    }
+
+
+    //同步应用床头屏医嘱分类选择项
+    private void syncPartScreenAdviceItem(NursingMarkOptionConfigDO settingDO, NurseConfigDO nurseConfigDO, List<NurseConfigOptionDO> partOptionDOS) {
+        //查询是否存在与设置对应的项目
+        NurseConfigOptionDO nurseConfigOptionDO = partOptionDOS.stream().filter(p -> !StringUtil.isEmpty(p.getOptionName()) &&
+                StringUtil.md5(p.getOptionName()).equalsIgnoreCase(settingDO.getItemNameMd5()) && p.getNcfgId().equals(nurseConfigDO.getId())).findFirst().orElse(null);
+        if (nurseConfigOptionDO == null) {
+            nurseConfigOptionDO = new NurseConfigOptionDO();
+            nurseConfigOptionDO.setCreateTime(DateUtil.getDateline());
+            nurseConfigOptionDO.setNcfgId(nurseConfigDO.getId());
+            nurseConfigOptionDO.setUnionId(ObjectId.next());
+            nurseConfigOptionDO.setOptionName(settingDO.getItemName());
+            nurseConfigOptionDO.setColorRgb(settingDO.getColor().replace("#", ""));
+            nurseConfigOptionDO.setPartId(nurseConfigDO.getPartId());
+            this.nursingMarkFeignClient.addNursingOptionConfig(nurseConfigOptionDO);
+        } else {
+            nurseConfigOptionDO.setUpdateTime(DateUtil.getDateline());
+            nurseConfigOptionDO.setOptionName(settingDO.getItemName());
+            nurseConfigOptionDO.setColorRgb(settingDO.getColor().replace("#", ""));
+            nurseConfigOptionDO.setPartId(nurseConfigDO.getPartId());
+            this.nursingMarkFeignClient.updateNursingOptionConfig(nurseConfigOptionDO, nurseConfigOptionDO.getId());
+        }
+    }
+
+}

+ 267 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/PartTempBedService.java

@@ -0,0 +1,267 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import cn.hutool.core.lang.ObjectId;
+import cn.hutool.core.util.StrUtil;
+import com.wdklian.ncs.ms.common.entity.open.dos.PartTempBedDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.DeviceDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.FrameDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.CustomerFrameVO;
+import com.wdklian.ncs.ms.common.entity.system.vos.FrameRelationshipVO;
+import com.wdklian.ncs.ms.common.entity.system.vos.PartTempBedVO;
+
+import com.wdklian.ncs.ms.common.enums.DeviceTypeEnum;
+import com.wdklian.ncs.ms.common.enums.FrameTypeEnum;
+import com.wdklian.ncs.ms.feignclient.open.PartTempBedFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.CustomerFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.DeviceFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.FrameFeignClient;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.util.BeanUtil;
+import com.wdklian.ncs.ms.framework.util.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 09:20
+ * ${description}
+ */
+@Service
+@Slf4j
+public class PartTempBedService {
+
+    @Autowired
+    private PartTempBedFeignClient partTempBedFeignClient;
+
+    @Autowired
+    private CustomerFeignClient customerFeignClient;
+
+    @Autowired
+    private FrameFeignClient frameFeignClient;
+
+    @Autowired
+    private DeviceFeignClient deviceFeignClient;
+
+    public Page<PartTempBedVO> list(GridParameter gp) {
+        Page<PartTempBedDO> pageDO = partTempBedFeignClient.list(gp).getData();
+        List<PartTempBedDO> bedDOS = pageDO.getData();
+
+
+        List<PartTempBedVO> tempBedsVOS = new ArrayList<>();
+        if (bedDOS != null && bedDOS.size() > 0) {
+            List<CustomerFrameVO> partCustomerFrameVos = customerFeignClient.getHospitalizedBeds(bedDOS.get(0).getPartId()).getData();
+            tempBedsVOS = bedDOS.stream().map(p -> {
+                CustomerFrameVO customerFrameVO = partCustomerFrameVos.stream().filter(k -> !StrUtil.isEmpty(k.getBedNo()) && k.getBedNo().equalsIgnoreCase(p.getBedNo())).findFirst().orElse(null);
+                PartTempBedVO vo = new PartTempBedVO();
+                BeanUtil.copyProperties(p, vo);
+                if (customerFrameVO != null) {
+                    vo.setCustomerName(customerFrameVO.getNamed());
+                }
+                return vo;
+            }).collect(Collectors.toList());
+
+        }
+        return new Page(pageDO.getPageNo(), pageDO.getDataTotal(), pageDO.getPageSize(), tempBedsVOS);
+
+
+    }
+
+    public PartTempBedDO add(PartTempBedDO partTempBedsDO) {
+        FrameDO bedFrame = this.frameFeignClient.getFrameByName(partTempBedsDO.getPartId(), FrameTypeEnum.BED.value(), partTempBedsDO.getBedNo()).getData();
+        PartTempBedDO partTempBedByBedNo = this.partTempBedFeignClient.getPartTempBedByBedNo(partTempBedsDO.getPartId(), partTempBedsDO.getBedNo()).getData();
+        if (bedFrame != null || partTempBedByBedNo != null) {
+            throw new ServiceException("已存在的床位,无需新增!");
+        }
+        FrameDO virtual_room = this.frameFeignClient.getFrameByName(partTempBedsDO.getPartId(), FrameTypeEnum.ROOM.value(), "v-room").getData();
+        if (virtual_room == null) {
+            FrameDO partFrame = this.frameFeignClient.getPartFrame(partTempBedsDO.getPartId()).getData();
+            if (partFrame != null) {
+                virtual_room = new FrameDO();
+                virtual_room.setPartId(partTempBedsDO.getPartId());
+                virtual_room.setCreateTime(DateUtil.getDateline());
+                virtual_room.setName("v-room");
+                virtual_room.setFullName("v-room");
+                virtual_room.setParentId(partFrame.getId());
+                virtual_room.setAlias("v-room");
+                virtual_room.setType(FrameTypeEnum.ROOM.value());
+                virtual_room.setUnionId(ObjectId.next());
+                virtual_room.setSort(10000);
+                this.frameFeignClient.add(virtual_room);
+            } else {
+                throw new ServiceException("科室空间错误!");
+            }
+        }
+
+        if (!StrUtil.isEmpty(partTempBedsDO.getEthMac()) && partTempBedsDO.getDeviceType() != null) {
+            DeviceDO deviceByEthMac = this.deviceFeignClient.getDeviceByEthMac(partTempBedsDO.getEthMac()).getData();
+            //设备存在且不是正常注册设备设备,需要先删除,否则不允许操作,不然可能会把正常的设备给删除了
+            if (deviceByEthMac != null) {
+                FrameRelationshipVO frameAndParent = this.frameFeignClient.getFrameAndParent(deviceByEthMac.getFrameId()).getData();
+                if (frameAndParent != null && !frameAndParent.getParentName().equalsIgnoreCase("v-room")) {
+                    throw new ServiceException("设备地址码错误,请检查后重新输入!");
+                }
+                //如果其他床位使用过该设备,把他更新掉
+                List<PartTempBedDO> otherUsing = this.partTempBedFeignClient.getPartTempBedDeviceTypeAndMac(partTempBedsDO.getDeviceType(), partTempBedsDO.getEthMac()).getData();
+                if (otherUsing != null && otherUsing.size() > 0) {
+                    for (PartTempBedDO tempBedsDO : otherUsing) {
+                        tempBedsDO.setDeviceType(null);
+                        tempBedsDO.setEthMac("");
+                        this.partTempBedFeignClient.edit(tempBedsDO, tempBedsDO.getId());
+                    }
+                }
+                //删除设备
+                this.deviceFeignClient.delete(new Integer[]{deviceByEthMac.getId()});
+            }
+        }
+
+        PartTempBedDO data = this.partTempBedFeignClient.add(partTempBedsDO).getData();
+        // 给科室创建床位
+        bedFrame = new FrameDO();
+        //添加临时床位空间结构
+        addTempBedFrame(partTempBedsDO, bedFrame, virtual_room, data.getId());
+        //添加床位设备
+        handlerDeviceForTempBed(partTempBedsDO, bedFrame);
+
+        return data;
+    }
+
+    private void handlerDeviceForTempBed(PartTempBedDO partTempBedsDO, FrameDO bedFrame) {
+        //绑定设备
+        if (!StrUtil.isEmpty(partTempBedsDO.getEthMac()) && partTempBedsDO.getDeviceType() != null) {
+            DeviceDO deviceDO = new DeviceDO();
+            deviceDO.setEthMac(partTempBedsDO.getEthMac());
+            deviceDO.setDeviceType(partTempBedsDO.getDeviceType());
+            deviceDO.setPartId(partTempBedsDO.getPartId());
+            deviceDO.setName(DeviceTypeEnum.parse(partTempBedsDO.getDeviceType()).typeName());
+            deviceDO.setCode(DeviceTypeEnum.parse(partTempBedsDO.getDeviceType()).typeName() + partTempBedsDO.getBedNo());
+            deviceDO.setFrameId(bedFrame.getId());
+            deviceDO.setCreateTime(DateUtil.getDateline());
+            deviceDO.setStatus(1);
+            deviceDO.setModel(DeviceTypeEnum.parse(partTempBedsDO.getDeviceType()).typeName() + partTempBedsDO.getBedNo());
+            this.deviceFeignClient.add(deviceDO);
+        }
+    }
+
+    private void addTempBedFrame(PartTempBedDO partTempBedsDO, FrameDO bedFrame, FrameDO virtual_room, int id) {
+        bedFrame.setCreateTime(DateUtil.getDateline());
+        bedFrame.setSort(10000 + id);
+        bedFrame.setParentId(virtual_room.getId());
+        bedFrame.setPartId(virtual_room.getPartId());
+        bedFrame.setName(partTempBedsDO.getBedNo());
+        bedFrame.setFullName(partTempBedsDO.getBedNo());
+        bedFrame.setType(FrameTypeEnum.BED.value());
+        bedFrame.setAlias(partTempBedsDO.getBedNo());
+        bedFrame.setUnionId(ObjectId.next());
+        this.frameFeignClient.add(bedFrame);
+    }
+
+    public PartTempBedDO edit(PartTempBedDO partTempBedsDO, Integer id) {
+        PartTempBedDO partTempBedByBedNo = this.partTempBedFeignClient.getPartTempBedByBedNo(partTempBedsDO.getPartId(), partTempBedsDO.getBedNo()).getData();
+        if (partTempBedByBedNo != null && !partTempBedByBedNo.getId().equals(id)) {
+            throw new ServiceException("床位重复,已存在的床位号[" + partTempBedByBedNo.getBedNo() + "]");
+        }
+        PartTempBedDO oldBed = this.partTempBedFeignClient.get(id).getData();
+        if (oldBed == null) {
+            throw new ServiceException("参数错误,不存在的数据");
+        }
+        //        //原设备处理
+        if (!StrUtil.isEmpty(oldBed.getEthMac()) && oldBed.getDeviceType() != null) {
+            DeviceDO deviceByEthMac = this.deviceFeignClient.getDeviceByEthMac(oldBed.getEthMac()).getData();
+            //设备存在且不是正常注册设备设备,需要先删除,否则不允许操作,不然可能会把正常的设备给删除了
+            if (deviceByEthMac != null) {
+                FrameRelationshipVO frameAndParent = this.frameFeignClient.getFrameAndParent(deviceByEthMac.getFrameId()).getData();
+                if (!frameAndParent.getParentName().equalsIgnoreCase("v-room")) {
+                    throw new ServiceException("设备地址码已变成常用设备,无法更新!");
+                }
+                //删除设备
+                this.deviceFeignClient.delete(new Integer[]{deviceByEthMac.getId()});
+            }
+        }
+
+        //新设备地址码是否可用,且能否添加
+        if (!StrUtil.isEmpty(partTempBedsDO.getEthMac()) && partTempBedsDO.getDeviceType() != null) {
+
+            //如果其他床位使用过该设备,把他更新掉
+            List<PartTempBedDO> otherUsing = this.partTempBedFeignClient.getPartTempBedDeviceTypeAndMac(partTempBedsDO.getDeviceType(), partTempBedsDO.getEthMac()).getData();
+            if (otherUsing != null && otherUsing.size() > 0) {
+                for (PartTempBedDO tempBedsDO : otherUsing) {
+                    if (!tempBedsDO.getId().equals(id)) {
+                        tempBedsDO.setDeviceType(null);
+                        tempBedsDO.setEthMac("");
+                        this.partTempBedFeignClient.edit(tempBedsDO, tempBedsDO.getId());
+                    }
+                }
+            }
+            DeviceDO deviceByEthMac = this.deviceFeignClient.getDeviceByEthMac(partTempBedsDO.getEthMac()).getData();
+            //设备存在且不是正常注册设备设备,需要先删除,否则不允许操作,不然可能会把正常的设备给删除了
+            if (deviceByEthMac != null) {
+                FrameRelationshipVO frameAndParent = this.frameFeignClient.getFrameAndParent(deviceByEthMac.getFrameId()).getData();
+                if (!frameAndParent.getParentName().equalsIgnoreCase("v-room")) {
+                    throw new ServiceException("设备地址码错误,无法更新!");
+                }
+
+                //删除设备
+                this.deviceFeignClient.delete(new Integer[]{deviceByEthMac.getId()});
+            }
+        }
+
+        FrameDO bedFrame = this.frameFeignClient.getFrameByName(partTempBedsDO.getPartId(), FrameTypeEnum.BED.value(), oldBed.getBedNo()).getData();
+        if (bedFrame != null) { //查看旧的床位空间是否属于虚拟房间。
+            FrameDO roomFrame = this.frameFeignClient.getModel(bedFrame.getParentId()).getData();
+            if (!roomFrame.getName().equalsIgnoreCase("v-room")) {
+                throw new ServiceException("床位号[" + oldBed.getBedNo() + "]已经是常用床位,无法修改该记录");
+            } else {
+                bedFrame.setName(partTempBedsDO.getBedNo());
+                bedFrame.setFullName(partTempBedsDO.getBedNo());
+                bedFrame.setAlias(partTempBedsDO.getBedNo());
+                this.frameFeignClient.edit(bedFrame, bedFrame.getId());
+            }
+        } else { //不存在旧的床位,新建加床空间
+            FrameDO roomFrame = this.frameFeignClient.getFrameByName(partTempBedsDO.getPartId(), FrameTypeEnum.ROOM.value(), "v-room").getData();
+            bedFrame = new FrameDO();
+            //添加临时床位空间结构
+            addTempBedFrame(partTempBedsDO, bedFrame, roomFrame, id);
+        }
+        //绑定设备
+        handlerDeviceForTempBed(partTempBedsDO, bedFrame);
+        return this.partTempBedFeignClient.edit(partTempBedsDO, id).getData();
+    }
+
+    public void delete(Integer id) {
+        PartTempBedDO model = this.partTempBedFeignClient.get(id).getData();
+        FrameDO bedFrame = this.frameFeignClient.getFrameByName(model.getPartId(), FrameTypeEnum.BED.value(), model.getBedNo()).getData();
+        if (bedFrame != null) {
+            if (!StrUtil.isEmpty(model.getEthMac()) && model.getDeviceType() != null) {//床位绑定了设备
+                DeviceDO deviceByEthMac = this.deviceFeignClient.getDeviceByEthMac(model.getEthMac()).getData();
+
+                //设备存在且不是正常注册设备设备,需要先删除,否则不允许操作,不然可能会把正常的设备给删除了
+                if (deviceByEthMac != null) {
+                    FrameRelationshipVO frameAndParent = this.frameFeignClient.getFrameAndParent(deviceByEthMac.getFrameId()).getData();
+                    if (!frameAndParent.getParentName().equalsIgnoreCase("v-room")) {
+                        throw new ServiceException("设备地址码已变成常用设备,无法删除!");
+                    }
+                    //删除设备
+                    this.deviceFeignClient.delete(new Integer[]{deviceByEthMac.getId()});
+                }
+            }
+
+            FrameDO roomFrame = this.frameFeignClient.getModel(bedFrame.getParentId()).getData();
+            if (!roomFrame.getName().equalsIgnoreCase("v-room")) {
+                throw new ServiceException("床位号[" + model.getBedNo() + "]已经是常用床位,无法删除该记录");
+            }
+            //删除床位
+            this.frameFeignClient.delete(new Integer[]{bedFrame.getId()});
+        }
+        this.partTempBedFeignClient.delete(id);
+    }
+
+}
+
+

+ 83 - 0
ncs-entrace-service/src/main/java/com/wdklian/ncs/ms/entrace/service/PatientService.java

@@ -0,0 +1,83 @@
+package com.wdklian.ncs.ms.entrace.service;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.CustomerDO;
+import com.wdklian.ncs.ms.feignclient.open.PatientFeignClient;
+import com.wdklian.ncs.ms.feignclient.system.CustomerFeignClient;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:29
+ * ${description}
+ */
+@Service
+@Slf4j
+public class PatientService {
+
+    @Autowired
+    private PatientFeignClient patientFeignClient;
+
+    @Autowired
+    private CustomerFeignClient customerFeignClient;
+
+    public List<PatientDO> savePatient(List<PatientDO> patients) {
+        List<PatientDO> changedPatient = this.patientFeignClient.syncPatient(patients).getData();
+        //对有变化的患者,调用system接口更新数据
+        if (changedPatient != null && changedPatient.size() > 0) {
+            //更新呼叫系统数据
+            List<CustomerDO> changedCustomer = this.customerFeignClient.syncPatient(changedPatient).getData();
+            //更新patient的partId
+            if (changedCustomer != null && changedCustomer.size() > 0) {
+                this.patientFeignClient.updatePatientPartId(changedCustomer);
+            }
+        }
+        return changedPatient;
+    }
+
+    public PatientDO savePatient(PatientDO patient) {
+        PatientDO changedPatient = this.patientFeignClient.syncSinglePatient(patient).getData();
+        if (changedPatient != null) {
+            List<CustomerDO> changedCustomer = this.customerFeignClient.syncSinglePatient(changedPatient).getData();
+            //更新patient的partId
+            if (changedCustomer != null&&changedCustomer.size()>0) {
+                this.patientFeignClient.updatePatientPartId(changedCustomer);
+            }
+        }
+        return changedPatient;
+    }
+
+
+    public PatientDO patientOut(String patientKey) {
+        PatientDO outPatient = this.patientFeignClient.patientOut(patientKey).getData();
+        if (outPatient != null) {
+            this.customerFeignClient.patientOut(outPatient);
+        }
+        return outPatient;
+    }
+
+    public PatientDO syncPatientByKey(String patientKey) {
+        PatientDO patientDO = this.patientFeignClient.getPatient(patientKey).getData();
+        if (patientDO == null) {
+            throw new ServiceException("不存在的患者");
+        }
+        List<CustomerDO> customerDOS = this.customerFeignClient.syncSinglePatient(patientDO).getData();
+
+        //更新patient的partId
+        if (customerDOS != null&&customerDOS.size()>0) {
+            this.patientFeignClient.updatePatientPartId(customerDOS);
+        }
+        return patientDO;
+    }
+
+    public void syncAllPatient() {
+        this.customerFeignClient.syncAllPatient();
+    }
+}
+

+ 51 - 0
ncs-entrace-service/src/main/resources/bootstrap.yml

@@ -0,0 +1,51 @@
+spring:
+  main:
+    allow-bean-definition-overriding: true
+    allow-circular-references: true
+  cloud:
+    nacos:
+      config:
+        server-addr: 192.168.1.198:8848
+        file-extension: yaml
+        username: nacos
+        password: nacos
+        context-path: /nacos
+        shared-configs:
+          - application-common.yaml #公共配置
+      discovery:
+        server-addr: 192.168.1.198:8848
+        username: nacos
+        password: nacos
+        namespace: public
+  config:
+    import: nacos:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}?refresh=true
+  profiles:
+    active: dev
+  application:
+    name: entrace-service
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher
+#  rabbitmq:
+#    host: localhost
+#    port: 5672
+#    username: guest
+#    password: guest
+
+server:
+  port: 8013
+swagger:
+  enable: true
+  application-name: security-demo
+  application-version: 1.0.0
+  application-description: client
+#            slow-sql-millis: 5000
+logging:
+  level:
+    com.wdklian.ncs.ms.feignclient.*: debug
+ribbon:
+  MaxAutoRetries: 2
+  MaxAutoRetriesNextServer: 3
+  OkToRetryOnAllOperations: false
+
+

+ 42 - 0
ncs-ms-feign/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ncs-ms</artifactId>
+        <groupId>com.wdklian</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>ncs-ms-feign</artifactId>
+    <description>openFeign调用依赖工程</description>
+    <version>1.0.0</version>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-loadbalancer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.ben-manes.caffeine</groupId>
+            <artifactId>caffeine</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.wdklian</groupId>
+            <artifactId>third-party-common</artifactId>
+            <version>1.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 19 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/exception/CustomizedConfiguration.java

@@ -0,0 +1,19 @@
+package com.wdklian.ncs.ms.exception;
+
+import feign.codec.ErrorDecoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CustomizedConfiguration {
+
+    @Bean
+    public ErrorDecoder feignDecoder() {
+        return new FeignErrorDecoder();
+    }
+
+//    @Bean
+//    Logger.Level feignLoggerLevel() {
+//        return Logger.Level.FULL;
+//    }
+}

+ 28 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/exception/FeignErrorDecoder.java

@@ -0,0 +1,28 @@
+package com.wdklian.ncs.ms.exception;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import feign.Response;
+import feign.Util;
+import feign.codec.ErrorDecoder;
+
+public class FeignErrorDecoder implements ErrorDecoder {
+
+
+    @Override
+    public Exception decode(String methodKey, Response response) {
+
+        String message = null;
+        try {
+            if (response.body() != null) {
+                message = Util.toString(response.body().asReader(Util.UTF_8));
+                Exception result = JSONObject.parseObject(message, Exception.class);
+
+                return new ServiceException(result.getMessage());
+            }
+        } catch (Exception ignored) {
+        }
+        return new ServiceException(message);
+    }
+
+}

+ 34 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceDepartmentFeignClient.java

@@ -0,0 +1,34 @@
+package com.wdklian.ncs.ms.feignclient.entrace;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DepartmentDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-19 11:45
+ * ${description}
+ */
+@Component
+@FeignClient(value = "entrace-service", path = "/department")
+public interface EntraceDepartmentFeignClient {
+
+    @PostMapping("/sync-list")
+    List<ShopDO> syncDepartment(@RequestBody @NotEmpty(message = "科室列表不能为空") @Validated List<DepartmentDO> departments);
+
+    @PostMapping("/sync-single")
+    ShopDO syncSingleDepartment(@RequestBody @NotNull(message = "科室数据不能为null") DepartmentDO departmentDO);
+
+    @GetMapping("/sync-single/{key}")
+    ShopDO syncDepartmentByKey(@PathVariable("key") @NotEmpty(message = "科室主键不能为空") String key);
+}

+ 33 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceDoctorAdviceFeignClient.java

@@ -0,0 +1,33 @@
+package com.wdklian.ncs.ms.feignclient.entrace;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DoctorAdviceDO;
+import com.wdklian.ncs.ms.exception.CustomizedConfiguration;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-19 11:39
+ * ${description}
+ */
+@Component
+@FeignClient(value = "entrace-service", path = "/doctor-advice")
+public interface EntraceDoctorAdviceFeignClient {
+    @PostMapping("/sync-list")
+    List<DoctorAdviceDO> syncDoctorAdvice(@RequestBody @NotEmpty(message = "医嘱列表不能为空") @Validated List<DoctorAdviceDO> doctoradvices);
+
+    @PostMapping("/sync-single")
+    DoctorAdviceDO syncSingleDoctorAdvice(@RequestBody @NotNull(message = "医嘱数据不能为null") @Validated DoctorAdviceDO doctorAdvice);
+
+    @DeleteMapping("/{his_keys}")
+    Integer deleteDoctorAdvice(@PathVariable(value = "his_keys") @NotEmpty(message = "医嘱主键不能为空") String[] hisKeys);
+}

+ 35 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntraceEmployeeFeignClient.java

@@ -0,0 +1,35 @@
+package com.wdklian.ncs.ms.feignclient.entrace;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.EmployeeDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ClerkDO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-19 11:43
+ * ${description}
+ */
+@Component
+@FeignClient(value = "entrace-service", path = "/employee")
+public interface EntraceEmployeeFeignClient {
+
+
+    @PostMapping("/sync-list")
+    List<ClerkDO> syncEmployee(@RequestBody @NotEmpty(message = "职员列表不能为空") @Validated List<EmployeeDO> employees);
+
+    @PostMapping("/sync-single")
+    ClerkDO syncSingleEmployee(@RequestBody @NotNull(message = "科室数据不能为null") @Validated EmployeeDO employee);
+
+    @GetMapping("/sync-single/{key}")
+    ClerkDO syncSingleEmployeeByKey(@NotEmpty(message = "职工主键不能为空") @PathVariable("key") String key);
+}

+ 40 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/entrace/EntracePatientFeignClient.java

@@ -0,0 +1,40 @@
+package com.wdklian.ncs.ms.feignclient.entrace;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-19 11:36
+ * ${description}
+ */
+@Component
+@FeignClient(value = "entrace-service", path = "/patient")
+public interface EntracePatientFeignClient {
+    @PostMapping("/sync-list")
+    List<PatientDO> syncPatient(@RequestBody @NotEmpty(message = "患者列表不能为空") @Validated List<PatientDO> patients);
+
+    @PostMapping("/sync-single")
+    PatientDO syncSinglePatient(@RequestBody @NotNull(message = "患者数据不能为null") @Validated PatientDO patient);
+
+
+    @GetMapping("/sync-single/{patient_key}")
+    PatientDO syncSinglePatientByKey(@PathVariable("patient_key") String patientKey);
+
+    @PostMapping("/patient-out/{patient_key}")
+    PatientDO patientOut(@NotEmpty(message = "患者主键不能为空") @PathVariable(value = "patient_key") String patientKey);
+
+    @GetMapping("/sync-all")
+    void syncAllPatient();
+
+}

+ 30 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceRefBoardItemFeignClient.java

@@ -0,0 +1,30 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.AdviceRefBoardItemDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 09:34
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/advice-refer-board-item")
+public interface AdviceRefBoardItemFeignClient {
+    @PostMapping(value = "/{part_id}/{item_name_md5}")
+    CommonResult<List<AdviceRefBoardItemDO>> addAdviceReferenceBoardItem(@RequestBody String[] adviceContentMd5s,
+                                                                         @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                                                         @PathVariable(name = "part_id") Integer partId);
+
+    @DeleteMapping(value = "/{part_id}/{item_name_md5}")
+    CommonResult<Integer> deleteAdviceReferenceBoardItem(@RequestBody String[] adviceContentMd5s,
+                                                         @PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId);
+}

+ 33 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceRefNursingMarkFeignClient.java

@@ -0,0 +1,33 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.AdviceRefNursingMarkOptionDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 10:57
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/advice-refer-nurse")
+public interface AdviceRefNursingMarkFeignClient {
+    @PostMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    CommonResult<List<AdviceRefNursingMarkOptionDO>> addAdviceReferenceNurse(@RequestBody String[] adviceContentMd5s,
+                                                                             @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                                             @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                                                             @PathVariable(name = "part_id") Integer partId);
+
+    @DeleteMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    CommonResult<Integer> deleteMapping(@RequestBody String[] adviceContentMd5s,
+                                        @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                        @PathVariable(name = "item_name_md5") String itemNameMd5,
+                                        @PathVariable(name = "part_id") Integer partId);
+}

+ 59 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/AdviceUniqueContentFeignClient.java

@@ -0,0 +1,59 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DoctorAdviceDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.AdviceUniqueContentMatchVO;
+import com.wdklian.ncs.ms.common.pojo.PageShopParam;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-16 09:47
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/advice-unique-content")
+public interface AdviceUniqueContentFeignClient {
+    //获取能匹配指定护理标识项目的医嘱分页
+    @PostMapping("/{category_name_md5}/{item_name_md5}/page")
+    CommonResult<Page<AdviceUniqueContentMatchVO>> listNurseOptionAvailable(@RequestBody PageShopParam pageShopParam,
+                                                                            @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                                            @PathVariable(name = "item_name_md5") String itemNameMd5
+    );
+    //获取已匹配指定护理标识项目的医嘱分页
+    @PostMapping("/match/nurse-option/{category_name_md5}/{item_name_md5}/page")
+    CommonResult<Page> listNurseOptionMatch(@RequestBody PageShopParam pageShopParam,
+                                            @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                            @PathVariable(name = "item_name_md5") String itemNameMd5
+    );
+
+    @PostMapping("/nurse-category/{category_id}/page")
+    CommonResult<Page> listNurseCategoryAvailable(@RequestBody PageShopParam pageShopParam,
+                                                  @PathVariable(name = "category_id") Integer categoryId
+    );
+
+    @PostMapping("/match/nurse-category/{category_id}/page")
+    CommonResult<Page> listNurseCategoryMatch(@RequestBody PageShopParam pageShopParam,
+                                              @PathVariable(name = "category_id") Integer categoryId);
+
+    @PostMapping("/{item_name_md5}/page")
+    CommonResult<Page> listBoardItemAvailable(@RequestBody PageShopParam pageShopParam,
+                                              @PathVariable(name = "item_name_md5") String itemNameMd5
+    );
+
+    @PostMapping("/match/board-item/{item_name_md5}/page")
+    CommonResult<Page> listBoardItemMatch(@RequestBody PageShopParam pageShopParam,
+                                          @PathVariable(name = "item_name_md5") String itemNameMd5);
+
+    //更新医嘱列表的唯一条目
+    @PostMapping("/update-advice-unique-content")
+    CommonResult<Integer[]> updateAdviceUniqueContent(@RequestBody List<DoctorAdviceDO> doctorAdviceDOList);
+}

+ 63 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/BoardItemConfigFeignClient.java

@@ -0,0 +1,63 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.BoardItemConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.BoardItemConfigVO;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 10:22
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/board-item-config")
+public interface BoardItemConfigFeignClient {
+
+    @PostMapping("/page")
+    CommonResult<Page<BoardItemConfigVO>> list(@RequestBody GridParameter gp);
+
+    @PostMapping("/{part_id}/page")
+    CommonResult<Page<BoardItemConfigDO>> listPartPage(@RequestBody GridParameter gp, @PathVariable("part_id") Integer partId);
+
+    @PostMapping
+    CommonResult<BoardItemConfigDO> add(@RequestBody @Valid BoardItemConfigDO boardItemSettingDO);
+
+    @GetMapping(value = "/{id}")
+    CommonResult<BoardItemConfigDO> get(@PathVariable("id") Integer id);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<BoardItemConfigDO> edit(@RequestBody @Valid BoardItemConfigDO boardItemSettingDO, @PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{ids}")
+    CommonResult delete(@PathVariable("ids") Integer[] ids);
+
+    @GetMapping(value = "/forselect/{part_id}")
+    CommonResult<List<BoardItemConfigDO>> getForSelect(@PathVariable(name = "part_id") Integer partId);
+
+    @PutMapping(value = "/keywords/{part_id}/{item_name_md5}")
+    CommonResult<BoardItemConfigDO> updateKeywords(@RequestBody @Valid BoardItemConfigDO itemSettingDO,
+                                                   @PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId);
+
+    @GetMapping(value = "/{part_id}/{item_name_md5}")
+    CommonResult<BoardItemConfigDO> getModelByMd5(@PathVariable(name = "item_name_md5") String itemNameMd5, @PathVariable(name = "part_id") Integer partId);
+
+
+    @GetMapping("/list-part/{part_id}")
+    CommonResult<List<BoardItemConfigDO>> listPartBoardItemConfig(@PathVariable(name = "part_id") Integer partId);
+
+    @GetMapping("/list-all")
+    CommonResult<List<BoardItemConfigDO>> listAllBoardItemConfig();
+
+
+}

+ 36 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/DepartmentFeignClient.java

@@ -0,0 +1,36 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DepartmentDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:00
+ * ${description}
+ */
+@Component()
+@FeignClient(value = "open-service")
+public interface DepartmentFeignClient {
+
+    @PostMapping("/department/save-list")
+    CommonResult<List<DepartmentDO>> saveDepartments(@RequestBody @NotEmpty(message = "部门列表不能为空") @Validated List<DepartmentDO> departments);
+
+    @PostMapping("/department/save-single")
+    CommonResult<DepartmentDO> saveSingleDepartment(@RequestBody() @NotNull(message = "部门数据不能为null") @Validated DepartmentDO departmentDO);
+
+
+    @GetMapping("/{depart_key}")
+    CommonResult<DepartmentDO> getDepartment(@PathVariable("depart_key") @NotEmpty(message = "部门主键不能为空") String departKey);
+}

+ 50 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/DoctorAdviceFeignClient.java

@@ -0,0 +1,50 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DoctorAdviceDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.DoctorAdviceMatchBoardItemVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.DoctorAdviceMatchNursingMarkCategoryVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.DoctorAdviceMatchNursingMarkOptionVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-14 15:29
+ * ${description}
+ */
+@Component()
+@FeignClient(value = "open-service",path = "/doctor-advice")
+public interface DoctorAdviceFeignClient {
+    @PostMapping()
+    CommonResult<List<DoctorAdviceDO>> listPatients(@RequestBody @NotNull(message = "医嘱主键列表不能为空") String[] adviceKeys);
+
+    @PostMapping("/part-match-nurseing-mark-option-list")
+    CommonResult<List<DoctorAdviceMatchNursingMarkOptionVO>> listDoctorAdviceRefNurseByHisPartKey(@RequestBody @NotNull(message = "科室不能为空") ShopDO part, @RequestParam(name = "distinct") Boolean distinct);
+
+    @PostMapping("/part-match-nurseing-mark-category-list")
+    CommonResult<List<DoctorAdviceMatchNursingMarkCategoryVO>> listDoctorAdviceRefNurseCategoryByHisPartKey(@RequestBody @NotNull(message = "科室不能为空") ShopDO part);
+
+    @PostMapping("/part-match-board-item-list")
+    CommonResult<List<DoctorAdviceMatchBoardItemVO>> listAdviceReferenceBoardItem(@RequestBody @NotNull(message = "科室列表不能为空") List<ShopDO> parts);
+
+
+    @GetMapping("/his-changed-departkeys")
+    CommonResult<List<String>> listChangedDepartKeys();
+
+    @PostMapping("/save-list")
+    CommonResult<List<DoctorAdviceDO>> syncDoctorAdvice(@RequestBody @NotEmpty(message = "医嘱列表不能为空") @Validated List<DoctorAdviceDO> doctoradvices);
+
+    @PostMapping("/save-single")
+    CommonResult<DoctorAdviceDO> syncSingleDoctorAdvice(@RequestBody @NotNull(message = "医嘱数据不能为null") @Validated DoctorAdviceDO doctorAdvice);
+
+    @DeleteMapping("/{his_keys}")
+    CommonResult<List<DoctorAdviceDO>> deleteDoctorAdvice(@PathVariable(value = "his_keys") @NotEmpty(message = "医嘱主键不能为空") String[] hisKeys);
+}

+ 37 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/EmployeeFeignClient.java

@@ -0,0 +1,37 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.EmployeeDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-14 15:32
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service")
+public interface EmployeeFeignClient {
+
+    //根据主键查询职工信息
+    @GetMapping("/employee/{employee_key}")
+    CommonResult<EmployeeDO> getEmployee(@PathVariable("employee_key") @NotEmpty(message = "职工主键不能为空") String employeeKey);
+
+
+    @PostMapping("/employee/save-list")
+    CommonResult<List<EmployeeDO>> saveEmployeeList(@RequestBody @NotEmpty(message = "职员列表不能为空") @Validated List<EmployeeDO> employees);
+
+    @PostMapping("/employee/save-single")
+    CommonResult<EmployeeDO> saveEmployee(@RequestBody @NotNull(message = "科室数据不能为null") @Validated EmployeeDO employee);
+}

+ 39 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/ManualInputBoardItemConfigFeignClient.java

@@ -0,0 +1,39 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.ManualInputBoardItemConfingDO;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 16:43
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/manual-input-board-item-config")
+public interface ManualInputBoardItemConfigFeignClient {
+    @PostMapping("/{part_id}/page")
+    CommonResult<Page<ManualInputBoardItemConfingDO>> listPartPage(@RequestBody GridParameter gp, @PathVariable("part_id") Integer partId);
+
+    @PostMapping
+    CommonResult<ManualInputBoardItemConfingDO> add(@Valid @RequestBody ManualInputBoardItemConfingDO manualInputBoardItemSettingDO);
+
+    @GetMapping(value = "/{id}")
+    CommonResult<ManualInputBoardItemConfingDO> get(@PathVariable("id") Integer id);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<ManualInputBoardItemConfingDO> edit(@Valid @RequestBody ManualInputBoardItemConfingDO manualInputBoardItemSettingDO, @PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{ids}")
+    CommonResult delete(@PathVariable("ids") Integer[] ids);
+
+    @GetMapping(value = "list/{ids}")
+    CommonResult<List<ManualInputBoardItemConfingDO>> listByIds(@PathVariable("ids") Integer[] ids);
+}

+ 49 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/NursingMarkCategoryConfigFeignClient.java

@@ -0,0 +1,49 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkCategoryConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NurseCascaderVO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NursingMarkCategoryConfigVO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-14 15:43
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/nursing-mark-category-config")
+public interface NursingMarkCategoryConfigFeignClient {
+
+    @PostMapping
+    CommonResult<NursingMarkCategoryConfigDO> add(@RequestBody NursingMarkCategoryConfigDO categoryDO);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<NursingMarkCategoryConfigDO> edit(@RequestBody NursingMarkCategoryConfigDO categoryDO, @PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{id}")
+    CommonResult<Integer> delete(@PathVariable("id") Integer id);
+
+    @GetMapping(value = "/list/{part_id}")
+    CommonResult<List<NursingMarkCategoryConfigVO>> list(@PathVariable("part_id") Integer partId);
+
+
+    @GetMapping(value = "/list-all")
+    CommonResult<List<NursingMarkCategoryConfigVO>> listAll();
+
+    @GetMapping(value = "/{id}")
+    CommonResult<NursingMarkCategoryConfigDO> get(@PathVariable("id") Integer id);
+
+    @GetMapping(value = "/cascader/{part_id}")
+    CommonResult<List<NurseCascaderVO>> cascader(@PathVariable("part_id") Integer partId);
+
+    @GetMapping(value = "/auto-match-category/{part_id}")
+    CommonResult<List<NursingMarkCategoryConfigDO>> autoChildrenCategory(@PathVariable("part_id") Integer partId);
+}

+ 45 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/NursingMarkOptionConfigFeignClient.java

@@ -0,0 +1,45 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.NursingMarkOptionConfigDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.NursingMarkOptionConfigVO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-14 16:53
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/nursing-mark-option-config")
+public interface NursingMarkOptionConfigFeignClient {
+
+    @PostMapping
+    CommonResult<NursingMarkOptionConfigDO> add(@RequestBody @Valid NursingMarkOptionConfigDO optionConfigDO);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<NursingMarkOptionConfigDO> edit(@RequestBody @Valid NursingMarkOptionConfigDO itemSettingDO, @PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{id}")
+    void delete(@PathVariable("id") Integer id);
+
+    @PutMapping(value = "/keywords/{category_name_md5}/{item_name_md5}")
+    CommonResult<NursingMarkOptionConfigDO> updateKeywords(@RequestBody @Valid NursingMarkOptionConfigDO itemSettingDO, @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                           @PathVariable(name = "item_name_md5") String itemNameMd5);
+
+    @GetMapping(value = "/{part_id}/{category_name_md5}/{item_name_md5}")
+    CommonResult<NursingMarkOptionConfigDO> getModelByCIMd5(@PathVariable(name = "part_id") Integer partId,
+                                                            @PathVariable(name = "category_name_md5") String categoryNameMd5,
+                                                            @PathVariable(name = "item_name_md5") String itemNameMd5);
+
+
+
+    @PostMapping(value = "/list-parts-option-config")
+    CommonResult<List<NursingMarkOptionConfigVO>> listNurseOptionConfigVOByPartIds(@RequestBody List<Integer> partIds);
+}

+ 49 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/PartTempBedFeignClient.java

@@ -0,0 +1,49 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PartTempBedDO;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 19:31
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/part-temp-bed")
+public interface PartTempBedFeignClient {
+
+    @PostMapping
+    CommonResult<PartTempBedDO> add(@Valid @RequestBody PartTempBedDO partTempBedsDO);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<PartTempBedDO> edit(@Valid @RequestBody PartTempBedDO partTempBedsDO, @PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{id}")
+    void delete(@PathVariable("id") Integer id);
+
+    @GetMapping(value = "/{id}")
+    CommonResult<PartTempBedDO> get(@PathVariable("id") Integer id);
+
+    @PostMapping(value = "/page")
+    CommonResult<Page<PartTempBedDO>> list(@RequestBody GridParameter gp);
+
+    @GetMapping("{part_id}/{bed_no}")
+    CommonResult<PartTempBedDO> getPartTempBedByBedNo(@PathVariable("part_id") @NotEmpty(message = "科室Id不能为空") Integer partId,
+                                                      @PathVariable("bed_no") @NotEmpty(message = "床位号不能为空") String bedNo);
+
+    @GetMapping("list-bed/{device_type}/{eth_mac}")
+    CommonResult<List<PartTempBedDO>> getPartTempBedDeviceTypeAndMac(@PathVariable("device_type") @NotEmpty(message = "科室Id不能为空") Integer deviceType,
+                                                                     @PathVariable("eth_mac") @NotEmpty(message = "床位号不能为空") String ethMac);
+}

+ 52 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/open/PatientFeignClient.java

@@ -0,0 +1,52 @@
+package com.wdklian.ncs.ms.feignclient.open;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import com.wdklian.ncs.ms.common.entity.open.vos.PatientDataVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.CustomerDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-14 15:37
+ * ${description}
+ */
+@Component
+@FeignClient(value = "open-service", path = "/patient")
+public interface PatientFeignClient {
+
+    @GetMapping("/{patient_key}")
+    CommonResult<PatientDO> getPatient(@PathVariable("patient_key") @NotEmpty(message = "患者主键不能为空") String patientKey);
+
+    @GetMapping("/{start_date}/{end_date}")
+    CommonResult<PatientDataVO> getPatientData(@PathVariable("start_date") @NotEmpty(message = "开始日期不能为空") String startDate,
+                                               @PathVariable("end_date") @NotEmpty(message = "结束日期不能为空") String endDate);
+
+    @GetMapping("/his-outed")
+    CommonResult<List<PatientDO>> listHisOutedPatients();
+
+    @GetMapping("/his-hospitalized")
+    CommonResult<List<PatientDO>> listHospitaledPatient();
+
+    @PutMapping("/update-part-id")
+    CommonResult updatePatientPartId(@RequestBody @NotNull(message = "患者主键列表不能为空") List<CustomerDO> patients);
+
+    @PostMapping("/save-list")
+    CommonResult<List<PatientDO>> syncPatient(@RequestBody @NotEmpty(message = "患者列表不能为空") @Validated List<PatientDO> patients);
+
+    @PostMapping("/save-single")
+    CommonResult<PatientDO> syncSinglePatient(@RequestBody @NotNull(message = "患者数据不能为null") @Validated PatientDO patient);
+
+    @PostMapping("/patient-out/{patient_key}")
+    CommonResult<PatientDO> patientOut(@NotEmpty(message = "患者主键不能为空") @PathVariable(value = "patient_key") String patientKey);
+
+    @GetMapping("/tp-hospitalized")
+    CommonResult<List<PatientDO>> listHospitaledPatientTp();
+}

+ 28 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/BoardItemDisplayConfigFeignClient.java

@@ -0,0 +1,28 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.open.vos.BoardItemDisplayConfigVO;
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDisplayDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 14:18
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/boarditem-display-config")
+public interface BoardItemDisplayConfigFeignClient {
+    @PostMapping
+    CommonResult<BoardItemDisplayConfigVO> edit(@RequestBody BoardItemDisplayConfigVO boardItemDisplayConfigVO);
+
+    @GetMapping("/{part_id}")
+    CommonResult<List<BoardItemDisplayDO>> listByPartId(@PathVariable("part_id") Integer partId);
+}

+ 67 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/BoardItemFeignClient.java

@@ -0,0 +1,67 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.BoardItemDO;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 17:59
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/infomation-board-item")
+public interface BoardItemFeignClient {
+    @PostMapping("/renew-by-partids")
+    CommonResult<List<Integer>> renewDepartBoardItemByPartIds(@NotEmpty(message = "科室主键列表不能为空") @RequestBody List<Integer> ids);
+
+
+    @PostMapping("/renew-by-his-part-keys")
+    CommonResult<List<Integer>> renewDepartBoardItemByHisPartKeys(@NotEmpty(message = "科室主键列表不能为空") @RequestBody List<String> keys);
+
+
+    @GetMapping("/renew-part/{partid}")
+    CommonResult<List<Integer>> renewPartByPartId(@NotNull(message = "科室主键不能为空") @PathVariable("partid") Integer id);
+
+
+    @GetMapping("/renew-department/{partkey}")
+    CommonResult<List<Integer>> renewByDepartKey(@NotNull(message = "科室主键不能为空") @PathVariable("partkey") String key);
+
+    @PostMapping("data/page")
+    CommonResult<Page> listDataPage(@RequestBody GridParameter gp,
+                                    @ApiIgnore @NotNull(message = "是否返回项目匹配明细") @RequestParam("with_detail") Integer withDetail);
+
+    @GetMapping("/list/{part_id}")
+    CommonResult<List<BoardItemDO>> listPartAll(@NotNull(message = "科室主键不能为空") @PathVariable("part_id") Integer partId);
+
+    @GetMapping("/list-all")
+    CommonResult<List<BoardItemDO>> listAll();
+
+
+    @PostMapping
+    CommonResult<BoardItemDO> add(@Valid @RequestBody BoardItemDO boardItemDO);
+
+    @PutMapping(value = "/{id}")
+    CommonResult<BoardItemDO> edit(@Valid @RequestBody BoardItemDO boardItemDO, @PathVariable("id") Integer id);
+
+
+    @GetMapping(value = "/{id}")
+    CommonResult<BoardItemDO> get(@PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{id}")
+    void delete(@PathVariable("id") Integer[] id);
+
+}

+ 30 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ClerkFeignClient.java

@@ -0,0 +1,30 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.EmployeeDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ClerkDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:20
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/employee")
+public interface ClerkFeignClient {
+    @PostMapping("/sync-list")
+    CommonResult<List<ClerkDO>> syncEmployee(@NotEmpty(message = "职工数据不能为空") @RequestBody List<EmployeeDO> employees);
+
+
+    @PostMapping("/sync-single")
+    CommonResult<ClerkDO> syncSingleEmployee(@RequestBody @NotNull(message = "职工数据不能为null") @Validated EmployeeDO employee);
+}

+ 41 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/CustomerFeignClient.java

@@ -0,0 +1,41 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.PatientDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.CustomerDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.CustomerFrameVO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:31
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/patient")
+public interface CustomerFeignClient {
+
+    @PostMapping("/sync-list")
+    CommonResult<List<CustomerDO>> syncPatient(@NotEmpty(message = "患者数据不能为空") @RequestBody List<PatientDO> patients);
+
+    @PostMapping("/sync-single")
+   CommonResult<List<CustomerDO>> syncSinglePatient(@RequestBody @NotNull(message = "患者数据不能为null") PatientDO patient);
+
+    @PostMapping("/patient-out")
+    CommonResult<List<CustomerDO>> patientOut(@RequestBody @NotNull(message = "患者信息不能为空") PatientDO patientDO);
+
+    @GetMapping("/{part_id}/hospitalized-bed")
+    CommonResult<List<CustomerFrameVO>> getHospitalizedBeds(@PathVariable("part_id") Integer partId);
+
+    @GetMapping("/sync-all")
+    CommonResult syncAllPatient();
+}

+ 27 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/DeviceFeignClient.java

@@ -0,0 +1,27 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.DeviceDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 10:02
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/device")
+public interface DeviceFeignClient {
+    @GetMapping("/{eth_mac}")
+    CommonResult<DeviceDO> getDeviceByEthMac(@PathVariable("eth_mac") String ethMac);
+
+    @DeleteMapping(value = "/{id}")
+    void delete(@PathVariable("id") Integer[] id);
+
+    @PostMapping
+    CommonResult<DeviceDO> add(@Valid @RequestBody DeviceDO deviceDO);
+}

+ 43 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/FrameFeignClient.java

@@ -0,0 +1,43 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.FrameDO;
+import com.wdklian.ncs.ms.common.entity.system.vos.FrameRelationshipVO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 10:01
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/frame")
+public interface FrameFeignClient {
+
+    @GetMapping("/{part_id}/{frame_type}/{frame_name}")
+    CommonResult<FrameDO> getFrameByName(@PathVariable("part_id") Integer partId, @PathVariable("frame_type") Integer frameType, @PathVariable("frame_name") String frameName);
+
+
+    @GetMapping("/part-frame/{part_id}")
+    CommonResult<FrameDO> getPartFrame(@PathVariable("part_id") Integer partId);
+
+
+    @PostMapping
+    CommonResult<FrameDO> add(@Valid @RequestBody FrameDO frameDO);
+
+    @GetMapping("/get/{id}")
+    CommonResult<FrameDO> getModel(@PathVariable("id") Integer id);
+
+    @PutMapping("/{id}")
+    CommonResult<FrameDO> edit(@Valid @RequestBody FrameDO frameDO, @PathVariable("id") Integer id);
+
+    @GetMapping("/frame-with-parent/{frame_id}")
+    CommonResult<FrameRelationshipVO> getFrameAndParent(@PathVariable("frame_id") Integer frameId);
+
+    @DeleteMapping(value = "/{id}")
+    void delete(@PathVariable("id") Integer[] id);
+}

+ 45 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ManualInputBoardItemFeignClient.java

@@ -0,0 +1,45 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.ManualInputBoardItemDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-17 17:35
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/manual-input-boarditem")
+public interface ManualInputBoardItemFeignClient {
+
+    @PutMapping(value = "/{id}")
+    CommonResult<ManualInputBoardItemDO> edit(@Valid @RequestBody ManualInputBoardItemDO manualInputBoardItemDO, @PathVariable("id") Integer id);
+
+    @PostMapping
+    CommonResult<ManualInputBoardItemDO> add(@Valid @RequestBody ManualInputBoardItemDO manualInputBoardItemDO);
+
+    @GetMapping(value = "/list/{part_id}")
+    CommonResult<List<ManualInputBoardItemDO>> getList(@PathVariable(name = "part_id") Integer partId);
+
+    @GetMapping(value = "/{id}")
+    CommonResult<ManualInputBoardItemDO> get(@PathVariable("id") Integer id);
+
+    @DeleteMapping(value = "/{ids}")
+    CommonResult delete(@PathVariable("ids") Integer[] ids);
+
+
+    @GetMapping(value = "/{part_id}/{item_name_md5}")
+    CommonResult<ManualInputBoardItemDO> getPartItemByName(@PathVariable("part_id") Integer partId, @PathVariable("item_name_md5") String itemNameMd5);
+
+    @DeleteMapping(value = "/{part_id}/{item_name_md5}")
+    CommonResult<Integer> deletePartItem(@PathVariable("part_id") Integer partId,@PathVariable("item_name_md5") String itemNameMd5);
+}

+ 24 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/NursingMarkDisplayFeignClient.java

@@ -0,0 +1,24 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigDisplayDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-18 15:14
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/nursing-mark-display-config")
+public interface NursingMarkDisplayFeignClient {
+    @GetMapping("/{part_id}")
+    CommonResult<List<NurseConfigDisplayDO>> listByPartId(@PathVariable("part_id") Integer partId);
+
+
+}

+ 63 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/NursingMarkFeignClient.java

@@ -0,0 +1,63 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.system.dos.CustomerDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.NurseConfigOptionDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 17:44
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/nursing-mark")
+public interface NursingMarkFeignClient {
+
+    @PostMapping("/renew-by-his-part-keys")
+    CommonResult<List<CustomerDO>> renewDepartNursingByHisPartKeys(@NotEmpty(message = "科室主键列表不能为空") @RequestBody List<String> keys);
+
+    @GetMapping("/renew-department/{department_key}")
+    CommonResult renewDepartByDepartKey(@NotNull(message = "科室主键不能为空") @PathVariable("department_key") String departmentKey);
+
+
+
+    @GetMapping("/list-all-nursing-mark")
+    CommonResult<List<NurseConfigDO>> listAllNursingMark();
+
+
+    @GetMapping("/list-all-nursing-mark-option")
+    CommonResult<List<NurseConfigOptionDO>> listAllNursingMarkOption();
+
+
+    @PostMapping("/batch-update")
+    void batchUpdate(@RequestBody String[] sqls);
+
+
+    @PostMapping("/add-nursing-config")
+    CommonResult<NurseConfigDO> addNursingConfig(@RequestBody NurseConfigDO nurseConfigDO);
+
+
+    @PostMapping("/add-nursing-option-config")
+    CommonResult<NurseConfigOptionDO> addNursingOptionConfig(@RequestBody NurseConfigOptionDO nurseConfigOptionDO);
+
+
+    @PutMapping("/update-nursing-option-config/{id}")
+    CommonResult<NurseConfigOptionDO> updateNursingOptionConfig(@RequestBody NurseConfigOptionDO nurseConfigOptionDO, @PathVariable("id") Integer id);
+
+
+    @PutMapping("/update-nursing-config/{id}")
+    CommonResult<NurseConfigDO> updateNursingConfig(@RequestBody NurseConfigDO nurseConfigDO, @PathVariable("id") Integer id);
+
+
+}

+ 41 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/feignclient/system/ShopFeignClient.java

@@ -0,0 +1,41 @@
+package com.wdklian.ncs.ms.feignclient.system;
+
+import com.wdklian.ncs.ms.common.entity.open.dos.DepartmentDO;
+import com.wdklian.ncs.ms.common.entity.system.dos.ShopDO;
+import com.wdklian.ncs.ms.framework.mvc.CommonResult;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author wuyunfeng
+ * 2024-01-15 16:07
+ * ${description}
+ */
+@Component
+@FeignClient(value = "system-service", path = "/department")
+public interface ShopFeignClient {
+
+    @PostMapping("/sync-list")
+    CommonResult<List<ShopDO>> syncDepartment(@RequestBody @NotEmpty(message = "科室列表不能为空") List<DepartmentDO> departments);
+
+    @PostMapping("/sync-single")
+    CommonResult<ShopDO> syncSingleDepartment(@RequestBody @NotNull(message = "科室数据不能为null") @Validated DepartmentDO departmentDO);
+
+    @GetMapping("/{part_id}")
+    CommonResult<ShopDO> getPartById(@NotNull(message = "科室主键不能为空") @PathVariable("part_id") Integer partId);
+
+    @GetMapping("list-type/{part_type}")
+    CommonResult<List<ShopDO>> listShopByType(@NotNull(message = "科室类型不能为空") @PathVariable("part_type") Integer partType);
+}

+ 18 - 0
ncs-ms-feign/src/main/java/com/wdklian/ncs/ms/retryer/MyRetryer.java

@@ -0,0 +1,18 @@
+package com.wdklian.ncs.ms.retryer;
+
+import feign.RetryableException;
+import feign.Retryer;
+
+import java.util.concurrent.TimeUnit;
+
+public class MyRetryer implements Retryer {
+    @Override
+    public void continueOrPropagate(RetryableException e) {
+        throw e;
+    }
+
+    @Override
+    public Retryer clone() {
+        return new Default(100, TimeUnit.SECONDS.toMillis(1), 2);
+    }
+}

+ 125 - 0
ncs-ms-framework/pom.xml

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ncs-ms</artifactId>
+        <groupId>com.wdklian</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>ncs-ms-framework</artifactId>
+    <version>1.0.0</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc -->
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>mssql-jdbc</artifactId>
+
+        </dependency>
+
+        <dependency>
+            <groupId>com.oracle.database.jdbc</groupId>
+            <artifactId>ojdbc6</artifactId>
+
+        </dependency>
+
+
+
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>20.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.15.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>1.1.1</version>
+                <configuration>
+                    <skipDocker>true</skipDocker>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 119 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/cache/Cache.java

@@ -0,0 +1,119 @@
+package com.wdklian.ncs.ms.framework.cache;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 缓存接口
+ * @author Allen
+ *
+ */
+public interface Cache<T> {
+	
+	/**
+	 * Get an item from the cache, nontransactionally
+	 * @param key
+	 * @return the cached object or <tt>null</tt>
+	 */
+	T get(Object key);
+
+
+	/**
+	 *  multiGet
+	 * @param keys  要查询的key集合
+	 * @return
+	 */
+	List  multiGet(Collection keys);
+
+	/**
+	 * 批量set
+	 * @param map
+	 */
+	void multiSet(Map map);
+
+
+	/**
+	 * 批量删除
+	 * @param keys 要删除的key集合
+	 */
+	void multiDel(Collection keys);
+
+	/**
+	 * Add an item to the cache, nontransactionally, with
+	 * failfast semantics
+	 * @param key
+	 * @param value
+	 */
+	void put(Object key, T value);
+	
+	/**
+	 * 往缓存中写入内容
+	 * @param key
+	 * @param value
+	 * @param exp	超时时间,单位为秒
+	 */
+	void put(Object key, T value, int exp);
+
+	/**
+	 * 删除
+	 * @param key
+	 */
+	void remove(Object key);
+
+	/**
+	 * 删除
+	 * @param key
+	 */
+	void vagueDel(Object key);
+
+	/**
+	 * Clear the cache
+	 */
+	void clear();
+
+
+	/**
+	 * 往缓存中写入内容
+	 * @param key		缓存key
+	 * @param hashKey	缓存中hashKey
+	 * @param hashValue hash值
+	 */
+	void putHash(Object key, Object hashKey, Object hashValue);
+
+	/**
+	 * 玩缓存中写入内容
+	 * @param key
+	 * @param map
+	 */
+	void putAllHash(Object key, Map map);
+
+	/**
+	 * 读取缓存值
+	 * @param key
+	 * @param hashKey
+	 * @return
+	 */
+	T getHash(Object key, Object hashKey);
+
+	/**
+	 * 读取缓存值
+	 * @param key
+	 * @return
+	 */
+	Map<Object,Object> getHash(Object key);
+
+	Long deleteHash(Object key, Object... hashKey);
+
+	Set<String> getSetElements(String key);
+
+	void addSetElement(String key, String value);
+
+	void addSetElement(String key, Object value);
+
+	void removeSetElement(String key, String value);
+
+	void removeSetElement(String key, Object value);
+}

+ 139 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/cache/RedisCacheImpl.java

@@ -0,0 +1,139 @@
+package com.wdklian.ncs.ms.framework.cache;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * redis的cache实现
+ *
+ * @author Allen
+ * @version v6.4
+ * @since v6.4 2017年9月25日 下午4:32:49
+ */
+@Component
+public class RedisCacheImpl implements Cache {
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+
+    public RedisCacheImpl() {
+
+    }
+
+    @Override
+    public Object get(Object key) {
+
+        return redisTemplate.opsForValue().get(key);
+    }
+
+    @Override
+    public List multiGet(Collection  keys) {
+       return redisTemplate.opsForValue().multiGet(keys);
+
+    }
+
+
+    @Override
+    public void multiSet(Map map) {
+        redisTemplate.opsForValue().multiSet(map);
+    }
+
+    @Override
+    public void multiDel(Collection keys) {
+        redisTemplate.delete(keys);
+    }
+
+    @Override
+    public void put(Object key, Object value) {
+
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    @Override
+    public void put(Object key, Object value, int exp) {
+
+        redisTemplate.opsForValue().set(key, value, exp, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void remove(Object key) {
+
+        redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除
+     *
+     * @param key
+     */
+    @Override
+    public void vagueDel(Object key) {
+        Set<String> keys = redisTemplate.keys(key + "*");
+        redisTemplate.delete(keys);
+    }
+
+    @Override
+    public void clear() {
+
+        Set keys = redisTemplate.keys("*");
+        redisTemplate.delete(keys);
+    }
+
+    @Override
+    public void putHash(Object key, Object hashKey, Object hashValue) {
+        redisTemplate.opsForHash().put(key, hashKey, hashValue);
+    }
+
+    @Override
+    public void putAllHash(Object key, Map map) {
+        redisTemplate.opsForHash().putAll(key, map);
+    }
+
+    @Override
+    public Object getHash(Object key, Object hashKey) {
+        return redisTemplate.opsForHash().get(key, hashKey);
+    }
+
+    @Override
+    public Map<Object, Object> getHash(Object key) {
+        return this.redisTemplate.opsForHash().entries(key);
+    }
+    @Override
+    public Long deleteHash(Object key,Object ... hashKey){
+        return this.redisTemplate.opsForHash().delete(key,hashKey);
+    }
+
+
+    @Override
+    public Set getSetElements(String key){
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    @Override
+    public void addSetElement(String key, String value){
+        redisTemplate.opsForSet().add(key, value);
+    }
+
+    @Override
+    public void addSetElement(String key, Object value) {
+        redisTemplate.opsForSet().add(key, value);
+    }
+
+    @Override
+    public void removeSetElement(String key, String value){
+        redisTemplate.opsForSet().remove(key, value);
+    }
+
+    @Override
+    public void removeSetElement(String key, Object value) {
+        redisTemplate.opsForSet().remove(key, value);
+    }
+}

+ 148 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/config/TaskSchedule.java

@@ -0,0 +1,148 @@
+package com.wdklian.ncs.ms.framework.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.Trigger;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+
+/**
+ * @author wuyunfeng
+ * 2021-06-08 10:14
+ * 任务调度器,用于调度定时任务
+ */
+@Configuration
+@EnableScheduling
+public class TaskSchedule implements SchedulingConfigurer {
+
+
+    private ScheduledTaskRegistrar taskRegistrar;
+
+    @Autowired
+    private ScheduledAnnotationBeanPostProcessor postProcessor;
+
+    //任务池
+    private final Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<>();
+
+    @Override
+    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+        this.taskRegistrar = taskRegistrar;
+
+        //创建一个线程池调度器
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        scheduler.initialize();
+        //设置线程池容量
+        scheduler.setPoolSize(20);
+        //线程名前缀
+        scheduler.setThreadNamePrefix("task-");
+        //等待时长
+        scheduler.setAwaitTerminationSeconds(60);
+        //当调度器shutdown被调用时等待当前被调度的任务完成
+        scheduler.setWaitForTasksToCompleteOnShutdown(true);
+        //设置当任务被取消的同时从当前调度器移除的策略
+        scheduler.setRemoveOnCancelPolicy(true);
+        //设置任务注册器的调度器
+        taskRegistrar.setTaskScheduler(scheduler);
+    }
+
+    /**
+     * 调度 定时任务
+     *
+     * @param taskName 任务名称
+     * @param task     任务函数
+     * @param trigger  定时器
+     * @return
+     */
+    public ScheduledFuture<?> scheduleTask(@NotNull String taskName, @NotNull Runnable task, @NotNull Trigger trigger) {
+        while (true) {
+            if (this.taskRegistrar != null) {
+                cancelTask(taskName);
+                ScheduledFuture<?> futureTask = this.taskRegistrar.getScheduler().schedule(task, trigger);
+                this.taskFutures.put(taskName, futureTask);
+                return futureTask;
+            }
+        }
+    }
+
+    /**
+     * 调度 即时任务
+     *
+     * @param taskName 任务名称
+     * @param task     任务函数
+     * @param date     开始时间
+     * @return
+     */
+    public ScheduledFuture<?> scheduleTask(@NotNull String taskName, @NotNull Runnable task, @NotNull Date date) {
+        while (true) {
+            if (this.taskRegistrar != null) {
+                cancelTask(taskName);
+                ScheduledFuture<?> future = this.taskRegistrar.getScheduler().schedule(task, date);
+
+                this.taskFutures.put(taskName, future);
+                return future;
+            }
+        }
+    }
+
+
+    /**
+     * 调度 延迟任务
+     *
+     * @param taskName  任务名称
+     * @param task      任务函数
+     * @param startTime 开始时间
+     * @param period 执行周期
+     * @return
+     */
+    public ScheduledFuture<?> scheduleTask(@NotNull String taskName, @NotNull Runnable task, @NotNull Date startTime, Long period) {
+       while (true) {
+           if(this.taskRegistrar!=null) {
+               cancelTask(taskName);
+               ScheduledFuture<?> future = this.taskRegistrar.getScheduler().scheduleAtFixedRate(task, startTime, period);
+               this.taskFutures.put(taskName, future);
+               return future;
+           }
+       }
+    }
+
+    /**
+     * 取消任务
+     *
+     * @param taskName
+     */
+    public void cancelTask(String taskName) {
+        while (true) {
+            if (this.taskRegistrar != null) {
+//                for (ScheduledTask scheduledTask : this.taskRegistrar.getScheduledTasks()) {
+//                    Task t = scheduledTask.getTask();
+//                }
+                ScheduledFuture<?> future = this.taskFutures.get(taskName);
+                if (future != null) {
+                    future.cancel(true);
+                }
+                this.taskFutures.remove(taskName);
+                break;
+            }
+        }
+    }
+
+
+    public ScheduledTaskRegistrar getTaskRegistrar() {
+        return taskRegistrar;
+    }
+
+    public Map<String, ScheduledFuture<?>> getTaskFutures() {
+        return taskFutures;
+    }
+
+
+}

+ 66 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/ApplicationContextHolder.java

@@ -0,0 +1,66 @@
+package com.wdklian.ncs.ms.framework.context;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * spring 上下文件获取类
+ * Created by Allen on 2018/3/23.
+ * @author Allen
+ * @version 1.0.0
+ */
+@Component
+public class ApplicationContextHolder implements ApplicationContextAware {
+
+    /**
+     * 上下文对象实例
+     */
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext appContext) throws BeansException {
+        applicationContext = appContext;
+    }
+
+    /**
+     * 获取applicationContext
+     * @return  spring applicationContext
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
+     * 通过name获取 Bean.
+     * @param name bean的名字
+     * @return bean实例
+     */
+    public static Object getBean(String name){
+        return getApplicationContext().getBean(name);
+    }
+
+    /**
+     * 通过class获取Bean.
+     * @param clazz bean的类型
+     * @param <T> bean的类型
+     * @return bean实例
+     */
+    public static <T> T getBean(Class<T> clazz){
+        return getApplicationContext().getBean(clazz);
+    }
+
+    /**
+     * 通过name,以及Clazz返回指定的Bean
+     * @param name bean的名字
+     * @param clazz bean的类型
+     * @param <T>  bean的类型
+     * @return bean实例
+     */
+    public static <T> T getBean(String name,Class<T> clazz){
+        return getApplicationContext().getBean(name, clazz);
+    }
+
+}

+ 89 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelArgumentResolver.java

@@ -0,0 +1,89 @@
+package com.wdklian.ncs.ms.framework.context;
+
+
+import com.google.common.base.CaseFormat;
+import org.jsoup.Jsoup;
+import org.jsoup.safety.Safelist;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.SimpleTypeConverter;
+import org.springframework.core.MethodParameter;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+/**
+ * 蛇形转驼峰参数转换器
+ * 以及防xss的参数过滤
+ * 用于基本类型
+ * @author Allen
+ * @version 1.0
+ */
+public class SnakeToCamelArgumentResolver implements HandlerMethodArgumentResolver {
+
+	/**
+	 * 默认分页大小
+	 */
+	private static final int DEFAULT_SIZE = 10;
+
+	/**
+	 * 默认开始页码
+	 */
+	private static final int DEFAULT_NO = 1;
+	
+	/**
+	 * 定义只有基本类型参数才转换
+	 * @param parameter spring机制传过来的当前要处理的参数
+	 * @return 只有基本类型参数才返回true,否则返回false
+	 */
+	@Override
+	public boolean supportsParameter(MethodParameter parameter) {
+		//只处理基本类型的参数
+		return  BeanUtils.isSimpleProperty(parameter.getParameterType());
+	}
+
+
+	/**
+	 * 将蛇形参数值转换给驼峰参数值
+	 * @param parameter 要处理的参数
+	 * @param mavContainer spring mavContainer
+	 * @param webRequest  spring  webRequest
+	 * @param binderFactory spring binderFactory
+	 * @return 转换后的参数值
+	 * @throws Exception
+	 */
+	@Override
+	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
+                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
+
+		//将蛇形参数名转为驼峰参数名,再读值返回
+		String paramName  = parameter.getParameterName();
+		String camelName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, paramName);
+		SimpleTypeConverter converter = new SimpleTypeConverter();
+
+		Object param = converter.convertIfNecessary(webRequest.getParameter(camelName),parameter.getParameterType());
+
+		//如果是字串型参数,则进行xss过滤
+		if( param instanceof String){
+			param = Jsoup.clean((String)param, Safelist.basicWithImages());
+		}
+
+		//分页相关,增加默认分页
+		if(param == null ){
+			if ("pageNo".equals(paramName)) {
+
+				return DEFAULT_NO;
+			}
+
+			if ("pageSize".equals(paramName)) {
+
+				return DEFAULT_SIZE;
+			}
+		}
+
+		return 	param;
+
+	}
+
+
+}

+ 45 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelModelAttributeMethodProcessor.java

@@ -0,0 +1,45 @@
+package com.wdklian.ncs.ms.framework.context;
+
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
+
+import javax.servlet.ServletRequest;
+
+/**
+ * 蛇形转驼峰参数转换器
+ * 用于非基本类型
+ * Created by Allen.
+ *
+ * @author Allen
+ * @version 1.0
+ */
+public class SnakeToCamelModelAttributeMethodProcessor extends ServletModelAttributeMethodProcessor {
+
+
+    /**
+     * 构造函数
+     *
+     * @param annotationNotRequired 注解是否必须
+     */
+    public SnakeToCamelModelAttributeMethodProcessor(boolean annotationNotRequired) {
+        super(annotationNotRequired);
+    }
+
+    /**
+     * 绑定蛇形转驼峰Binder
+     *
+     * @param binder  spring 机制传琛来的binder
+     * @param request spring机制的web request
+     */
+    @Override
+    @InitBinder
+    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
+        SnakeToCamelRequestDataBinder camelBinder = new SnakeToCamelRequestDataBinder(binder.getTarget(), binder.getObjectName());
+        camelBinder.bind(request.getNativeRequest(ServletRequest.class));
+        super.bindRequestParameters(binder, request);
+    }
+
+
+}

+ 71 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/SnakeToCamelRequestDataBinder.java

@@ -0,0 +1,71 @@
+package com.wdklian.ncs.ms.framework.context;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.CaseFormat;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
+
+import javax.servlet.ServletRequest;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 蛇形转驼峰数据绑定器
+ * Created by Allen
+ *
+ * @author Allen
+ * @version 1.0
+ */
+public class SnakeToCamelRequestDataBinder extends ExtendedServletRequestDataBinder {
+
+
+    /**
+     * 构造器,根据spring机制机要求存在
+     *
+     * @param target     spring 机制传递 target
+     * @param objectName spring 机制传递 objectName
+     */
+    public SnakeToCamelRequestDataBinder(Object target, String objectName) {
+        super(target, objectName);
+    }
+
+    /**
+     * 对蛇形参数绑定值
+     *
+     * @param mpvs    spring 机制传递   mpvs
+     * @param request spring 机制传递  request
+     */
+    @Override
+    protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
+        super.addBindValues(mpvs, request);
+
+        //处理JsonProperty注释的对象
+        Class<?> targetClass = getTarget().getClass();
+        Field[] fields = targetClass.getDeclaredFields();
+        for (Field field : fields) {
+            JsonProperty jsonPropertyAnnotation = field.getAnnotation(JsonProperty.class);
+            if (jsonPropertyAnnotation != null && mpvs.contains(jsonPropertyAnnotation.value())) {
+                if (!mpvs.contains(field.getName())) {
+                    mpvs.add(field.getName(), mpvs.getPropertyValue(jsonPropertyAnnotation.value()).getValue());
+                }
+            }
+        }
+
+        List<PropertyValue> covertValues = new ArrayList<PropertyValue>();
+        for (PropertyValue propertyValue : mpvs.getPropertyValueList()) {
+            if (propertyValue.getName().contains("_")) {
+                String camelName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, propertyValue.getName());
+                if (!mpvs.contains(camelName)) {
+                    covertValues.add(new PropertyValue(camelName, propertyValue.getValue()));
+                }
+            }
+        }
+
+
+        mpvs.getPropertyValueList().addAll(covertValues);
+    }
+
+
+}

+ 47 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/ThreadContextHolder.java

@@ -0,0 +1,47 @@
+package com.wdklian.ncs.ms.framework.context;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ *  用ThreadLocal来存储Session,以便实现Session any where 
+ * @author Allen
+ * @version 1.1
+ * 新增request any where
+ */
+public class ThreadContextHolder  {
+
+	private static final ThreadLocal<HttpServletRequest> requestThreadLocalHolder = new ThreadLocal<HttpServletRequest>();
+	private static final ThreadLocal<HttpServletResponse> responseThreadLocalHolder = new ThreadLocal<HttpServletResponse>();
+
+
+	public static void setHttpRequest(HttpServletRequest request){
+		
+		requestThreadLocalHolder.set(request);
+	}
+
+	public static void setHttpResponse(HttpServletResponse response){
+		responseThreadLocalHolder.set(response);
+	}
+
+	
+	public static void remove(){
+		requestThreadLocalHolder.remove();
+		responseThreadLocalHolder.remove();
+	}
+	
+	
+
+	public static HttpServletResponse getHttpResponse(){
+		
+		return responseThreadLocalHolder.get();
+	}
+	public static HttpServletRequest getHttpRequest(){
+		return  requestThreadLocalHolder.get();
+	}
+
+
+	
+}

+ 53 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/WdklRequestInterceptor.java

@@ -0,0 +1,53 @@
+package com.wdklian.ncs.ms.framework.context;
+
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * 上下文初始化
+ * 以及跨域的支持
+ * @author Allen
+ * @version v1.0
+ */
+public class WdklRequestInterceptor extends HandlerInterceptorAdapter {
+
+
+	/**
+	 * 拦截request和response并放到上下文中
+	 * @param request 要拦截的request
+	 * @param response 要拦截的response
+	 * @param handler spring 机制传递过来的
+	 * @return 不中断,继续执行,返回为true
+	 * @throws Exception
+	 */
+	@Override
+    public boolean preHandle(HttpServletRequest request,
+                             HttpServletResponse response, Object handler) throws Exception {
+
+		//request 和response存到 上下文中
+		ThreadContextHolder.setHttpResponse(response);
+		ThreadContextHolder.setHttpRequest(request);
+
+		return super.preHandle(request, response, handler);
+	}
+
+
+	/**
+	 * 处理完成 从上下文中移除 request 和respseon
+	 * @param request
+	 * @param response
+	 * @param handler
+	 * @param ex
+	 * @throws Exception
+	 */
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
+		ThreadContextHolder.remove();
+
+		super.afterCompletion(request, response, handler, ex);
+	}
+}

+ 61 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/context/WebInterceptorConfigurer.java

@@ -0,0 +1,61 @@
+package com.wdklian.ncs.ms.framework.context;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.wdklian.ncs.ms.framework.security.XssStringJsonSerializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+
+import java.util.List;
+
+/**
+ * 
+ * 加载自定义的 拦截器
+ * @author Chopper
+ * @version v1.0
+ * @since v6.2 2019年3月7日 下午5:29:56
+ *
+ */
+@Configuration
+public class WebInterceptorConfigurer implements WebMvcConfigurer {
+
+	@Override
+	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+
+		//参数蛇形转驼峰拦截
+		argumentResolvers.add(new SnakeToCamelModelAttributeMethodProcessor(true));
+		argumentResolvers.add(new SnakeToCamelArgumentResolver());
+
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new WdklRequestInterceptor()).addPathPatterns("/**");
+	}
+
+	/**
+	 * 自定义 ObjectMapper ,用于xss攻击过滤
+ 	 * @param builder
+	 * @return
+	 */
+	@Bean
+	@Primary
+	public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) {
+		//解析器
+		ObjectMapper objectMapper = builder.createXmlMapper(false).build();
+		//注册xss解析器
+		SimpleModule xssModule = new SimpleModule("XssStringJsonSerializer");
+		xssModule.addSerializer(new XssStringJsonSerializer());
+		objectMapper.registerModule(xssModule);
+		//返回
+		return objectMapper;
+	}
+
+
+}

+ 46 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/CRUDBaseManager.java

@@ -0,0 +1,46 @@
+package com.wdklian.ncs.ms.framework.database;
+
+
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+
+/**
+ * 描述
+ *
+ * @author allen
+ */
+public interface CRUDBaseManager<T> {
+    /**
+     * 分页对象
+     * @param gp
+     * @return
+     */
+    Page list(GridParameter gp);
+
+    /**
+     * 编辑对象
+     * @param t
+     * @param id
+     * @return
+     */
+    T edit(T t, Integer id);
+
+    /**
+     * 新增对象
+     * @param t
+     * @return
+     */
+    T add(T t);
+
+    /**
+     * 删除
+     * @param ids
+     */
+    void delete(Integer[] ids);
+
+    /**
+     * 获取单个对象
+     * @param id
+     * @return
+     */
+    T getModel(Integer id);
+}

+ 34 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ColumnMeta.java

@@ -0,0 +1,34 @@
+package com.wdklian.ncs.ms.framework.database;
+
+/**
+ * 列数据
+ * @author Allen
+ */
+public class ColumnMeta {
+
+    /**
+     * 字段名
+     */
+    private Object[] names;
+
+    /**
+     * 字段值
+     */
+    private Object[] values;
+
+    public Object[] getNames() {
+        return names;
+    }
+
+    public void setNames(Object[] names) {
+        this.names = names;
+    }
+
+    public Object[] getValues() {
+        return values;
+    }
+
+    public void setValues(Object[] values) {
+        this.values = values;
+    }
+}

+ 43 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DBRuntimeException.java

@@ -0,0 +1,43 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 数据库操作运行期异常
+ * @author Allen
+ */
+public class DBRuntimeException extends RuntimeException {
+
+ 
+	private static final long serialVersionUID = -368646349014580765L;
+	
+	private static final Log loger = LogFactory
+			.getLog(DBRuntimeException.class);
+
+	
+	public DBRuntimeException(String message){
+		super(message);
+	}
+	public DBRuntimeException(Exception e,String sql) {
+		
+		super("数据库运行期异常");
+		e.printStackTrace();
+		if(loger.isErrorEnabled()){
+			loger.error("数据库运行期异常,相关sql语句为"+ sql);
+		}
+	}
+	
+	
+	public DBRuntimeException(String message,String sql) {
+		
+		super(message);
+		if(loger.isErrorEnabled()){
+			loger.error(message+",相关sql语句为"+ sql);
+		 
+		}
+		
+	}
+	
+	
+}

+ 310 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DaoSupport.java

@@ -0,0 +1,310 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import org.springframework.jdbc.core.RowMapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 数据库操作支撑接口
+ * @author Allen
+ */
+public interface DaoSupport {
+
+	/**
+	 * 执行sql语句
+	 * @param sql	sql语句
+	 * @param args	参数组
+	 */
+	int execute(String sql, Object... args) ;
+	
+	/**
+	 * 查询单一结果集<br/>
+	 * 并将结果转为<code>int</code>型返回
+	 * @param sql 查询的sql语句,确定结果为一行一列,且为数字型
+	 * @param args 对应sql语句中的参数值
+	 * @return
+	 */
+	Integer queryForInt(String sql, Object... args);
+	
+	/**
+	 * 查询单一结果集<br/>
+	 * 并将结果转为<code>long</code>型返回
+	 * @param sql 查询的sql语句,确保结果为一行一列,且为数字型
+	 * @param args 对应sql语句中的参数值
+	 * @return
+	 */
+	Long queryForLong(String sql, Object... args);
+	
+	
+	/**
+	 * 查询单一结果集<br/>
+	 * 并将结果转为<code>float</code>型返回
+	 * @param sql 查询的sql语句,确保结果为一行一列,且为数字型
+	 * @param args 对应sql语句中的参数值
+	 * @return
+	 */
+	Float queryForFloat(String sql, Object... args);
+	
+	
+	/**
+	 * 查询单一结果集<br/>
+	 * 并将结果转为<code>dobule</code>型返回
+	 * @param sql 查询的sql语句,确保结果为一行一列,且为数字型
+	 * @param args 对应sql语句中的参数值
+	 * @return
+	 */
+	Double queryForDouble(String sql, Object... args);
+	
+	
+	
+	
+	/**
+	 * 查询String 结果
+	 * @param sql 查询语句
+	 * @param args 参数 
+	 * @return String型的结果
+	 */
+	String queryForString(String sql, Object... args);
+	
+	/**
+	 * 查询单一结果集<br/>
+	 * 并将结果转为<code>Map</code>对象返回
+	 * @param sql 查询的sql语句
+	 * @param args 对应sql语句中的参数值
+	 * @return 以结果集中的列为key,值为value的<code>Map</code>
+	 */
+	@SuppressWarnings("unchecked")
+	Map queryForMap(String sql, Object... args) ;
+	
+	/**
+	 * 查询多行结果集<br/>
+	 * 并将结果转为<code>List<Map></code>
+	 * @param sql 查询的sql语句
+	 * @param args 对应sql语句中的参数值
+	 * @return  列表中元素为<code>Map</code>的<code>List</code>,<br/>Map结构:以结果集中的列为key,值为value,
+	 */
+	@SuppressWarnings("unchecked")
+	List  queryForList(String sql, Object... args);
+	
+	
+	
+	/**
+	 * 查询多行结果集<br/>
+	 * 并将结果转为<code>List<T></code>
+	 * @param sql 查询的sql语句
+	 * @param clazz <code><T></code>的Class对象
+	 * @param args 对应sql语句中的参数值
+	 * @return  列表中元素为<code>T</code>的<code>List</code>
+	 */
+	<T> List<T> queryForList(String sql, Class<T> clazz, Object... args);
+
+
+	/**
+	 * 使用rowmapper查询多行结果集<br/>
+	 * 并将结果转为<code>List<T></code>
+	 * @param sql 查询的sql语句
+	 * @param rowMapper mapper
+	 * @param args  查询参数
+	 * @param <T>   列表中元素类型
+	 * @return
+	 */
+	<T> List<T> queryForList(String sql, RowMapper<T> rowMapper, Object... args);
+
+
+	/**
+	 * 分页查询多行结果集<br/>
+	 * @param sql 查询的sql语句
+	 * @param pageNo 查询的起始页
+	 * @param pageSize  每页数量
+	 * @param args  对应sql语句中的参数值
+	 * @return 列表中元素为<code>Map</code>的<code>List</code>,<br/>Map结构:以结果集中的列为key,值为value,
+	 */
+	@SuppressWarnings("unchecked")
+	<T> List<Map> queryForListPage(String sql, int pageNo, int pageSize, Object... args);
+	
+
+	/**
+	 * 分页查询
+	 * @param sql  查询的sql语句
+	 * @param pageNo 查询的起始页
+	 * @param pageSize  每页数量
+	 * @param args  对应sql语句中的参数值
+	 * @return 分页结果集对象
+	 */
+	Page queryForPage(String sql, int pageNo, int pageSize, Object... args) ;
+	
+	/**
+	 * 分页查询
+	 * @param sql  查询的sql语句
+	 * @param countSql 用于查询总记录数的sql语句
+	 * @param pageNo 查询的起始页
+	 * @param pageSize  每页数量
+	 * @param args  对应sql语句中的参数值
+	 * @return 分页结果集对象
+	 */
+	Page queryForPage(String sql, String countSql, int pageNo, int pageSize, Object... args);
+
+	/**
+	 * 分页查询
+	 * @param sql  查询的sql语句
+	 * @param countSql 用于查询总记录数的sql语句
+	 * @param pageNo 查询的起始页
+	 * @param pageSize  每页数量
+	 * @return 分页结果集对象
+	 */
+	Page queryForPage(String sql, String countSql, int pageNo, int pageSize);
+
+	
+	/**
+	 * 分页查询
+	 * @param sql 查询的sql语句
+	 * @param pageNo 查询的起始页
+	 * @param pageSize 每页数量
+	 * @param clazz  <code><T></code>的Class对象
+	 * @param args 对应sql语句中的参数值
+	 * @return
+	 */
+	<T> Page queryForPage(String sql, int pageNo, int pageSize, Class<T> clazz, Object... args);
+
+	/**
+	 * 分页查询 Add By Allen. 20190325
+	 *
+	 * @param gp
+	 * @param clazz
+	 * @param <T>
+	 * @return
+	 */
+	<T> Page queryForPage(GridParameter gp, Class<T> clazz);
+	
+	/**
+	 * 更新数据
+	 * @param table 表名
+	 * @param fields 字段-值Map
+	 * @param where 更新条件(字段-值Map)
+	 */
+	@SuppressWarnings("unchecked")
+	int update(String table, Map fields, Map<String, ?> where);
+
+	/**
+	 * 批量更新数据
+	 * @param sql 要执行的sql
+	 * @param batchArgs 相应的参数
+	 * @return
+	 */
+	int[] batchUpdate(String sql, List<Object[]> batchArgs);
+
+	/**
+	 * 批量更新数据
+	 * @param sql 要执行的sql数组
+	 * @return
+	 */
+	int[] batchUpdate(String... sql);
+
+
+	/**
+	 * 更新数据
+	 * @param table 表名
+	 * @param po 要更新的对象,保证对象的属性名和字段名对应
+	 * @param where 更新条件(字段-值Map)
+	 */
+	@SuppressWarnings("unchecked")
+	int update(String table, Object po, Map<String, ?> where);
+
+
+
+	/**
+	 * 新增数据
+	 * @param table  表名
+	 * @param fields 字段-值Map
+	 */
+	@SuppressWarnings("unchecked")
+	void insert(String table, Map fields);
+    /**
+     * 新增或更新数据 仅MySQL 可用
+     *
+     * @date 2024-01-10 16:41
+     * @author wuyunfeng
+     * @param table 表名
+     * @param fields 字段-值Map
+     * @return
+     */
+    int insertOrUpdate(String table, Map fields);
+
+	int insertOrUpdate(String table, Object po);
+
+	/**
+	 * 新增数据
+	 * @param table 表名
+	 * @param po 要新增的对象,保证对象的属性名和字段名对应
+	 */
+	void insert(String table, Object po);
+
+	/**
+	 * 读取最后插入的主键id
+	 * @param table	表名
+	 * @return
+	 */
+	int getLastId(String table);
+
+
+	/**
+	 * 执行带分页的sql语句
+	 * @param sql	sql语句
+	 * @param page	页数
+	 * @param pageSize	条数
+	 * @return
+	 */
+	String buildPageSql(String sql, int page, int pageSize);
+
+	/**
+	 * 新增数据
+	 * @param t  DO对象
+	 * @param <T>
+	 */
+	<T> void insert(T t);
+
+    /**
+     * 新增数据
+     *
+     * @param t   DO对象
+     * @param <T>
+     */
+    <T> int insertRecord(T t);
+
+	/**
+	 * 修改数据
+	 * @param model	DO对象
+	 * @param id	主键ID
+	 * @param <T>
+	 */
+	<T> void update(T model, Integer id);
+
+	/**
+	 * 删除数据
+	 * @param clazz	DO对象的class
+	 * @param id	主键ID
+	 * @param <T>
+	 */
+	<T> void delete(Class<T> clazz, Integer id);
+
+	/**
+	 * 查询一行数据
+	 * @param clazz	DO对象的class
+	 * @param id	主键ID
+	 * @param <T>
+	 * @return
+	 */
+	<T> T queryForObject(Class<T> clazz, Integer id);
+
+
+	/**
+	 * 查询一个对象
+	 * @param sql 查询 sql
+	 * @param args  sql中的查询 参数
+	 * @param clazz 对象的类型
+	 * @return 数据转后的对象
+	 */
+	<T> T queryForObject(String sql, Class<T> clazz, Object... args);
+}

+ 45 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DataMeta.java

@@ -0,0 +1,45 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import java.util.Arrays;
+
+/**
+ * 元数据
+ * @author Allen
+ */
+public class DataMeta {
+
+    /**
+     * sql 语句
+     */
+    private String sql;
+
+    /**
+     * sql 语句中需要的参数
+     */
+    private Object[] paramter;
+
+
+    public String getSql() {
+        return sql;
+    }
+
+    public void setSql(String sql) {
+        this.sql = sql;
+    }
+
+    public Object[] getParamter() {
+        return paramter;
+    }
+
+    public void setParamter(Object[] paramter) {
+        this.paramter = paramter;
+    }
+
+    @Override
+    public String toString() {
+        return "DataMeta{" +
+                "sql='" + sql + '\'' +
+                ", paramter=" + Arrays.toString(paramter) +
+                '}';
+    }
+}

+ 21 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DoubleMapper.java

@@ -0,0 +1,21 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 浮点型mapper
+ * @author Allen
+ */
+public class DoubleMapper implements RowMapper<Double> {
+
+	
+	@Override
+    public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
+		Double dobule = new Double(rs.getDouble(1));
+		return dobule;
+	}
+
+}

+ 29 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/DynamicField.java

@@ -0,0 +1,29 @@
+package com.wdklian.ncs.ms.framework.database;
+
+
+import com.wdklian.ncs.ms.framework.database.annotation.NotDbField;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 动态字段
+ * @author Allen
+ */
+public class DynamicField {
+	
+	private final Map<String,Object> fields;
+	public DynamicField(){
+		fields = new HashMap<String, Object>();
+	}
+	
+	public void addField(String name,Object value){
+		fields.put(name, value);
+	}
+	
+	@NotDbField
+	public Map<String,Object> getFields(){
+		return fields;
+	}
+}

+ 17 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ISqlFileExecutor.java

@@ -0,0 +1,17 @@
+package com.wdklian.ncs.ms.framework.database;
+
+
+/**
+ * sql文件执行器
+ * @author Allen
+ */
+public interface ISqlFileExecutor {
+	
+	/**
+	 * 批量执行sql语句
+	 * @param sql 可以以两种形式传递sql:<br>
+	 * <li>1.路径方式:file:com/enation/eop/eop_empty.sql</li>
+	 * <li>2.sql内容:直接传递文件内容</li>
+	 */
+    void execute(String sql);
+}

+ 20 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/IntegerMapper.java

@@ -0,0 +1,20 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 整型mapper
+ * @author Allen
+ */
+public class IntegerMapper implements RowMapper<Integer> {
+	
+	@Override
+    public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
+		Integer  v = rs.getInt(1);
+		return v;
+	}
+
+}

+ 24 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/ObjectNotFoundException.java

@@ -0,0 +1,24 @@
+package com.wdklian.ncs.ms.framework.database;
+
+/**
+ * 对像未找到异常<br>
+ * 多用于根据某id查询一条记录,但此记录不存在
+ * @author Allen
+ */
+public class ObjectNotFoundException extends DBRuntimeException {
+
+	public ObjectNotFoundException(String message) {
+		super(message);
+	}
+		
+	public ObjectNotFoundException(Exception e, String sql) {
+		super(e, sql);
+	 
+	}
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3403302876974180460L;
+
+}

+ 138 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/Page.java

@@ -0,0 +1,138 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 分页对象. 包含当前页数据及分页信息如总记录数.
+ *
+ * @param <T> 数据类型
+ * @author Allen
+ */
+@ApiModel(value = "数据分页对象")
+@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
+public class Page<T> implements Serializable {
+
+	/**
+	 * 数据列表
+	 */
+	@ApiModelProperty(value = "列表数据")
+	private List<T> data;
+
+	/**
+	 * 当前页码
+	 */
+	@ApiModelProperty(value = "当前页码")
+	private Integer pageNo;
+
+
+	/**
+	 * 分页大小
+	 */
+	@ApiModelProperty(value = "分页大小")
+	private Integer pageSize;
+
+	/**
+	 * 总计录数
+	 */
+	@ApiModelProperty(value = "总计录数")
+	private Long dataTotal;
+
+
+	/**
+	 * 构造方法
+	 *
+	 * @param data      数据列表
+	 * @param pageNo    当前页码
+	 * @param pageSize  页大小
+	 * @param dataTotal 总计录数
+	 */
+	public Page(Integer pageNo, Long dataTotal, Integer pageSize, List<T> data) {
+		this.data = data;
+		this.pageNo = pageNo;
+		this.pageSize = pageSize;
+		this.dataTotal = dataTotal;
+	}
+
+	public Page() {
+	}
+
+	public List<T> getData() {
+		return data;
+	}
+
+	public void setData(List<T> data) {
+		this.data = data;
+	}
+
+	public Integer getPageNo() {
+		return pageNo;
+	}
+
+	public void setPageNo(Integer pageNo) {
+		this.pageNo = pageNo;
+	}
+
+	public Integer getPageSize() {
+		return pageSize;
+	}
+
+	public void setPageSize(Integer pageSize) {
+		this.pageSize = pageSize;
+	}
+
+	public Long getDataTotal() {
+		return dataTotal;
+	}
+
+	public void setDataTotal(Long dataTotal) {
+		this.dataTotal = dataTotal;
+	}
+
+	@Override
+	public String toString() {
+		return "Page{" +
+				"data=" + data +
+				", pageNo=" + pageNo +
+				", pageSize=" + pageSize +
+				", dataTotal=" + dataTotal +
+				'}';
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) {
+			return true;
+		}
+		if (o == null || getClass() != o.getClass()) {
+			return false;
+		}
+
+		Page<?> page = (Page<?>) o;
+
+		if (data != null ? !data.equals(page.data) : page.data != null) {
+			return false;
+		}
+		if (pageNo != null ? !pageNo.equals(page.pageNo) : page.pageNo != null) {
+			return false;
+		}
+		if (pageSize != null ? !pageSize.equals(page.pageSize) : page.pageSize != null) {
+			return false;
+		}
+		return dataTotal != null ? dataTotal.equals(page.dataTotal) : page.dataTotal == null;
+	}
+
+	@Override
+	public int hashCode() {
+		int result = data != null ? data.hashCode() : 0;
+		result = 31 * result + (pageNo != null ? pageNo.hashCode() : 0);
+		result = 31 * result + (pageSize != null ? pageSize.hashCode() : 0);
+		result = 31 * result + (dataTotal != null ? dataTotal.hashCode() : 0);
+		return result;
+	}
+}

+ 40 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/SqlMetaBuilder.java

@@ -0,0 +1,40 @@
+package com.wdklian.ncs.ms.framework.database;
+
+/**
+ * 元数据构建器
+ * 构建模型构建执行sql的构建器
+ * @author Allen
+ */
+public interface SqlMetaBuilder {
+
+    /**
+     * 通过一个模型,获取新增数据的元数据信息
+     * @param <T> model的类型
+     * @param model 模型
+     * @return insert的元数据
+     */
+    <T> DataMeta insert(T model);
+
+    /**
+     * 通过一个模型,获取修改数据的元数据信息
+     * @param <T>  model的类型
+     * @param model 模型
+     * @param id 主键值
+     * @return update的元数据
+     */
+    <T> DataMeta update(T model, Integer id);
+
+    /**
+     * 通过Class,获取查询一行数据的sql
+     * @param clazz 模型的类型
+     * @return 查询一个模型的sql,其中已经拼接好根据主键查询的的where条件
+     */
+    String queryForModel(Class clazz);
+
+    /**
+     * 通过Class,获取删除一行数据的sql
+     * @param clazz 模型的类型
+     * @return 删除的sql语句,其中已经拼接好根据主键删除的where条件
+     */
+    String delete(Class clazz);
+}

+ 21 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/StringMapper.java

@@ -0,0 +1,21 @@
+package com.wdklian.ncs.ms.framework.database;
+
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 字符串型mapper
+ * @author Allen
+ */
+public class StringMapper implements RowMapper<String> {
+
+	
+	@Override
+    public String mapRow(ResultSet rs, int rowNum) throws SQLException {
+		String str = rs.getString(1);
+		return str;
+	}
+
+}

+ 21 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Column.java

@@ -0,0 +1,21 @@
+package com.wdklian.ncs.ms.framework.database.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 标识为数据库的字段
+ * @author Allen
+ */
+@Target(ElementType.FIELD) 
+@Retention(RetentionPolicy.RUNTIME) 
+public @interface Column {
+
+	String name() default "";
+
+	boolean allowNullUpdate() default  false;
+
+
+}

+ 17 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Id.java

@@ -0,0 +1,17 @@
+package com.wdklian.ncs.ms.framework.database.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 标识为此表的主键ID
+ * @author Allen
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Id {
+
+    String name() default "";
+}

+ 17 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/NotDbField.java

@@ -0,0 +1,17 @@
+package com.wdklian.ncs.ms.framework.database.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 标识不是数据库读写的字段
+ * @author Allen
+ * 2010-1-22下午04:08:58
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target(ElementType.METHOD) 
+public @interface NotDbField {
+
+}

+ 17 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/PrimaryKeyField.java

@@ -0,0 +1,17 @@
+package com.wdklian.ncs.ms.framework.database.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 标识不是数据库读写的字段
+ * @author Allen
+ * 2010-1-22下午04:08:58
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target(ElementType.METHOD) 
+public @interface PrimaryKeyField {
+
+}

+ 21 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/annotation/Table.java

@@ -0,0 +1,21 @@
+package com.wdklian.ncs.ms.framework.database.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 标识为数据库的表名
+ * @author Allen
+ */
+@Target(ElementType.TYPE) 
+@Retention(RetentionPolicy.RUNTIME) 
+public @interface Table {
+
+	/**
+	 * 数据库的表名
+	 * @return
+	 */
+	String name();
+}

+ 58 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/AbstractCRUDBaseManagerImpl.java

@@ -0,0 +1,58 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import com.wdklian.ncs.ms.framework.database.CRUDBaseManager;
+import com.wdklian.ncs.ms.framework.database.DaoSupport;
+import com.wdklian.ncs.ms.framework.database.Page;
+import com.wdklian.ncs.ms.framework.exception.ServiceException;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.util.BeanUtil;
+
+import java.lang.reflect.ParameterizedType;
+
+public abstract class AbstractCRUDBaseManagerImpl<T> implements CRUDBaseManager<T> {
+
+
+    public DaoSupport daoSupport;
+
+   public abstract void setDaoSupport(DaoSupport daoSupport);
+
+    private Class<T> getGenericClass(){
+        Class<T> entityClass = (Class <T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+        return entityClass;
+    }
+
+    @Override
+    public Page list(GridParameter gp) {
+        return daoSupport.queryForPage(gp,getGenericClass());
+    }
+
+    @Override
+    public T edit(T t, Integer id) {
+        T dbModel = daoSupport.queryForObject(getGenericClass(), id);
+        if (dbModel == null) {
+            throw new ServiceException("没有找到数据");
+        }
+
+        BeanUtil.copyProperties(t, dbModel);
+        daoSupport.update(dbModel, id);
+        return dbModel;
+    }
+
+    @Override
+    public T add(T t) {
+        daoSupport.insert(t);
+        return t;
+    }
+
+    @Override
+    public void delete(Integer[] ids) {
+        for (Integer id : ids) {
+            daoSupport.delete(getGenericClass(), id);
+        }
+    }
+
+    @Override
+    public T getModel(Integer id) {
+        return daoSupport.queryForObject(getGenericClass(), id);
+    }
+}

+ 669 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/DaoSupportImpl.java

@@ -0,0 +1,669 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import com.wdklian.ncs.ms.framework.database.*;
+import com.wdklian.ncs.ms.framework.mvc.GridParameter;
+import com.wdklian.ncs.ms.framework.util.ReflectionUtil;
+import com.wdklian.ncs.ms.framework.util.StringUtil;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * jdbc数据库操作支撑实现类
+ *
+ * @author Allen create in 2018/3/21
+ * @version v2.0
+ * @since v7.0.0
+ */
+
+public class DaoSupportImpl implements DaoSupport {
+    private String dbType = "mysql";
+
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private SqlMetaBuilder sqlMetaBuilder;
+
+    /**
+     * 日志记录
+     */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * order by 语句正则
+     */
+    private static final Pattern ORDER_PATTERN = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
+
+    /**
+     * 删除select正则
+     */
+    private static final Pattern REMOVE_SELECT_PATTERN = Pattern.compile("\\(.*\\)", Pattern.CASE_INSENSITIVE);
+
+    public DaoSupportImpl() {
+    }
+
+    /**
+     * 实例化jdbcTemplate
+     */
+    public DaoSupportImpl(JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+        try {
+            String databaseProductName = this.jdbcTemplate.getDataSource().getConnection().getMetaData().getDatabaseProductName();
+            logger.info("数据库类型:" + databaseProductName);
+            if (databaseProductName.equals("Microsoft SQL Server")) {
+                this.dbType = "sqlserver";
+            } else if (databaseProductName.equals("MySQL")) {
+                this.dbType = "mysql";
+            } else {
+                this.dbType = "oracle";
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public DaoSupportImpl(JdbcTemplate jdbcTemplate, SqlMetaBuilder sqlMetaBuilder) {
+        this.jdbcTemplate = jdbcTemplate;
+        try {
+            String databaseProductName = this.jdbcTemplate.getDataSource().getConnection().getMetaData().getDatabaseProductName();
+            logger.info("数据库类型:" + databaseProductName);
+            if (databaseProductName.equals("Microsoft SQL Server")) {
+                this.dbType = "sqlserver";
+            } else if (databaseProductName.equals("MySQL")) {
+                this.dbType = "mysql";
+            } else {
+                this.dbType = "oracle";
+            }
+            this.sqlMetaBuilder = sqlMetaBuilder;
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public int execute(String sql, Object... args) {
+        try {
+            int rowNum = this.jdbcTemplate.update(sql, args);
+
+            return rowNum;
+        } catch (Exception e) {
+            throw new DBRuntimeException(e, sql);
+        }
+    }
+
+
+    @Override
+    public int getLastId(String table) {
+        String sql;
+        switch (dbType) {
+            case "sqlserver":
+                sql = "SELECT SCOPE_IDENTITY() as id";
+                break;
+            case "oracle":
+                sql = "SELECT SEQNAME.CURRVAL as id FROM DUAL";
+                break;
+            case "postgresql":
+                sql = "SELECT lastval() as id";
+                break;
+            case "mysql":
+            default:
+                sql = "SELECT last_insert_id() as id";
+                break;
+        }
+        return queryForInt(sql);
+    }
+
+    @Override
+    public void insert(String table, Map fields) {
+        String sql = "";
+
+        try {
+
+            Assert.hasText(table, "表名不能为空");
+            Assert.notEmpty(fields, "字段不能为空");
+            table = quoteCol(table);
+
+            Object[] cols = fields.keySet().toArray();
+            Object[] values = new Object[cols.length];
+
+            for (int i = 0; i < cols.length; i++) {
+                if (fields.get(cols[i]) == null) {
+                    values[i] = null;
+                } else {
+                    values[i] = fields.get(cols[i]).toString();
+                }
+                cols[i] = quoteCol(cols[i].toString());
+            }
+
+            sql = "INSERT INTO " + table + " (" + StringUtil.implode(", ", cols);
+
+            sql = sql + ") VALUES (" + StringUtil.implodeValue(", ", values);
+
+            sql = sql + ")";
+
+            jdbcTemplate.update(sql, values);
+        } catch (Exception e) {
+            this.logger.error(e.getMessage(), e);
+            throw new DBRuntimeException(e, sql);
+        }
+    }
+
+
+    @Override
+    public int insertOrUpdate(String table, Map fields) {
+        String sql = "";
+
+        try {
+
+            Assert.hasText(table, "表名不能为空");
+            Assert.notEmpty(fields, "字段不能为空");
+            table = quoteCol(table);
+            String fieldSql = "";
+            Object[] cols = fields.keySet().toArray();
+            Object[] values = new Object[cols.length];
+
+            for (int i = 0; i < cols.length; i++) {
+                if (fields.get(cols[i]) == null) {
+                    values[i] = null;
+                } else {
+                    values[i] = fields.get(cols[i]).toString();
+                }
+                cols[i] = quoteCol(cols[i].toString());
+                fieldSql += cols[i] + "=?";
+                if (i != cols.length - 1) {
+                    fieldSql += ",";
+                }
+            }
+
+            sql = "INSERT INTO " + table + " (" + StringUtil.implode(", ", cols);
+
+            sql = sql + ") VALUES (" + StringUtil.implodeValue(", ", values);
+
+            sql = sql + ") on DUPLICATE KEY UPDATE " + fieldSql;
+
+            return jdbcTemplate.update(sql, ArrayUtils.addAll(values, values));
+        } catch (Exception e) {
+            this.logger.error(e.getMessage(), e);
+            throw new DBRuntimeException(e, sql);
+        }
+    }
+
+    @Override
+    public int insertOrUpdate(String table, Object po) {
+        return insertOrUpdate(table, ReflectionUtil.po2Map(po));
+    }
+
+    @Override
+    public void insert(String table, Object po) {
+        insert(table, ReflectionUtil.po2Map(po));
+    }
+
+    @Override
+    public Integer queryForInt(String sql, Object... args) {
+        try {
+            Integer value = jdbcTemplate.queryForObject(sql, Integer.class, args);
+            return value == null ? 0 : value;
+        } catch (EmptyResultDataAccessException e) {
+            return 0;
+        } catch (RuntimeException e) {
+            this.logger.error(e.getMessage(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public Float queryForFloat(String sql, Object... args) {
+        try {
+
+            Float value = jdbcTemplate.queryForObject(sql, Float.class, args);
+            return value == null ? 0F : value;
+
+        } catch (EmptyResultDataAccessException e) {
+            return 0F;
+        } catch (RuntimeException e) {
+            this.logger.error(e.getMessage(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public Long queryForLong(String sql, Object... args) {
+        try {
+            Long value = jdbcTemplate.queryForObject(sql, Long.class, args);
+            return value == null ? 0L : value;
+        } catch (EmptyResultDataAccessException e) {
+            return 0L;
+        } catch (RuntimeException e) {
+            this.logger.error(e.getMessage(), e);
+            throw e;
+        }
+
+    }
+
+    @Override
+    public Double queryForDouble(String sql, Object... args) {
+        try {
+
+            Double value = jdbcTemplate.queryForObject(sql, Double.class, args);
+            return value == null ? 0D : value;
+
+        } catch (EmptyResultDataAccessException e) {
+            return 0D;
+        } catch (RuntimeException e) {
+            this.logger.error(e.getMessage(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public String queryForString(String sql, Object... args) {
+
+        String s = "";
+        try {
+            s = this.jdbcTemplate.queryForObject(sql, String.class, args);
+        } catch (EmptyResultDataAccessException e) {
+            return "";
+        } catch (RuntimeException e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("查询sql:[" + sql + "]出错", e);
+            }
+
+        }
+        return s;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List queryForList(String sql, Object... args) {
+        return this.jdbcTemplate.queryForList(sql, args);
+    }
+
+
+    @Override
+    public <T> List<T> queryForList(String sql, Class<T> clazz, Object... args) {
+
+        return this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<T>(clazz), args);
+
+    }
+
+    @Override
+    public <T> List<T> queryForList(String sql, RowMapper<T> rowMapper, Object... args) {
+        return jdbcTemplate.query(sql, rowMapper, args);
+    }
+
+    @Override
+    public List queryForListPage(String sql, int pageNo, int pageSize, Object... args) {
+
+        try {
+            Assert.hasText(sql, "SQL语句不能为空");
+            Assert.isTrue(pageNo >= 1, "pageNo 必须大于等于1");
+            String listSql = this.buildPageSql(sql, pageNo, pageSize);
+            return queryForList(listSql, args);
+        } catch (Exception ex) {
+            throw new DBRuntimeException(ex, sql);
+        }
+
+    }
+
+    @Override
+    public Map queryForMap(String sql, Object... args) {
+        try {
+            Map map = this.jdbcTemplate.queryForMap(sql, args);
+
+            return map;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new ObjectNotFoundException(ex, sql);
+        }
+    }
+
+    @Override
+    public Page queryForPage(String sql, int pageNo, int pageSize, Object... args) {
+        String countSql = "SELECT COUNT(*) " + removeSelect(removeOrders(sql));
+        return this.queryForPage(sql, countSql, pageNo, pageSize, args);
+    }
+
+    @Override
+    public Page queryForPage(String sql, String countSql, int pageNo, int pageSize, Object... args) {
+        Assert.hasText(sql, "SQL语句不能为空");
+        Assert.isTrue(pageNo >= 1, "pageNo 必须大于等于1");
+        String listSql = buildPageSql(sql, pageNo, pageSize);
+
+        List list = queryForList(listSql, args);
+        Long totalCount = queryForLong(countSql, args);
+        return new Page(pageNo, totalCount, pageSize, list);
+
+    }
+
+    @Override
+    public Page queryForPage(String sql, String countSql, int pageNo, int pageSize) {
+        Assert.hasText(sql, "SQL语句不能为空");
+        Assert.isTrue(pageNo >= 1, "pageNo 必须大于等于1");
+        String listSql = buildPageSql(sql, pageNo, pageSize);
+
+        List list = queryForList(listSql);
+        Long totalCount = queryForLong(countSql);
+        return new Page(pageNo, totalCount, pageSize, list);
+    }
+
+    @Override
+    public <T> Page queryForPage(String sql, int pageNo, int pageSize, Class<T> clazz, Object... args) {
+
+        Assert.hasText(sql, "SQL语句不能为空");
+        Assert.isTrue(pageNo >= 1, "pageNo 必须大于等于1");
+        String listSql = buildPageSql(sql, pageNo, pageSize);
+        String countSql = "SELECT COUNT(*) " + removeSelect(removeOrders(sql));
+        List<T> list = this.queryForList(listSql, clazz, args);
+        Long totalCount = queryForLong(countSql, args);
+        return new Page(pageNo, totalCount, pageSize, list);
+
+    }
+
+    @Override
+    public <T> Page queryForPage(GridParameter gp, Class<T> clazz) {
+        Assert.isTrue(gp.getPageNo() >= 1, "pageNo 必须大于等于1");
+        Assert.isTrue(gp.getPageSize() >= 1, "每页显示条数不能小于1");
+
+
+        StringBuilder sb = new StringBuilder();
+        if (!StringUtil.isEmpty(gp.getDir()) && !StringUtil.isEmpty(gp.getSort())) {
+            sb.append(" ORDER BY ").append(gp.getSort()).append(" ").append(gp.getDir()).append(" ");
+        }
+        String listSql = buildPageSql(gp.getSqlSelect() +" "+ gp.getSqlWhere() + sb.toString(), gp.getPageNo(), gp.getPageSize());
+        String countSql = "SELECT COUNT(*) " + removeSelect(removeOrders(gp.getSqlSelect() +" "+ gp.getSqlWhere()));
+        if (gp.getTerm().size() == 0) {
+            List<T> list = this.queryForList(listSql, clazz);
+            Long totalCount = queryForLong(countSql);
+            return new Page(gp.getPageNo(), totalCount, gp.getPageSize(), list);
+        } else {
+            List<T> list = this.queryForList(listSql, clazz, gp.getTerm().toArray());
+            Long totalCount = queryForLong(countSql, gp.getTerm().toArray());
+            return new Page(gp.getPageNo(), totalCount, gp.getPageSize(), list);
+        }
+    }
+
+    @Override
+    public int update(String table, Map fields, Map<String, ?> where) {
+
+        Assert.hasText(table, "表名不能为空");
+        Assert.notEmpty(fields, "字段不能为空");
+        Assert.notEmpty(where, "where条件不能为空");
+
+        String whereSql = this.createWhereSql(where);
+
+        // 字段名
+        Object[] cols = fields.keySet().toArray();
+        String fieldSql = "";
+
+        for (int i = 0; i < cols.length; i++) {
+
+            fieldSql += cols[i] + "=?";
+            if (i != cols.length - 1) {
+                fieldSql += ",";
+            }
+        }
+
+        // 字段值
+        Object[] values = ArrayUtils.addAll(fields.values().toArray(), where.values().toArray());
+
+        String sql = "UPDATE " + table + " SET " + fieldSql + " WHERE " + whereSql;
+
+        return this.jdbcTemplate.update(sql, values);
+
+    }
+
+
+    @Override
+    public int[] batchUpdate(String sql, List<Object[]> batchArgs) {
+        return jdbcTemplate.batchUpdate(sql, batchArgs);
+    }
+
+    @Override
+    public int[] batchUpdate(String... sql) {
+        return jdbcTemplate.batchUpdate(sql);
+    }
+
+    @Override
+    public int update(String table, Object po, Map<String, ?> where) {
+
+        return update(table, ReflectionUtil.po2Map(po), where);
+    }
+
+
+    @Override
+    public String buildPageSql(String sql, int page, int pageSize) {
+
+        String sqlStr = null;
+
+        //防止魔法值
+        String mysqlStr = "mysql";
+        String sqlserverStr = "sqlserver";
+        String oracleStr = "oracle";
+
+        if (mysqlStr.equals(dbType)) {
+            sqlStr = sql + " LIMIT " + (page - 1) * pageSize + "," + pageSize;
+        } else if (oracleStr.equals(dbType)) {
+            StringBuffer localSql = new StringBuffer("SELECT * FROM (SELECT t1.*,rownum sn1 FROM (");
+            localSql.append(sql);
+            localSql.append(") t1) t2 WHERE t2.sn1 BETWEEN ");
+            localSql.append((page - 1) * pageSize + 1);
+            localSql.append(" AND ");
+            localSql.append(page * pageSize);
+            sqlStr = localSql.toString();
+        } else if (sqlserverStr.equals(dbType)) {
+            StringBuffer localSql = new StringBuffer();
+            // 找到order by 子句
+            String order = SqlPaser.findOrderStr(sql);
+
+            // 剔除order by 子句
+            if (order != null) {
+                sql = removeOrders(sql);
+            } else {
+                // SQLServer分页必需有order by
+                // 子句,如果默认语句不包含order by,
+                // 自动以id降序,如果没有id字段会报错
+                order = "order by id desc";
+
+            }
+
+            // 拼装分页sql
+            localSql.append("select * from (");
+            localSql.append(SqlPaser.insertSelectField("ROW_NUMBER() Over(" + order + ") as rowNum", sql));
+            localSql.append(") tb where rowNum between ");
+            localSql.append((page - 1) * pageSize + 1);
+            localSql.append(" AND ");
+            localSql.append(page * pageSize);
+
+            return localSql.toString();
+
+        }
+
+        return sqlStr;
+
+    }
+
+    /**
+     * 格式化列名 只适用于Mysql
+     *
+     * @param col
+     * @return
+     */
+    private String quoteCol(String col) {
+        if (col == null || "".equals(col)) {
+            return "";
+        } else {
+            // if("2".equals(EopSetting.DBTYPE))//Oracle
+            // return "\"" + col + "\"";
+            // else if("1".equals(EopSetting.DBTYPE))//mysql
+            // return "`" + col + "`";
+            // else //mssql
+            // return "[" + col + "]";
+            return col;
+        }
+    }
+
+    /**
+     * 格式化值 只适用于Mysql
+     *
+     * @param value
+     * @return
+     */
+    private String quoteValue(String value) {
+        if (value == null || "".equals(value)) {
+            return "''";
+        } else {
+            return "'" + value.replaceAll("'", "''") + "'";
+        }
+    }
+
+    private String getStr(int num, String str) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < num; i++) {
+            sb.append(str);
+        }
+        return sb.toString();
+    }
+
+
+    @Override
+    public <T> void insert(T t) {
+        DataMeta dataMeta = this.sqlMetaBuilder.insert(t);
+        String sql = dataMeta.getSql();
+        Object[] param = dataMeta.getParamter();
+        this.jdbcTemplate.update(sql, param);
+    }
+
+    @Override
+    public <T> int insertRecord(T t) {
+        int i = 0;
+        DataMeta dataMeta = this.sqlMetaBuilder.insert(t);
+        String sql = dataMeta.getSql();
+        Object[] param = dataMeta.getParamter();
+        i = this.jdbcTemplate.update(sql, param);
+        return i;
+    }
+
+
+    @Override
+    public <T> void update(T model, Integer id) {
+        DataMeta dataMeta = this.sqlMetaBuilder.update(model, id);
+        String sql = dataMeta.getSql();
+        Object[] param = dataMeta.getParamter();
+        this.jdbcTemplate.update(sql, param);
+    }
+
+
+    @Override
+    public <T> void delete(Class<T> clazz, Integer id) {
+        String sql = this.sqlMetaBuilder.delete(clazz);
+        Integer[] ids = {id};
+        this.jdbcTemplate.update(sql, ids);
+    }
+
+
+    @Override
+    public <T> T queryForObject(Class<T> clazz, Integer id) {
+
+        String sql = this.sqlMetaBuilder.queryForModel(clazz);
+        Integer[] ids = {id};
+        List<T> objList = this.queryForList(sql, clazz, ids);
+        if (objList.isEmpty()) {
+            return null;
+        }
+        return objList.get(0);
+    }
+
+
+    @Override
+    public <T> T queryForObject(String sql, Class<T> clazz, Object... args) {
+        List<T> objList = this.queryForList(sql, clazz, args);
+        if (objList.isEmpty()) {
+            return null;
+        }
+        return objList.get(0);
+    }
+
+
+    /**
+     * 去除hql的order by 子句,用于pagedQuery.
+     */
+    private String removeOrders(String hql) {
+        Assert.hasText(hql, "hql must hast text");
+
+        Matcher m = ORDER_PATTERN.matcher(hql);
+        StringBuffer sb = new StringBuffer();
+        while (m.find()) {
+            m.appendReplacement(sb, "");
+        }
+        m.appendTail(sb);
+        return sb.toString();
+    }
+
+    /**
+     * 去除sql的select 子句,未考虑union的情况,用于pagedQuery.
+     */
+    private String removeSelect(String sql) {
+
+        String groupBySql = "group by";
+//        sql = sql.toLowerCase();
+        if (sql.indexOf(groupBySql) != -1) {
+            return " from (" + sql + ") temp_table";
+        }
+
+        // FIXME 当查询中含有函数,比如SUM(),替换SQL出错
+        Matcher m = REMOVE_SELECT_PATTERN.matcher(sql);
+        StringBuffer sb = new StringBuffer();
+        while (m.find()) {
+            int c = m.end() - m.start();
+            m.appendReplacement(sb, getStr(c, "~"));
+        }
+        m.appendTail(sb);
+
+        String replacedSql = sb.toString();
+
+        int index = replacedSql.indexOf("from");
+
+        // 如果不存在
+        if (index == -1) {
+            index = replacedSql.indexOf("FROM");
+        }
+        return sql.substring(index);
+    }
+
+    /**
+     * 根据一个Map的条件,生成where 语句
+     *
+     * @param where key为条件,value为条件值
+     * @return where 语句
+     */
+    private String createWhereSql(Map<String, ?> where) {
+
+        String whereSql = "";
+        if (where != null) {
+            Object[] whereCols = where.keySet().toArray();
+            for (int i = 0; i < whereCols.length; i++) {
+                StringBuffer str = new StringBuffer();
+                str.append(whereCols[i].toString());
+                str.append("=?");
+                whereCols[i] = str.toString();
+            }
+            whereSql += StringUtil.implode(" AND ", whereCols);
+        }
+
+        return whereSql;
+    }
+}

+ 36 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/FilterColumnMapRowMapper.java

@@ -0,0 +1,36 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+import org.springframework.jdbc.support.JdbcUtils;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * map mapper
+ * @author Allen
+ */
+public class FilterColumnMapRowMapper extends ColumnMapRowMapper {
+	private final IRowMapperColumnFilter filter;
+	public FilterColumnMapRowMapper(IRowMapperColumnFilter filter){
+		this.filter = filter;
+	}
+	
+	@Override
+	public  Map<String, Object>  mapRow(ResultSet rs, int rowNum) throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int columnCount = rsmd.getColumnCount();
+		Map mapOfColValues = createColumnMap(columnCount);
+		for (int i = 1; i <= columnCount; i++) {
+			String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
+			key  = key.toLowerCase();
+			Object obj = getColumnValue(rs, i);
+			mapOfColValues.put(key, obj);
+			//对此行结果集进行过滤
+			this.filter.filter(mapOfColValues, rs);
+		}
+		return mapOfColValues;
+	}
+}

+ 25 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/IRowMapperColumnFilter.java

@@ -0,0 +1,25 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * 数据库结果集过滤器
+ * 可对RowMapper的结果某或多列进行过滤 
+ * @author Allen
+ *
+ */
+public interface IRowMapperColumnFilter {
+	
+	
+	/**
+	 * 对结果集的行进行过滤
+	 * @param colValues 结果集一行的map
+	 * @param rs 结果集
+	 * @throws  SQLException 可能的sql异常
+	 */
+    void filter(Map colValues, ResultSet rs) throws SQLException;
+	
+	
+}

+ 19 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/LowerCaseJdbcTemplate.java

@@ -0,0 +1,19 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+
+
+/**
+ * 覆写jdbctemlate ,使用LowerCaseColumnMapRowMapper
+ * @author Allen
+ */
+public class LowerCaseJdbcTemplate extends JdbcTemplate {
+	@Override
+	protected RowMapper getColumnMapRowMapper() {
+
+		return new MySqlColumnMapRowMapper();
+
+	}
+
+}

+ 36 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/MySqlColumnMapRowMapper.java

@@ -0,0 +1,36 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+import org.springframework.jdbc.support.JdbcUtils;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * map mapper
+ * @author Allen
+ */
+public class MySqlColumnMapRowMapper extends ColumnMapRowMapper {
+	@Override
+	public Map<String, Object>  mapRow(ResultSet rs, int rowNum) throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int columnCount = rsmd.getColumnCount();
+		Map mapOfColValues = createColumnMap(columnCount);
+		for (int i = 1; i <= columnCount; i++) {
+			String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
+			key = key.toLowerCase();
+			Object obj = null;
+			String typename= rsmd.getColumnTypeName(i).toUpperCase();
+			if("DECIMAL".equals(typename)){
+				obj = rs.getDouble(i);
+			}else{
+				obj = getColumnValue(rs, i);
+			}
+			 
+			mapOfColValues.put(key, obj);
+		}
+		return mapOfColValues;
+	}
+}

+ 91 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/MySqlMetaBuilderImpl.java

@@ -0,0 +1,91 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+
+import com.wdklian.ncs.ms.framework.database.ColumnMeta;
+import com.wdklian.ncs.ms.framework.database.DataMeta;
+import com.wdklian.ncs.ms.framework.database.SqlMetaBuilder;
+import com.wdklian.ncs.ms.framework.database.annotation.Table;
+import com.wdklian.ncs.ms.framework.util.ReflectionUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 基于Mysql的基本增删改查操作实现类
+ * @author Allen
+ */
+@Service
+public class MySqlMetaBuilderImpl implements SqlMetaBuilder {
+
+    @Override
+    public <T> DataMeta insert(T model) {
+        ColumnMeta columnMeta = ReflectionUtil.getColumnMeta(model);
+        Object[] columnName = columnMeta.getNames();
+        Object[] columnValue = columnMeta.getValues();
+
+        StringBuffer  questionMarkStr = new StringBuffer();
+        for (int i =0;i < columnValue.length; i++ ){
+            questionMarkStr.append("?");
+            if ( (i+1) != columnValue.length) {
+                questionMarkStr.append(",");
+            }
+        }
+
+        Table table = model.getClass().getAnnotation(Table.class);
+        String columnNameStr = StringUtils.join(columnName,",");
+
+        String addSql = "INSERT INTO "+table.name()+" ("+columnNameStr+") VALUES ("+questionMarkStr.toString()+")";
+
+        DataMeta dataMeta = new DataMeta();
+        dataMeta.setSql(addSql);
+        dataMeta.setParamter(columnValue);
+        return dataMeta;
+    }
+
+    @Override
+    public <T> DataMeta update(T model, Integer id) {
+        ColumnMeta columnMeta = ReflectionUtil.getColumnMeta(model);
+        Object[] columnName = columnMeta.getNames();
+        Object[] columnValue = columnMeta.getValues();
+
+        String columnId = ReflectionUtil.getPrimaryKey(model.getClass());
+        Table table = model.getClass().getAnnotation(Table.class);
+
+        List valueList = new ArrayList();
+        StringBuffer  setStr = new StringBuffer();
+        for ( int i =0; i < columnName.length; i++ ){
+            setStr.append(columnName[i]+"=?");
+            valueList.add(columnValue[i]);
+            if ( (i+1) != columnName.length) {
+                setStr.append(",");
+            }
+        }
+        String editSql = "UPDATE "+table.name()+" SET "+setStr.toString()+" WHERE "+columnId+"=?";
+        valueList.add(id);
+
+        DataMeta dataMeta = new DataMeta();
+        dataMeta.setSql(editSql);
+        dataMeta.setParamter(valueList.toArray());
+        return dataMeta;
+    }
+
+
+    @Override
+    public String queryForModel(Class clazz) {
+        Table table =  (Table) clazz.getAnnotation(Table.class);
+        String columnId = ReflectionUtil.getPrimaryKey(clazz);
+        String queryOneSql = "SELECT * FROM "+table.name()+" WHERE "+columnId+"=?";
+        return queryOneSql;
+    }
+
+    @Override
+    public String delete(Class clazz) {
+        Table table =  (Table) clazz.getAnnotation(Table.class);
+        String columnId = ReflectionUtil.getPrimaryKey(clazz);
+        String deleteSql = "DELETE FROM "+table.name()+" WHERE "+columnId+"=?";
+        return deleteSql;
+    }
+
+}

+ 51 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/OracleColumnMapRowMapper.java

@@ -0,0 +1,51 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+import org.springframework.jdbc.support.JdbcUtils;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * 小写key的columnrowmapper
+ *  本类覆写了spring 的ColumnMapRowMapper,将字段名全部小写
+ * @author Allen
+ */
+public class OracleColumnMapRowMapper extends ColumnMapRowMapper {
+
+	@Override
+	public Map<String, Object>  mapRow(ResultSet rs, int rowNum) throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int columnCount = rsmd.getColumnCount();
+		Map mapOfColValues = createColumnMap(columnCount);
+		for (int i = 1; i <= columnCount; i++) {
+			String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
+			key = key.toLowerCase();
+			Object obj = null;
+			String typename= rsmd.getColumnTypeName(i);
+			if("NUMBER".equals(typename)){
+				int scale = rsmd.getScale(i);
+				int precision = rsmd.getPrecision(i);
+				if(scale == 0){
+					if(precision<=10) {
+						obj = rs.getInt(i);
+					}
+					else {
+						obj = rs.getLong(i);
+					}
+				}else if(scale>0){
+					obj = rs.getDouble(i);
+				}else {
+					obj = rs.getLong(i);
+				}
+			}else{
+				obj = getColumnValue(rs, i);
+			}
+ 
+			mapOfColValues.put(key, obj);
+		}
+		return mapOfColValues;
+	}
+}

+ 42 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/database/impl/SqlPaser.java

@@ -0,0 +1,42 @@
+package com.wdklian.ncs.ms.framework.database.impl;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * sql解析器
+ * @author Allen
+ *
+ */
+public class SqlPaser {
+	
+	
+	public static String insertSelectField(String field,String sql){
+		sql = "select " + field+","+sql.substring(6);
+		return sql;
+	}
+	
+	
+	/**
+	 * 从一个sql语句中找到order by 子句
+	 * @param sql
+	 * @return
+	 */
+	public static String findOrderStr(String sql ){
+
+		String pattern = "(order\\s*by[\\w|\\W|\\s|\\S]*)";
+		Pattern p = Pattern.compile(pattern, 2 | Pattern.DOTALL);
+		Matcher m = p.matcher(sql);
+
+		if (m.find()) {
+			return m.group();
+		 
+		} 
+		return null;
+	}
+	
+	
+	public static void main(String[] args){
+		String sql ="select * from abc where 12=12 order by id asc ";
+	}
+}

+ 0 - 0
ncs-ms-framework/src/main/java/com/wdklian/ncs/ms/framework/exception/ErrorMessage.java


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است