Browse Source

Merge branch 'dev' of ssh://10.10.100.21/source/saas-platform into dev

rainco 7 years ago
parent
commit
6fbd0d760a
80 changed files with 2828 additions and 468 deletions
  1. 35 0
      applications/common-dto/src/main/java/com/usoftchina/saas/common/dto/DocReqDTO.java
  2. 31 0
      applications/document/document-api/pom.xml
  3. 23 0
      applications/document/document-api/src/main/java/com/usoftchina/saas/document/api/ProductApi.java
  4. 22 0
      applications/document/document-api/src/main/java/com/usoftchina/saas/document/api/VendorApi.java
  5. 44 0
      applications/document/document-api/src/main/resources/application.yml
  6. 0 0
      applications/document/document-api/src/main/resources/banner.txt
  7. 64 0
      applications/document/document-api/src/main/resources/logback-spring.xml
  8. 23 0
      applications/document/document-dto/pom.xml
  9. 61 0
      applications/document/document-dto/src/main/java/com.usoftchina.saas.document.dto/ProductDTO.java
  10. 61 0
      applications/document/document-dto/src/main/java/com.usoftchina.saas.document.dto/VendorDTO.java
  11. 87 0
      applications/document/document-server/pom.xml
  12. 22 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/DocumentApplication.java
  13. 29 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/ProductController.java
  14. 35 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/VendorController.java
  15. 14 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/ProductMapper.java
  16. 14 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/VendorMapper.java
  17. 274 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/po/Product.java
  18. 291 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/po/Vendor.java
  19. 38 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/Impl/ProductServiceImpl.java
  20. 41 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/Impl/VendorServiceImpl.java
  21. 14 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/ProductService.java
  22. 15 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/VendorService.java
  23. 47 0
      applications/document/document-server/src/main/resources/application.yml
  24. BIN
      applications/document/document-server/src/main/resources/auth/pub.key
  25. 0 0
      applications/document/document-server/src/main/resources/banner.txt
  26. 42 0
      applications/document/document-server/src/main/resources/config/application-dev.yml
  27. 7 0
      applications/document/document-server/src/main/resources/config/application-docker.yml
  28. 64 0
      applications/document/document-server/src/main/resources/logback-spring.xml
  29. 48 0
      applications/document/document-server/src/main/resources/mapper/ProductMapper.xml
  30. 41 0
      applications/document/document-server/src/main/resources/mapper/VendorMapper.xml
  31. 32 0
      applications/document/document-server/src/test/java/com/usoftchina/saas/document/service/VendorServiceTest.java
  32. 6 1
      applications/document/pom.xml
  33. 5 8
      applications/purchase/purchase-server/pom.xml
  34. 3 0
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/PurchaseApplication.java
  35. 36 0
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/config/WebMvcConfig.java
  36. 36 0
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/ComponentController.java
  37. 2 2
      base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java
  38. 1 9
      base-servers/account/account-server/pom.xml
  39. 1 1
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java
  40. 1 1
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java
  41. 3 0
      base-servers/admin-server/src/main/resources/config/application-docker.yml
  42. 2 29
      base-servers/auth/auth-server/pom.xml
  43. 2 0
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/AuthApplication.java
  44. 12 14
      base-servers/gateway-server/pom.xml
  45. 0 2
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/GatewayApplication.java
  46. 0 103
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AccessFilter.java
  47. 25 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AuthFilter.java
  48. 65 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/ErrorConfig.java
  49. 0 18
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/SecurityConfig.java
  50. 49 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/WebConfig.java
  51. 0 47
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/ZuulConfig.java
  52. 99 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/error/MyExceptionHandler.java
  53. 103 39
      base-servers/gateway-server/src/main/resources/application.yml
  54. 0 15
      base-servers/gateway-server/src/main/resources/banner.txt
  55. 3 0
      base-servers/gateway-server/src/main/resources/config/application-docker.yml
  56. 4 11
      base-servers/ui-server/pom.xml
  57. 15 10
      base-servers/ui-server/src/main/java/com/usoftchina/saas/ui/controller/co/CoViewController.java
  58. 2 0
      base-servers/ui-server/src/main/resources/application.yml
  59. 0 15
      base-servers/ui-server/src/main/resources/banner.txt
  60. 3 0
      base-servers/zipkin-server/src/main/resources/config/application-docker.yml
  61. 1 0
      framework/pom.xml
  62. 44 0
      framework/server-starter/pom.xml
  63. 14 0
      framework/server-starter/src/main/java/com/usoftchina/saas/server/ServerAutoConfiguration.java
  64. 16 0
      framework/server-starter/src/main/java/com/usoftchina/saas/server/context/SpringContextListener.java
  65. 41 0
      framework/server-starter/src/main/java/com/usoftchina/saas/server/error/MyErrorController.java
  66. 7 0
      framework/server-starter/src/main/resources/META-INF/spring.factories
  67. BIN
      framework/server-starter/src/main/resources/auth/pub.key
  68. 0 0
      framework/server-starter/src/main/resources/banner.txt
  69. 2 1
      frontend/saas-web/app/util/BaseUtil.js
  70. 33 7
      frontend/saas-web/app/util/FormUtil.js
  71. 28 4
      frontend/saas-web/app/view/core/dbfind/DbfindGridPanel.js
  72. 103 40
      frontend/saas-web/app/view/core/dbfind/DbfindTrigger.js
  73. 32 0
      frontend/saas-web/app/view/core/form/DateField.js
  74. 12 8
      frontend/saas-web/app/view/core/form/FormPanel.js
  75. 153 3
      frontend/saas-web/app/view/core/form/FormPanelController.js
  76. 60 24
      frontend/saas-web/app/view/core/form/field/DetailGridField.js
  77. 20 0
      frontend/saas-web/app/view/main/Main.scss
  78. 80 53
      frontend/saas-web/app/view/test/order/FormController.js
  79. 179 2
      frontend/saas-web/app/view/test/order/FormPanel.js
  80. 6 1
      pom.xml

+ 35 - 0
applications/common-dto/src/main/java/com/usoftchina/saas/common/dto/DocReqDTO.java

@@ -0,0 +1,35 @@
+package com.usoftchina.saas.common.dto;
+
+
+/**
+ * @author chenwei
+ * @date   2018/10/15
+ */
+public class DocReqDTO {
+
+    /**
+     * where 条件
+     */
+    private String condition;
+
+    /**
+     * order by 语句
+     */
+    private String orderbyClause;
+
+    public String getCondition() {
+        return condition;
+    }
+
+    public void setCondition(String condition) {
+        this.condition = condition;
+    }
+
+    public String getOrderbyClause() {
+        return orderbyClause;
+    }
+
+    public void setOrderbyClause(String orderbyClause) {
+        this.orderbyClause = orderbyClause;
+    }
+}

+ 31 - 0
applications/document/document-api/pom.xml

@@ -0,0 +1,31 @@
+<?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>document</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>document-api</artifactId>
+    <description>document-api server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>document-dto</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 23 - 0
applications/document/document-api/src/main/java/com/usoftchina/saas/document/api/ProductApi.java

@@ -0,0 +1,23 @@
+package com.usoftchina.saas.document.api;
+
+import com.usoftchina.saas.document.dto.ProductDTO;
+import com.usoftchina.saas.page.PageRequest;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(name = "document-server")
+public interface ProductApi {
+
+    /**
+     * 查询Products
+     * @param page
+     * @param condition
+     * @return
+     */
+    @GetMapping("/api/document/product/getProductsByCondition")
+    public List<ProductDTO> getProductsByCondition(@RequestParam(value = "page") PageRequest page, @RequestParam(value = "condition") String condition);
+
+}

+ 22 - 0
applications/document/document-api/src/main/java/com/usoftchina/saas/document/api/VendorApi.java

@@ -0,0 +1,22 @@
+package com.usoftchina.saas.document.api;
+
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.document.dto.VendorDTO;
+import com.usoftchina.saas.page.PageRequest;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(name = "document-server")
+public interface VendorApi {
+
+    /**
+     * 查询Vendors
+     * @param condition
+     * @return
+     */
+    @GetMapping("/api/document/vendor/getVendorsByCondition")
+    public List<VendorDTO> getVendorsByCondition(@RequestParam(value = "page") PageRequest page, @RequestParam(value = "condition") String condition);
+}

+ 44 - 0
applications/document/document-api/src/main/resources/application.yml

@@ -0,0 +1,44 @@
+spring:
+  application:
+    name: document-api
+  security:
+    user:
+      name: admin
+      password: select111***
+  datasource:
+    driver-class-name: com.mysql.jdbc.Driver
+    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false
+    username: root
+    password: select111***
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 50
+      idle-timeout: 30000
+      max-lifetime: 1800000
+      connection-timeout: 30000
+  messages:
+    basename: i18n/messages
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@192.168.0.181:8500/eureka/
+server:
+  port: 9481
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'
+auth:
+  public-key: auth/pub.key

+ 0 - 0
applications/purchase/purchase-server/src/main/resources/banner.txt → applications/document/document-api/src/main/resources/banner.txt


+ 64 - 0
applications/document/document-api/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/document-api"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="document-api"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 23 - 0
applications/document/document-dto/pom.xml

@@ -0,0 +1,23 @@
+<?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>document</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>document-dto</artifactId>
+    <description>document data transfer object</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 61 - 0
applications/document/document-dto/src/main/java/com.usoftchina.saas.document.dto/ProductDTO.java

@@ -0,0 +1,61 @@
+package com.usoftchina.saas.document.dto;
+
+import java.io.Serializable;
+
+public class ProductDTO implements Serializable {
+
+    private String pr_id;
+    private String pr_code;
+    private String pr_detail;
+    private String pr_spec;
+    private String pr_orispeccode;
+    private String pr_brand;
+
+    public String getPr_id() {
+        return pr_id;
+    }
+
+    public void setPr_id(String pr_id) {
+        this.pr_id = pr_id;
+    }
+
+    public String getPr_code() {
+        return pr_code;
+    }
+
+    public void setPr_code(String pr_code) {
+        this.pr_code = pr_code;
+    }
+
+    public String getPr_detail() {
+        return pr_detail;
+    }
+
+    public void setPr_detail(String pr_detail) {
+        this.pr_detail = pr_detail;
+    }
+
+    public String getPr_spec() {
+        return pr_spec;
+    }
+
+    public void setPr_spec(String pr_spec) {
+        this.pr_spec = pr_spec;
+    }
+
+    public String getPr_orispeccode() {
+        return pr_orispeccode;
+    }
+
+    public void setPr_orispeccode(String pr_orispeccode) {
+        this.pr_orispeccode = pr_orispeccode;
+    }
+
+    public String getPr_brand() {
+        return pr_brand;
+    }
+
+    public void setPr_brand(String pr_brand) {
+        this.pr_brand = pr_brand;
+    }
+}

+ 61 - 0
applications/document/document-dto/src/main/java/com.usoftchina.saas.document.dto/VendorDTO.java

@@ -0,0 +1,61 @@
+package com.usoftchina.saas.document.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+@ApiModel(value = "Vendor", description = "供应商资料")
+public class VendorDTO implements Serializable{
+
+    @ApiModelProperty(value = "ID")
+    private long ve_id;
+    @ApiModelProperty(value = "供应商编号")
+    private String ve_code;
+    @ApiModelProperty(value = "供应商名称")
+    private String ve_name;
+    @ApiModelProperty(value = "供应商类型")
+    private String ve_type;
+    @ApiModelProperty(value = "状态")
+    private String ve_status;
+
+    public long getVe_id() {
+        return ve_id;
+    }
+
+    public void setVe_id(long ve_id) {
+        this.ve_id = ve_id;
+    }
+
+    public String getVe_code() {
+        return ve_code;
+    }
+
+    public void setVe_code(String ve_code) {
+        this.ve_code = ve_code;
+    }
+
+    public String getVe_name() {
+        return ve_name;
+    }
+
+    public void setVe_name(String ve_name) {
+        this.ve_name = ve_name;
+    }
+
+    public String getVe_type() {
+        return ve_type;
+    }
+
+    public void setVe_type(String ve_type) {
+        this.ve_type = ve_type;
+    }
+
+    public String getVe_status() {
+        return ve_status;
+    }
+
+    public void setVe_status(String ve_status) {
+        this.ve_status = ve_status;
+    }
+}

+ 87 - 0
applications/document/document-server/pom.xml

@@ -0,0 +1,87 @@
+<?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>document</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>document-server</artifactId>
+    <description>document server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <!-- db -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+        <!-- sleuth -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.amqp</groupId>
+            <artifactId>spring-rabbit</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+        <!-- feign -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>document-dto</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>common-dto</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 22 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/DocumentApplication.java

@@ -0,0 +1,22 @@
+package com.usoftchina.saas.document;
+
+import com.usoftchina.saas.auth.client.EnableAuthClient;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication
+@EnableEurekaClient
+//@EnableAuthClient
+@EnableTransactionManagement
+@MapperScan("com.usoftchina.saas.document.mapper")
+public class DocumentApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(DocumentApplication.class);
+    }
+
+}

+ 29 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/ProductController.java

@@ -0,0 +1,29 @@
+package com.usoftchina.saas.document.controller;
+
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.po.Product;
+import com.usoftchina.saas.document.service.ProductService;
+import com.usoftchina.saas.page.PageRequest;
+import feign.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/document/product")
+public class ProductController {
+
+    @Autowired
+    private ProductService productService;
+
+    @RequestMapping("/getProductsByCondition")
+    @ResponseBody
+    public List<Product> getProductsByCondition(PageRequest page, DocReqDTO docReqDTO){
+        List<Product> productList = productService.getProductsByCondition(page, docReqDTO);
+        return productList;
+    }
+
+}

