Quellcode durchsuchen

Merge branch 'master' of http://47.101.159.18:3000/Muchinfo/MTP2.0_WEB

li.shaoyi vor 4 Jahren
Ursprung
Commit
0f64eaa0bd
91 geänderte Dateien mit 5447 neuen und 1025 gelöschten Zeilen
  1. 1 1
      public/config/app.config.json
  2. 18 0
      public/proto/mtp.proto
  3. 705 47
      src/assets/styles/index.css
  4. 60 30
      src/assets/styles/index.less
  5. 24 4
      src/assets/styles/mixin.less
  6. 26 3
      src/assets/styles/symbol_no_color/demo_index.html
  7. 7 3
      src/assets/styles/symbol_no_color/iconfont.css
  8. 0 0
      src/assets/styles/symbol_no_color/iconfont.js
  9. 7 0
      src/assets/styles/symbol_no_color/iconfont.json
  10. BIN
      src/assets/styles/symbol_no_color/iconfont.ttf
  11. BIN
      src/assets/styles/symbol_no_color/iconfont.woff
  12. BIN
      src/assets/styles/symbol_no_color/iconfont.woff2
  13. 6 0
      src/assets/styles/theme.css
  14. 2 0
      src/assets/styles/variables.less
  15. 15 1
      src/common/components/filter/index.vue
  16. 7 2
      src/common/components/friends/index.vue
  17. 9 5
      src/common/components/thirdMenu/index.vue
  18. 17 0
      src/common/constants/enumCommon.ts
  19. 3 0
      src/common/constants/enumsName.ts
  20. 26 0
      src/common/setup/account/index.ts
  21. 2 2
      src/common/setup/form/index.ts
  22. 15 9
      src/common/setup/table/tableQuote.ts
  23. 171 0
      src/common/setup/trade/index.ts
  24. 13 0
      src/common/setup/trade/interface.ts
  25. 8 0
      src/router/index.ts
  26. 12 4
      src/services/bus/account.ts
  27. 13 2
      src/services/bus/goods.ts
  28. 14 0
      src/services/bus/market.ts
  29. 3 2
      src/services/bus/user.ts
  30. 3 0
      src/services/funcode/index.ts
  31. 41 0
      src/services/go/Tjmd/index.ts
  32. 91 0
      src/services/go/Tjmd/interface.ts
  33. 11 0
      src/services/go/order/index.ts
  34. 61 0
      src/services/go/order/interface.ts
  35. 1 1
      src/services/go/wrtrade/interface.ts
  36. 12 1
      src/services/proto/warehousetrade/index.ts
  37. 10 0
      src/services/proto/warehousetrade/interface.ts
  38. 6 0
      src/services/socket/order/index.ts
  39. 5 1
      src/services/socket/protobuf/protoHeader.ts
  40. 4 0
      src/utils/eventBus/index.ts
  41. 1 0
      src/utils/timer/timerUtil.ts
  42. 1 0
      src/views/market/spot_trade/components/buy-sell-market/components/financing_delisting/components/choose-finance/index.vue
  43. 16 2
      src/views/market/spot_trade/components/filter/index.vue
  44. 1 1
      src/views/market/spot_trade/spot_trade_order_transaction/setup.ts
  45. 157 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy-sell-market/index.vue
  46. 159 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy/index.vue
  47. 426 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/index.vue
  48. 13 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/interface.ts
  49. 31 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/setup.ts
  50. 125 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/detail/index.vue
  51. 119 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/history-chart/index.vue
  52. 437 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/index.vue
  53. 14 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/interface.ts
  54. 80 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts
  55. 169 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/sell/index.vue
  56. 43 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/setup.ts
  57. 206 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue
  58. 6 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/interface.ts
  59. 112 0
      src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/setup.ts
  60. 7 3
      src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/index.vue
  61. 18 14
      src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/post-buying/index.vue
  62. 7 3
      src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/delisting/index.vue
  63. 163 155
      src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/post-buying/index.vue
  64. 125 0
      src/views/order/commodity_contract/components/commodity_contract_bargain/index.vue
  65. 9 0
      src/views/order/commodity_contract/components/commodity_contract_bargain/setup.ts
  66. 419 0
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/index.vue
  67. 10 0
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/interface.ts
  68. 49 0
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/setup.ts
  69. 2 1
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_settlement/index.vue
  70. 1 1
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_settlement/setup.ts
  71. 2 1
      src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_transfer/index.vue
  72. 13 2
      src/views/order/commodity_contract/components/commodity_contract_summary/index.vue
  73. 33 10
      src/views/order/commodity_contract/index.vue
  74. 21 2
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/components/bargain_detail/index.vue
  75. 17 2
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/index.vue
  76. 4 0
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/setup.ts
  77. 276 281
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_order_summary/components/listed/index.vue
  78. 121 0
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_pending_order/components/detail/index.vue
  79. 7 1
      src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_pending_order/index.vue
  80. 19 1
      src/views/order/spot_warran/components/spot_warrant_bargain/components/bargain_detail/index.vue
  81. 19 3
      src/views/order/spot_warran/components/spot_warrant_bargain/index.vue
  82. 4 0
      src/views/order/spot_warran/components/spot_warrant_bargain/setup.ts
  83. 13 13
      src/views/order/spot_warran/components/spot_warrant_in_and_out_warehouse/components/cancel/index.vue
  84. 13 13
      src/views/order/spot_warran/components/spot_warrant_in_and_out_warehouse/components/pick_up/index.vue
  85. 121 0
      src/views/order/spot_warran/components/spot_warrant_pending_order/components/detail/index.vue
  86. 7 1
      src/views/order/spot_warran/components/spot_warrant_pending_order/index.vue
  87. 260 264
      src/views/order/spot_warran/components/spot_warrant_spot_details/components/listing/index.vue
  88. 2 2
      src/views/ping_an/spot_price_management/spot_price_management_pending/index.vue
  89. 3 2
      src/views/setting/friends/index.vue
  90. 51 46
      swagger-to-ts/swagger.ts
  91. 86 83
      swagger-to-ts/swagger.txt

+ 1 - 1
public/config/app.config.json

@@ -1,3 +1,3 @@
 {
-    "apiUrl": "http://192.168.31.139:8080/cfg?key=test_139"
+    "apiUrl": "http://103.40.249.123:38280/cfg?key=mtp_20"
 }

+ 18 - 0
public/proto/mtp.proto

@@ -439,6 +439,24 @@ message SearchReceiverRsp {
 		repeated ReceiverInfo InfoList = 5; // 用户收货信息
 }
 
