Преглед изворни кода

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

chenw пре 7 година
родитељ
комит
ff0a3f8a11
100 измењених фајлова са 3588 додато и 717 уклоњено
  1. 9 0
      applications/document/document-dto/src/main/java/com/usoftchina/saas/document/entities/Subledger.java
  2. 1 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/CustomerServiceImpl.java
  3. 1 0
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/VendorServiceImpl.java
  4. 11 1
      applications/document/document-server/src/main/resources/mapper/SubledgerMapper.xml
  5. 20 0
      applications/money/money-dto/src/main/java/com/usoftchina/saas/money/dto/VerificationDTO.java
  6. 37 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Fundtransferdetail.java
  7. 20 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Paybalance.java
  8. 19 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Paybalancedet.java
  9. 19 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Recbalance.java
  10. 19 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Recbalancedet.java
  11. 10 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Subledger.java
  12. 19 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Verification.java
  13. 2 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/OthreceiptsServiceImpl.java
  14. 3 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/PaybalanceServiceImpl.java
  15. 3 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/RecbalanceServiceImpl.java
  16. 1 0
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java
  17. 43 1
      applications/money/money-server/src/main/resources/mapper/FundtransferdetailMapper.xml
  18. 21 1
      applications/money/money-server/src/main/resources/mapper/PaybalanceMapper.xml
  19. 21 1
      applications/money/money-server/src/main/resources/mapper/PaybalancedetMapper.xml
  20. 21 0
      applications/money/money-server/src/main/resources/mapper/RecbalanceMapper.xml
  21. 23 1
      applications/money/money-server/src/main/resources/mapper/RecbalancedetMapper.xml
  22. 11 1
      applications/money/money-server/src/main/resources/mapper/SubledgerMapper.xml
  23. 22 1
      applications/money/money-server/src/main/resources/mapper/VerificationMapper.xml
  24. 4 3
      applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/AccountMapper.java
  25. 2 1
      applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/CompanyMapper.java
  26. 2 1
      applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/CustomerfeedbackMapper.java
  27. 4 1
      applications/operation/operation-server/src/main/resources/config/application-dev.yml
  28. 17 3
      applications/operation/operation-server/src/main/resources/mapper/AccoutMapper.xml
  29. 6 1
      applications/operation/operation-server/src/main/resources/mapper/CompanyMapper.xml
  30. 6 1
      applications/operation/operation-server/src/main/resources/mapper/CustomerfeedbackMapper.xml
  31. 146 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/DeviceDTO.java
  32. 85 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/DeviceReqDTO.java
  33. 5 0
      applications/purchase/purchase-server/pom.xml
  34. 2 1
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/PurchaseApplication.java
  35. 15 0
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/PurchaseController.java
  36. 10 0
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/PurchaseService.java
  37. 63 3
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/impl/PurchaseServiceImpl.java
  38. 5 1
      applications/purchase/purchase-server/src/main/resources/application.yml
  39. 2 1
      applications/transfers/mall-api/src/main/java/com/usoftchina/inquiry/api/SearchApi.java
  40. 13 0
      applications/transfers/transfers-server/pom.xml
  41. 2 2
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/TransfersApplication.java
  42. 3 1
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/controller/TransfersController.java
  43. 20 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/mapper/BrokerMessageLogMapper.java
  44. 29 15
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/BrokerMessagelog.java
  45. 2 13
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/MessageInfo.java
  46. 26 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/Status.java
  47. 45 4
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/service/ReceiveService.java
  48. 51 26
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/service/SendService.java
  49. 22 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/Executable.java
  50. 12 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseInTask.java
  51. 12 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseOutTask.java
  52. 12 0
      applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseTask.java
  53. 14 0
      applications/transfers/transfers-server/src/main/resources/application.yml
  54. 3 0
      applications/transfers/transfers-server/src/main/resources/config/application-dev.yml
  55. 128 0
      applications/transfers/transfers-server/src/main/resources/mapper/BrokermessagelogMapper.xml
  56. 2 2
      applications/transfers/transfers-server/src/test/java/com/usoftchina/saas/transfers/service/RabbitSendServiceTest.java
  57. 3 2
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/AuthRestInterceptor.java
  58. 5 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/ServiceFeignInterceptor.java
  59. 0 3
      frontend/operation-web/app/view/core/List.js
  60. 248 0
      frontend/operation-web/app/view/core/base/BasePanel.js
  61. 97 0
      frontend/operation-web/app/view/core/base/BasePanel.scss
  62. 47 0
      frontend/operation-web/app/view/core/base/BasePanelController.js
  63. 8 0
      frontend/operation-web/app/view/core/base/BasePanelModel.js
  64. 224 0
      frontend/operation-web/app/view/core/base/GridPanel.js
  65. 309 0
      frontend/operation-web/app/view/core/base/ImportWindow.js
  66. 268 0
      frontend/operation-web/app/view/core/form/field/ConDateField.js
  67. 26 0
      frontend/operation-web/app/view/core/form/field/ConDateField.scss
  68. 70 59
      frontend/operation-web/app/view/cuservice/Feedback.js
  69. 0 25
      frontend/operation-web/app/view/cuservice/Models.js
  70. 57 27
      frontend/operation-web/app/view/statistical/CompanyAnalysis.js
  71. 0 57
      frontend/operation-web/app/view/statistical/CompanyInfo.js
  72. 69 0
      frontend/operation-web/app/view/statistical/CompanyRegInfo.js
  73. 42 31
      frontend/operation-web/app/view/statistical/LoginLog.js
  74. 0 63
      frontend/operation-web/app/view/statistical/Models.js
  75. 0 64
      frontend/operation-web/app/view/statistical/PersonInfo.js
  76. 74 0
      frontend/operation-web/app/view/statistical/PersonRegInfo.js
  77. 6 2
      frontend/operation-web/resources/json/navigation.json
  78. 10 6
      frontend/saas-portal-web/src/components/conenter/addenterprise.vue
  79. 8 2
      frontend/saas-portal-web/src/components/conenter/enterprise.vue
  80. 114 4
      frontend/saas-portal-web/src/components/conenter/home.vue
  81. 1 1
      frontend/saas-portal-web/static/css/main.css
  82. BIN
      frontend/saas-portal-web/static/img/weiruan@2x.png
  83. 172 33
      frontend/saas-web/app/view/core/base/BasePanel.js
  84. 0 139
      frontend/saas-web/app/view/core/base/BasePanelController.js
  85. 4 0
      frontend/saas-web/app/view/core/base/BasePanelModel.js
  86. 11 9
      frontend/saas-web/app/view/core/base/GridPanel.js
  87. 2 0
      frontend/saas-web/app/view/core/form/FormPanelModel.js
  88. 1 1
      frontend/saas-web/app/view/core/form/field/DetailGridField.js
  89. 10 10
      frontend/saas-web/app/view/core/query/QueryGridPanel.js
  90. 9 0
      frontend/saas-web/app/view/core/query/QueryPanel.js
  91. 3 1
      frontend/saas-web/app/view/core/query/QueryPanelModel.js
  92. 87 87
      frontend/saas-web/app/view/document/product/BasePanel.js
  93. 217 0
      frontend/saas-web/app/view/sale/business/Business.js
  94. 19 0
      frontend/saas-web/app/view/sale/business/BusinessController.js
  95. 8 0
      frontend/saas-web/app/view/sale/business/BusinessModel.js
  96. 12 0
      frontend/saas-web/app/view/sale/business/MyBusiness.js
  97. 206 0
      frontend/saas-web/app/view/sale/business/QuoteWin.js
  98. 3 3
      frontend/saas-web/electron/package.json
  99. 3 0
      frontend/saas-web/overrides/form/field/Number.js
  100. 9 1
      frontend/saas-web/resources/json/navigation.json

+ 9 - 0
applications/document/document-dto/src/main/java/com/usoftchina/saas/document/entities/Subledger.java