+ 35 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/VendorController.java

@@ -0,0 +1,35 @@
+package com.usoftchina.saas.document.controller;
+
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.po.Vendor;
+import com.usoftchina.saas.document.service.VendorService;
+import com.usoftchina.saas.page.PageRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/document/vendor")
+public class VendorController {
+
+    @Autowired
+    private VendorService vendorService;
+
+
+    @RequestMapping(value = "")
+    @ResponseBody
+    public String getVendorList(){
+
+        return "HelloWorld!";
+    }
+
+    @RequestMapping("/getVendorsByCondition")
+    @ResponseBody
+    public List<Vendor> getVendorsByCondition(PageRequest page, DocReqDTO docReqDTO){
+        List<Vendor> vendorList = vendorService.getVendorsByCondition(page, docReqDTO);
+        return vendorList;
+    }
+}

+ 14 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/ProductMapper.java

@@ -0,0 +1,14 @@
+package com.usoftchina.saas.document.mapper;
+
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.po.Product;
+import com.usoftchina.saas.page.PageRequest;
+
+import java.util.List;
+
+public interface ProductMapper extends CommonBaseMapper<Product> {
+
+    List<Product> getProductsByCondition(DocReqDTO docReqDTO);
+
+}

+ 14 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/VendorMapper.java

@@ -0,0 +1,14 @@
+package com.usoftchina.saas.document.mapper;
+
+import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.po.Vendor;
+import com.usoftchina.saas.page.PageRequest;
+
+import java.util.List;
+
+public interface VendorMapper extends CommonBaseMapper<Vendor> {
+
+    List<Vendor> getVendorsByCondition(DocReqDTO docReqDTO);
+
+}

+ 274 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/po/Product.java

@@ -0,0 +1,274 @@
+package com.usoftchina.saas.document.po;
+
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class Product extends CommonBaseEntity implements Serializable {
+
+    private long pr_id;
+    private String pr_code;
+    private String pr_detail;
+    private String pr_spec;
+    private String pr_unit;
+    private String pr_kind;
+    private String pr_orispeccode;
+    private long pr_whid;
+    private String pr_whcode;
+    private String pr_whname;
+    private long pr_zxbzs;
+    private long pr_leadtime;
+    private String pr_brand;
+    private String pr_standardprice;
+    private String pr_purcprice;
+    private String pr_saleprice;
+    private long pr_vendid;
+    private String pr_vendname;
+    private String pr_vendcode;
+    private Date pr_docdate;
+    private long pr_recordmanid;
+    private String pr_recordman;
+    private String pr_status;
+    private String pr_statuscode;
+    private String pr_text1;
+    private String pr_text2;
+    private String pr_text3;
+    private String pr_text4;
+
+    public long getPr_id() {
+        return pr_id;
+    }
+
+    public void setPr_id(long pr_id) {
+        this.pr_id = pr_id;
+    }
+
+    public String getPr_code() {
+        return pr_code;
+    }
+
+    public void setPr_code(String pr_code) {
+        this.pr_code = pr_code;
+    }
+
+    public String getPr_detail() {
+        return pr_detail;
+    }
+
+    public void setPr_detail(String pr_detail) {
+        this.pr_detail = pr_detail;
+    }
+
+    public String getPr_spec() {
+        return pr_spec;
+    }
+
+    public void setPr_spec(String pr_spec) {
+        this.pr_spec = pr_spec;
+    }
+
+    public String getPr_unit() {
+        return pr_unit;
+    }
+
+    public void setPr_unit(String pr_unit) {
+        this.pr_unit = pr_unit;
+    }
+
+    public String getPr_kind() {
+        return pr_kind;
+    }
+
+    public void setPr_kind(String pr_kind) {
+        this.pr_kind = pr_kind;
+    }
+
+    public String getPr_orispeccode() {
+        return pr_orispeccode;
+    }
+
+    public void setPr_orispeccode(String pr_orispeccode) {
+        this.pr_orispeccode = pr_orispeccode;
+    }
+
+    public long getPr_whid() {
+        return pr_whid;
+    }
+
+    public void setPr_whid(long pr_whid) {
+        this.pr_whid = pr_whid;
+    }
+
+    public String getPr_whcode() {
+        return pr_whcode;
+    }
+
+    public void setPr_whcode(String pr_whcode) {
+        this.pr_whcode = pr_whcode;
+    }
+
+    public String getPr_whname() {
+        return pr_whname;
+    }
+
+    public void setPr_whname(String pr_whname) {
+        this.pr_whname = pr_whname;
+    }
+
+    public long getPr_zxbzs() {
+        return pr_zxbzs;
+    }
+
+    public void setPr_zxbzs(long pr_zxbzs) {
+        this.pr_zxbzs = pr_zxbzs;
+    }
+
+    public long getPr_leadtime() {
+        return pr_leadtime;
+    }
+
+    public void setPr_leadtime(long pr_leadtime) {
+        this.pr_leadtime = pr_leadtime;
+    }
+
+    public String getPr_brand() {
+        return pr_brand;
+    }
+
+    public void setPr_brand(String pr_brand) {
+        this.pr_brand = pr_brand;
+    }
+
+    public String getPr_standardprice() {
+        return pr_standardprice;
+    }
+
+    public void setPr_standardprice(String pr_standardprice) {
+        this.pr_standardprice = pr_standardprice;
+    }
+
+    public String getPr_purcprice() {
+        return pr_purcprice;
+    }
+
+    public void setPr_purcprice(String pr_purcprice) {
+        this.pr_purcprice = pr_purcprice;
+    }
+
+    public String getPr_saleprice() {
+        return pr_saleprice;
+    }
+
+    public void setPr_saleprice(String pr_saleprice) {
+        this.pr_saleprice = pr_saleprice;
+    }
+
+    public long getPr_vendid() {
+        return pr_vendid;
+    }
+
+    public void setPr_vendid(long pr_vendid) {
+        this.pr_vendid = pr_vendid;
+    }
+
+    public String getPr_vendname() {
+        return pr_vendname;
+    }
+
+    public void setPr_vendname(String pr_vendname) {
+        this.pr_vendname = pr_vendname;
+    }
+
+    public String getPr_vendcode() {
+        return pr_vendcode;
+    }
+
+    public void setPr_vendcode(String pr_vendcode) {
+        this.pr_vendcode = pr_vendcode;
+    }
+
+    public Date getPr_docdate() {
+        return pr_docdate;
+    }
+
+    public void setPr_docdate(Date pr_docdate) {
+        this.pr_docdate = pr_docdate;
+    }
+
+    public long getPr_recordmanid() {
+        return pr_recordmanid;
+    }
+
+    public void setPr_recordmanid(long pr_recordmanid) {
+        this.pr_recordmanid = pr_recordmanid;
+    }
+
+    public String getPr_recordman() {
+        return pr_recordman;
+    }
+
+    public void setPr_recordman(String pr_recordman) {
+        this.pr_recordman = pr_recordman;
+    }
+
+    public String getPr_status() {
+        return pr_status;
+    }
+
+    public void setPr_status(String pr_status) {
+        this.pr_status = pr_status;
+    }
+
+    public String getPr_statuscode() {
+        return pr_statuscode;
+    }
+
+    public void setPr_statuscode(String pr_statuscode) {
+        this.pr_statuscode = pr_statuscode;
+    }
+
+    public String getPr_text1() {
+        return pr_text1;
+    }
+
+    public void setPr_text1(String pr_text1) {
+        this.pr_text1 = pr_text1;
+    }
+
+    public String getPr_text2() {
+        return pr_text2;
+    }
+
+    public void setPr_text2(String pr_text2) {
+        this.pr_text2 = pr_text2;
+    }
+
+    public String getPr_text3() {
+        return pr_text3;
+    }
+
+    public void setPr_text3(String pr_text3) {
+        this.pr_text3 = pr_text3;
+    }
+
+    public String getPr_text4() {
+        return pr_text4;
+    }
+
+    public void setPr_text4(String pr_text4) {
+        this.pr_text4 = pr_text4;
+    }
+
+    public String getPr_text5() {
+        return pr_text5;
+    }
+
+    public void setPr_text5(String pr_text5) {
+        this.pr_text5 = pr_text5;
+    }
+
+    private String pr_text5;
+
+}

+ 291 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/po/Vendor.java

@@ -0,0 +1,291 @@
+package com.usoftchina.saas.document.po;
+
+import com.usoftchina.saas.base.entity.CommonBaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 供应商资料
+ * @author chenwei
+ * @Date 2018/10/13
+ */
+public class Vendor extends CommonBaseEntity implements Serializable{
+
+    /**
+     * 供应商ID
+     */
+    private long ve_id;
+    /**
+     * 供应商编号
+     */
+    private String ve_code;
+    /**
+     * 供应商名称
+     */
+    private String ve_name;
+    /**
+     * 供应商UU
+     */
+    private String ve_uu;
+    /**
+     * 供应商类型
+     */
+    private String ve_type;
+    /**
+     * 期初日期
+     */
+    private Date ve_begindate;
+    /**
+     * 期初应付
+     */
+    private long ve_beginapamount;
+    /**
+     * 期初预付
+     */
+    private long ve_beginprepayamount;
+    /**
+     * 承付天数
+     */
+    private long ve_promisedays;
+    /**
+     * 税率
+     */
+    private double ve_taxrate;
+    /**
+     * 纳税人识别号
+     */
+    private String ve_nsrzh;
+    /**
+     * 银行账号
+     */
+    private String ve_bankaccount;
+    /**
+     * 银行行号
+     */
+    private String ve_bankcode;
+    /**
+     * 状态   defualt "启用"
+     */
+    private String ve_status;
+    /**
+     * 状态码
+     */
+    private String ve_statuscode;
+    /**
+     * 录入人ID
+     */
+    private long ve_recordid;
+    /**
+     * 录入人
+     */
+    private String ve_recordname;
+    /**
+     * 建立日期
+     */
+    private Date ve_initdate;
+    /**
+     * 自定义字段
+     */
+    private String ve_text1;
+    /**
+     * 自定义字段
+     */
+    private String ve_text2;
+    /**
+     * 自定义字段
+     */
+    private String ve_text3;
+    /**
+     * 自定义字段
+     */
+    private String ve_text4;
+    /**
+     * 自定义字段
+     */
+    private String ve_text5;
+
+    public long getVe_id() {
+        return ve_id;
+    }
+
+    public void setVe_id(long ve_id) {
+        this.ve_id = ve_id;
+    }
+
+    public String getVe_code() {
+        return ve_code;
+    }
+
+    public void setVe_code(String ve_code) {
+        this.ve_code = ve_code;
+    }
+
+    public String getVe_name() {
+        return ve_name;
+    }
+
+    public void setVe_name(String ve_name) {
+        this.ve_name = ve_name;
+    }
+
+    public String getVe_uu() {
+        return ve_uu;
+    }
+
+    public void setVe_uu(String ve_uu) {
+        this.ve_uu = ve_uu;
+    }
+
+    public String getVe_type() {
+        return ve_type;
+    }
+
+    public void setVe_type(String ve_type) {
+        this.ve_type = ve_type;
+    }
+
+    public Date getVe_begindate() {
+        return ve_begindate;
+    }
+
+    public void setVe_begindate(Date ve_begindate) {
+        this.ve_begindate = ve_begindate;
+    }
+
+    public long getVe_beginapamount() {
+        return ve_beginapamount;
+    }
+
+    public void setVe_beginapamount(long ve_beginapamount) {
+        this.ve_beginapamount = ve_beginapamount;
+    }
+
+    public long getVe_beginprepayamount() {
+        return ve_beginprepayamount;
+    }
+
+    public void setVe_beginprepayamount(long ve_beginprepayamount) {
+        this.ve_beginprepayamount = ve_beginprepayamount;
+    }
+
+    public long getVe_promisedays() {
+        return ve_promisedays;
+    }
+
+    public void setVe_promisedays(long ve_promisedays) {
+        this.ve_promisedays = ve_promisedays;
+    }
+
+    public double getVe_taxrate() {
+        return ve_taxrate;
+    }
+
+    public void setVe_taxrate(double ve_taxrate) {
+        this.ve_taxrate = ve_taxrate;
+    }
+
+    public String getVe_nsrzh() {
+        return ve_nsrzh;
+    }
+
+    public void setVe_nsrzh(String ve_nsrzh) {
+        this.ve_nsrzh = ve_nsrzh;
+    }
+
+    public String getVe_bankaccount() {
+        return ve_bankaccount;
+    }
+
+    public void setVe_bankaccount(String ve_bankaccount) {
+        this.ve_bankaccount = ve_bankaccount;
+    }
+
+    public String getVe_bankcode() {
+        return ve_bankcode;
+    }
+
+    public void setVe_bankcode(String ve_bankcode) {
+        this.ve_bankcode = ve_bankcode;
+    }
+
+    public String getVe_status() {
+        return ve_status;
+    }
+
+    public void setVe_status(String ve_status) {
+        this.ve_status = ve_status;
+    }
+
+    public String getVe_statuscode() {
+        return ve_statuscode;
+    }
+
+    public void setVe_statuscode(String ve_statuscode) {
+        this.ve_statuscode = ve_statuscode;
+    }
+
+    public long getVe_recordid() {
+        return ve_recordid;
+    }
+
+    public void setVe_recordid(long ve_recordid) {
+        this.ve_recordid = ve_recordid;
+    }
+
+    public String getVe_recordname() {
+        return ve_recordname;
+    }
+
+    public void setVe_recordname(String ve_recordname) {
+        this.ve_recordname = ve_recordname;
+    }
+
+    public Date getVe_initdate() {
+        return ve_initdate;
+    }
+
+    public void setVe_initdate(Date ve_initdate) {
+        this.ve_initdate = ve_initdate;
+    }
+
+    public String getVe_text1() {
+        return ve_text1;
+    }
+
+    public void setVe_text1(String ve_text1) {
+        this.ve_text1 = ve_text1;
+    }
+
+    public String getVe_text2() {
+        return ve_text2;
+    }
+
+    public void setVe_text2(String ve_text2) {
+        this.ve_text2 = ve_text2;
+    }
+
+    public String getVe_text3() {
+        return ve_text3;
+    }
+
+    public void setVe_text3(String ve_text3) {
+        this.ve_text3 = ve_text3;
+    }
+
+    public String getVe_text4() {
+        return ve_text4;
+    }
+
+    public void setVe_text4(String ve_text4) {
+        this.ve_text4 = ve_text4;
+    }
+
+    public String getVe_text5() {
+        return ve_text5;
+    }
+
+    public void setVe_text5(String ve_text5) {
+        this.ve_text5 = ve_text5;
+    }
+}

