Browse Source

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

hy 7 years ago
parent
commit
5531be444f
47 changed files with 1568 additions and 122 deletions
  1. 8 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/mapper/SubledgerMapper.java
  2. 45 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/PaybalanceServiceImpl.java
  3. 39 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/RecbalanceServiceImpl.java
  4. 96 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java
  5. 16 0
      applications/money/money-server/src/main/resources/mapper/SubledgerMapper.xml
  6. 2 1
      applications/storage/storage-server/src/main/java/com/usoftchina/saas/storage/service/impl/MakeServiceImpl.java
  7. 1 1
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountCenterServiceImpl.java
  8. 1 1
      base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml
  9. 4 2
      base-servers/account/account-server/src/test/java/com/usoftchina/saas/account/api/AccountCacheTest.java
  10. 4 0
      base-servers/auth/auth-api/pom.xml
  11. 10 0
      base-servers/auth/auth-api/src/main/java/com/usoftchina/saas/auth/api/AuthApi.java
  12. 6 0
      base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtToken.java
  13. 1 1
      base-servers/auth/auth-common/src/test/java/com/usoftchina/saas/auth/common/jwt/JwtHelperTest.java
  14. 29 0
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/config/CookieConfig.java
  15. 68 1
      base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java
  16. 4 1
      base-servers/auth/auth-server/src/main/resources/application.yml
  17. 49 4
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/AuthFilter.java
  18. 29 0
      base-servers/gateway-server/src/main/java/com/usoftchina/saas/gateway/config/CookieConfig.java
  19. 3 0
      base-servers/gateway-server/src/main/resources/application.yml
  20. 3 2
      frontend/saas-portal-web/src/components/conenter/addgongsi.vue
  21. 6 6
      frontend/saas-portal-web/src/components/conenter/company.vue
  22. 5 3
      frontend/saas-portal-web/src/components/conenter/enterprise.vue
  23. 32 2
      frontend/saas-portal-web/src/components/conenter/home.vue
  24. 2 2
      frontend/saas-portal-web/src/components/conenter/qiyexiangxi.vue
  25. 1 0
      frontend/saas-portal-web/src/pages/index/index.js
  26. 8 6
      frontend/saas-web/app/Application.scss
  27. 2 0
      frontend/saas-web/app/util/FormUtil.js
  28. 21 0
      frontend/saas-web/app/view/core/base/BasePanel.js
  29. 1 1
      frontend/saas-web/app/view/core/form/FormPanel.js
  30. 7 35
      frontend/saas-web/app/view/core/query/QueryGridPanel.js
  31. 1 21
      frontend/saas-web/app/view/core/query/QueryPanel.js
  32. 8 1
      frontend/saas-web/app/view/document/bom/FormPanel.js
  33. 9 0
      frontend/saas-web/app/view/document/product/FormController.js
  34. 2 12
      frontend/saas-web/app/view/document/product/FormModel.js
  35. 4 1
      frontend/saas-web/app/view/document/product/FormPanel.js
  36. 7 16
      frontend/saas-web/app/view/home/InfoCard.js
  37. 6 1
      frontend/saas-web/app/view/home/charts/MonthPurchase.js
  38. 212 0
      frontend/saas-web/app/view/home/infoCardList/InfoList.js
  39. 14 0
      frontend/saas-web/app/view/home/infoCardList/InfoList.scss
  40. 130 0
      frontend/saas-web/app/view/home/infoCardList/Payment.js
  41. 118 0
      frontend/saas-web/app/view/home/infoCardList/PurchaseIn.js
  42. 139 0
      frontend/saas-web/app/view/home/infoCardList/Recment.js
  43. 118 0
      frontend/saas-web/app/view/home/infoCardList/SaleOut.js
  44. 130 0
      frontend/saas-web/app/view/home/infoCardList/UnauditCheckIn.js
  45. 139 0
      frontend/saas-web/app/view/home/infoCardList/UnauditSaleOut.js
  46. 26 1
      frontend/saas-web/app/view/stock/make/FormPanel.js
  47. 2 0
      frontend/saas-web/app/view/stock/make/FormPanelController.js

+ 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);
         }
     }
 

+ 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>

+ 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
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

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

@@ -211,6 +211,6 @@
         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 COMPANYID = #{companyId}
+        UPDATE AC_ACCOUNT_COMPANY SET STATUS = #{status} WHERE ACCOUNT_ID = #{accountId} AND COMPANY_ID = #{companyId}
     </update>
 </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());
     }
 }

+ 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()) {

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

@@ -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

+ 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;
+    }
+}

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