@@ -33,6 +33,15 @@ public class Subledger extends CommonBaseEntity implements Serializable {
     private Double sl_discount;
 
     private Integer sl_ym;
+    private String sl_currency;
+
+    public String getSl_currency() {
+        return sl_currency;
+    }
+
+    public void setSl_currency(String sl_currency) {
+        this.sl_currency = sl_currency;
+    }
 
     public String getSl_code() {
         return sl_code;

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

@@ -322,6 +322,7 @@ public class CustomerServiceImpl extends CommonBaseServiceImpl<CustomerMapper, C
         subledger.setCreateTime(new Date());
         subledger.setCreatorId(BaseContextHolder.getUserId());
         subledger.setCreatorName(BaseContextHolder.getUserName());
+        subledger.setSl_currency(customer.getCu_currency());
         if (amount > new Double(0)){
             subledger.setSl_amount(amount);
             subledger.setSl_preamount(new Double(0));

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

@@ -278,6 +278,7 @@ public class VendorServiceImpl extends CommonBaseServiceImpl<VendorMapper, Vendo
         subledger.setCompanyId(BaseContextHolder.getCompanyId());
         subledger.setSl_date(DateUtils.getFirstDay(main.getVe_begindate()));
         subledger.setSl_ym(DateUtils.getYm(main.getVe_begindate()));
+        subledger.setSl_currency(main.getVe_currency());
         if (amount > new Double(0)){
             subledger.setSl_preamount(new Double(0));
             subledger.setSl_amount(Math.abs(amount));

+ 11 - 1
applications/document/document-server/src/main/resources/mapper/SubledgerMapper.xml

@@ -19,11 +19,12 @@
     <result column="sl_orderamount" property="sl_orderamount" jdbcType="DOUBLE" />
     <result column="sl_discount" property="sl_discount" jdbcType="DOUBLE" />
     <result column="sl_ym" property="sl_ym" jdbcType="INTEGER" />
+    <result column="sl_currency" property="sl_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Base_Column_List" >
     sl_id, sl_code, sl_kind, sl_custid, sl_vendid, sl_date, sl_amount, sl_preamount, 
     sl_yamount, sl_namount, sl_remark, companyId, updaterId, updateTime, sl_orderamount, 
-    sl_discount, sl_ym
+    sl_discount, sl_ym, sl_currency
   </sql>
   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
     select 
@@ -111,6 +112,9 @@
       <if test="creatorName != null" >
         creatorName,
       </if>
+      <if test="sl_currency != null" >
+        sl_currency,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="sl_code != null" >
@@ -170,6 +174,9 @@
       <if test="creatorName != null" >
         #{creatorName,jdbcType=VARCHAR},
       </if>
+      <if test="sl_currency != null" >
+        #{sl_currency,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.document.entities.Subledger" >
@@ -223,6 +230,9 @@
       <if test="sl_ym != null" >
         sl_ym = #{sl_ym,jdbcType=INTEGER},
       </if>
+      <if test="sl_currency != null" >
+        sl_currency = #{sl_currency,jdbcType=INTEGER},
+      </if>
     </set>
     where sl_id = #{id,jdbcType=INTEGER}
   </update>

+ 20 - 0
applications/money/money-dto/src/main/java/com/usoftchina/saas/money/dto/VerificationDTO.java

@@ -72,6 +72,26 @@ public class VerificationDTO extends  CommonBaseDTO implements Serializable {
 
     private String vc_auditman;
 
+    private String vc_currency;
+
+    private Double vc_rate;
+
+    public String getVc_currency() {
+        return vc_currency;
+    }
+
+    public void setVc_currency(String vc_currency) {
+        this.vc_currency = vc_currency;
+    }
+
+    public Double getVc_rate() {
+        return vc_rate;
+    }
+
+    public void setVc_rate(Double vc_rate) {
+        this.vc_rate = vc_rate;
+    }
+
     public Date getVc_auditdate() {
         return vc_auditdate;
     }

+ 37 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Fundtransferdetail.java

@@ -50,6 +50,43 @@ public class Fundtransferdetail extends CommonBaseEntity implements Serializable
     private Double bk_outthisamount;
     private Double bk_inthisamount;
 
+    private String ftd_currency;
+    private String ftd_incurrency;
+    private Double ftd_innowbalance;
+    private Double ftd_rate;
+
+    public String getFtd_currency() {
+        return ftd_currency;
+    }
+
+    public void setFtd_currency(String ftd_currency) {
+        this.ftd_currency = ftd_currency;
+    }
+
+    public String getFtd_incurrency() {
+        return ftd_incurrency;
+    }
+
+    public void setFtd_incurrency(String ftd_incurrency) {
+        this.ftd_incurrency = ftd_incurrency;
+    }
+
+    public Double getFtd_innowbalance() {
+        return ftd_innowbalance;
+    }
+
+    public void setFtd_innowbalance(Double ftd_innowbalance) {
+        this.ftd_innowbalance = ftd_innowbalance;
+    }
+
+    public Double getFtd_rate() {
+        return ftd_rate;
+    }
+
+    public void setFtd_rate(Double ftd_rate) {
+        this.ftd_rate = ftd_rate;
+    }
+
     public Double getBk_outthisamount() {
         return bk_outthisamount;
     }

+ 20 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Paybalance.java

@@ -83,6 +83,26 @@ public class Paybalance extends CommonBaseEntity implements Serializable {
 
     private Double pb_amount;
 
+    private String pb_currency;
+
+    private Double pb_rate;
+
+    public String getPb_currency() {
+        return pb_currency;
+    }
+
+    public void setPb_currency(String pb_currency) {
+        this.pb_currency = pb_currency;
+    }
+
+    public Double getPb_rate() {
+        return pb_rate;
+    }
+
+    public void setPb_rate(Double pb_rate) {
+        this.pb_rate = pb_rate;
+    }
+
     public Double getPb_amount() {
         return pb_amount;
     }

+ 19 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Paybalancedet.java

@@ -39,6 +39,25 @@ public class Paybalancedet extends CommonBaseEntity implements Serializable {
 
     private String pd_text5;
     private Date pb_date;
+    private String pd_currency;
+
+    private Double pd_rate;
+
+    public String getPd_currency() {
+        return pd_currency;
+    }
+
+    public void setPd_currency(String pd_currency) {
+        this.pd_currency = pd_currency;
+    }
+
+    public Double getPd_rate() {
+        return pd_rate;
+    }
+
+    public void setPd_rate(Double pd_rate) {
+        this.pd_rate = pd_rate;
+    }
 
     public Date getPb_date() {
         return pb_date;

+ 19 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Recbalance.java

@@ -82,6 +82,25 @@ public class Recbalance extends CommonBaseEntity implements Serializable {
     private Date rb_auditdate;
 
     private Double rb_amount;
+    private String rb_currency;
+
+    private Double rb_rate;
+
+    public String getRb_currency() {
+        return rb_currency;
+    }
+
+    public void setRb_currency(String rb_currency) {
+        this.rb_currency = rb_currency;
+    }
+
+    public Double getRb_rate() {
+        return rb_rate;
+    }
+
+    public void setRb_rate(Double rb_rate) {
+        this.rb_rate = rb_rate;
+    }
 
     public Double getRb_amount() {
         return rb_amount;

+ 19 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Recbalancedet.java

@@ -45,6 +45,25 @@ public class Recbalancedet extends CommonBaseEntity implements Serializable{
 
     private String rd_text5;
     private Date rb_date;
+    private String rd_currency;
+
+    private Double rd_rate;
+
+    public String getRd_currency() {
+        return rd_currency;
+    }
+
+    public void setRd_currency(String rd_currency) {
+        this.rd_currency = rd_currency;
+    }
+
+    public Double getRd_rate() {
+        return rd_rate;
+    }
+
+    public void setRd_rate(Double rd_rate) {
+        this.rd_rate = rd_rate;
+    }
 
     public Date getRb_date() {
         return rb_date;

+ 10 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Subledger.java

@@ -35,6 +35,16 @@ public class Subledger extends CommonBaseEntity implements Serializable {
 
     private Integer sl_ym;
 
+    private String sl_currency;
+
+    public String getSl_currency() {
+        return sl_currency;
+    }
+
+    public void setSl_currency(String sl_currency) {
+        this.sl_currency = sl_currency;
+    }
+
     public String getSl_code() {
         return sl_code;
     }

+ 19 - 0
applications/money/money-server/src/main/java/com/usoftchina/saas/money/po/Verification.java

@@ -68,6 +68,25 @@ public class Verification extends CommonBaseEntity implements Serializable {
     private Date vc_auditdate;
 
     private String vc_auditman;
+    private String vc_currency;
+
+    private Double vc_rate;
+
+    public String getVc_currency() {
+        return vc_currency;
+    }
+
+    public void setVc_currency(String vc_currency) {
+        this.vc_currency = vc_currency;
+    }
+
+    public Double getVc_rate() {
+        return vc_rate;
+    }
+
+    public void setVc_rate(Double vc_rate) {
+        this.vc_rate = vc_rate;
+    }
 
     public Date getVc_auditdate() {
         return vc_auditdate;

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

@@ -104,6 +104,8 @@ public class OthreceiptsServiceImpl extends CommonBaseServiceImpl<OthreceiptsMap
             othreceiptsdetail1.setOr_date(othreceipts.getOr_date());
             othreceiptsdetail1.setOrd_currency(othreceipts.getOr_currency());
             othreceiptsdetail1.setOrd_rate(othreceipts.getOr_rate());
+            othreceiptsdetail1.setOrd_currency(othreceipts.getOr_currency());
+            othreceiptsdetail1.setOrd_rate(othreceipts.getOr_rate());
             if (othreceiptsdetail1.getId() > 0 ){
                 othreceiptsdetailMapper.updateByPrimaryKeySelective(othreceiptsdetail1);
             }else {

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

@@ -101,6 +101,8 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
             paybalancedet1.setPd_pbid(Math.toIntExact(pbId));
             paybalancedet1.setCompanyId(BaseContextHolder.getCompanyId());
             paybalancedet1.setPb_date(paybalance.getPb_date());
+            paybalancedet1.setPd_currency(paybalance.getPb_currency());
+            paybalancedet1.setPd_rate(paybalance.getPb_rate());
             if (paybalancedet1.getId() > 0 ){
                 paybalancedetMapper.updateByPrimaryKeySelective(paybalancedet1);
             }else {
@@ -563,6 +565,7 @@ public class PaybalanceServiceImpl extends CommonBaseServiceImpl<PaybalanceMappe
         Double pbdamount = paybalance.getPb_pbdamount()==null?new Double(0):paybalance.getPb_pbdamount();
         subledger.setSl_amount(-pbdamount);
         subledger.setSl_orderamount(pdamount);
+        subledger.setSl_currency(paybalance.getPb_currency());
 
         if(preamount!=0){
             subledger.setSl_yamount(pbdamount);

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

@@ -102,6 +102,8 @@ public class RecbalanceServiceImpl extends CommonBaseServiceImpl<RecbalanceMappe
             recbalancedet1.setRd_rbid(Math.toIntExact(rbId));
             recbalancedet1.setCompanyId(BaseContextHolder.getCompanyId());
             recbalancedet1.setRb_date(recbalance.getRb_date());
+            recbalancedet1.setRd_currency(recbalance.getRb_currency());
+            recbalancedet1.setRd_rate(recbalance.getRb_rate());
             if (recbalancedet1.getId() > 0 ){
                 recbalancedetMapper.updateByPrimaryKeySelective(recbalancedet1);
             }else {
@@ -573,6 +575,7 @@ public class RecbalanceServiceImpl extends CommonBaseServiceImpl<RecbalanceMappe
         Double rbdamount = recbalance.getRb_rbdamount()==null?new Double(0):recbalance.getRb_rbdamount();
         subledger.setSl_amount(-rbdamount);
         subledger.setSl_orderamount(rdamount);
+        subledger.setSl_currency(recbalance.getRb_currency());
 
         if(preamount!=0){
             subledger.setSl_yamount(rbdamount);

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

@@ -277,6 +277,7 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
         String kind = verification.getVc_kind();
         subledger.setCompanyId(BaseContextHolder.getCompanyId());
         subledger.setSl_code(verification.getVc_code());
+        subledger.setSl_currency(verification.getVc_currency());
         Double amount1 = verification.getVc_amount1()==null?new Double(0):verification.getVc_amount1();
         Double amount2 = verification.getVc_amount2()==null?new Double(0):verification.getVc_amount2();
 

+ 43 - 1
applications/money/money-server/src/main/resources/mapper/FundtransferdetailMapper.xml

@@ -27,11 +27,17 @@
     <result column="ftd_text5" property="ftd_text5" jdbcType="VARCHAR" />
       <result column="bk_outthisamount" property="bk_outthisamount" jdbcType="DOUBLE" />
       <result column="bk_inthisamount" property="bk_inthisamount" jdbcType="DOUBLE" />
+
+    <result column="ftd_currency" property="ftd_currency" jdbcType="VARCHAR" />
+    <result column="ftd_incurrency" property="ftd_incurrency" jdbcType="VARCHAR" />
+    <result column="ftd_innowbalance" property="ftd_innowbalance" jdbcType="DOUBLE" />
+    <result column="ftd_rate" property="ftd_rate" jdbcType="DOUBLE" />
   </resultMap>
   <sql id="Base_Column_List" >
     ftd_id, ftd_ftid, ftd_detno, ftd_ym, ftd_bankid, ftd_bankcode, ftd_bankname, ftd_inbankid, 
     ftd_inbankcode, ftd_inbankname, ftd_nowbalance, ftd_paymethod, ftd_paycode, ftd_remark, 
-    companyid, updaterId, updatedate, ftd_text1, ftd_text2, ftd_text3, ftd_text4, ftd_text5
+    companyid, updaterId, updatedate, ftd_text1, ftd_text2, ftd_text3, ftd_text4, ftd_text5, ftd_currency,
+    ftd_incurrency,ftd_innowbalance,ftd_rate
   </sql>
     <sql id="Bank_Column_List">
         b.bk_thisamount as bk_outthisamount,c.bk_thisamount as bk_inthisamount
@@ -147,6 +153,18 @@
       <if test="ftd_text5 != null" >
         ftd_text5,
       </if>
+      <if test="ftd_currency != null" >
+        ftd_currency,
+      </if>
+      <if test="ftd_incurrency != null" >
+        ftd_incurrency,
+      </if>
+      <if test="ftd_innowbalance != null" >
+        ftd_innowbalance,
+      </if>
+      <if test="ftd_rate != null" >
+        ftd_rate,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="ftd_ftid != null" >
@@ -212,6 +230,18 @@
       <if test="ftd_text5 != null" >
         #{ftd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="ftd_currency != null" >
+        #{ftd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="ftd_incurrency != null" >
+        #{ftd_incurrency,jdbcType=VARCHAR},
+      </if>
+      <if test="ftd_innowbalance != null" >
+        #{ftd_innowbalance,jdbcType=DOUBLE},
+      </if>
+      <if test="ftd_rate != null" >
+        #{ftd_rate,jdbcType=DOUBLE},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.money.po.Fundtransferdetail" >
@@ -278,6 +308,18 @@
       <if test="ftd_text5 != null" >
         ftd_text5 = #{ftd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="ftd_currency != null" >
+        ftd_currency = #{ftd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="ftd_incurrency != null" >
+        ftd_incurrency = #{ftd_incurrency,jdbcType=VARCHAR},
+      </if>
+      <if test="ftd_innowbalance != null" >
+        ftd_innowbalance = #{ftd_innowbalance,jdbcType=DOUBLE},
+      </if>
+      <if test="ftd_rate != null" >
+        ftd_rate = #{ftd_rate,jdbcType=DOUBLE},
+      </if>
     </set>
     where ftd_id = #{id,jdbcType=INTEGER}
   </update>

+ 21 - 1
applications/money/money-server/src/main/resources/mapper/PaybalanceMapper.xml

@@ -43,6 +43,8 @@
     <result column="pb_auditman" property="pb_auditman" jdbcType="VARCHAR" />
     <result column="pb_amount" property="pb_amount" jdbcType="DOUBLE" />
     <result column="pd_paycode" property="pd_paycode" jdbcType="VARCHAR" />
+    <result column="pb_rate" property="pb_rate" jdbcType="DOUBLE" />
+    <result column="pb_currency" property="pb_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -107,7 +109,7 @@
     pb_pdamount, pb_pbdamount, pb_preamount, pb_discounts, pb_havebalance,
      pb_status, pb_statuscode, pb_remark, paybalance.companyId,
     paybalance.updaterId,paybalance.updatedate, pb_text1, pb_text2, pb_text3, pb_text4, pb_text5, paybalance.creatorName,
-    paybalance.createTime, pb_auditdate, pb_auditman,pb_amount
+    paybalance.createTime, pb_auditdate, pb_auditman,pb_amount,pb_rate,pb_currency
   </sql>
   <sql id="left_Column_List">
     ve_leftamount
@@ -241,6 +243,12 @@
       <if test="pb_amount != null" >
         pb_amount,
       </if>
+      <if test="pb_currency != null">
+        pb_currency,
+      </if>
+      <if test="pb_rate != null">
+        pb_rate,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="pb_code != null">
@@ -318,6 +326,12 @@
       <if test="pb_amount != null" >
         #{pb_amount,jdbcType=DOUBLE},
       </if>
+      <if test="pb_currency != null">
+        #{pb_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="pb_rate != null">
+        #{pb_rate,jdbcType=DOUBLE},
+      </if>
     </trim>
     <selectKey resultType="Long" keyProperty="id" order="AFTER">
       SELECT LAST_INSERT_ID()
@@ -401,6 +415,12 @@
       </if>
       <if test="pb_amount != null">
         pb_amount = #{pb_amount,jdbcType=DOUBLE},
+      </if>
+      <if test="pb_currency != null">
+        pb_currency = #{pb_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="pb_rate != null">
+        pb_rate = #{pb_rate,jdbcType=DOUBLE},
       </if>
         pb_auditman = #{pb_auditman,jdbcType=VARCHAR},
         pb_auditdate = #{pb_auditdate,jdbcType=TIMESTAMP}

+ 21 - 1
applications/money/money-server/src/main/resources/mapper/PaybalancedetMapper.xml

@@ -22,11 +22,13 @@
     <result column="pd_text3" property="pd_text3" jdbcType="VARCHAR" />
     <result column="pd_text4" property="pd_text4" jdbcType="VARCHAR" />
     <result column="pd_text5" property="pd_text5" jdbcType="VARCHAR" />
+    <result column="pd_rate" property="pd_rate" jdbcType="DOUBLE" />
+    <result column="pd_currency" property="pd_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Base_Column_List" >
     pd_id, pd_pbid, pd_detno, pd_ym, pd_bankid, pd_bankcode, pd_bankname, pd_amount,
     pd_paymethod, pd_paycode, pd_remark, companyId, updaterId, updatedate, pd_text1, 
-    pd_text2, pd_text3, pd_text4, pd_text5
+    pd_text2, pd_text3, pd_text4, pd_text5,pd_rate,pd_currency
   </sql>
   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
     select 
@@ -119,6 +121,12 @@
       <if test="pd_text5 != null" >
         pd_text5,
       </if>
+      <if test="pd_currency != null">
+        pd_currency,
+      </if>
+      <if test="pd_rate != null">
+        pd_rate,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="pd_pbid != null" >
@@ -175,6 +183,12 @@
       <if test="pd_text5 != null" >
         #{pd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="pd_currency != null">
+        #{pd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="pd_rate != null">
+        #{pd_rate,jdbcType=DOUBLE},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.money.po.Paybalancedet" >
@@ -234,6 +248,12 @@
       <if test="pd_text5 != null" >
         pd_text5 = #{pd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="pd_currency != null">
+        pd_currency = #{pd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="pd_rate != null">
+        pd_rate = #{pd_rate,jdbcType=DOUBLE},
+      </if>
     </set>
     where pd_id = #{id,jdbcType=INTEGER}
   </update>

+ 21 - 0
applications/money/money-server/src/main/resources/mapper/RecbalanceMapper.xml

@@ -43,6 +43,9 @@
     <result column="rb_auditdate" property="rb_auditdate" jdbcType="TIMESTAMP" />
     <result column="rb_amount" property="rb_amount" jdbcType="DOUBLE" />
     <result column="rd_paycode" property="rd_paycode" jdbcType="VARCHAR" />
+
+    <result column="rb_rate" property="rb_rate" jdbcType="DOUBLE" />
+    <result column="rb_currency" property="rb_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -284,6 +287,12 @@
       <if test="rb_amount != null">
         rb_amount,
       </if>
+      <if test="rb_currency != null">
+        rb_currency,
+      </if>
+      <if test="rb_rate != null">
+      rb_rate,
+    </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="rb_code != null">
@@ -361,6 +370,12 @@
       <if test="rb_amount != null">
         #{rb_amount,jdbcType=DOUBLE},
       </if>
+      <if test="rb_currency != null">
+        #{rb_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="rb_rate != null">
+        #{rb_rate,jdbcType=DOUBLE},
+      </if>
     </trim>
     <selectKey resultType="Long" keyProperty="id" order="AFTER">
       SELECT LAST_INSERT_ID()
@@ -556,6 +571,12 @@
       </if>
       <if test="rb_amount != null">
         rb_amount = #{rb_amount,jdbcType=DOUBLE},
+      </if>
+      <if test="rb_currency != null">
+        rb_currency = #{rb_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="rb_rate != null">
+        rb_rate = #{rb_rate,jdbcType=DOUBLE},
       </if>
         rb_auditman = #{rb_auditman,jdbcType=VARCHAR},
       rb_auditdate = #{rb_auditdate,jdbcType=TIMESTAMP}

+ 23 - 1
applications/money/money-server/src/main/resources/mapper/RecbalancedetMapper.xml

@@ -22,6 +22,10 @@
     <result column="rd_text3" jdbcType="VARCHAR" property="rd_text3" />
     <result column="rd_text4" jdbcType="VARCHAR" property="rd_text4" />
     <result column="rd_text5" jdbcType="VARCHAR" property="rd_text5" />
+    <result column="rd_amount" property="rd_amount" jdbcType="DOUBLE" />
+    <result column="rd_paycode" property="rd_paycode" jdbcType="VARCHAR" />
+    <result column="rd_rate" property="rd_rate" jdbcType="DOUBLE" />
+    <result column="rd_currency" property="rd_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -84,7 +88,7 @@
   <sql id="Base_Column_List">
     rd_id, rd_rbid, rd_detno, rd_ym, rd_bankid, rd_bankcode, rd_bankname, rd_amount, 
     rd_paymethod, rd_paycode, rd_remark, companyId, updaterId, updatedate, rd_text1,
-    rd_text2, rd_text3, rd_text4, rd_text5
+    rd_text2, rd_text3, rd_text4, rd_text5,rd_currency,rd_rate
   </sql>
   <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
     select 
@@ -175,6 +179,12 @@
       <if test="rd_text5 != null">
         rd_text5,
       </if>
+      <if test="rd_currency != null">
+        rd_currency,
+      </if>
+      <if test="rd_rate != null">
+        rd_rate,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="rd_rbid != null">
@@ -231,6 +241,12 @@
       <if test="rd_text5 != null">
         #{rd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="rd_currency != null">
+        #{rd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="rd_rate != null">
+        #{rd_rate,jdbcType=DOUBLE},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.money.po.Recbalancedet">
@@ -287,6 +303,12 @@
       <if test="rd_text5 != null">
         rd_text5 = #{rd_text5,jdbcType=VARCHAR},
       </if>
+      <if test="rd_currency != null">
+        rd_currency = #{rd_currency,jdbcType=VARCHAR},
+      </if>
+      <if test="rd_rate != null">
+        rd_rate = #{rd_rate,jdbcType=DOUBLE},
+      </if>
     </set>
     where rd_id = #{id,jdbcType=INTEGER}
   </update>

+ 11 - 1
applications/money/money-server/src/main/resources/mapper/SubledgerMapper.xml

@@ -19,12 +19,13 @@
     <result column="sl_orderamount" property="sl_orderamount" jdbcType="DOUBLE" />
     <result column="sl_discount" property="sl_discount" jdbcType="DOUBLE" />
     <result column="sl_ym" property="sl_ym" jdbcType="INTEGER" />
+    <result column="sl_currency" property="sl_currency" jdbcType="VARCHAR" />
   </resultMap>
 
   <sql id="Base_Column_List" >
     sl_id, sl_code, sl_kind, sl_custid, sl_vendid, sl_date, sl_amount, sl_preamount, 
     sl_yamount, sl_namount, sl_remark, companyId, updaterId, updateTime, sl_orderamount, 
-    sl_discount, sl_ym
+    sl_discount, sl_ym, sl_currency
   </sql>
   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
     select 
@@ -102,6 +103,9 @@
       <if test="sl_ym != null" >
         sl_ym,
       </if>
+      <if test="sl_currency != null" >
+        sl_currency,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="sl_code != null" >
@@ -152,6 +156,9 @@
       <if test="sl_ym != null" >
         #{sl_ym,jdbcType=INTEGER},
       </if>
+      <if test="sl_currency != null" >
+        #{sl_currency,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.money.po.Subledger" >
@@ -205,6 +212,9 @@
       <if test="sl_ym != null" >
         sl_ym = #{sl_ym,jdbcType=INTEGER},
       </if>
+      <if test="sl_currency != null" >
+        sl_currency = #{sl_currency,jdbcType=VARCHAR},
+      </if>
     </set>
     where sl_id = #{id,jdbcType=INTEGER}
   </update>

+ 22 - 1
applications/money/money-server/src/main/resources/mapper/VerificationMapper.xml

@@ -35,6 +35,9 @@
     <result column="vc_auditdate" property="vc_auditdate" jdbcType="TIMESTAMP" />
     <result column="creatorName" property="creatorName" jdbcType="VARCHAR" />
     <result column="createTime" property="createTime" jdbcType="TIMESTAMP" />
+
+    <result column="vc_rate" property="vc_rate" jdbcType="DOUBLE" />
+    <result column="vc_currency" property="vc_currency" jdbcType="VARCHAR" />
   </resultMap>
   <sql id="Example_Where_Clause" >
     <where >
@@ -98,7 +101,7 @@
     vc_id, vc_code, vc_kind, vc_date, vc_vendid, vc_vendcode, vc_vendname, vc_custid, 
     vc_custcode, vc_custname, vc_turnvendid, vc_turnvendcode, vc_turnvendname, vc_turncustid, 
     vc_turncustcode, vc_turncustname, vc_amount1, vc_amount2, vc_status, vc_statuscode, vc_remark, companyId, updaterId, updateTime,
-    vc_text1, vc_text2, vc_text3, vc_text4, vc_text5, vc_auditman, vc_auditdate, createTime, creatorName
+    vc_text1, vc_text2, vc_text3, vc_text4, vc_text5, vc_auditman, vc_auditdate, createTime, creatorName,vc_currency,vc_rate
   </sql>
   <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.usoftchina.saas.money.po.VerificationExample" >
     select
@@ -245,6 +248,12 @@
       <if test="createTime != null" >
         createTime,
       </if>
+      <if test="vc_currency != null" >
+        vc_currency,
+      </if>
+      <if test="vc_rate != null" >
+        vc_rate,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="vc_code != null" >
@@ -337,6 +346,12 @@
       <if test="createTime != null" >
         #{createTime,jdbcType=TIMESTAMP},
       </if>
+      <if test="vc_rate != null" >
+        #{vc_rate,jdbcType=DOUBLE},
+      </if>
+      <if test="vc_currency != null" >
+        #{vc_currency,jdbcType=VARCHAR},
+      </if>
     </trim>
     <selectKey resultType="Long" keyProperty="id" order="AFTER">
       SELECT LAST_INSERT_ID()
@@ -564,6 +579,12 @@
       </if>
       <if test="vc_text5 != null" >
         vc_text5 = #{vc_text5,jdbcType=VARCHAR},
+      </if>
+      <if test="vc_rate != null" >
+        vc_rate = #{vc_rate,jdbcType=DOUBLE},
+      </if>
+      <if test="vc_currency != null" >
+        vc_currency = #{vc_currency,jdbcType=VARCHAR},
       </if>
         vc_auditman = #{vc_auditman,jdbcType=VARCHAR},
         vc_auditdate = #{vc_auditdate,jdbcType=TIMESTAMP}

+ 4 - 3
applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/AccountMapper.java

@@ -3,16 +3,17 @@ package com.usoftchina.saas.operation.mapper;
 import com.usoftchina.saas.operation.dto.AccountDTO;
 import com.usoftchina.saas.operation.dto.CompanyAnalyzeDTO;
 import com.usoftchina.saas.operation.dto.LoginDTO;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
 public interface AccountMapper {
 
-    List<AccountDTO> findAccountByCondition(String con);
+    List<AccountDTO> findAccountByCondition(@Param("con") String con);
 
-    List<LoginDTO> getLogin(String con);
+    List<LoginDTO> getLogin(@Param("con") String con);
 
-    List<CompanyAnalyzeDTO> getConpanyAnalyze(String con);
+    List<CompanyAnalyzeDTO> getConpanyAnalyze(@Param("con") String con);
 
     void analyzeCompany();
 }

+ 2 - 1
applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/CompanyMapper.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.operation.mapper;
 import com.usoftchina.saas.operation.dto.CompanyAnalyzeDTO;
 import com.usoftchina.saas.operation.dto.CompanyAnalyzedetailDTO;
 import com.usoftchina.saas.operation.dto.CompanyDTO;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -13,7 +14,7 @@ import java.util.Map;
  **/
 public interface CompanyMapper {
 
-    List<CompanyDTO> findCompanyByCondition(String con);
+    List<CompanyDTO> findCompanyByCondition(@Param("con") String con);
 
     CompanyAnalyzeDTO selectCompanyAnalyze(Long id);
 

+ 2 - 1
applications/operation/operation-server/src/main/java/com/usoftchina/saas/operation/mapper/CustomerfeedbackMapper.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.operation.mapper;
 
 import com.usoftchina.saas.operation.po.CustomerFeedBack;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -17,5 +18,5 @@ public interface CustomerfeedbackMapper {
 
     int updateByPrimaryKey(CustomerFeedBack record);
 
-    List<CustomerFeedBack> selectByCondition(String con);
+    List<CustomerFeedBack> selectByCondition(@Param("con") String con);
 }

+ 4 - 1
applications/operation/operation-server/src/main/resources/config/application-dev.yml

@@ -10,4 +10,7 @@ eureka:
   client:
     registryFetchIntervalSeconds: 5
     serviceUrl:
-      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+logging:
+  level:
+    com.usoftchina.saas.operation.mapper : debug

+ 17 - 3
applications/operation/operation-server/src/main/resources/mapper/AccoutMapper.xml

@@ -38,15 +38,29 @@
     </resultMap>
 
     <select id="findAccountByCondition" parameterType="string" resultMap="BaseResultMap">
-        select * from saas_account.ac_account  where #{con}
+        select * from saas_account.ac_account  <where>
+        <if test="con != null">
+            ${con}
+        </if>
+    </where>
     </select>
     <select id="getLogin" parameterType="string" resultMap="loginMap">
         SELECT * FROM (select account_id  ,count(account_id) login_num,max(ac_account.realname) username,max(login_time) lastesttime, max(ac_account.mobile) mobile from au_authorize_log left join saas_account.ac_account on account_id= ac_account.id  where login_time >  date_sub(now(),interval 3 MONTH) GROUP BY account_id order by lastesttime desc
-        )login_info where #{con}
+        )login_info
+        <where>
+            <if test="con != null">
+                ${con}
+            </if>
+        </where>
     </select>
 
     <select id="getConpanyAnalyze" parameterType="string" resultMap="companymap">
-        select  *  from company_analyze  where #{con} order by ca_createtime desc
+        select  *  from company_analyze  <where>
+        <if test="con != null">
+            ${con}
+        </if>
+    </where>
+        order by ca_createtime desc
     </select>
 
     <select id="analyzeCompany"  statementType="CALLABLE">

+ 6 - 1
applications/operation/operation-server/src/main/resources/mapper/CompanyMapper.xml

@@ -15,7 +15,12 @@
 
     <select id="findCompanyByCondition" parameterType="string" resultMap="baseMap">
          select name,business_code,address,tel,fax,realname,mobile,ac_company.create_time,ac_company.uu from saas_account.ac_company
-        left join saas_account.ac_account on ac_account.id = ac_company.creator_id where #{con}
+        left join saas_account.ac_account on ac_account.id = ac_company.creator_id
+        <where>
+            <if test="con != null">
+                ${con}
+            </if>
+        </where>
     </select>
 
 

+ 6 - 1
applications/operation/operation-server/src/main/resources/mapper/CustomerfeedbackMapper.xml

@@ -165,6 +165,11 @@
     where cf_id = #{cf_id,jdbcType=INTEGER}
   </update>
   <select id="selectByCondition" parameterType="string" resultMap="BaseResultMap">
-      select * from saas_manage.customerfeedback where #{con} order by cf_creatime desc
+      select * from saas_manage.customerfeedback
+    <where>
+    <if test="con != null">
+      ${con}
+    </if>
+  </where> order by cf_creatime desc
   </select>
 </mapper>

+ 146 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/DeviceDTO.java

@@ -0,0 +1,146 @@
+package com.usoftchina.saas.purchase.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by hey
+ * 2018-10-17 13:44.
+ */
+@Data
+public class DeviceDTO implements Serializable {
+
+    /**
+     * 品牌
+     */
+    private String pr_brand;
+    /**
+     * 名称
+     */
+    private String pr_detail;
+    /**
+     * 型号
+     */
+    private String pr_orispeccode;
+    /**
+     * 规格
+     */
+    private String pr_spec;
+    /**
+     * 包装
+     */
+    private String pr_pack;
+    /**
+     * 供应商
+     */
+    private String pr_vendor;
+    /**
+     * 库存
+     */
+    private Double pr_qty;
+    /**
+     * 梯度
+     */
+    private Double pr_level;
+    /**
+     * 大陆交货单价
+     */
+    private Double pr_cnprice;
+    /**
+     * 香港交货单价
+     */
+    private Double pr_hkprice;
+    /**
+     * 交期
+     */
+    private Double pr_leadtime;
+
+    public String getPr_brand() {
+        return pr_brand;
+    }
+
+    public void setPr_brand(String pr_brand) {
+        this.pr_brand = pr_brand;
+    }
+
+    public String getPr_detail() {
+        return pr_detail;
+    }
+
+    public void setPr_detail(String pr_detail) {
+        this.pr_detail = pr_detail;
+    }
+
+    public String getPr_orispeccode() {
+        return pr_orispeccode;
+    }
+
+    public void setPr_orispeccode(String pr_orispeccode) {
+        this.pr_orispeccode = pr_orispeccode;
+    }
+
+    public String getPr_spec() {
+        return pr_spec;
+    }
+
+    public void setPr_spec(String pr_spec) {
+        this.pr_spec = pr_spec;
+    }
+
+    public String getPr_vendor() {
+        return pr_vendor;
+    }
+
+    public void setPr_vendor(String pr_vendor) {
+        this.pr_vendor = pr_vendor;
+    }
+
+    public Double getPr_qty() {
+        return pr_qty;
+    }
+
+    public void setPr_qty(Double pr_qty) {
+        this.pr_qty = pr_qty;
+    }
+
+    public Double getPr_level() {
+        return pr_level;
+    }
+
+    public void setPr_level(Double pr_level) {
+        this.pr_level = pr_level;
+    }
+
+    public Double getPr_cnprice() {
+        return pr_cnprice;
+    }
+
+    public void setPr_cnprice(Double pr_cnprice) {
+        this.pr_cnprice = pr_cnprice;
+    }
+
+    public Double getPr_hkprice() {
+        return pr_hkprice;
+    }
+
+    public void setPr_hkprice(Double pr_hkprice) {
+        this.pr_hkprice = pr_hkprice;
+    }
+
+    public Double getPr_leadtime() {
+        return pr_leadtime;
+    }
+
+    public void setPr_leadtime(Double pr_leadtime) {
+        this.pr_leadtime = pr_leadtime;
+    }
+
+    public String getPr_pack() {
+        return pr_pack;
+    }
+
+    public void setPr_pack(String pr_pack) {
+        this.pr_pack = pr_pack;
+    }
+}

+ 85 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/DeviceReqDTO.java

@@ -0,0 +1,85 @@
+package com.usoftchina.saas.purchase.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by hey
+ * 2018-10-17 13:44.
+ */
+@Data
+public class DeviceReqDTO implements Serializable {
+    /**
+     * 页码
+     */
+    private int page;
+    /**
+     * 每页条数
+     */
+    private int count;
+    /**
+     * 搜索类型
+     */
+    private String type = "component";
+    /**
+     * 搜索关键字
+     */
+    private String keyword;
+    /**
+     * 过滤
+     */
+    private String filter;
+    /**
+     * 排序
+     */
+    private String sorting;
+
+    public int getPage() {
+        return page;
+    }
+
+    public void setPage(int page) {
+        this.page = page;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public String getFilter() {
+        return filter;
+    }
+
+    public void setFilter(String filter) {
+        this.filter = filter;
+    }
+
+    public String getSorting() {
+        return sorting;
+    }
+
+    public void setSorting(String sorting) {
+        this.sorting = sorting;
+    }
+}

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

@@ -29,6 +29,11 @@
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>server-starter</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>mall-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
 
         <!--test-->
         <dependency>

+ 2 - 1
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/PurchaseApplication.java

@@ -17,7 +17,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 @SpringBootApplication
 @EnableEurekaClient
 @EnableTransactionManagement
-@EnableFeignClients("com.usoftchina.saas")
+@EnableFeignClients({"com.usoftchina.saas",
+                     "com.usoftchina.inquiry"})
 @EnableAuthClient
 @MapperScan("com.usoftchina.saas.purchase.mapper")
 @EnableDynamicDataSource

+ 15 - 0
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/PurchaseController.java

@@ -1,11 +1,15 @@
 package com.usoftchina.saas.purchase.controller;
 
+
 import com.github.pagehelper.PageInfo;
+import com.usoftchina.inquiry.po.inquiry.IPage;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
 import com.usoftchina.saas.page.PageRequest;
+import com.usoftchina.saas.purchase.dto.DeviceDTO;
+import com.usoftchina.saas.purchase.dto.DeviceReqDTO;
 import com.usoftchina.saas.purchase.dto.PurchaseFormDTO;
 import com.usoftchina.saas.purchase.po.PurchaseList;
 import com.usoftchina.saas.purchase.service.PurchaseService;
@@ -178,4 +182,15 @@ public class PurchaseController {
     public String getPurchaseCode(@RequestBody DocBaseDTO baseDTO) {
         return purchaseService.getPurchaseCode(baseDTO);
     }
+
+    /**
+     * 获取器件列表
+     *
+     * @return
+     */
+    @GetMapping("/device/list")
+    public Result getDevice(DeviceReqDTO deviceReqDTO){
+        IPage<DeviceDTO> deviceDTOIPage = purchaseService.getDevice(deviceReqDTO);
+        return Result.success(deviceDTOIPage);
+    }
 }

+ 10 - 0
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/PurchaseService.java

@@ -1,12 +1,15 @@
 package com.usoftchina.saas.purchase.service;
 
 import com.github.pagehelper.PageInfo;
+import com.usoftchina.inquiry.po.inquiry.IPage;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.base.service.CommonBaseService;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
 import com.usoftchina.saas.page.PageRequest;
+import com.usoftchina.saas.purchase.dto.DeviceDTO;
+import com.usoftchina.saas.purchase.dto.DeviceReqDTO;
 import com.usoftchina.saas.purchase.dto.PurchaseFormDTO;
 import com.usoftchina.saas.purchase.mapper.PurchaseMapper;
 import com.usoftchina.saas.purchase.po.Purchase;
@@ -137,4 +140,11 @@ public interface PurchaseService extends CommonBaseService<PurchaseMapper, Purch
     Result turnProdin(Long id);
 
     String getPurchaseCode(DocBaseDTO baseDTO);
+
+    /**
+     * 器件查询
+     * @param deviceReqDTO
+     * @return
+     */
+    IPage<DeviceDTO> getDevice(DeviceReqDTO deviceReqDTO);
 }

+ 63 - 3
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/impl/PurchaseServiceImpl.java

@@ -2,6 +2,13 @@ package com.usoftchina.saas.purchase.service.impl;
 
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.usoftchina.inquiry.api.SearchApi;
+import com.usoftchina.inquiry.po.inquiry.IPage;
+import com.usoftchina.inquiry.po.inquiry.InquiryEnRemind;
+import com.usoftchina.inquiry.po.inquiry.InquiryRemind;
+import com.usoftchina.inquiry.po.search.FuturesEntity;
+import com.usoftchina.inquiry.po.search.ProductEntity;
+import com.usoftchina.inquiry.po.search.SearchComponentResp;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
 import com.usoftchina.saas.commons.api.CommonService;
@@ -18,14 +25,15 @@ import com.usoftchina.saas.context.BaseContextHolder;
 import com.usoftchina.saas.exception.BizException;
 import com.usoftchina.saas.exception.ExceptionCode;
 import com.usoftchina.saas.page.PageRequest;
-import com.usoftchina.saas.purchase.dto.PurchaseDTO;
-import com.usoftchina.saas.purchase.dto.PurchaseDetailDTO;
-import com.usoftchina.saas.purchase.dto.PurchaseFormDTO;
+import com.usoftchina.saas.purchase.dto.*;
 import com.usoftchina.saas.purchase.mapper.*;
 import com.usoftchina.saas.purchase.po.*;
 import com.usoftchina.saas.purchase.service.ProdInOutService;
 import com.usoftchina.saas.purchase.service.PurchaseService;
 import com.usoftchina.saas.utils.BeanMapper;
+import com.usoftchina.saas.utils.CollectionUtils;
+import com.usoftchina.saas.utils.JsonUtils;
+import com.usoftchina.saas.utils.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -61,6 +69,8 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
     private ProdInOutService prodInOutService;
     @Autowired
     private CommonService commonService;
+    @Autowired
+    private SearchApi searchApi;
 
 
     @Override
@@ -456,6 +466,9 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
         prodInOut.setPi_buyerid(purchase.getPu_buyerid());
         prodInOut.setPi_buyercode(purchase.getPu_buyercode());
         prodInOut.setPi_buyername(purchase.getPu_buyername());
+        //币别
+        prodInOut.setPi_currency(purchase.getPu_currency());
+        prodInOut.setPi_rate(purchase.getPu_rate());
         prodInOutMapper.insertSelective(prodInOut);
         //插入验收单从表
         long pi_id = prodInOut.getId();
@@ -663,4 +676,51 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
         purchasedetailMapper.calcPurchase(pu_id);
     }
 
+    /**
+     * 获取器件列表
+     * @param deviceReqDTO
+     * @return
+     */
+    @Override
+    public IPage<DeviceDTO> getDevice(DeviceReqDTO deviceReqDTO) {
+        SearchComponentResp searchComponentResp = searchApi.getInquiry(deviceReqDTO.getKeyword(),deviceReqDTO.getCount(),deviceReqDTO.getSorting(),
+                deviceReqDTO.getType(),deviceReqDTO.getPage(),deviceReqDTO.getFilter());
+        List<ProductEntity> productEntities = searchComponentResp.getFutures().getContent();
+        if (CollectionUtils.isEmpty(productEntities)){
+            return null;
+        }
+        //IPage<FuturesEntity> futuresEntityIPage = searchComponentResps.get(0).getFutures();
+        List<DeviceDTO> deviceDTOList = convertToDeviceDTO(productEntities);
+        int page = Integer.parseInt(String.valueOf(searchComponentResp.getFutures().getPage()));
+        int size = Integer.parseInt(String.valueOf(searchComponentResp.getFutures().getSize()));
+        int total = Integer.parseInt(String.valueOf(searchComponentResp.getFutures().getTotal()));
+        //转换成分页对象
+        IPage<DeviceDTO> deviceDTOIPage = new IPage<DeviceDTO>(page, size,
+                0,deviceDTOList, false, false,
+                total);
+        return deviceDTOIPage;
+    }
+
+    /**
+     * 将平台返回的结果集转成SAAS的传输对象
+     * @param data
+     * @return
+     */
+    private List<DeviceDTO> convertToDeviceDTO(List<ProductEntity> data) {
+        List<DeviceDTO> deviceDTOS = new ArrayList<DeviceDTO>();
+        DeviceDTO deviceDTO = null;
+        for (ProductEntity item : data){
+            deviceDTO = new DeviceDTO();
+            deviceDTO.setPr_brand(item.getPbranden());
+            deviceDTO.setPr_detail(item.getKind());
+            deviceDTO.setPr_orispeccode(item.getPcmpcode());
+            deviceDTO.setPr_spec(item.getSpec());
+            deviceDTO.setPr_pack(item.getPackaging());
+            deviceDTO.setPr_vendor(item.getEnName());
+            deviceDTO.setPr_qty(item.getErpReserve());
+            deviceDTOS.add(deviceDTO);
+        }
+        return deviceDTOS;
+    }
+
 }

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

@@ -88,4 +88,8 @@ hystrix:
                 enabled: true
               isolation:
                     thread:
-                        timeoutInMilliseconds: 4000
+                        timeoutInMilliseconds: 4000
+inquiry:
+  base-url: https://test-inquiry.uuzcc.cn
+Component:
+  base-url: https://test-mall.uuzcc.cn

+ 2 - 1
applications/transfers/mall-api/src/main/java/com/usoftchina/inquiry/api/SearchApi.java

@@ -1,5 +1,6 @@
 package com.usoftchina.inquiry.api;
 
+import com.usoftchina.inquiry.po.inquiry.IPage;
 import com.usoftchina.inquiry.po.search.SearchComponentResp;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.*;
@@ -20,5 +21,5 @@ public interface SearchApi {
      */
     @GetMapping("/201819")
     SearchComponentResp getInquiry(@RequestParam("keyword") String keyword, @RequestParam("count") int count, @RequestParam("sorting") String sorting,
-                                   @RequestParam("type") String type, @RequestParam("page") int page, @RequestParam("filter") String filter);
+                                          @RequestParam("type") String type, @RequestParam("page") int page, @RequestParam("filter") String filter);
 }

+ 13 - 0
applications/transfers/transfers-server/pom.xml

@@ -48,6 +48,19 @@
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>commons-dto</artifactId>
+        </dependency>
+        <!-- db -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 2
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/TransfersApplication.java

@@ -1,5 +1,6 @@
 package com.usoftchina.saas.transfers;
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@@ -8,10 +9,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
 @SpringBootApplication
 @EnableEurekaClient
 @EnableFeignClients("com.usoftchina.saas")
+@MapperScan("com.usoftchina.saas.transfers.mapper")
 public class TransfersApplication {
     public static void main(String[] args) {
         SpringApplication.run(TransfersApplication.class, args);
     }
-
-
 }

+ 3 - 1
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/controller/TransfersController.java

@@ -5,6 +5,7 @@ import com.usoftchina.saas.transfers.po.MessageInfo;
 import com.usoftchina.saas.transfers.service.SendService;
 import com.usoftchina.saas.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
@@ -14,12 +15,13 @@ import org.springframework.web.bind.annotation.RestController;
  * @create: 2019-01-06 22:15
  **/
 @RestController
+@RequestMapping("/send")
 public class TransfersController {
 
     @Autowired
     private SendService sendService;
 
-    @RequestMapping("/sendMsg")
+    @PostMapping("/Message")
     public Result sendMsg(@RequestBody MessageInfo info) {
         if (StringUtils.isEmpty(info)) {
             return Result.error("信息为空");

+ 20 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/mapper/BrokerMessageLogMapper.java

@@ -8,4 +8,24 @@ import com.usoftchina.saas.transfers.po.BrokerMessagelog;
  **/
 public interface BrokerMessageLogMapper {
     BrokerMessagelog getMessage(String msgId);
+
+    BrokerMessagelog getLiveMessage(String msgId);
+
+    BrokerMessagelog getDeadMessage(String msgId);
+
+    int deleteByPrimaryKey(Integer id);
+
+    int insert(BrokerMessagelog record);
+
+    int insertSelective(BrokerMessagelog record);
+
+    BrokerMessagelog selectByPrimaryKey(Integer id);
+
+    int updateByPrimaryKeySelective(BrokerMessagelog record);
+
+    int updateByPrimaryKey(BrokerMessagelog record);
+
+    int updateMessageLogandAddRetry(BrokerMessagelog record);
+
+    void updateSuccess(String msgId);
 }

+ 29 - 15
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/BrokerMessagelog.java

@@ -1,19 +1,41 @@
 package com.usoftchina.saas.transfers.po;
 
+import java.io.Serializable;
 import java.util.Date;
 
 /**
  * @author: guq
  * @create: 2018-12-29 09:46
  **/
-public class BrokerMessagelog {
+public class BrokerMessagelog implements Serializable{
 
     private Long id;
-    private String messageId;
+    private String msgId;
     private String message;
-    private Integer tryCount;
     private String status;
+
     private Date createTime;
+    private int retry;
+    /**
+     * 失败原因
+     */
+    private String reason;
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+
+    public int getRetry() {
+        return retry;
+    }
+
+    public void setRetry(int retry) {
+        this.retry = retry;
+    }
 
     public Long getId() {
         return id;
@@ -23,12 +45,12 @@ public class BrokerMessagelog {
         this.id = id;
     }
 
-    public String getMessageId() {
-        return messageId;
+    public String getMsgId() {
+        return msgId;
     }
 
-    public void setMessageId(String messageId) {
-        this.messageId = messageId;
+    public void setMsgId(String msgId) {
+        this.msgId = msgId;
     }
 
     public String getMessage() {
@@ -39,14 +61,6 @@ public class BrokerMessagelog {
         this.message = message;
     }
 
-    public Integer getTryCount() {
-        return tryCount;
-    }
-
-    public void setTryCount(Integer tryCount) {
-        this.tryCount = tryCount;
-    }
-
     public String getStatus() {
         return status;
     }

+ 2 - 13
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/MessageInfo.java

@@ -1,6 +1,7 @@
 package com.usoftchina.saas.transfers.po;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * @Description 消息内容
@@ -49,19 +50,6 @@ public class MessageInfo implements Serializable {
         this.timestamp = timestamp;
     }
 
-    public int getRetryCount() {
-        return retryCount;
-    }
-
-    public void setRetryCount(int retryCount) {
-        this.retryCount = retryCount;
-    }
-
-    /**
-     * 重试次数
-     */
-    private int retryCount;
-
     public String getMsgId() {
         return msgId;
     }
@@ -107,6 +95,7 @@ public class MessageInfo implements Serializable {
         this.appId = appId;
         this.bizType = bizType;
         this.bizId = bizId;
+        this.timestamp = new Date().getTime();
     }
 
     public MessageInfo() {

+ 26 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/po/Status.java

@@ -0,0 +1,26 @@
+package com.usoftchina.saas.transfers.po;
+
+public enum Status {
+
+    SEND("已发送"),
+
+    RETRY("重新发送"),
+
+    FAILURE("投递失败"),
+
+    SUCCESS("投递成功");
+
+    private String display;
+
+    public String getDisplay() {
+        return display;
+    }
+
+    public void setDisplay(String display) {
+        this.display = display;
+    }
+
+    Status(String display) {
+        this.display = display;
+    }
+}

+ 45 - 4
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/service/ReceiveService.java

@@ -1,8 +1,16 @@
 package com.usoftchina.saas.transfers.service;
 
 import com.rabbitmq.client.Channel;
+import com.usoftchina.saas.commons.po.BillCodeSeq;
 import com.usoftchina.saas.transfers.config.RabbitConfig;
+import com.usoftchina.saas.transfers.mapper.BrokerMessageLogMapper;
+import com.usoftchina.saas.transfers.po.BrokerMessagelog;
 import com.usoftchina.saas.transfers.po.MessageInfo;
+import com.usoftchina.saas.transfers.task.*;
+import com.usoftchina.saas.utils.JsonUtils;
+import com.usoftchina.saas.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.amqp.rabbit.annotation.*;
 import org.springframework.amqp.support.AmqpHeaders;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -11,6 +19,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.messaging.handler.annotation.Headers;
 import org.springframework.messaging.handler.annotation.Payload;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.io.IOException;
 import java.util.Map;
@@ -22,31 +31,62 @@ import java.util.Map;
 @Service
 public class ReceiveService {
 
+    @Autowired
+    private SendService sendService;
+
+    @Autowired
+    private BrokerMessageLogMapper brokerMessageLogMapper;
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
     private final static String EXCHANGE = "saas_trade_dev_exchange";
     private final static String DLEXCHANGE = "saas_trade_dev_dlexchange";
     private final static String QUEUE = "saas_trade_dev_queue";
     private final static String DLQUEUE = "saas_trade_dev_dlqueue";
     private final static String ROUTINGKEY = "saas_trade_dev_dl.*";
 
+
     //配置监听的哪一个队列,同时在没有queue和exchange的情况下会去创建并建立绑定关系
     @RabbitListener(bindings = @QueueBinding(value = @Queue(value = QUEUE,durable = "true"),
             exchange = @Exchange(name= DLEXCHANGE ,durable = "true",type = "topic"),
             key = ROUTINGKEY))
     @RabbitHandler
+    @Transactional
     public void onMessage(@Payload MessageInfo info, @Headers Map<String,Object> headers, Channel channel)
             throws IOException {
         //消费者操作
-        System.out.println("---------收到消息,开始消费---------");
-        System.out.println("订单ID:" + info.getBizId());
-        System.out.println("信息ID:" + info.getMsgId());
+       logger.info("---------收到消息,消息id={},开始消费---------", info.getMsgId());
+        Executable task = null;
+       try {
+           switch(BillCodeSeq.valueOf(info.getBizType())) {
+               case PURCHASE:
+                   task = new SendPurchaseTask();
+                   break;
+               case PURCHASEIN:
+                   task = new SendPurchaseInTask();
+                   break;
+               case PURCHASEOUT:
+                   task = new SendPurchaseOutTask();
+                   break;
+           }
+
+           task.execute();
 
+           //更新状态
+           brokerMessageLogMapper.updateSuccess(info.getMsgId());
+        } catch (Exception e) {
+            BrokerMessagelog message = brokerMessageLogMapper.getLiveMessage(info.getMsgId());
+            if (null != message && !StringUtils.isEmpty(message.getMessage())) {
+                MessageInfo messageInfo = JsonUtils.fromJsonString(message.getMessage(), MessageInfo.class);
+                sendService.sendDelayMessage(messageInfo, e.getMessage());
+            }
+        }
         /**
          * Delivery Tag 用来标识信道中投递的消息。RabbitMQ 推送消息给 Consumer 时,会附带一个 Delivery Tag,
          * 以便 Consumer 可以在消息确认时告诉 RabbitMQ 到底是哪条消息被确认了。
          * RabbitMQ 保证在每个信道中,每条消息的 Delivery Tag 从 1 开始递增。
          */
         Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
-
         /**
          *  multiple 取值为 false 时,表示通知 RabbitMQ 当前消息被确认
          *  如果为 true,则额外将比第一个参数指定的 delivery tag 小的消息一并确认
@@ -55,6 +95,7 @@ public class ReceiveService {
 
         //ACK,确认一条消息已经被消费
         channel.basicAck(deliveryTag,multiple);
+        //重新返回队列 重新消费
         //channel.basicNack(deliveryTag,false,true);
     }
 }

+ 51 - 26
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/service/SendService.java

@@ -5,6 +5,9 @@ import com.usoftchina.saas.transfers.config.RabbitConfig;
 import com.usoftchina.saas.transfers.mapper.BrokerMessageLogMapper;
 import com.usoftchina.saas.transfers.po.BrokerMessagelog;
 import com.usoftchina.saas.transfers.po.MessageInfo;
+import com.usoftchina.saas.transfers.po.Status;
+import com.usoftchina.saas.utils.JsonUtils;
+import com.usoftchina.saas.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -13,6 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+
 /**
  * @author: guq
  * @create: 2019-01-06 22:04
@@ -35,58 +40,78 @@ public class SendService {
 
     //发送消息方法调用: 构建自定义对象消息
     public void sendMessage(MessageInfo info) {
+        String messageId = info.getMsgId();
+        //消息入库
+        BrokerMessagelog messagelog = new BrokerMessagelog();
+        messagelog.setCreateTime(new Date());
+        messagelog.setMessage(JsonUtils.toJsonString(info));
+        messagelog.setMsgId(messageId);
+        messagelog.setStatus(Status.SEND.getDisplay());
+        messagelog.setRetry(0);
+        brokerMessageLogMapper.insertSelective(messagelog);
+
         // 通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中
         rabbitTemplate.setConfirmCallback(confirmCallback);
         //消息唯一ID
-        CorrelationData correlationData = new CorrelationData(info.getMsgId());
+        CorrelationData correlationData = new CorrelationData(messageId);
         rabbitTemplate.convertAndSend(rabbitConfig.getDlexchange(), rabbitConfig.getRoutingkey(), info, correlationData);
-    }
-
-    //发送消息方法调用: 构建自定义对象消息
-    public void sendDelayMessage(MessageInfo info) {
-        // 通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中
-        rabbitTemplate.setConfirmCallback(delayConfirmCallback);
-        //消息唯一ID
-        CorrelationData correlationData = new CorrelationData(info.getMsgId());
-        rabbitTemplate.convertAndSend(rabbitConfig.getExchange(), rabbitConfig.getRoutingkey(), info,
-                new ExpirationMessagePostProcessor(rabbitConfig.getExpired()), correlationData);
+        logger.info("msgId={}, 消息发送", messageId);
     }
 
     //回调函数: confirm确认
     final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
         @Override
         public void confirm(CorrelationData correlationData, boolean confirm, String cause) {
-            System.out.println("correlationData: " + correlationData);
             String messageId = correlationData.getId();
             if (confirm) {
-                logger.info("msgId={},已发送服务器", correlationData.getId());
-                //如果confirm返回成功 则进行更新
-                // brokerMessageLogMapper.changeBrokerMessageLogStatus(messageId, Constants.ORDER_SEND_SUCCESS, new Date());
+                logger.info("msgId={},已发送服务器", messageId);
             } else {
-                //失败则进行具体的后续操作:重试 或者补偿等手段
-                BrokerMessagelog message = brokerMessageLogMapper.getMessage(correlationData.getId());
-                // sendDelayMessage((MessageInfo) message.getMessage());
+                //失败则进行具体的后续操作:进入延迟队列
+                BrokerMessagelog message = brokerMessageLogMapper.getLiveMessage(messageId);
+                String info = message.getMessage();
+                if (!StringUtils.isEmpty(info)) {
+                    MessageInfo messageInfo = JsonUtils.fromJsonString(info, MessageInfo.class);
+                    sendDelayMessage(messageInfo, cause);
+                }
                 logger.error("msgId={},发送失败:{}", correlationData.getId(), cause);
-
             }
         }
     };
 
-    //回调函数: confirm确认
+    //发送消息方法调用: 构建自定义对象消息
+    public void sendDelayMessage(MessageInfo info, String error) {
+        if (StringUtils.isEmpty(info) || StringUtils.isEmpty(info.getMsgId())) {
+            logger.error("消息为空");
+            return;
+        }
+        String messageId = info.getMsgId();
+        //更新状态且失败次数加1
+        BrokerMessagelog messagelog = new BrokerMessagelog();
+        messagelog.setMsgId(messageId);
+        messagelog.setStatus(Status.RETRY.getDisplay());
+        messagelog.setReason(error);
+        brokerMessageLogMapper.updateMessageLogandAddRetry(messagelog);
+
+        //发送至延迟队列
+        rabbitTemplate.setConfirmCallback(confirmCallback);
+        //消息唯一ID
+        CorrelationData correlationData = new CorrelationData(info.getMsgId());
+        rabbitTemplate.convertAndSend(rabbitConfig.getExchange(), rabbitConfig.getRoutingkey(), info,
+                new ExpirationMessagePostProcessor(rabbitConfig.getExpired()), correlationData);
+    }
+
+    /*//回调函数: confirm确认
     final RabbitTemplate.ConfirmCallback delayConfirmCallback = new RabbitTemplate.ConfirmCallback() {
         @Override
         public void confirm(CorrelationData correlationData, boolean confirm, String cause) {
-            System.err.println("correlationData: " + correlationData);
             String messageId = correlationData.getId();
             if (confirm) {
-                System.out.println("发射成功");
-                //如果confirm返回成功 则进行更新
-                // brokerMessageLogMapper.changeBrokerMessageLogStatus(messageId, Constants.ORDER_SEND_SUCCESS, new Date());
+                logger.info("msgId={},已发送延迟队列", messageId);
             } else {
                 //失败则进行具体的后续操作:重试 或者补偿等手段
-                System.err.println("发送失败,原因:" + cause);
+                logger.info("msgId={},发送延迟队列失败:{}", messageId, cause);
             }
         }
-    };
+    };*/
 
 }

+ 22 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/Executable.java

@@ -0,0 +1,22 @@
+package com.usoftchina.saas.transfers.task;
+
+/**
+ * @author: guq
+ * @create: 2019-01-08 13:38
+ **/
+public abstract class Executable {
+
+
+
+    /**
+     * @return 任务名称
+     */
+    protected String getTaskName() {
+        return this.getClass().getSimpleName();
+    }
+
+    /**
+     * 执行任务
+     */
+    public abstract void execute();
+}

+ 12 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseInTask.java

@@ -0,0 +1,12 @@
+package com.usoftchina.saas.transfers.task;
+
+/**
+ * @author: guq
+ * @create: 2019-01-08 13:53
+ **/
+public class SendPurchaseInTask extends Executable{
+    @Override
+    public void execute() {
+        //TODO
+    }
+}

+ 12 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseOutTask.java

@@ -0,0 +1,12 @@
+package com.usoftchina.saas.transfers.task;
+
+/**
+ * @author: guq
+ * @create: 2019-01-08 13:53
+ **/
+public class SendPurchaseOutTask extends Executable{
+    @Override
+    public void execute() {
+        //TODO
+    }
+}

+ 12 - 0
applications/transfers/transfers-server/src/main/java/com/usoftchina/saas/transfers/task/SendPurchaseTask.java

@@ -0,0 +1,12 @@
+package com.usoftchina.saas.transfers.task;
+
+/**
+ * @author: guq
+ * @create: 2019-01-08 13:45
+ **/
+public class SendPurchaseTask extends Executable {
+    @Override
+    public void execute() {
+        //TODO
+    }
+}

+ 14 - 0
applications/transfers/transfers-server/src/main/resources/application.yml

@@ -5,6 +5,17 @@ spring:
     user:
       name: admin
       password: select111***
+  datasource:
+      driver-class-name: com.mysql.jdbc.Driver
+      url: jdbc:mysql://10.1.81.79:3306/saas_biz?characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
+      username: root
+      password: select111***
+      hikari:
+        minimum-idle: 5
+        maximum-pool-size: 50
+        idle-timeout: 30000
+        max-lifetime: 1800000
+        connection-timeout: 30000
   messages:
     basename: i18n/messages
     encoding: UTF-8
@@ -60,6 +71,9 @@ info:
   version: '@project.version@'
   spring-boot-version: '@spring.boot.version@'
   spring-cloud-version: '@spring.cloud.version@'
+mybatis:
+  type-aliases-package: com.usoftchina.saas.transfers.po
+  mapper-locations: classpath:mapper/*.xml
 auth:
   public-key: auth/pub.key
 ribbon:

+ 3 - 0
applications/transfers/transfers-server/src/main/resources/config/application-dev.yml

@@ -11,3 +11,6 @@ eureka:
     registryFetchIntervalSeconds: 5
     serviceUrl:
       defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@127.0.0.1:8500/eureka/
+logging:
+  level:
+    com.usoftchina.saas.transfers.mapper : debug

+ 128 - 0
applications/transfers/transfers-server/src/main/resources/mapper/BrokermessagelogMapper.xml

@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.usoftchina.saas.transfers.mapper.BrokerMessageLogMapper" >
+  <resultMap id="BaseResultMap" type="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    <id column="id" property="id" jdbcType="INTEGER" />
+    <result column="msgId" property="msgId" jdbcType="VARCHAR" />
+    <result column="message" property="message" jdbcType="VARCHAR" />
+    <result column="status" property="status" jdbcType="VARCHAR" />
+    <result column="createTime" property="createTime" jdbcType="TIMESTAMP" />
+    <result column="reason" property="reason" jdbcType="VARCHAR" />
+    <result column="retry" property="retry" jdbcType="INTEGER" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    id, msgId, message, status, createTime, reason, retry
+  </sql>
+  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
+    select 
+    <include refid="Base_Column_List" />
+    from brokermessagelog
+    where id = #{id,jdbcType=INTEGER}
+  </select>
+
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
+    delete from brokermessagelog
+    where id = #{id,jdbcType=INTEGER}
+  </delete>
+  <insert id="insert" parameterType="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    insert into brokermessagelog (msgId, message,
+      status, createTime, reason
+      )
+    values ( #{msgId,jdbcType=VARCHAR}, #{message,jdbcType=VARCHAR},
+      #{status,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{reason,jdbcType=VARCHAR}
+      )
+  </insert>
+  <insert id="insertSelective" parameterType="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    insert into brokermessagelog
+    <trim prefix="(" suffix=")" suffixOverrides="," >
+      <if test="msgId != null" >
+        msgId,
+      </if>
+      <if test="message != null" >
+        message,
+      </if>
+      <if test="status != null" >
+        status,
+      </if>
+      <if test="createTime != null" >
+        createTime,
+      </if>
+      <if test="reason != null" >
+        reason,
+      </if>
+      <if test="retry != null" >
+        retry,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides="," >
+      <if test="msgId != null" >
+        #{msgId,jdbcType=VARCHAR},
+      </if>
+      <if test="message != null" >
+        #{message,jdbcType=VARCHAR},
+      </if>
+      <if test="status != null" >
+        #{status,jdbcType=VARCHAR},
+      </if>
+      <if test="createTime != null" >
+        #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="reason != null" >
+        #{reason,jdbcType=VARCHAR},
+      </if>
+      <if test="retry != null" >
+        #{retry},
+      </if>
+    </trim>
+  </insert>
+  <update id="updateByPrimaryKeySelective" parameterType="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    update brokermessagelog
+    <set >
+      <if test="message != null" >
+        message = #{message,jdbcType=VARCHAR},
+      </if>
+      <if test="status != null" >
+        status = #{status,jdbcType=VARCHAR},
+      </if>
+      <if test="createTime != null" >
+        createTime = #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="reason != null" >
+        reason = #{reason,jdbcType=VARCHAR},
+      </if>
+    </set>
+    where msgId = #{msgId,jdbcType=VARCHAR}
+  </update>
+
+  <update id="updateMessageLogandAddRetry" parameterType="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    update brokermessagelog
+    set  status = #{status}, reason = #{reason}, retry = retry + 1
+    where msgId = #{msgId,jdbcType=VARCHAR}
+  </update>
+
+  <update id="updateByPrimaryKey" parameterType="com.usoftchina.saas.transfers.po.BrokerMessagelog" >
+    update brokermessagelog
+    set msgId = #{msgId,jdbcType=VARCHAR},
+      message = #{message,jdbcType=VARCHAR},
+      status = #{status,jdbcType=VARCHAR},
+      createTime = #{createTime,jdbcType=TIMESTAMP},
+      reason = #{reason,jdbcType=VARCHAR}
+    where id = #{id,jdbcType=INTEGER}
+  </update>
+
+  <select id="getMessage" parameterType="string" resultMap="BaseResultMap">
+    select * from BrokerMessagelog where msgId = #{msgId}
+  </select>
+
+  <select id="getLiveMessage" parameterType="string" resultMap="BaseResultMap">
+    select * from BrokerMessagelog where msgId = #{msgId} and retry &lt; 3
+  </select>
+
+  <select id="getDeadMessage" parameterType="string" resultMap="BaseResultMap">
+    select * from BrokerMessagelog where msgId = #{msgId} and retry &gt; 3
+  </select>
+
+  <update id="updateSuccess" parameterType="string">
+    update BrokerMessagelog set status='投递成功',reason='' where msgid = #{msgId}
+  </update>
+</mapper>

+ 2 - 2
applications/transfers/transfers-server/src/test/java/com/usoftchina/saas/transfers/service/RabbitSendServiceTest.java

@@ -25,7 +25,7 @@ public class RabbitSendServiceTest {
     public void TestA_Send() {
         MessageInfo msg = new MessageInfo();
         msg.setBizId("测试");
-        msg.setMsgId("测试0001");
+        msg.setMsgId("测试00001");
         sendService.sendMessage(msg);
     }
 
@@ -34,7 +34,7 @@ public class RabbitSendServiceTest {
         MessageInfo msg = new MessageInfo();
         msg.setBizId("测试");
         msg.setMsgId("测试延迟0001");
-        sendService.sendDelayMessage(msg);
+        sendService.sendDelayMessage(msg, "测试");
     }
 
 

+ 3 - 2
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/AuthRestInterceptor.java

@@ -21,7 +21,7 @@ import java.util.Enumeration;
  */
 public class AuthRestInterceptor extends HandlerInterceptorAdapter {
 
-    private static final Logger log = LoggerFactory.getLogger(AuthRestInterceptor.class);
+    private static final Logger logger = LoggerFactory.getLogger(AuthRestInterceptor.class);
 
     @Autowired
     private AuthConfig authConfig;
@@ -51,7 +51,8 @@ public class AuthRestInterceptor extends HandlerInterceptorAdapter {
                 BaseContextHolder.setUserName(infoFromToken.getRealName());
                 BaseContextHolder.setCompanyId(infoFromToken.getCompanyId());
                 BaseContextHolder.setToken(token);
-                log.info("request={} CompanyId={} token={} \\r\\n userName={}  ", request.getRequestURI(),
+                logger.debug("{}: {}", authConfig.getAuthHeader(), BaseContextHolder.getToken());
+                logger.info("request={} CompanyId={} token={} \\r\\n userName={}  ", request.getRequestURI(),
                         infoFromToken.getCompanyId(), token, infoFromToken.getUserName());
             }
         } else {

+ 5 - 0
base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/ServiceFeignInterceptor.java

@@ -4,6 +4,8 @@ import com.usoftchina.saas.auth.client.configuration.AuthConfig;
 import com.usoftchina.saas.context.BaseContextHolder;
 import feign.RequestInterceptor;
 import feign.RequestTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -14,11 +16,14 @@ public class ServiceFeignInterceptor implements RequestInterceptor {
     @Autowired
     private AuthConfig authConfig;
 
+    private Logger logger = LoggerFactory.getLogger(ServiceFeignInterceptor.class);
+
     public ServiceFeignInterceptor() {
     }
 
     @Override
     public void apply(RequestTemplate requestTemplate) {
+        logger.debug("{}: {}", authConfig.getAuthHeader(), BaseContextHolder.getToken());
         requestTemplate.header(authConfig.getAuthHeader(), BaseContextHolder.getToken());
     }
 

+ 0 - 3
frontend/operation-web/app/view/core/List.js

@@ -1,6 +1,3 @@
-/**
- * 用户访问日志
- */
 Ext.define('saas.view.core.List', {
     extend: 'Ext.grid.Panel',
     xtype: 'corelist',

+ 248 - 0
frontend/operation-web/app/view/core/base/BasePanel.js

@@ -0,0 +1,248 @@
+Ext.define('saas.view.core.base.BasePanel', {
+    extend: 'Ext.form.Panel',
+    xtype: 'core-base-basepanel',
+    
+    controller: 'core-base-basepanel',
+    viewModel: 'core-base-basepanel',
+
+    cls:'core-base-basepanel',
+
+    //基础属性
+    frame:false,
+    autoScroll: true,
+    border: 0,
+    bodyPadding: 0,
+    layout: 'fit',
+    
+    fieldDefaults: {
+        margin: '0 5 5 0',
+        labelAlign: 'right',
+        labelWidth: 90,
+        columnWidth: 0.25,
+        blankText: '该字段不能为空'
+    },
+    
+    searchField:[],
+    gridColumns: [],
+
+    deleteMoreMsg: '确认删除所选单据?',
+    deleteOneMsg: '确认删除该单据?',
+
+    initComponent: function() {
+
+        var me = this,
+        gridConfig = me.gridConfig,
+        gridColumns = Ext.Array.clone(gridConfig.columns);
+
+        var gridcfg = {
+            layout: 'fit',
+            xtype: 'core-base-gridpanel',
+            padding: '8 12',
+            _columns: gridColumns.map(function(c) {
+                return Object.assign({}, c);
+            }),
+        };
+        Ext.apply(gridcfg ,me.gridConfig);
+
+        Ext.apply(me, {
+            dockedItems: [{
+                frame:false,
+                xtype: 'toolbar',
+                dock: 'top',
+                layout: 'column',
+                style: {
+                    margin: '0 0 12px 0',
+                    padding: '10px 0 14px 8px',
+                },
+                items: me.searchField.concat([{
+                    xtype: 'button',
+                    text: '查询',
+                    handler: function() {
+                        me.onQuery()
+                    }
+                }])
+            }],
+            items: [gridcfg]
+        });
+        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);
+
+                if(field) {
+                    field.enableKeyEvents = true;
+                    field.on && field.on({
+                        keydown: {
+                            fn: function(th, e, eOpts) {
+                                if(e.keyCode == 13) {
+                                    form.onQuery()
+                                }
+                            }
+                        }
+                    });
+                }
+            });
+        }
+    },
+
+    onQuery: function() {
+        var me = this;
+        var grid = me.down('core-base-gridpanel');
+        
+        grid.store.loadPage(1);
+    },
+
+    /**
+     * 获得过滤条件
+     */
+    getConditions: function() {
+        var me = this;
+        var items = me.dockedItems.items[0].items.items;
+        var conditions = [];
+
+        for(let i = 0; i < items.length; i++) {
+            var item = items[i];
+            var field = item.name,
+            func = item.getCondition,
+            value = item.value,
+            condition;
+
+            if(value&&value!=''){
+                if(typeof func == 'function') {
+                    condition = {
+                        type: 'condition',
+                        value: func(value)
+                    }
+                }else {
+                    var type = item.fieldType || me.getDefaultFieldType(item),
+                    operation = item.operation || me.getDefaultFieldOperation(item),
+                    conditionValue = me.getConditionValue(item, value);
+        
+                    if(!conditionValue) {
+                        continue;
+                    }
+                    condition = {
+                        type: type,
+                        field: field,
+                        operation: operation,
+                        value: conditionValue
+                    }
+                }
+                conditions.push(condition);
+            }
+        }
+
+        return conditions;
+    },
+
+    /**
+     * 只要arr1和arr2中存在相同项即返回真
+     */
+    isContainsAny: function (arr1, arr2) {
+        for (var i = 0; i < arr2.length; i++) {
+            var a2 = arr2[i];
+            if (!!arr1.find(function (a1) {
+                    return a1 == a2
+                })) {
+                return true;
+            }
+        }
+        return false;
+    },
+
+    getDefaultFieldType: function (field) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            type;
+
+        if (me.isContainsAny(xtypes, ['numberfield'])) {
+            type = 'number';
+        } else if (me.isContainsAny(xtypes, ['datefield', 'condatefield', 'conmonthfield'])) {
+            type = 'date';
+        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
+            type = 'enum';
+        } else if (me.isContainsAny(xtypes, ['combobox', 'multicombo', 'combo', 'radiofield', 'radio'])) {
+            type = 'enum';
+        } else {
+            type = 'string';
+        }
+
+        return type;
+    },
+
+    getDefaultFieldOperation: function (field) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            operation;
+
+        if (me.isContainsAny(xtypes, ['numberfield', 'datefield', 'dbfindtrigger'])) {
+            operation = '=';
+        } else if (me.isContainsAny(xtypes, ['condatefield', 'conmonthfield'])) {
+            operation = 'between';
+        } else if (me.isContainsAny(xtypes, ['multidbfindtrigger', 'combobox', 'multicombo', 'combo'])) {
+            operation = 'in';
+        } else {
+            operation = 'like';
+        }
+
+        return operation;
+    },
+
+    /**
+     * 处理部分字段值
+     */
+    getConditionValue: function (field, value) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            conditionValue;
+        if (me.isContainsAny(xtypes, ['datefield'])) {
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d H:i:s');
+        } else if (me.isContainsAny(xtypes, ['conmonthfield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = from + ',' + to;
+        } else if (me.isContainsAny(xtypes, ['condatefield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d 00:00:00') + ',' + Ext.Date.format(new Date(to), 'Y-m-d 23:59:59');
+        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
+            conditionValue = value;
+        } else if (me.isContainsAny(xtypes, ['combobox', 'combo'])) {
+            conditionValue = '\'' + value + '\'';
+        } else if (me.isContainsAny(xtypes, ['multicombo'])) {
+            conditionValue = value.map ? value.map(function (v) {
+                return '\'' + v.value + '\'';
+            }).join(',') : '';
+        } else {
+            conditionValue = value;
+        }
+
+        return conditionValue;
+    },
+
+    getExtraParams: function(store, op, condition) {
+        return {
+            number: store.exportNumber?store.exportNumber:op._page,
+            size: store.exportPageSize?store.exportPageSize:store.pageSize,
+            condition: JSON.stringify(condition)
+        };
+    },
+
+    refresh: function () {
+        this.items.items[0].store.load()
+    },
+
+    refreshViewConfig: function() {
+        var me = this;
+        var grid = me.items.items[0];
+        grid.refreshColumns();
+    }
+});

+ 97 - 0
frontend/operation-web/app/view/core/base/BasePanel.scss

@@ -0,0 +1,97 @@
+.core-base-basepanel{
+    background: $panel-body-background;
+
+    .x-panel-default-outer-border-trl {
+        border-top-color: #fff !important;
+        border-top-width: 1px !important;
+        border-right-color: #fff !important;
+        border-right-width: 1px !important;
+        border-left-color: #fff !important;
+        border-left-width: 1px !important;
+    }
+    .x-panel-default-outer-border-rbl {
+        border-top-color: #fff !important;
+        border-top-width: 1px !important;
+        border-right-color: #fff !important;
+        border-right-width: 1px !important;
+        border-left-color: #fff !important;
+        border-left-width: 1px !important;
+        border-bottom-color: #fff !important;
+        border-bottom-width: 1px !important;
+    }
+    .x-btn-menu-active{
+        .x-btn-wrap{
+            .x-btn-button{
+                .x-btn-inner{
+                    color:#fff;
+                }
+            }
+        }
+    }
+}
+.core-base-gridpanel{
+    .x-grid-body{
+        border:1px solid #abdaff !important;
+        border-top-width: 0 !important;
+    }
+    .x-grid-header-ct{
+        border:1px solid #abdaff !important;
+    }
+}
+.x-basepanel-pagingtoolbar{
+    padding: 6px 0 5px 8px;
+    border:1px solid #abdaff !important;
+    border-top-width: 0 !important;
+}
+
+.x-btn-import-middle:after{
+    content: ' ';
+    display: block;
+    width: 0;
+    height: 0;
+    border-style: solid;
+    border-width: 15px 0 16px 18px;
+    border-color: transparent transparent transparent #34baf6;
+    position: absolute;
+    left: 0;
+    top: 0;
+}
+
+.x-btn-import-middle-next:after{
+    content: ' ';
+    display: block;
+    width: 0;
+    height: 0;
+    border-style: solid;
+    border-width: 15px 0 16px 18px;
+    border-color: transparent transparent transparent #fff;
+    position: absolute;
+    left: 0;
+    top: 0;
+}
+
+.x-btn-import-first{
+    .x-btn-wrap{
+        .x-btn-button{
+          .x-btn-inner{
+            color:#fff !important
+          }
+        }
+    }
+}
+
+.x-btn-import-last{
+    .x-btn-wrap{
+        .x-btn-button{
+          .x-btn-inner{
+            color:#34baf6 !important
+          }
+        }
+    }
+}
+
+.x-btn-import-last{
+    .x-btn.x-btn-disabled.x-btn-default-toolbar-small .x-btn-inner-default-toolbar-small {
+        color: #34baf6;
+    }
+}

+ 47 - 0
frontend/operation-web/app/view/core/base/BasePanelController.js

@@ -0,0 +1,47 @@
+Ext.define('saas.view.core.base.BasePanelController', {
+    extend: 'Ext.app.ViewController',
+    alias: 'controller.core-base-basepanel',
+
+    add: function(){
+        var form = this.getView();
+        var id = form.xtype + '_add';
+        saas.util.BaseUtil.openTab(form.xtype,'新增' + form._title,id);
+    },
+
+    onColSetting: function() {
+        var me = this,
+        panel = me.getView(),
+        viewName = panel.viewName,
+        columns = panel.defaultColumns,
+        items = [];
+
+        for(let i = 0; i < columns.length; i++) {
+            let col = columns[i];
+            if(!col.initHidden) {
+                items.push(Object.assign({}, col));
+            }
+        }
+
+        me.openSettingWindow(viewName, items, 'columns');
+    },
+
+    openSettingWindow: function(viewName, items, settype) {
+        var panel = saas.util.BaseUtil.getCurrentTab(),
+        box = panel.getBox(),
+        refs = panel.getReferences() || {},
+        win = refs.settingwin;
+
+        title = '列设置';
+
+        if(!win) {
+            win = panel.add({
+                title: title,
+                xtype: 'settingwin',
+                viewName: viewName,
+                fieldItems: Ext.Array.clone(items),
+                settype: settype,
+            });
+        }
+        win.show();
+    }
+});

+ 8 - 0
frontend/operation-web/app/view/core/base/BasePanelModel.js

@@ -0,0 +1,8 @@
+Ext.define('saas.view.core.base.BasePanelModel', {
+    extend: 'Ext.app.ViewModel',
+    alias: 'viewmodel.core-base-basepanel',
+
+    data: {
+        configurable: true
+    }
+});

+ 224 - 0
frontend/operation-web/app/view/core/base/GridPanel.js

@@ -0,0 +1,224 @@
+Ext.define('saas.view.core.base.GridPanel', {
+    extend: 'Ext.grid.Panel',
+    xtype: 'core-base-gridpanel',
+
+    requires: [
+        'Ext.grid.plugin.Exporter'
+    ],
+    plugins: [{
+        ptype: 'gridexporter',
+    }, {
+        ptype: 'menuclipboard'
+    }],
+
+    cls:'core-base-gridpanel',
+    
+    dataUrl: '',
+    dbSearchFields: [],
+    condition:'',
+    rootProperty: 'data.list',
+    totalProperty: 'data.total',
+
+    flexColumn: [{
+        flex: 1,
+        dataIndex:'',
+        initHidden: true,
+        allowBlank: true
+    }],
+
+
+    initComponent: function() {
+        var me = this;
+        me.frame = false;
+        if(me._columns){
+            var fields = me._columns.map(column => column.dataIndex);
+
+            me.store = Ext.create('Ext.data.Store',{
+                fields:fields,
+                autoLoad: true,
+                pageSize: 10,
+                data: [],
+                proxy: {
+                    timeout:8000,
+                    type: 'ajax',
+                    url: me.dataUrl,
+                    actionMethods: {
+                        read: 'GET'
+                    },
+                    reader: {
+                        type: 'json',
+                        rootProperty: me.rootProperty,
+                        totalProperty: me.totalProperty,
+                    },
+                    listeners: {
+                        exception: function(proxy, response, operation, eOpts) {
+                            if(operation.success) {
+                                if(response.timedout) {
+                                    saas.util.BaseUtil.showErrorToast('请求超时');
+                                }
+                            }else {
+                                console.error('exception: ', response);
+                                saas.util.BaseUtil.showErrorToast('查询失败:' + (response.responseJson?response.responseJson.message:'请求超时'));
+                            }
+                        }
+                    }
+                },
+                listeners: {
+                    beforeload: function (store, op) {
+                        var basePanel = me.up('core-base-basepanel');
+                        var condition = basePanel.getConditions();
+                        if (Ext.isEmpty(condition)) {
+                            condition = "";
+                        }
+
+                        var obj = basePanel.getExtraParams(store, op, condition);
+                        Ext.apply(store.proxy.extraParams, obj);
+                    }
+                }
+            });
+
+            Ext.apply(me, {
+                dockedItems:[{
+                    xtype: 'pagingtoolbar',
+                    dock: 'bottom',
+                    cls:'x-basepanel-pagingtoolbar',
+                    displayInfo: true,
+                    store: me.store
+                }]
+            });
+        }
+        me.callParent(arguments);
+        me.refreshColumns();
+    },
+
+    listeners:{
+        boxready: function(grid, width, height, eOpts) {
+            var store = grid.getStore(),
+            gridBodyBox = grid.body.dom.getBoundingClientRect(),
+            gridBodyBoxHeight = gridBodyBox.height;//可能有滚动条
+            var pageSize = Math.floor(gridBodyBoxHeight / 33);
+            store.setPageSize(pageSize);
+        }
+    },
+
+    refreshColumns: function() {
+        var me = this,
+        basePanel = me.up('core-base-basepanel');
+        me.reconfigure(me.store, Ext.Array.merge(Ext.Array.clone(basePanel.gridConfig.columns), me.flexColumn));
+        me.applyScrollable(true)
+    },
+
+    onLoad:function(){
+        this.ownerCt.ownerCt.store.load();
+    },
+
+    onImport:function(){
+        var grid = this.ownerCt.ownerCt;
+        var form = grid.ownerCt,panelEl = form.getEl();
+        var box = panelEl.getBox();
+        var height = box.height;
+        var width = box.width;
+        var win = form.add(Ext.create('saas.view.core.base.ImportWindow', {  
+            cls:'x-window-dbfind', 
+            belong:form,  
+            modal:true,
+            height: height * 0.8,
+            width: width * 0.8,
+            title: form._title + '导入',
+            scrollable: true,
+            bodyPadding: 10,
+            constrain: true,
+            closable: true,
+            layout:'fit',
+            renderTo:form.getEl()
+        }));
+        win.show();
+    },
+
+    onExport:function(me){
+        var grid = me.ownerCt.ownerCt;
+        //导出接口权限设置
+        var url = '/api/commons/'+grid.ownerCt.caller+'/export';
+        saas.util.BaseUtil.request({
+            url: url,
+            params: '',
+            method: 'GET',
+        })
+        .then(function(localJson) {
+            if(localJson.success){
+                grid.store.exportPageSize = 5000;
+                grid.store.exportNumber = 1;
+                grid.store.load(function(records, operation, success) {
+                    grid.saveDocumentAs({
+                        type: 'xlsx',
+                        title: grid.ownerCt._title + '列表',
+                        fileName: grid.ownerCt._title + '列表'+Ext.Date.format(new Date(),'Y-m-d_H-i-s')+'.xlsx'
+                    });
+                    grid.store.exportPageSize = null;
+                    grid.store.exportNumber = null;
+                    grid.store.load(function(records, operation, success) {
+                    });
+                });
+            }
+        })
+        .catch(function(e) {
+            saas.util.BaseUtil.showErrorToast('导出失败: ' + e.message);
+        });
+    },
+
+    onVastDeal:function(url,type){
+        var form = this.ownerCt;
+        var grid = this;
+        var data = grid.getGridSelected(type);
+        if(!data){
+            saas.util.BaseUtil.showErrorToast('请勾选符合条件的行进行操作。');
+            return false;
+        }
+        if(data&&data.length>0){
+            var params = JSON.stringify({baseDTOs:data});
+            saas.util.BaseUtil.request({
+                url: url,
+                params: params,
+                method: 'POST',
+                async:false
+            })
+            .then(function() {
+                saas.util.BaseUtil.showSuccessToast('操作成功');
+                grid.store.load();
+                grid.selModel.deselectAll();
+            })
+            .catch(function(e) {
+                saas.util.BaseUtil.showErrorToast('操作失败: ' + e.message);
+            });
+        }else{
+            saas.util.BaseUtil.showErrorToast('请勾选至少一条明细');
+        }
+    },
+
+    getGridSelected:function(type){
+        var isErrorSelect = false;
+        var checkField = this.statusCodeField;
+        var me = this,
+        items = me.selModel.getSelection(),
+        data = new Array() ;
+        Ext.each(items, function(item, index){
+            if(!Ext.isEmpty(item.data[me.idField])){
+                var o = new Object();
+                if(me.idField){
+                    o['id'] = item.data[me.idField];
+                }
+                if(me.codeField){
+                    o['code'] = item.data[me.codeField];
+                }
+                if(type&&type==item.data[checkField]){
+                    isErrorSelect = true
+                }
+                data.push(o);
+            }
+        });
+        if(isErrorSelect){
+            return false;
+        }
+		return data;
+    },
+});

+ 309 - 0
frontend/operation-web/app/view/core/base/ImportWindow.js

@@ -0,0 +1,309 @@
+Ext.define('saas.view.core.base.ImportWindow', {
+    extend: 'Ext.window.Window',
+    xtype: 'importwindow',
+    layout:'fit',
+
+    requires: [
+        'Ext.form.field.File',
+        'Ext.container.ButtonGroup'
+    ],
+
+    bbar:['->',{
+        hidden:true,
+        name:'prev',
+        text:'上一步',
+        handler:function(b){
+            var p = this.ownerCt.ownerCt.items.items[0];
+            var tbar = p.dockedItems.items[0];
+            //first
+            var first = tbar.down('[name=first]').el.dom;
+            first.classList.add('x-btn-import-first');
+            first.style.background = '#34baf6';
+            first.childNodes[0].childNodes[0].childNodes[1].style.color = '#fff';
+            //middle
+            var middle = tbar.down('[name=middle]').el.dom;
+            middle.classList.add('x-btn-import-middle');
+            middle.classList.remove('x-btn-import-middle-next');
+            middle.style.background = '#fff';
+            //last
+            var last = tbar.down('[name=last]').el.dom;
+            last.classList.add('x-btn-import-last');
+            last.style.background = '#fff';
+            last.childNodes[0].childNodes[0].childNodes[1].style.color = '#34baf6';
+            //按钮逻辑
+            b.hide();
+            b.ownerCt.down('[name=next]').show();
+            b.ownerCt.down('[name=over]').hide();
+            //字段逻辑
+            p.down('[name=download]').show();
+            p.down('[name=upload]').hide();
+            p.down('[name=detail]').show();
+            p.down('[name=message]').hide();
+        }
+    },{
+        name:'next',
+        text:'下一步',
+        handler:function(b){
+            var p = this.ownerCt.ownerCt.items.items[0];
+            var tbar = p.dockedItems.items[0];
+            //first
+            var first = tbar.down('[name=first]').el.dom;
+            first.classList.remove('x-btn-import-first');
+            first.style.background = '#fff';
+            first.childNodes[0].childNodes[0].childNodes[1].style.color = '#34baf6';
+            //middle
+            var middle = tbar.down('[name=middle]').el.dom;
+            middle.classList.remove('x-btn-import-middle');
+            middle.classList.add('x-btn-import-middle-next');
+            middle.style.background = '#34baf6';
+            //last
+            var last = tbar.down('[name=last]').el.dom;
+            last.classList.remove('x-btn-import-last');
+            last.style.background = '#34baf6';
+            last.childNodes[0].childNodes[0].childNodes[1].style.color = '#fff';
+            //按钮逻辑
+            b.hide();
+            b.ownerCt.down('[name=prev]').show();
+            b.ownerCt.down('[name=over]').show();
+            //字段逻辑
+            p.down('[name=download]').hide();
+            p.down('[name=upload]').show();
+            p.down('[name=detail]').hide();
+            p.down('[name=message]').show();
+        }
+    },{
+        hidden:true,
+        name:'over',
+        text:'完成',
+        disabled:true,
+        handler:function(b){
+            var form = b.ownerCt.ownerCt;
+            var id = form.importId;
+            if(id){
+                form.setLoading(true);
+                Ext.Ajax.request({
+                    url: '/api/document/'+form.ownerCt.caller.toLocaleLowerCase()+'/saveToFormal',//这里是填写需要跨域访问的URL
+                    method: 'post',
+                    headers: {
+                        'Access-Control-Allow-Origin': '*',
+                        'Authorization':  saas.util.State.get('session').token,
+                        "Content-Type": 'application/x-www-form-urlencoded;charset=UTF-8'
+                    },
+                    params:{
+                        id:id,
+                        update:false
+                    },
+                    success: function (response, opts) {
+                        form.setLoading(false);
+                        var res = Ext.decode(response.responseText);
+                        if(!res.success){
+                            var upload = form.down('[name=upload]');
+                            upload.reset();
+                            form.dockedItems.items[1].down('[name=over]').setDisabled(true);
+                            form.down('[name=messagedetail]').setHtml(res.message + '</br></br><span style="color:#ff0000">请修改后重新上传</span>');
+                        }else{
+                            //刷新界面
+                            var g = form.ownerCt.down('grid');
+                            g.store.loadPage(g.store.currentPage);
+                            form.close();
+                        }
+                    },
+                    failure: function (response, opts) {
+                        form.setLoading(false);
+                        var upload = form.down('[name=upload]');
+                        upload.reset();
+                        form.dockedItems.items[1].down('[name=over]').setDisabled(true);
+                        var res = Ext.decode(response.responseText);
+                        saas.util.BaseUtil.showErrorToast('导入数据失败: ' + res.message);
+                        
+                    }
+                });
+            }else{
+                form.close();
+            }
+        }
+    },{
+        name:'close',
+        text:'关闭',
+        handler:function(b){
+            b.ownerCt.ownerCt.close()
+        }
+    }],
+
+    initComponent: function() {
+        var me = this;
+        Ext.apply(me, {
+            items:[{
+                cls:'x-panel-import',
+                padding:'10px 100px 10px 100px',
+                xtype:'panel',
+                layout:'vbox',
+                tbar:['->',{
+                    name:'first',
+                    cls:'x-btn-import-first',
+                    style:'background: #34baf6;border-color: #35baf6;    opacity: 1;',
+                    focusable:false,
+                    disabled:true,
+                    width:300,
+                    text:'下载模板并填写',
+                },{
+                    name:'middle',
+                    disabled:true,
+                    focusable:false,
+                    style:'width: 20px;margin: 0px;margin-left: -16px;border-width: 1px 0px;min-width: 0px;border-style: solid;border-color: rgb(53, 186, 246);    opacity: 1;    background-color: #fff;',
+                    width:20,
+                    cls:'x-btn-import-middle'
+                },{
+                    name:'last',
+                    disabled:true,
+                    cls:'x-btn-import-last',
+                    style:'border-left-width: 0px;background: #fff;border-color: #35baf6;opacity:1;background-color: #fff;',
+                    focusable:false,
+                    margin:'0 0 0 -1',
+                    width:300,
+                    text:'上传导入文件',
+                },'->'],
+                items:[{
+                    margin:'15px 0 0 0',
+                    width: 240,
+                    labelWidth:160,
+                    buttonOnly:true,
+                    fieldLabel:'导入模板下载',
+                    name:'download',
+                    xtype: 'filefield',
+                    buttonText: '下载模板',
+                    buttonConfig:{
+                        xtype:'button',
+                        handler:function(b){
+                            var caller = b.ownerCt.ownerCt.ownerCt.ownerCt.caller;
+                            //获取模版
+                            var serverOptions = Ext.manifest.server;
+                            window.location.href = (serverOptions.basePath.https?serverOptions.basePath.https:serverOptions.basePath) + '/api/commons/excel/import/templet?caller='+caller;
+                        }
+                    }
+                },{
+                    margin:'10px 0 0 45px',
+                    xtype: 'fieldset',
+                    title: '导入说明',
+                    name:'detail',
+                    collapsible: false,
+                    items: [{
+                        xtype : 'fieldcontainer',
+                        html: '1.下载模板后打开</br>2.查看模板内说明、并修改模板内容,保存后点击下一步按钮</br>3.上传Excel文件,此时会校验文件的字段格式,有问题则需要修改错误数据后再次上传文件</br>4.校验成功后'+
+                        '点击完成按钮将数据进行数据库校验'
+                    }]
+                },{
+                    hidden:true,
+                    margin:'15px 0 0 0',
+                    labelWidth:100,
+                    allowBlank : true, 
+                    width:180,
+                    buttonOnly:true,
+                    fieldLabel:'上传文件',
+                    xtype: 'filefield',
+                    name:'upload',
+                    buttonText: '选择文件',
+                    createFileInput : function() {
+                            var me = this;
+                            me.fileInputEl = me.button.el.createChild({
+                            name: me.getName(),
+                            cls: Ext.baseCSSPrefix + 'form-file-input',
+                            tag: 'input',
+                            type: 'file',
+                            size: 1
+                        }).on('change', me.onFileChange, me);
+                    },
+                    listeners: {
+                        change: function(field){
+                            var form = field.ownerCt.ownerCt;
+                            var myForm = field.ownerCt;
+                            var fileEl = field.fileInputEl.dom;
+                            var file = fileEl.files[0];
+                            var type = file.name.substring(file.name.lastIndexOf('.'),file.name.length);
+                            if(type.indexOf('xlsx')<0||type.indexOf('xls')<0){
+                                saas.util.BaseUtil.showErrorToast('文件格式不正确,只能选择xlsx或xls格式的文件进行上传');
+                                field.reset();
+                                return;
+                            }
+
+                            //导入权限校验
+                            var hasPower = false;
+                            Ext.Ajax.request({
+                                url: '/api/commons/'+form.ownerCt.caller+'/import',
+                                async:false,
+                                method: 'GET',
+                                success: function(response, opts) {
+                                    var data = Ext.decode(response.responseText);
+                                    if(data.success){
+                                        hasPower = true
+                                    }
+                                },
+                                failure: function(response, opts) {}
+                            }); 
+                            if(!hasPower){
+                                saas.util.BaseUtil.showErrorToast('上传失败:没有 导入 权限');
+                                return false;
+                            }
+                            
+                            var fd = new FormData();
+                            fd.append('file', fileEl.files[0]);
+                            fd.append('caller', myForm.ownerCt.ownerCt.caller);
+                            form.setLoading(true);
+                            Ext.Ajax.request({
+                                url: '/api/commons/excel/import/parse',//这里是填写需要跨域访问的URL
+                                cors: true,
+                                useDefaultXhrHeader: false,
+                                method: 'post',
+                                rawData: fd,
+                                headers: {
+                                    'Access-Control-Allow-Origin': '*',
+                                    'Authorization':  saas.util.State.get('session').token,
+                                    //"Content-Type": 'multipart/form-data'  //文件上传的格式, 
+                                    "Content-Type":null
+                                },
+                                success: function (response, opts) {
+                                    form.setLoading(false);
+                                    var res = Ext.decode(response.responseText);
+                                    if(res.success){
+                                        var id = res.data;
+                                        if(id){
+                                            field.ownerCt.down('[name=messagedetail]').setHtml('文件名: ' + file.name + ' 导入格式校验成功!</br></br>请点击 <span style="color:#35baf6">完成</span> 执行数据库校验');
+                                            form.importId = id;
+                                            field.ownerCt.ownerCt.dockedItems.items[1].down('[name=over]').setDisabled(false)
+                                        }else{
+                                            field.reset();
+                                            saas.util.BaseUtil.showErrorToast('上传失败:后台未返回信息');
+                                        }
+                                    }else{
+                                        field.reset();
+                                        field.ownerCt.down('[name=messagedetail]').setHtml(res.message + '</br><span style="color:#ff0000">请修改后重新上传</span>');
+                                    }
+                                },
+                                failure: function (response, opts) {
+                                    form.setLoading(false);
+                                    field.reset();
+                                    var res = Ext.decode(response.responseText);
+                                    saas.util.BaseUtil.showErrorToast('上传失败: ' + res.message);
+                                }
+                            });
+                        }
+                    }
+                },{
+                    hidden:true,
+                    margin:'10px 0 0 45px',
+                    xtype: 'fieldset',
+                    title: '导入详情',
+                    name:'message',
+                    collapsible: false,
+                    items: [{
+                        name:'messagedetail',
+                        xtype : 'fieldcontainer',
+                        html:'暂无导入信息'
+                    }]
+                }]
+            }]
+        });
+        me.callParent(arguments);
+    }
+
+});

+ 268 - 0
frontend/operation-web/app/view/core/form/field/ConDateField.js

@@ -0,0 +1,268 @@
+/**
+ * Created by UAS30 on 2018/10/11.
+ */
+Ext.define('saas.view.core.form.field.ConDateField', {
+    extend: 'Ext.form.FieldContainer',
+    alias: 'widget.condatefield',
+    layout: 'hbox',
+    valuePrint:"",
+    ombineErrors: true,
+    items: [],
+    showscope: true,
+    defaults: {
+        margin: '0 0 0 0'
+    },
+    columnWidth: 0.5,
+    defaultBindProperty: 'value',
+
+    cls: 'x-condatefield',
+
+    initComponent : function(){
+        this.cls = (this.cls || '') + ' x-form-field-multi';
+        this.callParent(arguments);
+        var me = this, allowBlank = (Ext.isDefined(me.allowBlank) ? me.allowBlank : true);
+        me.combo = Ext.create('Ext.form.field.ComboBox', {
+            width: 100,
+            editable: false,
+            hidden: !me.showscope,
+            fieldStyle: 'background:#eef1f7',
+            store: Ext.create('Ext.data.Store', {
+                fields: ['display', 'value'],
+                data : [
+                    {"display":"本月", "value": 1},
+                    {"display":"上个月", "value": 2},
+                    {"display":"近三月", "value": 3},
+                    {"display":"近半年", "value": 4},
+                    {"display":"本年度", "value": 5},
+                    {"display":"上年度", "value": 6},
+                    {"display":"自定义", "value": 7}
+                ]
+            }),
+            triggerAction: 'all',
+            forceSelection: true,
+            queryMode: 'local',
+            displayField: 'display',
+            valueField: 'value',
+            emptyText: '请选择',
+            listeners: {
+                select: function(combo, records, obj){
+                    me.setDateFieldValue(combo.value);
+                }
+            }
+        });
+        me.insert(0, me.combo);
+        me.from = me.insert(1, {
+            xtype: 'datefield',
+            name: me.name + '_from',
+            format: 'Y-m-d',
+            formatText: '',
+            allowBlank: allowBlank,
+            flex: 1,
+            editable:false,
+            fieldStyle: me.fieldStyle,
+            emptyText: '起始时间',
+            //matchFieldWidth:true,
+            listeners: {
+                change: function(f){
+                    var from =me.from.value,to = me.to.value;
+                    var v = me.items.items[0].value;
+                    if(v != 7) {
+                        me.to.setMinValue(me.from.value);
+                    }
+                    from = from == null || from == '' ? to == null || to == '' ? '' : to : from;
+                    to = to == null || to == '' ? from == null || from == '' ? '' : from : to;
+                    me.firstVal = from;
+                    me.secondVal = to;
+                    if(to!=''&&from!=''){
+                        me.value = "BETWEEN to_date('" + Ext.Date.format(from,'Y-m-d') + " 00:00:00','yyyy-MM-dd HH24:mi:ss') AND to_date('"
+                            + Ext.Date.format(to,'Y-m-d') + " 23:59:59','yyyy-MM-dd HH24:mi:ss')";
+                        if(me.ownerCt){
+                            var tablename = me.ownerCt.tablename;
+                            me.valuePrint="{"+tablename+"."+me.name+"}>=date('"+Ext.Date.format(from,'Y-m-d')+"') and {"+tablename+"."+me.name+"}<=date('"+Ext.Date.format(to,'Y-m-d')+"')";
+                        }
+                    }else {
+                        me.value=null;
+                    }
+                    me.setBindValue(v, from, to);
+                }
+            }
+        });
+        me.to = me.insert(2, {
+            xtype: 'datefield',
+            name: me.name + '_to',
+            allowBlank: allowBlank,
+            format: 'Y-m-d',
+            formatText: '',
+            flex: 1,
+            editable:false,
+            fieldStyle: me.fieldStyle,
+            emptyText: '结束时间',
+            listeners: {
+                change: function(){
+                    var from = me.from.value, to =me.to.value;
+                    var v = me.items.items[0].value;
+                    me.from.setMaxValue(me.to.value);
+                    from = from == null || from == '' ? to == null || to == '' ? '' : to : from;
+                    to = to == null || to == '' ? from == null || from == '' ? '' : from : to;
+                    me.firstVal = from;
+                    me.secondVal = to;
+                    if(to!=''&& from!=''){
+                        me.value = "BETWEEN to_date('" + Ext.Date.format(from,'Y-m-d') + " 00:00:00','yyyy-MM-dd HH24:mi:ss') AND to_date('"
+                            + Ext.Date.format(to,'Y-m-d') + " 23:59:59','yyyy-MM-dd HH24:mi:ss')";
+                        if(me.ownerCt){
+                            var tablename = me.ownerCt.tablename;
+                            me.valuePrint = "{"+tablename+"."+me.name+"}>=date('"+Ext.Date.format(from,'Y-m-d')+"') and {"+tablename+"."+me.name+"}<=date('"+Ext.Date.format(to,'Y-m-d')+"')";
+                        }
+                    }else {
+                        me.value=null;
+                    }
+                    me.setBindValue(v, from, to);
+                }
+            }
+        });
+        var t = this.value;
+        if(!t || !t in [1,2,3,4,5,6,7]) {
+            t = 1;
+        }
+        this.value = null;
+        this.setInitValue(t);
+    },
+    setDateFieldValue: function(v){
+        v = Number(v);
+        var me = this,from =me.from ,to=me.to;
+        var now = new Date();                    //当前日期
+        var nowDay = now.getDate();              //当前日
+        var nowMonth = now.getMonth();           //当前月
+        var nowYear = now.getYear();             //当前年
+        nowYear += (nowYear < 2000) ? 1900 : 0;
+        var maxDate = null;
+        var minDate = null;
+        switch (v) {
+            case 1://本月
+                minDate = Ext.Date.getFirstDateOfMonth(now);
+                maxDate = Ext.Date.getLastDateOfMonth(now);
+                break;
+            case 2://上个月
+                if(nowMonth == 0) {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear - 1, 11, 1));
+                    maxDate = Ext.Date.getLastDateOfMonth(new Date(nowYear - 1, 11, 1));
+                }else {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear, nowMonth - 1, 1));
+                    maxDate = Ext.Date.getLastDateOfMonth(new Date(nowYear, nowMonth - 1, 1));
+                }
+                break;
+            case 3: {//近三个月
+                if(nowMonth < 2) {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear - 1, nowMonth + 12 - 2, 1));
+                }else {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear, nowMonth - 2, 1));
+                }
+                maxDate = now;
+                break;
+            }
+            case 4: {//近半年
+                if(nowMonth < 5) {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear - 1, nowMonth + 12 - 5, 1));
+                }else {
+                    minDate = Ext.Date.getFirstDateOfMonth(new Date(nowYear, nowMonth - 5, 1));
+                }
+                maxDate = now;
+                break;
+            }
+            case 5://本年度
+                minDate = new Date(nowYear, 0, 1);
+                maxDate = new Date(nowYear, 11, 31);
+                break;
+            case 6://上年度
+                minDate = new Date(nowYear - 1, 0, 1);
+                maxDate = new Date(nowYear - 1, 11, 31);
+                break;
+            case 7://自定义
+                minDate = new Date(1970, 0, 1);
+                maxDate = new Date(nowYear + 100, 11, 31);
+                break;
+            default:
+                minDate = new Date(1970, 0, 1);
+                maxDate = new Date(nowYear + 100, 11, 31);
+                break;
+        }
+        from.setMaxValue(maxDate);
+        from.setMinValue(minDate);
+        to.setMaxValue(maxDate);
+        to.setMinValue(minDate);
+        if(v == 7) {
+            from.setValue(null);
+            to.setValue(null);
+            me.firstVal = null;
+            me.secondVal = null;
+            //from.setEditable(true);
+            //to.setEditable(true);
+        } else {
+            from.setValue(minDate);
+            to.setValue(maxDate);
+            me.firstVal = minDate;
+            me.secondVal = maxDate;
+            from.setEditable(false);
+            to.setEditable(false);
+        }
+        me.setBindValue(v, minDate, maxDate);
+    },
+    setInitValue: function(v) {
+        if (v) {
+            this.combo.setValue(v);
+            this.setDateFieldValue(v);
+        }
+    },
+    setBindValue: function(v, from, to){
+        this.value = {
+            type: v,
+            from: from,
+            to: to
+        };
+        this.publishState('value', this.value);
+    },
+    setValue: function(v) {
+        this.value = v;
+    },
+    getValue: function(){
+        return this.value;
+    },
+    listeners: {
+        afterrender: function(){
+            var tablename = this.ownerCt == null ? '' : this.ownerCt.tablename;
+            if(this.firstVal != null && this.secondVal != null) {
+                this.valuePrint = "{"+tablename+"."+this.name+"}>=date('"+Ext.Date.toString(this.firstVal)+"') and {"
+                    +tablename+"."+this.name+"}<=date('"+Ext.Date.toString(this.secondVal)+"')";
+            }
+        }
+    },
+    hideScope: function(bool) {
+        if(bool)
+            this.items.items[0].hide();
+        else
+            this.items.items[0].show();
+    },
+    mregex: /^[1-9]\d{3}[0-1]\d$/,
+    setMonthValue: function(val) {
+        if(this.mregex.test(val)) {
+            var me = this,
+                d = Ext.Date.parse(val + '01', 'Ymd'),
+                f = Ext.Date.getFirstDateOfMonth(d),
+                l = Ext.Date.getLastDateOfMonth(d);
+            var from =me.from,to=me.to;
+            from.setMaxValue(l);
+            from.setMinValue(f);
+            to.setMaxValue(l);
+            to.setMinValue(f);
+            from.setValue(f);
+            to.setValue(l);
+        }
+    },
+    getFilter: function() {
+        var me = this, fromVal = me.from.getValue(), toVal = me.to.getValue();
+        return (fromVal || toVal) ? {
+            "gte": fromVal ? Ext.Date.format(fromVal, 'Y-m-d') : null,
+            "lte": toVal ? Ext.Date.format(toVal, 'Y-m-d') : null
+        } : null;
+    }
+});

+ 26 - 0
frontend/operation-web/app/view/core/form/field/ConDateField.scss

@@ -0,0 +1,26 @@
+.x-condatefield {
+    .x-field {
+        background: #fff;
+    }
+
+    .x-field:first-child {
+        .x-form-trigger-wrap-default {
+            border-top-right-radius: 0;
+            border-bottom-right-radius: 0;
+        }
+    }
+    .x-field:nth-child(2) {
+        .x-form-trigger-wrap-default {
+            border-radius: 0;
+            border-left: 0;
+            border-right: 0;
+        }
+    }
+    .x-field:last-child {
+        .x-form-trigger-wrap-default {
+            border-top-left-radius: 0;
+            border-bottom-left-radius: 0;
+        }
+    }
+
+}

+ 70 - 59
frontend/operation-web/app/view/cuservice/Feedback.js

@@ -2,68 +2,79 @@
  * 在线反馈
  */
 Ext.define('saas.view.cuservice.Feedback', {
-    extend: 'saas.view.core.List',
+    extend: 'saas.view.core.base.BasePanel',
     xtype: 'cuservice-feedback',
 
-    viewModel: 'cuservice',
+    initComponent: function () {
+        Ext.apply(this, {
+            searchField: [{
+                xtype: "textfield",
+                name: "cf_name",
+                width: 300,
+                emptyText: '反馈人/反馈内容',
+                getCondition: function (v) {
+                    return "(upper(CONCAT(cf_name, '#', cf_content) like '%" + v.toUpperCase() + "%' ))";
+                },
+            }, {
+                xtype: 'condatefield',
+                name: 'cf_creatime',
+                columnWidth: 0.4
+            }],
 
-    cls: 'x-infocardlist',
-
-    id: 'feedback',
-
-    border: 1,
-
-    columns: [{
-        text: 'id',
-        dataIndex: 'cf_id',
-        hidden: true
-    }, {
-        text: '反馈人',
-        dataIndex: 'cf_name',
-        width: 120
-    }, {
-        text: '反馈时间',
-        dataIndex: 'cf_creatime',
-        width: 180,
-        renderer: function(v, m, r) {
-            return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
-        }
-    }, {
-        text: '反馈内容',
-        width: 250,
-        dataIndex: 'cf_content'
-    }, {
-        text: '状态',
-        dataIndex: 'cf_status',
-        width: 80
-    }, {
-        text: '企业id',
-        dataIndex: 'cf_companyid',
-        hidden: true
-    }, {
-        text: '企业名',
-        dataIndex: 'cf_company',
-        width: 120
-    }, {
-        text: '联系电话',
-        dataIndex: 'cf_mobile',
-        width: 120
-    }, {
-        text: 'QQ',
-        dataIndex: 'cf_qq',
-        width: 120
-    }, {
-        text: '微信',
-        dataIndex: 'cf_wechat',
-        width: 120
-    }, {
-        text: '备注',
-        dataIndex: 'cf_remark',
-        width: 250
-    }],
-
-    bind: {
-        store: '{feedback}'
+            gridConfig: {
+                // dataUrl: '/api/operation/customerFeedBack/list',
+                dataUrl: 'http://10.1.80.35:9040/customerFeedBack/list',
+                columns: [{
+                    text: 'id',
+                    dataIndex: 'cf_id',
+                    hidden: true
+                }, {
+                    text: '反馈人',
+                    dataIndex: 'cf_name',
+                    width: 120
+                }, {
+                    text: '反馈时间',
+                    dataIndex: 'cf_creatime',
+                    width: 180,
+                    renderer: function(v, m, r) {
+                        return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
+                    }
+                }, {
+                    text: '反馈内容',
+                    width: 250,
+                    dataIndex: 'cf_content'
+                }, {
+                    text: '状态',
+                    dataIndex: 'cf_status',
+                    width: 80
+                }, {
+                    text: '企业id',
+                    dataIndex: 'cf_companyid',
+                    hidden: true
+                }, {
+                    text: '企业名',
+                    dataIndex: 'cf_company',
+                    width: 120
+                }, {
+                    text: '联系电话',
+                    dataIndex: 'cf_mobile',
+                    width: 120
+                }, {
+                    text: 'QQ',
+                    dataIndex: 'cf_qq',
+                    width: 120
+                }, {
+                    text: '微信',
+                    dataIndex: 'cf_wechat',
+                    width: 120
+                }, {
+                    text: '备注',
+                    dataIndex: 'cf_remark',
+                    width: 250
+                }]
+            },
+        });
+        this.callParent(arguments);
     }
 
 });

+ 0 - 25
frontend/operation-web/app/view/cuservice/Models.js

@@ -1,25 +0,0 @@
-Ext.define('saas.view.cuservice.Models', {
-    extend: 'Ext.app.ViewModel',
-    alias: 'viewmodel.cuservice',
-
-    stores: {
-        feedback: {
-            model: 'saas.model.cuservice.Feedback',
-            autoLoad: true,
-            proxy: {
-                type: 'ajax',
-                // url: 'http://10.1.80.33:9040/customerFeedBack/list',
-                url: '/api/operation/customerFeedBack/list',
-                timeout: 8000,
-                actionMethods: {
-                    read: 'GET'
-                },
-                reader: {
-                    type: 'json',
-                    rootProperty: 'data.list',
-                    totalProperty: 'data.total',
-                }
-            }
-        }
-    }
-});

+ 57 - 27
frontend/operation-web/app/view/statistical/CompanyAnalysis.js

@@ -2,35 +2,65 @@
  * 企业分析
  */
 Ext.define('saas.view.statistical.CompanyAnalysis', {
-    extend: 'saas.view.core.List',
+    extend: 'saas.view.core.base.BasePanel',
     xtype: 'statistical-companyanalysis',
 
-    columns: [{
-        text: '企业名称',
-        dataIndex: 'name'
-    }, {
-        text: '企业地址',
-        dataIndex: 'address'
-    }, {
-        text: '管理员',
-        dataIndex: 'administrator'
-    }, {
-        text: '注册时间',
-        dataIndex: 'registeTime'
-    }, {
-        text: '最近操作时间',
-        dataIndex: 'lastTime'
-    }, {
-        text: '目前阶段',
-        dataIndex: 'step'
-    }, {
-        text: '使用状态',
-        dataIndex: 'status'
-    }],
+    initComponent: function () {
+        Ext.apply(this, {
+            searchField: [{
+                xtype: "textfield",
+                name: "ca_company",
+                emptyText: '企业名称'
+            }, {
+                xtype: 'textfield',
+                name: 'ca_admin',
+                emptyText: '管理员'
+            }],
 
-    store: Ext.create('Ext.data.Store', {
-        fields: ['name', 'address', 'administrator', 'registeTime', 'lastTime', 'step', 'status'],
-        data: [],
-    })
+            gridConfig: {
+                // dataUrl: '/api/operation/data/getCompany',
+                dataUrl: 'http://10.1.80.35:9040/data/getConpanyAnalyze',
+                columns: [{
+                    text: 'ID',
+                    dataIndex: 'ca_id',
+                    hidden: true
+                }, {
+                    text: '企业ID',
+                    dataIndex: 'ca_companyid',
+                    hidden: true
+                }, {
+                    text: '企业名称',
+                    dataIndex: 'ca_company',
+                    width: 200
+                }, {
+                    text: '企业地址',
+                    dataIndex: 'ca_address',
+                    width: 200
+                }, {
+                    text: '管理员',
+                    dataIndex: 'ca_admin'
+                }, {
+                    text: '注册时间',
+                    dataIndex: 'ca_createtime',
+                    xtype: 'datecolumn',
+                    format: 'Y-m-d H:i:s',
+                    width: 150
+                }, {
+                    text: '最近操作时间',
+                    dataIndex: 'ca_newestlogtime',
+                    xtype: 'datecolumn',
+                    format: 'Y-m-d H:i:s',
+                    width: 150
+                }, {
+                    text: '目前阶段',
+                    dataIndex: 'ca_phase'
+                }, {
+                    text: '使用状态',
+                    dataIndex: 'ca_status'
+                }]
+            },
+        });
+        this.callParent(arguments);
+    }
 
 });

+ 0 - 57
frontend/operation-web/app/view/statistical/CompanyInfo.js

@@ -1,57 +0,0 @@
-/**
- * 企业注册数据
- */
-Ext.define('saas.view.statistical.CompanyInfo', {
-    extend: 'saas.view.core.List',
-    xtype: 'statistical-companyinfo',
-
-    viewModel: 'statistical',
-
-    id: 'companyinfo',
-    columns: [{
-        text: '注册时间',
-        dataIndex: 'create_time',
-        width: 180,
-        xtype: 'datecolumn',
-        renderer: function(v, m, r) {
-            return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
-        }
-    }, {
-        text: '企业编号',
-        width: 200,
-        dataIndex: 'business_code'
-    }, {
-        text: '企业名称',
-        width: 200,
-        dataIndex: 'name'
-    }, {
-        text: 'UU号',
-        width: 120,
-        dataIndex: 'uu'
-    }, {
-        text: '企业地址',
-        width: 250,
-        dataIndex: 'address'
-    }, {
-        text: '电话',
-        width: 120,
-        dataIndex: 'tel'
-    }, {
-        text: '传真',
-        width: 150,
-        dataIndex: 'fax'
-    }, {
-        text: '管理员',
-        width: 100,
-        dataIndex: 'realname'
-    }, {
-        text: '联系方式',
-        width: 150,
-        dataIndex: 'mobile'
-    }],
-
-    bind: {
-        store: '{companyinfo}'
-    }
-
-});

+ 69 - 0
frontend/operation-web/app/view/statistical/CompanyRegInfo.js

@@ -0,0 +1,69 @@
+/**
+ * 企业注册数据
+ */
+Ext.define('saas.view.statistical.CompanyRegInfo', {
+    extend: 'saas.view.core.base.BasePanel',
+    xtype: 'statistical-companyreginfo',
+
+    initComponent: function () {
+        Ext.apply(this, {
+            searchField: [{
+                xtype: "textfield",
+                name: "name",
+                emptyText: '企业名称'
+            }, {
+                xtype: 'textfield',
+                name: 'realname',
+                emptyText: '管理员'
+            }],
+
+            gridConfig: {
+                // dataUrl: '/api/operation/data/getCompany',
+                dataUrl: 'http://10.1.80.35:9040/data/getCompany',
+                columns: [{
+                    text: '注册时间',
+                    dataIndex: 'create_time',
+                    width: 180,
+                    xtype: 'datecolumn',
+                    renderer: function(v, m, r) {
+                        return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
+                    }
+                }, {
+                    text: '企业编号',
+                    width: 200,
+                    dataIndex: 'business_code'
+                }, {
+                    text: '企业名称',
+                    width: 200,
+                    dataIndex: 'name'
+                }, {
+                    text: 'UU号',
+                    width: 120,
+                    dataIndex: 'uu'
+                }, {
+                    text: '企业地址',
+                    width: 250,
+                    dataIndex: 'address'
+                }, {
+                    text: '电话',
+                    width: 120,
+                    dataIndex: 'tel'
+                }, {
+                    text: '传真',
+                    width: 150,
+                    dataIndex: 'fax'
+                }, {
+                    text: '管理员',
+                    width: 100,
+                    dataIndex: 'realname'
+                }, {
+                    text: '联系方式',
+                    width: 150,
+                    dataIndex: 'mobile'
+                }]
+            },
+        });
+        this.callParent(arguments);
+    }
+
+});

+ 42 - 31
frontend/operation-web/app/view/statistical/LoginLog.js

@@ -2,40 +2,51 @@
  * 登录日志
  */
 Ext.define('saas.view.statistical.LoginLog', {
-    extend: 'saas.view.core.List',
+    extend: 'saas.view.core.base.BasePanel',
     xtype: 'statistical-loginlog',
 
-    viewModel: 'statistical',
+    initComponent: function () {
+        Ext.apply(this, {
+            searchField: [{
+                xtype: "textfield",
+                name: "username",
+                emptyText: '用户名/手机号',
+                getCondition: function (v) {
+                    return "(upper(CONCAT(username, '#', mobile) like '%" + v.toUpperCase() + "%' )";
+                },
+            }],
 
-    id: 'loginlog',
-
-    columns: [{
-        text: 'id',
-        dataIndex: 'account_id',
-        hidden: true
-    }, {
-        text: '用户名',
-        dataIndex: 'username',
-        width: 120
-    }, {
-        text: '手机号',
-        dataIndex: 'mobile',
-        width: 120
-    }, {
-        text: '近三月登录次数',
-        dataIndex: 'login_num'
-    }, {
-        text: '最后登录时间',
-        dataIndex: 'lastesttime',
-        width: 180,
-        xtype: 'datecolumn',
-        renderer: function(v, m, r) {
-            return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
-        }
-    }],
-
-    bind: {
-        store: '{loginlog}'
+            gridConfig: {
+                // dataUrl: '/api/operation/data/getLogin',
+                dataUrl: 'http://10.1.80.35:9040/data/getLogin',
+                columns: [{
+                    text: 'id',
+                    dataIndex: 'account_id',
+                    hidden: true
+                }, {
+                    text: '用户名',
+                    dataIndex: 'username',
+                    width: 120
+                }, {
+                    text: '手机号',
+                    dataIndex: 'mobile',
+                    width: 120
+                }, {
+                    text: '近三月登录次数',
+                    dataIndex: 'login_num',
+                    width: 120
+                }, {
+                    text: '最后登录时间',
+                    dataIndex: 'lastesttime',
+                    width: 180,
+                    xtype: 'datecolumn',
+                    renderer: function(v, m, r) {
+                        return Ext.Date.format(new Date(v), 'Y-m-d H:i:s');
+                    }
+                }]
+            },
+        });
+        this.callParent(arguments);
     }
 
 });

+ 0 - 63
frontend/operation-web/app/view/statistical/Models.js

@@ -1,63 +0,0 @@
-Ext.define('saas.view.statistical.Models', {
-    extend: 'Ext.app.ViewModel',
-    alias: 'viewmodel.statistical',
-
-    stores: {
-        personinfo: {
-            model: 'saas.model.statistical.PersonInfo',
-            autoLoad: true,
-            proxy: {
-                type: 'ajax',
-                // url: 'http://10.1.80.33:9040/data/getAccount',
-                url: '/api/operation/data/getAccount',
-                timeout: 8000,
-                actionMethods: {
-                    read: 'GET'
-                },
-                reader: {
-                    type: 'json',
-                    rootProperty: 'data.list',
-                    totalProperty: 'data.total',
-                }
-            }
-        },
-
-        companyinfo: {
-            model: 'saas.model.statistical.CompanyInfo',
-            autoLoad: true,
-            proxy: {
-                type: 'ajax',
-                // url: 'http://10.1.80.33:9040/data/getCompany',
-                url: '/api/operation/data/getCompany',
-                timeout: 8000,
-                actionMethods: {
-                    read: 'GET'
-                },
-                reader: {
-                    type: 'json',
-                    rootProperty: 'data.list',
-                    totalProperty: 'data.total',
-                }
-            }
-        },
-
-        loginlog: {
-            model: 'saas.model.statistical.LoginLog',
-            autoLoad: true,
-            proxy: {
-                type: 'ajax',
-                // url: 'http://10.1.80.33:9040/data/getLogin',
-                url: '/api/operation/data/getLogin',
-                timeout: 8000,
-                actionMethods: {
-                    read: 'GET'
-                },
-                reader: {
-                    type: 'json',
-                    rootProperty: 'data.list',
-                    totalProperty: 'data.total',
-                },
-            }
-        },
-    }
-});

+ 0 - 64
frontend/operation-web/app/view/statistical/PersonInfo.js

@@ -1,64 +0,0 @@
-/**
- * 个人注册数据
- */
-Ext.define('saas.view.statistical.PersonInfo', {
-    extend: 'saas.view.core.List',
-    xtype: 'statistical-personinfo',
-
-    viewModel: 'statistical',
-
-    id: 'personinfo',
-
-    columns: [{
-        text: 'id',
-        dataIndex: 'id',
-        hidden: true
-    }, {
-        text: '账号',
-        dataIndex: 'username',
-        width: 120
-    }, {
-        text: '姓名',
-        dataIndex: 'realname',
-        width: 120
-    }, {
-        text: '邮箱',
-        dataIndex: 'email',
-        width: 180
-    }, {
-        text: '手机号',
-        dataIndex: 'mobile',
-        width: 120
-    }, {
-        text: '类型',
-        dataIndex: 'type',
-        width: 140,
-        renderer: function(v, m, r) {
-            return v == 1 ? '<span style="font-weight: bold;">管理员</span>' : '普通用户';
-        }
-    }, {
-        text: '状态',
-        dataIndex: 'enabled',
-        width: 80,
-        renderer: function(v, m, r) {
-            return v == true ? '<span style="color: #81CB31;">正常</span>' : '<span style="color: #DD6550;">禁用</span>';
-        }
-    }, {
-        text: '注册时间',
-        xtype: 'datecolumn',
-        dataIndex: 'createTime',
-        width: 180,
-        renderer: function(v, m, r) {
-            return Ext.Date.format(new Date(v), 'Y-m-d H:i:s'); 
-        }
-    }, {
-        text: 'UU号',
-        dataIndex: 'uu',
-        width: 120
-    }],
-
-    bind: {
-        store: '{personinfo}'
-    }
-
-});

+ 74 - 0
frontend/operation-web/app/view/statistical/PersonRegInfo.js

@@ -0,0 +1,74 @@
+/**
+ * 个人注册数据
+ */
+Ext.define('saas.view.statistical.PersonRegInfo', {
+    extend: 'saas.view.core.base.BasePanel',
+    xtype: 'statistical-personreginfo',
+
+    initComponent: function () {
+        Ext.apply(this, {
+            searchField: [{
+                xtype: "textfield",
+                name: "username",
+                emptyText: '用户名/手机号',
+                getCondition: function (v) {
+                    return "(upper(CONCAT(username, '#', mobile) like '%" + v.toUpperCase() + "%'))";
+                },
+            }],
+
+            gridConfig: {
+                // dataUrl: '/api/operation/data/getAccount',
+                dataUrl: 'http://10.1.80.35:9040/data/getAccount',
+                columns: [{
+                    text: 'id',
+                    dataIndex: 'id',
+                    hidden: true
+                }, {
+                    text: '账号',
+                    dataIndex: 'username',
+                    width: 120
+                }, {
+                    text: '姓名',
+                    dataIndex: 'realname',
+                    width: 120
+                }, {
+                    text: '邮箱',
+                    dataIndex: 'email',
+                    width: 180
+                }, {
+                    text: '手机号',
+                    dataIndex: 'mobile',
+                    width: 120
+                }, {
+                    text: '类型',
+                    dataIndex: 'type',
+                    width: 140,
+                    renderer: function(v, m, r) {
+                        return v == 1 ? '<span style="font-weight: bold;">管理员</span>' : '普通用户';
+                    }
+                }, {
+                    text: '状态',
+                    dataIndex: 'enabled',
+                    width: 80,
+                    renderer: function(v, m, r) {
+                        return v == true ? '<span style="color: #81CB31;">正常</span>' : '<span style="color: #DD6550;">禁用</span>';
+                    }
+                }, {
+                    text: '注册时间',
+                    xtype: 'datecolumn',
+                    dataIndex: 'createTime',
+                    width: 180,
+                    renderer: function(v, m, r) {
+                        return Ext.Date.format(new Date(v), 'Y-m-d H:i:s'); 
+                    }
+                }, {
+                    text: 'UU号',
+                    dataIndex: 'uu',
+                    width: 120
+                }]
+            },
+        });
+        this.callParent(arguments);
+    }
+
+});

+ 6 - 2
frontend/operation-web/resources/json/navigation.json

@@ -6,11 +6,11 @@
         "items": [{
             "id": "1",
             "text": "企业注册数据",
-            "viewType": "statistical-companyinfo"
+            "viewType": "statistical-companyreginfo"
         }, {
             "id": "2",
             "text": "个人注册数据",
-            "viewType": "statistical-personinfo"
+            "viewType": "statistical-personreginfo"
         }]
     }, {
         "text": "行为统计",
@@ -18,6 +18,10 @@
             "id": "4",
             "text": "用户访问日志",
             "viewType": "statistical-loginlog"
+        }, {
+            "id": "5",
+            "text": "企业分析",
+            "viewType": "statistical-companyanalysis"
         }]
     }]
 }, {

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

@@ -263,7 +263,7 @@ import { setTimeout, clearTimeout } from 'timers';
                                 this.islookup = true;
                                 this.companyId = null;
                                 this.isgsname = true;//公司是否存在
-                            } else if (res.data.success == false && res.data.message == '公司不存在') {
+                            } else if (res.data.success == false && res.data.message == '企业不存在') {
                                 this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/warning.png" alt=""> 企业或管理员不存在';
                                 this.islookup = false;
                                 this.isgsname = false;//公司是否存在 
@@ -279,11 +279,15 @@ import { setTimeout, clearTimeout } from 'timers';
             //企业名称2提示语显示
             showwarning(){
                 let qyname = this.$refs.lookupqyname.value.replace(/\s+/g, "");//企业名字
-                if (!this.companyId && qyname!='') {
-                    this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/warning.png" alt=""> 请选择要加入的企业';
-                } else {
-                    this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/ok.png" alt="">'
-                }
+                if (!qyname) {
+                    this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/warning.png" alt=""> 企业或管理员不能为空';
+                } else if (this.isgsname) {
+                    if (this.companyId == null) {
+                        this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/warning.png" alt=""> 请选择要加入的企业';
+                    } else {
+                        this.$refs.warningqyname.innerHTML = '<img style="width:14px" src="/static/img/ok.png" alt="">'
+                    }
+                };
                 setTimeout(()=>{
                     this.iswarning = true;
                 },100)

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

@@ -38,6 +38,7 @@
                 <li><router-link to="/home"><a @click="setTurnHome"><span style="color: white">首页</span></a></router-link></li>
                 <li><a href="#" @click="feature"><span>特色</span></a></li>
                 <li><a href="#" @click="service"><span>功能</span></a></li>
+                <!-- <li><a href="#" @click="download"><span>下载</span></a></li> -->
                 <!-- <router-link to="/invitation"><a ><span style="color: white">邀请</span></a></router-link> -->
                 <li>
                     <el-menu  
@@ -450,12 +451,17 @@ import { setTimeout } from 'timers';
             },
             // 特色
             feature(){
-                this.$router.push({name: 'Home', params: {isfeature: 700}});
+                this.$router.push({name: 'Home', params: {isfeature: 730}});
                 this.setTurnHome();
             },
             //功能
             service(){
-                this.$router.push({name: 'Home', params: {isfeature: 3550}});
+                this.$router.push({name: 'Home', params: {isfeature: 3670}});
+                this.setTurnHome();
+            },
+            // 下载
+            download(){
+                this.$router.push({name: 'Home', params: {isfeature: 4400}});
                 this.setTurnHome();
             },
             gohome(e){

+ 114 - 4
frontend/saas-portal-web/src/components/conenter/home.vue

@@ -47,6 +47,7 @@
             <li><a href="#" @click="setTurnHome"><span>首页</span></a></li>
             <li class="xs"><a @click="feature2"><span>特色</span></a></li>
             <li class="xs"><a @click="service2"><span>功能</span></a></li>
+            <!-- <li class="xs"><a @click="download"><span>下载</span></a></li> -->
             <li>
               <el-menu  
               class="el-menu-demo" 
@@ -252,6 +253,45 @@
         </div>
       </section>
       <!-- end Service section -->
+      <!-- 下载 -->
+      <!-- <section>
+        <div class="container ts-worp">
+          <div class="section-title text-center" style="margin-bottom: 50px">
+            <p class="ts-title">下载</p>
+            <p class="ts-text">下载U企云服客户端</p>
+          </div>
+          <div class="download-conenter">
+            <div class="left download-box">
+              <div class="download-box-shang">
+                <img style="width:140px" src="/static/img/weiruan@2x.png" alt="">
+              </div>
+              <div class="download-box-xia">
+                <p class="download-title">U企云服PC版</p>
+                <p>适用于Windows86</p>
+                <p class="download-Edition">
+                  <span>-最新版:16.30.0</span> <br/>
+                  <span>-发布时间:2018-10-20</span>
+                </p>
+                <button class="download-btn" @click="downloadOne">立即下载</button>
+              </div>
+            </div>
+            <div class="right download-box">
+              <div class="download-box-shang">
+                <img style="width:140px" src="/static/img/weiruan@2x.png" alt="">
+              </div>
+              <div class="download-box-xia">
+                <p class="download-title">U企云服PC版</p>
+                <p>适用于Windows64</p>
+                <p class="download-Edition">
+                  <span>-最新版:16.30.0</span> <br/>
+                  <span>-发布时间:2018-10-20</span>
+                </p>
+                <button class="download-btn">立即下载</button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section> -->
     </main>
     <problem v-else></problem>
   </div>
@@ -316,7 +356,7 @@
               const me = this || _this;
               //点击首页按钮时不跳转企业列表
               if(!me.$parent.turnHome){
-                me.$router.push({path: '/enterprise'})
+                me.$router.push({path: '/enterprise'});
               }else{
                 me.$parent.turnHome = false
               }
@@ -331,7 +371,6 @@
       document.documentElement.scrollTop = this.isfeature;
       $(window).scroll(function() {
         let Y = $(window).scrollTop();
-        console.log(Y);
         if (Y >= 500 && Y <= 1500) {
           $(".animate1").stop();
           $(".animate1").animate({
@@ -482,6 +521,21 @@
           me.isRegister = false
         })
       },
+      // 下载1
+      downloadOne(){
+        console.log('我是下载按钮')
+        let url = '/static/img/banner--X.jpg';
+        // let url = 'http://h.hiphotos.baidu.com/image/h%3D300/sign=f2db86688ccb39dbdec06156e01709a7/2f738bd4b31c87018e9450642a7f9e2f0708ff16.jpg';
+        let alink = document.createElement("a");
+        alink.style.display = 'none';
+        // let blob = new Blob([url]);
+        // alink.href = URL.createObjectURL(blob);
+        alink.href = url;//下载地址
+        alink.download = "pic"; //文件名(自定义)
+        document.body.appendChild(alink);
+        alink.click();
+        // URL.revokeObjectURL(alink.href);
+      },
       //体验
       experience(){
         if (this.account) {
@@ -546,14 +600,21 @@
       //特色
       feature2(){
         setTimeout(()=>{
-          document.documentElement.scrollTop = 700;
+          document.documentElement.scrollTop = 730;
         },5);
         this.setTurnHome();
       },
       //功能
       service2(){
         setTimeout(()=>{
-          document.documentElement.scrollTop = 3550;
+          document.documentElement.scrollTop = 3670;
+        },5);
+        this.setTurnHome();
+      },
+      // 下载
+      download(){
+        setTimeout(()=>{
+          document.documentElement.scrollTop = 4400;
         },5);
         this.setTurnHome();
       },
@@ -674,4 +735,53 @@
   display: inline-block;
   height: 16px;
 }
+/* 下载 */
+.download-conenter {
+  width: 55%;
+  height: 420px;
+  position: relative;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 100px;
+}
+.download-box {
+  width: 49%;
+  height: 100%;
+  border: 1px solid #5DA9F8;
+}
+.download-box-shang {
+  height: 50%;
+  background: #1E88F5;
+  text-align: center;
+  line-height: 210px;
+}
+.download-title {
+  font-size: 18px;
+  color: #0D253E;
+  font-weight: 550;
+}
+.download-box-xia {
+  text-align: center;
+  padding: 20px;
+  line-height: 30px;
+  color: rgb(103, 107, 112);
+  font-size: 14px;
+}
+.download-Edition {
+  text-align: left;
+  margin-left: 28%;
+  line-height: 20px;
+}
+.download-btn {
+  font-family: PingFangSC-Regular;
+  font-size: 14px;
+  color: #FFFFFF;
+  letter-spacing: 0.7px;
+  background: #1E88F5;
+  box-shadow: 0 0 99px 0 #E4F2FF;
+  border-radius: 4px;
+  padding: 2px 30px;
+  border: 0;
+  margin-top: 5%
+}
 </style>

+ 1 - 1
frontend/saas-portal-web/static/css/main.css

@@ -38,7 +38,7 @@ h1, h2, h3, h4, h5, h6,
     color: #252525;
 }
 p {
-    font-size: 15px;
+    font-size: 14px;
 }
 li {
     list-style: none;

BIN
frontend/saas-portal-web/static/img/weiruan@2x.png


+ 172 - 33
frontend/saas-web/app/view/core/base/BasePanel.js

@@ -6,9 +6,6 @@ Ext.define('saas.view.core.base.BasePanel', {
     viewModel: 'core-base-basepanel',
 
     cls:'core-base-basepanel',
-    //工具类
-    FormUtil: Ext.create('saas.util.FormUtil'),
-    BaseUtil: Ext.create('saas.util.BaseUtil'),
 
     //基础属性
     frame:false,
@@ -35,43 +32,37 @@ Ext.define('saas.view.core.base.BasePanel', {
 
         var me = this,
         gridConfig = me.gridConfig,
-        gridDataUrl = gridConfig.dataUrl,
-        gridIdField = gridConfig.idField,
-        gridCodeField = gridConfig.codeField,
-        gridStatusCodeField = gridConfig.statusCodeField,
-        gridColumns = Ext.Array.clone(gridConfig.columns),
-        deleteMsg = gridConfig.deleteMsg;
+        gridColumns = Ext.Array.clone(gridConfig.columns);
+
+        var gridcfg = {
+            layout: 'fit',
+            xtype: 'core-base-gridpanel',
+            padding: '8 12',
+            _columns: gridColumns.map(function(c) {
+                return Object.assign({}, c);
+            }),
+        };
+        Ext.apply(gridcfg ,me.gridConfig);
 
         Ext.apply(me, {
             dockedItems: [{
                 frame:false,
                 xtype: 'toolbar',
                 dock: 'top',
+                layout: 'column',
                 style: {
-                    // 'border-bottom': '1px solid #35baf6 !important',
                     margin: '0 0 12px 0',
                     padding: '10px 0 14px 8px',
                 },
                 items: me.searchField.concat([{
-                    // cls:'x-formpanel-btn-orange',
                     xtype: 'button',
                     text: '查询',
-                    handler: 'query'
+                    handler: function() {
+                        me.onQuery()
+                    }
                 }])
             }],
-            items: [{
-                layout: 'fit',
-                xtype: 'core-base-gridpanel',
-                padding: '8 12',
-                dataUrl: gridDataUrl,
-                idField: gridIdField,
-                codeField: gridCodeField,
-                _columns: gridColumns.map(function(c) {
-                    return Object.assign({}, c);
-                }),
-                statusCodeField : gridStatusCodeField,
-                deleteMsg: deleteMsg
-            }]
+            items: [gridcfg]
         });
         me.callParent(arguments);
     },
@@ -83,20 +74,168 @@ Ext.define('saas.view.core.base.BasePanel', {
             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()
+
+                if(field) {
+                    field.enableKeyEvents = true;
+                    field.on && field.on({
+                        keydown: {
+                            fn: function(th, e, eOpts) {
+                                if(e.keyCode == 13) {
+                                    form.onQuery()
+                                }
                             }
                         }
-                    }
-                });
+                    });
+                }
             });
         }
     },
 
+    onQuery: function() {
+        var me = this;
+        var grid = me.down('core-base-gridpanel');
+        
+        grid.store.loadPage(1);
+    },
+
+    /**
+     * 获得过滤条件
+     */
+    getConditions: function() {
+        var me = this;
+        var items = me.dockedItems.items[0].items.items;
+        var conditions = [];
+
+        for(let i = 0; i < items.length; i++) {
+            var item = items[i];
+            var field = item.name,
+            func = item.getCondition,
+            value = item.value,
+            condition;
+
+            if(value&&value!=''){
+                if(typeof func == 'function') {
+                    condition = {
+                        type: 'condition',
+                        value: func(value)
+                    }
+                }else {
+                    var type = item.fieldType || me.getDefaultFieldType(item),
+                    operation = item.operation || me.getDefaultFieldOperation(item),
+                    conditionValue = me.getConditionValue(item, value);
+        
+                    if(!conditionValue) {
+                        continue;
+                    }
+                    condition = {
+                        type: type,
+                        field: field,
+                        operation: operation,
+                        value: conditionValue
+                    }
+                }
+                conditions.push(condition);
+            }
+        }
+
+        return conditions;
+    },
+
+    /**
+     * 只要arr1和arr2中存在相同项即返回真
+     */
+    isContainsAny: function (arr1, arr2) {
+        for (var i = 0; i < arr2.length; i++) {
+            var a2 = arr2[i];
+            if (!!arr1.find(function (a1) {
+                    return a1 == a2
+                })) {
+                return true;
+            }
+        }
+        return false;
+    },
+
+    getDefaultFieldType: function (field) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            type;
+
+        if (me.isContainsAny(xtypes, ['numberfield'])) {
+            type = 'number';
+        } else if (me.isContainsAny(xtypes, ['datefield', 'condatefield', 'conmonthfield'])) {
+            type = 'date';
+        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
+            type = 'enum';
+        } else if (me.isContainsAny(xtypes, ['combobox', 'multicombo', 'combo', 'radiofield', 'radio'])) {
+            type = 'enum';
+        } else {
+            type = 'string';
+        }
+
+        return type;
+    },
+
+    getDefaultFieldOperation: function (field) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            operation;
+
+        if (me.isContainsAny(xtypes, ['numberfield', 'datefield', 'dbfindtrigger'])) {
+            operation = '=';
+        } else if (me.isContainsAny(xtypes, ['condatefield', 'conmonthfield'])) {
+            operation = 'between';
+        } else if (me.isContainsAny(xtypes, ['multidbfindtrigger', 'combobox', 'multicombo', 'combo'])) {
+            operation = 'in';
+        } else {
+            operation = 'like';
+        }
+
+        return operation;
+    },
+
+    /**
+     * 处理部分字段值
+     */
+    getConditionValue: function (field, value) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            conditionValue;
+        if (me.isContainsAny(xtypes, ['datefield'])) {
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d H:i:s');
+        } else if (me.isContainsAny(xtypes, ['conmonthfield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = from + ',' + to;
+        } else if (me.isContainsAny(xtypes, ['condatefield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d 00:00:00') + ',' + Ext.Date.format(new Date(to), 'Y-m-d 23:59:59');
+        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
+            conditionValue = value;
+        } else if (me.isContainsAny(xtypes, ['combobox', 'combo'])) {
+            conditionValue = '\'' + value + '\'';
+        } else if (me.isContainsAny(xtypes, ['multicombo'])) {
+            conditionValue = value.map ? value.map(function (v) {
+                return '\'' + v.value + '\'';
+            }).join(',') : '';
+        } else {
+            conditionValue = value;
+        }
+
+        return conditionValue;
+    },
+
+    getExtraParams: function(store, op, condition) {
+        return {
+            number: store.exportNumber?store.exportNumber:op._page,
+            size: store.exportPageSize?store.exportPageSize:store.pageSize,
+            condition: JSON.stringify(condition)
+        };
+    },
+
     refresh: function () {
         this.items.items[0].store.load()
     },

+ 0 - 139
frontend/saas-web/app/view/core/base/BasePanelController.js

@@ -5,151 +5,12 @@ Ext.define('saas.view.core.base.BasePanelController', {
     BaseUtil: Ext.create('saas.util.BaseUtil'),
     FormUtil: Ext.create('saas.util.FormUtil'),
 
-    query: function() {
-        var form = this.view;
-        var grid = form.down('core-base-gridpanel');
-        
-        grid.condition = this.getConditions();
-        grid.store.loadPage(1);
-    },
-
     add: function(){
         var form = this.getView();
         var id = form.xtype + '_add';
         saas.util.BaseUtil.openTab(form.xtype,'新增' + form._title,id);
     },
 
-    /**
-     * 获得过滤条件
-     */
-    getConditions: function() {
-        var me = this;
-        var form = this.view;
-        var items = form.dockedItems.items[0].items.items;
-        var conditions = [];
-
-        for(let i = 0; i < items.length; i++) {
-            var item = items[i];
-            var field = item.name,
-            func = item.getCondition,
-            value = item.value,
-            condition;
-
-            if(value&&value!=''){
-                if(typeof func == 'function') {
-                    condition = {
-                        type: 'condition',
-                        value: func(value)
-                    }
-                }else {
-                    var type = item.fieldType || me.getDefaultFieldType(item),
-                    operation = item.operation || me.getDefaultFieldOperation(item),
-                    conditionValue = me.getConditionValue(item, value);
-        
-                    if(!conditionValue) {
-                        continue;
-                    }
-                    condition = {
-                        type: type,
-                        field: field,
-                        operation: operation,
-                        value: conditionValue
-                    }
-                }
-                conditions.push(condition);
-            }
-        }
-
-        return conditions;
-    },
-
-    /**
-     * 只要arr1和arr2中存在相同项即返回真
-     */
-    isContainsAny: function (arr1, arr2) {
-        for (var i = 0; i < arr2.length; i++) {
-            var a2 = arr2[i];
-            if (!!arr1.find(function (a1) {
-                    return a1 == a2
-                })) {
-                return true;
-            }
-        }
-        return false;
-    },
-
-    getDefaultFieldType: function (field) {
-        var me = this,
-            xtypes = field.getXTypes().split('/'),
-            type;
-
-        if (me.isContainsAny(xtypes, ['numberfield'])) {
-            type = 'number';
-        } else if (me.isContainsAny(xtypes, ['datefield', 'condatefield', 'conmonthfield'])) {
-            type = 'date';
-        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
-            type = 'enum';
-        } else if (me.isContainsAny(xtypes, ['combobox', 'multicombo', 'combo', 'radiofield', 'radio'])) {
-            type = 'enum';
-        } else {
-            type = 'string';
-        }
-
-        return type;
-    },
-
-    getDefaultFieldOperation: function (field) {
-        var me = this,
-            xtypes = field.getXTypes().split('/'),
-            operation;
-
-        if (me.isContainsAny(xtypes, ['numberfield', 'datefield', 'dbfindtrigger'])) {
-            operation = '=';
-        } else if (me.isContainsAny(xtypes, ['condatefield', 'conmonthfield'])) {
-            operation = 'between';
-        } else if (me.isContainsAny(xtypes, ['multidbfindtrigger', 'combobox', 'multicombo', 'combo'])) {
-            operation = 'in';
-        } else {
-            operation = 'like';
-        }
-
-        return operation;
-    },
-
-    /**
-     * 处理部分字段值
-     */
-    getConditionValue: function (field, value) {
-        var me = this,
-            xtypes = field.getXTypes().split('/'),
-            conditionValue;
-        if (me.isContainsAny(xtypes, ['datefield'])) {
-            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d H:i:s');
-        } else if (me.isContainsAny(xtypes, ['conmonthfield'])) {
-            var from = value.from,
-                to = value.to;
-
-            conditionValue = from + ',' + to;
-        } else if (me.isContainsAny(xtypes, ['condatefield'])) {
-            var from = value.from,
-                to = value.to;
-
-            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d 00:00:00') + ',' + Ext.Date.format(new Date(to), 'Y-m-d 23:59:59');
-        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
-            conditionValue = value;
-        } else if (me.isContainsAny(xtypes, ['combobox', 'combo'])) {
-            conditionValue = '\'' + value + '\'';
-        } else if (me.isContainsAny(xtypes, ['multicombo'])) {
-            conditionValue = value.map ? value.map(function (v) {
-                return '\'' + v.value + '\'';
-            }).join(',') : '';
-        } else {
-            conditionValue = value;
-        }
-
-        return conditionValue;
-    },
-
     onColSetting: function() {
         var me = this,
         panel = me.getView(),

+ 4 - 0
frontend/saas-web/app/view/core/base/BasePanelModel.js

@@ -1,4 +1,8 @@
 Ext.define('saas.view.core.base.BasePanelModel', {
     extend: 'Ext.app.ViewModel',
     alias: 'viewmodel.core-base-basepanel',
+
+    data: {
+        configurable: true
+    }
 });

+ 11 - 9
frontend/saas-web/app/view/core/base/GridPanel.js

@@ -23,6 +23,8 @@ Ext.define('saas.view.core.base.GridPanel', {
     dataUrl: '',
     dbSearchFields: [],
     condition:'',
+    rootProperty: 'data.list',
+    totalProperty: 'data.total',
 
     actionColumn: [{
         xtype:'actioncolumn',
@@ -71,8 +73,8 @@ Ext.define('saas.view.core.base.GridPanel', {
                     },
                     reader: {
                         type: 'json',
-                        rootProperty: 'data.list',
-                        totalProperty: 'data.total',
+                        rootProperty: me.rootProperty,
+                        totalProperty: me.totalProperty,
                     },
                     listeners: {
                         exception: function(proxy, response, operation, eOpts) {
@@ -89,15 +91,14 @@ Ext.define('saas.view.core.base.GridPanel', {
                 },
                 listeners: {
                     beforeload: function (store, op) {
-                        var condition = me.condition;
+                        var basePanel = me.up('core-base-basepanel');
+                        var condition = basePanel.getConditions();
                         if (Ext.isEmpty(condition)) {
                             condition = "";
                         }
-                        Ext.apply(store.proxy.extraParams, {
-                            number: store.exportNumber?store.exportNumber:op._page,
-                            size: store.exportPageSize?store.exportPageSize:store.pageSize,
-                            condition: JSON.stringify(condition)
-                        });
+
+                        var obj = basePanel.getExtraParams(store, op, condition);
+                        Ext.apply(store.proxy.extraParams, obj);
                     }
                 }
             });
@@ -106,6 +107,7 @@ Ext.define('saas.view.core.base.GridPanel', {
                 dockedItems:[{
                     xtype:'toolbar',
                     dock:'top',
+                    hidden: me.hiddenTools,
                     defaults: { // defaults 将会应用所有的子组件上,而不是父容器
                         listeners: {
                             'mouseover':function(){
@@ -187,7 +189,7 @@ Ext.define('saas.view.core.base.GridPanel', {
                         text: '列设置',
                         handler: 'onColSetting',
                         bind: {
-                            hidden: '{!isAdmin}'
+                            hidden: '{!configurable || !isAdmin}'
                         }
                     }]
                 }]

+ 2 - 0
frontend/saas-web/app/view/core/form/FormPanelModel.js

@@ -16,6 +16,8 @@ Ext.define('saas.view.core.form.FormPanelModel', {
         showAuditBtn: true, // 显示审核、反审核按钮
         detailBindeFields: [], // 从表绑定列
         detailStore: null, // 从表store
+
+        configurable: true
     },
 
     formulas:{

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

@@ -138,7 +138,7 @@ Ext.define('saas.view.core.form.field.DetailGridField', {
             // text : "序号", 
             // text: '<div class="x-sa sa-setting" style="cursor: pointer;" title="列设置"></div>',
             bind: {
-                text: "{isAdmin ? ('<div class=\"x-sa sa-setting\" style=\"cursor: pointer;\" title=\"列设置\"></div>') : '序号'}"
+                text: "{(configurable && isAdmin) ? ('<div class=\"x-sa sa-setting\" style=\"cursor: pointer;\" title=\"列设置\"></div>') : '序号'}"
             },
             dataIndex : detnoField, 
             width : 60, 

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

@@ -34,6 +34,10 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
     columnWidth: 1.0,
     showRowNum: true,
     autoQuery: true,
+
+    rootProperty: 'data.list',
+    totalProperty: 'data.total',
+
     selModel: {
         checkOnly:true,
         type:'checkboxmodel',
@@ -85,8 +89,8 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                     },
                     reader: {
                         type: 'json',
-                        rootProperty: 'data.list',
-                        totalProperty: 'data.total',
+                        rootProperty: me.rootProperty,
+                        totalProperty: me.totalProperty,
                     },
                     listeners: {
                         exception: function(proxy, response, operation, eOpts) {
@@ -119,13 +123,9 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                                 value: defaultCondition
                             });
                         }
-                        Ext.apply(store.proxy.extraParams, {
-                            number: store.exportNumber?store.exportNumber:op._page,
-                            size: store.exportPageSize?store.exportPageSize:store.pageSize,
-                            mode:mode,
-                            condition: JSON.stringify(condition)
-                        });
-    
+
+                        var obj = queryPanel.getExtraParams(store, op, mode, condition);
+                        Ext.apply(store.proxy.extraParams, obj);
                     },
                     load: function(store, records, successful, operation, eOpts) {
                         var queryPanel = me.up('core-query-querypanel'),
@@ -260,7 +260,7 @@ Ext.define('saas.view.core.query.QueryGridPanel', {
                     text: '列设置',
                     handler: 'onColSetting',
                     bind: {
-                        hidden: '{!isAdmin}'
+                        hidden: '{!configurable || !isAdmin}'
                     }
                 }]
             }]

+ 9 - 0
frontend/saas-web/app/view/core/query/QueryPanel.js

@@ -313,6 +313,15 @@ Ext.define('saas.view.core.query.QueryPanel', {
 
         return detailModel ? 'DETAIL' : 'MAIN';
     },
+
+    getExtraParams: function(store, op, mode, condition) {
+       return {
+            number: store.exportNumber?store.exportNumber:op._page,
+            size: store.exportPageSize?store.exportPageSize:store.pageSize,
+            mode:mode,
+            condition: JSON.stringify(condition)
+        }
+    },
     
     refresh: function() {
         var me = this;

+ 3 - 1
frontend/saas-web/app/view/core/query/QueryPanelModel.js

@@ -10,6 +10,8 @@ Ext.define('saas.view.core.query.QueryPanelModel', {
         importEnable: true, // 显示导入按钮
         closeEnable: true, // 显示关闭按钮
         deleteEnable: true, // 显示删除按钮
-        deleteDisable:false //删除按钮是否可使用
+        deleteDisable:false, //删除按钮是否可使用
+
+        configurable: true, // 允许列设置
     }
 });

+ 87 - 87
frontend/saas-web/app/view/document/product/BasePanel.js

@@ -10,23 +10,23 @@ Ext.define('saas.view.document.product.BasePanel', {
     deleteMoreMsg: '删除的物料将不能恢复,请确认是否删除?',
     deleteOneMsg: '删除的物料将不能恢复,请确认是否删除?',
 
-    initComponent: function() {
+    initComponent: function () {
         Ext.apply(this, {
-            searchField:[{
-                xtype : "textfield", 
-                name : "pr_code", 
-                width:300, 
-                emptyText:'输入物料编号、名称、型号或品牌',
+            searchField: [{
+                xtype: "textfield",
+                name: "pr_code",
+                width: 300,
+                emptyText: '输入物料编号、名称、型号或品牌',
                 getCondition: function (v) {
                     return "(upper(CONCAT(pr_code,'#',pr_detail,'#',ifnull(pr_orispeccode,''),'#',ifnull(pr_brand,''))) like '%" + v.toUpperCase() + "%' )";
                 },
-            },{
-                editable:true,
-                hiddenBtn:true,
-                xtype : "remotecombo", 
+            }, {
+                editable: true,
+                hiddenBtn: true,
+                xtype: "remotecombo",
                 storeUrl: '/api/document/producttype/getCombo',
-                name : "pr_kind", 
-                fieldLabel : '物料类型',
+                name: "pr_kind",
+                fieldLabel: '物料类型',
                 emptyText: '全部',
             }, {
                 xtype: 'combobox',
@@ -34,123 +34,123 @@ Ext.define('saas.view.document.product.BasePanel', {
                 queryMode: 'local',
                 displayField: 'pr_status',
                 valueField: 'pr_statuscode',
-                fieldLabel : '状态',
+                fieldLabel: '状态',
                 emptyText: '全部',
-                editable:false,
-                defaultValue:'ENABLE',
+                editable: false,
+                defaultValue: 'ENABLE',
                 store: Ext.create('Ext.data.ArrayStore', {
-                fields: ['pr_statuscode', 'pr_status'],
-                data: [
-                    ["ALL", "全部"],
-                    ["ENABLE", "已启用"],
-                    ["BANNED", "已禁用"]
-                ]
+                    fields: ['pr_statuscode', 'pr_status'],
+                    data: [
+                        ["ALL", "全部"],
+                        ["ENABLE", "已启用"],
+                        ["BANNED", "已禁用"]
+                    ]
                 }),
-                getCondition: function(value) {
-                    if(value == 'ALL' || !value) {
+                getCondition: function (value) {
+                    if (value == 'ALL' || !value) {
                         return '1=1';
-                    }else {
+                    } else {
                         return 'pr_statuscode=\'' + value + '\'';
                     }
                 }
             }],
-        
+
             //字段属性
-            caller:'Product',
-            _formXtype:'document-product-formpanel',
-            _title:'物料资料',
-            _deleteUrl:'/api/document/product/delete',
-            _batchOpenUrl:'/api/document/product/batchOpen',
-            _batchCloseUrl:'/api/document/product/batchClose',
-            _batchDeleteUrl:'/api/document/product/batchDelete',
-        
+            caller: 'Product',
+            _formXtype: 'document-product-formpanel',
+            _title: '物料资料',
+            _deleteUrl: '/api/document/product/delete',
+            _batchOpenUrl: '/api/document/product/batchOpen',
+            _batchCloseUrl: '/api/document/product/batchClose',
+            _batchDeleteUrl: '/api/document/product/batchDelete',
+
             gridConfig: {
                 idField: 'id',
                 codeField: 'pr_code',
-                statusCodeField:'pr_statuscode',
+                statusCodeField: 'pr_statuscode',
                 dataUrl: '/api/document/product/list',
                 caller: 'Product',
-                columns : [{
-                    text : "id", 
-                    width : 0, 
-                    dataIndex : "id", 
-                    xtype : "numbercolumn", 
-                },{
-                    text : "物料编号", 
-                    dataIndex : "pr_code", 
-                    width : 150.0
-                },{
-                    text : "品牌", 
-                    dataIndex : "pr_brand", 
-                    width : 100.0
+                columns: [{
+                    text: "id",
+                    width: 0,
+                    dataIndex: "id",
+                    xtype: "numbercolumn",
                 }, {
-                    text : "物料名称", 
-                    dataIndex : "pr_detail", 
-                    width : 150.0
+                    text: "物料编号",
+                    dataIndex: "pr_code",
+                    width: 150.0
                 }, {
-                    text : "型号", 
-                    dataIndex : "pr_orispeccode", 
-                    width : 200.0
+                    text: "品牌",
+                    dataIndex: "pr_brand",
+                    width: 100.0
                 }, {
-                    text : "规格", 
-                    dataIndex : "pr_spec", 
-                    width : 200.0
+                    text: "物料名称",
+                    dataIndex: "pr_detail",
+                    width: 150.0
                 }, {
-                    text : "物料类型", 
-                    dataIndex : "pr_kind", 
-                    width:100
+                    text: "型",
+                    dataIndex: "pr_orispeccode",
+                    width: 200.0
                 }, {
-                    text : "库存", 
-                    dataIndex : "po_onhand",
+                    text: "规格",
+                    dataIndex: "pr_spec",
+                    width: 200.0
+                }, {
+                    text: "物料类型",
+                    dataIndex: "pr_kind",
+                    width: 100
+                }, {
+                    text: "库存",
+                    dataIndex: "po_onhand",
                     xtype: 'numbercolumn',
-                    width : 100.0,
-                    renderer : function(v, m, r) {
+                    width: 100.0,
+                    renderer: function (v, m, r) {
                         return saas.util.BaseUtil.numberFormat(v, 3, false);
                     }
                 }, {
-                    text : "单位", 
-                    dataIndex : "pr_unit", 
-                    width : 65.0 
+                    text: "单位",
+                    dataIndex: "pr_unit",
+                    width: 65.0
                 }, {
-                    text : "标准定价(元)", 
-                    dataIndex : "pr_standardprice",
+                    text: "标准定价(元)",
+                    dataIndex: "pr_standardprice",
                     xtype: 'numbercolumn',
-                    width : 110.0,
-                    renderer : function(v, m, r) {
+                    width: 110.0,
+                    renderer: function (v, m, r) {
                         return saas.util.BaseUtil.numberFormat(v, 4, true);
                     }
-                },  {
-                    text : "最新购价(元)", 
-                    dataIndex : "pr_purcprice",
+                }, {
+                    text: "最新购价(元)",
+                    dataIndex: "pr_purcprice",
                     xtype: 'numbercolumn',
-                    width : 110.0,
-                    renderer : function(v, m, r) {
+                    width: 110.0,
+                    renderer: function (v, m, r) {
                         return saas.util.BaseUtil.numberFormat(v, 4, true);
                     }
                 }, {
-                    text : "最新售价(元)", 
-                    dataIndex : "pr_saleprice",
+                    text: "最新售价(元)",
+                    dataIndex: "pr_saleprice",
                     xtype: 'numbercolumn',
-                    width : 110.0,
-                    renderer : function(v, m, r) {
+                    width: 110.0,
+                    renderer: function (v, m, r) {
                         return saas.util.BaseUtil.numberFormat(v, 4, true);
                     }
                 }, {
-                    text : "备注", 
-                    dataIndex : "pr_text1",
-                    width :250.0
+                    text: "备注",
+                    dataIndex: "pr_text1",
+                    width: 250.0
                 }, {
-                    text : "状态", 
-                    dataIndex : "pr_status",
-                    align:'center',
-                    width : 80.0
+                    text: "状态",
+                    dataIndex: "pr_status",
+                    align: 'center',
+                    width: 80.0
                 }]
             },
         });
         this.callParent(arguments);
     },
 
-    refresh:function(){
+    refresh: function () {
         this.items.items[0].store.load()
     }
 

+ 217 - 0
frontend/saas-web/app/view/sale/business/Business.js

@@ -0,0 +1,217 @@
+/**
+ * 商机-公司商机
+ */
+Ext.define('saas.view.sale.business.Business', {
+    extend: 'saas.view.core.base.BasePanel',
+    xtype: 'sale-business-business',
+
+    controller: 'sale-business-business',
+    viewModel: 'sale-business-business',
+    viewName: 'sale-business-business',
+
+
+    // dataUrl: 'http://10.1.80.23:8560/api/sale/sale/enterprise/businessChance',
+    dataUrl: '/api/sale/sale/enterprise/businessChance',
+    initComponent: function() {
+        var me = this;
+        Ext.apply(this, {
+            searchField: [{
+                xtype: 'textfield',
+                name: 'keyword',
+                columnWidth: 0.15,
+                emptyText:'请输入物料编号/名称/型号/品牌'
+            }, {
+                xtype: 'condatefield',
+                name: 'date',
+                fieldLabel: '日期',
+                labelWidth: 50,
+                columnWidth: 0.4,
+            }, {
+                xtype: 'combobox',
+                name: 'quoted',
+                fieldLabel: '报价状态',
+                queryMode: 'local',
+                displayField: 'name',
+                valueField: 'value',
+                emptyText :'全部',
+                editable:false,
+                labelWidth: 80,
+                columnWidth: 0.2,
+                store: Ext.create('Ext.data.ArrayStore', {
+                    fields: ['name', 'value'],
+                    data: [
+                        ["全部", "all"],
+                        ["未报价", "0"],
+                        ["已报价", "1"]
+                    ]
+                })
+            // }, {
+            //     xtype: 'combobox',
+            //     name: 'closed',
+            //     fieldLabel: '截止状态',
+            //     queryMode: 'local',
+            //     displayField: 'name',
+            //     valueField: 'value',
+            //     emptyText :'全部',
+            //     editable:false,
+            //     columnWidth: 0.2,
+            //     store: Ext.create('Ext.data.ArrayStore', {
+            //         fields: ['name', 'value'],
+            //         data: [
+            //             ["全部", "all"],
+            //             ["未截止", "0"],
+            //             ["已截止", "1"]
+            //         ]
+            //     })
+            }],
+        
+            caller: null,
+            _formXtype: null,
+            _title: null,
+            _deleteUrl: null,
+            _batchOpenUrl: null,
+            _batchCloseUrl: null,
+            _batchDeleteUrl: null,
+        
+            gridConfig: {
+                idField: null,
+                codeField: null,
+                statusCodeField: null,
+                dataUrl: me.dataUrl,
+                caller: null,
+                rootProperty: 'data.content',
+                totalProperty: 'data.totalElements',
+                actionColumn: [],
+                selModel: {
+                    type: 'cellmodel'
+                },
+                hiddenTools: true,
+                data: [{
+
+                }],
+                columns : [{
+                    text: '客户名称',
+                    dataIndex: 'custName',
+                    width: 200
+                }, {
+                    text: '物料品牌',
+                    dataIndex: 'prodBrand',
+                    width: 100
+                }, {
+                    text: '物料名称',
+                    dataIndex: 'prodName',
+                    width: 120
+                }, {
+                    text: '物料型号',
+                    dataIndex: 'prodOrispeccode',
+                    width: 120
+                }, {
+                    text: '物料规格',
+                    dataIndex: 'prodSpec',
+                    width: 120
+                }, {
+                    text: '物料单位',
+                    dataIndex: 'prodUnit'
+                }, {
+                    text: '采购数量',
+                    xtype: 'numbercolumn',
+                    dataIndex: 'needQty',
+                    renderer: function (v, m, r) {
+                        return saas.util.BaseUtil.numberFormat(v, 0, false);
+                    }
+                }, {
+                    text: '发布时间',
+                    xtype: 'datecolumn',
+                    dataIndex: 'startDate',
+                    format: 'Y-m-d H:i:s'
+                }, {
+                    text: '截止时间',
+                    xtype: 'datecolumn',
+                    dataIndex: 'endDate'
+                }, {
+                    text: '操作',
+                    dataIndex: 'quoted',
+                    renderer: function(v, m) {
+                        return v == 1 ? '<a style="color: green; cursor: pointer;">报价中</a>' : '<a style="color: #35BAF6; cursor: pointer;">报价</a>';
+                    },
+                    listeners: {
+                        click: function(tableView, td, rowIdx, colIdx, e, model, tr) {
+                            var dataIndex = this.dataIndex;
+                            var record = tableView.store.getAt(rowIdx);
+                            var value = record.get(dataIndex);
+                            
+                            if(value == '0') {
+                                me.getController().showQuoteWin(record);
+                            }
+                        }
+                    }
+                }]
+            },
+        });
+        this.callParent(arguments);
+    },
+
+    /**
+     * 处理部分字段值
+     */
+    getConditionValue: function (field, value) {
+        var me = this,
+            xtypes = field.getXTypes().split('/'),
+            conditionValue;
+        if (me.isContainsAny(xtypes, ['datefield'])) {
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d H:i:s');
+        } else if (me.isContainsAny(xtypes, ['conmonthfield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = from + ',' + to;
+        } else if (me.isContainsAny(xtypes, ['condatefield'])) {
+            var from = value.from,
+                to = value.to;
+
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d 00:00:00') + ',' + Ext.Date.format(new Date(to), 'Y-m-d 23:59:59');
+        } else if (me.isContainsAny(xtypes, ['dbfindtrigger'])) {
+            conditionValue = value;
+        } else if (me.isContainsAny(xtypes, ['combobox', 'combo'])) {
+            conditionValue = value;
+        } else if (me.isContainsAny(xtypes, ['multicombo'])) {
+            conditionValue = value.map ? value.map(function (v) {
+                return v.value;
+            }).join(',') : '';
+        } else {
+            conditionValue = value;
+        }
+
+        return conditionValue;
+    },
+
+    getExtraParams: function(store, op, condition) {
+        var temp = {};
+
+        for(let x = 0; x < condition.length; x++) {
+            let c = condition[x];
+            if(c.field == 'keyword') {
+                temp.keyword = c.value;
+            }else if(c.field == 'date') {
+                temp.fromDate = new Date(c.value.split(',')[0]).getTime();
+                temp.endDate = new Date(c.value.split(',')[1]).getTime();
+            }else if(c.field == 'quoted') {
+                temp.quoted = c.value == 'all' ? null : c.value;
+            }else if(c.field == 'closed') {
+                // temp.endDate = c.value == 'all' ? null : (
+                //     c.value == '0' ? 
+                // );
+            }
+        }
+        let obj = {
+            pageNumber: store.exportNumber?store.exportNumber:op._page,
+            pageSize: store.exportPageSize?store.exportPageSize:store.pageSize
+        };
+        for(let k in temp) {
+            if(!!temp[k]) {
+                obj[k] = temp[k];
+            }
+        }
+        return obj;
+     },
+});

+ 19 - 0
frontend/saas-web/app/view/sale/business/BusinessController.js

@@ -0,0 +1,19 @@
+Ext.define('saas.view.sale.business.BusinessController', {
+    extend: 'saas.view.core.base.BasePanelController',
+    alias: 'controller.sale-business-business',
+
+    showQuoteWin: function(record) {
+        var me = this,
+        view = me.getView();
+
+        var win = Ext.getCmp();
+        if(!win) {
+            win = Ext.create('saas.view.sale.business.QuoteWin', {
+                record: record,
+                listView: view
+            });
+            view.add(win);
+        }
+        win.show();
+    },
+});

+ 8 - 0
frontend/saas-web/app/view/sale/business/BusinessModel.js

@@ -0,0 +1,8 @@
+Ext.define('saas.view.sale.business.BusinessModel', {
+    extend: 'saas.view.core.base.BasePanelModel',
+    alias: 'viewmodel.sale-business-business',
+
+    data: {
+        configurable: false
+    }
+});

+ 12 - 0
frontend/saas-web/app/view/sale/business/MyBusiness.js

@@ -0,0 +1,12 @@
+/**
+ * 商机-我的商机
+ */
+Ext.define('saas.view.sale.business.MyBusiness', {
+    extend: 'saas.view.sale.business.Business',
+    xtype: 'sale-business-mybusiness',
+
+    viewName: 'sale-business-mybusiness',
+
+    // dataUrl: 'http://10.1.80.23:8560/api/sale/sale/personal/businessChance',
+    dataUrl: '/api/sale/sale/personal/businessChance',
+});

+ 206 - 0
frontend/saas-web/app/view/sale/business/QuoteWin.js

@@ -0,0 +1,206 @@
+Ext.define('saas.view.sale.business.QuoteWin', {
+    extend: 'Ext.window.Window',
+    xtype: 'quotewin',
+
+    title: '报价信息',
+    width: 600,
+    cls: 'x-window-dbfind',
+    closlayout: 'fit',
+    modal: true,
+    bodyPadding: 20,
+
+    initComponent: function () {
+        var me = this;
+        var record = me.record;
+        Ext.apply(me, {
+            items: [{
+                xtype: 'form',
+                layout: 'column',
+                fieldDefaults: {
+                    margin: '0 0 10 0',
+                    labelAlign: 'right',
+                    labelWidth: 90,
+                    columnWidth: 0.5,
+                },
+                isValid: function (values) {
+                    var leadtimeField = this.getForm().findField('leadtime');
+                    var taxrateField = this.getForm().findField('taxrate');
+                    var grid = this.down('grid');
+                    var gridData = grid.store.getData().items;
+                    var flag = gridData.length > 0;
+
+                    for (var x = 0; x < gridData.length; x++) {
+                        var d = gridData[x];
+                        if (!d.get('step') || !d.get('price')) {
+                            flag = false
+                        }
+                    }
+
+                    if(flag) {
+                        flag = leadtimeField.getValue() && taxrateField.getValue();
+                    }
+                    return flag;
+                },
+                items: [{
+                    xtype: 'textfield',
+                    fieldLabel: '品牌',
+                    name: 'prodBrand',
+                    readOnly: true,
+                    value: record.get('prodBrand')
+                }, {
+                    xtype: 'textfield',
+                    fieldLabel: '名称',
+                    name: 'prodName',
+                    readOnly: true,
+                    value: record.get('prodName')
+                }, {
+                    xtype: 'textfield',
+                    fieldLabel: '型号',
+                    name: 'prodOrispeccode',
+                    readOnly: true,
+                    value: record.get('prodOrispeccode')
+                }, {
+                    xtype: 'textfield',
+                    fieldLabel: '规格',
+                    name: 'prodSpec',
+                    readOnly: true,
+                    value: record.get('prodSpec')
+                }, {
+                    xtype: 'numberfield',
+                    fieldLabel: '交期(天)',
+                    name: 'leadtime',
+                    allowBlank: false,
+                    beforeLabelTextTpl: "<font color=\"red\" style=\"position:relative; top:2px;right:2px; font-weight: bolder;\">*</font>"
+                }, {
+                    xtype: 'numberfield',
+                    fieldLabel: '税率',
+                    name: 'taxrate',
+                    minValue: 0,
+                    maxValue: 100,
+                    allowBlank: false,
+                    beforeLabelTextTpl: "<font color=\"red\" style=\"position:relative; top:2px;right:2px; font-weight: bolder;\">*</font>"
+                }, {
+                    xtype: 'detailGridField',
+                    detnoColumn: 'no',
+                    minHeight: 145,
+                    emptyRows: 3,
+                    showCount: false,
+                    width: 280,
+                    store: Ext.create('Ext.data.Store', {
+                        fields: [{
+                            name: 'no',
+                            type: 'int'
+                        }, {
+                            name: 'step',
+                            type: 'int'
+                        }, {
+                            name: 'price',
+                            type: 'float'
+                        }],
+                        data: []
+                    }),
+                    columns: [{
+                        text: '梯度',
+                        dataIndex: 'step',
+                        xtype: 'numbercolumn',
+                        editor: {
+                            xtype: "numberfield",
+                            decimalPrecision: 0,
+                            minValue: 0
+                        },
+                        renderer: function (v, m, r) {
+                            return saas.util.BaseUtil.numberFormat(v, 0, false);
+                        },
+                    }, {
+                        text: '单价',
+                        dataIndex: 'price',
+                        xtype: 'numbercolumn',
+                        editor: {
+                            xtype: "numberfield",
+                            decimalPrecision: 4,
+                            minValue: 0
+                        },
+                        renderer: function (v, m, r) {
+                            return saas.util.BaseUtil.numberFormat(v, 4, true);
+                        },
+                    }]
+                }]
+            }],
+            buttonAlign: 'center',
+            buttons: [{
+                text: '确定',
+                handler: function () {
+                    var win = this.up('window'),
+                        form = win.down('form')
+                        grid = form.down('grid');
+
+                    if (form.isValid()) {
+                        var values = form.getValues();
+                        Ext.Object.mergeIf(values, record.data);
+                        values.detail = grid.store.getData().items.map(function(r) {
+                            return r.data;
+                        })
+                        me.onQuote(values);
+                    } else {
+                        saas.util.BaseUtil.showErrorToast('表单校验失败,请检查字段是否合法');
+                    }
+                }
+            }, {
+                text: '取消',
+                handler: function () {
+
+                }
+            }]
+        });
+        me.callParent(arguments);
+    },
+
+    onQuote: function (values) {
+        var view = this;
+        var params = {
+            sourceId: values.sourceId,
+            inquiry: {
+                id: values.inquiryId,
+                enUU: values.enUU,
+                recorderUU: values.recorderUU,
+                code: values.inquiryCode,
+            },
+            userUU: values.userUU,
+            userName: values.userName,
+            userTel: values.userTel,
+            currency: "RMB",
+            taxrate: values.taxrate,
+            leadtime: values.leadtime, // 交期
+            replies: values.detail.map(function(d) {
+                return {
+                    lapQty: d.step,
+                    price: d.price
+                }
+            }), // 梯度价格,
+            date: Ext.Date.format(new Date(), 'Y-m-d H:i:s'), // 当前日期
+            qutoApp: "sp", // 固定标识
+            endDate: values.endDate,
+            prodTitle: values.prodName,
+            spec: values.prodSpec,
+            cmpCode: values.prodOrispeccode,
+            inbrand: values.prodBrand,
+            isReplace: 0,
+        };
+
+        view.setLoading(true);
+        saas.util.BaseUtil.request({
+            // url: 'http://10.1.80.23:8560/api/sale/sale/businessChance/saveQuote',
+            url: '/api/sale/sale/businessChance/saveQuote',
+            params: JSON.stringify(params),
+            method: 'POST'
+        }).then(function (res) {
+            view.setLoading(false);
+            saas.util.BaseUtil.showSuccessToast('报价成功');
+            view.close();
+            view.listView.refresh();
+        }).catch(function (e) {
+            view.setLoading(false);
+            saas.util.BaseUtil.showErrorToast('报价失败: ' + e.message);
+        });
+    },
+});

+ 3 - 3
frontend/saas-web/electron/package.json

@@ -1,14 +1,14 @@
 {
   "name": "UsoftchinaSaasClient",
-  "version": "0.0.2",
+  "version": "0.0.3",
   "description": "saas在线进销存系统",
   "main": "./main.js",
   "scripts": {
     "dev-start": "electron . dev",
     "local-start": "electron . local",
     "build": "cd ../ && sencha app build --build prod --destination electron/dist/ --production",
-    "pack": "npm run build && electron-builder --dir",
-    "dist": "npm run build && electron-builder"
+    "pack": "npm run build && electron-builder --win --x64 --ia32 --dir",
+    "dist": "npm run build && electron-builder --win --x64 --ia32"
   },
   "author": "深圳市优软科技有限公司",
   "license": "ISC",

+ 3 - 0
frontend/saas-web/overrides/form/field/Number.js

@@ -1,6 +1,9 @@
 Ext.define("saas.override.form.field.Number", {
     override: "Ext.form.field.Number",
     
+
+    hideTrigger: true, // 隐藏trigger
+    mouseWheelEnabled: false, // 取消滚轮事件
     /**
     * @cfg {Boolean} thousandSeparator
     */

+ 9 - 1
frontend/saas-web/resources/json/navigation.json

@@ -55,6 +55,14 @@
             "text": "销售退货单",
             "addType": "sale-salein-formpanel",
             "viewType": "sale-salein-querypanel"
+        }, {
+            "id": "sale-business-business",
+            "text": "公司商机",
+            "viewType": "sale-business-business"
+        }, {
+            "id": "sale-business-mybusiness",
+            "text": "我的商机",
+            "viewType": "sale-business-mybusiness"
         }]
     }, {
         "text": "报表",
@@ -287,7 +295,7 @@
             "leaf": true
         }]
     }]
-},{
+}, {
     "text": "设置",
     "iconCls": "x-sa sa-setting",
     "items": [{