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

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

jinsy 7 лет назад
Родитель
Сommit
3d4b2ca85c
98 измененных файлов с 1930 добавлено и 166 удалено
  1. 10 7
      README.md
  2. 4 0
      applications/commons/commons-dto/src/main/java/com/usoftchina/saas/commons/exception/BizExceptionCode.java
  3. 4 0
      applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/mapper/EndProductMapper.java
  4. 8 0
      applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/service/impl/EndProductServiceImpl.java
  5. 1 1
      applications/commons/commons-server/src/main/resources/application.yml
  6. 9 0
      applications/commons/commons-server/src/main/resources/logback-spring.xml
  7. 86 0
      applications/commons/commons-server/src/main/resources/mapper/EndProductMapper.xml
  8. 12 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/CustomerController.java
  9. 6 2
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/CustomerMapper.java
  10. 3 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/EmployeeMapper.java
  11. 3 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/CustomerService.java
  12. 8 2
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/CustomerServiceImpl.java
  13. 22 9
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/EmployeeServiceImpl.java
  14. 2 2
      applications/document/document-server/src/main/resources/application.yml
  15. 9 0
      applications/document/document-server/src/main/resources/logback-spring.xml
  16. 5 0
      applications/document/document-server/src/main/resources/mapper/CustomerMapper.xml
  17. 8 0
      applications/document/document-server/src/main/resources/mapper/EmployeeMapper.xml
  18. 8 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/mapper/SubledgerMapper.java
  19. 45 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/PaybalanceServiceImpl.java
  20. 39 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/RecbalanceServiceImpl.java
  21. 96 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java
  22. 5 2
      applications/money/money-server/src/main/resources/application.yml
  23. 9 0
      applications/money/money-server/src/main/resources/logback-spring.xml
  24. 16 0
      applications/money/money-server/src/main/resources/mapper/SubledgerMapper.xml
  25. 1 1
      applications/purchase/purchase-server/src/main/resources/application.yml
  26. 9 0
      applications/purchase/purchase-server/src/main/resources/logback-spring.xml
  27. 1 1
      applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/service/impl/SaleServiceImpl.java
  28. 1 1
      applications/sale/sale-server/src/main/resources/application.yml
  29. 9 0
      applications/sale/sale-server/src/main/resources/logback-spring.xml
  30. 2 1
      applications/storage/storage-server/src/main/java/com/usoftchina/saas/storage/service/impl/MakeServiceImpl.java
  31. 1 1
      applications/storage/storage-server/src/main/resources/application.yml
  32. 9 0
      applications/storage/storage-server/src/main/resources/logback-spring.xml
  33. 3 3
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyRspDTO.java
  34. 4 4
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java
  35. 8 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java
  36. 8 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java
  37. 1 1
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountCenterServiceImpl.java
  38. 5 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java
  39. 2 2
      base-servers/account/account-server/src/main/resources/application.yml
  40. 9 0
      base-servers/account/account-server/src/main/resources/logback-spring.xml
  41. 2 2
      base-servers/account/account-server/src/main/resources/mapper/AccountCompanyMapper.xml
  42. 3 0
      base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml
  43. 2 2
      base-servers/account/account-server/src/main/resources/mapper/AccountRoleMapper.xml
  44. 1 1
      base-servers/account/account-server/src/main/resources/mapper/RoleMapper.xml
  45. 4 2
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/api/AccountCacheTest.java
  46. 9 0
      base-servers/admin-server/src/main/resources/logback-spring.xml
  47. 4 0
      base-servers/auth/auth-api/pom.xml
  48. 10 0
      base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/AuthApi.java
  49. 6 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtToken.java
  50. 1 1
      base-servers/auth/auth-common/src/test/java/com/usoftchina/saas/auth/common/jwt/JwtHelperTest.java
  51. 29 0
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/config/CookieConfig.java
  52. 68 1
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java
  53. 6 3
      base-servers/auth/auth-server/src/main/resources/application.yml
  54. 9 0
      base-servers/auth/auth-server/src/main/resources/logback-spring.xml
  55. 9 0
      base-servers/eureka-server/src/main/resources/logback-spring.xml
  56. 2 2
      base-servers/file/file-server/src/main/resources/application.yml
  57. 9 0
      base-servers/file/file-server/src/main/resources/logback-spring.xml
  58. 49 4
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AuthFilter.java
  59. 29 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/CookieConfig.java
  60. 4 1
      base-servers/gateway-server/src/main/resources/application.yml
  61. 9 0
      base-servers/gateway-server/src/main/resources/logback-spring.xml
  62. 2 2
      base-servers/mail/mail-server/src/main/resources/application.yml
  63. 9 0
      base-servers/mail/mail-server/src/main/resources/logback-spring.xml
  64. 1 1
      base-servers/socket/socket-server/src/main/resources/application.yml
  65. 9 0
      base-servers/socket/socket-server/src/main/resources/logback-spring.xml
  66. 1 1
      base-servers/ui-server/src/main/resources/application.yml
  67. 9 0
      base-servers/ui-server/src/main/resources/logback-spring.xml
  68. 8 0
      base-servers/zipkin-server/src/main/resources/logback-spring.xml
  69. 3 0
      frontend/saas-web/app.json
  70. 8 7
      frontend/saas-web/app/Application.scss
  71. 2 0
      frontend/saas-web/app/util/FormUtil.js
  72. 21 0
      frontend/saas-web/app/view/core/base/BasePanel.js
  73. 1 0
      frontend/saas-web/app/view/core/base/GridPanel.js
  74. 1 1
      frontend/saas-web/app/view/core/form/FormPanel.js
  75. 8 35
      frontend/saas-web/app/view/core/query/QueryGridPanel.js
  76. 1 21
      frontend/saas-web/app/view/core/query/QueryPanel.js
  77. 8 1
      frontend/saas-web/app/view/document/bom/FormPanel.js
  78. 1 1
      frontend/saas-web/app/view/document/customer/FormPanel.js
  79. 9 0
      frontend/saas-web/app/view/document/product/FormController.js
  80. 2 12
      frontend/saas-web/app/view/document/product/FormModel.js
  81. 4 1
      frontend/saas-web/app/view/document/product/FormPanel.js
  82. 7 16
      frontend/saas-web/app/view/home/InfoCard.js
  83. 6 1
      frontend/saas-web/app/view/home/charts/MonthPurchase.js
  84. 212 0
      frontend/saas-web/app/view/home/infoCardList/InfoList.js
  85. 14 0
      frontend/saas-web/app/view/home/infoCardList/InfoList.scss
  86. 130 0
      frontend/saas-web/app/view/home/infoCardList/Payment.js
  87. 118 0
      frontend/saas-web/app/view/home/infoCardList/PurchaseIn.js
  88. 139 0
      frontend/saas-web/app/view/home/infoCardList/Recment.js
  89. 118 0
      frontend/saas-web/app/view/home/infoCardList/SaleOut.js
  90. 130 0
      frontend/saas-web/app/view/home/infoCardList/UnauditCheckIn.js
  91. 139 0
      frontend/saas-web/app/view/home/infoCardList/UnauditSaleOut.js
  92. 1 1
      frontend/saas-web/app/view/main/Main.js
  93. 6 1
      frontend/saas-web/app/view/sale/sale/QueryPanel.js
  94. 26 1
      frontend/saas-web/app/view/stock/make/FormPanel.js
  95. 2 0
      frontend/saas-web/app/view/stock/make/FormPanelController.js
  96. 1 1
      frontend/saas-web/app/view/sys/finish/DataList.js
  97. 8 3
      frontend/saas-web/app/view/viewport/ViewportController.js
  98. 9 0
      frontend/saas-web/index.html

+ 10 - 7
README.md

@@ -81,31 +81,34 @@
 
 | 数据库      | 类型   | 地址   |  账号  |  密码  |  说明  |
 | --------   | :-----: | :-----:  | :----:  | :----: | :------  |