+ 38 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/Impl/ProductServiceImpl.java

@@ -0,0 +1,38 @@
+package com.usoftchina.saas.document.service.Impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.mapper.ProductMapper;
+import com.usoftchina.saas.document.po.Product;
+import com.usoftchina.saas.document.service.ProductService;
+import com.usoftchina.saas.page.PageRequest;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ProductServiceImpl extends CommonBaseServiceImpl<ProductMapper, Product> implements ProductService {
+
+    @Autowired
+    private ProductMapper productMapper;
+
+    @Override
+    public List<Product> getProductsByCondition(PageRequest page, DocReqDTO docReqDTO) {
+        //设置分页
+        if (null == page || page.getSize() == 0 || page.getNumber() == 0) {
+            page = new PageRequest();
+            page.setNumber(1);
+            page.setSize(10);
+        }
+        PageHelper.startPage(page.getNumber(), page.getSize());
+        System.out.println("condition:    " + docReqDTO);
+        List<Product> productList = productMapper.getProductsByCondition(docReqDTO);
+        //取分页信息
+        PageInfo<Product> pageInfo = new PageInfo<Product>(productList);
+        return productList;
+    }
+}

+ 41 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/Impl/VendorServiceImpl.java

@@ -0,0 +1,41 @@
+package com.usoftchina.saas.document.service.Impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.mapper.VendorMapper;
+import com.usoftchina.saas.document.po.Vendor;
+import com.usoftchina.saas.document.service.VendorService;
+import com.usoftchina.saas.page.PageRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author chenwei
+ * @Date 2018/10/13
+ */
+@Service
+public class VendorServiceImpl extends CommonBaseServiceImpl<VendorMapper, Vendor> implements VendorService {
+
+    @Autowired
+    private VendorMapper vendorMapper;
+
+
+    @Override
+    public List<Vendor> getVendorsByCondition(PageRequest page, DocReqDTO docReqDTO) {
+        //设置分页
+        if (null == page || page.getSize() == 0 || page.getNumber() == 0) {
+            page = new PageRequest();
+            page.setNumber(1);
+            page.setSize(10);
+        }
+        PageHelper.startPage(page.getNumber(), page.getSize());
+        List<Vendor> vendorList = vendorMapper.getVendorsByCondition(docReqDTO);
+        //取分页信息
+        PageInfo<Vendor> pageInfo = new PageInfo<Vendor>(vendorList);
+        return vendorList;
+    }
+}

+ 14 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/ProductService.java

@@ -0,0 +1,14 @@
+package com.usoftchina.saas.document.service;
+
+import com.usoftchina.saas.base.service.CommonBaseService;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.mapper.ProductMapper;
+import com.usoftchina.saas.document.po.Product;
+import com.usoftchina.saas.page.PageRequest;
+
+import java.util.List;
+
+public interface ProductService extends CommonBaseService<ProductMapper, Product> {
+
+    List<Product> getProductsByCondition(PageRequest page, DocReqDTO docReqDTO);
+}

+ 15 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/VendorService.java

@@ -0,0 +1,15 @@
+package com.usoftchina.saas.document.service;
+
+import com.usoftchina.saas.base.service.CommonBaseService;
+import com.usoftchina.saas.common.dto.DocReqDTO;
+import com.usoftchina.saas.document.mapper.VendorMapper;
+import com.usoftchina.saas.document.po.Vendor;
+import com.usoftchina.saas.page.PageRequest;
+
+import java.util.List;
+
+public interface VendorService extends CommonBaseService<VendorMapper, Vendor>{
+
+    List<Vendor> getVendorsByCondition(PageRequest page, DocReqDTO docReqDTO);
+
+}

+ 47 - 0
applications/document/document-server/src/main/resources/application.yml

@@ -0,0 +1,47 @@
+spring:
+  application:
+    name: document-server
+  security:
+    user:
+      name: admin
+      password: select111***
+  datasource:
+    driver-class-name: com.mysql.jdbc.Driver
+    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false
+    username: root
+    password: select111***
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 50
+      idle-timeout: 30000
+      max-lifetime: 1800000
+      connection-timeout: 30000
+  messages:
+    basename: i18n/messages
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@192.168.0.181:8500/eureka/
+server:
+  port: 9480
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'
+mybatis:
+  type-aliases-package: com.usoftchina.saas.document.po
+  mapper-locations: classpath:mapper/*.xml
+auth:
+  public-key: auth/pub.key

BIN
applications/document/document-server/src/main/resources/auth/pub.key


+ 0 - 0
base-servers/account/account-server/src/main/resources/banner.txt → applications/document/document-server/src/main/resources/banner.txt


+ 42 - 0
applications/document/document-server/src/main/resources/config/application-dev.yml

@@ -0,0 +1,42 @@
+spring:
+  application:
+    name: document-server
+  security:
+    user:
+      name: admin
+      password: select111***
+  datasource:
+    hikari:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false
+      username: root
+      password: select111***
+  messages:
+    basename: i18n/messages
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    health-check-url-path: /actuator/health
+    status-page-url-path: /actuator/info
+    metadata-map:
+      user.name: ${spring.security.user.name}
+      user.password: ${spring.security.user.password}
+  client:
+    registryFetchIntervalSeconds: 5
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@192.168.253.12:8500/eureka/
+server:
+  port: 9480
+  tomcat:
+    uri-encoding: UTF-8
+info:
+  name: '@project.artifactId@'
+  description: '@project.description@'
+  version: '@project.version@'
+  spring-boot-version: '@spring.boot.version@'
+  spring-cloud-version: '@spring.cloud.version@'
+mybatis:
+  type-aliases-package: com.usoftchina.saas.document.po
+  mapper-locations: classpath:mapper/*.xml
+auth:
+  publie-key: auth/pub.key

+ 7 - 0
applications/document/document-server/src/main/resources/config/application-docker.yml

@@ -0,0 +1,7 @@
+eureka:
+  instance:
+    hostname: saas-document-server
+    prefer-ip-address: false
+  client:
+    serviceUrl:
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@saas-eureka-server:8500/eureka/

+ 64 - 0
applications/document/document-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <jmxConfigurator/>
+
+    <!--
+    %m
+    输出代码中指定的消息
+    %p
+    输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
+    %r
+    输出自应用启动到输出该log信息耗费的毫秒数
+    %c
+    输出所属的类目,通常就是所在类的全名
+    %t
+    输出产生该日志事件的线程名
+    %n
+    输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
+    %d
+    输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},
+    输出类似:2002年10月18日 22:10:28,921
+    %l
+    输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
+    -->
+
+    <springProperty scope="context" name="log.path" source="logging.path" defaultValue="/var/log/saas/document-server"/>
+    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="document-server"/>
+    <springProperty scope="context" name="spring.profiles.active" source="spring.profiles.active" defaultValue="dev"/>
+    <springProperty scope="context" name="common-pattern" source="logging.common-pattern" defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS}:[%5p] [%t:%r] [%C{1}:%M:%L] --> %m%n"/>
+    <springProperty scope="context" name="log.level.console" source="logging.level.console" defaultValue="INFO"/>
+
+    <contextName>${spring.application.name}-${spring.profiles.active}-logback</contextName>
+
+
+    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level.console}</level>
+        </filter>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="ROOT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/root.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 每天一归档 -->
+            <fileNamePattern>${log.path}/%d{yyyy-MM}/root-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
+            <!-- 单个日志文件最多 100MB, 60天的日志周期,最大不能超过20GB -->
+            <maxFileSize>128MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${common-pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="${log.level.console}">
+        <appender-ref ref="CONSOLE_APPENDER"/>
+        <appender-ref ref="ROOT_APPENDER"/>
+    </root>
+
+</configuration>

+ 48 - 0
applications/document/document-server/src/main/resources/mapper/ProductMapper.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.document.mapper.ProductMapper">
+    <resultMap id="ProductResultMapper" type="com.usoftchina.saas.document.po.Product">
+        <id column="pr_id" property="pr_id" jdbcType="INTEGER" />
+        <result column="pr_code" property="pr_code" jdbcType="VARCHAR" />
+        <result column="pr_detail" property="pr_detail" jdbcType="VARCHAR" />
+        <result column="pr_spec" property="pr_spec" jdbcType="VARCHAR" />
+        <result column="pr_unit" property="pr_unit" jdbcType="VARCHAR" />
+        <result column="pr_kind" property="pr_kind" jdbcType="VARCHAR" />
+        <result column="pr_orispeccode" property="pr_orispeccode" jdbcType="VARCHAR" />
+        <result column="pr_whid" property="pr_whid" jdbcType="INTEGER" />
+        <result column="pr_whcode" property="pr_whcode" jdbcType="VARCHAR" />
+        <result column="pr_whname" property="pr_whname" jdbcType="VARCHAR" />
+        <result column="pr_zxbzs" property="pr_zxbzs" jdbcType="INTEGER" />
+        <result column="pr_leadtime" property="pr_leadtime" jdbcType="INTEGER" />
+        <result column="pr_brand" property="pr_brand" jdbcType="VARCHAR" />
+        <result column="pr_standardprice" property="pr_standardprice" jdbcType="DOUBLE" />
+        <result column="pr_purcprice" property="pr_purcprice" jdbcType="DOUBLE" />
+        <result column="pr_saleprice" property="pr_saleprice" jdbcType="DOUBLE" />
+        <result column="pr_vendid" property="pr_vendid" jdbcType="INTEGER" />
+        <result column="pr_vendcode" property="pr_vendcode" jdbcType="VARCHAR" />
+        <result column="pr_vendname" property="pr_vendname" jdbcType="VARCHAR" />
+        <result column="pr_docdate" property="pr_docdate" jdbcType="TIMESTAMP" />
+        <result column="pr_recordmanid" property="pr_recordmanid" jdbcType="INTEGER" />
+        <result column="pr_recordman" property="pr_recordman" jdbcType="VARCHAR" />
+        <result column="pr_status" property="pr_status" jdbcType="VARCHAR" />
+        <result column="pr_statuscode" property="pr_statuscode" jdbcType="VARCHAR" />
+        <result column="companyid" property="companyId" jdbcType="INTEGER" />
+        <result column="updatemanid" property="updaterId" jdbcType="INTEGER" />
+        <result column="updatetime" property="updateTime" jdbcType="TIMESTAMP" />
+        <result column="pr_text1" property="pr_text1" jdbcType="VARCHAR" />
+        <result column="pr_text2" property="pr_text2" jdbcType="VARCHAR" />
+        <result column="pr_text3" property="pr_text3" jdbcType="VARCHAR" />
+        <result column="pr_text4" property="pr_text4" jdbcType="VARCHAR" />
+        <result column="pr_text5" property="pr_text5" jdbcType="VARCHAR" />
+    </resultMap>
+    <select id="getProductsByCondition" resultMap="ProductResultMapper" parameterType="com.usoftchina.saas.common.dto.DocReqDTO">
+        SELECT * FROM PRODUCT
+        <where>
+            <if test="condition!=null">
+                ${condition}
+            </if>
+        </where>
+
+    </select>
+</mapper>
+

+ 41 - 0
applications/document/document-server/src/main/resources/mapper/VendorMapper.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.document.mapper.VendorMapper">
+    <resultMap id="VendorResultMapper" type="com.usoftchina.saas.document.po.Vendor">
+        <id column="ve_id" property="ve_id" jdbcType="INTEGER" />
+        <result column="ve_code" property="ve_code" jdbcType="VARCHAR" />
+        <result column="ve_uu" property="ve_uu" jdbcType="VARCHAR" />
+        <result column="ve_name" property="ve_name" jdbcType="VARCHAR" />
+        <result column="ve_type" property="ve_type" jdbcType="VARCHAR" />
+        <result column="ve_begindate" property="ve_begindate" jdbcType="TIMESTAMP" />
+        <result column="ve_beginapamount" property="ve_beginapamount" jdbcType="INTEGER" />
+        <result column="ve_beginprepayamount" property="ve_beginprepayamount" jdbcType="INTEGER" />
+        <result column="ve_promisedays" property="ve_promisedays" jdbcType="INTEGER" />
+        <result column="ve_taxrate" property="ve_taxrate" jdbcType="DOUBLE" />
+        <result column="ve_nsrzh" property="ve_nsrzh" jdbcType="VARCHAR" />
+        <result column="ve_bankaccount" property="ve_bankaccount" jdbcType="VARCHAR" />
+        <result column="ve_bankcode" property="ve_bankcode" jdbcType="VARCHAR" />
+        <result column="ve_status" property="ve_status" jdbcType="VARCHAR" />
+        <result column="ve_statuscode" property="ve_statuscode" jdbcType="VARCHAR" />
+        <result column="ve_recordid" property="ve_recordid" jdbcType="INTEGER" />
+        <result column="ve_recordname" property="ve_recordname" jdbcType="VARCHAR" />
+        <result column="ve_initdate" property="ve_initdate" jdbcType="TIMESTAMP" />
+        <result column="companyid" property="companyId" jdbcType="INTEGER" />
+        <result column="updatemanid" property="updaterId" jdbcType="INTEGER" />
+        <result column="updatedate" property="updateTime" jdbcType="TIMESTAMP" />
+        <result column="ve_text1" property="ve_text1" jdbcType="VARCHAR" />
+        <result column="ve_text2" property="ve_text2" jdbcType="VARCHAR" />
+        <result column="ve_text3" property="ve_text3" jdbcType="VARCHAR" />
+        <result column="ve_text4" property="ve_text4" jdbcType="VARCHAR" />
+        <result column="ve_text5" property="ve_text5" jdbcType="VARCHAR" />
+    </resultMap>
+    <select id="getVendorsByCondition" resultMap="VendorResultMapper" parameterType="com.usoftchina.saas.common.dto.DocReqDTO">
+        SELECT * FROM VENDOR
+        <where>
+            <if test="condition!=null">
+                ${condition}
+            </if>
+        </where>
+    </select>
+</mapper>
+

+ 32 - 0
applications/document/document-server/src/test/java/com/usoftchina/saas/document/service/VendorServiceTest.java

@@ -0,0 +1,32 @@
+package com.usoftchina.saas.document.service;
+
+
+import com.usoftchina.saas.document.DocumentApplication;
+import com.usoftchina.saas.document.po.Vendor;
+import com.usoftchina.saas.page.PageRequest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = DocumentApplication.class)
+@EnableAutoConfiguration
+public class VendorServiceTest {
+
+    @Autowired
+    private VendorService vendorService;
+
+    @Test
+    public void testSelectAll(){
+        List<Vendor> vendorList = vendorService.getVendorsByCondition(null, null);
+        System.out.println("vendCode: " + vendorList.get(0).getVe_code());
+        System.out.println("vendName: " + vendorList.get(0).getVe_name());
+        System.out.println("vendType: " + vendorList.get(0).getVe_type());
+        System.out.println("vendBeginDate: " + vendorList.get(0).getVe_begindate());
+    }
+}

+ 6 - 1
applications/document/pom.xml

@@ -10,7 +10,12 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>document</artifactId>
+    <packaging>pom</packaging>
     <description>base document server</description>
-
+    <modules>
+        <module>document-dto</module>
+        <module>document-server</module>
+        <module>document-api</module>
+    </modules>
 
 </project>

+ 5 - 8
applications/purchase/purchase-server/pom.xml

@@ -15,23 +15,20 @@
     <dependencies>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
-            <artifactId>core</artifactId>
+            <artifactId>purchase-dto</artifactId>
         </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
-            <artifactId>purchase-dto</artifactId>
+            <artifactId>document-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>auth-client</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>server-starter</artifactId>
         </dependency>
         <!-- db -->
         <dependency>

+ 3 - 0
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/PurchaseApplication.java

@@ -5,6 +5,7 @@ import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 /**
@@ -14,6 +15,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 @SpringBootApplication
 @EnableEurekaClient
 @EnableTransactionManagement
+@EnableFeignClients("com.usoftchina.saas.document.api")
+//@EnableAuthClient
 @MapperScan("com.usoftchina.saas.purchase.mapper")
 public class PurchaseApplication {
     public static void main(String[] args) {

+ 36 - 0
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/config/WebMvcConfig.java

@@ -0,0 +1,36 @@
+package com.usoftchina.saas.purchase.config;
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.nio.charset.Charset;
+import java.util.List;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer{
+
+    @Bean
+    public HttpMessageConverter<String> responseBodyConverter() {
+        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
+        return converter;
+    }
+
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        WebMvcConfigurer.super.configureMessageConverters(converters);
+        converters.add(responseBodyConverter());
+    }
+
+    @Bean
+    public RestTemplate restTemplate(){
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().add(0, responseBodyConverter());
+        return restTemplate;
+    }
+
+}

+ 36 - 0
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/ComponentController.java

@@ -0,0 +1,36 @@
+package com.usoftchina.saas.purchase.controller;
+
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.document.api.ProductApi;
+import com.usoftchina.saas.document.api.VendorApi;
+import com.usoftchina.saas.document.dto.ProductDTO;
+import com.usoftchina.saas.document.dto.VendorDTO;
+import com.usoftchina.saas.page.PageRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/purchase/component")
+public class ComponentController {
+
+    @Autowired
+    private VendorApi vendorApi;
+    @Autowired
+    private ProductApi productApi;
+
+    @GetMapping("/dbfind/vendor")
+    @ResponseBody
+    public Result<VendorDTO> getVendorList(PageRequest page, String condition){
+        List<VendorDTO> vendorDTOResult = vendorApi.getVendorsByCondition(page, condition);
+        return Result.success(vendorDTOResult);
+    }
+
+    @GetMapping("/dbfind/product")
+    @ResponseBody
+    public Result<ProductDTO> getProductList(PageRequest page, String condition){
+        List<ProductDTO> productDTOResult = productApi.getProductsByCondition(page, condition);
+        return Result.success(productDTOResult);
+    }
+}

+ 2 - 2
base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java

@@ -19,7 +19,7 @@ public interface AccountApi {
      * @param password 明文密码
      * @return
      */
