瀏覽代碼

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

hy 7 年之前
父節點
當前提交
a1217bba95
共有 82 個文件被更改,包括 3678 次插入681 次删除
  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. 66 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryAddDTO.java
  25. 47 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryDealReqDTO.java
  26. 47 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryReplayDTO.java
  27. 108 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryReqDTO.java
  28. 133 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryRspDTO.java
  29. 100 0
      applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/QuotationRspDTO.java
  30. 33 4
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/PurchaseController.java
  31. 21 3
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/PurchaseService.java
  32. 168 10
      applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/impl/PurchaseServiceImpl.java
  33. 108 0
      applications/sale/sale-dto/src/main/java/com/usoftchina/saas/sale/dto/RemindRspDTO.java
  34. 11 0
      applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/controller/SaleController.java
  35. 3 0
      applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/service/SaleService.java
  36. 53 5
      applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/service/impl/SaleServiceImpl.java
  37. 2 3
      applications/transfers/mall-api/src/main/java/com/usoftchina/inquiry/api/InquiryApi.java
  38. 41 4
      applications/transfers/mall-api/src/test/java/com/usoftchina/inquiry/test/InquiryApiTest.java
  39. 23 4
      base-servers/account/account-dto/src/main/java/com/usoftchina/saas/account/dto/CompanyRspDTO.java
  40. 1 1
      base-servers/account/account-server/src/main/resources/mapper/CompanyMapper.xml
  41. 3 2
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/AuthRestInterceptor.java
  42. 5 0
      base-servers/auth/auth-client/src/main/java/com/usoftchina/saas/auth/client/interceptor/ServiceFeignInterceptor.java
  43. 0 3
      frontend/operation-web/app/view/core/List.js
  44. 248 0
      frontend/operation-web/app/view/core/base/BasePanel.js
  45. 97 0
      frontend/operation-web/app/view/core/base/BasePanel.scss
  46. 47 0
      frontend/operation-web/app/view/core/base/BasePanelController.js
  47. 8 0
      frontend/operation-web/app/view/core/base/BasePanelModel.js
  48. 224 0
      frontend/operation-web/app/view/core/base/GridPanel.js
  49. 309 0
      frontend/operation-web/app/view/core/base/ImportWindow.js
  50. 268 0
      frontend/operation-web/app/view/core/form/field/ConDateField.js
  51. 26 0
      frontend/operation-web/app/view/core/form/field/ConDateField.scss
  52. 70 59
      frontend/operation-web/app/view/cuservice/Feedback.js
  53. 0 25
      frontend/operation-web/app/view/cuservice/Models.js
  54. 57 27
      frontend/operation-web/app/view/statistical/CompanyAnalysis.js
  55. 0 57
      frontend/operation-web/app/view/statistical/CompanyInfo.js
  56. 69 0
      frontend/operation-web/app/view/statistical/CompanyRegInfo.js
  57. 42 31
      frontend/operation-web/app/view/statistical/LoginLog.js
  58. 0 63
      frontend/operation-web/app/view/statistical/Models.js
  59. 0 64
      frontend/operation-web/app/view/statistical/PersonInfo.js
  60. 74 0
      frontend/operation-web/app/view/statistical/PersonRegInfo.js
  61. 6 2
      frontend/operation-web/resources/json/navigation.json
  62. 10 6
      frontend/saas-portal-web/src/components/conenter/addenterprise.vue
  63. 172 33
      frontend/saas-web/app/view/core/base/BasePanel.js
  64. 0 139
      frontend/saas-web/app/view/core/base/BasePanelController.js
  65. 4 0
      frontend/saas-web/app/view/core/base/BasePanelModel.js
  66. 11 9
      frontend/saas-web/app/view/core/base/GridPanel.js
  67. 2 0
      frontend/saas-web/app/view/core/form/FormPanelModel.js
  68. 1 1
      frontend/saas-web/app/view/core/form/field/DetailGridField.js
  69. 10 10
      frontend/saas-web/app/view/core/query/QueryGridPanel.js
  70. 9 0
      frontend/saas-web/app/view/core/query/QueryPanel.js
  71. 3 1
      frontend/saas-web/app/view/core/query/QueryPanelModel.js
  72. 9 9
      frontend/saas-web/app/view/document/customer/FormPanel.js
  73. 87 87
      frontend/saas-web/app/view/document/product/BasePanel.js
  74. 11 11
      frontend/saas-web/app/view/document/vendor/FormPanel.js
  75. 1 0
      frontend/saas-web/app/view/money/fundtransfer/FormPanel.js
  76. 217 0
      frontend/saas-web/app/view/sale/business/Business.js
  77. 19 0
      frontend/saas-web/app/view/sale/business/BusinessController.js
  78. 8 0
      frontend/saas-web/app/view/sale/business/BusinessModel.js
  79. 12 0
      frontend/saas-web/app/view/sale/business/MyBusiness.js
  80. 206 0
      frontend/saas-web/app/view/sale/business/QuoteWin.js
  81. 3 0
      frontend/saas-web/overrides/form/field/Number.js
  82. 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}

+ 66 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryAddDTO.java

@@ -0,0 +1,66 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+
+/**
+ * @Description 发起询价
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class InquiryAddDTO implements Serializable {
+
+    private String prodCode;
+    private String prodName;
+    private String prodSpec;
+    private String prodOrispeccode;
+    private String prodBrand;
+    private Long leadTime;
+
+    public String getProdCode() {
+        return prodCode;
+    }
+
+    public void setProdCode(String prodCode) {
+        this.prodCode = prodCode;
+    }
+
+    public String getProdName() {
+        return prodName;
+    }
+
+    public void setProdName(String prodName) {
+        this.prodName = prodName;
+    }
+
+    public String getProdSpec() {
+        return prodSpec;
+    }
+
+    public void setProdSpec(String prodSpec) {
+        this.prodSpec = prodSpec;
+    }
+
+    public String getProdOrispeccode() {
+        return prodOrispeccode;
+    }
+
+    public void setProdOrispeccode(String prodOrispeccode) {
+        this.prodOrispeccode = prodOrispeccode;
+    }
+
+    public String getProdBrand() {
+        return prodBrand;
+    }
+
+    public void setProdBrand(String prodBrand) {
+        this.prodBrand = prodBrand;
+    }
+
+    public Long getLeadTime() {
+        return leadTime;
+    }
+
+    public void setLeadTime(Long leadTime) {
+        this.leadTime = leadTime;
+    }
+}

+ 47 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryDealReqDTO.java

@@ -0,0 +1,47 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+
+/**
+ * @Description 报价采纳拒绝
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class InquiryDealReqDTO implements Serializable {
+    /**
+     * 报价单ID
+     */
+    private Long id;
+    /**
+     * 是否采纳:1是 0否
+     */
+    private Short status;
+    /**
+     * 拒绝原因
+     */
+    private String refusereason;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public String getRefusereason() {
+        return refusereason;
+    }
+
+    public void setRefusereason(String refusereason) {
+        this.refusereason = refusereason;
+    }
+}

