Browse Source

Merge branch 'stage'
测试合并到正式

asd26269546 1 year ago
parent
commit
7eafd960d1
65 changed files with 8460 additions and 1130 deletions
  1. 2 0
      .env.development
  2. 3 1
      .env.production
  3. 3 1
      .env.staging
  4. 2 1
      package.json
  5. 739 3
      src/assets/icons/iconfont/demo_index.html
  6. 131 3
      src/assets/icons/iconfont/iconfont.css
  7. 0 0
      src/assets/icons/iconfont/iconfont.js
  8. 224 0
      src/assets/icons/iconfont/iconfont.json
  9. BIN
      src/assets/icons/iconfont/iconfont.ttf
  10. BIN
      src/assets/icons/iconfont/iconfont.woff
  11. BIN
      src/assets/icons/iconfont/iconfont.woff2
  12. 408 0
      src/components/PDF/contractPDF.vue
  13. 281 0
      src/components/PDF/purchasePDF.vue
  14. 3 4
      src/components/byForm/index.vue
  15. 243 0
      src/components/contractCom/contractDetails.vue
  16. 8 9
      src/components/headerBar/header-bar.vue
  17. 4 0
      src/components/headerBar/header.scss
  18. 20 20
      src/components/notice/index.vue
  19. 11 1
      src/components/process/Contract.vue
  20. 1381 0
      src/components/process/ContractAlteration.vue
  21. 3 0
      src/components/process/EHSD/Contract.vue
  22. 4 1
      src/components/process/EHSD/PriceSheet.vue
  23. 4 1
      src/components/process/EHSD/Purchase.vue
  24. 4 1
      src/components/process/EHSD/Sample.vue
  25. 4 1
      src/components/process/PriceSheet.vue
  26. 130 2
      src/components/process/PurchasePayment.vue
  27. 17 2
      src/components/process/PurchaseRefund.vue
  28. 4 1
      src/components/process/ReturnGood.vue
  29. 716 108
      src/components/process/SendFunds.vue
  30. 7 5
      src/components/process/SendPurchase.vue
  31. 4 1
      src/components/process/SendSubscribe.vue
  32. 4 1
      src/components/process/ServiceContract.vue
  33. 45 22
      src/components/product/SelectGoods.vue
  34. 4 0
      src/components/selectCity/index.vue
  35. 5 5
      src/lang/index.js
  36. 5 0
      src/main.js
  37. 70 3
      src/utils/util.js
  38. 21 32
      src/views/finance/fundManage/accountPayment/index.vue
  39. 357 41
      src/views/finance/fundManage/accountStatement/index.vue
  40. 436 0
      src/views/finance/fundManage/comeAndGo/index.vue
  41. 1 1
      src/views/finance/fundManage/depExpenses/index.vue
  42. 640 120
      src/views/finance/fundManage/funds/index.vue
  43. 10 7
      src/views/finance/fundManage/fundsStatement/index.vue
  44. 30 1
      src/views/process/processApproval/auxiliary.vue
  45. 96 18
      src/views/process/processApproval/index.vue
  46. 135 53
      src/views/product/material/index.vue
  47. 84 58
      src/views/product/product/index.vue
  48. 36 11
      src/views/product/product/index2.vue
  49. 1 0
      src/views/publicModule/codingRule/index.vue
  50. 40 0
      src/views/publicModule/salesman/index.vue
  51. 348 18
      src/views/purchaseManage/purchaseManage/alreadyPurchase/index.vue
  52. 53 5
      src/views/purchaseManage/purchaseManage/handoverSlip/index.vue
  53. 4 1
      src/views/purchaseManage/purchaseManage/purchase/index.vue
  54. 24 4
      src/views/purchaseManage/purchaseManage/returnGoods/index.vue
  55. 3 51
      src/views/purchaseManage/purchasePayment/payment/index.vue
  56. 1 1
      src/views/purchaseManage/supplier/supplyPrice/index.vue
  57. 165 11
      src/views/purchaseSales/outAndInWarehouse/record/index.vue
  58. 220 241
      src/views/salesMange/saleContract/contract/index.vue
  59. 614 0
      src/views/salesMange/saleContract/middle/index.vue
  60. 373 163
      src/views/salesMange/saleContract/priceSheet/index.vue
  61. 141 53
      src/views/salesMange/salesMange/profitSettlement/index.vue
  62. 2 2
      src/views/salesMange/shipmentMange/document/index.vue
  63. 117 35
      src/views/salesMange/shipmentMange/packing/index.vue
  64. 6 6
      src/views/system/dept2/index.vue
  65. 9 0
      src/views/system/user2/index.vue

+ 2 - 0
.env.development

@@ -6,3 +6,5 @@ VITE_APP_ENV = 'development'
 
 # 若依管理系统/开发环境
 VITE_APP_BASE_API = '/dev-api'
+
+VITE_APP_IP = '36.134.91.96'

+ 3 - 1
.env.production

@@ -8,4 +8,6 @@ VITE_APP_ENV = 'production'
 VITE_APP_BASE_API = '/prod-api'
 
 # 是否在打包时开启压缩,支持 gzip 和 brotli
-VITE_BUILD_COMPRESS = gzip
+VITE_BUILD_COMPRESS = gzip
+
+VITE_APP_IP = '139.159.251.109'

+ 3 - 1
.env.staging

@@ -8,4 +8,6 @@ VITE_APP_ENV = 'staging'
 VITE_APP_BASE_API = '/test-api'
 
 # 是否在打包时开启压缩,支持 gzip 和 brotli
-VITE_BUILD_COMPRESS = gzip
+VITE_BUILD_COMPRESS = gzip
+
+VITE_APP_IP = '36.134.91.96'

+ 2 - 1
package.json

@@ -51,7 +51,8 @@
     "vue-cropper": "1.0.3",
     "vue-i18n": "^9.3.0-beta.17",
     "vue-router": "4.1.4",
-    "vue-super-flow": "^1.3.8"
+    "vue-super-flow": "^1.3.8",
+    "vue3-print-nb": "^0.1.4"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "3.1.0",

+ 739 - 3
src/assets/icons/iconfont/demo_index.html

@@ -55,6 +55,198 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe8d2;</span>
+                <div class="name">iconm_gongncd</div>
+                <div class="code-name">&amp;#xe8d2;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8d3;</span>
+                <div class="name">iconm_changycd</div>
+                <div class="code-name">&amp;#xe8d3;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8d4;</span>
+                <div class="name">iconx_changycd</div>
+                <div class="code-name">&amp;#xe8d4;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8d5;</span>
+                <div class="name">iconx_gongncd</div>
+                <div class="code-name">&amp;#xe8d5;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8ba;</span>
+                <div class="name">icomx_xiaosht</div>
+                <div class="code-name">&amp;#xe8ba;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8bb;</span>
+                <div class="name">iconm_daicg</div>
+                <div class="code-name">&amp;#xe8bb;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8bc;</span>
+                <div class="name">iconm_fukgl</div>
+                <div class="code-name">&amp;#xe8bc;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8bd;</span>
+                <div class="name">iconm_hetgl</div>
+                <div class="code-name">&amp;#xe8bd;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8be;</span>
+                <div class="name">iconm_jihuagl</div>
+                <div class="code-name">&amp;#xe8be;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8bf;</span>
+                <div class="name">iconx_daicg</div>
+                <div class="code-name">&amp;#xe8bf;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c0;</span>
+                <div class="name">iconm_xiaosht</div>
+                <div class="code-name">&amp;#xe8c0;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c1;</span>
+                <div class="name">iconm_shenggl</div>
+                <div class="code-name">&amp;#xe8c1;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c2;</span>
+                <div class="name">iconx_caigth</div>
+                <div class="code-name">&amp;#xe8c2;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c3;</span>
+                <div class="name">iconx_daishenpi (1)</div>
+                <div class="code-name">&amp;#xe8c3;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c4;</span>
+                <div class="name">iconx_fukgl</div>
+                <div class="code-name">&amp;#xe8c4;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c5;</span>
+                <div class="name">iconm_daishenpi</div>
+                <div class="code-name">&amp;#xe8c5;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c6;</span>
+                <div class="name">iconm_caigth</div>
+                <div class="code-name">&amp;#xe8c6;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c7;</span>
+                <div class="name">iconm_xiaosth</div>
+                <div class="code-name">&amp;#xe8c7;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c8;</span>
+                <div class="name">iconx_hetgl</div>
+                <div class="code-name">&amp;#xe8c8;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c9;</span>
+                <div class="name">iconm_wulwh</div>
+                <div class="code-name">&amp;#xe8c9;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8ca;</span>
+                <div class="name">iconx_shenggl</div>
+                <div class="code-name">&amp;#xe8ca;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8cb;</span>
+                <div class="name">iconm_yicg</div>
+                <div class="code-name">&amp;#xe8cb;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8cc;</span>
+                <div class="name">iconx_lisfk</div>
+                <div class="code-name">&amp;#xe8cc;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8cd;</span>
+                <div class="name">iconm_lisfk</div>
+                <div class="code-name">&amp;#xe8cd;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8ce;</span>
+                <div class="name">iconx_daishenpi</div>
+                <div class="code-name">&amp;#xe8ce;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8cf;</span>
+                <div class="name">iconx_wulwh</div>
+                <div class="code-name">&amp;#xe8cf;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8d0;</span>
+                <div class="name">iconx_jihuagl</div>
+                <div class="code-name">&amp;#xe8d0;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8d1;</span>
+                <div class="name">iconx_yicg</div>
+                <div class="code-name">&amp;#xe8d1;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8b6;</span>
+                <div class="name">iconm_saixuan</div>
+                <div class="code-name">&amp;#xe8b6;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8b7;</span>
+                <div class="name">iconm_play2</div>
+                <div class="code-name">&amp;#xe8b7;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8b8;</span>
+                <div class="name">iconx_daishenpi</div>
+                <div class="code-name">&amp;#xe8b8;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8b9;</span>
+                <div class="name">iconm_daishenpi</div>
+                <div class="code-name">&amp;#xe8b9;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe8b4;</span>
                 <div class="name">iconx_saixuan</div>
                 <div class="code-name">&amp;#xe8b4;</div>
@@ -2766,9 +2958,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1686554047584') format('woff2'),
-       url('iconfont.woff?t=1686554047584') format('woff'),
-       url('iconfont.ttf?t=1686554047584') format('truetype');
+  src: url('iconfont.woff2?t=1687672153417') format('woff2'),
+       url('iconfont.woff?t=1687672153417') format('woff'),
+       url('iconfont.ttf?t=1687672153417') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -2795,6 +2987,294 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-iconm_gongncd"></span>
+            <div class="name">
+              iconm_gongncd
+            </div>
+            <div class="code-name">.icon-iconm_gongncd
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_changycd"></span>
+            <div class="name">
+              iconm_changycd
+            </div>
+            <div class="code-name">.icon-iconm_changycd
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_changycd"></span>
+            <div class="name">
+              iconx_changycd
+            </div>
+            <div class="code-name">.icon-iconx_changycd
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_gongncd"></span>
+            <div class="name">
+              iconx_gongncd
+            </div>
+            <div class="code-name">.icon-iconx_gongncd
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-icomx_xiaosht"></span>
+            <div class="name">
+              icomx_xiaosht
+            </div>
+            <div class="code-name">.icon-icomx_xiaosht
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_daicg"></span>
+            <div class="name">
+              iconm_daicg
+            </div>
+            <div class="code-name">.icon-iconm_daicg
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_fukgl"></span>
+            <div class="name">
+              iconm_fukgl
+            </div>
+            <div class="code-name">.icon-iconm_fukgl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_hetgl"></span>
+            <div class="name">
+              iconm_hetgl
+            </div>
+            <div class="code-name">.icon-iconm_hetgl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_jihuagl"></span>
+            <div class="name">
+              iconm_jihuagl
+            </div>
+            <div class="code-name">.icon-iconm_jihuagl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_daicg"></span>
+            <div class="name">
+              iconx_daicg
+            </div>
+            <div class="code-name">.icon-iconx_daicg
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_xiaosht"></span>
+            <div class="name">
+              iconm_xiaosht
+            </div>
+            <div class="code-name">.icon-iconm_xiaosht
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_shenggl"></span>
+            <div class="name">
+              iconm_shenggl
+            </div>
+            <div class="code-name">.icon-iconm_shenggl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_caigth"></span>
+            <div class="name">
+              iconx_caigth
+            </div>
+            <div class="code-name">.icon-iconx_caigth
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-iconx_daishenpi1"></span>
+            <div class="name">
+              iconx_daishenpi (1)
+            </div>
+            <div class="code-name">.icon-a-iconx_daishenpi1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_fukgl"></span>
+            <div class="name">
+              iconx_fukgl
+            </div>
+            <div class="code-name">.icon-iconx_fukgl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_daishenpi1"></span>
+            <div class="name">
+              iconm_daishenpi
+            </div>
+            <div class="code-name">.icon-iconm_daishenpi1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_caigth"></span>
+            <div class="name">
+              iconm_caigth
+            </div>
+            <div class="code-name">.icon-iconm_caigth
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_xiaosth"></span>
+            <div class="name">
+              iconm_xiaosth
+            </div>
+            <div class="code-name">.icon-iconm_xiaosth
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_hetgl"></span>
+            <div class="name">
+              iconx_hetgl
+            </div>
+            <div class="code-name">.icon-iconx_hetgl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_wulwh"></span>
+            <div class="name">
+              iconm_wulwh
+            </div>
+            <div class="code-name">.icon-iconm_wulwh
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_shenggl"></span>
+            <div class="name">
+              iconx_shenggl
+            </div>
+            <div class="code-name">.icon-iconx_shenggl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_yicg"></span>
+            <div class="name">
+              iconm_yicg
+            </div>
+            <div class="code-name">.icon-iconm_yicg
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_lisfk"></span>
+            <div class="name">
+              iconx_lisfk
+            </div>
+            <div class="code-name">.icon-iconx_lisfk
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_lisfk"></span>
+            <div class="name">
+              iconm_lisfk
+            </div>
+            <div class="code-name">.icon-iconm_lisfk
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_daishenpi1"></span>
+            <div class="name">
+              iconx_daishenpi
+            </div>
+            <div class="code-name">.icon-iconx_daishenpi1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_wulwh"></span>
+            <div class="name">
+              iconx_wulwh
+            </div>
+            <div class="code-name">.icon-iconx_wulwh
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_jihuagl"></span>
+            <div class="name">
+              iconx_jihuagl
+            </div>
+            <div class="code-name">.icon-iconx_jihuagl
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_yicg"></span>
+            <div class="name">
+              iconx_yicg
+            </div>
+            <div class="code-name">.icon-iconx_yicg
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_saixuan1"></span>
+            <div class="name">
+              iconm_saixuan
+            </div>
+            <div class="code-name">.icon-iconm_saixuan1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_play2"></span>
+            <div class="name">
+              iconm_play2
+            </div>
+            <div class="code-name">.icon-iconm_play2
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconx_daishenpi"></span>
+            <div class="name">
+              iconx_daishenpi
+            </div>
+            <div class="code-name">.icon-iconx_daishenpi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-iconm_daishenpi"></span>
+            <div class="name">
+              iconm_daishenpi
+            </div>
+            <div class="code-name">.icon-iconm_daishenpi
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-iconx_saixuan"></span>
             <div class="name">
               iconx_saixuan
@@ -6864,6 +7344,262 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_gongncd"></use>
+                </svg>
+                <div class="name">iconm_gongncd</div>
+                <div class="code-name">#icon-iconm_gongncd</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_changycd"></use>
+                </svg>
+                <div class="name">iconm_changycd</div>
+                <div class="code-name">#icon-iconm_changycd</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_changycd"></use>
+                </svg>
+                <div class="name">iconx_changycd</div>
+                <div class="code-name">#icon-iconx_changycd</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_gongncd"></use>
+                </svg>
+                <div class="name">iconx_gongncd</div>
+                <div class="code-name">#icon-iconx_gongncd</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-icomx_xiaosht"></use>
+                </svg>
+                <div class="name">icomx_xiaosht</div>
+                <div class="code-name">#icon-icomx_xiaosht</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_daicg"></use>
+                </svg>
+                <div class="name">iconm_daicg</div>
+                <div class="code-name">#icon-iconm_daicg</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_fukgl"></use>
+                </svg>
+                <div class="name">iconm_fukgl</div>
+                <div class="code-name">#icon-iconm_fukgl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_hetgl"></use>
+                </svg>
+                <div class="name">iconm_hetgl</div>
+                <div class="code-name">#icon-iconm_hetgl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_jihuagl"></use>
+                </svg>
+                <div class="name">iconm_jihuagl</div>
+                <div class="code-name">#icon-iconm_jihuagl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_daicg"></use>
+                </svg>
+                <div class="name">iconx_daicg</div>
+                <div class="code-name">#icon-iconx_daicg</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_xiaosht"></use>
+                </svg>
+                <div class="name">iconm_xiaosht</div>
+                <div class="code-name">#icon-iconm_xiaosht</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_shenggl"></use>
+                </svg>
+                <div class="name">iconm_shenggl</div>
+                <div class="code-name">#icon-iconm_shenggl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_caigth"></use>
+                </svg>
+                <div class="name">iconx_caigth</div>
+                <div class="code-name">#icon-iconx_caigth</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-iconx_daishenpi1"></use>
+                </svg>
+                <div class="name">iconx_daishenpi (1)</div>
+                <div class="code-name">#icon-a-iconx_daishenpi1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_fukgl"></use>
+                </svg>
+                <div class="name">iconx_fukgl</div>
+                <div class="code-name">#icon-iconx_fukgl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_daishenpi1"></use>
+                </svg>
+                <div class="name">iconm_daishenpi</div>
+                <div class="code-name">#icon-iconm_daishenpi1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_caigth"></use>
+                </svg>
+                <div class="name">iconm_caigth</div>
+                <div class="code-name">#icon-iconm_caigth</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_xiaosth"></use>
+                </svg>
+                <div class="name">iconm_xiaosth</div>
+                <div class="code-name">#icon-iconm_xiaosth</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_hetgl"></use>
+                </svg>
+                <div class="name">iconx_hetgl</div>
+                <div class="code-name">#icon-iconx_hetgl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_wulwh"></use>
+                </svg>
+                <div class="name">iconm_wulwh</div>
+                <div class="code-name">#icon-iconm_wulwh</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_shenggl"></use>
+                </svg>
+                <div class="name">iconx_shenggl</div>
+                <div class="code-name">#icon-iconx_shenggl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_yicg"></use>
+                </svg>
+                <div class="name">iconm_yicg</div>
+                <div class="code-name">#icon-iconm_yicg</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_lisfk"></use>
+                </svg>
+                <div class="name">iconx_lisfk</div>
+                <div class="code-name">#icon-iconx_lisfk</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_lisfk"></use>
+                </svg>
+                <div class="name">iconm_lisfk</div>
+                <div class="code-name">#icon-iconm_lisfk</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_daishenpi1"></use>
+                </svg>
+                <div class="name">iconx_daishenpi</div>
+                <div class="code-name">#icon-iconx_daishenpi1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_wulwh"></use>
+                </svg>
+                <div class="name">iconx_wulwh</div>
+                <div class="code-name">#icon-iconx_wulwh</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_jihuagl"></use>
+                </svg>
+                <div class="name">iconx_jihuagl</div>
+                <div class="code-name">#icon-iconx_jihuagl</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_yicg"></use>
+                </svg>
+                <div class="name">iconx_yicg</div>
+                <div class="code-name">#icon-iconx_yicg</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_saixuan1"></use>
+                </svg>
+                <div class="name">iconm_saixuan</div>
+                <div class="code-name">#icon-iconm_saixuan1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_play2"></use>
+                </svg>
+                <div class="name">iconm_play2</div>
+                <div class="code-name">#icon-iconm_play2</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconx_daishenpi"></use>
+                </svg>
+                <div class="name">iconx_daishenpi</div>
+                <div class="code-name">#icon-iconx_daishenpi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-iconm_daishenpi"></use>
+                </svg>
+                <div class="name">iconm_daishenpi</div>
+                <div class="code-name">#icon-iconm_daishenpi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-iconx_saixuan"></use>
                 </svg>
                 <div class="name">iconx_saixuan</div>

+ 131 - 3
src/assets/icons/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 3933484 */
-  src: url('iconfont.woff2?t=1686554047584') format('woff2'),
-       url('iconfont.woff?t=1686554047584') format('woff'),
-       url('iconfont.ttf?t=1686554047584') format('truetype');
+  src: url('iconfont.woff2?t=1687672153417') format('woff2'),
+       url('iconfont.woff?t=1687672153417') format('woff'),
+       url('iconfont.ttf?t=1687672153417') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,134 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-iconm_gongncd:before {
+  content: "\e8d2";
+}
+
+.icon-iconm_changycd:before {
+  content: "\e8d3";
+}
+
+.icon-iconx_changycd:before {
+  content: "\e8d4";
+}
+
+.icon-iconx_gongncd:before {
+  content: "\e8d5";
+}
+
+.icon-icomx_xiaosht:before {
+  content: "\e8ba";
+}
+
+.icon-iconm_daicg:before {
+  content: "\e8bb";
+}
+
+.icon-iconm_fukgl:before {
+  content: "\e8bc";
+}
+
+.icon-iconm_hetgl:before {
+  content: "\e8bd";
+}
+
+.icon-iconm_jihuagl:before {
+  content: "\e8be";
+}
+
+.icon-iconx_daicg:before {
+  content: "\e8bf";
+}
+
+.icon-iconm_xiaosht:before {
+  content: "\e8c0";
+}
+
+.icon-iconm_shenggl:before {
+  content: "\e8c1";
+}
+
+.icon-iconx_caigth:before {
+  content: "\e8c2";
+}
+
+.icon-a-iconx_daishenpi1:before {
+  content: "\e8c3";
+}
+
+.icon-iconx_fukgl:before {
+  content: "\e8c4";
+}
+
+.icon-iconm_daishenpi1:before {
+  content: "\e8c5";
+}
+
+.icon-iconm_caigth:before {
+  content: "\e8c6";
+}
+
+.icon-iconm_xiaosth:before {
+  content: "\e8c7";
+}
+
+.icon-iconx_hetgl:before {
+  content: "\e8c8";
+}
+
+.icon-iconm_wulwh:before {
+  content: "\e8c9";
+}
+
+.icon-iconx_shenggl:before {
+  content: "\e8ca";
+}
+
+.icon-iconm_yicg:before {
+  content: "\e8cb";
+}
+
+.icon-iconx_lisfk:before {
+  content: "\e8cc";
+}
+
+.icon-iconm_lisfk:before {
+  content: "\e8cd";
+}
+
+.icon-iconx_daishenpi1:before {
+  content: "\e8ce";
+}
+
+.icon-iconx_wulwh:before {
+  content: "\e8cf";
+}
+
+.icon-iconx_jihuagl:before {
+  content: "\e8d0";
+}
+
+.icon-iconx_yicg:before {
+  content: "\e8d1";
+}
+
+.icon-iconm_saixuan1:before {
+  content: "\e8b6";
+}
+
+.icon-iconm_play2:before {
+  content: "\e8b7";
+}
+
+.icon-iconx_daishenpi:before {
+  content: "\e8b8";
+}
+
+.icon-iconm_daishenpi:before {
+  content: "\e8b9";
+}
+
 .icon-iconx_saixuan:before {
   content: "\e8b4";
 }

File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/iconfont/iconfont.js


+ 224 - 0
src/assets/icons/iconfont/iconfont.json