-    @GetMapping(value = "/api/account/pwd/check")
+    @GetMapping(value = "/pwd/check")
     Result<AccountDTO> validByUsernameAndPwd(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password);
 
     /**
@@ -28,6 +28,6 @@ public interface AccountApi {
      * @param username
      * @return
      */
-    @GetMapping(value = "/api/account")
+    @GetMapping
     Result<AccountDTO> getAccount(@RequestParam(value = "username") String username);
 }

+ 1 - 9
base-servers/account/account-server/pom.xml

@@ -15,20 +15,12 @@
     <dependencies>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
-            <artifactId>core</artifactId>
+            <artifactId>server-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>account-dto</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
-        </dependency>
         <!-- db -->
         <dependency>
             <groupId>mysql</groupId>

+ 1 - 1
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java

@@ -21,7 +21,7 @@ import java.util.List;
  * @date 2018/10/2
  */
 @RestController
-@RequestMapping("/api/account")
+@RequestMapping("/account")
 public class AccountController {
 
     @Autowired

+ 1 - 1
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/CompanyController.java

@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*;
  * @date 2018/10/2
  */
 @RestController
-@RequestMapping("/api/account/company")
+@RequestMapping("/company")
 public class CompanyController {
 
     @Autowired

+ 3 - 0
base-servers/admin-server/src/main/resources/config/application-docker.yml

@@ -1,4 +1,7 @@
 eureka:
+  instance:
+    hostname: saas-admin-server
+    prefer-ip-address: false
   client:
     serviceUrl:
       defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@saas-eureka-server:8500/eureka/

+ 2 - 29
base-servers/auth/auth-server/pom.xml

@@ -21,40 +21,13 @@
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>auth-dto</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.usoftchina.saas</groupId>
-            <artifactId>core</artifactId>
-        </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>account-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.hibernate</groupId>
-                    <artifactId>hibernate-validator</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.apache.tomcat.embed</groupId>
-                    <artifactId>tomcat-embed-websocket</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <!-- management -->
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>server-starter</artifactId>
         </dependency>
         <!-- db -->
         <dependency>

+ 2 - 0
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/AuthApplication.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.auth;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 
 /**
  * @author yingp
@@ -10,6 +11,7 @@ import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
  */
 @SpringBootApplication
 @EnableEurekaClient
+@EnableFeignClients(basePackages = "com.usoftchina.saas.account.api")
 public class AuthApplication {
     public static void main(String[] args) {
         SpringApplication.run(AuthApplication.class, args);

+ 12 - 14
base-servers/gateway-server/pom.xml

@@ -16,43 +16,41 @@
     </properties>
 
     <dependencies>
-        <!-- management -->
         <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>server-starter</artifactId>
         </dependency>
-        <dependency>
+        <!--<dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-gateway</artifactId>
         </dependency>
-        <!-- zuul -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
+            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
         </dependency>
         <!-- rate limit -->
-        <dependency>
+        <!--<dependency>
             <groupId>com.marcosbarbero.cloud</groupId>
             <artifactId>spring-cloud-zuul-ratelimit</artifactId>
             <version>${ratelimit.version}</version>
-        </dependency>
+        </dependency>-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
         <!-- sleuth -->
-        <dependency>
+        <!--<dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-zipkin</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.amqp</groupId>
             <artifactId>spring-rabbit</artifactId>
-        </dependency>
+        </dependency>-->
         <!-- auth -->
         <dependency>
             <groupId>com.usoftchina.saas</groupId>

+ 0 - 2
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/GatewayApplication.java

@@ -3,7 +3,6 @@ package com.usoftchina.saas.gateway;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
-import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
 import org.springframework.cloud.openfeign.EnableFeignClients;
 
 /**
@@ -11,7 +10,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
  * @date 2018/9/30
  */
 @SpringBootApplication
-@EnableZuulProxy
 @EnableEurekaClient
 @EnableFeignClients(basePackages = "com.usoftchina.saas.auth.api")
 public class GatewayApplication {

+ 0 - 103
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AccessFilter.java

@@ -1,103 +0,0 @@
-package com.usoftchina.saas.gateway.config;
-
-import com.netflix.zuul.ZuulFilter;
-import com.netflix.zuul.context.RequestContext;
-import com.netflix.zuul.exception.ZuulException;
-import com.usoftchina.saas.auth.api.AuthApi;
-import com.usoftchina.saas.auth.common.jwt.JwtHelper;
-import com.usoftchina.saas.auth.common.jwt.JwtInfo;
-import com.usoftchina.saas.base.Result;
-import com.usoftchina.saas.exception.BizException;
-import com.usoftchina.saas.exception.ExceptionCode;
-import com.usoftchina.saas.utils.JsonUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.MediaType;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * @author yingp
- * @date 2018/9/30
- */
-public class AccessFilter extends ZuulFilter {
-
-    @Autowired
-    private AuthApi authApi;
-
-    @Autowired
-    private AuthConfig authConfig;
-
-    @Override
-    public String filterType() {
-        return "pre";
-    }
-
-    @Override
-    public int filterOrder() {
-        return 1;
-    }
-
-    @Override
-    public boolean shouldFilter() {
-        return true;
-    }
-
-    /**
-     * 具体过滤逻辑
-     *
-     * @return
-     * @throws ZuulException
-     */
-    @Override
-    public Object run() throws ZuulException {
-        RequestContext ctx = RequestContext.getCurrentContext();
-        HttpServletRequest request = ctx.getRequest();
-        if (isIgnore(request.getRequestURI())) {
-            return null;
-        }
-        String token = request.getHeader(authConfig.getAuthHeader());
-        if (StringUtils.isEmpty(token)) {
-            setFailedRequest(ctx, 401, Result.error(ExceptionCode.JWT_ILLEGAL_ARGUMENT));
-            return null;
-        }
-        try {
-            JwtInfo infoFromToken = JwtHelper.getInfoFromToken(token, authConfig.getPublicKey());
-            // TODO resource + role
-        } catch (BizException e) {
-            setFailedRequest(ctx, 401, Result.error(e));
-            return null;
-        }
-        return null;
-    }
-
-    private boolean isIgnore(String requestUri) {
-        if (!CollectionUtils.isEmpty(authConfig.getIgnores())) {
-            for (String ignore : authConfig.getIgnores()) {
-                if (requestUri.startsWith(ignore)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 异常请求
-     *
-     * @param ctx
-     * @param code
-     * @param result
-     */
-    public void setFailedRequest(RequestContext ctx, int code, Result result) {
-        ctx.setSendZuulResponse(false);
-        HttpServletResponse httpResponse = ctx.getResponse();
-        httpResponse.setCharacterEncoding("UTF-8");
-        httpResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
-        httpResponse.setStatus(code);
-        ctx.setResponseBody(JsonUtils.toJsonString(result));
-        ctx.setResponse(httpResponse);
-    }
-}

+ 25 - 0
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AuthFilter.java

@@ -0,0 +1,25 @@
+package com.usoftchina.saas.gateway.config;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * 全局过滤器鉴权
+ *
+ * @author yingp
+ * @date 2018/10/13
+ */
+public class AuthFilter implements GlobalFilter, Ordered {
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        return chain.filter(exchange);
+    }
+
+    @Override
+    public int getOrder() {
+        return -100;
+    }
+}

+ 65 - 0
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/ErrorConfig.java

@@ -0,0 +1,65 @@
+package com.usoftchina.saas.gateway.config;
+
+import com.usoftchina.saas.gateway.error.MyExceptionHandler;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.codec.ServerCodecConfigurer;
+import org.springframework.web.reactive.result.view.ViewResolver;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author yingp
+ * @date 2018/10/13
+ */
+@Configuration
+@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
+public class ErrorConfig {
+
+    private final ServerProperties serverProperties;
+
+    private final ApplicationContext applicationContext;
+
+    private final ResourceProperties resourceProperties;
+
+    private final List<ViewResolver> viewResolvers;
+
+    private final ServerCodecConfigurer serverCodecConfigurer;
+
+    public ErrorConfig(ServerProperties serverProperties,
+                                     ResourceProperties resourceProperties,
+                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
+                                     ServerCodecConfigurer serverCodecConfigurer,
+                                     ApplicationContext applicationContext) {
+        this.serverProperties = serverProperties;
+        this.applicationContext = applicationContext;
+        this.resourceProperties = resourceProperties;
+        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
+        this.serverCodecConfigurer = serverCodecConfigurer;
+    }
+
+
+    @Bean
+    @Order(Ordered.HIGHEST_PRECEDENCE)
+    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
+        MyExceptionHandler exceptionHandler = new MyExceptionHandler(
+                errorAttributes,
+                this.resourceProperties,
+                this.serverProperties.getError(),
+                this.applicationContext);
+        exceptionHandler.setViewResolvers(this.viewResolvers);
+        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
+        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
+        return exceptionHandler;
+    }
+}

+ 0 - 18
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/SecurityConfig.java

@@ -1,18 +0,0 @@
-package com.usoftchina.saas.gateway.config;
-
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-
-/**
- * @author yingp
- * @date 2018/10/10
- */
-@EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
-    @Override
-    public void configure(WebSecurity web) throws Exception {
-        web.ignoring().antMatchers("/api/**");
-    }
-}

+ 49 - 0
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/WebConfig.java

@@ -0,0 +1,49 @@
+package com.usoftchina.saas.gateway.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.cors.reactive.CorsUtils;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author yingp
+ * @date 2018/10/13
+ */
+@Configuration
+public class WebConfig {
+
+    @Bean
+    public WebFilter corsFilter() {
+        return (ServerWebExchange ctx, WebFilterChain chain) -> {
+            ServerHttpRequest request = ctx.getRequest();
+            if (!CorsUtils.isCorsRequest(request)) {
+                return chain.filter(ctx);
+            }
+            HttpHeaders requestHeaders = request.getHeaders();
+            ServerHttpResponse response = ctx.getResponse();
+            HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
+            HttpHeaders headers = response.getHeaders();
+            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
+            headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
+            if (requestMethod != null) {
+                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
+            }
+            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
+            headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
+            headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "18000L");
+            if (request.getMethod() == HttpMethod.OPTIONS) {
+                response.setStatusCode(HttpStatus.OK);
+                return Mono.empty();
+            }
+            return chain.filter(ctx);
+        };
+    }
+}

+ 0 - 47
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/ZuulConfig.java

@@ -1,47 +0,0 @@
-package com.usoftchina.saas.gateway.config;
-
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-
-/**
- * @author yingp
- * @date 2018/9/30
- */
-@Configuration
-@EnableConfigurationProperties(AuthConfig.class)
-public class ZuulConfig {
-
-    @Bean
-    public CorsFilter corsFilter() {
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        CorsConfiguration config = new CorsConfiguration();
-        // 允许cookies跨域
-        config.setAllowCredentials(true);
-        // 允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
-        config.addAllowedOrigin("*");
-        // 允许访问的头信息,*表示全部
-        config.addAllowedHeader("*");
-        // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
-        config.setMaxAge(18000L);
-        // 允许提交请求的方法,*表示全部允许
-        config.addAllowedMethod("OPTIONS");
-        config.addAllowedMethod("HEAD");
-        // 允许Get的请求方法
-        config.addAllowedMethod("GET");
-        config.addAllowedMethod("PUT");
-        config.addAllowedMethod("POST");
-        config.addAllowedMethod("DELETE");
-        config.addAllowedMethod("PATCH");
-        source.registerCorsConfiguration("/**", config);
-        return new CorsFilter(source);
-    }
-
-    @Bean
-    public AccessFilter accessFilter() {
-        return new AccessFilter();
-    }
-}

+ 99 - 0
base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/error/MyExceptionHandler.java

@@ -0,0 +1,99 @@
+package com.usoftchina.saas.gateway.error;
+
+import org.springframework.boot.autoconfigure.web.ErrorProperties;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.cloud.gateway.support.NotFoundException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.reactive.function.server.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 自定义异常处理
+ *
+ * @author yingp
+ * @date 2018/10/13
+ */
+public class MyExceptionHandler extends DefaultErrorWebExceptionHandler {
+
+    public MyExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
+                              ErrorProperties errorProperties, ApplicationContext applicationContext) {
+        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
+    }
+
+    /**
+     * 获取异常属性
+     */
+    @Override
+    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
+        int code = 500;
+        Throwable error = super.getError(request);
+        if (error instanceof NotFoundException) {
+            code = 404;
+        }
+        return response(code, this.buildMessage(request, error));
+    }
+
+    /**
+     * 构建返回的JSON数据格式
+     *
+     * @param status  状态码
+     * @param message 异常信息
+     * @return
+     */
+    private Map<String, Object> response(int status, String message) {
+        Map<String, Object> map = new HashMap<>(4);
+        map.put("success", false);
+        map.put("code", status);
+        map.put("message", message);
+        map.put("data", null);
+        return map;
+
+    }
+
+    /**
+     * 构建异常信息
+     *
+     * @param request
+     * @param ex
+     * @return
+     */
+    private String buildMessage(ServerRequest request, Throwable ex) {
+        StringBuilder message = new StringBuilder("Failed to handle request [");
+        message.append(request.methodName());
+        message.append(" ");
+        message.append(request.uri());
+        message.append("]");
+        if (ex != null) {
+            message.append(": ");
+            message.append(ex.getMessage());
+        }
+        return message.toString();
+    }
+
+    /**
+     * 根据code获取对应的HttpStatus
+     *
+     * @param errorAttributes
+     */
+    @Override
+    protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
+        int statusCode = (int) errorAttributes.get("code");
+        return HttpStatus.valueOf(statusCode);
+    }
+
+    /**
+     * 指定响应处理方法为JSON处理的方法
+     *
+     * @param errorAttributes
+     */
+    @Override
+    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
+        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
+    }
+
+}

+ 103 - 39
base-servers/gateway-server/src/main/resources/application.yml

@@ -17,9 +17,87 @@ spring:
   zipkin:
     sender:
       type: rabbit
+    service:
+      name: ${spring.application.name}
   sleuth:
     sampler:
-      percentage: 1.0
+      percentage: 1
+    integration:
+      enabled: false
+    scheduled:
+      skip-pattern: "^org.*HystrixStreamTask$"
+  cloud:
+    gateway:
+      discovery:
+        locator:
+          enabled: true
+      routes:
+      - id: UI-SERVER
+        uri: lb://UI-SERVER
+        predicates:
+        - Path=/api/ui/**
+        filters:
+        - RewritePath=/api/ui/(?<segment>.*), /$\{segment}
+      - id: ACCOUNT-SERVER
+        uri: lb://ACCOUNT-SERVER
+        predicates:
+        - Path=/api/account/**
+        filters:
+        - RewritePath=/api/account/(?<segment>.*), /$\{segment}
+      - id: AUTH-SERVER
+        uri: lb://AUTH-SERVER
+        predicates:
+        - Path=/api/auth/**
+        filters:
+        - RewritePath=/api/auth/(?<segment>.*), /$\{segment}
+      - id: FILE-SERVER
+        uri: lb://FILE-SERVER
+        predicates:
+        - Path=/api/file/**
+        filters:
+        - RewritePath=/api/file/(?<segment>.*), /$\{segment}
+      - id: MAIL-SERVER
+        uri: lb://MAIL-SERVER
+        predicates:
+        - Path=/api/mail/**
+        filters:
+        - RewritePath=/api/mail/(?<segment>.*), /$\{segment}
+      - id: SMS-SERVER
+        uri: lb://SMS-SERVER
+        predicates:
+        - Path=/api/sms/**
+        filters:
+        - RewritePath=/api/sms/(?<segment>.*), /$\{segment}
+      - id: PURCHASE-SERVER
+        uri: lb://PURCHASE-SERVER
+        predicates:
+        - Path=/api/purchase/**
+        filters:
+        - RewritePath=/api/purchase/(?<segment>.*), /$\{segment}
+      - id: SALE-SERVER
+        uri: lb://SALE-SERVER
+        predicates:
+        - Path=/api/sale/**
+        filters:
+        - RewritePath=/api/sale/(?<segment>.*), /$\{segment}
+      - id: STORAGE-SERVER
+        uri: lb://STORAGE-SERVER
+        predicates:
+        - Path=/api/storage/**
+        filters:
+        - RewritePath=/api/storage/(?<segment>.*), /$\{segment}
+      - id: DOCUMENT-SERVER
+        uri: lb://DOCUMENT-SERVER
+        predicates:
+        - Path=/api/document/**
+        filters:
+        - RewritePath=/api/document/(?<segment>.*), /$\{segment}
+      - id: MONEY-SERVER
+        uri: lb://MONEY-SERVER
+        predicates:
+        - Path=/api/money/**
+        filters:
+        - RewritePath=/api/money/(?<segment>.*), /$\{segment}
 server:
   port: 8560
   tomcat:
@@ -38,6 +116,8 @@ eureka:
     serviceUrl:
       defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@192.168.0.181:8500/eureka/
 feign:
+  hystrix:
+    enabled: true
   compression:
     request:
       enabled: true
@@ -45,44 +125,21 @@ feign:
       min-request-size: 2048
     response:
       enabled: true
-zuul:
-  ignored-services: "*"   # 忽略eureka上的所有服务
-  sensitive-headers:      # 一些比较敏感的请求头,不想通过zuul传递过去, 可以通过该属性进行设置
-  prefix: /api            # 公共的前缀
-  routes:  # 路由配置
-    ui:
-      path: /ui/**
-      serviceId: ui-server
-    account:
-      path: /account/**
-      serviceId: account-server
-    auth:
-      path: /auth/**
-      serviceId: auth-server
-    file:
-      path: /file/**
-      serviceId: file-server
-    mail:
-      path: /mail/**
-      serviceId: mail-server
-    sms:
-      path: /sms/**
-      serviceId: sms-server
-    purchase:
-      path: /purchase/**
-      serviceId: purchase-server
-    sale:
-      path: /sale/**
-      serviceId: sale-server
-    storage:
-      path: /storage/**
-      serviceId: storage-server
-    document:
-      path: /document/**
-      serviceId: document-server
-    money:
-      path: /money/**
-      serviceId: money-server                       
+hystrix:
+  command:
+    default:
+      execution:
+        isolation:
+          thread:
+            timeoutInMilliseconds: 3000
+ribbon:
+  eureka:
+    enabled: true
+  ReadTimeout: 60000
+  ConnectTimeout: 60000
+  MaxAutoRetries: 0
+  MaxAutoRetriesNextServer: 1
+  OkToRetryOnAllOperations: false
 info:
   name: '@project.artifactId@'
   description: '@project.description@'
@@ -95,3 +152,10 @@ auth:
     - /api/auth
     # 忽略全部
     - /
+logging:
+  level:
+    org.springframework.cloud.gateway: debug
+    org.springframework.http.server.reactive: debug
+    org.springframework.web.reactive: debug
+    org.springframework.security: debug
+    reactor.ipc.netty: debug

+ 0 - 15
base-servers/gateway-server/src/main/resources/banner.txt

@@ -1,15 +0,0 @@
-${AnsiColor.BRIGHT_YELLOW}
-
-88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
-88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
-88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
-88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
-88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
-88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
-Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
- `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
-
-
-Application Version: ${application.version}${application.formatted-version}
-Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
-${AnsiColor.DEFAULT}

+ 3 - 0
base-servers/gateway-server/src/main/resources/config/application-docker.yml

@@ -1,4 +1,7 @@
 eureka:
+  instance:
+    hostname: saas-gateway-server
+    prefer-ip-address: false
   client:
     serviceUrl:
       defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@saas-eureka-server:8500/eureka/

+ 4 - 11
base-servers/ui-server/pom.xml

@@ -15,38 +15,31 @@
     <dependencies>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
-            <artifactId>core</artifactId>
+            <artifactId>server-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>auth-client</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
-        </dependency>
         <!-- db -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
         </dependency>
         <!-- sleuth -->
-        <dependency>
+        <!--<dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-zipkin</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.amqp</groupId>
             <artifactId>spring-rabbit</artifactId>
-        </dependency>
+        </dependency>-->
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
     <build>

+ 15 - 10
base-servers/ui-server/src/main/java/com/usoftchina/saas/ui/controller/co/CoViewController.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.ui.controller.co;
 
 import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.context.BaseContextHolder;
 import com.usoftchina.saas.ui.service.ViewService;
 import com.usoftchina.saas.ui.service.co.CoViewService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,20 +27,24 @@ public class CoViewController {
      * 获取企业视图配置
      *
      * @param name
-     * @param refresh 是否强制刷新
+     * @param refresh    是否强制刷新
+     * @param useDefault 当自定义配置为空时,是否返回标准配置
      * @return
      */
     @GetMapping("/config")
-    public Result<Object> getViewConfig(@RequestParam String name, Boolean refresh) {
-//        if (null != refresh && refresh) {
-//            coViewService.cacheEvict(name);
-//            viewService.cacheEvict(name);
-//        }
-        coViewService.cacheEvict(name);// 暂时强制刷新
-        viewService.cacheEvict(name);
-
+    public Result<Object> getViewConfig(@RequestParam String name,
+                                        @RequestParam(required = false, defaultValue = "true") Boolean refresh,
+                                        @RequestParam(required = false, defaultValue = "false") Boolean useDefault) {
+        if (null != refresh && refresh) {
+            coViewService.cacheEvict(name);
+            viewService.cacheEvict(name);
+        }
+        // TODO 开发默认设置,及时去掉
+        if (null == BaseContextHolder.getCompanyId()) {
+            BaseContextHolder.setCompanyId(0);
+        }
         Object config = coViewService.getDeepConfig(name);
-        if (null == config) {
+        if (null == config && null != useDefault && useDefault) {
             // 企业配置不存在则取标准配置
             config = viewService.getDeepConfig(name);
         }

+ 2 - 0
base-servers/ui-server/src/main/resources/application.yml

@@ -13,6 +13,8 @@ spring:
   zipkin:
     sender:
       type: rabbit
+    service:
+      name: ${spring.application.name}
   sleuth:
     sampler:
       percentage: 1.0

+ 0 - 15
base-servers/ui-server/src/main/resources/banner.txt

@@ -1,15 +0,0 @@
-${AnsiColor.BRIGHT_YELLOW}
-
-88        88   ad88888ba     ,ad8888ba,    88888888888  888888888888  ,ad8888ba,   88        88  88  888b      88         db
-88        88  d8"     "8b   d8"'    `"8b   88                88      d8"'    `"8b  88        88  88  8888b     88        d88b
-88        88  Y8,          d8'        `8b  88                88     d8'            88        88  88  88 `8b    88       d8'`8b
-88        88  `Y8aaaaa,    88          88  88aaaaa           88     88             88aaaaaaaa88  88  88  `8b   88      d8'  `8b
-88        88    `"""""8b,  88          88  88"""""           88     88             88""""""""88  88  88   `8b  88     d8YaaaaY8b
-88        88          `8b  Y8,        ,8P  88                88     Y8,            88        88  88  88    `8b 88    d8""""""""8b
-Y8a.    .a8P  Y8a     a8P   Y8a.    .a8P   88                88      Y8a.    .a8P  88        88  88  88     `8888   d8'        `8b
- `"Y8888Y"'    "Y88888P"     `"Y8888Y"'    88                88       `"Y8888Y"'   88        88  88  88      `888  d8'          `8b
-
-
-Application Version: ${application.version}${application.formatted-version}
-Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
-${AnsiColor.DEFAULT}

+ 3 - 0
base-servers/zipkin-server/src/main/resources/config/application-docker.yml

@@ -1,4 +1,7 @@
 eureka:
+  instance:
+    hostname: saas-zipkin-server
+    prefer-ip-address: false
   client:
     serviceUrl:
       defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@saas-eureka-server:8500/eureka/

+ 1 - 0
framework/pom.xml

@@ -14,6 +14,7 @@
     <description>saas framework</description>
     <modules>
         <module>core</module>
+        <module>server-starter</module>
     </modules>
 
 </project>

+ 44 - 0
framework/server-starter/pom.xml

@@ -0,0 +1,44 @@
+<?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>framework</artifactId>
+        <groupId>com.usoftchina.saas</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>server-starter</artifactId>
+    <description>server starter</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</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-security</artifactId>
+        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

+ 14 - 0
framework/server-starter/src/main/java/com/usoftchina/saas/server/ServerAutoConfiguration.java

@@ -0,0 +1,14 @@
+package com.usoftchina.saas.server;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author yingp
+ * @date 2018/10/13
+ */
+@Configuration
+@ComponentScan(basePackages = {"com.usoftchina.saas.server"})
+public class ServerAutoConfiguration {
+    
+}

+ 16 - 0
framework/server-starter/src/main/java/com/usoftchina/saas/server/context/SpringContextListener.java

@@ -0,0 +1,16 @@
+package com.usoftchina.saas.server.context;
+
+import com.usoftchina.saas.context.SpringContextHolder;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+/**
+ * @author yingp
+ * @date 2018/7/18
+ */
+public class SpringContextListener implements ApplicationListener<ContextRefreshedEvent> {
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent event) {
+        SpringContextHolder.setContext(event.getApplicationContext());
+    }
+}

+ 41 - 0
framework/server-starter/src/main/java/com/usoftchina/saas/server/error/MyErrorController.java

@@ -0,0 +1,41 @@
+package com.usoftchina.saas.server.error;
+
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
+import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author yingp
+ * @date 2018/10/13
+ */
+@Controller
+public class MyErrorController extends BasicErrorController {
+
+    public MyErrorController(ServerProperties serverProperties) {
+        super(new DefaultErrorAttributes(), serverProperties.getError());
+    }
+
+    /**
+     * 覆盖默认的错误响应
+     */
+    @Override
+    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
+        Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
+        HttpStatus status = getStatus(request);
+        // 输出自定义格式
+        Map<String, Object> map = new HashMap<>(4);
+        map.put("success", false);
+        map.put("code", body.get("status"));
+        map.put("message", body.get("message"));
+        map.put("data", null);
+        return new ResponseEntity<>(map, status);
+    }
+}

+ 7 - 0
framework/server-starter/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,7 @@
+# Auto Configuration
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.usoftchina.saas.server.ServerAutoConfiguration
+
+# Application Listeners
+org.springframework.context.ApplicationListener=\
+com.usoftchina.saas.server.context.SpringContextListener

BIN
framework/server-starter/src/main/resources/auth/pub.key


+ 0 - 0
base-servers/auth/auth-server/src/main/resources/banner.txt → framework/server-starter/src/main/resources/banner.txt


+ 2 - 1
frontend/saas-web/app/util/BaseUtil.js

@@ -20,7 +20,8 @@ Ext.define('saas.util.BaseUtil', {
                 method: method,
                 timeout: timeout,
                 header: {
-                    'Access-Control-Allow-Origin': '*'
+                    'Access-Control-Allow-Origin': '*',
+                    "Content-Type": 'application/json;charset=UTF-8' 
                 },
                 success: function (response, opts) {
                     resolve(response);

+ 33 - 7
frontend/saas-web/app/util/FormUtil.js

@@ -3,9 +3,9 @@ Ext.define('saas.util.FormUtil', {
     BaseUtil: Ext.create('saas.util.BaseUtil'),
 
     // 请求页面组件接口模板
-    baseUrl: 'http://192.168.0.181:8560/api/ui/co_view/config?name={xtype}',
+    baseUrl: 'http://192.168.0.181:8560/api/ui/co_view/config?name={viewName}',
     // 模板替换正则
-    urlRe: /(.*){xtype}(.*)/g,
+    urlRe: /(.*){viewName}(.*)/g,
     
     /**
      * 获得form的字段配置
@@ -14,17 +14,43 @@ Ext.define('saas.util.FormUtil', {
      */
     setItems: function(form) {
         var me = this,
-            xtype = form.xtype,
-            url = me.baseUrl.replace(me.urlRe, '$1' + xtype);
+        viewName = form.viewName,
+        defaultItems = form.defaultItems,
+        formModel = form.getViewModel(),
+        url = me.baseUrl.replace(me.urlRe, '$1' + viewName);
         
         this.BaseUtil.request({url, })
         .then(function(response) {
             var res = Ext.decode(response.responseText);
             if(res.success) {
-
-                var config = res.data, items = [];
+                
+                var config = res.data || true, items = defaultItems || [];
                 if(config) {
-                    items = config.items,
+                    var cusItems = config.items || [];
+                    Ext.Array.each(cusItems, function(cusItem) {
+                        var item = items.find(function(item) {
+                            return item.name == cusItem.name;
+                        });
+                        Ext.apply(item, cusItem);
+                    });
+                    Ext.Array.each(items, function(item) {
+                        if(item.xtype == 'detailGridField') {
+                            var storeName = item.name || item.xtype + Ext.id();
+                            item.bind = {
+                                store: '{' + storeName + '}'
+                            };
+                            
+                            formModel.set(storeName, Ext.create('Ext.data.Store', {
+                                fields: item.columns ? item.columns.filter(function(c) {
+                                    return !!c.dataIndex;
+                                }).map(function(c) {
+                                    return c.dataIndex;
+                                }) : [],
+                                data: []
+                            }));
+                        }
+                    });
+
                     form.addItems(items);
                 }
 

+ 28 - 4
frontend/saas-web/app/view/core/dbfind/DbfindGridPanel.js

@@ -1,19 +1,43 @@
 Ext.define('saas.view.core.dbfind.DbfindGridPanel', {
     extend: 'saas.view.core.grid.GridPanel',
     xtype: 'dbfindgridpanel',
-
     GridUtil: Ext.create('saas.util.GridUtil'),
-
-    configUrl: '',
+    BaseUtil: Ext.create('saas.util.BaseUtil'),
     dataUrl: '',
 
     initComponent: function() {
         var me = this;
-        me.configUrl && me.GridUtil.setColumns(me, me.configUrl);
+        if(me.columns){
+            var fields = me.columns.map(column => column.dataIndex);
+            Ext.apply(me, {
+                store:Ext.create('Ext.data.Store', {
+                    fields:fields
+                })
+            });
+        }
         me.callParent(arguments);
     },
 
+    loadData: function(grid, url) {
+        this.BaseUtil.request({url})
+        .then(function(response) {
+            var data = Ext.decode(response.responseText);
+                grid.getStore().loadData(data.data);
+                grid.fireEvent('afterLoadData', grid, data.data);
+                grid.setLoading(false);
+        })
+        .catch(function(response) {
+            // something...
+        });
+    },
+
     listeners:{
+        afterrender:function(grid){
+            if(grid.dataUrl){
+                grid.setLoading(true);
+                grid.loadData(grid, grid.dataUrl);
+            }
+        },
         itemClick: function(view,record) {
             var me = this;
             var dbfinds = me.dbfinds;

+ 103 - 40
frontend/saas-web/app/view/core/dbfind/DbfindTrigger.js

@@ -12,18 +12,13 @@ Ext.define('saas.view.core.dbfind.DbfindTrigger', {
     enableKeyEvents:true,
     initComponent:function() {
         var me = this;
-        this.displayField='display';	   
-		this.valueField='value';
-		this.queryMode='local';
-		if(me.value){
-			me.store=Ext.create('Ext.data.Store', {
-				   fields: ['display','value'],
-				   data : [{
-					   'display':me.value,
-					   'value':me.value
-				   }]
-			});
-		}
+        me.store=Ext.create('Ext.data.Store', {
+            fields: ['display','value'],
+            data : [{
+                'display':me.value,
+                'value':me.value
+            }]
+        });
         this.callParent();
     },
     //输入值之后进行模糊查询
@@ -73,33 +68,29 @@ Ext.define('saas.view.core.dbfind.DbfindTrigger', {
                                 '</li>',
                             '</tpl></ul>'
                         );
-                        me.store=Ext.create('Ext.data.Store', {
-                            fields: field,
-                            data : []
-                        });
+                        me.store.setFields(field);
                     }
                 }
                 //加载数据
                 var data;
-                var url = 'resources/json/purchase/vendorDataDbfind.json';
                 Ext.Ajax.request({
-                    url: url,
+                    url: me.dataUrl,
                     params: '',
-                    async:false,
                     success: function(response, opts) {
                         data = Ext.decode(response.responseText);
+                        data = data.data;
+                        if(data!=null && data.length>0 && me.store && field.length>0){
+                            me.store.loadData(data,false);
+                            me.expand();
+                        }else{
+                            me.collapse( );
+                        }
                     },
                     failure: function(response, opts) {
                         console.log('server-side failure with status code ' + response.status);
                         return reject(response);
                     }
                 });                
-                if(data!=null && data.length>2 && me.store && field.length>0){
-                    me.store.loadData(data,false);
-                    me.expand();
-                }else{
-                    me.collapse( );
-                }
             }
             return true;
     	}else{
@@ -121,10 +112,10 @@ Ext.define('saas.view.core.dbfind.DbfindTrigger', {
             constrain: true,
             closable: true,
             layout:'fit',
-            renderTo:belong=='form'?f.ownerCt.getEl():f.column.ownerCt.ownerCt.ownerCt.getEl(),
+            renderTo:Ext.getCmp('main-tab-panel').getActiveTab().getEl(),
             items:[{
                 xtype:'dbfindgridpanel',
-                configUrl: f.configUrl,
+                columns: f.dbColumns,
                 dataUrl: f.dataUrl,
                 dbfinds: f.dbfinds
             }]
@@ -144,26 +135,98 @@ Ext.define('saas.view.core.dbfind.DbfindTrigger', {
     },
 
     listeners: {
+        focus: function(f) {
+            return true;
+		},
 		select:function(combo,record,eOpts){
             var me = combo;
             var dbfinds = me.dbfinds;
             if(dbfinds&&dbfinds.length>0){
-                for (let index = 0; index < dbfinds.length; index++) {
-                    var item = dbfinds[index];
-                    var field = me.ownerCt.down('[name='+item.to+']');
-                    if(field){
-                        var val = record.get(item.from);
-                        if(field.xtype=='dbfindtrigger'){
-                            field.setRawValue(val);
-                            field.value = val;
-                            field.lastTriggerValue=val;
-                        }else{
-                            field.setValue(val);
-                        }    
+                if(me.belong=='grid'){
+                    for (let index = 0; index < dbfinds.length; index++) {
+                        var item = dbfinds[index];
+                        debugger
+                        var field = me.ownerCt.down('[name='+item.to+']');
+                        if(field){
+                            var val = record.get(item.from);
+                            if(field.xtype=='dbfindtrigger'){
+                                field.setRawValue(val);
+                                field.value = val;
+                                field.lastTriggerValue=val;
+                            }else{
+                                field.setValue(val);
+                            }    
+                        }
+                    }
+                }else if(me.belong=='form'){
+                    for (let index = 0; index < dbfinds.length; index++) {
+                        var item = dbfinds[index];
+                        var field = me.ownerCt.down('[name='+item.to+']');
+                        if(field){
+                            var val = record.get(item.from);
+                            if(field.xtype=='dbfindtrigger'){
+                                field.setRawValue(val);
+                                field.value = val;
+                                field.lastTriggerValue=val;
+                            }else{
+                                field.setValue(val);
+                            }    
+                        }
                     }
                 }
             }
         }
-    }
+    },
+
+    getValue: function(f) {
+        var me = this,val = me.rawToValue(me.processRawValue(me.getRawValue()));
+        me.value = val;
+        return val;
+    },
+
+    autoSetValue: function(data, dbfinds) {
+		var trigger = this;
+		var triggerV = null;
+		if (!trigger.ownerCt || trigger.column) { //如果是grid的dbfind
+			var grid = trigger.owner;
+			var record = grid.lastSelectedRecord || trigger.record || grid.getSelectionModel().selected.items[0] || grid.selModel.lastSelected; //detailgrid里面selected
+			Ext.Array.each(Ext.Object.getKeys(data),
+					function(k) {
+				Ext.Array.each(dbfinds,
+						function(ds) {
+					if (ds.trigger == trigger.name || Ext.isEmpty(ds.trigger)) {
+						if (Ext.Array.contains(ds.dbGridField.split(';'), k)) { //k == ds.dbGridField//支持多dbgrid的字段对应grid同一字段
+							if (ds.field == trigger.name) {
+								triggerV = data[k]; //trigger所在位置赋值
+							}
+							record.set(ds.field, data[k]);
+						}
+					}
+				});
+			});
+		} else {
+			var ff;
+			Ext.Array.each(Ext.Object.getKeys(data),
+					function(k) {
+				Ext.Array.each(dbfinds,
+						function(ds) {
+					if (k == ds.dbGridField) {
+							if (trigger.name == ds.field||trigger.name.substring(0,trigger.name.indexOf('-new'))==ds.field) {
+								triggerV = data[k];
+							} else {
+								ff = Ext.getCmp(ds.field);
+								if (ff && ff.setValue) ff.setValue(data[k]);
+							}
+					}
+				});
+			});
+		}
+		trigger.setValue(triggerV);
+		data.data = data;
+		trigger.lastTriggerValue='';
+		trigger.fireEvent('aftertrigger', trigger, data);
+		trigger.lastTriggerId = null;
+		trigger.lastQueryValue='';
+	}
 
 });

+ 32 - 0
frontend/saas-web/app/view/core/form/DateField.js

@@ -0,0 +1,32 @@
+Ext.define('saas.view.core.form.DateField', {
+    extend: 'Ext.form.field.Date',
+    alias: 'widget.datetimefield',
+
+    setValue: function(v) {
+        var me = this,
+            utilDate = Ext.Date,
+            rawDate;
+        me.lastValue = me.rawDateText;
+        me.lastDate = me.rawDate;
+        if (Ext.isDate(v)) {
+            rawDate = me.rawDate = v;
+            me.rawDateText = me.formatDate(v);
+        } else {
+            rawDate = me.rawDate = me.rawToValue(v);
+            me.rawDateText = me.formatDate(v);
+            if (rawDate === v) {
+                if(v&&v.indexOf('.')>-1&&v.indexOf('T')>-1){
+                     v = v.substring(0,v.indexOf('T'));
+                    rawDate = null;
+                }else{
+                    rawDate = me.rawDate = null;
+                    me.rawDateText = '';
+                }     
+            }
+        }
+        if (rawDate && !utilDate.formatContainsHourInfo(me.format)) {
+            me.rawDate = utilDate.clearTime(rawDate, true);
+        }
+        me.callParent(arguments);
+    }
+});

+ 12 - 8
frontend/saas-web/app/view/core/form/FormPanel.js

@@ -14,6 +14,7 @@ Ext.define('saas.view.core.form.FormPanel', {
     _idField: '',
 
     //基础属性
+    initId: 0,
     layout: 'column',
     autoScroll: true,
     border: 1,
@@ -30,16 +31,15 @@ Ext.define('saas.view.core.form.FormPanel', {
     items: [],
 
     remoteConfig: true, // 是否需要从远端读取form配置
-    bindFields: [], // 已绑定字段(需要保存到数据库)
     toolBtns: [], // 自定义按钮
 
     initComponent: function() {
 
         var me = this;
-
+        me.FormUtil.setItems(me);
         //判断是否加载数据
         if(me.initId&&me.initId!=0){
-            var url = 'http://192.168.253.58:8800/purchase/form?id={id}',async=false;
+            var url = me._dataModelUrl,async=false;
             url = url.replace(/(.*){id}(.*)/g, '$1' + me.initId);
             me.BaseUtil.request({url,async })
             .then(function(response) {
@@ -47,17 +47,19 @@ Ext.define('saas.view.core.form.FormPanel', {
                 if(res.success) {
                     viewModel = me.getViewModel();
                     viewModel.data = res.data.main;
-                    viewModel.data.detailGridField = res.data.items;
                     viewModel._data = res.data.main;
-                    viewModel._data.detailGridField = res.data.items;
+                    viewModel.data.detailGridStore = res.data.items;                   
+                    viewModel._data.detailGridStore = res.data.items;
                 }
             })
             .catch(function(response) {
+                console.error(response);
             });
         }
 
         Ext.apply(me, {
             remoteConfig: me.remoteConfig,
+            items:me._baseItems,
             dockedItems: [{
                 xtype: 'toolbar',
                 dock: 'top',
@@ -65,7 +67,7 @@ Ext.define('saas.view.core.form.FormPanel', {
                     'border-bottom': '1px solid #35baf6 !important'
                 },
                 items: ['->'].concat(me.toolBtns.map(function(btn){
-                    btn.cls += ' x-formpanel-btn-blue';
+                    btn.cls = btn.cls ? btn.cls + ' x-formpanel-btn-blue':'x-formpanel-btn-blue';
                     return btn;
                 }).concat([{
                     cls:'x-formpanel-btn-orange',
@@ -76,6 +78,10 @@ Ext.define('saas.view.core.form.FormPanel', {
                     xtype: 'button',
                     text: '保存',
                     handler: 'save'
+                }, {
+                    xtype: 'button',
+                    text: '删除',
+                    handler: 'delete'
                 }, {
                     xtype: 'button',
                     text: '审核',
@@ -83,8 +89,6 @@ Ext.define('saas.view.core.form.FormPanel', {
                 }]))
             }]
         });
-        
-        me.remoteConfig && me.FormUtil.setItems(me);
         me.callParent(arguments);
     },
 

+ 153 - 3
frontend/saas-web/app/view/core/form/FormPanelController.js

@@ -2,10 +2,160 @@ Ext.define('saas.view.core.form.FormPanelController', {
     extend: 'Ext.app.ViewController',
     alias: 'controller.core-form-formpanel',
 
+    BaseUtil: Ext.create('saas.util.BaseUtil'),
     FormUtil: Ext.create('saas.util.FormUtil'),
 
-    add: Ext.emptyFn,
-    save: Ext.emptyFn,
-    audit: Ext.emptyFn,
+    add: function(btn){
+        var form = btn.ownerCt.ownerCt;
+        var mainTab = Ext.getCmp('main-tab-panel');
+        var title = '新增' + btn.ownerCt.ownerCt._title;
+        var id = form.xtype + '_add';
+        existingItem = mainTab.down('[id=' + id + ']');
 
+        lastView = mainTab.getActiveTab();
+
+        if (!existingItem) {
+            var form = {
+                id,
+                title,
+                xtype:form.xtype
+            };
+            mainTab.setActiveTab(mainTab.add(form));
+        }else{
+            mainTab.setActiveTab(existingItem);
+        }
+    },
+    
+    delete: function(btn){
+        var form = btn.ownerCt.ownerCt;
+        var id = form.getForm().findField(form._idField);
+        if(id&&id.value!=0){
+            Ext.Ajax.request({
+                url: form._deleteUrl,
+                params: {
+                    id:id.value
+                },
+                method: 'POST',
+                data:{_method:"DELETE"},
+                headers: {
+                    'Access-Control-Allow-Origin': '*',
+                    "Content-Type": 'application/json;charset=UTF-8' 
+                },
+                success: function (response, opts) {
+                    //解析参数
+                    Ext.Msg.alert('提示','删除成功');
+                },
+                failure: function (response, opts) {
+                    //失败
+                    Ext.Msg.alert('提示','删除失败');
+                }
+            });
+        }
+    },
+
+    save:function(btn){
+        var me = this;
+        var form = btn.ownerCt.ownerCt;
+        if(form.getForm().wasDirty==false){
+            Ext.Msg.alert('提示','未修改数据,请修改后保存');
+            return false;
+        }
+        if(form.getForm().wasValid==false){
+            Ext.Msg.alert('提示','表单校验有误,请检查');
+            return false;
+        }
+        //form里面数据
+        var formData = form.viewModel.data;
+        var gridData = [];
+        var newGridData = [];
+        if(formData.detailGridField){
+            gridData = formData.detailGridField;
+        }
+        var grid = form.query('detailGridField')[0];
+        var updRecords = grid.store.getUpdatedRecords();
+        if(updRecords.length>0){
+            Ext.each(updRecords, function(rec){
+                Ext.each(gridData, function(data,index){
+                    if(data.id==rec.id){
+                        if(data.id.indexOf('extMode')>-1){
+                            data.id = '';
+                            data[form._detnoColumn] = index + 1;
+                        }
+                        newGridData.push(data);
+                    }
+                });
+            });
+        }   
+        var params = {
+            main:formData,
+            items:newGridData
+        }
+        me.BaseUtil.request({
+            url: form._saveUrl,
+            params: JSON.stringify(params),
+            method: 'POST',
+        })
+        .then(function() {
+            Ext.Msg.alert('提示','保存成功');
+        })
+        .catch(function() {
+            Ext.Msg.alert('提示','保存失败');
+        });
+    },
+    audit: function(btn){
+        var form = btn.ownerCt.ownerCt;
+        if(form.getForm().wasValid==false){
+            Ext.Msg.alert('提示','表单校验有误,请检查');
+            return false;
+        }
+        //form里面数据
+        var formData = form.viewModel.data;
+        var gridData = [];
+        var newGridData = [];
+        if(formData.detailGridField){
+            gridData = formData.detailGridField;
+        }
+        var grid = form.query('detailGridField')[0];
+        var updRecords = grid.store.getUpdatedRecords();
+        if(updRecords.length>0){
+            Ext.each(updRecords, function(rec){
+                Ext.each(gridData, function(data,index){
+                    if(data.id==rec.id){
+                        if(data.id.indexOf('extMode')>-1){
+                            data.id = '';
+                            data[form._detnoColumn] = index + 1;
+                        }
+                        newGridData.push(data);
+                    }
+                });
+            });
+        }   
+        var params = {
+            main:formData,
+            items:newGridData
+        }
+        Ext.Ajax.request({
+            url: form._auditUrl,
+            params: JSON.stringify(params),
+            method: 'POST',
+            headers: {
+                'Access-Control-Allow-Origin': '*',
+                "Content-Type": 'application/json;charset=UTF-8' 
+            },
+            success: function (response, opts) {
+                //解析参数
+                Ext.Msg.alert('提示','审核成功');
+            },
+            failure: function (response, opts) {
+                //失败
+                Ext.Msg.alert('提示','审核失败');
+            }
+        });
+    },
+    /**
+     * 获取form数据
+     */
+    getFormData: function() {
+        
+    }
 });

+ 60 - 24
frontend/saas-web/app/view/core/form/field/DetailGridField.js

@@ -7,6 +7,7 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
     border: 1,
     margin: '0 5 5 0', // formpanel的fieldDefaults未生效
     height: 300,
+    columnWidth : 1.0, 
 
     requires: [
         'Ext.selection.CellModel'
@@ -17,15 +18,10 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
     },
     plugins: {
         cellediting: {
-            clicksToEdit: 1
+            clicksToEdit: 2
         }
     },
 
-
-    store: {
-        data: []
-    },
-
     showIndex: true,
     configUrl: '',
 
@@ -37,16 +33,30 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
                 dock: 'bottom',
                 items: [{
                     iconCls: 'x-fa fa-plus-circle',
-                    handler: me.addDetail
+                    handler: function() {
+                        me.addDetail();
+                    }
                 }, {
                     iconCls: 'x-fa fa-trash',
-                    handler: me.deleteDetail
+                    handler: function() {
+                        me.deleteDetail();
+                    }
                 }, {
                     iconCls: 'x-fa fa-arrow-up',
-                    handler: me.swapUp
+                    handler: function() {
+                        me.swapUp();
+                    }
                 }, {
                     iconCls: 'x-fa fa-arrow-down',
-                    handler: me.swapDown
+                    handler: function() {
+                        me.swapDown();
+                    }
+                }, {
+                    text: 'Debugger',
+                    handler: function() {
+                        var detailGrid = me;
+                        debugger;
+                    }
                 }]
             }]
         });
@@ -54,8 +64,9 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
     },
 
     listeners: {
-        afterrender: function(grid) {
-            if(grid.store.count()==0){
+        afterrender:function(grid){
+            var count = grid.store.getCount();
+            if(count==0){
                 grid.add10EmptyRow();
             }
         },
@@ -83,31 +94,56 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
     },
 
     addDetail: function() {
-        var grid = this.up('grid'),
-            store = grid.getStore(),
-            selectedRecord = grid.selModel.lastSelected;
+        var me = this,
+            store = me.getStore(),
+            selectedRecord = me.selModel.lastSelected;
 
         store.insert(store.indexOf(selectedRecord) + 1, {});
     },
 
     deleteDetail: function() {
-        var grid = this.up('grid'),
-            store = grid.getStore(),
-            selectedRecord = grid.selModel.lastSelected;
+        var me = this,
+            store = me.getStore(),
+            selectedRecord = me.selModel.lastSelected;
 
         store.remove(selectedRecord);
     },
 
     swapUp: function() {
-        var grid = this.up('grid'),
-            store = grid.getStore(),
-            record = grid.selModel.lastSelected,
-            selectedIdx = store.indexOf(record),
-            to = store.getAt(selectedIdx - 1);
-
+        var me = this,
+            store = me.getStore(),
+            record = me.selModel.lastSelected,
+            selectedIdx = store.indexOf(record);
+            
+            me.swap(record, selectedIdx, -1);
     },
 
     swapDown: function() {
+        var me = this,
+        store = me.getStore(),
+        record = me.selModel.lastSelected,
+        selectedIdx = store.indexOf(record);
+        
+        me.swap(record, selectedIdx, 1);
+    },
 
+    swap: function(from, index, dir) {
+        var me = this,
+        store = me.getStore(),
+        to = store.getAt(index + dir);
+
+        if(from && to) {
+            var keys = me.getColumns().map(function(c) { return c.dataIndex }),
+            data = from.getData(),
+            toData = to.getData();
+
+            Ext.each(keys, function(key, index) {
+                to.set(key, null);
+                from.set(key, toData[key]);
+                to.set(key, data[key]);
+            });
+            //聚焦目标行
+            me.selModel.select(to);
+        }
     }
 });

+ 20 - 0
frontend/saas-web/app/view/main/Main.scss

@@ -106,3 +106,23 @@ $treelist-nav-ui: (
 .x-html-editor-input {
     border: 1px solid #ccc;
 }
+
+.x-btn-default-toolbar-small{
+    border-radius: 5px !important;
+}
+
+.x-formpanel-btn-orange {
+    background: linear-gradient(to bottom,#da7101 0,#f67f00 100%) !important;
+}
+
+.x-formpanel-btn-orange .x-btn-inner-default-toolbar-small{
+    color:#fff !important;
+}
+
+.x-formpanel-btn-blue {
+    background: linear-gradient(to bottom,#3876c3 0,#346fb9 100%) !important;
+}
+
+.x-formpanel-btn-blue .x-btn-inner-default-toolbar-small{
+    color:#fff !important;
+}

+ 80 - 53
frontend/saas-web/app/view/test/order/FormController.js

@@ -12,72 +12,101 @@ Ext.define('saas.view.test.order.FormController', {
                 }
             },
             //放大镜赋值关系 以及 tpl模板
-            'dbfindtrigger[name=pu_vendorcode]':{
+            'dbfindtrigger[name=puVendcode]':{
                 beforerender:function(f){
                     Ext.apply(f,{
+                        conditionCode:'ve_code',
+                        dataUrl:'http://192.168.253.41:8800/purchase/component/dbfind/vendor',
                         dbfinds:[{
-                            from:'pu_vendorcode',to:'pu_vendorcode'
+                            from:'vendCode',to:'puVendcode'
                         },{
-                            from:'pu_vendorname',to:'pu_vendorname'
+                            from:'vendName',to:'puVendname'
                         }],
                         dbtpls:[{
-                            field:'pu_vendorcode',width:100
+                            field:'vendCode',width:100
                         },{
-                            field:'pu_vendorname',width:100
+                            field:'vendName',width:100
+                        }],
+                        dbColumns:[{
+                            "text": "供应商ID",
+                            "flex": 0,
+                            "dataIndex": "vendId",
+                            "width": 0,
+                            "xtype": "",
+                            "items": null
+                        },{
+                            "text": "供应商编号",
+                            "flex": 1,
+                            "dataIndex": "vendCode",
+                            "width": 100,
+                            "xtype": "",
+                            "items": null
+                        }, {
+                            "text": "供应商名称",
+                            "flex": 1,
+                            "dataIndex": "vendName",
+                            "xtype": "",
+                            "items": null
+                        }, {
+                            "text": "供应商类型",
+                            "flex": 0,
+                            "dataIndex": "vendType",
+                            "width": 200,
+                            "xtype": "",
+                            "items": null
                         }]
                     }) ;   
 
                 }
-            }
-        });
+            },
+            //放大镜赋值关系 以及 tpl模板
+            'dbfindtrigger[name=pdProdcode]':{
+                beforerender:function(f){
+                    Ext.apply(f,{
+                        conditionCode:'pr_code',
+                        dataUrl:'http://192.168.253.41:8800/purchase/component/dbfind/product',
+                        dbfinds:[{
+                            from:'pr_code',to:'pdVendcode'
+                        }],
+                        dbtpls:[{
+                            field:'pr_code',width:100
+                        },{
+                            field:'pr_detail',width:100
+                        }],
+                        dbColumns:[{
+                            "text": "物料ID",
+                            "flex": 0,
+                            "dataIndex": "pr_id",
+                            "width": 0,
+                            "xtype": "",
+                            "items": null
+                        },{
+                            "text": "物料编号",
+                            "flex": 1,
+                            "dataIndex": "pr_code",
+                            "width": 100,
+                            "xtype": "",
+                            "items": null
+                        }, {
+                            "text": "物料名称",
+                            "flex": 1,
+                            "dataIndex": "pr_detail",
+                            "xtype": "",
+                            "items": null
+                        }, {
+                            "text": "物料规格",
+                            "flex": 0,
+                            "dataIndex": "pr_spec",
+                            "width": 200,
+                            "xtype": "",
+                            "items": null
+                        }]
+                    }) ;   
 
-    },
-    save:function(btn){
-        var form = btn.ownerCt.ownerCt;
-        if(form.getForm().wasDirty==false){
-            Ext.Msg.alert('提示','未修改数据,请修改后保存');
-            return false;
-        }
-        if(form.getForm().wasValid==false){
-            Ext.Msg.alert('提示','表单校验有误,请检查');
-            return false;
-        }
-        //form里面数据
-        Ext.each(form.items.items, function(item){
-            if(item.xtype == 'numberfield'){
-                //number类型赋默认值,不然sql无法执行
-                if(item.value == null || item.value == ''){
-                    item.setValue(0);
                 }
             }
         });
-        var r = form.getValues();
-        var keys = Ext.Object.getKeys(r), f;
-        var reg = /[!@#$%^&*()'":,\/?]|[\t|\n|\r]/g;
-        Ext.each(keys, function(k){
-            r[k] = r[k].trim().replace(reg, '');           	
-        });
-        var formData = {
-            main:r,
-            items:[{}]          
-        };
-        var params = {};
-        params.formData = formData;   
-        Ext.Ajax.request({
-            url: 'http://192.168.253.58:8800/purchase/form',
-            params: JSON.stringify(params),
-            method: 'POST',
-            headers: {
-                'Access-Control-Allow-Origin': '*',
-                "Content-Type": 'application/json;charset=UTF-8' 
-            },
-            success: function (response, opts) {
-                debugger
-            },
-            failure: function (response, opts) {
-                debugger
-            }
-        });
+
     },
     addCombo:function(){
         var combo=this.ownerCmp;
@@ -103,6 +132,4 @@ Ext.define('saas.view.test.order.FormController', {
         }).show();
 
     }
-
-
 });

+ 179 - 2
frontend/saas-web/app/view/test/order/FormPanel.js

@@ -5,10 +5,16 @@ Ext.define('saas.view.test.order.FormPanel', {
     controller: 'test-order-formcontroller',
     viewModel: 'test-order-formmodel',
     
+    _title:'采购单',
     _codeField: 'puCode',
     _statusField: 'puStatuscode',
-    _idField: 'puId',
-    initId : 11,
+    _idField: 'id',
+    _detnoColumn:  'pdDetno',
+    _dataModelUrl:'http://192.168.253.58:8800/purchase/form?id={id}',
+    _saveUrl:'http://192.168.253.58:8800/purchase/form',
+    _auditUrl:'http://192.168.253.58:8800/purchase/audit',
+    _deleteUrl:'http://192.168.253.58:8800/purchase/detele',
+    initId:0,
 
     toolBtns: [{
         xtype: 'button',
@@ -16,5 +22,176 @@ Ext.define('saas.view.test.order.FormPanel', {
         handler: function() {
             console.log('11');
         }
+    }],
+
+    defaultItems: [{
+        xtype: 'hidden',
+        name: 'id',
+        bind: '{id}',
+        fieldLabel: 'id',
+        allowBlank: true,
+        columnWidth: 0
+    }, {
+        xtype : "textfield", 
+        name : "puCode", 
+        bind : "{puCode}", 
+        fieldLabel : "采购单号", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "datefield", 
+        name : "puDate", 
+        bind : "{puDate}", 
+        fieldLabel : "采购日期", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "hidden", 
+        name : "puVendid", 
+        bind : "{puVendid}", 
+        fieldLabel : "供应商ID", 
+        allowBlank : true, 
+        columnWidth : 0.0
+    }, {
+        xtype : "dbfindtrigger", 
+        name : "puVendcode", 
+        bind : "{puVendcode}", 
+        fieldLabel : "供应商编号", 
+        allowBlank : true, 
+        columnWidth : 0.25, 
+    }, {
+        xtype : "textfield", 
+        name : "puVendname", 
+        bind : "{puVendname}", 
+        fieldLabel : "供应商名称", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "hidden", 
+        name : "puBuyerid", 
+        bind : "{puBuyerid}", 
+        fieldLabel : "采购员ID", 
+        allowBlank : true, 
+        columnWidth : 0.0
+    }, {
+        xtype : "dbfindtrigger", 
+        name : "puBuyercode", 
+        bind : "{puBuyercode}", 
+        fieldLabel : "采购员编号", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "textfield", 
+        name : "puBuyername", 
+        bind : "{puBuyername}", 
+        fieldLabel : "采购员名称", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        name : "detailGridField", 
+        xtype : "detailGridField", 
+        columns : [
+            {
+                text : "序号", 
+                dataIndex : "pdDetno", 
+                width : 80.0, 
+                xtype : "rownumberer"
+            }, 
+            {
+                editor : {
+                    displayField : "display", 
+                    editable : true, 
+                    format : "", 
+                    hideTrigger : false, 
+                    maxLength : 100.0, 
+                    minValue : null, 
+                    positiveNum : false, 
+                    queryMode : "local", 
+                    store : null, 
+                    valueField : "value", 
+                    xtype : "dbfindtrigger"
+                }, 
+                text : "物料编号", 
+                width : 200.0, 
+                dataIndex : "pdProdcode", 
+                xtype : "", 
+                items : null
+            }, 
+            {
+                text : "单位", 
+                editor : {
+                    xtype : "textfield"
+                }, 
+                dataIndex : "pdUnit", 
+                width : 120.0, 
+                xtype : "", 
+                items : null
+            }, 
+            {
+                text : "数量", 
+                dataIndex : "pdQty", 
+                width : 120.0, 
+                xtype : "", 
+                items : null
+            }, 
+            {
+                text : "单价", 
+                dataIndex : "pdPrice", 
+                width : 120.0, 
+                xtype : "numbercolumn", 
+                items : null
+            }, 
+            {
+                text : "总额", 
+                dataIndex : "pdTotal", 
+                width : 120.0, 
+                xtype : "numbercolumn"
+            }, 
+            {
+                text : "税额", 
+                dataIndex : "pdTaxtotal", 
+                flex : 1.0, 
+                xtype : "numbercolumn"
+            }, 
+            {
+                text : "id", 
+                dataIndex : "id", 
+                flex : 1.0, 
+                xtype : "numbercolumn"
+            }
+        ]
+    }, {
+        format : "Y-m-d", 
+        xtype : "datetimefield", 
+        name : "createTime", 
+        bind : "{createTime}", 
+        fieldLabel : "创建时间", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "datefield", 
+        name : "updateTime", 
+        bind : "{updateTime}", 
+        fieldLabel : "更新时间", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "textfield", 
+        readOnly : true, 
+        editable : false, 
+        name : "puStatus", 
+        bind : "{puStatus}", 
+        fieldLabel : "单据状态", 
+        allowBlank : true, 
+        columnWidth : 0.25
+    }, {
+        xtype : "hidden", 
+        readOnly : true, 
+        editable : false, 
+        name : "puStatuscode", 
+        bind : "{puStatuscode}", 
+        fieldLabel : "单据状态码", 
+        allowBlank : true, 
+        columnWidth : 0.0
     }]
 });

+ 6 - 1
pom.xml

@@ -16,7 +16,7 @@
     <groupId>com.usoftchina.saas</groupId>
     <artifactId>saas-platform</artifactId>
     <packaging>pom</packaging>
-    <version>${project.release.version}</version>
+    <version>1.0.0-SNAPSHOT</version>
     <description>saas framework parent</description>
 
     <properties>
@@ -190,6 +190,11 @@
                 <artifactId>core</artifactId>
                 <version>${project.release.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.usoftchina.saas</groupId>
+                <artifactId>server-starter</artifactId>
+                <version>${project.release.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.usoftchina.saas</groupId>
                 <artifactId>file-dto</artifactId>