+ 47 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryReplayDTO.java

@@ -0,0 +1,47 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+
+/**
+ * @Description TODO
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class InquiryReplayDTO implements Serializable {
+    /**
+     * id
+     */
+    private Long id;
+    /**
+     * (买家或卖家定义的)分段数量
+     */
+    private Double lapQty;
+    /**
+     * (卖家报的)单价
+     */
+    private Double price;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Double getLapQty() {
+        return lapQty;
+    }
+
+    public void setLapQty(Double lapQty) {
+        this.lapQty = lapQty;
+    }
+
+    public Double getPrice() {
+        return price;
+    }
+
+    public void setPrice(Double price) {
+        this.price = price;
+    }
+}

+ 108 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryReqDTO.java

@@ -0,0 +1,108 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+
+/**
+ * @Description TODO
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class InquiryReqDTO implements Serializable {
+
+    /**
+     * 页码
+     */
+    private int pageNumber;
+    /**
+     * 每页条数
+     */
+    private int pageSize;
+    /**
+     * 关键词
+     */
+    private String keyword;
+    /**
+     * 企业UU
+     */
+    private Long enUU;
+    /**
+     *  已报价:1, 未报价:0
+     */
+    private Long quoted;
+    /**
+     * 开始日期
+     */
+    private Long fromDate;
+    /**
+     * 结束日期
+     */
+    private Long endDate;
+    /**
+     * 1已过期 0 未过期
+     */
+    private Integer overdue;
+
+    public int getPageNumber() {
+        return pageNumber;
+    }
+
+    public void setPageNumber(int pageNumber) {
+        this.pageNumber = pageNumber;
+    }
+
+    public int getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public Long getEnUU() {
+        return enUU;
+    }
+
+    public void setEnUU(Long enUU) {
+        this.enUU = enUU;
+    }
+
+    public Long getQuoted() {
+        return quoted;
+    }
+
+    public void setQuoted(Long quoted) {
+        this.quoted = quoted;
+    }
+
+    public Long getFromDate() {
+        return fromDate;
+    }
+
+    public void setFromDate(Long fromDate) {
+        this.fromDate = fromDate;
+    }
+
+    public Long getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Long endDate) {
+        this.endDate = endDate;
+    }
+
+    public Integer getOverdue() {
+        return overdue;
+    }
+
+    public void setOverdue(Integer overdue) {
+        this.overdue = overdue;
+    }
+}

+ 133 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/InquiryRspDTO.java