@@ -6,6 +6,230 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "36123929",
+      "name": "iconm_gongncd",
+      "font_class": "iconm_gongncd",
+      "unicode": "e8d2",
+      "unicode_decimal": 59602
+    },
+    {
+      "icon_id": "36123930",
+      "name": "iconm_changycd",
+      "font_class": "iconm_changycd",
+      "unicode": "e8d3",
+      "unicode_decimal": 59603
+    },
+    {
+      "icon_id": "36123931",
+      "name": "iconx_changycd",
+      "font_class": "iconx_changycd",
+      "unicode": "e8d4",
+      "unicode_decimal": 59604
+    },
+    {
+      "icon_id": "36123932",
+      "name": "iconx_gongncd",
+      "font_class": "iconx_gongncd",
+      "unicode": "e8d5",
+      "unicode_decimal": 59605
+    },
+    {
+      "icon_id": "36111345",
+      "name": "icomx_xiaosht",
+      "font_class": "icomx_xiaosht",
+      "unicode": "e8ba",
+      "unicode_decimal": 59578
+    },
+    {
+      "icon_id": "36111346",
+      "name": "iconm_daicg",
+      "font_class": "iconm_daicg",
+      "unicode": "e8bb",
+      "unicode_decimal": 59579
+    },
+    {
+      "icon_id": "36111347",
+      "name": "iconm_fukgl",
+      "font_class": "iconm_fukgl",
+      "unicode": "e8bc",
+      "unicode_decimal": 59580
+    },
+    {
+      "icon_id": "36111348",
+      "name": "iconm_hetgl",
+      "font_class": "iconm_hetgl",
+      "unicode": "e8bd",
+      "unicode_decimal": 59581
+    },
+    {
+      "icon_id": "36111349",
+      "name": "iconm_jihuagl",
+      "font_class": "iconm_jihuagl",
+      "unicode": "e8be",
+      "unicode_decimal": 59582
+    },
+    {
+      "icon_id": "36111350",
+      "name": "iconx_daicg",
+      "font_class": "iconx_daicg",
+      "unicode": "e8bf",
+      "unicode_decimal": 59583
+    },
+    {
+      "icon_id": "36111351",
+      "name": "iconm_xiaosht",
+      "font_class": "iconm_xiaosht",
+      "unicode": "e8c0",
+      "unicode_decimal": 59584
+    },
+    {
+      "icon_id": "36111352",
+      "name": "iconm_shenggl",
+      "font_class": "iconm_shenggl",
+      "unicode": "e8c1",
+      "unicode_decimal": 59585
+    },
+    {
+      "icon_id": "36111353",
+      "name": "iconx_caigth",
+      "font_class": "iconx_caigth",
+      "unicode": "e8c2",
+      "unicode_decimal": 59586
+    },
+    {
+      "icon_id": "36111354",
+      "name": "iconx_daishenpi (1)",
+      "font_class": "a-iconx_daishenpi1",
+      "unicode": "e8c3",
+      "unicode_decimal": 59587
+    },
+    {
+      "icon_id": "36111355",
+      "name": "iconx_fukgl",
+      "font_class": "iconx_fukgl",
+      "unicode": "e8c4",
+      "unicode_decimal": 59588
+    },
+    {
+      "icon_id": "36111356",
+      "name": "iconm_daishenpi",
+      "font_class": "iconm_daishenpi1",
+      "unicode": "e8c5",
+      "unicode_decimal": 59589
+    },
+    {
+      "icon_id": "36111357",
+      "name": "iconm_caigth",
+      "font_class": "iconm_caigth",
+      "unicode": "e8c6",
+      "unicode_decimal": 59590
+    },
+    {
+      "icon_id": "36111358",
+      "name": "iconm_xiaosth",
+      "font_class": "iconm_xiaosth",
+      "unicode": "e8c7",
+      "unicode_decimal": 59591
+    },
+    {
+      "icon_id": "36111359",
+      "name": "iconx_hetgl",
+      "font_class": "iconx_hetgl",
+      "unicode": "e8c8",
+      "unicode_decimal": 59592
+    },
+    {
+      "icon_id": "36111360",
+      "name": "iconm_wulwh",
+      "font_class": "iconm_wulwh",
+      "unicode": "e8c9",
+      "unicode_decimal": 59593
+    },
+    {
+      "icon_id": "36111361",
+      "name": "iconx_shenggl",
+      "font_class": "iconx_shenggl",
+      "unicode": "e8ca",
+      "unicode_decimal": 59594
+    },
+    {
+      "icon_id": "36111362",
+      "name": "iconm_yicg",
+      "font_class": "iconm_yicg",
+      "unicode": "e8cb",
+      "unicode_decimal": 59595
+    },
+    {
+      "icon_id": "36111363",
+      "name": "iconx_lisfk",
+      "font_class": "iconx_lisfk",
+      "unicode": "e8cc",
+      "unicode_decimal": 59596
+    },
+    {
+      "icon_id": "36111364",
+      "name": "iconm_lisfk",
+      "font_class": "iconm_lisfk",
+      "unicode": "e8cd",
+      "unicode_decimal": 59597
+    },
+    {
+      "icon_id": "36111365",
+      "name": "iconx_daishenpi",
+      "font_class": "iconx_daishenpi1",
+      "unicode": "e8ce",
+      "unicode_decimal": 59598
+    },
+    {
+      "icon_id": "36111366",
+      "name": "iconx_wulwh",
+      "font_class": "iconx_wulwh",
+      "unicode": "e8cf",
+      "unicode_decimal": 59599
+    },
+    {
+      "icon_id": "36111367",
+      "name": "iconx_jihuagl",
+      "font_class": "iconx_jihuagl",
+      "unicode": "e8d0",
+      "unicode_decimal": 59600
+    },
+    {
+      "icon_id": "36111368",
+      "name": "iconx_yicg",
+      "font_class": "iconx_yicg",
+      "unicode": "e8d1",
+      "unicode_decimal": 59601
+    },
+    {
+      "icon_id": "36040573",
+      "name": "iconm_saixuan",
+      "font_class": "iconm_saixuan1",
+      "unicode": "e8b6",
+      "unicode_decimal": 59574
+    },
+    {
+      "icon_id": "36040574",
+      "name": "iconm_play2",
+      "font_class": "iconm_play2",
+      "unicode": "e8b7",
+      "unicode_decimal": 59575
+    },
+    {
+      "icon_id": "36040575",
+      "name": "iconx_daishenpi",
+      "font_class": "iconx_daishenpi",
+      "unicode": "e8b8",
+      "unicode_decimal": 59576
+    },
+    {
+      "icon_id": "36040576",
+      "name": "iconm_daishenpi",
+      "font_class": "iconm_daishenpi",
+      "unicode": "e8b9",
+      "unicode_decimal": 59577
+    },
+    {
       "icon_id": "35941342",
       "name": "iconx_saixuan",
       "font_class": "iconx_saixuan",

BIN
src/assets/icons/iconfont/iconfont.ttf


BIN
src/assets/icons/iconfont/iconfont.woff


BIN
src/assets/icons/iconfont/iconfont.woff2


+ 408 - 0
src/components/PDF/contractPDF.vue

@@ -0,0 +1,408 @@
+<template>
+  <div>
+    <div id="printMe">
+      <div
+        id="pdfDom"
+        style="width: 800px; padding: 16px; font-size: 12px !important"
+      >
+        <div style="font-size: 18px; text-align: center">
+          {{ printDetails.sellCorporationNameEn }}
+        </div>
+        <div style="text-align: center">
+          {{ printDetails.sellCountryName }},{{
+            printDetails.sellProvinceName
+          }},{{ printDetails.sellCityName }},{{
+            printDetails.sellDetailedAddress
+          }}
+        </div>
+        <div
+          style="
+            font-size: 14px;
+            color: #409eff;
+            text-align: center;
+            padding-top: 16px;
+          "
+        >
+          PROFORMA INVOICE
+        </div>
+        <div style="padding-top: 8px">
+          <div>PI NO. : {{ printDetails.contractCode }}</div>
+          <div>PI DATE: {{ printDetails.createTimeEn }}</div>
+        </div>
+        <div style="border: 1px solid black; display: flex">
+          <div style="width: 50%; border-right: 1px solid black">
+            <div style="color: #409eff">VENDOR:</div>
+            <div>{{ printDetails.sellCorporationNameEn }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.sellCountryName }},{{
+                printDetails.sellProvinceName
+              }},{{ printDetails.sellCityName }},{{
+                printDetails.sellDetailedAddress
+              }}
+            </div>
+            <div>CONTACT: {{ printDetails.sellContactName }}</div>
+            <div>TEL.: {{ printDetails.sellContactNumber }}</div>
+          </div>
+          <div style="width: 50%">
+            <div style="color: #409eff">BUYER:</div>
+            <div>{{ printDetails.buyCorporationName }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.buyDetailedAddress }},{{
+                printDetails.buyCityName
+              }},{{ printDetails.buyProvinceName }},{{
+                printDetails.buyCountryName
+              }}
+            </div>
+            <div>CONTACT: {{ printDetails.buyContactName }}</div>
+            <div>TEL.: {{ printDetails.buyContactNumber }}</div>
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <div style="border: 1px solid black">
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+              "
+            >
+              <div style="color: #409eff">COUNTRY OF ORIGIN:</div>
+              <div>{{ printDetails.sellCountryName }}</div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+              "
+            >
+              <div style="color: #409eff">COUNTRY OF DESTINATION:</div>
+              <div>{{ printDetails.buyCountryName }}</div>
+            </div>
+            <div style="width: 33%; border-bottom: 1px solid black">
+              <div style="color: #409eff">PLACE OF DISCHARGE:</div>
+              <div>{{ printDetails.transportRemark }}</div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+              "
+            >
+              <div style="color: #409eff">TERMS OF DELIVERY:</div>
+              <div>
+                {{ dictValueLabel(printDetails.tradeMethods, tradeMethods) }}
+              </div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+              "
+            >
+              <div style="color: #409eff">CURRENCY:</div>
+              <div>
+                {{ printDetails.currency }}
+              </div>
+            </div>
+            <div style="width: 33%; border-bottom: 1px solid black">
+              <div style="color: #409eff">EXPORT BY/VIA:</div>
+              <div>
+                {{
+                  dictValueLabel(printDetails.transportMethod, shippingMethod)
+                }}
+              </div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div style="width: 33%; border-right: 1px solid black">
+              <div style="color: #409eff">DELIVERY TIME:</div>
+              <div>{{ printDetails.deliveryTime }}</div>
+            </div>
+            <div style="width: 67%">
+              <div style="color: #409eff">TERMS OF PAYMENT:</div>
+              <div>{{ printDetails.remark }}</div>
+            </div>
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <div class="baseRow" style="display: flex; color: #409eff">
+          <div class="contentRow" style="width: 50px; text-align: center">
+            NO.
+          </div>
+          <div
+            class="contentRow"
+            style="width: calc(100% - 450px); text-align: center"
+          >
+            COMMODITY, SPECIFICATION
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            UNIT
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            QUANTITY
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            UNIT PRICE
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            TOTAL PRICE
+          </div>
+        </div>
+        <div
+          v-if="
+            printDetails.productInfoList &&
+            printDetails.productInfoList.length > 0
+          "
+        >
+          <div
+            class="baseRow"
+            style="display: flex"
+            v-for="(item, index) in printDetails.productInfoList"
+            :key="item.productId"
+          >
+            <div class="contentRow" style="width: 50px; text-align: center">
+              {{ index + 1 }}
+            </div>
+            <div
+              class="contentRow"
+              style="width: calc(100% - 450px); text-align: center"
+            >
+              {{ item.productName }}
+            </div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ dictValueLabel(item.productUnit, productUnit) }}
+            </div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ item.productQuantity }}
+            </div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ item.productPrice }}
+            </div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ item.amount }}
+            </div>
+          </div>
+        </div>
+        <div class="baseRow" style="display: flex; color: #409eff">
+          <div
+            class="contentRow"
+            style="width: calc(100% - 400px); text-align: center"
+          >
+            SUBTOTAL:
+          </div>
+          <div
+            class="contentRow"
+            style="width: 100px; text-align: center"
+          ></div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            {{ statistics("productQuantity", 0) }}
+          </div>
+          <div
+            class="contentRow"
+            style="width: 100px; text-align: center"
+          ></div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            {{ statistics("amount", 2) }}
+          </div>
+        </div>
+        <!-- <div v-if="printDetails.quotationPayList && printDetails.quotationPayList.length > 0">
+            <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.quotationPayList" :key="index">
+              <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">{{ item.payName }}:</div>
+              <div class="contentRow" style="width: 100px; text-align: center">{{ item.amount }}</div>
+            </div>
+          </div> -->
+        <div class="baseRow" style="display: flex">
+          <div
+            class="contentRow"
+            style="width: calc(100% - 100px); text-align: right; color: #409eff"
+          >
+            FREIGHT COST:
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            {{ statisticsTwo("amount", 2) }}
+          </div>
+        </div>
+        <div class="baseRow" style="display: flex">
+          <div
+            class="contentRow"
+            style="width: calc(100% - 100px); text-align: right; color: #409eff"
+          >
+            TOTAL PRICE:
+          </div>
+          <div class="contentRow" style="width: 100px; text-align: center">
+            {{ printDetails.totalAmount }}
+          </div>
+        </div>
+        <div
+          class="baseRow"
+          style="display: flex; border-bottom: 1px solid black"
+        >
+          <div class="contentRow" style="width: 100%">
+            {{
+              translateIntoEnglish(
+                printDetails.totalAmount,
+                printDetails.currency
+              )
+            }}
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <div class="baseRow" style="color: #409eff">
+          <div class="contentRow" style="width: 100%">ACCOUNT INFORMATION:</div>
+        </div>
+        <div class="baseRow" style="border-bottom: 1px solid black">
+          <div class="contentRow" style="width: 100%">
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Beneficiary Name: {{ printDetails.beneficiaryName }}
+            </div>
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Beneficiary Bank: {{ printDetails.beneficiaryBank }}
+            </div>
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Beneficiary Bank Address:
+              {{ printDetails.beneficiaryBankAddress }}
+            </div>
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Beneficiary Account Number:
+              {{ printDetails.beneficiaryAccountNumber }}
+            </div>
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Swift Code: {{ printDetails.swiftCode }}
+            </div>
+            <div
+              style="
+                line-height: 24px;
+                padding-left: 4px;
+                word-break: break-all;
+                word-wrap: break-word;
+              "
+            >
+              Beneficiary Address: {{ printDetails.beneficiaryAddress }}
+            </div>
+          </div>
+        </div>
+        <div style="height: 32px"></div>
+        <div style="display: flex">
+          <div style="width: 50%">
+            <div style="color: #409eff">CONFIRMED BY VENDOR:</div>
+            <div>{{ printDetails.sellCorporationNameEn }}</div>
+          </div>
+          <div style="width: 50%">
+            <div style="color: #409eff">CONFIRMED BY BUYER:</div>
+            <div>{{ printDetails.buyCorporationName }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { NumberToChinese } from "@/utils/util.js";
+import { watch } from "vue";
+const { proxy } = getCurrentInstance();
+const printDetails = ref({});
+const props = defineProps({
+  rowData: Object,
+});
+const getPdfData = (row) => {
+  proxy.post("/contract/getContractPdfInfo", { id: row.id }).then((res) => {
+    printDetails.value = res;
+  });
+};
+const statistics = (label, index) => {
+  let num = 0;
+  if (
+    printDetails.value.productInfoList &&
+    printDetails.value.productInfoList.length > 0
+  ) {
+    printDetails.value.productInfoList.map((item) => {
+      if (item[label]) {
+        num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
+      }
+    });
+  }
+  return num;
+};
+const statisticsTwo = (label, index) => {
+  let num = 0;
+  if (
+    printDetails.value.contractProjectList &&
+    printDetails.value.contractProjectList.length > 0
+  ) {
+    printDetails.value.contractProjectList.map((item) => {
+      if (item[label]) {
+        num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
+      }
+    });
+  }
+  return num;
+};
+
+if (props.rowData && props.rowData.id) {
+  getPdfData(props.rowData);
+}
+
+watch(
+  () => props.rowData.id,
+  (val) => {
+    if (props.rowData && props.rowData.id) {
+      getPdfData(props.rowData);
+    }
+  }
+);
+</script>
+
+<style lang="scss" scoped>
+.baseRow {
+  min-height: 24px;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+}
+.contentRow {
+  border-right: 1px solid black;
+  line-height: 24px;
+  padding-left: 4px;
+}
+</style>

+ 281 - 0
src/components/PDF/purchasePDF.vue

@@ -0,0 +1,281 @@
+<template>
+  <div>
+    <div id="pdfDom" ref="pdfDom" style="width: 776px">
+      <div style="border: 1px solid #000; border-collapse: collapse">
+        <div style="text-align: right; padding: 2px 4px 0 0">
+          合同号:{{ pdfData.code }}
+        </div>
+        <div class="title">购销合同</div>
+        <div style="display: flex">
+          <div style="display: flex; width: 50%; padding-right: 20px">
+            <div style="width: 60px">买方:</div>
+            <div style="width: calc(100% - 60px)">
+              <div>福建宏星电子科技有限公司</div>
+              <div>福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层</div>
+            </div>
+          </div>
+          <div style="display: flex; width: 50%; padding-left: 20px">
+            <div style="width: 60px">卖方:</div>
+            <div style="width: calc(100% - 60px)">
+              {{ pdfData.supplyName }}
+            </div>
+          </div>
+        </div>
+        <div style="display: flex">
+          <div style="display: flex; width: 50%; padding-right: 20px">
+            <div style="width: 60px">经手人:</div>
+            <div style="width: calc(100% - 60px)">
+              {{ pdfData.purchaseName }}
+            </div>
+          </div>
+          <div style="display: flex; width: 50%; padding-left: 20px">
+            <div style="width: 60px">经手人:</div>
+            <div style="width: calc(100% - 60px)">
+              {{ pdfData.contactPerson }}
+            </div>
+          </div>
+        </div>
+        <div>买卖双方经协商,一致同意签订以下合同</div>
+        <div>货物名称、规格型号、单位、数量、单价及金额:</div>
+        <table border="1" style="width: 100%" class="table">
+          <tr>
+            <td style="width: 70px">序号</td>
+            <td>品名</td>
+            <td>规格型号</td>
+            <td style="width: 60px">单位</td>
+            <td style="width: 60px">数量</td>
+            <td style="width: 100px">单价</td>
+            <td style="width: 100px">金额</td>
+          </tr>
+          <tr v-for="(row, index) in pdfData.purchaseDetailList" :key="row.id">
+            <td style="width: 70px">{{ index + 1 }}</td>
+            <td>{{ row.productName }}</td>
+            <td>{{ row.productSpec }}</td>
+            <td style="width: 60px">{{ row.productUnitName }}</td>
+            <td style="width: 60px">{{ row.count }}</td>
+            <td style="width: 100px">
+              <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+              >{{ row.price }}
+            </td>
+            <td style="width: 100px">
+              <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+              >{{ row.amount }}
+            </td>
+          </tr>
+          <tr>
+            <td colspan="4" style="text-align: right">其他收费项目:</td>
+            <td></td>
+            <td></td>
+            <td>
+              <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+              >{{ pdfData.otherMoney }}
+            </td>
+          </tr>
+          <tr>
+            <td colspan="4" style="text-align: right">合计:</td>
+            <td>{{ pdfData.countTotal }}</td>
+            <td></td>
+            <td>
+              <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+              >{{ pdfData.amount }}
+            </td>
+          </tr>
+          <tr>
+            <td colspan="7" style="text-align: left">
+              合计人民币金额(大写):{{ pdfData.moneyChinese }}
+            </td>
+          </tr>
+          <tr>
+            <td>交货地点:</td>
+            <td colspan="6" style="text-align: left">
+              福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层
+            </td>
+          </tr>
+          <!-- <tr>
+              <td>交货时间:</td>
+              <td colspan="6" style="text-align: left"></td>
+            </tr> -->
+          <tr>
+            <td>保修期:</td>
+            <td colspan="6" style="text-align: left">一年</td>
+          </tr>
+          <tr>
+            <td colspan="7" style="text-align: left; padding: 0px">
+              <div style="padding: 2px 0px">
+                一、交货地点:福州软件园A区28座5层。
+              </div>
+              <div style="padding: 2px 0px">二、运输方式及运费:买方承担。</div>
+              <div style="padding: 2px 0px">
+                三、质量要求:样品品质、型号、规格、数量如同买方确认上表规格所示,不符合则由卖方承担责任。
+              </div>
+              <div style="padding: 2px 0px">四、交货时间:2023年4月13日。</div>
+              <div style="padding: 2px 0px">五、付款方式:银行转账。</div>
+              <div style="padding: 2px 0px">六、保修期:一年。</div>
+              <div style="padding: 2px 0px">
+                七、本合同经买卖双方签字盖章后生效,传真件有效。
+              </div>
+              <div style="padding: 2px 0px">
+                八、解决合同纠纷:原双方另有约定外,均按《中华人民共和国合同法》有关规定处理。
+              </div>
+              <div style="padding: 2px 0px">九、其他约定事项:友好解决。</div>
+            </td>
+          </tr>
+        </table>
+        <div style="display: flex">
+          <div style="width: 50%; padding-right: 20px">
+            <div>买方:</div>
+            <div>单位名称:福建宏星电子科技有限公司</div>
+            <div>
+              地址:福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层
+            </div>
+            <div>电话:</div>
+            <div>传真:</div>
+            <div style="opacity: 0">|</div>
+            <div style="margin-top: auto">代表人签字:</div>
+          </div>
+          <div style="width: 50%; padding-left: 20px">
+            <div>卖方:</div>
+            <div>单位名称:{{ pdfData.supplyName }}</div>
+            <div>统一社会信用代码:</div>
+            <div>开户银行:{{ pdfData.openingBank }}</div>
+            <div>帐号:{{ pdfData.accountOpening }}</div>
+            <div>
+              地址:<span
+                v-if="
+                  pdfData.supplyAddress && pdfData.supplyAddress.countryName
+                "
+                >{{ pdfData.supplyAddress.countryName }}</span
+              >
+              <span
+                v-if="
+                  pdfData.supplyAddress && pdfData.supplyAddress.provinceName
+                "
+                >,{{ pdfData.supplyAddress.provinceName }}</span
+              >
+              <span
+                v-if="pdfData.supplyAddress && pdfData.supplyAddress.cityName"
+                >,{{ pdfData.supplyAddress.cityName }}</span
+              >
+              <span
+                v-if="pdfData.supplyAddress && pdfData.supplyAddress.areaDetail"
+                >,{{ pdfData.supplyAddress.areaDetail }}</span
+              >
+            </div>
+            <div>电话:{{ pdfData.contactNumber }}</div>
+            <div>代表人签字:</div>
+          </div>
+        </div>
+        <div
+          style="
+            padding: 30px 0px 20px 0;
+            text-align: right;
+            border-top: 1px solid #000;
+          "
+        >
+          签订日期:{{ pdfData.approvedDate }}
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { NumberToChinese } from "@/utils/util.js";
+const { proxy } = getCurrentInstance();
+const pdfData = ref({});
+const props = defineProps({
+  rowData: Object,
+});
+const productUnit = ref([]);
+proxy.getDictOne(["unit"]).then((res) => {
+  productUnit.value = res["unit"].map((x) => ({
+    label: x.dictValue,
+    value: x.dictKey,
+  }));
+});
+const handlePrintPdf = (row) => {
+  proxy.post("/purchase/detail", { id: row.id }).then((res) => {
+    proxy
+      .post("/supplierInfo/detail", { id: res.supplyId })
+      .then((supplyData) => {
+        res.contactPerson = supplyData.contactPerson;
+        res.contactNumber = supplyData.contactNumber;
+        res.openingBank = supplyData.openingBank;
+        res.accountOpening = supplyData.accountOpening;
+        let countTotal = 0;
+        let productMoney = 0;
+        for (let i = 0; i < res.purchaseDetailList.length; i++) {
+          const e = res.purchaseDetailList[i];
+          e.productUnitName = proxy.dictValueLabel(
+            e.productUnit,
+            productUnit.value
+          );
+          countTotal += Number(e.count);
+          productMoney += Number(e.amount);
+        }
+        res.countTotal = countTotal;
+        res.productMoney = productMoney;
+        res.otherMoney = res.amount - res.productMoney;
+        res.moneyChinese = NumberToChinese(res.amount);
+        res.supplyAddress = {
+          countryName: supplyData.countryName,
+          provinceName: supplyData.provinceName,
+          cityName: supplyData.cityName,
+          areaDetail: supplyData.areaDetail,
+        };
+        if (res.approvedDate) {
+          res.approvedDate = res.approvedDate.slice(0, 10);
+        }
+        pdfData.value = res;
+      });
+  });
+};
+
+if (props.rowData && props.rowData.id) {
+  handlePrintPdf(props.rowData);
+}
+
+watch(
+  () => props.rowData.id,
+  (val) => {
+    if (props.rowData && props.rowData.id) {
+      handlePrintPdf(props.rowData);
+    }
+  }
+);
+</script>
+
+<style lang="scss" scoped>
+#pdfDom {
+  font-size: 12px;
+  color: #000000;
+  padding: 60px 30px;
+  .title {
+    font-size: 16px;
+    font-weight: 700;
+    margin-top: 10px;
+    margin-bottom: 20px;
+    text-align: center;
+  }
+  .table {
+    // width: calc(100% + 2px) !important;
+    border-collapse: collapse;
+    border-spacing: 0;
+    // margin-left: -1px;
+    // margin-right: -1px;
+
+    td {
+      text-align: center;
+      padding: 8px 0px;
+    }
+    // tr td:last-child {
+    //   border-right: 0 !important;
+    // }
+  }
+  .flex-top-bottom {
+    display: flex;
+    justify-content: space-between;
+    margin: 5px 0px;
+  }
+}
+</style>

+ 3 - 4
src/components/byForm/index.vue

@@ -308,7 +308,6 @@ const handleSuccess = (res, file, files) => {
   emit("update:modelValue", formData.value);
 };
 
-
 const handleRemove = (file) => {
   const index = fileListCopy.value.findIndex(
     (x) => x.uid === file.uid || x.id === file.id
@@ -336,10 +335,10 @@ const formData = computed(() => {
 });
 const formDataReset = ref({ ...proxy.modelValue });
 const commonsEmit = (prop, item) => {
-  if(item.type == 'input' && item.itemType == 'number'){
-    console.log(formData.value)
+  if (item.type == "input" && item.itemType == "number") {
+    console.log(formData.value);
   }
-    
+
   if (item.fn) {
     item.fn(prop);
   }

+ 243 - 0
src/components/contractCom/contractDetails.vue

@@ -0,0 +1,243 @@
+<template>
+  <div>
+    <el-tabs
+      v-model="activeName"
+      class="demo-tabs"
+      @tab-click="handleClick"
+      @tab-change="handleChange"
+      stretch
+    >
+      <el-tab-pane label="销售合同" name="first"></el-tab-pane>
+      <el-tab-pane label="采购合同" name="second"></el-tab-pane>
+      <el-tab-pane label="交易明细" name="third"></el-tab-pane>
+    </el-tabs>
+    <div class="content-box" v-show="activeName !== 'third'">
+      <div class="left">
+        <div
+          v-for="i in leftList"
+          :key="i.id"
+          class="left-item"
+          :style="{ color: currentItem.id === i.id ? '#409eff' : '' }"
+          @click="handleItemClick(i)"
+        >
+          <div v-show="activeName === 'first'">v {{ i.version }}</div>
+          <div v-show="activeName === 'second'">
+            {{ i.code }}
+          </div>
+        </div>
+      </div>
+      <div class="right">
+        <div v-if="leftList && leftList.length > 0">
+          <div style="text-align: right" v-show="activeName === 'first'">
+            <el-button type="primary" @click="pushProcessApproval(currentItem)"
+              >查看详情</el-button
+            >
+          </div>
+          <div v-show="activeName === 'first'">
+            <ContractPDF :rowData="rowData"></ContractPDF>
+          </div>
+          <div v-show="activeName === 'second'">
+            <PurchasePDF :rowData="rowDataOne"></PurchasePDF>
+          </div>
+        </div>
+        <div v-else style="padding-left: 300px">暂无数据</div>
+      </div>
+    </div>
+    <div v-show="activeName === 'third'">
+      <byTable
+        :hidePagination="true"
+        :hideSearch="true"
+        :source="tableData"
+        :config="config"
+        highlight-current-row
+        :action-list="[]"
+      >
+        <template #amount="{ item }">
+          <div>{{ item.currency }} {{ moneyFormat(item.amount, 2) }}</div>
+        </template>
+        <template #accountManagementName="{ item }">
+          <div>
+            {{ item.accountManagementName }} ({{
+              item.accountManagementOpening
+            }})
+          </div>
+        </template>
+      </byTable>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import PurchasePDF from "@/components/PDF/purchasePDF.vue";
+import ContractPDF from "@/components/PDF/contractPDF.vue";
+import byTable from "@/components/byTable/index";
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  contractId: String,
+});
+const activeName = ref("first");
+const currentItem = ref({});
+const rowData = ref({});
+const rowDataOne = ref({});
+const leftList = ref([]);
+const contractDataList = ref([]);
+const purchaseDataList = ref([]);
+const tableData = ref([]);
+const transactionType = ref([
+  {
+    label: "请款",
+    value: "1",
+  },
+  {
+    label: "采购付款",
+    value: "20",
+  },
+  {
+    label: "到账认领",
+    value: "30",
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "交易时间",
+        prop: "createTime",
+        width: 155,
+      },
+    },
+    {
+      attrs: {
+        label: "交易类型",
+        prop: "type",
+        width: 80,
+      },
+      render(type) {
+        return proxy.dictValueLabel(type, transactionType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "交易金额",
+        prop: "amount",
+        slot: "amount",
+        width: 130,
+      },
+    },
+    {
+      attrs: {
+        label: "摘要",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "资金账户",
+        prop: "accountManagementName",
+        slot: "accountManagementName",
+      },
+    },
+    {
+      attrs: {
+        label: "对方账户",
+        prop: "name",
+        width: 120,
+      },
+    },
+  ];
+});
+const handleClick = () => {};
+
+const handleItemClick = (item) => {
+  currentItem.value = item;
+  if (activeName.value === "first") {
+    rowData.value = {
+      id: item.id,
+    };
+  } else if (activeName.value === "second") {
+    rowDataOne.value = {
+      id: item.id,
+    };
+  }
+};
+
+const pushProcessApproval = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "contract_flow",
+      id: row.flowId,
+      processType: 20,
+      random: proxy.random(),
+      flowName: "销售合同详情",
+    },
+  });
+  return;
+};
+const handleChange = (val) => {
+  if (val === "first") {
+    leftList.value = contractDataList.value;
+  }
+  if (val === "second") {
+    leftList.value = purchaseDataList.value;
+  }
+  if (leftList.value && leftList.value.length > 0) {
+    handleItemClick(leftList.value[0]);
+  }
+};
+const getDetailsData = () => {
+  proxy
+    .post("/contract/getVersionList", { id: props.contractId })
+    .then((res) => {
+      contractDataList.value = res;
+      leftList.value = contractDataList.value;
+      if (contractDataList.value && contractDataList.value.length > 0) {
+        handleItemClick(contractDataList.value[0]);
+      }
+    });
+  proxy
+    .post("/contract/getPurchaseListByContractId", { id: props.contractId })
+    .then((res) => {
+      purchaseDataList.value = res;
+    });
+
+  proxy
+    .post("/contract/getAccountRunningWaterByContractId", {
+      id: props.contractId,
+    })
+    .then((res) => {
+      tableData.value = res;
+    });
+};
+getDetailsData();
+</script>
+
+<style lang="scss" scoped>
+.content-box {
+  display: flex;
+  .left {
+    width: 100px;
+    // background: #ccc;
+    .left-item {
+      height: 36px;
+      line-height: 36px;
+      text-align: center;
+      cursor: pointer;
+    }
+  }
+  .right {
+    width: calc(100% - 100px);
+    padding-left: 10px;
+  }
+}
+.baseRow {
+  min-height: 24px;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+}
+.contentRow {
+  border-right: 1px solid black;
+  line-height: 24px;
+  padding-left: 4px;
+}
+</style>

+ 8 - 9
src/components/headerBar/header-bar.vue

@@ -32,20 +32,17 @@
           <div class="header-bar-hover" @click.stop>
             <div class="header-bar-hover-content">
               <div class="left-banner">
-                <div class="first-order" @click="leftBanerType = 2">
-                  <el-icon size="16" color="#0084FF">
-                    <edit />
-                  </el-icon>
+                <!-- :style="leftBanerType == 2 ? 'color:#0084ff' : ''" -->
+                <div class="first-order" @click="leftBanerType = 2" >
+                  <i class="iconfont icon-iconm_changycd" style="position: relative;top:-1px;"></i>
                   {{$t('header.commonFunctions')}}
                 </div>
                 <div class="first-order">
-                  <el-icon size="16" color="#0084FF">
-                    <edit />
-                  </el-icon>
+                  <i class="iconfont icon-iconm_gongncd" style="position: relative;top:-1px;"></i>
                   {{$t('header.functionMenu')}}
                 </div>
                 <ul>
-                  <li @click="openLeftBaner(i, index)" v-for="(i, index) in sidebarRoutersCopy" :key="i.name" v-show="i.type == 1 && i.status == '0'">
+                  <li :class="menuName == i.menuName ? 'active' : ''" @click="openLeftBaner(i, index)" v-for="(i, index) in sidebarRoutersCopy" :key="i.name" v-show="i.type == 1 && i.status == '0'">
                     {{ i.menuName }}
                   </li>
                 </ul>
@@ -57,7 +54,7 @@
 								</div> -->
               </div>
               <div class="menu-warp" v-show="leftBanerType == 1">
-                <div class="first-order-title">{{ activeLeftData.menuName }}</div>
+                <div class="first-order-title">{{ menuName }}</div>
                 <!-- <ul class="second-level" v-for="i in activeLeftData.children" :key="i.menuId">
 									<li class="menu-title">
 											
@@ -187,8 +184,10 @@ const activeLeftData = ref({});
 const openLeftBaner = (i, index) => {
   leftBanerType.value = 1;
   activeLeftData.value = i;
+  menuName.value = i.menuName;
   routerInit(i);
 };