-| saas_account | mysql | 192.168.253.12:3306 |  root  | select111*** |  账户中心  |
-| saas_auth | mysql | 192.168.253.12:3306 |  root  | select111*** |  鉴权系统  |
-| saas_file | mysql | 192.168.253.12:3306 |  root  | select111*** |  文件系统  |
-| saas_mail | mysql | 192.168.253.12:3306 |  root  | select111*** |  邮件系统  |
-| saas_biz | mysql | 192.168.253.12:3306 |  root  | select111*** |  业务系统  |
-| saas_ui | mongo | 192.168.253.12:27017 |    |  |  UI配置  |
+| saas_account | mysql | 192.168.0.172:3306 |  root  | select111*** |  账户中心  |
+| saas_auth | mysql | 192.168.0.172:3306 |  root  | select111*** |  鉴权系统  |
+| saas_file | mysql | 192.168.0.172:3306 |  root  | select111*** |  文件系统  |
+| saas_mail | mysql | 192.168.0.172:3306 |  root  | select111*** |  邮件系统  |
+| saas_biz | mysql | 192.168.0.172:3306 |  root  | select111*** |  业务系统  |
+| saas_ui | mongo | 192.168.0.183:27017 |    |  |  UI配置  |
 
 > 中间件
 
 | 类型 | 地址 | 账号 | 密码 | 说明 |
 | ---- | :----: | :----: | :----: | ---- |
 | rabbitmq | 192.168.0.176:5672 | saas | select123*** | 消息中间件 [控制台](http://192.168.0.176:15672)|
-| redis | 192.168.253.12:6379 | | | 内存数据库 |
+| redis | 192.168.0.182:6379 | | | 内存数据库 |
 
 
 > 服务器
 
 | IP      |  账号  |  密码  |  环境  |  资源  |
 | --------   | :----:  | :----: | :------:  | :------:  |
+| 192.168.0.172 |  root  | select123*** |  CentOS7, MySQL  | Cpu: 8, Mem: 16G, Disk: 80G |
 | 192.168.0.176 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 20G |
 | 192.168.0.177 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 20G |
 | 192.168.0.178 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 20G |
 | 192.168.0.179 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 20G |
 | 192.168.0.180 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 20G |
 | 192.168.0.181 |  root  | select123*** |  CentOS7, Docker  | Cpu: 4, Mem: 8G, Disk: 80G |
+| 192.168.0.182 |  root  | select123*** |  CentOS7, Redis  | Cpu: 2, Mem: 8G, Disk: 20G |
+| 192.168.0.183 |  root  | select123*** |  CentOS7, Mongo  | Cpu: 4, Mem: 8G, Disk: 50G |
 
 > 构建
 

+ 4 - 0
applications/commons/commons-dto/src/main/java/com/usoftchina/saas/commons/exception/BizExceptionCode.java

@@ -41,6 +41,7 @@ public enum BizExceptionCode implements BaseExceptionCode {
     REPEAT_CODE(79502, "编号重复"),
     REPEAT_CUSTOMERCODE(79503, "客户名称或编号重复"),
     REPEAT_TEL(79504, "电话号码重复"),
+    REPEAT_EMNAMECODE(79505, "姓名或编号重复"),
     NO_DATA(79998, "未找到数据"),
     ILLEGAL_ID(79999, "id不正确"),
     PRODUCT_HAS_WAREHOUSE(79502, "存在物料默认仓库资料为该仓库,无法删除"),
@@ -94,6 +95,9 @@ public enum BizExceptionCode implements BaseExceptionCode {
     DOCUMENTS_UNAUDITED(74010,"存在未审核单据:%S"),
     BANK_AMOUNT_NOTENOUGHS(74011, "资金账号不足:%S"),
 
+    //反结账
+    EARLY_USERING(74012, "期初余额被使用,无法反结账"),
+
 
 
     //库存

+ 4 - 0
applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/mapper/EndProductMapper.java

@@ -17,4 +17,8 @@ public interface EndProductMapper {
     List<MessagelogDTO> getListData(@Param("condition") String condition, @Param("companyId") Long companyId);
 
     void updatePeriodStatus(@Param("status") Long status,@Param("period") String period, @Param("companyId") Long companyId);
+
+    int checkPay(Long companyId);
+    int checkRec(Long companyId);
+    void deleteSub(Long companyId);
 }

+ 8 - 0
applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/service/impl/EndProductServiceImpl.java

@@ -58,6 +58,7 @@ public class EndProductServiceImpl implements EndProductService {
     @Override
     public String endAccount() {
         String period = endProductMapper.selectPeriod(BaseContextHolder.getCompanyId());
+
         Map<String, Object> map = new HashMap<String, Object>();
         map.put("yearMonth", period);
         map.put("companyId", BaseContextHolder.getCompanyId());
@@ -71,6 +72,13 @@ public class EndProductServiceImpl implements EndProductService {
 
     @Override
     public void unEndAccount() {
+        int payc = endProductMapper.checkPay(BaseContextHolder.getCompanyId());
+        int recc = endProductMapper.checkRec(BaseContextHolder.getCompanyId());
+        if(payc !=0 || recc != 0){
+            throw new BizException(500, BizExceptionCode.EARLY_USERING.getMessage());
+        }
+        endProductMapper.deleteSub(BaseContextHolder.getCompanyId());
+
         String period = endProductMapper.selectUnPeriod(BaseContextHolder.getCompanyId());
         if (StringUtils.isEmpty(period)){
             throw new BizException(BizExceptionCode.BIZ_UNENDPRODUCT);

+ 1 - 1
applications/commons/commons-server/src/main/resources/application.yml

@@ -7,7 +7,7 @@ spring:
       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&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:

+ 9 - 0
applications/commons/commons-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 86 - 0
applications/commons/commons-server/src/main/resources/mapper/EndProductMapper.xml

@@ -31,4 +31,90 @@
     <update id="updatePeriodStatus" >
         update periodsdetail set pd_status=#{status} where pd_detno=#{period} and companyId=#{companyId}
     </update>
+
+    <select id="checkPay" parameterType="java.lang.Long" resultType="java.lang.Integer">
+        select count(1) from vendor where (ve_id,companyid) in (select pb_vendid,companyid from (
+        select pbd_ym,pb_vendid,paybalance.companyid from paybalance,paybalancedetail where pb_id=pbd_pbid and pbd_slkind='期初余额'
+        union all select vd_ym,vc_vendid,verification.companyid from verification,verificationdet where vc_id=vd_vcid and vd_slkind='期初余额'
+        and ifnull(vc_vendid,0)!=0
+        union all select vcd_ym,vc_vendid,verification.companyid from verification,verificationdetail where vc_id=vcd_vcid and vcd_slkind='期初余额' and ifnull(vc_vendid,0)!=0
+        union all select vd_ym,vc_turnvendid,verification.companyid from verification,verificationdet where vc_id=vd_vcid and vd_slkind='期初余额' and ifnull(vc_turnvendid,0)!=0
+        )a where a.pbd_ym =(select min(pd_detno) from periodsdetail where pd_status=0 and companyId = #{companyId} )) ;
+    </select>
+
+    <select id="checkRec" parameterType="java.lang.Long" resultType="java.lang.Integer">
+        SELECT
+        count(1)
+        FROM
+        customer
+        WHERE
+        (cu_id, companyid) IN (
+        SELECT
+        rb_custid,
+        companyid
+        FROM
+        (
+        SELECT
+        rbd_ym,
+        rb_custid,
+        recbalance.companyid
+        FROM
+        recbalance,
+        recbalancedetail
+        WHERE
+        rb_id = rbd_rbid
+        AND rbd_slkind = '期初余额'
+        UNION ALL
+        SELECT
+        vd_ym,
+        vc_custid,
+        verification.companyid
+        FROM
+        verification,
+        verificationdet
+        WHERE
+        vc_id = vd_vcid
+        AND vd_slkind = '期初余额'
+        AND ifnull(vc_custid, 0) != 0
+        UNION ALL
+        SELECT
+        vcd_ym,
+        vc_custid,
+        verification.companyid
+        FROM
+        verification,
+        verificationdetail
+        WHERE
+        vc_id = vcd_vcid
+        AND vcd_slkind = '期初余额'
+        AND ifnull(vc_custid, 0) != 0
+        UNION ALL
+        SELECT
+        vd_ym,
+        vc_turncustid,
+        verification.companyid
+        FROM
+        verification,
+        verificationdet
+        WHERE
+        vc_id = vd_vcid
+        AND vd_slkind = '期初余额'
+        AND ifnull(vc_turncustid, 0) != 0
+        ) a
+        WHERE
+        a.rbd_ym = (
+        SELECT
+        min(pd_detno)
+        FROM
+        periodsdetail
+        WHERE
+        pd_status = 0 and companyid = #{companyId}
+        )
+        )
+    </select>
+
+    <delete id="deleteSub" parameterType="java.lang.Long" >
+    DELETE from subledger where sl_ym =
+    (select min(pd_detno) from periodsdetail where pd_status=0 and companyid=#{companyId}) and companyid = #{companyId}
+  </delete>
 </mapper>

+ 12 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/controller/CustomerController.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.document.controller;
 import com.github.pagehelper.PageInfo;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
+import com.usoftchina.saas.commons.dto.ComboDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
 import com.usoftchina.saas.document.dto.CustomerFormDTO;
@@ -12,6 +13,8 @@ import com.usoftchina.saas.page.PageRequest;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * Created by zdw
  * 2018-10-23 11:39.
@@ -101,6 +104,15 @@ public class CustomerController {
         return Result.success();
     }
 
+
+    @GetMapping("/getAddressCombo")
+    public Result getCombo(Long id){
+        List<ComboDTO> comboDTOList = customerService.getAddressCombo(id);
+        return Result.success(comboDTOList);
+    }
+
+
+
     /**
      * 客户资料批量删除
      *

+ 6 - 2
applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/CustomerMapper.java

@@ -1,9 +1,11 @@
 package com.usoftchina.saas.document.mapper;
 
 import com.usoftchina.saas.base.mapper.CommonBaseMapper;
+import com.usoftchina.saas.commons.dto.ComboDTO;
 import com.usoftchina.saas.document.entities.Customer;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
 import java.util.Map;
 
 public interface CustomerMapper extends CommonBaseMapper<Customer> {
@@ -24,13 +26,15 @@ public interface CustomerMapper extends CommonBaseMapper<Customer> {
     Integer validateCodeWhenUpdate(@Param("code") String code, @Param("id") Long id,
                                    @Param("companyId") Long companyId);
 
-    int validNameAndCodeWhenInsert(Customer record);
+    int validNameAndCodeWhenInsert(@Param("cu_code") String cu_code,@Param("cu_name") String cu_name,@Param("companyId") Long companyId);
 
-    int validNameAndCodeWhenUpdate(Customer record);
+    int validNameAndCodeWhenUpdate(@Param("cu_code") String cu_code,@Param("cu_name") String cu_name,@Param("id") Long cu_id,@Param("companyId") Long companyId);
 
     int validFinish(@Param("id") Long id,@Param("companyId") Long companyId);
 
     void check(Map<String, Object> map);
 
     int validNameAndCodeWhenRelated(Customer customer);
+
+    List<ComboDTO> getCombo(@Param("id") Long id,@Param("companyId") Long companyId);
 }

+ 3 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/EmployeeMapper.java

@@ -29,4 +29,7 @@ public interface EmployeeMapper extends CommonBaseMapper<Employee> {
     Integer validatePhoneWhenUpdate(@Param("phone") String phone, @Param("id") Long id, @Param("companyId") Long company);
 
 
+    Integer validateNameAndCodeWhenInsert(@Param("code") String code,@Param("name") String em_name,@Param("companyId") Long companyId);
+
+    Integer validateNameAndCodeWhenUpdate(@Param("code") String code,@Param("name") String em_name,@Param("id") Long em_id,@Param("companyId") Long id);
 }

+ 3 - 0
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/CustomerService.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.document.service;
 import com.github.pagehelper.PageInfo;
 import com.usoftchina.saas.base.service.CommonBaseService;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
+import com.usoftchina.saas.commons.dto.ComboDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
 import com.usoftchina.saas.document.dto.CustomerFormDTO;
@@ -41,4 +42,6 @@ public interface CustomerService extends CommonBaseService<CustomerMapper, Custo
     void batchOpen(BatchDealBaseDTO baseDTOs);
 
     PageInfo<CustomerList> getDbfind(PageRequest page, ListReqDTO listReqDTO);
+
+    List<ComboDTO> getAddressCombo(Long id);
 }

+ 8 - 2
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/CustomerServiceImpl.java

@@ -6,6 +6,7 @@ import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
 import com.usoftchina.saas.commons.api.MaxnumberService;
 import com.usoftchina.saas.commons.api.MessageLogService;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
+import com.usoftchina.saas.commons.dto.ComboDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
 import com.usoftchina.saas.commons.exception.BizExceptionCode;
@@ -160,7 +161,7 @@ public class CustomerServiceImpl extends CommonBaseServiceImpl<CustomerMapper, C
         //新增
         if (StringUtils.isEmpty(cu_id) || "0".equals(cu_id.toString())) {
             //检查名称和编号
-            int count = getMapper().validNameAndCodeWhenInsert(customer);
+            int count = getMapper().validNameAndCodeWhenInsert(cu_code,customer.getCu_name(),companyId);
             if (count>0) {
                 throw new BizException(BizExceptionCode.REPEAT_CUSTOMERCODE);
             }
@@ -197,7 +198,7 @@ public class CustomerServiceImpl extends CommonBaseServiceImpl<CustomerMapper, C
             //更新
         }else {
             //检查名称和编号
-            int count = getMapper().validNameAndCodeWhenUpdate(customer);
+            int count = getMapper().validNameAndCodeWhenUpdate(cu_code,customer.getCu_name(),customer.getId(),companyId);
             if (count > 0) {
                 throw new BizException(BizExceptionCode.REPEAT_CUSTOMERCODE);
             }
@@ -479,6 +480,11 @@ public class CustomerServiceImpl extends CommonBaseServiceImpl<CustomerMapper, C
         return pageInfo;
     }
 
+    @Override
+    public List<ComboDTO> getAddressCombo(Long id) {
+        return getMapper().getCombo(id,BaseContextHolder.getCompanyId());
+    }
+
 
     private List<CustomerList> getListByMode(ListReqDTO req) {
         List<CustomerList> list = null;

+ 22 - 9
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/EmployeeServiceImpl.java

@@ -65,29 +65,39 @@ public class EmployeeServiceImpl extends CommonBaseServiceImpl<EmployeeMapper, E
     @Override
     public DocBaseDTO saveFormData(Employee employee) {
         DocBaseDTO docBaseDTO = null;
+        String code = pushMaxnubmer(employee.getEm_code(), employee.getId());
         if(employee.getId() == 0){
-            String code = pushMaxnubmer(employee.getEm_code(), employee.getId());
-            employee.setCompanyId(BaseContextHolder.getCompanyId());
-            employee.setCreatorId(BaseContextHolder.getUserId());
-            employee.setCreateTime(new Date());
-            employee.setCreatorName(BaseContextHolder.getUserName());
+            //检查名称和编号
+            int count = getMapper().validateNameAndCodeWhenInsert(code,employee.getEm_name(),BaseContextHolder.getCompanyId());
+            if (count>0) {
+                throw new BizException(BizExceptionCode.REPEAT_EMNAMECODE);
+            }
             //检查电话号码
-            int count = getMapper().validatePhoneWhenInsert(employee.getEm_mobile(),BaseContextHolder.getCompanyId());
+            count = getMapper().validatePhoneWhenInsert(employee.getEm_mobile(),BaseContextHolder.getCompanyId());
             if (count>0) {
                 throw new BizException(BizExceptionCode.REPEAT_TEL);
             }
+            employee.setCompanyId(BaseContextHolder.getCompanyId());
+            employee.setCreatorId(BaseContextHolder.getUserId());
+            employee.setCreateTime(new Date());
+            employee.setCreatorName(BaseContextHolder.getUserName());
             getMapper().insertSelective(employee);
             docBaseDTO = generateMsgObj(employee.getId(), code);
             //记录LOG
             messageLogService.save(docBaseDTO);
         }else{
-            employee.setUpdaterId(BaseContextHolder.getUserId());
-            employee.setUpdateTime(new Date());
+            //检查名称和编号
+            int count = getMapper().validateNameAndCodeWhenUpdate(code,employee.getEm_name(),employee.getId(),BaseContextHolder.getCompanyId());
+            if (count>0) {
+                throw new BizException(BizExceptionCode.REPEAT_EMNAMECODE);
+            }
             //检查电话号码
-            int count = getMapper().validatePhoneWhenUpdate(employee.getEm_mobile(),employee.getId(),BaseContextHolder.getCompanyId());
+            count = getMapper().validatePhoneWhenUpdate(employee.getEm_mobile(),employee.getId(),BaseContextHolder.getCompanyId());
             if (count>0) {
                 throw new BizException(BizExceptionCode.REPEAT_TEL);
             }
+            employee.setUpdaterId(BaseContextHolder.getUserId());
+            employee.setUpdateTime(new Date());
             getMapper().updateByPrimaryKeySelective(employee);
             docBaseDTO = generateMsgObj(employee.getId(), employee.getEm_code());
             //记录LOG
@@ -199,6 +209,9 @@ public class EmployeeServiceImpl extends CommonBaseServiceImpl<EmployeeMapper, E
             Integer count = "0".equals(String.valueOf(id)) ? getMapper().validateCodeWhenInsert(code, companyId) :
                     getMapper().validateCodeWhenUpdate(code, id, companyId);
             em_code =  maxnumberService.pushMaxnubmer(count, code, BillCodeSeq.EMPLOYEE.getCaller()).getData();
+            if (em_code==null){
+                em_code = code;
+            }
         }
         return em_code;
     }

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

@@ -9,7 +9,7 @@ spring:
       password: select111***
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:
@@ -21,7 +21,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   rabbitmq:
     host: 192.168.0.176

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

@@ -104,4 +104,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 5 - 0
applications/document/document-server/src/main/resources/mapper/CustomerMapper.xml

@@ -393,4 +393,9 @@
   </select>
 
 
+  <select id="getCombo" resultType="com.usoftchina.saas.commons.dto.ComboDTO">
+    SELECT ca_address display,ca_address value FROM customeraddress WHERE ca_cuid=#{id} and COMPANYID=#{companyId} order by ca_id desc
+  </select>
+
+
 </mapper>

+ 8 - 0
applications/document/document-server/src/main/resources/mapper/EmployeeMapper.xml

@@ -236,4 +236,12 @@
   </select>
 
 
+  <select id="validateNameAndCodeWhenInsert" resultType="int">
+    select count(*) from Employee where (em_code = #{code} or em_name = #{name}) and companyId =#{companyId}
+  </select>
+  <select id="validateNameAndCodeWhenUpdate" resultType="int" >
+    select count(*) from Employee where (em_code = #{code} or em_name = #{name}) and em_id !=#{id} and companyId =#{companyId}
+  </select>
+
+
 </mapper>

+ 8 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/mapper/SubledgerMapper.java

@@ -24,4 +24,12 @@ public interface SubledgerMapper {
     int updateByPrimaryKey(Subledger record);
 
     List<Subledger> selectSubledgerBycondition(@Param("con") String con, @Param("companyId") Long companyId);
+
+    String selectPayView(@Param("companyid") Long companyid , @Param("code") String code , @Param("kind") String kind);
+
+    String selectRecView(@Param("companyid") Long companyid , @Param("code") String code , @Param("kind") String kind);
+
+
+    void updateProdInOut(@Param("companyid") Long companyid , @Param("code") String code , @Param("kind") String kind ,
+                         @Param("status") String status , @Param("statuscode") String statuscode);
 }

+ 45 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/PaybalanceServiceImpl.java

@@ -259,6 +259,9 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         for (Paybalancedetail detail: paybalancedetail) {
             Subledger subledger1 = new Subledger();
             Subledger nowSubledger = subledgerMapper.selectByPrimaryKey(detail.getPbd_slid());
+            if (nowSubledger == null){
+                throw new BizException(500, BizExceptionCode.SUBLEDGER_NOT_EXIS.getMessage());
+            }
             subledger1.setId(Long.valueOf(String.valueOf(detail.getPbd_slid())));
             Double yamount = nowSubledger.getSl_yamount()==null?new Double(0):nowSubledger.getSl_yamount();
             Double namount = nowSubledger.getSl_namount()==null?new Double(0):nowSubledger.getSl_namount();
@@ -282,6 +285,9 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         }else {
             statsinfoMapper.update(statsinfo);
         }
+        //更新出入库单据的付款状态
+        this.updateProdInoutStatus(id);
+
         DocBaseDTO baseDTO = getBaseDTOById(id);
 //        commonService.commonAudit(BillCodeSeq.PAYBALANCE.getCaller(),
 //                "pb_id="+baseDTO.getId(),"pb_status","pb_statuscode",
@@ -291,6 +297,39 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         return baseDTO;
     }
 
+    /**
+     * 根据来源单据更新出入库单据状态 C VC               N
+     * @param id
+     */
+    private void updateProdInoutStatus(Long id){
+        List<Paybalancedetail> list = paybalancedetailMapper.selectByPrimaryKey(Math.toIntExact(id));
+
+        if(list!=null && list.size()>0){
+            for (Paybalancedetail detail:list) {
+                String kind = detail.getPbd_slkind();
+                if(kind.equals("采购验收单") || kind.equals("采购验退单")) {
+                    String status = subledgerMapper.selectPayView(BaseContextHolder.getCompanyId(),detail.getPbd_slcode(),
+                            kind);
+                    String statuscode = "";
+                    if(status!=null){
+                        switch (status) {
+                            case  "已付款" :
+                                statuscode = Status.PAYALL.name();
+                            case "部分付款":
+                                statuscode = Status.PAYPART.name();
+                            default: statuscode = Status.PAYNONE.name();
+                        }
+                    }else{
+                        statuscode = "PAYNONE";
+                        status = "未付款";
+                    }
+                    subledgerMapper.updateProdInOut(BaseContextHolder.getCompanyId(),detail.getPbd_slcode(),
+                            kind,status,statuscode);
+                }
+            }
+        }
+    }
+
     @Override
     public void unAudit(int id) {
         //更新供应商资料
@@ -334,6 +373,9 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         for(Paybalancedetail detail: paybalancedetail) {
             Subledger subledger1 = new Subledger();
             Subledger nowSubledger = subledgerMapper.selectByPrimaryKey(detail.getPbd_slid());
+            if (nowSubledger == null){
+                throw new BizException(500, BizExceptionCode.SUBLEDGER_NOT_EXIS.getMessage());
+            }
             subledger1.setId(Long.valueOf(String.valueOf(detail.getPbd_slid())));
             Double yamount = nowSubledger.getSl_yamount()==null?new Double(0):nowSubledger.getSl_yamount();
             Double namount = nowSubledger.getSl_namount()==null?new Double(0):nowSubledger.getSl_namount();
@@ -370,6 +412,9 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         }else {
             statsinfoMapper.update(statsinfo);
         }
+
+        //更新出入库单据的付款状态
+        this.updateProdInoutStatus(Long.valueOf(id));
         DocBaseDTO baseDTO = getBaseDTOById(Long.valueOf(id));
         //日志记录
         messageLogService.unAudit(baseDTO);

+ 39 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/RecbalanceServiceImpl.java

@@ -325,6 +325,9 @@ public class RecbalanceServiceImpl extends CommonBaseServiceImpl<RecbalanceMappe
         }else {
             statsinfoMapper.update(statsinfo);
         }
+        //更新出入库单据的收款状态
+        this.updateProdInoutStatus(id);
+
         DocBaseDTO baseDTO = getBaseDTOById(id);
 //        commonService.commonAudit(BillCodeSeq.RECBALANCE.getCaller(),
 //                "rb_id="+baseDTO.getId(),"rb_status","rb_statuscode",
@@ -334,6 +337,39 @@ public class RecbalanceServiceImpl extends CommonBaseServiceImpl<RecbalanceMappe
         return baseDTO;
     }
 
+    /**
+     * 根据来源单据更新出入库单据状态 C VC               N
+     * @param id
+     */
+    private void updateProdInoutStatus(Long id){
+        List<Recbalancedetail> list = recbalancedetailMapper.selectByPrimaryKey(Math.toIntExact(id));
+
+        if(list!=null && list.size()>0){
+            for (Recbalancedetail detail:list) {
+                String kind = detail.getRbd_slkind();
+                if(kind.equals("出货单") || kind.equals("销售退货单")) {
+                    String status = subledgerMapper.selectRecView(BaseContextHolder.getCompanyId(),detail.getRbd_slcode(),
+                            kind);
+                    String statuscode = "";
+                    if(status!=null){
+                        switch (status) {
+                            case  "已收款" :
+                                statuscode = Status.RECALL.name();
+                            case "部分收款":
+                                statuscode = Status.RECPART.name();
+                            default: statuscode = Status.RECNONE.name();
+                        }
+                    }else{
+                        statuscode = "RECNONE";
+                        status = "未收款";
+                    }
+                    subledgerMapper.updateProdInOut(BaseContextHolder.getCompanyId(),detail.getRbd_slcode(),
+                            kind,status,statuscode);
+                }
+            }
+        }
+    }
+
     @Override
     public void unAudit(Long id) {
         //更新供应商资料
@@ -417,6 +453,9 @@ public class RecbalanceServiceImpl extends CommonBaseServiceImpl<RecbalanceMappe
         }else {
             statsinfoMapper.update(statsinfo);
         }
+        //更新出入库单据的收款状态
+        this.updateProdInoutStatus(id);
+
         DocBaseDTO baseDTO = getBaseDTOById(id);
         //日志记录
         messageLogService.unAudit(baseDTO);

+ 96 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java

@@ -367,6 +367,91 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
         }
     }
 
+    /**
+     * 根据来源单据更新出入库单据状态 C VC               N
+     * @param id
+     */
+    private void updateProdInoutStatus(Long id){
+        List<Verificationdet> list = verificationdetMapper.selectByFK(id);
+
+        List<Verificationdetail> list2 = verificationdetailMapper.selectByFK(id);
+        if(list!=null && list.size()>0){
+            for (Verificationdet detail:list) {
+                String kind = detail.getVd_slkind();
+                String status = subledgerMapper.selectPayView(BaseContextHolder.getCompanyId(),detail.getVd_slcode(),
+                        kind);
+                String statuscode = "";
+                if(kind.equals("采购验收单") || kind.equals("采购验退单")) {
+                    if(status!=null){
+                        switch (status) {
+                            case  "已付款" :
+                                statuscode = Status.PAYALL.name();
+                            case "部分付款":
+                                statuscode = Status.PAYPART.name();
+                            default: statuscode = Status.PAYNONE.name();
+                        }
+                    }else{
+                        statuscode = "PAYNONE";
+                        status = "未付款";
+                    }
+                }else if(kind.equals("出货单") || kind.equals("销售退货单")){
+                    if(status!=null){
+                        switch (status) {
+                            case  "已收款" :
+                                statuscode = Status.RECALL.name();
+                            case "部分收款":
+                                statuscode = Status.RECPART.name();
+                            default: statuscode = Status.RECNONE.name();
+                        }
+                    }else{
+                        statuscode = "RECNONE";
+                        status = "未收款";
+                    }
+                }
+                subledgerMapper.updateProdInOut(BaseContextHolder.getCompanyId(),detail.getVd_slkind(),
+                        kind,status,statuscode);
+            }
+        }
+
+        if(list2!=null && list2.size()>0){
+            for (Verificationdetail detail:list2) {
+                String kind = detail.getVcd_slkind();
+                String status = subledgerMapper.selectPayView(BaseContextHolder.getCompanyId(),detail.getVcd_slcode(),
+                        kind);
+                String statuscode = "";
+                if(kind.equals("采购验收单") || kind.equals("采购验退单")) {
+                    if(status!=null){
+                        switch (status) {
+                            case  "已付款" :
+                                statuscode = Status.PAYALL.name();
+                            case "部分付款":
+                                statuscode = Status.PAYPART.name();
+                            default: statuscode = Status.PAYNONE.name();
+                        }
+                    }else{
+                        statuscode = "PAYNONE";
+                        status = "未付款";
+                    }
+                }else if(kind.equals("出货单") || kind.equals("销售退货单")){
+                    if(status!=null){
+                        switch (status) {
+                            case  "已收款" :
+                                statuscode = Status.RECALL.name();
+                            case "部分收款":
+                                statuscode = Status.RECPART.name();
+                            default: statuscode = Status.RECNONE.name();
+                        }
+                    }else{
+                        statuscode = "RECNONE";
+                        status = "未收款";
+                    }
+                }
+                subledgerMapper.updateProdInOut(BaseContextHolder.getCompanyId(),detail.getVcd_slcode(),
+                        kind,status,statuscode);
+            }
+        }
+    }
+
     @Override
     public void delete(Long id) {
         if (null != id) {
@@ -484,6 +569,9 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
                 }
             }
         }
+        //更新出入库状态
+        this.updateProdInoutStatus(id);
+
         baseDTO.setId(id);
         baseDTO.setName(BillCodeSeq.VERIFICATION.getCaller());
         baseDTO.setCode(formData.getMain().getVc_code());
@@ -700,6 +788,10 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
         verification.setUpdaterId(BaseContextHolder.getUserId());
         //更新存在字段
         verificationMapper.updateByPrimaryKeySelective(verification);
+
+        //更新出入库状态
+        this.updateProdInoutStatus(id);
+
         DocBaseDTO baseDTO = new DocBaseDTO();
         baseDTO.setId(id);
         baseDTO.setCode(code);
@@ -913,6 +1005,8 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
             verification.setUpdaterName(BaseContextHolder.getUserName());
             verification.setUpdateTime(new Date());
             verificationMapper.updateByPrimaryKeySelective(verification);
+
+            this.updateProdInoutStatus(id);
         }
     }
 
@@ -951,6 +1045,8 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
             verification.setUpdaterName(BaseContextHolder.getUserName());
             verification.setUpdateTime(new Date());
             verificationMapper.updateByPrimaryKeySelective(verification);
+
+            this.updateProdInoutStatus(id);
         }
     }
 

+ 5 - 2
applications/money/money-server/src/main/resources/application.yml

@@ -7,7 +7,7 @@ spring:
       password: select111***
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:
@@ -19,7 +19,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   rabbitmq:
     host: 192.168.0.176
@@ -69,5 +69,8 @@ info:
 mybatis:
   type-aliases-package: com.usoftchina.saas.money.po
   mapper-locations: classpath:mapper/*.xml
+logging:
+  level:
+     com.usoftchina.saas.money.mapper : debug
 auth:
   public-key: auth/pub.key

+ 9 - 0
applications/money/money-server/src/main/resources/logback-spring.xml

@@ -104,4 +104,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 16 - 0
applications/money/money-server/src/main/resources/mapper/SubledgerMapper.xml

@@ -249,4 +249,20 @@
         where sl_code = #{sl_code,jdbcType=VARCHAR}
     </select>
 
+  <select id="selectPayView" resultType="java.lang.String">
+    select case when balance=pi_total then '已付款' when pi_total>balance then '部分付款'
+    when balance=0 then '未付款' ELSE '未付款' end as status from payment_received_view where companyId = #{companyid}
+    and pbd_slcode = #{code} and pbd_slkind = #{kind}
+  </select>
+
+  <select id="selectRecView" resultType="java.lang.String">
+    select case when balance=pi_total then '已收款' when pi_total>balance then '部分收款'
+    when balance=0 then '未收款' ELSE '未收款' end as status from payment_received_view where companyId = #{companyid}
+    and pbd_slcode = #{code} and pbd_slkind = #{kind}
+  </select>
+
+  <update id="updateProdInOut">
+    update prodinout set pi_prstatuscode=#{statuscode},pi_prstatus=#{status} where
+    companyid=#{companyid} and pi_class=#{kind} and pi_inoutno=#{code}
+  </update>
 </mapper>

+ 1 - 1
applications/purchase/purchase-server/src/main/resources/application.yml

@@ -9,7 +9,7 @@ spring:
       password: select111***
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:

+ 9 - 0
applications/purchase/purchase-server/src/main/resources/logback-spring.xml

@@ -104,4 +104,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 1 - 1
applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/service/impl/SaleServiceImpl.java

@@ -220,7 +220,6 @@ public class SaleServiceImpl implements SaleService{
     }
 
     @Override
-    @Transactional
     public DocBaseDTO audit(SaleFormDTO formData) {
         Long id = null;
         DocBaseDTO baseDTO = null;
@@ -235,6 +234,7 @@ public class SaleServiceImpl implements SaleService{
         return baseDTO;
     }
 
+    @Transactional
     private void singleAudit(Long id) {
         /*Sale sale = new Sale();
         //生成更新对象

+ 1 - 1
applications/sale/sale-server/src/main/resources/application.yml

@@ -7,7 +7,7 @@ spring:
       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&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:

+ 9 - 0
applications/sale/sale-server/src/main/resources/logback-spring.xml

@@ -104,4 +104,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 2 - 1
applications/storage/storage-server/src/main/java/com/usoftchina/saas/storage/service/impl/MakeServiceImpl.java

@@ -101,9 +101,10 @@ public class MakeServiceImpl extends CommonBaseServiceImpl<MakeMapper, Make> imp
         if(make.getId() == 0){
             //保存主表
             make.setCompanyId(BaseContextHolder.getCompanyId());
-
+            make.setCreateTime(new Date());
             make.setMa_code(code);
             getMapper().insertSelective(make);
+            ma_id = make.getId();
             //录入人
             getMapper().updateCreator(userId, userName, ma_id);
             if (makeMaterialList.size() > 0) {

+ 1 - 1
applications/storage/storage-server/src/main/resources/application.yml

@@ -9,7 +9,7 @@ spring:
       password: select111***
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
+    url: jdbc:mysql://192.168.0.172:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
     username: root
     password: select111***
     hikari:

+ 9 - 0
applications/storage/storage-server/src/main/resources/logback-spring.xml

@@ -104,4 +104,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 3 - 3
base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyRspDTO.java

@@ -43,13 +43,13 @@ public class CompanyRspDTO implements Serializable {
 
     private Long adminId;
 
-    private Long adminEmail;
+    private String adminEmail;
 
-    public Long getAdminEmail() {
+    public String getAdminEmail() {
         return adminEmail;
     }
 
-    public void setAdminEmail(Long adminEmail) {
+    public void setAdminEmail(String adminEmail) {
         this.adminEmail = adminEmail;
     }
 

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

@@ -420,9 +420,9 @@ public class AccountController {
      */
     @PostMapping("/disable")
     public Result disableAccount(@RequestParam long accountId) {
-        accountService.disable(accountId);
+        //accountService.disable(accountId);
         //移除账户绑定的企业关系
-        accountService.unbindCompany(accountId, BaseContextHolder.getCompanyId());
+        accountService.updateBindCompanyStatus(accountId, BaseContextHolder.getCompanyId(), "0");
         //同步到优软云
         Long userUU = accountService.findByPrimaryKey(accountId).getUu();
         Long companyUU = companyService.findByPrimaryKey(BaseContextHolder.getCompanyId()).getUu();
@@ -439,9 +439,9 @@ public class AccountController {
      */
     @PostMapping("/enable")
     public Result enableAccount(@RequestParam long accountId) {
-        accountService.enable(accountId);
+        //accountService.enable(accountId);
         //添加账户绑定的企业关系
-        accountService.bindCompany(accountId, BaseContextHolder.getCompanyId());
+        accountService.updateBindCompanyStatus(accountId, BaseContextHolder.getCompanyId(), "1");
         //同步到优软云
         Long userUU = accountService.findByPrimaryKey(accountId).getUu();
         Long companyUU = companyService.findByPrimaryKey(BaseContextHolder.getCompanyId()).getUu();

+ 8 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/mapper/AccountMapper.java

@@ -122,4 +122,12 @@ public interface AccountMapper {
      * @return
      */
     int findByUsernameOrMobileOrEmail(@Param("username") String username, @Param("mobile") String mobile, @Param("email") String email);
+
+    /**
+     * 更新账户公司绑定状态
+     * @param accountId
+     * @param companyId
+     * @param status
+     */
+    void updateBindCompanyStatus(@Param("accountId") Long accountId, @Param("companyId") Long companyId, @Param("status") String status);
 }

+ 8 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java

@@ -194,4 +194,12 @@ public interface AccountService {
      * @return
      */
     boolean findByUsernameOrMobileOrEmail(String username, String mobile, String email);
+
+    /**
+     * 更新账户公司的绑定状态
+     * @param accountId
+     * @param companyId
+     * @param status
+     */
+    void updateBindCompanyStatus(Long accountId, Long companyId, String status);
 }

+ 1 - 1
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountCenterServiceImpl.java

@@ -101,7 +101,7 @@ public class AccountCenterServiceImpl implements AccountCenterService {
         if (role != null) {
             accountService.bindRole(accountId, role.getId());
         }
-        return Result.success();
+        return Result.success(company.getId());
     }
 
     @Override

+ 5 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java

@@ -209,4 +209,9 @@ public class AccountServiceImpl implements AccountService {
         return accountMapper.findByUsernameOrMobileOrEmail(username, mobile, email) > 0;
     }
 
+    @Override
+    public void updateBindCompanyStatus(Long accountId, Long companyId, String status) {
+        accountMapper.updateBindCompanyStatus(accountId, companyId, status);
+    }
+
 }

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

@@ -24,7 +24,7 @@ spring:
       probability: 1.0
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_account?characterEncoding=utf-8&useSSL=false
+    url: jdbc:mysql://192.168.0.172:3306/saas_account?characterEncoding=utf-8&useSSL=false
     username: root
     password: select111***
     hikari:
@@ -36,7 +36,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss

+ 9 - 0
base-servers/account/account-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 2 - 2
base-servers/account/account-server/src/main/resources/mapper/AccountCompanyMapper.xml

@@ -2,7 +2,7 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.usoftchina.saas.account.mapper.AccountCompanyMapper">
     <insert id="insert">
-        insert into ac_account_company(account_id,company_id) values (#{accountId}, #{companyId})
+        insert into ac_account_company(account_id,company_id,status) values (#{accountId}, #{companyId}, 1)
     </insert>
     <delete id="delete">
         delete from ac_account_company where account_id=#{accountId} and company_id=#{companyId}
@@ -18,7 +18,7 @@
         left join ac_account_company accmp on accmp.company_id=cmp.id
         left join ac_account ac on ac.id = accmp.account_id
         left join ac_account aci on aci.id = cmp.creator_id
-        where ac.mobile = #{mobile}
+        where ac.mobile = #{mobile} and accmp.status = 1
         order by is_default desc
     </select>
     <update id="unBindDefault" >

+ 3 - 0
base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml

@@ -210,4 +210,7 @@
         SELECT COUNT(*) FROM AC_ACCOUNT
         WHERE USERNAME = #{username} OR MOBILE = #{mobile} OR EMAIL = #{email};
     </select>
+    <update id="updateBindCompanyStatus">
+        UPDATE AC_ACCOUNT_COMPANY SET STATUS = #{status} WHERE ACCOUNT_ID = #{accountId} AND COMPANY_ID = #{companyId}
+    </update>
 </mapper>

+ 2 - 2
base-servers/account/account-server/src/main/resources/mapper/AccountRoleMapper.xml

@@ -17,7 +17,7 @@
         delete from ac_account_role where company_id=#{companyId}
     </delete>
     <select id="selectAccountRole" resultType="com.usoftchina.saas.account.dto.AccountRoleDTO">
-        SELECT a.id id,a.username,a.realname,a.email,a.mobile,GROUP_CONCAT(c.name) roleNames,GROUP_CONCAT(c.id) roleIds,a.enabled
+        SELECT a.id id,a.username,a.realname,a.email,a.mobile,GROUP_CONCAT(c.name) roleNames,GROUP_CONCAT(c.id) roleIds,d.status enabled
         FROM ac_account a
         left join ac_account_company d on a.id = d.account_id
         left join ac_account_role b on a.id=b.account_id and d.company_id = b.company_id
@@ -30,7 +30,7 @@
                 AND d.COMPANY_ID = #{companyId}
             </if>
         </where>
-        group by a.id,a.username,a.realname,a.email,a.mobile,a.enabled
+        group by a.id,a.username,a.realname,a.email,a.mobile,d.status
     </select>
     <delete id="unBindRolesById" >
         DELETE FROM AC_ACCOUNT_ROLE WHERE ACCOUNT_ID = #{id} and company_id = #{companyId}

+ 1 - 1
base-servers/account/account-server/src/main/resources/mapper/RoleMapper.xml

@@ -104,7 +104,7 @@
         select <include refid="baseColumns"/> from ac_role,ac_account_role
         where ac_role.id=ac_account_role.role_id and ac_account_role.account_id=#{accountId,jdbcType=BIGINT}
     </select>
-    <select id="findManagerByCompanyId" parameterType="int" resultType="com.usoftchina.saas.account.po.Role">
+    <select id="findManagerByCompanyId" resultType="com.usoftchina.saas.account.po.Role">
         SELECT * FROM AC_ROLE WHERE COMPANY_ID = #{companyId} AND TYPE = 0 limit 1
     </select>
 </mapper>

+ 4 - 2
base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/api/AccountCacheTest.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.account.api;
 
 import com.usoftchina.saas.account.cache.AccountCache;
+import com.usoftchina.saas.context.BaseContextHolder;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -17,7 +18,8 @@ public class AccountCacheTest {
 
     @Test
     public void hdel() {
-        AccountCache.of(43).hdel();
-        System.out.println(AccountCache.of(43).exists());
+//        AccountCache.of(43).hdel();
+        BaseContextHolder.setToken("eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdWx5IiwiYXBwSWQiOiJ0cmFkZS1hcHAiLCJ1c2VySWQiOjQzLCJjb21wYW55SWQiOjEsInVzZXJOYW1lIjoic3VseSIsInJlYWxOYW1lIjoi6IuP54G16LCjIiwiZXhwIjoxNTQzNDg5NjM0fQ.oqOIqO97zAH2W1RZsofmCstKHNYsQlnMr_UkOw69zw175fhAefysux2njV1FEbldTQA62RiQ7JrnntWPqOmsNmrBsD0cwvy9xkUma3CNjIuZirbg09CYjUVIFnDpwz-WpmZMQFDIBVQYchCDRzDUgPYPB4phptCGNpTG6VpztPo");
+        System.out.println(AccountCache.of(43).getAccount());
     }
 }

+ 9 - 0
base-servers/admin-server/src/main/resources/logback-spring.xml

@@ -103,4 +103,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 4 - 0
base-servers/auth/auth-api/pom.xml

@@ -17,6 +17,10 @@
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>auth-dto</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-common</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>core</artifactId>

+ 10 - 0
base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/AuthApi.java

@@ -1,5 +1,6 @@
 package com.usoftchina.saas.auth.api;
 
+import com.usoftchina.saas.auth.common.cookie.CookieInfo;
 import com.usoftchina.saas.auth.dto.AuthDTO;
 import com.usoftchina.saas.auth.dto.TokenDTO;
 import com.usoftchina.saas.base.Result;
@@ -40,4 +41,13 @@ public interface AuthApi {
      */
     @GetMapping("/info")
     Result<AuthDTO> getInfo();
+
+    /**
+     * 使用账户中心登录cookie信息产生token登录
+     *
+     * @param info
+     * @return
+     */
+    @PostMapping(value = "/sso/authorize")
+    Result<AuthDTO> ssoAuthorize(CookieInfo info);
 }

+ 6 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtToken.java

@@ -24,6 +24,12 @@ public class JwtToken implements Serializable {
         this.timestamp = System.currentTimeMillis();
     }
 
+    public JwtToken(String token, Integer expire, Long timestamp) {
+        this.token = token;
+        this.expire = expire;
+        this.timestamp = timestamp;
+    }
+
     public String getToken() {
         return token;
     }

+ 1 - 1
base-servers/auth/auth-common/src/test/java/com/usoftchina/saas/auth/common/jwt/JwtHelperTest.java

@@ -9,7 +9,7 @@ public class JwtHelperTest {
 
     @org.junit.Test
     public void getInfoFromToken() throws Exception {
-        String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdWx5IiwiYXBwSWQiOiJ0cmFkZS1hcHAiLCJ1c2VySWQiOjQzLCJjb21wYW55SWQiOjEsInVzZXJOYW1lIjoic3VseSIsInJlYWxOYW1lIjoi6IuP54G16LCjIiwiZXhwIjoxNTQzNDExNzY0fQ.KMZV5H4tH4ifYBmY7rV4HSsW1fZHU2k-Yl47b9C3bt6S1_BqzTO-RbVDNMR-WXHpHFwXiq0aoHbqaA512z_-icLPcmeCb2TmnERisgjhnqn7OYordtAWahNlZfiaExnnttLvcNHQSiOWK9vYxxHnf2gC34XdKI0Bo8QZRSR3eo8";
+        String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdWx5IiwiYXBwSWQiOiJ0cmFkZS1hcHAiLCJ1c2VySWQiOjQzLCJjb21wYW55SWQiOjEsInVzZXJOYW1lIjoic3VseSIsInJlYWxOYW1lIjoi6IuP54G16LCjIiwiZXhwIjoxNTQzNDg5NjM0fQ.oqOIqO97zAH2W1RZsofmCstKHNYsQlnMr_UkOw69zw175fhAefysux2njV1FEbldTQA62RiQ7JrnntWPqOmsNmrBsD0cwvy9xkUma3CNjIuZirbg09CYjUVIFnDpwz-WpmZMQFDIBVQYchCDRzDUgPYPB4phptCGNpTG6VpztPo";
         String keyPath = "pub.key";
         JwtInfo info = JwtHelper.getInfoFromToken(token, keyPath);
     }

+ 29 - 0
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/config/CookieConfig.java

@@ -0,0 +1,29 @@
+package com.usoftchina.saas.auth.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author yingp
+ * @date 2018/11/29
+ */
+@ConfigurationProperties("auth.cookie")
+public class CookieConfig {
+    private String name;
+    private String secretKey;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+}

+ 68 - 1
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java

@@ -7,10 +7,13 @@ import com.usoftchina.saas.account.dto.AccountCopyDTO;
 import com.usoftchina.saas.account.dto.AccountDTO;
 import com.usoftchina.saas.account.dto.AccountUpdateDTO;
 import com.usoftchina.saas.account.dto.CompanyBaseDTO;
+import com.usoftchina.saas.auth.common.cookie.CookieHelper;
 import com.usoftchina.saas.auth.common.cookie.CookieInfo;
+import com.usoftchina.saas.auth.common.cookie.CookieUtils;
 import com.usoftchina.saas.auth.common.jwt.JwtHelper;
 import com.usoftchina.saas.auth.common.jwt.JwtInfo;
 import com.usoftchina.saas.auth.common.jwt.JwtToken;
+import com.usoftchina.saas.auth.config.CookieConfig;
 import com.usoftchina.saas.auth.dto.AuthDTO;
 import com.usoftchina.saas.auth.dto.AuthorizeLogDTO;
 import com.usoftchina.saas.auth.dto.TokenDTO;
@@ -30,6 +33,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
@@ -45,6 +51,7 @@ import java.util.List;
  */
 @RestController
 @RequestMapping
+@EnableConfigurationProperties(CookieConfig.class)
 public class AuthController {
 
     @Autowired
@@ -65,6 +72,9 @@ public class AuthController {
     @Value("${auth.max-errors:5}")
     private int maxErrors;
 
+    @Autowired
+    private CookieConfig cookieConfig;
+
     @Autowired
     private AuthorizeLogService authorizeLogService;
 
@@ -151,6 +161,53 @@ public class AuthController {
         return Result.success(new AuthDTO(tokenDTO, accountDTO));
     }
 
+    /**
+     * 使用账户中心登录cookie信息产生token登录
+     *
+     * @param info
+     * @return
+     */
+    @GetMapping("/sso/authorize")
+    public Result<AuthDTO> ssoAuthorize(HttpServletRequest request, HttpServletResponse response, CookieInfo info) throws IOException{
+        if (null != info && null != info.getMobile()) {
+            AccountDTO accountDTO = null;
+            Result<AccountDTO> result = accountApi.getAccount(info.getMobile());
+            if (!result.isSuccess()) {
+                if (ExceptionCode.USER_NOT_EXIST.getCode() == result.getCode()) {
+                    // 新用户,自动注册
+                    accountDTO = createAccountByCookieInfo(info);
+                } else {
+                    return Result.error(result);
+                }
+            } else {
+                accountDTO = result.getData();
+                // 检测uu是否正确
+                if (null == accountDTO.getUu() || !info.getUserUU().equals(accountDTO.getUu())) {
+                    accountDTO.setUu(info.getUserUU());
+                    Result updateResult = accountApi.update(BeanMapper.map(accountDTO, AccountUpdateDTO.class));
+                    if (!updateResult.isSuccess()) {
+                        return Result.error(updateResult);
+                    }
+                }
+            }
+            // TODO
+            String appId = "trade-app";
+            // 登录日志
+            authorizeLogService.save(AuthorizeLog.from(request)
+                    .setAccountId(accountDTO.getId())
+                    .setAppId(appId).build());
+            Long companyId = null;
+            if (!CollectionUtils.isEmpty(accountDTO.getCompanies())) {
+                companyId = accountDTO.getCompanies().get(0).getId();
+            }
+            JwtInfo jwtInfo = new JwtInfo(appId, companyId, accountDTO.getId(), accountDTO.getUsername(), accountDTO.getRealname());
+            JwtToken jwtToken = JwtHelper.generateToken(jwtInfo, privateKeyPath, expire);
+            TokenDTO tokenDTO = BeanMapper.map(jwtToken, TokenDTO.class);
+            return Result.success(new AuthDTO(tokenDTO, accountDTO));
+        }
+        return Result.error(ExceptionCode.COOKIE_ILLEGAL_ARGUMENT);
+    }
+
     /**
      * 账户中心登录时jsonp回调
      *
@@ -261,8 +318,18 @@ public class AuthController {
      * @return
      */
     @GetMapping("/info")
-    public Result<AuthDTO> getInfo(HttpServletRequest request) {
+    public Result<AuthDTO> getInfo(HttpServletRequest request, HttpServletResponse response) throws IOException{
         String token = request.getHeader(authHeader);
+        if (StringUtils.isEmpty(token)) {
+            // 解析cookie获取身份
+            CookieInfo info = CookieHelper.geInfoFromRequest(request,
+                    cookieConfig.getName(), cookieConfig.getSecretKey());
+            if (null != info) {
+                return ssoAuthorize(request, response, info);
+            } else {
+                return Result.error(ExceptionCode.JWT_ILLEGAL_ARGUMENT);
+            }
+        }
         JwtInfo infoFromToken = JwtHelper.getInfoFromToken(token, publicKeyPath);
         Result<AccountDTO> result = accountApi.getAccount(infoFromToken.getUserName());
         if (result.isSuccess()) {

+ 6 - 3
base-servers/auth/auth-server/src/main/resources/application.yml

@@ -24,7 +24,7 @@ spring:
       probability: 1.0
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_auth?characterEncoding=utf-8&useSSL=false
+    url: jdbc:mysql://192.168.0.172:3306/saas_auth?characterEncoding=utf-8&useSSL=false
     username: root
     password: select111***
     hikari:
@@ -36,7 +36,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss
@@ -81,4 +81,7 @@ mybatis:
   mapper-locations: classpath:mapper/*.xml
 auth:
   private-key: auth/pri.key
-  public-key: auth/pub.key
+  public-key: auth/pub.key
+  cookie:
+    name: uid
+    secret-key: 0taQcW073Z7G628g5H

+ 9 - 0
base-servers/auth/auth-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 9 - 0
base-servers/eureka-server/src/main/resources/logback-spring.xml

@@ -109,4 +109,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

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

@@ -22,7 +22,7 @@ spring:
       probability: 1.0
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_file?characterEncoding=utf-8&useSSL=false
+    url: jdbc:mysql://192.168.0.172:3306/saas_file?characterEncoding=utf-8&useSSL=false
     username: root
     password: select111***
     hikari:
@@ -34,7 +34,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss

+ 9 - 0
base-servers/file/file-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

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

@@ -4,8 +4,14 @@ import com.usoftchina.saas.account.cache.AccountCache;
 import com.usoftchina.saas.account.cache.ResourceCache;
 import com.usoftchina.saas.account.dto.AccountDTO;
 import com.usoftchina.saas.account.dto.UrlResourceDTO;
+import com.usoftchina.saas.auth.api.AuthApi;
+import com.usoftchina.saas.auth.common.cookie.CookieHelper;
+import com.usoftchina.saas.auth.common.cookie.CookieInfo;
 import com.usoftchina.saas.auth.common.jwt.JwtHelper;
 import com.usoftchina.saas.auth.common.jwt.JwtInfo;
+import com.usoftchina.saas.auth.dto.AuthDTO;
+import com.usoftchina.saas.auth.dto.TokenDTO;
+import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.context.BaseContextHolder;
 import com.usoftchina.saas.exception.BizException;
 import com.usoftchina.saas.exception.ExceptionCode;
@@ -34,18 +40,27 @@ import java.util.stream.Collectors;
  * @date 2018/10/13
  */
 @Configuration
-@EnableConfigurationProperties(AuthConfig.class)
+@EnableConfigurationProperties({
+        AuthConfig.class,
+        CookieConfig.class
+})
 public class AuthFilter implements GlobalFilter, Ordered {
 
     @Autowired
     private AuthConfig authConfig;
 
+    @Autowired
+    private CookieConfig cookieConfig;
+
+    @Autowired
+    private AuthApi authApi;
+
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         try {
             if (!isIgnore(exchange.getRequest())) {
                 // 鉴别身份信息
-                String token = getAuthHeaderToken(exchange.getRequest());
+                String token = getAuthToken(exchange.getRequest());
                 JwtInfo jwt = JwtHelper.getInfoFromToken(token, authConfig.getPublicKey());
                 BaseContextHolder.setAppId(jwt.getAppId());
                 BaseContextHolder.setUserId(jwt.getUserId());
@@ -121,10 +136,17 @@ public class AuthFilter implements GlobalFilter, Ordered {
                 new AntPathRequestMatcher(ignore).matches(request));
     }
 
-    private String getAuthHeaderToken(ServerHttpRequest request) {
+    private String getAuthToken(ServerHttpRequest request) {
+        // from header
         if (!request.getHeaders().containsKey(authConfig.getAuthHeader())) {
-            throw new BizException(ExceptionCode.JWT_ILLEGAL_ARGUMENT);
+            // from cookie
+            String token = getAuthCookieInfo(request);
+            if (null == token) {
+                throw new BizException(ExceptionCode.JWT_ILLEGAL_ARGUMENT);
+            }
+            return token;
         }
+
         List<String> headers = request.getHeaders().get(authConfig.getAuthHeader());
         if (headers.isEmpty()) {
             throw new BizException(ExceptionCode.JWT_ILLEGAL_ARGUMENT);
@@ -132,6 +154,29 @@ public class AuthFilter implements GlobalFilter, Ordered {
         return headers.get(0).trim();
     }
 
+    /**
+     * 解析cookie获取身份
+     *
+     * @param request
+     * @return
+     */
+    private String getAuthCookieInfo(ServerHttpRequest request) {
+        if (request.getCookies().containsKey(cookieConfig.getName())) {
+            String value = request.getCookies().getFirst(cookieConfig.getName()).getValue();
+            CookieInfo info = CookieHelper.geInfoFromToken(value, cookieConfig.getSecretKey());
+            Result<AuthDTO> result = authApi.ssoAuthorize(info);
+            if (result.isSuccess()) {
+                TokenDTO token = result.getData().getToken();
+                // 传递身份信息到后面代理的服务
+                request.getHeaders().add(authConfig.getAuthHeader(), token.getToken());
+                return token.getToken();
+            } else {
+                throw new BizException(result.getCode(), result.getMessage());
+            }
+        }
+        return null;
+    }
+
     @Override
     public int getOrder() {
         return -100;

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

@@ -0,0 +1,29 @@
+package com.usoftchina.saas.gateway.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author yingp
+ * @date 2018/11/29
+ */
+@ConfigurationProperties("auth.cookie")
+public class CookieConfig {
+    private String name;
+    private String secretKey;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+}

+ 4 - 1
base-servers/gateway-server/src/main/resources/application.yml

@@ -109,7 +109,7 @@ spring:
         predicates:
         - Path=/ws/**
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss
@@ -185,3 +185,6 @@ auth:
     - /api/auth/info
     - /ws/**
     - /api/file/download
+  cookie:
+    name: uid
+    secret-key: 0taQcW073Z7G628g5H

+ 9 - 0
base-servers/gateway-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

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

@@ -22,7 +22,7 @@ spring:
       probability: 1.0
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.253.12:3306/saas_mail?characterEncoding=utf-8&useSSL=false
+    url: jdbc:mysql://192.168.0.172:3306/saas_mail?characterEncoding=utf-8&useSSL=false
     username: root
     password: select111***
     hikari:
@@ -34,7 +34,7 @@ spring:
   messages:
     basename: i18n/messages
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss

+ 9 - 0
base-servers/mail/mail-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 1 - 1
base-servers/socket/socket-server/src/main/resources/application.yml

@@ -23,7 +23,7 @@ spring:
     sampler:
       probability: 1.0
   redis:
-    host: 192.168.253.12
+    host: 192.168.0.182
     port: 6379
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss

+ 9 - 0
base-servers/socket/socket-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

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

@@ -24,7 +24,7 @@ spring:
       probability: 1.0
   data:
     mongodb:
-      uri: mongodb://192.168.253.12:27017/saas_ui
+      uri: mongodb://192.168.0.183:27017/saas_ui
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss
     time-zone: GMT+8

+ 9 - 0
base-servers/ui-server/src/main/resources/logback-spring.xml

@@ -110,4 +110,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
+
 </configuration>

+ 8 - 0
base-servers/zipkin-server/src/main/resources/logback-spring.xml

@@ -103,4 +103,12 @@
         </root>
     </springProfile>
 
+    <springProfile name="docker-prod">
+        <logger name="org.springframework" level="WARN"/>
+        <logger name="com.usoftchina.saas" level="WARN"/>
+        <root level="WARN">
+            <appender-ref ref="CONSOLE_APPENDER"/>
+            <appender-ref ref="JSON_APPENDER"/>
+        </root>
+    </springProfile>
 </configuration>

+ 3 - 0
frontend/saas-web/app.json

@@ -295,6 +295,7 @@
             "type": "yui"
         },
         "server": {
+            "accountCenter":"https://saas.usoftchina.com",
             "basePath": "https://saas-api.usoftchina.com",
             "urlPattern": "^\/api\/"
         }
@@ -305,6 +306,7 @@
      */
     "testing": {
         "server": {
+            "accountCenter":"http://192.168.0.181:8000",
             "basePath": {
                 "https": "https://saas-api-dev.usoftchina.com:5443",
                 "http": "http://192.168.0.181:8560"
@@ -321,6 +323,7 @@
             "delay": 250
         },
         "server": {
+            "accountCenter":"http://192.168.0.181:8000",
             "basePath": {
                 "https": "https://saas-api-dev.usoftchina.com:5443",
                 "http": "http://192.168.0.181:8560"

+ 8 - 7
frontend/saas-web/app/Application.scss

@@ -187,7 +187,6 @@ body.launching {
 
 .x-btn-default-small,
 .x-btn-default-toolbar-small{
-  min-width: 86px !important;
   border-radius: 2px !important;
 }
 
@@ -257,15 +256,17 @@ body.launching {
 }
 
 .x-grid-header-ct {
-  border-top-color: #ABDAFF;
+  border-top-color: #ABDAFF !important;
+  border-right-color: #ABDAFF !important;
+  border-left-color: #ABDAFF !important;
   border-top-width: 1px;
+  border-right-width: 1px;
+  border-left-width: 1px;
 }
 
-.x-panel-default-outer-border-rl {
-  border-right-color: #ABDAFF !important;
-  border-right-width: 1px !important;
-  border-left-color: #ABDAFF !important;
-  border-left-width: 1px !important;
+.x-panel-default-outer-border-rl,
+.x-panel-default-outer-border-rbl {
+  border-color: #ABDAFF !important;
 }
 
 .x-grid-item-alt {

+ 2 - 0
frontend/saas-web/app/util/FormUtil.js

@@ -280,8 +280,10 @@ Ext.define('saas.util.FormUtil', {
                     if(initData) {
                         Ext.apply(initData.main, formData.main);
                         form.setFormData(initData);
+                        form.fireEvent('load', form, initData);
                     }else {
                         form.initFormData(formData);
+                        form.fireEvent('load', form, formData);
                     }
                 }).catch(function(res) {
                     saas.util.BaseUtil.showErrorToast(res.message);

+ 21 - 0
frontend/saas-web/app/view/core/base/BasePanel.js

@@ -73,4 +73,25 @@ Ext.define('saas.view.core.base.BasePanel', {
         });
         me.callParent(arguments);
     },
+    listeners: {
+        beforerender: function(form) {
+            var items = form.dockedItems.items[0].items.items,
+            searchField = form.searchField;
+
+            Ext.Array.each(searchField, function(f) {
+                var name = f.name;
+                var field = form.getForm().findField(name);
+                field.enableKeyEvents = true;
+                field.on && field.on({
+                    keydown: {
+                        fn: function(th, e, eOpts) {
+                            if(e.keyCode == 13) {
+                                form.getController().query()
+                            }
+                        }
+                    }
+                });
+            });
+        }
+    }
 });

+ 1 - 0
frontend/saas-web/app/view/core/base/GridPanel.js

@@ -93,6 +93,7 @@ Ext.define('saas.view.core.base.GridPanel', {
                     },
                     items:['->',{
                         xtype:'button',
+                        cls:'x-formpanel-btn-blue',
                         text:'新增',
                         handler:function(b){
                             var form = b.ownerCt.ownerCt.ownerCt;

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

@@ -331,7 +331,7 @@ Ext.define('saas.view.core.form.FormPanel', {
                     var d = detailData[j];
                     var o = {};
                     o[detnoColumn] = j + 1;
-                    var r = store.getAt(j) || store.add(o)[0];
+                    var r = store.add(o)[0];
                     for(var k in d) {
                         r.set(k, d[k]);
                     }

+ 8 - 35
frontend/saas-web/app/view/core/query/QueryGridPanel.js

@@ -53,7 +53,6 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
     initComponent: function () {
         var me = this;
 
-        console.log(me.idField);
         if(me.idField == 'id') {
             me.idField = '_id';
         }
@@ -120,19 +119,13 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                         viewModel = queryPanel.getViewModel(),
                         moreQuery = viewModel.get('moreQuery'),
                         condition = queryPanel.getConditions(moreQuery),
-                        defaultCondition1 = queryPanel.defaultCondition,
-                        defaultCondition2 = me.defaultCondition,
+                        defaultCondition = me.defaultCondition,
                         mode = queryPanel.getQueryMode();
 
-                        if(defaultCondition1) {
+                        if(defaultCondition) {
                             condition.push({
                                 type: 'condition',
-                                value: defaultCondition1
-                            });
-                        }else if(defaultCondition2) {
-                            condition.push({
-                                type: 'condition',
-                                value: defaultCondition2
+                                value: defaultCondition
                             });
                         }
                         Ext.apply(store.proxy.extraParams, {
@@ -166,8 +159,7 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
             dockedItems: [{
                 xtype: 'toolbar',
                 dock: 'top',
-                hidden: me.simpleMode,
-                defaults: { // defaults 将会应用所有的子组件上,而不是父容器
+                defaults: {
                     listeners: {
                         'mouseover':function(){
                             this.showMenu(); 
@@ -183,6 +175,7 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                 },
                 items: ['->', {
                     text: '新增',
+                    cls:'x-formpanel-btn-blue',
                     handler: 'onAddClick',
                     bind: {
                         hidden: '{!addEnable}'
@@ -211,22 +204,7 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                     }
                 },  {
                     text: '导出',
-                    handler: me.onImport,
-                    // menu: {
-                    //     cls:'x-query-menu',
-                    //     width: 80,
-                    //     items: [{
-                    //         text:'导出',
-                    //         handler:function(){
-                    //             me.onExport(this)
-                    //         }
-                    //     }],
-                    //     // listeners: {
-                    //     //     'mouseleave':function(enu){
-                    //     //         this.hide();
-                    //     //     } 
-                    //     // }
-                    // },
+                    handler: me.onExport,
                     bind: {
                         hidden: '{!importEnable}'
                     }
@@ -270,11 +248,6 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
         me.callParent(arguments);
     },
     listeners: {
-        afterrender: function(grid) {
-            if(grid.simpleMode) {
-                grid.headerCt.child('gridcolumn[isCheckerHd]').hide();
-            }
-        },
         boxready: function(grid, width, height, eOpts) {
             var store = grid.getStore(),
             gridBodyBox = grid.body.dom.getBoundingClientRect(),
@@ -344,8 +317,8 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
     onImport:function(me){
         console.log("导入");
     },
-    onExport: function (me) {
-        var grid = me.ownerCt.ownerCmp.ownerCt.ownerCt;
+    onExport: function () {
+        var grid = this.up('grid');
         //导出接口权限设置
         var _url = grid.baseVastUrl.substring(0,grid.baseVastUrl.length-1);
         var lastIndex = _url.lastIndexOf('/');

+ 1 - 21
frontend/saas-web/app/view/core/query/QueryPanel.js

@@ -29,22 +29,11 @@ Ext.define('saas.view.core.query.QueryPanel', {
 
     initComponent: function () {
         var me = this;
-        me.initQueryPanel();
-        // me.setQueryFormItems();
+        me.setQueryFormItems();
         me.setQuertGridConfigs();
         me.callParent(arguments);
     },
 
-    initQueryPanel: function() {
-        var me = this;
-        if(me.simpleMode) {
-            me.items[0].hidden = true;
-        }else {
-            me.items[0].hidden = false;
-            me.setQueryFormItems();
-        }
-    },
-
     getQueryForm: function () {
         var me = this,
         queryForm = me.items[0];
@@ -129,7 +118,6 @@ Ext.define('saas.view.core.query.QueryPanel', {
         }
 
         me.queryGridConfig['columns']=columns;
-        me.queryGridConfig['simpleMode'] = me.simpleMode;
         Ext.apply(queryGrid,me.queryGridConfig);
     },
 
@@ -147,10 +135,6 @@ Ext.define('saas.view.core.query.QueryPanel', {
         condition,
         conditions = [];
 
-        if(me.simpleMode) {
-            return conditions;
-        }
-
         if(moreQuery) {
             for(k in moreItems) {
                 var item = Ext.Array.findBy(moreQueryFormItems, function(i) {
@@ -292,10 +276,6 @@ Ext.define('saas.view.core.query.QueryPanel', {
         formData = viewModelData['form'],
         detailModel = false;
 
-        if(me.simpleMode) {
-            return 'DETAIL';
-        }
-
         for(var i = 0; i < formItems.length; i++) {
             var item = formItems[i],
             showDetail = item.showDetail,

+ 8 - 1
frontend/saas-web/app/view/document/bom/FormPanel.js

@@ -161,7 +161,14 @@ Ext.define('saas.view.document.bom.FormPanel', {
                     xtype : "numberfield",
                     decimalPrecision: 0,
                     minValue:0,
-                    maxLength: 10
+                    maxLength: 10,
+                    listeners: {
+                        change: function(f, v) {
+                            if((v+'').length > 10) {
+                                f.setValue(Number((v+'').substr(0, 10)));
+                            }
+                        }
+                    }
                 },
                 renderer : function(v) {
                     var arr = (v + '.').split('.');

+ 1 - 1
frontend/saas-web/app/view/document/customer/FormPanel.js

@@ -347,7 +347,7 @@ Ext.define('saas.view.document.customer.FormPanel', {
                     xtype : "textfield"
                 },
                 dataIndex : "ca_address", 
-                width:110 
+                width:300 
             },  
             {
                 allowBlank:true,

+ 9 - 0
frontend/saas-web/app/view/document/product/FormController.js

@@ -146,6 +146,15 @@ Ext.define('saas.view.document.product.FormController', {
             saas.util.BaseUtil.showErrorToast('禁用失败: ' + res.message);
         });
     },
+
+    qcsz_change: function(field, value) {
+        var me = this,
+        form = me.getView(),
+        detailGrid = form.down('detailGridField');
+        form.getForm().findField('qcsz').resetOriginalValue();
+        detailGrid.setHidden(!value);
+    },
+
     amount_change:function() {
         var me = this,
         viewModel = me.getViewModel(),

+ 2 - 12
frontend/saas-web/app/view/document/product/FormModel.js

@@ -3,7 +3,8 @@ Ext.define('saas.view.document.product.FormModel', {
     alias: 'viewmodel.document-product-formpanel',
 
     data: {
-        id: 0
+        id: 0,
+        qcsz: true,
     },
 
     formulas:{
@@ -13,17 +14,6 @@ Ext.define('saas.view.document.product.FormModel', {
                 return value;
             }
         },
-        qcsz_change: {
-            bind: '{qcsz}',
-            get: function(v) {
-                var form = this.getView(),
-                detailGrid = form.down('detailGridField');
-                //detailGrid.allowEmpty = !v;
-                //form.isValid();
-                form.getForm().findField('qcsz').resetOriginalValue();
-                detailGrid.setHidden(!v);
-            }
-        },
         
         /* ,
         pd_num_change: {

+ 4 - 1
frontend/saas-web/app/view/document/product/FormPanel.js

@@ -212,13 +212,16 @@ Ext.define('saas.view.document.product.FormPanel', {
         fieldLabel: '期初设置',
         name: 'qcsz',
         ignore: true,
+        listeners: {
+            change: 'qcsz_change'
+        }
     }, {
         xtype : "detailGridField", 
         storeModel:'saas.model.document.ProductDetail',
         detnoColumn: 'pd_detno',
         showCount: false,
         allowEmpty:true,
-        hidden: true,
+        // hidden: true,
         deleteDetailUrl:'/api/document/product/deleteDetail',
         columns : [{
             text : "ID", 

+ 7 - 16
frontend/saas-web/app/view/home/InfoCard.js

@@ -41,38 +41,32 @@ Ext.define('saas.view.home.InfoCard', {
                 unship: {
                     title: '待出货销售',
                     color: 'yellow',
-                    viewType: 'sale-sale-querypanel',
-                    condition: 'sale.companyid=' + companyId + ' and sa_statuscode=\'AUDITED\' and exists (select 1 from saledetail detail where sd_id=saledetail.sd_id and  IFNULL(sd_sendqty,0)<ifnull(sd_qty,0) and TO_DAYS(sd_delivery)-TO_DAYS(now())<= 7)'
+                    viewType: 'home-infocardlist-saleout',
                 },
                 unstorage: {
                     title: '待入库采购',
                     color: 'purple',
-                    viewType: 'purchase-purchase-querypanel',
-                    condition: 'purchase.companyId=' + companyId + ' and pu_statuscode=\'AUDITED\' and exists (select 1 from purchasedetail detail where pd_id=purchasedetail.pd_id and IFNULL(pd_acceptqty,0) < ifnull(pd_qty,0) and TO_DAYS(PD_DELIVERY)-TO_DAYS(now()) <= 7)'
+                    viewType: 'home-infocardlist-purchasein',
                 },
                 unpay: {
                     title: '待付款',
                     color: 'red',
-                    viewType: 'purchase-purchasein-querypanel',
-                    condition: 'pi_class in(\'采购验收单\',\'采购验退单\') and prodinout.companyId=' + companyId + ' and TO_DAYS(pi_date+ifnull(ve_promisedays,0))-TO_DAYS(now()) <= 7 and exists (select 1 from subledger where sl_code=pi_inoutno and sl_kind=pi_class and subledger.companyId=' + companyId + ' and ifnull(sl_namount,0)<>0)'
+                    viewType: 'home-infocardlist-payment',
                 },
                 unreceive: {
                     title: '待收款',
                     color: 'pink',
-                    viewType: 'sale-saleout-querypanel',
-                    condition: 'pi_class in(\'出货单\',\'销售退货单\') and prodinout.companyId=' + companyId + ' and TO_DAYS(pi_date+ifnull(cu_promisedays,0))-TO_DAYS(now()) <= 7 and exists (select 1 from subledger where sl_code=pi_inoutno and sl_kind=pi_class and subledger.companyId=' + companyId + ' and ifnull(sl_namount,0)<>0)'
+                    viewType: 'home-infocardlist-recment',
                 },
                 unauditcheck: {
                     title: '未审核验收',
                     color: 'blue',
-                    viewType: 'purchase-purchasein-querypanel',
-                    condition: 'pi_statuscode<>\'AUDITED\' and pi_class=\'采购验收单\' and prodinout.companyId=' + companyId
+                    viewType: 'home-infocardlist-unauditcheckin',
                 },
                 unauditship: {
                     title: '未审核出货',
                     color: 'default',
-                    viewType: 'sale-saleout-querypanel',
-                    condition: 'pi_statuscode<>\'AUDITED\' and pi_class=\'出货单\' and prodinout.companyId=' + companyId
+                    viewType: 'home-infocardlist-unauditsaleout',
                 }
             },
             userCls: 'x-info-card ' + me.userCls,
@@ -147,10 +141,7 @@ Ext.define('saas.view.home.InfoCard', {
                 itemSelector: 'div.x-box',
                 listeners: {
                     itemclick: function(th, record, item, index, e, eOpts) {
-                        saas.util.BaseUtil.openTab(record.get('viewType'), record.get('title'), record.get('id'), {
-                            simpleMode: true,
-                            defaultCondition: record.get('condition')
-                        });
+                        saas.util.BaseUtil.openTab(record.get('viewType'), record.get('title'), record.get('id'));
                     }
                 }
             });

+ 6 - 1
frontend/saas-web/app/view/home/charts/MonthPurchase.js

@@ -27,12 +27,13 @@ Ext.define('saas.view.home.charts.MonthPurchase', {
                     position: 'bottom',
                     label: {
                         fontSize: '12px',
-                        fillStyle: '#485465'
+                        fillStyle: '#485465',
                     },
                     style: {
                         fill: '#F7F8FA',
                         strokeStyle: 'transparent'
                     },
+                    renderer: me.onCategoryLabelRender
                 },{
                     type: 'numeric',
                     fields: ['y'],
@@ -79,6 +80,10 @@ Ext.define('saas.view.home.charts.MonthPurchase', {
         me.callParent(arguments);
     },
 
+    onCategoryLabelRender: function(axis, label, layoutContent, lastLabel) {
+        return label.substr(0,2) + '...';
+    },
+
     onBarTipRender: function (tooltip, record, item) {
         tooltip.setHtml(record.get('x') + ': ' + record.get('y') + '万元');
     },

+ 212 - 0
frontend/saas-web/app/view/home/infoCardList/InfoList.js

@@ -0,0 +1,212 @@
+Ext.define('saas.view.home.infoCardList.InfoList', {
+    extend: 'Ext.grid.Panel',
+    xtype: 'home-infocardlist-infolist',
+
+    cls: 'x-infocardlist',
+
+    //基础属性
+    border: 1,
+    loadMask: true,
+    showIndex: true,
+    columnWidth: 1.0,
+    showRowNum: true,
+
+    codeField: '',
+    columns: [],
+    condition: '1=1',
+
+    initComponent: function () {
+        var me = this,
+        listUrl = me.listUrl,
+        condition = me.initCondition(me.condition);
+
+        if(me.idField == 'id') {
+            me.idField = '_id';
+        }
+
+        Ext.apply(me, {
+            actions: {
+                copy: {
+                    iconCls: 'x-fa fa-copy',
+                    text: '复制单元格',
+                    handler: function() {
+                        me.onCopy(me.selectedData);
+                    }
+                }
+            },
+            viewConfig: {
+                deferEmptyText: false,
+                emptyText: '无数据',
+                listeners: {
+                    itemcontextmenu: function(view, rec, node, index, e) {
+                        e.stopEvent();
+                        me.getContextMenu().show().setLocalXY(e.getXY());
+                        me.selectedData = e.target.innerText;
+                        return false;
+                    }
+                }
+            },
+            columns: me.initColumns(),
+            store: Ext.create('Ext.data.Store', {
+                fields: me.getFields(),
+                autoLoad: true,
+                pageSize: 15,
+                data: [],
+                proxy: {
+                    type: 'ajax',
+                    url: listUrl,
+                    timeout: 8000,
+                    actionMethods: {
+                        read: 'GET'
+                    },
+                    reader: {
+                        type: 'json',
+                        rootProperty: 'data.list',
+                        totalProperty: 'data.total',
+                    },
+                    listeners: {
+                        exception: function(proxy, response, operation, eOpts) {
+                            if(operation.success) {
+                                if(response.timedout) {
+                                    saas.util.BaseUtil.showErrorToast('请求超时');
+                                }
+                            }else {
+                                if(response.timedout) {
+                                    saas.util.BaseUtil.showErrorToast('请求超时');
+                                }else{
+                                    saas.util.BaseUtil.showErrorToast('查询失败:' + response.responseJson.message);
+                                }
+                            }
+                        }
+                    }
+                },
+                listeners: {
+                    beforeload: function (store, op) {
+                        var conditions = [{
+                            type: 'condition',
+                            value: condition
+                        }];
+
+                        Ext.apply(store.proxy.extraParams, {
+                            number: store.exportNumber?store.exportNumber:op._page,
+                            size: store.exportPageSize?store.exportPageSize:store.pageSize,
+                            mode: 'DETAIL',
+                            condition: JSON.stringify(conditions)
+                        });
+    
+                    },
+                    load: function(store, records, successful, operation, eOpts) {
+                        var datas = [];
+
+                        Ext.Array.each(records, function(r, i) {
+                            var d = Object.assign({}, r.data, { _id: r.data.id, id: Ext.id() });
+                            datas.push(d);
+                        });
+
+                        store.loadData(datas, false);
+                        me.reconfigure(store, me.initColumns());
+                    }
+                }
+            }),
+            dockedItems: [{
+                xtype: 'pagingtoolbar',
+                cls: 'core-query-pagingtoolbar',
+                dock: 'bottom',
+                displayInfo: true,
+                store: me.store
+            }]
+        });
+        me.callParent(arguments);
+    },
+    listeners: {
+        boxready: function(grid, width, height, eOpts) {
+            var store = grid.getStore(),
+            gridBodyBox = grid.body.dom.getBoundingClientRect(),
+            gridBodyBoxHeight = gridBodyBox.height;
+
+            var pageSize = Math.floor(gridBodyBoxHeight / 32);
+
+            store.setPageSize(pageSize);
+        },
+        itemClick: function(tableView, record, item, index, e, eOpts) {
+            var grid = tableView.up('grid');
+
+            if(!grid.fireEvent('beforeopendetail', grid, record)) {
+                return false;
+            }
+
+            var idField = grid.idField,
+            codeField = grid.codeField,
+            detailTitle = grid.detailTitle,
+            detailXType = grid.detailXType;
+
+            if(e.target.parentElement.classList.contains('x-code-column')) {
+                var idValue = record.get(idField),
+                codeValue = record.get(codeField),
+                id = detailXType + '-' + idValue;
+                saas.util.BaseUtil.openTab(detailXType, detailTitle+"("+codeValue+")", id, {
+                    initId: idValue
+                });
+            }
+        },
+    },
+
+    initCondition: function(condition) {
+        var companyId = saas.util.BaseUtil.getCurrentUser().companyId;
+        return condition.replace('#{companyId}', companyId);;
+    },
+
+    initColumns: function() {
+        var me = this,
+        columns = me.listColumns;
+
+        Ext.Array.each(columns, function(c) {
+            if(c.dataIndex == me.codeField) {
+                Ext.applyIf(c, {
+                    tdCls: 'x-code-column'
+                });
+            }
+        });
+
+        return columns;
+    },
+    getFields: function() {
+        var me = this;
+
+        return me.columns.filter(function(c) {
+            return !!c.dataIndex;
+        }).map(function(c) {
+            return c.dataIndex;
+        });
+    },
+
+    getContextMenu: function() {
+        var me = this;
+
+        return me.contextMenu || (me.contextMenu = me.add({
+            xtype: 'menu',
+            items: [
+                // Actions can be converted into MenuItems
+                '@copy',
+            ]
+        }));
+    },
+
+    onCopy: function(text) {
+		var target = Ext.DomHelper.append(document.body, {
+			tag: 'textarea',
+			style: 'opacity: 0;position: absolute;top: -10000px;right: 0;',
+			html: text
+		});
+		target.focus();
+		target.select();
+	    document.execCommand('Copy');
+	    target.blur();
+	    document.body.removeChild(target);
+    },
+    
+    refresh: function() {
+        var me = this;
+        me.store.reload();
+    }
+});

+ 14 - 0
frontend/saas-web/app/view/home/infoCardList/InfoList.scss

@@ -0,0 +1,14 @@
+.x-infocardlist {
+    .x-grid-header-ct {
+        border-top-color: #ABDAFF !important;
+    }
+
+    .x-code-column {
+
+        .x-grid-cell-inner {
+            text-decoration: underline;
+            color: #3E80F6;
+            cursor: pointer;
+        }
+    }
+}

+ 130 - 0
frontend/saas-web/app/view/home/infoCardList/Payment.js

@@ -0,0 +1,130 @@
+/**
+ * 待付款
+ */
+Ext.define('saas.view.home.infoCardList.Payment', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-payment',
+
+    listUrl: '/api/purchase/prodinout/list',
+    idField: 'id',
+    codeField: 'pi_inoutno',
+    // detailTitle: '采购验收单',
+    // detailXType: 'purchase-purchasein-formpanel',
+    condition: 'pi_class in (\'采购验收单\',\'采购验退单\') and prodinout.companyId=#{companyId} and TO_DAYS(pi_date+ifnull(ve_promisedays,0))-TO_DAYS(now()) <= 7 and exists (select 1 from subledger where sl_code=pi_inoutno and sl_kind=pi_class and subledger.companyId=#{companyId} and ifnull(sl_namount,0)<>0)',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'pu_id',
+        xtype: 'numbercolumn',
+        hidden: true
+    }, {
+        text: '单据编号',
+        dataIndex: 'pi_inoutno',
+        width: 150
+    }, {
+        text: '单据类型',
+        dataIndex: 'pd_piclass',
+        width: 0
+    }, {
+        text: '单据日期',
+        dataIndex: 'pi_date',
+        xtype: 'datecolumn',
+        width: 110
+    }, {
+        text: '供应商编号',
+        dataIndex: 'pi_vendcode',
+        width: 0
+    }, {
+        text: '供应商名称',
+        dataIndex: 'pi_vendname',
+        width: 150
+    }, {
+        text: '审核状态',
+        align: 'center',
+        dataIndex: 'pi_status',
+        width: 90
+    }, {
+        text: '序号',
+        dataIndex: 'pd_pdno',
+        width: 80
+    }, {
+        text: '相关单号',
+        dataIndex: 'pd_ordercode',
+        width: 150
+    }, {
+        text: '物料编号',
+        dataIndex: 'pd_prodcode',
+        width: 150
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 200
+    }, {
+        text: '物料规格',
+        dataIndex: 'pr_spec',
+        width: 150
+    }, {
+        text: '单位',
+        dataIndex: 'pr_unit',
+        width: 80
+    }, {
+        text: '数量',
+        dataIndex: 'pd_inqty',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '仓库',
+        dataIndex: 'pd_whname',
+        width: 150
+    }, {
+        text: '单价',
+        dataIndex: 'pd_orderprice',
+        xtype: 'numbercolumn',
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+        width: 110
+    }, {
+        text: '税率',
+        dataIndex: 'pd_taxrate',
+        xtype: 'numbercolumn',
+        width: 80,
+        renderer: function (v) {
+            return Ext.util.Format.number(v, '0');
+        },
+    }, {
+        text: '金额',
+        dataIndex: 'pd_total',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 2 ? 2 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }],
+    listeners: {
+        beforeopendetail: function(grid, record) {
+            var pi_class = record.get('pi_class'),
+            detailTitle = '采购验收单',
+            detailXType = 'purchase-purchasein-formpanel';
+
+            if(pi_class == '采购验退单') {
+                detailTitle = '采购验退单';
+                detailXType = 'purchase-purchaseout-formpanel';
+            }
+            grid.detailTitle = detailTitle;
+            grid.detailXType = detailXType;
+            return true;
+        }
+    }
+});

+ 118 - 0
frontend/saas-web/app/view/home/infoCardList/PurchaseIn.js

@@ -0,0 +1,118 @@
+/**
+ * 待入库采购
+ */
+Ext.define('saas.view.home.infoCardList.PurchaseIn', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-purchasein',
+
+    listUrl: '/api/purchase/purchase/list',
+    idField: 'pu_id',
+    codeField: 'pu_code',
+    detailTitle: '采购订单',
+    detailXType: 'purchase-purchase-formpanel',
+    condition: 'purchase.companyId=#{companyId} and pu_statuscode=\'AUDITED\' and exists (select 1 from purchasedetail detail where pd_id=purchasedetail.pd_id and IFNULL(pd_acceptqty,0) < ifnull(pd_qty,0) and TO_DAYS(PD_DELIVERY)-TO_DAYS(now()) <= 7)',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'pu_id',
+        width: 0,
+        hidden: true
+    }, {
+        text: '采购单号',
+        dataIndex: 'pu_code',
+        width: 150
+    }, {
+        text: '单据日期',
+        dataIndex: 'pu_date',
+        xtype: 'datecolumn',
+        width: 110
+    }, {
+        text: '供应商名称',
+        dataIndex: 'pu_vendname',
+        width: 150
+    }, {
+        text: '审核状态',
+        align: 'center',
+        dataIndex: 'pu_status',
+        width: 90
+    }, {
+        text: '业务状态',
+        align: 'center',
+        dataIndex: 'pu_acceptstatus',
+        width: 90
+    }, {
+        text: '序号',
+        dataIndex: 'pd_detno',
+        xtype: 'numbercolumn',
+        width: 80,
+        renderer: function (v) {
+            return Ext.util.Format.number(v, '0');
+        }
+    }, {
+        text: '物料编号',
+        dataIndex: 'pd_prodcode',
+        width: 150
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 200
+    }, {
+        text: '物料规格',
+        dataIndex: 'pr_spec',
+        width: 150
+    }, {
+        text: '单位',
+        dataIndex: 'pr_unit',
+        width: 80
+    }, {
+        text: '采购数量',
+        dataIndex: 'pd_qty',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '需求日期',
+        dataIndex: 'pd_delivery',
+        xtype: 'datecolumn',
+        width: 110
+    }, {
+        text: '单价',
+        dataIndex: 'pd_price',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 8 ? 8 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '税率',
+        dataIndex: 'pd_taxrate',
+        xtype: 'numbercolumn',
+        width: 80,
+        renderer: function (v) {
+            return Ext.util.Format.number(v, '0');
+        },
+    }, {
+        text: '金额',
+        dataIndex: 'pd_total',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 2 ? 2 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '备注',
+        dataIndex: 'pd_remark',
+        width: 250
+    }]
+
+});

+ 139 - 0
frontend/saas-web/app/view/home/infoCardList/Recment.js

@@ -0,0 +1,139 @@
+/**
+ * 待收款
+ */
+Ext.define('saas.view.home.infoCardList.Recment', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-recment',
+
+    listUrl: '/api/sale/prodinout/list',
+    idField: 'id',
+    codeField: 'pi_inoutno',
+    // detailTitle: '出货单',
+    // detailXType: 'sale-saleout-formpanel',
+    condition: 'pi_class in (\'出货单\',\'销售退货单\') and prodinout.companyId=#{companyId} and TO_DAYS(pi_date+ifnull(cu_promisedays,0))-TO_DAYS(now()) <= 7 and exists (select 1 from subledger where sl_code=pi_inoutno and sl_kind=pi_class and subledger.companyId=#{companyId} and ifnull(sl_namount,0)<>0)',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'id',
+        hidden:true,
+        xtype: 'numbercolumn'
+    }, {
+        text: '出货单号',
+        dataIndex: 'pi_inoutno',
+        width: 150
+    }, {
+        text: '单据日期',
+        dataIndex: 'pi_date',
+        xtype:'datecolumn',
+        width: 110
+    },{
+        text: '客户名称',
+        dataIndex: 'pi_custname',
+        width: 250
+    }, {
+        text: '单据状态',
+        align: 'center',
+        dataIndex: 'pi_status',
+        width: 90
+    }, {
+        text: '明细序号',
+        dataIndex: 'pd_pdno',
+        xtype: 'numbercolumn',
+        width: 100,
+        renderer : function(v) {
+            var format = '0'
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '关联销售单号',
+        dataIndex: 'pd_ordercode',
+        width: 150
+    }, {
+        text: '订单序号',
+        dataIndex: 'pd_orderdetno',
+        xtype:'numbercolumn',
+        width: 100,
+        renderer : function(v) {
+            var format = '0'
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '物料编号',
+        dataIndex: 'pd_prodcode',
+        width: 150
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 150
+    }, {
+        text: '出货数量',
+        dataIndex: 'pd_outqty',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '销售单价',
+        dataIndex: 'pd_sendprice',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 8 ? 8 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '金额',
+        dataIndex: 'pd_ordertotal',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '税率',
+        dataIndex: 'pd_taxrate',
+        xtype:'numbercolumn',
+        width: 80,
+        renderer : function(v) {
+            return Ext.util.Format.number(v, '0');
+        }
+    }, {
+        text: '成本单价',
+        dataIndex: 'pd_price',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 2 ? 2 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '备注',
+        dataIndex: 'pd_remark',
+        width: 250
+    }],
+    listeners: {
+        beforeopendetail: function(grid, record) {
+            var pi_class = record.get('pi_class'),
+            detailTitle = '出货单',
+            detailXType = 'sale-saleout-formpanel';
+
+            if(pi_class == '销售退货单') {
+                detailTitle = '销售退货单';
+                detailXType = 'sale-salein-formpanel';
+            }
+            grid.detailTitle = detailTitle;
+            grid.detailXType = detailXType;
+            return true;
+        }
+    }
+});

+ 118 - 0
frontend/saas-web/app/view/home/infoCardList/SaleOut.js

@@ -0,0 +1,118 @@
+/**
+ * 待出货销售
+ */
+Ext.define('saas.view.home.infoCardList.SaleOut', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-saleout',
+
+    listUrl: '/api/sale/sale/list',
+    idField: 'sa_id',
+    codeField: 'sa_code',
+    detailTitle: '销售订单',
+    detailXType: 'sale-sale-formpanel',
+    condition: 'sale.companyid=#{companyId} and sa_statuscode=\'AUDITED\' and exists (select 1 from saledetail detail where sd_id=saledetail.sd_id and  IFNULL(sd_sendqty,0)<ifnull(sd_qty,0) and TO_DAYS(sd_delivery)-TO_DAYS(now())<= 7)',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'sa_id',
+        hidden: true,
+        xtype: 'numbercolumn'
+    }, {
+        text: '单据编号',
+        dataIndex: 'sa_code',
+        width: 200
+    }, {
+        text: '单据状态',
+        align: 'center',
+        dataIndex: 'sa_status',
+        width: 120
+    }, {
+        text: '单据日期',
+        dataIndex: 'sa_date',
+        xtype: 'datecolumn',
+        width: 200
+    }, {
+        text: '客户名称',
+        dataIndex: 'sa_custname',
+        width: 120
+    }, {
+        text: '明细序号',
+        dataIndex: 'sd_detno',
+        xtype: 'numbercolumn',
+        width: 120,
+        renderer: function (v) {
+            return Ext.util.Format.number(v, '0');
+        }
+    }, {
+        text: '物料编号',
+        dataIndex: 'sd_prodcode',
+        width: 120
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 120
+    }, {
+        text: '物料规格',
+        dataIndex: 'pr_spec',
+        width: 120
+    }, {
+        text: '数量',
+        dataIndex: 'sd_qty',
+        xtype: 'numbercolumn',
+        width: 120,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '单价',
+        dataIndex: 'sd_price',
+        xtype: 'numbercolumn',
+        width: 120,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 8 ? 8 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '已转数',
+        dataIndex: 'sd_yqty',
+        xtype: 'numbercolumn',
+        width: 120,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '已出货数',
+        dataIndex: 'sd_sendqty',
+        xtype: 'numbercolumn',
+        width: 120,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '已审核采购单数',
+        dataIndex: 'sd_pdqty',
+        xtype: 'numbercolumn',
+        width: 180,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '备注',
+        dataIndex: 'sd_remark',
+        width: 250
+    }],
+
+});

+ 130 - 0
frontend/saas-web/app/view/home/infoCardList/UnauditCheckIn.js

@@ -0,0 +1,130 @@
+/**
+ * 未审核验收
+ */
+Ext.define('saas.view.home.infoCardList.UnauditCheckIn', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-unauditcheckin',
+
+    listUrl: '/api/purchase/prodinout/list',
+    idField: 'id',
+    codeField: 'pi_inoutno',
+    // detailTitle: '采购验收单',
+    // detailXType: 'purchase-purchasein-formpanel',
+    condition: 'pi_statuscode<>\'AUDITED\' and pi_class in (\'采购验收单\',\'采购验退单\') and prodinout.companyId=#{companyId}',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'pu_id',
+        xtype: 'numbercolumn',
+        hidden: true
+    }, {
+        text: '单据编号',
+        dataIndex: 'pi_inoutno',
+        width: 150
+    }, {
+        text: '单据类型',
+        dataIndex: 'pd_piclass',
+        width: 0
+    }, {
+        text: '单据日期',
+        dataIndex: 'pi_date',
+        xtype: 'datecolumn',
+        width: 110
+    }, {
+        text: '供应商编号',
+        dataIndex: 'pi_vendcode',
+        width: 0
+    }, {
+        text: '供应商名称',
+        dataIndex: 'pi_vendname',
+        width: 150
+    }, {
+        text: '审核状态',
+        align: 'center',
+        dataIndex: 'pi_status',
+        width: 90
+    }, {
+        text: '序号',
+        dataIndex: 'pd_pdno',
+        width: 80
+    }, {
+        text: '相关单号',
+        dataIndex: 'pd_ordercode',
+        width: 150
+    }, {
+        text: '物料编号',
+        dataIndex: 'pd_prodcode',
+        width: 150
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 200
+    }, {
+        text: '物料规格',
+        dataIndex: 'pr_spec',
+        width: 150
+    }, {
+        text: '单位',
+        dataIndex: 'pr_unit',
+        width: 80
+    }, {
+        text: '数量',
+        dataIndex: 'pd_inqty',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }, {
+        text: '仓库',
+        dataIndex: 'pd_whname',
+        width: 150
+    }, {
+        text: '单价',
+        dataIndex: 'pd_orderprice',
+        xtype: 'numbercolumn',
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+        width: 110
+    }, {
+        text: '税率',
+        dataIndex: 'pd_taxrate',
+        xtype: 'numbercolumn',
+        width: 80,
+        renderer: function (v) {
+            return Ext.util.Format.number(v, '0');
+        },
+    }, {
+        text: '金额',
+        dataIndex: 'pd_total',
+        xtype: 'numbercolumn',
+        width: 110,
+        renderer: function (v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 2 ? 2 : arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    }],
+    listeners: {
+        beforeopendetail: function(grid, record) {
+            var pi_class = record.get('pi_class'),
+            detailTitle = '采购验收单',
+            detailXType = 'purchase-purchasein-formpanel';
+
+            if(pi_class == '采购验退单') {
+                detailTitle = '采购验退单';
+                detailXType = 'purchase-purchaseout-formpanel';
+            }
+            grid.detailTitle = detailTitle;
+            grid.detailXType = detailXType;
+            return true;
+        }
+    }
+});

+ 139 - 0
frontend/saas-web/app/view/home/infoCardList/UnauditSaleOut.js

@@ -0,0 +1,139 @@
+/**
+ * 未审核出货
+ */
+Ext.define('saas.view.home.infoCardList.UnauditSaleOut', {
+    extend: 'saas.view.home.infoCardList.InfoList',
+    xtype: 'home-infocardlist-unauditsaleout',
+
+    listUrl: '/api/sale/prodinout/list',
+    idField: 'id',
+    codeField: 'pi_inoutno',
+    // detailTitle: '出货单',
+    // detailXType: 'sale-saleout-formpanel',
+    condition: 'pi_statuscode<>\'AUDITED\' and pi_class in (\'出货单\',\'销售退货单\') and prodinout.companyId=#{companyId}',
+    listColumns: [{
+        text: 'id',
+        dataIndex: 'id',
+        hidden:true,
+        xtype: 'numbercolumn'
+    }, {
+        text: '出货单号',
+        dataIndex: 'pi_inoutno',
+        width: 150
+    }, {
+        text: '单据日期',
+        dataIndex: 'pi_date',
+        xtype:'datecolumn',
+        width: 110
+    },{
+        text: '客户名称',
+        dataIndex: 'pi_custname',
+        width: 250
+    }, {
+        text: '单据状态',
+        align: 'center',
+        dataIndex: 'pi_status',
+        width: 90
+    }, {
+        text: '明细序号',
+        dataIndex: 'pd_pdno',
+        xtype: 'numbercolumn',
+        width: 100,
+        renderer : function(v) {
+            var format = '0'
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '关联销售单号',
+        dataIndex: 'pd_ordercode',
+        width: 150
+    }, {
+        text: '订单序号',
+        dataIndex: 'pd_orderdetno',
+        xtype:'numbercolumn',
+        width: 100,
+        renderer : function(v) {
+            var format = '0'
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '物料编号',
+        dataIndex: 'pd_prodcode',
+        width: 150
+    }, {
+        text: '物料名称',
+        dataIndex: 'pr_detail',
+        width: 150
+    }, {
+        text: '出货数量',
+        dataIndex: 'pd_outqty',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '销售单价',
+        dataIndex: 'pd_sendprice',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 8 ? 8 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '金额',
+        dataIndex: 'pd_ordertotal',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 3 ? 3 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '税率',
+        dataIndex: 'pd_taxrate',
+        xtype:'numbercolumn',
+        width: 80,
+        renderer : function(v) {
+            return Ext.util.Format.number(v, '0');
+        }
+    }, {
+        text: '成本单价',
+        dataIndex: 'pd_price',
+        xtype:'numbercolumn',
+        width: 110,
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length > 2 ? 2 : arr[1].length)).fill('0');
+            var format = '0.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        }
+    }, {
+        text: '备注',
+        dataIndex: 'pd_remark',
+        width: 250
+    }],
+    listeners: {
+        beforeopendetail: function(grid, record) {
+            var pi_class = record.get('pi_class'),
+            detailTitle = '出货单',
+            detailXType = 'sale-saleout-formpanel';
+
+            if(pi_class == '销售退货单') {
+                detailTitle = '销售退货单';
+                detailXType = 'sale-salein-formpanel';
+            }
+            grid.detailTitle = detailTitle;
+            grid.detailXType = detailXType;
+            return true;
+        }
+    }
+});

+ 1 - 1
frontend/saas-web/app/view/main/Main.js

@@ -140,7 +140,7 @@ Ext.define('saas.view.main.Main', {
                             text: '账户中心',
                             iconCls:'x-fa fa-user-o sa-navicon',
                             handler:function(){
-                                window.open('http://www.usoftchina.com','_blank');
+                                window.open(Ext.manifest.server.accountCenter,'_blank');
                             }
                         },{  
                             text: '意见反馈',

+ 6 - 1
frontend/saas-web/app/view/sale/sale/QueryPanel.js

@@ -124,7 +124,7 @@ Ext.define('saas.view.sale.sale.QueryPanel', {
             text: '业务状态',
             align: 'center',
             dataIndex: 'sa_sendstatus',
-            width: 90
+            width: 100
         }, {
             text: '业务员',
             dataIndex: 'sa_seller',
@@ -170,6 +170,11 @@ Ext.define('saas.view.sale.sale.QueryPanel', {
             text: '客户名称',
             dataIndex: 'sa_custname',
             width: 120
+        },  {
+            text: '业务状态',
+            align: 'center',
+            dataIndex: 'sa_sendstatus',
+            width: 90
         }, {
             text: '明细序号',
             dataIndex: 'sd_detno',

+ 26 - 1
frontend/saas-web/app/view/stock/make/FormPanel.js

@@ -385,5 +385,30 @@ Ext.define('saas.view.stock.make.FormPanel', {
         name : "ma_auditdate", 
         fieldLabel : "审核日期",
         readOnly:true
-    }]
+    }],
+    beforeAudit:function(){
+        var me = this,
+        controller = me.getController(),
+        viewModel = me.getViewModel(),
+        grid = me.down('detailGridField'),
+        data = grid.getTrueData()
+        str='';
+        Ext.Array.each(data,function(item){
+            if(item.mm_price==0){     
+                str=str+item.mm_detno+'行'+item.mm_prodcode+'物料成本单价为0!'+'<br>'
+            }
+        });
+    
+        if(str!=''){
+            saas.util.BaseUtil.showConfirm('提示',str)
+            .then(function(y) {
+                if(y == 'yes') {
+                    controller.audit();
+                }
+            });
+        }else{
+            controller.audit();
+        }
+        return false;
+    }
 });

+ 2 - 0
frontend/saas-web/app/view/stock/make/FormPanelController.js

@@ -47,6 +47,8 @@ Ext.define('saas.view.stock.make.FormPanelController', {
                             from:'pr_spec',to:'pr_spec'
                         },{
                             from:'pr_unit',to:'pr_unit'
+                        },{
+                            from:'pr_purcprice',to:'mm_price'
                         }],
                     }) ;   
 

+ 1 - 1
frontend/saas-web/app/view/sys/finish/DataList.js

@@ -84,7 +84,7 @@ Ext.define('saas.view.sys.finish.DataList', {
         width : 110.0, 
     },{
         text : "操作日期", 
-        width : 150.0, 
+        width : 220.0, 
         format:'Y-m-d H:i:s',
         dataIndex : "createTime", 
         xtype:'datecolumn',

+ 8 - 3
frontend/saas-web/app/view/viewport/ViewportController.js

@@ -23,6 +23,8 @@ Ext.define('saas.view.viewport.ViewportController', {
     },
 
     mainviewboxready: function() {
+        //初始化accountPage地址
+        document.getElementsByName('accountPage')[0].setAttribute('src',getTokenPage());
         if(!Ext.isChrome && !Ext.isFirefox) {
             saas.util.BaseUtil.showConfirm('温馨提示', '为了更好地呈现页面效果,推荐使用Chrome浏览器或火狐浏览器');
         }
@@ -117,7 +119,7 @@ Ext.define('saas.view.viewport.ViewportController', {
     terminateSession: function() {
         this.setRequestToken(null);
         this.saveSession(null);
-        this.showAuth();
+        //this.showAuth();
     },
 
     saveSession: function(session) {
@@ -141,7 +143,6 @@ Ext.define('saas.view.viewport.ViewportController', {
         var me = this,
             view = me.getView(),
             session = me.session;
-
         if (!session || !session.isValid()) {
             return false;
         }
@@ -153,7 +154,11 @@ Ext.define('saas.view.viewport.ViewportController', {
             me.originalRoute = Ext.History.getToken();
             me.terminateSession();
             view.unmask();
-            me.redirectTo('login', {replace: true});
+            //跳转到账户中心
+            const frame = window.frames[window.frames.length - 1];
+            frame.postMessage('removeToken','*');
+            window.location.href = getAccountPage();
+            //me.redirectTo('login', {replace: true});
         });
     },
 

+ 9 - 0
frontend/saas-web/index.html

@@ -12,6 +12,15 @@
 
     <!-- The line below must be kept intact for Sencha Cmd to build your application -->
     <script id="microloader" data-app="a20e1670-7932-41f6-8e9c-55b77cba3f26" type="text/javascript" src="bootstrap.js"></script>
+    <script>
+        function getTokenPage(){
+            return Ext.manifest.server.accountCenter + "/remove-token.html"
+        }
+        function getAccountPage(){
+            return Ext.manifest.server.accountCenter
+        }
+    </script>
 </head>
+<iframe name="accountPage" hidden></iframe>
 <body class="launching"></body>
 </html>