@@ -0,0 +1,133 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Description TODO
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class InquiryRspDTO implements Serializable {
+    /**
+     * 物料编号
+     */
+    private String prodCode;
+    /**
+     * 物料品牌
+     */
+    private String prodBrand;
+    /**
+     * 物料名称
+     */
+    private String prodName;
+    /**
+     * 物料型号
+     */
+    private String prodOrispeccode;
+    /**
+     * 物料规格
+     */
+    private String prodSpec;
+    /**
+     * 物料单位
+     */
+    private String prodUnit;
+    /**
+     * 起始日期
+     */
+    private Date startDate;
+    /**
+     * 截止日期
+     */
+    private Date endDate;
+    /**
+     * 是否已报价 1、是;0、否
+     */
+    private Short quoted;
+    /**
+     * 报价信息
+     */
+    private List<QuotationRspDTO> qutations;
+
+    public String getProdCode() {
+        return prodCode;
+    }
+
+    public void setProdCode(String prodCode) {
+        this.prodCode = prodCode;
+    }
+
+    public String getProdBrand() {
+        return prodBrand;
+    }
+
+    public void setProdBrand(String prodBrand) {
+        this.prodBrand = prodBrand;
+    }
+
+    public String getProdName() {
+        return prodName;
+    }
+
+    public void setProdName(String prodName) {
+        this.prodName = prodName;
+    }
+
+    public String getProdOrispeccode() {
+        return prodOrispeccode;
+    }
+
+    public void setProdOrispeccode(String prodOrispeccode) {
+        this.prodOrispeccode = prodOrispeccode;
+    }
+
+    public String getProdSpec() {
+        return prodSpec;
+    }
+
+    public void setProdSpec(String prodSpec) {
+        this.prodSpec = prodSpec;
+    }
+
+    public String getProdUnit() {
+        return prodUnit;
+    }
+
+    public void setProdUnit(String prodUnit) {
+        this.prodUnit = prodUnit;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public Short getQuoted() {
+        return quoted;
+    }
+
+    public void setQuoted(Short quoted) {
+        this.quoted = quoted;
+    }
+
+    public List<QuotationRspDTO> getQutations() {
+        return qutations;
+    }
+
+    public void setQutations(List<QuotationRspDTO> qutations) {
+        this.qutations = qutations;
+    }
+}

+ 100 - 0
applications/purchase/purchase-dto/src/main/java/com/usoftchina/saas/purchase/dto/QuotationRspDTO.java

@@ -0,0 +1,100 @@
+package com.usoftchina.saas.purchase.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author chenwei
+ * @Date 2019/01/08
+ */
+public class QuotationRspDTO implements Serializable {
+
+    private Long id;
+    private String vendName;
+    private String tel;
+    private String replaceOrispeccode;
+    private Long leadTime;
+    private Double texRate;
+    /**
+     * 是否采纳 1 为已采纳 0为已拒绝  空 未处理
+     */
+    private Short agreed;
+    /**
+     * 拒绝采纳理由
+     */
+    private String refusereason;
+
+    private List<InquiryReplayDTO> replies;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getVendName() {
+        return vendName;
+    }
+
+    public void setVendName(String vendName) {
+        this.vendName = vendName;
+    }
+
+    public String getTel() {
+        return tel;
+    }
+
+    public void setTel(String tel) {
+        this.tel = tel;
+    }
+
+    public String getReplaceOrispeccode() {
+        return replaceOrispeccode;
+    }
+
+    public void setReplaceOrispeccode(String replaceOrispeccode) {
+        this.replaceOrispeccode = replaceOrispeccode;
+    }
+
+    public Long getLeadTime() {
+        return leadTime;
+    }
+
+    public void setLeadTime(Long leadTime) {
+        this.leadTime = leadTime;
+    }
+
+    public Double getTexRate() {
+        return texRate;
+    }
+
+    public void setTexRate(Double texRate) {
+        this.texRate = texRate;
+    }
+
+    public Short getAgreed() {
+        return agreed;
+    }
+
+    public void setAgreed(Short agreed) {
+        this.agreed = agreed;
+    }
+
+    public String getRefusereason() {
+        return refusereason;
+    }
+
+    public void setRefusereason(String refusereason) {
+        this.refusereason = refusereason;
+    }
+
+    public List<InquiryReplayDTO> getReplies() {
+        return replies;
+    }
+
+    public void setReplies(List<InquiryReplayDTO> replies) {
+        this.replies = replies;
+    }
+}

+ 33 - 4
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/controller/PurchaseController.java

@@ -8,14 +8,13 @@ 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.dto.*;
 import com.usoftchina.saas.purchase.po.PurchaseList;
 import com.usoftchina.saas.purchase.service.PurchaseService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
 
 
 /**
@@ -189,8 +188,38 @@ public class PurchaseController {
      * @return
      */
     @GetMapping("/device/list")
-    public Result getDevice(DeviceReqDTO deviceReqDTO){
+    public Result getDevice(DeviceReqDTO deviceReqDTO) {
         IPage<DeviceDTO> deviceDTOIPage = purchaseService.getDevice(deviceReqDTO);
         return Result.success(deviceDTOIPage);
     }
+
+    /**
+     * 询价列表
+     * @param inquiryReqDTO
+     * @return
+     */
+    @GetMapping("/inquiry/list")
+    public Result inquiryList(InquiryReqDTO inquiryReqDTO){
+        return Result.success(purchaseService.getInquiryList(inquiryReqDTO));
+    }
+
+    /**
+     * 对报价采纳/拒绝
+     * @return
+     */
+    @PostMapping("/inquiry/deal")
+    public Result dealInquiry(InquiryDealReqDTO inquiryDealReqDTO){
+        purchaseService.DealInquiry(inquiryDealReqDTO);
+        return Result.success();
+    }
+
+    /**
+     * 发起询价
+     * @return
+     */
+    @PostMapping("/inquiry/save")
+    public Result saveInquiry(List<InquiryAddDTO> inquiryAddDTO){
+        purchaseService.saveInquiry(inquiryAddDTO);
+        return Result.success();
+    }
 }

+ 21 - 3
applications/purchase/purchase-server/src/main/java/com/usoftchina/saas/purchase/service/PurchaseService.java

@@ -8,13 +8,13 @@ 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.dto.*;
 import com.usoftchina.saas.purchase.mapper.PurchaseMapper;
 import com.usoftchina.saas.purchase.po.Purchase;
 import com.usoftchina.saas.purchase.po.PurchaseList;
 
+import java.util.List;
+
 /**
  * @author yingp
  * @date 2018/10/9
@@ -147,4 +147,22 @@ public interface PurchaseService extends CommonBaseService<PurchaseMapper, Purch
      * @return
      */
     IPage<DeviceDTO> getDevice(DeviceReqDTO deviceReqDTO);
+    /**
+     * 查询询价列表
+     * @param inquiryReqDTO
+     * @return
+     */
+    IPage<InquiryRspDTO> getInquiryList(InquiryReqDTO inquiryReqDTO);
+
+    /**
+     * 报价信息的采纳/拒绝
+     * @param inquiryDealReqDTO
+     */
+    void DealInquiry(InquiryDealReqDTO inquiryDealReqDTO);
+
+    /**
+     * 发起询价
+     * @param inquiryAddDTO
+     */
+    void saveInquiry(List<InquiryAddDTO> inquiryAddDTO);
 }

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

@@ -2,13 +2,15 @@ package com.usoftchina.saas.purchase.service.impl;
 
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.usoftchina.inquiry.api.InquiryApi;
 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.inquiry.*;
 import com.usoftchina.inquiry.po.search.ProductEntity;
 import com.usoftchina.inquiry.po.search.SearchComponentResp;
+import com.usoftchina.saas.account.api.AccountApi;
+import com.usoftchina.saas.account.api.CompanyApi;
+import com.usoftchina.saas.account.dto.AccountDTO;
+import com.usoftchina.saas.account.dto.CompanyRspDTO;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.base.service.CommonBaseServiceImpl;
 import com.usoftchina.saas.commons.api.CommonService;
@@ -26,22 +28,23 @@ import com.usoftchina.saas.exception.BizException;
 import com.usoftchina.saas.exception.ExceptionCode;
 import com.usoftchina.saas.page.PageRequest;
 import com.usoftchina.saas.purchase.dto.*;