+let menuName = ref("");
 const logoUrl = ref();
 const getLogo = () => {
   proxy.post("/tenantInfo/getLogo", {}).then((res) => {

+ 4 - 0
src/components/headerBar/header.scss

@@ -51,6 +51,10 @@
 						font-size: 12px;
 						cursor: pointer;
 					}
+					li.active{
+						color: #0084FF;
+						background-color: #D9EDFF;
+					}
 				}
 				.first-order {
 					height: 50px;

+ 20 - 20
src/components/notice/index.vue

@@ -4,6 +4,7 @@
 			title="系统公告"
 			v-model="value"
 			width="460px"
+			:align-center="true"
 			:before-close="handleClose"
 		>
 			<div class="title">
@@ -18,7 +19,7 @@
 			</div>
 			<template #footer>
 				<span class="dialog-footer">
-					<el-button
+					<!-- <el-button
 						size="small"
 						@click="index--"
 						:disabled="data.length < 2 || index == 0"
@@ -29,7 +30,7 @@
 						@click="index++"
 						:disabled="data.length == index + 1"
 						>下一条</el-button
-					>
+					> -->
 					<!-- <el-button
 						type="primary"
 						size="small"
@@ -81,7 +82,7 @@ import { ElMessageBox, ElNotification } from 'element-plus'
 import {
   getToken
 } from '@/utils/auth'
-
+const { proxy } = getCurrentInstance();
 defineProps({
   modelValue: {
     type: Object,
@@ -115,14 +116,9 @@ let noticeData = ref([
 	// 	address: '上海市普陀区金沙江路 1516 弄',
 	// },
 ])
-const index = ref(1)
-const data = ref([
-	{ title: '11', content: '11' },
-	{ title: '22', content: '22' },
-	{ title: '33', content: '33' },
-	{ title: '44', content: '44' },
-])
-const value = ref(false)
+let index = ref(0)
+let data = ref([])
+let value = ref(false)
 const moreFn = () => {
 	noticeTableModal.value = true
 }
@@ -130,10 +126,16 @@ const moreFn = () => {
 const confirm = () => {
 	value.value = false
 }
+// proxy.post('sendMeg/page',{
+// 	pageNum:1,
+// 	pageSize:30,
+// }).then(res=>{
+// 	data.value = res.rows
+// })
 
 const socketInit = () => {
 	window.ws = new WebSocket(
-		'ws://36.134.91.96:9898/test-api/webStock/' +
+		'ws://'+ import.meta.env.VITE_APP_IP +':9898/test-api/webStock/' +
 			getToken()
 		// 'ws://192.168.1.97:8300/webStock/' + window.localStorage.getItem('token')
 	)
@@ -144,14 +146,12 @@ const socketInit = () => {
 	}
 	window.ws.onmessage = function (e) {
 		//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
-
-		var msg = JSON.parse(e.data)
-		console.log(msg)
-		//系统消息
-		if (msg.data.type == 1) {
-			data.value = msg.data
-			value.value = true
-		}
+		//在data.value前面插入
+		console.log(JSON.parse(e.data).data)
+		data.value.unshift({title:"最新公告",content:JSON.parse(e.data).data})
+		index.value = 0
+		value.value = true
+		
 		
 	}
 	window.ws.onclose = function (e) {

+ 11 - 1
src/components/process/Contract.vue

@@ -518,6 +518,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -918,7 +921,14 @@ const querySearchPerson = (queryString, callback) => {
   callback(results);
 };
 const handlePerson = (item) => {
-  formData.data.buyContactNumber = item.phone;
+  if (item.contactJson) {
+    let contactJson = JSON.parse(item.contactJson);
+    if (contactJson && contactJson.length > 0) {
+      formData.data.buyContactNumber = contactJson[0].contactNo;
+    } else {
+      formData.data.buyContactNumber = "";
+    }
+  }
 };
 const pushGoods = (goods) => {
   if (goods && goods.length > 0) {

+ 1381 - 0
src/components/process/ContractAlteration.vue

@@ -0,0 +1,1381 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+      <template #seller>
+        <div style="width: 100%">
+          <el-form-item prop="sellCorporationId">
+            <el-select v-model="formData.data.sellCorporationId" style="width: 100%" disabled>
+              <el-option v-for="item in corporationList" :key="item.value" :label="item.label" :value="item.value" />
+            </el-select>
+          </el-form-item>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="8">
+              <el-form-item label="地址" prop="sellCountryName">
+                <el-input v-model="formData.data.sellCountryName" placeholder="请输入国家" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label=" " prop="sellProvinceName">
+                <el-input v-model="formData.data.sellProvinceName" placeholder="请输入省/州" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label=" " prop="sellCityName">
+                <el-input v-model="formData.data.sellCityName" placeholder="请输入城市" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-form-item prop="sellAddress">
+                <el-input v-model="formData.data.sellAddress" type="textarea"> </el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="8">
+              <el-form-item label="联系人" prop="sellContactName">
+                <el-input v-model="formData.data.sellContactName" placeholder="请输入联系人" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="16">
+              <el-form-item label=" " prop="sellContactNumber">
+                <el-input v-model="formData.data.sellContactNumber" placeholder="请输入联系人电话" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+      </template>
+      <template #buyer>
+        <div style="width: 100%">
+          <div style="width: 100%">
+            <el-form-item prop="buyCorporationId">
+              <el-select v-model="formData.data.buyCorporationId" filterable style="width: 100%" @change="changeCustomer">
+                <el-option v-for="item in customerList" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+            <el-row style="margin-top: 20px; width: 100%">
+              <el-col :span="6">
+                <el-form-item label="地址" prop="countryId">
+                  <el-select v-model="formData.data.countryId" placeholder="国家" filterable @change="(val) => getCityData(val, '20', true)">
+                    <el-option v-for="item in countryData" :label="formData.data.contractType == '2' ? item.chineseName : item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label=" " prop="provinceName">
+                  <selectCity
+                    placeholder="省/洲"
+                    @change="(val) => getCityData(val, '30', true)"
+                    addressId="provinceId"
+                    addressName="provinceName"
+                    v-model="formData.data"
+                    :data="provinceData">
+                  </selectCity>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label=" " prop="cityName">
+                  <selectCity placeholder="城市" addressId="cityId" addressName="cityName" v-model="formData.data" :data="cityData"> </selectCity>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label=" " prop="buyPostalCode">
+                  <el-input v-model="formData.data.buyPostalCode" placeholder="请输入邮编" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row style="margin-top: 20px; width: 100%">
+              <el-col :span="24">
+                <el-form-item prop="buyAddress">
+                  <el-input v-model="formData.data.buyAddress" type="textarea"> </el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row style="margin-top: 20px; width: 100%">
+              <el-col :span="8">
+                <el-form-item label="联系人" prop="buyContactName">
+                  <el-autocomplete
+                    v-model="formData.data.buyContactName"
+                    :fetch-suggestions="querySearchPerson"
+                    clearable
+                    class="inline-input w-50"
+                    placeholder="请输入联系人"
+                    @select="handlePerson">
+                  </el-autocomplete>
+                </el-form-item>
+              </el-col>
+              <el-col :span="16">
+                <el-form-item label=" " prop="buyContactNumber">
+                  <el-input v-model="formData.data.buyContactNumber" placeholder="请输入联系人电话" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+      </template>
+      <template #commodity>
+        <div style="width: 100%">
+          <el-button @click="openProduct = true">添加商品</el-button>
+          <el-table :data="formData.data.contractProductList" style="width: 100%; margin-top: 16px">
+            <el-table-column label="商品图片" width="80">
+              <template #default="{ row }">
+                <div v-if="row.fileUrl">
+                  <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
+                </div>
+                <div v-else></div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="productCode" label="商品编码" width="120" />
+            <el-table-column prop="productCnName" label="商品中文名" width="160" />
+            <el-table-column label="商品英文名" min-width="200">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProductList.' + $index + '.productName'" :rules="rules.productName" :inline-message="true">
+                    <el-input v-model="row.productName" placeholder="请输入商品英文名" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="规格型号" width="180">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProductList.' + $index + '.productModel'" :inline-message="true">
+                    <el-input v-model="row.productModel" placeholder="请输入规格型号" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="单位" width="100" :formatter="(row) => dictValueLabel(row.productUnit, productUnit)" />
+            <el-table-column label="数量" width="150">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.quantity"
+                      placeholder="请输入数量"
+                      style="width: 100%"
+                      :precision="4"
+                      :controls="false"
+                      :min="0"
+                      @change="calculationAmount()" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="单价" width="160">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProductList.' + $index + '.price'" :rules="rules.price" :inline-message="true">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.price"
+                      placeholder="请输入单价"
+                      style="width: 100%"
+                      :precision="2"
+                      :controls="false"
+                      :min="0"
+                      @change="calculationAmount()" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="amount" label="金额" width="100" />
+            <el-table-column align="center" label="操作" width="120" fixed="right">
+              <template #default="{ row, $index }">
+                <el-button type="primary" link @click="handleHandover(row, $index)">交接单</el-button>
+                <el-button type="primary" link @click="handleRemove($index, row)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+      <template #otherCharge>
+        <div style="width: 100%">
+          <el-button type="primary" @click="clickAdd()">添加行</el-button>
+          <el-table :data="formData.data.contractProjectList" style="width: 100%; margin-top: 16px">
+            <el-table-column label="收费项目" width="220">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProjectList.' + $index + '.payName'" :rules="rules.payName" :inline-message="true">
+                    <el-autocomplete v-model="row.payName" :fetch-suggestions="querySearch" clearable class="inline-input w-50" placeholder="请输入收费项目" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="金额" width="180">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProjectList.' + $index + '.amount'" :rules="rules.amount" :inline-message="true">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.amount"
+                      placeholder="请输入金额"
+                      style="width: 100%"
+                      :precision="2"
+                      :controls="false"
+                      :min="0"
+                      @change="totalAmount()" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="备注">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractProjectList.' + $index + '.remark'">
+                    <el-input v-model="row.remark" placeholder="请输入备注" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="80" fixed="right">
+              <template #default="{ row, $index }">
+                <el-button type="primary" link @click="handleDelete($index)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+      <template #offerMoney>
+        <div style="width: 100%">
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="4">
+              <el-form-item label="币种" prop="currency">
+                <el-select v-model="formData.data.currency" placeholder="请选择币种" style="width: 100%">
+                  <el-option v-for="item in accountCurrency" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="合同总金额" prop="amount">
+                <el-input v-model="formData.data.amount" placeholder="合同总金额" disabled />
+              </el-form-item>
+            </el-col>
+            <!-- <el-col :span="4">
+                <el-form-item label="报价有效期 (天)" prop="effective">
+                  <el-input-number onmousewheel="return false;"
+                    v-model="formData.data.effective"
+                    placeholder="请输入有效期"
+                    style="width: 100%"
+                    :precision="0"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </el-col> -->
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="7">
+              <el-form-item label="付款方式" prop="paymentMethod">
+                <el-select v-model="formData.data.paymentMethod" placeholder="请选择付款方式" style="width: 100%">
+                  <el-option v-for="item in fundsPaymentMethod" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="7">
+              <el-form-item label="预付比例 (%)" prop="advanceRatio">
+                <el-input-number
+                  onmousewheel="return false;"
+                  v-model="formData.data.advanceRatio"
+                  placeholder="请输入预付比例"
+                  style="width: 100%"
+                  :precision="2"
+                  :controls="false"
+                  :min="0"
+                  :max="100" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="7">
+              <el-form-item label="收款账号" prop="shroffAccountId">
+                <el-select v-model="formData.data.shroffAccountId" placeholder="请选择收款账号" style="width: 100%" @change="changeShroffAccount">
+                  <el-option v-for="item in accountList" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="3">
+              <el-form-item label="  ">
+                <el-button type="primary" @click="changeActiveName" text>
+                  <span v-if="activeName == '1'">收起</span>
+                  <span v-else>展开</span>
+                </el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <div style="width: 100%; margin-top: 34px">
+            <el-collapse v-model="activeName" class="hideCollapse" accordion>
+              <el-collapse-item title="" name="1">
+                <el-row style="width: 100%">
+                  <el-col :span="9">
+                    <el-form-item label="Beneficiary Name" prop="beneficiaryName">
+                      <el-input v-model="formData.data.beneficiaryName" placeholder="请输入Beneficiary Name" />
+                    </el-form-item>
+                    <div style="height: 20px"></div>
+                    <el-form-item label="Beneficiary Bank" prop="beneficiaryBank">
+                      <el-input v-model="formData.data.beneficiaryBank" placeholder="请输入Beneficiary Bank" />
+                    </el-form-item>
+                    <div style="height: 20px"></div>
+                    <el-form-item label="Beneficiary Bank Address" prop="beneficiaryBankAddress">
+                      <el-input v-model="formData.data.beneficiaryBankAddress" placeholder="请输入Beneficiary Bank Address" />
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="9">
+                    <el-form-item label="Beneficiary Account Number" prop="beneficiaryAccountNumber">
+                      <el-input v-model="formData.data.beneficiaryAccountNumber" placeholder="请输入Beneficiary Account Number" />
+                    </el-form-item>
+                    <div style="height: 20px"></div>
+                    <el-form-item label="Swift Code" prop="swiftCode">
+                      <el-input v-model="formData.data.swiftCode" placeholder="请输入Swift Code" />
+                    </el-form-item>
+                    <div style="height: 20px"></div>
+                    <el-form-item label="Beneficiary Address" prop="beneficiaryAddress">
+                      <el-input v-model="formData.data.beneficiaryAddress" placeholder="请输入Beneficiary Address" />
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-collapse-item>
+            </el-collapse>
+          </div>
+        </div>
+      </template>
+      <template #delivery>
+        <div style="width: 100%">
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="7">
+              <el-form-item label="贸易方式" prop="tradeMethods">
+                <el-select v-model="formData.data.tradeMethods" placeholder="请选择贸易方式" style="width: 100%">
+                  <el-option v-for="item in tradeMethods" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="7">
+              <el-form-item label="运输方式" prop="transportMethod">
+                <el-select v-model="formData.data.transportMethod" placeholder="请选择运输方式" style="width: 100%">
+                  <el-option v-for="item in shippingMethod" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="7">
+              <el-form-item label="运输说明" prop="transportRemark">
+                <el-input v-model="formData.data.transportRemark" placeholder="请输入运输说明" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="14">
+              <el-form-item label="付款条件" prop="remark">
+                <el-input v-model="formData.data.remark" :rows="2" type="textarea" placeholder="请输入付款条件" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="7">
+              <el-form-item label="交货期限 (天)" prop="deliveryTime">
+                <!-- <el-date-picker v-model="formData.data.deliveryTime" type="date" placeholder="请选择交货期限" value-format="YYYY-MM-DD" /> -->
+                <el-input-number
+                  onmousewheel="return false;"
+                  v-model="formData.data.deliveryTime"
+                  placeholder="请输入交货期限"
+                  style="width: 100%"
+                  :precision="0"
+                  :controls="false"
+                  :min="0" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="7">
+              <el-form-item label="质保期 (天)" prop="warranty">
+                <el-input-number
+                  onmousewheel="return false;"
+                  v-model="formData.data.warranty"
+                  placeholder="请输入质保期"
+                  style="width: 100%"
+                  :precision="0"
+                  :controls="false"
+                  :min="0" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+      </template>
+      <template #shipment>
+        <div style="width: 100%">
+          <el-table :data="formData.data.contractShipmentList" style="width: 100%; margin-top: 16px">
+            <el-table-column prop="productCode" label="商品编码" width="120" />
+            <el-table-column prop="productCnName" label="商品名称" />
+            <el-table-column label="出货日期" width="220">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractShipmentList.' + $index + '.shipmentTime'" :rules="rules.shipmentTime" :inline-message="true">
+                    <el-date-picker v-model="row.shipmentTime" type="date" placeholder="请选择出货日期" value-format="YYYY-MM-DD" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="数量" width="160">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'contractShipmentList.' + $index + '.quantity'" :inline-message="true">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.quantity"
+                      placeholder="请输入数量"
+                      style="width: 100%"
+                      :precision="4"
+                      :controls="false"
+                      :min="0"
+                      @change="calculationAmount()" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="120" fixed="right">
+              <template #default="{ row, $index }">
+                <el-button type="primary" link @click="clickSplit(row)">拆分</el-button>
+                <el-button type="primary" link @click="clickDelete($index)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+    </byForm>
+
+    <el-dialog v-if="openProduct" v-model="openProduct" title="选择商品" width="70%" append-to-body>
+      <SelectGoods :selectList="acquireSelectList()" @cancel="openProduct = false" @pushGoods="pushGoods"></SelectGoods>
+    </el-dialog>
+
+    <el-dialog title="交接单" v-if="openHandover" v-model="openHandover" width="800">
+      <byForm :formConfig="formHandoverConfig" :formOption="formOption" v-model="productRow.data">
+        <template #remark>
+          <div style="width: 100%">
+            <Editor :value="productRow.data.remark" @updateValue="updateContent" />
+          </div>
+        </template>
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile">
+              <el-button>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openHandover = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitHandoverForm()" size="large">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import SelectGoods from "@/components/product/SelectGoods";
+import { ElMessage } from "element-plus";
+import Editor from "@/components/Editor/index.vue";
+import selectCity from "@/components/selectCity/index.vue";
+import { useRoute } from "vue-router";
+
+const route = useRoute();
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+const { proxy } = getCurrentInstance();
+const contractType = ref([]);
+const accountCurrency = ref([]);
+const fundsPaymentMethod = ref([]);
+const tradeMethods = ref([]);
+const shippingMethod = ref([]);
+const templateList = ref([]);
+const corporationList = ref([]);
+const customerList = ref([]);
+const countryData = ref([]);
+const provinceData = ref([]);
+const cityData = ref([]);
+const customerUserList = ref([]);
+const accountList = ref([]);
+const productUnit = ref([]);
+const openProduct = ref(false);
+const activeName = ref("");
+const formData = reactive({
+  data: {
+    contractType: "1",
+    amount: undefined,
+    contractProductList: [],
+    contractProjectList: [],
+    contractShipmentList: [],
+  },
+});
+const submit = ref(null);
+const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
+  if (props.queryData.recordList && props.queryData.recordList.length > 0) {
+    let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
+    if (data && data.length > 0) {
+      return true;
+    }
+  }
+  return false;
+};
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+  disabled: false,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "合同模板",
+      label: "",
+    },
+    {
+      type: "select",
+      label: "合同类型",
+      prop: "contractType",
+      data: contractType.value,
+      itemWidth: 25,
+    },
+    {
+      type: "select",
+      label: "选择合同模板",
+      prop: "contractTemplateId",
+      data: templateList.value,
+      fn: (val) => {
+        changeTemplate(val);
+      },
+      itemWidth: 26,
+    },
+    {
+      type: "slot",
+      slotName: "seller",
+      label: "卖方信息",
+      itemWidth: 50,
+    },
+    {
+      type: "slot",
+      slotName: "buyer",
+      label: "买方信息",
+      itemWidth: 50,
+    },
+    {
+      type: "slot",
+      slotName: "commodity",
+      label: "商品信息",
+    },
+    {
+      type: "slot",
+      slotName: "otherCharge",
+      label: "其他收费项目",
+    },
+    {
+      type: "slot",
+      slotName: "offerMoney",
+      label: "收款信息",
+    },
+    {
+      type: "slot",
+      slotName: "delivery",
+      label: "交付信息",
+    },
+    {
+      type: "slot",
+      slotName: "shipment",
+      label: "出货计划",
+    },
+  ];
+});
+const rules = ref({
+  contractType: [{ required: true, message: "请选择合同类型", trigger: "change" }],
+  contractTemplateId: [{ required: true, message: "请选择合同模板", trigger: "change" }],
+  buyCorporationId: [{ required: true, message: "请选择公司", trigger: "change" }],
+  countryId: [{ required: true, message: "请选择国家", trigger: "change" }],
+  sellAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  buyAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  buyContactName: [{ required: true, message: "请输入联系人", trigger: ["change", "blur"] }],
+  buyContactNumber: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
+  productName: [{ required: true, message: "请输入商品英文名", trigger: "blur" }],
+  productModel: [{ required: true, message: "请输入规格型号", trigger: "blur" }],
+  quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
+  price: [{ required: true, message: "请输入单价", trigger: "blur" }],
+  amount: [{ required: true, message: "请输入金额", trigger: "blur" }],
+  payName: [{ required: true, message: "请输入收费项目", trigger: ["change", "blur"] }],
+  currency: [{ required: true, message: "请选择币种", trigger: "change" }],
+  effective: [{ required: true, message: "请输入报价有效期", trigger: "blur" }],
+  deliveryTime: [{ required: true, message: "请选择交货期限", trigger: "blur" }],
+  paymentMethod: [{ required: true, message: "请选择付款方式", trigger: "change" }],
+  advanceRatio: [{ required: true, message: "请输入预付比例", trigger: "blur" }],
+  shroffAccountId: [{ required: true, message: "请选择收款账号", trigger: "change" }],
+  tradeMethods: [{ required: true, message: "请选择贸易方式", trigger: "change" }],
+  transportMethod: [{ required: true, message: "请选择运输方式", trigger: "change" }],
+  transportRemark: [{ required: true, message: "请输入运输说明", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入付款条件", trigger: "blur" }],
+});
+const getDict = () => {
+  proxy.getDictOne(["account_currency", "funds_payment_method", "trade_mode", "shipping_method", "contract_type", "unit"]).then((res) => {
+    accountCurrency.value = res["account_currency"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    fundsPaymentMethod.value = res["funds_payment_method"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    tradeMethods.value = res["trade_mode"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    shippingMethod.value = res["shipping_method"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    contractType.value = res["contract_type"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    productUnit.value = res["unit"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+  proxy.post("/contractTemplate/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    templateList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.templateName,
+        value: item.id,
+      };
+    });
+  });
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    corporationList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.name,
+        value: item.id,
+      };
+    });
+  });
+  proxy.post("/customer/privateSeaPage", { pageNum: 1, pageSize: 999 }).then((res) => {
+    customerList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.name,
+        value: item.id,
+      };
+    });
+  });
+  proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    accountList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.alias,
+        value: item.id,
+      };
+    });
+  });
+};
+getDict();
+const changeTemplate = (val) => {
+  formData.data.sellCorporationId = "";
+  formData.data.sellContactName = "";
+  formData.data.sellContactNumber = "";
+  formData.data.sellCountryName = "";
+  formData.data.sellProvinceName = "";
+  formData.data.sellCityName = "";
+  formData.data.sellAddress = "";
+  if (val) {
+    proxy.post("/contractTemplate/detail", { id: val }).then((res) => {
+      formData.data.sellCorporationId = res.corporationId;
+      if (res.corporationId) {
+        proxy.post("/corporation/detail", { id: res.corporationId }).then((detailCorporation) => {
+          if (detailCorporation.countryEnStr) {
+            formData.data.sellCountryName = detailCorporation.countryEnStr;
+          }
+          if (detailCorporation.provinceEnStr) {
+            formData.data.sellProvinceName = detailCorporation.provinceEnStr;
+          }
+          if (detailCorporation.cityEnStr) {
+            formData.data.sellCityName = detailCorporation.cityEnStr;
+          }
+          if (detailCorporation.addressEn) {
+            formData.data.sellAddress = detailCorporation.addressEn;
+          }
+        });
+      }
+      formData.data.sellContactName = res.contactName;
+      formData.data.sellContactNumber = res.contactNumber;
+    });
+  }
+};
+const getCityData = (id, type, isChange) => {
+  proxy.post("/customizeArea/list", { parentId: id }).then((res) => {
+    if (type === "20") {
+      provinceData.value = res;
+      if (isChange) {
+        formData.data.provinceId = "";
+        formData.data.provinceName = "";
+        formData.data.cityId = "";
+        formData.data.cityName = "";
+      }
+    } else if (type === "30") {
+      cityData.value = res;
+      if (isChange) {
+        formData.data.cityId = "";
+        formData.data.cityName = "";
+      }
+    } else {
+      countryData.value = res;
+    }
+  });
+};
+getCityData("0");
+const changeCustomer = (val) => {
+  formData.data.buyContactName = "";
+  formData.data.buyContactNumber = "";
+  if (val) {
+    proxy.post("/customer/detail", { id: val }).then(
+      (res) => {
+        if (res.customerUserList && res.customerUserList.length > 0) {
+          formData.data.buyContactName = res.customerUserList[0].name;
+          if (res.customerUserList[0].contactJson) {
+            let contactJson = JSON.parse(res.customerUserList[0].contactJson);
+            if (contactJson && contactJson.length > 0) {
+              formData.data.buyContactNumber = contactJson[0].contactNo;
+            }
+          }
+          customerUserList.value = res.customerUserList.map((item) => {
+            return {
+              ...item,
+              value: item.name,
+            };
+          });
+        }
+        formData.data.countryId = res.countryId;
+        formData.data.provinceId = res.provinceId;
+        formData.data.cityId = res.cityId;
+        formData.data.buyPostalCode = res.zipCode;
+        formData.data.buyAddress = res.address;
+        getCityData(formData.data.countryId, "20");
+        if (formData.data.provinceId) {
+          getCityData(formData.data.provinceId, "30");
+        }
+      },
+      (err) => {
+        console.log(err);
+        formData.data.countryId = "";
+        formData.data.provinceId = "";
+        formData.data.cityId = "";
+        formData.data.buyPostalCode = "";
+        formData.data.buyAddress = "";
+      }
+    );
+  } else {
+    formData.data.countryId = "";
+    formData.data.provinceId = "";
+    formData.data.cityId = "";
+    formData.data.buyPostalCode = "";
+    formData.data.buyAddress = "";
+  }
+  getDecisionAids();
+};
+let auxiliaryData = ref([
+  {
+    label: "最近合同",
+    data: [],
+  },
+  {
+    label: "产品价格",
+    data: [],
+  },
+]);
+const emit = defineEmits(["auxiliaryChange"]);
+const getDecisionAids = () => {
+  let data = {
+    buyCorporationId: formData.data.buyCorporationId,
+    productIdList: [],
+  };
+  if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+    data.productIdList = formData.data.contractProductList.map((item) => item.productId);
+  }
+  proxy.post("/contract/decisionAid", data).then((res) => {
+    if (res.lastContractList && res.lastContractList.length > 0) {
+      auxiliaryData.value[0].data = res.lastContractList.map((item) => {
+        return [
+          {
+            label: "合同编号",
+            value: item.code,
+            style: {
+              color: "#0084FF",
+            },
+            id: item.id,
+            num: 1,
+            // fn: () => {},
+          },
+          {
+            label: "下单日期",
+            value: item.createTime,
+            id: item.id,
+            num: 1,
+          },
+          {
+            label: "合同金额",
+            value: item.currency + item.amount,
+            id: item.id,
+            num: 1,
+          },
+        ];
+      });
+    } else {
+      auxiliaryData.value[0].data = [];
+    }
+    if (res.productPriceList && res.productPriceList.length > 0) {
+      auxiliaryData.value[1].data = res.productPriceList.map((item) => {
+        return [
+          {
+            label: "产品名称",
+            value: item.name,
+            id: item.id,
+            num: 1,
+          },
+          {
+            label: "最近价格",
+            value: item.lastPrice,
+            id: item.id,
+            num: 1,
+          },
+          {
+            label: "历史最高",
+            value: item.maxPrice,
+            id: item.id,
+            num: 1,
+          },
+          {
+            label: "历史最低",
+            value: item.minPrice,
+            id: item.id,
+            num: 1,
+          },
+        ];
+      });
+    } else {
+      auxiliaryData.value[1].data = [];
+    }
+    emit("auxiliaryChange", auxiliaryData.value);
+  });
+};
+const createFilter = (queryString) => {
+  return (restaurant) => {
+    return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
+  };
+};
+const querySearchPerson = (queryString, callback) => {
+  const results = queryString ? customerUserList.value.filter(createFilter(queryString)) : customerUserList.value;
+  callback(results);
+};
+const handlePerson = (item) => {
+  formData.data.buyContactNumber = item.phone;
+};
+const pushGoods = (goods) => {
+  if (goods && goods.length > 0) {
+    let afterFiltering = [];
+    if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+      afterFiltering = goods.filter((item) => {
+        let data = formData.data.contractProductList.filter((itemProduct) => itemProduct.productId === item.id);
+        if (data && data.length > 0) {
+          return false;
+        }
+        return true;
+      });
+    } else {
+      afterFiltering = goods;
+    }
+    formData.data.contractProductList = formData.data.contractProductList.concat(
+      afterFiltering.map((item) => {
+        let fileUrl = "";
+        if (item.fileList && item.fileList.length > 0) {
+          fileUrl = item.fileList[0].fileUrl;
+        }
+        let name = item.name;
+        if (item.standardJson) {
+          let standardJson = JSON.parse(item.standardJson);
+          if (standardJson && standardJson.englishName) {
+            name = standardJson.englishName;
+          }
+        }
+        return {
+          fileUrl: fileUrl,
+          productCode: item.code,
+          productId: item.id,
+          productCnName: item.name,
+          productName: name,
+          productModel: item.spec,
+          productUnit: item.unit,
+          quantity: undefined,
+          price: undefined,
+          amount: "",
+          remark: "",
+          fileList: [],
+        };
+      })
+    );
+    formData.data.contractShipmentList = formData.data.contractShipmentList.concat(
+      afterFiltering.map((item) => {
+        return {
+          productCode: item.code,
+          productId: item.id,
+          productCnName: item.name,
+          shipmentTime: "",
+          quantity: undefined,
+        };
+      })
+    );
+    ElMessage({
+      message: "添加成功!",
+      type: "success",
+    });
+    openProduct.value = false;
+    getDecisionAids();
+  } else {
+    ElMessage("请选择至少一件商品");
+  }
+};
+const onPicture = (path) => {
+  window.open(path, "_blank");
+};
+const productRow = reactive({
+  data: {
+    productName: "",
+    productModel: "",
+    remark: "",
+  },
+});
+const productIndex = ref(0);
+const openHandover = ref(false);
+const fileList = ref([]);
+const uploadData = ref({});
+const formHandoverConfig = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "产品信息",
+      label: "",
+    },
+    {
+      type: "input",
+      prop: "productName",
+      label: "产品名称",
+      itemType: "text",
+      disabled: true,
+    },
+    {
+      type: "input",
+      prop: "productModel",
+      label: "规格型号",
+      itemType: "text",
+      disabled: true,
+    },
+    {
+      type: "slot",
+      slotName: "remark",
+      label: "交接单",
+    },
+    {
+      type: "slot",
+      prop: "file",
+      slotName: "file",
+      label: "上传附件",
+    },
+  ];
+});
+const handleHandover = (row, index) => {
+  productRow.data = {
+    productName: row.productName,
+    productModel: row.productModel,
+    remark: row.remark,
+  };
+  if (row.fileList && row.fileList.length > 0) {
+    fileList.value = row.fileList.map((item) => {
+      return {
+        raw: item,
+        name: item.fileName,
+        url: item.fileUrl,
+      };
+    });
+  } else {
+    fileList.value = [];
+  }
+  productIndex.value = index;
+  openHandover.value = true;
+};
+const updateContent = (val) => {
+  productRow.data.remark = val;
+};
+const changeActiveName = () => {
+  if (activeName.value) {
+    activeName.value = "";
+  } else {
+    activeName.value = "1";
+  }
+};
+const uploadFile = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  file.id = res.id;
+  file.fileName = res.fileName;
+  file.fileUrl = res.fileUrl;
+  file.uploadState = true;
+  return true;
+};
+const handleSuccess = (any, UploadFile) => {
+  UploadFile.raw.uploadState = false;
+};
+const onPreviewFile = (file) => {
+  window.open(file.raw.fileUrl, "_blank");
+};
+const submitHandoverForm = () => {
+  if (fileList.value && fileList.value.length > 0) {
+    for (let i = 0; i < fileList.value.length; i++) {
+      if (fileList.value[i].raw.uploadState) {
+        ElMessage("文件上传中,请稍后提交");
+        return;
+      }
+    }
+    formData.data.contractProductList[productIndex.value].fileList = fileList.value.map((item) => {
+      return {
+        id: item.raw.id,
+        fileName: item.raw.fileName,
+        fileUrl: item.raw.fileUrl,
+        uploadState: item.raw.uploadState,
+      };
+    });
+  } else {
+    formData.data.contractProductList[productIndex.value].fileList = [];
+  }
+  formData.data.contractProductList[productIndex.value].remark = productRow.data.remark;
+  openHandover.value = false;
+};
+const handleRemove = async (index, row) => {
+  formData.data.contractShipmentList = formData.data.contractShipmentList.filter((item) => item.productId !== row.productId);
+  await formData.data.contractProductList.splice(index, 1);
+  totalAmount();
+  getDecisionAids();
+};
+const calculationAmount = () => {
+  nextTick(() => {
+    if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+      for (let i = 0; i < formData.data.contractProductList.length; i++) {
+        let money = 0;
+        if (formData.data.contractProductList[i].quantity && formData.data.contractProductList[i].price) {
+          money = parseFloat(Number(formData.data.contractProductList[i].quantity) * Number(formData.data.contractProductList[i].price)).toFixed(2);
+        }
+        formData.data.contractProductList[i].amount = money;
+      }
+    }
+    nextTick(() => {
+      totalAmount();
+    });
+  });
+};
+const totalAmount = () => {
+  let money = 0;
+  if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+    for (let i = 0; i < formData.data.contractProductList.length; i++) {
+      if (formData.data.contractProductList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.contractProductList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  if (formData.data.contractProjectList && formData.data.contractProjectList.length > 0) {
+    for (let i = 0; i < formData.data.contractProjectList.length; i++) {
+      if (formData.data.contractProjectList[i].amount) {
+        money = parseFloat(Number(money) + Number(formData.data.contractProjectList[i].amount)).toFixed(2);
+      }
+    }
+  }
+  formData.data.amount = money;
+};
+const clickAdd = () => {
+  if (formData.data.contractProjectList && formData.data.contractProjectList.length > 0) {
+    formData.data.contractProjectList.push({
+      payName: "",
+      amount: undefined,
+      remark: "",
+    });
+  } else {
+    formData.data.contractProjectList = [{ payName: "", amount: undefined, remark: "" }];
+  }
+};
+const handleDelete = async (index) => {
+  await formData.data.contractProjectList.splice(index, 1);
+  totalAmount();
+};
+const querySearch = (queryString, callback) => {
+  proxy.post("/quotationPay/page", { payName: queryString }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      res.rows = res.rows.map((item) => {
+        return {
+          ...item,
+          value: item.payName,
+        };
+      });
+      callback(res.rows);
+    } else {
+      callback([]);
+    }
+  });
+};
+const clickSplit = (item) => {
+  formData.data.contractShipmentList.push({
+    code: item.code,
+    productId: item.productId,
+    productName: item.productName,
+    shipmentTime: "",
+    quantity: undefined,
+  });
+};
+const clickDelete = (index) => {
+  formData.data.contractShipmentList.splice(index, 1);
+};
+
+const handleSubmit = async () => {
+  let status = await submit.value.handleSubmit(() => {});
+  if (status) {
+    if (!(formData.data.contractProductList && formData.data.contractProductList.length > 0)) {
+      ElMessage("请添加至少一件商品");
+      return false;
+    }
+    if (formData.data.contractShipmentList && formData.data.contractShipmentList.length > 0) {
+      for (let i = 0; i < formData.data.contractProductList.length; i++) {
+        let data = formData.data.contractShipmentList.filter((item) => item.productId === formData.data.contractProductList[i].productId);
+        if (data && data.length > 0) {
+          let quantity = 0;
+          for (let j = 0; j < data.length; j++) {
+            quantity = parseFloat(Number(quantity) + Number(data[j].quantity));
+          }
+          if (quantity > formData.data.contractProductList[i].quantity) {
+            ElMessage("出货数量不能大于商品数量");
+            return false;
+          }
+        }
+      }
+    }
+    return true;
+  } else {
+    setTimeout(() => {
+      const errorDiv = document.getElementsByClassName("is-error");
+      errorDiv[0].scrollIntoView();
+    }, 0);
+  }
+  return false;
+};
+const getFormData = () => {
+  return formData.data;
+};
+// 向父组件暴露
+defineExpose({
+  getFormData,
+  handleSubmit,
+});
+const changeShroffAccount = (val) => {
+  if (val) {
+    let data = accountList.value.filter((item) => item.value === val);
+    if (data && data.length > 0) {
+      formData.data.beneficiaryName = data[0].beneficiaryName;
+      formData.data.beneficiaryBank = data[0].beneficiaryBank;
+      formData.data.beneficiaryBankAddress = data[0].beneficiaryBankAddress;
+      formData.data.beneficiaryAccountNumber = data[0].beneficiaryAccountNumber;
+      formData.data.swiftCode = data[0].swiftCode;
+      formData.data.beneficiaryAddress = data[0].beneficiaryAddress;
+    }
+  }
+};
+watch(
+  props.queryData,
+  () => {
+    formOption.disabled = judgeStatus();
+    if (props.queryData && ["10", "20", "30"].includes(route.query.processType)) {
+      for (var text in props.queryData) {
+        formData.data[text] = props.queryData[text];
+      }
+      if (formData.data.countryId) {
+        getCityData(formData.data.countryId, "20");
+      }
+      if (formData.data.provinceId) {
+        getCityData(formData.data.provinceId, "30");
+      }
+      getDecisionAids();
+    }
+  },
+  {
+    deep: true,
+  }
+);
+const acquireSelectList = () => {
+  let data = [];
+  if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+    data = formData.data.contractProductList.map((item) => {
+      return {
+        id: item.productId,
+        name: item.name,
+      };
+    });
+  }
+  return data;
+};
+onMounted(() => {
+  if (props.queryData.priceSheetId) {
+    proxy.post("/saleQuotation/detail", { id: props.queryData.priceSheetId }).then((res) => {
+      res.countryId = res.buyCountryId;
+      res.provinceId = res.buyProvinceId;
+      res.cityId = res.buyCityId;
+      for (var text in res) {
+        formData.data[text] = res[text];
+      }
+      if (formData.data.quotationProductList && formData.data.quotationProductList.length > 0) {
+        formData.data.contractProductList = formData.data.quotationProductList.map((item) => {
+          delete item.id;
+          return {
+            ...item,
+          };
+        });
+        formData.data.contractShipmentList = proxy.deepClone(
+          formData.data.contractProductList.map((item) => {
+            return {
+              ...item,
+              quantity: undefined,
+            };
+          })
+        );
+        for (let i = 0; i < formData.data.contractProductList.length; i++) {
+          proxy.post("/productInfo/detail", { id: formData.data.contractProductList[i].productId }).then((resProduct) => {
+            let name = resProduct.name;
+            if (resProduct.standardJson) {
+              let standardJson = JSON.parse(resProduct.standardJson);
+              if (standardJson && standardJson.englishName) {
+                name = standardJson.englishName;
+              }
+            }
+            formData.data.contractProductList[i].productCnName = resProduct.name;
+            formData.data.contractProductList[i].productName = name;
+            formData.data.contractProductList[i].productCode = resProduct.code;
+            formData.data.contractProductList[i].productUnit = resProduct.unit;
+            formData.data.contractShipmentList[i].productCode = resProduct.code;
+          });
+        }
+      }
+      delete formData.data.id;
+      delete formData.data.code;
+      getCityData(formData.data.countryId, "20");
+      if (formData.data.provinceId) {
+        getCityData(formData.data.provinceId, "30");
+      }
+      if (formData.data.quotationPayList && formData.data.quotationPayList.length > 0) {
+        formData.data.contractProjectList = formData.data.quotationPayList.map((item) => {
+          delete item.id;
+          return {
+            ...item,
+          };
+        });
+      }
+    });
+  } else if (props.queryData.contractId) {
+    proxy.post("/contract/detail", { id: props.queryData.contractId }).then((res) => {
+      res.countryId = res.buyCountryId;
+      res.provinceId = res.buyProvinceId;
+      res.cityId = res.buyCityId;
+      for (var text in res) {
+        if (text === "contractType") {
+          formData.data[text] = res[text] + "";
+        } else {
+          formData.data[text] = res[text];
+        }
+      }
+      formData.data.oldContractId = formData.data.id;
+      delete formData.data.id;
+      delete formData.data.code;
+      getCityData(formData.data.countryId, "20");
+      if (formData.data.provinceId) {
+        getCityData(formData.data.provinceId, "30");
+      }
+      if (formData.data.contractProductList && formData.data.contractProductList.length > 0) {
+        let productIds = formData.data.contractProductList.map((item) => item.productId);
+        proxy.post("/fileInfo/getList", { businessIdList: productIds }).then((resFile) => {
+          for (let i = 0; i < formData.data.contractProductList.length; i++) {
+            if (resFile[formData.data.contractProductList[i].productId] && resFile[formData.data.contractProductList[i].productId].length > 0) {
+              formData.data.contractProductList[i].fileUrl = resFile[formData.data.contractProductList[i].productId][0].fileUrl;
+            }
+          }
+        });
+        let ids = formData.data.contractProductList.map((item) => item.id);
+        proxy.post("/fileInfo/getList", { businessIdList: ids }).then((resFile) => {
+          for (let i = 0; i < formData.data.contractProductList.length; i++) {
+            if (resFile[formData.data.contractProductList[i].id] && resFile[formData.data.contractProductList[i].id].length > 0) {
+              formData.data.contractProductList[i].fileList = resFile[formData.data.contractProductList[i].id];
+            }
+          }
+        });
+      }
+      if (formData.data.contractProjectList && formData.data.contractProjectList.length > 0) {
+        formData.data.contractProjectList = formData.data.contractProjectList.map((item) => {
+          delete item.id;
+          return {
+            ...item,
+          };
+        });
+      }
+      if (formData.data.contractShipmentList && formData.data.contractShipmentList.length > 0) {
+        formData.data.contractShipmentList = formData.data.contractShipmentList.map((item) => {
+          delete item.id;
+          return {
+            ...item,
+          };
+        });
+      }
+    });
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+.pic {
+  object-fit: contain;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+  vertical-align: middle;
+}
+.shrinkPadding {
+  padding-right: 0 !important;
+}
+.hideCollapse {
+  margin-top: -62px;
+  border: 0 !important;
+}
+::v-deep(.el-collapse-item__arrow) {
+  display: none !important;
+}
+::v-deep(.el-collapse-item__wrap) {
+  border: 0 !important;
+}
+::v-deep(.el-collapse-item__header) {
+  border: 0 !important;
+}
+</style>

+ 3 - 0
src/components/process/EHSD/Contract.vue

@@ -523,6 +523,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {

+ 4 - 1
src/components/process/EHSD/PriceSheet.vue

@@ -399,6 +399,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -406,7 +409,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 const formOption = reactive({
   inline: true,
   labelWidth: 100,

+ 4 - 1
src/components/process/EHSD/Purchase.vue

@@ -500,6 +500,9 @@ const productType = ref([
   },
 ]);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -507,7 +510,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 const formOption = reactive({
   inline: true,
   labelWidth: 100,

+ 4 - 1
src/components/process/EHSD/Sample.vue

@@ -521,6 +521,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -528,7 +531,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 const formOption = reactive({
   inline: true,
   labelWidth: 100,

+ 4 - 1
src/components/process/PriceSheet.vue

@@ -376,6 +376,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -383,7 +386,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 const formOption = reactive({
   inline: true,
   labelWidth: 100,

+ 130 - 2
src/components/process/PurchasePayment.vue

@@ -38,7 +38,7 @@
               <template #default="{ row, $index }">
                 <div style="width: 100%">
                   <el-form-item :prop="'payDetailList.' + $index + '.purchaseId'" :rules="rules.purchaseId" :inline-message="true">
-                    <el-select v-model="row.purchaseId" placeholder="请选择采购合同" style="width: 100%" @change="changePurchaseId(row)">
+                    <el-select v-model="row.purchaseId" placeholder="请选择采购合同" style="width: 100%" @change="changePurchaseId(row, true)">
                       <el-option v-for="item in contractList" :key="item.value" :label="item.label" :value="item.value" />
                     </el-select>
                   </el-form-item>
@@ -119,6 +119,9 @@ let formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -352,6 +355,8 @@ const changeSupply = async (val) => {
   } else {
     contractList.value = [];
   }
+  formData.data.payDetailList = [];
+  getDecisionAids();
 };
 const clickAdd = () => {
   if (formData.data.payDetailList && formData.data.payDetailList.length > 0) {
@@ -366,6 +371,7 @@ const clickAdd = () => {
 };
 const handleRemove = (index) => {
   formData.data.payDetailList.splice(index, 1);
+  getDecisionAids();
 };
 const changeAccount = (val) => {
   if (val) {
@@ -378,7 +384,7 @@ const changeAccount = (val) => {
     }
   }
 };
-const changePurchaseId = (row) => {
+const changePurchaseId = (row, status) => {
   let data = contractList.value.filter((item) => item.value === row.purchaseId);
   if (data && data.length > 0) {
     row.amount = data[0].amount;
@@ -389,6 +395,9 @@ const changePurchaseId = (row) => {
     row.sumPayMoney = "";
     row.sumInvoiceMoney = "";
   }
+  if (status) {
+    getDecisionAids();
+  }
 };
 const changeMoney = () => {
   let money = 0;
@@ -476,6 +485,7 @@ onMounted(async () => {
           for (let i = 0; i < formData.data.payDetailList.length; i++) {
             changePurchaseId(formData.data.payDetailList[i]);
           }
+          getDecisionAids();
         }
       }
     }
@@ -489,6 +499,124 @@ defineExpose({
   getFormData,
   handleSubmit,
 });
+let auxiliaryData = ref([
+  {
+    label: "关联销售合同",
+    data: [],
+  },
+  {
+    label: "到货数据",
+    data: [],
+  },
+  {
+    label: "质检数据",
+    data: [],
+  },
+]);
+const emit = defineEmits(["auxiliaryChange"]);
+const getDecisionAids = () => {
+  let data = {
+    purchaseIdList: [],
+  };
+  if (formData.data.payDetailList && formData.data.payDetailList.length > 0) {
+    data.purchaseIdList = formData.data.payDetailList.map((item) => item.purchaseId);
+  }
+  proxy.post("/contract/payDecisionAid", data).then((res) => {
+    if (res.contractList && res.contractList.length > 0) {
+      auxiliaryData.value[0].data = res.contractList.map((item) => {
+        return [
+          {
+            label: "合同编号",
+            value: item.code,
+            style: {
+              color: "#0084FF",
+            },
+            id: item.id,
+            num: 1,
+          },
+          {
+            label: "下单日期",
+            value: item.createTime,
+            id: item.id,
+            num: 1,
+          },
+        ];
+      });
+    } else {
+      auxiliaryData.value[0].data = [];
+    }
+    if (res.purchaseInfoList && res.purchaseInfoList.length > 0) {
+      auxiliaryData.value[1].data = res.purchaseInfoList.map((item) => {
+        return [
+          {
+            label: "物品编码",
+            value: item.productCode,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "物品名称",
+            value: item.productName,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "采购数量",
+            value: item.purchaseQuantity,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "到货数量",
+            value: item.invoiceQuantity,
+            id: item.productId,
+            num: 1,
+          },
+        ];
+      });
+      auxiliaryData.value[2].data = res.purchaseInfoList.map((item) => {
+        let odds = 0;
+        if (item.invoiceQuantity && item.qualifiedCount) {
+          odds = parseFloat((Number(item.qualifiedCount) / Number(item.invoiceQuantity)) * 100).toFixed(2);
+        }
+        return [
+          {
+            label: "物品编码",
+            value: item.productCode,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "物品名称",
+            value: item.productName,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "到货数量",
+            value: item.invoiceQuantity,
+            id: item.productId,
+            num: 1,
+          },
+          {
+            label: "合格率",
+            value: odds + "%",
+            id: item.productId,
+            num: 1,
+          },
+        ];
+      });
+    } else {
+      auxiliaryData.value[1].data = [];
+      auxiliaryData.value[2].data = [];
+    }
+    let list = proxy.deepClone(auxiliaryData.value);
+    if (!(list[0].data && list[0].data.length > 0)) {
+      list.splice(0, 1);
+    }
+    emit("auxiliaryChange", list);
+  });
+};
 </script>
 
 <style lang="scss" scoped>

+ 17 - 2
src/components/process/PurchaseRefund.vue

@@ -114,6 +114,9 @@ let formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -212,7 +215,10 @@ const getDict = () => {
   });
 };
 getDict();
-const changeSupply = (val) => {
+const changeSupply = (val, status) => {
+  if (!status) {
+    formData.data.refundDetailList = [];
+  }
   if (val) {
     proxy.get("/salesReturn/getBySupplyId", { supplyId: val }).then((res) => {
       if (res.data && res.data.length > 0) {
@@ -226,11 +232,17 @@ const changeSupply = (val) => {
       } else {
         returnGoods.value = [];
       }
+      if (status) {
+        if (formData.data.refundDetailList && formData.data.refundDetailList.length > 0) {
+          for (let i = 0; i < formData.data.refundDetailList.length; i++) {
+            changePurchaseId(formData.data.refundDetailList[i]);
+          }
+        }
+      }
     });
   } else {
     returnGoods.value = [];
   }
-  formData.data.refundDetailList = [];
 };
 const clickAdd = () => {
   if (formData.data.refundDetailList && formData.data.refundDetailList.length > 0) {
@@ -288,6 +300,9 @@ watch(
       for (var text in props.queryData) {
         formData.data[text] = props.queryData[text];
       }
+      if (formData.data.supplyId) {
+        changeSupply(formData.data.supplyId, true);
+      }
     }
   },
   {

+ 4 - 1
src/components/process/ReturnGood.vue

@@ -203,6 +203,9 @@ onMounted(() => {
 });
 
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -210,7 +213,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 
 watch(
   props.queryData,

File diff suppressed because it is too large
+ 716 - 108
src/components/process/SendFunds.vue


+ 7 - 5
src/components/process/SendPurchase.vue

@@ -725,6 +725,9 @@ watch(
   }
 );
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter(
       (item) => item.status === 2 && item.nodeType !== 1
@@ -747,12 +750,11 @@ onMounted(() => {
     ids.value = props.queryData.ids.split(",") || [];
     getDetails();
   }
-  // if (props.queryData.type === "handoverSlip") {
-  //   formData.data.dataResource = "1"; //外销合同采购
-  //   formData.data.dataResourceId = "";
-  // }
-
   if (props.queryData.type === "handoverSlip" && props.queryData.arr) {
+    formData.data.dataResourceId = JSON.parse(
+      props.queryData.arr
+    )[0].contractId;
+    formData.data.dataResource = "1"; //外销合同采购
     contractData.value = JSON.parse(props.queryData.arr);
     auxiliaryData.value.unshift({
       label: "关联销售合同",

+ 4 - 1
src/components/process/SendSubscribe.vue

@@ -180,6 +180,9 @@ onMounted(() => {
 });
 
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -187,7 +190,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 
 watch(
   props.queryData,

+ 4 - 1
src/components/process/ServiceContract.vue

@@ -364,6 +364,9 @@ const formData = reactive({
 });
 const submit = ref(null);
 const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
   if (props.queryData.recordList && props.queryData.recordList.length > 0) {
     let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
     if (data && data.length > 0) {
@@ -371,7 +374,7 @@ const judgeStatus = () => {
     }
   }
   return false;
-};
+};;
 const formOption = reactive({
   inline: true,
   labelWidth: 100,

+ 45 - 22
src/components/product/SelectGoods.vue

@@ -2,6 +2,7 @@
   <div>
     <byTable
       ref="table"
+      :tableHeight="tableHeight"
       :source="sourceList.data"
       :pagination="sourceList.pagination"
       :config="config"
@@ -9,18 +10,28 @@
       highlight-current-row
       :selectConfig="selectConfig"
       :action-list="[]"
-      @get-list="getList">
+      @get-list="getList"
+    >
     </byTable>
     <div>
       <div>已选择货品</div>
       <div style="margin: 10px 0px">
-        <el-tag style="margin-right: 10px" type="info" closable v-for="(good, index) in goodList" :key="good.id" @close="handleRemove(index)">
+        <el-tag
+          style="margin-right: 10px; margin-bottom: 5px"
+          type="info"
+          closable
+          v-for="(good, index) in goodList"
+          :key="good.id"
+          @close="handleRemove(index)"
+        >
           {{ good.name }}
         </el-tag>
       </div>
       <div style="text-align: center">
         <el-button @click="handleCancel" size="large">取 消</el-button>
-        <el-button type="primary" @click="handleSubmit" size="large">确 定</el-button>
+        <el-button type="primary" @click="handleSubmit" size="large"
+          >确 定</el-button
+        >
       </div>
     </div>
   </div>
@@ -31,6 +42,14 @@ import { ElMessage } from "element-plus";
 import byTable from "@/components/byTable/index";
 import { computed, ref } from "vue";
 
+const tableHeight = ref(0);
+const getTableHeight = () => {
+  tableHeight.value = window.innerHeight - 455;
+};
+getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
 const loading = ref(false);
 const sourceList = ref({
   data: [],
@@ -149,26 +168,30 @@ const getList = async (req = {}) => {
     ...req,
   };
   loading.value = true;
-  proxy.post("/productInfo/page", sourceList.value.pagination).then((message) => {
-    sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
-    sourceList.value.pagination.total = message.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-    const productIdList = message.rows.map((x) => x.id);
-    if (productIdList.length > 0) {
-      proxy.post("/fileInfo/getList", { businessIdList: productIdList }).then((fileObj) => {
-        for (let i = 0; i < sourceList.value.data.length; i++) {
-          const e = sourceList.value.data[i];
-          for (const key in fileObj) {
-            if (e.id === key) {
-              e.fileList = fileObj[key];
+  proxy
+    .post("/productInfo/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+      const productIdList = message.rows.map((x) => x.id);
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
+              }
             }
-          }
-        }
-      });
-    }
-  });
+          });
+      }
+    });
 };
 getList();
 // 接收父组件的传值

+ 4 - 0
src/components/selectCity/index.vue

@@ -39,6 +39,10 @@ defineProps({
 watch(
   formData.value,
   (val) => {
+    if (formData.value[proxy.addressId || "provinceId"] === "-1") {
+      formData.value[proxy.addressId || "provinceId"] = "";
+      formData.value[proxy.addressName || "provinceName"] = "";
+    }
     // console.log(formData.value[proxy.addressId || 'provinceId'],formData.value[proxy.addressName || 'provinceName'])
     if (!formData.value[proxy.addressId || "provinceId"] && !formData.value[proxy.addressName || "provinceName"]) {
       showModel.value = "";

+ 5 - 5
src/lang/index.js

@@ -19,10 +19,10 @@ const i18n = createI18n({
   }
 })
 
-get('/open/multilingual/getJson',{}).then(res=>{
-  // console.log(JSON.parse(res.data),'下载')
-  window.localStorage.setItem('lang',res.data)
-  i18n.global.setLocaleMessage('zh-cn', cn)
-})
+// get('/open/multilingual/getJson',{}).then(res=>{
+//   // console.log(JSON.parse(res.data),'下载')
+//   window.localStorage.setItem('lang',res.data)
+//   i18n.global.setLocaleMessage('zh-cn', cn)
+// })
 
 export default i18n

+ 5 - 0
src/main.js

@@ -77,6 +77,10 @@ import TreeSelect from '@/components/TreeSelect'
 import DictTag from '@/components/DictTag'
 // 多语言
 import i18n from "@/lang/index";
+
+// 打印
+import print from "vue3-print-nb"
+
 const app = createApp(App)
 console.log(i18n.global.t('login.welcomeToLogin'))
 // 全局方法挂载
@@ -123,6 +127,7 @@ app.use(plugins)
 
 app.use(i18n)
 app.use(elementIcons)
+app.use(print)
 app.component('svg-icon', SvgIcon)
 
 directive(app)

+ 70 - 3
src/utils/util.js

@@ -1,5 +1,8 @@
 import moment from "moment";
-import { post, get } from "@/utils/request";
+import {
+  post,
+  get
+} from "@/utils/request";
 import Cookies from "js-cookie";
 import html2Canvas from "html2canvas";
 import JsPDF from "jspdf";
@@ -353,9 +356,19 @@ export function timeInterval(smallTime, largeTime) {
     //计算相差秒数
     let leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
     let seconds = Math.round(leave3 / 1000);
-    return { days: days, hours: hours, minutes: minutes, seconds: seconds };
+    return {
+      days: days,
+      hours: hours,
+      minutes: minutes,
+      seconds: seconds
+    };
   }
-  return { days: 0, hours: 0, minutes: 0, seconds: 0 };
+  return {
+    days: 0,
+    hours: 0,
+    minutes: 0,
+    seconds: 0
+  };
 }
 
 // 比较时间大小
@@ -368,3 +381,57 @@ export function compareTime(date1, date2) {
     return false; //第二个大
   }
 }
+export function toDx(n) {
+  //阿拉伯数字转换函数
+  switch (n) {
+    case "0":
+      return "零";
+    case "1":
+      return "壹";
+    case "2":
+      return "贰";
+    case "3":
+      return "叁";
+    case "4":
+      return "肆";
+    case "5":
+      return "伍";
+    case "6":
+      return "陆";
+    case "7":
+      return "柒";
+    case "8":
+      return "捌";
+    case "9":
+      return "玖";
+  }
+};
+
+
+// 金额转大写
+export function NumberToChinese(m) {
+  let unit = ["仟", "佰", "拾", "", "仟", "佰", "拾", "", "角", "分", "厘"];
+  m *= 1000;
+  m = Number(parseFloat(m).toFixed(0));
+  m += "";
+  var x = m.length;
+  var result = "";
+  for (var i = 0; i < x; i++) {
+    if (i == 3) {
+      result = "元" + result;
+    } else if (i == 7) {
+      result = "万" + result;
+    }
+    if (m.charAt(x - i - 1) == 0) {
+      if (i != 0 && i != 1 && i != 2) {
+        if (result.charAt(0) != "零" && result.charAt(0) != "元" && result.charAt(0) != "万") {
+          result = "零" + result;
+        }
+      }
+      continue;
+    }
+    result = toDx(m.charAt(x - i - 1)) + unit[unit.length - i - 1] + result;
+  }
+  result += result.charAt(result.length - 1) == "元" ? "整" : "";
+  return result;
+};

+ 21 - 32
src/views/finance/fundManage/accountPayment/index.vue

@@ -15,11 +15,10 @@
         :action-list="[]"
         @moreSearch="moreSearch"
         @get-list="getList">
-        <template #pic="{ item }">
-          <div v-if="item.fileList.length > 0">
-            <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
+        <template #amount="{ item }">
+          <div style="width: 100%">
+            <span>{{ item.currency }}{{ item.amount }}</span>
           </div>
-          <div v-else></div>
         </template>
       </byTable>
     </div>
@@ -203,14 +202,14 @@ const config = computed(() => {
       attrs: {
         label: "归属公司",
         prop: "corporationName",
-        width: 220,
+        width: 160,
       },
     },
     {
       attrs: {
         label: "归属部门",
         prop: "deptName",
-        width: 180,
+        width: 160,
       },
     },
     {
@@ -231,7 +230,7 @@ const config = computed(() => {
       attrs: {
         label: "申请人",
         prop: "userName",
-        width: 130,
+        width: 140,
       },
     },
     {
@@ -251,15 +250,15 @@ const config = computed(() => {
     {
       attrs: {
         label: "金额",
-        prop: "amount",
-        width: 130,
+        slot: "amount",
+        width: 120,
       },
     },
     {
       attrs: {
         label: "款项说明",
         prop: "paymentRemark",
-        "min-width": 220,
+        "min-width": 200,
       },
     },
     {
@@ -281,20 +280,18 @@ const config = computed(() => {
       },
       renderHTML(row) {
         return [
-          row.status == 20
-            ? {
-                attrs: {
-                  label: "打款",
-                  type: "primary",
-                  text: true,
-                },
-                el: "button",
-                click() {
-                  formOption.disabled = false;
-                  getDtl(row);
-                },
-              }
-            : {},
+          {
+            attrs: {
+              label: "打款",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              formOption.disabled = false;
+              getDtl(row);
+            },
+          },
           {
             attrs: {
               label: "查看",
@@ -576,7 +573,6 @@ const getDtl = (row) => {
   proxy.post("/accountPayment/detail", { id: row.id }).then((res) => {
     formData.data = res;
     formData.data.expensesTime = moment().format("yyyy-MM-DD HH:mm:ss");
-    formData.data.remark = formData.data.paymentRemark;
     dialogVisible.value = true;
   });
 };
@@ -707,13 +703,6 @@ const submitSearch = () => {
 .user {
   padding: 20px;
 }
-.pic {
-  object-fit: contain;
-  width: 50px;
-  height: 50px;
-  cursor: pointer;
-  vertical-align: middle;
-}
 ::v-deep(.el-input-number .el-input__inner) {
   text-align: left;
 }

+ 357 - 41
src/views/finance/fundManage/accountStatement/index.vue

@@ -14,11 +14,16 @@
           //   action: () => deriveExcel(),
           // },
           {
+            text: '退税登记',
+            action: () => openModalOne('add'),
+          },
+          {
             text: '添加流水',
             action: () => openModal('add'),
           },
         ]"
-        @get-list="getList">
+        @get-list="getList"
+      >
         <!-- <template #amount="{ item }">
           <div :style="'color: ' + (item.status === '10' ? '#04cb04;' : 'red;')">
             <span style="padding-right: 4px">{{ item.currency }}</span>
@@ -39,11 +44,28 @@
       </byTable>
     </div>
 
-    <el-dialog :title="modalType == 'add' ? '添加流水' : '编辑流水'" v-if="dialogVisible" v-model="dialogVisible" width="600" v-loading="loadingDialog">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+    <el-dialog
+      :title="modalType == 'add' ? '添加流水' : '编辑流水'"
+      v-if="dialogVisible"
+      v-model="dialogVisible"
+      width="600"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="submit"
+        v-loading="loadingDialog"
+      >
         <template #transactionTime>
           <div>
-            <el-date-picker v-model="formData.data.transactionTime" type="datetime" placeholder="请选择交易时间" value-format="YYYY-MM-DD HH:mm:ss" />
+            <el-date-picker
+              v-model="formData.data.transactionTime"
+              type="datetime"
+              placeholder="请选择交易时间"
+              value-format="YYYY-MM-DD HH:mm:ss"
+            />
           </div>
         </template>
         <template #money>
@@ -51,15 +73,34 @@
             <el-row :gutter="10">
               <el-col :span="6">
                 <el-form-item prop="status">
-                  <el-select v-model="formData.data.status" placeholder="请选择" style="width: 100%" @change="changeStatus()">
-                    <el-option v-for="item in status" :key="item.value" :label="item.label" :value="item.value" />
+                  <el-select
+                    v-model="formData.data.status"
+                    placeholder="请选择"
+                    style="width: 100%"
+                    @change="changeStatus()"
+                  >
+                    <el-option
+                      v-for="item in status"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    />
                   </el-select>
                 </el-form-item>
               </el-col>
               <el-col :span="6">
                 <el-form-item prop="currency">
-                  <el-select v-model="formData.data.currency" placeholder="请选择" style="width: 100%">
-                    <el-option v-for="item in accountCurrency" :key="item.value" :label="item.label" :value="item.value" />
+                  <el-select
+                    v-model="formData.data.currency"
+                    placeholder="请选择"
+                    style="width: 100%"
+                  >
+                    <el-option
+                      v-for="item in accountCurrency"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    />
                   </el-select>
                 </el-form-item>
               </el-col>
@@ -72,7 +113,8 @@
                     style="width: 100%"
                     :precision="2"
                     :controls="false"
-                    :min="0" />
+                    :min="0"
+                  />
                 </el-form-item>
               </el-col>
             </el-row>
@@ -82,7 +124,13 @@
           <div>
             <el-form-item prop="received">
               <el-radio-group v-model="formData.data.received">
-                <el-radio v-for="item in received" :key="item.value" :label="item.value" border>{{ item.label }}</el-radio>
+                <el-radio
+                  v-for="item in received"
+                  :key="item.value"
+                  :label="item.value"
+                  border
+                  >{{ item.label }}</el-radio
+                >
               </el-radio-group>
             </el-form-item>
           </div>
@@ -90,7 +138,95 @@
       </byForm>
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm()" size="large">确 定</el-button>
+        <el-button type="primary" @click="submitForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      :title="'退税登记'"
+      v-if="dialogVisibleOne"
+      v-model="dialogVisibleOne"
+      width="600"
+    >
+      <byForm
+        :formConfig="formConfigOne"
+        :formOption="formOption"
+        v-model="formData.dataOne"
+        :rules="rulesOne"
+        ref="submitOne"
+        v-loading="loadingDialog"
+      >
+        <template #details>
+          <div style="width: 100%">
+            <el-button
+              type="primary"
+              @click="handleAddRow"
+              style="margin: 10px 0"
+            >
+              添加
+            </el-button>
+            <el-table :data="formData.dataOne.taxRefundDetailsList">
+              <el-table-column prop="count" label="合同编号" min-width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item
+                    :prop="'taxRefundDetailsList.' + $index + '.contractId'"
+                    :rules="rulesOne.contractId"
+                    :inline-message="true"
+                  >
+                    <el-select
+                      v-model="row.contractId"
+                      placeholder="请选择"
+                      filterable
+                      style="width: 100%"
+                    >
+                      <el-option
+                        v-for="item in contractList"
+                        :label="item.code"
+                        :value="item.id"
+                      >
+                      </el-option>
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="amount" label="关联金额" min-width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item
+                    :prop="'taxRefundDetailsList.' + $index + '.amount'"
+                    :rules="rulesOne.amount"
+                    :inline-message="true"
+                  >
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.amount"
+                      :precision="2"
+                      :controls="false"
+                      :min="0"
+                      style="width: 100%"
+                    />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="zip" label="操作" width="80">
+                <template #default="{ $index }">
+                  <el-button type="primary" link @click="handleRemove($index)"
+                    >删除</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisibleOne = false" size="large"
+          >取 消</el-button
+        >
+        <el-button type="primary" @click="submitFormOne()" size="large"
+          >确 定</el-button
+        >
       </template>
     </el-dialog>
   </div>
@@ -107,6 +243,7 @@ import moment from "moment";
 const { proxy } = getCurrentInstance();
 const accountCurrency = ref([]);
 const accountList = ref([]);
+const contractList = ref([]);
 const status = ref([
   {
     label: "收入",
@@ -262,11 +399,15 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-              }).then(() => {
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
                 proxy
                   .post("/accountRunningWater/delete", {
                     id: row.id,
@@ -307,19 +448,29 @@ const getCurrency = () => {
     });
 };
 const getAccountList = () => {
-  return proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 999 }).then((res) => {
-    if (res.rows && res.rows.length > 0) {
-      accountList.value = res.rows.map((item) => {
-        return {
-          label: item.alias,
-          value: item.id,
-        };
-      });
-      sourceList.value.pagination.accountManagementId = accountList.value[0].value;
-    }
-  });
+  return proxy
+    .post("/accountManagement/page", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        accountList.value = res.rows.map((item) => {
+          return {
+            label: item.alias,
+            value: item.id,
+          };
+        });
+        sourceList.value.pagination.accountManagementId =
+          accountList.value[0].value;
+      }
+    });
 };
 const getDict = () => {
+  // 关联合同
+  proxy
+    .post("/contract/page", { pageNum: 1, pageSize: 9999, status: 30 })
+    .then((res) => {
+      contractList.value = res.rows;
+    });
+
   Promise.all([getCurrency(), getAccountList()]).then(() => {
     getList();
   });
@@ -327,19 +478,23 @@ const getDict = () => {
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/accountRunningWater/page1", sourceList.value.pagination).then((res) => {
-    sourceList.value.data = res.rows;
-    sourceList.value.pagination.total = res.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-  });
+  proxy
+    .post("/accountRunningWater/page1", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
 };
 getDict();
 const modalType = ref("add");
 const dialogVisible = ref(false);
+const dialogVisibleOne = ref(false);
 const loadingDialog = ref(false);
 const submit = ref(null);
+const submitOne = ref(null);
 const formOption = reactive({
   inline: true,
   labelWidth: 100,
@@ -348,11 +503,15 @@ const formOption = reactive({
 });
 const formData = reactive({
   data: {},
+  dataOne: {
+    taxRefundDetailsList: [],
+  },
 });
 const formConfig = computed(() => {
   return [
     {
-      label: "账户信息",
+      type: "title",
+      title: "账户信息",
     },
     {
       type: "select",
@@ -361,7 +520,8 @@ const formConfig = computed(() => {
       data: accountList.value,
     },
     {
-      label: "交易信息",
+      type: "title",
+      title: "交易信息",
     },
     {
       type: "slot",
@@ -384,7 +544,8 @@ const formConfig = computed(() => {
         }
       : {},
     {
-      label: "对方信息",
+      type: "title",
+      title: "对方信息",
     },
     {
       type: "input",
@@ -405,7 +566,8 @@ const formConfig = computed(() => {
       itemType: "text",
     },
     {
-      label: "其他信息",
+      type: "title",
+      title: "其他信息",
     },
     {
       type: "input",
@@ -415,17 +577,105 @@ const formConfig = computed(() => {
     },
   ];
 });
+const formConfigOne = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "账户信息",
+    },
+    {
+      type: "select",
+      prop: "accountManagementId",
+      label: "选择账户",
+      data: accountList.value,
+    },
+    {
+      type: "title",
+      title: "退税信息",
+    },
+    {
+      type: "date",
+      itemType: "datetime",
+      prop: "transactionTime",
+      label: "退税时间",
+    },
+    {
+      type: "selectInput",
+      prop: "amount",
+      selectProp: "currency",
+      label: "退税金额",
+      data: accountCurrency.value,
+    },
+    {
+      type: "title",
+      title: "对方信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "账户名称",
+      itemType: "text",
+    },
+    {
+      type: "input",
+      prop: "openingBank",
+      label: "开户银行",
+      itemType: "text",
+    },
+    {
+      type: "input",
+      prop: "accountOpening",
+      label: "银行账号",
+      itemType: "text",
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "关联合同",
+    },
+    {
+      type: "title",
+      title: "其他信息",
+    },
+    {
+      type: "input",
+      prop: "remarks",
+      label: "摘要",
+      itemType: "textarea",
+    },
+  ];
+});
+
 const rules = ref({
-  accountManagementId: [{ required: true, message: "请选择账户", trigger: "change" }],
-  transactionTime: [{ required: true, message: "请选择交易时间", trigger: "change" }],
+  accountManagementId: [
+    { required: true, message: "请选择账户", trigger: "change" },
+  ],
+  transactionTime: [
+    { required: true, message: "请选择交易时间", trigger: "change" },
+  ],
   status: [{ required: true, message: "请选择收支类型", trigger: "change" }],
   currency: [{ required: true, message: "请选择币种", trigger: "change" }],
-  received: [{ required: true, message: "请选择合同是否到账", trigger: "change" }],
+  received: [
+    { required: true, message: "请选择合同是否到账", trigger: "change" },
+  ],
   amount: [{ required: true, message: "请输入金额", trigger: "blur" }],
   // name: [{ required: true, message: "请输入账户名称", trigger: "blur" }],
   // openingBank: [{ required: true, message: "请输入开户银行", trigger: "blur" }],
   // accountOpening: [{ required: true, message: "请输入银行账号", trigger: "blur" }],
 });
+const rulesOne = ref({
+  accountManagementId: [
+    { required: true, message: "请选择账户", trigger: "change" },
+  ],
+  transactionTime: [
+    { required: true, message: "请选择退税时间", trigger: "change" },
+  ],
+  currency: [{ required: true, message: "请选择币种", trigger: "change" }],
+  // amount: [{ required: true, message: "请输入退税金额", trigger: "blur" }],
+  contractId: [{ required: true, message: "请选择合同", trigger: "change" }],
+  amount: [{ required: true, message: "请输入金额", trigger: "blur" }],
+});
+
 const openModal = (val) => {
   modalType.value = val;
   formData.data = {
@@ -434,6 +684,16 @@ const openModal = (val) => {
   loadingDialog.value = false;
   dialogVisible.value = true;
 };
+const openModalOne = () => {
+  modalType.value = "add";
+  formData.dataOne = {
+    transactionTime: moment().format("yyyy-MM-DD HH:mm:ss"),
+    currency: accountCurrency.value[0].value,
+    taxRefundDetailsList: [],
+  };
+  dialogVisibleOne.value = true;
+};
+
 const changeStatus = () => {
   formData.data.received = "";
 };
@@ -459,6 +719,62 @@ const submitForm = () => {
     );
   });
 };
+
+const handleAddRow = () => {
+  formData.dataOne.taxRefundDetailsList.push({
+    contractId: "",
+    amount: null,
+  });
+};
+const handleRemove = (index) => {
+  formData.dataOne.taxRefundDetailsList.splice(index, 1);
+};
+
+const submitFormOne = () => {
+  submitOne.value.handleSubmit(() => {
+    if (!formData.dataOne.taxRefundDetailsList.length > 0) {
+      return ElMessage({
+        message: "请关联合同",
+        type: "info",
+      });
+    }
+    const submitData = { ...formData.dataOne };
+    for (let i = 0; i < submitData.taxRefundDetailsList.length; i++) {
+      const e = submitData.taxRefundDetailsList[i];
+      if (e.amount === 0) {
+        return ElMessage({
+          message: "关联金额不能为0",
+          type: "info",
+        });
+      }
+    }
+    const total = submitData.taxRefundDetailsList.reduce(
+      (sum, crr) => (sum += crr.amount),
+      0
+    );
+    if (total !== Number(submitData.amount)) {
+      return ElMessage({
+        message: "关联合同明细的关联金额总合必须等于退税金额",
+        type: "info",
+      });
+    }
+    loadingDialog.value = true;
+    proxy.post("/accountRunningWater/taxRefund", submitData).then(
+      () => {
+        ElMessage({
+          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          type: "success",
+        });
+        dialogVisibleOne.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+  });
+};
 const update = (row) => {
   modalType.value = "edit";
   loadingDialog.value = true;

+ 436 - 0
src/views/finance/fundManage/comeAndGo/index.vue

@@ -0,0 +1,436 @@
+<template>
+  <div class="tenant">
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :selectConfig="selectConfig"
+      highlight-current-row
+      :action-list="[
+        {
+          text: '往来单位',
+          action: () => addUnit(),
+          type: ' ',
+        },
+        {
+          text: '添加往来',
+          action: () => addModal(),
+        },
+      ]"
+      @get-list="getList">
+      <template #amount="{ item }">
+        <div>
+          <span style="padding-right: 4px">{{ item.currency }}</span>
+          <span>{{ moneyFormat(item.amount, 2) }}</span>
+        </div>
+      </template>
+    </byTable>
+
+    <el-dialog title="往来单位" v-if="openUnit" v-model="openUnit" width="700">
+      <div style="width: 100%">
+        <el-button @click="clickAddUnit">添 加</el-button>
+        <el-table :data="departmentList" style="margin-top: 20px">
+          <el-table-column label="单位名称" prop="name" width="220" />
+          <el-table-column label="备注" prop="remark" />
+          <el-table-column label="操作" align="center" width="120" fixed="right">
+            <template #default="{ row }">
+              <el-button type="primary" link @click="handleUpdate(row)">修改</el-button>
+              <el-button type="primary" link @click="handleDelete(row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <template #footer>
+        <el-button @click="openUnit = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog :title="modalType == 'add' ? '添加单位' : '编辑单位'" v-if="openAddUnit" v-model="openAddUnit" width="400">
+      <byForm :formConfig="formUnitConfig" :formOption="formOption" v-model="formUnitData.data" :rules="rulesUnit" ref="unit"></byForm>
+      <template #footer>
+        <el-button @click="openAddUnit = false" size="large">关 闭</el-button>
+        <el-button type="primary" @click="submitUnitForm()" size="large">确 定</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="添加往来" v-if="openComeAndGo" v-model="openComeAndGo" width="500">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="comeAndGo">
+        <template #amount>
+          <div style="width: 100%">
+            <el-form-item prop="amount">
+              <div style="display: flex">
+                <div style="width: 100px">
+                  <el-select v-model="formData.data.currency" placeholder="请选择币种" style="width: 100px">
+                    <el-option v-for="item in accountCurrency" :key="item.value" :label="item.value" :value="item.value" />
+                  </el-select>
+                </div>
+                <div style="width: calc(100% - 100px)">
+                  <el-input-number
+                    onmousewheel="return false;"
+                    v-model="formData.data.amount"
+                    placeholder="请输入金额"
+                    style="width: 100%"
+                    :precision="2"
+                    :controls="false"
+                    :min="0" />
+                </div>
+              </div>
+            </el-form-item>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openComeAndGo = false" size="large">关 闭</el-button>
+        <el-button type="primary" @click="submitForm()" size="large">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const accountCurrency = ref([]);
+const accountList = ref([]);
+const departmentList = ref([]);
+const isFlowingWater = ref([
+  {
+    label: "是",
+    value: "1",
+  },
+  {
+    label: "否",
+    value: "0",
+  },
+]);
+const type = ref([
+  {
+    label: "收入",
+    value: "0",
+  },
+  {
+    label: "支出",
+    value: "1",
+  },
+]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    isFlowingWater: "",
+    departmentId: "",
+    type: "",
+  },
+});
+const selectConfig = computed(() => {
+  return [
+    {
+      label: "是否流水",
+      prop: "isFlowingWater",
+      data: isFlowingWater.value,
+    },
+    {
+      label: "往来单位",
+      prop: "departmentId",
+      data: departmentList.value,
+    },
+    {
+      label: "往来类型",
+      prop: "type",
+      data: type.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "往来单位",
+        prop: "departmentId",
+        "min-width": 180,
+      },
+      render(val) {
+        return proxy.dictValueLabel(val, departmentList.value);
+      },
+    },
+    {
+      attrs: {
+        label: "往来类型",
+        prop: "type",
+        width: 140,
+      },
+      render(val) {
+        return proxy.dictValueLabel(val, type.value);
+      },
+    },
+    {
+      attrs: {
+        label: "往来金额",
+        slot: "amount",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "是否流水",
+        prop: "isFlowingWater",
+        width: 140,
+      },
+      render(val) {
+        return proxy.dictValueLabel(val, isFlowingWater.value);
+      },
+    },
+    {
+      attrs: {
+        label: "往来账户",
+        prop: "accountId",
+        "min-width": 180,
+      },
+      render(val) {
+        return proxy.dictValueLabel(val, accountList.value);
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        prop: "remark",
+        "min-width": 240,
+      },
+    },
+  ];
+});
+const getDict = () => {
+  proxy.getDictOne(["account_currency"]).then((res) => {
+    if (res["account_currency"] && res["account_currency"].length > 0) {
+      accountCurrency.value = res["account_currency"].map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    }
+  });
+  proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      accountList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.alias + " (" + item.accountOpening + ")",
+          value: item.id,
+        };
+      });
+    }
+  });
+  getDepartmentList();
+};
+const getDepartmentList = () => {
+  proxy.get("/transactionDepartment/list", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.data && res.data.length > 0) {
+      departmentList.value = res.data.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    } else {
+      departmentList.value = [];
+    }
+  });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/transaction/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getDict();
+getList();
+const openComeAndGo = ref(false);
+const formData = reactive({
+  data: {
+    departmentId: "",
+    type: "",
+    currency: "",
+    amount: undefined,
+    isFlowingWater: "",
+    accountId: "",
+    remark: "",
+  },
+});
+const comeAndGo = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "departmentId",
+      label: "往来单位",
+      data: departmentList.value,
+    },
+    {
+      type: "select",
+      prop: "type",
+      label: "往来类型",
+      data: type.value,
+    },
+    {
+      type: "select",
+      prop: "isFlowingWater",
+      label: "是否流水",
+      data: isFlowingWater.value,
+    },
+    {
+      type: "select",
+      prop: "accountId",
+      label: "往来账户",
+      data: accountList.value,
+    },
+    {
+      type: "slot",
+      slotName: "amount",
+      prop: "amount",
+      label: "往来金额",
+    },
+    {
+      type: "input",
+      prop: "remark",
+      label: "备注",
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = computed(() => {
+  return {
+    departmentId: [{ required: true, message: "请选择往来单位", trigger: "change" }],
+    type: [{ required: true, message: "请选择往来类型", trigger: "change" }],
+    isFlowingWater: [{ required: true, message: "请选择是否流水", trigger: "change" }],
+    accountId: [{ required: formData.data.isFlowingWater === "1" ? true : false, message: "请选择往来账户", trigger: "change" }],
+    amount: [{ required: true, message: "请输入往来金额", trigger: "blur" }],
+  };
+});
+const addModal = () => {
+  formData.data = {
+    departmentId: "",
+    type: "",
+    currency: "",
+    amount: undefined,
+    isFlowingWater: "0",
+    accountId: "",
+    remark: "",
+  };
+  if (accountCurrency.value && accountCurrency.value.length > 0) {
+    formData.data.currency = accountCurrency.value[0].value;
+  }
+  openComeAndGo.value = true;
+};
+const submitForm = () => {
+  comeAndGo.value.handleSubmit(() => {
+    proxy.post("/transaction/add", formData.data).then(() => {
+      ElMessage({
+        message: "添加成功",
+        type: "success",
+      });
+      openComeAndGo.value = false;
+      getList();
+    });
+  });
+};
+const openUnit = ref(false);
+const addUnit = () => {
+  openUnit.value = true;
+};
+const handleDelete = (row) => {
+  ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(() => {
+    proxy.post("/transactionDepartment/delete", { id: row.id }).then(() => {
+      ElMessage({
+        message: "删除成功",
+        type: "success",
+      });
+      getDepartmentList();
+    });
+  });
+};
+const modalType = ref("add");
+const openAddUnit = ref(false);
+const formUnitData = reactive({
+  data: {
+    name: "",
+    remark: "",
+  },
+});
+const unit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formUnitConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "name",
+      label: "单位名称",
+      itemType: "text",
+    },
+    {
+      type: "input",
+      prop: "remark",
+      label: "备注",
+      itemType: "textarea",
+    },
+  ];
+});
+const rulesUnit = ref({
+  name: [{ required: true, message: "请输入单位名称", trigger: "blur" }],
+});
+const clickAddUnit = () => {
+  modalType.value = "add";
+  formUnitData.data = {
+    name: "",
+    remark: "",
+  };
+  openAddUnit.value = true;
+};
+const submitUnitForm = () => {
+  unit.value.handleSubmit(() => {
+    proxy.post("/transactionDepartment/" + modalType.value, formUnitData.data).then(() => {
+      ElMessage({
+        message: modalType.value == "add" ? "添加成功" : "编辑成功",
+        type: "success",
+      });
+      openAddUnit.value = false;
+      getDepartmentList();
+    });
+  });
+};
+const handleUpdate = (row) => {
+  modalType.value = "edit";
+  formUnitData.data = proxy.deepClone(row);
+  openAddUnit.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 1 - 1
src/views/finance/fundManage/depExpenses/index.vue

@@ -376,7 +376,7 @@ const getList = async (req) => {
     }, 200);
   });
 };
-proxy.getDict(["payment_status", "account_currency"]).then((res) => {
+proxy.getDict(["account_currency"]).then((res) => {
   accountCurrency.value = res.account_currency.map((item) => {
     return {
       label: item.dictValue,

File diff suppressed because it is too large
+ 640 - 120
src/views/finance/fundManage/funds/index.vue


+ 10 - 7
src/views/finance/fundManage/fundsStatement/index.vue

@@ -79,13 +79,16 @@ const flitterData = (arr) => {
   };
 };
 let req = ref({
-  dateBetween: formatDate(new Date(), "yyyy-MM"),
-  managementId: "",
-});
-let dictsData = {};
-proxy.getDict(["payment_status", "account_currency"]).then((res) => {
-  dictsData = res;
-});
+	dateBetween: formatDate(new Date(), 'yyyy-MM'),
+	managementId:null,
+})
+let dictsData = {}
+proxy
+	.getDict(['account_currency'])
+	.then((res) => {
+		dictsData = res
+	})
+
 const getList = async () => {
   loading.value = true;
   proxy.post("/accountStatement/capitalDaily", req.value).then((message) => {

+ 30 - 1
src/views/process/processApproval/auxiliary.vue

@@ -31,6 +31,31 @@ defineProps({
 })
 console.log(proxy.data)
 </script>
+<style>
+.auxiliary .el-collapse-item{
+	border:1px solid #dddddd;
+	margin-bottom:20px;
+}
+.auxiliary .el-collapse-item__header{
+	border:none !important;
+	padding-left: 20px;
+	font-size: 14px;
+	font-weight: bold;
+}
+.el-collapse-item__wrap{
+	border:none !important;
+}
+.el-collapse-item__wrap{
+	padding: 0 20px;
+}
+.el-collapse-item__content{
+	padding-bottom:10px;
+}
+
+.el-collapse{
+	border:none;
+}
+</style>
 <style lang="scss">
 .auxiliary {
 	ul {
@@ -42,7 +67,7 @@ console.log(proxy.data)
 			background: #f1f1f1;
 			overflow: hidden;
 			margin-bottom: 10px;
-			
+			border-radius: 2px 2px 2px 2px;
 			.list-box {
 				float: left;
 				width: 50%;
@@ -70,6 +95,10 @@ console.log(proxy.data)
 				}
 			}
 		}
+		li:hover{
+			background: #EFF6FF;
+		}
+	
 	}
 }
 </style>

+ 96 - 18
src/views/process/processApproval/index.vue

@@ -11,7 +11,7 @@
         <SendFunds ref="makeDom" v-else-if="flowForm.flowKey == 'account_request_funds_flow'" :queryData="queryData.data"></SendFunds>
         <ReturnGood ref="makeDom" v-else-if="flowForm.flowKey == 'sales_return_flow'" :queryData="queryData.data"></ReturnGood>
         <PurchaseRefund ref="makeDom" v-else-if="flowForm.flowKey == 'refund_flow'" :queryData="queryData.data"></PurchaseRefund>
-        <PurchasePayment ref="makeDom" v-else-if="flowForm.flowKey == 'pay_flow'" :queryData="queryData.data"></PurchasePayment>
+        <PurchasePayment ref="makeDom"  @auxiliaryChange='(e) => getAuxiliaryData(e)' v-else-if="flowForm.flowKey == 'pay_flow'" :queryData="queryData.data"></PurchasePayment>
         <template v-else-if="flowForm.flowKey == 'sale_quotation_flow'">
           <PriceSheetEHSD ref="makeDom" v-if="flowForm.tenantType === 'EHSD'" :queryData="queryData.data"></PriceSheetEHSD>
           <PriceSheet ref="makeDom" v-else :queryData="queryData.data"></PriceSheet>
@@ -20,6 +20,9 @@
           <ContractEHSD ref="makeDom" v-if="flowForm.tenantType === 'EHSD'" :queryData="queryData.data"></ContractEHSD>
           <Contract ref="makeDom" v-else :queryData="queryData.data" @auxiliaryChange='(e) => getAuxiliaryData(e)'></Contract>
         </template>
+        <template v-else-if="flowForm.flowKey == 'contract_update_flow'">
+          <ContractAlteration ref="makeDom" :queryData="queryData.data" @auxiliaryChange='(e) => getAuxiliaryData(e)'></ContractAlteration>
+        </template>
         <template v-else-if="flowForm.flowKey == 'sample_flow'">
           <SampleEHSD ref="makeDom" :queryData="queryData.data"></SampleEHSD>
         </template>
@@ -38,9 +41,21 @@
           <el-form-item prop="remark" label-width="0px" label="">
             <el-input type="textarea" placeholder="请输入" v-model="flowForm.remark"> </el-input>
           </el-form-item>
+          <el-form-item prop="remark" label-width="80px" label="附件上传">
+            <el-upload
+              v-model:fileList="flowForm.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile">
+              <el-button>选择</el-button>
+            </el-upload>
+          </el-form-item>
           <el-form-item>
-            <el-button type="primary" v-if="approvalRecordData.buttonInfoList.length == 0" @click="handleSubmit">提交</el-button>
-            <el-button type="primary" v-else v-for="i in approvalRecordData.buttonInfoList" :key="i.type" @click="handleSubmit(i.type)">{{ i.name }}</el-button>
+            <el-button type="primary" v-if="approvalRecordData.buttonInfoList.length == 0" @click="handleSubmit" :loading="btnLoading">提交</el-button>
+            <el-button type="primary" v-else v-for="i in approvalRecordData.buttonInfoList" :key="i.type" :loading="btnLoading" @click="handleSubmit(i.type)">{{ i.name }}</el-button>
           </el-form-item>
         </el-form>
       </div>
@@ -74,21 +89,19 @@
                     <span v-if="item.status != 3">办理人:</span>{{ item.processedUser }}<span class="time">{{ item.processedDate }}</span>
                   </div>
                   {{ item.remark }}
+                  <div v-for="j in fileObj[item.flowExampleDetailId]" v-if="fileObj[item.flowExampleDetailId]">
+                    <a :href="j.fileUrl" style="color:#409EFF;line-height: 30px;">{{ j.fileName }}</a>
+                  </div>
                 </div>
               </div>
               <div class="line"></div>
             </li>
           </ul>
         </el-tab-pane>
-        <!-- v-if="flowForm.flowKey == 'contract_flow' && flowForm.tenantType !== 'EHSD'" -->
         <el-tab-pane label="决策辅助" name="second" v-if="auxiliaryData.length > 0">
           <div style="overflow: auto; height: calc(100vh - 200px)">
           <auxiliary :data="auxiliaryData"></auxiliary>
-
           </div>
-          <!-- <div style="overflow: auto; height: calc(100vh - 200px)">
-            <purchaseAuxiliary></purchaseAuxiliary>
-          </div> -->
         </el-tab-pane>
       </el-tabs>
     </div>
@@ -137,6 +150,8 @@ import PriceSheet from "@/components/process/PriceSheet";
 import PriceSheetEHSD from "@/components/process/EHSD/PriceSheet";
 // 销售合同
 import Contract from "@/components/process/Contract";
+// 销售合同-变更
+import ContractAlteration from "@/components/process/ContractAlteration";
 // 销售合同-EHSD
 import ContractEHSD from "@/components/process/EHSD/Contract";
 // 样品单-EHSD
@@ -160,6 +175,8 @@ let auxiliaryData = ref([]);
 const getAuxiliaryData = (data)=>{
   auxiliaryData.value=data
 }
+
+const btnLoading = ref(false)
 // 意见表单
 const flowForm = reactive({
   flowKey: "",
@@ -167,7 +184,10 @@ const flowForm = reactive({
   handleUserId: "",
   remark: "",
   data: {},
+  fileList:[],
 });
+
+const uploadData = ref({});
 const flowRules = reactive({
   // remark: [{ required: true, message: "请输入处理意见", trigger: "blur" }],
 });
@@ -194,6 +214,24 @@ const handleResult = (res) => {
     nextHandleUser.value = res.userList;
   }
 };
+
+
+const uploadFile = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  file.id = res.id;
+  file.fileName = res.fileName;
+  file.fileUrl = res.fileUrl;
+  file.uploadState = true;
+  return true;
+};
+const handleSuccess = (any, UploadFile) => {
+  UploadFile.raw.uploadState = false;
+};
+const onPreviewFile = (file) => {
+  window.open(file.raw.fileUrl, "_blank");
+};
+
 // 提交逻辑
 const handleSubmit = async (_type) => {
   try {
@@ -201,8 +239,9 @@ const handleSubmit = async (_type) => {
     const flag = await makeDom.value.handleSubmit();
     if (flag) {
       flowFormDom.value.validate((valid) => {
+        btnLoading.value  = true
         if (valid) {
-          const data = makeDom.value.getFormData();
+          const data = {...makeDom.value.getFormData()};
           if (flowForm.flowKey == "subscribe_flow") {
             // data.subscribeDetailList = data.subscribeDetailList.map((x) => ({
             //   bussinessId: x.bussinessId,
@@ -338,7 +377,21 @@ const handleSubmit = async (_type) => {
               };
             });
           }
+          flowForm.fileList = flowForm.fileList.map((item) => {
+            return {
+              ...item,
+              ...item.raw
+            };
+          });
           if (route.query.processType == 10 || route.query.processType == 30) {
+            if (_type && _type == 1) {
+              proxy
+                .post("/flowExample/setStartData", {
+                  exampleId: route.query.id,
+                  startData: data,
+                })
+                .then();
+            }
             proxy
               .post("/flowProcess/jump", {
                 ...flowForm,
@@ -349,15 +402,9 @@ const handleSubmit = async (_type) => {
               })
               .then((res) => {
                 handleResult(res);
+              },err=>{
+                 btnLoading.value  = false
               });
-            if (_type && _type == 1) {
-              proxy
-                .post("/flowExample/setStartData", {
-                  exampleId: route.query.id,
-                  startData: data,
-                })
-                .then();
-            }
             return;
           } else {
             proxy
@@ -367,6 +414,8 @@ const handleSubmit = async (_type) => {
               })
               .then((res) => {
                 handleResult(res);
+              },err=>{
+                 btnLoading.value  = false
               });
           }
         }
@@ -433,6 +482,10 @@ const skipPage = () => {
           path: "/ERP/saleContract/contract",
         });
       }
+    } else if (flowForm.flowKey == "contract_update_flow") {
+      router.replace({
+        path: "/ERP/saleContract/contract",
+      });
     } else if (flowForm.flowKey == "sample_flow") {
       router.replace({
         path: "/EHSD/saleContract/sampleEHSD",
@@ -461,6 +514,8 @@ let queryData = reactive({
 });
 // 记录
 const recordList = ref([]);
+const fileIds = ref([]);
+const fileObj = ref({}); 
 const approvalRecordData = ref({
   buttonInfoList: [],
 });
@@ -474,6 +529,14 @@ const getRecords = (_id) => {
         recordList.value = res.recordList;
         queryData.data.recordList = res.recordList;
         approvalRecordData.value = res;
+        fileIds.value = res.recordList.map((item) => {
+          return item.flowExampleDetailId;
+        });
+        proxy.post('fileInfo/getList',{businessIdList:fileIds.value}).then(res2=>{
+          console.log(res2)
+          fileObj.value = res2
+        })  
+        console.log(fileObj.value)
       });
   } else {
     proxy
@@ -499,8 +562,23 @@ onMounted(async () => {
   getRecords(route.query.id);
 });
 </script>
+<style>
+.el-upload-list{
+  float: left;
+  margin: 0!important;
+  
+}
+.el-upload-list li{
+  width:100px;
+  margin-left: 10px;
+}
+.el-upload--text{
+  float: left;
+}
 
+</style>
 <style lang="scss" scoped>
+
 .processApproval {
   display: flex;
   justify-content: space-between;
@@ -528,7 +606,7 @@ onMounted(async () => {
     }
     .bottom {
       margin-top: 10px;
-      height: 170px;
+      height: 220px;
       background: #fff;
       padding: 20px 20px 0px 20px;
     }

+ 135 - 53
src/views/product/material/index.vue

@@ -7,7 +7,8 @@
         :data="treeListData"
         v-model="sourceList.pagination.productClassifyId"
         @change="treeChange"
-        @changeTreeList="getTreeList">
+        @changeTreeList="getTreeList"
+      >
       </treeList>
     </div>
     <div class="content">
@@ -38,18 +39,35 @@
                 disabled: false,
               },
         ]"
-        @get-list="getList">
+        @get-list="getList"
+      >
         <template #pic="{ item }">
           <div v-if="item.fileList.length > 0">
-            <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
+            <img
+              :src="item.fileList[0].fileUrl"
+              class="pic"
+              @click="handleClickFile(item.fileList[0])"
+            />
           </div>
           <div v-else></div>
         </template>
       </byTable>
     </div>
-    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-model="dialogVisible" width="500" v-loading="loading" destroy-on-close>
+    <el-dialog
+      :title="modalType == 'add' ? '添加' : '编辑'"
+      v-model="dialogVisible"
+      width="500"
+      v-loading="loading"
+      destroy-on-close
+    >
       <div class="public_height_dialog">
-        <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
+        <byForm
+          :formConfig="formConfig"
+          :formOption="formOption"
+          v-model="formData.data"
+          :rules="rules"
+          ref="byform"
+        >
           <template #productPic>
             <div>
               <el-upload
@@ -59,7 +77,8 @@
                 list-type="picture-card"
                 :on-remove="handleRemove"
                 :on-success="handleSuccess"
-                :before-upload="handleBeforeUpload">
+                :before-upload="handleBeforeUpload"
+              >
                 <el-icon><Plus /></el-icon>
               </el-upload>
             </div>
@@ -69,13 +88,34 @@
 
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading"> 确 定 </el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
       </template>
     </el-dialog>
-    <el-dialog title="Excel导入" v-model="openExcelDialog" width="400" v-loading="loading">
+    <el-dialog
+      title="Excel导入"
+      v-model="openExcelDialog"
+      width="400"
+      v-loading="loading"
+    >
       <template #footer>
-        <el-button @click="openExcelDialog = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitExcel()" size="large" :loading="submitLoading"> 确 定 </el-button>
+        <el-button @click="openExcelDialog = false" size="large"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          @click="submitExcel()"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
       </template>
     </el-dialog>
   </div>
@@ -110,7 +150,9 @@ const materialUnit = ref([]);
 const materialType = ref([]);
 const treeData = ref([]);
 let rules = ref({
-  productClassifyId: [{ required: true, message: "请选择物料分类", trigger: "change" }],
+  productClassifyId: [
+    { required: true, message: "请选择物料分类", trigger: "change" },
+  ],
   type: [{ required: true, message: "请选择物料类型", trigger: "change" }],
   name: [{ required: true, message: "请输入物料名称", trigger: "blur" }],
   unit: [{ required: true, message: "请选择单位", trigger: "change" }],
@@ -145,15 +187,21 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "图片",
+        prop: "unit",
+        slot: "pic",
+      },
+    },
+    {
+      attrs: {
         label: "物料名称",
         prop: "name",
       },
     },
     {
       attrs: {
-        label: "图片",
-        prop: "unit",
-        slot: "pic",
+        label: "规格型号",
+        prop: "spec",
       },
     },
     {
@@ -167,12 +215,6 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "规格型号",
-        prop: "spec",
-      },
-    },
-    {
-      attrs: {
         label: "物料备注",
         prop: "remark",
       },
@@ -180,12 +222,26 @@ const config = computed(() => {
     {
       attrs: {
         label: "操作",
-        width: "200",
-        align: "right",
+        width: "160",
+        align: "center",
+        fixed: "right",
       },
       renderHTML(row) {
         return [
           props.selectStatus
+            ? {}
+            : {
+                attrs: {
+                  label: "复制",
+                  type: "primary",
+                  text: true,
+                },
+                el: "button",
+                click() {
+                  getDtlOne(row);
+                },
+              },
+          props.selectStatus
             ? {
                 attrs: {
                   label: "选择",
@@ -218,11 +274,15 @@ const config = computed(() => {
                 },
                 el: "button",
                 click() {
-                  ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                    confirmButtonText: "确定",
-                    cancelButtonText: "取消",
-                    type: "warning",
-                  }).then(() => {
+                  ElMessageBox.confirm(
+                    "此操作将永久删除该数据, 是否继续?",
+                    "提示",
+                    {
+                      confirmButtonText: "确定",
+                      cancelButtonText: "取消",
+                      type: "warning",
+                    }
+                  ).then(() => {
                     proxy
                       .post("/productInfo/delete", {
                         id: row.id,
@@ -322,29 +382,33 @@ const generatePassword = () => {
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/productInfo/page", sourceList.value.pagination).then((message) => {
-    console.log(message);
-    sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
-    sourceList.value.pagination.total = message.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
+  proxy
+    .post("/productInfo/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
 
-    const productIdList = message.rows.map((x) => x.id);
-    // 请求文件数据并回显
-    if (productIdList.length > 0) {
-      proxy.post("/fileInfo/getList", { businessIdList: productIdList }).then((fileObj) => {
-        for (let i = 0; i < sourceList.value.data.length; i++) {
-          const e = sourceList.value.data[i];
-          for (const key in fileObj) {
-            if (e.id === key) {
-              e.fileList = fileObj[key];
+      const productIdList = message.rows.map((x) => x.id);
+      // 请求文件数据并回显
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
+              }
             }
-          }
-        }
-      });
-    }
-  });
+          });
+      }
+    });
 };
 const uploadData = ref({});
 const fileList = ref([]);
@@ -410,10 +474,12 @@ const submitForm = () => {
 };
 
 const getTreeList = () => {
-  proxy.post("/productClassify/tree", { parentId: "", name: "", definition: "2" }).then((message) => {
-    treeListData.value = message;
-    treeData.value = message;
-  });
+  proxy
+    .post("/productClassify/tree", { parentId: "", name: "", definition: "2" })
+    .then((message) => {
+      treeListData.value = message;
+      treeData.value = message;
+    });
 };
 
 const getDtl = (row) => {
@@ -427,6 +493,20 @@ const getDtl = (row) => {
     dialogVisible.value = true;
   });
 };
+
+const getDtlOne = (row) => {
+  modalType.value = "add";
+  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+    fileList.value = [];
+    fileListCopy.value = [];
+    res.type = res.type + "";
+    res.definition = "2";
+    delete res.id;
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
 getTreeList();
 getList();
 const handleBeforeUpload = async (file) => {
@@ -449,7 +529,9 @@ const handleSuccess = (res, file, files) => {
 };
 
 const handleRemove = (file) => {
-  const index = fileListCopy.value.findIndex((x) => x.uid === file.uid || x.id === file.id);
+  const index = fileListCopy.value.findIndex(
+    (x) => x.uid === file.uid || x.id === file.id
+  );
   fileListCopy.value.splice(index, 1);
 };
 

+ 84 - 58
src/views/product/product/index.vue

@@ -19,7 +19,7 @@
         :loading="loading"
         highlight-current-row
         :selectConfig="selectConfig"
-        :statConfig='statConfig'
+        :statConfig="statConfig"
         :table-events="{
           //element talbe事件都能传
           select: select,
@@ -52,25 +52,25 @@
       </byTable>
     </div>
     <el-drawer v-model="retrievalModal" direction="rtl">
-			<template #header>
-				<h4>高级检索</h4>
-			</template>
-			<template #default>
-				<byForm
-					:formConfig="formConfig2"
-					:formOption="formOption"
-					v-model="sourceList.pagination"
-				>
-					<template #slot> 可自定义所需功能 </template>
-				</byForm>
-			</template>
-			<template #footer>
-				<div style="flex: auto">
-				<el-button @click="retrievalModal = false">取消</el-button>
-				<el-button type="primary" @click="getList">确认</el-button>
-				</div>
-			</template>
-		</el-drawer>
+      <template #header>
+        <h4>高级检索</h4>
+      </template>
+      <template #default>
+        <byForm
+          :formConfig="formConfig2"
+          :formOption="formOption"
+          v-model="sourceList.pagination"
+        >
+          <template #slot> 可自定义所需功能 </template>
+        </byForm>
+      </template>
+      <template #footer>
+        <div style="flex: auto">
+          <el-button @click="retrievalModal = false">取消</el-button>
+          <el-button type="primary" @click="getList">确认</el-button>
+        </div>
+      </template>
+    </el-drawer>
     <el-dialog
       :title="modalType == 'add' ? '添加' : '编辑'"
       v-model="dialogVisible"
@@ -160,11 +160,11 @@ const sourceList = ref({
     productClassifyId: "",
     keyword: "",
     definition: "1",
-    name:null,
-    customCode:null,
-    barCode:null,
-    englishName:null,
-    customsCode:null,
+    name: null,
+    customCode: null,
+    barCode: null,
+    englishName: null,
+    customsCode: null,
   },
 });
 const retrievalModal = ref(false);
@@ -207,15 +207,21 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "图片",
+        prop: "unit",
+        slot: "pic",
+      },
+    },
+    {
+      attrs: {
         label: "产品名称",
         prop: "name",
       },
     },
     {
       attrs: {
-        label: "图片",
-        prop: "unit",
-        slot: "pic",
+        label: "规格型号",
+        prop: "spec",
       },
     },
     {
@@ -229,28 +235,33 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "规格型号",
-        prop: "spec",
-      },
-    },
-    {
-      attrs: {
         label: "产品备注",
         prop: "remark",
       },
     },
-
     {
       attrs: {
         label: "操作",
-        width: "200",
-        align: "right",
+        width: "160",
+        align: "center",
+        fixed: "right",
       },
       // 渲染 el-button,一般用在最后一列。
       renderHTML(row) {
         return [
           {
             attrs: {
+              label: "复制",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtlOne(row);
+            },
+          },
+          {
+            attrs: {
               label: "修改",
               type: "primary",
               text: true,
@@ -298,7 +309,7 @@ const config = computed(() => {
     },
   ];
 });
-let statConfig = ref([])
+let statConfig = ref([]);
 const uploadData = ref({});
 const fileList = ref([]);
 const fileListCopy = ref([]);
@@ -306,30 +317,31 @@ const fileListCopy = ref([]);
 let formData = reactive({
   data: {},
 });
-const getproductInfoStatistics = (()=>{
-  proxy.post('/productInfo/productInfoStatistics').then(res=>{
-    statConfig.value = [{
-			label: '产品类型统计',
-			data:[
-				{
-					label:'合计',
-					num:res.amount,
-					type:1,
-				},
-			],
-		},]
+const getproductInfoStatistics = () => {
+  proxy.post("/productInfo/productInfoStatistics").then((res) => {
+    statConfig.value = [
+      {
+        label: "产品类型统计",
+        data: [
+          {
+            label: "合计",
+            num: res.amount,
+            type: 1,
+          },
+        ],
+      },
+    ];
     for (let i = 0; i < res.typeList.length; i++) {
       const element = res.typeList[i];
       statConfig.value[0].data.push({
-        label:element.type,
-        num:element.count,
-        type:i+ 2
-      })
+        label: element.type,
+        num: element.count,
+        type: i + 2,
+      });
     }
-    
-  })
-}) 
-getproductInfoStatistics()
+  });
+};
+getproductInfoStatistics();
 const formOption = reactive({
   inline: true,
   labelWidth: 100,
@@ -604,6 +616,20 @@ const getDtl = (row) => {
     dialogVisible.value = true;
   });
 };
+
+const getDtlOne = (row) => {
+  modalType.value = "add";
+  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+    fileList.value = [];
+    fileListCopy.value = [];
+    res.type = res.type + ""; //type回显
+    res.definition = "1"; //产品
+    res.standardJson = JSON.parse(res.standardJson);
+    delete res.id;
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
 getTreeList();
 getList();
 const handleBeforeUpload = async (file) => {

+ 36 - 11
src/views/product/product/index2.vue

@@ -179,14 +179,20 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "图片",
+        slot: "pic",
+      },
+    },
+    {
+      attrs: {
         label: "产品名称",
         prop: "name",
       },
     },
     {
       attrs: {
-        label: "图片",
-        slot: "pic",
+        label: "规格型号",
+        prop: "spec",
       },
     },
     {
@@ -200,28 +206,33 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "规格型号",
-        prop: "spec",
-      },
-    },
-    {
-      attrs: {
         label: "产品备注",
         prop: "remark",
       },
     },
-
     {
       attrs: {
         label: "操作",
-        width: "200",
-        align: "right",
+        width: "160",
+        align: "center",
+        fixed: "right",
       },
       // 渲染 el-button,一般用在最后一列。
       renderHTML(row) {
         return [
           {
             attrs: {
+              label: "复制",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtlOne(row);
+            },
+          },
+          {
+            attrs: {
               label: "修改",
               type: "primary",
               text: true,
@@ -477,6 +488,20 @@ const getDtl = (row) => {
     dialogVisible.value = true;
   });
 };
+const getDtlOne = (row) => {
+  modalType.value = "add";
+  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+    fileList.value = [];
+    fileListCopy.value = [];
+    res.type = res.type + ""; //type回显
+    res.definition = "1"; //产品
+    res.standardJson = JSON.parse(res.standardJson);
+    delete res.id;
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
 getTreeList();
 getList();
 const handleBeforeUpload = async (file) => {

+ 1 - 0
src/views/publicModule/codingRule/index.vue

@@ -349,6 +349,7 @@ const getCodingKey = () => {
   }
   return text;
 };
+
 </script>
 <style>
   .sortableActive{

+ 40 - 0
src/views/publicModule/salesman/index.vue

@@ -106,6 +106,22 @@ const formOption = reactive({
 const formConfig = computed(() => {
   return [
     {
+      type: "treeSelect",
+      prop: "deptId",
+      label: "部门名称",
+      data: [],
+      disabled:true,
+    },
+    {
+      type: "input",
+      prop: "nickName",
+      label: "姓名",
+      required: true,
+      itemWidth: 50,
+      disabled:true,
+      itemType: "text",
+    },
+    {
       type: "input",
       prop: "userCode",
       label: "业务员代码",
@@ -116,6 +132,30 @@ const formConfig = computed(() => {
 const rules = ref({
   userCode: [{ required: true, message: "请输入业务员代码", trigger: "blur" }],
 });
+const recursive = (data) => {
+  data.map((item) => {
+    item.label = item.deptName;
+    item.id = item.deptId;
+    if (item.children) {
+      recursive(item.children);
+    } else {
+      item.children = [];
+    }
+  });
+};
+const getDept = () => {
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      tenantId: sourceList.value.pagination.tenantId,
+    })
+    .then((message) => {
+      recursive(message.data);
+      formConfig.value[0].data = proxy.handleTree(message.data, "deptId");
+      console.log(formConfig.value[0].data);
+    });
+};
+getDept()
 const formData = reactive({
   data: {},
 });

+ 348 - 18
src/views/purchaseManage/purchaseManage/alreadyPurchase/index.vue

@@ -20,12 +20,12 @@
         ]"
         @get-list="getList"
       >
-        <template #fileSlot="{ item }">
+        <template #code="{ item }">
           <div
             style="cursor: pointer; color: #409eff"
-            @click="handleClickFile(item)"
+            @click="handleClickCode(item)"
           >
-            {{ item.fileName }}
+            {{ item.code }}
           </div>
         </template>
       </byTable>
@@ -86,7 +86,11 @@
             <el-table-column prop="productCode" label="货品编码" />
             <el-table-column prop="productName" label="货品名称" />
             <el-table-column prop="productSpec" label="规格型号" />
-            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column
+              prop="productUnit"
+              label="单位"
+              :formatter="(row) => dictValueLabel(row.productUnit, productUnit)"
+            />
             <el-table-column prop="purchaseCount" label="采购数量" />
             <el-table-column prop="sumArrivalCount" label="已到货" />
             <el-table-column prop="count" label="本次到货" min-width="150">
@@ -122,6 +126,200 @@
         </el-button>
       </template>
     </el-dialog>
+
+    <el-dialog title="打印" v-if="openPdf" v-model="openPdf" width="840px">
+      <!-- <div id="pdfDom" ref="pdfDom" style="width: 776px">
+        <div style="border: 1px solid #000; border-collapse: collapse">
+          <div style="text-align: right; padding: 2px 4px 0 0">
+            合同号:{{ pdfData.code }}
+          </div>
+          <div class="title">购销合同</div>
+          <div style="display: flex">
+            <div style="display: flex; width: 50%; padding-right: 20px">
+              <div style="width: 60px">买方:</div>
+              <div style="width: calc(100% - 60px)">
+                <div>福建宏星电子科技有限公司</div>
+                <div>福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层</div>
+              </div>
+            </div>
+            <div style="display: flex; width: 50%; padding-left: 20px">
+              <div style="width: 60px">卖方:</div>
+              <div style="width: calc(100% - 60px)">
+                {{ pdfData.supplyName }}
+              </div>
+            </div>
+          </div>
+          <div style="display: flex">
+            <div style="display: flex; width: 50%; padding-right: 20px">
+              <div style="width: 60px">经手人:</div>
+              <div style="width: calc(100% - 60px)">
+                {{ pdfData.purchaseName }}
+              </div>
+            </div>
+            <div style="display: flex; width: 50%; padding-left: 20px">
+              <div style="width: 60px">经手人:</div>
+              <div style="width: calc(100% - 60px)">
+                {{ pdfData.contactPerson }}
+              </div>
+            </div>
+          </div>
+          <div>买卖双方经协商,一致同意签订以下合同</div>
+          <div>货物名称、规格型号、单位、数量、单价及金额:</div>
+          <table border="1" style="width: 100%" class="table">
+            <tr>
+              <td style="width: 70px">序号</td>
+              <td>品名</td>
+              <td>规格型号</td>
+              <td style="width: 60px">单位</td>
+              <td style="width: 60px">数量</td>
+              <td style="width: 100px">单价</td>
+              <td style="width: 100px">金额</td>
+            </tr>
+            <tr
+              v-for="(row, index) in pdfData.purchaseDetailList"
+              :key="row.id"
+            >
+              <td style="width: 70px">{{ index + 1 }}</td>
+              <td>{{ row.productName }}</td>
+              <td>{{ row.productSpec }}</td>
+              <td style="width: 60px">{{ row.productUnitName }}</td>
+              <td style="width: 60px">{{ row.count }}</td>
+              <td style="width: 100px">
+                <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+                >{{ row.price }}
+              </td>
+              <td style="width: 100px">
+                <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+                >{{ row.amount }}
+              </td>
+            </tr>
+            <tr>
+              <td colspan="4" style="text-align: right">其他收费项目:</td>
+              <td></td>
+              <td></td>
+              <td>
+                <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+                >{{ pdfData.otherMoney }}
+              </td>
+            </tr>
+            <tr>
+              <td colspan="4" style="text-align: right">合计:</td>
+              <td>{{ pdfData.countTotal }}</td>
+              <td></td>
+              <td>
+                <span v-if="pdfData.currency">{{ pdfData.currency }}</span
+                >{{ pdfData.amount }}
+              </td>
+            </tr>
+            <tr>
+              <td colspan="7" style="text-align: left">
+                合计人民币金额(大写):{{ pdfData.moneyChinese }}
+              </td>
+            </tr>
+            <tr>
+              <td>交货地点:</td>
+              <td colspan="6" style="text-align: left">
+                福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层
+              </td>
+            </tr>
+            <tr>
+              <td>保修期:</td>
+              <td colspan="6" style="text-align: left">一年</td>
+            </tr>
+            <tr>
+              <td colspan="7" style="text-align: left; padding: 0px">
+                <div style="padding: 2px 0px">
+                  一、交货地点:福州软件园A区28座5层。
+                </div>
+                <div style="padding: 2px 0px">
+                  二、运输方式及运费:买方承担。
+                </div>
+                <div style="padding: 2px 0px">
+                  三、质量要求:样品品质、型号、规格、数量如同买方确认上表规格所示,不符合则由卖方承担责任。
+                </div>
+                <div style="padding: 2px 0px">
+                  四、交货时间:2023年4月13日。
+                </div>
+                <div style="padding: 2px 0px">五、付款方式:银行转账。</div>
+                <div style="padding: 2px 0px">六、保修期:一年。</div>
+                <div style="padding: 2px 0px">
+                  七、本合同经买卖双方签字盖章后生效,传真件有效。
+                </div>
+                <div style="padding: 2px 0px">
+                  八、解决合同纠纷:原双方另有约定外,均按《中华人民共和国合同法》有关规定处理。
+                </div>
+                <div style="padding: 2px 0px">九、其他约定事项:友好解决。</div>
+              </td>
+            </tr>
+          </table>
+          <div style="display: flex">
+            <div style="width: 50%; padding-right: 20px">
+              <div>买方:</div>
+              <div>单位名称:福建宏星电子科技有限公司</div>
+              <div>
+                地址:福建省福州市鼓楼区软件大道89号福州软件园A区28号楼五层
+              </div>
+              <div>电话:</div>
+              <div>传真:</div>
+              <div style="opacity: 0">|</div>
+              <div style="margin-top: auto">代表人签字:</div>
+            </div>
+            <div style="width: 50%; padding-left: 20px">
+              <div>卖方:</div>
+              <div>单位名称:{{ pdfData.supplyName }}</div>
+              <div>统一社会信用代码:</div>
+              <div>开户银行:{{ pdfData.openingBank }}</div>
+              <div>帐号:{{ pdfData.accountOpening }}</div>
+              <div>
+                地址:<span
+                  v-if="
+                    pdfData.supplyAddress && pdfData.supplyAddress.countryName
+                  "
+                  >{{ pdfData.supplyAddress.countryName }}</span
+                >
+                <span
+                  v-if="
+                    pdfData.supplyAddress && pdfData.supplyAddress.provinceName
+                  "
+                  >,{{ pdfData.supplyAddress.provinceName }}</span
+                >
+                <span
+                  v-if="pdfData.supplyAddress && pdfData.supplyAddress.cityName"
+                  >,{{ pdfData.supplyAddress.cityName }}</span
+                >
+                <span
+                  v-if="
+                    pdfData.supplyAddress && pdfData.supplyAddress.areaDetail
+                  "
+                  >,{{ pdfData.supplyAddress.areaDetail }}</span
+                >
+              </div>
+              <div>电话:{{ pdfData.contactNumber }}</div>
+              <div>代表人签字:</div>
+            </div>
+          </div>
+          <div
+            style="
+              padding: 30px 0px 20px 0;
+              text-align: right;
+              border-top: 1px solid #000;
+            "
+          >
+            签订日期:{{ pdfData.approvedDate }}
+          </div>
+        </div>
+      </div> -->
+      <PurchasePDF :rowData="rowData"></PurchasePDF>
+      <template #footer ref="printBtn">
+        <el-button @click="openPdf = false" size="large">关闭</el-button>
+        <el-button type="primary" v-print="printObj" size="large"
+          >打印</el-button
+        >
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
+      </template>
+    </el-dialog>
   </div>
 </template>
   
@@ -129,6 +327,8 @@
 import { ElMessage, ElMessageBox } from "element-plus";
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
+import { NumberToChinese } from "@/utils/util.js";
+import PurchasePDF from "@/components/PDF/purchasePDF.vue";
 
 const loading = ref(false);
 const submitLoading = ref(false);
@@ -219,6 +419,7 @@ const config = computed(() => {
       attrs: {
         label: "采购单号",
         prop: "code",
+        slot: "code",
       },
     },
     {
@@ -232,6 +433,7 @@ const config = computed(() => {
       attrs: {
         label: "采购金额",
         prop: "amount",
+        width: 120,
       },
       render(amount) {
         return proxy.moneyFormat(amount, 2);
@@ -247,12 +449,14 @@ const config = computed(() => {
       attrs: {
         label: "采购时间",
         prop: "createTime",
+        width: 155,
       },
     },
     {
       attrs: {
         label: "采购状态",
         prop: "purchaseStatus",
+        width: 80,
       },
       render(status) {
         return proxy.dictValueLabel(status, statusData.value);
@@ -263,6 +467,7 @@ const config = computed(() => {
       attrs: {
         label: "到货状态",
         prop: "arrivalStatus",
+        width: 80,
       },
       render(status) {
         return proxy.dictValueLabel(status, arrivalStatus.value);
@@ -272,31 +477,45 @@ const config = computed(() => {
       attrs: {
         label: "付款状态",
         prop: "payStatus",
+        width: 80,
       },
       render(status) {
         return proxy.dictValueLabel(status, paymentStatus.value);
       },
     },
-
     {
       attrs: {
         label: "操作",
-        width: "200",
-        align: "right",
+        width: "250",
+        align: "center",
+        fixed: "right",
       },
       renderHTML(row) {
         return [
           {
             attrs: {
-              label: "到货通知",
+              label: "打印",
               type: "primary",
               text: true,
             },
             el: "button",
             click() {
-              handleArrival(row);
+              handlePrintPdf(row);
             },
           },
+          row.purchaseStatus == 30
+            ? {
+                attrs: {
+                  label: "到货通知",
+                  type: "primary",
+                  text: true,
+                },
+                el: "button",
+                click() {
+                  handleArrival(row);
+                },
+              }
+            : {},
           {
             attrs: {
               label: "作废",
@@ -461,14 +680,20 @@ const handleEdit = (row, status) => {
   });
 };
 
-// 获取供应商数据
 const supplierData = ref([]);
-const getSupplierList = async (req) => {
+const productUnit = ref([]);
+const getDict = async (req) => {
   proxy
     .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
     .then((res) => {
       supplierData.value = res.rows;
     });
+  proxy.getDictOne(["unit"]).then((res) => {
+    productUnit.value = res["unit"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
 };
 const handleArrival = (row) => {
   proxy.post("/purchase/detail", { id: row.id }).then((res) => {
@@ -476,12 +701,16 @@ const handleArrival = (row) => {
       purchaseId: row.id,
       code: res.code,
       supplyId: res.supplyId,
-      arrivalDetailList: res.purchaseDetailList.map((x) => ({
-        ...x,
-        purchaseDetailId: x.id,
-        purchaseCount: x.count,
-        count: Number(x.count) - Number(x.sumArrivalCount),
-      })),
+      arrivalDetailList: res.purchaseDetailList.map((x) => {
+        let obj = {
+          ...x,
+          purchaseDetailId: x.id,
+          purchaseCount: x.count,
+          count: Number(x.count) - Number(x.sumArrivalCount),
+        };
+        delete obj.status;
+        return obj;
+      }),
       arrivalStatus: "",
     };
     dialogVisible.value = true;
@@ -489,7 +718,7 @@ const handleArrival = (row) => {
 };
 
 getList();
-getSupplierList();
+getDict();
 const start = () => {
   proxy.$router.replace({
     path: "/platform_manage/process/processApproval",
@@ -501,10 +730,111 @@ const start = () => {
     },
   });
 };
+
+const handleClickCode = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: row.processInstanceId,
+      id: row.flowId,
+      processType: 20,
+    },
+  });
+};
+
+const openPdf = ref(false);
+const pdfData = ref({});
+const rowData = ref({});
+const handlePrintPdf = (row) => {
+  rowData.value = {
+    id: row.id,
+    code: row.code,
+  };
+  openPdf.value = true;
+  // proxy.post("/purchase/detail", { id: row.id }).then((res) => {
+  //   proxy
+  //     .post("/supplierInfo/detail", { id: res.supplyId })
+  //     .then((supplyData) => {
+  //       res.contactPerson = supplyData.contactPerson;
+  //       res.contactNumber = supplyData.contactNumber;
+  //       res.openingBank = supplyData.openingBank;
+  //       res.accountOpening = supplyData.accountOpening;
+  //       let countTotal = 0;
+  //       let productMoney = 0;
+  //       for (let i = 0; i < res.purchaseDetailList.length; i++) {
+  //         const e = res.purchaseDetailList[i];
+  //         e.productUnitName = proxy.dictValueLabel(
+  //           e.productUnit,
+  //           productUnit.value
+  //         );
+  //         countTotal += Number(e.count);
+  //         productMoney += Number(e.amount);
+  //       }
+  //       res.countTotal = countTotal;
+  //       res.productMoney = productMoney;
+  //       res.otherMoney = res.amount - res.productMoney;
+  //       res.moneyChinese = NumberToChinese(res.amount);
+  //       res.supplyAddress = {
+  //         countryName: supplyData.countryName,
+  //         provinceName: supplyData.provinceName,
+  //         cityName: supplyData.cityName,
+  //         areaDetail: supplyData.areaDetail,
+  //       };
+  //       if (res.approvedDate) {
+  //         res.approvedDate = res.approvedDate.slice(0, 10);
+  //       }
+  //       pdfData.value = res;
+  //       openPdf.value = true;
+  //     });
+  // });
+};
+const clickDownload = () => {
+  proxy.getPdf("购销合同" + rowData.value.code);
+};
+const pdfDom = ref(null);
+const printObj = ref({
+  id: "pdfDom",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
 </script>
   
 <style lang="scss" scoped>
 .tenant {
   padding: 20px;
 }
+#pdfDom {
+  font-size: 12px;
+  color: #000000;
+  padding: 60px 30px;
+  .title {
+    font-size: 16px;
+    font-weight: 700;
+    margin-top: 10px;
+    margin-bottom: 20px;
+    text-align: center;
+  }
+  .table {
+    // width: calc(100% + 2px) !important;
+    border-collapse: collapse;
+    border-spacing: 0;
+    // margin-left: -1px;
+    // margin-right: -1px;
+
+    td {
+      text-align: center;
+      padding: 8px 0px;
+    }
+    // tr td:last-child {
+    //   border-right: 0 !important;
+    // }
+  }
+  .flex-top-bottom {
+    display: flex;
+    justify-content: space-between;
+    margin: 5px 0px;
+  }
+}
 </style>

+ 53 - 5
src/views/purchaseManage/purchaseManage/handoverSlip/index.vue

@@ -6,6 +6,7 @@
       :config="config"
       :loading="loading"
       highlight-current-row
+      :selectConfig="selectConfig"
       :row-class-name="getRowClass"
       :table-events="{
         select: selectRow,
@@ -31,8 +32,21 @@
       </template>
       <template #details="{ item }">
         <div>
-          <el-button type="primary" link v-if="item.expendQuantity > 0" @click="handleClickDetails(item)">查看</el-button>
-          <el-button type="primary" link style="color: #f54a45" v-else @click="handleClickDetails(item)">查看</el-button>
+          <el-button
+            type="primary"
+            link
+            v-if="item.expendQuantity >= 0"
+            @click="handleClickDetails(item)"
+            >查看</el-button
+          >
+          <el-button
+            type="primary"
+            link
+            style="color: #f54a45"
+            v-else
+            @click="handleClickDetails(item)"
+            >查看</el-button
+          >
         </div>
       </template>
       <template #btn="{ item }">
@@ -40,6 +54,14 @@
           <el-button type="primary" link @click="start(10, item)">采购</el-button>
           <el-button type="primary" link @click="transferToProduction(item)">转生产</el-button>
         </div>
+        <div v-else-if="item.expendQuantity == 0">
+          <el-button type="primary" link @click="handleFollow(item)"
+            >跟进</el-button
+          >
+          <el-button type="primary" link @click="lookRecords(item)"
+            >跟进记录</el-button
+          >
+        </div>
         <div v-else>
           <el-button type="primary" link style="color: #f54a45" @click="handleFollow(item)">跟进</el-button>
           <el-button type="primary" link style="color: #f54a45" @click="lookRecords(item)">跟进记录</el-button>
@@ -141,7 +163,6 @@ import byForm from "@/components/byForm/index";
 import { computed, nextTick, ref } from "vue";
 import { ElMessage } from "element-plus";
 import Editor from "@/components/Editor/index.vue";
-import { async } from "@antv/x6/lib/registry/marker/async";
 
 const { proxy } = getCurrentInstance();
 const loading = ref(false);
@@ -154,6 +175,23 @@ const sourceList = ref({
     status: "15",
   },
 });
+const isReceivedArr = ref([
+  { label: "是", value: "1" },
+  { label: "否", value: "0" },
+]);
+const corporationArr = ref([]);
+const selectConfig = computed(() => [
+  {
+    label: "归属公司",
+    prop: "corporationId",
+    data: corporationArr.value,
+  },
+  {
+    label: "是否到账",
+    prop: "isReceived",
+    data: isReceivedArr.value,
+  },
+]);
 const config = computed(() => {
   return [
     {
@@ -263,6 +301,15 @@ const getList = async (req) => {
 getList();
 const productUnit = ref([]);
 const getDict = () => {
+  proxy
+    .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      corporationArr.value = res.rows.map((x) => ({
+        ...x,
+        label: x.name,
+        value: x.id,
+      }));
+    });
   proxy.getDictOne(["unit"]).then((res) => {
     productUnit.value = res["unit"].map((x) => ({
       label: x.dictValue,
@@ -389,14 +436,15 @@ const lookRecords = (row) => {
       contractProductId: row.productId,
     })
     .then((res) => {
-      if (res.length > 0) {
+      if (res && res.length > 0) {
         activities.value = res;
         dialogVisibleTwo.value = true;
-      } else
+      } else {
         return ElMessage({
           message: "暂无跟进记录!",
           type: "info",
         });
+      }
     });
 };
 const handleFollow = (row) => {

+ 4 - 1
src/views/purchaseManage/purchaseManage/purchase/index.vue

@@ -156,7 +156,7 @@ const sourceList = ref({
     total: 3,
     pageNum: 1,
     pageSize: 10,
-    status: "15",
+    status: "15,30",
   },
 });
 let dialogVisible = ref(false);
@@ -356,6 +356,9 @@ const formConfig = computed(() => {
   ];
 });
 const getList = async (req) => {
+  if (req && !req.status) {
+    req.status = "15,30";
+  }
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
   proxy

+ 24 - 4
src/views/purchaseManage/purchaseManage/returnGoods/index.vue

@@ -172,6 +172,21 @@ const statusData = ref([
     value: "50",
   },
 ]);
+const refundStatus = ref([
+  {
+    label: "未退款",
+    value: "0",
+  },
+  {
+    label: "部分退款",
+    value: "10",
+  },
+  {
+    label: "已退款",
+    value: "20",
+  },
+]);
+
 const selectConfig = reactive([
   {
     label: "退货状态",
@@ -210,6 +225,7 @@ const config = computed(() => {
       attrs: {
         label: "单位",
         prop: "productUnit",
+        width: 100,
       },
       render(unit) {
         return proxy.dictDataEcho(unit, productUnit.value);
@@ -219,12 +235,14 @@ const config = computed(() => {
       attrs: {
         label: "退货数量",
         prop: "count",
+        width: 100,
       },
     },
     {
       attrs: {
         label: "退货状态",
         prop: "status",
+        width: 90,
       },
       render(status) {
         return proxy.dictValueLabel(status, statusData.value);
@@ -233,16 +251,17 @@ const config = computed(() => {
     {
       attrs: {
         label: "退款状态",
-        prop: "payStatus",
+        prop: "refundStatus",
+        width: 90,
       },
-      render() {
-        return "暂无";
+      render(status) {
+        return proxy.dictValueLabel(status, refundStatus.value);
       },
     },
     {
       attrs: {
         label: "操作人",
-        prop: "createUser",
+        prop: "opUserName",
       },
       //      render() {
       //   return "暂无";
@@ -252,6 +271,7 @@ const config = computed(() => {
       attrs: {
         label: "操作时间",
         prop: "createTime",
+        width: 155,
       },
     },
 

+ 3 - 51
src/views/purchaseManage/purchasePayment/payment/index.vue

@@ -156,6 +156,7 @@ import { computed, ref } from "vue";
 import byTable from "@/components/byTable/index";
 import useUserStore from "@/store/modules/user";
 import moment from "moment";
+import { NumberToChinese } from "@/utils/util.js";
 
 const { proxy } = getCurrentInstance();
 const payStatus = ref([]);
@@ -462,57 +463,8 @@ const computeMoney = () => {
   }
   return money;
 };
-const toDx = (n) => {
-  //阿拉伯数字转换函数
-  switch (n) {
-    case "0":
-      return "零";
-    case "1":
-      return "壹";
-    case "2":
-      return "贰";
-    case "3":
-      return "叁";
-    case "4":
-      return "肆";
-    case "5":
-      return "伍";
-    case "6":
-      return "陆";
-    case "7":
-      return "柒";
-    case "8":
-      return "捌";
-    case "9":
-      return "玖";
-  }
-};
-const NumberToChinese = (m) => {
-  let unit = ["仟", "佰", "拾", "", "仟", "佰", "拾", "", "角", "分", "厘"];
-  m *= 1000;
-  m = Number(parseFloat(m).toFixed(0));
-  m += "";
-  var x = m.length;
-  var result = "";
-  for (var i = 0; i < x; i++) {
-    if (i == 3) {
-      result = "元" + result;
-    } else if (i == 7) {
-      result = "万" + result;
-    }
-    if (m.charAt(x - i - 1) == 0) {
-      if (i != 0 && i != 1 && i != 2) {
-        if (result.charAt(0) != "零" && result.charAt(0) != "元" && result.charAt(0) != "万") {
-          result = "零" + result;
-        }
-      }
-      continue;
-    }
-    result = toDx(m.charAt(x - i - 1)) + unit[unit.length - i - 1] + result;
-  }
-  result += result.charAt(result.length - 1) == "元" ? "整" : "";
-  return result;
-};
+
+
 </script>
 
 <style lang="scss" scoped>

+ 1 - 1
src/views/purchaseManage/supplier/supplyPrice/index.vue

@@ -42,7 +42,7 @@
                 <el-table-column prop="price" label="供应单价" min-width="150">
                   <template #default="{ row, $index }">
                     <el-form-item :prop="'supplierPriceList.' + $index + '.price'" :rules="rules.price" :inline-message="true">
-                      <el-input-number v-model="row.price" :precision="2" :controls="false" :min="1" />
+                      <el-input-number v-model="row.price" :precision="2" :controls="false" :min="1"  onmousewheel="return false;" />
                     </el-form-item>
                   </template>
                 </el-table-column>

+ 165 - 11
src/views/purchaseSales/outAndInWarehouse/record/index.vue

@@ -25,11 +25,74 @@
         </template>
       </byTable>
     </div>
+
+    <el-dialog title="打印" v-if="openPdf" v-model="openPdf" width="840px">
+      <div id="pdfDom" ref="pdfDom" style="width: 776px">
+        <div class="title">
+          {{ dictValueLabel(printData.type, typeList) }}单
+        </div>
+        <div class="flex-top-bottom">
+          <div>
+            <span v-show="printData.corporateName && printData.code">
+              {{ printData.corporateName }} ({{ printData.code }})</span
+            >
+          </div>
+          <div>{{ printData.createTime }}</div>
+        </div>
+        <table border="1" style="width: 100%" class="table">
+          <tr>
+            <td style="width: 80px">物品编码</td>
+            <td>物品名称</td>
+            <td>规格型号</td>
+            <td style="width: 60px">单位</td>
+            <td style="width: 60px">数量</td>
+            <td style="width: 70px">单价</td>
+            <td style="width: 90px">金额</td>
+          </tr>
+          <tr v-for="(row, index) in printData.list" :key="row.id">
+            <td>{{ row.productCode }}</td>
+            <td>{{ row.productName }}</td>
+            <td>{{ row.productSpec }}</td>
+            <td>{{ dictValueLabel(row.productUnit, productUnit) }}</td>
+            <td>{{ row.quantity }}</td>
+            <td>
+              <!-- {{ dictValueLabel(printData.currency, currencyType) }} -->
+              <span v-show="row.price">
+                {{ printData.currency }}
+                {{ row.price }}
+              </span>
+            </td>
+            <td>
+              <!-- {{ dictValueLabel(printData.currency, currencyType) }} -->
+              <span v-show="row.amount">
+                {{ printData.currency }}
+                {{ row.amount }}
+              </span>
+            </td>
+          </tr>
+        </table>
+        <div class="flex-top-bottom">
+          <div>仓库名称:{{ printData.warehouseName }}</div>
+          <div>
+            合计金额:{{ getTotalAmount(printData.currency, printData.list) }}
+          </div>
+        </div>
+      </div>
+      <template #footer ref="printBtn">
+        <el-button @click="openPdf = false" size="large">关闭</el-button>
+        <el-button type="primary" v-print="printObj" size="large"
+          >打印</el-button
+        >
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { computed, ref } from "vue";
+import { computed, nextTick, ref, toRef } from "vue";
 import byTable from "@/components/byTable/index";
 
 const { proxy } = getCurrentInstance();
@@ -106,12 +169,21 @@ const typeList = ref([
     value: "15",
   },
   {
+    label: "采购到货",
+    value: "18",
+  },
+  {
+    label: "到货质检",
+    value: "19",
+  },
+  {
     label: "生产任务出库",
     value: "20",
   },
 ]);
 const warehouseList = ref([]);
 const productUnit = ref([]);
+const currencyType = ref([]);
 const sourceList = ref({
   data: [],
   pagination: {
@@ -124,6 +196,8 @@ const sourceList = ref({
   },
 });
 const loading = ref(false);
+const openPdf = ref(false);
+let printData = ref({});
 const selectConfig = computed(() => {
   return [
     {
@@ -144,7 +218,7 @@ const config = computed(() => {
       attrs: {
         label: "操作类型",
         prop: "opType",
-        width: 140,
+        width: 80,
       },
       render(type) {
         return proxy.dictValueLabel(type, opTypeList.value);
@@ -154,7 +228,7 @@ const config = computed(() => {
       attrs: {
         label: "出入库类型",
         prop: "type",
-        width: 140,
+        width: 130,
       },
       render(type) {
         return proxy.dictValueLabel(type, typeList.value);
@@ -164,35 +238,32 @@ const config = computed(() => {
       attrs: {
         label: "仓库名称",
         slot: "warehouseName",
-        width: 200,
       },
     },
     {
       attrs: {
         label: "物品编码",
         prop: "productCode",
-        width: 160,
+        width: 110,
       },
     },
     {
       attrs: {
         label: "物品名称",
         prop: "productName",
-        "min-width": 220,
       },
     },
     {
       attrs: {
         label: "规格型号",
         prop: "productSpec",
-        width: 160,
       },
     },
     {
       attrs: {
         label: "单位",
         prop: "productUnit",
-        width: 120,
+        width: 80,
       },
       render(unit) {
         return proxy.dictValueLabel(unit, productUnit.value);
@@ -209,14 +280,36 @@ const config = computed(() => {
       attrs: {
         label: "操作人",
         prop: "opUserName",
-        width: 120,
+        width: 130,
       },
     },
     {
       attrs: {
         label: "操作时间",
         prop: "createTime",
-        width: 160,
+        width: 155,
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "打印",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handlePrintPdf(row);
+            },
+          },
+        ];
       },
     },
   ];
@@ -232,11 +325,15 @@ const getDict = () => {
       });
     }
   });
-  proxy.getDictOne(["unit"]).then((res) => {
+  proxy.getDictOne(["unit", "account_currency"]).then((res) => {
     productUnit.value = res["unit"].map((x) => ({
       label: x.dictValue,
       value: x.dictKey,
     }));
+    currencyType.value = res["account_currency"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
   });
 };
 const getList = async (req) => {
@@ -260,9 +357,42 @@ onMounted(() => {
   }
   getList();
 });
+
 const deriveExcel = () => {
   console.log("deriveExcel");
 };
+
+const handlePrintPdf = (row) => {
+  proxy.post("/stockJournal/detail", { id: row.stockJournalId }).then((res) => {
+    printData.value = res;
+    printData.value.createTime = printData.value.createTime.slice(0, 10);
+    openPdf.value = true;
+  });
+};
+
+const getTotalAmount = (currency, arr) => {
+  let total = arr.reduce((total, cur) => (total += cur.amount), 0);
+  total = total ? total : "";
+  if (currency && total) {
+    return currency + " " + proxy.moneyFormat(total, 2);
+  } else {
+    return proxy.moneyFormat(total, 2);
+  }
+};
+
+const clickDownload = () => {
+  proxy.getPdf(
+    proxy.dictValueLabel(printData.value.type, typeList.value) + "单"
+  );
+};
+const pdfDom = ref(null);
+const printObj = ref({
+  id: "pdfDom",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
 </script>
 
 <style lang="scss" scoped>
@@ -272,4 +402,28 @@ const deriveExcel = () => {
 ::v-deep(.el-input-number .el-input__inner) {
   text-align: left;
 }
+#pdfDom {
+  font-size: 12px;
+  color: #000000;
+  padding: 60px 30px;
+  .title {
+    font-size: 16px;
+    // font-weight: 700;
+    margin-bottom: 20px;
+    text-align: center;
+  }
+  .table {
+    border-collapse: collapse;
+    border-spacing: 0;
+    td {
+      text-align: center;
+      padding: 8px 0px;
+    }
+  }
+  .flex-top-bottom {
+    display: flex;
+    justify-content: space-between;
+    margin: 5px 0px;
+  }
+}
 </style>

+ 220 - 241
src/views/salesMange/saleContract/contract/index.vue

@@ -14,16 +14,41 @@
             action: () => newContract(),
           },
         ]"
-        @get-list="getList">
+        @get-list="getList"
+      >
+        <!-- <template #code="{ item }">
+          <div style="width: 100%">
+            <a
+              style="color: #409eff; cursor: pointer; word-break: break-all"
+              @click="pushProcessApproval(item)"
+              >{{ item.code }}</a
+            >
+          </div>
+        </template> -->
+        <template #code="{ item }">
+          <div style="width: 100%">
+            <a
+              style="color: #409eff; cursor: pointer; word-break: break-all"
+              @click="openDetails(item)"
+              >{{ item.code }}</a
+            >
+          </div>
+        </template>
         <template #amount="{ item }">
           <div>
             <span style="padding-right: 4px">{{ item.currency }}</span>
             <span>{{ moneyFormat(item.amount, 2) }}</span>
           </div>
         </template>
+        <template #amountCNY="{ item }">
+          <div>
+            <!-- <span style="padding-right: 4px">{{ item.currency }}</span> -->
+            <span>{{ moneyFormat(item.amountCNY, 2) }}</span>
+          </div>
+        </template>
         <template #sumClaimMoney="{ item }">
           <div>
-            <span style="padding-right: 4px">{{ item.currency }}</span>
+            <!-- <span style="padding-right: 4px">{{ item.currency }}</span> -->
             <span>{{ moneyFormat(item.sumClaimMoney, 2) }}</span>
           </div>
         </template>
@@ -37,198 +62,40 @@
             <span v-if="item.refundStatus && item.refundStatus !== 0">
               {{ dictValueLabel(item.refundStatus, refundStatusNew) }}
             </span>
-            <span v-else>{{ dictValueLabel(item.refundStatusNew, refundStatusNew) }}</span>
+            <span v-else>{{
+              dictValueLabel(item.refundStatusNew, refundStatusNew)
+            }}</span>
+          </div>
+        </template>
+        <template #status="{ item }">
+          <div>
+            <span :style="getStyle(item.status)">{{
+              dictValueLabel(item.status, status)
+            }}</span>
           </div>
         </template>
       </byTable>
     </div>
 
     <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="860">
-      <div id="pdfDom" style="width: 800px; padding: 16px; font-size: 12px !important">
-        <div style="font-size: 18px; text-align: center">
-          {{ printDetails.sellCorporationNameEn }}
-        </div>
-        <div style="text-align: center">
-          {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellDetailedAddress }}
-        </div>
-        <div style="font-size: 14px; color: #409eff; text-align: center; padding-top: 16px">PROFORMA INVOICE</div>
-        <div style="padding-top: 8px">
-          <div>PI NO. : {{ printDetails.contractCode }}</div>
-          <div>PI DATE: {{ printDetails.createTimeEn }}</div>
-        </div>
-        <div style="border: 1px solid black; display: flex">
-          <div style="width: 50%; border-right: 1px solid black">
-            <div style="color: #409eff">VENDOR:</div>
-            <div>{{ printDetails.sellCorporationNameEn }}</div>
-            <div style="padding: 16px 0">
-              {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellDetailedAddress }}
-            </div>
-            <div>CONTACT: {{ printDetails.sellContactName }}</div>
-            <div>TEL.: {{ printDetails.sellContactNumber }}</div>
-          </div>
-          <div style="width: 50%">
-            <div style="color: #409eff">BUYER:</div>
-            <div>{{ printDetails.buyCorporationName }}</div>
-            <div style="padding: 16px 0">
-              {{ printDetails.buyDetailedAddress }},{{ printDetails.buyCityName }},{{ printDetails.buyProvinceName }},{{ printDetails.buyCountryName }}
-            </div>
-            <div>CONTACT: {{ printDetails.buyContactName }}</div>
-            <div>TEL.: {{ printDetails.buyContactNumber }}</div>
-          </div>
-        </div>
-        <div style="height: 16px"></div>
-        <div style="border: 1px solid black">
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">COUNTRY OF ORIGIN:</div>
-              <div>{{ printDetails.sellCountryName }}</div>
-            </div>
-            <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">COUNTRY OF DESTINATION:</div>
-              <div>{{ printDetails.buyCountryName }}</div>
-            </div>
-            <div style="width: 33%; border-bottom: 1px solid black">
-              <div style="color: #409eff">PLACE OF DISCHARGE:</div>
-              <div>{{ printDetails.transportRemark }}</div>
-            </div>
-          </div>
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">TERMS OF DELIVERY:</div>
-              <div>
-                {{ dictValueLabel(printDetails.tradeMethods, tradeMethods) }}
-              </div>
-            </div>
-            <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">CURRENCY:</div>
-              <div>
-                {{ printDetails.currency }}
-              </div>
-            </div>
-            <div style="width: 33%; border-bottom: 1px solid black">
-              <div style="color: #409eff">EXPORT BY/VIA:</div>
-              <div>
-                {{ dictValueLabel(printDetails.transportMethod, shippingMethod) }}
-              </div>
-            </div>
-          </div>
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-right: 1px solid black">
-              <div style="color: #409eff">DELIVERY TIME:</div>
-              <div>{{ printDetails.deliveryTime }}</div>
-            </div>
-            <div style="width: 67%">
-              <div style="color: #409eff">TERMS OF PAYMENT:</div>
-              <div>{{ printDetails.remark }}</div>
-            </div>
-          </div>
-        </div>
-        <div style="height: 16px"></div>
-        <div class="baseRow" style="display: flex; color: #409eff">
-          <div class="contentRow" style="width: 50px; text-align: center">NO.</div>
-          <div class="contentRow" style="width: calc(100% - 450px); text-align: center">COMMODITY, SPECIFICATION</div>
-          <div class="contentRow" style="width: 100px; text-align: center">UNIT</div>
-          <div class="contentRow" style="width: 100px; text-align: center">QUANTITY</div>
-          <div class="contentRow" style="width: 100px; text-align: center">UNIT PRICE</div>
-          <div class="contentRow" style="width: 100px; text-align: center">TOTAL PRICE</div>
-        </div>
-        <div v-if="printDetails.productInfoList && printDetails.productInfoList.length > 0">
-          <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.productInfoList" :key="item.productId">
-            <div class="contentRow" style="width: 50px; text-align: center">
-              {{ index + 1 }}
-            </div>
-            <div class="contentRow" style="width: calc(100% - 450px); text-align: center">
-              {{ item.productName }}
-            </div>
-            <div class="contentRow" style="width: 100px; text-align: center">
-              {{ dictValueLabel(item.productUnit, productUnit) }}
-            </div>
-            <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.productQuantity }}
-            </div>
-            <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.productPrice }}
-            </div>
-            <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.amount }}
-            </div>
-          </div>
-        </div>
-        <div class="baseRow" style="display: flex; color: #409eff">
-          <div class="contentRow" style="width: calc(100% - 400px); text-align: center">SUBTOTAL:</div>
-          <div class="contentRow" style="width: 100px; text-align: center"></div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ statistics("productQuantity", 0) }}
-          </div>
-          <div class="contentRow" style="width: 100px; text-align: center"></div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ statistics("amount", 2) }}
-          </div>
-        </div>
-        <!-- <div v-if="printDetails.quotationPayList && printDetails.quotationPayList.length > 0">
-          <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.quotationPayList" :key="index">
-            <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">{{ item.payName }}:</div>
-            <div class="contentRow" style="width: 100px; text-align: center">{{ item.amount }}</div>
-          </div>
-        </div> -->
-        <div class="baseRow" style="display: flex">
-          <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">FREIGHT COST:</div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ statisticsTwo("amount", 2) }}
-          </div>
-        </div>
-        <div class="baseRow" style="display: flex">
-          <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">TOTAL PRICE:</div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ printDetails.totalAmount }}
-          </div>
-        </div>
-        <div class="baseRow" style="display: flex; border-bottom: 1px solid black">
-          <div class="contentRow" style="width: 100%">
-            {{ translateIntoEnglish(printDetails.totalAmount, printDetails.currency) }}
-          </div>
-        </div>
-        <div style="height: 16px"></div>
-        <div class="baseRow" style="color: #409eff">
-          <div class="contentRow" style="width: 100%">ACCOUNT INFORMATION:</div>
-        </div>
-        <div class="baseRow" style="border-bottom: 1px solid black">
-          <div class="contentRow" style="width: 100%">
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Name: {{ printDetails.beneficiaryName }}
-            </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Bank: {{ printDetails.beneficiaryBank }}
-            </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Bank Address: {{ printDetails.beneficiaryBankAddress }}
-            </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Account Number: {{ printDetails.beneficiaryAccountNumber }}
-            </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">Swift Code: {{ printDetails.swiftCode }}</div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Address: {{ printDetails.beneficiaryAddress }}
-            </div>
-          </div>
-        </div>
-        <div style="height: 32px"></div>
-        <div style="display: flex">
-          <div style="width: 50%">
-            <div style="color: #409eff">CONFIRMED BY VENDOR:</div>
-            <div>{{ printDetails.sellCorporationNameEn }}</div>
-          </div>
-          <div style="width: 50%">
-            <div style="color: #409eff">CONFIRMED BY BUYER:</div>
-            <div>{{ printDetails.buyCorporationName }}</div>
-          </div>
-        </div>
-      </div>
+      <ContractPDF :rowData="rowData"></ContractPDF>
       <template #footer>
         <el-button @click="openPrint = false" size="large">取消</el-button>
-        <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
+        <el-button v-print="printObj" size="large">打印</el-button>
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
       </template>
     </el-dialog>
+
+    <el-dialog
+      title="合同详情"
+      v-if="openDetailsDialog"
+      v-model="openDetailsDialog"
+      width="1000"
+    >
+      <ContractDetails :contractId="currentContractId"></ContractDetails>
+    </el-dialog>
   </div>
 </template>
 
@@ -237,8 +104,9 @@ import { computed, ref } from "vue";
 import byTable from "@/components/byTable/index";
 import useUserStore from "@/store/modules/user";
 import { ElMessage, ElMessageBox } from "element-plus";
+import ContractDetails from "@/components/contractCom/contractDetails.vue";
+import ContractPDF from "@/components/PDF/contractPDF.vue";
 const route = useRoute();
-
 const { proxy } = getCurrentInstance();
 const contractType = ref([]);
 const accountCurrency = ref([]);
@@ -248,6 +116,7 @@ const customerList = ref([]);
 const shippingMethod = ref([]);
 const productUnit = ref([]);
 const userList = ref([]);
+const openDetailsDialog = ref(false);
 const status = ref([
   {
     label: "草稿",
@@ -266,6 +135,10 @@ const status = ref([
     value: 30,
   },
   {
+    label: "作废",
+    value: 70,
+  },
+  {
     label: "终止",
     value: 99,
   },
@@ -340,7 +213,7 @@ const config = computed(() => {
     {
       attrs: {
         label: "合同编码",
-        prop: "code",
+        slot: "code",
         width: 180,
       },
     },
@@ -354,25 +227,32 @@ const config = computed(() => {
         return proxy.dictValueLabel(type, customerList.value);
       },
     },
+    // {
+    //   attrs: {
+    //     label: "版本号",
+    //     prop: "version",
+    //     width: 80,
+    //   },
+    // },
     {
       attrs: {
-        label: "版本号",
-        prop: "version",
-        width: 80,
+        label: "合同金额",
+        slot: "amount",
+        width: 120,
       },
     },
     {
       attrs: {
-        label: "合同金额",
-        slot: "amount",
+        label: "合同金额(CNY)",
+        slot: "amountCNY",
         width: 120,
       },
     },
     {
       attrs: {
-        label: "已到账金额",
+        label: "已到账金额(CNY)",
         slot: "sumClaimMoney",
-        width: 120,
+        width: 140,
       },
     },
     {
@@ -404,10 +284,11 @@ const config = computed(() => {
         label: "审批状态",
         prop: "status",
         width: 120,
+        slot: "status",
       },
-      render(type) {
-        return proxy.dictValueLabel(type, status.value);
-      },
+      // render(type) {
+      //   return proxy.dictValueLabel(type, status.value);
+      // },
     },
     {
       attrs: {
@@ -438,6 +319,19 @@ const config = computed(() => {
                 },
               }
             : {},
+          row.status == 30
+            ? {
+                attrs: {
+                  label: "变更",
+                  type: "primary",
+                  text: true,
+                },
+                el: "button",
+                click() {
+                  clickAlteration(row);
+                },
+              }
+            : {},
           {
             attrs: {
               label: "打印",
@@ -457,11 +351,15 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-              }).then(() => {
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
                 proxy
                   .post("/contract/edit", {
                     id: row.id,
@@ -483,38 +381,46 @@ const config = computed(() => {
   ];
 });
 const getDict = () => {
-  proxy.getDictOne(["contract_type", "account_currency", "trade_mode", "shipping_method", "unit"]).then((res) => {
-    if (res.contract_type && res.contract_type.length > 0) {
-      contractType.value = res.contract_type.map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    }
-    if (res.account_currency && res.account_currency.length > 0) {
-      accountCurrency.value = res.account_currency.map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    }
-    if (res.trade_mode && res.trade_mode.length > 0) {
-      tradeMethods.value = res.trade_mode.map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    }
-    if (res.shipping_method && res.shipping_method.length > 0) {
-      shippingMethod.value = res.shipping_method.map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    }
-    if (res.unit && res.unit.length > 0) {
-      productUnit.value = res.unit.map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    }
-  });
+  proxy
+    .getDictOne([
+      "contract_type",
+      "account_currency",
+      "trade_mode",
+      "shipping_method",
+      "unit",
+    ])
+    .then((res) => {
+      if (res.contract_type && res.contract_type.length > 0) {
+        contractType.value = res.contract_type.map((x) => ({
+          label: x.dictValue,
+          value: x.dictKey,
+        }));
+      }
+      if (res.account_currency && res.account_currency.length > 0) {
+        accountCurrency.value = res.account_currency.map((x) => ({
+          label: x.dictValue,
+          value: x.dictKey,
+        }));
+      }
+      if (res.trade_mode && res.trade_mode.length > 0) {
+        tradeMethods.value = res.trade_mode.map((x) => ({
+          label: x.dictValue,
+          value: x.dictKey,
+        }));
+      }
+      if (res.shipping_method && res.shipping_method.length > 0) {
+        shippingMethod.value = res.shipping_method.map((x) => ({
+          label: x.dictValue,
+          value: x.dictKey,
+        }));
+      }
+      if (res.unit && res.unit.length > 0) {
+        productUnit.value = res.unit.map((x) => ({
+          label: x.dictValue,
+          value: x.dictKey,
+        }));
+      }
+    });
   proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
     corporationList.value = res.rows.map((item) => {
       return {
@@ -593,19 +499,28 @@ const newContract = () => {
 };
 const openPrint = ref(false);
 const printDetails = ref({});
+const rowData = ref({});
 const clickPrint = (row) => {
-  printDetails.value = {};
+  // printDetails.value = {};
+  // openPrint.value = true;
+  // proxy.post("/contract/getContractPdfInfo", { id: row.id }).then((res) => {
+  //   printDetails.value = res;
+  // });
+
+  rowData.value = {
+    id: row.id,
+  };
   openPrint.value = true;
-  proxy.post("/contract/getContractPdfInfo", { id: row.id }).then((res) => {
-    printDetails.value = res;
-  });
 };
 const clickDownload = () => {
   proxy.getPdf("外销合同PDF文件");
 };
 const statistics = (label, index) => {
   let num = 0;
-  if (printDetails.value.productInfoList && printDetails.value.productInfoList.length > 0) {
+  if (
+    printDetails.value.productInfoList &&
+    printDetails.value.productInfoList.length > 0
+  ) {
     printDetails.value.productInfoList.map((item) => {
       if (item[label]) {
         num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
@@ -616,7 +531,10 @@ const statistics = (label, index) => {
 };
 const statisticsTwo = (label, index) => {
   let num = 0;
-  if (printDetails.value.contractProjectList && printDetails.value.contractProjectList.length > 0) {
+  if (
+    printDetails.value.contractProjectList &&
+    printDetails.value.contractProjectList.length > 0
+  ) {
     printDetails.value.contractProjectList.map((item) => {
       if (item[label]) {
         num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
@@ -627,8 +545,15 @@ const statisticsTwo = (label, index) => {
 };
 const computeScale = (item) => {
   let text = 0;
-  if (item.sumClaimMoney && Number(item.sumClaimMoney) > 0 && item.amount && Number(item.amount) > 0) {
-    text = parseFloat((Number(item.sumClaimMoney) / Number(item.amount)) * 100).toFixed(2);
+  if (
+    item.sumClaimMoney &&
+    Number(item.sumClaimMoney) > 0 &&
+    item.amountCNY &&
+    Number(item.amountCNY) > 0
+  ) {
+    text = parseFloat(
+      (Number(item.sumClaimMoney) / Number(item.amountCNY)) * 100
+    ).toFixed(2);
   }
   return text + "%";
 };
@@ -637,6 +562,60 @@ const clickAccomplish = (row) => {
     getList();
   });
 };
+const pushProcessApproval = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "contract_flow",
+      id: row.flowId,
+      processType: 20,
+      random: proxy.random(),
+      flowName: "销售合同详情",
+    },
+  });
+  return;
+};
+const currentContractId = ref("");
+const openDetails = (row) => {
+  currentContractId.value = row.id;
+  openDetailsDialog.value = true;
+};
+const printObj = ref({
+  id: "printMe",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
+const clickAlteration = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "contract_update_flow",
+      flowName: "销售合同变更流程",
+      contractId: row.id,
+      random: proxy.random(),
+    },
+  });
+};
+
+const getStyle = (status) => {
+  if (status == 10) {
+    return {
+      color: "#FF9315",
+    };
+  } else if (status == 30) {
+    return {
+      color: "#39C55A",
+    };
+  } else if (status == 20 || status == 99) {
+    return {
+      color: "#FF655B",
+    };
+  } else {
+    return {};
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 614 - 0
src/views/salesMange/saleContract/middle/index.vue

@@ -0,0 +1,614 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        :selectConfig="selectConfig"
+        highlight-current-row
+        @get-list="getList">
+        <template #code="{ item }">
+          <div style="width: 100%">
+            <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="pushProcessApproval(item)">{{ item.code }}</a>
+          </div>
+        </template>
+        <template #amount="{ item }">
+          <div>
+            <span style="padding-right: 4px">{{ item.currency }}</span>
+            <span>{{ moneyFormat(item.amount, 2) }}</span>
+          </div>
+        </template>
+        <template #sellCorporationName="{ item }">
+          <div>
+            <span v-if="item.sellCorporationName">{{ item.sellCorporationName }}</span>
+            <span v-else>{{ item.oldSellCorporationName }}</span>
+          </div>
+        </template>
+        <template #buyCorporationName="{ item }">
+          <div>
+            <span v-if="item.buyCorporationName">{{ item.buyCorporationName }}</span>
+            <span v-else>{{ item.oldBuyCorporationName }}</span>
+          </div>
+        </template>
+      </byTable>
+    </div>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="860">
+      <div id="printMe">
+        <div id="pdfDom" style="width: 800px; padding: 16px; font-size: 12px !important">
+          <div style="font-size: 18px; text-align: center">
+            {{ printDetails.sellCorporationNameEn }}
+          </div>
+          <div style="text-align: center">
+            {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellDetailedAddress }}
+          </div>
+          <div style="font-size: 14px; color: #409eff; text-align: center; padding-top: 16px">PROFORMA INVOICE</div>
+          <div style="padding-top: 8px">
+            <div>PI NO. : {{ printDetails.contractCode }}</div>
+            <div>PI DATE: {{ printDetails.createTimeEn }}</div>
+          </div>
+          <div style="border: 1px solid black; display: flex">
+            <div style="width: 50%; border-right: 1px solid black">
+              <div style="color: #409eff">VENDOR:</div>
+              <div>{{ printDetails.sellCorporationNameEn }}</div>
+              <div style="padding: 16px 0">
+                {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellDetailedAddress }}
+              </div>
+              <div>CONTACT: {{ printDetails.sellContactName }}</div>
+              <div>TEL.: {{ printDetails.sellContactNumber }}</div>
+            </div>
+            <div style="width: 50%">
+              <div style="color: #409eff">BUYER:</div>
+              <div>{{ printDetails.buyCorporationName }}</div>
+              <div style="padding: 16px 0">
+                {{ printDetails.buyDetailedAddress }},{{ printDetails.buyCityName }},{{ printDetails.buyProvinceName }},{{ printDetails.buyCountryName }}
+              </div>
+              <div>CONTACT: {{ printDetails.buyContactName }}</div>
+              <div>TEL.: {{ printDetails.buyContactNumber }}</div>
+            </div>
+          </div>
+          <div style="height: 16px"></div>
+          <div style="border: 1px solid black">
+            <div style="display: flex; width: 100%">
+              <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
+                <div style="color: #409eff">COUNTRY OF ORIGIN:</div>
+                <div>{{ printDetails.sellCountryName }}</div>
+              </div>
+              <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
+                <div style="color: #409eff">COUNTRY OF DESTINATION:</div>
+                <div>{{ printDetails.buyCountryName }}</div>
+              </div>
+              <div style="width: 33%; border-bottom: 1px solid black">
+                <div style="color: #409eff">PLACE OF DISCHARGE:</div>
+                <div>{{ printDetails.transportRemark }}</div>
+              </div>
+            </div>
+            <div style="display: flex; width: 100%">
+              <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
+                <div style="color: #409eff">TERMS OF DELIVERY:</div>
+                <div>
+                  {{ dictValueLabel(printDetails.tradeMethods, tradeMethods) }}
+                </div>
+              </div>
+              <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
+                <div style="color: #409eff">CURRENCY:</div>
+                <div>
+                  {{ printDetails.currency }}
+                </div>
+              </div>
+              <div style="width: 33%; border-bottom: 1px solid black">
+                <div style="color: #409eff">EXPORT BY/VIA:</div>
+                <div>
+                  {{ dictValueLabel(printDetails.transportMethod, shippingMethod) }}
+                </div>
+              </div>
+            </div>
+            <div style="display: flex; width: 100%">
+              <div style="width: 33%; border-right: 1px solid black">
+                <div style="color: #409eff">DELIVERY TIME:</div>
+                <div>{{ printDetails.deliveryTime }}</div>
+              </div>
+              <div style="width: 67%">
+                <div style="color: #409eff">TERMS OF PAYMENT:</div>
+                <div>{{ printDetails.remark }}</div>
+              </div>
+            </div>
+          </div>
+          <div style="height: 16px"></div>
+          <div class="baseRow" style="display: flex; color: #409eff">
+            <div class="contentRow" style="width: 50px; text-align: center">NO.</div>
+            <div class="contentRow" style="width: calc(100% - 450px); text-align: center">COMMODITY, SPECIFICATION</div>
+            <div class="contentRow" style="width: 100px; text-align: center">UNIT</div>
+            <div class="contentRow" style="width: 100px; text-align: center">QUANTITY</div>
+            <div class="contentRow" style="width: 100px; text-align: center">UNIT PRICE</div>
+            <div class="contentRow" style="width: 100px; text-align: center">TOTAL PRICE</div>
+          </div>
+          <div v-if="printDetails.productInfoList && printDetails.productInfoList.length > 0">
+            <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.productInfoList" :key="item.productId">
+              <div class="contentRow" style="width: 50px; text-align: center">
+                {{ index + 1 }}
+              </div>
+              <div class="contentRow" style="width: calc(100% - 450px); text-align: center">
+                {{ item.productName }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ dictValueLabel(item.productUnit, productUnit) }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.productQuantity }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.productPrice }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.amount }}
+              </div>
+            </div>
+          </div>
+          <div class="baseRow" style="display: flex; color: #409eff">
+            <div class="contentRow" style="width: calc(100% - 400px); text-align: center">SUBTOTAL:</div>
+            <div class="contentRow" style="width: 100px; text-align: center"></div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ statistics("productQuantity", 0) }}
+            </div>
+            <div class="contentRow" style="width: 100px; text-align: center"></div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ statistics("amount", 2) }}
+            </div>
+          </div>
+          <div class="baseRow" style="display: flex">
+            <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">FREIGHT COST:</div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ statisticsTwo("amount", 2) }}
+            </div>
+          </div>
+          <div class="baseRow" style="display: flex">
+            <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">TOTAL PRICE:</div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ printDetails.totalAmount }}
+            </div>
+          </div>
+          <div class="baseRow" style="display: flex; border-bottom: 1px solid black">
+            <div class="contentRow" style="width: 100%">
+              {{ translateIntoEnglish(printDetails.totalAmount, printDetails.currency) }}
+            </div>
+          </div>
+          <div style="height: 16px"></div>
+          <div class="baseRow" style="color: #409eff">
+            <div class="contentRow" style="width: 100%">ACCOUNT INFORMATION:</div>
+          </div>
+          <div class="baseRow" style="border-bottom: 1px solid black">
+            <div class="contentRow" style="width: 100%">
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Name: {{ printDetails.beneficiaryName }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Bank: {{ printDetails.beneficiaryBank }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Bank Address: {{ printDetails.beneficiaryBankAddress }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Account Number: {{ printDetails.beneficiaryAccountNumber }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">Swift Code: {{ printDetails.swiftCode }}</div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Address: {{ printDetails.beneficiaryAddress }}
+              </div>
+            </div>
+          </div>
+          <div style="height: 32px"></div>
+          <div style="display: flex">
+            <div style="width: 50%">
+              <div style="color: #409eff">CONFIRMED BY VENDOR:</div>
+              <div>{{ printDetails.sellCorporationNameEn }}</div>
+            </div>
+            <div style="width: 50%">
+              <div style="color: #409eff">CONFIRMED BY BUYER:</div>
+              <div>{{ printDetails.buyCorporationName }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="openPrint = false" size="large">取消</el-button>
+        <el-button v-print="printObj" size="large">打印</el-button>
+        <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="编辑" v-if="openUpdate" v-model="openUpdate" width="500">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="update">
+        <template #sellContactName>
+          <div style="width: 100%">
+            <el-autocomplete
+              v-model="formData.data.sellContactName"
+              :fetch-suggestions="querySearchSellPerson"
+              clearable
+              class="inline-input w-50"
+              placeholder="请输入联系人"
+              @select="handleSellPerson">
+            </el-autocomplete>
+          </div>
+        </template>
+        <template #buyContactName>
+          <div style="width: 100%">
+            <el-autocomplete
+              v-model="formData.data.buyContactName"
+              :fetch-suggestions="querySearchBuyPerson"
+              clearable
+              class="inline-input w-50"
+              placeholder="请输入联系人"
+              @select="handleBuyPerson">
+            </el-autocomplete>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openUpdate = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="clickSubmit()" size="large">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import { ElMessage } from "element-plus";
+import byForm from "@/components/byForm/index";
+
+const { proxy } = getCurrentInstance();
+const tradeMethods = ref([]);
+const corporationList = ref([]);
+const shippingMethod = ref([]);
+const productUnit = ref([]);
+const sellPerson = ref([]);
+const buyPerson = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const loading = ref(false);
+const selectConfig = computed(() => {
+  return [
+    {
+      label: "销售方",
+      prop: "sellCorporationId",
+      data: corporationList.value,
+    },
+    {
+      label: "采购方",
+      prop: "buyCorporationId",
+      data: corporationList.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "合同编码",
+        slot: "code",
+        width: 220,
+      },
+    },
+    {
+      attrs: {
+        label: "合同金额",
+        slot: "amount",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "销售方",
+        slot: "sellCorporationName",
+        "min-width": 200,
+      },
+    },
+    {
+      attrs: {
+        label: "采购方",
+        slot: "buyCorporationName",
+        "min-width": 200,
+      },
+    },
+    {
+      attrs: {
+        label: "最近操作人",
+        prop: "opUserName",
+        width: 180,
+      },
+    },
+    {
+      attrs: {
+        label: "最近操作时间",
+        prop: "updateTime",
+        width: 180,
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+        fixed: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "编辑",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickUpdate(row);
+            },
+          },
+          {
+            attrs: {
+              label: "打印",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickPrint(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getDict = () => {
+  proxy.getDictOne(["trade_mode", "shipping_method", "unit"]).then((res) => {
+    if (res.trade_mode && res.trade_mode.length > 0) {
+      tradeMethods.value = res.trade_mode.map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    }
+    if (res.shipping_method && res.shipping_method.length > 0) {
+      shippingMethod.value = res.shipping_method.map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    }
+    if (res.unit && res.unit.length > 0) {
+      productUnit.value = res.unit.map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    }
+  });
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    corporationList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.name,
+        value: item.id,
+      };
+    });
+  });
+};
+const getPerson = () => {
+  proxy.post("/intermediateContract/contactList", {}).then((res) => {
+    sellPerson.value = res.map((item) => {
+      return {
+        ...item,
+        value: item.sellContactName,
+      };
+    });
+    buyPerson.value = res.map((item) => {
+      return {
+        ...item,
+        value: item.buyContactName,
+      };
+    });
+  });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/intermediateContract/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getDict();
+getList();
+const openPrint = ref(false);
+const printDetails = ref({});
+const clickPrint = (row) => {
+  printDetails.value = {};
+  openPrint.value = true;
+  proxy.post("/intermediateContract/getPrintInfo", { documentsId: row.documentsId }).then((res) => {
+    printDetails.value = res;
+  });
+};
+const clickDownload = () => {
+  proxy.getPdf("外销合同PDF文件");
+};
+const statistics = (label, index) => {
+  let num = 0;
+  if (printDetails.value.productInfoList && printDetails.value.productInfoList.length > 0) {
+    printDetails.value.productInfoList.map((item) => {
+      if (item[label]) {
+        num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
+      }
+    });
+  }
+  return num;
+};
+const statisticsTwo = (label, index) => {
+  let num = 0;
+  if (printDetails.value.contractProjectList && printDetails.value.contractProjectList.length > 0) {
+    printDetails.value.contractProjectList.map((item) => {
+      if (item[label]) {
+        num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
+      }
+    });
+  }
+  return num;
+};
+const pushProcessApproval = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "contract_flow",
+      id: row.flowId,
+      processType: 20,
+      random: proxy.random(),
+      flowName: "销售合同详情",
+    },
+  });
+  return;
+};
+const printObj = ref({
+  id: "printMe",
+  popTitle: "",
+  extraCss: "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
+const openUpdate = ref(false);
+const update = ref(null);
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      label: "销售方",
+      prop: "sellCorporationId",
+      data: corporationList.value,
+    },
+    {
+      type: "slot",
+      slotName: "sellContactName",
+      prop: "sellContactName",
+      label: "销售联系信息",
+      itemWidth: 40,
+    },
+    {
+      type: "input",
+      prop: "sellContactNumber",
+      label: " ",
+      itemWidth: 60,
+      itemType: "text",
+    },
+    {
+      type: "select",
+      label: "采购方",
+      prop: "buyCorporationId",
+      data: corporationList.value,
+    },
+    {
+      type: "slot",
+      slotName: "buyContactName",
+      prop: "buyContactName",
+      label: "采购联系信息",
+      itemWidth: 40,
+    },
+    {
+      type: "input",
+      prop: "buyContactNumber",
+      label: " ",
+      itemWidth: 60,
+      itemType: "text",
+    },
+  ];
+});
+const rules = ref({
+  sellCorporationId: [{ required: true, message: "请选择销售方", trigger: "change" }],
+  sellContactName: [{ required: true, message: "请输入销售联系人", trigger: "blur" }],
+  sellContactNumber: [{ required: true, message: "请输入销售联系电话", trigger: "blur" }],
+  buyCorporationId: [{ required: true, message: "请选择采购方", trigger: "change" }],
+  buyContactName: [{ required: true, message: "请输入采购联系人", trigger: "blur" }],
+  buyContactNumber: [{ required: true, message: "请输入采购联系电话", trigger: "blur" }],
+});
+const clickUpdate = (row) => {
+  getPerson();
+  formData.data = {
+    documentsId: row.documentsId,
+    sellCorporationId: "",
+    sellContactName: "",
+    sellContactNumber: "",
+    buyCorporationId: "",
+    buyContactName: "",
+    buyContactNumber: "",
+  };
+  openUpdate.value = true;
+};
+const clickSubmit = () => {
+  update.value.handleSubmit(() => {
+    proxy.post("/intermediateContract/edit", formData.data).then((res) => {
+      printDetails.value = res;
+      ElMessage({
+        message: "编辑成功",
+        type: "success",
+      });
+      openUpdate.value = false;
+      getList();
+    });
+  });
+};
+const createFilter = (queryString) => {
+  return (restaurant) => {
+    return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
+  };
+};
+const querySearchSellPerson = (queryString, callback) => {
+  const resultsSell = queryString ? sellPerson.value.filter(createFilter(queryString)) : sellPerson.value;
+  callback(resultsSell);
+};
+const handleSellPerson = (item) => {
+  formData.data.sellContactNumber = item.sellContactNumber;
+};
+const querySearchBuyPerson = (queryString, callback) => {
+  const resultsBuy = queryString ? buyPerson.value.filter(createFilter(queryString)) : buyPerson.value;
+  callback(resultsBuy);
+};
+const handleBuyPerson = (item) => {
+  formData.data.buyContactNumber = item.buyContactNumber;
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+.baseRow {
+  min-height: 24px;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+}
+.contentRow {
+  border-right: 1px solid black;
+  line-height: 24px;
+  padding-left: 4px;
+}
+</style>

+ 373 - 163
src/views/salesMange/saleContract/priceSheet/index.vue

@@ -14,7 +14,17 @@
             action: () => newPriceSheet(),
           },
         ]"
-        @get-list="getList">
+        @get-list="getList"
+      >
+        <template #code="{ item }">
+          <div style="width: 100%">
+            <a
+              style="color: #409eff; cursor: pointer; word-break: break-all"
+              @click="pushProcessApproval(item)"
+              >{{ item.code }}</a
+            >
+          </div>
+        </template>
         <template #amount="{ item }">
           <div>
             <span style="padding-right: 4px">{{ item.currency }}</span>
@@ -26,197 +36,360 @@
             <span>{{ item.advanceRatio }}%</span>
           </div>
         </template>
+        <template #status="{ item }">
+          <div>
+            <span :style="getStyle(item.status)">{{
+              dictValueLabel(item.status, status)
+            }}</span>
+          </div>
+        </template>
       </byTable>
     </div>
 
     <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="860">
-      <div id="pdfDom" style="width: 800px; padding: 16px; font-size: 12px !important">
-        <div style="font-size: 18px; text-align: center">
-          {{ getLabel(printDetails.sellCorporationId, corporationList, "nameEn") }}
-        </div>
-        <div style="text-align: center">
-          {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellAddress }}
-        </div>
-        <div style="font-size: 14px; color: #409eff; text-align: center; padding-top: 16px">QUOTATION</div>
-        <div style="padding-top: 8px">
-          <div>Reference NO. : {{ printDetails.code }}</div>
-          <div style="display: flex">
-            <div style="width: 50%">DATE: {{ moment(printDetails.createTime).format("DD/MMM/yyyy") }}</div>
-            <div style="width: 50%">Valid Date:</div>
+      <div id="printMe">
+        <div
+          id="pdfDom"
+          style="width: 800px; padding: 16px; font-size: 12px !important"
+        >
+          <div style="font-size: 18px; text-align: center">
+            {{
+              getLabel(
+                printDetails.sellCorporationId,
+                corporationList,
+                "nameEn"
+              )
+            }}
           </div>
-        </div>
-        <div style="border: 1px solid black; display: flex">
-          <div style="width: 50%; border-right: 1px solid black">
-            <div style="color: #409eff">VENDOR:</div>
-            <div>
-              {{ getLabel(printDetails.sellCorporationId, corporationList, "nameEn") }}
-            </div>
-            <div style="padding: 16px 0">
-              {{ printDetails.sellCountryName }},{{ printDetails.sellProvinceName }},{{ printDetails.sellCityName }},{{ printDetails.sellAddress }}
-            </div>
-            <div>{{ printDetails.sellContactName }},{{ printDetails.sellContactNumber }}</div>
+          <div style="text-align: center">
+            {{ printDetails.sellCountryName }},{{
+              printDetails.sellProvinceName
+            }},{{ printDetails.sellCityName }},{{ printDetails.sellAddress }}
           </div>
-          <div style="width: 50%">
-            <div style="color: #409eff">BUYER:</div>
-            <div>
-              {{ getLabel(printDetails.buyCorporationId, customerList, "name") }}
-            </div>
-            <div style="padding: 16px 0">
-              {{ printDetails.buyCountryName }},{{ printDetails.buyProvinceName }},{{ printDetails.buyCityName }},{{ printDetails.buyAddress }}
-            </div>
-            <div>{{ printDetails.buyContactName }},{{ printDetails.buyContactNumber }}</div>
+          <div
+            style="
+              font-size: 14px;
+              color: #409eff;
+              text-align: center;
+              padding-top: 16px;
+            "
+          >
+            QUOTATION
           </div>
-        </div>
-        <div style="height: 16px"></div>
-        <div style="border: 1px solid black">
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">COUNTRY OF ORIGIN:</div>
-              <div>{{ printDetails.sellCountryName }}</div>
-            </div>
-            <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">COUNTRY OF DESTINATION:</div>
-              <div>{{ printDetails.buyCountryName }}</div>
-            </div>
-            <div style="width: 33%; border-bottom: 1px solid black">
-              <div style="color: #409eff">PLACE OF DISCHARGE:</div>
-              <div>{{ printDetails.transportRemark }}</div>
+          <div style="padding-top: 8px">
+            <div>Reference NO. : {{ printDetails.code }}</div>
+            <div style="display: flex">
+              <div style="width: 50%">
+                DATE:
+                {{ moment(printDetails.createTime).format("DD/MMM/yyyy") }}
+              </div>
+              <div style="width: 50%">Valid Date:</div>
             </div>
           </div>
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">TERMS OF DELIVERY:</div>
+          <div style="border: 1px solid black; display: flex">
+            <div style="width: 50%; border-right: 1px solid black">
+              <div style="color: #409eff">VENDOR:</div>
               <div>
-                {{ dictValueLabel(printDetails.tradeMethods, tradeMethods) }}
+                {{
+                  getLabel(
+                    printDetails.sellCorporationId,
+                    corporationList,
+                    "nameEn"
+                  )
+                }}
+              </div>
+              <div style="padding: 16px 0">
+                {{ printDetails.sellCountryName }},{{
+                  printDetails.sellProvinceName
+                }},{{ printDetails.sellCityName }},{{
+                  printDetails.sellAddress
+                }}
               </div>
-            </div>
-            <div style="width: 34%; border-bottom: 1px solid black; border-right: 1px solid black">
-              <div style="color: #409eff">CURRENCY:</div>
               <div>
-                {{ dictValueLabel(printDetails.currency, accountCurrency) }}
+                {{ printDetails.sellContactName }},{{
+                  printDetails.sellContactNumber
+                }}
               </div>
             </div>
-            <div style="width: 33%; border-bottom: 1px solid black">
-              <div style="color: #409eff">EXPORT BY/VIA:</div>
+            <div style="width: 50%">
+              <div style="color: #409eff">BUYER:</div>
+              <div>
+                {{
+                  getLabel(printDetails.buyCorporationId, customerList, "name")
+                }}
+              </div>
+              <div style="padding: 16px 0">
+                {{ printDetails.buyCountryName }},{{
+                  printDetails.buyProvinceName
+                }},{{ printDetails.buyCityName }},{{ printDetails.buyAddress }}
+              </div>
               <div>
-                {{ dictValueLabel(printDetails.transportMethod, shippingMethod) }}
+                {{ printDetails.buyContactName }},{{
+                  printDetails.buyContactNumber
+                }}
               </div>
             </div>
           </div>
-          <div style="display: flex; width: 100%">
-            <div style="width: 33%; border-right: 1px solid black">
-              <div style="color: #409eff">DELIVERY TIME:</div>
+          <div style="height: 16px"></div>
+          <div style="border: 1px solid black">
+            <div style="display: flex; width: 100%">
+              <div
+                style="
+                  width: 33%;
+                  border-bottom: 1px solid black;
+                  border-right: 1px solid black;
+                "
+              >
+                <div style="color: #409eff">COUNTRY OF ORIGIN:</div>
+                <div>{{ printDetails.sellCountryName }}</div>
+              </div>
+              <div
+                style="
+                  width: 34%;
+                  border-bottom: 1px solid black;
+                  border-right: 1px solid black;
+                "
+              >
+                <div style="color: #409eff">COUNTRY OF DESTINATION:</div>
+                <div>{{ printDetails.buyCountryName }}</div>
+              </div>
+              <div style="width: 33%; border-bottom: 1px solid black">
+                <div style="color: #409eff">PLACE OF DISCHARGE:</div>
+                <div>{{ printDetails.transportRemark }}</div>
+              </div>
+            </div>
+            <div style="display: flex; width: 100%">
+              <div
+                style="
+                  width: 33%;
+                  border-bottom: 1px solid black;
+                  border-right: 1px solid black;
+                "
+              >
+                <div style="color: #409eff">TERMS OF DELIVERY:</div>
+                <div>
+                  {{ dictValueLabel(printDetails.tradeMethods, tradeMethods) }}
+                </div>
+              </div>
+              <div
+                style="
+                  width: 34%;
+                  border-bottom: 1px solid black;
+                  border-right: 1px solid black;
+                "
+              >
+                <div style="color: #409eff">CURRENCY:</div>
+                <div>
+                  {{ dictValueLabel(printDetails.currency, accountCurrency) }}
+                </div>
+              </div>
+              <div style="width: 33%; border-bottom: 1px solid black">
+                <div style="color: #409eff">EXPORT BY/VIA:</div>
+                <div>
+                  {{
+                    dictValueLabel(printDetails.transportMethod, shippingMethod)
+                  }}
+                </div>
+              </div>
             </div>
-            <div style="width: 67%">
-              <div style="color: #409eff">TERMS OF PAYMENT:</div>
-              <div>{{ printDetails.remark }}</div>
+            <div style="display: flex; width: 100%">
+              <div style="width: 33%; border-right: 1px solid black">
+                <div style="color: #409eff">DELIVERY TIME:</div>
+              </div>
+              <div style="width: 67%">
+                <div style="color: #409eff">TERMS OF PAYMENT:</div>
+                <div>{{ printDetails.remark }}</div>
+              </div>
             </div>
           </div>
-        </div>
-        <div style="height: 16px"></div>
-        <div class="baseRow" style="display: flex; color: #409eff">
-          <div class="contentRow" style="width: 50px; text-align: center">NO.</div>
-          <div class="contentRow" style="width: calc(100% - 450px); text-align: center">COMMODITY, SPECIFICATION</div>
-          <div class="contentRow" style="width: 100px; text-align: center">UNIT</div>
-          <div class="contentRow" style="width: 100px; text-align: center">QUANTITY</div>
-          <div class="contentRow" style="width: 100px; text-align: center">UNIT PRICE</div>
-          <div class="contentRow" style="width: 100px; text-align: center">TOTAL PRICE</div>
-        </div>
-        <div v-if="printDetails.quotationProductList && printDetails.quotationProductList.length > 0">
-          <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.quotationProductList" :key="item.productId">
+          <div style="height: 16px"></div>
+          <div class="baseRow" style="display: flex; color: #409eff">
             <div class="contentRow" style="width: 50px; text-align: center">
-              {{ index + 1 }}
+              NO.
             </div>
-            <div class="contentRow" style="width: calc(100% - 450px); text-align: center">
-              {{ item.productName }}
+            <div
+              class="contentRow"
+              style="width: calc(100% - 450px); text-align: center"
+            >
+              COMMODITY, SPECIFICATION
             </div>
             <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.productUnit }}
+              UNIT
             </div>
             <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.quantity }}
+              QUANTITY
             </div>
             <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.price }}
+              UNIT PRICE
             </div>
             <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.amount }}
+              TOTAL PRICE
             </div>
           </div>
-        </div>
-        <div class="baseRow" style="display: flex; color: #409eff">
-          <div class="contentRow" style="width: calc(100% - 400px); text-align: center">SUBTOTAL:</div>
-          <div class="contentRow" style="width: 100px; text-align: center"></div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ statistics("quantity", 0) }}
-          </div>
-          <div class="contentRow" style="width: 100px; text-align: center"></div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ statistics("amount", 2) }}
-          </div>
-        </div>
-        <div v-if="printDetails.quotationPayList && printDetails.quotationPayList.length > 0">
-          <div class="baseRow" style="display: flex" v-for="(item, index) in printDetails.quotationPayList" :key="index">
-            <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">{{ item.payName }}:</div>
-            <div class="contentRow" style="width: 100px; text-align: center">
-              {{ item.amount }}
+          <div
+            v-if="
+              printDetails.quotationProductList &&
+              printDetails.quotationProductList.length > 0
+            "
+          >
+            <div
+              class="baseRow"
+              style="display: flex"
+              v-for="(item, index) in printDetails.quotationProductList"
+              :key="item.productId"
+            >
+              <div class="contentRow" style="width: 50px; text-align: center">
+                {{ index + 1 }}
+              </div>
+              <div
+                class="contentRow"
+                style="width: calc(100% - 450px); text-align: center"
+              >
+                {{ item.productName }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.productUnit }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.quantity }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.price }}
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.amount }}
+              </div>
             </div>
           </div>
-        </div>
-        <div class="baseRow" style="display: flex">
-          <div class="contentRow" style="width: calc(100% - 100px); text-align: right; color: #409eff">TOTAL PRICE:</div>
-          <div class="contentRow" style="width: 100px; text-align: center">
-            {{ getAllMoney(statistics("amount", 2)) }}
-          </div>
-        </div>
-        <div class="baseRow" style="display: flex; border-bottom: 1px solid black">
-          <div class="contentRow" style="width: 100%">
-            {{ translateIntoEnglish(printDetails.amount, printDetails.currency) }}
-          </div>
-        </div>
-        <!-- <div style="height: 16px"></div>
-        <div class="baseRow" style="color: #409eff">
-          <div class="contentRow" style="width: 100%">ACCOUNT INFORMATION:</div>
-        </div>
-        <div class="baseRow" style="border-bottom: 1px solid black">
-          <div class="contentRow" style="width: 100%">
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Name: {{ printDetails.beneficiaryName }}
+          <div class="baseRow" style="display: flex; color: #409eff">
+            <div
+              class="contentRow"
+              style="width: calc(100% - 400px); text-align: center"
+            >
+              SUBTOTAL:
+            </div>
+            <div
+              class="contentRow"
+              style="width: 100px; text-align: center"
+            ></div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ statistics("quantity", 0) }}
             </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Bank: {{ printDetails.beneficiaryBank }}
+            <div
+              class="contentRow"
+              style="width: 100px; text-align: center"
+            ></div>
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ statistics("amount", 2) }}
             </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Bank Address: {{ printDetails.beneficiaryBankAddress }}
+          </div>
+          <div
+            v-if="
+              printDetails.quotationPayList &&
+              printDetails.quotationPayList.length > 0
+            "
+          >
+            <div
+              class="baseRow"
+              style="display: flex"
+              v-for="(item, index) in printDetails.quotationPayList"
+              :key="index"
+            >
+              <div
+                class="contentRow"
+                style="
+                  width: calc(100% - 100px);
+                  text-align: right;
+                  color: #409eff;
+                "
+              >
+                {{ item.payName }}:
+              </div>
+              <div class="contentRow" style="width: 100px; text-align: center">
+                {{ item.amount }}
+              </div>
             </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Account Number: {{ printDetails.beneficiaryAccountNumber }}
+          </div>
+          <div class="baseRow" style="display: flex">
+            <div
+              class="contentRow"
+              style="
+                width: calc(100% - 100px);
+                text-align: right;
+                color: #409eff;
+              "
+            >
+              TOTAL PRICE:
             </div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">Swift Code: {{ printDetails.swiftCode }}</div>
-            <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
-              Beneficiary Address: {{ printDetails.beneficiaryAddress }}
+            <div class="contentRow" style="width: 100px; text-align: center">
+              {{ getAllMoney(statistics("amount", 2)) }}
             </div>
           </div>
-        </div> -->
-        <div style="height: 32px"></div>
-        <div style="display: flex">
-          <div style="width: 50%">
-            <div style="color: #409eff">CONFIRMED BY VENDOR:</div>
-            <div>
-              {{ getLabel(printDetails.sellCorporationId, corporationList, "nameEn") }}
+          <div
+            class="baseRow"
+            style="display: flex; border-bottom: 1px solid black"
+          >
+            <div class="contentRow" style="width: 100%">
+              {{
+                translateIntoEnglish(printDetails.amount, printDetails.currency)
+              }}
             </div>
           </div>
-          <div style="width: 50%">
-            <div style="color: #409eff">CONFIRMED BY BUYER:</div>
-            <div>
-              {{ getLabel(printDetails.buyCorporationId, customerList, "name") }}
+          <!-- <div style="height: 16px"></div>
+          <div class="baseRow" style="color: #409eff">
+            <div class="contentRow" style="width: 100%">ACCOUNT INFORMATION:</div>
+          </div>
+          <div class="baseRow" style="border-bottom: 1px solid black">
+            <div class="contentRow" style="width: 100%">
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Name: {{ printDetails.beneficiaryName }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Bank: {{ printDetails.beneficiaryBank }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Bank Address: {{ printDetails.beneficiaryBankAddress }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Account Number: {{ printDetails.beneficiaryAccountNumber }}
+              </div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">Swift Code: {{ printDetails.swiftCode }}</div>
+              <div style="line-height: 24px; padding-left: 4px; word-break: break-all; word-wrap: break-word">
+                Beneficiary Address: {{ printDetails.beneficiaryAddress }}
+              </div>
+            </div>
+          </div> -->
+          <div style="height: 32px"></div>
+          <div style="display: flex">
+            <div style="width: 50%">
+              <div style="color: #409eff">CONFIRMED BY VENDOR:</div>
+              <div>
+                {{
+                  getLabel(
+                    printDetails.sellCorporationId,
+                    corporationList,
+                    "nameEn"
+                  )
+                }}
+              </div>
+            </div>
+            <div style="width: 50%">
+              <div style="color: #409eff">CONFIRMED BY BUYER:</div>
+              <div>
+                {{
+                  getLabel(printDetails.buyCorporationId, customerList, "name")
+                }}
+              </div>
             </div>
           </div>
         </div>
       </div>
       <template #footer>
         <el-button @click="openPrint = false" size="large">取消</el-button>
-        <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
+        <el-button v-print="printObj" size="large">打印</el-button>
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
       </template>
     </el-dialog>
   </div>
@@ -289,7 +462,7 @@ const config = computed(() => {
     {
       attrs: {
         label: "报价单号",
-        prop: "code",
+        slot: "code",
         width: 200,
       },
     },
@@ -360,16 +533,7 @@ const config = computed(() => {
         label: "审批状态",
         prop: "status",
         width: 140,
-      },
-      render(type) {
-        let text = "";
-        if (status.value && status.value.length > 0) {
-          let data = status.value.filter((item) => item.value == type);
-          if (data && data.length > 0) {
-            text = data[0].label;
-          }
-        }
-        return text;
+        slot: "status",
       },
     },
     {
@@ -422,14 +586,16 @@ const config = computed(() => {
   ];
 });
 const getDict = () => {
-  proxy.post("/saleQuotation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
-    accountList.value = res.rows.map((item) => {
-      return {
-        label: item.alias,
-        value: item.id,
-      };
+  proxy
+    .post("/saleQuotation/page", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      accountList.value = res.rows.map((item) => {
+        return {
+          label: item.alias,
+          value: item.id,
+        };
+      });
     });
-  });
   proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
     corporationList.value = res.rows.map((item) => {
       return {
@@ -551,7 +717,10 @@ const clickDownload = () => {
 };
 const statistics = (label, index) => {
   let num = 0;
-  if (printDetails.value.quotationProductList && printDetails.value.quotationProductList.length > 0) {
+  if (
+    printDetails.value.quotationProductList &&
+    printDetails.value.quotationProductList.length > 0
+  ) {
     printDetails.value.quotationProductList.map((item) => {
       if (item[label]) {
         num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
@@ -572,7 +741,10 @@ const getLabel = (key, list, label) => {
 };
 const getAllMoney = (num) => {
   let money = num;
-  if (printDetails.value.quotationPayList && printDetails.value.quotationPayList.length > 0) {
+  if (
+    printDetails.value.quotationPayList &&
+    printDetails.value.quotationPayList.length > 0
+  ) {
     printDetails.value.quotationPayList.map((item) => {
       if (item.amount) {
         money = parseFloat(Number(money) + Number(item.amount)).toFixed(2);
@@ -592,6 +764,44 @@ const generateContract = (row) => {
     },
   });
 };
+const pushProcessApproval = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "sale_quotation_flow",
+      id: row.flowId,
+      processType: 20,
+      random: proxy.random(),
+      flowName: "报价单详情",
+    },
+  });
+  return;
+};
+const printObj = ref({
+  id: "printMe",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
+
+const getStyle = (status) => {
+  if (status == 10) {
+    return {
+      color: "#FF9315",
+    };
+  } else if (status == 30) {
+    return {
+      color: "#39C55A",
+    };
+  } else if (status == 20 || status == 99) {
+    return {
+      color: "#FF655B",
+    };
+  } else {
+    return {};
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 141 - 53
src/views/salesMange/salesMange/profitSettlement/index.vue

@@ -15,12 +15,16 @@
           action: () => openModal(),
         },
       ]"
-      @get-list="getList">
+      @get-list="getList"
+    >
       <template #amount="{ item }">
         <div></div>
       </template>
     </byTable>
-    <div style="padding: 0 20px 20px 20px; background-color: white" v-if="rateStatus">
+    <div
+      style="padding: 0 20px 20px 20px; background-color: white"
+      v-if="rateStatus"
+    >
       <el-table v-loading="loading" :data="sourceList.data">
         <el-table-column label="合同编号">
           <el-table-column label="" prop="contractCode" width="160" />
@@ -34,55 +38,64 @@
         <el-table-column label="销售合同金额">
           <el-table-column label="" width="120">
             <template #default="{ row }">
-              <div>{{ row.currency }}{{ row.contractAmount }}</div>
+              <div>
+                {{ row.currency }} {{ moneyFormat(row.contractAmount, 2) }}
+              </div>
             </template>
           </el-table-column>
         </el-table-column>
-        <el-table-column label="收入">
+        <el-table-column label="收入(CNY)">
           <el-table-column label="合同到账" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.contractArrival }}</div>
+              <div>{{ moneyFormat(row.contractArrival, 2) }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column label="退税" width="120">
+            <template #default="{ row }">
+              <div>{{ moneyFormat(row.taxReturnMoney, 2) }}</div>
             </template>
           </el-table-column>
           <el-table-column label="其他收入" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.otherIncome }}</div>
+              <div>{{ moneyFormat(row.otherIncome, 2) }}</div>
             </template>
           </el-table-column>
         </el-table-column>
         <el-table-column label="采购合同金额">
           <el-table-column label="" width="120">
             <template #default="{ row }">
-              <div>{{ row.currency }}{{ row.purchaseAmount }}</div>
+              <div>
+                {{ row.currency }} {{ moneyFormat(row.purchaseAmount, 2) }}
+              </div>
             </template>
           </el-table-column>
         </el-table-column>
-        <el-table-column label="支出">
+        <el-table-column label="支出(CNY)">
           <el-table-column label="支付货款" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.payForGoods }}</div>
+              <div>{{ moneyFormat(row.payForGoods, 2) }}</div>
             </template>
           </el-table-column>
           <el-table-column label="其他支出" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.otherExpenses }}</div>
+              <div>{{ moneyFormat(row.otherExpenses, 2) }}</div>
             </template>
           </el-table-column>
         </el-table-column>
         <el-table-column label="统计">
           <el-table-column label="收入合计" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.totalIncome }}</div>
+              <div>{{ moneyFormat(row.totalIncome, 2) }}</div>
             </template>
           </el-table-column>
           <el-table-column label="支出合计" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.totalExpenses }}</div>
+              <div>{{ moneyFormat(row.totalExpenses, 2) }}</div>
             </template>
           </el-table-column>
           <el-table-column label="毛利" width="120">
             <template #default="{ row }">
-              <div>¥{{ row.grossProfit }}</div>
+              <div>{{ moneyFormat(row.grossProfit, 2) }}</div>
             </template>
           </el-table-column>
           <el-table-column label="毛利率" prop="grossProfitMargin" width="120">
@@ -94,9 +107,23 @@
         <el-table-column label="操作" align="center" width="170" fixed="right">
           <template #default="{ row }">
             <div>
-              <el-button type="primary" @click="changeExchangeRate(row)" link>调整汇率</el-button>
-              <el-button type="primary" @click="clickSettlement(row)" v-if="row.settlementStatus === 0" link>结算</el-button>
-              <el-button type="primary" @click="clickCancelSettlement(row)" v-else link>取消结算</el-button>
+              <el-button type="primary" @click="changeExchangeRate(row)" link
+                >调整汇率</el-button
+              >
+              <el-button
+                type="primary"
+                @click="clickSettlement(row)"
+                v-if="row.settlementStatus === 0"
+                link
+                >结算</el-button
+              >
+              <el-button
+                type="primary"
+                @click="clickCancelSettlement(row)"
+                v-else
+                link
+                >取消结算</el-button
+              >
             </div>
           </template>
         </el-table-column>
@@ -109,14 +136,30 @@
           :page-size="sourceList.pagination.pageSize"
           :total="sourceList.pagination.total"
           @size-change="handleSizeChange"
-          @current-change="handlePageChange" />
+          @current-change="handlePageChange"
+        />
       </el-row>
     </div>
 
-    <el-dialog title="默认汇率" v-if="dialogVisible" v-model="dialogVisible" width="600">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+    <el-dialog
+      title="默认汇率"
+      v-if="dialogVisible"
+      v-model="dialogVisible"
+      width="600"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="submit"
+      >
         <template #currencyList>
-          <el-table :data="formData.data.list" style="width: 100%" v-loading="loadingDialog">
+          <el-table
+            :data="formData.data.list"
+            style="width: 100%"
+            v-loading="loadingDialog"
+          >
             <el-table-column label="币种">
               <template #default="{ row }">
                 <div>{{ dictValueLabel(row.type, accountCurrency) }}</div>
@@ -124,8 +167,19 @@
             </el-table-column>
             <el-table-column label="兑 CHY 汇率">
               <template #default="{ row, $index }">
-                <el-form-item :prop="'list.' + $index + '.rate'" :rules="rules.rate" :inline-message="true">
-                  <el-input-number v-model="row.rate" placeholder="请输入兑 CHY 汇率" style="width: 100%" :precision="6" :controls="false" :min="0" />
+                <el-form-item
+                  :prop="'list.' + $index + '.rate'"
+                  :rules="rules.rate"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.rate"
+                    placeholder="请输入兑 CHY 汇率"
+                    style="width: 100%"
+                    :precision="6"
+                    :controls="false"
+                    :min="0"
+                  />
                 </el-form-item>
               </template>
             </el-table-column>
@@ -134,14 +188,31 @@
       </byForm>
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm()" size="large">确 定</el-button>
+        <el-button type="primary" @click="submitForm()" size="large"
+          >确 定</el-button
+        >
       </template>
     </el-dialog>
 
-    <el-dialog title="调整汇率" v-if="openChange" v-model="openChange" width="600">
-      <byForm :formConfig="formChangeConfig" :formOption="formOption" v-model="formChangeData.data" :rules="rules" ref="change">
+    <el-dialog
+      title="调整汇率"
+      v-if="openChange"
+      v-model="openChange"
+      width="600"
+    >
+      <byForm
+        :formConfig="formChangeConfig"
+        :formOption="formOption"
+        v-model="formChangeData.data"
+        :rules="rules"
+        ref="change"
+      >
         <template #currencyList>
-          <el-table :data="formChangeData.data.list" style="width: 100%" v-loading="loadingDialog">
+          <el-table
+            :data="formChangeData.data.list"
+            style="width: 100%"
+            v-loading="loadingDialog"
+          >
             <el-table-column label="币种">
               <template #default="{ row }">
                 <div>{{ dictValueLabel(row.type, accountCurrency) }}</div>
@@ -149,8 +220,19 @@
             </el-table-column>
             <el-table-column label="兑 CHY 汇率">
               <template #default="{ row, $index }">
-                <el-form-item :prop="'list.' + $index + '.rate'" :rules="rules.rate" :inline-message="true">
-                  <el-input-number v-model="row.rate" placeholder="请输入兑 CHY 汇率" style="width: 100%" :precision="6" :controls="false" :min="0" />
+                <el-form-item
+                  :prop="'list.' + $index + '.rate'"
+                  :rules="rules.rate"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.rate"
+                    placeholder="请输入兑 CHY 汇率"
+                    style="width: 100%"
+                    :precision="6"
+                    :controls="false"
+                    :min="0"
+                  />
                 </el-form-item>
               </template>
             </el-table-column>
@@ -159,7 +241,9 @@
       </byForm>
       <template #footer>
         <el-button @click="openChange = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitChangeForm()" size="large">确 定</el-button>
+        <el-button type="primary" @click="submitChangeForm()" size="large"
+          >确 定</el-button
+        >
       </template>
     </el-dialog>
   </div>
@@ -253,13 +337,15 @@ const getDict = () => {
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/saleStatement/getProfitSettlement", sourceList.value.pagination).then((res) => {
-    sourceList.value.data = res.rows;
-    sourceList.value.pagination.total = res.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-  });
+  proxy
+    .post("/saleStatement/getProfitSettlement", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
 };
 const rateStatus = ref(false);
 const judgeRate = () => {
@@ -466,10 +552,10 @@ const submitChangeForm = () => {
     let data = {};
     data.id = formChangeData.data.id;
     data.currencyRateJson = JSON.stringify(formChangeData.data.list);
-    proxy.post("/commission/add", data).then(
+    proxy.post("/saleStatement/update", data).then(
       () => {
         ElMessage({
-          message: "保存成功",
+          message: "操作成功",
           type: "success",
         });
         openChange.value = false;
@@ -483,29 +569,31 @@ const submitChangeForm = () => {
   });
 };
 const clickSettlement = (row) => {
-  let data = proxy.deepClone(row);
-  data.afterSalesAmount = 0;
-  data.publicAmount = 0;
-  data.haveOverallAmount = 0;
-  data.departmentalCommission = 0;
-  data.personalCommission = 0;
-  data.settlementStatus = 1;
-  proxy.post("/commission/add", data).then(() => {
+  const data = {
+    id: row.contractId,
+    settlementStatus: 1,
+  };
+  proxy.post("/saleStatement/update", data).then(() => {
     ElMessage({
-      message: "保存成功",
+      message: "操作成功",
       type: "success",
     });
     getList();
   });
 };
 const clickCancelSettlement = (row) => {
-  proxy.post("/commission/add", { id: row.contractId, settlementStatus: 0 }).then(() => {
-    ElMessage({
-      message: "保存成功",
-      type: "success",
+  proxy
+    .post("/saleStatement/update", {
+      id: row.contractId,
+      settlementStatus: 0,
+    })
+    .then(() => {
+      ElMessage({
+        message: "操作成功",
+        type: "success",
+      });
+      getList();
     });
-    getList();
-  });
 };
 </script>
 

+ 2 - 2
src/views/salesMange/shipmentMange/document/index.vue

@@ -1655,13 +1655,13 @@ const getAllMoney = (num) => {
   border-right: 1px solid black;
   border-bottom: 1px solid black;
 }
-:deep(.el-textarea__inner) {
+:deep(#pdfDom .el-textarea__inner) {
   background: transparent !important;
   overflow-y: hidden;
   padding: 0 4px !important;
   resize: none;
 }
-:deep(.el-textarea) {
+:deep(#pdfDom .el-textarea) {
   --el-input-focus-border: transparent;
   --el-input-transparent-border: 0 0 0 0px;
   --el-input-border-color: transparent;

+ 117 - 35
src/views/salesMange/shipmentMange/packing/index.vue

@@ -47,6 +47,48 @@
             </div>
           </div>
         </template>
+        <template #netWeight="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.netWeight + " kg" }}
+            </div>
+          </div>
+        </template>
+        <template #roughWeight="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.roughWeight + " kg" }}
+            </div>
+          </div>
+        </template>
+        <template #boxLong="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxLong + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #boxWide="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxWide + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #boxHigh="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxHigh + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #bomVolume="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.bomVolume + " m³" }}
+            </div>
+          </div>
+        </template>
       </byTable>
     </div>
     <el-dialog
@@ -103,6 +145,7 @@
             :data="formData.data.contractProductData"
             @select="handleSelectProduct"
             @select-all="handleSelectProduct"
+            ref="tableDom"
           >
             <el-table-column type="selection" label="" width="50" />
             <el-table-column prop="contractCode" label="合同编码" />
@@ -120,6 +163,7 @@
                     :precision="4"
                     :controls="false"
                     :min="0"
+                    onmousewheel="return false;"
                   />
                 </el-form-item>
               </template>
@@ -341,6 +385,7 @@
                         :precision="4"
                         :controls="false"
                         :min="0"
+                        onmousewheel="return false;"
                       />
                     </el-form-item>
                   </template>
@@ -499,53 +544,64 @@ const config = computed(() => {
     {
       attrs: {
         label: "净重",
-        prop: "netWeight",
+        slot: "netWeight",
         width: 90,
       },
-      render(netWeight) {
-        return netWeight + "kg";
-      },
     },
     {
       attrs: {
         label: "毛重",
-        prop: "roughWeight",
+        slot: "roughWeight",
         width: 90,
       },
-
-      render(roughWeight) {
-        return roughWeight + "kg";
-      },
     },
     {
       attrs: {
         label: "长",
-        prop: "boxLong",
+        slot: "boxLong",
         width: 90,
       },
-      render(boxLong) {
-        return boxLong + "cm";
-      },
     },
 
     {
       attrs: {
         label: "宽",
-        prop: "boxWide",
+        slot: "boxWide",
         width: 90,
       },
-      render(boxWide) {
-        return boxWide + "cm";
-      },
     },
     {
       attrs: {
         label: "高",
-        prop: "boxHigh",
+        slot: "boxHigh",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "体积",
+        slot: "bomVolume",
         width: 90,
       },
-      render(boxHigh) {
-        return boxHigh + "cm";
+    },
+    {
+      attrs: {
+        label: "总净重",
+        prop: "netWeight",
+        width: 120,
+      },
+      render(netWeight) {
+        return netWeight + " kg";
+      },
+    },
+    {
+      attrs: {
+        label: "总毛重",
+        prop: "roughWeight",
+        width: 120,
+      },
+      render(roughWeight) {
+        return roughWeight + " kg";
       },
     },
     {
@@ -555,7 +611,7 @@ const config = computed(() => {
         width: 120,
       },
       render(bomVolume) {
-        return bomVolume + "m³";
+        return bomVolume + " m³";
       },
     },
     {
@@ -574,6 +630,13 @@ const config = computed(() => {
         prop: "shipmentTime",
         width: 155,
       },
+      render(shipmentTime) {
+        if (shipmentTime) {
+          return shipmentTime.slice(5, 10);
+        } else {
+          return "";
+        }
+      },
     },
     {
       attrs: {
@@ -661,18 +724,33 @@ const getList = async (req) => {
   selectData.value = [];
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy
-    .post("/packDetail/page", sourceList.value.pagination)
-    .then((message) => {
-      sourceList.value.data = message.rows.map((x) => ({
-        ...x,
-        isCheck: x.shipmentStatus == 1 ? false : true,
-      }));
-      sourceList.value.pagination.total = message.total;
-      setTimeout(() => {
-        loading.value = false;
-      }, 200);
-    });
+  proxy.post("/packDetail/page", sourceList.value.pagination).then((res) => {
+    for (let i = 0; i < res.rows.length; i++) {
+      const e = res.rows[i];
+      e.isCheck = e.shipmentStatus == 1 ? false : true;
+      let arr = [];
+      let newArr = [];
+      arr = e.dataJsonList.split("_");
+      for (let j = 0; j < arr.length; j++) {
+        const jele = arr[j];
+        const jarr = jele.split(",");
+        const obj = {
+          bomVolume: jarr[0],
+          boxLong: jarr[1],
+          boxWide: jarr[2],
+          boxHigh: jarr[3],
+          roughWeight: jarr[4],
+          netWeight: jarr[5],
+        };
+        let createArr = new Array(Number(jarr[6])).fill(obj);
+        newArr = [...newArr, ...createArr];
+      }
+      e.dataJsonListCopy = newArr;
+    }
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    loading.value = false;
+  });
 };
 
 const openModal = () => {
@@ -696,7 +774,7 @@ const openModalOne = () => {
   for (let i = 0; i < list.length; i++) {
     const e = list[i];
     ids = [...ids, ...e.contractIds.split(",")];
-    idsOne.push(e.id);
+    idsOne = [...idsOne, ...e.ids.split(",")];
   }
   formData.dataOne.ids = idsOne;
   proxy.post(`/contract/getByIds`, ids).then((res) => {
@@ -743,7 +821,7 @@ const submitForm = () => {
     }
   });
 };
-
+const table = ref(null);
 const submitFormOne = () => {
   byform.value.handleSubmit((valid) => {
     loading.value = true;
@@ -776,6 +854,7 @@ const selectProductData = ref([]);
 const handleSelectProduct = (data) => {
   selectProductData.value = data;
 };
+const tableDom = ref(null);
 const handleClickPacking = () => {
   if (selectProductData.value.length > 0) {
     const list = selectProductData.value;
@@ -832,7 +911,9 @@ const handleClickPacking = () => {
       item.packQuantity,
       formData.data.packDetailList.length - 1
     );
+    tableDom.value.clearSelection();
     selectProductData.value = [];
+    table.value.clearSelection();
   } else {
     return ElMessage({
       message: "请选择产品 !",
@@ -984,6 +1065,7 @@ getList();
     flex-wrap: wrap;
     .item {
       width: 50%;
+      margin-bottom: 10px;
       div {
         line-height: 22px;
       }

+ 6 - 6
src/views/system/dept2/index.vue

@@ -62,14 +62,14 @@
         </template>
       </byForm>
       <template #footer>
-        <el-button @click="dialogVisible = false" size="large">{{$t('dept.cancel')}}</el-button>
-        <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading">{{$t('dept.confirm')}}</el-button>
+        <el-button @click="dialogVisible = false" size="large">{{$t('common.cancel')}}</el-button>
+        <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading">{{$t('common.confirm')}}</el-button>
       </template>
     </el-dialog>
     <el-dialog title="修改密码" v-model="roomDialogVisible" width="500" :before-close="handleClose" v-loading="loading">
       <template #footer>
-        <el-button @click="roomDialogVisible = false" size="large">{{$t('dept.cancel')}}</el-button>
-        <el-button type="primary" @click="submitTree('byform')" size="large" :loading="submitLoading">{{$t('dept.confirm')}}</el-button>
+        <el-button @click="roomDialogVisible = false" size="large">{{$t('common.cancel')}}</el-button>
+        <el-button type="primary" @click="submitTree('byform')" size="large" :loading="submitLoading">{{$t('common.confirm')}}</el-button>
       </template>
     </el-dialog>
   </div>
@@ -391,7 +391,7 @@ const showType = (type) => {
 const getDtl = (row) => {
   formData.data = { ...row };
   modalType.value = "edit";
-  getUserList();
+  
   dialogVisible.value = true;
 };
 
@@ -412,7 +412,7 @@ const getUserList = () => {
       console.log(config);
     });
 };
-
+getUserList();
 getTreeList();
 getList();
 </script>

+ 9 - 0
src/views/system/user2/index.vue

@@ -121,7 +121,16 @@ const config = computed(() => {
       render(userType) {
         return userType == 1 ? "是" : "否";
       },
+    },{
+      attrs: {
+        label: "角色",
+        prop: "sysRoleList",
+      },
+      render(sysRoleList) {
+        return sysRoleList.map((item) => item.roleName).join(",")
+      },
     },
+    
     {
       attrs: {
         label: "手机号",

Some files were not shown because too many files changed in this diff