@@ -185,3 +185,6 @@ auth:
     - /api/auth/info
     - /ws/**
     - /api/file/download
+  cookie:
+    name: uid
+    secret-key: 0taQcW073Z7G628g5H

+ 3 - 2
frontend/saas-portal-web/src/components/conenter/addgongsi.vue

@@ -63,7 +63,7 @@
                     <ul>
                         <li style="margin:0">
                             <span class="qy-biaoti"><span class="xingxing">*</span>姓名</span>
-                            <input class="inpind" @change= "yzusername" ref="name" type="text">
+                            <input class="inpind" @change= "yzusername" ref="name" type="text" value="">
                             <div class="qy-Tips Tips-buttom"><span ref="usname" style="color:red"></span></div>
                         </li>
                         <li><span class="qy-biaoti">手机号</span><span>{{mytoken.account.mobile}}</span></li>
@@ -102,7 +102,8 @@ import VDistpicker from 'v-distpicker'
             VDistpicker
         },
         mounted(){
-
+            this.$refs.name.value = this.mytoken.account.realname
+            this.$refs.email.value = this.mytoken.account.email
         },
         methods: {
             //取消添加企业

+ 6 - 6
frontend/saas-portal-web/src/components/conenter/company.vue

@@ -38,9 +38,9 @@
       <div>
         <div class="tc-okkaitong"><span>该企业已开通服务,联系管理员邀请加入</span></div>
         <div class="tc-context">
-          <p><span>管理员:</span><span>{{arr[0].admin}}</span></p>
-          <p><span>管理员手机号:</span><span>{{mytoken.account.mobile}}</span></p>
-          <p><span>管理员邮箱:</span><span></span></p>
+          <p><span>saas服务管理员:</span><span>{{arr[0].admin}}</span></p>
+          <p><span>saas服务管理员手机号:</span><span>{{mytoken.account.mobile}}</span></p>
+          <p><span>saas服务管理员邮箱:</span><span></span></p>
         </div>
       </div>
     </div>
@@ -62,7 +62,7 @@
                 <div class="left gs-xqleft" @click= "getEnterpriseInfo(d)">
                     <div class="gs-lefttext">
                         <p class="gs-qynema"><span>企业名称:</span>{{d.name}}</p>
-                        <p><span>管理员:</span>{{d.admin}}</p>
+                        <p v-if= "d.saas_" ><span>saas服务管理员:</span>{{d.admin}}</p>
                         <p v-if= "d.time"><span>开通日期:</span>{{d.time}}</p>
                     </div>
                 </div>
@@ -149,8 +149,7 @@
                         }
                     }
                     this.$store.commit('Loginfalse')
-                    // console.log(res.data.data)
-                    this.$store.state.email = this.arr[0].adminEmail
+                    this.$store.state.email = res.data.data.spaces[0].adminEmail
                 })
                 .catch(err=>{
                     // console.log("请求失败",err)
@@ -258,6 +257,7 @@
                     // console.log('请求成功',res)
                     if (res.data.success) {
                         this.ktsass = false;
+                        this.saasid = res.data.data
                     } else {
                         this.isokopensaas = true;
                     }

+ 5 - 3
frontend/saas-portal-web/src/components/conenter/enterprise.vue

@@ -71,7 +71,7 @@
                     </div>
                 </div>
     <!-- 安全信息----------------------------------------------------------------------------- -->
-                <!-- <sjld></sjld> -->
+
                 <div :class="{gsqiye:nowindex == 2}">
                     <div class="gs-anquanxinxi">
                         <div class="over aq-title"><span class="left">登录密码</span><button class="right dianji">更换密码</button></div>
@@ -111,7 +111,6 @@ import { setTimeout } from 'timers';
             return{
                 nowindex: 0,//tab切换
                 tianjiaqiye: true,//添加企业切换
-                email: this.$store.state.email,
                 mytoken: JSON.parse(localStorage.getItem('app-state-session')).account,//本地储存的用户信息
                 tab: [
                     {name: '企业信息'},
@@ -123,10 +122,13 @@ import { setTimeout } from 'timers';
         computed :{
             setTokenPage() {
                 return this.$url.web + '/set-token.html'
+            },
+            email(){
+                return this.$store.state.email
             }
         },
         mounted(){
-
+            
         },
         methods: {
             // tab切换

+ 32 - 2
frontend/saas-portal-web/src/components/conenter/home.vue

@@ -68,7 +68,7 @@
             <span><img style="margin: 6px 8px 10px 15px;" src="/static/img/assets/phone.png" alt=""></span>
             <input ref="typhone" type="text" placeholder="请输入您的11位手机号">
           </div>
-          <div class="left" style="margin-left: 8px;"><button @click="experience1">立即体验</button></div>
+          <div class="left" style="margin-left: 8px;"><button @click="openexperience">立即体验</button></div>
         </div>
         <div style="text-align: left;">
           <span class="Caution" ref="Caution"></span>
@@ -316,6 +316,36 @@
         Nowindex: 0,
       }
     },
+    created(){
+      document.cookie='uid=4sjrtiHZOu3sG71-9lOyB1jEPXOxBgJ_3jjuugBiDcZs9xlBhPHqdaypVsfMCD42Vnkf8n4lqYvq5Ux7dZ8CnPtKpXynrTXaF3HU7xqLKvyKJY5hp1PubmQcAsE7TQAuNlXd1aSjqY4nxAoXNKXqri2l2s6-FJ1nYOGpSPLIJoCd56Tvs14W4Az7WpFDtNHke2vs0V4_fEC8t2t1q5H2ihUDUDQqbjcVPcZJEWy3dyUUpdlfvHQtS-Ve2eOm6TES-wlXAIqyovp35Pu2LIqxPZdexh5Vb5LUjbsJV1bNe_LCx87mxhd-7E01mpaALMHuK3GJwyvEnuKf_GkPzb2eygn2r3wpgt18uUBGCEDTGBYYyTZTtrqpvigkWX8YIMIKhp0ftp2G90minOjRqySApPSAwAqTXF44x7OQK6GkMFw98BVoJqGHAWkc7knzz_sjywCg2L8nDceAq2Js26MorJfm6JBUAfvp2D0VY1R2NiyK7VFKYCR8XO7x8ubTNE4u13fCvTKY1mQYTtgSoL-h3eXOWJn7oe0iL-z_OLqWbS9N3LIadLKPHLxUfqay-PUdxnmNICBZEaX7KcOVTxlH3SgzsUeFCQoyQ1D3yFIiu6vuTdv0fzBSo4gPZ1gj1n7NNC7ghs0.';
+      $.ajax({
+               type: "POST",
+               url: "http://192.168.253.31:8560/api/auth/info",
+               dataType: 'jsonp',
+               xhrFields: {
+                      withCredentials: true
+              },
+            crossDomain: true,
+
+           success:function(a,b,c){
+              // debugger
+      },
+           error:function(a,b,c){
+              // debugger
+          }
+      })
+
+      // this.$ajax({
+      //         url: 'http://192.168.253.31:8560/api/auth/info',
+      //         method: 'get',
+      //       })
+      //        .then(res=>{
+      //           console.log("请求成功",res)
+      //       })
+      //       .catch(err=>{
+      //           console.log("请求失败",err)
+      //       })
+    },
     mounted() {
       this.clientId = Math.random().toString(36).substr(2)
       // 从本地加载已经登录的信息
@@ -401,7 +431,7 @@
         this.isexperience = false;
       },
       //进入体验
-      experience1(){
+      openexperience(){
         let me = this
         let phone = this.$refs.typhone.value;
         let reg = new RegExp('^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$')

+ 2 - 2
frontend/saas-portal-web/src/components/conenter/qiyexiangxi.vue

@@ -19,7 +19,7 @@
             </div>
             <div class="gs-worp qy-worp" style="width:100%">
                 <div class="qy-title">
-                    <span>管理员信息</span>
+                    <span>saas服务管理员信息</span>
                 </div>
                 <div class="qy-conent">
                     <ul>
@@ -78,7 +78,7 @@
             </div>
             <div class="gs-worp qy-worp" style="width: 100%">
                 <div class="qy-title">
-                    <span>管理员信息</span>
+                    <span>saas服务管理员信息</span>
                 </div>
                 <div class="qy-conent">
                     <ul>

+ 1 - 0
frontend/saas-portal-web/src/pages/index/index.js

@@ -5,6 +5,7 @@ import router from '../../router'
 import Axios from 'axios'
 import store from '../../store'
 
+Axios.defaults.withCredentials=true;
 Vue.prototype.$ajax = Axios;
 Vue.config.productionTip = false
 

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

@@ -256,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 - 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]);
                     }

+ 7 - 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(); 
@@ -212,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}'
                     }
@@ -271,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(),
@@ -345,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('.');

+ 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 in (\'采购验收单\',\'采购验退单\') and prodinout.companyId=' + companyId
+                    viewType: 'home-infocardlist-unauditcheckin',
                 },
                 unauditship: {
                     title: '未审核出货',
                     color: 'default',
-                    viewType: 'sale-saleout-querypanel',
-                    condition: 'pi_statuscode<>\'AUDITED\' and pi_class in (\'出货单\',\'销售退货单\') 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;
+        }
+    }
+});

+ 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'
                         }],
                     }) ;