+import com.usoftchina.saas.purchase.dto.InquiryReqDTO;
+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.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;
 import org.springframework.util.StringUtils;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
 
 
 /**
@@ -71,6 +74,12 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
     private CommonService commonService;
     @Autowired
     private SearchApi searchApi;
+    @Autowired
+    private InquiryApi inquiryApi;
+    @Autowired
+    private CompanyApi companyApi;
+    @Autowired
+    private AccountApi accountApi;
 
 
     @Override
@@ -169,6 +178,8 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
                 purchasedetailMapper.batchInsert(insertDetails);
             }
             baseDTO = getBaseDTOById(pu_id);
+            //明细需求日期为空时==主表交货日期
+            getMapper().updateDelivery(pu_id);
             //计算金额,未税单价,未税金额等
             calcPurchase(pu_id);
             //日志记录
@@ -466,6 +477,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();
@@ -652,7 +666,151 @@ public class PurchaseServiceImpl extends CommonBaseServiceImpl<PurchaseMapper, P
        String code = maxnumberService.getMaxnumber(caller, false).getData();
        return pushMaxnubmer(code, baseDTO.getId());
     }
-    /** 
+
+    /**
+     * 询价单列表
+     * @param inquiryReqDTO
+     * @return
+     */
+    @Override
+    public IPage<InquiryRspDTO> getInquiryList(InquiryReqDTO inquiryReqDTO) {
+        IPage<PurcInquiryItemInfo> purcInquiryItemInfoIPage = null;
+        Long enUU = companyApi.getCompanyById(BaseContextHolder.getCompanyId()).getData().getUu();
+        if (inquiryReqDTO.getQuoted() == 1){
+            purcInquiryItemInfoIPage = inquiryApi.findQuotationsByPage("done", enUU, inquiryReqDTO.getPageNumber(), inquiryReqDTO.getPageSize());
+        }else{
+            purcInquiryItemInfoIPage = inquiryApi.getInquiryList(enUU, inquiryReqDTO.getOverdue(), inquiryReqDTO.getPageNumber(), inquiryReqDTO.getPageSize(), "todo");
+        }
+        List<PurcInquiryItemInfo> purcInquiryItemInfoList =  purcInquiryItemInfoIPage.getContent();
+        if (CollectionUtils.isEmpty(purcInquiryItemInfoList)){
+            return null;
+        }
+        List<InquiryRspDTO> inquiryRspDTOList = convertToInquiryRspDTO(purcInquiryItemInfoList);
+        //转换成分页对象
+        IPage<InquiryRspDTO> remindRspDTOIPage = new IPage<InquiryRspDTO>(purcInquiryItemInfoIPage.getNumber(), purcInquiryItemInfoIPage.getSize(),
+                purcInquiryItemInfoIPage.getNumberOfElements(),inquiryRspDTOList, purcInquiryItemInfoIPage.isFirst(), purcInquiryItemInfoIPage.isLast(),
+                purcInquiryItemInfoIPage.getTotalElements());
+        return remindRspDTOIPage;
+    }
+
+    /**
+     * 报价的采纳/拒绝
+     * @param inquiryDealReqDTO
+     */
+    @Override
+    public void DealInquiry(InquiryDealReqDTO inquiryDealReqDTO) {
+        Long enUU = companyApi.getCompanyById(BaseContextHolder.getCompanyId()).getData().getUu();
+        Long userUU = accountApi.getAccountById(BaseContextHolder.getUserId()).getData().getUu();
+        if (inquiryDealReqDTO.getStatus() == 1){
+            inquiryApi.adoptQuote(inquiryDealReqDTO.getId(), inquiryDealReqDTO.getStatus(), enUU, userUU);
+        }else{
+            inquiryApi.refuseQuote(inquiryDealReqDTO.getId(), inquiryDealReqDTO.getStatus(), enUU, userUU, inquiryDealReqDTO.getRefusereason());
+        }
+    }
+
+    /**
+     * 发起询价
+     * @param inquiryAddDTOList
+     */
+    @Override
+    public void saveInquiry(List<InquiryAddDTO> inquiryAddDTOList) {
+        List<PurcInquiry> purcInquiryList = new ArrayList<PurcInquiry>();
+        CompanyRspDTO companyRspDTO = companyApi.getCompanyRspDTOById(BaseContextHolder.getCompanyId()).getData();
+        AccountDTO accountDTO = accountApi.getAccountById(BaseContextHolder.getUserId()).getData();
+        //企业信息
+        Enterprise enterprise = new Enterprise();
+        enterprise.setAdminUU(companyRspDTO.getAdminUU());
+        enterprise.setBusinesscode(companyRspDTO.getBusinessCode());
+        enterprise.setEnAddress(companyRspDTO.getAddress());
+        enterprise.setEnName(companyRspDTO.getName());
+        enterprise.setEnTel(companyRspDTO.getTel());
+        enterprise.setUu(companyRspDTO.getUu());
+        for (InquiryAddDTO inquiryAddDTO : inquiryAddDTOList){
+            PurcInquiry purcInquiry = new PurcInquiry();
+            //询价主表信息
+            purcInquiry.setEnterprise(enterprise);
+            purcInquiry.setEnName(companyRspDTO.getName());
+            purcInquiry.setRecorderUU(accountDTO.getUu());
+            purcInquiry.setDate(new Date());
+            purcInquiry.setRecorder(accountDTO.getRealname());
+            purcInquiry.setEndDate(new Date(System.currentTimeMillis() + inquiryAddDTO.getLeadTime() * 24 * 60 * 60 * 1000));
+            purcInquiry.setSourceapp("sp");
+            purcInquiry.setShip(companyRspDTO.getAddress());
+            //询价明细
+            PurcInquiryItem purcInquiryItem = new PurcInquiryItem();
+            purcInquiryItem.setCmpCode(inquiryAddDTO.getProdOrispeccode());
+            purcInquiryItem.setUserUU(accountDTO.getUu());
+            purcInquiryItem.setUserName(accountDTO.getRealname());
+            purcInquiryItem.setUserTel(accountDTO.getMobile());
+            purcInquiryItem.setProdCode(inquiryAddDTO.getProdCode());
+            purcInquiryItem.setProdTitle(inquiryAddDTO.getProdName());
+            purcInquiryItem.setSpec(inquiryAddDTO.getProdSpec());
+            purcInquiryItem.setInbrand(inquiryAddDTO.getProdBrand());
+
+            Set<PurcInquiryItem> purcInquiryItemSet = new HashSet<PurcInquiryItem>();
+            purcInquiryItemSet.add(purcInquiryItem);
+
+            purcInquiry.setInquiryItems(purcInquiryItemSet);
+            purcInquiryList.add(purcInquiry);
+        }
+        //调用商城ap,保存询价
+
+    }
+
+    /**
+     * 将平台返回的结果集转成SAAS的传输对象
+     * @param purcInquiryItemInfoList
+     * @return
+     */
+    private List<InquiryRspDTO> convertToInquiryRspDTO(List<PurcInquiryItemInfo> purcInquiryItemInfoList) {
+        List<InquiryRspDTO> inquiryRspDTOList = new ArrayList<InquiryRspDTO>();
+        for (PurcInquiryItemInfo purcInquiryItemInfo : purcInquiryItemInfoList){
+            InquiryRspDTO inquiryRspDTO = new InquiryRspDTO();
+            inquiryRspDTO.setProdCode(purcInquiryItemInfo.getProdCode());
+            inquiryRspDTO.setProdUnit(purcInquiryItemInfo.getProduct().getUnit());
+            inquiryRspDTO.setProdOrispeccode(purcInquiryItemInfo.getCmpCode());
+            inquiryRspDTO.setProdBrand(purcInquiryItemInfo.getProduct().getBrand());
+            inquiryRspDTO.setProdName(purcInquiryItemInfo.getProdTitle());
+            inquiryRspDTO.setProdSpec(purcInquiryItemInfo.getSpec());
+            inquiryRspDTO.setStartDate(purcInquiryItemInfo.getFromDate());
+            inquiryRspDTO.setEndDate(purcInquiryItemInfo.getEndDate());
+            inquiryRspDTO.setQuoted(purcInquiryItemInfo.getQuoted());
+            //报价信息
+            List<PublicInquiryItem> publicInquiryItemList = purcInquiryItemInfo.getQutations();
+            List<QuotationRspDTO> quotationRspDTOList = new ArrayList<QuotationRspDTO>();
+            if (!CollectionUtils.isEmpty(publicInquiryItemList)){
+                for (PublicInquiryItem publicInquiryItem : publicInquiryItemList){
+                    QuotationRspDTO quotationRspDTO = new QuotationRspDTO();
+                    quotationRspDTO.setId(publicInquiryItem.getId());
+                    quotationRspDTO.setVendName(publicInquiryItem.getVendName());
+                    quotationRspDTO.setTexRate(new BigDecimal(publicInquiryItem.getTaxrate()).doubleValue());
+                    quotationRspDTO.setLeadTime(publicInquiryItem.getLeadtime());
+                    quotationRspDTO.setTel(publicInquiryItem.getUserTel());
+                    quotationRspDTO.setAgreed(publicInquiryItem.getAgreed());
+                    quotationRspDTO.setReplaceOrispeccode(publicInquiryItem.getCmpCode());
+                    //分段报价信息
+                    List<PublicInquiryReply> publicInquiryReplyList = publicInquiryItem.getReplies();
+                    List<InquiryReplayDTO> inquiryReplayDTOList = new ArrayList<InquiryReplayDTO>();
+                    if (!CollectionUtils.isEmpty(publicInquiryReplyList)){
+                        for (PublicInquiryReply publicInquiryReply : publicInquiryReplyList){
+                            InquiryReplayDTO inquiryReplayDTO = new InquiryReplayDTO();
+                            inquiryReplayDTO.setId(publicInquiryReply.getId());
+                            inquiryReplayDTO.setLapQty(publicInquiryReply.getLapQty());
+                            inquiryReplayDTO.setPrice(publicInquiryReply.getPrice());
+                            inquiryReplayDTOList.add(inquiryReplayDTO);
+                        }
+                        quotationRspDTO.setReplies(inquiryReplayDTOList);
+                    }
+                    quotationRspDTOList.add(quotationRspDTO);
+                }
+                inquiryRspDTO.setQutations(quotationRspDTOList);
+            }
+            inquiryRspDTOList.add(inquiryRspDTO);
+        }
+        return inquiryRspDTOList;
+    }
+
+    /**
     * @Description
     * @Param: [id]
     * @return: com.usoftchina.saas.commons.dto.DocBaseDTO 

+ 108 - 0
applications/sale/sale-dto/src/main/java/com/usoftchina/saas/sale/dto/RemindRspDTO.java

@@ -46,6 +46,42 @@ public class RemindRspDTO implements Serializable {
      * 截止日期
      */
     private Date endDate;