+// 按单协议平仓申请 0 29 213
+message TradeHoldTransferApplyReq {
+	optional MessageHead Header = 1; // MessageHead
+	optional uint64 TradeID = 2; // uint64 申请人的持仓单表ID
+	optional uint32 BuyorSell = 3; // uint32 持仓单方向  卖 - 0:买 1:卖
+	optional double TransferPrice = 4; // double 转让价格
+	optional uint32 ApplySrc = 5; // uint32 申请来源 - 1:管理端 2:终端
+	optional uint64 ApplicantID = 6; // uint64 登录账号
+	optional string Remark = 7; // string 申请备注
+}
+// 按单协议平仓申请响应 0 29 214
+message TradeHoldTransferApplyRsp {
+	optional MessageHead Header = 1; // MessageHead 消息头
+	optional int32 RetCode = 2; // int32 返回码
+	optional string RetDesc = 3; // string 描述信息
+	optional uint64 applyid = 4; // uint64 申请ID
+}
+
 // 新增修改收货地址请求
 message UserReceiveInfoReq {
 	optional MessageHead Header = 1;

Datei-Diff unterdrückt, da er zu groß ist
+ 705 - 47
src/assets/styles/index.css


+ 60 - 30
src/assets/styles/index.less

@@ -25,32 +25,37 @@ body {
 // 布局组件样式初始化
 .ant-layout {
     background: @m-white0;
+
     aside {
         background: @m-white0;
+
         .ant-layout-sider-children {
-            section {
-            }
+            section {}
         }
     }
-    > section {
+
+    >section {
         header {
             background: @m-white0;
             padding: 0;
         }
+
         main {
             background: @m-white0;
-            header {
-            }
-            main {
-            }
+
+            header {}
+
+            main {}
         }
     }
 }
 
 .ant-card .ant-card-head {
     border: none;
+
     .ant-card-head-wrapper {
         border-bottom: 1px solid @m-white2;
+
         .ant-card-head-title {
             text-align: left;
             font-size: 16px;
@@ -61,25 +66,29 @@ body {
     }
 }
 
-.ant-steps .ant-steps-item:not(.ant-steps-item-active) > .ant-steps-item-container[role='button']:hover .ant-steps-item-title,
-.ant-steps .ant-steps-item:not(.ant-steps-item-active) > .ant-steps-item-container[role='button']:hover .ant-steps-item-subtitle,
-.ant-steps .ant-steps-item:not(.ant-steps-item-active) > .ant-steps-item-container[role='button']:hover .ant-steps-item-description {
+.ant-steps .ant-steps-item:not(.ant-steps-item-active)>.ant-steps-item-container[role='button']:hover .ant-steps-item-title,
+.ant-steps .ant-steps-item:not(.ant-steps-item-active)>.ant-steps-item-container[role='button']:hover .ant-steps-item-subtitle,
+.ant-steps .ant-steps-item:not(.ant-steps-item-active)>.ant-steps-item-container[role='button']:hover .ant-steps-item-description {
     color: @m-green2;
 }
-.ant-steps .ant-steps-item:not(.ant-steps-item-active):not(.ant-steps-item-process) > .ant-steps-item-container[role='button']:hover .ant-steps-item-icon {
+
+.ant-steps .ant-steps-item:not(.ant-steps-item-active):not(.ant-steps-item-process)>.ant-steps-item-container[role='button']:hover .ant-steps-item-icon {
     border-color: @m-green2;
 }
+
 .ant-modal-title {
     font-size: 18px;
     font-family: Source Han Sans CN;
     font-weight: 500;
     color: @m-green3;
 }
+
 .submit {
     background: @m-green3;
     border-radius: 3px;
     color: @m-white0;
 }
+
 .ant-btn-primary {
     background-color: @m-green3;
 }
@@ -94,8 +103,8 @@ body {
 .ant-menu-submenu-title:hover,
 .ant-menu-submenu-selected,
 .ant-menu-item-selected,
-.ant-menu-item-selected > a,
-.ant-menu-item-selected > a:hover {
+.ant-menu-item-selected>a,
+.ant-menu-item-selected>a:hover {
     color: @m-green3;
 }
 
@@ -109,7 +118,7 @@ body {
 .ant-checkbox-checked::after,
 .ant-checkbox-wrapper:hover .ant-checkbox-inner,
 .ant-checkbox:hover .ant-checkbox-inner,
-.ant-checkbox-input:focus + .ant-checkbox-inner,
+.ant-checkbox-input:focus+.ant-checkbox-inner,
 .ant-input-affix-wrapper:hover,
 .ant-input-affix-wrapper:focus,
 .ant-select:not(.ant-select-disabled):hover .ant-select-selector,
@@ -152,19 +161,22 @@ body {
     overflow: hidden;
 }
 
-.ant-spin-nested-loading > div > .ant-spin {
+.ant-spin-nested-loading>div>.ant-spin {
     // height: 90%;
     max-height: 100%;
 }
+
 .ant-spin-nested-loading {
     width: 100%;
     height: 100%;
+
     .ant-spin-container {
         width: 100%;
         height: 100%;
         display: flex;
     }
 }
+
 .ant-switch-checked {
     background-color: @theme;
 }
@@ -198,6 +210,7 @@ body {
     width: 120px;
     display: inline-block;
 }
+
 .ellipsis_temp {
     white-space: nowrap;
     overflow: hidden;
@@ -210,32 +223,36 @@ body {
 .ant-menu-dark,
 .ant-menu-dark {
     background-color: @m-grey18;
+
     .ant-menu-submenu-title {
         font-size: 16px;
         text-align: left;
     }
+
     .ant-menu-sub {
         background-color: @m-black4;
+
         .ant-menu-item {
             font-size: 14px;
             font-family: @menu-item-family;
             color: @menu-item-color;
             text-align: left;
         }
+
         .ant-menu-item-selected {
             color: @m-white0;
         }
     }
 }
 
-.ant-menu-horizontal > .ant-menu-item-active,
-.ant-menu-horizontal > .ant-menu-item-open,
-.ant-menu-horizontal > .ant-menu-item-selected,
-.ant-menu-horizontal > .ant-menu-item:hover,
-.ant-menu-horizontal > .ant-menu-submenu-active,
-.ant-menu-horizontal > .ant-menu-submenu-open,
-.ant-menu-horizontal > .ant-menu-submenu-selected,
-.ant-menu-horizontal > .ant-menu-submenu:hover {
+.ant-menu-horizontal>.ant-menu-item-active,
+.ant-menu-horizontal>.ant-menu-item-open,
+.ant-menu-horizontal>.ant-menu-item-selected,
+.ant-menu-horizontal>.ant-menu-item:hover,
+.ant-menu-horizontal>.ant-menu-submenu-active,
+.ant-menu-horizontal>.ant-menu-submenu-open,
+.ant-menu-horizontal>.ant-menu-submenu-selected,
+.ant-menu-horizontal>.ant-menu-submenu:hover {
     color: @theme;
 }
 
@@ -259,23 +276,28 @@ body {
         }
 
 
-        > tr:first-child {
-            > th:last-child, > th:first-child {
+        >tr:first-child {
+
+            >th:last-child,
+            >th:first-child {
                 border-radius: 0px;
 
             }
         }
     }
 
-    .ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
+    .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td {
         background: @m-blue3;
     }
+
     .ant-table-body tr td {
         background-color: @m-black2;
         color: white;
         cursor: pointer;
     }
-    .ant-table-bordered .ant-table-thead > tr > th, .ant-table-bordered .ant-table-tbody > tr > td {
+
+    .ant-table-bordered .ant-table-thead>tr>th,
+    .ant-table-bordered .ant-table-tbody>tr>td {
         padding: 0;
         height: 34px;
         line-height: 34px;
@@ -283,12 +305,13 @@ body {
         font-family: Adobe Heiti Std;
         font-size: 16px;
     }
+
     .ant-table-fixed {
         width: max-content !important;
         color: @m-white1;
         background: @m-black2;
-        border-top-color: @m-black2 !important;
-        border-left-color: @m-black9 !important;
+        border-top-color: @m-black2  !important;
+        border-left-color: @m-black9  !important;
     }
 }
 
@@ -303,7 +326,8 @@ body {
 
 .iframe-container {
     height: calc(100% - 40px);
-    > iframe {
+
+    >iframe {
         border: 0;
         width: 100%;
         height: 100%;
@@ -314,6 +338,12 @@ body {
 .up-quote-color {
     color: @m-red1;
 }
+
 .down-quote-color {
     color: @m-green4;
+}
+
+// 不可复制
+.not-copy {
+    user-select: none
 }

+ 24 - 4
src/assets/styles/mixin.less

@@ -784,7 +784,9 @@
 
         }
     }
-
+    .mb10.ant-row.ant-form-item {
+        margin-bottom: 10px;
+    }
     .relative.ant-form-item {
         position: relative;
 
@@ -1204,7 +1206,9 @@
 .mt10 {
     margin-top: 10px;
 }
-
+.mt12 {
+    margin-top: 12px;
+}
 .mt20 {
     margin-top: 20px;
 }
@@ -2240,9 +2244,9 @@ input:-internal-autofill-selected {
     }
 }
 
-.commonRadioGroup {
+.commonRadioGroup,.conditionCommonRadioGroup {
     .ant-radio-wrapper {
-        color: @m-white0;
+        color: @m-white6;
         font-size: 14px;
 
         .ant-radio {
@@ -2285,6 +2289,22 @@ input:-internal-autofill-selected {
         }
     }
 }
+.conditionCommonRadioGroup {
+    margin-bottom: 2px;
+    .ant-radio-wrapper {
+        font-size: 12px;
+        .ant-radio {
+            .ant-radio-inner {
+               width: 14px;
+               height: 14px;
+               &::after {
+                    left: 3px;
+                    top: 3px;
+                }
+            }
+        }
+    }
+}
 
 .tc {
     text-align: center;

+ 26 - 3
src/assets/styles/symbol_no_color/demo_index.html

@@ -55,6 +55,12 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe70a;</span>
+                <div class="name">切换</div>
+                <div class="code-name">&amp;#xe70a;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe653;</span>
                 <div class="name">表单 列表-03</div>
                 <div class="code-name">&amp;#xe653;</div>
@@ -372,9 +378,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1630590563275') format('woff2'),
-       url('iconfont.woff?t=1630590563275') format('woff'),
-       url('iconfont.ttf?t=1630590563275') format('truetype');
+  src: url('iconfont.woff2?t=1632896613541') format('woff2'),
+       url('iconfont.woff?t=1632896613541') format('woff'),
+       url('iconfont.ttf?t=1632896613541') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -401,6 +407,15 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-B"></span>
+            <div class="name">
+              切换
+            </div>
+            <div class="code-name">.icon-B
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-biaodanliebiao-"></span>
             <div class="name">
               表单 列表-03
@@ -879,6 +894,14 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-B"></use>
+                </svg>
+                <div class="name">切换</div>
+                <div class="code-name">#icon-B</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-biaodanliebiao-"></use>
                 </svg>
                 <div class="name">表单 列表-03</div>

+ 7 - 3
src/assets/styles/symbol_no_color/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2293216 */
-  src: url('iconfont.woff2?t=1630590563275') format('woff2'),
-       url('iconfont.woff?t=1630590563275') format('woff'),
-       url('iconfont.ttf?t=1630590563275') format('truetype');
+  src: url('iconfont.woff2?t=1632896613541') format('woff2'),
+       url('iconfont.woff?t=1632896613541') format('woff'),
+       url('iconfont.ttf?t=1632896613541') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-B:before {
+  content: "\e70a";
+}
+
 .icon-biaodanliebiao-:before {
   content: "\e653";
 }

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
src/assets/styles/symbol_no_color/iconfont.js


+ 7 - 0
src/assets/styles/symbol_no_color/iconfont.json

@@ -6,6 +6,13 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "13479212",
+      "name": "切换",
+      "font_class": "B",
+      "unicode": "e70a",
+      "unicode_decimal": 59146
+    },
+    {
       "icon_id": "13965701",
       "name": "表单 列表-03",
       "font_class": "biaodanliebiao-",

BIN
src/assets/styles/symbol_no_color/iconfont.ttf


BIN
src/assets/styles/symbol_no_color/iconfont.woff


BIN
src/assets/styles/symbol_no_color/iconfont.woff2


+ 6 - 0
src/assets/styles/theme.css

@@ -122,6 +122,8 @@
     --m-black44: #1B2F41;
     --m-black45: #10202F;
     --m-black46: rgba(0, 0, 0, 0.45);
+    --m-black47: #0e263a;
+    --m-black48: rgba(122, 155, 164,0.20);
 
     --m-blue0: #3a87f7;
     --m-blue0-hover: rgba(58, 135, 247, .8);
@@ -335,6 +337,8 @@
     --m-black44: #1B2F41;
     --m-black45: #10202F;
     --m-black46: rgba(0, 0, 0, 0.45);
+    --m-black47: #0e263a;
+    --m-black48: rgba(122, 155, 164,0.20);
 
     --m-blue0: #3a87f7;
     --m-blue0-hover: rgba(58, 135, 247, .8);
@@ -544,6 +548,8 @@
     --m-black44: #ebf1f5;
     --m-black45: #D6E0F0;
     --m-black46: rgba(0, 0, 0, 0.45);
+    --m-black47: #ffffff;
+    --m-black48: rgba(122, 155, 164,0.20);
 
     --m-blue0: #5179E2;
     --m-blue0-hover: rgba(81, 121, 226, .8);

+ 2 - 0
src/assets/styles/variables.less

@@ -130,6 +130,8 @@
 @m-black44: var(--m-black44);
 @m-black45: var(--m-black45);
 @m-black46: var(--m-black46);
+@m-black47: var(--m-black47);
+@m-black48: var(--m-black48);
 
 @m-blue0: var(--m-blue0);
 @m-blue0-hover: var(--m-blue0-hover);

+ 15 - 1
src/common/components/filter/index.vue

@@ -62,6 +62,15 @@ export default defineComponent({
 </script>
 
 <style lang="less">
+.btnDeafault.ant-btn {
+    margin-left: 0;
+}
+.ant-select + .btnDeafault.ant-btn {
+    margin-left: 10px;
+}
+.ant-space.ant-space-vertical + .btnDeafault.ant-btn {
+    margin-left: 0;
+}
 .filter-custom-table {
     display: inline-flex;
     padding-top: 4px;
@@ -74,8 +83,12 @@ export default defineComponent({
         height: 26px !important;
         line-height: 26px !important;
     }
+
+    .ant-select-single:not(.ant-select-customize-input) + .ant-select-single:not(.ant-select-customize-input),
+    .ant-select + .ant-space.ant-space-vertical {
+        margin-left: 10px;
+    }
     .ant-select-single:not(.ant-select-customize-input) {
-        margin-right: 10px;
         height: 26px;
         line-height: 26px !important;
         .ant-select-selector {
@@ -98,6 +111,7 @@ export default defineComponent({
             }
         }
     }
+
     .allDatePicker.ant-calendar-picker {
         height: 26px !important;
         border: 1px solid @m-grey46 !important;

+ 7 - 2
src/common/components/friends/index.vue

@@ -69,6 +69,10 @@ export default defineComponent({
             type: String,
             default: 'top',
         },
+        friends: {
+            type: Array as PropType<number[]>,
+            default: [],
+        },
     },
     setup(props, context) {
         const { visible, cancel } = _closeModal(context);
@@ -83,7 +87,8 @@ export default defineComponent({
                     if (res) {
                         myFriends.value = [];
                         res.forEach((el) => {
-                            myFriends.value.push({ ...el, checked: false });
+                            const checked = props.friends.includes(el.frienduserid) ? true : false;
+                            myFriends.value.push({ ...el, checked });
                         });
                     }
                 })
@@ -101,7 +106,7 @@ export default defineComponent({
             }
         }
         function submit() {
-            const result: string[] = [];
+            const result: number[] = [];
             myFriends.value.forEach((el) => {
                 if (el.checked) {
                     result.push(el.frienduserid);

+ 9 - 5
src/common/components/thirdMenu/index.vue

@@ -1,9 +1,13 @@
 <template>
-    <div class="thirdMenu">
-        <a-tabs v-model:activeKey="current" @change="menuClick">
-            <a-tab-pane :key="String(index)" v-for="(item, index) in list" :tab="item[value]"></a-tab-pane>
-        </a-tabs>
-    </div>
+  <div class="thirdMenu">
+    <a-tabs v-model:activeKey="current"
+            @change="menuClick">
+      <a-tab-pane :key="String(index)"
+                  v-for="(item, index) in list"
+                  :tab="item[value]"></a-tab-pane>
+    </a-tabs>
+    <slot></slot>
+  </div>
 </template>
 
 <script lang="ts">

+ 17 - 0
src/common/constants/enumCommon.ts

@@ -116,6 +116,7 @@ export enum TradeMode {
     Bidding_large = 21, // 受托竞价
     EntrustedBidding = 21, // 受托竞价
     Wrtrade = 45, // 供应链金融
+    DiaoQi = 46, // 掉期
     Platinum = 69, // 铂金宝
     quote99 = 99,
 }
@@ -125,4 +126,20 @@ export enum AgreementType {
     register = 1,   // 注册
     login,  // 登录
     trade,  // 交易
+}
+
+// 账户类型
+export enum UserType {
+    exchange = 1,   // 交易所
+    institution,    //机构
+    memberSubOrganizations, //会员子机构
+    broker, //经纪人
+    investment, //投资者
+    customer, //客户
+    memberOfTheEnterprise, // 企业成员
+}
+
+export enum ApplyType {
+    my = 1, // 我的申请
+    counterpart, // 对方申请
 }

+ 3 - 0
src/common/constants/enumsName.ts

@@ -923,6 +923,9 @@ export function getPickUpStatusName(type: number) {
 export function getScfContractStatusName(type: number) {
     let result = "--"
     switch (type) {
+        case 0:
+            result = "未提交";
+            break;
         case 1:
             result = '待审核'
             break

+ 26 - 0
src/common/setup/account/index.ts

@@ -0,0 +1,26 @@
+import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
+import { UnwrapRef } from "vue";
+
+// 交易账号
+export function useTaAccount<T extends { accountid: undefined | number }>(formState: UnwrapRef<T>) {
+    // 资金账号
+    const accountList = getAccountTypeList([2]);
+    if (accountList.length) {
+        formState.accountid = accountList[0].accountid;
+    }
+    // 资金账号
+    function getSelectedAccount() {
+        return accountList.find((e) => e.accountid === formState.accountid);
+    }
+    // 可用资金
+    function canUseMoney() {
+        return getCanUseMoney(getSelectedAccount()!)
+    }
+    // 处理内部资金账号
+    function handleSelectedAccount() {
+        const item = getSelectedAccount()!;
+        const list = getAccountTypeList([2]);
+        return item.taaccounttype === 2 ? item : list[0];
+    }
+    return { handleSelectedAccount, canUseMoney, getSelectedAccount, accountList };
+}

+ 2 - 2
src/common/setup/form/index.ts

@@ -1,2 +1,2 @@
-import { validateAction } from './validateAction'
-export { validateAction }
+export { validateAction } from './validateAction';
+

+ 15 - 9
src/common/setup/table/tableQuote.ts

@@ -18,9 +18,9 @@ export function handleSubcriteOnDemandQuote<T extends object>(tableList: Ref<T[]
         listenSrcoll(document.querySelector(selector)!)
     });
     onBeforeUnmount(() => {
-        removeSubscribeQuotation(uuid);
-        TimerUtils.clearTimeout('subscribeQuote')
+        stopSubcribe()
     })
+
     // 第一次自动订阅当前可视区域的数据
     const stop = watchEffect(() => {
         const len = tableList.value.length
@@ -29,6 +29,12 @@ export function handleSubcriteOnDemandQuote<T extends object>(tableList: Ref<T[]
             subscribeAction(0, end)
         }
     })
+    // 停止订阅
+    function stopSubcribe() {
+        removeSubscribeQuotation(uuid);
+        TimerUtils.clearTimeout('subscribeQuote')
+        stop()
+    }
     function listenSrcoll(ele: Element) {
         ele.addEventListener('scroll', (event: any) => {
             stop && stop()
@@ -86,6 +92,7 @@ export function handleSubcriteOnDemandQuote<T extends object>(tableList: Ref<T[]
         console.log('开始订阅', result)
         addSubscribeQuotation(uuid, result);
     }
+    return stopSubcribe
 }
 
 // 处理行情订阅,注意这里不是按需订阅
@@ -115,17 +122,16 @@ function isPrice(price1: number | string, price2: number | string) {
 
 /**
  * 处理行情价格颜色
- * @param price1
- * @param price2
+ * @param value
+ * @param presettle 昨结价
  * @returns
  */
-export function handleQuotePriceColor(record: QueryQuoteDayRsp) {
-    const { presettle, bid } = record
+export function handleQuotePriceColor(value: number, presettle: number) {
     let result = ''
-    if (isPrice(bid, presettle)) {
-        if (bid === presettle) {
+    if (isPrice(value, presettle)) {
+        if (value === presettle) {
             result = ''
-        } else if (bid > presettle) {
+        } else if (value > presettle) {
             result = 'up-quote-color'
         } else {
             result = 'down-quote-color'

+ 171 - 0
src/common/setup/trade/index.ts

@@ -0,0 +1,171 @@
+import { getQuoteDayInfoByCodeFindPrice } from "@/services/bus/goods";
+import { getRules } from "@/services/bus/rules";
+import { WrMarketTradeConfig } from "@/services/go/wrtrade/interface";
+import { CommomTradeForm, ListingTradeNumAndPrice } from './interface';
+
+// 获取交易规则
+export function useTradeRule() {
+    // 交易规则
+    const rules = getRules()
+    console.log('rules', rules)
+    // 获取履约规则中具体某个值
+    // 如果没有找到就默认为0
+    function getItemTradeRule(value: keyof WrMarketTradeConfig, initValue = 0) {
+        return rules.length ? rules[0][value] : initValue
+    }
+    // 买保证金模式 1: 比率 2: 固定
+    function isRatioInBuyMarginType() {
+        const type = getItemTradeRule('buymarginalgorithm', 1)
+        return type === 1
+    }
+    // 卖保证金模式 1: 比率 2: 固定
+    function isRationInSellMarginType() {
+        const type = getItemTradeRule('sellchargealgorithm', 1)
+        return type === 1
+    }
+
+    return {
+        getItemTradeRule,
+        isRatioInBuyMarginType,
+        isRationInSellMarginType,
+        buymarginvalue: getItemTradeRule('buymarginvalue') as number,
+        sellmarginvalue: getItemTradeRule('sellmarginvalue') as number
+    }
+}
+
+
+// 买 挂牌/摘牌 固定价 最大数量 = 可用资金/(买方履约保证金比例*挂牌价格)
+export function useBuyFixedPricMaxNum<T extends CommomTradeForm>(formState: T, canUseMoney: Function) {
+    let result = 0
+    // 可用资金
+    const money = canUseMoney()
+    const { isRatioInBuyMarginType, buymarginvalue } = useTradeRule()
+
+    // 最大数量 = 可用资金/(履约保证金*挂牌价格)
+    const marginValue = isRatioInBuyMarginType() ? (buymarginvalue * formState.FixedPrice) : (buymarginvalue + formState.FixedPrice)
+
+    // 处理 0 特殊情况
+    if (marginValue) {
+        result = Math.floor(money / marginValue)
+    }
+    return result
+}
+
+// 卖 挂牌/摘牌  固定价 最大数量 = 可用资金/(卖方履约保证金比例*挂牌价格)
+export function useSellFixedPriceMaxNum<T extends CommomTradeForm>(formState: T, canUseMoney: Function) {
+    let result = 0
+    // 可用资金
+    const money = canUseMoney()
+    const { isRationInSellMarginType, sellmarginvalue } = useTradeRule()
+    // 最大数量 = 可用资金/(履约保证金*挂牌价格)
+    const marginValue = isRationInSellMarginType() ? (sellmarginvalue * formState.FixedPrice) : (sellmarginvalue + formState.FixedPrice)
+    if (marginValue) { // 处理 0 特殊情况
+        result = Math.floor(money / marginValue)
+    }
+    return result
+}
+
+
+// 获取浮动价
+export function useFloatPrice<T extends CommomTradeForm>(formState: T, goodscode: string) {
+    let result = '--'
+    if (formState.OrderQty) {
+        const goodsPrice = getQuoteDayInfoByCodeFindPrice(goodscode)
+        if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+            result = ((goodsPrice as number) * formState.OrderQty + formState.PriceMove * formState.OrderQty).toFixed(2)
+        }
+    }
+    return result
+}
+
+//  浮动价 挂牌/摘牌 金额
+export function useFloatPriceMoney<T extends CommomTradeForm>(formState: T, goodscode: string) {
+    let result = 0
+    const goodsPrice = getQuoteDayInfoByCodeFindPrice(goodscode)
+    if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+        // 估算总价=挂牌基差+期货合约价;
+        const predictTotal = formState.PriceMove + (goodsPrice as number);
+        // 估算总额=估算总价*摘牌数量;
+        result = predictTotal * formState.OrderQty
+    }
+    return result
+}
+
+// 获取 挂牌 的 最大可挂数量,金额,保证金
+export function useListingTradeNumAndPrice<T extends CommomTradeForm>({ formState, goodscode, isFloat, canUseMoney }: ListingTradeNumAndPrice<T>) {
+
+    function getMaxNum(value: number, isBuy: boolean) {
+        // 可用资金
+        const money = canUseMoney()
+        // 挂牌 最大数量=可用资金/(买方履约保证金比例*挂牌价格)
+        let result = 0
+        if (isFloat()) {
+            const price = useFloatPrice<T>(formState, goodscode)
+            if (price !== '--') {
+                result = money / (Number(price) * value)
+            }
+        } else {
+            result = isBuy ? useBuyFixedPricMaxNum(formState, canUseMoney) : useSellFixedPriceMaxNum(formState, canUseMoney)
+        }
+        return +result.toFixed(0)
+    }
+
+    // 挂买 最大数量
+    function getListingBuyMaxNum() {
+        const { buymarginvalue } = useTradeRule()
+        return getMaxNum(buymarginvalue, true)
+    }
+
+    // 挂卖 最大数量
+    function getListingSellMaxNum() {
+        const { sellmarginvalue } = useTradeRule()
+        return getMaxNum(sellmarginvalue, false)
+    }
+
+    // 金额
+    function getMoney() {
+        let result = 0
+        if (isFloat()) {
+            result = useFloatPriceMoney(formState, goodscode)
+        } else {
+            // 摘牌金额=挂牌价格*摘牌数量
+            result = formState.OrderQty * formState.FixedPrice
+        }
+        return Number(result.toFixed(2))
+    }
+
+    // 挂买 履约保证金
+    function getListingBuyMargin() {
+        // 浮动价 履约保证金=估算总额*买方履约保证金比例
+        // 一口价 履约保证金=挂牌金额*买方履约保证金比例
+        const { isRatioInBuyMarginType, buymarginvalue } = useTradeRule()
+        const margin = isRatioInBuyMarginType() ? (buymarginvalue * getMoney()) : (buymarginvalue + getMoney())
+        return Number((margin).toFixed(2))
+    }
+
+    // 挂卖 履约保证金
+    function getListingSellMargin() {
+        // 浮动价 履约保证金=估算总额*买方履约保证金比例
+        // 一口价 履约保证金=挂牌金额*买方履约保证金比例
+        const { isRationInSellMarginType, sellmarginvalue } = useTradeRule()
+        const margin = isRationInSellMarginType() ? (sellmarginvalue * getMoney()) : (sellmarginvalue + getMoney())
+        return Number((margin).toFixed(2))
+    }
+    function getFloatPrice() {
+        useFloatPrice(formState, goodscode)
+    }
+    return { getFloatPrice, getListingBuyMaxNum, getListingSellMaxNum, getListingBuyMargin, getListingSellMargin, getMoney }
+}
+
+// 获取 摘牌 买 比例 的 最大数量
+export function useBuyDelistingRatioMaxNum(OrderQty: number, canUseMoney: Function) {
+    let result = 0;
+    const { buymarginvalue } = useTradeRule()
+    const money = canUseMoney()
+    if (money && !isNaN(money)) {
+        const num = +(money / buymarginvalue).toFixed(0);
+        // 买 最大可摘数量=min{挂牌数量,可用资金/(履约保证金比例)}
+        result = Math.min(OrderQty, num);
+    }
+    return result
+}

+ 13 - 0
src/common/setup/trade/interface.ts

@@ -0,0 +1,13 @@
+// 通用交易下单 表单接口
+export interface CommomTradeForm {
+    PriceMove: number; // 基差
+    OrderQty: number; // 数量
+    FixedPrice: number; // 价格
+}
+
+export interface ListingTradeNumAndPrice<T> {
+    formState: T, // 表单数据
+    goodscode: string, // 选中数据的goodscode
+    isFloat: Function, // 是否是浮动价
+    canUseMoney: Function, // 可用资金
+}

+ 8 - 0
src/router/index.ts

@@ -1724,6 +1724,14 @@ const routes: Array<RouteRecordRaw> = [
                                     requireAuth: true,
                                 },
                             },
+                            {
+                                path: '/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap',
+                                name: 'spot_trade_order_transaction_swap',
+                                component: () => import('@/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue'),
+                                meta: {
+                                    requireAuth: true,
+                                },
+                            },
                         ]
                     },
                     {

+ 12 - 4
src/services/bus/account.ts

@@ -24,7 +24,7 @@ export const getAccoutIdList = (): string => {
 };
 
 // taaccounttype: number;//账号类型 - 1:外部账号 2:内部账号 3:内部做市自营账号 4:内部做市接单账号
-type taaccounttype = 1 | 2 | 3 | 4
+export type taaccounttype = 1 | 2 | 3 | 4
 export function getAccountTypeList(type: taaccounttype[]): AccountListItem[] {
     return APP.get('accountList').filter((e: AccountListItem) => type.includes(e.taaccounttype as taaccounttype))
 }
@@ -33,9 +33,17 @@ export function getAccountTypeList(type: taaccounttype[]): AccountListItem[] {
 // 先判断当前选中的资金账号是否为内部账号,是的话取当前的账号,不是的话,取内部账号列表里的第一个
 export function getInTaAccount(): number {
     const seleced = getSelectedAccount()
-    let result: number = seleced.accountid
-    if (seleced.taaccounttype !== 2) {
-        const list = getAccountTypeList([2])
+    let result: number = seleced?.accountid
+    const list = getAccountTypeList([2])
+    if (seleced) {
+        if (seleced.taaccounttype !== 2) {
+            if (list.length) {
+                result = list[0].accountid
+            } else {
+                throw new Error('未获取到内部资金账号,请确认!')
+            }
+        }
+    } else {
         if (list.length) {
             result = list[0].accountid
         } else {

+ 13 - 2
src/services/bus/goods.ts

@@ -4,7 +4,7 @@ import APP from '@/services';
 import { Ref, ref } from 'vue';
 import { Goods } from '../go/ermcp/goodsInfo/interface';
 import { QueryQuoteDayRsp } from '../go/quote/interface';
-import { Goodsgroup } from '../go/useInfo/interface';
+import { Goodsgroup, Market } from '../go/useInfo/interface';
 import { getMarketByTradeMode } from './market';
 
 // 获取全部商品信息
@@ -99,8 +99,19 @@ export function getGoodsGroupsByTradeMode(trademode: TradeMode): Goodsgroup[] {
     return result
 }
 
+// 通过 goodsid 查找 商品
+export function getGoodsById(goodsid: number) {
+    return getGoodsList().find(el => el.goodsid === goodsid)
+}
+
 // 通过goodsid 获取商品合约单位
 export function getGoodsAgreeunitByGoodsId(goodsid: number): number | null {
-    const result = getGoodsList().find(el => el.goodsid === goodsid)
+    const result = getGoodsById(goodsid)
     return result ? result.agreeunit : null
+}
+
+// 通过 goodsid 查找 trademode
+export function findGoodsTradeModeById(goodsid: number) {
+    const marketid = getGoodsById(goodsid)!.marketid
+    return APP.get('markets').find((el: Market) => el.marketid === marketid).trademode
 }

+ 14 - 0
src/services/bus/market.ts

@@ -7,6 +7,20 @@ export function getMarketByTradeMode(trademode: TradeMode): Market | undefined {
     return APP.get('markets').find((el: Market) => el.trademode === trademode)
 }
 
+// 通过 trademode 获取市场信息列表
+export function getMarketsByTradeMode(trademode: TradeMode): Market[] {
+    return APP.get('markets').filter((el: Market) => el.trademode === trademode)
+}
+
+
+//  通过 trademode 获取市场ids
+export function getMarketIdsByTradeMode(trademode: TradeMode): string {
+    const arr = getMarketsByTradeMode(trademode)
+    return arr.reduce((str: string, current: Market) => {
+        return str ? (str + ',' + current.marketid) : current.marketid.toString()
+    }, '')
+}
+
 // 获取市场运行信息
 export function getMarketRunByTradeMode(trademode: TradeMode): Marketrun | null {
     const marketInfo = getMarketByTradeMode(trademode)

+ 3 - 2
src/services/bus/user.ts

@@ -5,7 +5,7 @@ import { Arearole, Ermcp3RootUserAccount } from '../go/useInfo/interface';
  * 获取用户账户类型
  * @returns
  */
-export function getUserAccountType() {
+export function getUserAccountType(): number {
     return APP.get('userAccount').usertype
 }
 
@@ -21,7 +21,8 @@ export function getUserInfo() {
  * @returns
  */
 export function getUserName() {
-    return APP.get('loginAccount').accountname
+    const name = APP.get('loginAccount').accountname
+    return name ? name : getUserInfo().customername
 }
 
 // 公司名

+ 3 - 0
src/services/funcode/index.ts

@@ -30,6 +30,9 @@ export const funCode: Code = {
     SearchReceiverReq: 1900575, // 查询用户收货信息表请求
     SearchReceiverRsp: 1900576, // 查询用户收货信息表应答
 
+    TradeHoldTransferApplyReq: 1900757, // /按单协议平仓申请
+    TradeHoldTransferApplyRsp: 1900758, // /按单协议平仓申请
+
     UserReceiveInfoReq: 1900545, // 新增修改收货地址请求
     UserReceiveInfoRsp: 1900546, // 新增修改收货地址请求响应
     DelUserReceiveInfoReq: 1900547, // 删除收货地址请求请求

+ 41 - 0
src/services/go/Tjmd/index.ts

@@ -0,0 +1,41 @@
+import { commonSearch_go } from "@/services/go";
+import * as type from './interface';
+
+/**
+ * 查询掉期报价列表  /Tjmd/QueryQuoteGoodsList
+ */
+export function queryQuoteGoodsList(req: type.QueryQuoteGoodsListReq): Promise<type.QueryQuoteGoodsListRsp[]> {
+    return commonSearch_go('/Tjmd/QueryQuoteGoodsList', req).catch((err) => {
+        throw new Error(`查询掉期报价列表 : ${err}`);
+    });
+}
+
+/**
+ * 查询今日账户保证金配置  /Tjmd/QueryTjmdTodayAccountMargin
+ */
+export function queryTjmdTodayAccountMargin(req: type.QueryTjmdTodayAccountMarginReq): Promise<type.TjmdTodayAccountMarginReq[]> {
+    return commonSearch_go('/Tjmd/QueryTjmdTodayAccountMargin', req).catch((err) => {
+        throw new Error(`查询今日账户保证金配置 : ${err}`);
+    });
+}
+
+/**
+ * 查询掉期买卖大厅  /Tjmd/QueryTjmdTradeOrderDetail
+ */
+export function queryTjmdTradeOrderDetail(req: type.QueryTjmdTradeOrderDetailReq): Promise<type.QueryTjmdTradeOrderDetailRsp[]> {
+    return commonSearch_go('/Tjmd/QueryTjmdTradeOrderDetail', req).catch((err) => {
+        throw new Error(`查询掉期买卖大厅 : ${err}`);
+    });
+}
+
+/**
+ * 查询掉期协议单  /Tjmd/QueryTjmdTransferApply
+ */
+export function queryTjmdTransferApply(req: type.QueryTjmdTransferApplyReq): Promise<type.QueryTjmdTransferApplyRsp[]> {
+    return commonSearch_go('/Tjmd/QueryTjmdTransferApply', req).catch((err) => {
+        throw new Error(`查询掉期协议单 : ${err}`);
+    });
+}
+
+
+

+ 91 - 0
src/services/go/Tjmd/interface.ts

@@ -0,0 +1,91 @@
+export interface QueryQuoteGoodsListReq {
+    usertype: number;//用户类型
+    marketids?: string;//市场id, 格式 1,2,3
+    goodsgroupid?: number;//商品组id
+    goodsid?: number;//商品id
+}
+
+export interface QueryQuoteGoodsListRsp {
+    buyqty: number;//买量(暂不做, 无值, 保留字段)
+    goodscode: string;//合约代码
+    goodsgroupid: number;//商品组ID(自增ID)
+    goodsgroupname: string;//商品组名称
+    goodsid: number;//合约id
+    goodsname: string;//合约名称
+    refgoodscode: string;//标的合约代码
+    refgoodsid: number;//标的合约id
+    refgoodsname: string;//标的合约名称
+    sellqty: number;//卖量(暂不做, 无值, 保留字段)
+}
+
+export interface QueryTjmdTodayAccountMarginReq {
+    marketids?: string;//市场id, 格式 1,2,3
+    goodsid?: number;//商品id
+    accountid?: string; // 资金账号
+}
+
+export interface GoodsMarginCfgStruct {
+    CustomerTypeID: number;//投资者客户类型
+    GoodsID: number;//商品ID
+    IsDefault: number;//是否默认标志位
+    LockMarginValue: number;//锁仓保证金
+    MarginAlgorithm: number;//保证金计算方式
+    MarketMarginValue: number;//即市保证金值
+    RealMarginAlgorithm: number;//实付保证金计算方式
+    RealMarginValue: number;//实付比例
+    ReckonMarginValue: number;//结算保证金值
+}
+
+export interface TjmdTodayAccountMarginReq {
+    accountid: number; // 账号ID
+    goodsid: number; // 商品ID
+    marketid: number; // 市场ID
+    infoc: GoodsMarginCfgStruct[]
+}
+
+export interface QueryTjmdTradeOrderDetailReq {
+    page?: number; // 页码
+    pagesize?: number; // 每页条数
+    userid: number; // 用户id
+    usertype: number; // 用户类型
+    marketids?: string; // 市场id, 格式 1,2,3
+    goodsid: number; // 商品id
+    buyorsell: 0 | 1; // 买卖方向 0-买 1-卖
+}
+
+export interface QueryTjmdTradeOrderDetailRsp {
+    buyorsell: number;//买卖方向 number;
+    //-买 1-卖
+    goodsid: number;//商品id
+    marketmaxsub: number;//市价最大偏移范围 [浮动价 - 点差]
+    orderid: string;//委托单号
+    orderprice: number;//委托价格
+    orderqty: number;//委托数量
+    pricemode: number;//取价方式 - 1:市价 2: 限价 3:浮动价
+    userid: number;//用户id
+    username: string;//用户名称(已脱敏)
+}
+
+export interface QueryTjmdTransferApplyReq {
+    applytype: 1 | 2  // 类型 1-我的申请 2-对方申请
+    marketids?: string  // 市场id, 格式 1,2,3
+    accountids?: string  // 资金账号, 格式 25000000001,25000000003
+}
+
+export interface QueryTjmdTransferApplyRsp {
+    applyid: number;//申请ID(自增ID SEQ_TRADE_HOLDTRANSFERAPPLY)
+    applystatus: number;//状态 - number;
+    //:未提交 1:待审核 2:审核中 3:审核通过 4:审核拒绝 5:审核失败 6:已撤销
+    applytime: string;//申请时间(时间)
+    auditremark: string;//审核备注(拒绝原因?)
+    buyorsell: number;//买卖 - number;
+    //:买 1:卖
+    goodscode: string;//商品代码
+    goodsid: number;//商品ID
+    goodsname: string;//商品名称
+    marketid: number;//市场ID
+    qty: number;//转让数量(数量)
+    tradeid: string;//成交单号(关联持仓)
+    transferamount: number;//转让总金额(金额)
+    transferprice: number;//转让价格(协议价格)
+}

+ 11 - 0
src/services/go/order/index.ts

@@ -0,0 +1,11 @@
+import { commonSearch_go } from "@/services/go";
+import * as type from './interface';
+
+/**
+ * 查询持仓明细  /Order/QueryTradeHolderDetail
+ */
+export function queryTradeHolderDetail(req: type.QueryTradeHolderDetailReq): Promise<type.QueryTradeHolderDetailRsp[]> {
+    return commonSearch_go('/Order/QueryTradeHolderDetail', req).catch((err) => {
+        throw new Error(`查询持仓明细 : ${err}`);
+    });
+}

+ 61 - 0
src/services/go/order/interface.ts

@@ -0,0 +1,61 @@
+export interface QueryTradeHolderDetailReq {
+    userid?: number; // 用户id
+    accids?: string; // 资金账号, 格式 1,2,3
+    trademodes?: string; // 交易模式, 格式 1,2,3
+    marketids?: string; // 市场id, 格式 1,2,3
+    goodsid?: number; // 商品id
+    buyorsell?: number; // 买卖方向 0-买 1-卖
+}
+
+export interface QueryTradeHolderDetailRsp {
+    accountid: number;//账号ID
+    agreeunit: number;//合约乘数
+    buyorsell: number;//方向 - number;
+    //:买 1:卖
+    currencyid: number;//商品币种id
+    currencyname: string;//币种名称
+    decimalplace: number;//商品价格小数位
+    enumdicname: string;//商品单位名称
+    expirecycle: number;//行权周期(天) - 1:滚动行权时填写
+    expiredate: string;//行权日(yyyyMMdd) - 到期日
+    expiretype: number;//行权日类型 - 1:滚动行权 2:固定日行权
+    freezeqty: number;//冻结数量
+    goodscode: string;//商品代码
+    goodsid: number;//商品ID
+    goodsname: string;//商品名称
+    goodunitid: number;//商品单位id
+    holderamount: number;//持仓金额
+    holdercredit: number;//持仓授信金额
+    holderdays: number;//剩余冻结天数
+    holderprice: number;//持仓价格
+    holderqty: number;//持仓数量
+    isconfirmexercise: number;//是否确认行权- number;
+    //:否 1:是
+    ispreexercise: number;//是否预申报- number;
+    //:否 1:是 2:不可行权
+    marketid: number;//市场id
+    marketname: string;//市场名称
+    openprice: number;//建仓价格
+    openqty: number;//建仓数量
+    optiontype: number;//期权类型 - 1:认购(看涨) 2:认沽(看跌)
+    preexerciseprice: number;//预申报价格
+    premium: number;//权利金
+    qtydecimalplace: number;//商品成交量小数位
+    refgoodscode: string;//标的合约代码
+    refgoodsid: number;//标的合约id
+    releaseamount: number;//释放持仓金额
+    releaseholdercredit: number;//释放持仓授信金额
+    taname: string;//资金账号名称
+    tradeamount: number;//成交金额
+    tradedate: string;//交易日(yyyyMMdd)
+    tradeid: string;//成交单号(1number;
+    //1+Unix秒时间戳(1number;
+    //位)+2位(MarketServiceID)+xxxx)
+    trademode: number;//交易模式 - 1number;
+    //:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 2number;
+    //:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
+    tradeproperty: number;//交易属性
+    tradetime: string;//交易时间
+    userid: number;//用户id
+    username: string;//用户名称
+}

+ 1 - 1
src/services/go/wrtrade/interface.ts

@@ -1121,7 +1121,7 @@ export interface QueryWrTradeBargainApplyQsp {
 
 export interface QueryWrFriendApplyRsp {
     friendname: string;//好友名字(已脱敏)
-    frienduserid: string;//好友用户ID
+    frienduserid: number;//好友用户ID
     isfriend: number; // 是否好友 0-不是 1-是
     userid: number;//用户ID
 }

+ 12 - 1
src/services/proto/warehousetrade/index.ts

@@ -1,7 +1,7 @@
 import {
     DeliveryOrderReq,
     HdWRDealOrderReq,
-    HdWROrderReq, PaymentArrearsReq, WarehouseRepurchaseReq, WrBargainApplyReq, WRListingCancelOrderReq, WROutApplyCancelReq,
+    HdWROrderReq, PaymentArrearsReq, TradeHoldTransferApplyReq, WarehouseRepurchaseReq, WrBargainApplyReq, WRListingCancelOrderReq, WROutApplyCancelReq,
     WROutApplyReq, WROutCancelReq, WROutConfirmReq, WRTradeFinanceBuyCancelReq
 } from "@/services/proto/warehousetrade/interface";
 import { protoMiddleware } from "@/services/socket/protobuf/buildReq";
@@ -116,6 +116,17 @@ export const DeliveryOrder = (param: DeliveryOrderReq): Promise<any> => {
     return protoMiddleware<DeliveryOrderReq>(param, 'DeliveryOrderReq', 'DeliveryOrderRsp', HeadEnum.tradeMode17)
 }
 
+/**
+ * 单协议平仓
+ * @param param
+ * @constructor
+ */
+export const tradeHoldTransferApply = (param: TradeHoldTransferApplyReq): Promise<any> => {
+    return protoMiddleware<TradeHoldTransferApplyReq>(param, 'TradeHoldTransferApplyReq', 'TradeHoldTransferApplyRsp', HeadEnum.tradeMode17)
+}
+
+
+
 // /**
 //  * 议价申请拒绝请求
 //  * @param param

+ 10 - 0
src/services/proto/warehousetrade/interface.ts

@@ -1,3 +1,4 @@
+
 // 持仓单挂牌请求 0 22 15
 export interface HdWROrderReq {
     LadingBillId: number; // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
@@ -308,6 +309,15 @@ export interface DeliveryOrderDetail {
     WRFactorTypeID: number // uint64 仓单要素类型ID
 }
 
+export interface TradeHoldTransferApplyReq {
+    TradeID: number; //  申请人的持仓单表ID
+    BuyorSell: number; // 持仓单方向  卖 - 0:买 1:卖
+    TransferPrice: number; // 转让价格
+    ApplySrc: number; // 申请来源 - 1:管理端 2:终端
+    ApplicantID: number; // 登录账号
+    Remark: string; // 申请备注
+}
+
 // // 议价申请审核请求 0 29 59
 // export interface WrBargainNoAgreeReq {
 //     WrBargainID: number // uint64 申请ID

+ 6 - 0
src/services/socket/order/index.ts

@@ -8,6 +8,7 @@ import { buildProtoReq50, parseProtoRsp50, protoMiddleware } from '@/services/so
 import { Callback } from '@/utils/websocket/index';
 import moment from 'moment';
 import { v4 as uuidv4 } from 'uuid';
+import { HeadEnum } from '../protobuf/protoHeader';
 import * as orderType from './interface/index';
 
 /**
@@ -19,6 +20,11 @@ export const Order = (param: OrderReq): Promise<any> => {
     return protoMiddleware<OrderReq>(param, 'OrderReq', 'OrderRsp', 8)
 }
 
+// 掉期 下单接口
+export const diaoQiOrder = (param: OrderReq): Promise<any> => {
+    return protoMiddleware<OrderReq>(param, 'OrderReq', 'OrderRsp', HeadEnum.tradeMode46)
+}
+
 /**
  * 交易委托请求
  */

+ 5 - 1
src/services/socket/protobuf/protoHeader.ts

@@ -14,7 +14,8 @@ export enum HeadEnum {
     MarketID45201,
     tradeMode17,
     tradeMode45,
-    MarketID16201
+    MarketID16201,
+    tradeMode46,
 }
 
 /**
@@ -62,6 +63,9 @@ export function getProtoHeadParam(funCodeName: string, type: HeadEnum = 0): IMes
         case HeadEnum.MarketID16201:
             result = Object.assign(result, { MarketID: 16201 })
             break;
+        case HeadEnum.tradeMode46:
+            result = Object.assign(result, { MarketID: getMarketByTradeMode(TradeMode.DiaoQi)?.marketid, })
+            break;
     }
     return result
 }

+ 4 - 0
src/utils/eventBus/index.ts

@@ -2,8 +2,10 @@
 interface EnentNames {
     loadComplete: string; //加载状态名
     spotTrade: string;  // 挂牌成功,通知报价大厅更新数据
+    blocsTrade: string; // 贸易圈 挂牌成功
     moneyChangedNtf_UI: string; // /接收到资金变化通知 UI 成 使用
     financing_manager: string; // 融资摘牌
+    changeTheme: string; // 切换主题
 }
 
 /** 一个事件只能存储一个回调 */
@@ -18,6 +20,8 @@ interface EnentNamesOnlyOneValue {
     posChangedNtf: string; //接收到头寸变化通知
     moneyChangedNtf: string; //接收到资金变化通知
 
+    bargain: string; // 议价单
+
     orderCanceledNtf: string; //接收到委托单撤单通知
     quoteReceiveNtf: string; // 接收实时行情推送
 }

+ 1 - 0
src/utils/timer/timerUtil.ts

@@ -16,6 +16,7 @@ export interface TimeoutTimerNames {
     loadMylieList: string; //发布闲置之后延时请求接口数据 不然马上新增数据马上请求是请求不到的
     debounce: string; // 防抖
     debounceInput: string; // 输入框防抖
+    filterTimer: string;
     debounceOnSearch: string; // 搜索框防抖
     overtimeOut: string; // 超时,如果太久没有操作界面,则退出登录
     subscribeQuote: string; //按需订阅防抖

+ 1 - 0
src/views/market/spot_trade/components/buy-sell-market/components/financing_delisting/components/choose-finance/index.vue

@@ -168,6 +168,7 @@ export default defineComponent({
                         height: 40px;
                         line-height: 40px;
                         color: @m-white6;
+                        white-space: nowrap;
                     }
                     .ant-col:nth-child(2) {
                         text-align: center;

+ 16 - 2
src/views/market/spot_trade/components/filter/index.vue

@@ -3,7 +3,7 @@
   <div class="filterTable">
     <div class="filter-custom-table">
       <a-tree-select v-model:value="selectedFT"
-                     @change="changeFT"
+                     @select="changeFT"
                      style="width: 200px"
                      :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                      :tree-data="FtDeliveryGoods"
@@ -23,6 +23,7 @@
       <a-space direction="vertical"
                v-if="!isWR()">
         <a-month-picker :allowClear="false"
+                        :style="{marginRight: '10px' }"
                         placeholder="全部交收月"
                         v-model:value="time"
                         class="commonDatePicker conditionPicker allDatePicker" />
@@ -65,6 +66,7 @@ import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
 import { handleIs, setGoodsPrice } from '../buy-sell-market/setup';
 import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
 import { getMarketByTradeMode } from '@/services/bus/market';
+import TimerUtils from '@/utils/timer/timerUtil';
 
 const ALL = TreeSelect.SHOW_ALL;
 
@@ -91,6 +93,17 @@ export default defineComponent({
         // 仓单要素
         const wrLsit = ref<SelectList[]>([]);
         function changeFT(value: number, label: any, extra: any) {
+            const children = label?.children;
+            if (Array.isArray(children) && children.length) {
+                TimerUtils.setTimeout(
+                    () => {
+                        selectedFT.value = undefined;
+                    },
+                    100,
+                    'filterTimer'
+                );
+                return;
+            }
             queryWrStandardFactoryItem({ wrstandardid: value }).then((res) => {
                 const result: SelectList[] = [];
                 res.forEach((el) => {
@@ -99,8 +112,9 @@ export default defineComponent({
                 wrLsit.value = result;
             });
         }
+
         // 全部期货合约
-        const goodsList = getGoodsListByTrade(TradeMode.ListingAndSelection);
+        const goodsList = getGoodsListByTrade(TradeMode.quote99);
         const selectedGoods = ref<Goods>();
 
         const uuid = v4();

+ 1 - 1
src/views/market/spot_trade/spot_trade_order_transaction/setup.ts

@@ -24,7 +24,7 @@ export function handleDeliveryRelation(param: deliverytype[]) {
             allDeliverGoods.value = res
             deliverGoods.value = getDeliverGoods()
             res.forEach(el => {
-                // 找到行情数据
+                // 找到盘面数据
                 const quote = getQuoteDayInfoByCode(el.goodscode);
                 if (quote) {
                     Object.assign(quote, { goodsname: el.goodsname, deliverytype: el.deliverytype })

+ 157 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy-sell-market/index.vue

@@ -0,0 +1,157 @@
+<template>
+    <!-- 买卖大厅 -->
+    <div class="buy-sell-market">
+        <div class="buy-sell-market-title">
+            <a class="backIcon" @click="cancel">
+                <LeftOutlined />
+            </a>
+            <div class="titleBtn">
+                <div class="name">{{selectedRow.goodsname}}</div>
+                <div class="arrowRightIcon"></div>
+            </div>
+            <div class="priceBar bdf1 ml20">
+                <div class="greenBar">
+                    <div class="numBlock">
+                        <div class="first">卖量</div>
+                        <div class="last green">{{selectedRow.sellqty}}</div>
+                    </div>
+                    <div class="numBlock">
+                        <div class="first">买量</div>
+                        <div class="last white">{{selectedRow.buyqty}}</div>
+                    </div>
+                </div>
+            </div>
+            <!-- 历史走势按钮 -->
+            <a-button class="historyBtn" @click="openComponent({code: 'HisChart'})">
+                历史走势
+                <LineChartOutlined />
+            </a-button>
+            <BtnList :btnList="firstBtn" :record="selectedRow" @click="openComponent" />
+        </div>
+        <a-row class="buySellHall">
+            <a-col :span="12">
+                <Sell :enumName="enumName" ref="sellRef" :parantSelectedRow="selectedRow" />
+            </a-col>
+            <a-col :span="12">
+                <Buy :enumName="enumName" ref="buyRef" :parantSelectedRow="selectedRow" />
+            </a-col>
+        </a-row>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :selectedRow="selectedRow"
+            :goodsPrice="getGoodsPrice()"
+            :enumName="enumName"
+            @cancel="closeComponent"
+        ></component>
+    </div>
+</template>
+
+<script lang="ts">
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { defineAsyncComponent, defineComponent, BtnList, ModalEnum } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { WrOrderQuote } from '@/services/go/wrtrade/interface';
+import { LeftOutlined } from '@ant-design/icons-vue';
+import Buy from '../buy/index.vue';
+import Sell from '../sell/index.vue';
+import { LineChartOutlined, DownOutlined } from '@ant-design/icons-vue';
+import { handleModalComponent } from '@/common/setup/asyncComponent';
+import { onBeforeUnmount, onMounted, PropType, ref } from 'vue';
+import { v4 } from 'uuid';
+import { addSubscribeQuotation, removeSubscribeQuotation } from '@/services/socket/quota';
+import Bus from '@/utils/eventBus/index';
+import { getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import TimerUtils from '@/utils/timer/timerUtil';
+import { BtnListType } from '@/common/components/btnList/interface';
+import moment, { Moment } from 'moment';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { getBtnList } from '../../setup';
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: 'buy-sell-market',
+    props: {
+        selectedRow: {
+            type: Object as PropType<WrOrderQuote>,
+            default: {},
+        },
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+    },
+    components: {
+        Buy,
+        Sell,
+        BtnList,
+        LeftOutlined,
+        DownOutlined,
+        LineChartOutlined,
+        Detail: defineAsyncComponent(() => import('../detail/index.vue')),
+        PostBuying: defineAsyncComponent(() => import('../post_buying/index.vue')),
+        HisChart: defineAsyncComponent(() => import('../history-chart/index.vue')),
+    },
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+
+        // const { isWR, isFloat } = handleIs(props.enumName, BuyOrSell.buy);
+        // 买卖大厅 配置数据
+        // 表格操作按钮列表
+        // 获取浮动价商品实时价格
+
+        function getGoodsPrice() {
+            const result = getQuoteDayInfoByCodeFindPrice(props.selectedRow.goodscode);
+            // setGoodsPrice(result);
+            return result;
+        }
+        const buyRef = ref<null | { queryTableAction: Function }>(null);
+        const sellRef = ref<null | { queryTableAction: Function }>(null);
+        const queryFn = () => {
+            buyRef.value?.queryTableAction();
+            sellRef.value?.queryTableAction();
+        };
+        const { componentId, closeComponent, openComponent } = handleModalComponent(queryFn, ref({}));
+        // const { hasFinacing } = handleFinacing(loading, props.selectedRow.wrfactortypeid);
+        function handleBtnList(list: BtnListType[]) {
+            // if (!hasFinacing()) {
+            //     return list.filter((e) => e.code !== 'spot_trade_warehouse_financing_delisting');
+            // } else {
+            //     return list;
+            // }
+        }
+        // 单据挂牌成功 通知买大厅刷新数据
+        Bus.$on('spotTrade', queryFn);
+
+        return {
+            buyRef,
+            sellRef,
+            cancel,
+            getGoodsPrice,
+            visible,
+            firstBtn: getBtnList(false),
+            buyMarket: [],
+            sellMarket: [],
+            componentId,
+            closeComponent,
+            openComponent,
+            enumName: props.enumName,
+            handleBtnList,
+        };
+    },
+});
+</script>
+<style lang="less">
+.priceBar {
+    .flex;
+    flex-direction: column;
+    height: 32px;
+    .greenBar,
+    .redBar {
+        height: 16px;
+        line-height: 16px;
+        color: var(--m-grey17);
+    }
+}
+</style>

+ 159 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy/index.vue

@@ -0,0 +1,159 @@
+<template>
+  <!--  现货贸易 - 买卖大厅 - 卖报价牌 -->
+  <a-table :columns="columns"
+           :class="['buyHallTable', isBottom ? '' : 'buyHallTableHigh', tableList.length ? '' : 'noDataTable']"
+           :scroll="{ x: '100%', y: isBottom ? 'calc(100vh- 378px)' : 'calc(100vh - 135px)' }"
+           :pagination="false"
+           :loading="loading"
+           :expandedRowKeys="expandedRowKeys"
+           :customRow="Rowclick"
+           :expandIcon="expandIcon"
+           :expandIconAsCell="false"
+           rowKey="key"
+           :data-source="tableList">
+    <!-- ,  -->
+    <!-- 额外的展开行 -->
+    <template #expandedRowRender="{ record }">
+      <BtnList :btnList="btnList"
+               :record="record"
+               class="btn-list-sticky"
+               @click="openComponent" />
+    </template>
+    <template #username="{text, record }">
+      <span>{{record.userid + " "}}{{text}}</span>
+    </template>
+  </a-table>
+  <component :is="componentId"
+             v-if="componentId"
+             :selectedRow="selectedRow"
+             :buyOrSell="BuyOrSell.buy"
+             :enumName="enumName"
+             :parantSelectedRow="parantSelectedRow"
+             @cancel="closeComponent"></component>
+</template>
+
+<script lang="ts">
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { ComposeTableParam, BtnList, defineComponent, handleComposeTable, queryTableList, ModalEnum } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryOrderQuoteDetail } from '@/services/go/wrtrade';
+import { QueryOrderQuoteDetailReq, WrOrderQuote, WrOrderQuoteDetail } from '@/services/go/wrtrade/interface';
+import { defineAsyncComponent, PropType } from 'vue';
+import { BtnListType } from '@/common/components/btnList/interface';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { expandIcon } from '@/common/setup/table/clolumn';
+import { ColumnType } from '@/common/methods/table/interface';
+import { Moment } from 'moment';
+import moment from 'moment';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { queryTjmdTradeOrderDetail } from '@/services/go/Tjmd';
+import { QueryTjmdTradeOrderDetailReq, QueryTjmdTradeOrderDetailRsp } from '@/services/go/Tjmd/interface';
+import { getUserId } from '@/services/bus/account';
+import { getUserAccountType } from '@/services/bus/user';
+import { useBuyOrSellBtnList } from '../setup';
+import { findItemGoods } from '../../setup';
+
+const columns = [
+    {
+        key: '0th',
+        dataIndex: 'index',
+        title: '序号',
+        align: 'center',
+        slots: {
+            customRender: 'index',
+        },
+        width: 60,
+    },
+    {
+        key: '1th',
+        dataIndex: 'orderprice',
+        title: '买价',
+        align: 'center',
+        slots: {
+            customRender: 'orderprice',
+        },
+        width: 120,
+    },
+    {
+        key: '2th',
+        dataIndex: 'orderqty',
+        title: '买量',
+        align: 'center',
+        slots: {
+            customRender: 'orderqty',
+        },
+        width: 120,
+    },
+    {
+        key: '3th',
+        dataIndex: 'username',
+        title: '购买方',
+        align: 'center',
+        slots: {
+            customRender: 'username',
+        },
+    },
+];
+
+export default defineComponent({
+    emits: ['cancel', 'openComponent'],
+    name: 'warehouse_receipt_trade_price_delisting_buy',
+    props: {
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+        parantSelectedRow: {
+            type: Object as PropType<WrOrderQuote>,
+            default: {},
+        },
+    },
+    components: {
+        BtnList,
+        Listing: defineAsyncComponent(() => import('../delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<QueryTjmdTradeOrderDetailRsp>();
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryTjmdTradeOrderDetailReq = {
+                buyorsell: 0,
+                userid: getUserId(),
+                usertype: getUserAccountType(),
+                goodsid: findItemGoods(props.parantSelectedRow.goodscode)?.goodsid,
+            };
+            queryTable(queryTjmdTradeOrderDetail, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: props.enumName,
+            tableFilterKey: [],
+            isDetail: false,
+        };
+
+        return {
+            isBottom,
+            ...handleComposeTable<WrOrderQuoteDetail>(param),
+            queryTableAction,
+            BuyOrSell,
+            loading,
+            tableList,
+            enumName: props.enumName,
+            expandIcon,
+            btnList: useBuyOrSellBtnList(),
+            columns,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 426 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/index.vue

@@ -0,0 +1,426 @@
+<template>
+    <!-- 挂牌求购 -->
+    <Drawer
+        :title="isBuy() ? '摘牌买入' : '摘牌卖出' "
+        :placement="'right'"
+        :visible="visible"
+        @cancel="cancel"
+        class="top"
+    >
+        <div class="post_buying">
+            <a-form class="inlineForm dialogForm" ref="formRef" :model="formState" :rules="rules">
+                <div class="formBar">
+                    <a-row :gutter="24">
+                        <a-col :span="24">
+                            <a-form-item label="交易账户" name="accountid">
+                                <a-select
+                                    class="inlineFormSelect"
+                                    style="width: 260px"
+                                    v-model:value="formState.accountid"
+                                    placeholder="请选择"
+                                >
+                                    <a-select-option
+                                        v-for="item in accountList"
+                                        :value="item.accountid"
+                                        :key="item.accountid"
+                                    >{{item.accountid}}</a-select-option>
+                                </a-select>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="挂牌方">
+                                <span class="white">{{selectedRow.username}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="!isFloat()">
+                            <a-form-item label="价格类型">
+                                <span class="white">固定价</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="isFloat()">
+                            <a-form-item label="挂牌估算价">
+                                <span class="white">3444</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="isFloat()">
+                            <a-form-item label="卖出价格" name="priceType">
+                                <a-radio-group
+                                    class="commonRadioGroup"
+                                    v-model:value="formState.priceType"
+                                >
+                                    <a-radio :value="1">市价</a-radio>
+                                    <a-radio :value="2">限价</a-radio>
+                                </a-radio-group>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="isFloat() && isLimit()">
+                            <a-form-item label="摘牌价格" name="price" class="inputIconBox">
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    v-model:value="formState.price"
+                                />
+                                <MinusOutlined @click="decreasePrice" />
+                                <PlusOutlined @click="increasePrice" />
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="挂牌数量">
+                                <span class="white">{{selectedRow.orderqty}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="!useUserType()">
+                            <a-form-item label="摘牌数量">
+                                <span class="white">{{formState.num}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="useUserType()">
+                            <a-form-item label="摘牌数量" name="num" class="inputIconBox">
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    :max="99"
+                                    v-model:value="formState.num"
+                                />
+                                <MinusOutlined @click="decreasePrice" />
+                                <PlusOutlined @click="increasePrice" />
+                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="useUserType()" class="mt-10">
+                            <a-form-item>
+                                <a-slider
+                                    :min="0"
+                                    v-model:value="formState.num"
+                                    :max="selectedRow.orderqty"
+                                    class="formSlider"
+                                />
+                                <div class="unit">
+                                    <span>0</span>
+                                    <span>{{selectedRow.orderqty}}{{selectedRow.enumdicname}}</span>
+                                </div>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" class="relative mt20" v-if="!isFloat()">
+                            <a-form-item :label="'摘牌金额'">
+                                <span class="white ml8">{{getMoney()}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" class="relative mt20" v-if="isFloat()">
+                            <a-form-item :label="'估算金额'">
+                                <span class="white ml8">{{getMoney()}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="getMargin()">
+                            <a-form-item :label="'履约保证金'">
+                                <span class="white ml8">{{getMargin()}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="可用资金">
+                                <span class="white ml8">{{canUseMoney()}}</span>
+                            </a-form-item>
+                        </a-col>
+                    </a-row>
+                </div>
+                <a-row :gutter="24">
+                    <a-col :span="24" class="fixedBtns">
+                        <a-form-item class="btnCenter">
+                            <a-button class="listedBtn" @click="submit">{{isBuy() ? '买入' : '卖出'}}</a-button>
+                            <a-button class="ml10 cancelBtn" @click="cancel">取消</a-button>
+                        </a-form-item>
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+    </Drawer>
+</template>
+
+<script lang="ts">
+import { Des } from '@/common/components/commonDes';
+import Drawer from '@/common/components/drawer/index.vue';
+import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { useTaAccount } from '@/common/setup/account';
+import { validateAction } from '@/common/setup/form';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { useTradeRule } from '@/common/setup/trade';
+import { getGoodsAgreeunitByGoodsId } from '@/services/bus/goods';
+import { geLoginID_number } from '@/services/bus/login';
+import { getMarketByTradeMode } from '@/services/bus/market';
+import { QueryQuoteGoodsListRsp, QueryTjmdTradeOrderDetailRsp } from '@/services/go/Tjmd/interface';
+import { diaoQiOrder } from '@/services/socket/order';
+import { OrderReq } from '@/services/socket/order/interface';
+import { MinusOutlined, PlusOutlined } from '@ant-design/icons-vue';
+import Long from 'long';
+import moment from 'moment';
+import { v4 as uuidv4 } from 'uuid';
+import { defineComponent, PropType, ref } from 'vue';
+import { useUserType } from '../setup';
+import { FormParam } from './interface';
+import { handleForm } from './setup';
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: ModalEnum.spot_trade_warehouse_post_buying,
+    components: { Des, Drawer, PlusOutlined, MinusOutlined },
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryTjmdTradeOrderDetailRsp>,
+            default: {},
+        },
+        refGoods: {
+            type: Object as PropType<QueryQuoteGoodsListRsp[]>,
+            default: [],
+        },
+        buyOrSell: {
+            type: Number as PropType<BuyOrSell>,
+            defualt: BuyOrSell.buy,
+        },
+    },
+    setup(props, context) {
+        // 控制弹窗
+        const { visible, cancel } = _closeModal(context);
+        // 表单
+        const { rules, formState, formRef } = handleForm();
+        const loading = ref<boolean>(false);
+        // 资金账号
+        const { canUseMoney, accountList } = useTaAccount<FormParam>(formState);
+
+        const isBuy = () => props.buyOrSell === BuyOrSell.buy;
+        const isFloat = () => props.selectedRow.pricemode === 3;
+        // 投资者摘牌时可以选择数量,机构摘牌时不能改数量只能整单摘(全部挂牌数量
+        if (!useUserType() || !isFloat()) {
+            formState.num = props.selectedRow.orderqty;
+        }
+        // 是否是 限价
+        const isLimit = () => formState.priceType === 2;
+        const getPrice = () => (isFloat() && isLimit() ? formState.price : props.selectedRow.orderprice);
+        // 金额
+        const getMoney = () => {
+            const temp = getGoodsAgreeunitByGoodsId(props.selectedRow.goodsid);
+            const argeeunit = temp ? temp : 1;
+            const price = getPrice();
+            return Math.round(formState.num * argeeunit * price * 100) / 100;
+        };
+        // 保证金
+        const getMargin = () => {
+            const { buymarginvalue, sellmarginvalue } = useTradeRule();
+            const marginvalue = isBuy() ? buymarginvalue : sellmarginvalue;
+            let result = 0;
+            if (formState.num) {
+                result = (getMoney() + props.selectedRow.marketmaxsub) * formState.num * marginvalue;
+            }
+            return result ? result.toFixed(2) : '--';
+        };
+        // const { getMaxNum, getMoney, getMargin, getPrice } = handleNumAndPrice(props.selectedRow);
+        function submit() {
+            validateAction<FormParam>(formRef, formState).then((res) => {
+                const param: OrderReq = {
+                    ClientSerialNo: uuidv4(), // 客户端流水号
+                    ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // 客户端委托时间
+                    ClientType: 4, // 终端类型
+                    LoginID: geLoginID_number()!, // 登陆账号
+                    AccountID: res.accountid, // 交易账号
+                    GoodsID: props.selectedRow.goodsid, // 商品ID
+                    MarketID: getMarketByTradeMode(TradeMode.DiaoQi)?.marketid, // 市场ID
+                    ValidType: 1, // 校验类型 当日有效
+                    OperateType: 1, // 操作类型: 申请
+                    OrderSrc: 1, // 单据来源: 客户端下单
+                    RelatedID: Long.fromString(props.selectedRow.orderid), // 操作员账号ID
+                    OrderPrice: getPrice(), // 委托价格
+                    OperatorID: Number(geLoginID_number()),
+                    // MarketMaxSub: number // 市价允许最大偏差(做市)
+                    OrderQty: formState.num, // 委托数量
+                    BuyOrSell: isBuy() ? BuyOrSell.sell : BuyOrSell.buy, // 买卖方向  0 买 1 卖
+                    BuildType: 1, // 下单类型  1 建 2 平
+                    // CurtQuotePrice: 0, // 保留,计算冻结金额使用
+                    // SpPrice: 0 ,// 止盈价格
+                    // SlPrice: 0 , // 止损价格
+                    PriceMode: res.priceType, // 取价方式
+                    TimevalidType: 1, // 时间有效类型 单日有效
+                    TriggerType: 1, // 预埋单触发类型
+                    // TriggerPrice: number // 预埋单触发价格
+                    ListingSelectType: 2, // 挂牌点选类型 1:挂牌 2:摘牌 3:先摘后挂
+                    DelistingType: 2, // 摘牌类型 2:点选成交
+                    // RelatedID: number // 关联单号
+                    OptionType: 1, // 期权类型(1:认购(看涨)2:认沽(看跌))
+                    // Premium: number // 权利金
+                    // TriggerOperator: number // 触发条件(1:大于等于2:小于等于)
+                    // ServiceTime: string // 服务端时间
+                    // CouponTypeID: number // 优惠券类型ID(买方)
+                    // UsedQty: number // 使用数量
+                    // ValidTime: string // 指定有效日期
+                    // ReceiveInfoID: number // 收货地址ID
+                };
+                // if (isFloat()) {
+                //     // 浮动价
+                //     param.MarketMaxSub = res.PriceMove; // 基差
+                //     param.OrderPrice = +getQuoteDayInfoByCodeFindPrice(goodscode)!;
+                // }
+                requestResultLoadingAndInfo(diaoQiOrder, param, loading, ['摘牌求购成功', '摘牌求购失败:']).then(() => {
+                    cancel(true);
+                });
+            });
+        }
+        return {
+            submit,
+            cancel,
+            visible,
+            accountList,
+            rules,
+            formState,
+            formRef,
+            isFloat,
+            getMoney,
+            getMargin,
+            canUseMoney,
+            isBuy,
+            useUserType,
+            isLimit,
+        };
+    },
+});
+</script>
+
+<style lang="less">
+.post_buying {
+    width: 100%;
+    height: 100%;
+    .flex;
+    flex-direction: column;
+    position: relative;
+    overflow: hidden;
+    .ant-form {
+        height: 100%;
+    }
+    .condition {
+        width: 100%;
+        height: 48px;
+        margin: 0 16px;
+        padding: 10px 0;
+        border-bottom: 1px solid @m-black6;
+        .inlineflex;
+        .conditionBtn {
+            align-self: center;
+            align-items: center;
+            border: 0;
+            min-width: 80px;
+            height: 28px;
+            line-height: 28px;
+            background: @m-black7;
+            .rounded-corners(3px);
+            font-size: 14px;
+            color: @m-blue0;
+            &:hover {
+                background: @m-black7-hover;
+                color: @m-blue0-hover;
+            }
+        }
+        .conditionBtn + .conditionBtn {
+            margin-left: 10px;
+        }
+    }
+}
+
+.unit {
+    margin-left: 70px;
+    width: 260px;
+    .flex;
+    justify-content: space-between;
+    font-size: 14px;
+    color: @m-grey41;
+    height: 14px;
+    line-height: 14px;
+}
+.listedBtn {
+    width: 120px;
+    height: 30px;
+    line-height: 30px;
+    background: linear-gradient(0deg, @m-blue2 0%, @m-blue0 100%);
+    border-radius: 3px;
+    color: @m-white0;
+    font-size: 14px;
+    text-align: center;
+    border: 0;
+    &:hover {
+        background: linear-gradient(0deg, @m-blue0-hover 0%, @m-blue2-hover 100%);
+        color: @m-white0-hover;
+    }
+}
+.cancelBtn:extend(.listedBtn) {
+    background: linear-gradient(0deg, @m-grey12 0%, @m-grey13 100%) !important;
+    &:hover {
+        background: linear-gradient(0deg, @m-grey12-hover 0%, @m-grey13-hover 100%) !important;
+        color: @m-white0-hover;
+    }
+}
+.ml10 {
+    margin-left: 10px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item {
+    margin-bottom: 14px;
+}
+.mt20 {
+    margin-top: 20px;
+}
+.mt-10 {
+    margin-top: -10px;
+}
+.ant-input-suffix {
+    position: absolute;
+    right: -25px;
+}
+.minusBtn,
+.plusBtn {
+    width: 15px;
+    height: 32px;
+    line-height: 32px;
+    font-size: 15px;
+    color: @m-blue15;
+    cursor: pointer;
+}
+.minusBtn {
+    position: absolute;
+    top: -6px;
+    left: 14px;
+    z-index: 1;
+}
+.plusBtn {
+    position: absolute;
+    top: -6px;
+    right: 14px;
+    z-index: 1;
+}
+.stepper {
+    padding-left: 30px;
+    padding-right: 30px;
+    text-align: center;
+    color: @m-yellow1;
+    font-size: 16px;
+}
+.ant-slider.formSlider {
+    width: 260px !important;
+    margin-left: 70px;
+    .ant-slider-rail {
+        margin-right: 0;
+        padding-right: 0;
+        height: 3px !important;
+        border-radius: 2px !important;
+        background-color: @m-blue14;
+    }
+    .ant-slider-track {
+        height: 3px;
+        background-color: @m-blue0;
+    }
+    .ant-slider-step {
+        height: 3px;
+    }
+    .ant-progress-text {
+        display: none;
+    }
+}
+</style>

+ 13 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/interface.ts

@@ -0,0 +1,13 @@
+import { WrOrderQuote } from "@/services/go/wrtrade/interface";
+
+export interface FormParam {
+    accountid: undefined | number,
+    num: number,
+    priceType: 1 | 2,
+    price: number,
+}
+
+
+export interface TempWrOrderQuoteDetail extends WrOrderQuote {
+    wrResult: { dgfactoryitemtypeid: number; dgfactoryitemid: number }[]
+}

+ 31 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/setup.ts

@@ -0,0 +1,31 @@
+import { validateCommon } from "@/common/setup/validate";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { onBeforeUnmount, reactive, ref, UnwrapRef } from "vue";
+import { FormParam } from "./interface";
+
+
+const formState: UnwrapRef<FormParam> = reactive({
+    accountid: undefined,
+    num: 0,
+    priceType: 1,
+    price: 0,
+})
+
+function initForm() {
+    formState.num = 0
+}
+export function handleForm() {
+    const v_price = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入限价');
+    };
+    const formRef = ref();
+    const rules = {
+        num: [{ required: true, message: '请输入挂牌数量', trigger: 'blur', type: 'number', min: 1 }],
+        price: [{ required: true, trigger: 'blur', type: 'number', validator: v_price }],
+    }
+    onBeforeUnmount(() => {
+        initForm()
+        formRef.value.resetFields()
+    })
+    return { rules, formState, formRef }
+}

+ 125 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/detail/index.vue

@@ -0,0 +1,125 @@
+<template>
+    <!-- 买卖大厅详情 -->
+    <Drawer
+        :title="'详情'"
+        :placement="'right'"
+        :visible="visible"
+        class="top top486"
+        @cancel="cancel"
+    >
+        <div class="detailCont">
+            <div class="rows">
+                <div class="row" v-for="item in lstitem" :key="item.name">
+                    <div class="left">{{item.name}}</div>
+                    <div class="right">{{item.value}}</div>
+                </div>
+            </div>
+            <div class="ruleTitle">履约规则:</div>
+            <div class="rulesCont">
+                <a-row>
+                    <a-col :span="24" class="ruleCol">
+                        <div class="line" v-for="item in lststep" :key="item.autoid">
+                            <!-- <div class="no">{{index + 1}}</div> -->
+                            <div class="name">{{item.steptypename}}</div>
+                            <div class="time">{{item.stepdate}}</div>
+                        </div>
+                    </a-col>
+                </a-row>
+            </div>
+        </div>
+    </Drawer>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { QueryWrGoodsInfoReq, WrGoodsPerformanceStep, WrOrderQuote, WrTypeItem } from '@/services/go/wrtrade/interface';
+import { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryWrGoodsInfo } from '@/services/go/wrtrade';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+
+export default defineComponent({
+    name: ModalEnum.spot_trade_warehouse_delisting,
+    components: { Drawer },
+    emits: ['cancel', 'update'],
+    props: {
+        selectedRow: {
+            type: Object as PropType<WrOrderQuote>,
+            default: {},
+        },
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+    },
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+        const lstitem = ref<WrTypeItem[]>();
+        const lststep = ref<WrGoodsPerformanceStep[]>();
+        function isSale(): boolean {
+            return props.enumName === EnumRouterName.warehouse_pre_sale_price || props.enumName === EnumRouterName.warehouse_pre_sale_floating_price;
+        }
+        const param: QueryWrGoodsInfoReq = {
+            haswr: isSale() ? 0 : 1,
+            wrfactortypeid: props.selectedRow.wrfactortypeid,
+        };
+        queryResultLoadingAndInfo(queryWrGoodsInfo, loading, param).then((res) => {
+            if (res.length) {
+                lstitem.value = res[0].lstitem;
+                lststep.value = res[0].lststep;
+            }
+        });
+
+        return {
+            lstitem,
+            lststep,
+            visible,
+            cancel,
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.detailCont {
+    padding: 10px;
+    .rows {
+        .flex;
+        flex-direction: column;
+        width: 100%;
+        border: 1px solid @m-black6;
+        background: @m-black13;
+        .row {
+            display: inline-flex;
+            width: 100%;
+            height: 38px;
+            line-height: 38px;
+            border-bottom: 1px solid @m-black6;
+            > div {
+                text-align: center;
+                font-size: 16px;
+            }
+            .left {
+                width: 126px;
+                color: @m-grey1;
+                border-right: 1px solid @m-black6;
+            }
+            .right {
+                flex: 1;
+                color: @m-white11;
+            }
+        }
+    }
+    .ruleTitle {
+        width: 100%;
+        height: 30px;
+        line-height: 30px;
+        margin-top: 10px;
+        font-size: 16px;
+        color: @m-grey1;
+    }
+}
+</style>

+ 119 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/history-chart/index.vue

@@ -0,0 +1,119 @@
+<template>
+  <!-- 历史走势-->
+  <Drawer :title="'历史走势'"
+          :placement="'right'"
+          :visible="visible"
+          @cancel="cancel"
+          class="top500">
+    <div class="chart-main"
+         ref="chartRef"
+         id="history-chart"></div>
+  </Drawer>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType, ref, watchEffect } from 'vue';
+import { initData } from '@/common/methods';
+``;
+import * as echarts from 'echarts/core';
+import {
+    BarChart,
+    // 系列类型的定义后缀都为 SeriesOption
+    BarSeriesOption,
+    LineChart,
+    LineSeriesOption,
+} from 'echarts/charts';
+import {
+    TitleComponent,
+    // 组件类型的定义后缀都为 ComponentOption
+    TitleComponentOption,
+    GridComponent,
+    GridComponentOption,
+} from 'echarts/components';
+import { CanvasRenderer } from 'echarts/renderers';
+import { queryWrAverageTradePrice } from '@/services/go/wrtrade';
+import { TempWrOrderQuoteDetail } from '../post_buying/interface';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { WrAverageTradePriceQsq } from '@/services/go/wrtrade/interface';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { _closeModal } from '@/common/setup/modal/modal';
+import Drawer from '@/common/components/drawer/index.vue';
+
+// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
+type ECOption = echarts.ComposeOption<BarSeriesOption | LineSeriesOption | TitleComponentOption | GridComponentOption>;
+
+// 注册必须的组件
+echarts.use([TitleComponent, GridComponent, LineChart, BarChart, CanvasRenderer]);
+export default defineComponent({
+    name: 'purchase-history',
+    emits: ['cancel', 'update'],
+    components: { Drawer },
+    props: {
+        selectedRow: {
+            type: Object as PropType<TempWrOrderQuoteDetail>,
+            default: {},
+        },
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+    },
+    setup(props, context) {
+        const { visible, cancel } = _closeModal(context);
+        const option = {
+            xAxis: {
+                type: 'category',
+                data: [''],
+            },
+            yAxis: {
+                type: 'value',
+            },
+            series: [
+                {
+                    data: [1],
+                    type: 'line',
+                    smooth: true,
+                },
+            ],
+        };
+        const chartRef = ref();
+        const chartInstance = ref<echarts.ECharts>();
+        function queryHistoryData() {
+            const param: WrAverageTradePriceQsq = {
+                haswr: 1,
+                wrfactortypeid: props.selectedRow.wrfactortypeid,
+            };
+            queryWrAverageTradePrice(param).then((res) => {
+                option.xAxis.data.length = 0;
+                option.series[0].data.length = 0;
+                res.forEach((el) => {
+                    option.xAxis.data.push(el.tradedate);
+                    option.series[0].data.push(el.averageprice);
+                });
+                if (chartInstance.value) {
+                    chartInstance.value.setOption(option);
+                }
+            });
+        }
+
+        watchEffect(() => {
+            if (chartRef.value) {
+                chartInstance.value = echarts.init(chartRef.value as HTMLElement);
+                chartInstance.value.setOption(option);
+            }
+        });
+
+        initData(() => {
+            queryHistoryData();
+        });
+        return { option, visible, cancel, chartRef };
+    },
+});
+</script>
+
+<style lang="less">
+// .chart-main {
+//     height: 441px;
+//     width: 100%;
+// }
+</style>;

+ 437 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/index.vue

@@ -0,0 +1,437 @@
+<template>
+    <!-- 挂牌求购 -->
+    <Drawer
+        :title="isBuy() ? '挂牌求购' : '挂牌卖出' "
+        :placement="'right'"
+        :visible="visible"
+        @cancel="cancel"
+        class="top"
+    >
+        <div class="title_right">
+            <span class="tline"></span>
+            <svg class="icon svg-icon" aria-hidden="true">
+                <use xlink:href="#icon-B" />
+            </svg>
+            <span @click="changeDirection">{{isBuy() ? '卖出' : '求购'}}</span>
+        </div>
+        <div class="post_buying">
+            <a-form class="inlineForm dialogForm" ref="formRef" :model="formState" :rules="rules">
+                <div class="formBar">
+                    <a-row :gutter="24">
+                        <a-col :span="24">
+                            <a-form-item label="交易账户" name="accountid">
+                                <a-select
+                                    class="inlineFormSelect"
+                                    style="width: 260px"
+                                    v-model:value="formState.accountid"
+                                    placeholder="请选择"
+                                >
+                                    <a-select-option
+                                        v-for="item in accountList"
+                                        :value="item.accountid"
+                                        :key="item.accountid"
+                                    >{{item.accountid}}</a-select-option>
+                                </a-select>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="价格类型" name>
+                                <a-radio-group
+                                    class="commonRadioGroup"
+                                    v-model:value="formState.priceType"
+                                >
+                                    <a-radio :value="2">固定价</a-radio>
+                                    <!-- 掉期交易商有固定价和浮动价选择 -->
+                                    <!-- 普通交易商只有固定价 -->
+                                    <a-radio :value="3" v-if="!useUserType()">浮动价</a-radio>
+                                </a-radio-group>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="!isFloat()">
+                            <a-form-item label="挂牌价格" name="FixedPrice" class="inputIconBox">
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    v-model:value="formState.FixedPrice"
+                                />
+                                <MinusOutlined @click="decreasePrice" />
+                                <PlusOutlined @click="increasePrice" />
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-else>
+                            <a-form-item label="基差" name="PriceMove">
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    v-model:value="formState.PriceMove"
+                                />
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="isFloat()">
+                            <a-form-item label="估算价" name="PriceMove">
+                                <span class="white">{{getFloatPrice()}}</span>
+                            </a-form-item>
+                        </a-col>
+
+                        <a-col :span="24">
+                            <a-form-item label="挂牌数量" name="OrderQty" class="inputIconBox">
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    :max="getMaxNum()"
+                                    v-model:value="formState.OrderQty"
+                                />
+                                <MinusOutlined @click="increaseNum" />
+                                <PlusOutlined @click="decreaseNum" />
+                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" class="mt-10">
+                            <a-form-item>
+                                <a-slider
+                                    :min="0"
+                                    v-model:value="formState.OrderQty"
+                                    :max="getMaxNum()"
+                                    class="formSlider"
+                                />
+                                <div class="unit">
+                                    <span>{{getMaxNum() ? selectedRow.minivalue : 0}}</span>
+                                    <span>{{getMaxNum()}}{{selectedRow.enumdicname}}</span>
+                                </div>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" class="relative mt20">
+                            <a-form-item :label="'挂牌金额'">
+                                <span class="white ml8">{{getMoney()}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24" v-if="getMargin()">
+                            <a-form-item :label="'履约保证金'">
+                                <span class="white ml8">{{getMargin()}}</span>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="可用资金">
+                                <span class="white ml8">{{canUseMoney()}}</span>
+                            </a-form-item>
+                        </a-col>
+                    </a-row>
+                </div>
+                <a-row :gutter="24">
+                    <a-col :span="24" class="fixedBtns">
+                        <a-form-item class="btnCenter">
+                            <a-button class="listedBtn" @click="submit">{{isBuy() ? '买入' : '卖出'}}</a-button>
+                            <a-button class="ml10 cancelBtn" @click="cancel">取消</a-button>
+                        </a-form-item>
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+    </Drawer>
+</template>
+
+<script lang="ts">
+import { Des } from '@/common/components/commonDes';
+import Drawer from '@/common/components/drawer/index.vue';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { useTaAccount } from '@/common/setup/account';
+import { validateAction } from '@/common/setup/form';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { useListingTradeNumAndPrice } from '@/common/setup/trade';
+import { ListingTradeNumAndPrice } from '@/common/setup/trade/interface';
+import { getGoodsByCode, getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import { geLoginID_number } from '@/services/bus/login';
+import { getMarketByTradeMode } from '@/services/bus/market';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryQuoteGoodsListRsp } from '@/services/go/Tjmd/interface';
+import { diaoQiOrder } from '@/services/socket/order';
+import { OrderReq } from '@/services/socket/order/interface';
+import { MinusOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons-vue';
+import moment from 'moment';
+import { v4 as uuidv4 } from 'uuid';
+import { defineComponent, PropType, ref } from 'vue';
+import { useUserType } from '../setup';
+import { FormParam } from './interface';
+import { handleForm, isFloat, useBuySellDirection, usePrice, useNum } from './setup';
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: ModalEnum.spot_trade_warehouse_post_buying,
+    components: { Des, Drawer, PlusOutlined, MinusOutlined, SwapOutlined },
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryQuoteDayRsp>,
+            default: {},
+        },
+        refGoods: {
+            type: Object as PropType<QueryQuoteGoodsListRsp[]>,
+            default: [],
+        },
+    },
+    setup(props, context) {
+        // 控制弹窗
+        const { visible, cancel } = _closeModal(context);
+        // 表单
+        const { rules, formState, formRef } = handleForm();
+        const loading = ref<boolean>(false);
+        // 买卖方向
+        const { direction, changeDirection, isBuy } = useBuySellDirection();
+        // 资金账号
+        const { canUseMoney, accountList } = useTaAccount<FormParam>(formState);
+        // 金额 数量 保证金
+        const param: ListingTradeNumAndPrice<FormParam> = {
+            formState,
+            goodscode: props.selectedRow.goodscode,
+            isFloat,
+            canUseMoney,
+        };
+        const { getFloatPrice, getListingBuyMaxNum, getListingSellMaxNum, getListingBuyMargin, getListingSellMargin, getMoney } = useListingTradeNumAndPrice<FormParam>(param);
+        // 保证金
+        const getMargin = isBuy() ? getListingBuyMargin : getListingSellMargin;
+        // 最大数量
+        const getMaxNum = isBuy() ? getListingBuyMaxNum : getListingSellMaxNum;
+
+        function submit() {
+            validateAction<FormParam>(formRef, formState).then((res) => {
+                const { goodscode, orderid } = props.selectedRow;
+                const param: OrderReq = {
+                    ClientSerialNo: uuidv4(), // 客户端流水号
+                    ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // 客户端委托时间
+                    ClientType: 4, // 终端类型
+                    LoginID: geLoginID_number()!, // 登陆账号
+                    AccountID: res.accountid, // 交易账号
+                    GoodsID: getGoodsByCode(goodscode)?.goodsid, // 商品ID
+                    MarketID: getMarketByTradeMode(TradeMode.DiaoQi)?.marketid, // 市场ID
+                    ValidType: 1, // 校验类型 当日有效
+                    OperateType: 1, // 操作类型: 申请
+                    OrderSrc: 1, // 单据来源: 客户端下单
+                    RelatedID: orderid, // 操作员账号ID
+                    OrderPrice: res.FixedPrice, // 委托价格
+                    OperatorID: Number(geLoginID_number()),
+                    // MarketMaxSub: number // 市价允许最大偏差(做市)
+                    OrderQty: res.OrderQty, // 委托数量
+                    BuyOrSell: direction.value, // 买卖方向  0 买 1 卖
+                    BuildType: 1, // 下单类型  1 建 2 平
+                    // CurtQuotePrice: 0, // 保留,计算冻结金额使用
+                    // SpPrice: 0 ,// 止盈价格
+                    // SlPrice: 0 , // 止损价格
+                    PriceMode: res.priceType, // 取价方式
+                    TimevalidType: 1, // 时间有效类型 单日有效
+                    TriggerType: 1, // 预埋单触发类型
+                    // TriggerPrice: number // 预埋单触发价格
+                    ListingSelectType: 1, // 挂牌点选类型 1:挂牌 2:摘牌 3:先摘后挂
+                    DelistingType: 2, // 摘牌类型 2:点选成交
+                    // RelatedID: number // 关联单号
+                    OptionType: 1, // 期权类型(1:认购(看涨)2:认沽(看跌))
+                    // Premium: number // 权利金
+                    // TriggerOperator: number // 触发条件(1:大于等于2:小于等于)
+                    // ServiceTime: string // 服务端时间
+                    // CouponTypeID: number // 优惠券类型ID(买方)
+                    // UsedQty: number // 使用数量
+                    // ValidTime: string // 指定有效日期
+                    // ReceiveInfoID: number // 收货地址ID
+                };
+                if (isFloat()) {
+                    // 浮动价
+                    param.MarketMaxSub = res.PriceMove; // 基差
+                    param.OrderPrice = +getQuoteDayInfoByCodeFindPrice(goodscode)!;
+                }
+                requestResultLoadingAndInfo(diaoQiOrder, param, loading, ['挂牌求购成功', '挂牌求购失败:']).then(() => {
+                    cancel(true);
+                });
+            });
+        }
+        return {
+            submit,
+            cancel,
+            visible,
+            rules,
+            formState,
+            formRef,
+            isFloat,
+            getMaxNum,
+            getMoney,
+            getMargin,
+            getFloatPrice,
+            direction,
+            changeDirection,
+            isBuy,
+            useUserType,
+            canUseMoney,
+            accountList,
+            ...usePrice(),
+            ...useNum(),
+        };
+    },
+});
+</script>
+
+<style lang="less">
+.post_buying {
+    width: 100%;
+    height: 100%;
+    .flex;
+    flex-direction: column;
+    position: relative;
+    overflow: hidden;
+
+    .ant-form {
+        height: 100%;
+    }
+    .condition {
+        width: 100%;
+        height: 48px;
+        margin: 0 16px;
+        padding: 10px 0;
+        border-bottom: 1px solid @m-black6;
+        .inlineflex;
+        .conditionBtn {
+            align-self: center;
+            align-items: center;
+            border: 0;
+            min-width: 80px;
+            height: 28px;
+            line-height: 28px;
+            background: @m-black7;
+            .rounded-corners(3px);
+            font-size: 14px;
+            color: @m-blue0;
+            &:hover {
+                background: @m-black7-hover;
+                color: @m-blue0-hover;
+            }
+        }
+        .conditionBtn + .conditionBtn {
+            margin-left: 10px;
+        }
+    }
+}
+.title_right {
+    color: @m-blue25;
+    position: absolute;
+    top: 8px;
+    right: 19px;
+    cursor: pointer;
+    display: flex;
+    .tline {
+        width: 1px;
+        height: 18px;
+        background: @m-black47;
+        margin-top: 2px;
+        box-shadow: 1px 0px 0px 0px @m-black48;
+    }
+    .icon {
+        font-size: 16px;
+        height: 16px;
+        line-height: 16px;
+        margin: 3px 7px 3px 17px;
+        fill: @m-blue25;
+    }
+    span {
+        font-size: 14px;
+        font-family: Adobe Heiti Std;
+        font-weight: normal;
+    }
+}
+.unit {
+    margin-left: 70px;
+    width: 260px;
+    .flex;
+    justify-content: space-between;
+    font-size: 14px;
+    color: @m-grey41;
+    height: 14px;
+    line-height: 14px;
+}
+.listedBtn {
+    width: 120px;
+    height: 30px;
+    line-height: 30px;
+    background: linear-gradient(0deg, @m-blue2 0%, @m-blue0 100%);
+    border-radius: 3px;
+    color: @m-white0;
+    font-size: 14px;
+    text-align: center;
+    border: 0;
+    &:hover {
+        background: linear-gradient(0deg, @m-blue0-hover 0%, @m-blue2-hover 100%);
+        color: @m-white0-hover;
+    }
+}
+.cancelBtn:extend(.listedBtn) {
+    background: linear-gradient(0deg, @m-grey12 0%, @m-grey13 100%) !important;
+    &:hover {
+        background: linear-gradient(0deg, @m-grey12-hover 0%, @m-grey13-hover 100%) !important;
+        color: @m-white0-hover;
+    }
+}
+.ml10 {
+    margin-left: 10px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item {
+    margin-bottom: 14px;
+}
+.mt20 {
+    margin-top: 20px;
+}
+.mt-10 {
+    margin-top: -10px;
+}
+.ant-input-suffix {
+    position: absolute;
+    right: -25px;
+}
+.minusBtn,
+.plusBtn {
+    width: 15px;
+    height: 32px;
+    line-height: 32px;
+    font-size: 15px;
+    color: @m-blue15;
+    cursor: pointer;
+}
+.minusBtn {
+    position: absolute;
+    top: -6px;
+    left: 14px;
+    z-index: 1;
+}
+.plusBtn {
+    position: absolute;
+    top: -6px;
+    right: 14px;
+    z-index: 1;
+}
+.stepper {
+    padding-left: 30px;
+    padding-right: 30px;
+    text-align: center;
+    color: @m-yellow1;
+    font-size: 16px;
+}
+.ant-slider.formSlider {
+    width: 260px !important;
+    margin-left: 70px;
+    .ant-slider-rail {
+        margin-right: 0;
+        padding-right: 0;
+        height: 3px !important;
+        border-radius: 2px !important;
+        background-color: @m-blue14;
+    }
+    .ant-slider-track {
+        height: 3px;
+        background-color: @m-blue0;
+    }
+    .ant-slider-step {
+        height: 3px;
+    }
+    .ant-progress-text {
+        display: none;
+    }
+}
+</style>

+ 14 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/interface.ts

@@ -0,0 +1,14 @@
+import { WrOrderQuote } from "@/services/go/wrtrade/interface";
+
+export interface FormParam {
+    accountid: undefined | number,
+    FixedPrice: number,
+    priceType: 2 | 3,
+    OrderQty: number,
+    PriceMove: number,
+}
+
+
+export interface TempWrOrderQuoteDetail extends WrOrderQuote {
+    wrResult: { dgfactoryitemtypeid: number; dgfactoryitemid: number }[]
+}

+ 80 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts

@@ -0,0 +1,80 @@
+import { BuyOrSell } from "@/common/constants/enumCommon";
+import { validateCommon } from "@/common/setup/validate";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { onBeforeUnmount, reactive, ref, UnwrapRef } from "vue";
+import { FormParam } from "./interface";
+
+
+const formState: UnwrapRef<FormParam> = reactive({
+    accountid: undefined,
+    FixedPrice: 0,
+    OrderQty: 0,
+    PriceMove: 0,
+    priceType: 2,
+})
+
+function initForm() {
+    formState.FixedPrice = 0
+    formState.OrderQty = 0
+    formState.PriceMove = 0
+    formState.priceType = 2
+}
+export function handleForm() {
+    const v_price = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入挂牌价格');
+    };
+    const formRef = ref();
+    const rules = {
+        FixedPrice: [{ required: true, message: '请输入挂牌价格', trigger: 'blur', type: 'number', validator: v_price }],
+        OrderQty: [{ required: true, message: '请输入挂牌数量', trigger: 'blur', type: 'number', min: 1 }],
+        PriceMove: [{ required: true, message: '请输入基差', trigger: 'blur', type: 'number' }],
+        accountid: [{ required: true, message: '请输入交易账号' }],
+    }
+    onBeforeUnmount(() => {
+        initForm()
+        formRef.value.resetFields()
+    })
+    return { rules, formState, formRef }
+}
+
+// 是否是浮动价
+export function isFloat() { return formState.priceType === 3 }
+
+
+// 挂牌买卖方向
+export function useBuySellDirection() {
+    const direction = ref<BuyOrSell>(BuyOrSell.buy)
+    function changeDirection() {
+        initForm()
+        direction.value = direction.value === BuyOrSell.buy ? BuyOrSell.sell : BuyOrSell.buy
+    }
+    function isBuy() {
+        return direction.value === BuyOrSell.buy
+    }
+    return { direction, changeDirection, isBuy }
+}
+
+// 价格
+export const usePrice = () => {
+    function increasePrice() {
+        formState.FixedPrice++;
+    }
+    function decreasePrice() {
+        if (formState.FixedPrice) {
+            formState.FixedPrice--;
+        }
+    }
+    return { increasePrice, decreasePrice };
+};
+
+export const useNum = () => {
+    function increaseNum() {
+        formState.OrderQty++;
+    }
+    function decreaseNum() {
+        if (formState.OrderQty) {
+            formState.OrderQty--;
+        }
+    }
+    return { increaseNum, decreaseNum };
+}

+ 169 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/sell/index.vue

@@ -0,0 +1,169 @@
+<template>
+  <!-- 现货贸易 - 买卖大厅 - 买报价牌 -->
+  <a-table :columns="handleColumn(columns)"
+           :class="['sellHallTable', isBottom ? '' : 'sellHallTableHigh', tableList.length ? '' : 'noDataTable']"
+           :scroll="{ x: '100%', y: isBottom ? 'calc(100vh- 378px)' : 'calc(100vh - 135px)' }"
+           :pagination="false"
+           :loading="loading"
+           :expandedRowKeys="expandedRowKeys"
+           :customRow="Rowclick"
+           :expandIcon="expandIcon"
+           :expandIconAsCell="false"
+           rowKey="key"
+           :data-source="tableList">
+    <!-- 额外的展开行 -->
+    <template #expandedRowRender="{ record }">
+      <BtnList :btnList="btnList"
+               :record="record"
+               @click="openComponent" />
+    </template>
+    <template #username="{text, record }">
+      <span>{{record.userid + " " }}{{text}}</span>
+    </template>
+  </a-table>
+  <component :is="componentId"
+             v-if="componentId"
+             :selectedRow="selectedRow"
+             :enumName="enumName"
+             :buyOrSell="BuyOrSell.sell"
+             :parantSelectedRow="parantSelectedRow"
+             @cancel="closeComponent"></component>
+</template>
+
+<script lang="ts">
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { ComposeTableParam, BtnList, defineComponent, handleComposeTable, queryTableList, ModalEnum } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryOrderQuoteDetail } from '@/services/go/wrtrade';
+import { QueryOrderQuoteDetailReq, WrOrderQuote, WrOrderQuoteDetail } from '@/services/go/wrtrade/interface';
+import { defineAsyncComponent, PropType } from 'vue';
+import { BtnListType } from '@/common/components/btnList/interface';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { expandIcon } from '@/common/setup/table/clolumn';
+import { ColumnType } from '@/common/methods/table/interface';
+import { Moment } from 'moment';
+import moment from 'moment';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { useBuyOrSellBtnList } from '../setup';
+import { getUserId } from '@/services/bus/account';
+import { getUserAccountType } from '@/services/bus/user';
+import { queryTjmdTradeOrderDetail } from '@/services/go/Tjmd';
+import { QueryTjmdTradeOrderDetailReq } from '@/services/go/Tjmd/interface';
+import { findItemGoods } from '../../setup';
+
+const columns = [
+    {
+        key: '0th',
+        dataIndex: 'index',
+        title: '序号',
+        align: 'center',
+        slots: {
+            customRender: 'index',
+        },
+        width: 60,
+    },
+    {
+        key: '1th',
+        dataIndex: 'orderprice',
+        title: '卖价',
+        align: 'center',
+        slots: {
+            customRender: 'orderprice',
+        },
+        width: 120,
+    },
+    {
+        key: '2th',
+        dataIndex: 'orderqty',
+        title: '卖量',
+        align: 'center',
+        slots: {
+            customRender: 'orderqty',
+        },
+        width: 120,
+    },
+    {
+        key: '3th',
+        dataIndex: 'username',
+        title: '购买方',
+        align: 'center',
+        slots: {
+            customRender: 'username',
+        },
+    },
+];
+
+export default defineComponent({
+    emits: ['cancel', 'openComponent'],
+    name: 'warehouse_receipt_trade_price_delisting_sell',
+    props: {
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+        parantSelectedRow: {
+            type: Object as PropType<WrOrderQuote>,
+            default: {},
+        },
+    },
+    components: {
+        BtnList,
+        Listing: defineAsyncComponent(() => import('../delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        console.log(isBottom.value, 'isBottom');
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuoteDetail>();
+
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryTjmdTradeOrderDetailReq = {
+                buyorsell: 1,
+                userid: getUserId(),
+                usertype: getUserAccountType(),
+                goodsid: findItemGoods(props.parantSelectedRow.goodscode)?.goodsid,
+            };
+            queryTable(queryTjmdTradeOrderDetail, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: EnumRouterName.warehouse_receipt_trade_floating_price,
+            tableFilterKey: [],
+            isDetail: false,
+        };
+        function handleColumn(columns: ColumnType[]) {
+            columns.forEach((item) => {
+                columns.forEach((item) => {
+                    if (item.dataIndex == 'username') {
+                        delete item.width;
+                    }
+                });
+            });
+            return columns;
+        }
+        return {
+            isBottom,
+            ...handleComposeTable<WrOrderQuoteDetail>(param),
+            queryTableAction,
+            loading,
+            tableList,
+            BuyOrSell,
+            enumName: props.enumName,
+            expandIcon,
+            handleColumn,
+            btnList: useBuyOrSellBtnList(),
+            columns,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 43 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/setup.ts

@@ -0,0 +1,43 @@
+import { BtnListType } from "@/common/components/btnList/interface";
+import { UserType } from "@/common/constants/enumCommon";
+import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
+import { getUserAccountType } from "@/services/bus/user";
+import { UnwrapRef } from "vue";
+
+// 获取按钮列表
+export function useBuyOrSellBtnList() {
+    const btnList: BtnListType[] = [
+        { lable: '摘牌', code: 'Listing', className: 'operBtn' },
+    ];
+    return btnList
+}
+
+// true: 普通交易商;false: 机构
+export const useUserType = () => {
+    return getUserAccountType() === UserType.investment
+}
+
+// 交易账号
+export function useBlocksAccount<T extends { accountid: number }>(formState: UnwrapRef<T>) {
+    // 资金账号
+    const accountList = getAccountTypeList([2]);
+    if (accountList.length) {
+        formState.accountid = accountList[0].accountid;
+    }
+    // 资金账号
+    function getSelectedAccount() {
+        return accountList.find((e) => e.accountid === formState.accountid);
+    }
+    // 可以资金
+    function canUseMoney() {
+        return getCanUseMoney(getSelectedAccount()!)
+    }
+    // 处理内部资金账号
+    function handleSelectedAccount() {
+        const item = getSelectedAccount()!;
+        const list = getAccountTypeList([2]);
+        return item.taaccounttype === 2 ? item : list[0];
+    }
+    return { handleSelectedAccount, canUseMoney, getSelectedAccount, accountList };
+}
+

+ 206 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue

@@ -0,0 +1,206 @@
+<template>
+    <!--订单交易 挂牌转让-->
+    <div class="topTableHeight">
+        <div class="filterTable">
+            <div class="filter-custom-table">
+                <a-select
+                    class="conditionSelect"
+                    :style="{width: '180px', maxHeight: '400px', overflow: 'auto' }"
+                    @change="goodsChange"
+                    placeholder="全部标的合约"
+                >
+                    <a-select-option
+                        v-for="item in getRefGoodsList()"
+                        :value="item"
+                        :key="item"
+                    >{{item}}</a-select-option>
+                </a-select>
+                <!-- <a-button class="btnDeafault"
+                @click="search(true)"
+                style="width: 80px">筛选</a-button>-->
+            </div>
+        </div>
+        <a-table
+            :columns="columns"
+            :class="['srcollYTable', isBottom ? 'secondTabTable' : 'secondTabTableNoBottom', goodsList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+            :scroll="{ x: '100%', y: isBottom ? 'calc(100vh- 407px)' : 'calc(100vh - 167px)' }"
+            :pagination="false"
+            :loading="loading"
+            :expandedRowKeys="expandedRowKeys"
+            :customRow="Rowclick"
+            rowKey="goodscode"
+            ref="tableRef"
+            :data-source="goodsList"
+        >
+            <template #totalturnover="{ text }">
+                <span>{{changeUnit(text)}}</span>
+            </template>
+            <!-- 涨跌 -->
+            <template #change="{ record }">
+                <span>{{quoteChange(record, record.decimalplace)}}</span>
+            </template>
+            <!-- 幅度 -->
+            <template #amplitude="{ record }">
+                <span>{{quoteAmplituOfVibration(record, record.decimalplace)}}</span>
+            </template>
+            <!-- 振幅 -->
+            <template #vibration="{ record }">
+                <span>{{quoteAmplituOfVibration(record, record.decimalplace)}}</span>
+            </template>
+            <template #index="{ index }">
+                <span>{{index + 1}}</span>
+            </template>
+            <!-- 买价 -->
+            <template #bid="{ text, record }">
+                <span :class="handleQuotePriceColor(text, record.presettle)">{{text}}</span>
+            </template>
+            <!-- 卖价 -->
+            <template #ask="{ text, record }">
+                <span :class="handleQuotePriceColor(text, record.presettle)">{{text}}</span>
+            </template>
+            <!-- 最新价 -->
+            <template #last="{ text, record }">
+                <span :class="handleQuotePriceColor(text, record.presettle)">{{text}}</span>
+            </template>
+            <!-- 最低价 -->
+            <template #lowest="{ text, record }">
+                <span :class="handleQuotePriceColor(text, record.presettle)">{{text}}</span>
+            </template>
+            <!-- 最高价 -->
+            <template #highest="{ text, record }">
+                <span :class="handleQuotePriceColor(text, record.presettle)">{{text}}</span>
+            </template>
+        </a-table>
+        <!-- 右键 -->
+        <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="btnList"></contextMenu>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :selectedRow="selectedRow"
+            @cancel="closeComponent"
+        ></component>
+    </div>
+</template>
+
+<script lang="ts">
+import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+
+import { handleSubcriteOnDemandQuote, handleQuotePriceColor, quoteChange, quoteAmplitude, quoteAmplituOfVibration } from '@/common/setup/table/tableQuote';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { BtnListType } from '@/common/components/btnList/interface';
+import { RefGoodsList } from './interface';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { ref } from 'vue';
+import { useQueryData } from '@/common/setup/request';
+import { QueryQuoteGoodsListReq } from '@/services/go/Tjmd/interface';
+import { queryQuoteGoodsList } from '@/services/go/Tjmd';
+import { useSwapList, columnsList, getBtnList } from './setup';
+
+export default defineComponent({
+    name: 'spot_trade_order_transaction_swap',
+    components: {
+        contextMenu,
+        BuyAndSell: defineAsyncComponent(() => import('./components/buy-sell-market/index.vue')),
+        PostBuying: defineAsyncComponent(() => import('./components/post_buying/index.vue')),
+        Detail: defineAsyncComponent(() => import('./components/detail/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        const { loading, goodsList, getRefGoodsList, filterGoodsList } = useSwapList();
+
+        const param: TableParam = {
+            columnsList,
+            queryFn: () => {},
+            clickName: 'BuyAndSell',
+        };
+
+        // 行情按需订阅
+        let stopSubcribe = handleSubcriteOnDemandQuote<RefGoodsList>(goodsList);
+        // 过滤标的合约
+        function goodsChange(value: string) {
+            const goodsList = filterGoodsList(value);
+            // 停止上次订阅
+            stopSubcribe();
+            // 重新发起订阅
+            stopSubcribe = handleSubcriteOnDemandQuote<RefGoodsList>(goodsList);
+        }
+        return {
+            isBottom,
+            ...handleTableEventAndData<RefGoodsList>(param),
+            btnList: getBtnList(true),
+            handleQuotePriceColor,
+            quoteChange,
+            quoteAmplitude,
+            quoteAmplituOfVibration,
+            getRefGoodsList,
+            goodsList,
+            loading,
+            goodsChange,
+        };
+    },
+});
+</script>
+<style lang="less">
+.noData {
+    .position(absolute, 28px, 0, 0, 0);
+}
+.filter-custom-table {
+    display: inline-flex;
+    padding-top: 4px;
+    height: 34px;
+    .conditionSelect:first-child {
+        margin-right: 10px;
+    }
+    .btnDeafault.ant-btn,
+    .operBtn.ant-btn {
+        height: 26px !important;
+        line-height: 26px !important;
+    }
+
+    .ant-select-single:not(.ant-select-customize-input) + .ant-select-single:not(.ant-select-customize-input),
+    .ant-select + .ant-space.ant-space-vertical {
+        margin-left: 10px;
+    }
+    .ant-select-single:not(.ant-select-customize-input) {
+        height: 26px;
+        line-height: 26px !important;
+        .ant-select-selector {
+            height: 26px;
+            border-color: @m-grey46 !important;
+            background: @m-grey47;
+            .rounded-corners(3px);
+            .ant-select-selection-item {
+                line-height: 26px;
+            }
+            .ant-select-selection-search {
+                height: 26px;
+                .ant-select-selection-search-input {
+                    height: 26px;
+                    line-height: 27px !important;
+                }
+            }
+            .ant-select-selection-placeholder {
+                line-height: 26px;
+            }
+        }
+    }
+
+    .allDatePicker.ant-calendar-picker {
+        height: 26px !important;
+        border: 1px solid @m-grey46 !important;
+        .ant-calendar-picker-input.ant-input {
+            height: 26px;
+            line-height: 26px;
+            &::placeholder {
+                color: @m-grey10 !important;
+            }
+        }
+    }
+    .conditionSelect + .conditionSelect {
+        margin-left: 10px;
+    }
+}
+</style>

+ 6 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/interface.ts

@@ -0,0 +1,6 @@
+import { QueryQuoteDayRsp } from "@/services/go/quote/interface";
+
+export interface RefGoodsList extends QueryQuoteDayRsp {
+    refgoodsname: string
+    goodsname: string
+}

+ 112 - 0
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/setup.ts

@@ -0,0 +1,112 @@
+import { BtnListType } from "@/common/components/btnList/interface"
+import { TradeMode } from "@/common/constants/enumCommon"
+import { initData } from "@/common/methods"
+import { queryTableList } from "@/common/setup/table"
+import { getQuoteDayInfoByCode } from "@/services/bus/goods"
+import { getMarketIdsByTradeMode } from "@/services/bus/market"
+import { getUserAccountType } from "@/services/bus/user"
+import { queryQuoteGoodsList } from "@/services/go/Tjmd"
+import { QueryQuoteGoodsListReq, QueryQuoteGoodsListRsp } from "@/services/go/Tjmd/interface"
+import { ref } from "vue"
+import { RefGoodsList } from './interface'
+
+const refGoods = ref<QueryQuoteGoodsListRsp[]>([])
+
+export function findItemGoods(goodscode: string) {
+    return refGoods.value.find(el => el.goodscode === goodscode)!
+}
+// 获取 商品掉期 商品列表
+export const useSwapList = () => {
+    const { loading, queryTable } = queryTableList<QueryQuoteGoodsListRsp>();
+    // 行情商品
+    const goodsList = ref<RefGoodsList[]>([])
+    initData(() => {
+        // 组装 参数
+        const marketids = getMarketIdsByTradeMode(TradeMode.DiaoQi)
+        const param: QueryQuoteGoodsListReq = {
+            usertype: getUserAccountType(),
+        }
+        if (marketids) {
+            param.marketids = marketids
+        }
+        // 开始查询 商品掉期
+        queryTable(queryQuoteGoodsList, param).then(res => {
+            refGoods.value = res
+            goodsList.value.length = 0
+            res.forEach(el => {
+                // 找到盘面数据
+                const quote = getQuoteDayInfoByCode(el.goodscode);
+                if (quote) {
+                    const result: RefGoodsList = {
+                        ...quote,
+                        goodsname: el.goodsname, refgoodsname: el.refgoodsname
+                    }
+                    goodsList.value.push(result)
+                }
+            })
+        })
+    })
+    // 获取标记商品列表
+    function getRefGoodsList(): string[] {
+        const result = new Set<string>(['全部标的合约'])
+        refGoods.value.forEach(el => {
+            result.add(el.refgoodsname)
+        })
+        return [...result]
+    }
+    // 过滤标的合约
+    function filterGoodsList(value: string) {
+        const result = ref<RefGoodsList[]>([])
+        if (value === '全部标的合约') {
+            result.value = goodsList.value
+        } else {
+            result.value = goodsList.value.filter(goods => goods.refgoodsname === value)
+        }
+        return result
+    }
+
+    return { loading, goodsList, getRefGoodsList, filterGoodsList }
+}
+
+export const columnsList = [
+    { title: '序号', key: 'index', width: 80 },
+    { title: '代码', key: 'goodscode' },
+    { title: '名称', key: 'goodsname' },
+
+    { title: '标的合约', key: 'refgoodsname' },
+
+    { title: '买价', key: 'bid' },
+    { title: '买量', key: 'bidvolume' },
+    { title: '卖价', key: 'ask' },
+    { title: '卖量', key: 'askvolume' },
+
+    { title: '当前价', key: 'last' },
+    { title: '涨跌', key: 'change' }, // 最新价 - 昨结价
+    { title: '幅度', key: 'amplitude' }, // (最新价 - 昨结价) / 100 %
+    { title: '开盘', key: 'opened' },
+    { title: '最高', key: 'highest' },
+    { title: '最低', key: 'lowest' },
+
+    { title: '结算', key: 'settle' },
+
+    { title: '昨结算', key: 'presettle' },
+
+    // { title: '振幅', key: 'vibration' }, // (最高价 - 最低价 ) / 最新价  * 100 %
+    // { title: '总量', key: 'totalvolume' },
+    // { title: '现量', key: 'lastvolume' },
+    // { title: '持仓量', key: 'holdvolume' },
+    // { title: '日增', key: 'holdincrement' },
+    // { title: '金额', key: 'totalturnover' },
+];
+
+// 获取按钮列表
+export function getBtnList(isBuyAndSell: boolean) {
+    const btnList: BtnListType[] = [
+        { lable: '挂牌求购', code: 'PostBuying', className: 'operBtn' },
+        { lable: '详情', code: 'Detail', className: 'btnDeafault' },
+    ];
+    if (isBuyAndSell) {
+        btnList.push({ lable: '买卖大厅', code: 'BuyAndSell', className: 'btnDeafault' })
+    }
+    return btnList
+}

+ 7 - 3
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/index.vue

@@ -81,7 +81,8 @@
                                 :max="getMaxNum()"
                                 v-model:value="formState.num" />
                 <span class="input-enumdicname-absolute">{{selectedRow.enumdicname}}</span>
-                <div class="labelTip">({{selectedRow.minivalue}}{{selectedRow.enumdicname}}起)</div>
+                <div class="labelTip">({{selectedRow.delistminqty}}{{selectedRow.enumdicname}}起)
+                </div>
               </a-form-item>
             </a-col>
           </a-row>
@@ -178,6 +179,7 @@ import { getRules } from '@/services/bus/rules';
 import { ListingForm } from './interface';
 import { HdWRDealOrder, wrBargainApply } from '@/services/proto/warehousetrade';
 import Long from 'long';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
@@ -234,9 +236,9 @@ export default defineComponent({
             let result = 0;
             const { marginvalue } = props.selectedRow;
             if (price && num && marginvalue) {
-                result = (price * num * marginvalue) / 100;
+                result = price * num * marginvalue;
             }
-            return result ? result.toFixed(2) : '--';
+            return result ? Math.floor(2) : '--';
         }
         function getMaxNum() {
             const qty = props.selectedRow.orderqty;
@@ -293,6 +295,7 @@ export default defineComponent({
                     };
                     requestResultLoadingAndInfo(wrBargainApply, param, loading, ['议价摘牌成功', '议价摘牌失败:']).then(() => {
                         cancel(true);
+                        Bus.$emit('blocsTrade', true);
                     });
                 } else {
                     // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
@@ -333,6 +336,7 @@ export default defineComponent({
 
                     requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
                         cancel(true);
+                        Bus.$emit('blocsTrade', true);
                     });
                 }
             });

+ 18 - 14
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/post-buying/index.vue

@@ -152,7 +152,12 @@
         </div>
     </Drawer>
     <!-- 选择朋友 -->
-    <Friend v-if="showFriend" @cancel="chooseFriend" @update="chooseFriend" />
+    <Friend
+        v-if="showFriend"
+        :friends="formState.friends"
+        @cancel="chooseFriend"
+        @update="chooseFriend"
+    />
     <!-- 选择履约模板 -->
     <Permance v-if="showPermance" @cancel="choosePermance" @update="choosePermance" />
 </template>
@@ -208,20 +213,19 @@ export default defineComponent({
         // 摘牌数量
         const { numCheck, increaseNumber, decreaseNumber } = useBlocksNumber(formState);
         function submit() {
-            if (!formState.permanceTempName) {
-                message.error('请选择履约模板');
-                return;
-            }
-            if (!friendCheck.value) {
-                if (formState.friends.length === 0) {
-                    message.error('请选择朋友');
-                    return;
-                }
-            }
-
             const marketInfo = getMarketRunByTradeMode(17);
             if (marketInfo) {
                 validateAction<BlocsListingForm>(formRef, formState).then((res) => {
+                    if (!formState.permanceTempName) {
+                        message.error('请选择履约模板');
+                        return;
+                    }
+                    if (!friendCheck.value) {
+                        if (formState.friends.length === 0) {
+                            message.error('请选择朋友');
+                            return;
+                        }
+                    }
                     const param = {
                         AccountID: res.accountid, // 默认内部资金账号第一个
                         ClientSerialNo: uuidv4(), // 客户端流水号
@@ -243,7 +247,7 @@ export default defineComponent({
                         FixedPrice: res.FixedPrice, // 固定价格
                         PriceFactor: 1, // 价格系数(浮动价时填写)
                         PriceMove: 0, // 升贴水(浮动价时填写)
-                        TimevalidType: 4, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
+                        TimevalidType: 3, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
                         ValidTime: moment(formState.vidaliteTime).format('YYYY-MM-DD HH:mm:ss'), // 有效期限
                         ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
                         FirstRatio: 0, // 首付比例
@@ -262,7 +266,7 @@ export default defineComponent({
                         WRStandardID: props.selectedRow.wrstandardid,
                         HasWr: 0, // 无仓单挂牌  是否有无仓单
                         DeliveryMonth: moment(formState.DeliveryMonth).format('YYYY-MM-DD HH:mm:ss'),
-                        DelistMinQty: numCheck.value ? formState.delistingQty : 0, // 起摘数量
+                        DelistMinQty: formState.delistingQty, // 起摘数量
                         MarginFlag: 1, // 挂牌是否指定保证金 0:否 1:是
                         MarginAlgorithm: 1, // 指定保证金方式 1:比率 2:固定
                         MarginValue: +(formState.margin / 100), // 指定保证金设置值

+ 7 - 3
src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/delisting/index.vue

@@ -81,7 +81,8 @@
                                 :max="getMaxNum()"
                                 v-model:value="formState.num" />
                 <span class="input-enumdicname-absolute">{{selectedRow.enumdicname}}</span>
-                <div class="labelTip">({{selectedRow.minivalue}}{{selectedRow.enumdicname}}起)</div>
+                <div class="labelTip">({{selectedRow.delistminqty}}{{selectedRow.enumdicname}}起)
+                </div>
               </a-form-item>
             </a-col>
           </a-row>
@@ -178,6 +179,7 @@ import { getRules } from '@/services/bus/rules';
 import { ListingForm } from './interface';
 import { HdWRDealOrder, wrBargainApply } from '@/services/proto/warehousetrade';
 import Long from 'long';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
@@ -234,9 +236,9 @@ export default defineComponent({
             let result = 0;
             const { marginvalue } = props.selectedRow;
             if (price && num && marginvalue) {
-                result = (price * num * marginvalue) / 100;
+                result = price * num * marginvalue;
             }
-            return result ? result.toFixed(2) : '--';
+            return result ? Math.floor(2) : '--';
         }
         function getMaxNum() {
             const qty = props.selectedRow.orderqty;
@@ -292,6 +294,7 @@ export default defineComponent({
                         ApplyRemark: '',
                     };
                     requestResultLoadingAndInfo(wrBargainApply, param, loading, ['议价摘牌成功', '议价摘牌失败:']).then(() => {
+                        Bus.$emit('spotTrade', true);
                         cancel(true);
                     });
                 } else {
@@ -333,6 +336,7 @@ export default defineComponent({
 
                     requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
                         cancel(true);
+                        Bus.$emit('blocsTrade', true);
                     });
                 }
             });

+ 163 - 155
src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/post-buying/index.vue

@@ -1,150 +1,159 @@
 <template>
-    <!--仓单贸易 贸易圈挂牌 挂牌求购 -->
-    <Drawer :title="'挂牌求购'" :placement="'right'" :visible="visible" @cancel="cancel" class="top486">
-        <div class="post_buying">
-            <a-form class="inlineForm dialogForm" ref="formRef" :model="formState" :rules="rules">
-                <div class="formBar">
-                    <a-row :gutter="24">
-                        <a-col :span="24">
-                            <a-form-item label="交易账户" name="accountid">
-                                <a-select
-                                    class="inlineFormSelect"
-                                    style="width: 260px"
-                                    v-model:value="formState.accountid"
-                                    placeholder="请选择"
-                                >
-                                    <a-select-option
-                                        v-for="item in accountList"
-                                        :value="item.accountid"
-                                        :key="item.accountid"
-                                    >{{item.accountid}}</a-select-option>
-                                </a-select>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="挂牌价格" name="FixedPrice" class="inputIconBox">
-                                <a-input-number
-                                    class="commonInput"
-                                    style="width: 260px"
-                                    :min="0"
-                                    v-model:value="formState.FixedPrice"
-                                />
-                                <MinusOutlined @click="decreasePrice" />
-                                <PlusOutlined @click="increasePrice" />
-                                <a-checkbox class="commonCheckbox" v-model:checked="priceCheck">可议价</a-checkbox>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="挂牌数量" name="OrderQty" class="inputIconBox">
-                                <a-input-number
-                                    class="commonInput"
-                                    style="width: 260px"
-                                    :min="0"
-                                    v-model:value="formState.OrderQty"
-                                />
-                                <MinusOutlined @click="decreaseNumber" />
-                                <PlusOutlined @click="increaseNumber" />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                                <a-checkbox v-model:checked="numCheck" class="commonCheckbox">整单</a-checkbox>
-                            </a-form-item>
-                        </a-col>
+  <!--仓单贸易 贸易圈挂牌 挂牌求购 -->
+  <Drawer :title="'挂牌求购'"
+          :placement="'right'"
+          :visible="visible"
+          @cancel="cancel"
+          class="top486">
+    <div class="post_buying">
+      <a-form class="inlineForm dialogForm"
+              ref="formRef"
+              :model="formState"
+              :rules="rules">
+        <div class="formBar">
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="交易账户"
+                           name="accountid">
+                <a-select class="inlineFormSelect"
+                          style="width: 260px"
+                          v-model:value="formState.accountid"
+                          placeholder="请选择">
+                  <a-select-option v-for="item in accountList"
+                                   :value="item.accountid"
+                                   :key="item.accountid">{{item.accountid}}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌价格"
+                           name="FixedPrice"
+                           class="inputIconBox">
+                <a-input-number class="commonInput"
+                                style="width: 260px"
+                                :min="0"
+                                v-model:value="formState.FixedPrice" />
+                <MinusOutlined @click="decreasePrice" />
+                <PlusOutlined @click="increasePrice" />
+                <a-checkbox class="commonCheckbox"
+                            v-model:checked="priceCheck">可议价</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌数量"
+                           name="OrderQty"
+                           class="inputIconBox">
+                <a-input-number class="commonInput"
+                                style="width: 260px"
+                                :min="0"
+                                v-model:value="formState.OrderQty" />
+                <MinusOutlined @click="decreaseNumber" />
+                <PlusOutlined @click="increaseNumber" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                <a-checkbox v-model:checked="numCheck"
+                            class="commonCheckbox">整单</a-checkbox>
+              </a-form-item>
+            </a-col>
 
-                        <a-col :span="24" v-if="!numCheck">
-                            <a-form-item label="起摘数量" name="delistingQty">
-                                <a-input-number
-                                    class="commonInput"
-                                    v-model:value="formState.delistingQty"
-                                    :min="0"
-                                    style="width: 260px !important"
-                                />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="履约保证金" name="margin">
-                                <a-input-number
-                                    class="commonInput"
-                                    v-model:value="formState.margin"
-                                    :min="0"
-                                    style="width: 260px"
-                                />
-                                <span class="input-enumdicname">%</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="挂牌有效期" name="vidaliteTime" class="inputIconBox">
-                                <a-date-picker
-                                    style="width: 260px"
-                                    v-model:value="formState.vidaliteTime"
-                                    :allowClear="false"
-                                    class="commonDatePicker dialogDatePicker"
-                                />
-                            </a-form-item>
-                        </a-col>
+            <a-col :span="24"
+                   v-if="!numCheck">
+              <a-form-item label="起摘数量"
+                           name="delistingQty">
+                <a-input-number class="commonInput"
+                                v-model:value="formState.delistingQty"
+                                :min="0"
+                                style="width: 260px !important" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="履约保证金"
+                           name="margin">
+                <a-input-number class="commonInput"
+                                v-model:value="formState.margin"
+                                :min="0"
+                                style="width: 260px" />
+                <span class="input-enumdicname">%</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌有效期"
+                           name="vidaliteTime"
+                           class="inputIconBox">
+                <a-date-picker style="width: 260px"
+                               v-model:value="formState.vidaliteTime"
+                               :allowClear="false"
+                               class="commonDatePicker dialogDatePicker" />
+              </a-form-item>
+            </a-col>
 
-                        <a-col :span="24">
-                            <a-form-item label="履约方式" class="inputIconBox">
-                                <span
-                                    class="clickBox"
-                                    @click="openPermance"
-                                >{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
-                                <svg
-                                    class="icon svg-icon"
-                                    aria-hidden="true"
-                                    @click="openPermance"
-                                >
-                                    <use xlink:href="#icon-moban" />
-                                </svg>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="指定朋友" class="inputIconBox">
-                                <span
-                                    class="clickBox"
-                                    @click="openFriend"
-                                >{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
-                                <svg class="icon svg-icon" aria-hidden="true" @click="openFriend">
-                                    <use xlink:href="#icon-pengyou1" />
-                                </svg>
-                                <a-checkbox
-                                    class="commonCheckbox"
-                                    v-model:checked="friendCheck"
-                                    @change="limiteFriends"
-                                >不限</a-checkbox>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="挂牌金额">
-                                <span class="white ml8">{{getMoney()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="履约保证金">
-                                <span class="white ml8">{{getMargin()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="可用资金">
-                                <span class="white ml8">{{getCanUseMoney(getSelectedAccount())}}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                </div>
-                <a-row :gutter="24">
-                    <a-col :span="24" class="fixedBtns">
-                        <a-form-item class="btnCenter">
-                            <a-button class="listedBtn" @click="submit">买入</a-button>
-                            <a-button class="ml10 cancelBtn" @click="cancel">取消</a-button>
-                        </a-form-item>
-                    </a-col>
-                </a-row>
-            </a-form>
+            <a-col :span="24">
+              <a-form-item label="履约方式"
+                           class="inputIconBox">
+                <span class="clickBox"
+                      @click="openPermance">{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
+                <svg class="icon svg-icon"
+                     aria-hidden="true"
+                     @click="openPermance">
+                  <use xlink:href="#icon-moban" />
+                </svg>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="指定朋友"
+                           class="inputIconBox">
+                <span class="clickBox"
+                      @click="openFriend">{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
+                <svg class="icon svg-icon"
+                     aria-hidden="true"
+                     @click="openFriend">
+                  <use xlink:href="#icon-pengyou1" />
+                </svg>
+                <a-checkbox class="commonCheckbox"
+                            v-model:checked="friendCheck"
+                            @change="limiteFriends">不限</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌金额">
+                <span class="white ml8">{{getMoney()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{getMargin()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="可用资金">
+                <span class="white ml8">{{getCanUseMoney(getSelectedAccount())}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
         </div>
-    </Drawer>
-    <!-- 选择朋友 -->
-    <Friend v-if="showFriend" @cancel="chooseFriend" @update="chooseFriend" />
-    <!-- 选择履约模板 -->
-    <Permance v-if="showPermance" @cancel="choosePermance" @update="choosePermance" />
+        <a-row :gutter="24">
+          <a-col :span="24"
+                 class="fixedBtns">
+            <a-form-item class="btnCenter">
+              <a-button class="listedBtn"
+                        @click="submit">买入</a-button>
+              <a-button class="ml10 cancelBtn"
+                        @click="cancel">取消</a-button>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+  </Drawer>
+  <!-- 选择朋友 -->
+  <Friend v-if="showFriend"
+          :friends=formState.friends
+          @cancel="chooseFriend"
+          @update="chooseFriend" />
+  <!-- 选择履约模板 -->
+  <Permance v-if="showPermance"
+            @cancel="choosePermance"
+            @update="choosePermance" />
 </template>
 
 <script lang="ts">
@@ -194,20 +203,19 @@ export default defineComponent({
         // 摘牌数量
         const { numCheck, increaseNumber, decreaseNumber } = useBlocksNumber(formState);
         function submit() {
-            if (!formState.permanceTempName) {
-                message.error('请选择履约模板');
-                return;
-            }
-            if (!friendCheck.value) {
-                if (formState.friends.length === 0) {
-                    message.error('请选择朋友');
-                    return;
-                }
-            }
-
             const marketInfo = getMarketRunByTradeMode(17);
             if (marketInfo) {
                 validateAction<BlocsListingForm>(formRef, formState).then((res) => {
+                    if (!formState.permanceTempName) {
+                        message.error('请选择履约模板');
+                        return;
+                    }
+                    if (!friendCheck.value) {
+                        if (formState.friends.length === 0) {
+                            message.error('请选择朋友');
+                            return;
+                        }
+                    }
                     const param = {
                         AccountID: res.accountid, // 默认内部资金账号第一个
                         ClientSerialNo: uuidv4(), // 客户端流水号
@@ -229,7 +237,7 @@ export default defineComponent({
                         FixedPrice: res.FixedPrice, // 固定价格
                         PriceFactor: 1, // 价格系数(浮动价时填写)
                         PriceMove: 0, // 升贴水(浮动价时填写)
-                        TimevalidType: 4, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
+                        TimevalidType: 3, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
                         ValidTime: moment(formState.vidaliteTime).format('YYYY-MM-DD HH:mm:ss'), // 有效期限
                         ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
                         FirstRatio: 0, // 首付比例

+ 125 - 0
src/views/order/commodity_contract/components/commodity_contract_bargain/index.vue

@@ -0,0 +1,125 @@
+<template>
+  <!-- 商品订单 - 议价单 -->
+  <section>
+    <a-table :columns="columns"
+             class="srcollYTable expandLeftTable"
+             :scroll="{ x: '100%', y: '190px' }"
+             :pagination="false"
+             :loading="loading"
+             :expandedRowKeys="expandedRowKeys"
+             :customRow="Rowclick"
+             :expandIcon="expandIcon"
+             :expandIconAsCell="false"
+             rowKey="key"
+             :data-source="tableList">
+      <!-- 额外的展开行 -->
+      <template v-if="btnList.length"
+                #expandedRowRender="{ record }">
+        <BtnList :btnList="handleBtnList(record, btnList)"
+                 :record="record"
+                 class="btn-list-sticky"
+                 @click="openComponent" />
+      </template>
+      <template #applytime="{ text }">
+        <span>{{ formatTime(text) }}</span>
+      </template>
+      <template #buyorsell="{ text }">
+        <span>{{ getBuyOrSellName(text) }}</span>
+      </template>
+      <template #applystatus="{ text }">
+        <span>{{ getScfContractStatusName(text) }}</span>
+      </template>
+    </a-table>
+    <component :is="componentId"
+               v-if="componentId"
+               :selectedRow="selectedRow"
+               :tableList="tableList"
+               @cancel="closeComponent"></component>
+  </section>
+</template>
+
+<script lang="ts">
+import { enumOrderComponents } from '@/common/constants/enumOrderComponents';
+import { queryTableList, BtnList, defineAsyncComponent, defineComponent, ModalEnum } from '@/common/export/commonTable';
+import { getRecordItemTab } from '@/common/setup/order/orderData';
+import { handleComposeOrderTable } from '@/common/setup/table/compose';
+import { ComposeOrderTableParam } from '@/common/setup/table/interface';
+import { formatTime } from '@/common/methods';
+import { expandIcon } from '@/common/setup/table/clolumn';
+import { queryTradePosition } from '@/services/go/ermcp/order';
+import { QueryTradePositionRsp } from '@/services/go/ermcp/order/interface';
+import { handleSubcriteQuote } from '@/common/setup/table/tableQuote';
+import { findGoodsTradeModeById, getQuoteDayInfoByCode } from '@/services/bus/goods';
+import { handleDeliveryRelation } from '@/common/setup/deliveryRelation';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { BtnListType } from '@/common/components/btnList/interface';
+import { columns } from './setup';
+import { queryTjmdTransferApply } from '@/services/go/Tjmd';
+import { QueryTjmdTransferApplyReq, QueryTjmdTransferApplyRsp } from '@/services/go/Tjmd/interface';
+import Bus from '@/utils/eventBus/index';
+import { ref } from 'vue';
+import { ApplyType } from '@/common/constants/enumCommon';
+import { getBuyOrSellName, getScfContractStatusName } from '@/common/constants/enumsName';
+
+export default defineComponent({
+    name: 'commodity_contract_bargain',
+    components: {
+        BtnList,
+        // [ModalEnum.commodity_contract_summary_settlement]: defineAsyncComponent(() => import('./components/commodity_contract_summary_settlement/index.vue')),
+        // [ModalEnum.commodity_contract_summary_transfer]: defineAsyncComponent(() => import('./components/commodity_contract_summary_transfer/index.vue')),
+        // commodity_contract_summary_deal_closed: defineAsyncComponent(() => import('./components/commodity_contract_summary_deal_closed/index.vue')),
+    },
+    setup() {
+        // 类型 1-我的申请 2-对方申请
+        const margainType = ref<number>(ApplyType.my);
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<QueryTjmdTransferApplyRsp>();
+        // 交割商品
+        handleDeliveryRelation();
+        // 获取列表数据
+        const queryTableAction = (applytype: ApplyType) => {
+            const param: QueryTjmdTransferApplyReq = {
+                applytype,
+            };
+            queryTable(queryTjmdTransferApply, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeOrderTableParam = {
+            queryFn: () => queryTableAction(1),
+            recordList: getRecordItemTab(),
+        };
+        // 切换 我的申请和对方申请
+        Bus.$onOnly('bargain', (value: ApplyType) => {
+            margainType.value = value;
+            queryTableAction(value);
+        });
+        function handleBtnList(record: QueryTjmdTransferApplyRsp, btnList: BtnListType[]) {
+            if (record.applystatus === 1) {
+                if (margainType.value === ApplyType.my) {
+                    // 我的申请
+                    return btnList.filter((e) => e.code === 'commodity_contract_bargain_cancel_order');
+                } else {
+                    // 对方的申请
+                    return btnList.filter((e) => e.code !== 'commodity_contract_bargain_cancel_order');
+                }
+            } else {
+                return [];
+            }
+        }
+        return {
+            ...handleComposeOrderTable<QueryTradePositionRsp>(param),
+            columns,
+            loading,
+            tableList,
+            formatTime,
+            expandIcon,
+            handleBtnList,
+            getBuyOrSellName,
+            getScfContractStatusName,
+        };
+    },
+});
+</script>
+
+<style lang="less">
+</style>;

+ 9 - 0
src/views/order/commodity_contract/components/commodity_contract_bargain/setup.ts

@@ -0,0 +1,9 @@
+export const columns = [
+    { title: '订单合约', dataIndex: 'goodsname', key: 'goodsname', align: 'center', width: 120 },
+    { title: '方向', dataIndex: 'buyorsell', key: 'buyorsell', align: 'center', width: 120, slots: { customRender: 'buyorsell' } },
+    { title: '协议价', dataIndex: 'transferprice', key: 'transferprice', width: 120, align: 'center' },
+    { title: '数量', dataIndex: 'qty', key: 'qty', align: 'center', width: 120, slots: { customRender: 'qty' } },
+    { title: '金额', dataIndex: 'transferamount', key: 'transferamount', width: 120, align: 'center', slots: { customRender: 'transferamount' } },
+    { title: '状态', dataIndex: 'applystatus', key: 'applystatus', width: 120, align: 'center', slots: { customRender: 'applystatus' } },
+    { title: '时间', dataIndex: 'applytime', key: 'applytime', width: 120, align: 'center', slots: { customRender: 'applytime' } },
+];

+ 419 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/index.vue

@@ -0,0 +1,419 @@
+<template>
+  <!-- 协议平仓-->
+  <Drawer :title="'协议平仓'"
+          :placement="'right'"
+          class="bottom486"
+          :visible="visible"
+          @cancel="cancel">
+    <div class="listed c_c_s_s">
+      <a-form class="inlineForm dialogForm"
+              ref="formRef"
+              :model="formState"
+              :rules="rules">
+        <div class="formBar">
+          <div class="formtop">
+            <div class="firstTitle">
+              <span>合约:{{selectedRow.goodscode}}/{{selectedRow.goodsname}}</span>
+            </div>
+            <div class="secondLine">
+              <div class="left">持仓单号/方向</div>
+              <div class="middle">数量/价格/金额</div>
+              <div class="right">到期日/盈亏</div>
+            </div>
+            <!-- <a-checkbox-group class="commonCheckboxGroup"
+                              v-model:value="checked"
+                              @change="checkGroupChange">
+              <div class="lineBar"
+                   v-for="(item, index) in tableList"
+                   :key="index + '11'">
+                <div class="line1">
+                  <div class>
+                    <a-checkbox @change="checkboxChange(item)"
+                                :value="item.tradeid"></a-checkbox>
+                  </div>
+                  <div class="name">{{item.username}}</div>
+                </div>
+                <div class="line2">
+                  <div class="left">
+                    <div>{{item.wrtypename}}</div>
+                    <div>{{item.warehousename}}</div>
+                  </div>
+                  <div class="middle">
+                    <div>{{item.pricemove}}</div>
+                    <div>{{toFixed0(item.avalidqty)}}{{item.enumdicname}}</div>
+                  </div>
+                  <div class="right">
+                    <template class="inputNumberBlock"
+                              :class="isChecked(item.ladingbillid) ? '' : 'disabled'">
+                      <a-input-number class="dialogInput dialogInput34"
+                                      v-model:value="item.num"
+                                      style="width: 130px !important; height: 34px;"
+                                      :disabled="!isChecked(item.ladingbillid)"
+                                      :max="toFixed0(item.avalidqty)"
+                                      :min="0"></a-input-number>
+                      <MinusOutlined @click="decrease(item)" />
+                      <PlusOutlined @click="increase(item)" />
+                    </template>
+                  </div>
+                </div>
+              </div>
+                        </a-checkbox-group>-->
+            <a-checkbox-group class="commonCheckboxGroup"
+                              v-model:value="checked"
+                              @change="checkGroupChange">
+              <div class="lineBar"
+                   v-for="item in tableList"
+                   :key="item.tradeid">
+                <div class="line1">
+                  <div class>
+                    <a-checkbox @change="checkboxChange(item)"
+                                :value="item.tradeid"></a-checkbox>
+                  </div>
+                  <div class="name">{{item.tradeid}}</div>
+                  <div class="date">{{item.tradetime}}</div>
+                </div>
+                <div class="line2">
+                  <div class="left">{{item.buyorsell === BuyOrSell.buy ? '买入' : '卖出'}}</div>
+                  <div class="middle">
+                    <div>{{item.holderqty}}</div>
+                    <div>{{item.holderprice}}</div>
+                    <div>{{item.holderamount}}</div>
+                  </div>
+                  <div class="right red">+100</div>
+                </div>
+              </div>
+            </a-checkbox-group>
+          </div>
+        </div>
+        <div class="fixedBtns">
+          <a-row :gutter="24">
+            <a-col :span="24"
+                   class="mt12">
+              <a-form-item label="协议价"
+                           name="price"
+                           class="inputIconBox mb10 not-copy">
+                <a-input-number class="commonInput not-copy"
+                                v-model:value="formState.price"
+                                style="width: 200px"
+                                :min="0" />
+                <MinusOutlined @click="decreasePrice" />
+                <PlusOutlined @click="increasePirce" />
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="平仓金额"
+                           class="mb10 not-copy ">
+                <span class="white">50400.20</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-form-item class="btnCenter mt10">
+            <a-button class="listedBtn"
+                      :loading="loading"
+                      :disabled="loading"
+                      @click="submit">提交</a-button>
+            <a-button class="ml10 cancelBtn"
+                      @click="cancel">取消</a-button>
+          </a-form-item>
+        </div>
+      </a-form>
+    </div>
+  </Drawer>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { _closeModal } from '@/common/setup/modal/modal';
+
+import UploadImg from '@/common/components/uploadImg/index.vue';
+import { getSelectedAccountId, getUserId } from '@/services/bus/account';
+
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import Long from 'long';
+import { QueryTradePositionRsp } from '@/services/go/ermcp/order/interface';
+import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { DeliveryOrder, tradeHoldTransferApply } from '@/services/proto/warehousetrade';
+import { v4 } from 'uuid';
+import moment from 'moment';
+import { DeliveryOrderReq, TradeHoldTransferApplyReq } from '@/services/proto/warehousetrade/interface';
+import { geLoginID_number, getLoginData } from '@/services/bus/login';
+import { message } from 'ant-design-vue';
+import { getGoodsByCode } from '@/services/bus/goods';
+import { queryTableList } from '@/common/setup/table';
+import { queryTjmdTransferApply } from '@/services/go/Tjmd';
+import { QueryTjmdTransferApplyRsp } from '@/services/go/Tjmd/interface';
+import { GetLoginID } from '@/services/go/useInfo';
+import { queryTradeHolderDetail } from '@/services/go/order';
+import { QueryTradeHolderDetailReq } from '@/services/go/order/interface';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { validateAction } from '@/common/setup/form';
+import { FormState, BargainList } from './interface';
+import { handleForm, usePrice, useCheckd } from './setup';
+
+export default defineComponent({
+    name: ModalEnum.commodity_contract_summary_settlement,
+    components: { Drawer, UploadImg, PlusOutlined, MinusOutlined },
+    emits: ['cancel', 'update'],
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryTradePositionRsp>,
+            default: {},
+        },
+        buyOrSell: {
+            type: Number as PropType<BuyOrSell>,
+            default: BuyOrSell.buy,
+        },
+    },
+    setup(props, context) {
+        const { visible, cancel } = _closeModal(context);
+        const { rules, formState, formRef } = handleForm();
+        // 选中逻辑
+        const { checked, selected, checkGroupChange, checkboxChange } = useCheckd();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<BargainList>();
+        const param: QueryTradeHolderDetailReq = {
+            buyorsell: props.selectedRow.buyorsell,
+            userid: getUserId(),
+            goodsid: props.selectedRow.goodsid,
+        };
+        queryTable(queryTradeHolderDetail, param).then((res) => {
+            tableList.value = res.map((e, i) => {
+                if (i) {
+                    return { ...e, checked: false };
+                } else {
+                    // 默认勾选第一个
+                    checked.value = e.tradeid;
+                    const result = { ...e, checked: true };
+                    return result;
+                }
+            });
+        });
+
+        const toFixed0 = (value: number) => +value.toFixed(0);
+
+        function submit() {
+            validateAction<FormState>(formRef, formState).then((res) => {
+                const item = tableList.value[0];
+                const param: TradeHoldTransferApplyReq = {
+                    TradeID: Long.fromString(item.tradeid),
+                    BuyorSell: item.buyorsell,
+                    TransferPrice: res.price,
+                    ApplySrc: 2,
+                    ApplicantID: geLoginID_number()!,
+                    Remark: '',
+                };
+                requestResultLoadingAndInfo(tradeHoldTransferApply, param, loading, ['协议平仓成功', '协议平仓失败:']).then(() => {
+                    cancel(true);
+                });
+            });
+        }
+        return {
+            visible,
+            cancel,
+            submit,
+            tableList,
+            loading,
+            toFixed0,
+            rules,
+            formState,
+            formRef,
+            ...usePrice(formState),
+            checked,
+            checkGroupChange,
+            checkboxChange,
+            BuyOrSell,
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.c_c_s_s {
+    background: @m-black40;
+    width: 100%;
+    height: 100%;
+    position: relative;
+    .formBar {
+        padding: 0;
+        height: calc(100% - 170px);
+        background: @m-black41;
+        .formtop {
+            width: 100%;
+            padding: 0 20px;
+            .flex;
+            flex-direction: column;
+            .firstTitle {
+                width: calc(100% + 40px);
+                height: 40px;
+                line-height: 40px;
+                margin-left: -20px;
+                padding: 0 20px;
+                font-size: 14px;
+                color: @m-white6;
+                border-bottom: 1px solid @m-black42;
+            }
+            .secondLine {
+                width: 100%;
+                height: 40px;
+                line-height: 40px;
+                display: inline-flex;
+                > div {
+                    flex: 1;
+                    font-size: 14px;
+                    color: @m-grey1;
+                }
+                .left {
+                    text-align: left;
+                }
+                .middle {
+                    text-align: center;
+                }
+                .right {
+                    text-align: right;
+                }
+            }
+            .lineBar {
+                width: 100%;
+                min-height: 100px;
+                padding-left: 15px;
+                padding-right: 10px;
+                background: @m-blue19;
+                margin-bottom: 10px;
+                .rounded-corners(5px);
+                .line1 {
+                    display: inline-flex;
+                    user-select: none;
+                    width: 100%;
+                    height: 40px;
+                    line-height: 40px;
+                    font-size: 16px;
+                    color: @m-white6;
+                    white-space: nowrap;
+                    text-overflow: ellipsis;
+                    overflow: hidden;
+                    border-bottom: 1px solid @m-blue20;
+                    > div {
+                        align-self: center;
+                        align-items: center;
+                    }
+                    .name {
+                        margin-left: 10px;
+                    }
+                    .date {
+                        flex: 1;
+                        text-align: right;
+                        font-size: 14px;
+                        color: @m-grey1;
+                    }
+                }
+                .line2 {
+                    width: 100%;
+                    user-select: none;
+                    padding: 12px 0 14px 0;
+                    display: inline-flex;
+                    .left {
+                        width: 25%;
+                        color: @m-white6;
+                        font-size: 14px;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        line-height: 34px;
+                        // }
+                    }
+                    .middle {
+                        width: 50%;
+                        display: inline-flex;
+                        justify-content: space-between;
+                        padding: 0 10px;
+                        font-size: 16px;
+                        color: @m-white6;
+                        line-height: 34px;
+                        > div {
+                            white-space: nowrap;
+                        }
+                    }
+                    .right {
+                        width: 25%;
+                        font-size: 16px;
+                        text-align: right;
+                        line-height: 34px;
+                        white-space: nowrap;
+                    }
+                }
+            }
+        }
+    }
+    .fixedBtns {
+        padding-top: 0;
+        left: 0;
+        right: 0;
+        padding-left: 20px;
+        padding-right: 20px;
+    }
+    .formbottom {
+        width: 100%;
+        .flex;
+        flex-direction: column;
+        background: @m-black40;
+        padding: 0 18px 0 20px;
+        .line1 {
+            width: 100%;
+            padding: 0 12px 0 16px;
+            height: 36px;
+            line-height: 36px;
+            display: inline-flex;
+            justify-content: space-between;
+            color: @m-grey1;
+            font-size: 14px;
+        }
+        .line2 {
+            width: 100%;
+            height: 35px;
+            line-height: 34px;
+            padding-left: 15px;
+            padding-right: 10px;
+            background: @m-black43;
+            .rounded-corners(5px);
+            font-size: 14px;
+            color: @m-grey1;
+            display: inline-flex;
+            justify-content: space-between;
+            > div {
+                align-self: baseline;
+                align-items: baseline;
+            }
+            .right {
+                display: inline-flex;
+                color: @m-yellow6;
+                div:last-child {
+                    font-size: 16px;
+                    margin-left: 2px;
+                }
+            }
+        }
+        .line3 {
+            margin-top: 16px;
+            width: 100%;
+            height: 15px;
+            line-height: 15px;
+            font-size: 14px;
+            text-align: right;
+            color: @m-white6;
+        }
+    }
+    .inputIconBox {
+        .ant-form-item-children {
+            .anticon-plus {
+                right: 156px;
+            }
+        }
+    }
+}
+</style>;
+
+function queryTradeHolderDetail(queryTradeHolderDetail: any, param: { applytype: number; }) {
+  throw new Error('Function not implemented.');
+}

+ 10 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/interface.ts

@@ -0,0 +1,10 @@
+import { QueryTradeHolderDetailRsp } from "@/services/go/order/interface";
+
+export interface FormState {
+    price: number,
+}
+
+
+export interface BargainList extends QueryTradeHolderDetailRsp {
+    checked: boolean
+}

+ 49 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_deal_closed/setup.ts

@@ -0,0 +1,49 @@
+import { validateCommon } from "@/common/setup/validate";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { reactive, ref, UnwrapRef } from "vue";
+import { BargainList, FormState } from "./interface";
+
+export function handleForm() {
+    const formRef = ref();
+    const v_num = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入协议价');
+    };
+    const formState: UnwrapRef<FormState> = reactive({
+        price: 0,
+    })
+    const rules = {
+        price: [
+            { require, message: '请输入协议价', trigger: 'blur', type: 'number', validator: v_num },
+        ],
+    }
+    return { rules, formState, formRef }
+}
+
+export function usePrice(formState: UnwrapRef<FormState>) {
+    function increasePirce() {
+        formState.price++
+    }
+    function decreasePrice() {
+        if (formState.price) {
+            formState.price--
+        }
+    }
+    return { increasePirce, decreasePrice }
+}
+
+export function useCheckd() {
+    const checked = ref<string>();
+    const selected = ref<BargainList>()
+    function checkGroupChange(checkedValue: string[]) {
+        checked.value = checkedValue[checkedValue.length - 1];
+    }
+    function checkboxChange(item: BargainList) {
+        selected.value = item;
+    }
+    return { checked, selected, checkGroupChange, checkboxChange }
+}
+
+// 计算盈亏
+export function useProfit(item: BargainList) {
+
+}

+ 2 - 1
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_settlement/index.vue

@@ -182,7 +182,8 @@ export default defineComponent({
                 if (isBaseSpread()) {
                     param.PGoodsID = deliveryGoods.value.pgoodsid;
                 } else {
-                    param.PGoodsID = 0;
+                    // param.PGoodsID = 0;
+                    param.PQty = 0;
                 }
                 console.log('param', param);
                 DeliveryOrder(param)

+ 1 - 1
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_settlement/setup.ts

@@ -156,7 +156,7 @@ export function handleCalculation(selectedRow: QueryTradePositionRsp) {
             if (num !== '--' && price !== '--') {
                 if (deliveryGoods.value) {
                     const agreeunit = getAgreeunit(selected.value.pgoodscode)
-                    result = (+num) * (+price) * agreeunit + (selected.value.pricemove + selected.value.num)
+                    result = (Number(num) * Number(price) * agreeunit) + (selected.value.pricemove * selected.value.num)
                 }
             }
         }

+ 2 - 1
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_transfer/index.vue

@@ -1,8 +1,9 @@
 <template>
   <!-- 转让-->
   <Drawer :title="'转让'"
-          :placement="'bottom'"
+          :placement="'right'"
           :visible="visible"
+          class="delistingBottom"
           @cancel="cancel">
     <div class="listed">
       <a-form class="inlineForm dialogForm"

+ 13 - 2
src/views/order/commodity_contract/components/commodity_contract_summary/index.vue

@@ -15,7 +15,7 @@
       <!-- 额外的展开行 -->
       <template v-if="btnList.length"
                 #expandedRowRender="{ record }">
-        <BtnList :btnList="btnList"
+        <BtnList :btnList="handleBtnList(record, btnList)"
                  :record="record"
                  class="btn-list-sticky"
                  @click="openComponent" />
@@ -55,8 +55,10 @@ import { expandIcon } from '@/common/setup/table/clolumn';
 import { queryTradePosition } from '@/services/go/ermcp/order';
 import { QueryTradePositionRsp } from '@/services/go/ermcp/order/interface';
 import { handleSubcriteQuote } from '@/common/setup/table/tableQuote';
-import { getQuoteDayInfoByCode } from '@/services/bus/goods';
+import { findGoodsTradeModeById, getQuoteDayInfoByCode } from '@/services/bus/goods';
 import { handleDeliveryRelation } from '@/common/setup/deliveryRelation';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { BtnListType } from '@/common/components/btnList/interface';
 
 export default defineComponent({
     name: enumOrderComponents.commodity_contract_summary,
@@ -64,6 +66,7 @@ export default defineComponent({
         BtnList,
         [ModalEnum.commodity_contract_summary_settlement]: defineAsyncComponent(() => import('./components/commodity_contract_summary_settlement/index.vue')),
         [ModalEnum.commodity_contract_summary_transfer]: defineAsyncComponent(() => import('./components/commodity_contract_summary_transfer/index.vue')),
+        commodity_contract_summary_deal_closed: defineAsyncComponent(() => import('./components/commodity_contract_summary_deal_closed/index.vue')),
     },
     setup() {
         // 表格列表数据
@@ -121,6 +124,13 @@ export default defineComponent({
                 return price;
             }
         }
+        function handleBtnList(record: QueryTradePositionRsp, btnList: BtnListType[]) {
+            if (findGoodsTradeModeById(record.goodsid) === TradeMode.DiaoQi) {
+                return btnList.filter((e) => e.code === 'commodity_contract_summary_deal_closed');
+            } else {
+                return btnList.filter((e) => e.code !== 'commodity_contract_summary_deal_closed');
+            }
+        }
         return {
             ...handleComposeOrderTable<QueryTradePositionRsp>(param),
             loading,
@@ -130,6 +140,7 @@ export default defineComponent({
             getLastprice,
             getHolderprice,
             getProfitloss,
+            handleBtnList,
         };
     },
 });

+ 33 - 10
src/views/order/commodity_contract/index.vue

@@ -1,13 +1,22 @@
 <template>
-  <!-- 商品合约 -->
-  <section class="spot_warran">
-    <component :is="componentId"
-               v-if="componentId">
-    </component>
-    <thirdMenu :list="tabList"
-               @selectMenu="changeTab"
-               :value="'title'"></thirdMenu>
-  </section>
+    <!-- 商品合约 -->
+    <section class="spot_warran">
+        <component :is="componentId" v-if="componentId"></component>
+        <thirdMenu :list="tabList" @selectMenu="changeTab" :value="'title'">
+            <!-- 议价单 -->
+            <div class="goods-apply" v-if="componentId === BARGIN">
+                <!-- <span @click="changeBargain(ApplyType.my)">我的议价</span>
+                <span @click="changeBargain(ApplyType.counterpart)">对方议价</span>-->
+                <a-radio-group class="conditionCommonRadioGroup">
+                    <a-radio @focus="changeBargain(ApplyType.my)" :value="ApplyType.my">我的议价</a-radio>
+                    <a-radio
+                        @focus="changeBargain(ApplyType.counterpart)"
+                        :value="ApplyType.counterpart"
+                    >对方议价</a-radio>
+                </a-radio-group>
+            </div>
+        </thirdMenu>
+    </section>
 </template>
 
 <script lang="ts">
@@ -15,6 +24,10 @@ import { defineAsyncComponent, defineComponent } from 'vue';
 import { enumOrderComponents } from '@/common/constants/enumOrderComponents';
 import thirdMenu from '@/common/components/thirdMenu/index.vue';
 import { handleOrderDetailList } from '@/common/setup/order/orderData';
+import Bus from '@/utils/eventBus/index';
+import { ApplyType } from '@/common/constants/enumCommon';
+
+const BARGIN = 'commodity_contract_bargain'; // 议价单
 
 export default defineComponent({
     name: enumOrderComponents.commodity_contract,
@@ -24,12 +37,22 @@ export default defineComponent({
         [enumOrderComponents.commodity_contract_commission]: defineAsyncComponent(() => import('./components/commodity_contract_commission/index.vue')),
         [enumOrderComponents.commodity_contract_make_deal]: defineAsyncComponent(() => import('./components/commodity_contract_make_deal/index.vue')),
         [enumOrderComponents.commodity_contract_settlement]: defineAsyncComponent(() => import('./components/commodity_contract_settlement/index.vue')),
+        [BARGIN]: defineAsyncComponent(() => import('./components/commodity_contract_bargain/index.vue')),
     },
     setup() {
-        return { ...handleOrderDetailList(enumOrderComponents.commodity_contract) };
+        // 切换 我的
+        function changeBargain(value: ApplyType) {
+            Bus.$emit('bargain', value);
+        }
+        return { ...handleOrderDetailList(enumOrderComponents.commodity_contract), changeBargain, BARGIN, ApplyType };
     },
 });
 </script>
 
 <style lang="less">
+.goods-apply {
+    position: absolute;
+    bottom: 2px;
+    right: 20px;
+}
 </style>;

+ 21 - 2
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/components/bargain_detail/index.vue

@@ -23,7 +23,8 @@
         </div>
         <a-row :gutter="24"
                type="flex"
-               justify="center">
+               justify="center"
+               v-if="isShowBtn()">
           <a-col :span="24"
                  class="fixedBtns">
             <a-form-item class="btnCenter">
@@ -83,7 +84,24 @@ export default defineComponent({
             haswr: 0,
             wrtradeorderid: props.selectedRow.wrtradeorderid,
         };
-        queryTable(queryQueryWrTradeBargainApply, param);
+        // 判断是否有 待确认 状态的 数据,如果有需要显示操作按钮,没就无操作按钮
+        function isShowBtn() {
+            let result = false;
+            tableList.value.forEach((el) => {
+                if (el.applystatus === 1) {
+                    result = true;
+                }
+            });
+            return result;
+        }
+        queryTable(queryQueryWrTradeBargainApply, param).then((res) => {
+            // 时间 倒序排序
+            tableList.value = res.sort((a, b) => {
+                const time1 = new Date(a.applytime).getTime();
+                const time2 = new Date(b.applytime).getTime();
+                return time2 - time1;
+            });
+        });
         // 我对别人的 => 撤销
         // 别人对我的 => 确认、拒绝
         const { isMy, getColums } = getSpotWarrantBargainDetailColumns(props.selectedRow);
@@ -127,6 +145,7 @@ export default defineComponent({
             cancel,
             cancelAction,
             getBarmaginApplyStatus,
+            isShowBtn,
         };
     },
 });

+ 17 - 2
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/index.vue

@@ -35,6 +35,15 @@
       <template #wrtradetype="{ record }">
         <a>{{ getWrOrderTypeName(record.buyorsell, record.wrtradetype) }}</a>
       </template>
+      <template #applystatus="{ text }">
+        <span>{{ getBarmaginApplyStatus(text) }}</span>
+      </template>
+      <template #applytime="{ text }">
+        <span>{{ formatTime(text) }}</span>
+      </template>
+      <template #marginvalue="{ text }">
+        <span>{{ (text * 100).toFixed(2) }}%</span>
+      </template>
       <!-- 挂牌价格 -->
     </a-table>
     <component :is="componentId"
@@ -52,11 +61,13 @@ import { QueryWrOrderDetailReq, QueryWrTradeBargainApplyQsp, QueryWrTradeBargain
 import { getRecordItemTab } from '@/common/setup/order/orderData';
 import { handleComposeOrderTable } from '@/common/setup/table/compose';
 import { ComposeOrderTableParam } from '@/common/setup/table/interface';
-import { getWrOrderTypeName, getWrTradeOrderStatusName } from '@/common/constants/enumsName';
+import { getWrOrderTypeName, getWrTradeOrderStatusName, getBarmaginApplyStatus } from '@/common/constants/enumsName';
 import { BtnListType } from '@/common/components/btnList/interface';
 import { expandIcon } from '@/common/setup/table/clolumn';
 import { getSpotWarrantBargainColumns } from './setup';
 import { formatTime } from '@/common/methods';
+import { getUserId } from '@/services/bus/account';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     name: enumOrderComponents.pre_sale_warehouse_receipt_bargain,
@@ -70,14 +81,17 @@ export default defineComponent({
         // 获取列表数据
         const queryTableAction = () => {
             const param: QueryWrTradeBargainApplyReq = {
+                userid: getUserId(),
                 haswr: 0,
             };
             queryTable(queryQueryWrTradeBargainApply, param);
         };
+        Bus.$on('blocsTrade', () => {
+            queryTableAction();
+        });
         // 表格通用逻辑
         const param: ComposeOrderTableParam = {
             queryFn: queryTableAction,
-            tableName: 'table_pcweb_spot_trade_bottom_spot_warrant_pending_order',
             recordList: getRecordItemTab(),
         };
         const {
@@ -111,6 +125,7 @@ export default defineComponent({
             getWrOrderTypeName,
             expandIcon,
             formatTime,
+            getBarmaginApplyStatus,
         };
     },
 });

+ 4 - 0
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_bargain/setup.ts

@@ -14,6 +14,10 @@ export function getSpotWarrantBargainColumns() {
         { title: '挂牌有效期', key: 'validtime', align: 'center', width: 120 },
         { title: '履约保证金', key: 'marginvalue', align: 'center', width: 120 },
         { title: '履约方式', key: 'templatename', align: 'center', width: 160 },
+        { title: '最新议价价格', key: 'applyprice', align: 'center', width: 120 },
+        { title: '最新议价数量', key: 'applyqty', align: 'center', width: 120 },
+        { title: '最新议价时间', key: 'applytime', align: 'center', width: 160 },
+        { title: '最新议价状态', key: 'applystatus', align: 'center', width: 140 },
     ];
     return columns.map(el => {
         const slots = { customRender: el.key };

+ 276 - 281
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_order_summary/components/listed/index.vue

@@ -1,285 +1,279 @@
 <template>
-    <!-- 预售仓单 现货明细 挂牌 -->
-    <Drawer
-        :title="'挂牌'"
-        :placement="'right'"
-        class="delistingBottom650"
-        :visible="visible"
-        @cancel="cancel"
-    >
-        <div class="listed">
-            <div class="condition">
-                <a-button class="conditionBtn">{{selectedRow.deliverygoodsname}}</a-button>
-                <a-button class="conditionBtn">{{selectedRow.wrtypename}}</a-button>
-                <a-button class="conditionBtn">{{selectedRow.warehousename}}</a-button>
-            </div>
+  <!-- 预售仓单 现货明细 挂牌 -->
+  <Drawer :title="'挂牌'"
+          :placement="'right'"
+          class="delistingBottom650"
+          :visible="visible"
+          @cancel="cancel">
+    <div class="listed">
+      <div class="condition">
+        <a-button class="conditionBtn">{{selectedRow.deliverygoodsname}}</a-button>
+        <a-button class="conditionBtn">{{selectedRow.wrtypename}}</a-button>
+        <a-button class="conditionBtn">{{selectedRow.warehousename}}</a-button>
+      </div>
 
-            <a-form class="inlineForm dialogForm" ref="formRef" :model="formState" :rules="rules">
-                <div class="formBar">
-                    <a-row :gutter="24">
-                        <a-col :span="12">
-                            <a-form-item label="挂牌方式" name="WRPriceType">
-                                <a-select
-                                    class="inlineFormSelect"
-                                    default-value="1"
-                                    v-model:value="formState.WRPriceType"
-                                    style="width: 140px"
-                                >
-                                    <a-select-option :value="1">一口价</a-select-option>
-                                    <a-select-option :value="2">浮动价</a-select-option>
-                                    <a-select-option :value="3">贸易圈</a-select-option>
-                                </a-select>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isFixed()">
-                            <a-form-item label="挂牌价" name="FixedPrice">
-                                <a-input-number
-                                    class="dialogInput"
-                                    :min="0"
-                                    style="width: 140px"
-                                    v-model:value="formState.FixedPrice"
-                                    placeholder="请输入挂牌价"
-                                />
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isBlocs()">
-                            <a-form-item label="挂牌价格" name="FixedPrice" class="inputIconBox">
-                                <a-input-number
-                                    class="commonInput"
-                                    style="width: 140px"
-                                    :min="0"
-                                    v-model:value="formState.FixedPrice"
-                                />
-                                <a-checkbox class="commonCheckbox" v-model:checked="priceCheck">可议价</a-checkbox>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isFloat()">
-                            <a-form-item label="基差" name="PriceMove">
-                                <a-input-number
-                                    class="commonInput"
-                                    v-model:value="formState.PriceMove"
-                                    style="width: 140px"
-                                />
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="12">
-                            <a-form-item label="挂牌数量" name="OrderQty">
-                                <a-input-number
-                                    class="dialogInput"
-                                    style="width: 140px !important"
-                                    :min="0"
-                                    v-model:value="formState.OrderQty"
-                                    placeholder="请输入挂牌数量"
-                                />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="起摘数量" class="relative" name="DelistMinQty">
-                                <a-input-number
-                                    class="commonInput"
-                                    :min="0"
-                                    v-model:value="formState.DelistMinQty"
-                                    style="width: 140px !important"
-                                />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                                <div class="tip">最小单位:1{{selectedRow.enumdicname}}</div>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="12" class="mt-20">
-                            <a-form-item>
-                                <a-slider
-                                    v-model:value="formState.OrderQty"
-                                    ::min="0"
-                                    :max="selectedRow.enableqty"
-                                    class="formSlider"
-                                    style="width: 140px;"
-                                />
-                                <div class="unit">
-                                    <span>0</span>
-                                    <span>{{selectedRow.enableqty}}{{selectedRow.enumdicname}}</span>
-                                </div>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">&nbsp;</a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="12">
-                            <a-form-item label="交收月" name="DeliveryMonth">
-                                <a-month-picker
-                                    style="width: 140px"
-                                    v-model:value="formState.DeliveryMonth"
-                                    :allowClear="false"
-                                    class="commonDatePicker dialogDatePicker"
-                                />
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item>&nbsp;</a-form-item>
-                        </a-col>
-                    </a-row>
-                    <template v-if="isBlocs()">
-                        <a-row :gutter="24">
-                            <a-col :span="12">
-                                <a-form-item label="履约保证金" name="margin">
-                                    <a-input-number
-                                        class="commonInput"
-                                        v-model:value="formState.margin"
-                                        :min="0"
-                                        style="width: 140px"
-                                    />
-                                    <span class="input-enumdicname">%</span>
-                                </a-form-item>
-                            </a-col>
-                            <a-col :span="12">
-                                <a-form-item label="挂牌有效期" name="vidaliteTime" class="inputIconBox">
-                                    <a-date-picker
-                                        style="width: 140px"
-                                        v-model:value="formState.vidaliteTime"
-                                        :allowClear="false"
-                                        class="commonDatePicker dialogDatePicker"
-                                    />
-                                </a-form-item>
-                            </a-col>
-                        </a-row>
-                        <a-row :gutter="24">
-                            <a-col :span="12">
-                                <a-form-item label="履约方式" class="inputIconBox">
-                                    <span
-                                        class="clickBox"
-                                        style="width: 140px"
-                                        @click="openPermance"
-                                    >{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
-                                    <svg
-                                        class="icon svg-icon"
-                                        aria-hidden="true"
-                                        @click="openPermance"
-                                    >
-                                        <use xlink:href="#icon-moban" />
-                                    </svg>
-                                </a-form-item>
-                            </a-col>
-                            <a-col :span="12">
-                                <a-form-item label="指定朋友" class="inputIconBox">
-                                    <span
-                                        class="clickBox"
-                                        style="width: 140px"
-                                        @click="openFriend"
-                                    >{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
-                                    <svg
-                                        class="icon svg-icon"
-                                        aria-hidden="true"
-                                        @click="openFriend"
-                                    >
-                                        <use xlink:href="#icon-pengyou1" />
-                                    </svg>
-                                    <a-checkbox
-                                        class="commonCheckbox"
-                                        v-model:checked="friendCheck"
-                                        @change="limiteFriends"
-                                    >不限</a-checkbox>
-                                </a-form-item>
-                            </a-col>
-                        </a-row>
-                    </template>
-                    <a-row :gutter="24" v-if="isFloat()">
-                        <a-col :span="24">
-                            <a-form-item label="行情商品" name="goodsid">
-                                <!-- <a-select class="inlineFormSelect"
+      <a-form class="inlineForm dialogForm"
+              ref="formRef"
+              :model="formState"
+              :rules="rules">
+        <div class="formBar">
+          <a-row :gutter="24">
+            <a-col :span="12">
+              <a-form-item label="挂牌方式"
+                           name="WRPriceType">
+                <a-select class="inlineFormSelect"
+                          default-value="1"
+                          v-model:value="formState.WRPriceType"
+                          style="width: 140px">
+                  <a-select-option :value="1">一口价</a-select-option>
+                  <a-select-option :value="2">浮动价</a-select-option>
+                  <a-select-option :value="3">贸易圈</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isFixed()">
+              <a-form-item label="挂牌价"
+                           name="FixedPrice">
+                <a-input-number class="dialogInput"
+                                :min="0"
+                                style="width: 140px"
+                                v-model:value="formState.FixedPrice"
+                                placeholder="请输入挂牌价" />
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isBlocs()">
+              <a-form-item label="挂牌价格"
+                           name="FixedPrice"
+                           class="inputIconBox">
+                <a-input-number class="commonInput"
+                                style="width: 140px"
+                                :min="0"
+                                v-model:value="formState.FixedPrice" />
+                <a-checkbox class="commonCheckbox"
+                            v-model:checked="priceCheck">可议价</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isFloat()">
+              <a-form-item label="基差"
+                           name="PriceMove">
+                <a-input-number class="commonInput"
+                                v-model:value="formState.PriceMove"
+                                style="width: 140px" />
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="12">
+              <a-form-item label="挂牌数量"
+                           name="OrderQty">
+                <a-input-number class="dialogInput"
+                                style="width: 140px !important"
+                                :min="0"
+                                v-model:value="formState.OrderQty"
+                                placeholder="请输入挂牌数量" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                <a-checkbox class="commonCheckbox"
+                            v-if="isBlocs()"
+                            v-model:checked="numCheck">整单</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="!numCheck">
+              <a-form-item label="起摘数量"
+                           class="relative"
+                           name="DelistMinQty">
+                <a-input-number class="commonInput"
+                                :min="0"
+                                v-model:value="formState.DelistMinQty"
+                                style="width: 140px !important" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                <div class="tip">最小单位:1{{selectedRow.enumdicname}}</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="12"
+                   class="mt-20">
+              <a-form-item>
+                <a-slider v-model:value="formState.OrderQty"
+                          ::min="0"
+                          :max="selectedRow.enableqty"
+                          class="formSlider"
+                          style="width: 140px;" />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{selectedRow.enableqty}}{{selectedRow.enumdicname}}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="12">
+              <a-form-item label="交收月"
+                           name="DeliveryMonth">
+                <a-month-picker style="width: 140px"
+                                v-model:value="formState.DeliveryMonth"
+                                :allowClear="false"
+                                class="commonDatePicker dialogDatePicker" />
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item>&nbsp;</a-form-item>
+            </a-col>
+          </a-row>
+          <template v-if="isBlocs()">
+            <a-row :gutter="24">
+              <a-col :span="12">
+                <a-form-item label="履约保证金"
+                             name="margin">
+                  <a-input-number class="commonInput"
+                                  v-model:value="formState.margin"
+                                  :min="0"
+                                  style="width: 140px" />
+                  <span class="input-enumdicname">%</span>
+                </a-form-item>
+              </a-col>
+              <a-col :span="12">
+                <a-form-item label="挂牌有效期"
+                             name="vidaliteTime"
+                             class="inputIconBox">
+                  <a-date-picker style="width: 140px"
+                                 v-model:value="formState.vidaliteTime"
+                                 :allowClear="false"
+                                 class="commonDatePicker dialogDatePicker" />
+                </a-form-item>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :span="12">
+                <a-form-item label="履约方式"
+                             class="inputIconBox">
+                  <span class="clickBox"
+                        style="width: 140px"
+                        @click="openPermance">{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
+                  <svg class="icon svg-icon"
+                       aria-hidden="true"
+                       @click="openPermance">
+                    <use xlink:href="#icon-moban" />
+                  </svg>
+                </a-form-item>
+              </a-col>
+              <a-col :span="12">
+                <a-form-item label="指定朋友"
+                             class="inputIconBox">
+                  <span class="clickBox"
+                        style="width: 140px"
+                        @click="openFriend">{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
+                  <svg class="icon svg-icon"
+                       aria-hidden="true"
+                       @click="openFriend">
+                    <use xlink:href="#icon-pengyou1" />
+                  </svg>
+                  <a-checkbox class="commonCheckbox"
+                              v-model:checked="friendCheck"
+                              @change="limiteFriends">不限</a-checkbox>
+                </a-form-item>
+              </a-col>
+            </a-row>
+          </template>
+          <a-row :gutter="24"
+                 v-if="isFloat()">
+            <a-col :span="24">
+              <a-form-item label="行情商品"
+                           name="goodsid">
+                <!-- <a-select class="inlineFormSelect"
                           style="width: 135px"
                           placeholder="请择交易所">
                                 </a-select>-->
-                                <a-select
-                                    class="inlineFormSelect ml5"
-                                    @change="handleGoodsGroups"
-                                    style="width: 135px"
-                                    v-model:value="formState.goodsgroupid"
-                                    placeholder="请选择商品"
-                                >
-                                    <a-select-option
-                                        v-for="item in goodsGroup"
-                                        :value="item.goodsgroupid"
-                                        :key="item.goodsgroupid"
-                                    >{{item.goodsgroupname}}</a-select-option>
-                                </a-select>
-                                <a-select
-                                    class="inlineFormSelect ml5"
-                                    style="width: 135px"
-                                    @change="handleGoodsChange"
-                                    v-model:value="formState.goodsid"
-                                    placeholder="请选择合约"
-                                >
-                                    <a-select-option
-                                        v-for="item in goodsList"
-                                        :value="item.goodsid"
-                                        :key="item.goodsid"
-                                    >{{item.goodsname}}</a-select-option>
-                                </a-select>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="24" v-if="isFloat()" class="relative">
-                            <a-form-item :label="'估算金额'">
-                                <span class="white ml8">{{getWrMoney()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="isFixed()" class="relative">
-                            <a-form-item :label="'挂牌金额'">
-                                <span class="white ml8">{{getWrMoney()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="getWrMargin() && !isBlocs()">
-                            <a-form-item :label="getWrMargin() ? '履约保证金' : ''">
-                                <span class="white ml8">{{getWrMargin()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="isBlocs()">
-                            <a-form-item label="履约保证金">
-                                <span class="white ml8">{{getMargin()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="可用资金">
-                                <span class="white ml8">{{getCanUseMoney(handleSelectedAccount())}}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                </div>
-                <a-row :gutter="24">
-                    <a-col :span="24" class="fixedBtns">
-                        <a-form-item class="btnCenter">
-                            <a-button
-                                class="listedBtn"
-                                :loading="loading"
-                                :disabled="loading"
-                                @click="submit"
-                            >卖出</a-button>
-                            <a-button
-                                class="ml10 cancelBtn"
-                                :loading="loading"
-                                :disabled="loading"
-                                @click="cancel"
-                            >取消</a-button>
-                        </a-form-item>
-                    </a-col>
-                </a-row>
-            </a-form>
+                <a-select class="inlineFormSelect ml5"
+                          @change="handleGoodsGroups"
+                          style="width: 135px"
+                          v-model:value="formState.goodsgroupid"
+                          placeholder="请选择商品">
+                  <a-select-option v-for="item in goodsGroup"
+                                   :value="item.goodsgroupid"
+                                   :key="item.goodsgroupid">{{item.goodsgroupname}}
+                  </a-select-option>
+                </a-select>
+                <a-select class="inlineFormSelect ml5"
+                          style="width: 135px"
+                          @change="handleGoodsChange"
+                          v-model:value="formState.goodsid"
+                          placeholder="请选择合约">
+                  <a-select-option v-for="item in goodsList"
+                                   :value="item.goodsid"
+                                   :key="item.goodsid">{{item.goodsname}}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24"
+                   v-if="isFloat()"
+                   class="relative">
+              <a-form-item :label="'估算金额'">
+                <span class="white ml8">{{getWrMoney()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="isFixed()"
+                   class="relative">
+              <a-form-item :label="'挂牌金额'">
+                <span class="white ml8">{{getWrMoney()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="getWrMargin() && !isBlocs()">
+              <a-form-item :label="getWrMargin() ? '履约保证金' : ''">
+                <span class="white ml8">{{getWrMargin()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="isBlocs()">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{getMargin()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="可用资金">
+                <span class="white ml8">{{getCanUseMoney(handleSelectedAccount())}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
         </div>
-    </Drawer>
-    <!-- 选择朋友 -->
-    <Friend v-if="showFriend" :position="'bottom'" @cancel="chooseFriend" @update="chooseFriend" />
-    <!-- 选择履约模板 -->
-    <Permance
-        v-if="showPermance"
-        :position="'bottom'"
-        @cancel="choosePermance"
-        @update="choosePermance"
-    />
+        <a-row :gutter="24">
+          <a-col :span="24"
+                 class="fixedBtns">
+            <a-form-item class="btnCenter">
+              <a-button class="listedBtn"
+                        :loading="loading"
+                        :disabled="loading"
+                        @click="submit">卖出</a-button>
+              <a-button class="ml10 cancelBtn"
+                        :loading="loading"
+                        :disabled="loading"
+                        @click="cancel">取消</a-button>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+  </Drawer>
+  <!-- 选择朋友 -->
+  <Friend v-if="showFriend"
+          :friends=formState.friends
+          :position="'bottom'"
+          @cancel="chooseFriend"
+          @update="chooseFriend" />
+  <!-- 选择履约模板 -->
+  <Permance v-if="showPermance"
+            :position="'bottom'"
+            @cancel="choosePermance"
+            @update="choosePermance" />
 </template>
 
 <script lang="ts">
@@ -376,11 +370,11 @@ export default defineComponent({
                         // OperateSrc: 2,
                         ClientType: 4,
                         // MarketID: 17201,
-                        LadingBillId: props.selectedRow.ladingbillid, // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
+                        LadingBillId: props.selectedRow.ladingbillid ? props.selectedRow.ladingbillid : 0, // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
                         // LadingBillId: 'uint642081626946446000001', // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
                         TradeDate: moment(marketInfo.tradedate).format('YYYYMMDD'), // 交易日 string
                         // SubNum: '0', // 提单子单号
-                        SubNum: props.selectedRow.subnum,
+                        SubNum: props.selectedRow.subnum ? props.selectedRow.subnum : 0,
                         // WRFactorTypeId: '2121626946446000001', // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
                         WRFactorTypeId: props.selectedRow.wrfactortypeid, // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
                         IsSpecified: 0, // 是否指定对手 0:不指定 1:指定 uint32
@@ -399,8 +393,8 @@ export default defineComponent({
                         UserID: getUserId(),
                         OperatorID: getUserId(), // 操作员账号ID
                         BuyOrSell: BuyOrSell.sell, // 买卖方向 0买1卖
-                        PriceDisplayMode: priceCheck.value ? 1 : 0, // 浮动价显示方式 1:合并显示 2:分开显示
-                        CanBargain: 0, // 挂牌是否可议价0:不可1:可-摘牌是否议价
+                        PriceDisplayMode: 1, // 浮动价显示方式 1:合并显示 2:分开显示
+                        CanBargain: priceCheck.value ? 1 : 0, // 挂牌是否可议价0:不可1:可-摘牌是否议价
                         Attachment1: '', // 附件1
                         Attachment2: '', // 附件2
                         Remark: '', // 备注
@@ -426,11 +420,12 @@ export default defineComponent({
                             }
                         }
                         const obj = {
-                            IsSpecified: 1,
                             MatchAccIDs: res.friends,
                             WRPriceType: 1,
+                            TimevalidType: 3, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
                             MarginFlag: 1, // 挂牌是否指定保证金 0:否 1:是
                             MarginAlgorithm: 1, // 指定保证金方式 1:比率 2:固定
+                            ValidTime: moment(res.vidaliteTime).format('YYYY-MM-DD HH:mm:ss'), // 有效期限
                             MarginValue: +(formState.margin / 100).toFixed(2), // 指定保证金设置值
                             AllFriendsFlag: friendCheck.value ? 1 : 0, //是否全好友可见 0:否 1:是
                         };

+ 121 - 0
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_pending_order/components/detail/index.vue

@@ -0,0 +1,121 @@
+<template>
+  <!-- 现货仓单 挂单 详情 -->
+  <Drawer :title="'详情'"
+          :placement="'right'"
+          :visible="visible"
+          class="bottom486"
+          @cancel="cancel">
+    <div class="detailCont">
+      <div class="rows">
+        <div class="row"
+             v-for="item in lstitem"
+             :key="item.name">
+          <div class="left">{{item.name}}</div>
+          <div class="right">{{item.value}}</div>
+        </div>
+      </div>
+      <div class="ruleTitle">履约规则:</div>
+      <div class="rulesCont">
+        <a-row>
+          <a-col :span="24"
+                 class="ruleCol">
+            <div class="line"
+                 v-for="item in lststep"
+                 :key="item.autoid">
+              <!-- <div class="no">{{index + 1}}</div> -->
+              <div class="name">{{item.steptypename}}</div>
+              <div class="time">{{item.stepdate}}</div>
+            </div>
+          </a-col>
+        </a-row>
+      </div>
+    </div>
+  </Drawer>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { QueryWrGoodsInfoReq, WrGoodsPerformanceStep, WrOrderDetail, WrOrderQuote, WrTypeItem } from '@/services/go/wrtrade/interface';
+import { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryWrGoodsInfo } from '@/services/go/wrtrade';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+
+export default defineComponent({
+    name: ModalEnum.spot_trade_warehouse_delisting,
+    components: { Drawer },
+    emits: ['cancel', 'update'],
+    props: {
+        selectedRow: {
+            type: Object as PropType<WrOrderDetail>,
+            default: {},
+        },
+    },
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+        const lstitem = ref<WrTypeItem[]>();
+        const lststep = ref<WrGoodsPerformanceStep[]>();
+        const param: QueryWrGoodsInfoReq = {
+            haswr: 0,
+            wrfactortypeid: props.selectedRow.wrfactortypeid,
+        };
+        queryResultLoadingAndInfo(queryWrGoodsInfo, loading, param).then((res) => {
+            if (res.length) {
+                lstitem.value = res[0].lstitem;
+                lststep.value = res[0].lststep;
+            }
+        });
+
+        return {
+            lstitem,
+            lststep,
+            visible,
+            cancel,
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.detailCont {
+    padding: 10px;
+    .rows {
+        .flex;
+        flex-direction: column;
+        width: 100%;
+        border: 1px solid @m-black6;
+        background: @m-black13;
+        .row {
+            display: inline-flex;
+            width: 100%;
+            height: 38px;
+            line-height: 38px;
+            border-bottom: 1px solid @m-black6;
+            > div {
+                text-align: center;
+                font-size: 16px;
+            }
+            .left {
+                width: 126px;
+                color: @m-grey1;
+                border-right: 1px solid @m-black6;
+            }
+            .right {
+                flex: 1;
+                color: @m-white11;
+            }
+        }
+    }
+    .ruleTitle {
+        width: 100%;
+        height: 30px;
+        line-height: 30px;
+        margin-top: 10px;
+        font-size: 16px;
+        color: @m-grey1;
+    }
+}
+</style>

+ 7 - 1
src/views/order/pre_sale_warehouse_receipt/components/pre_sale_warehouse_receipt_pending_order/index.vue

@@ -44,12 +44,14 @@ import { ComposeOrderTableParam } from '@/common/setup/table/interface';
 import { getWrOrderTypeName, getOrderStatusName } from '@/common/constants/enumsName';
 import { BtnListType } from '@/common/components/btnList/interface';
 import { expandIcon } from '@/common/setup/table/clolumn';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     name: enumOrderComponents.pre_sale_warehouse_receipt_pending_order,
     components: {
         BtnList,
         [ModalEnum.pre_sale_warehouse_receipt_pending_order_cancel_order]: defineAsyncComponent(() => import('./components/cancle/index.vue')),
+        detail: defineAsyncComponent(() => import('./components/detail/index.vue')),
     },
     setup() {
         // 表格列表数据
@@ -61,15 +63,19 @@ export default defineComponent({
             };
             queryTable(queryWrOrderDetail, param);
         };
+        Bus.$on('blocsTrade', () => {
+            queryTableAction();
+        });
         // 表格通用逻辑
         const param: ComposeOrderTableParam = {
             queryFn: queryTableAction,
             tableName: 'table_pcweb_spot_trade_bottom_pre_sale_pending_order',
             recordList: getRecordItemTab(),
+            isDetail: true,
         };
         function filterBtnList(list: BtnListType[], record: WrOrderDetail) {
             //委托状态 - 1:委托请求 2:待冻结 3:委托成功 4:委托失败 5:配对成功 6:已撤 7:已成 8:成交失败 9:委托拒绝 1number;
-            const arr = [3, 10];
+            const arr = [3, 7];
             if (!arr.includes(record.wrtradeorderstatus)) {
                 return list.filter((e) => e.code !== ModalEnum.pre_sale_warehouse_receipt_pending_order_cancel_order);
             } else {

+ 19 - 1
src/views/order/spot_warran/components/spot_warrant_bargain/components/bargain_detail/index.vue

@@ -23,6 +23,7 @@
         </div>
         <a-row :gutter="24"
                type="flex"
+               v-if="isShowBtn()"
                justify="center">
           <a-col :span="24"
                  class="fixedBtns">
@@ -83,7 +84,23 @@ export default defineComponent({
             haswr: 1,
             wrtradeorderid: props.selectedRow.wrtradeorderid,
         };
-        queryTable(queryQueryWrTradeBargainApply, param);
+        queryTable(queryQueryWrTradeBargainApply, param).then((res) => {
+            // 时间 倒序排序
+            tableList.value = res.sort((a, b) => {
+                const time1 = new Date(a.applytime).getTime();
+                const time2 = new Date(b.applytime).getTime();
+                return time2 - time1;
+            });
+        });
+        function isShowBtn() {
+            let result = false;
+            tableList.value.forEach((el) => {
+                if (el.applystatus === 1) {
+                    result = true;
+                }
+            });
+            return result;
+        }
         // 我对别人的 => 撤销
         // 别人对我的 => 确认、拒绝
         const { isMy, getColums } = getSpotWarrantBargainDetailColumns(props.selectedRow);
@@ -127,6 +144,7 @@ export default defineComponent({
             cancelAction,
             cancel,
             getBarmaginApplyStatus,
+            isShowBtn,
         };
     },
 });

+ 19 - 3
src/views/order/spot_warran/components/spot_warrant_bargain/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <!-- 现货仓单 挂单 -->
+  <!-- 现货仓单 议价 -->
   <section>
     <a-table :columns="columns"
              class="srcollYTable expandLeftTable"
@@ -27,6 +27,9 @@
       <template #buyorsell="{ text }">
         <span>{{ text ? '买' : '卖' }}</span>
       </template>
+      <template #marginvalue="{ text }">
+        <span>{{ (text * 100).toFixed(2) }}%</span>
+      </template>
       <!--  委托状态-->
       <!-- <template #wrtradeorderstatus="{ record }">
         <a>{{ getWrTradeOrderStatusName(record.wrtradeorderstatus) }}</a>
@@ -35,6 +38,12 @@
       <template #wrtradetype="{ record }">
         <a>{{ getWrOrderTypeName(record.buyorsell, record.wrtradetype) }}</a>
       </template>
+      <template #applystatus="{ text }">
+        <span>{{ getBarmaginApplyStatus(text) }}</span>
+      </template>
+      <template #applytime="{ text }">
+        <span>{{ formatTime(text) }}</span>
+      </template>
       <!-- 挂牌价格 -->
     </a-table>
     <component :is="componentId"
@@ -52,11 +61,13 @@ import { QueryWrOrderDetailReq, QueryWrTradeBargainApplyQsp, QueryWrTradeBargain
 import { getRecordItemTab } from '@/common/setup/order/orderData';
 import { handleComposeOrderTable } from '@/common/setup/table/compose';
 import { ComposeOrderTableParam } from '@/common/setup/table/interface';
-import { getWrOrderTypeName, getWrTradeOrderStatusName } from '@/common/constants/enumsName';
+import { getWrOrderTypeName, getWrTradeOrderStatusName, getBarmaginApplyStatus } from '@/common/constants/enumsName';
 import { BtnListType } from '@/common/components/btnList/interface';
 import { expandIcon } from '@/common/setup/table/clolumn';
 import { getSpotWarrantBargainColumns } from './setup';
 import { formatTime } from '@/common/methods';
+import { getUserId } from '@/services/bus/account';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     name: enumOrderComponents.spot_warrant_pending_order,
@@ -70,14 +81,18 @@ export default defineComponent({
         // 获取列表数据
         const queryTableAction = () => {
             const param: QueryWrTradeBargainApplyReq = {
+                userid: getUserId(),
                 haswr: 1,
             };
             queryTable(queryQueryWrTradeBargainApply, param);
         };
+        Bus.$on('blocsTrade', () => {
+            queryTableAction();
+        });
+
         // 表格通用逻辑
         const param: ComposeOrderTableParam = {
             queryFn: queryTableAction,
-            tableName: 'table_pcweb_spot_trade_bottom_spot_warrant_pending_order',
             recordList: getRecordItemTab(),
         };
         const {
@@ -111,6 +126,7 @@ export default defineComponent({
             getWrOrderTypeName,
             expandIcon,
             formatTime,
+            getBarmaginApplyStatus,
         };
     },
 });

+ 4 - 0
src/views/order/spot_warran/components/spot_warrant_bargain/setup.ts

@@ -14,6 +14,10 @@ export function getSpotWarrantBargainColumns() {
         { title: '挂牌有效期', key: 'validtime', align: 'center', width: 120 },
         { title: '履约保证金', key: 'marginvalue', align: 'center', width: 120 },
         { title: '履约方式', key: 'templatename', align: 'center', width: 160 },
+        { title: '最新议价价格', key: 'applyprice', align: 'center', width: 120 },
+        { title: '最新议价数量', key: 'applyqty', align: 'center', width: 120 },
+        { title: '最新议价时间', key: 'applytime', align: 'center', width: 160 },
+        { title: '最新议价状态', key: 'applystatus', align: 'center', width: 140 },
     ];
     return columns.map(el => {
         const slots = { customRender: el.key };

+ 13 - 13
src/views/order/spot_warran/components/spot_warrant_in_and_out_warehouse/components/cancel/index.vue

@@ -7,14 +7,14 @@
 <script lang="ts">
 import { defineComponent, PropType, ref } from 'vue';
 import Drawer from '@/common/components/drawer/index.vue';
-import { WrFinanceBuyApply } from '@/services/go/wrtrade/interface';
+import { WrFinanceBuyApply, WrOutInApply } from '@/services/go/wrtrade/interface';
 import { ModalEnum } from '@/common/constants/modalNameEnum';
 import { _closeModal } from '@/common/setup/modal/modal';
 import { Modal } from 'ant-design-vue';
-import { WRTradeFinanceBuyCancel } from '@/services/proto/warehousetrade';
+import { WROutCancel } from '@/services/proto/warehousetrade';
+import { WROutCancelReq } from '@/services/proto/warehousetrade/interface';
 import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
-import { WRTradeFinanceBuyCancelReq } from '@/services/proto/warehousetrade/interface';
-import { getSelectedAccountId } from '@/services/bus/account';
+import { getSelectedAccountId, getUserId } from '@/services/bus/account';
 import { v4 as uuidv4 } from 'uuid';
 import Long from 'long';
 
@@ -24,7 +24,7 @@ export default defineComponent({
     emits: ['cancel', 'update'],
     props: {
         selectedRow: {
-            type: Object as PropType<WrFinanceBuyApply>,
+            type: Object as PropType<WrOutInApply>,
             default: {},
         },
     },
@@ -39,14 +39,14 @@ export default defineComponent({
         });
         function submit() {
             // 挂牌撤单请求
-            // const paramReq: WRTradeFinanceBuyCancelReq = {
-            //     AccountID: getSelectedAccountId(), // uint64 资金账号
-            //     FinanceApplyID : Long.fromString(props.selectedRow.financeapplyid), // uint64 融资申请单ID
-            //     ClientSerialNo: uuidv4(), // 客户端流水号 // string 客户端流水号
-            // };
-            // requestResultLoadingAndInfo(WRTradeFinanceBuyCancel, paramReq, loading, ['撤销成功', '撤销失败:']).then(() => {
-            //     cancel(true);
-            // });
+            const paramReq: WROutCancelReq = {
+                applyid: Long.fromString(props.selectedRow.applyid),
+                operatesrc: 2,
+                ooperateid: getUserId(),
+            };
+            requestResultLoadingAndInfo(WROutCancel, paramReq, loading, ['撤销成功', '撤销失败:']).then(() => {
+                cancel(true);
+            });
         }
         return {
             visible,

+ 13 - 13
src/views/order/spot_warran/components/spot_warrant_in_and_out_warehouse/components/pick_up/index.vue

@@ -7,16 +7,16 @@
 <script lang="ts">
 import { defineComponent, PropType, ref } from 'vue';
 import Drawer from '@/common/components/drawer/index.vue';
-import { WrFinanceBuyApply } from '@/services/go/wrtrade/interface';
+import { WrFinanceBuyApply, WrOutInApply } from '@/services/go/wrtrade/interface';
 import { ModalEnum } from '@/common/constants/modalNameEnum';
 import { _closeModal } from '@/common/setup/modal/modal';
 import { Modal } from 'ant-design-vue';
-import { WRTradeFinanceBuyCancel } from '@/services/proto/warehousetrade';
 import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
-import { WRTradeFinanceBuyCancelReq } from '@/services/proto/warehousetrade/interface';
-import { getSelectedAccountId } from '@/services/bus/account';
+import { WROutConfirmReq, WRTradeFinanceBuyCancelReq } from '@/services/proto/warehousetrade/interface';
+import { getUserId } from '@/services/bus/account';
 import { v4 as uuidv4 } from 'uuid';
 import Long from 'long';
+import { WROutConfirm } from '@/services/proto/warehousetrade';
 
 export default defineComponent({
     name: ModalEnum.financing_manager_apply_cancel,
@@ -24,7 +24,7 @@ export default defineComponent({
     emits: ['cancel', 'update'],
     props: {
         selectedRow: {
-            type: Object as PropType<WrFinanceBuyApply>,
+            type: Object as PropType<WrOutInApply>,
             default: {},
         },
     },
@@ -39,14 +39,14 @@ export default defineComponent({
         });
         function submit() {
             // 挂牌撤单请求
-            // const paramReq: WRTradeFinanceBuyCancelReq = {
-            //     AccountID: getSelectedAccountId(), // uint64 资金账号
-            //     FinanceApplyID : Long.fromString(props.selectedRow.financeapplyid), // uint64 融资申请单ID
-            //     ClientSerialNo: uuidv4(), // 客户端流水号 // string 客户端流水号
-            // };
-            // requestResultLoadingAndInfo(WRTradeFinanceBuyCancel, paramReq, loading, ['撤销成功', '撤销失败:']).then(() => {
-            //     cancel(true);
-            // });
+            const paramReq: WROutConfirmReq = {
+                applyid: Long.fromString(props.selectedRow.applyid),
+                operatesrc: 2,
+                operateid: getUserId(),
+            };
+            requestResultLoadingAndInfo(WROutConfirm, paramReq, loading, ['提货成功', '提货失败:']).then(() => {
+                cancel(true);
+            });
         }
         return {
             visible,

+ 121 - 0
src/views/order/spot_warran/components/spot_warrant_pending_order/components/detail/index.vue

@@ -0,0 +1,121 @@
+<template>
+  <!-- 现货仓单 挂单 详情 -->
+  <Drawer :title="'详情'"
+          :placement="'right'"
+          :visible="visible"
+          class="bottom486"
+          @cancel="cancel">
+    <div class="detailCont">
+      <div class="rows">
+        <div class="row"
+             v-for="item in lstitem"
+             :key="item.name">
+          <div class="left">{{item.name}}</div>
+          <div class="right">{{item.value}}</div>
+        </div>
+      </div>
+      <div class="ruleTitle">履约规则:</div>
+      <div class="rulesCont">
+        <a-row>
+          <a-col :span="24"
+                 class="ruleCol">
+            <div class="line"
+                 v-for="item in lststep"
+                 :key="item.autoid">
+              <!-- <div class="no">{{index + 1}}</div> -->
+              <div class="name">{{item.steptypename}}</div>
+              <div class="time">{{item.stepdate}}</div>
+            </div>
+          </a-col>
+        </a-row>
+      </div>
+    </div>
+  </Drawer>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { QueryWrGoodsInfoReq, WrGoodsPerformanceStep, WrOrderDetail, WrOrderQuote, WrTypeItem } from '@/services/go/wrtrade/interface';
+import { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryWrGoodsInfo } from '@/services/go/wrtrade';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+
+export default defineComponent({
+    name: ModalEnum.spot_trade_warehouse_delisting,
+    components: { Drawer },
+    emits: ['cancel', 'update'],
+    props: {
+        selectedRow: {
+            type: Object as PropType<WrOrderDetail>,
+            default: {},
+        },
+    },
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+        const lstitem = ref<WrTypeItem[]>();
+        const lststep = ref<WrGoodsPerformanceStep[]>();
+        const param: QueryWrGoodsInfoReq = {
+            haswr: 1,
+            wrfactortypeid: props.selectedRow.wrfactortypeid,
+        };
+        queryResultLoadingAndInfo(queryWrGoodsInfo, loading, param).then((res) => {
+            if (res.length) {
+                lstitem.value = res[0].lstitem;
+                lststep.value = res[0].lststep;
+            }
+        });
+
+        return {
+            lstitem,
+            lststep,
+            visible,
+            cancel,
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.detailCont {
+    padding: 10px;
+    .rows {
+        .flex;
+        flex-direction: column;
+        width: 100%;
+        border: 1px solid @m-black6;
+        background: @m-black13;
+        .row {
+            display: inline-flex;
+            width: 100%;
+            height: 38px;
+            line-height: 38px;
+            border-bottom: 1px solid @m-black6;
+            > div {
+                text-align: center;
+                font-size: 16px;
+            }
+            .left {
+                width: 126px;
+                color: @m-grey1;
+                border-right: 1px solid @m-black6;
+            }
+            .right {
+                flex: 1;
+                color: @m-white11;
+            }
+        }
+    }
+    .ruleTitle {
+        width: 100%;
+        height: 30px;
+        line-height: 30px;
+        margin-top: 10px;
+        font-size: 16px;
+        color: @m-grey1;
+    }
+}
+</style>

+ 7 - 1
src/views/order/spot_warran/components/spot_warrant_pending_order/index.vue

@@ -47,12 +47,14 @@ import { ComposeOrderTableParam } from '@/common/setup/table/interface';
 import { getWrOrderTypeName, getOrderStatusName } from '@/common/constants/enumsName';
 import { BtnListType } from '@/common/components/btnList/interface';
 import { expandIcon } from '@/common/setup/table/clolumn';
+import Bus from '@/utils/eventBus';
 
 export default defineComponent({
     name: enumOrderComponents.spot_warrant_pending_order,
     components: {
         BtnList,
         [ModalEnum.spot_warrant_pending_order_cancel_order]: defineAsyncComponent(() => import('./components/cancle/index.vue')),
+        detail: defineAsyncComponent(() => import('./components/detail/index.vue')),
     },
     setup() {
         // 表格列表数据
@@ -64,15 +66,19 @@ export default defineComponent({
             };
             queryTable(queryWrOrderDetail, param);
         };
+        Bus.$on('blocsTrade', () => {
+            queryTableAction();
+        });
         // 表格通用逻辑
         const param: ComposeOrderTableParam = {
             queryFn: queryTableAction,
             tableName: 'table_pcweb_spot_trade_bottom_spot_warrant_pending_order',
             recordList: getRecordItemTab(),
+            isDetail: true,
         };
         function filterBtnList(list: BtnListType[], record: WrOrderDetail) {
             //委托状态 - 1:委托请求 2:待冻结 3:委托成功 4:委托失败 5:配对成功 6:已撤 7:已成 8:成交失败 9:委托拒绝 1number;
-            const arr = [3, 10];
+            const arr = [3, 7];
             if (!arr.includes(record.wrtradeorderstatus)) {
                 return list.filter((e) => e.code !== ModalEnum.spot_warrant_pending_order_cancel_order);
             } else {

+ 260 - 264
src/views/order/spot_warran/components/spot_warrant_spot_details/components/listing/index.vue

@@ -1,272 +1,266 @@
 <template>
-    <!-- 现货仓单 现货明细 挂牌 -->
-    <Drawer
-        :title="'挂牌'"
-        :placement="'right'"
-        class="delistingBottom650"
-        :visible="visible"
-        @cancel="cancel"
-    >
-        <div class="listing">
-            <div class="condition">
-                <a-button class="conditionBtn">{{selectedRow.deliverygoodsname}}</a-button>
-                <a-button class="conditionBtn">{{selectedRow.wrtypename}}</a-button>
-                <a-button class="conditionBtn">{{selectedRow.warehousename}}</a-button>
-            </div>
+  <!-- 现货仓单 现货明细 挂牌 -->
+  <Drawer :title="'挂牌'"
+          :placement="'right'"
+          class="delistingBottom650"
+          :visible="visible"
+          @cancel="cancel">
+    <div class="listing">
+      <div class="condition">
+        <a-button class="conditionBtn">{{selectedRow.deliverygoodsname}}</a-button>
+        <a-button class="conditionBtn">{{selectedRow.wrtypename}}</a-button>
+        <a-button class="conditionBtn">{{selectedRow.warehousename}}</a-button>
+      </div>
 
-            <a-form class="inlineForm dialogForm" ref="formRef" :model="formState" :rules="rules">
-                <div class="formBar">
-                    <a-row :gutter="24">
-                        <a-col :span="12">
-                            <a-form-item label="挂牌方式" name="WRPriceType">
-                                <a-select
-                                    class="inlineFormSelect"
-                                    default-value="1"
-                                    v-model:value="formState.WRPriceType"
-                                    style="width: 140px"
-                                >
-                                    <a-select-option :value="1">一口价</a-select-option>
-                                    <a-select-option :value="2">浮动价</a-select-option>
-                                    <a-select-option :value="3">贸易圈</a-select-option>
-                                </a-select>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isFixed()">
-                            <a-form-item label="挂牌价" name="FixedPrice">
-                                <a-input-number
-                                    class="dialogInput"
-                                    :min="0"
-                                    style="width: 140px"
-                                    v-model:value="formState.FixedPrice"
-                                    placeholder="请输入挂牌价"
-                                />
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isBlocs()">
-                            <a-form-item label="挂牌价格" name="FixedPrice" class="inputIconBox">
-                                <a-input-number
-                                    class="commonInput"
-                                    style="width: 140px"
-                                    :min="0"
-                                    v-model:value="formState.FixedPrice"
-                                />
-                                <a-checkbox class="commonCheckbox" v-model:checked="priceCheck">可议价</a-checkbox>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12" v-if="isFloat()">
-                            <a-form-item label="基差" name="PriceMove">
-                                <a-input-number
-                                    class="commonInput"
-                                    v-model:value="formState.PriceMove"
-                                    style="width: 140px"
-                                />
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="12">
-                            <a-form-item label="挂牌数量" name="OrderQty">
-                                <a-input-number
-                                    class="dialogInput"
-                                    style="width: 140px !important"
-                                    :min="0"
-                                    v-model:value="formState.OrderQty"
-                                    placeholder="请输入挂牌数量"
-                                />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="起摘数量" class="relative" name="DelistMinQty">
-                                <a-input-number
-                                    class="commonInput"
-                                    :min="0"
-                                    v-model:value="formState.DelistMinQty"
-                                    style="width: 140px !important"
-                                />
-                                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
-                                <div
-                                    class="tip"
-                                >最小单位:{{selectedRow.minivalue}}{{selectedRow.enumdicname}}</div>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="12" class="mt-20">
-                            <a-form-item>
-                                <a-slider
-                                    v-model:value="formState.OrderQty"
-                                    ::min="0"
-                                    :max="selectedRow.enableqty"
-                                    class="formSlider"
-                                    style="width: 140px;"
-                                />
-                                <div class="unit">
-                                    <span>0</span>
-                                    <span>{{selectedRow.enableqty}}{{selectedRow.enumdicname}}</span>
-                                </div>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">&nbsp;</a-col>
-                    </a-row>
-                    <template v-if="isBlocs()">
-                        <a-row :gutter="24">
-                            <a-col :span="12">
-                                <a-form-item label="履约保证金" name="margin">
-                                    <a-input-number
-                                        class="commonInput"
-                                        v-model:value="formState.margin"
-                                        :min="0"
-                                        style="width: 140px"
-                                    />
-                                    <span class="input-enumdicname">%</span>
-                                </a-form-item>
-                            </a-col>
-                            <a-col :span="12">
-                                <a-form-item label="挂牌有效期" name="vidaliteTime" class="inputIconBox">
-                                    <a-date-picker
-                                        style="width: 140px"
-                                        v-model:value="formState.vidaliteTime"
-                                        :allowClear="false"
-                                        class="commonDatePicker dialogDatePicker"
-                                    />
-                                </a-form-item>
-                            </a-col>
-                        </a-row>
-                        <a-row :gutter="24">
-                            <a-col :span="12">
-                                <a-form-item label="履约方式" class="inputIconBox">
-                                    <span
-                                        class="clickBox"
-                                        style="width: 140px"
-                                        @click="openPermance"
-                                    >{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
-                                    <svg
-                                        class="icon svg-icon"
-                                        aria-hidden="true"
-                                        @click="openPermance"
-                                    >
-                                        <use xlink:href="#icon-moban" />
-                                    </svg>
-                                </a-form-item>
-                            </a-col>
-                            <a-col :span="12">
-                                <a-form-item label="指定朋友" class="inputIconBox">
-                                    <span
-                                        class="clickBox"
-                                        style="width: 140px"
-                                        @click="openFriend"
-                                    >{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
-                                    <svg
-                                        class="icon svg-icon"
-                                        aria-hidden="true"
-                                        @click="openFriend"
-                                    >
-                                        <use xlink:href="#icon-pengyou1" />
-                                    </svg>
-                                    <a-checkbox
-                                        class="commonCheckbox"
-                                        v-model:checked="friendCheck"
-                                        @change="limiteFriends"
-                                    >不限</a-checkbox>
-                                </a-form-item>
-                            </a-col>
-                        </a-row>
-                    </template>
-                    <a-row :gutter="24" v-if="isFloat()">
-                        <a-col :span="24">
-                            <a-form-item label="行情商品" name="goodsid">
-                                <!-- <a-select class="inlineFormSelect"
+      <a-form class="inlineForm dialogForm"
+              ref="formRef"
+              :model="formState"
+              :rules="rules">
+        <div class="formBar">
+          <a-row :gutter="24">
+            <a-col :span="12">
+              <a-form-item label="挂牌方式"
+                           name="WRPriceType">
+                <a-select class="inlineFormSelect"
+                          default-value="1"
+                          v-model:value="formState.WRPriceType"
+                          style="width: 140px">
+                  <a-select-option :value="1">一口价</a-select-option>
+                  <a-select-option :value="2">浮动价</a-select-option>
+                  <a-select-option :value="3">贸易圈</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isFixed()">
+              <a-form-item label="挂牌价"
+                           name="FixedPrice">
+                <a-input-number class="dialogInput"
+                                :min="0"
+                                style="width: 140px"
+                                v-model:value="formState.FixedPrice"
+                                placeholder="请输入挂牌价" />
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isBlocs()">
+              <a-form-item label="挂牌价格"
+                           name="FixedPrice"
+                           class="inputIconBox">
+                <a-input-number class="commonInput"
+                                style="width: 140px"
+                                :min="0"
+                                v-model:value="formState.FixedPrice" />
+                <a-checkbox class="commonCheckbox"
+                            v-model:checked="priceCheck">可议价</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="isFloat()">
+              <a-form-item label="基差"
+                           name="PriceMove">
+                <a-input-number class="commonInput"
+                                v-model:value="formState.PriceMove"
+                                style="width: 140px" />
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="12">
+              <a-form-item label="挂牌数量"
+                           class="inputIconBox"
+                           name="OrderQty">
+                <a-input-number class="dialogInput"
+                                style="width: 140px !important"
+                                :min="0"
+                                v-model:value="formState.OrderQty"
+                                placeholder="请输入挂牌数量" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                <a-checkbox class="commonCheckbox"
+                            v-if="isBlocs()"
+                            v-model:checked="numCheck">整单</a-checkbox>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12"
+                   v-if="!numCheck">
+              <a-form-item label="起摘数量"
+                           class="relative"
+                           name="DelistMinQty">
+                <a-input-number class="commonInput"
+                                :min="0"
+                                v-model:value="formState.DelistMinQty"
+                                style="width: 140px !important" />
+                <span class="input-enumdicname">{{selectedRow.enumdicname}}</span>
+                <div class="tip">最小单位:{{selectedRow.minivalue}}{{selectedRow.enumdicname}}</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="12"
+                   class="mt-20">
+              <a-form-item>
+                <a-slider v-model:value="formState.OrderQty"
+                          ::min="0"
+                          :max="selectedRow.enableqty"
+                          class="formSlider"
+                          style="width: 140px;" />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{selectedRow.enableqty}}{{selectedRow.enumdicname}}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <template v-if="isBlocs()">
+            <a-row :gutter="24">
+              <a-col :span="12">
+                <a-form-item label="履约保证金"
+                             name="margin">
+                  <a-input-number class="commonInput"
+                                  v-model:value="formState.margin"
+                                  :min="0"
+                                  style="width: 140px" />
+                  <span class="input-enumdicname">%</span>
+                </a-form-item>
+              </a-col>
+              <a-col :span="12">
+                <a-form-item label="挂牌有效期"
+                             name="vidaliteTime"
+                             class="inputIconBox">
+                  <a-date-picker style="width: 140px"
+                                 v-model:value="formState.vidaliteTime"
+                                 :allowClear="false"
+                                 class="commonDatePicker dialogDatePicker" />
+                </a-form-item>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :span="12">
+                <a-form-item label="履约方式"
+                             class="inputIconBox">
+                  <span class="clickBox"
+                        style="width: 140px"
+                        @click="openPermance">{{formState.permanceTempName ? formState.permanceTempName : '选择履约模板'}}</span>
+                  <svg class="icon svg-icon"
+                       aria-hidden="true"
+                       @click="openPermance">
+                    <use xlink:href="#icon-moban" />
+                  </svg>
+                </a-form-item>
+              </a-col>
+              <a-col :span="12">
+                <a-form-item label="指定朋友"
+                             class="inputIconBox">
+                  <span class="clickBox"
+                        style="width: 140px"
+                        @click="openFriend">{{getFriendLength() ? `已选${getFriendLength() }人` : '选择朋友'}}</span>
+                  <svg class="icon svg-icon"
+                       aria-hidden="true"
+                       @click="openFriend">
+                    <use xlink:href="#icon-pengyou1" />
+                  </svg>
+                  <a-checkbox class="commonCheckbox"
+                              v-model:checked="friendCheck"
+                              @change="limiteFriends">不限</a-checkbox>
+                </a-form-item>
+              </a-col>
+            </a-row>
+          </template>
+          <a-row :gutter="24"
+                 v-if="isFloat()">
+            <a-col :span="24">
+              <a-form-item label="行情商品"
+                           name="goodsid">
+                <!-- <a-select class="inlineFormSelect"
                           style="width: 135px"
                           placeholder="请择交易所">
                                 </a-select>-->
-                                <a-select
-                                    class="inlineFormSelect ml5"
-                                    @change="handleGoodsGroups"
-                                    style="width: 135px"
-                                    v-model:value="formState.goodsgroupid"
-                                    placeholder="请选择商品"
-                                >
-                                    <a-select-option
-                                        v-for="item in goodsGroup"
-                                        :value="item.goodsgroupid"
-                                        :key="item.goodsgroupid"
-                                    >{{item.goodsgroupname}}</a-select-option>
-                                </a-select>
-                                <a-select
-                                    class="inlineFormSelect ml5"
-                                    style="width: 135px"
-                                    @change="handleGoodsChange"
-                                    v-model:value="formState.goodsid"
-                                    placeholder="请选择合约"
-                                >
-                                    <a-select-option
-                                        v-for="item in goodsList"
-                                        :value="item.goodsid"
-                                        :key="item.goodsid"
-                                    >{{item.goodsname}}</a-select-option>
-                                </a-select>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="24" v-if="isFloat()" class="relative">
-                            <a-form-item :label="'估算金额'">
-                                <span class="white ml8">{{getWrMoney()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="isFixed()" class="relative">
-                            <a-form-item :label="'挂牌金额'">
-                                <span class="white ml8">{{getWrMoney()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="getWrMargin() && !isBlocs()">
-                            <a-form-item :label="getWrMargin() ? '履约保证金' : ''">
-                                <span class="white ml8">{{getWrMargin()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24" v-if="isBlocs()">
-                            <a-form-item label="履约保证金">
-                                <span class="white ml8">{{getMargin()}}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="可用资金">
-                                <span class="white ml8">{{getCanUseMoney(handleSelectedAccount())}}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                </div>
-                <a-row :gutter="24">
-                    <a-col :span="24" class="fixedBtns">
-                        <a-form-item class="btnCenter">
-                            <a-button
-                                class="listedBtn"
-                                :loading="loading"
-                                :disabled="loading"
-                                @click="submit"
-                            >卖出</a-button>
-                            <a-button
-                                class="ml10 cancelBtn"
-                                :loading="loading"
-                                :disabled="loading"
-                                @click="cancel"
-                            >取消</a-button>
-                        </a-form-item>
-                    </a-col>
-                </a-row>
-            </a-form>
+                <a-select class="inlineFormSelect ml5"
+                          @change="handleGoodsGroups"
+                          style="width: 135px"
+                          v-model:value="formState.goodsgroupid"
+                          placeholder="请选择商品">
+                  <a-select-option v-for="item in goodsGroup"
+                                   :value="item.goodsgroupid"
+                                   :key="item.goodsgroupid">{{item.goodsgroupname}}
+                  </a-select-option>
+                </a-select>
+                <a-select class="inlineFormSelect ml5"
+                          style="width: 135px"
+                          @change="handleGoodsChange"
+                          v-model:value="formState.goodsid"
+                          placeholder="请选择合约">
+                  <a-select-option v-for="item in goodsList"
+                                   :value="item.goodsid"
+                                   :key="item.goodsid">{{item.goodsname}}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24"
+                   v-if="isFloat()"
+                   class="relative">
+              <a-form-item :label="'估算金额'">
+                <span class="white ml8">{{getWrMoney()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="isFixed()"
+                   class="relative">
+              <a-form-item :label="'挂牌金额'">
+                <span class="white ml8">{{getWrMoney()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="getWrMargin() && !isBlocs()">
+              <a-form-item :label="getWrMargin() ? '履约保证金' : ''">
+                <span class="white ml8">{{getWrMargin()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24"
+                   v-if="isBlocs()">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{getMargin()}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="可用资金">
+                <span class="white ml8">{{getCanUseMoney(handleSelectedAccount())}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
         </div>
-    </Drawer>
-    <!-- 选择朋友 -->
-    <Friend v-if="showFriend" :position="'bottom'" @cancel="chooseFriend" @update="chooseFriend" />
-    <!-- 选择履约模板 -->
-    <Permance
-        v-if="showPermance"
-        :position="'bottom'"
-        @cancel="choosePermance"
-        @update="choosePermance"
-    />
+        <a-row :gutter="24">
+          <a-col :span="24"
+                 class="fixedBtns">
+            <a-form-item class="btnCenter">
+              <a-button class="listedBtn"
+                        :loading="loading"
+                        :disabled="loading"
+                        @click="submit">卖出</a-button>
+              <a-button class="ml10 cancelBtn"
+                        :loading="loading"
+                        :disabled="loading"
+                        @click="cancel">取消</a-button>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+  </Drawer>
+  <!-- 选择朋友 -->
+  <Friend v-if="showFriend"
+          :friends=formState.friends
+          :position="'bottom'"
+          @cancel="chooseFriend"
+          @update="chooseFriend" />
+  <!-- 选择履约模板 -->
+  <Permance v-if="showPermance"
+            :position="'bottom'"
+            @cancel="choosePermance"
+            @update="choosePermance" />
 </template>
 
 <script lang="ts">
@@ -377,7 +371,7 @@ export default defineComponent({
                         PriceFactor: 1, // 价格系数(浮动价时填写)
                         PriceMove: res.PriceMove, // 升贴水(浮动价时填写)
                         TimevalidType: 4, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
-                        // ValidTime: moment('2021-08-25 00:00:00').format('YYYY-MM-DD HH:mm:ss'), // 有效期限
+                        // ValidTime: isBlocs() ? moment(res.vidaliteTime).format('YYYY-MM-DD HH:mm:ss') : '', // 有效期限
                         ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
                         FirstRatio: 0, // 首付比例
                         PerformanceTemplateID: res.permaceTempId, // 履约计划模板ID
@@ -414,8 +408,10 @@ export default defineComponent({
                             IsSpecified: 1,
                             MatchAccIDs: res.friends,
                             WRPriceType: 1,
+                            TimevalidType: 3, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
                             MarginFlag: 1, // 挂牌是否指定保证金 0:否 1:是
                             MarginAlgorithm: 1, // 指定保证金方式 1:比率 2:固定
+                            ValidTime: moment(res.vidaliteTime).format('YYYY-MM-DD HH:mm:ss'), // 有效期限
                             MarginValue: +(formState.margin / 100).toFixed(2), // 指定保证金设置值
                             AllFriendsFlag: friendCheck.value ? 1 : 0, //是否全好友可见 0:否 1:是
                         };

+ 2 - 2
src/views/ping_an/spot_price_management/spot_price_management_pending/index.vue

@@ -22,10 +22,10 @@
         components: {},
         setup() {
             onMounted(() => {
-                //const bridge = window.chrome.webview.hostObjects.bridge;
+                const bridge = window.chrome.webview.hostObjects.bridge;
                 window.aaa = (str: string) => {
                     console.log(str)
-                    // bridge.Func("testing...");
+                    bridge.Func(str);
                 }
             });
 

+ 3 - 2
src/views/setting/friends/index.vue

@@ -87,10 +87,11 @@ export default defineComponent({
             });
         }
         function operate({ frienduserid, isfriend }: QueryWrFriendApplyRsp) {
+            const id = frienduserid.toString();
             if (isfriend) {
-                deleteFriend(frienduserid);
+                deleteFriend(id);
             } else {
-                addFriend(frienduserid);
+                addFriend(id);
             }
         }
         // 查询好友列表

+ 51 - 46
swagger-to-ts/swagger.ts

@@ -1,47 +1,52 @@
-export interface Name {
-    accountid: number;//摘牌资金账号
-    applyprice: string;//申请价格(议价价格)
-    applyqty: number;//摘牌数量(议价数量)
-    applyremark: string;//申请备注
-    applystatus: number;//申请状态(议价状态) - 1:待确认 2:已确认 3:已拒绝 4:已撤销 5:系统撤销 6:处理失败 7:确认中
-    applytime: string;//申请时间(议价时间)
-    buyorsell: number;//买卖(挂牌类型) - number;
-    //:买 1:卖
-    confirmremark: string;//确认备注
-    confirmtime: string;//确认时间
-    confirmuserid: number;//确认人
-    deliverygoodscode: string;//品种代码
-    deliverygoodsid: number;//品种ID
-    deliverygoodsname: string;//品种名称
-    deliverymonth: string;//交收月
-    enumdicname: string;//单位名称
-    fixedprice: number;//挂牌价格
-    handlestatus: number;//处理状态
-    marginvalue: number;//履约保证金比例
-    marketid: number;//市场ID
-    matchaccountid: number;//挂牌方资金账号
-    matchuserid: number;//挂牌方用户id
-    matchusername: string;//挂牌方用户名称(已脱敏)
-    minivalue: number;//现货商品最小变动值
-    optioncompare: string;//选择项比较串【{选择项ID}+{冒号}+选择项值 } ,逗号分隔,头尾加逗号】-- 所有选择项拼接,用于比较
-    orderqty: number;//挂牌数量
-    refprice: string;//参考价格
-    retcode: number;//委托返回代码
-    templatename: string;//履约方式(履约模板名称)
-    tradedate: string;//交易日(yyyyMMdd)
-    userid: number;//摘牌人用户ID(议价人ID)
-    username: string;//议价人名字(已脱敏)
-    validtime: string;//有效期限
-    warehouseid: number;//仓库ID
-    warehousename: string;//仓库名称
-    wrbargainid: string;//议价申请单ID(327+Unix秒时间戳(1number;
-    //位)+xxxxxx)
-    wrfactortypeid: string;//仓单要素类型ID(212+Unix秒时间戳(1number;
-    //位)+xxxxxx)
-    wrfactortypename: string;//仓单要素类型名称(选择项要素的名称合并显示,逗号分隔)
-    wrstandardcode: string;//现货商品代码
-    wrstandardid: number;//现货商品ID
-    wrstandardname: string;//商品名称
-    wrtradeorderid: string;//关联委托单ID
-    wrtypename: string;//商品
+export interface Name{
+    accountid	:number;//账号ID
+agreeunit	:number;//合约乘数
+buyorsell	:number;//方向 - number;
+//:买 1:卖
+currencyid	:number;//商品币种id
+currencyname	:string;//币种名称
+decimalplace	:number;//商品价格小数位
+enumdicname	:string;//商品单位名称
+expirecycle	:number;//行权周期(天) - 1:滚动行权时填写
+expiredate	:string;//行权日(yyyyMMdd) - 到期日
+expiretype	:number;//行权日类型 - 1:滚动行权 2:固定日行权
+freezeqty	:number;//冻结数量
+goodscode	:string;//商品代码
+goodsid	:number;//商品ID
+goodsname	:string;//商品名称
+goodunitid	:number;//商品单位id
+holderamount	:number;//持仓金额
+holdercredit	:number;//持仓授信金额
+holderdays	:number;//剩余冻结天数
+holderprice	:number;//持仓价格
+holderqty	:number;//持仓数量
+isconfirmexercise	:number;//是否确认行权- number;
+//:否 1:是
+ispreexercise	:number;//是否预申报- number;
+//:否 1:是 2:不可行权
+marketid	:number;//市场id
+marketname	:string;//市场名称
+openprice	:number;//建仓价格
+openqty	:number;//建仓数量
+optiontype	:number;//期权类型 - 1:认购(看涨) 2:认沽(看跌)
+preexerciseprice	:number;//预申报价格
+premium	:number;//权利金
+qtydecimalplace	:number;//商品成交量小数位
+refgoodscode	:string;//标的合约代码
+refgoodsid	:number;//标的合约id
+releaseamount	:number;//释放持仓金额
+releaseholdercredit	:number;//释放持仓授信金额
+taname	:string;//资金账号名称
+tradeamount	:number;//成交金额
+tradedate	:string;//交易日(yyyyMMdd)
+tradeid	:string;//成交单号(1number;
+//1+Unix秒时间戳(1number;
+//位)+2位(MarketServiceID)+xxxx)
+trademode	:number;//交易模式 - 1number;
+//:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 2number;
+//:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
+tradeproperty	:number;//交易属性
+tradetime	:string;//交易时间
+userid	:number;//用户id
+username	:string;//用户名称
 }

+ 86 - 83
swagger-to-ts/swagger.txt

@@ -1,127 +1,130 @@
 {
     accountid	integer
-摘牌资金账号
+账号ID
 
-applyprice	string
-申请价格(议价价格)
+agreeunit	number
+合约乘数
 
-applyqty	number
-摘牌数量(议价数量)
+buyorsell	integer
+方向 - 0:买 1:卖
 
-applyremark	string
-申请备注
+currencyid	integer
+商品币种id
 
-applystatus	integer
-申请状态(议价状态) - 1:待确认 2:已确认 3:已拒绝 4:已撤销 5:系统撤销 6:处理失败 7:确认中
+currencyname	string
+币种名称
 
-applytime	string
-申请时间(议价时间)
+decimalplace	integer
+商品价格小数位
 
-buyorsell	integer
-买卖(挂牌类型) - 0:买 1:卖
+enumdicname	string
+商品单位名称
 
-confirmremark	string
-确认备注
+expirecycle	integer
+行权周期(天) - 1:滚动行权时填写
 
-confirmtime	string
-确认时间
+expiredate	string
+行权日(yyyyMMdd) - 到期日
 
-confirmuserid	integer
-确认人
+expiretype	integer
+行权日类型 - 1:滚动行权 2:固定日行权
 
-deliverygoodscode	string
-品种代码
+freezeqty	number
+冻结数量
 
-deliverygoodsid	integer
-品种ID
+goodscode	string
+商品代码
 
-deliverygoodsname	string
-品种名称
+goodsid	integer
+商品ID
 
-deliverymonth	string
-交收月
+goodsname	string
+商品名称
 
-enumdicname	string
-单位名称
+goodunitid	integer
+商品单位id
 
-fixedprice	number
-挂牌价格
+holderamount	number
+持仓金额
 
-handlestatus	integer
-处理状态
+holdercredit	number
+持仓授信金额
 
-marginvalue	number
-履约保证金比例
+holderdays	integer
+剩余冻结天数
 
-marketid	integer
-市场ID
+holderprice	number
+持仓价格
 
-matchaccountid	integer
-挂牌方资金账号
+holderqty	number
+持仓数量
 
-matchuserid	integer
-挂牌方用户id
+isconfirmexercise	integer
+是否确认行权- 0:否 1:是
 
-matchusername	string
-挂牌方用户名称(已脱敏)
+ispreexercise	integer
+是否预申报- 0:否 1:是 2:不可行权
 
-minivalue	integer
-现货商品最小变动值
+marketid	integer
+市场id
 
-optioncompare	string
-选择项比较串【{选择项ID}+{冒号}+选择项值 } ,逗号分隔,头尾加逗号】-- 所有选择项拼接,用于比较
+marketname	string
+市场名称
 
-orderqty	integer
-挂牌数量
+openprice	number
+建仓价格
 
-refprice	string
-参考价格
+openqty	number
+建仓数量
 
-retcode	integer
-委托返回代码
+optiontype	integer
+期权类型 - 1:认购(看涨) 2:认沽(看跌)
 
-templatename	string
-履约方式(履约模板名称)
+preexerciseprice	number
+预申报价格
 
-tradedate	string
-交易日(yyyyMMdd)
+premium	number
+权利金
 
-userid	integer
-摘牌人用户ID(议价人ID)
+qtydecimalplace	integer
+商品成交量小数位
 
-username	string
-议价人名字(已脱敏)
+refgoodscode	string
+标的合约代码
 
-validtime	string
-有效期限
+refgoodsid	integer
+标的合约id
 
-warehouseid	integer
-仓库ID
+releaseamount	number
+释放持仓金额
 
-warehousename	string
-仓库名称
+releaseholdercredit	number
+释放持仓授信金额
 
-wrbargainid	string
-议价申请单ID(327+Unix秒时间戳(10位)+xxxxxx)
+taname	string
+资金账号名称
 
-wrfactortypeid	string
-仓单要素类型ID(212+Unix秒时间戳(10位)+xxxxxx)
+tradeamount	number
+成交金额
+
+tradedate	string
+交易日(yyyyMMdd)
 
-wrfactortypename	string
-仓单要素类型名称(选择项要素的名称合并显示,逗号分隔)
+tradeid	string
+成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
 
-wrstandardcode	string
-现货商品代码
+trademode	integer
+交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
 
-wrstandardid	integer
-现货商品ID
+tradeproperty	integer
+交易属性
 
-wrstandardname	string
-商品名称
+tradetime	string
+交易时间
 
-wrtradeorderid	string
-关联委托单ID
+userid	integer
+用户id
 
-wrtypename	string
-商品
+username	string
+用户名称
 }

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.