+    /**
+     * 是否已报价, 1是  0否
+     */
+    private int quoted;
+    /**
+     * 买家联系人名称
+     */
+    private String userName;
+    /**
+     * 买家联系人UU
+     */
+    private Long userUU;
+    /**
+     * 买家联系人电话
+     */
+    private String userTel;
+    /**
+     * 询价明细ID
+     */
+    private Long sourceId;
+    /**
+     * 询价企业UU
+     */
+    private Long enUU;
+    /**
+     * 询价单录入人UU
+     */
+    private Long recorderUU;
+    /**
+     * 询价单号
+     */
+    private String inquiryCode;
+    /**
+     * 询价单ID
+     */
+    private Long inquiryId;
 
     public String getCustName() {
         return custName;
@@ -118,4 +154,76 @@ public class RemindRspDTO implements Serializable {
     public void setEndDate(Date endDate) {
         this.endDate = endDate;
     }
+
+    public int getQuoted() {
+        return quoted;
+    }
+
+    public void setQuoted(int quoted) {
+        this.quoted = quoted;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Long getUserUU() {
+        return userUU;
+    }
+
+    public void setUserUU(Long userUU) {
+        this.userUU = userUU;
+    }
+
+    public String getUserTel() {
+        return userTel;
+    }
+
+    public void setUserTel(String userTel) {
+        this.userTel = userTel;
+    }
+
+    public Long getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(Long sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    public Long getEnUU() {
+        return enUU;
+    }
+
+    public void setEnUU(Long enUU) {
+        this.enUU = enUU;
+    }
+
+    public Long getRecorderUU() {
+        return recorderUU;
+    }
+
+    public void setRecorderUU(Long recorderUU) {
+        this.recorderUU = recorderUU;
+    }
+
+    public String getInquiryCode() {
+        return inquiryCode;
+    }
+
+    public void setInquiryCode(String inquiryCode) {
+        this.inquiryCode = inquiryCode;
+    }
+
+    public Long getInquiryId() {
+        return inquiryId;
+    }
+
+    public void setInquiryId(Long inquiryId) {
+        this.inquiryId = inquiryId;
+    }
 }

+ 11 - 0
applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/controller/SaleController.java

@@ -2,6 +2,7 @@ package com.usoftchina.saas.sale.controller;
 
 import com.github.pagehelper.PageInfo;
 import com.usoftchina.inquiry.po.inquiry.IPage;
+import com.usoftchina.inquiry.po.inquiry.PublicInquiryItem;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
@@ -215,4 +216,14 @@ public class SaleController {
         IPage<RemindRspDTO> remindRspDTOIPage = saleService.findRemindByUserInfo(remindReqDTO);
         return Result.success(remindRspDTOIPage);
     }
+
+    /**
+     * 报价
+     * @param publicInquiryItem
+     * @return
+     */
+    @PostMapping("/businessChance/saveQuote")
+    public Result saveQuote(PublicInquiryItem publicInquiryItem){
+        return Result.success(saleService.saveQuote(publicInquiryItem));
+    }
 }

+ 3 - 0
applications/sale/sale-server/src/main/java/com/usoftchina/saas/sale/service/SaleService.java

@@ -2,6 +2,7 @@ package com.usoftchina.saas.sale.service;
 
 import com.github.pagehelper.PageInfo;
 import com.usoftchina.inquiry.po.inquiry.IPage;
+import com.usoftchina.inquiry.po.inquiry.PublicInquiryItem;
 import com.usoftchina.saas.commons.dto.BatchDealBaseDTO;
 import com.usoftchina.saas.commons.dto.DocBaseDTO;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
@@ -52,4 +53,6 @@ public interface SaleService {
     IPage<RemindRspDTO> getEnremind(RemindReqDTO remindReqDTO);
 
     IPage<RemindRspDTO> findRemindByUserInfo(RemindReqDTO remindReqDTO);
+
+    String saveQuote(PublicInquiryItem publicInquiryItem);
 }

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

@@ -6,6 +6,7 @@ import com.usoftchina.inquiry.api.InquiryApi;
 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.inquiry.PublicInquiryItem;
 import com.usoftchina.saas.account.api.AccountApi;
 import com.usoftchina.saas.account.api.CompanyApi;
 import com.usoftchina.saas.base.Result;
@@ -33,13 +34,13 @@ import com.usoftchina.saas.sale.service.ProdInOutService;
 import com.usoftchina.saas.sale.service.SaleService;
 import com.usoftchina.saas.storage.po.ProdIODetail;
 import com.usoftchina.saas.storage.po.ProdInOut;
-import com.usoftchina.saas.utils.BeanMapper;
-import com.usoftchina.saas.utils.CollectionUtils;
-import com.usoftchina.saas.utils.DateUtils;
-import com.usoftchina.saas.utils.JsonUtils;
+import com.usoftchina.saas.utils.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.ModelMap;
 import org.springframework.util.StringUtils;
 
 import java.util.*;
@@ -78,6 +79,8 @@ public class SaleServiceImpl implements SaleService{
     @Autowired
     private CompanyApi companyApi;
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(SaleServiceImpl.class);
+
     @Override
     public PageInfo<SaleList> getListData(@PageDefault(size = 10) PageRequest page, ListReqDTO req) {
         PageHelper.startPage(page.getNumber(), page.getSize());
@@ -678,7 +681,7 @@ public class SaleServiceImpl implements SaleService{
         Long enUU = companyApi.getCompanyById(BaseContextHolder.getCompanyId()).getData().getUu();
         //Long userUU = 1000002503L, enUU = 10041559L;
         IPage<InquiryEnRemind> inquiryEnRemindIPage = inquiryApi.findEnRemind(userUU, enUU, remindReqDTO.getPageNumber(),
-                remindReqDTO.getPageSize(), remindReqDTO.getEnableOffer(), remindReqDTO.getKeyword(), /*remindReqDTO.getQuoted(),*/
+                remindReqDTO.getPageSize(), remindReqDTO.getEnableOffer(), remindReqDTO.getKeyword(), remindReqDTO.getQuoted(),
                 remindReqDTO.getFromDate(), remindReqDTO.getEndDate());
         List<InquiryEnRemind> inquiryEnRemindList = inquiryEnRemindIPage.getContent();
         if (CollectionUtils.isEmpty(inquiryEnRemindList)){
@@ -716,6 +719,23 @@ public class SaleServiceImpl implements SaleService{
         return remindRspDTOIPage;
     }
 
+    /**
+     * 报价
+     * @param publicInquiryItem
+     * @return
+     */
+    @Override
+    public String saveQuote(PublicInquiryItem publicInquiryItem) {
+        Long enUU = companyApi.getCompanyById(BaseContextHolder.getCompanyId()).getData().getUu();
+        Long userUU = accountApi.getAccountById(BaseContextHolder.getUserId()).getData().getUu();
+        publicInquiryItem.setVendUU(enUU);
+        publicInquiryItem.setVendUserUU(userUU);
+        LOGGER.info("publicInquiryItem, {}", JsonUtils.toJsonString(publicInquiryItem));
+        ModelMap modelMap = inquiryApi.saveQuote(publicInquiryItem);
+        LOGGER.info("返回结果, ModelMap{}", JsonUtils.toJsonString(modelMap));
+        return null;
+    }
+
     /**
      * 将平台返回的结果集转成SAAS的传输对象
      * @param data
@@ -738,6 +758,20 @@ public class SaleServiceImpl implements SaleService{
                 remindRspDTO.setNeedQty(inquiryEnRemind.getNeedQty());
                 remindRspDTO.setStartDate(inquiryEnRemind.getReDate());
                 remindRspDTO.setEndDate(inquiryEnRemind.getEndDate());
+                if (ObjectUtils.isEmpty(inquiryEnRemind.getQuotation())){
+                    remindRspDTO.setQuoted(0);
+                }else{
+                    remindRspDTO.setQuoted(1);
+                }
+                Long userUU = inquiryEnRemind.getInquiry().getRecorderUU();
+                remindRspDTO.setUserName(inquiryEnRemind.getUserName());
+                remindRspDTO.setUserTel(inquiryEnRemind.getUserTel());
+                remindRspDTO.setUserUU(userUU);
+                remindRspDTO.setSourceId(inquiryEnRemind.getItemId());
+                remindRspDTO.setEnUU(inquiryEnRemind.getEnUU());
+                remindRspDTO.setRecorderUU(userUU);
+                remindRspDTO.setInquiryCode(inquiryEnRemind.getCode());
+                remindRspDTO.setInquiryId(inquiryEnRemind.getId());
                 remindRspDTOList.add(remindRspDTO);
             }
         }else if("personal".equals(type)){
@@ -753,6 +787,20 @@ public class SaleServiceImpl implements SaleService{
                 remindRspDTO.setNeedQty(inquiryRemind.getNeedQty());
                 remindRspDTO.setStartDate(inquiryRemind.getReDate());
                 remindRspDTO.setEndDate(inquiryRemind.getEndDate());
+                if (ObjectUtils.isEmpty(inquiryRemind.getQuotation())){
+                    remindRspDTO.setQuoted(0);
+                }else{
+                    remindRspDTO.setQuoted(1);
+                }
+                Long userUU = inquiryRemind.getInquiry().getRecorderUU();
+                remindRspDTO.setUserName(inquiryRemind.getUserName());
+                remindRspDTO.setUserTel(inquiryRemind.getUserTel());
+                remindRspDTO.setUserUU(userUU);
+                remindRspDTO.setSourceId(inquiryRemind.getItemId());
+                remindRspDTO.setEnUU(inquiryRemind.getEnUU());
+                remindRspDTO.setRecorderUU(userUU);
+                remindRspDTO.setInquiryCode(inquiryRemind.getCode());
+                remindRspDTO.setInquiryId(inquiryRemind.getId());
                 remindRspDTOList.add(remindRspDTO);
             }
         }

+ 2 - 3
applications/transfers/mall-api/src/main/java/com/usoftchina/inquiry/api/InquiryApi.java

@@ -36,7 +36,7 @@ public interface InquiryApi {
     IPage<InquiryEnRemind> findEnRemind(@RequestParam("useruu") Long useruu, @RequestParam("enuu") Long enuu,
                                         @RequestParam("pageNumber") int pageNumber, @RequestParam("pageSize") int pageSize,
                                         @RequestParam("enableOffer") Integer enableOffer, @RequestParam("keyword") String keyword,
-                                        /*@RequestParam("quoted") Integer quoted, */@RequestParam("fromDate") Long fromDate,
+                                        @RequestParam("quoted") Integer quoted, @RequestParam("fromDate") Long fromDate,
                                         @RequestParam("endDate") Long endDate);
 
     /**
@@ -98,8 +98,7 @@ public interface InquiryApi {
      * @return
      */
     @GetMapping("/buyer/quotations")
-    IPage<PurcInquiryItemInfo> findQuotationsByPage(@RequestParam(value = "state", defaultValue = "done") String state,
-                                                    @RequestParam("enUU") Long enUU,
+    IPage<PurcInquiryItemInfo> findQuotationsByPage(@RequestParam("state") String state, @RequestParam("enUU") Long enUU,
                                                     @RequestParam("pageNumber") int pageNumber, @RequestParam("pageSize") int pageSize);
 
     /**

+ 41 - 4
applications/transfers/mall-api/src/test/java/com/usoftchina/inquiry/test/InquiryApiTest.java

@@ -13,9 +13,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.ui.ModelMap;
 
 import javax.naming.directory.InvalidSearchFilterException;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
 
 /**
  * 询报价接口测试
@@ -44,7 +42,7 @@ public class InquiryApiTest {
 
     @Test
     public void testB_findEnRemind(){
-        IPage<InquiryEnRemind> inquiryEnRemindIPage = inquiryApi.findEnRemind(userUU, enUU, pageNum, pageSize, 0, "", /*0,*/ null, null);
+        IPage<InquiryEnRemind> inquiryEnRemindIPage = inquiryApi.findEnRemind(userUU, enUU, pageNum, pageSize, 0, "", 0, null, null);
         System.out.println(JsonUtils.toJsonString(inquiryEnRemindIPage));
     }
 
@@ -57,6 +55,45 @@ public class InquiryApiTest {
     @Test
     public void testD_saveQuote(){
         PublicInquiryItem publicInquiryItem = new PublicInquiryItem();
+        publicInquiryItem.setSourceId(2443698L);
+        publicInquiryItem.setVendUU(10050549L);     //祝通鸿
+        publicInquiryItem.setVendUserUU(1000027410L);   //祝通鸿
+        publicInquiryItem.setIsReplace((short) 0);
+        publicInquiryItem.setCmpCode("MT8783V");
+        publicInquiryItem.setSpec("MT8783V/CT,VFBGA641,SMD,无卤");
+        publicInquiryItem.setDate(new Date());
+        publicInquiryItem.setEndDate(new Date(System.currentTimeMillis() + 3 * 24 * 60 * 60 * 1000));
+        publicInquiryItem.setInbrand("MTK");
+        publicInquiryItem.setProdTitle("控制器IC");
+        publicInquiryItem.setQutoApp("sp");
+        publicInquiryItem.setCurrency("RMB");
+        publicInquiryItem.setLeadtime(3L);
+        publicInquiryItem.setTaxrate(0.16f);
+        //分段报价信息
+        List<PublicInquiryReply> replyList = new ArrayList<PublicInquiryReply>();
+        PublicInquiryReply publicInquiryReply = new PublicInquiryReply();
+        publicInquiryReply.setLapQty(100.0);
+        publicInquiryReply.setPrice(23.13);
+        replyList.add(publicInquiryReply);
+        publicInquiryReply = new PublicInquiryReply();
+        publicInquiryReply.setLapQty(200.0);
+        publicInquiryReply.setPrice(22.13);
+        replyList.add(publicInquiryReply);
+
+        //买家采购员信息
+        publicInquiryItem.setUserName("何炎");
+        publicInquiryItem.setUserTel("13978887888");
+        publicInquiryItem.setUserUU(1000012297L);
+        //询价单信息
+        PublicInquiry inquiry = new PublicInquiry();
+        inquiry.setId(2293571L);
+        inquiry.setEnUU(10050573L);
+        inquiry.setRecorderUU(1000012297L);
+        inquiry.setCode("sp1546790412000295579");
+
+        publicInquiryItem.setInquiry(inquiry);
+        publicInquiryItem.setReplies(replyList);
+        System.out.println(JsonUtils.toJsonString(publicInquiryItem));
         ModelMap modelMap = inquiryApi.saveQuote(publicInquiryItem);
         System.out.println(JsonUtils.toJsonString(modelMap));
     }

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

@@ -22,7 +22,8 @@ public class CompanyRspDTO implements Serializable {
      * 是否开通saas
      */
     private boolean saas_;
-    private String uu;
+    private Long uu;
+    private String tel;
     /**
      * 所属行业
      */
@@ -47,6 +48,24 @@ public class CompanyRspDTO implements Serializable {
 
     private String adminMobile;
 
+    private Long adminUU;
+
+    public String getTel() {
+        return tel;
+    }
+
+    public void setTel(String tel) {
+        this.tel = tel;
+    }
+
+    public Long getAdminUU() {
+        return adminUU;
+    }
+
+    public void setAdminUU(Long adminUU) {
+        this.adminUU = adminUU;
+    }
+
     public String getAdminMobile() {
         return adminMobile;
     }
@@ -103,11 +122,11 @@ public class CompanyRspDTO implements Serializable {
         this.defaultCompanyId = defaultCompanyId;
     }
 
-    public String getUu() {
+    public Long getUu() {
         return uu;
     }
 
-    public void setUu(String uu) {
+    public void setUu(Long uu) {
         this.uu = uu;
     }
 
@@ -159,7 +178,7 @@ public class CompanyRspDTO implements Serializable {
         this.default_ = default_;
     }
 
-    public CompanyRspDTO(String name, String businessCode, String address, boolean default_, boolean saas_, String uu, String admin, Long adminId, String type, String adminMobile) {
+    public CompanyRspDTO(String name, String businessCode, String address, boolean default_, boolean saas_, Long uu, String admin, Long adminId, String type, String adminMobile) {
         this.name = name;
         this.businessCode = businessCode;
         this.address = address;

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

@@ -117,7 +117,7 @@
     </select>
     <select id="findByFuzzyName" parameterType="java.lang.String" resultType="com.usoftchina.saas.account.dto.CompanyRspDTO">
         SELECT
-          ac.id,ac.name,aa.realname admin,aa.mobile adminMobile
+          ac.id,ac.name,aa.realname admin,aa.mobile adminMobile,aa.uu adminUU,ac.uu,ac.tel,ac.address,ac.business_code businessCode
         FROM
           ac_company ac
           INNER JOIN ac_account aa on ac.creator_id = aa.id

+ 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/getConpanyAnalyze',
+                // 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)

+ 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, // 允许列设置
     }
 });

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

@@ -138,6 +138,15 @@ Ext.define('saas.view.document.customer.FormPanel', {
                 allowBlank: false,
                 columnWidth: 0.25,
                 group: '交易信息',
+            }, {
+                xtype: "numberfield",
+                name: "cu_taxrate",
+                fieldLabel: "税率(%)",
+                allowBlank: false,
+                columnWidth: 0.25,
+                minValue: 0,
+                maxValue: 100,
+                group: '交易信息',
             },{
                 xtype: "numberfield",
                 hideTrigger: true,
@@ -179,15 +188,6 @@ Ext.define('saas.view.document.customer.FormPanel', {
                 renderer: function(v, m, r) {
                     return saas.util.BaseUtil.numberFormat(v, 2, true);
                 },
-            }, {
-                xtype: "numberfield",
-                name: "cu_taxrate",
-                fieldLabel: "税率(%)",
-                allowBlank: false,
-                columnWidth: 0.25,
-                minValue: 0,
-                maxValue: 100,
-                group: '交易信息',
             }, {
                 xtype: "numberfield",
                 hideTrigger: 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()
     }
 

+ 11 - 11
frontend/saas-web/app/view/document/vendor/FormPanel.js

@@ -144,6 +144,16 @@ Ext.define('saas.view.document.vendor.FormPanel', {
                 allowBlank: false,
                 columnWidth: 0.25,
                 group: '交易信息',
+            }, {
+                xtype: "numberfield",
+                name: "ve_taxrate",
+                hideTrigger: true,
+                fieldLabel: "税率(%)",
+                allowBlank: false,
+                columnWidth: 0.25,
+                minValue: 0,
+                maxValue: 100,
+                group: '交易信息',
             },{
                 xtype: "numberfield",
                 hideTrigger: true,
@@ -186,16 +196,6 @@ Ext.define('saas.view.document.vendor.FormPanel', {
                 renderer: function(v, m, r) {
                     return saas.util.BaseUtil.numberFormat(v, 2, true);
                 },
-            }, {
-                xtype: "numberfield",
-                name: "ve_taxrate",
-                hideTrigger: true,
-                fieldLabel: "税率(%)",
-                allowBlank: false,
-                columnWidth: 0.25,
-                minValue: 0,
-                maxValue: 100,
-                group: '交易信息',
             }, {
                 xtype: "numberfield",
                 hideTrigger: true,
@@ -262,7 +262,7 @@ Ext.define('saas.view.document.vendor.FormPanel', {
                 name: "ve_address",
                 fieldLabel: "公司地址",
                 allowBlank: true,
-                columnWidth: 0.75
+                columnWidth: 0.5
             }, {
                 fieldLabel: "备注",
                 xtype: 'textfield',

+ 1 - 0
frontend/saas-web/app/view/money/fundtransfer/FormPanel.js

@@ -87,6 +87,7 @@ Ext.define('saas.view.money.fundtransfer.FormPanel', {
                     }
                 }, {
                     text: "转出账户余额(元)",
+                    width: 200.0,
                     dataIndex: "bk_outthisamount",
                     ignore: true
                 }, {

+ 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 - 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": [{