ソースを参照

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

li.shaoyi 3 年 前
コミット
ac25855f03
100 ファイル変更9403 行追加1654 行削除
  1. 1 1
      public/config/app.config.json
  2. 278 265
      src/assets/styles/mixin.less
  3. 76 72
      src/common/components/drawer/index.vue
  4. 47 44
      src/common/components/friends/index.vue
  5. 4 2
      src/common/setup/table/compose.ts
  6. 1 0
      src/common/setup/table/interface.ts
  7. 13 0
      src/common/setup/warehouse_receipt_trade/interface.ts
  8. 3 3
      src/common/setup/warehouse_receipt_trade/listing.ts
  9. 23 1
      src/hooks/form/verify.ts
  10. 14 1
      src/services/bus/account.ts
  11. 2 2
      src/services/go/Tjmd/index.ts
  12. 1 1
      src/services/proto/warehousetrade/interface.ts
  13. 3 0
      src/utils/timer/timerUtil.ts
  14. 4 1
      src/views/market/futures/compoments/futures-trade/interface.ts
  15. 69 53
      src/views/market/futures/index.vue
  16. 0 256
      src/views/market/market-spot/compoments/goods-chart/chart/index.vue
  17. 0 163
      src/views/market/market-spot/compoments/goods-chart/index.vue
  18. 0 229
      src/views/market/market-spot/compoments/spot_trade_order_transaction/index.vue
  19. 142 0
      src/views/market/market-spot/components/buy-sell-market/components/buy/index.vue
  20. 429 0
      src/views/market/market-spot/components/buy-sell-market/components/delisting/index.vue
  21. 1 1
      src/views/market/market-spot/components/buy-sell-market/components/delisting/interface.ts
  22. 16 18
      src/views/market/market-spot/components/buy-sell-market/components/delisting/setup.ts
  23. 48 50
      src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/components/choose-finance/index.vue
  24. 523 0
      src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/index.vue
  25. 0 0
      src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/interface.ts
  26. 12 30
      src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/setup.ts
  27. 149 0
      src/views/market/market-spot/components/buy-sell-market/components/sell/index.vue
  28. 250 0
      src/views/market/market-spot/components/buy-sell-market/index.vue
  29. 4 44
      src/views/market/market-spot/components/buy-sell-market/setup.ts
  30. 47 17
      src/views/market/market-spot/components/designate-buy/index.vue
  31. 173 127
      src/views/market/market-spot/components/designate-delisting/index.vue
  32. 0 0
      src/views/market/market-spot/components/designate-delisting/interface.ts
  33. 56 0
      src/views/market/market-spot/components/designate-delisting/setup.ts
  34. 403 0
      src/views/market/market-spot/components/designate-post-buying/index.vue
  35. 31 9
      src/views/market/market-spot/components/designate-sell/index.vue
  36. 1 1
      src/views/market/market-spot/components/detail/index.vue
  37. 56 16
      src/views/market/market-spot/components/filter/index.vue
  38. 1 4
      src/views/market/market-spot/components/goods-chart/chart/index.less
  39. 325 0
      src/views/market/market-spot/components/goods-chart/chart/index.vue
  40. 180 0
      src/views/market/market-spot/components/goods-chart/index.vue
  41. 0 0
      src/views/market/market-spot/components/goods-chart/setup.ts
  42. 112 0
      src/views/market/market-spot/components/goods-chart/stock-exchange/index.vue
  43. 3 4
      src/views/market/market-spot/components/history-chart/index.vue
  44. 158 37
      src/views/market/market-spot/components/post_buying/index.vue
  45. 3 0
      src/views/market/market-spot/components/post_buying/interface.ts
  46. 42 23
      src/views/market/market-spot/components/post_buying/setup.ts
  47. 2 2
      src/views/market/market-spot/components/setup.ts
  48. 0 0
      src/views/market/market-spot/goods-chart/chart/index.less
  49. 322 0
      src/views/market/market-spot/goods-chart/chart/index.vue
  50. 73 37
      src/views/market/market-spot/goods-chart/index.vue
  51. 0 0
      src/views/market/market-spot/goods-chart/setup.ts
  52. 0 0
      src/views/market/market-spot/goods-chart/stock-exchange/index.vue
  53. 35 10
      src/views/market/market-spot/index.vue
  54. 0 0
      src/views/market/market-spot/interface.ts
  55. 136 2
      src/views/market/market-spot/setup.ts
  56. 125 0
      src/views/market/market-spot/spot_trade_order_transaction/components/buy-market/index.vue
  57. 96 70
      src/views/market/market-spot/spot_trade_order_transaction/components/buy-sell-market/index.vue
  58. 0 31
      src/views/market/market-spot/spot_trade_order_transaction/components/buy-sell-market/setup.ts
  59. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/components/chart/index.vue
  60. 366 0
      src/views/market/market-spot/spot_trade_order_transaction/components/delisting/index.vue
  61. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/components/delisting/interface.ts
  62. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/components/delisting/setup.ts
  63. 1 1
      src/views/market/market-spot/spot_trade_order_transaction/components/detail/index.vue
  64. 14 5
      src/views/market/market-spot/spot_trade_order_transaction/components/listing/index.vue
  65. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/components/listing/interface.ts
  66. 32 0
      src/views/market/market-spot/spot_trade_order_transaction/components/listing/setup.ts
  67. 119 0
      src/views/market/market-spot/spot_trade_order_transaction/components/sell-market/index.vue
  68. 112 0
      src/views/market/market-spot/spot_trade_order_transaction/components/stock-exchange/index.vue
  69. 12 2
      src/views/market/market-spot/spot_trade_order_transaction/index.vue
  70. 30 11
      src/views/market/market-spot/spot_trade_order_transaction/setup.ts
  71. 146 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_basis_difference/index.vue
  72. 160 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_listing_transfer/index.vue
  73. 6 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_listing_transfer/interface.ts
  74. 147 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy-sell-market/index.vue
  75. 179 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy/index.vue
  76. 655 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/index.vue
  77. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/interface.ts
  78. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/setup.ts
  79. 1 1
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/detail/index.vue
  80. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/history-chart/index.vue
  81. 692 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/index.vue
  82. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/interface.ts
  83. 10 1
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts
  84. 190 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/sell/index.vue
  85. 82 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/setup.ts
  86. 189 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue
  87. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/interface.ts
  88. 0 0
      src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/setup.ts
  89. 0 0
      src/views/market/market-spot/spot_trade_reference_market/index.vue
  90. 0 0
      src/views/market/market-spot/warehouse_pre_sale/index.vue
  91. 138 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/buy/index.vue
  92. 512 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/index.vue
  93. 0 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/interface.ts
  94. 1 1
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/setup.ts
  95. 403 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/post-buying/index.vue
  96. 22 5
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/sell/index.vue
  97. 0 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/index.vue
  98. 41 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/setup.ts
  99. 138 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_designate/components/buy/index.vue
  100. 512 0
      src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_designate/components/delisting/index.vue

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

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

ファイルの差分が大きいため隠しています
+ 278 - 265
src/assets/styles/mixin.less


+ 76 - 72
src/common/components/drawer/index.vue

@@ -1,80 +1,83 @@
 <template>
-  <a-drawer placement="right" :closable="false" :visible="visible" :destroyOnClose="true" class="bottomListed" height="405px">
-    <!-- 摘牌是top  挂牌是bottom 期货交易是tradeDialog -->
-    <div class="collapse" @click="cancel">
-      <DoubleRightOutlined />
-    </div>
-    <div class="collapseCont">
-      <div class="title">{{ title }}</div>
-      <div class="content highContent">
-        <!-- <Listed></Listed> -->
-        <!-- <Delisting></Delisting> -->
-        <slot></slot>
-        <!-- <Trade></Trade> -->
-      </div>
-    </div>
-
-    <div class="gpDetail" style="display: none">
-      <div class="title">挂牌详情</div>
-      <div class="content">
-        <div class="item">
-          <div class="left">交易账户</div>
-          <div class="right">3237545143</div>
-        </div>
-        <div class="item">
-          <div class="left">挂牌方式</div>
-          <div class="right">贸易圈</div>
-        </div>
-        <div class="item">
-          <div class="left">挂牌价格</div>
-          <div class="right">
-            <span>1680.00</span>
-            <span class="grey">(可议价)</span>
-          </div>
-        </div>
-        <div class="item">
-          <div class="left">现货仓单</div>
-          <div class="right">335999666555222222</div>
-        </div>
-        <div class="item">
-          <div class="left">挂牌数量</div>
-          <div class="right">
-            <span>30吨</span>
-            <span class="grey">整单</span>
-          </div>
+    <a-drawer
+        placement="right"
+        :closable="false"
+        :visible="visible"
+        :destroyOnClose="true"
+        class="bottomListed"
+        height="405px"
+    >
+        <!-- 摘牌是top  挂牌是bottom 期货交易是tradeDialog -->
+        <div class="collapse" @click="cancel">
+            <DoubleRightOutlined />
         </div>
-        <div class="item">
-          <div class="left">起摘数量</div>
-          <div class="right">2吨</div>
+        <div class="collapseCont">
+            <div class="title">{{ title }}</div>
+            <div class="content highContent">
+                <slot></slot>
+            </div>
         </div>
-        <div class="someItems">1000 江**业、1201 *融、1123 南**业、1000 江**业、1201 *融、1123 南**业、1000 江**业、1201 *融、1123 南**业</div>
-        <div class="item">
-          <div class="left">现货仓单</div>
-          <div class="right">335999666555222222</div>
-        </div>
-        <div class="item">
-          <div class="left">指定朋友</div>
-          <div class="right">1000 江**业、1201 *融、1123 南...</div>
-        </div>
-        <div class="item">
-          <div class="left">挂牌金额</div>
-          <div class="right">50400.00</div>
-        </div>
-        <div class="item">
-          <div class="left">履约保证金</div>
-          <div class="right">5040.00</div>
+
+        <div class="gpDetail" style="display: none">
+            <div class="title">挂牌详情</div>
+            <div class="content">
+                <div class="item">
+                    <div class="left">交易账户</div>
+                    <div class="right">3237545143</div>
+                </div>
+                <div class="item">
+                    <div class="left">挂牌方式</div>
+                    <div class="right">贸易圈</div>
+                </div>
+                <div class="item">
+                    <div class="left">挂牌价格</div>
+                    <div class="right">
+                        <span>1680.00</span>
+                        <span class="grey">(可议价)</span>
+                    </div>
+                </div>
+                <div class="item">
+                    <div class="left">现货仓单</div>
+                    <div class="right">335999666555222222</div>
+                </div>
+                <div class="item">
+                    <div class="left">挂牌数量</div>
+                    <div class="right">
+                        <span>30吨</span>
+                        <span class="grey">整单</span>
+                    </div>
+                </div>
+                <div class="item">
+                    <div class="left">起摘数量</div>
+                    <div class="right">2吨</div>
+                </div>
+                <div
+                    class="someItems"
+                >1000 江**业、1201 *融、1123 南**业、1000 江**业、1201 *融、1123 南**业、1000 江**业、1201 *融、1123 南**业</div>
+                <div class="item">
+                    <div class="left">现货仓单</div>
+                    <div class="right">335999666555222222</div>
+                </div>
+                <div class="item">
+                    <div class="left">指定朋友</div>
+                    <div class="right">1000 江**业、1201 *融、1123 南...</div>
+                </div>
+                <div class="item">
+                    <div class="left">挂牌金额</div>
+                    <div class="right">50400.00</div>
+                </div>
+                <div class="item">
+                    <div class="left">履约保证金</div>
+                    <div class="right">5040.00</div>
+                </div>
+            </div>
         </div>
-      </div>
-    </div>
-  </a-drawer>
+    </a-drawer>
 </template>
 
 <script lang="ts">
 import { defineComponent, ref, PropType } from 'vue';
 import { closeModal, ModalName } from '@/common/setup/modal/index';
-import Listed from '@/views/market/warehouseTrade/components/listed/index.vue';
-import Delisting from '@/views/market/warehouseTrade/components/delisting/index.vue';
-import Trade from '@/views/market/warehouseTrade/components/trade/index.vue';
 import { _closeModal } from '@/common/setup/modal/modal';
 import { DoubleRightOutlined } from '@ant-design/icons-vue';
 
@@ -101,9 +104,6 @@ export default defineComponent({
         },
     },
     components: {
-        Listed,
-        Delisting,
-        Trade,
         DoubleRightOutlined,
     },
     setup(props, context) {
@@ -430,7 +430,11 @@ export default defineComponent({
                             height: 38px;
                             line-height: 38px;
                             text-align: center;
-                            background: linear-gradient(0deg, @m-blue4, @m-blue5);
+                            background: linear-gradient(
+                                0deg,
+                                @m-blue4,
+                                @m-blue5
+                            );
                             font-size: 16px;
                             color: @m-white10;
                             // border-bottom: 2px solid @m-blue0;

+ 47 - 44
src/common/components/friends/index.vue

@@ -1,48 +1,51 @@
 <template>
-  <!--选择朋友-->
-  <Drawer :title="'选择朋友'"
-          :placement="'right'"
-          :visible="visible"
-          @cancel="cancel"
-          :class="[position === 'top' ? 'top486' : 'delistingBottom']">
-    <a-spin :spinning="loading">
-      <div class="listed">
-        <a-form class="inlineForm dialogForm">
-          <a-input-search placeholder="搜索朋友编码或名称"
-                          class="searchFriendInput noSuffixInput"
-                          enter-button
-                          v-model:value="searchValue">
-            <template #prefix>
-              <SearchOutlined />
-            </template>
-          </a-input-search>
-          <div class="formBar ant-checkbox-group commonCheckboxGroup whitebgCheckbox">
-            <!-- <a-checkbox-group class="commonCheckboxGroup"> -->
-            <div class="ant-checkbox-wrapper"
-                 style="width: 100%">
-              <div class="item"
-                   v-for="(item, index) in getViewFriends()"
-                   :key="index + '11'">
-                <a-checkbox v-model:checked="item.checked">
-                  <span class="txt">{{item.frienduserid}} {{ item.friendname }}</span>
-                </a-checkbox>
-              </div>
+    <!--选择朋友-->
+    <Drawer
+        :title="'选择朋友'"
+        :placement="'right'"
+        :visible="visible"
+        @cancel="cancel"
+        :class="[position === 'top' ? 'top486' : 'delistingBottom']"
+    >
+        <a-spin :spinning="loading">
+            <div class="listed">
+                <a-form class="inlineForm dialogForm">
+                    <a-input-search
+                        placeholder="搜索朋友编码或名称"
+                        class="searchFriendInput noSuffixInput"
+                        enter-button
+                        v-model:value="searchValue"
+                    >
+                        <template #prefix>
+                            <SearchOutlined />
+                        </template>
+                    </a-input-search>
+                    <div class="formBar ant-checkbox-group commonCheckboxGroup whitebgCheckbox">
+                        <!-- <a-checkbox-group class="commonCheckboxGroup"> -->
+                        <div class="ant-checkbox-wrapper" style="width: 100%">
+                            <div
+                                class="item"
+                                v-for="(item, index) in getViewFriends()"
+                                :key="index + '11'"
+                            >
+                                <a-checkbox v-model:checked="item.checked">
+                                    <span class="txt">{{ item.frienduserid }} {{ item.friendname }}</span>
+                                </a-checkbox>
+                            </div>
+                        </div>
+                        <!-- </a-checkbox-group> -->
+                    </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-form-item>
+                        </a-col>
+                    </a-row>
+                </a-form>
             </div>
-            <!-- </a-checkbox-group> -->
-          </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-form-item>
-            </a-col>
-          </a-row>
-        </a-form>
-      </div>
-    </a-spin>
-  </Drawer>
+        </a-spin>
+    </Drawer>
 </template>
 
 <script lang="ts">
@@ -52,7 +55,7 @@ import { _closeModal } from '@/common/setup/modal/modal';
 import Drawer from '@/common/components/drawer/index.vue';
 import { PlusOutlined, MinusOutlined, SearchOutlined } from '@ant-design/icons-vue';
 import { QueryWrFriendApplyRsp } from '@/services/go/wrtrade/interface';
-import { TempWrOrderQuoteDetail } from '@/views/market/spot_trade/components/post_buying/interface';
+import { TempWrOrderQuoteDetail } from '@/views/market/market-spot/components/post_buying/interface';
 import { queryQueryWrFriend } from '@/services/go/wrtrade';
 import { message } from 'ant-design-vue';
 

+ 4 - 2
src/common/setup/table/compose.ts

@@ -120,7 +120,7 @@ export function handleComposeTable_detail<T>({ queryFn, tableName, tableFilterKe
 }
 
 // 获取单据table通用逻辑
-export function handleComposeOrderTable<T>({ queryFn, recordList, tableName, }: ComposeOrderTableParam) {
+export function handleComposeOrderTable<T>({ queryFn, recordList, tableName, clickCB }: ComposeOrderTableParam) {
     // 右键逻辑
     const { contextMenu, openContext, closeContext: closeContextAction } = handleContextMenu();
     // 表头数据
@@ -130,6 +130,9 @@ export function handleComposeOrderTable<T>({ queryFn, recordList, tableName, }:
         contextmenuCB: (record: T, value: ContextMenuTemp) => {
             // 控制打开右键
             contextMenu.value = value
+        },
+        clickCB: (record: T) => {
+            clickCB?.(record)
         }
     }
     // 表格事件
@@ -141,7 +144,6 @@ export function handleComposeOrderTable<T>({ queryFn, recordList, tableName, }:
         code: code,
         className: getClassName(code),
     }], [] as BtnListType[]);
-
     // 控制异步组件
     const { componentId, closeComponent, openComponent } = handleModalComponent(queryFn, selectedRow);
     // 关闭右键

+ 1 - 0
src/common/setup/table/interface.ts

@@ -49,6 +49,7 @@ export interface ComposeOrderTableParam {
     recordList: OperationTabMenuAuth[], // 当前tab页配置数据
     tableName?: keyof TableKey, // 表头key
     isDetail?: boolean,  // 是否需要详情
+    clickCB?: Function, // 点击表格行
 }
 
 export interface ButtonListKey {

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

@@ -12,4 +12,17 @@ export interface BlocsListingForm {
     friends: number[],
     permanceTempName: string,
     permaceTempId: number,
+}
+
+export interface RuleItem {
+    required?: boolean,
+    message?: string,
+    trigger?: 'blur' | 'change' | ['change', 'blur'],
+    type?: string,
+    validator?: Function,
+    min?: number,
+    max?: number,
+}
+export interface Rules {
+    [key: string]: RuleItem[]
 }

+ 3 - 3
src/common/setup/warehouse_receipt_trade/listing.ts

@@ -3,7 +3,7 @@ import { QueryPermancePlanTmpRsp } from "@/services/go/wrtrade/interface";
 import { RuleObject } from "ant-design-vue/lib/form/interface";
 import moment from "moment";
 import { computed, onBeforeUnmount, reactive, ref, UnwrapRef } from "vue";
-import { BlocsListingForm } from './interface';
+import { BlocsListingForm, Rules } from './interface';
 
 /************************ ============= 仓单贸易 贸易圈 挂牌 ================ ****************/
 
@@ -146,7 +146,7 @@ const handleForm = () => {
         }
     }
     const formRef = ref();
-    const rules = {
+    const rules: Rules = {
         FixedPrice: [{ required: true, message: '请输入挂牌价格', trigger: 'blur', type: 'number', }],
         OrderQty: [
             { required: true, message: '请输入挂牌数量', trigger: 'blur', type: 'number' },
@@ -154,7 +154,7 @@ const handleForm = () => {
         ],
         delistingQty: [
             { required: true, message: '请输入起摘数量', trigger: 'blur', type: 'number' },
-            { min: 1, message: '起摘数量不能小于1', type: 'number' }
+            // { min: 1, message: '起摘数量不能小于1', type: 'number' }
         ],
         margin: [
             // { required: true, message: '请输入履约保证金', trigger: 'blur', type: 'number' },

+ 23 - 1
src/hooks/form/verify.ts

@@ -1,6 +1,7 @@
-import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { RuleItem } from '@/common/setup/warehouse_receipt_trade/interface';
 import { getGoodsById, getQuoteDayInfoByCode } from '@/services/bus/goods';
 import { getRules } from '@/services/bus/rules';
+import { RuleObject } from "ant-design-vue/lib/form/interface";
 
 // 验证 挂牌数量
 /**
@@ -73,4 +74,25 @@ export const useVerifyListingBasis = <T, k extends keyof T>(formState: T, key: k
         }
     };
     return { v_basis }
+}
+
+/**
+ * 验证 起摘数量
+ * @param minValue 最小变动值
+ */
+export const useVerifyBeginDelistingNum = (minValue: number) => {
+    const v_beginDelistingNum = async (rule: RuleObject, value: number) => {
+        if (value) {
+            if (minValue) {
+                if (value % minValue !== 0) {
+                    return Promise.reject(`起摘数量不是${minValue}的倍数`);
+                }
+            }
+            return Promise.resolve();
+        } else {
+            return Promise.reject('请输入起摘数量');
+        }
+    }
+    const v_beginDelistingRules: RuleItem[] = [{ required: true, validator: v_beginDelistingNum, trigger: 'blur', type: 'number', }]
+    return { v_beginDelistingNum, v_beginDelistingRules }
 }

+ 14 - 1
src/services/bus/account.ts

@@ -130,4 +130,17 @@ export function getFreeze(value: AccountListItem, isFixed2 = false) {
 export function getCanUseMoney(value: AccountListItem) {
     const freeze = getFreeze(value) as number
     return (value.currentbalance - freeze).toFixed(2)
-}
+}
+
+/**
+ *  获取用户id
+ */
+export const getUserId = (): number => {
+    const loginData = getLoginData();
+    if (loginData) {
+        return loginData.UserID;
+    } else {
+        console.warn('没有获取到用户id');
+        return 0;
+    }
+};

+ 2 - 2
src/services/go/Tjmd/index.ts

@@ -42,11 +42,11 @@ export function queryTjmdTransferApply(req: type.QueryTjmdTransferApplyReq): Pro
 /**
  * 查询市场板块  /Tjmd/QueryTjmdMarketSection
  */
-export function queryTjmdMarketSection(): Promise<string> {
+export function queryTjmdMarketSection(): Promise<type.TjmdMarketSection[]> {
     return commonSearch_go('/Tjmd/QueryTjmdMarketSection', {}).then(res => {
         console.log('查询市场板块:  ', res)
         APP.set('marketsSection', res);
-        return 'ok'
+        return res
     }).catch((err) => {
         throw new Error(`查询市场板块 : ${err}`);
     });

+ 1 - 1
src/services/proto/warehousetrade/interface.ts

@@ -69,7 +69,7 @@ export interface HdWRDealOrderReq {
     OperatorID: number; // uint64 操作员账号ID
     BuyOrSell: number; // uint32 买卖方向
     ApplyID: number; // uint64 申请ID
-    LadingBillId?: string; // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
+    LadingBillId?: string | number; // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
     SubNum: number; // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
     WRFactorTypeId: number; // uint64 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写
     TradeDate: string; // string 交易日

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

@@ -8,8 +8,11 @@ export interface IntervalTimerNames {
     accountStauts: string; // 账号状态
     spotTrade: string; // 仓单报价列表
     buyAndSellMartet: string; // 买卖大厅
+    buyMarket: string; // 买大厅
+    sellMarket: string; // 卖大厅
     realTime: string; // 实时敞口监控
     countdown: string; // 倒计时
+    quoteSucribe: string; // 行情订阅
 }
 export interface TimeoutTimerNames {
     logoutTimer: string; //登出1s延时器

+ 4 - 1
src/views/market/futures/compoments/futures-trade/interface.ts

@@ -11,7 +11,10 @@ export interface FormParam {
     DelistMinQty: number,
 }
 
+export interface WrResultItem {
+    dgfactoryitemtypeid: number; dgfactoryitemid: number
+}
 
 export interface TempTableQuoteDetail extends TableQuote {
-    wrResult: { dgfactoryitemtypeid: number; dgfactoryitemid: number }[]
+    wrResult: WrResultItem[]
 }

+ 69 - 53
src/views/market/futures/index.vue

@@ -2,9 +2,18 @@
   <!--期货-->
   <mtp-table-scroll>
     <template #default="{ scroll }">
-      <a-table :columns="getColumnsList()" class="srcollYTable" :scroll="scroll" :pagination="false" :loading="loading" :customRow="Rowclick" :rowKey="(record,index)=>index" :data-source="tableList">
+      <a-table
+        :columns="getColumnsList()"
+        class="srcollYTable"
+        :scroll="scroll"
+        :pagination="false"
+        :loading="loading"
+        :customRow="Rowclick"
+        :rowKey="(record, index) => index"
+        :data-source="tableList"
+      >
         <template #index="{ index }">
-          <span>{{index + 1}}</span>
+          <span>{{ index + 1 }}</span>
         </template>
       </a-table>
     </template>
@@ -14,7 +23,13 @@
   </mtp-table-scroll>
   <!-- 右键 -->
   <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="buttons"></contextMenu>
-  <component :is="componentId" v-if="componentId" :selectedRow="selectedRow" @cancel="closeComponent"></component>
+  <component
+    :is="componentId"
+    v-if="componentId"
+    :selectedRow="selectedRow"
+    :isShowTrade="true"
+    @cancel="closeComponent"
+  ></component>
 </template>
 
 <script lang="ts">
@@ -38,7 +53,7 @@ export default defineComponent({
     MtpTableScroll,
     ThridMenu,
     contextMenu,
-    chart: defineAsyncComponent(() => import('../spot_trade/components/goods-chart/index.vue')),
+    chart: defineAsyncComponent(() => import('../market-spot/goods-chart/index.vue')),
     trade: defineAsyncComponent(() => import('./compoments/futures-trade/index.vue')),
   },
   setup() {
@@ -90,62 +105,63 @@ export default defineComponent({
 });
 </script>
 <style lang="less">
-@import './index.less';
+@import "./index.less";
 .noData {
-    .position(absolute, 28px, 0, 0, 0);
+  .position(absolute, 28px, 0, 0, 0);
 }
 .filter-custom-table {
-    display: inline-flex;
-    align-items: center;
-    padding: 7px 0;
-    .conditionSelect:first-child {
-        margin-right: 10px;
-    }
-    .btnDeafault.ant-btn,
-    .operBtn.ant-btn {
-        height: 26px !important;
-        line-height: 26px !important;
-    }
+  display: inline-flex;
+  align-items: center;
+  padding: 7px 0;
+  .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) {
-        .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;
-            }
+  .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) {
+    .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;
+  .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>

+ 0 - 256
src/views/market/market-spot/compoments/goods-chart/chart/index.vue

@@ -1,256 +0,0 @@
-<template>
-  <!-- 交易图表  -->
-  <div class="chart-container">
-    <div class="chart-content">
-      <div class="chart-content__header">
-        <a-menu class="chart-content__tabs" v-model:selectedKeys="activeCycleName" mode="horizontal" @click="changeCycleType">
-          <a-menu-item v-for="item in chartType" :key="item.name">{{ item.label }}</a-menu-item>
-        </a-menu>
-        <a-menu class="chart-content__tabs" v-model:selectedKeys="activeSeriesType" mode="horizontal" v-if="activeCycleType !== CycleType.time">
-          <a-menu-item key="MACD">MACD</a-menu-item>
-          <a-menu-item key="VOL">VOL</a-menu-item>
-          <a-menu-item key="KDJ">KDJ</a-menu-item>
-          <a-menu-item key="CCI">CCI</a-menu-item>
-        </a-menu>
-      </div>
-      <echart-time class="chart-content__main" :quote-data="selectedRow" @change="getHistoryTikDatas" v-if="activeCycleType === CycleType.time"></echart-time>
-      <echart-kline class="chart-content__main" :quote-data="selectedRow" :cycle-type="activeCycleType" :series-type="activeSeriesType[0]" v-else></echart-kline>
-      <div class="chart-content__footer"></div>
-    </div>
-    <div class="chart-slider">
-      <div class="chart-slider__button"></div>
-    </div>
-    <div class="chart-tips" v-if="showExchange">
-      <div>
-        <div class="chart-tips__nav">
-          <div class="content content--left">{{ selectedRow.goodscode }}</div>
-          <div class="content content--right">{{ selectedRow.goodsname }}</div>
-        </div>
-        <div class="chart-tips__last">
-          <div :class="['content content--left', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]">{{ handleNoneValue(selectedRow.last) }}</div>
-          <div class="content content--right">
-            <span :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteChange(selectedRow) }}</span>
-            <span :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteAmplitude(selectedRow) }}</span>
-          </div>
-        </div>
-        <div class="chart-tips__volume">
-          <a-row>
-            <a-col :span="8">卖一</a-col>
-            <a-col :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.ask) }}</a-col>
-            <a-col :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.askvolume) }}</a-col>
-          </a-row>
-          <a-row>
-            <a-col :span="8">买一</a-col>
-            <a-col :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.bid) }}</a-col>
-            <a-col :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.bidvolume) }}</a-col>
-          </a-row>
-        </div>
-      </div>
-      <div class="chart-tips__tik">
-        <div class="row-header">
-          <h4>分时成交</h4>
-          <a-row>
-            <a-col :span="8">时间</a-col>
-            <a-col :span="8">价格</a-col>
-            <a-col :span="8">现量</a-col>
-          </a-row>
-        </div>
-        <div class="row-content">
-          <a-row v-for="(item, index) in tradedList" :key="index + '11'">
-            <a-col :span="8">{{ formatTime(item.TS, 'hm') }}</a-col>
-            <a-col :class="handleQuotePriceColor(item.PE, selectedRow.presettle)" :span="8">{{ item.PE }}</a-col>
-            <a-col :class="handleQuotePriceColor(item.Vol, selectedRow.presettle)" :span="8">{{ item.Vol }}</a-col>
-          </a-row>
-        </div>
-      </div>
-      <div class="chart-tips__info">
-        <a-row>
-          <a-col :span="4">最新</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.last) }}</a-col>
-          <a-col :span="4">均价</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.averageprice, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.averageprice) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">涨跌</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ quoteChange(selectedRow) }}</a-col>
-          <a-col :span="4">今开</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.opened, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.opened) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">涨幅</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ quoteAmplitude(selectedRow) }}</a-col>
-          <a-col :span="4">最高</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.highest, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.highest) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">总量</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.totalvolume) }}</a-col>
-          <a-col :span="4">最低</a-col>
-          <a-col :class="handleQuotePriceColor(selectedRow.lowest, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.lowest) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">金额</a-col>
-          <a-col :span="8" style="color: #0d96ff">{{ changeUnit(selectedRow.totalturnover) }}</a-col>
-          <a-col :span="4">量比</a-col>
-          <a-col :span="8">{{ '--' }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">涨停</a-col>
-          <a-col class="red1" :span="8">{{ handleNoneValue(selectedRow.limitup) }}</a-col>
-          <a-col :span="4">跌停</a-col>
-          <a-col class="green" :span="8">{{ handleNoneValue(selectedRow.limitdown) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">外盘</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.totalbidvolume) }}</a-col>
-          <a-col :span="4">内盘</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.totalaskvolume) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">持仓</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.holdvolume) }}</a-col>
-          <a-col :span="4">结算</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.settle) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">仓差</a-col>
-          <a-col :span="8">{{ '--' }}</a-col>
-          <a-col :span="4">昨结</a-col>
-          <a-col :span="8">{{ handleNoneValue(selectedRow.presettle) }}</a-col>
-        </a-row>
-        <a-row>
-          <a-col :span="4">日增</a-col>
-          <a-col :span="8">{{ '--' }}</a-col>
-          <a-col :span="4">开平</a-col>
-          <a-col :span="8">{{ '--' }}</a-col>
-        </a-row>
-      </div>
-      <div @click="watchMore" class="watchMore">
-        <strong>查看更多</strong>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from '@/common/export/commonTable';
-import { _closeModal } from '@/common/setup/modal/modal';
-import { PropType, ref, watch } from 'vue';
-import { QueryQuoteDayRsp, QueryHistoryTikDatasRsp, CycleType } from '@/services/go/quote/interface';
-import { QueryHistoryTikDatas } from '@/services/go/quote';
-import { formatTime } from '@/common/methods';
-import { changeUnit } from '@/utils/qt/common';
-import { ComponentType } from '@/views/market/spot_trade/spot_trade_order_transaction/setup';
-import { EchartKline, EchartTime } from '@/common/components/echart';
-import { handleQuotePriceColor, quoteChange, handleNoneValue, quoteAmplitude } from '@/common/setup/table/tableQuote';
-import moment from 'moment';
-
-export default defineComponent({
-    emits: ['cancel', 'update'],
-    name: 'stock-exchange',
-    components: {
-        EchartKline,
-        EchartTime,
-    },
-    props: {
-        selectedRow: {
-            type: Object as PropType<QueryQuoteDayRsp>,
-            default: {},
-        },
-        showExchange: {
-            type: Boolean,
-            default: true,
-        },
-    },
-    setup(props, context) {
-        const { visible, cancel } = _closeModal(context),
-            activeCycleName = ref<string[]>(['time']),
-            activeCycleType = ref<CycleType>(CycleType.time),
-            activeSeriesType = ref<string[]>(['MACD']),
-            tradedList = ref<QueryHistoryTikDatasRsp[]>([]);
-
-        function watchMore() {
-            context.emit('update', ComponentType.marketContent);
-        }
-
-        // 周期类型
-        const chartType = [
-            { label: '分时', name: 'time', value: CycleType.time },
-            { label: '1分钟', name: 'minutes', value: CycleType.minutes },
-            { label: '5分钟', name: 'minutes5', value: CycleType.minutes5 },
-            { label: '30分钟', name: 'minutes30', value: CycleType.minutes30 },
-            { label: '60分钟', name: 'minutes60', value: CycleType.minutes60 },
-            { label: '4小时', name: 'Hours4', value: CycleType.Hours4 },
-            { label: '日 K', name: 'days', value: CycleType.days },
-        ];
-
-        // 切换图表周期类型
-        const changeCycleType = (e: { key: string }) => {
-            activeCycleType.value = chartType.find((item) => item.name === e.key)!.value;
-        };
-
-        // Tik列表
-        const getHistoryTikDatas = (startTime: string, endTime: string) => {
-            const param = {
-                goodsCode: props.selectedRow.goodscode.toUpperCase(),
-                count: 20,
-                startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'),
-                endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'),
-            };
-            QueryHistoryTikDatas(param).then((res) => {
-                tradedList.value = res;
-            });
-        };
-
-        // 监听行情变化刷Tik列表
-        watch(
-            () => props.selectedRow.last,
-            () => {
-                if (tradedList.value.length > 19) {
-                    // 移除列表最后一条记录
-                    tradedList.value.pop();
-                }
-                // 向列表开头添加新纪录
-                tradedList.value.unshift({
-                    AV: 0,
-                    Ask: 0,
-                    BV: 0,
-                    Bid: 0,
-                    HI: 0,
-                    HV: 0,
-                    PE: props.selectedRow.last,
-                    TDR: 0,
-                    TK: 0,
-                    TS: props.selectedRow.lasttime,
-                    TT: 0,
-                    Vol: props.selectedRow.lastvolume,
-                });
-            }
-        );
-
-        return {
-            cancel,
-            visible,
-            chartType,
-            tradedList,
-            CycleType,
-            activeCycleName,
-            activeCycleType,
-            activeSeriesType,
-            changeUnit,
-            watchMore,
-            formatTime,
-            quoteChange,
-            handleNoneValue,
-            quoteAmplitude,
-            handleQuotePriceColor,
-            changeCycleType,
-            getHistoryTikDatas,
-        };
-    },
-});
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 163
src/views/market/market-spot/compoments/goods-chart/index.vue

@@ -1,163 +0,0 @@
-<template>
-  <!-- 买卖大厅 -->
-  <div class="buy-sell-market">
-    <div class="buy-sell-market-title">
-      <a class="backIcon" @click="cancelAction">
-        <LeftOutlined />
-      </a>
-      <div class="titleBtn">
-        <div class="name">{{ selectedRow.goodscode }} {{ selectedRow.goodsname }}</div>
-        <div class="arrowRightIcon"></div>
-      </div>
-      <div class="inlineBar">
-        <div class="valNums bdf1 ml10">
-          <!-- 最新价 -->
-          <div class="firstNum start" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ selectedRow.last }}</div>
-          <div class="lastNum start">
-            <!-- 涨跌值 -->
-            <div :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
-            <!-- 涨跌幅 -->
-            <div class="ml20" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
-          </div>
-        </div>
-        <div class="priceBar ml20">
-          <div class="inlineBar start">
-            <div class="greenBar">
-              <div class="numBlock ml15">
-                <div class="first grey">卖价</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.ask }}</div>
-              </div>
-              <div class="numBlock">
-                <div class="first grey">卖量</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.askvolume }}</div>
-              </div>
-            </div>
-          </div>
-          <div class="inlineBar start">
-            <div class="redBar">
-              <div class="numBlock">
-                <div class="first grey">买价</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bid }}</div>
-              </div>
-              <div class="numBlock">
-                <div class="first grey">买量</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bidvolume }}</div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="btn-list">
-        <a-button class="operBtn" @click="openComponent({ code: 'trade' })">交易</a-button>
-      </div>
-    </div>
-    <!-- 交易图表 -->
-    <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :selectedRow="selectedRow" />
-    <!-- 成交明细 -->
-    <StockExchange :selectedRow="selectedRow" v-if="showComponentsId === ComponentType.tradeDetail" />
-    <component :is="componentId" v-if="componentId" :selectedRow="selectedRow" @cancel="closeComponent"></component>
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent, defineAsyncComponent } from '@/common/export/commonTable';
-import { _closeModal } from '@/common/setup/modal/modal';
-import { handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
-import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
-import { LeftOutlined } from '@ant-design/icons-vue';
-import { PropType, ref } from 'vue';
-import Chart from './chart/index.vue';
-import { ComponentType } from './setup';
-import StockExchange from './stock-exchange/index.vue';
-import { handleModalComponent } from '@/common/setup/asyncComponent';
-
-export default defineComponent({
-  emits: ['cancel', 'update'],
-  name: 'buy-sell-market',
-  props: {
-    selectedRow: {
-      type: Object as PropType<QueryQuoteDayRsp>,
-      default: () => ({}),
-    },
-  },
-  components: {
-    Chart,
-    LeftOutlined,
-    StockExchange,
-    trade: defineAsyncComponent(() => import('@/views/market/futures/compoments/futures-trade/index.vue')), // 期货交易
-  },
-  setup(props, context) {
-    const loading = ref<boolean>(false);
-    const { visible, cancel } = _closeModal(context);
-
-    const showComponentsId = ref<ComponentType>(ComponentType.chart);
-
-    const { componentId, closeComponent, openComponent } = handleModalComponent(() => { }, ref({}));
-
-    // 切换组件
-    function changeComponent(type: ComponentType) {
-      showComponentsId.value = type;
-    }
-    // 返回上层组件
-    function cancelAction() {
-      if (showComponentsId.value === ComponentType.chart) {
-        cancel();
-      } else {
-        showComponentsId.value = ComponentType.chart;
-      }
-    }
-    return {
-      cancel,
-      visible,
-      changeComponent,
-      ComponentType,
-      showComponentsId,
-      cancelAction,
-      handleSubcriteOnDemandQuote,
-      handleQuotePriceColor,
-      quoteChange,
-      quoteAmplitude,
-      quoteAmplituOfVibration,
-      componentId,
-      closeComponent,
-      openComponent,
-    };
-  },
-});
-</script>
-<style lang="less">
-.valNums {
-    .flex;
-    flex-direction: column;
-    padding-left: 20px;
-    .firstNum {
-        font-size: 18px;
-        line-height: 18px;
-        font-weight: 400;
-    }
-    .lastNum {
-        margin-top: 2px;
-        display: inline-flex;
-        font-size: 12px;
-        line-height: 12px;
-        font-weight: 300;
-    }
-}
-.inlineBar {
-    display: inline-flex;
-}
-.priceBar {
-    .flex;
-    flex-direction: column;
-    height: 32px;
-    .greenBar,
-    .redBar {
-        height: 16px;
-        line-height: 16px;
-    }
-}
-.start {
-    align-self: flex-start !important;
-    align-items: flex-start !important;
-}
-</style>

+ 0 - 229
src/views/market/market-spot/compoments/spot_trade_order_transaction/index.vue

@@ -1,229 +0,0 @@
-<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="refgoodscode"
-            ref="tableRef"
-            :data-source="goodsList"
-        >
-            <!-- <template #totalturnover="{ text }">
-        <span>{{changeUnit(text)}}</span>
-            </template>-->
-            <!-- 涨跌 -->
-            <template #change="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
-                >{{ quoteChange_out(record.refgoodscode) }}</span>
-            </template>
-            <!-- 幅度 -->
-            <template #amplitude="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
-                >{{ quoteAmplitude_out(record.refgoodscode) }}</span>
-            </template>
-            <!-- 振幅 -->
-            <template #vibration="{ record }">
-                <span>{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
-            </template>
-            <template #index="{ index }">
-                <span>{{ index + 1 }}</span>
-            </template>
-            <!-- 买价 -->
-            <!-- <template #bid="{ record }">
-        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'bid')">
-          {{getQuoteValue_out(record.refgoodscode, 'bid')}}</span>
-            </template>-->
-            <!-- 卖价 -->
-            <!-- <template #ask="{  record }">
-        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'ask')">
-          {{getQuoteValue_out(record.refgoodscode, 'ask')}}</span>
-            </template>-->
-            <!-- 最新价 -->
-            <template #last="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
-                >{{ getQuoteValue_out(record.refgoodscode, 'last') }}</span>
-            </template>
-            <!-- 开盘 -->
-            <template #opened="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'opened')"
-                >{{ getQuoteValue_out(record.refgoodscode, 'opened') }}</span>
-            </template>
-            <!-- 结算 -->
-            <template #settle="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'settle')"
-                >{{ getQuoteValue_out(record.refgoodscode, 'settle') }}</span>
-            </template>
-            <!-- 昨结算 -->
-            <template #presettle="{ record }">
-                <span>{{ getQuoteValue_out(record.refgoodscode, 'presettle') }}</span>
-            </template>
-            <!-- 最低价 -->
-            <template #lowest="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'lowest')"
-                >{{ getQuoteValue_out(record.refgoodscode, 'lowest') }}</span>
-            </template>
-            <!-- 最高价 -->
-            <template #highest="{ record }">
-                <span
-                    :class="handleQuotePriceColor_out(record.refgoodscode, 'highest')"
-                >{{ getQuoteValue_out(record.refgoodscode, 'highest') }}</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 { getShowBottomValue } from '@/common/config/constrolBottom';
-import { contextMenu, defineComponent } from '@/common/export/commonTable';
-import { handleTableEventAndData } from '@/common/setup/table/compose';
-import { TableParam } from '@/common/setup/table/interface';
-import { getQuoteValue_out, handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out } from '@/common/setup/table/tableQuote';
-import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
-import { QueryQuoteGoodsListRsp } from '@/services/go/Tjmd/interface';
-import { columnsList, getBtnList, useSwapList } 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<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
-        // 过滤标的合约
-        function goodsChange(value: string) {
-            filterGoodsList(value);
-            // 停止上次订阅
-            stopSubcribe();
-            // 重新发起订阅
-            stopSubcribe = handleSubcriteOnDemandQuote<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
-        }
-        return {
-            isBottom,
-            ...handleTableEventAndData<QueryQuoteDayRsp>(param),
-            btnList: getBtnList(true),
-            handleQuotePriceColor_out,
-            quoteChange_out,
-            quoteAmplitude_out,
-            quoteAmplituOfVibration,
-            getRefGoodsList,
-            goodsList,
-            loading,
-            goodsChange,
-            getQuoteValue_out,
-        };
-    },
-});
-</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>

+ 142 - 0
src/views/market/market-spot/components/buy-sell-market/components/buy/index.vue

@@ -0,0 +1,142 @@
+<template>
+    <!--  现货贸易 - 买卖大厅 - 卖报价牌 -->
+    <a-table
+        :columns="handleColumn(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="(record, index) => index"
+        :data-source="tableList"
+    >
+        <!-- ,  -->
+        <!-- 额外的展开行 -->
+        <template #expandedRowRender="{ record }">
+            <BtnList
+                :btnList="buttonList"
+                :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 { getBuyMarketParam } from '../../setup';
+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';
+
+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: {},
+        },
+        time: {
+            type: Object as PropType<Moment>,
+            default: moment(),
+        },
+    },
+    components: {
+        BtnList,
+        delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuoteDetail>();
+        const { wrpricetype, haswr, tableKey } = getBuyMarketParam(props.enumName);
+
+        const buttonList: BtnListType[] = [
+            { lable: '摘牌', code: 'delisting', className: 'operBtn' },
+        ]
+
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteDetailReq = {
+                buyorsell: 0,
+                wrpricetype,
+                haswr,
+                wrfactortypeid: props.parantSelectedRow.wrfactortypeid,
+                goodsid: props.parantSelectedRow.goodsid,
+            };
+            if (!haswr) {
+                // 无仓单 需要交收月过滤数据
+                param.deliverymonth = moment(props.time).format('YYYY-MM');
+            }
+            queryTable(queryOrderQuoteDetail, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: props.enumName,
+            tableName: tableKey,
+            tableFilterKey: [],
+            isDetail: false,
+        };
+        function handleColumn(columns: ColumnType[]) {
+            columns.forEach((item) => {
+                if (item.dataIndex == 'username') {
+                    delete item.width;
+                }
+            });
+            return columns;
+        }
+        function handleBtnList() { }
+        return {
+            isBottom,
+            ...handleComposeTable<WrOrderQuoteDetail>(param),
+            queryTableAction,
+            BuyOrSell,
+            loading,
+            tableList,
+            enumName: props.enumName,
+            expandIcon,
+            handleColumn,
+            buttonList,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 429 - 0
src/views/market/market-spot/components/buy-sell-market/components/delisting/index.vue

@@ -0,0 +1,429 @@
+<template>
+  <!-- 仓单贸易&仓单预售 买/卖 摘牌 -->
+  <Drawer
+    :title="'摘牌'"
+    :placement="'right'"
+    :visible="visible"
+    width="486px"
+    height="479px"
+    @cancel="cancel"
+    class="top"
+  >
+    <div class="delisting">
+      <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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{ selectedRow.username }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="基差" v-if="getListingMode(ListingMode.float)">
+                <span class="yellow ml8">{{ selectedRow.pricemove }}</span>
+              </a-form-item>
+              <a-form-item label="挂牌价格" v-if="!getListingMode(ListingMode.float)">
+                <span class="yellow ml8">{{ selectedRow.fixedprice }}</span>
+              </a-form-item>
+              <a-row :gutter="24">
+                <a-col :span="24"></a-col>
+              </a-row>
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="isBuy() && getAuctionwrType(AuctionwrType.hasWr)">
+            <a-col :span="24">
+              <a-form-item label="现货仓单" name="LadingBillId">
+                <a-select
+                  class="inlineFormSelect"
+                  style="width: 260px"
+                  v-model:value="formState.LadingBillId"
+                  placeholder="请选择"
+                >
+                  <a-select-option
+                    v-for="item in wrHoldList"
+                    :value="item.id"
+                    :key="item.id"
+                  >{{ item.name }}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量" class="relative" name="num">
+                <a-input-number
+                  class="dialogInput yellowInput"
+                  style="width: 260px"
+                  :min="0"
+                  :max="getMaxNum()"
+                  v-model:value="formState.num"
+                />
+                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
+                <div class="labelTip">({{ selectedRow.delistminqty }}{{ selectedRow.enumdicname }}起)</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item>
+                <a-slider
+                  :min="0"
+                  v-model:value="formState.num"
+                  :max="selectedRow.orderqty"
+                  class="formSlider"
+                  style="width: 260px;"
+                />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{ getMaxNum() }}{{ selectedRow.enumdicname }}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-col :span="24" v-if="getListingMode(ListingMode.float)">
+            <a-form-item label="估算价" name="PriceMove">
+              <span class="white">{{ getPrice() }}</span>
+            </a-form-item>
+          </a-col>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item :label="getListingMode(ListingMode.float) ? '估算金额' : '摘牌金额'">
+                <span class="white ml8">{{ getMoney() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="getMargin()">
+            <a-col :span="24">
+              <a-form-item :label="getMargin() ? '履约保证金' : ''">
+                <a-row>
+                  <a-col :span="24">
+                    <span class="white ml8">{{ getMargin() }}</span>
+                  </a-col>
+                </a-row>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <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"
+                :loading="loading"
+                :disabled="loading"
+                @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 { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { WrOrderQuote, WrOrderQuoteDetail } from '@/services/go/wrtrade/interface';
+import { getAccountTypeList, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { HdWRDealOrder } from '@/services/proto/warehousetrade';
+import { v4 as uuidv4 } from 'uuid';
+import moment from 'moment';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { HdWRDealOrderReq } from '@/services/proto/warehousetrade/interface';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { handleForm, handleNumAndMoney, handleSpotWarrant, getWrPosition } from './setup';
+import { validateAction } from '@/common/setup/form';
+import { ListingForm, TempWrOrderQuoteDetail } from './interface';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { getCanUseMoney } from '@/services/bus/account';
+import { getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import { message } from 'ant-design-vue';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { TradeMode, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
+
+export default defineComponent({
+  name: ModalEnum.spot_trade_warehouse_financing_delisting,
+  components: { Drawer, PlusOutlined, MinusOutlined },
+  emits: ['cancel', 'update'],
+  props: {
+    enumName: {
+      default: '',
+      type: String as PropType<EnumRouterName>,
+    },
+    selectedRow: {
+      type: Object as PropType<TempWrOrderQuoteDetail>,
+      default: {},
+    },
+    parantSelectedRow: {
+      type: Object as PropType<WrOrderQuote>,
+      default: {},
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      default: BuyOrSell.buy,
+    },
+  },
+
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    // 资金账号
+    const accountList = getAccountTypeList([2]);
+    const { rules, formState, formRef } = handleForm(props.selectedRow);
+    if (accountList.length) {
+      formState.accountid = accountList[0].accountid;
+    }
+    function getSelectedAccount() {
+      return accountList.find((e) => e.accountid === formState.accountid);
+    }
+    const loading = ref<boolean>(false);
+    const isBuy = () => props.buyOrSell === BuyOrSell.buy
+    // 现货仓单
+    const { wrHoldList } = handleSpotWarrant(props.enumName, props.buyOrSell, props.parantSelectedRow, loading);
+    getWrPosition(props.enumName, props.buyOrSell, loading);
+    const { getMaxNum, getMoney, getMargin } = handleNumAndMoney(props.enumName, props.buyOrSell, props.selectedRow, props.parantSelectedRow, formState);
+    // 估算价
+    function getPrice() {
+      let result = '--';
+      const goodsPrice = getQuoteDayInfoByCodeFindPrice(props.parantSelectedRow.goodscode);
+      if (goodsPrice && goodsPrice !== '--' && props.selectedRow.pricemove !== null) {
+        // 有实时行情价格
+        result = ((goodsPrice as number) + props.selectedRow.pricemove).toFixed(2);
+      }
+
+      return result;
+    }
+    function submit() {
+      if (getMaxNum() === 0) {
+        message.error('没有可用的预售仓单头寸');
+        return;
+      }
+      validateAction<ListingForm>(formRef, formState).then((res) => {
+        // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
+        // 其次判断  摘牌 1。摘买 (需要通过自己的仓单进行摘买)  2。摘卖 (不需要通过仓单)
+        const param: HdWRDealOrderReq = {
+          UserID: getUserId(), // uint32 用户ID
+          AccountID: getSelectedAccountId(), // uint64 资金账号
+          RelatedWRTradeOrderID: props.selectedRow.wrtradeorderid, // uint64 关联委托单号(摘牌委托关联挂牌委托单ID)
+          WRTransferUserID: props.selectedRow.userid, // uint32 仓单受让用户
+          OrderQty: res.num as number, // uint64 委托数量
+          OrderSrc: 0, // uint32 委托来源
+          ClientSerialNo: uuidv4(), // string 客户端流水号
+          ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // string 客户端委托时间
+          ClientType: 4, // uint32 终端类型
+          OperatorID: getUserId(), // uint64 操作员账号ID
+          BuyOrSell: 0, // uint32 买卖方向
+          ApplyID: 0, // uint64 申请ID
+          LadingBillId: 0, // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
+          SubNum: 0, // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
+          WRFactorTypeId: props.parantSelectedRow.wrfactortypeid, // uint64 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写
+          TradeDate: moment().format('YYYYMMDD'), // string 交易日
+          DeliveryMonth: '', // string 交收月
+          HasWr: getAuctionwrType(AuctionwrType.noWr) ? 0 : 1, // uint32 是否有仓单-0:没有仓单 1:有仓单
+          IsFinancing: 0, // uint32 是否融资购买(买摘牌时有效)-0:否 1:是
+          ProductDetailID: 0, // uint64 金融机构产品组合ID(融资购买时有效)
+        };
+        // 摘买方向
+        if (isBuy()) {
+          param.BuyOrSell = 1;
+          param.LadingBillId = res.LadingBillId as string;
+          const item = wrHoldList.value.find((el) => el.id === res.LadingBillId);
+          if (item) {
+            param.SubNum = +item.subnum;
+          } else {
+            param.LadingBillId = 0;
+          }
+        } else {
+          param.BuyOrSell = 0;
+        }
+
+        requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
+          cancel(true);
+        });
+      });
+    }
+
+    return {
+      visible,
+      cancel,
+      accountList,
+      wrHoldList,
+      loading,
+      submit,
+      isBuy,
+      rules,
+      formState,
+      formRef,
+      getCanUseMoney,
+      getSelectedAccount,
+      getMaxNum,
+      getMoney,
+      getMargin,
+      getPrice,
+      getAuctionwrType, getListingMode, ListingMode, AuctionwrType
+    };
+  },
+});
+</script>
+
+<style lang="less">
+.delisting {
+  width: 100%;
+  height: 100%;
+  .flex;
+  flex-direction: column;
+  overflow: hidden;
+  .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;
+    }
+  }
+  .ant-form {
+    height: 100%;
+  }
+}
+::v-deep.ant-slider.formSlider {
+  width: 260px;
+}
+::v-deep.ant-input-suffix {
+  position: absolute;
+  right: -25px;
+}
+.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%);
+  &:hover,
+  &:active,
+  &:focus,
+  &::after {
+    background: linear-gradient(
+      0deg,
+      @m-grey12-hover 0%,
+      @m-grey13-hover 100%
+    ) !important;
+    color: @m-white0-hover !important;
+    border: 0 !important;
+  }
+}
+.ml10 {
+  margin-left: 10px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item {
+  margin-bottom: 14px;
+}
+.mt20 {
+  margin-top: 20px;
+}
+.mt-20 {
+  margin-top: -20px;
+}
+.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;
+}
+</style>;

+ 1 - 1
src/views/market/spot_trade/spot_trade_order_transaction/components/delisting/interface.ts → src/views/market/market-spot/components/buy-sell-market/components/delisting/interface.ts

@@ -3,7 +3,7 @@ import { WrOrderQuoteDetail } from "@/services/go/wrtrade/interface";
 export interface ListingForm {
     accountid: undefined | number,
     num: number,
-    LadingBillId: string,
+    LadingBillId: string | number,
 }
 
 export interface Wrhold {

+ 16 - 18
src/views/market/spot_trade/components/buy-sell-market/components/delisting/setup.ts → src/views/market/market-spot/components/buy-sell-market/components/delisting/setup.ts

@@ -1,4 +1,4 @@
-import { BuyOrSell } from "@/common/constants/enumCommon";
+import { AuctionwrType, BuyOrSell, ListingMode } from '@/common/constants/enumCommon';
 import { EnumRouterName } from "@/common/constants/enumRouterName";
 import { queryResultLoadingAndInfo } from "@/common/methods/request/resultInfo";
 import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
@@ -7,10 +7,12 @@ import { getRules } from '@/services/bus/rules';
 import { AccountListItem } from "@/services/dataCenter/interafce/account";
 import { queryHoldLB, queryWrPosition } from '@/services/go/wrtrade';
 import { QueryWrPositionReq, WrHoldLB, WrOrderQuote, WrOrderQuoteDetail, WrPosition } from "@/services/go/wrtrade/interface";
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup';
 import { reactive, Ref, ref, UnwrapRef } from "vue";
-import { handleIs } from "../../setup";
 import { ListingForm, Wrhold } from "./interface";
 
+const isBuy = (buyOrSell: BuyOrSell) => buyOrSell === BuyOrSell.buy
+
 export function handleForm(data: WrOrderQuoteDetail) {
     const formRef = ref();
     const formState: UnwrapRef<ListingForm> = reactive({
@@ -30,8 +32,7 @@ export function handleForm(data: WrOrderQuoteDetail) {
 // 预售仓单汇总
 const wrPostion = ref<WrPosition[]>([])
 export function getWrPosition(enumName: EnumRouterName, buyOrSell: BuyOrSell, loading: Ref<boolean>) {
-    const { isWR, isBuy } = handleIs(enumName, buyOrSell)
-    if (isBuy() && !isWR()) {
+    if (isBuy(buyOrSell) && getAuctionwrType(AuctionwrType.noWr)) {
         const param: QueryWrPositionReq = {
             haswr: 0,
             querytype: 2,
@@ -45,13 +46,11 @@ export function getWrPosition(enumName: EnumRouterName, buyOrSell: BuyOrSell, lo
 const allWR = ref<WrHoldLB[]>([])
 // 处理现货仓单
 export function handleSpotWarrant(enumName: EnumRouterName, buyOrSell: BuyOrSell, selectedRow: WrOrderQuote, loading: Ref<boolean>) {
-    const { isWR, isBuy } = handleIs(enumName, buyOrSell)
     const wrHoldList = ref<Wrhold[]>([])
-    if (isBuy()) {
-        if (isWR()) {
+    if (isBuy(buyOrSell)) {
+        if (getAuctionwrType(AuctionwrType.hasWr)) {
             queryResultLoadingAndInfo(queryHoldLB, loading).then(res => {
                 allWR.value = res;
-                wrHoldList.value = []
                 wrHoldList.value.length = 0
                 res.forEach(e => {
                     if (e.wrfactortypeid === String(selectedRow.wrfactortypeid)) {
@@ -67,7 +66,6 @@ export function handleSpotWarrant(enumName: EnumRouterName, buyOrSell: BuyOrSell
 }
 
 export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell, selectedRow: WrOrderQuoteDetail, parantSelectedRow: WrOrderQuote, formState: UnwrapRef<ListingForm>) {
-    const { isWR, isBuy, isFloat } = handleIs(enumName, buyOrSell)
     // 资金账号
     const accountList = getAccountTypeList([2]);
     // 获取选中的资金账号
@@ -86,11 +84,11 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
         if (hasRule()) {
             // 可用资金
             const canUseMoney = Number(getCanUseMoney(getSelectedAccount() as AccountListItem))
-            if (!isBuy()) {
-                if (isFloat()) {
+            if (!isBuy(buyOrSell)) {
+                if (getListingMode(ListingMode.float)) {
                     const goodsPrice = getQuoteDayInfoByCodeFindPrice(parantSelectedRow.goodscode);
                     // 估算总价=挂牌基差+期货合约价;
-                    if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+                    if (goodsPrice && goodsPrice !== '--' && pricemove !== null) {   // 有实时行情价格
                         // 估算总价
                         const predictTotal = pricemove + (goodsPrice as number);
                         // 买方履约保证金比例*估算总价
@@ -105,10 +103,10 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
                     result = Math.min(orderqty, canUseMoney / marginMoney)
                 }
             } else {
-                if (isWR()) {
+                if (getAuctionwrType(AuctionwrType.hasWr)) {
                     if (formState.LadingBillId) {
                         // 现货库存数量
-                        const warehouseNum = allWR.value.find((e) => e.ladingbillid === formState.LadingBillId)?.enableqty;
+                        const warehouseNum = allWR.value.find((e) => String(e.ladingbillid) === String(formState.LadingBillId))?.enableqty;
                         // 仓单贸易 一口价/浮动价 摘卖 最大数量=min(现货库存可用数量,挂牌数量),现货库存数量为所选仓单数量
                         if (warehouseNum) {
                             result = Math.min(orderqty, warehouseNum)
@@ -118,7 +116,7 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
                     // 获取头寸
                     const item = wrPostion.value.find(e => String(e.wrfactortypeid) === String(parantSelectedRow.wrfactortypeid))
                     if (item) {
-                        result = item.enalbeqty
+                        result = Math.min(item.creditenableqty, selectedRow.orderqty)
                     }
                 }
             }
@@ -128,10 +126,10 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
     //  摘牌金额
     function getMoney() {
         let result = 0
-        if (isFloat()) {
+        if (getListingMode(ListingMode.float)) {
             const goodsPrice = getQuoteDayInfoByCodeFindPrice(parantSelectedRow.goodscode);
             const agreeunit = getGoodsAgreeunitByGoodsCode(parantSelectedRow.goodscode);
-            if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+            if (goodsPrice && goodsPrice !== '--' && pricemove !== null) {   // 有实时行情价格
                 // 估算总价=挂牌基差+期货合约价;
                 const predictTotal = pricemove + (goodsPrice as number);
                 // 估算总额=估算总价*摘牌数量;
@@ -152,7 +150,7 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
         let result = 0
         if (hasRule()) {
             const { buymarginvalue, sellmarginvalue } = rules[0]
-            const margin = isBuy() ? sellmarginvalue : buymarginvalue
+            const margin = isBuy(buyOrSell) ? sellmarginvalue : buymarginvalue
             result = marginMethod() ? margin * getMoney() : margin + getMoney()
         }
         return Number(result.toFixed(2))

+ 48 - 50
src/views/market/spot_trade/components/buy-sell-market/components/financing_delisting/components/choose-finance/index.vue → src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/components/choose-finance/index.vue

@@ -1,57 +1,55 @@
 <template>
-    <!-- 仓单贸易&仓单预售 融资-->
+  <!-- 仓单贸易&仓单预售 融资-->
 
-    <Drawer
-        :title="'选择融资方案'"
-        :placement="'right'"
-        :visible="visible"
-        width="486px"
-        height="580px"
-        @cancel="update"
-        class="topHigh financing"
-    >
-        <div class="financingCont">
-            <a-row class="f-t">
-                <a-col :span="7">融出方/名称</a-col>
-                <a-col :span="10">天数/保证金/利息</a-col>
-                <a-col :span="7">结息/起息天数</a-col>
-            </a-row>
-            <div
-                class="contBar"
-                v-for="(item, index) in list"
-                :key="index + 11"
-                @click="choose(item)"
-            >
-                <a-row class="firstRow">
-                    <a-col :span="17">{{item.username}}</a-col>
-                    <a-col :span="7" v-if="item.isautoloan">放款快</a-col>
-                </a-row>
-                <a-row class="secondRow">
-                    <a-col :span="7">{{item.productname}}</a-col>
-                    <a-col :span="10">
-                        <a-row class="middle">
-                            <a-col :span="7">{{item.financingdays}}天</a-col>
-                            <a-col :span="10">{{(item.marginratio * 100).toFixed(2)}}%</a-col>
-                            <a-col :span="7">
-                                <!-- <div class="two">{{item.interestrate * 100}}%</div>
+  <Drawer :title="'选择融资方案'"
+          :placement="'right'"
+          :visible="visible"
+          width="486px"
+          height="580px"
+          @cancel="update"
+          class="topHigh financing">
+    <div class="financingCont">
+      <a-row class="f-t">
+        <a-col :span="7">融出方/名称</a-col>
+        <a-col :span="10">天数/保证金/利息</a-col>
+        <a-col :span="7">结息/起息天数</a-col>
+      </a-row>
+      <div class="contBar"
+           v-for="(item, index) in list"
+           :key="index + 11"
+           @click="choose(item)">
+        <a-row class="firstRow">
+          <a-col :span="17">{{item.username}}</a-col>
+          <a-col :span="7"
+                 v-if="item.isautoloan">放款快</a-col>
+        </a-row>
+        <a-row class="secondRow">
+          <a-col :span="7">{{item.productname}}</a-col>
+          <a-col :span="10">
+            <a-row class="middle">
+              <a-col :span="7">{{item.financingdays}}天</a-col>
+              <a-col :span="10">{{(item.marginratio * 100).toFixed(2)}}%</a-col>
+              <a-col :span="7">
+                <!-- <div class="two">{{item.interestrate * 100}}%</div>
                                 <div class="two">{{item.interestrate * 100}}%</div>-->
-                                {{item.interestratemode === 3 ? item.interestrate : (item.interestrate * 10000).toFixed(2)}}{{item.interestratemode === 3 ? '' : '‱'}}
-                            </a-col>
-                        </a-row>
-                    </a-col>
-                    <a-col :span="7">
-                        <div class="settle">
-                            <div>{{item.interestsettlemode === 1 ? '日' : '月'}}结</div>
-                            <div>{{item.interestminlen}}天起息</div>
-                        </div>
-                    </a-col>
-                </a-row>
-            </div>
-            <div class="noDataContBar" v-if="!list.length">
-                <div class="noData"></div>
+                {{item.interestratemode === 3 ? item.interestrate : (item.interestrate * 10000).toFixed(2)}}{{item.interestratemode === 3 ? `/${selectedRow.enumdicname }` : '‱'}}
+              </a-col>
+            </a-row>
+          </a-col>
+          <a-col :span="7">
+            <div class="settle">
+              <div>{{item.interestsettlemode === 1 ? '日' : '月'}}结</div>
+              <div>{{item.interestminlen}}天起息</div>
             </div>
-        </div>
-    </Drawer>
+          </a-col>
+        </a-row>
+      </div>
+      <div class="noDataContBar"
+           v-if="!list.length">
+        <div class="noData"></div>
+      </div>
+    </div>
+  </Drawer>
 </template>
 
 <script lang="ts">

+ 523 - 0
src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/index.vue

@@ -0,0 +1,523 @@
+<template>
+  <!-- 仓单贸易&仓单预售 买/卖 摘牌 -->
+  <Drawer
+    :title="'摘牌'"
+    :placement="'right'"
+    :visible="visible"
+    width="486px"
+    height="580px"
+    @cancel="cancel"
+    class="top"
+  >
+    <div class="delisting">
+      <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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{ selectedRow.username }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="基差" v-if="getListingMode(ListingMode.float)">
+                <span class="yellow ml8">{{ selectedRow.pricemove }}</span>
+              </a-form-item>
+              <a-form-item label="挂牌价格" v-if="!getListingMode(ListingMode.float)">
+                <span class="yellow ml8">{{ selectedRow.fixedprice }}</span>
+              </a-form-item>
+              <a-row :gutter="24">
+                <a-col :span="24"></a-col>
+              </a-row>
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-10">
+              <a-form-item
+                label="融资方案"
+                @click="openComponent({ code: 'ChooseFinance' })"
+                name="caseId"
+              >
+                <div class="way">
+                  <div class="left">{{ formState.case ? formState.case : '请选择' }}</div>
+                  <div class="right">
+                    <svg class="icon svg-icon" aria-hidden="true">
+                      <use xlink:href="#icon-fangan" />
+                    </svg>
+                  </div>
+                </div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="isBuy() && getAuctionwrType(AuctionwrType.hasWr)">
+            <a-col :span="24">
+              <a-form-item label="现货仓单" name="LadingBillId">
+                <a-select
+                  class="inlineFormSelect"
+                  style="width: 260px"
+                  v-model:value="formState.LadingBillId"
+                  placeholder="请选择"
+                >
+                  <a-select-option
+                    v-for="item in wrHoldList"
+                    :value="item.id"
+                    :key="item.id"
+                  >{{ item.name }}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量" class="relative" name="num">
+                <a-input-number
+                  class="dialogInput yellowInput"
+                  style="width: 260px"
+                  :min="0"
+                  :max="getMaxNum()"
+                  v-model:value="formState.num"
+                />
+                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
+                <div class="labelTip">({{ selectedRow.delistminqty }}{{ selectedRow.enumdicname }}起)</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item>
+                <a-slider
+                  :min="0"
+                  v-model:value="formState.num"
+                  :max="selectedRow.orderqty"
+                  class="formSlider"
+                  style="width: 260px;"
+                />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{ getMaxNum() }}{{ selectedRow.enumdicname }}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-col :span="24" v-if="getListingMode(ListingMode.float)">
+            <a-form-item label="估算价" name="PriceMove">
+              <span class="white">{{ getPrice() }}</span>
+            </a-form-item>
+          </a-col>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item :label="getListingMode(ListingMode.float) ? '估算金额' : '摘牌金额'">
+                <span class="white ml8">{{ getMoney() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="getMargin()">
+            <a-col :span="24">
+              <a-form-item :label="getMargin() ? '履约保证金' : ''">
+                <!-- <a-row>
+                <a-col :span="8">-->
+                <span class="white ml8">{{ getMargin() }}</span>
+                <!-- </a-col>
+                                    <a-col :span="5" class="tr">
+                                        <span class="grey1">可用资金</span>
+                                    </a-col>
+                                    <a-col :span="11">
+                                        <span
+                                            class="white ml8"
+                                        >{{getCanUseMoney(getSelectedAccount())}}</span>
+                                    </a-col>
+                </a-row>-->
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <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"
+                :loading="loading"
+                :disabled="loading"
+                @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>
+  <component
+    :is="componentId"
+    v-if="componentId"
+    :selectedRow="selectedRow"
+    :isFloat="getListingMode(ListingMode.float)"
+    @update="choose"
+    @cancel="closeComponent"
+  ></component>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent, onMounted, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { WrOrderQuote, WrOrderQuoteDetail } from '@/services/go/wrtrade/interface';
+import { getAccountTypeList, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { handleForm, handleSpotWarrant } from './setup';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { handleModalComponent } from '@/common/setup/asyncComponent';
+import { WrFAProductDetail } from '@/services/go/wrtrade/interface';
+import { validateAction } from '@/common/setup/form';
+import { handleNumAndMoney, getWrPosition, selecedFinance } from './setup';
+import { getCanUseMoney } from '@/services/bus/account';
+import Bus from '@/utils/eventBus/index';
+import { ListingForm } from '@/views/market/market-spot/components/buy-sell-market/components/financing_delisting/interface';
+import { HdWRDealOrderReq } from '@/services/proto/warehousetrade/interface';
+import { v4 as uuidv4 } from 'uuid';
+import moment from 'moment';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { HdWRDealOrder } from '@/services/proto/warehousetrade';
+import { getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { TradeMode, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
+
+export default defineComponent({
+  name: ModalEnum.spot_trade_warehouse_delisting,
+  components: { Drawer, ChooseFinance: defineAsyncComponent(() => import('./components/choose-finance/index.vue')) },
+  emits: ['cancel', 'update'],
+  props: {
+    enumName: {
+      default: '',
+      type: String as PropType<EnumRouterName>,
+    },
+    selectedRow: {
+      type: Object as PropType<WrOrderQuoteDetail>,
+      default: {},
+    },
+    parantSelectedRow: {
+      type: Object as PropType<WrOrderQuote>,
+      default: {},
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      default: BuyOrSell.buy,
+    },
+  },
+
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    // 资金账号
+    const accountList = getAccountTypeList([2]);
+    const { rules, formState, formRef } = handleForm(props.selectedRow);
+    if (accountList.length) {
+      formState.accountid = accountList[0].accountid;
+    }
+    function getSelectedAccount() {
+      return accountList.find((e) => e.accountid === formState.accountid);
+    }
+    const loading = ref<boolean>(false);
+    const isBuy = () => props.buyOrSell === BuyOrSell.buy
+    // 现货仓单
+    const { wrHoldList } = handleSpotWarrant(props.enumName, props.buyOrSell, props.parantSelectedRow, loading);
+    getWrPosition(props.enumName, props.buyOrSell, loading);
+    const { getMaxNum, getMoney, getMargin } = handleNumAndMoney(props.enumName, props.buyOrSell, props.selectedRow, props.parantSelectedRow, formState);
+
+    const { componentId, closeComponent, openComponent } = handleModalComponent(() => { }, ref({}));
+
+    // 估算价
+    function getPrice() {
+      let result = '--';
+      const goodsPrice = getQuoteDayInfoByCodeFindPrice(props.parantSelectedRow.goodscode);
+      if (goodsPrice && goodsPrice !== '--') {
+        // 有实时行情价格
+        result = ((goodsPrice as number) + props.selectedRow.pricemove).toFixed(2);
+      }
+
+      return result;
+    }
+
+    const show = ref<boolean>(false);
+    function showAction() {
+      show.value = !show.value;
+    }
+    function choose(item: WrFAProductDetail) {
+      selecedFinance.value = item;
+      formState.caseId = item.productdetailid;
+      formState.case = `${item.productname}-${item.username}-${item.financingdays}天-${(item.marginratio * 100).toFixed(2)}%-${item.interestratemode === 3 ? item.interestrate : (item.interestrate * 10000).toFixed(2)}${item.interestratemode === 3 ? `/${props.selectedRow.enumdicname}` : '‱'}-${item.interestsettlemode === 1 ? '按日结息' : '按月结息'}-${item.interestminlen}天起息`;
+    }
+    function submit() {
+      validateAction<ListingForm>(formRef, formState).then((res) => {
+        // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
+        // 其次判断  摘牌 1。摘买 (需要通过自己的仓单进行摘买)  2。摘卖 (不需要通过仓单)
+        const param: HdWRDealOrderReq = {
+          UserID: getUserId(), // uint32 用户ID
+          AccountID: getSelectedAccountId(), // uint64 资金账号
+          RelatedWRTradeOrderID: props.selectedRow.wrtradeorderid, // uint64 关联委托单号(摘牌委托关联挂牌委托单ID)
+          WRTransferUserID: props.selectedRow.userid, // uint32 仓单受让用户
+          OrderQty: res.num as number, // uint64 委托数量
+          OrderSrc: 0, // uint32 委托来源
+          ClientSerialNo: uuidv4(), // string 客户端流水号
+          ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // string 客户端委托时间
+          ClientType: 4, // uint32 终端类型
+          OperatorID: getUserId(), // uint64 操作员账号ID
+          BuyOrSell: 0, // uint32 买卖方向
+          ApplyID: 0, // uint64 申请ID
+          // LadingBillId: 0, // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
+          SubNum: 0, // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
+          WRFactorTypeId: props.parantSelectedRow.wrfactortypeid, // uint64 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写
+          TradeDate: moment().format('YYYYMMDD'), // string 交易日
+          DeliveryMonth: '', // string 交收月
+          HasWr: getAuctionwrType(AuctionwrType.noWr) ? 0 : 1, // uint32 是否有仓单-0:没有仓单 1:有仓单
+          IsFinancing: 1, // uint32 是否融资购买(买摘牌时有效)-0:否 1:是
+          ProductDetailID: res.caseId, // uint64 金融机构产品组合ID(融资购买时有效)
+        };
+        // 摘买方向
+        if (isBuy()) {
+          param.BuyOrSell = 1;
+          param.LadingBillId = res.LadingBillId;
+          const item = wrHoldList.value.find((el) => el.id === res.LadingBillId);
+          if (item) {
+            param.SubNum = +item.subnum;
+          }
+        } else {
+          param.BuyOrSell = 0;
+        }
+
+        requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['融资摘牌成功', '融资摘牌失败:']).then(() => {
+          cancel(true);
+        });
+      });
+    }
+
+    return {
+      visible,
+      cancel,
+      choose,
+      accountList,
+      wrHoldList,
+      submit,
+      getMaxNum,
+      getMoney,
+      getMargin,
+      isBuy,
+      rules,
+      formState,
+      formRef,
+      show,
+      showAction,
+      componentId,
+      closeComponent,
+      openComponent,
+      getCanUseMoney,
+      getSelectedAccount,
+      getPrice,
+      getAuctionwrType, getListingMode, ListingMode, AuctionwrType
+    };
+  },
+});
+</script>
+
+<style lang="less">
+.delisting {
+  width: 100%;
+  height: 100%;
+  .flex;
+  flex-direction: column;
+  z-index: 10;
+  overflow: hidden;
+  .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;
+    }
+  }
+  .ant-form {
+    height: 100%;
+  }
+  .need {
+    color: @m-grey0;
+    font-size: 12px;
+    margin-left: 10px;
+  }
+  .tip {
+    .position(absolute, 20px, auto, auto, 0);
+    font-size: 12px;
+    z-index: 10;
+    color: @m-red1;
+    white-space: nowrap;
+  }
+  .way {
+    display: inline-flex;
+    width: 300px;
+    overflow: hidden;
+    background: @m-grey21;
+    border: 1px solid @m-grey14;
+    .rounded-corners(3px);
+    .left {
+      width: 260px;
+      .flex;
+      line-height: 25px;
+      padding: 5px;
+      color: @m-white6;
+      font-size: 14px;
+      text-overflow: -o-ellipsis-lastline;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-line-clamp: 2;
+      line-clamp: 2;
+      -webkit-box-orient: vertical;
+    }
+    .right {
+      width: 40px;
+      height: 60px;
+      background: @m-blue18;
+      border: 1px solid @m-blue0;
+      .rounded-corners(3px);
+      .flex;
+      justify-content: center;
+      .icon {
+        align-self: center;
+        align-items: center;
+        font-size: 24px;
+      }
+    }
+  }
+}
+::v-deep.ant-slider.formSlider {
+  width: 260px;
+}
+::v-deep.ant-input-suffix {
+  position: absolute;
+  right: -25px;
+}
+.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;
+}
+.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;
+}
+</style>;

+ 0 - 0
src/views/market/spot_trade/components/buy-sell-market/components/financing_delisting/interface.ts → src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/interface.ts


+ 12 - 30
src/views/market/spot_trade/components/buy-sell-market/components/financing_delisting/setup.ts → src/views/market/market-spot/components/buy-sell-market/components/financing_delisting/setup.ts

@@ -1,4 +1,4 @@
-import { BuyOrSell } from "@/common/constants/enumCommon";
+import { AuctionwrType, BuyOrSell, ListingMode } from '@/common/constants/enumCommon';
 import { EnumRouterName } from "@/common/constants/enumRouterName";
 import { queryResultLoadingAndInfo } from "@/common/methods/request/resultInfo";
 import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
@@ -7,10 +7,12 @@ import { getRules } from '@/services/bus/rules';
 import { AccountListItem } from "@/services/dataCenter/interafce/account";
 import { queryHoldLB, queryWrPosition } from '@/services/go/wrtrade';
 import { QueryWrPositionReq, WrFAProductDetail, WrHoldLB, WrOrderQuote, WrOrderQuoteDetail, WrPosition } from "@/services/go/wrtrade/interface";
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup';
 import { reactive, Ref, ref, UnwrapRef } from "vue";
-import { handleIs } from "../../setup";
 import { ListingForm, Wrhold } from "./interface";
 
+const isBuy = (buyOrSell: BuyOrSell) => buyOrSell === BuyOrSell.buy
+
 export const selecedFinance = ref<WrFAProductDetail>()
 
 export function handleForm(data: WrOrderQuoteDetail) {
@@ -35,8 +37,7 @@ export function handleForm(data: WrOrderQuoteDetail) {
 // 预售仓单汇总
 const wrPostion = ref<WrPosition[]>([])
 export function getWrPosition(enumName: EnumRouterName, buyOrSell: BuyOrSell, loading: Ref<boolean>) {
-    const { isWR, isBuy } = handleIs(enumName, buyOrSell)
-    if (isBuy() && !isWR()) {
+    if (isBuy(buyOrSell) && getAuctionwrType(AuctionwrType.noWr)) {
         const param: QueryWrPositionReq = {
             haswr: 0,
             querytype: 2,
@@ -50,10 +51,9 @@ export function getWrPosition(enumName: EnumRouterName, buyOrSell: BuyOrSell, lo
 const allWR = ref<WrHoldLB[]>([])
 // 处理现货仓单
 export function handleSpotWarrant(enumName: EnumRouterName, buyOrSell: BuyOrSell, selectedRow: WrOrderQuote, loading: Ref<boolean>) {
-    const { isWR, isBuy } = handleIs(enumName, buyOrSell)
     const wrHoldList = ref<Wrhold[]>([])
-    if (isBuy()) {
-        if (isWR()) {
+    if (isBuy(buyOrSell)) {
+        if (getAuctionwrType(AuctionwrType.hasWr)) {
             queryResultLoadingAndInfo(queryHoldLB, loading).then(res => {
                 allWR.value = res;
                 wrHoldList.value.length = 0
@@ -70,25 +70,7 @@ export function handleSpotWarrant(enumName: EnumRouterName, buyOrSell: BuyOrSell
     return { wrHoldList }
 }
 
-// // 处理现货仓单
-// export function handleSpotWarrant(enumName: EnumRouterName, buyOrSell: BuyOrSell, selectedRow: WrOrderQuote, loading: Ref<boolean>) {
-//     const { isWR, isBuy } = handleIs(enumName, buyOrSell)
-//     const wrHoldList = ref<Wrhold[]>([])
-//     if (isBuy()) {
-//         if (isWR()) {
-//             queryResultLoadingAndInfo(queryHoldLB, loading).then(res => {
-//                 wrHoldList.value = res.filter((e: WrHoldLB) => e.wrfactortypeid === String(selectedRow.wrfactortypeid)).map((e: WrHoldLB) => {
-//                     const { wrholdeno, enableqty, ladingbillid } = e
-//                     return { id: ladingbillid, name: `${wrholdeno}(${enableqty})` }
-//                 })
-//             })
-//         }
-//     }
-//     return { wrHoldList }
-// }
-
 export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell, selectedRow: WrOrderQuoteDetail, parantSelectedRow: WrOrderQuote, formState: UnwrapRef<ListingForm>) {
-    const { isWR, isBuy, isFloat } = handleIs(enumName, buyOrSell)
     // 资金账号
     const accountList = getAccountTypeList([2]);
     // 获取选中的资金账号
@@ -107,11 +89,11 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
         if (hasRule()) {
             // 可用资金
             const canUseMoney = Number(getCanUseMoney(getSelectedAccount() as AccountListItem))
-            if (!isBuy()) {
-                if (isFloat()) {
+            if (!isBuy(buyOrSell)) {
+                if (getListingMode(ListingMode.float)) {
                     const goodsPrice = getQuoteDayInfoByCodeFindPrice(parantSelectedRow.goodscode);
                     // 估算总价=挂牌基差+期货合约价;
-                    if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+                    if (goodsPrice && goodsPrice !== '--' && pricemove !== null) {   // 有实时行情价格
                         // 估算总价
                         const predictTotal = pricemove + (goodsPrice as number);
                         // 买方履约保证金比例*估算总价
@@ -126,7 +108,7 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
                     result = Math.min(orderqty, canUseMoney / marginMoney)
                 }
             } else {
-                if (isWR()) {
+                if (getAuctionwrType(AuctionwrType.hasWr)) {
                     if (formState.LadingBillId) {
                         // 现货库存数量
                         const warehouseNum = allWR.value.find((e) => e.ladingbillid === formState.LadingBillId)?.enableqty;
@@ -149,7 +131,7 @@ export function handleNumAndMoney(enumName: EnumRouterName, buyOrSell: BuyOrSell
     //  摘牌金额
     function getMoney() {
         let result = 0
-        if (isFloat()) {
+        if (getListingMode(ListingMode.float)) {
             const goodsPrice = getQuoteDayInfoByCodeFindPrice(parantSelectedRow.goodscode);
             const agreeunit = getGoodsAgreeunitByGoodsCode(parantSelectedRow.goodscode);
             if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格

+ 149 - 0
src/views/market/market-spot/components/buy-sell-market/components/sell/index.vue

@@ -0,0 +1,149 @@
+<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="(record, index) => index"
+        :data-source="tableList"
+    >
+        <!-- 额外的展开行 -->
+        <template #expandedRowRender="{ record }">
+            <BtnList :btnList="buttonList" :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, ref } from 'vue';
+import { BtnListType } from '@/common/components/btnList/interface';
+import { getSellMarketParam, setFinacingList } from '../../setup';
+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 { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { queryFaProductDetail } from '@/services/go/wrtrade';
+
+export default defineComponent({
+    emits: ['cancel', 'openComponent'],
+    name: 'warehouse_receipt_trade_price_delisting_sell',
+    props: {
+        enumName: {
+            default: '',
+            type: String as PropType<EnumRouterName>,
+        },
+        btnList: {
+            default: [],
+            type: Array as PropType<BtnListType[]>,
+        },
+        parantSelectedRow: {
+            type: Object as PropType<WrOrderQuote>,
+            default: {},
+        },
+        time: {
+            type: Object as PropType<Moment>,
+            default: moment(),
+        },
+    },
+    components: {
+        BtnList,
+        delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+        financing_delisting: defineAsyncComponent(() => import('../financing_delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuoteDetail>();
+
+        const buttonList = ref<BtnListType[]>([{ lable: '摘牌', code: 'delisting', className: 'operBtn' }])
+        // 融资摘牌
+        queryResultLoadingAndInfo(queryFaProductDetail, loading, { wrfactortypeid: props.parantSelectedRow.wrfactortypeid }).then((res) => {
+            if (res.length) {
+                setFinacingList(res)
+                buttonList.value.push({ lable: '融资摘牌', code: 'financing_delisting', className: 'operBtn' })
+            }
+        });
+
+        const { wrpricetype, haswr, tableKey } = getSellMarketParam(props.enumName);
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteDetailReq = {
+                buyorsell: 1,
+                wrpricetype,
+                haswr,
+                wrfactortypeid: props.parantSelectedRow.wrfactortypeid,
+                goodsid: props.parantSelectedRow.goodsid,
+            };
+            if (!haswr) {
+                // 无仓单 需要交收月过滤数据
+                param.deliverymonth = moment(props.time).format('YYYY-MM');
+            }
+            queryTable(queryOrderQuoteDetail, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: EnumRouterName.warehouse_receipt_trade_floating_price,
+            tableName: tableKey,
+            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,
+            buttonList,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 250 - 0
src/views/market/market-spot/components/buy-sell-market/index.vue

@@ -0,0 +1,250 @@
+<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.deliverygoodsname }}</div>
+        <div class="arrowRightIcon"></div>
+      </div>
+      <div class="titleBtn titleBtn2">
+        <div class="arrowLeftIcon"></div>
+        <div class="name">{{ selectedRow.wrgoodsname }}</div>
+        <div class="arrowRightIcon"></div>
+      </div>
+      <div class="titleBtn titleBtn2">
+        <div class="arrowLeftIcon"></div>
+        <div class="name">{{ selectedRow.warehousename }}</div>
+        <div class="arrowRightIcon"></div>
+      </div>
+      <div class="titleBtn titleBtn3" v-if="getAuctionwrType(AuctionwrType.noWr)">
+        <div class="arrowLeftIcon"></div>
+        <div class="name">
+          <a-month-picker
+            :allowClear="false"
+            v-model:value="time"
+            @change="timeChange"
+            class="commonDatePicker conditionPicker"
+          />
+        </div>
+        <DownOutlined />
+      </div>
+
+      <div class="priceBar bdf1 ml20">
+        <div class="greenBar green">
+          <div class="numBlock" v-if="getListingMode(ListingMode.float)">
+            <div class="first">卖基差</div>
+            <div class="last">{{ selectedRow.sellpricemove }}</div>
+          </div>
+          <div class="numBlock" v-else>
+            <div class="first">卖价</div>
+            <div class="last">{{ selectedRow.sellprice }}</div>
+          </div>
+          <div class="numBlock">
+            <div class="first">卖量</div>
+            <div class="last">{{ selectedRow.sellqty }}</div>
+          </div>
+        </div>
+        <div class="redBar red">
+          <div class="numBlock" v-if="getListingMode(ListingMode.float)">
+            <div class="first">买基差</div>
+            <div class="last">{{ selectedRow.buypricemove }}</div>
+          </div>
+          <div class="numBlock ml15" v-else>
+            <div class="first">买价</div>
+            <div class="last">{{ selectedRow.buyprice }}</div>
+          </div>
+          <div class="numBlock">
+            <div class="first">买量</div>
+            <div class="last">{{ selectedRow.buyqty }}</div>
+          </div>
+        </div>
+      </div>
+      <a-button
+        class="market"
+        v-if="getListingMode(ListingMode.float)"
+        @click="openComponent({ code: 'GoodsChart' })"
+      >
+        <div class="first">{{ selectedRow.goodscode }}</div>
+        <div class="last red">{{ getGoodsPrice() }}</div>
+        <LineChartOutlined />
+      </a-button>
+      <!-- 历史走势按钮 -->
+      <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" :time="time" />
+      </a-col>
+      <a-col :span="12">
+        <Buy :enumName="enumName" ref="buyRef" :time="time" :parantSelectedRow="selectedRow" />
+      </a-col>
+    </a-row>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :selectedRow="getSelectedRow()"
+      :goodsPrice="getGoodsPrice()"
+      :enumName="enumName"
+      :time="time"
+      @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 { setGoodsPrice } from './setup';
+import Buy from './components/buy/index.vue';
+import Sell from './components/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, getQuoteDayInfoByCode } 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 { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { OperationTabMenu } from '@/services/go/commonService/interface';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { TradeMode, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
+
+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')),
+    post_buying: defineAsyncComponent(() => import('../post_buying/index.vue')),
+    HisChart: defineAsyncComponent(() => import('../history-chart/index.vue')),
+    GoodsChart: defineAsyncComponent(() => import('../goods-chart/index.vue')), // 待优化
+  },
+  setup(props, context) {
+    const time = ref<Moment>(moment(props.selectedRow.deliverymonth)); // string 交收月
+    const loading = ref<boolean>(false);
+    const { visible, cancel } = _closeModal(context);
+
+    const firstBtn: BtnListType[] = [
+      { lable: '挂牌求购', code: 'post_buying', className: 'operBtn' },
+      { lable: '详情', code: 'detail', className: 'operBtn' },
+    ]
+
+    // 获取浮动价商品实时价格
+
+    function getGoodsPrice() {
+      const result = getQuoteDayInfoByCodeFindPrice(props.selectedRow.goodscode);
+      setGoodsPrice(result);
+      return result;
+    }
+    const uuid = v4();
+    if (getListingMode(ListingMode.float)) {
+      // 如果是浮动价需要行情订阅
+      const arr = [{ exchangeCode: 250, goodsCode: props.selectedRow.goodscode, subState: 0 }];
+      addSubscribeQuotation(uuid, arr);
+    }
+    onBeforeUnmount(() => {
+      removeSubscribeQuotation(uuid);
+      TimerUtils.clearInterval('buyAndSellMartet');
+      TimerUtils.clearTimeout('debounce');
+    });
+    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({}));
+
+    function timeChange() {
+      TimerUtils.setTimeout(
+        () => {
+          queryFn();
+        },
+        200,
+        'debounce'
+      );
+    }
+    TimerUtils.setInterval(
+      () => {
+        queryFn();
+      },
+      10 * 1000,
+      'buyAndSellMartet'
+    );
+    // 单据挂牌成功 通知买大厅刷新数据
+    Bus.$on('spotTrade', queryFn);
+
+    const quote = getQuoteDayInfoByCode(props.selectedRow.goodscode);
+    // 切换组件数据
+    const getSelectedRow = () => {
+      if (componentId.value === 'GoodsChart') {
+        return quote;
+      } else {
+        return props.selectedRow;
+      }
+    };
+
+    return {
+      time,
+      buyRef,
+      sellRef,
+      cancel,
+      getListingMode,
+      getGoodsPrice,
+      visible,
+      firstBtn,
+      componentId,
+      closeComponent,
+      openComponent,
+      enumName: props.enumName,
+      getAuctionwrType,
+      AuctionwrType,
+      ListingMode,
+      timeChange,
+      getSelectedRow,
+    };
+  },
+});
+</script>
+<style lang="less" scoped>
+.priceBar {
+  .flex;
+  flex-direction: column;
+  height: 32px;
+  .greenBar,
+  .redBar {
+    height: 16px;
+    line-height: 16px;
+  }
+}
+</style>

+ 4 - 44
src/views/market/spot_trade/components/buy-sell-market/setup.ts → src/views/market/market-spot/components/buy-sell-market/setup.ts

@@ -1,9 +1,6 @@
-import { BuyOrSell } from '@/common/constants/enumCommon';
 import { EnumRouterName } from '@/common/constants/enumRouterName';
-import { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
 import { TableKey } from '@/common/methods/table/interface';
 import { getTableColumns, getTableEvent, queryTableList } from "@/common/setup/table";
-import { queryFaProductDetail } from '@/services/go/wrtrade';
 import { WrFAProductDetail } from "@/services/go/wrtrade/interface";
 import { Ref, ref } from 'vue';
 
@@ -78,49 +75,12 @@ export function getSellMarketParam(enumName: EnumRouterName) {
     return { wrpricetype, haswr, tableKey }
 }
 
-export function handleIs(enumName: EnumRouterName, buyOrSell: BuyOrSell) {
-    /**
-     *
-     * @returns 1 => 仓单贸易; 0 => 仓单预售
-     */
-    function isWR(): 0 | 1 {
-        if (enumName === EnumRouterName.warehouse_receipt_trade_price || enumName === EnumRouterName.warehouse_receipt_trade_floating_price || enumName === EnumRouterName.warehouse_receipt_trade_blocs) {
-            return 1
-        } else {
-            return 0
-        }
-    }
-    /**
-     *
-     * @returns true => 买; false =>卖
-     */
-    function isBuy() {
-        return buyOrSell === BuyOrSell.buy
-    }
-    /**
-     *
-     * @returns  true => 浮动价; false =>一口价
-     */
-    function isFloat() {
-        return enumName === EnumRouterName.warehouse_receipt_trade_floating_price ||
-            enumName === EnumRouterName.warehouse_pre_sale_floating_price
-    }
-    return { isWR, isBuy, isFloat }
-}
-
+// 融资摘牌
 const list = ref<WrFAProductDetail[]>([]);
-// 获取融资摘牌
-export function handleFinacing(loading: Ref<boolean>, id: number) {
-    queryResultLoadingAndInfo(queryFaProductDetail, loading, { wrfactortypeid: id }).then((res) => {
-        list.value = res;
-        return res
-    });
-    function hasFinacing(): boolean {
-        return list.value.length > 0
-    }
-    return { hasFinacing }
-}
 
+export function setFinacingList(value: WrFAProductDetail[]) {
+    list.value = value
+}
 export function getFinacingList(): WrFAProductDetail[] {
     return list.value
 }

+ 47 - 17
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/buy/index.vue → src/views/market/market-spot/components/designate-buy/index.vue

@@ -1,12 +1,22 @@
 <template>
   <!-- 仓单贸易 贸易圈挂牌 卖-->
   <div>
-    <a-table :columns="columns" :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', 'halfBottom',  tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']" :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }" :pagination="false" :loading="loading" :expandedRowKeys="expandedRowKeys" :customRow="Rowclick" :rowKey="(record,index)=>index" :data-source="tableList">
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', 'halfBottom', tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+      :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }"
+      :pagination="false"
+      :loading="loading"
+      :expandedRowKeys="expandedRowKeys"
+      :customRow="Rowclick"
+      rowKey="key"
+      :data-source="tableList"
+    >
       <template #index="{ index }">
         <span>{{ index + 1 }}</span>
       </template>
       <template #marginvalue="{ text }">
-        <span>{{ (text * 100).toFixed(2) + '%'}}</span>
+        <span>{{ (text * 100).toFixed(2) + '%' }}</span>
       </template>
       <!-- 议价 -->
       <template #canbargain="{ text }">
@@ -14,7 +24,7 @@
       </template>
       <!-- 整单 -->
       <template #canpart="{ text }">
-        <span>{{ text  === 1 ? '否' : '是' }}</span>
+        <span>{{ text === 1 ? '否' : '是' }}</span>
       </template>
       <!-- 挂牌有效期 -->
       <template #validtime="{ text }">
@@ -22,32 +32,52 @@
       </template>
     </a-table>
     <!-- 右键 -->
-    <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="filterBtn(firstBtn)"></contextMenu>
-    <component :is="componentId" v-if="componentId" :componentId="componentId" :selectedRow="selectedRow" :buyOrSell="BuyOrSell.Buy" @cancel="closeComponent"></component>
+    <contextMenu
+      :contextMenu="contextMenu"
+      @cancel="closeContext"
+      :list="filterBtn(firstBtn, selectedRow)"
+    ></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :componentId="componentId"
+      :selectedRow="selectedRow"
+      :buyOrSell="BuyOrSell.Buy"
+      @cancel="closeComponent"
+    ></component>
   </div>
 </template>
 
 <script lang="ts">
-import { EnumRouterName } from '@/common/constants/enumRouterName';
-import { queryTableList, contextMenu, defineAsyncComponent, defineComponent, ModalEnum, ComposeTableParam } from '@/common/export/commonTable';
-import { QueryOrderQuoteMyqQsp, QueryOrderQuoteMyqReq, QueryOrderQuoteReq, WrOrderQuote } from '@/services/go/wrtrade/interface';
-import { queryOrderQuote, queryQueryOrderQuoteMyq } from '@/services/go/wrtrade';
-import { handleComposeTable } from '@/common/setup/table/compose';
-import Filter from '../../components/filter/index.vue';
-import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
 import { getShowBottomValue } from '@/common/config/constrolBottom';
-import { handleColumns, filterBtn } from '../../setup';
 import { BuyOrSell } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { ComposeTableParam, contextMenu, defineAsyncComponent, defineComponent, queryTableList } from '@/common/export/commonTable';
 import { formatTime } from '@/common/methods';
+import { handleComposeTable } from '@/common/setup/table/compose';
+import { queryQueryOrderQuoteMyq } from '@/services/go/wrtrade';
+import { QueryOrderQuoteMyqQsp, QueryOrderQuoteMyqReq } from '@/services/go/wrtrade/interface';
 import Bus from '@/utils/eventBus/index';
+import { filterBtn, handleColumns } from './../setup';
 
 export default defineComponent({
   name: 'warehouse_receipt_trade_blocs_buy',
+  props: {
+    isWR: {
+      type: Number,
+      default: 1, // 1 => 仓单贸易; 0 => 仓单预售
+    },
+    IsSpecified: {
+      // IsSpecified = 1 为贸易圈;IsSpecified = 2 为指定挂牌
+      type: Number,
+      default: 1,
+    },
+  },
   components: {
     contextMenu,
-    warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
-    warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
-    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/spot_trade/components/detail/index.vue')),
+    warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../designate-delisting/index.vue')),
+    warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../designate-delisting/index.vue')),
+    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('../detail/index.vue')),
   },
   setup() {
     const isBottom = getShowBottomValue();
@@ -61,7 +91,7 @@ export default defineComponent({
     const queryTableAction = () => {
       const param: QueryOrderQuoteMyqReq = {
         buyorsell: BuyOrSell.buy,
-        haswr: 0,
+        haswr: 1,
       };
       queryTable(queryQueryOrderQuoteMyq, param);
     };

+ 173 - 127
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/index.vue → src/views/market/market-spot/components/designate-delisting/index.vue

@@ -1,139 +1,177 @@
 <template>
-    <!--仓单贸易 贸易圈挂牌 摘牌-->
-    <Drawer :title="isBargin() ? '议价摘牌' : '摘牌'" :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-row>
-                    <a-row :gutter="24">
-                        <a-col :span="24">
-                            <a-form-item label="挂牌方">
-                                <span class="white ml8">{{ selectedRow.username }}</span>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="24">
-                            <a-form-item label="挂牌数量">
-                                <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-col :span="24" v-if="isBargin()">
-                        <a-form-item label="摘牌价格" name="price">
-                            <a-input-number class="commonInput" style="width: 260px" :min="0" v-model:value="formState.price" />
-                        </a-form-item>
-                    </a-col>
-                    <a-col :span="24" v-else>
-                        <a-form-item label="摘牌价格">
-                            <span class="white ml8">{{ selectedRow.fixedprice }}</span>
-                        </a-form-item>
-                    </a-col>
-                    <a-col :span="24" v-if="isBuy()">
-                        <a-form-item label="现货仓单" name="LadingBillId">
-                            <a-select class="inlineFormSelect" style="width: 260px" v-model:value="formState.LadingBillId" placeholder="请选择">
-                                <a-select-option v-for="item in wrHoldList" :value="item.id" :key="item.id">{{ item.name }}</a-select-option>
-                            </a-select>
-                        </a-form-item>
-                    </a-col>
+  <!--仓单贸易 贸易圈挂牌 摘牌-->
+  <Drawer :title="isBargin() ? '议价摘牌' : '摘牌'"
+          :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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{selectedRow.username}}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{selectedRow.orderqty}}{{selectedRow.enumdicname}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-col :span="24"
+                 v-if="isBargin()">
+            <a-form-item label="摘牌价格"
+                         name="price">
+              <a-input-number class="commonInput"
+                              style="width: 260px"
+                              :min="0"
+                              v-model:value="formState.price" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24"
+                 v-else>
+            <a-form-item label="摘牌价格">
+              <span class="white ml8">{{selectedRow.fixedprice}}</span>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24"
+                 v-if="isBuy()">
+            <a-form-item label="现货仓单"
+                         name="LadingBillId">
+              <a-select class="inlineFormSelect"
+                        style="width: 260px"
+                        v-model:value="formState.LadingBillId"
+                        placeholder="请选择">
+                <a-select-option v-for="item in wrHoldList"
+                                 :value="item.id"
+                                 :key="item.id">{{item.name}}</a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
 
-                    <a-row :gutter="24" v-if="isCanpart()">
-                        <a-col :span="24">
-                            <a-form-item label="摘牌数量" class="relative" name="num">
-                                <a-input-number class="dialogInput yellowInput" style="width: 260px" :min="0" :max="getMaxNum()" v-model:value="formState.num" />
-                                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
-                                <div class="labelTip">({{ selectedRow.delistminqty }}{{ selectedRow.enumdicname }}起) </div>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24" v-if="isCanpart()">
-                        <a-col :span="24" class="mt-20">
-                            <a-form-item>
-                                <a-slider :min="0" v-model:value="formState.num" :max="selectedRow.orderqty" class="formSlider" style="width: 260px" />
-                                <div class="unit">
-                                    <span>0</span>
-                                    <span>{{ getMaxNum() }}{{ selectedRow.enumdicname }}</span>
-                                </div>
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">&nbsp;</a-col>
-                    </a-row>
-                    <a-col :span="24" v-if="!isCanpart()">
-                        <a-form-item label="摘牌数量">
-                            <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
-                        </a-form-item>
-                    </a-col>
-                    <a-row :gutter="24">
-                        <a-col :span="24" class="mt-20">
-                            <a-form-item label="摘牌金额">
-                                <span class="white ml8">{{ getMoney() }}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="24">
-                            <a-form-item label="履约保证金">
-                                <span class="white ml8">{{ getMargin() }}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                    <a-row :gutter="24">
-                        <a-col :span="24">
-                            <a-form-item label="可用资金">
-                                <span class="white ml8">{{ getCanUseMoney(getSelectedAccount()) }}</span>
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
+          <a-row :gutter="24"
+                 v-if="isCanpart()">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量"
+                           class="relative"
+                           name="num">
+                <a-input-number class="dialogInput yellowInput"
+                                style="width: 260px"
+                                :min="0"
+                                :max="getMaxNum()"
+                                v-model:value="formState.num" />
+                <span class="input-enumdicname-absolute">{{selectedRow.enumdicname}}</span>
+                <div class="labelTip">({{selectedRow.delistminqty}}{{selectedRow.enumdicname}}起)
                 </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">{{ isBuy() ? '卖出' : '买入' }}</a-button>
-                            <a-button class="ml10 cancelBtn" @click="cancel">取消</a-button>
-                        </a-form-item>
-                    </a-col>
-                </a-row>
-            </a-form>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24"
+                 v-if="isCanpart()">
+            <a-col :span="24"
+                   class="mt-20">
+              <a-form-item>
+                <a-slider :min="0"
+                          v-model:value="formState.num"
+                          :max="selectedRow.orderqty"
+                          class="formSlider"
+                          style="width: 260px" />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{getMaxNum()}}{{selectedRow.enumdicname}}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-col :span="24"
+                 v-if="!isCanpart()">
+            <a-form-item label="摘牌数量">
+              <span class="white ml8">{{selectedRow.orderqty}}{{selectedRow.enumdicname}}</span>
+            </a-form-item>
+          </a-col>
+          <a-row :gutter="24">
+            <a-col :span="24"
+                   class="mt-20">
+              <a-form-item label="摘牌金额">
+                <span class="white ml8">{{getMoney()}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{getMargin()}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="可用资金">
+                <span class="white ml8">{{getCanUseMoney(getSelectedAccount())}}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
         </div>
-    </Drawer>
+        <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">{{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 { defineComponent, PropType, ref } from 'vue';
 import { Des } from '@/common/components/commonDes';
-import { _closeModal } from '@/common/setup/modal/modal';
-import { ModalEnum } from '@/common/constants/modalNameEnum';
 import Drawer from '@/common/components/drawer/index.vue';
-import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
-import { hdWROrder } from '@/services/proto/warehousetrade';
+import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
 import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
-import { DGFactoryItems, HdWRDealOrderReq, WrBargainApplyReq, WRGoodsInfo } from '@/services/proto/warehousetrade/interface';
-import { getAccountTypeList, getSelectedAccountId } from '@/services/bus/account';
-import { getUserId } from '@/services/bus/user';
-import { v4 as uuidv4 } from 'uuid';
-import moment, { Moment } from 'moment';
-import { getMarketRunByTradeMode, marketIsRun } from '@/services/bus/market';
-import { QueryOrderQuoteMyqQsp, WrOrderQuote } from '@/services/go/wrtrade/interface';
-
 import { validateAction } from '@/common/setup/form';
-
-import { EnumRouterName } from '@/common/constants/enumRouterName';
-
-import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
-import { getCanUseMoney } from '@/services/bus/account';
-import { TempWrOrderQuoteDetail } from '@/views/market/spot_trade/components/post_buying/interface';
-import { handleForm, handleSpotWarrant } from './setup';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { getAccountTypeList, getCanUseMoney, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { marketIsRun } from '@/services/bus/market';
 import { getRules } from '@/services/bus/rules';
-import { ListingForm } from './interface';
+import { QueryOrderQuoteMyqQsp } from '@/services/go/wrtrade/interface';
 import { HdWRDealOrder, wrBargainApply } from '@/services/proto/warehousetrade';
-import Long from 'long';
+import { WrBargainApplyReq } from '@/services/proto/warehousetrade/interface';
 import Bus from '@/utils/eventBus';
+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 { ListingForm } from './interface';
+import { handleForm, handleSpotWarrant } from './setup';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
@@ -152,6 +190,15 @@ export default defineComponent({
             type: String,
             default: '',
         },
+        isWR: {
+            type: Number,
+            default: 1, // 1 => 仓单贸易; 0 => 仓单预售
+        },
+        IsSpecified: {
+            // IsSpecified = 1 为贸易圈;IsSpecified = 2 为指定挂牌
+            type: Number,
+            default: 1,
+        },
     },
     setup(props, context) {
         const { visible, cancel } = _closeModal(context);
@@ -178,7 +225,7 @@ export default defineComponent({
             const price = getPrice();
             const num = getNum();
             if (price) {
-                return (price * num).toFixed(2);
+                return Math.round(price * num * 100) / 100;
             } else {
                 return '--';
             }
@@ -192,7 +239,7 @@ export default defineComponent({
             if (price && num && marginvalue) {
                 result = price * num * marginvalue;
             }
-            return result ? Math.floor(2) : '--';
+            return result ? Math.round(result * 100) / 100 : '--';
         }
         function getMaxNum() {
             const qty = props.selectedRow.orderqty;
@@ -252,8 +299,8 @@ export default defineComponent({
                         ApplyRemark: '',
                     };
                     requestResultLoadingAndInfo(wrBargainApply, param, loading, ['议价摘牌成功', '议价摘牌失败:']).then(() => {
+                        Bus.$emit('spotTrade', true);
                         cancel(true);
-                        Bus.$emit('blocsTrade', true);
                     });
                 } else {
                     // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
@@ -269,7 +316,7 @@ export default defineComponent({
                         ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // string 客户端委托时间
                         ClientType: 4, // uint32 终端类型
                         OperatorID: getUserId(), // uint64 操作员账号ID
-                        BuyOrSell: 0, // uint32 买卖方向
+                        BuyOrSell: isBuy() ? BuyOrSell.sell : BuyOrSell.buy, // uint32 买卖方向
                         ApplyID: 0, // uint64 申请ID
                         LadingBillId: 0, // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
                         SubNum: 0, // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
@@ -431,7 +478,6 @@ export default defineComponent({
     right: 14px;
     z-index: 1;
 }
-
 .stepper {
     padding-left: 30px;
     padding-right: 30px;

+ 0 - 0
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/interface.ts → src/views/market/market-spot/components/designate-delisting/interface.ts


+ 56 - 0
src/views/market/market-spot/components/designate-delisting/setup.ts

@@ -0,0 +1,56 @@
+import { BuyOrSell } from "@/common/constants/enumCommon";
+import { queryResultLoadingAndInfo } from "@/common/methods/request/resultInfo";
+import { validateCommon } from "@/common/setup/validate";
+import { queryHoldLB } from "@/services/go/wrtrade";
+import { QueryOrderQuoteMyqQsp, WrHoldLB } from "@/services/go/wrtrade/interface";
+import { Wrhold } from "@/views/market/market-spot/spot_trade_order_transaction/components/delisting/interface";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { reactive, Ref, ref, UnwrapRef } from "vue";
+import { ListingForm } from "./interface";
+
+
+
+export function handleForm() {
+    const formRef = ref();
+    const formState: UnwrapRef<ListingForm> = reactive({
+        accountid: undefined,
+        price: 0,
+        num: 0,
+        LadingBillId: '',
+        case: '',
+        caseId: 0
+    })
+    const v_ContractType = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入摘牌数量');
+    };
+    const rules = {
+        accountid: [{ required: true, message: '请选择交易账户' }],
+        LadingBillId: [{ required: true, message: '请选择现货仓单' }],
+        caseId: [{ required: true, message: '请选择融资方案' }],
+        num: [{ required: true, message: '请输入摘牌数量', trigger: 'blur', type: 'number', },
+        { required: true, validator: v_ContractType }],
+
+    }
+    return { rules, formState, formRef }
+}
+
+
+export function handleSpotWarrant(buyOrSell: BuyOrSell, selectedRow: QueryOrderQuoteMyqQsp, loading: Ref<boolean>) {
+    const wrHoldList = ref<Wrhold[]>([])
+    const allWrHoldList = ref<WrHoldLB[]>([])
+    if (buyOrSell === BuyOrSell.buy) {
+        queryResultLoadingAndInfo(queryHoldLB, loading).then(res => {
+            allWrHoldList.value = res
+            wrHoldList.value.length = 0
+            res.forEach(el => {
+                if (el.wrfactortypeid === String(selectedRow.wrfactortypeid)) {
+                    const { wrholdeno, enableqty, ladingbillid, enumdicname, subnum } = el
+                    const result = { id: ladingbillid, name: `${wrholdeno}(${enableqty}${enumdicname})`, subnum }
+                    wrHoldList.value.push(result)
+                }
+            })
+        })
+    }
+
+    return { wrHoldList, allWrHoldList }
+}

+ 403 - 0
src/views/market/market-spot/components/designate-post-buying/index.vue

@@ -0,0 +1,403 @@
+<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>
+
+            <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', formState.permanceTempName ? 'white' : '']"
+                  @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', getFriendLength() ? 'white' : '']"
+                  @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>
+    </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">
+import { defineComponent, PropType, ref, UnwrapRef } from 'vue';
+import { Des } from '@/common/components/commonDes';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import Drawer from '@/common/components/drawer/index.vue';
+import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { hdWROrder } from '@/services/proto/warehousetrade';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { getUserId } from '@/services/bus/account';
+import { v3, v4 as uuidv4 } from 'uuid';
+import moment, { Moment } from 'moment';
+import { getMarketRunByTradeMode, marketIsRun } from '@/services/bus/market';
+import { validateAction } from '@/common/setup/form';
+import { getCanUseMoney } from '@/services/bus/account';
+import { TempWrOrderQuoteDetail } from '@/views/market/market-spot/components/post_buying/interface';
+import Friend from '@/common/components/friends/index.vue';
+import Permance from '@/common/components/permanceTemp/choosePermancePlanTmp.vue';
+import { message } from 'ant-design-vue';
+import { useBlocksPrice, useBlocksNumber, useBlocksAccount, useBlocksMoney, useBlocksFriends, useBlocksPermaceTemp, handleForm } from '@/common/setup/warehouse_receipt_trade/listing';
+
+import { BlocsListingForm } from '@/common/setup/warehouse_receipt_trade/interface';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { useVerifyBeginDelistingNum } from '@/hooks/form/verify';
+import { WrResultItem } from '@/views/market/futures/compoments/futures-trade/interface'
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: ModalEnum.spot_trade_warehouse_post_buying,
+  components: { Des, Drawer, PlusOutlined, MinusOutlined, Friend, Permance },
+  props: {
+    selectedRow: {
+      type: Object as PropType<TempWrOrderQuoteDetail>,
+      default: { wrResult: [], wrstandardid: 0, deliverygoodsid: 0, wrfactortypeid: 0, minivalue: 0 },
+    },
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    // 表单
+    const { rules, formState, formRef } = handleForm();
+    // 验证 起摘数量
+    const { v_beginDelistingRules } = useVerifyBeginDelistingNum(props.selectedRow.minivalue);
+    rules.delistingQty = v_beginDelistingRules;
+    // 选择朋友
+    const { friendCheck, showFriend, chooseFriend, openFriend, getFriendLength, limiteFriends } = useBlocksFriends(formState);
+    // 履约模板
+    const { showPermance, choosePermance, openPermance } = useBlocksPermaceTemp(formState);
+    // 价格
+    const { priceCheck, increasePrice, decreasePrice } = useBlocksPrice(formState);
+    const loading = ref<boolean>(false);
+    // 摘牌数量
+    const { numCheck, increaseNumber, decreaseNumber } = useBlocksNumber(formState);
+    function submit() {
+      // 判断是否开市
+      if (!marketIsRun(TradeMode.WarehouseReceiptTrade)) {
+        return;
+      }
+      const marketInfo = getMarketRunByTradeMode(TradeMode.WarehouseReceiptTrade);
+      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(), // 客户端流水号
+            // OperateSrc: 2,
+            ClientType: 4,
+            // MarketID: marketInfo.marketid,
+            LadingBillId: 0, // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
+            // LadingBillId: 'uint642081626946446000001', // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
+            TradeDate: moment(marketInfo.tradedate).format('YYYYMMDD'), // 交易日 string
+            // SubNum: '0', // 提单子单号
+            SubNum: 0,
+            // WRFactorTypeId: '2121626946446000001', // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
+            WRFactorTypeId: props.selectedRow.wrfactortypeid ? props.selectedRow.wrfactortypeid : 0, // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
+            IsSpecified: 1, // 是否指定对手 0:不指定 1:指定 uint32
+            MatchAccIDs: res.friends, // 仓单贸易对手资金账号ID集合(指定对手时填写) uint32
+            OrderQty: res.OrderQty, // 委托数量(可挂部分数据量) ======
+            DeliveryGoodsID: props.selectedRow.deliverygoodsid, // 交割商品商品ID  // 有仓单求购
+            WRPriceType: 1, // 价格方式 1:固定价 2:浮动价
+            FixedPrice: res.FixedPrice, // 固定价格
+            PriceFactor: 1, // 价格系数(浮动价时填写)
+            PriceMove: 0, // 升贴水(浮动价时填写)
+            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, // 首付比例
+            PerformanceTemplateID: res.permaceTempId, // 履约计划模板ID
+            UserID: getUserId(),
+            OperatorID: getUserId(), // 操作员账号ID
+            BuyOrSell: 0, // 买卖方向 0买1卖
+            PriceDisplayMode: 1, // 浮动价显示方式 1:合并显示 2:分开显示
+            CanBargain: priceCheck.value ? 1 : 0, // 挂牌是否可议价0:不可1:可-摘牌是否议价
+            Attachment1: '', // 附件1
+            Attachment2: '', // 附件2
+            Remark: '', // 备注
+            ApplyID: 0, // 申请ID
+            WRTradeGoods: [],
+            CanPart: numCheck.value ? 0 : 1, // 是否允许部份摘牌0:不允许;1:允许
+            WRStandardID: props.selectedRow.wrstandardid,
+            HasWr: 1, // 无仓单挂牌  是否有无仓单
+            DeliveryMonth: '',
+            DelistMinQty: numCheck.value ? formState.delistingQty : res.delistingQty, // 起摘数量
+            MarginFlag: 1, // 挂牌是否指定保证金 0:否 1:是
+            MarginAlgorithm: 1, // 指定保证金方式 1:比率 2:固定
+            MarginValue: +(formState.margin / 100), // 指定保证金设置值
+            AllFriendsFlag: friendCheck.value ? 1 : 0, //是否全好友可见 0:否 1:是
+            FactoryItems:
+              props.selectedRow.wrResult != undefined
+                ? props.selectedRow.wrResult.map((it: WrResultItem) => {
+                  return {
+                    DGFactoryItemTypeID: it.dgfactoryitemtypeid, // uint64 要素项类型ID
+                    DGFactoryItemID: it.dgfactoryitemid, // uint64 预约要素项类型值
+                    ItemTypeMode: 1, // uint32 要素项类型模式
+                  };
+                })
+                : [], // DGFactoryItems 要素类型明细集合(没有仓单要素ID填写)
+          };
+          requestResultLoadingAndInfo(hdWROrder, param, loading, ['求购成功', '求购失败:']).then(() => {
+            cancel(true);
+          });
+        });
+      }
+    }
+    return {
+      submit,
+      cancel,
+      visible,
+      rules,
+      formState,
+      formRef,
+      getCanUseMoney,
+      priceCheck,
+      increasePrice,
+      decreasePrice,
+      ...useBlocksAccount(formState),
+      ...useBlocksMoney(formState),
+      showPermance,
+      choosePermance,
+      openPermance,
+      numCheck,
+      increaseNumber,
+      decreaseNumber,
+      friendCheck,
+      showFriend,
+      chooseFriend,
+      openFriend,
+      getFriendLength,
+      limiteFriends,
+    };
+  },
+});
+</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;
+    }
+  }
+}
+
+.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;
+}
+.ant-input-suffix {
+  position: absolute;
+  right: -25px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item .ant-form-item-label {
+  width: 80px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item .ant-form-item-control-wrapper {
+  width: calc(100% - 80px);
+}
+.ant-form.dialogForm {
+  .ant-row.btnCenter.ant-form-item {
+    width: 100%;
+    .ant-col.ant-form-item-control-wrapper {
+      width: 100%;
+    }
+  }
+}
+</style>

+ 31 - 9
src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/sell/index.vue → src/views/market/market-spot/components/designate-sell/index.vue

@@ -1,12 +1,22 @@
 <template>
   <!-- 仓单贸易 贸易圈挂牌 买-->
   <div>
-    <a-table :columns="columns" :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom',  tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']" :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }" :pagination="false" :loading="loading" :expandedRowKeys="expandedRowKeys" :customRow="Rowclick" :rowKey="(record,index)=>index" :data-source="tableList">
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+      :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }"
+      :pagination="false"
+      :loading="loading"
+      :expandedRowKeys="expandedRowKeys"
+      :customRow="Rowclick"
+      rowKey="key"
+      :data-source="tableList"
+    >
       <template #index="{ index }">
         <span>{{ index + 1 }}</span>
       </template>
       <template #marginvalue="{ text }">
-        <span>{{ (text * 100).toFixed(2) + '%'}}</span>
+        <span>{{ (text * 100).toFixed(2) + '%' }}</span>
       </template>
       <!-- 议价 -->
       <template #canbargain="{ text }">
@@ -14,7 +24,7 @@
       </template>
       <!-- 整单 -->
       <template #canpart="{ text }">
-        <span>{{ text  === 1 ? '否' : '是' }}</span>
+        <span>{{ text === 1 ? '否' : '是' }}</span>
       </template>
       <!-- 挂牌有效期 -->
       <template #validtime="{ text }">
@@ -22,8 +32,19 @@
       </template>
     </a-table>
     <!-- 右键 -->
-    <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="filterBtn(firstBtn, selectedRow)"></contextMenu>
-    <component :is="componentId" v-if="componentId" :componentId="componentId" :selectedRow="selectedRow" :buyOrSell="BuyOrSell.sell" @cancel="closeComponent"></component>
+    <contextMenu
+      :contextMenu="contextMenu"
+      @cancel="closeContext"
+      :list="filterBtn(firstBtn, selectedRow)"
+    ></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :componentId="componentId"
+      :selectedRow="selectedRow"
+      :buyOrSell="BuyOrSell.sell"
+      @cancel="closeComponent"
+    ></component>
   </div>
 </template>
 
@@ -36,7 +57,7 @@ import { handleComposeTable } from '@/common/setup/table/compose';
 import Filter from '../../components/filter/index.vue';
 import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
 import { getShowBottomValue } from '@/common/config/constrolBottom';
-import { handleColumns, filterBtn } from '../../setup';
+import { handleColumns, filterBtn } from './../setup';
 import { BuyOrSell } from '@/common/constants/enumCommon';
 import { formatTime } from '@/common/methods';
 import Bus from '@/utils/eventBus/index';
@@ -45,10 +66,11 @@ export default defineComponent({
   name: 'warehouse_receipt_trade_blocs_sell',
   components: {
     contextMenu,
-    warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
-    warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
-    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/spot_trade/components/detail/index.vue')),
+    warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../designate-delisting/index.vue')),
+    warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../designate-delisting/index.vue')),
+    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/market-spot/components/detail/index.vue')),
   },
+
   setup() {
     const isBottom = getShowBottomValue();
     // 表头

+ 1 - 1
src/views/market/spot_trade/components/detail/index.vue → src/views/market/market-spot/components/detail/index.vue

@@ -23,7 +23,7 @@
                  v-for="item in lststep"
                  :key="item.autoid">
               <!-- <div class="no">{{index + 1}}</div> -->
-              <div class="name">{{item.steptypename}}</div>
+              <div class="name">{{item.stepinfo}}</div>
               <div class="time">{{item.stepdate}}</div>
             </div>
           </a-col>

+ 56 - 16
src/views/market/spot_trade/components/filter/index.vue → src/views/market/market-spot/components/filter/index.vue

@@ -2,15 +2,52 @@
     <!-- 报表通用过滤 -->
     <div class="filterTable">
         <div class="filter-custom-table">
-            <a-tree-select v-model:value="selectedFT" @select="changeFT" style="width: 200px" :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :tree-data="FtDeliveryGoods" placeholder="全部商品" :showCheckedStrategy="ALL" tree-default-expand-all></a-tree-select>
-            <a-select label-in-value class="conditionSelect" v-for="(item, index) in wrLsit" :key="index + '11'" style="width: 120px" v-model:value="item.selected" :placeholder="`全部${item.itemtypename}`">
-                <a-select-option v-for="sub in item.itemlst" :key="sub.dgfactoryitemid">{{ sub.dgfactoryitemvalue }}</a-select-option>
+            <a-tree-select
+                v-model:value="selectedFT"
+                @select="changeFT"
+                style="width: 200px"
+                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+                :tree-data="FtDeliveryGoods"
+                placeholder="全部商品"
+                :showCheckedStrategy="ALL"
+                tree-default-expand-all
+            ></a-tree-select>
+            <a-select
+                label-in-value
+                class="conditionSelect"
+                v-for="(item, index) in wrLsit"
+                :key="index + '11'"
+                style="width: 120px"
+                v-model:value="item.selected"
+                :placeholder="`全部${item.itemtypename}`"
+            >
+                <a-select-option
+                    v-for="sub in item.itemlst"
+                    :key="sub.dgfactoryitemid"
+                >{{ sub.dgfactoryitemvalue }}</a-select-option>
             </a-select>
-            <a-space direction="vertical" v-if="!isWR()">
-                <a-month-picker :allowClear="false" :style="{ marginRight: '10px' }" placeholder="全部交收月" v-model:value="time" class="commonDatePicker conditionPicker allDatePicker" />
+            <a-space direction="vertical" v-if="getAuctionwrType(AuctionwrType.noWr)">
+                <a-month-picker
+                    :allowClear="false"
+                    :style="{ marginRight: '10px' }"
+                    placeholder="全部交收月"
+                    v-model:value="time"
+                    class="commonDatePicker conditionPicker allDatePicker"
+                />
             </a-space>
-            <a-select class="conditionSelect" v-if="isFloat()" :style="{ width: '180px', maxHeight: '400px', overflow: 'auto' }" @change="goodsChange" placeholder="全部期货合约">
-                <a-select-option v-for="item in goodsList" :value="item.goodsid" :key="item.goodsid">{{ item.goodscode }}({{ item.goodsname }}) </a-select-option>
+            <a-select
+                class="conditionSelect"
+                v-if="getListingMode(ListingMode.float)"
+                :style="{ width: '180px', maxHeight: '400px', overflow: 'auto' }"
+                @change="goodsChange"
+                v-model:value="goodsid"
+                placeholder="全部期货合约"
+            >
+                <a-select-option
+                    v-for="item in goodsList"
+                    :value="item.goodsid"
+                    :key="item.goodsid"
+                >{{ item.goodscode }}({{ item.goodsname }})</a-select-option>
             </a-select>
             <a-button class="btnDeafault" @click="search(true)" style="width: 80px">筛选</a-button>
             <a-button class="operBtn" @click="listingAction">挂牌求购</a-button>
@@ -34,10 +71,11 @@ import { addSubscribeQuotation, removeSubscribeQuotation } from '@/services/sock
 import { v4 } from 'uuid';
 import { getGoodsList, getGoodsListByTrade, getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
 import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
-import { handleIs, setGoodsPrice } from '../buy-sell-market/setup';
-import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
+import { setGoodsPrice } from '../buy-sell-market/setup';
 import { getMarketByTradeMode } from '@/services/bus/market';
 import TimerUtils from '@/utils/timer/timerUtil';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { TradeMode, BuyOrSell, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
 
 const ALL = TreeSelect.SHOW_ALL;
 
@@ -47,7 +85,6 @@ interface SelectList extends WrStandardFactoryItemEx {
 
 export default defineComponent({
     name: 'exposure-filter-table',
-    emits: ['search', 'buy'],
     components: { FilterOption },
     props: {
         enumName: {
@@ -56,7 +93,6 @@ export default defineComponent({
         },
     },
     setup(props, context) {
-        const { isWR, isFloat } = handleIs(props.enumName, BuyOrSell.buy);
         const loading = ref<boolean>(false);
         // 商品
         const { FtDeliveryGoods } = handleFtDeliveryGoods();
@@ -93,18 +129,22 @@ export default defineComponent({
         const uuid = v4();
         // 切换商品
         function goodsChange(id: number) {
+            console.log('id', id);
             //行情订阅
             removeSubscribeQuotation(uuid);
             const goods = goodsList.value.find((e) => e.goodsid === id);
             selectedGoods.value = goods;
             const arr = [{ exchangeCode: 250, goodsCode: goods!.goodscode, subState: 0 }];
             addSubscribeQuotation(uuid, arr);
+            context.emit('filterGoods', id);
         }
         onMounted(() => {
             removeSubscribeQuotation(uuid);
         });
         // 交收月
         const time = ref<Moment>(); // string 交收月
+        // 期货合约
+        const goodsid = ref<number | undefined>(undefined);
         function search(isQuery: boolean) {
             const result: any = {};
             if (selectedFT.value) {
@@ -137,7 +177,7 @@ export default defineComponent({
                     wrResult.push({ dgfactoryitemtypeid, dgfactoryitemid: key });
                 }
             });
-            if (!isWR()) {
+            if (getAuctionwrType(AuctionwrType.noWr)) {
                 // 预售
                 if (time.value) {
                     //   交收月(yyyy-mm) 仓单预售填写
@@ -165,13 +205,13 @@ export default defineComponent({
             }
 
             if (flag) {
-                if (!isWR()) {
+                if (getAuctionwrType(AuctionwrType.noWr)) {
                     if (!time.value) {
                         message.warn('请选中交收月!');
                         return;
                     }
                 }
-                if (isFloat()) {
+                if (getListingMode(ListingMode.float)) {
                     if (!selectedGoods.value) {
                         message.warn('请选中期货合约!');
                         return;
@@ -195,8 +235,8 @@ export default defineComponent({
             time,
             goodsList,
             goodsChange,
-            isWR,
-            isFloat,
+            goodsid,
+            getAuctionwrType, getListingMode, ListingMode, AuctionwrType,
         };
     },
 });

+ 1 - 4
src/views/market/spot_trade/components/goods-chart/chart/index.less → src/views/market/market-spot/components/goods-chart/chart/index.less

@@ -60,14 +60,11 @@
                 top          : 0;
                 padding      : 0 16px;
 
-                &::after {
-                    border: 0 !important;
-                }
-
                 &-active,
                 &-selected {
                     color           : var(--tab-checked-color, #0866b8);
                     background-color: var(--tab-checked-bgcolor, #0e2f4c);
+                    border-bottom   : 0;
                 }
             }
         }

+ 325 - 0
src/views/market/market-spot/components/goods-chart/chart/index.vue

@@ -0,0 +1,325 @@
+<template>
+  <!-- 交易图表  -->
+  <div class="chart-container">
+    <div class="chart-content">
+      <div class="chart-content__header">
+        <a-menu
+          class="chart-content__tabs"
+          v-model:selectedKeys="activeCycleName"
+          mode="horizontal"
+          @click="changeCycleType"
+        >
+          <a-menu-item v-for="item in chartType" :key="item.name">{{ item.label }}</a-menu-item>
+        </a-menu>
+        <a-menu
+          class="chart-content__tabs"
+          v-model:selectedKeys="activeSeriesType"
+          mode="horizontal"
+          v-show="activeCycleType !== CycleType.time"
+        >
+          <a-menu-item key="MACD">MACD</a-menu-item>
+          <a-menu-item key="VOL">VOL</a-menu-item>
+          <a-menu-item key="KDJ">KDJ</a-menu-item>
+          <a-menu-item key="CCI">CCI</a-menu-item>
+        </a-menu>
+      </div>
+      <echart-time
+        class="chart-content__main"
+        :quote-data="selectedRow"
+        @change="getHistoryTikDatas"
+        v-if="activeCycleType === CycleType.time"
+      ></echart-time>
+      <echart-kline
+        class="chart-content__main"
+        :quote-data="selectedRow"
+        :cycle-type="activeCycleType"
+        :series-type="activeSeriesType[0]"
+        v-else
+      ></echart-kline>
+      <div class="chart-content__footer"></div>
+    </div>
+    <div class="chart-slider">
+      <div class="chart-slider__button"></div>
+    </div>
+    <div class="chart-tips" v-if="showExchange">
+      <div>
+        <div class="chart-tips__nav">
+          <div class="content content--left">{{ selectedRow.goodscode }}</div>
+          <div class="content content--right">{{ selectedRow.goodsname }}</div>
+        </div>
+        <div class="chart-tips__last">
+          <div
+            :class="['content content--left', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]"
+          >{{ handleNoneValue(selectedRow.last) }}</div>
+          <div class="content content--right">
+            <span
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteChange(selectedRow) }}</span>
+            <span
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteAmplitude(selectedRow) }}</span>
+          </div>
+        </div>
+        <div class="chart-tips__volume">
+          <a-row>
+            <a-col :span="8">卖一</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.ask) }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.askvolume) }}</a-col>
+          </a-row>
+          <a-row>
+            <a-col :span="8">买一</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.bid) }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.bidvolume) }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__tik">
+        <div class="row-header">
+          <h4>分时成交</h4>
+          <a-row>
+            <a-col :span="8">时间</a-col>
+            <a-col :span="8">价格</a-col>
+            <a-col :span="8">现量</a-col>
+          </a-row>
+        </div>
+        <div class="row-content">
+          <a-row v-for="(item, index) in tradedList" :key="index + '11'">
+            <a-col :span="8">{{ formatTime(item.TS, 'hm') }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(item.PE, selectedRow.presettle)"
+              :span="8"
+            >{{ item.PE }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(item.Vol, selectedRow.presettle)"
+              :span="8"
+            >{{ item.Vol }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__info">
+        <a-row>
+          <a-col :span="4">最新</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.last) }}</a-col>
+          <a-col :span="4">均价</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.averageprice, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.averageprice) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨跌</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ quoteChange(selectedRow) }}</a-col>
+          <a-col :span="4">今开</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.opened, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.opened) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨幅</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ quoteAmplitude(selectedRow) }}</a-col>
+          <a-col :span="4">最高</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.highest, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.highest) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">总量</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalvolume) }}</a-col>
+          <a-col :span="4">最低</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.lowest, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.lowest) }}</a-col>
+        </a-row>
+        <!-- <a-row>
+          <a-col :span="4">金额</a-col>
+          <a-col :span="8" style="color: #0d96ff">{{ changeUnit(selectedRow.totalturnover) }}</a-col>
+          <a-col :span="4">量比</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>-->
+        <!-- <a-row>
+          <a-col :span="4">涨停</a-col>
+          <a-col class="red1" :span="8">{{ handleNoneValue(selectedRow.limitup) }}</a-col>
+          <a-col :span="4">跌停</a-col>
+          <a-col class="green" :span="8">{{ handleNoneValue(selectedRow.limitdown) }}</a-col>
+        </a-row>-->
+        <a-row>
+          <a-col :span="4">外盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalbidvolume) }}</a-col>
+          <a-col :span="4">内盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalaskvolume) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">持仓</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.holdvolume) }}</a-col>
+          <a-col :span="4">结算</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.settle) }}</a-col>
+        </a-row>
+        <a-row>
+          <!-- <a-col :span="4">仓差</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>-->
+          <a-col :span="4">昨结</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.presettle) }}</a-col>
+        </a-row>
+        <!-- <a-row>
+          <a-col :span="4">日增</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+          <a-col :span="4">开平</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>-->
+      </div>
+      <div @click="watchMore" class="watchMore">
+        <strong>查看更多</strong>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref, watch } from 'vue';
+import { QueryQuoteDayRsp, QueryHistoryTikDatasRsp, CycleType } from '@/services/go/quote/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+import { changeUnit } from '@/utils/qt/common';
+import { ComponentType } from '@/views/market/market-spot/spot_trade_order_transaction/setup';
+import { EchartKline, EchartTime } from '@/common/components/echart';
+import { handleQuotePriceColor, quoteChange, handleNoneValue, quoteAmplitude } from '@/common/setup/table/tableQuote';
+import { useQueryData } from '@/common/setup/request';
+import moment from 'moment';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: 'stock-exchange',
+  components: {
+    EchartKline,
+    EchartTime,
+  },
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryQuoteDayRsp>,
+      default: {},
+    },
+    showExchange: {
+      type: Boolean,
+      default: true
+    }
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context),
+      activeCycleName = ref<string[]>(['time']),
+      activeCycleType = ref<CycleType>(CycleType.time),
+      activeSeriesType = ref<string[]>(['MACD']),
+      tradedList = ref<QueryHistoryTikDatasRsp[]>([]);
+
+    function watchMore() {
+      context.emit('update', ComponentType.marketContent);
+    }
+
+    // 周期类型
+    const chartType = [
+      { label: '分时', name: 'time', value: CycleType.time },
+      { label: '1分钟', name: 'minutes', value: CycleType.minutes },
+      { label: '5分钟', name: 'minutes5', value: CycleType.minutes5 },
+      { label: '30分钟', name: 'minutes30', value: CycleType.minutes30 },
+      { label: '60分钟', name: 'minutes60', value: CycleType.minutes60 },
+      { label: '4小时', name: 'Hours4', value: CycleType.Hours4 },
+      { label: '日 K', name: 'days', value: CycleType.days },
+    ];
+
+    // 切换图表周期类型
+    const changeCycleType = (e: { key: string }) => {
+      activeCycleType.value = chartType.find((item) => item.name === e.key)!.value;
+    };
+
+    // Tik列表
+    const getHistoryTikDatas = (startTime: string, endTime: string) => {
+      if (!tradedList.value.length) {
+        const param = {
+          goodsCode: props.selectedRow.goodscode,
+          count: 20,
+          startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'),
+          endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'),
+        };
+        QueryHistoryTikDatas(param).then((res) => {
+          tradedList.value = res;
+        });
+      }
+    };
+
+    // 监听行情变化刷Tik列表
+    watch(
+      () => props.selectedRow.last,
+      () => {
+        if (tradedList.value.length) {
+          // 移除列表最后一条记录
+          tradedList.value.pop();
+          // 向列表开头添加新纪录
+          tradedList.value.unshift({
+            AV: 0,
+            Ask: 0,
+            BV: 0,
+            Bid: 0,
+            HI: 0,
+            HV: 0,
+            PE: props.selectedRow.last,
+            TDR: 0,
+            TK: 0,
+            TS: props.selectedRow.lasttime,
+            TT: 0,
+            Vol: props.selectedRow.lastvolume,
+          });
+        }
+      }
+    );
+
+    return {
+      cancel,
+      visible,
+      chartType,
+      tradedList,
+      CycleType,
+      activeCycleName,
+      activeCycleType,
+      activeSeriesType,
+      changeUnit,
+      watchMore,
+      formatTime,
+      quoteChange,
+      handleNoneValue,
+      quoteAmplitude,
+      handleQuotePriceColor,
+      changeCycleType,
+      getHistoryTikDatas,
+    };
+  },
+});
+</script>
+
+<style lang="less">
+@import "./index.less";
+</style>

+ 180 - 0
src/views/market/market-spot/components/goods-chart/index.vue

@@ -0,0 +1,180 @@
+<template>
+    <!-- 买卖大厅 -->
+    <div class="buy-sell-market">
+        <div class="buy-sell-market-title">
+            <a class="backIcon" @click="cancelAction">
+                <LeftOutlined />
+            </a>
+            <div class="titleBtn">
+                <div class="name">{{ selectedRow.goodscode }} {{ selectedRow.goodsname }}</div>
+                <div class="arrowRightIcon"></div>
+            </div>
+            <div class="inlineBar">
+                <div class="valNums bdf1 ml10">
+                    <!-- 最新价 -->
+                    <div
+                        class="firstNum start"
+                        :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+                    >{{ selectedRow.last }}</div>
+                    <div class="lastNum start">
+                        <!-- 涨跌值 -->
+                        <div
+                            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+                        >{{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
+                        <!-- 涨跌幅 -->
+                        <div
+                            class="ml20"
+                            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+                        >{{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
+                    </div>
+                </div>
+                <div class="priceBar ml20">
+                    <div class="inlineBar start">
+                        <div class="greenBar">
+                            <div class="numBlock ml15">
+                                <div class="first grey">卖价</div>
+                                <div
+                                    class="last"
+                                    :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+                                >{{ selectedRow.ask }}</div>
+                            </div>
+                            <div class="numBlock">
+                                <div class="first grey">卖量</div>
+                                <div
+                                    class="last"
+                                    :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+                                >{{ selectedRow.askvolume }}</div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="inlineBar start">
+                        <div class="redBar">
+                            <div class="numBlock">
+                                <div class="first grey">买价</div>
+                                <div
+                                    class="last"
+                                    :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+                                >{{ selectedRow.bid }}</div>
+                            </div>
+                            <div class="numBlock">
+                                <div class="first grey">买量</div>
+                                <div
+                                    class="last"
+                                    :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+                                >{{ selectedRow.bidvolume }}</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!-- 交易图表 -->
+        <Chart
+            v-if="showComponentsId === ComponentType.chart"
+            @update="changeComponent"
+            :selectedRow="selectedRow"
+        />
+        <!-- 成交明细 -->
+        <StockExchange
+            :selectedRow="selectedRow"
+            v-if="showComponentsId === ComponentType.tradeDetail"
+        />
+    </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { LeftOutlined } from '@ant-design/icons-vue';
+import { PropType, ref } from 'vue';
+import Chart from './chart/index.vue';
+import { ComponentType } from './setup';
+import StockExchange from './stock-exchange/index.vue';
+
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: 'buy-sell-market',
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryQuoteDayRsp>,
+            default: {},
+        },
+    },
+    components: {
+        Chart,
+        LeftOutlined,
+        StockExchange,
+    },
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+
+        const showComponentsId = ref<ComponentType>(ComponentType.chart);
+
+        // 切换组件
+        function changeComponent(type: ComponentType) {
+            showComponentsId.value = type;
+        }
+        // 返回上层组件
+        function cancelAction() {
+            if (showComponentsId.value === ComponentType.chart) {
+                cancel();
+            } else {
+                showComponentsId.value = ComponentType.chart;
+            }
+        }
+        return {
+            cancel,
+            visible,
+            changeComponent,
+            ComponentType,
+            showComponentsId,
+            cancelAction,
+            handleSubcriteOnDemandQuote,
+            handleQuotePriceColor,
+            quoteChange,
+            quoteAmplitude,
+            quoteAmplituOfVibration,
+        };
+    },
+});
+</script>
+<style lang="less">
+.valNums {
+    .flex;
+    flex-direction: column;
+    padding-left: 20px;
+    .firstNum {
+        font-size: 18px;
+        line-height: 18px;
+        font-weight: 400;
+    }
+    .lastNum {
+        margin-top: 2px;
+        display: inline-flex;
+        font-size: 12px;
+        line-height: 12px;
+        font-weight: 300;
+    }
+}
+.inlineBar {
+    display: inline-flex;
+}
+.priceBar {
+    .flex;
+    flex-direction: column;
+    height: 32px;
+    .greenBar,
+    .redBar {
+        height: 16px;
+        line-height: 16px;
+    }
+}
+.start {
+    align-self: flex-start !important;
+    align-items: flex-start !important;
+}
+</style>

+ 0 - 0
src/views/market/market-spot/compoments/goods-chart/setup.ts → src/views/market/market-spot/components/goods-chart/setup.ts


+ 112 - 0
src/views/market/market-spot/components/goods-chart/stock-exchange/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <!-- 成交明细  -->
+  <a-row>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[0]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[1]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[2]">
+      </a-table>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref } from 'vue';
+
+import { QueryHistoryTikDatasRsp, QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+
+const columnsList = [
+    { title: '时间', key: 'TS', dataIndex: 'TS', align: 'center' },
+    { title: '成交价', key: 'Vol', dataIndex: 'Vol', align: 'center' },
+    { title: '成交量', key: 'PE', dataIndex: 'PE', align: 'center' },
+];
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: 'stock-exchange',
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryQuoteDayRsp>,
+            default: {},
+        },
+    },
+
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+        const param = {
+            goodsCode: props.selectedRow.goodscode,
+        };
+        const tableList = ref<QueryHistoryTikDatasRsp[][]>([]);
+        QueryHistoryTikDatas(param).then((res) => {
+            res.forEach((el) => (el.TS = formatTime(el.TS)));
+            tableList.value = getHisList(res);
+        });
+        function getHisList(list: QueryHistoryTikDatasRsp[]) {
+            const len = list.length;
+            const result: QueryHistoryTikDatasRsp[][] = [[], [], []];
+            if (len) {
+                if (len === 1) {
+                    result[0] = list;
+                } else if (len === 2) {
+                    result[0].push(list[0]);
+                    result[1].push(list[1]);
+                } else {
+                    const temp = Math.floor(len / 3);
+                    result[0] = list.slice(0, temp);
+                    result[1] = list.slice(temp, 2 * temp);
+                    result[2] = list.slice(temp * 2, temp * 3);
+                    const last = len - temp;
+                    if (last) {
+                        if (last === 1) {
+                            result[0].push(list[len - 1]);
+                        } else {
+                            result[0].push(list[len - 2]);
+                            result[1].push(list[len - 1]);
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+        return {
+            cancel,
+            visible,
+            tableList,
+            columnsList,
+            loading,
+        };
+    },
+});
+</script>
+<style lang="less">
+</style>

+ 3 - 4
src/views/market/spot_trade/components/history-chart/index.vue → src/views/market/market-spot/components/history-chart/index.vue

@@ -29,10 +29,10 @@ 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 { handleIs } from '../buy-sell-market/setup';
-import { BuyOrSell } from '@/common/constants/enumCommon';
 import { _closeModal } from '@/common/setup/modal/modal';
 import Drawer from '@/common/components/drawer/index.vue';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { BuyOrSell, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
 
 // 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
 type ECOption = echarts.ComposeOption<BarSeriesOption | LineSeriesOption | TitleComponentOption | GridComponentOption>;
@@ -71,12 +71,11 @@ export default defineComponent({
                 },
             ],
         };
-        const { isWR } = handleIs(props.enumName, BuyOrSell.buy);
         const chartRef = ref();
         const chartInstance = ref<echarts.ECharts>();
         function queryHistoryData() {
             const param: WrAverageTradePriceQsq = {
-                haswr: isWR(),
+                haswr: getAuctionwrType(AuctionwrType.hasWr) ? 1 : 0,
                 wrfactortypeid: props.selectedRow.wrfactortypeid,
             };
             queryWrAverageTradePrice(param).then((res) => {

+ 158 - 37
src/views/market/spot_trade/components/post_buying/index.vue → src/views/market/market-spot/components/post_buying/index.vue

@@ -7,41 +7,75 @@
                     <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
+                                    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" v-if="!isFloat()">
+                        <a-col :span="24" v-if="getListingMode(ListingMode.fix)">
                             <a-form-item label="挂牌价格" name="FixedPrice">
-                                <a-input-number class="commonInput" style="width: 260px" :min="0" v-model:value="formState.FixedPrice" />
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    v-model:value="formState.FixedPrice"
+                                />
                             </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-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">
+                        <a-col :span="24" v-if="getListingMode(ListingMode.float)">
+                            <a-form-item label="估算价">
                                 <span class="white">{{ getPrice() }}</span>
                             </a-form-item>
                         </a-col>
 
                         <a-col :span="24">
                             <a-form-item label="挂牌数量" name="OrderQty">
-                                <a-input-number class="commonInput" style="width: 260px" :min="0" :max="getMaxNum()" v-model:value="formState.OrderQty" />
+                                <a-input-number
+                                    class="commonInput"
+                                    style="width: 260px"
+                                    :min="0"
+                                    :max="getMaxNum()"
+                                    v-model:value="formState.OrderQty"
+                                />
                                 <span class="input-enumdicname">{{ selectedRow.enumdicname }}</span>
                             </a-form-item>
                         </a-col>
-                        <a-col :span="24" v-if="!isWR()">
+                        <a-col :span="24" v-if="getAuctionwrType(AuctionwrType.noWr)">
                             <a-form-item label="交收月" name="DeliveryMonth">
-                                <a-month-picker style="width: 260px" v-model:value="formState.DeliveryMonth" :allowClear="false" class="commonDatePicker dialogDatePicker" />
+                                <a-month-picker
+                                    style="width: 260px"
+                                    v-model:value="formState.DeliveryMonth"
+                                    :allowClear="false"
+                                    class="commonDatePicker dialogDatePicker"
+                                />
                             </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" />
+                                <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>
@@ -50,12 +84,38 @@
                         </a-col>
                         <a-col :span="24">
                             <a-form-item label="起摘数量" name="DelistMinQty" class="relative">
-                                <a-input-number class="commonInput" :suffix="selectedRow.enumdicname" v-model:value="formState.DelistMinQty" :min="0" style="width: 260px !important" />
-                                <div class="tip">最小单位:{{ selectedRow.minivalue }}{{ selectedRow.enumdicname }}</div>
+                                <a-input-number
+                                    class="commonInput"
+                                    :suffix="selectedRow.enumdicname"
+                                    v-model:value="formState.DelistMinQty"
+                                    :min="0"
+                                    style="width: 260px !important"
+                                />
+                                <div
+                                    class="tip-listing"
+                                >最小单位:{{ selectedRow.minivalue }}{{ selectedRow.enumdicname }}</div>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :span="24">
+                            <a-form-item label="履约方式" class="inputIconBox">
+                                <span
+                                    :class="['clickBox', formState.permanceTempName ? 'white' : '']"
+                                    style="width: 260px"
+                                    @click="handlePermance"
+                                >{{ formState.permanceTempName ? formState.permanceTempName : '选择履约模板' }}</span>
+                                <svg
+                                    class="icon svg-icon"
+                                    aria-hidden="true"
+                                    @click="handlePermance"
+                                >
+                                    <use xlink:href="#icon-moban" />
+                                </svg>
                             </a-form-item>
                         </a-col>
                         <a-col :span="24" class="relative mt20">
-                            <a-form-item :label="isFloat() ? '估算金额' : '挂牌金额'">
+                            <a-form-item
+                                :label="getListingMode(ListingMode.float) ? '估算金额' : '挂牌金额'"
+                            >
                                 <span class="white ml8">{{ getMoney() }}</span>
                             </a-form-item>
                         </a-col>
@@ -94,6 +154,13 @@
             </a-form>
         </div>
     </Drawer>
+    <!-- 选择履约模板 -->
+    <Permance
+        v-if="showPermance"
+        :marketid="formState.marketid"
+        @cancel="choosePermance"
+        @update="choosePermance"
+    />
 </template>
 
 <script lang="ts">
@@ -106,8 +173,7 @@ import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
 import { hdWROrder } from '@/services/proto/warehousetrade';
 import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
 import { DGFactoryItems, WRGoodsInfo } from '@/services/proto/warehousetrade/interface';
-import { getAccountTypeList } from '@/services/bus/account';
-import { getUserId } from '@/services/bus/user';
+import { getAccountTypeList, getUserId } from '@/services/bus/account';
 import { v4 as uuidv4 } from 'uuid';
 import moment, { Moment } from 'moment';
 import { getMarketRunByTradeMode } from '@/services/bus/market';
@@ -116,14 +182,24 @@ import { handleForm, handleNumAndPrice } from './setup';
 import { validateAction } from '@/common/setup/form';
 import { FormParam, TempWrOrderQuoteDetail } from './interface';
 import { EnumRouterName } from '@/common/constants/enumRouterName';
-import { handleIs } from '../buy-sell-market/setup';
-import { BuyOrSell } from '@/common/constants/enumCommon';
+import { getAuctionwrType, getListingMode } from '@/views/market/market-spot/setup'
+import { BuyOrSell, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
 import { getCanUseMoney } from '@/services/bus/account';
+import { message } from 'ant-design-vue';
+import Permance from '@/common/components/permanceTemp/choosePermancePlanTmp.vue';
+import { QueryPermancePlanTmpRsp } from '@/services/go/wrtrade/interface';
+import { getMarketByTradeMode } from '@/services/bus/market';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
     name: ModalEnum.spot_trade_warehouse_post_buying,
-    components: { Des, Drawer, PlusOutlined, MinusOutlined },
+    components: {
+        Des,
+        Drawer,
+        Permance,
+        PlusOutlined,
+        MinusOutlined,
+    },
     props: {
         selectedRow: {
             type: Object as PropType<TempWrOrderQuoteDetail>,
@@ -140,7 +216,6 @@ export default defineComponent({
     },
     setup(props, context) {
         const { visible, cancel } = _closeModal(context);
-        const { isWR, isFloat } = handleIs(props.enumName, BuyOrSell.buy);
         const { rules, formState, formRef } = handleForm(props.selectedRow);
         const loading = ref<boolean>(false);
         const accountList = getAccountTypeList([2]);
@@ -152,7 +227,42 @@ export default defineComponent({
         }
         formState.DeliveryMonth = props.selectedRow.deliverymonth ? moment(props.selectedRow.deliverymonth) : props.time;
 
+        // 17=仓单贸易市场
+        const market = getMarketByTradeMode(17);
+        if (market) {
+            formState.marketid = market.marketid;
+        } else {
+            message.error('市场信息异常,请稍后重试');
+        }
+
         const { getMaxNum, getMoney, getMargin, getPrice } = handleNumAndPrice(props.enumName, props.selectedRow);
+        if (getMaxNum()) {
+            formState.OrderQty = props.selectedRow.minivalue;
+        }
+
+        const showPermance = ref<boolean>(false);
+        function choosePermance(value: QueryPermancePlanTmpRsp | false) {
+            if (value) {
+                formState.permanceTempName = value.templatename;
+                formState.permaceTempId = value.autoid;
+            }
+            showPermance.value = false;
+        }
+        function openPermance() {
+            showPermance.value = true;
+        }
+
+        // 点选履约模板
+        function handlePermance() {
+            // 必须先选择市场再选择对应的履约模板
+            if (!formState.marketid) {
+                message.info('请先选择市场');
+                return;
+            }
+
+            openPermance();
+        }
+
         function submit() {
             const marketInfo = getMarketRunByTradeMode(17);
             if (marketInfo) {
@@ -172,6 +282,7 @@ export default defineComponent({
                         ClientSerialNo: uuidv4(), // 客户端流水号
                         // OperateSrc: 2,
                         ClientType: 4,
+                        MarketID: res.marketid,
                         // MarketID: marketInfo.marketid,
                         LadingBillId: 0, // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
                         // LadingBillId: 'uint642081626946446000001', // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
@@ -184,15 +295,15 @@ export default defineComponent({
                         // MatchUserIDs: 0, // 仓单贸易对手资金账号ID集合(指定对手时填写) uint32
                         OrderQty: res.OrderQty, // 委托数量(可挂部分数据量) ======
                         DeliveryGoodsID: props.selectedRow.deliverygoodsid, // 交割商品商品ID  // 有仓单求购
-                        WRPriceType: isFloat() ? 2 : 1, // 价格方式 1:固定价 2:浮动价
+                        WRPriceType: getListingMode(ListingMode.float) ? 2 : 1, // 价格方式 1:固定价 2:浮动价
                         FixedPrice: res.FixedPrice, // 固定价格
                         PriceFactor: 1, // 价格系数(浮动价时填写)
-                        PriceMove: res.PriceMove, // 升贴水(浮动价时填写)
+                        PriceMove: res.PriceMove ? res.PriceMove : 0, // 升贴水(浮动价时填写)
                         TimevalidType: 4, // 时间有效类型 1:当日有效 2:本周有效 3:指定时间有效 4:一直有效
                         // ValidTime: moment('2021-08-25 00:00:00').format('YYYY-MM-DD HH:mm:ss'), // 有效期限
                         ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
                         FirstRatio: 0, // 首付比例
-                        PerformanceTemplateID: 0, // 履约计划模板ID
+                        PerformanceTemplateID: res.permaceTempId, // 履约计划模板ID
                         UserID: getUserId(),
                         OperatorID: getUserId(), // 操作员账号ID
                         BuyOrSell: 0, // 买卖方向 0买1卖
@@ -202,21 +313,21 @@ export default defineComponent({
                         Attachment2: '', // 附件2
                         Remark: '', // 备注
                         ApplyID: 0, // 申请ID
-                        WRTradeGoods: isFloat() ? [wrGoodsInfo] : [],
+                        WRTradeGoods: getListingMode(ListingMode.float) ? [wrGoodsInfo] : [],
                         CanPart: 1, // 是否允许部份摘牌0:不允许;1:允许
                         WRStandardID: props.selectedRow.wrstandardid,
-                        HasWr: isWR(), // 无仓单挂牌  是否有无仓单
+                        HasWr: getAuctionwrType(AuctionwrType.hasWr) ? 1 : 0, // 无仓单挂牌  是否有无仓单
                         DelistMinQty: res.DelistMinQty, // 起摘数量
-                        DeliveryMonth: isWR() ? '' : moment(res.DeliveryMonth).format('YYYY-MM'),
+                        DeliveryMonth: getAuctionwrType(AuctionwrType.hasWr) ? '' : moment(res.DeliveryMonth).format('YYYY-MM'),
                         FactoryItems:
                             props.selectedRow.wrResult != undefined
                                 ? props.selectedRow.wrResult.flatMap((it) => {
-                                      return {
-                                          DGFactoryItemTypeID: it.dgfactoryitemtypeid, // uint64 要素项类型ID
-                                          DGFactoryItemID: it.dgfactoryitemid, // uint64 预约要素项类型值
-                                          ItemTypeMode: 1, // uint32 要素项类型模式
-                                      };
-                                  })
+                                    return {
+                                        DGFactoryItemTypeID: it.dgfactoryitemtypeid, // uint64 要素项类型ID
+                                        DGFactoryItemID: it.dgfactoryitemid, // uint64 预约要素项类型值
+                                        ItemTypeMode: 1, // uint32 要素项类型模式
+                                    };
+                                })
                                 : [], // DGFactoryItems 要素类型明细集合(没有仓单要素ID填写)
                     };
                     requestResultLoadingAndInfo(hdWROrder, param, loading, ['求购成功', '求购失败:']).then(() => {
@@ -234,20 +345,22 @@ export default defineComponent({
             rules,
             formState,
             formRef,
-            isFloat,
-            isWR,
             getMaxNum,
             getMoney,
             getMargin,
             getSelectedAccount,
             getCanUseMoney,
             getPrice,
+            showPermance,
+            handlePermance,
+            choosePermance,
+            getAuctionwrType, getListingMode, ListingMode, AuctionwrType,
         };
     },
 });
 </script>
 
-<style lang="less">
+<style lang="less" scoped>
 .post_buying {
     width: 100%;
     height: 100%;
@@ -308,14 +421,22 @@ export default defineComponent({
     text-align: center;
     border: 0;
     &:hover {
-        background: linear-gradient(0deg, @m-blue0-hover 0%, @m-blue2-hover 100%);
+        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;
+        background: linear-gradient(
+            0deg,
+            @m-grey12-hover 0%,
+            @m-grey13-hover 100%
+        ) !important;
         color: @m-white0-hover;
     }
 }

+ 3 - 0
src/views/market/spot_trade/components/post_buying/interface.ts → src/views/market/market-spot/components/post_buying/interface.ts

@@ -8,6 +8,9 @@ export interface FormParam {
     PriceMove: number,
     DeliveryMonth: Moment,
     DelistMinQty: number,
+    permanceTempName:string;
+    permaceTempId:number;
+    marketid:number | undefined;
 }
 
 

+ 42 - 23
src/views/market/spot_trade/components/post_buying/setup.ts → src/views/market/market-spot/components/post_buying/setup.ts

@@ -1,13 +1,16 @@
-import { BuyOrSell } from "@/common/constants/enumCommon";
+import { ListingMode } from '@/common/constants/enumCommon';
 import { EnumRouterName } from "@/common/constants/enumRouterName";
-import { useVerifyListingNum, useVerifyListingBasis } from '@/hooks/form/verify';
+import { validateCommon } from "@/common/setup/validate";
+import { useVerifyBeginDelistingNum, useVerifyListingBasis, useVerifyListingNum } from '@/hooks/form/verify';
 import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
 import { getRules } from '@/services/bus/rules';
 import { AccountListItem } from "@/services/dataCenter/interafce/account";
 import { WrOrderQuote } from "@/services/go/wrtrade/interface";
+import { getListingMode } from '@/views/market/market-spot/setup';
+import { RuleObject } from "ant-design-vue/lib/form/interface";
 import moment from "moment";
 import { onBeforeUnmount, reactive, ref, UnwrapRef } from "vue";
-import { getGoodsPrice, handleIs } from "../buy-sell-market/setup";
+import { getGoodsPrice } from "../buy-sell-market/setup";
 import { FormParam, TempWrOrderQuoteDetail } from "./interface";
 
 function initFormData(): FormParam {
@@ -17,32 +20,37 @@ function initFormData(): FormParam {
         OrderQty: 0,
         PriceMove: 0,
         DelistMinQty: 0,
-        DeliveryMonth: moment()
+        DeliveryMonth: moment(),
+        permanceTempName: '',
+        permaceTempId: 0,
+        marketid: undefined,
     }
 }
 const formState: UnwrapRef<FormParam> = reactive(initFormData())
 export function handleForm(selectedRow: TempWrOrderQuoteDetail) {
     const formRef = ref();
-    formState.OrderQty = selectedRow.minivalue
-
+    //
     const { v_num } = useVerifyListingNum<FormParam, 'DelistMinQty'>(formState, 'DelistMinQty', selectedRow.minivalue);
     const { v_basis } = useVerifyListingBasis(selectedRow, 'goodsid');
-
+    const { v_beginDelistingRules, v_beginDelistingNum } = useVerifyBeginDelistingNum(selectedRow.minivalue)
+    const v_price = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入挂牌价格');
+    };
     const rules = {
-        FixedPrice: [{ required: true, message: '请输入挂牌价格', trigger: 'blur', type: 'number', }],
+        FixedPrice: [{ required: true, validator: v_price, trigger: 'blur', type: 'number', }],
         OrderQty: [{ required: true, validator: v_num, trigger: 'change', type: 'number' }],
         PriceMove: [{ required: true, validator: v_basis, trigger: 'blur', type: 'number', }],
+        DelistMinQty: [{ required: true, validator: v_beginDelistingNum, trigger: 'blur', type: 'number', }],
         accountid: [{ required: true, message: '请输入交易账号' }],
     }
     onBeforeUnmount(() => {
-        Object.assign(formState, initFormData(), { OrderQty: selectedRow.minivalue })
+        Object.assign(formState, initFormData())
     })
     return { rules, formState, formRef }
 }
 
 
 export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrderQuote) {
-    const { isFloat } = handleIs(enumName, BuyOrSell.buy)
     // 资金账号
     const accountList = getAccountTypeList([2]);
     // 获取选中的资金账号
@@ -58,7 +66,7 @@ export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrder
         const canUseMoney = Number(getCanUseMoney(getSelectedAccount() as AccountListItem))
         // 挂牌最大数量=可用资金/(买方履约保证金比例*挂牌价格)
         let result = 0
-        if (isFloat()) {
+        if (getListingMode(ListingMode.float)) {
             const price = getPrice()
             if (price !== '--') {
                 result = canUseMoney / (Number(price) * buymarginvalue)
@@ -69,22 +77,33 @@ export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrder
                 result = Math.round(canUseMoney / margin)
             }
         }
-        return +result.toFixed(0)
+
+        if (buymarginvalue !== 0) {
+            return +result.toFixed(0)
+        } else {
+            // 当市场设置的买保证金为0时,不做数量限制
+            return 10000
+        }
+
     }
     //  摘牌金额
     function getMoney() {
         let result = 0
-        if (isFloat()) {
-            const goodsPrice = getGoodsPrice()
-            if (goodsPrice.value && goodsPrice.value !== '--') {   // 有实时行情价格
-                // 估算总价=挂牌基差+期货合约价;
-                const predictTotal = formState.PriceMove + (goodsPrice.value as number);
-                // 估算总额=估算总价*摘牌数量;
-                result = predictTotal * formState.OrderQty
+        if (formState.OrderQty) {
+            if (getListingMode(ListingMode.float)) {
+                const goodsPrice = getGoodsPrice()
+                if (goodsPrice.value && goodsPrice.value !== '--') {   // 有实时行情价格
+                    // 估算总价=挂牌基差+期货合约价;
+                    const predictTotal = formState.PriceMove + (goodsPrice.value as number);
+                    // 估算总额=估算总价*摘牌数量;
+                    result = predictTotal * formState.OrderQty
+                }
+            } else {
+                // 摘牌金额=挂牌价格*摘牌数量
+                if (formState.FixedPrice) {
+                    result = formState.OrderQty * formState.FixedPrice
+                }
             }
-        } else {
-            // 摘牌金额=挂牌价格*摘牌数量
-            result = formState.OrderQty * formState.FixedPrice
         }
         return Number(result.toFixed(2))
     }
@@ -98,7 +117,7 @@ export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrder
     function getPrice() {
         let result = '--'
         const goodsPrice = getGoodsPrice()
-        if (goodsPrice.value && goodsPrice.value !== '--') {   // 有实时行情价格
+        if (goodsPrice.value && goodsPrice.value !== '--' && formState.PriceMove !== null) {   // 有实时行情价格
             result = ((goodsPrice.value as number) + formState.PriceMove).toFixed(2)
         }
         return result

+ 2 - 2
src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/setup.ts → src/views/market/market-spot/components/setup.ts

@@ -10,11 +10,11 @@ export function handleColumns() {
         { title: '仓库', key: 'warehousename', align: 'center', width: 200 },
         { title: '价格', key: 'fixedprice', align: 'center', width: 120 },
         { title: '议价', key: 'canbargain', align: 'center', width: 80 },
-        { title: '数量', key: 'orderqty', align: 'center' },
+        { title: '数量', key: 'orderqty', align: 'center', width: 120 },
         { title: '整单', key: 'canpart', align: 'center', width: 80 },
         { title: '挂牌有效期', key: 'validtime', align: 'center', width: 120 },
         { title: '履约保证金', key: 'marginvalue', align: 'center', width: 120 },
-        { title: '履约方式', key: 'templatename', align: 'center', width: 140 },
+        { title: '履约模板', key: 'templatename', align: 'center', width: 140 },
         { title: '挂牌方', key: 'username', align: 'center', width: 100 },
     ];
     function getBuyOrSellColumns(type: BuyOrSell) {

+ 0 - 0
src/views/market/market-spot/compoments/goods-chart/chart/index.less → src/views/market/market-spot/goods-chart/chart/index.less


+ 322 - 0
src/views/market/market-spot/goods-chart/chart/index.vue

@@ -0,0 +1,322 @@
+<template>
+  <!-- 交易图表  -->
+  <div class="chart-container">
+    <div class="chart-content">
+      <div class="chart-content__header">
+        <a-menu
+          class="chart-content__tabs"
+          v-model:selectedKeys="activeCycleName"
+          mode="horizontal"
+          @click="changeCycleType"
+        >
+          <a-menu-item v-for="item in chartType" :key="item.name">{{ item.label }}</a-menu-item>
+        </a-menu>
+        <a-menu
+          class="chart-content__tabs"
+          v-model:selectedKeys="activeSeriesType"
+          mode="horizontal"
+          v-if="activeCycleType !== CycleType.time"
+        >
+          <a-menu-item key="MACD">MACD</a-menu-item>
+          <a-menu-item key="VOL">VOL</a-menu-item>
+          <a-menu-item key="KDJ">KDJ</a-menu-item>
+          <a-menu-item key="CCI">CCI</a-menu-item>
+        </a-menu>
+      </div>
+      <echart-time
+        class="chart-content__main"
+        :quote-data="selectedRow"
+        @change="getHistoryTikDatas"
+        v-if="activeCycleType === CycleType.time"
+      ></echart-time>
+      <echart-kline
+        class="chart-content__main"
+        :quote-data="selectedRow"
+        :cycle-type="activeCycleType"
+        :series-type="activeSeriesType[0]"
+        v-else
+      ></echart-kline>
+      <div class="chart-content__footer"></div>
+    </div>
+    <div class="chart-slider">
+      <div class="chart-slider__button"></div>
+    </div>
+    <div class="chart-tips" v-if="showExchange">
+      <div>
+        <div class="chart-tips__nav">
+          <div class="content content--left">{{ selectedRow.goodscode }}</div>
+          <div class="content content--right">{{ selectedRow.goodsname }}</div>
+        </div>
+        <div class="chart-tips__last">
+          <div
+            :class="['content content--left', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]"
+          >{{ handleNoneValue(selectedRow.last) }}</div>
+          <div class="content content--right">
+            <span
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteChange(selectedRow) }}</span>
+            <span
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteAmplitude(selectedRow) }}</span>
+          </div>
+        </div>
+        <div class="chart-tips__volume">
+          <a-row>
+            <a-col :span="8">卖一</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.ask) }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.askvolume) }}</a-col>
+          </a-row>
+          <a-row>
+            <a-col :span="8">买一</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.bid) }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+              :span="8"
+            >{{ handleNoneValue(selectedRow.bidvolume) }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__tik">
+        <div class="row-header">
+          <h4>分时成交</h4>
+          <a-row>
+            <a-col :span="8">时间</a-col>
+            <a-col :span="8">价格</a-col>
+            <a-col :span="8">现量</a-col>
+          </a-row>
+        </div>
+        <div class="row-content">
+          <a-row v-for="(item, index) in tradedList" :key="index + '11'">
+            <a-col :span="8">{{ formatTime(item.TS, 'hm') }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(item.PE, selectedRow.presettle)"
+              :span="8"
+            >{{ item.PE }}</a-col>
+            <a-col
+              :class="handleQuotePriceColor(item.Vol, selectedRow.presettle)"
+              :span="8"
+            >{{ item.Vol }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__info">
+        <a-row>
+          <a-col :span="4">最新</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.last) }}</a-col>
+          <a-col :span="4">均价</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.averageprice, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.averageprice) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨跌</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ quoteChange(selectedRow) }}</a-col>
+          <a-col :span="4">今开</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.opened, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.opened) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨幅</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            :span="8"
+          >{{ quoteAmplitude(selectedRow) }}</a-col>
+          <a-col :span="4">最高</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.highest, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.highest) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">总量</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalvolume) }}</a-col>
+          <a-col :span="4">最低</a-col>
+          <a-col
+            :class="handleQuotePriceColor(selectedRow.lowest, selectedRow.presettle)"
+            :span="8"
+          >{{ handleNoneValue(selectedRow.lowest) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">金额</a-col>
+          <a-col :span="8" style="color: #0d96ff">{{ changeUnit(selectedRow.totalturnover) }}</a-col>
+          <a-col :span="4">量比</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨停</a-col>
+          <a-col class="red1" :span="8">{{ handleNoneValue(selectedRow.limitup) }}</a-col>
+          <a-col :span="4">跌停</a-col>
+          <a-col class="green" :span="8">{{ handleNoneValue(selectedRow.limitdown) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">外盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalbidvolume) }}</a-col>
+          <a-col :span="4">内盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalaskvolume) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">持仓</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.holdvolume) }}</a-col>
+          <a-col :span="4">结算</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.settle) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">仓差</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+          <a-col :span="4">昨结</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.presettle) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">日增</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+          <a-col :span="4">开平</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>
+      </div>
+      <div @click="watchMore" class="watchMore">
+        <strong>查看更多</strong>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref, watch } from 'vue';
+import { QueryQuoteDayRsp, QueryHistoryTikDatasRsp, CycleType } from '@/services/go/quote/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+import { changeUnit } from '@/utils/qt/common';
+import { ComponentType } from '@/views/market/market-spot/spot_trade_order_transaction/setup';
+import { EchartKline, EchartTime } from '@/common/components/echart';
+import { handleQuotePriceColor, quoteChange, handleNoneValue, quoteAmplitude } from '@/common/setup/table/tableQuote';
+import moment from 'moment';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: 'stock-exchange',
+  components: {
+    EchartKline,
+    EchartTime,
+  },
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryQuoteDayRsp>,
+      default: {},
+    },
+    showExchange: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context),
+      activeCycleName = ref<string[]>(['time']),
+      activeCycleType = ref<CycleType>(CycleType.time),
+      activeSeriesType = ref<string[]>(['MACD']),
+      tradedList = ref<QueryHistoryTikDatasRsp[]>([]);
+
+    function watchMore() {
+      context.emit('update', ComponentType.marketContent);
+    }
+
+    // 周期类型
+    const chartType = [
+      { label: '分时', name: 'time', value: CycleType.time },
+      { label: '1分钟', name: 'minutes', value: CycleType.minutes },
+      { label: '5分钟', name: 'minutes5', value: CycleType.minutes5 },
+      { label: '30分钟', name: 'minutes30', value: CycleType.minutes30 },
+      { label: '60分钟', name: 'minutes60', value: CycleType.minutes60 },
+      { label: '4小时', name: 'Hours4', value: CycleType.Hours4 },
+      { label: '日 K', name: 'days', value: CycleType.days },
+    ];
+
+    // 切换图表周期类型
+    const changeCycleType = (e: { key: string }) => {
+      activeCycleType.value = chartType.find((item) => item.name === e.key)!.value;
+    };
+
+    // Tik列表
+    const getHistoryTikDatas = (startTime: string, endTime: string) => {
+      const param = {
+        goodsCode: props.selectedRow.goodscode.toUpperCase(),
+        count: 20,
+        startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'),
+        endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'),
+      };
+      QueryHistoryTikDatas(param).then((res) => {
+        tradedList.value = res;
+      });
+    };
+
+    // 监听行情变化刷Tik列表
+    watch(
+      () => props.selectedRow.last,
+      () => {
+        if (tradedList.value.length > 19) {
+          // 移除列表最后一条记录
+          tradedList.value.pop();
+        }
+        // 向列表开头添加新纪录
+        tradedList.value.unshift({
+          AV: 0,
+          Ask: 0,
+          BV: 0,
+          Bid: 0,
+          HI: 0,
+          HV: 0,
+          PE: props.selectedRow.last,
+          TDR: 0,
+          TK: 0,
+          TS: props.selectedRow.lasttime,
+          TT: 0,
+          Vol: props.selectedRow.lastvolume,
+        });
+      }
+    );
+
+    return {
+      cancel,
+      visible,
+      chartType,
+      tradedList,
+      CycleType,
+      activeCycleName,
+      activeCycleType,
+      activeSeriesType,
+      changeUnit,
+      watchMore,
+      formatTime,
+      quoteChange,
+      handleNoneValue,
+      quoteAmplitude,
+      handleQuotePriceColor,
+      changeCycleType,
+      getHistoryTikDatas,
+    };
+  },
+});
+</script>
+
+<style lang="less">
+@import "./index.less";
+</style>

+ 73 - 37
src/views/market/spot_trade/components/goods-chart/index.vue → src/views/market/market-spot/goods-chart/index.vue

@@ -12,12 +12,20 @@
       <div class="inlineBar">
         <div class="valNums bdf1 ml10">
           <!-- 最新价 -->
-          <div class="firstNum start" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ selectedRow.last }}</div>
+          <div
+            class="firstNum start"
+            :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+          >{{ selectedRow.last }}</div>
           <div class="lastNum start">
             <!-- 涨跌值 -->
-            <div :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
+            <div
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
             <!-- 涨跌幅 -->
-            <div class="ml20" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
+            <div
+              class="ml20"
+              :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"
+            >{{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
           </div>
         </div>
         <div class="priceBar ml20">
@@ -25,11 +33,17 @@
             <div class="greenBar">
               <div class="numBlock ml15">
                 <div class="first grey">卖价</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.ask }}</div>
+                <div
+                  class="last"
+                  :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+                >{{ selectedRow.ask }}</div>
               </div>
               <div class="numBlock">
                 <div class="first grey">卖量</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.askvolume }}</div>
+                <div
+                  class="last"
+                  :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"
+                >{{ selectedRow.askvolume }}</div>
               </div>
             </div>
           </div>
@@ -37,25 +51,43 @@
             <div class="redBar">
               <div class="numBlock">
                 <div class="first grey">买价</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bid }}</div>
+                <div
+                  class="last"
+                  :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+                >{{ selectedRow.bid }}</div>
               </div>
               <div class="numBlock">
                 <div class="first grey">买量</div>
-                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bidvolume }}</div>
+                <div
+                  class="last"
+                  :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"
+                >{{ selectedRow.bidvolume }}</div>
               </div>
             </div>
           </div>
         </div>
       </div>
-      <div class="btn-list">
+      <div class="btn-list" v-if="isShowTrade">
         <a-button class="operBtn" @click="openComponent({ code: 'trade' })">交易</a-button>
       </div>
     </div>
     <!-- 交易图表 -->
-    <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :selectedRow="selectedRow" />
+    <Chart
+      v-if="showComponentsId === ComponentType.chart"
+      @update="changeComponent"
+      :selectedRow="selectedRow"
+    />
     <!-- 成交明细 -->
-    <StockExchange :selectedRow="selectedRow" v-if="showComponentsId === ComponentType.tradeDetail" />
-    <component :is="componentId" v-if="componentId" :selectedRow="selectedRow" @cancel="closeComponent"></component>
+    <StockExchange
+      :selectedRow="selectedRow"
+      v-if="showComponentsId === ComponentType.tradeDetail"
+    />
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :selectedRow="selectedRow"
+      @cancel="closeComponent"
+    ></component>
   </div>
 </template>
 
@@ -79,6 +111,10 @@ export default defineComponent({
       type: Object as PropType<QueryQuoteDayRsp>,
       default: () => ({}),
     },
+    isShowTrade: {
+      type: Boolean,
+      default: false,
+    }
   },
   components: {
     Chart,
@@ -127,37 +163,37 @@ export default defineComponent({
 </script>
 <style lang="less">
 .valNums {
-    .flex;
-    flex-direction: column;
-    padding-left: 20px;
-    .firstNum {
-        font-size: 18px;
-        line-height: 18px;
-        font-weight: 400;
-    }
-    .lastNum {
-        margin-top: 2px;
-        display: inline-flex;
-        font-size: 12px;
-        line-height: 12px;
-        font-weight: 300;
-    }
+  .flex;
+  flex-direction: column;
+  padding-left: 20px;
+  .firstNum {
+    font-size: 18px;
+    line-height: 18px;
+    font-weight: 400;
+  }
+  .lastNum {
+    margin-top: 2px;
+    display: inline-flex;
+    font-size: 12px;
+    line-height: 12px;
+    font-weight: 300;
+  }
 }
 .inlineBar {
-    display: inline-flex;
+  display: inline-flex;
 }
 .priceBar {
-    .flex;
-    flex-direction: column;
-    height: 32px;
-    .greenBar,
-    .redBar {
-        height: 16px;
-        line-height: 16px;
-    }
+  .flex;
+  flex-direction: column;
+  height: 32px;
+  .greenBar,
+  .redBar {
+    height: 16px;
+    line-height: 16px;
+  }
 }
 .start {
-    align-self: flex-start !important;
-    align-items: flex-start !important;
+  align-self: flex-start !important;
+  align-items: flex-start !important;
 }
 </style>

+ 0 - 0
src/views/market/spot_trade/components/goods-chart/setup.ts → src/views/market/market-spot/goods-chart/setup.ts


+ 0 - 0
src/views/market/market-spot/compoments/goods-chart/stock-exchange/index.vue → src/views/market/market-spot/goods-chart/stock-exchange/index.vue


+ 35 - 10
src/views/market/market-spot/index.vue

@@ -1,32 +1,49 @@
 <template>
-  <div class="topTableHeight">
-    <FristMenu :list="marketsSetion" :value="'marketsectionname'" @selectMenu="selectSection" />
-    <component :is="componentId" v-if="componentId"></component>
-    <ThirdMenu :list="markets" :value="'marketname'" @selectMenu="onSelectMarket" />
+  <div class="exposure">
+    <div class="topTableHeight">
+      <FristMenu :list="marketsSetion" :value="'marketsectionname'" @selectMenu="selectSection" />
+      <component :is="componentId" v-if="componentId"></component>
+      <ThirdMenu :list="markets" :value="'marketname'" @selectMenu="onSelectMarket" />
+    </div>
   </div>
 </template>
 
 <script lang="ts">
 import FristMenu from '@/common/components/firstMenu/index.vue';
 import ThirdMenu from '@/common/components/thirdMenu/index.vue';
-import { TradeMode } from '@/common/constants/enumCommon';
+import { TradeMode, ListingMode, AuctionwrType } from '@/common/constants/enumCommon';
 import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
 import { initData } from '@/common/methods';
 import APP from '@/services';
 import { TjmdMarketSection, TjmdMarketSectionConfig } from '@/services/go/Tjmd/interface';
 import { ref } from 'vue';
+import { setMarketId } from './setup'
 
 export default defineComponent({
   components: {
     FristMenu,
     ThirdMenu,
     contextMenu,
-    // 仓单贸易
-    [TradeMode.WarehouseReceiptTrade]: defineAsyncComponent(() => import('./compoments/warehouse_receipt_trade/index.vue')),
+    // 仓单贸易 有仓单 一口价
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.hasWr}-${ListingMode.fix}`]: defineAsyncComponent(() => import('./warehouse_receipt_trade/warehouse_receipt_trade_price/index.vue')),
+    // 仓单贸易 有仓单 浮动价
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.hasWr}-${ListingMode.float}`]: defineAsyncComponent(() => import('./warehouse_receipt_trade/warehouse_receipt_trade_floating_price/index.vue')),
+    // 仓单贸易 有仓单 贸易圈
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.hasWr}-${ListingMode.blocs}`]: defineAsyncComponent(() => import('./warehouse_receipt_trade/warehouse_receipt_trade_blocs/index.vue')),
+    // 仓单贸易 有仓单 协议指定
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.hasWr}-${ListingMode.designate}`]: defineAsyncComponent(() => import('./warehouse_receipt_trade/warehouse_receipt_trade_designate/index.vue')),
+    // 仓单贸易 无仓单 一口价
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.noWr}-${ListingMode.fix}`]: defineAsyncComponent(() => import('./warehouse_pre_sale/warehouse_pre_sale_price/index.vue')),
+    // 仓单贸易 无仓单 浮动价
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.noWr}-${ListingMode.float}`]: defineAsyncComponent(() => import('./warehouse_pre_sale/warehouse_pre_sale_floating_price/index.vue')),
+    // 仓单贸易 无仓单 贸易圈
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.noWr}-${ListingMode.blocs}`]: defineAsyncComponent(() => import('./warehouse_pre_sale/warehouse_pre_sale_blocs/index.vue')),
+    // 仓单贸易 无仓单 协议指定
+    [`${TradeMode.WarehouseReceiptTrade}-${AuctionwrType.noWr}-${ListingMode.designate}`]: defineAsyncComponent(() => import('./warehouse_pre_sale/warehouse_pre_sale_designate/index.vue')),
     // 参考行情
-    [TradeMode.quote99]: defineAsyncComponent(() => import('./compoments/spot_trade_reference_market/index.vue')),
+    [TradeMode.quote99]: defineAsyncComponent(() => import('./spot_trade_reference_market/index.vue')),
     // 掉期贸易
-    [TradeMode.DiaoQi]: defineAsyncComponent(() => import('./compoments/spot_trade_order_transaction/index.vue')),
+    [TradeMode.DiaoQi]: defineAsyncComponent(() => import('./spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue')),
   },
   setup() {
     // 市场板块
@@ -51,8 +68,16 @@ export default defineComponent({
     }
     // 切换市场
     function onSelectMarket(index: number, value: TjmdMarketSectionConfig) {
+      const { trademode, auctionwrtype, listingmode } = value
+      // 仓单贸易
+      if (value.trademode === TradeMode.WarehouseReceiptTrade) {
+        componentId.value = `${trademode}-${auctionwrtype}-${listingmode}`
+      } else {
+        componentId.value = value.trademode.toString()
+      }
+      // 缓存 当前市场 交易模式 是否有仓单,挂牌方式信息
+      setMarketId(componentId.value)
       selctedMarket.value = value
-      componentId.value = value.trademode.toString()
     }
 
     return { marketsSetion, selectSection, markets, onSelectMarket, componentId };

+ 0 - 0
src/views/market/spot_trade/interface.ts → src/views/market/market-spot/interface.ts


+ 136 - 2
src/views/market/market-spot/setup.ts

@@ -1,7 +1,42 @@
+import { BtnListType } from '@/common/components/btnList/interface';
+import { ContextMenuTemp } from '@/common/components/contextMenu/interface';
+import { handleContextMenu } from '@/common/components/contextMenu/setup';
+import { AuctionwrType, ListingMode } from '@/common/constants/enumCommon';
+import { ComposeTableParam } from '@/common/export/commonTable';
 import { initData } from '@/common/methods';
+import { getTableColumns, getTableEvent } from '@/common/setup/table';
+import { TableEventCB } from '@/common/setup/table/interface';
 import APP from '@/services';
 import { TjmdMarketSection, TjmdMarketSectionConfig } from '@/services/go/Tjmd/interface';
-import { ref } from 'vue';
+import { queryFtDeliveryGoods } from '@/services/go/wrtrade';
+import TimerUtils from '@/utils/timer/timerUtil';
+import { onUnmounted, ref } from 'vue';
+import { TreeDataItem } from './interface';
+
+const buyAndSellEunm = 'buyAndSell'
+
+// 动态市场 具体显示的市场
+export const marketTradeType = ref<string>('')
+
+export function setMarketId(value: string) {
+    marketTradeType.value = value
+}
+
+function getType() {
+    return marketTradeType.value.split('-')
+}
+
+// 判断 仓单类型
+export function getAuctionwrType(type: AuctionwrType) {
+    const arr = getType()
+    return type === +arr[1]
+}
+
+// 判断 挂牌方式
+export function getListingMode(mode: ListingMode) {
+    const arr = getType()
+    return mode === +arr[2]
+}
 
 export const useMarketsSection = () => {
     // 市场板块
@@ -25,4 +60,103 @@ export const useMarketsSection = () => {
     }
 
     return { marketsSetion, selectSection, markets, onSelectMarket, selctedMarket }
-}
+}
+
+const FtDeliveryGoods = ref<TreeDataItem[]>([])
+// 获取报价大厅商品过滤项数据
+export function handleFtDeliveryGoods() {
+    if (FtDeliveryGoods.value.length === 0) {
+        initData(() => {
+            queryFtDeliveryGoods().then(res => {
+                console.log('dddddddddd', res)
+                const result: TreeDataItem[] = []
+                res.forEach(el => {
+                    const { deliverygoodsid, deliverygoodsname, wdlst } = el
+                    const item: TreeDataItem = {
+                        title: deliverygoodsname,
+                        key: deliverygoodsid + '--',
+                        value: deliverygoodsid + '--',
+                        enumdicname: '',
+                        minivalue: 0,
+                        children: []
+                    }
+                    wdlst.forEach(e => {
+                        const { wrstandardid, wrstandardname, enumdicname, minivalue } = e
+                        item.children?.push({ value: wrstandardid, key: wrstandardid, title: wrstandardname, enumdicname, minivalue })
+                    })
+                    result.push(item)
+                })
+                FtDeliveryGoods.value = result;
+            })
+        })
+    }
+    return { FtDeliveryGoods }
+}
+
+// 表格 + 表头 + 右键 + 单击表格 + 按钮列表 通用处理逻辑
+export function handleComposeTable<T>({ queryFn, menuType, isDetail, tableName, tableFilterKey }: ComposeTableParam) {
+    // 右键逻辑
+    const { contextMenu, openContext, closeContext: closeContextAction } = handleContextMenu();
+    // 表头数据
+    const { columns, registerColumn, updateColumn } = getTableColumns();
+    // 控制异步组件
+    const componentId = ref<string>('');
+    // 关闭组件
+    function closeComponent(isRefresh: boolean) {
+        componentId.value = '';
+        if (isRefresh) {
+            queryFn()
+        }
+    }
+    // 右键回调函数
+    const eventsCB: TableEventCB = {
+        contextmenuCB: (record: T, value: ContextMenuTemp) => {
+            // 控制打开右键
+            contextMenu.value = value
+        },
+        clickCB: (record: T) => {
+            componentId.value = buyAndSellEunm
+        }
+    }
+    // 表格事件
+    const { expandedRowKeys, selectedRow, Rowclick } = getTableEvent<T>(eventsCB);
+    // 表格操作按钮列表
+    const firstBtn: BtnListType[] = []
+    firstBtn.push({ lable: '买卖大厅', code: buyAndSellEunm, className: 'btnPrimary' })
+
+    // 关闭右键
+    function closeContext(value: BtnListType | null) {
+        // 打开对应的弹窗组件
+        if (value) componentId.value = value.code;
+        // 关闭右键
+        closeContextAction()
+    }
+    onUnmounted(() => {
+        // 离开组件,手动关闭右键,防止出现bug
+        TimerUtils.clearInterval('spotTrade')
+        closeContextAction()
+    })
+    initData(() => {
+        // 获取列表数据
+        queryFn();
+        // 10秒刷新一次列表
+        TimerUtils.setInterval(() => {
+            queryFn()
+        }, 10 * 1000, 'spotTrade')
+        // 注册表头信息 过滤
+        if (tableName) {
+            registerColumn(tableName, tableFilterKey);
+        }
+
+    });
+
+    return {
+        contextMenu, openContext, closeContext, // 右键
+        columns, registerColumn, updateColumn,  // 表头
+        expandedRowKeys, selectedRow, Rowclick, // 表格折腾面板数据与单击、双击事件
+        componentId, closeComponent,  // 控制异步组件
+        firstBtn, // 表格按钮
+    }
+}
+
+

+ 125 - 0
src/views/market/market-spot/spot_trade_order_transaction/components/buy-market/index.vue

@@ -0,0 +1,125 @@
+<template>
+    <!--  现货贸易 - 买卖大厅 - 卖报价牌 -->
+    <a-table
+        :columns="handleColumn(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="btnListData"
+                :record="record"
+                class="btn-list-sticky"
+                @click="openComponent"
+            />
+        </template>
+        <template #fixedprice="{record }">
+            <span>{{record.useorderpricerid }}</span>
+        </template>
+        <template #username="{text, record }">
+            <span>{{record.userid + " "}}{{text}}</span>
+        </template>
+    </a-table>
+    <component
+        :is="componentId"
+        v-if="componentId"
+        :selectedRow="selectedRow"
+        :parantSelectedRow="parantSelectedRow"
+        :buyOrSell="BuyOrSell.buy"
+        @cancel="closeComponent"
+    ></component>
+</template>
+
+<script lang="ts">
+import { BtnList, defineComponent, queryTableList } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryWrTradeOrderDetail } from '@/services/go/wrtrade';
+import { WrOrderQuote, WrOrderQuoteDetail, WrTradeOrderDetailReq } 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 { getShowBottomValue } from '@/common/config/constrolBottom';
+import { TableParam } from '@/common/setup/table/interface';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+
+export default defineComponent({
+    emits: ['cancel', 'openComponent'],
+    name: 'warehouse_receipt_trade_price_delisting_buy',
+    props: {
+        parantSelectedRow: {
+            type: Object as PropType<QueryDeliveryRelationRsp>,
+            default: {},
+        },
+    },
+    components: {
+        BtnList,
+        Delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuoteDetail>();
+        const columnsList = [
+            { title: '序号', key: 'index', width: 60 },
+            { title: '买价', key: 'orderprice' },
+            { title: '买量', key: 'orderqty' },
+            { title: '购买方', key: 'username' },
+        ];
+        const btnListData: BtnListType[] = [{ lable: '摘牌', code: 'Delisting', className: 'operBtn' }];
+
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: WrTradeOrderDetailReq = {
+                buyorsell: 0,
+                goodsid: props.parantSelectedRow.goodsid,
+            };
+            queryTable(queryWrTradeOrderDetail, param);
+        };
+        const param: TableParam = {
+            columnsList,
+            queryFn: queryTableAction,
+        };
+        function handleColumn(columns: ColumnType[]) {
+            columns.forEach((item) => {
+                if (item.dataIndex == 'username') {
+                    delete item.width;
+                }
+            });
+            return columns;
+        }
+        return {
+            isBottom,
+            ...handleTableEventAndData(param),
+            queryTableAction,
+            BuyOrSell,
+            loading,
+            tableList,
+            expandIcon,
+            handleColumn,
+            btnListData,
+            columnsList,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 30px;
+    }
+}
+</style>

+ 96 - 70
src/views/market/spot_trade/spot_trade_order_transaction/components/buy-sell-market/index.vue → src/views/market/market-spot/spot_trade_order_transaction/components/buy-sell-market/index.vue

@@ -1,70 +1,92 @@
 <template>
-    <!-- 买卖大厅 -->
-    <div class="buy-sell-market">
-        <div class="buy-sell-market-title">
-            <a class="backIcon" @click="cancelAction">
-                <LeftOutlined />
-            </a>
-            <div class="titleBtn">
-                <div class="name">{{ selectedRow.goodscode }} {{ selectedRow.goodsname }}</div>
-                <div class="arrowRightIcon"></div>
+  <!-- 买卖大厅 -->
+  <div class="buy-sell-market">
+    <div class="buy-sell-market-title">
+      <a class="backIcon"
+         @click="cancelAction">
+        <LeftOutlined />
+      </a>
+      <div class="titleBtn">
+        <div class="name">{{ selectedRow.goodscode }} {{ selectedRow.goodsname }}</div>
+        <div class="arrowRightIcon"></div>
+      </div>
+      <div class="inlineBar">
+        <div class="valNums bdf1 ml10">
+          <!-- 最新价 -->
+          <div
+               :class="['firstNum', 'start', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]">
+            {{ handleNoneValue(selectedRow.last) }}</div>
+          <div class="lastNum start">
+            <!-- 涨跌值 -->
+            <div :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">
+              {{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
+            <!-- 涨跌幅 -->
+            <div class="ml20"
+                 :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">
+              {{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
+          </div>
+        </div>
+        <div class="priceBar ml20">
+          <div class="inlineBar start">
+            <div class="greenBar green">
+              <div class="numBlock ml15">
+                <div class="first">卖价</div>
+                <div class="last"
+                     :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">
+                  {{ handleNoneValue(selectedRow.ask) }}</div>
+              </div>
+              <div class="numBlock">
+                <div class="first">卖量</div>
+                <div class="last">{{ handleNoneValue(selectedRow.askvolume) }}</div>
+              </div>
             </div>
-            <div class="inlineBar">
-                <div class="valNums bdf1 ml10">
-                    <!-- 最新价 -->
-                    <div :class="['firstNum', 'start', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]"> {{ selectedRow.last }}</div>
-                    <div class="lastNum start">
-                        <!-- 涨跌值 -->
-                        <div :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"> {{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
-                        <!-- 涨跌幅 -->
-                        <div class="ml20" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)"> {{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
-                    </div>
-                </div>
-                <div class="priceBar ml20">
-                    <div class="inlineBar start">
-                        <div class="greenBar green">
-                            <div class="numBlock ml15">
-                                <div class="first">卖价</div>
-                                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)"> {{ selectedRow.ask }}</div>
-                            </div>
-                            <div class="numBlock">
-                                <div class="first">卖量</div>
-                                <div class="last">{{ selectedRow.askvolume }}</div>
-                            </div>
-                        </div>
-                    </div>
-                    <div class="inlineBar start">
-                        <div class="redBar red1">
-                            <div class="numBlock">
-                                <div class="first">买价</div>
-                                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)"> {{ selectedRow.bid }}</div>
-                            </div>
-                            <div class="numBlock">
-                                <div class="first">买量</div>
-                                <div class="last">{{ selectedRow.bidvolume }}</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <BtnList :btnList="btnListData" :record="selectedRow" @click="openComponent" />
+          </div>
+          <div class="inlineBar start">
+            <div class="redBar red1">
+              <div class="numBlock">
+                <div class="first">买价</div>
+                <div class="last"
+                     :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">
+                  {{ handleNoneValue(selectedRow.bid) }}</div>
+              </div>
+              <div class="numBlock">
+                <div class="first">买量</div>
+                <div class="last">{{ handleNoneValue(selectedRow.bidvolume) }}</div>
+              </div>
             </div>
+          </div>
         </div>
-        <!-- 交易图表 -->
-        <!-- <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :deliverGoods="deliverGoods" /> -->
-        <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :selectedRow="selectedRow" />
-        <!-- 买卖大厅内容 -->
-        <a-row class="buySellHall" v-if="showComponentsId === ComponentType.marketContent">
-            <a-col :span="12">
-                <Sell ref="sellRef" :parantSelectedRow="deliverGoods" />
-            </a-col>
-            <a-col :span="12">
-                <Buy ref="buyRef" :parantSelectedRow="deliverGoods" />
-            </a-col>
-        </a-row>
-        <!-- 成交明细 -->
-        <StockExchange :deliverGoods="deliverGoods" v-if="showComponentsId === ComponentType.tradeDetail" />
-        <component :is="componentId" v-if="componentId" :selectedRow="selectedRow" :deliverGoods="deliverGoods" @cancel="closeComponent"></component>
+        <BtnList :btnList="handleBtnList()"
+                 :record="selectedRow"
+                 @click="openComponent" />
+      </div>
     </div>
+    <!-- 交易图表 -->
+    <!-- <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :deliverGoods="deliverGoods" /> -->
+    <Chart v-if="showComponentsId === ComponentType.chart"
+           @update="changeComponent"
+           :selectedRow="selectedRow" />
+    <!-- 买卖大厅内容 -->
+    <a-row class="buySellHall"
+           v-if="showComponentsId === ComponentType.marketContent">
+      <a-col :span="12">
+        <Sell ref="sellRef"
+              :parantSelectedRow="deliverGoods" />
+      </a-col>
+      <a-col :span="12">
+        <Buy ref="buyRef"
+             :parantSelectedRow="deliverGoods" />
+      </a-col>
+    </a-row>
+    <!-- 成交明细 -->
+    <StockExchange :deliverGoods="deliverGoods"
+                   v-if="showComponentsId === ComponentType.tradeDetail" />
+    <component :is="componentId"
+               v-if="componentId"
+               :selectedRow="selectedRow"
+               :deliverGoods="deliverGoods"
+               @cancel="closeComponent"></component>
+  </div>
 </template>
 
 <script lang="ts">
@@ -88,14 +110,15 @@ import StockExchange from '../stock-exchange/index.vue';
 //import Chart from '../chart/index.vue';
 import Chart from '../../../components/goods-chart/chart/index.vue'; // 暂用组件,待优化
 import { ComponentType } from '../../setup';
-import { handleSubcriteOnDemandQuote, handleQuotePriceColor, quoteChange, quoteAmplitude, quoteAmplituOfVibration } from '@/common/setup/table/tableQuote';
+import { handleSubcriteOnDemandQuote, handleQuotePriceColor, quoteChange, quoteAmplitude, quoteAmplituOfVibration, handleNoneValue } from '@/common/setup/table/tableQuote';
+import { Tradesfer } from '../../spot_trade_order_transaction_listing_transfer/interface';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
     name: 'buy-sell-market',
     props: {
         selectedRow: {
-            type: Object as PropType<QueryQuoteDayRsp>,
+            type: Object as PropType<Tradesfer>,
             default: {},
         },
         deliverGoods: {
@@ -116,11 +139,13 @@ export default defineComponent({
     setup(props, context) {
         const loading = ref<boolean>(false);
         const { visible, cancel } = _closeModal(context);
-
-        const btnListData: BtnListType[] = [
-            { lable: '挂牌求购', code: 'Listing', className: 'operBtn' },
-            { lable: '详情', code: 'Detail', className: 'btnDeafault' },
-        ];
+        function handleBtnList() {
+            const result: BtnListType[] = [{ lable: '挂牌求购', code: 'Listing', className: 'operBtn' }];
+            if (props.selectedRow.deliverytype) {
+                result.push({ lable: '详情', code: 'Detail', className: 'btnDeafault' });
+            }
+            return result;
+        }
 
         onBeforeUnmount(() => {
             TimerUtils.clearInterval('buyAndSellMartet');
@@ -167,16 +192,17 @@ export default defineComponent({
             componentId,
             closeComponent,
             openComponent,
-            btnListData,
             changeComponent,
             ComponentType,
             showComponentsId,
             cancelAction,
             handleSubcriteOnDemandQuote,
             handleQuotePriceColor,
+            handleNoneValue,
             quoteChange,
             quoteAmplitude,
             quoteAmplituOfVibration,
+            handleBtnList,
         };
     },
 });

+ 0 - 31
src/views/market/spot_trade/spot_trade_order_transaction/components/buy-sell-market/setup.ts → src/views/market/market-spot/spot_trade_order_transaction/components/buy-sell-market/setup.ts

@@ -1,4 +1,3 @@
-import { BuyOrSell } from '@/common/constants/enumCommon';
 import { EnumRouterName } from '@/common/constants/enumRouterName';
 import { queryResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
 import { TableKey } from '@/common/methods/table/interface';
@@ -78,36 +77,6 @@ export function getSellMarketParam(enumName: EnumRouterName) {
     return { wrpricetype, haswr, tableKey }
 }
 
-export function handleIs(enumName: EnumRouterName, buyOrSell: BuyOrSell) {
-    /**
-     *
-     * @returns 1 => 仓单贸易; 0 => 仓单预售
-     */
-    function isWR(): 0 | 1 {
-        if (enumName === EnumRouterName.warehouse_receipt_trade_price || enumName === EnumRouterName.warehouse_receipt_trade_floating_price) {
-            return 1
-        } else {
-            return 0
-        }
-    }
-    /**
-     *
-     * @returns true => 买; false =>卖
-     */
-    function isBuy() {
-        return buyOrSell === BuyOrSell.buy
-    }
-    /**
-     *
-     * @returns  true => 浮动价; false =>一口价
-     */
-    function isFloat() {
-        return enumName === EnumRouterName.warehouse_receipt_trade_floating_price ||
-            enumName === EnumRouterName.warehouse_pre_sale_floating_price
-    }
-    return { isWR, isBuy, isFloat }
-}
-
 const list = ref<WrFAProductDetail[]>([]);
 // 获取融资摘牌
 export function handleFinacing(loading: Ref<boolean>, id: number) {

+ 0 - 0
src/views/market/spot_trade/spot_trade_order_transaction/components/chart/index.vue → src/views/market/market-spot/spot_trade_order_transaction/components/chart/index.vue


+ 366 - 0
src/views/market/market-spot/spot_trade_order_transaction/components/delisting/index.vue

@@ -0,0 +1,366 @@
+<template>
+  <!-- 仓单贸易&仓单预售 买/卖 摘牌 -->
+  <Drawer
+    :title="'摘牌'"
+    :placement="'right'"
+    :visible="visible"
+    width="486px"
+    height="479px"
+    @cancel="cancel"
+    class="top"
+  >
+    <div class="delisting">
+      <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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{ selectedRow.username }}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌价格">
+                <span class="white ml8">{{ selectedRow.orderprice.toFixed(2) }}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{ selectedRow.orderqty }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量" class="relative" name="num">
+                <a-input-number
+                  class="dialogInput yellowInput"
+                  style="width: 260px"
+                  :min="0"
+                  :max="99999"
+                  v-model:value="formState.num"
+                />
+                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
+                <!-- <div
+                                    class="labelTip"
+                >({{selectedRow.minivalue}}{{selectedRow.enumdicname}}起)</div>-->
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item>
+                <a-slider
+                  :min="0"
+                  v-model:value="formState.num"
+                  :max="selectedRow.orderqty"
+                  class="formSlider"
+                  style="width: 260px"
+                />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{ selectedRow.orderqty }}{{ 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="24" class="mt-20">
+              <a-form-item label="摘牌金额">
+                <span class="white ml8">{{ getMoney() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <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"
+                :loading="loading"
+                :disabled="loading"
+                @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 { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { defineComponent, PropType, ref } from 'vue';
+import Drawer from '@/common/components/drawer/index.vue';
+import { WrOrderQuote, WrOrderQuoteDetail, WrTradeOrderDetailReq, WrTradeOrderDetailRsp } from '@/services/go/wrtrade/interface';
+import { getAccount_longType, getAccountTypeList, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { HdWRDealOrder } from '@/services/proto/warehousetrade';
+import { v4 as uuidv4 } from 'uuid';
+import moment from 'moment';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { HdWRDealOrderReq } from '@/services/proto/warehousetrade/interface';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { handleForm } from './setup';
+import { validateAction } from '@/common/setup/form';
+import { ListingForm, TempWrOrderQuoteDetail } from './interface';
+import { BuyOrSell, DelistingType, PriceType } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { getCanUseMoney } from '@/services/bus/account';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { Order } from '@/services/socket/order';
+import { OrderReq } from '@/services/socket/order/interface';
+import { geLoginID_number } from '@/services/bus/login';
+import { LongType } from '@/services/socket/login/interface';
+import * as Long from 'long';
+export default defineComponent({
+  name: ModalEnum.spot_trade_warehouse_financing_delisting,
+  components: { Drawer, PlusOutlined, MinusOutlined },
+  emits: ['cancel', 'update'],
+  props: {
+    selectedRow: {
+      type: Object as PropType<WrTradeOrderDetailRsp>,
+      default: {},
+    },
+    parantSelectedRow: {
+      type: Object as PropType<QueryDeliveryRelationRsp>,
+      default: {},
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      default: BuyOrSell.buy,
+    },
+  },
+
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    // 资金账号
+    const accountList = getAccountTypeList([2]);
+    const { rules, formState, formRef } = handleForm(props.selectedRow);
+    if (accountList.length) {
+      formState.accountid = accountList[0].accountid;
+    }
+    function getSelectedAccount() {
+      return accountList.find((e) => e.accountid === formState.accountid);
+    }
+    const loading = ref<boolean>(false);
+    function isBuy() {
+      return props.buyOrSell === BuyOrSell.buy;
+    }
+    function getMoney() {
+      // return (formState.price * formState.num).toFixed(2);
+    }
+    // const { getMaxNum, getMoney, getMargin } = handleNumAndMoney(props.enumName, props.buyOrSell, props.selectedRow, props.parantSelectedRow, formState);
+    function submit() {
+      validateAction<ListingForm>(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: getSelectedAccountId(), // 交易账号
+          GoodsID: props.parantSelectedRow.goodsid, // 商品ID
+          MarketID: props.parantSelectedRow.marketid, // 市场ID
+          ValidType: 1, // 校验类型 当日有效
+          OperateType: 1, // 操作类型: 申请
+          OrderSrc: 1, // 单据来源: 客户端下单
+          RelatedID: Long.fromString(props.selectedRow.orderid), // 操作员账号ID
+          OrderPrice: props.selectedRow.orderprice, // 委托价格
+          OperatorID: Number(geLoginID_number()),
+          // MarketMaxSub: number // 市价允许最大偏差(做市)
+          OrderQty: res.num, // 委托数量
+          BuyOrSell: props.selectedRow.buyorsell === 1 ? 0 : 1, // 买卖方向  0 买 1 卖
+          BuildType: props.selectedRow.buyorsell === 1 ? 1 : 2, // 下单类型  1 建 2 平
+          // CurtQuotePrice: 0, // 保留,计算冻结金额使用
+          // SpPrice: 0 ,// 止盈价格
+          // SlPrice: 0 , // 止损价格
+          PriceMode: PriceType.limit, // 取价方式
+          TimevalidType: 1, // 时间有效类型 单日有效
+          TriggerType: 1, // 预埋单触发类型
+          // TriggerPrice: number // 预埋单触发价格
+          ListingSelectType: 2, // 挂牌点选类型 1:挂牌 2:摘牌 3:先摘后挂
+          DelistingType: DelistingType.selected, // 摘牌类型 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
+        };
+        requestResultLoadingAndInfo(Order, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
+          cancel(true);
+        });
+      });
+    }
+
+    return {
+      visible,
+      cancel,
+      accountList,
+      loading,
+      submit,
+      isBuy,
+      rules,
+      formState,
+      formRef,
+      getCanUseMoney,
+      getSelectedAccount,
+      getMoney,
+    };
+  },
+});
+</script>
+
+<style lang="less">
+.delisting {
+  width: 100%;
+  height: 100%;
+  .flex;
+  flex-direction: column;
+  overflow: hidden;
+  .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;
+    }
+  }
+  .ant-form {
+    height: 100%;
+  }
+}
+::v-deep.ant-slider.formSlider {
+  width: 260px;
+}
+::v-deep.ant-input-suffix {
+  position: absolute;
+  right: -25px;
+}
+.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-20 {
+  margin-top: -20px;
+}
+.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;
+}
+</style>;

+ 0 - 0
src/views/market/spot_trade/components/buy-sell-market/components/delisting/interface.ts → src/views/market/market-spot/spot_trade_order_transaction/components/delisting/interface.ts


+ 0 - 0
src/views/market/spot_trade/spot_trade_order_transaction/components/delisting/setup.ts → src/views/market/market-spot/spot_trade_order_transaction/components/delisting/setup.ts


+ 1 - 1
src/views/market/spot_trade/spot_trade_order_transaction/components/detail/index.vue → src/views/market/market-spot/spot_trade_order_transaction/components/detail/index.vue

@@ -23,7 +23,7 @@
                  v-for="item in lststep"
                  :key="item.autoid">
               <!-- <div class="no">{{index + 1}}</div> -->
-              <div class="name">{{item.steptypename}}</div>
+              <div class="name">{{item.stepinfo}}</div>
               <div class="time">{{item.stepdate}}</div>
             </div>
           </a-col>

+ 14 - 5
src/views/market/spot_trade/spot_trade_order_transaction/components/listing/index.vue → src/views/market/market-spot/spot_trade_order_transaction/components/listing/index.vue

@@ -1,6 +1,6 @@
 <template>
   <!-- 贸易圈挂牌 -->
-  <Drawer :title="'挂牌'"
+  <Drawer :title="'挂牌求购'"
           :placement="'right'"
           :visible="visible"
           width="486px"
@@ -45,7 +45,7 @@
             <a-col :span="24">
               <a-form-item label="挂牌数量"
                            class="relative"
-                           name="num">
+                           name="OrderQty">
                 <a-input-number class="dialogInput yellowInput"
                                 style="width: 260px"
                                 :min="0"
@@ -109,7 +109,7 @@
 
 <script lang="ts">
 import Drawer from '@/common/components/drawer/index.vue';
-import { DelistingType, PriceType } from '@/common/constants/enumCommon';
+import { DelistingType, PriceType, TradeMode } from '@/common/constants/enumCommon';
 import { ModalEnum } from '@/common/constants/modalNameEnum';
 import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
 import { validateAction } from '@/common/setup/form';
@@ -128,6 +128,9 @@ import { defineComponent, PropType, ref } from 'vue';
 import { useBlocksAccount } from '../../spot_trade_order_transaction_swap/components/setup';
 import { FormState } from './interface';
 import { handleForm } from './setup';
+import Bus from '@/utils/eventBus';
+import { Tradesfer } from '../../spot_trade_order_transaction_listing_transfer/interface';
+import { getMarketByTradeMode } from '@/services/bus/market';
 
 export default defineComponent({
     name: ModalEnum.spot_trade_warehouse_financing_delisting,
@@ -138,6 +141,10 @@ export default defineComponent({
             type: Object as PropType<QueryDeliveryRelationRsp>,
             default: {},
         },
+        selectedRow: {
+            type: Object as PropType<Tradesfer>,
+            default: {},
+        },
     },
 
     setup(props, context) {
@@ -161,6 +168,7 @@ export default defineComponent({
 
         function submit() {
             validateAction<FormState>(formRef, formState).then((res) => {
+                const marketid = getMarketByTradeMode(TradeMode.ListingAndSelection)!.marketid;
                 // 挂牌请求 通过挂牌求购进行挂牌
                 const param: OrderReq = {
                     ClientSerialNo: uuidv4(), // 客户端流水号
@@ -168,8 +176,8 @@ export default defineComponent({
                     ClientType: 4, // 终端类型
                     LoginID: geLoginID_number()!, // 登陆账号
                     AccountID: getSelectedAccountId(), // 交易账号
-                    GoodsID: props.deliverGoods.goodsid, // 商品ID
-                    MarketID: props.deliverGoods.marketid, // 市场ID
+                    GoodsID: props.selectedRow.goodsid, // 商品ID
+                    MarketID: props.deliverGoods.marketid ? props.deliverGoods.marketid : marketid, // 市场ID
                     ValidType: 1, // 校验类型 当日有效
                     OperateType: 1, // 操作类型: 申请
                     OrderSrc: 1, // 单据来源: 客户端下单
@@ -201,6 +209,7 @@ export default defineComponent({
                 };
                 requestResultLoadingAndInfo(Order, param, loading, ['挂牌成功', '挂牌失败:']).then(() => {
                     cancel(true);
+                    Bus.$emit('spotTrade', true);
                 });
             });
         }

+ 0 - 0
src/views/market/spot_trade/spot_trade_order_transaction/components/listing/interface.ts → src/views/market/market-spot/spot_trade_order_transaction/components/listing/interface.ts


+ 32 - 0
src/views/market/market-spot/spot_trade_order_transaction/components/listing/setup.ts

@@ -0,0 +1,32 @@
+import { validateCommon } from "@/common/setup/validate";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { reactive, ref, UnwrapRef } from "vue";
+import { FormState } from "./interface";
+
+export function handleForm() {
+    const formRef = ref();
+    const formState: UnwrapRef<FormState> = reactive({
+        accountid: undefined,
+        OrderQty: 0,
+        FixedPrice: 0,
+        PriceMove: 0
+    })
+    const v_price = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入挂牌价格');
+    };
+    const v_num = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入挂牌数量');
+    };
+    const rules = {
+        accountid: [{ required: true, message: '请选择交易账户' }],
+        OrderQty: [
+            { required: true, trigger: 'blur', type: 'number', validator: v_num },
+        ],
+        FixedPrice: [
+            { required: true, trigger: 'blur', type: 'number', validator: v_price },
+        ],
+
+    }
+    return { rules, formState, formRef }
+
+}

+ 119 - 0
src/views/market/market-spot/spot_trade_order_transaction/components/sell-market/index.vue

@@ -0,0 +1,119 @@
+<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="btnListData"
+               :record="record"
+               @click="openComponent" />
+    </template>
+    <template #username="{text, record }">
+      <span>{{record.userid + " " }}{{text}}</span>
+    </template>
+    <template #fixedprice="{record }">
+      <span>{{record.useorderpricerid }}</span>
+    </template>
+  </a-table>
+  <component :is="componentId"
+             v-if="componentId"
+             :selectedRow="selectedRow"
+             :parantSelectedRow="parantSelectedRow"
+             :buyOrSell="BuyOrSell.sell"
+             @cancel="closeComponent"></component>
+</template>
+
+<script lang="ts">
+import { BtnList, defineComponent, queryTableList } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryWrTradeOrderDetail } from '@/services/go/wrtrade';
+import { WrOrderQuote, WrOrderQuoteDetail, WrTradeOrderDetailReq } 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 { getShowBottomValue } from '@/common/config/constrolBottom';
+import { TableParam } from '@/common/setup/table/interface';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+
+export default defineComponent({
+    emits: ['cancel', 'openComponent'],
+    name: 'warehouse_receipt_trade_price_delisting_sell',
+    props: {
+        parantSelectedRow: {
+            type: Object as PropType<QueryDeliveryRelationRsp>,
+            default: {},
+        },
+    },
+    components: {
+        BtnList,
+        Delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+    },
+    setup(props, context) {
+        const isBottom = getShowBottomValue();
+        console.log(isBottom.value, 'isBottom');
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuoteDetail>();
+        const columnsList = [
+            { title: '序号', key: 'index', width: 60 },
+            { title: '销售方', key: 'username' },
+            { title: '卖量', key: 'orderqty' },
+            { title: '卖价', key: 'orderprice' },
+        ];
+        const btnListData: BtnListType[] = [{ lable: '摘牌', code: 'Delisting', className: 'operBtn' }];
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: WrTradeOrderDetailReq = {
+                buyorsell: 1,
+                goodsid: props.parantSelectedRow.goodsid,
+            };
+            queryTable(queryWrTradeOrderDetail, param);
+        };
+        // 表格通用逻辑
+        const param: TableParam = {
+            columnsList,
+            queryFn: queryTableAction,
+        };
+        function handleColumn(columns: ColumnType[]) {
+            columns.forEach((item) => {
+                columns.forEach((item) => {
+                    if (item.dataIndex == 'username') {
+                        delete item.width;
+                    }
+                });
+            });
+            return columns;
+        }
+        return {
+            isBottom,
+            ...handleTableEventAndData(param),
+            queryTableAction,
+            loading,
+            tableList,
+            BuyOrSell,
+            expandIcon,
+            handleColumn,
+            btnListData,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 112 - 0
src/views/market/market-spot/spot_trade_order_transaction/components/stock-exchange/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <!-- 成交明细  -->
+  <a-row>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[0]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[1]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList"
+               class="srcollYTable"
+               :pagination="false"
+               :loading="loading"
+               rowKey="key"
+               ref="tableRef"
+               :data-source="tableList[2]">
+      </a-table>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref } from 'vue';
+
+import { QueryHistoryTikDatasRsp, QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+
+const columnsList = [
+    { title: '时间', key: 'TS', dataIndex: 'TS', align: 'center' },
+    { title: '成交价', key: 'PE', dataIndex: 'PE', align: 'center' },
+    { title: '成交量', key: 'Vol', dataIndex: 'Vol', align: 'center' },
+];
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: 'stock-exchange',
+    props: {
+        deliverGoods: {
+            type: Object as PropType<QueryDeliveryRelationRsp>,
+            default: {},
+        },
+    },
+
+    setup(props, context) {
+        const loading = ref<boolean>(false);
+        const { visible, cancel } = _closeModal(context);
+        const param = {
+            goodsCode: props.deliverGoods.goodscode,
+        };
+        const tableList = ref<QueryHistoryTikDatasRsp[][]>([]);
+        QueryHistoryTikDatas(param).then((res) => {
+            res.forEach((el) => (el.TS = formatTime(el.TS)));
+            tableList.value = getHisList(res);
+        });
+        function getHisList(list: QueryHistoryTikDatasRsp[]) {
+            const len = list.length;
+            const result: QueryHistoryTikDatasRsp[][] = [[], [], []];
+            if (len) {
+                if (len === 1) {
+                    result[0] = list;
+                } else if (len === 2) {
+                    result[0].push(list[0]);
+                    result[1].push(list[1]);
+                } else {
+                    const temp = Math.floor(len / 3);
+                    result[0] = list.slice(0, temp);
+                    result[1] = list.slice(temp, 2 * temp);
+                    result[2] = list.slice(temp * 2, temp * 3);
+                    const last = len - temp;
+                    if (last) {
+                        if (last === 1) {
+                            result[0].push(list[len - 1]);
+                        } else {
+                            result[0].push(list[len - 2]);
+                            result[1].push(list[len - 1]);
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+        return {
+            cancel,
+            visible,
+            tableList,
+            columnsList,
+            loading,
+        };
+    },
+});
+</script>
+<style lang="less">
+</style>

+ 12 - 2
src/views/market/spot_trade/spot_trade_order_transaction/index.vue → src/views/market/market-spot/spot_trade_order_transaction/index.vue

@@ -9,10 +9,11 @@
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue';
+import { defineComponent, ref } from 'vue';
 import ThridMenu from '@/common/components/thirdMenu/index.vue';
 import { EnumRouterName } from '@/common/constants/enumRouterName';
 import { handleMartketThirdRouter } from '@/common/setup/matket/router';
+import { sessionStorageUtil } from '@/utils/storage';
 
 export default defineComponent({
     name: EnumRouterName.spot_trade_order_transaction,
@@ -20,7 +21,16 @@ export default defineComponent({
         ThridMenu,
     },
     setup() {
-        return { ...handleMartketThirdRouter(EnumRouterName.spot_trade_order_transaction) };
+        const { index, tabList, changeTab } = handleMartketThirdRouter(EnumRouterName.spot_trade_order_transaction);
+
+        const swap = sessionStorageUtil.getItem('transaction_swap');
+        if (!swap) {
+            index.value = '2';
+            changeTab(0, { lable: '商品掉期', code: 'spot_trade_order_transaction_swap' });
+            sessionStorageUtil.setItem('transaction_swap', '2');
+        }
+
+        return { index, tabList, changeTab };
     },
 });
 </script>

+ 30 - 11
src/views/market/spot_trade/spot_trade_order_transaction/setup.ts → src/views/market/market-spot/spot_trade_order_transaction/setup.ts

@@ -1,6 +1,6 @@
 import { TradeMode } from "@/common/constants/enumCommon"
 import { initData } from "@/common/methods"
-import { getQuoteDayInfoByCode } from "@/services/bus/goods"
+import { getGoodsListByTrade, getQuoteDayInfoByCode } from "@/services/bus/goods"
 import { getMarketByTradeMode } from "@/services/bus/market"
 import { queryDeliveryRelation } from "@/services/go/delivery"
 import { QueryDeliveryRelationRsp } from "@/services/go/delivery/interface"
@@ -18,16 +18,22 @@ export function handleDeliveryRelation(param: deliverytype[]) {
     // 查询交割商品
     const deliverGoods = ref<any[]>([])
     function queryAction() {
+        // 根据 交易模式 获取 商品
+        // 没有交割商品也要显示
+        const allGoodsLsit = getGoodsListByTrade(TradeMode.ListingAndSelection).value.filter(e => e.goodsstatus === 3)
         const marketid = getMarketByTradeMode(TradeMode.ListingAndSelection)!.marketid
         queryDeliveryRelation({ marketid }).then(res => {
             goodsList.value.length = 0
             allDeliverGoods.value = res
             deliverGoods.value = getDeliverGoods()
-            res.forEach(el => {
+
+            allGoodsLsit.forEach(el => {
                 // 找到盘面数据
                 const quote = getQuoteDayInfoByCode(el.goodscode);
                 if (quote) {
-                    Object.assign(quote, { goodsname: el.goodsname, deliverytype: el.deliverytype })
+                    const item = res.find(item => item.goodsid === el.goodsid)
+                    const deliverytype = item ? item.deliverytype : undefined
+                    Object.assign(quote, { goodsname: el.goodsname, goodsid: el.goodsid, deliverytype })
                     goodsList.value.push(quote)
                 }
             })
@@ -38,13 +44,14 @@ export function handleDeliveryRelation(param: deliverytype[]) {
         return allDeliverGoods.value.filter(e => param.includes(e.deliverytype as deliverytype))
     }
     initData(() => {
-        if (allDeliverGoods.value.length === 0) {
-            // 从服务交割商品
-            queryAction()
-        } else {
-            // 从缓存中获取交割商品
-            deliverGoods.value = getDeliverGoods()
-        }
+        // if (allDeliverGoods.value.length === 0) {
+        //     // 从服务交割商品
+        //     queryAction()
+        // } else {
+        //     // 从缓存中获取交割商品
+        //     deliverGoods.value = getDeliverGoods()
+        // }
+        queryAction()
     })
     // 更新交割商品
     function updateGeliverGoods() {
@@ -52,7 +59,19 @@ export function handleDeliveryRelation(param: deliverytype[]) {
     }
     // 获取对应的行情
     function getQuoteList() {
-        return goodsList.value.filter(e => param.includes((e as unknown as any).deliverytype))
+        if (param.includes(1) || param.includes(3)) {
+            return goodsList.value.filter(e => {
+                const item = (e as unknown as any).deliverytype
+                if (item) {
+                    return param.includes((e as unknown as any).deliverytype)
+                } else {
+                    return true
+                }
+            })
+
+        } else {
+            return goodsList.value.filter(e => param.includes((e as unknown as any).deliverytype))
+        }
     }
     // 通过goodscode 查找交割商品
     function findDeilverGoodsByGoodsCode(goodscode: string) {

+ 146 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_basis_difference/index.vue

@@ -0,0 +1,146 @@
+<template>
+  <!--订单交易 基差点价-->
+  <div class="topTableHeight">
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'secondTabTable' : 'secondTabTableNoBottom', getQuoteList().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="getQuoteList()"
+    >
+      <template #totalturnover="{ text }">
+        <span>{{ changeUnit(text) }}</span>
+      </template>
+      <!-- 买量 -->
+      <template #bidvolume="{ text }">
+        <span>{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 卖量 -->
+      <template #askvolume="{ text }">
+        <span>{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 开盘价 -->
+      <template #opened="{ record, text }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 涨跌 -->
+      <template #change="{ record, text }">
+        <span
+          :class="handleQuotePriceColor(text, record.presettle)"
+        >{{ quoteChange(record, record.decimalplace) }}</span>
+      </template>
+      <!-- 幅度 -->
+      <template #amplitude="{ record }">
+        <span
+          :class="handleQuotePriceColor(record.last, record.presettle)"
+        >{{ quoteAmplitude(record, record.decimalplace) }}</span>
+      </template>
+      <!-- 振幅 -->
+      <template #vibration="{ record, text }">
+        <span
+          :class="handleQuotePriceColor(text, record.presettle)"
+        >{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+      </template>
+      <template #index="{ index }">
+        <span>{{ index + 1 }}</span>
+      </template>
+      <!-- 买价 -->
+      <template #bid="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 卖价 -->
+      <template #ask="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最新价 -->
+      <template #last="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最低价 -->
+      <template #lowest="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最高价 -->
+      <template #highest="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+    </a-table>
+    <!-- 右键 -->
+    <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="btnList"></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :selectedRow="selectedRow"
+      :deliverGoods="findDeilverGoodsByGoodsCode(selectedRow.goodscode)"
+      @cancel="closeComponent"
+    ></component>
+  </div>
+</template>
+
+<script lang="ts">
+import { BtnListType } from '@/common/components/btnList/interface';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { handleNoneValue, handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { changeUnit } from '@/utils/qt/common';
+import { ref } from 'vue';
+import { columnsList, handleDeliveryRelation } from '../setup';
+
+
+
+
+export default defineComponent({
+  name: EnumRouterName.spot_trade_order_transaction_basis_difference,
+  components: {
+    contextMenu,
+    BuyAndSell: defineAsyncComponent(() => import('../components/buy-sell-market/index.vue')),
+    Listing: defineAsyncComponent(() => import('../components/listing/index.vue')),
+    Detail: defineAsyncComponent(() => import('../components/detail/index.vue')),
+  },
+  setup() {
+    const isBottom = getShowBottomValue();
+    const loading = ref<boolean>(false);
+    const param: TableParam = {
+      columnsList,
+      queryFn: () => { },
+      clickName: 'BuyAndSell',
+    };
+    const btnList: BtnListType[] = [
+      { lable: '挂牌求购', code: 'Listing', className: 'btnDeafault' },
+      { lable: '图表', code: 'BuyAndSell', className: 'btnDeafault' },
+      { lable: '详情', code: 'Detail', className: 'btnDeafault' },
+    ];
+    const { deliverGoods, getQuoteList, findDeilverGoodsByGoodsCode } = handleDeliveryRelation([2, 4]);
+    // 行情按需订阅
+    handleSubcriteOnDemandQuote<QueryDeliveryRelationRsp>(deliverGoods);
+
+    return {
+      isBottom,
+      ...handleTableEventAndData<QueryQuoteDayRsp>(param),
+      deliverGoods,
+      btnList,
+      handleQuotePriceColor,
+      quoteChange,
+      quoteAmplitude,
+      quoteAmplituOfVibration,
+      getQuoteList,
+      findDeilverGoodsByGoodsCode,
+      loading,
+      handleNoneValue,
+      changeUnit,
+    };
+  },
+});
+</script>
+<style lang="less">
+</style>

+ 160 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_listing_transfer/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <!--订单交易 挂牌转让-->
+  <div class="topTableHeight">
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'secondTabTable' : 'secondTabTableNoBottom', getQuoteList().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="getQuoteList()"
+    >
+      <template #totalturnover="{ text }">
+        <span>{{ changeUnit(text) }}</span>
+      </template>
+      <!-- 买量 -->
+      <template #bidvolume="{ text }">
+        <span>{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 卖量 -->
+      <template #askvolume="{ text }">
+        <span>{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 开盘价 -->
+      <template #opened="{ record, text }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 涨跌 -->
+      <template #change="{ record, text }">
+        <span
+          :class="handleQuotePriceColor(text, record.presettle)"
+        >{{ quoteChange(record, record.decimalplace) }}</span>
+      </template>
+      <!-- 幅度 -->
+      <template #amplitude="{ record }">
+        <span
+          :class="handleQuotePriceColor(record.last, record.presettle)"
+        >{{ quoteAmplitude(record, record.decimalplace) }}</span>
+      </template>
+      <!-- 振幅 -->
+      <template #vibration="{ record, text }">
+        <span
+          :class="handleQuotePriceColor(text, record.presettle)"
+        >{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+      </template>
+      <template #index="{ index }">
+        <span>{{ index + 1 }}</span>
+      </template>
+      <!-- 买价 -->
+      <template #bid="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 卖价 -->
+      <template #ask="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最新价 -->
+      <template #last="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最低价 -->
+      <template #lowest="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+      <!-- 最高价 -->
+      <template #highest="{ text, record }">
+        <span :class="handleQuotePriceColor(text, record.presettle)">{{ handleNoneValue(text) }}</span>
+      </template>
+    </a-table>
+    <!-- 右键 -->
+    <contextMenu
+      :contextMenu="contextMenu"
+      @cancel="closeContext"
+      :list="handleBtnList(selectedRow)"
+    ></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :selectedRow="selectedRow"
+      :deliverGoods="findDeilverGoodsByGoodsCode(selectedRow.goodscode)"
+      @cancel="closeComponent"
+    ></component>
+  </div>
+</template>
+
+<script lang="ts">
+import { BtnListType } from '@/common/components/btnList/interface';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { handleNoneValue, handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { changeUnit } from '@/utils/qt/common';
+import { ref } from 'vue';
+import { columnsList, handleDeliveryRelation } from '../setup';
+import { Tradesfer } from './interface';
+
+
+
+
+export default defineComponent({
+  name: EnumRouterName.spot_trade_order_transaction_listing_transfer,
+  components: {
+    contextMenu,
+    BuyAndSell: defineAsyncComponent(() => import('../components/buy-sell-market/index.vue')),
+    Listing: defineAsyncComponent(() => import('../components/listing/index.vue')),
+    Detail: defineAsyncComponent(() => import('../components/detail/index.vue')),
+  },
+  setup() {
+    const isBottom = getShowBottomValue();
+    const loading = ref<boolean>(false);
+    const param: TableParam = {
+      columnsList,
+      queryFn: () => { },
+      clickName: 'BuyAndSell',
+    };
+    function handleBtnList(record: Tradesfer) {
+      const result: BtnListType[] = [
+        { lable: '挂牌求购', code: 'Listing', className: 'btnDeafault' },
+        { lable: '图表', code: 'BuyAndSell', className: 'btnDeafault' },
+      ];
+      if (record && record.deliverytype) {
+        result.push({ lable: '详情', code: 'Detail', className: 'btnDeafault' });
+      }
+      return result;
+    }
+
+    const { deliverGoods, getQuoteList, goodsList, findDeilverGoodsByGoodsCode } = handleDeliveryRelation([1, 3]);
+    // 行情按需订阅
+    handleSubcriteOnDemandQuote<QueryDeliveryRelationRsp>(deliverGoods);
+
+    return {
+      isBottom,
+      ...handleTableEventAndData<Tradesfer>(param),
+      deliverGoods,
+      handleBtnList,
+      handleQuotePriceColor,
+      quoteChange,
+      quoteAmplitude,
+      quoteAmplituOfVibration,
+      getQuoteList,
+      findDeilverGoodsByGoodsCode,
+      goodsList,
+      loading,
+      handleNoneValue,
+      changeUnit,
+    };
+  },
+});
+</script>
+<style lang="less">
+.noData {
+  .position(absolute, 28px, 0, 0, 0);
+}
+</style>

+ 6 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_listing_transfer/interface.ts

@@ -0,0 +1,6 @@
+import { QueryQuoteDayRsp } from "@/services/go/quote/interface";
+
+export interface Tradesfer extends QueryQuoteDayRsp {
+    deliverytype: number | undefined,
+    goodsid: number
+}

+ 147 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy-sell-market/index.vue

@@ -0,0 +1,147 @@
+<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.askvolume ? selectedRow.askvolume : '--' }}</div>
+          </div>
+          <div class="numBlock">
+            <div class="first">买量</div>
+            <div class="last white">{{ selectedRow.bidvolume ? selectedRow.bidvolume : '--' }}</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';
+import { RefGoodsList } from '../../interface';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: 'buy-sell-market',
+  props: {
+    selectedRow: {
+      type: Object as PropType<RefGoodsList>,
+      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);
+
+    // 获取浮动价商品实时价格
+
+    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({}));
+
+    // 单据挂牌成功 通知买大厅刷新数据
+    Bus.$on('spotTrade', queryFn);
+
+    return {
+      buyRef,
+      sellRef,
+      cancel,
+      getGoodsPrice,
+      visible,
+      firstBtn: getBtnList(false),
+      buyMarket: [],
+      sellMarket: [],
+      componentId,
+      closeComponent,
+      openComponent,
+      enumName: props.enumName,
+    };
+  },
+});
+</script>
+<style lang="less">
+.priceBar {
+  .flex;
+  flex-direction: column;
+  height: 32px;
+  .greenBar,
+  .redBar {
+    height: 16px;
+    line-height: 16px;
+    color: var(--m-grey17);
+  }
+}
+</style>

+ 179 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy/index.vue

@@ -0,0 +1,179 @@
+<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>
+        <template #orderprice="{ record }">
+            <span>{{ getBuyOrSellMarketPrice(record, parantSelectedRow) }}</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 { getShowBottomValue } from '@/common/config/constrolBottom';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { BtnList, ComposeTableParam, defineComponent, handleComposeTable, queryTableList } from '@/common/export/commonTable';
+import { expandIcon } from '@/common/setup/table/clolumn';
+import { getUserId } from '@/services/bus/account';
+import { getUserAccountType } from '@/services/bus/user';
+import { queryTjmdTradeOrderDetail } from '@/services/go/Tjmd';
+import { QueryTjmdTradeOrderDetailReq, QueryTjmdTradeOrderDetailRsp } from '@/services/go/Tjmd/interface';
+import { WrOrderQuoteDetail } from '@/services/go/wrtrade/interface';
+import TimerUtils from '@/utils/timer/timerUtil';
+import { defineAsyncComponent, onBeforeUnmount, PropType } from 'vue';
+import { RefGoodsList } from '../../interface';
+import { findItemGoods } from '../../setup';
+import { getBuyOrSellMarketPrice, sortPirce, useBuyOrSellBtnList, hasFloat } 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<RefGoodsList>,
+            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).then((res) => {
+                // 先置空 要不然数据变更了,视图不更新
+                const fn = () => {
+                    tableList.value = [];
+                    tableList.value = sortPirce(res, props.parantSelectedRow, false).filter(el => el.userid !== getUserId());
+                };
+                fn()
+                if (hasFloat(res)) {
+                    // 有浮动价, 则每三秒更新一次数据
+                    TimerUtils.setInterval(fn, 3 * 1000, 'buyMarket');
+                }
+            });
+        };
+        onBeforeUnmount(() => {
+            TimerUtils.clearInterval('buyMarket');
+        });
+        // 表格通用逻辑
+        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,
+            getBuyOrSellMarketPrice,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 655 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/delisting/index.vue

@@ -0,0 +1,655 @@
+<template>
+  <!-- 挂牌求购 -->
+  <Drawer
+    :title="!isBuy() ? '摘牌买入' : '摘牌卖出'"
+    :placement="'right'"
+    :visible="visible"
+    :width="1052"
+    @cancel="cancel"
+    class="post-buying-container"
+  >
+    <a-row>
+      <a-col :span="12">
+        <div class="post_buying_chart">
+          <div class="buying_chart__nav">
+            <div class="content--left">{{ parantSelectedRow.goodscode }}</div>
+            <div class="content--right">{{ parantSelectedRow.goodsname }}</div>
+          </div>
+          <div class="chart-tips__last">
+            <div
+              :class="['content--left', handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'last')]"
+            >{{ getQuoteValue_out(parantSelectedRow.refgoodscode, 'last') }}</div>
+            <div class="content--right">
+              <span
+                :class="handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'last')"
+              >{{ quoteChange_out(parantSelectedRow.refgoodscode) }}</span>
+              <span
+                :class="handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'last')"
+              >{{ quoteAmplitude_out(parantSelectedRow.refgoodscode) }}</span>
+            </div>
+          </div>
+          <a-row>
+            <a-col :span="4" :offset="2">最高价</a-col>
+            <a-col :span="6">
+              <span
+                :class="handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'highest')"
+              >{{ getQuoteValue_out(parantSelectedRow.refgoodscode, 'highest') }}</span>
+            </a-col>
+            <a-col :span="4" :offset="2">开盘价</a-col>
+            <a-col :span="6">
+              <span
+                :class="handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'opened')"
+              >{{ getQuoteValue_out(parantSelectedRow.refgoodscode, 'opened') }}</span>
+            </a-col>
+          </a-row>
+          <a-row>
+            <a-col :span="4" :offset="2">最低价</a-col>
+            <a-col :span="6">
+              <span
+                :class="handleQuotePriceColor_out(parantSelectedRow.refgoodscode, 'lowest')"
+              >{{ getQuoteValue_out(parantSelectedRow.refgoodscode, 'lowest') }}</span>
+            </a-col>
+            <a-col :span="4" :offset="2">昨结价</a-col>
+            <a-col :span="6">{{ getQuoteValue_out(parantSelectedRow.refgoodscode, 'presettle') }}</a-col>
+          </a-row>
+          <div class="chart-content">
+            <Chart
+              :selectedRow="getQuoteDayInfoByCode(parantSelectedRow.refgoodscode)"
+              :showExchange="false"
+            />
+          </div>
+        </div>
+      </a-col>
+      <a-col :span="12">
+        <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">{{ getRatio() }}</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="selectedRow.orderqty"
+                      v-model:value="formState.num"
+                    />
+                    <MinusOutlined @click="decreaseNumber" />
+                    <PlusOutlined @click="increaseNumber" />
+                    <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>
+      </a-col>
+    </a-row>
+  </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 { getQuoteValue_out, handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out } from '@/common/setup/table/tableQuote';
+import { useTodayMargin } from '@/hooks/margin';
+import { getSelectedAccountId } from '@/services/bus/account';
+import { getGoodsAgreeunitByGoodsId, getQuoteDayInfoByCode, getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import { geLoginID_number } from '@/services/bus/login';
+import { getMarketByTradeMode, getMarketIdsByTradeMode } from '@/services/bus/market';
+import { QueryQuoteGoodsListRsp, QueryTjmdTodayAccountMarginReq, QueryTjmdTradeOrderDetailRsp } from '@/services/go/Tjmd/interface';
+import { diaoQiOrder } from '@/services/socket/order';
+import { OrderReq } from '@/services/socket/order/interface';
+import Bus from '@/utils/eventBus/index';
+import Chart from '@/views/market/market-spot/goods-chart/index.vue';
+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 { RefGoodsList } from '../../interface';
+import { useUserType } from '../setup';
+import { FormParam } from './interface';
+import { handleForm, useBlocksNumber, useBlocksPrice } from './setup';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: ModalEnum.spot_trade_warehouse_post_buying,
+  components: {
+    Des,
+    Drawer,
+    PlusOutlined,
+    MinusOutlined,
+    Chart,
+  },
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryTjmdTradeOrderDetailRsp>,
+      default: {},
+    },
+    parantSelectedRow: {
+      type: Object as PropType<RefGoodsList>,
+      default: {},
+    },
+    refGoods: {
+      type: Object as PropType<QueryQuoteGoodsListRsp[]>,
+      default: [],
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      defualt: BuyOrSell.buy,
+    },
+  },
+  setup(props, context) {
+    const marginParam: QueryTjmdTodayAccountMarginReq = {
+      accountid: getSelectedAccountId()!.toString(),
+      goodsid: props.selectedRow.goodsid,
+      marketids: getMarketIdsByTradeMode(TradeMode.DiaoQi),
+    };
+    // 获取保证金比例
+    const { getReckonMarginTypeAndValueByTradeMode } = useTodayMargin(marginParam);
+    // 控制弹窗
+    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 fn = (value: number) => Math.round(value * 100) / 100;
+    // 金额
+    const getMoney = () => {
+      let result = 0;
+      const temp = getGoodsAgreeunitByGoodsId(props.selectedRow.goodsid);
+      const argeeunit = temp ? temp : 1;
+      let priceTemp: number = 0;
+      // 限价
+      if (isLimit()) {
+        priceTemp = formState.price;
+      } else {
+        // 市价
+        if (isFloat()) {
+          const price = getQuoteDayInfoByCodeFindPrice(props.parantSelectedRow.refgoodscode);
+          if (price && price !== '--') {
+            // 浮动价
+            priceTemp = +price + props.selectedRow.marketmaxsub;
+          }
+        } else {
+          priceTemp = props.selectedRow.orderprice;
+        }
+      }
+      if (formState.num) {
+        // 四舍五入
+        result = fn(formState.num * argeeunit * +priceTemp);
+      }
+      return result ? result : '--';
+    };
+    // 估算价
+    const getRatio = () => {
+      let result = '--';
+      const price = getQuoteDayInfoByCodeFindPrice(props.parantSelectedRow.refgoodscode);
+      if (price && price !== '--') {
+        // 四舍五入
+        result = fn(+price + props.selectedRow.marketmaxsub).toString();
+      }
+      return result;
+    };
+    // 保证金
+    const getMargin = () => {
+      let result = '--';
+      const price = getMoney();
+      if (price !== '--') {
+        const [marginType, marginValue] = getReckonMarginTypeAndValueByTradeMode(TradeMode.DiaoQi);
+        if (marginValue && formState.num) {
+          const temp = marginType === 1 ? +price * marginValue : formState.num * marginValue
+          // 四舍五入
+          result = fn(temp).toString();
+        }
+      }
+      return result;
+    };
+    // 估算价
+    // function getGuseetPrice() {
+    //     let result = '--';
+    //     const goodsPrice = getQuoteDayInfoByCodeFindPrice(props.selectedRow.refgoodscode);
+    //     console.log('goodsPrice', goodsPrice);
+    //     if (goodsPrice && goodsPrice !== '--') {
+    //         // 有实时行情价格
+    //         result = ((goodsPrice as number) + formState.PriceMove).toFixed(2);
+    //     }
+    //     return result;
+    // }
+    // 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);
+          Bus.$emit('spotTrade', true);
+        });
+      });
+    }
+    return {
+      submit,
+      cancel,
+      visible,
+      accountList,
+      rules,
+      formState,
+      formRef,
+      isFloat,
+      getMoney,
+      getMargin,
+      canUseMoney,
+      isBuy,
+      useUserType,
+      isLimit,
+      ...useBlocksPrice(),
+      ...useBlocksNumber(),
+      getRatio,
+      handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out, getQuoteValue_out, getQuoteDayInfoByCode
+    };
+  },
+});
+
+
+</script>
+
+<style lang="less">
+.post-buying-container {
+  top: 101px;
+  .ant-drawer-content-wrapper {
+    height: 605px;
+  }
+}
+.chart-content {
+  height: 400px;
+  .chart-content__header,
+  .chart-content__main {
+    width: 90% !important;
+    margin: auto !important;
+  }
+
+  .chart-slider {
+    display: none;
+  }
+}
+.formBar {
+  height: 100%;
+  max-height: 100%;
+}
+.post_buying_chart {
+  [theme="light"] & {
+    --bgcolor: #fff;
+    --tab-border-color: #dae5ec;
+    --tab-checked-color: #0866b8;
+    --tab-checked-bgcolor: #d4e0ff;
+    --slider-border-color: #b2c4dd;
+    --slider-bgcolor: #edf2f7;
+    --slider-button-color: #b2c4dd;
+    --row-border-color: #dae5ec;
+    --row-title-color: #acb8c0;
+    --row-content-color: #3c454b;
+    --tik-title-bgcolor: #ecf2f5;
+    --tik-title-color: #7a8a94;
+  }
+  color: @m-grey67;
+
+  // background-color: var(--bgcolor, #0e0e0f);
+
+  // background: @m-blue37;
+  // color: @m-grey67;
+  .buying_chart {
+    display: flex;
+
+    // background-color: @m-blue36;
+    &__nav {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .content {
+        &:first-child:not(:last-child) {
+          margin-right: 16px;
+        }
+
+        &--left {
+          font-size: 16px;
+          color: var(--row-content-color, #acb8c0);
+          margin-right: 6px;
+        }
+
+        &--right {
+          font-size: 24px;
+          color: #fc9618;
+        }
+      }
+    }
+  }
+  .chart-tips {
+    display: flex;
+    flex-direction: column;
+    width: 300px;
+    height: 100%;
+
+    &__last {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 16px 0;
+      .content {
+        &--left {
+          font-size: 24px;
+          margin-right: 16px;
+        }
+
+        &--right {
+          display: flex;
+          flex-direction: column;
+          align-items: flex-start;
+        }
+      }
+    }
+  }
+}
+.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>

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


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


+ 1 - 1
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/detail/index.vue → src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/detail/index.vue

@@ -23,7 +23,7 @@
                  v-for="item in lststep"
                  :key="item.autoid">
               <!-- <div class="no">{{index + 1}}</div> -->
-              <div class="name">{{item.steptypename}}</div>
+              <div class="name">{{item.stepinfo}}<span></span></div>
               <div class="time">{{item.stepdate}}</div>
             </div>
           </a-col>

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


+ 692 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/index.vue

@@ -0,0 +1,692 @@
+<template>
+  <!-- 挂牌求购 -->
+  <a-drawer
+    placement="right"
+    :closable="false"
+    :visible="visible"
+    :width="1052"
+    :destroyOnClose="true"
+    class="post-buying-container"
+  >
+    <div class="collapse">
+      <div class="collapse-close" @click="cancelAction">
+        <DoubleRightOutlined />
+      </div>
+      <slot name="titleLeft"></slot>
+    </div>
+    <div class="collapseCont">
+      <div class="title">{{ isBuy() ? '挂牌求购' : '挂牌卖出' }}</div>
+      <div class="content highContent">
+        <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>
+        <a-row>
+          <a-col :span="12">
+            <div class="post_buying_chart">
+              <div class="buying_chart__nav">
+                <div class="content--left">{{ selectedRow.goodscode }}</div>
+                <div class="content--right">{{ selectedRow.goodsname }}</div>
+              </div>
+              <div class="chart-tips__last">
+                <div
+                  :class="['content--left', handleQuotePriceColor_out(selectedRow.refgoodscode, 'last')]"
+                >{{ getQuoteValue_out(selectedRow.refgoodscode, 'last') }}</div>
+                <div class="content--right">
+                  <span
+                    :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'last')"
+                  >{{ quoteChange_out(selectedRow.refgoodscode) }}</span>
+                  <span
+                    :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'last')"
+                  >{{ quoteAmplitude_out(selectedRow.refgoodscode) }}</span>
+                </div>
+              </div>
+              <a-row>
+                <a-col :span="4" :offset="2">最高价</a-col>
+                <a-col :span="6">
+                  <span
+                    :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'highest')"
+                  >{{ getQuoteValue_out(selectedRow.refgoodscode, 'highest') }}</span>
+                </a-col>
+                <a-col :span="4" :offset="2">开盘价</a-col>
+                <a-col :span="6">
+                  <span
+                    :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'opened')"
+                  >{{ getQuoteValue_out(selectedRow.refgoodscode, 'opened') }}</span>
+                </a-col>
+              </a-row>
+              <a-row>
+                <a-col :span="4" :offset="2">最低价</a-col>
+                <a-col :span="6">
+                  <span
+                    :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'lowest')"
+                  >{{ getQuoteValue_out(selectedRow.refgoodscode, 'lowest') }}</span>
+                </a-col>
+                <a-col :span="4" :offset="2">昨结价</a-col>
+                <a-col :span="6">{{ getQuoteValue_out(selectedRow.refgoodscode, 'presettle') }}</a-col>
+              </a-row>
+              <div class="chart-content">
+                <Chart
+                  :selectedRow="getQuoteDayInfoByCode(selectedRow.refgoodscode)"
+                  :showExchange="false"
+                />
+              </div>
+            </div>
+          </a-col>
+          <a-col :span="12">
+            <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">
+                      <a-form-item label="参考价">
+                        <span
+                          :class="handleQuotePriceColor_out(selectedRow.refgoodscode, 'last')"
+                        >{{ getQuoteValue_out(selectedRow.refgoodscode, 'last') }}</span>
+                      </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="估算价">
+                        <span class="white">{{ getPrice() }}</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="decreaseNum" />
+                        <PlusOutlined @click="increaseNum" />
+                        <span class="input-enumdicname">{{ selected.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() ? selected.minivalue : 0 }}</span>
+                          <span>{{ getMaxNum() }}{{ selected.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"
+                        :loading="loading"
+                        :disabled="loading"
+                        @click="submit"
+                      >{{ isBuy() ? '买入' : '卖出' }}</a-button>
+                      <a-button class="ml10 cancelBtn" @click="cancel">取消</a-button>
+                    </a-form-item>
+                  </a-col>
+                </a-row>
+              </a-form>
+            </div>
+          </a-col>
+        </a-row>
+      </div>
+    </div>
+  </a-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 { queryTableList } from '@/common/setup/table';
+import { getQuoteValue_out, handleNoneValue, handleQuotePriceColor, handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange, quoteChange_out } from '@/common/setup/table/tableQuote';
+import { useListingTradeNumAndPrice } from '@/common/setup/trade';
+import { ListingTradeNumAndPrice } from '@/common/setup/trade/interface';
+import { useTodayMargin } from '@/hooks/margin';
+import { getSelectedAccountId } from '@/services/bus/account';
+import { getGoodsAgreeunitByGoodsCode, getQuoteDayInfoByCode, getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
+import { geLoginID_number } from '@/services/bus/login';
+import { getMarketByTradeMode, getMarketIdsByTradeMode } from '@/services/bus/market';
+import { queryTradePosition } from '@/services/go/ermcp/order';
+import { QueryTradePositionRsp } from '@/services/go/ermcp/order/interface';
+import { QueryTjmdTodayAccountMarginReq } from '@/services/go/Tjmd/interface';
+import { diaoQiOrder } from '@/services/socket/order';
+import { OrderReq } from '@/services/socket/order/interface';
+import Bus from '@/utils/eventBus';
+import Chart from '@/views/market/market-spot/goods-chart/index.vue';
+import { DoubleRightOutlined, LineChartOutlined, 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 { RefGoodsList } from '../../interface';
+import { useUserType } from '../setup';
+import { FormParam } from './interface';
+import { handleForm, isFloat, useBuySellDirection, useChart, useNum, usePrice } from './setup';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: ModalEnum.spot_trade_warehouse_post_buying,
+  components: { Des, Drawer, PlusOutlined, MinusOutlined, SwapOutlined, LineChartOutlined, DoubleRightOutlined, Chart },
+  props: {
+    selectedRow: {
+      type: Object as PropType<RefGoodsList>,
+      default: {},
+    },
+  },
+  setup(props, context) {
+    // 查询 我的 持仓
+    const { tableList, queryTable } = queryTableList<QueryTradePositionRsp>();
+    queryTable(queryTradePosition);
+
+    // 外部参考行情数据
+    const selected = getQuoteDayInfoByCode(props.selectedRow.refgoodscode);
+
+    const marginParam: QueryTjmdTodayAccountMarginReq = {
+      accountid: getSelectedAccountId()!.toString(),
+      goodsid: props.selectedRow.goodsid,
+      marketids: getMarketIdsByTradeMode(TradeMode.DiaoQi),
+    };
+    // 获取保证金比例
+    const { getReckonMarginTypeAndValueByTradeMode } = useTodayMargin(marginParam);
+    // 控制弹窗
+    const { visible, cancel } = _closeModal(context);
+    const cancelAction = () => cancel()
+
+    // 表单
+    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.refgoodscode,
+      isFloat,
+      canUseMoney,
+    };
+    const { getFloatPrice, getMoney } = useListingTradeNumAndPrice<FormParam>(param);
+    // 保证金
+    const getMargin = () => {
+      let result = '--';
+      const [marginType, marginValue] = getReckonMarginTypeAndValueByTradeMode(TradeMode.DiaoQi);
+      if (marginType) {
+        // 保证金方式 1:比率 2:固定
+        if (marginType === 1) {
+          if (getMoney()) {
+            // 履约保证金=挂牌金额*保证金比例
+            result = (Math.round(getMoney() * marginValue * 100) / 100).toString();
+          }
+        } else {
+          if (formState.OrderQty) {
+            // 履约保证金=挂牌数量*保证金固定值
+            result = (Math.round(formState.OrderQty * marginValue * 100) / 100).toString();
+          }
+        }
+      }
+      return result;
+    };
+    // 最大数量
+    const getMaxNum = () => {
+      let result = 0;
+      const goodscode = props.selectedRow.goodscode;
+      const [marginType, marginValue] = getReckonMarginTypeAndValueByTradeMode(TradeMode.DiaoQi);
+      // 可用资金
+      const temp = +canUseMoney();
+      const money = temp > 0 ? temp : 0;
+      const price = isFloat() ? getQuoteDayInfoByCodeFindPrice(props.selectedRow.refgoodscode) : formState.FixedPrice;
+      if (marginType && money && price && price !== '--') {
+        // 保证金方式 1:比率 2:固定
+        if (marginType === 1) {
+          // 合约单位
+          const agreeunit = getGoodsAgreeunitByGoodsCode(goodscode);
+          // 最大可挂牌数量=可用/(价格*合约单位*保证金比例
+          result = money / (+price * marginValue * agreeunit);
+        } else {
+          // 最大可挂牌数量=可用/保证金固定值
+          result = money / marginValue;
+        }
+      }
+      return +result.toFixed(0);
+    };
+    // 估算价
+    function getPrice() {
+      let result = '--';
+      const goodsPrice = getQuoteDayInfoByCodeFindPrice(props.selectedRow.refgoodscode);
+      if (goodsPrice && goodsPrice !== '--') {
+        // 有实时行情价格
+        result = ((goodsPrice as number) + formState.PriceMove).toFixed(2);
+      }
+      return result;
+    }
+
+    function submit() {
+      validateAction<FormParam>(formRef, formState).then((res) => {
+        const { goodsid } = 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: goodsid, // 商品ID
+          MarketID: getMarketByTradeMode(TradeMode.DiaoQi)?.marketid, // 市场ID
+          ValidType: 1, // 校验类型 当日有效
+          OperateType: 1, // 操作类型: 申请
+          OrderSrc: 1, // 单据来源: 客户端下单
+          RelatedID: selected!.orderid, // 操作员账号ID
+          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; // 基差
+        } else {
+          // 浮动价 不传价格,固定价才传价格
+          param.OrderPrice = res.FixedPrice;
+        }
+        requestResultLoadingAndInfo(diaoQiOrder, param, loading, ['挂牌求购成功', '挂牌求购失败:']).then(() => {
+          cancel(true);
+          Bus.$emit('spotTrade', true);
+        });
+      });
+    }
+    return {
+      submit,
+      cancel,
+      cancelAction,
+      visible,
+      rules,
+      formState,
+      formRef,
+      isFloat,
+      getMaxNum,
+      getMoney,
+      getMargin,
+      getFloatPrice,
+      direction,
+      changeDirection,
+      isBuy,
+      useUserType,
+      canUseMoney,
+      accountList,
+      ...usePrice(),
+      ...useNum(getMaxNum),
+      ...useChart(),
+      getPrice,
+      loading,
+      selected,
+      handleQuotePriceColor, quoteChange, handleNoneValue, quoteAmplitude,
+      handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out, getQuoteValue_out, getQuoteDayInfoByCode
+    };
+  },
+});
+</script>
+
+<style lang="less">
+.post-buying-container {
+  top: 101px;
+  .ant-drawer-content-wrapper {
+    height: 605px;
+  }
+}
+.chart-content {
+  height: 400px;
+
+  .chart-content__header,
+  .chart-content__main {
+    width: 90% !important;
+    margin: auto !important;
+  }
+
+  .chart-slider {
+    display: none;
+  }
+}
+.formBar {
+  height: 100%;
+  max-height: 100%;
+}
+.post_buying_chart {
+  [theme="light"] & {
+    --bgcolor: #fff;
+    --tab-border-color: #dae5ec;
+    --tab-checked-color: #0866b8;
+    --tab-checked-bgcolor: #d4e0ff;
+    --slider-border-color: #b2c4dd;
+    --slider-bgcolor: #edf2f7;
+    --slider-button-color: #b2c4dd;
+    --row-border-color: #dae5ec;
+    --row-title-color: #acb8c0;
+    --row-content-color: #3c454b;
+    --tik-title-bgcolor: #ecf2f5;
+    --tik-title-color: #7a8a94;
+  }
+  color: @m-grey67;
+
+  // background-color: var(--bgcolor, #0e0e0f);
+
+  // background: @m-blue37;
+  // color: @m-grey67;
+  .buying_chart {
+    display: flex;
+
+    // background-color: @m-blue36;
+    &__nav {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .content {
+        &:first-child:not(:last-child) {
+          margin-right: 16px;
+        }
+
+        &--left {
+          font-size: 16px;
+          color: var(--row-content-color, #acb8c0);
+          margin-right: 6px;
+        }
+
+        &--right {
+          font-size: 24px;
+          color: #fc9618;
+        }
+      }
+    }
+  }
+  .chart-tips {
+    display: flex;
+    flex-direction: column;
+    width: 300px;
+    height: 100%;
+
+    &__last {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 16px 0;
+      .content {
+        &--left {
+          font-size: 24px;
+          margin-right: 16px;
+        }
+
+        &--right {
+          display: flex;
+          flex-direction: column;
+          align-items: flex-start;
+        }
+      }
+    }
+  }
+}
+.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>

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


+ 10 - 1
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts → src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts

@@ -27,7 +27,7 @@ export function handleForm() {
     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' }],
+        PriceMove: [{ required: true, message: '请输入差', trigger: 'blur', type: 'number' }],
         accountid: [{ required: true, message: '请输入交易账号' }],
     }
     onBeforeUnmount(() => {
@@ -80,4 +80,13 @@ export const useNum = (getMaxNum: Function) => {
         }
     }
     return { increaseNum, decreaseNum };
+}
+
+// 图表
+export const useChart = () => {
+    const showChart = ref<boolean>(false)
+    function showChartAction() {
+        showChart.value = !showChart.value
+    }
+    return { showChart, showChartAction }
 }

+ 190 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/sell/index.vue

@@ -0,0 +1,190 @@
+<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 #orderprice="{ record }">
+            <span>{{ getBuyOrSellMarketPrice(record, parantSelectedRow) }}</span>
+        </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, onBeforeUnmount, 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, getBuyOrSellMarketPrice, sortPirce, hasFloat } from '../setup';
+import { getUserId } from '@/services/bus/account';
+import { getUserAccountType } from '@/services/bus/user';
+import { queryTjmdTradeOrderDetail } from '@/services/go/Tjmd';
+import { QueryTjmdTradeOrderDetailReq, QueryTjmdTradeOrderDetailRsp } from '@/services/go/Tjmd/interface';
+import { findItemGoods } from '../../setup';
+import { RefGoodsList } from '../../interface';
+import TimerUtils from '@/utils/timer/timerUtil';
+
+const columns = [
+    {
+        key: '0th',
+        dataIndex: 'index',
+        title: '序号',
+        align: 'center',
+        slots: {
+            customRender: 'index',
+        },
+        width: 60,
+    },
+    {
+        key: '3th',
+        dataIndex: 'username',
+        title: '销售方',
+        align: 'center',
+        slots: {
+            customRender: 'username',
+        },
+    },
+    {
+        key: '2th',
+        dataIndex: 'orderqty',
+        title: '卖量',
+        align: 'center',
+        slots: {
+            customRender: 'orderqty',
+        },
+        width: 120,
+    },
+    {
+        key: '1th',
+        dataIndex: 'orderprice',
+        title: '卖价',
+        align: 'center',
+        slots: {
+            customRender: 'orderprice',
+        },
+        width: 120,
+    },
+];
+
+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<RefGoodsList>,
+            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: 1,
+                userid: getUserId(),
+                usertype: getUserAccountType(),
+                goodsid: findItemGoods(props.parantSelectedRow.goodscode)?.goodsid,
+            };
+            queryTable(queryTjmdTradeOrderDetail, param).then((res) => {
+                // 先置空 要不然数据变更了,视图不更新
+                const fn = () => {
+                    tableList.value = [];
+                    tableList.value = sortPirce(res, props.parantSelectedRow).filter(el => el.userid !== getUserId());
+                };
+                fn()
+                if (hasFloat(res)) {
+                    // 有浮动价, 则每三秒更新一次数据
+                    TimerUtils.setInterval(fn, 3 * 1000, 'sellMarket');
+                }
+            });
+        };
+        onBeforeUnmount(() => {
+            TimerUtils.clearInterval('sellMarket');
+        });
+        // 表格通用逻辑
+        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<QueryTjmdTradeOrderDetailRsp>(param),
+            queryTableAction,
+            loading,
+            tableList,
+            BuyOrSell,
+            enumName: props.enumName,
+            expandIcon,
+            handleColumn,
+            btnList: useBuyOrSellBtnList(),
+            columns,
+            getBuyOrSellMarketPrice,
+        };
+    },
+});
+</script>
+<style lang="less">
+.buy-sell-market {
+    .btnDeafault.ant-btn {
+        height: 28px;
+        line-height: 28px;
+    }
+}
+</style>

+ 82 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/setup.ts

@@ -0,0 +1,82 @@
+import { BtnListType } from "@/common/components/btnList/interface";
+import { UserType } from "@/common/constants/enumCommon";
+import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
+import { getGoodsByCode, getQuoteDayInfoByCodeFindPrice } from "@/services/bus/goods";
+import { getUserAccountType } from "@/services/bus/user";
+import { QueryTjmdTradeOrderDetailRsp } from "@/services/go/Tjmd/interface";
+import { UnwrapRef } from "vue";
+import { RefGoodsList } from "../interface";
+
+// 获取按钮列表
+export function useBuyOrSellBtnList() {
+    const btnList: BtnListType[] = [
+        { lable: '摘牌', code: 'Listing', className: 'operBtn' },
+    ];
+    return btnList
+}
+
+// true: 普通交易商;false: 机构
+export const useUserType = () => {
+    return getUserAccountType() === UserType.investment
+}
+
+// 判断是否是 机构
+export const isInstitution = () => {
+    return getUserAccountType() === UserType.institution
+}
+// 判断是否是 投资者
+export const isInvestment = () => {
+    return getUserAccountType() === UserType.investment
+}
+
+// 交易账号
+export function useBlocksAccount<T extends { accountid: number | undefined }>(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 };
+}
+
+// 获取买卖大厅的价格,如果是浮动价的时候,取行情最新价格价基差
+export function getBuyOrSellMarketPrice(record: QueryTjmdTradeOrderDetailRsp, selectedRow: RefGoodsList) {
+    let result = record.orderprice
+    // 浮动价
+    if (record.pricemode === 3) {
+        const price = getQuoteDayInfoByCodeFindPrice(selectedRow.refgoodscode);
+        const goods = getGoodsByCode(selectedRow.refgoodscode)?.decimalplace || 2
+        if (price && price !== '--') {
+            // 浮动价
+            result = +(+price + record.marketmaxsub).toFixed(goods);
+        }
+    }
+    return result
+}
+
+// 价格排序
+// true: 升序,false: 倒序
+export function sortPirce(arr: QueryTjmdTradeOrderDetailRsp[], selectedRow: RefGoodsList, isUp = true) {
+    return arr.sort((a, b) => {
+        return isUp ? getBuyOrSellMarketPrice(a, selectedRow) - getBuyOrSellMarketPrice(b, selectedRow) : getBuyOrSellMarketPrice(b, selectedRow) - getBuyOrSellMarketPrice(a, selectedRow)
+    })
+}
+
+// 是否有浮动价
+export function hasFloat(arr: QueryTjmdTradeOrderDetailRsp[]) {
+    return arr.find(e => e.pricemode === 3) ? true : false
+}

+ 189 - 0
src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue

@@ -0,0 +1,189 @@
+<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="refgoodscode" ref="tableRef" :data-source="goodsList">
+      <!-- <template #totalturnover="{ text }">
+        <span>{{changeUnit(text)}}</span>
+      </template>-->
+      <!-- 涨跌 -->
+      <template #change="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'last')">{{ quoteChange_out(record.refgoodscode) }}</span>
+      </template>
+      <!-- 幅度 -->
+      <template #amplitude="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'last')">{{ quoteAmplitude_out(record.refgoodscode) }}</span>
+      </template>
+      <!-- 振幅 -->
+      <template #vibration="{ record }">
+        <span>{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+      </template>
+      <template #index="{ index }">
+        <span>{{ index + 1 }}</span>
+      </template>
+      <!-- 买价 -->
+      <!-- <template #bid="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'bid')">
+          {{getQuoteValue_out(record.refgoodscode, 'bid')}}</span>
+      </template>-->
+      <!-- 卖价 -->
+      <!-- <template #ask="{  record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'ask')">
+          {{getQuoteValue_out(record.refgoodscode, 'ask')}}</span>
+      </template>-->
+      <!-- 最新价 -->
+      <template #last="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'last')">{{ getQuoteValue_out(record.refgoodscode, 'last') }}</span>
+      </template>
+      <!-- 开盘 -->
+      <template #opened="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'opened')">{{ getQuoteValue_out(record.refgoodscode, 'opened') }}</span>
+      </template>
+      <!-- 结算 -->
+      <template #settle="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'settle')">{{ getQuoteValue_out(record.refgoodscode, 'settle') }}</span>
+      </template>
+      <!-- 昨结算 -->
+      <template #presettle="{ record }">
+        <span>{{ getQuoteValue_out(record.refgoodscode, 'presettle') }}</span>
+      </template>
+      <!-- 最低价 -->
+      <template #lowest="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'lowest')">{{ getQuoteValue_out(record.refgoodscode, 'lowest') }}</span>
+      </template>
+      <!-- 最高价 -->
+      <template #highest="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'highest')">{{ getQuoteValue_out(record.refgoodscode, 'highest') }}</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 { getShowBottomValue } from '@/common/config/constrolBottom';
+import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { getQuoteValue_out, handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out } from '@/common/setup/table/tableQuote';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryQuoteGoodsListRsp } from '@/services/go/Tjmd/interface';
+import { columnsList, getBtnList, useSwapList } 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<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
+    // 过滤标的合约
+    function goodsChange(value: string) {
+      filterGoodsList(value);
+      // 停止上次订阅
+      stopSubcribe();
+      // 重新发起订阅
+      stopSubcribe = handleSubcriteOnDemandQuote<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
+    }
+    return {
+      isBottom,
+      ...handleTableEventAndData<QueryQuoteDayRsp>(param),
+      btnList: getBtnList(true),
+      handleQuotePriceColor_out,
+      quoteChange_out,
+      quoteAmplitude_out,
+      quoteAmplituOfVibration,
+      getRefGoodsList,
+      goodsList,
+      loading,
+      goodsChange,
+      getQuoteValue_out,
+    };
+  },
+});
+</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>

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


+ 0 - 0
src/views/market/market-spot/compoments/spot_trade_order_transaction/setup.ts → src/views/market/market-spot/spot_trade_order_transaction/spot_trade_order_transaction_swap/setup.ts


+ 0 - 0
src/views/market/market-spot/compoments/spot_trade_reference_market/index.vue → src/views/market/market-spot/spot_trade_reference_market/index.vue


+ 0 - 0
src/views/market/spot_trade/warehouse_pre_sale/index.vue → src/views/market/market-spot/warehouse_pre_sale/index.vue


+ 138 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/buy/index.vue

@@ -0,0 +1,138 @@
+<template>
+  <!-- 仓单贸易 贸易圈挂牌 卖-->
+  <div>
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', 'halfBottom', tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+      :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }"
+      :pagination="false"
+      :loading="loading"
+      :expandedRowKeys="expandedRowKeys"
+      :customRow="Rowclick"
+      rowKey="key"
+      :data-source="tableList"
+    >
+      <template #index="{ index }">
+        <span>{{ index + 1 }}</span>
+      </template>
+      <template #marginvalue="{ text }">
+        <span>{{ (text * 100).toFixed(2) + '%' }}</span>
+      </template>
+      <!-- 议价 -->
+      <template #canbargain="{ text }">
+        <span>{{ text ? '是' : '否' }}</span>
+      </template>
+      <!-- 整单 -->
+      <template #canpart="{ text }">
+        <span>{{ text === 1 ? '否' : '是' }}</span>
+      </template>
+      <!-- 挂牌有效期 -->
+      <template #validtime="{ text }">
+        <span>{{ formatTime(text, 'd') }}</span>
+      </template>
+    </a-table>
+    <!-- 右键 -->
+    <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="filterBtn(firstBtn)"></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :componentId="componentId"
+      :selectedRow="selectedRow"
+      :buyOrSell="BuyOrSell.Buy"
+      @cancel="closeComponent"
+    ></component>
+  </div>
+</template>
+
+<script lang="ts">
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { queryTableList, contextMenu, defineAsyncComponent, defineComponent, ModalEnum, ComposeTableParam } from '@/common/export/commonTable';
+import { QueryOrderQuoteMyqQsp, QueryOrderQuoteMyqReq, QueryOrderQuoteReq, WrOrderQuote } from '@/services/go/wrtrade/interface';
+import { queryOrderQuote, queryQueryOrderQuoteMyq } from '@/services/go/wrtrade';
+import { handleComposeTable } from '@/common/setup/table/compose';
+import Filter from '../../components/filter/index.vue';
+import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { handleColumns, filterBtn } from '../../setup';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { formatTime } from '@/common/methods';
+import Bus from '@/utils/eventBus/index';
+
+export default defineComponent({
+    name: 'warehouse_receipt_trade_blocs_buy',
+    components: {
+        contextMenu,
+        warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+        warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+        warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/market-spot/components/detail/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        // 表头
+        const { getBuyOrSellColumns } = handleColumns();
+        const columns = getBuyOrSellColumns(BuyOrSell.buy);
+
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<QueryOrderQuoteMyqQsp>();
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteMyqReq = {
+                buyorsell: BuyOrSell.buy,
+                haswr: 0,
+            };
+            queryTable(queryQueryOrderQuoteMyq, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: EnumRouterName.warehouse_receipt_trade_blocs,
+            tableFilterKey: [],
+            isDetail: false,
+        };
+        const {
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent,
+            openComponent, // 控制异步组件
+            firstBtn,
+            secondBtn, // 表格按钮
+        } = handleComposeTable<QueryOrderQuoteMyqQsp>(param);
+        function search(value: Object) {
+            // const param: QueryOrderQuoteReq = {
+            //     wrpricetype: 2,
+            //     haswr: 1,
+            // };
+            // Object.assign(param, value);
+            // queryTable(queryOrderQuote, param);
+        }
+        // 单据挂牌成功 刷新数据
+        Bus.$on('spotTrade', queryTableAction);
+        return {
+            isBottom,
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            columns,
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent, // 控制异步组件
+            firstBtn, // 表格按钮
+            loading,
+            tableList,
+            search,
+            formatTime,
+            filterBtn,
+            BuyOrSell,
+        };
+    },
+});
+</script>
+<style lang="less">
+</style>

+ 512 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/index.vue

@@ -0,0 +1,512 @@
+<template>
+  <!--仓单贸易 贸易圈挂牌 摘牌-->
+  <Drawer
+    :title="isBargin() ? '议价摘牌' : '摘牌'"
+    :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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{ selectedRow.username }}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-col :span="24" v-if="isBargin()">
+            <a-form-item label="摘牌价格" name="price">
+              <a-input-number
+                class="commonInput"
+                style="width: 260px"
+                :min="0"
+                v-model:value="formState.price"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24" v-else>
+            <a-form-item label="摘牌价格">
+              <span class="white ml8">{{ selectedRow.fixedprice }}</span>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24" v-if="isBuy()">
+            <a-form-item label="现货仓单" name="LadingBillId">
+              <a-select
+                class="inlineFormSelect"
+                style="width: 260px"
+                v-model:value="formState.LadingBillId"
+                placeholder="请选择"
+              >
+                <a-select-option
+                  v-for="item in wrHoldList"
+                  :value="item.id"
+                  :key="item.id"
+                >{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+
+          <a-row :gutter="24" v-if="isCanpart()">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量" class="relative" name="num">
+                <a-input-number
+                  class="dialogInput yellowInput"
+                  style="width: 260px"
+                  :min="0"
+                  :max="getMaxNum()"
+                  v-model:value="formState.num"
+                />
+                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
+                <div class="labelTip">({{ selectedRow.delistminqty }}{{ selectedRow.enumdicname }}起)</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="isCanpart()">
+            <a-col :span="24" class="mt-20">
+              <a-form-item>
+                <a-slider
+                  :min="0"
+                  v-model:value="formState.num"
+                  :max="selectedRow.orderqty"
+                  class="formSlider"
+                  style="width: 260px"
+                />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{ getMaxNum() }}{{ selectedRow.enumdicname }}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-col :span="24" v-if="!isCanpart()">
+            <a-form-item label="摘牌数量">
+              <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+            </a-form-item>
+          </a-col>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item label="摘牌金额">
+                <span class="white ml8">{{ getMoney() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{ getMargin() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <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"
+                :loading="loading"
+                :disabled="loading"
+                @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 { defineComponent, PropType, ref } from 'vue';
+import { Des } from '@/common/components/commonDes';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import Drawer from '@/common/components/drawer/index.vue';
+import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { hdWROrder } from '@/services/proto/warehousetrade';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { DGFactoryItems, HdWRDealOrderReq, WrBargainApplyReq, WRGoodsInfo } from '@/services/proto/warehousetrade/interface';
+import { getAccountTypeList, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { v4 as uuidv4 } from 'uuid';
+import moment, { Moment } from 'moment';
+import { getMarketRunByTradeMode, marketIsRun } from '@/services/bus/market';
+import { QueryOrderQuoteMyqQsp, WrOrderQuote } from '@/services/go/wrtrade/interface';
+
+import { validateAction } from '@/common/setup/form';
+
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+
+import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
+import { getCanUseMoney } from '@/services/bus/account';
+import { TempWrOrderQuoteDetail } from '@/views/market/market-spot/components/post_buying/interface';
+import { handleForm, handleSpotWarrant } from './setup';
+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'],
+  name: 'warehouse_receipt_trade_blocs_delisting_tab',
+  components: { Des, Drawer, PlusOutlined, MinusOutlined },
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryOrderQuoteMyqQsp>,
+      default: {},
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      default: BuyOrSell.buy,
+    },
+    componentId: {
+      type: String,
+      default: '',
+    },
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    const { rules, formState, formRef } = handleForm();
+    const loading = ref<boolean>(false);
+    const accountList = getAccountTypeList([2]);
+    // 现货仓单
+    const { wrHoldList, allWrHoldList } = handleSpotWarrant(props.buyOrSell, props.selectedRow, loading);
+    if (accountList.length) {
+      formState.accountid = accountList[0].accountid;
+    }
+
+    function getSelectedAccount() {
+      return accountList.find((e) => e.accountid === formState.accountid)!;
+    }
+    function getPrice() {
+      return isBargin() ? formState.price : props.selectedRow.fixedprice;
+    }
+    function getNum() {
+      return isCanpart() ? formState.num : props.selectedRow.orderqty;
+    }
+    // 摘牌金额
+    function getMoney() {
+      const price = getPrice();
+      const num = getNum();
+      if (price) {
+        return (price * num).toFixed(2);
+      } else {
+        return '--';
+      }
+    }
+    // 履约保证金
+    function getMargin() {
+      const price = getPrice();
+      const num = getNum();
+      let result = 0;
+      const { marginvalue } = props.selectedRow;
+      if (price && num && marginvalue) {
+        result = price * num * marginvalue;
+      }
+      return result ? Math.floor(2) : '--';
+    }
+    function getMaxNum() {
+      const qty = props.selectedRow.orderqty;
+      let result = 0;
+      if (!isBuy()) {
+        // 交易规则
+        const rules = getRules();
+        const { buymarginvalue } = rules.length ? rules[0] : { buymarginvalue: 0 };
+        const canUseMoney = Number(getCanUseMoney(getSelectedAccount()));
+        if (canUseMoney && !isNaN(canUseMoney)) {
+          const num = +(canUseMoney / buymarginvalue).toFixed(0);
+          // 买 最大可摘数量=min{挂牌数量,可用资金/(履约保证金比例)}
+          result = Math.min(qty, num);
+        }
+      } else {
+        // 卖出 最大可摘数量=min{挂牌数量,仓单可用数量}
+        const id = formState.LadingBillId;
+        if (id) {
+          const item = allWrHoldList.value.find((el) => el.ladingbillid === id)!;
+          result = Math.min(qty, item.enableqty);
+        }
+      }
+      return result;
+    }
+    function isBuy() {
+      return props.buyOrSell === BuyOrSell.buy;
+    }
+    // 是否部分摘牌
+    function isCanpart() {
+      return props.selectedRow.canpart === 1;
+    }
+    // 是否议价 摘牌
+    function isBargin() {
+      return props.componentId === 'warehouse_receipt_trade_blocs_bargain_delisting';
+    }
+    if (isBargin()) {
+      formState.price = props.selectedRow.fixedprice;
+    }
+
+    function submit() {
+      // 判断是否开市
+      if (!marketIsRun(TradeMode.WarehouseReceiptTrade)) {
+        return;
+      }
+      validateAction<ListingForm>(formRef, formState).then((res) => {
+        const price = getPrice();
+        const num = getNum();
+        if (isBargin()) {
+          // 议价摘牌
+          const param: WrBargainApplyReq = {
+            WRTradeOrderID: Long.fromString(props.selectedRow.wrtradeorderid),
+            ApplyQty: num,
+            UserID: getUserId().toString(),
+            AccountID: getSelectedAccountId().toString(),
+            BuyOrSell: (isBuy() ? BuyOrSell.sell : BuyOrSell.buy).toString(),
+            ApplyPrice: price.toString(),
+            ApplyRemark: '',
+          };
+          requestResultLoadingAndInfo(wrBargainApply, param, loading, ['议价摘牌成功', '议价摘牌失败:']).then(() => {
+            cancel(true);
+            Bus.$emit('blocsTrade', true);
+          });
+        } else {
+          // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
+          // 其次判断  摘牌 1。摘买 (需要通过自己的仓单进行摘买)  2。摘卖 (不需要通过仓单)
+          const param = {
+            UserID: getUserId(), // uint32 用户ID
+            AccountID: getSelectedAccountId(), // uint64 资金账号
+            RelatedWRTradeOrderID: props.selectedRow.wrtradeorderid, // uint64 关联委托单号(摘牌委托关联挂牌委托单ID)
+            WRTransferUserID: props.selectedRow.userid, // uint32 仓单受让用户
+            OrderQty: num, // uint64 委托数量
+            OrderSrc: 0, // uint32 委托来源
+            ClientSerialNo: uuidv4(), // string 客户端流水号
+            ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // string 客户端委托时间
+            ClientType: 4, // uint32 终端类型
+            OperatorID: getUserId(), // uint64 操作员账号ID
+            BuyOrSell: 0, // uint32 买卖方向
+            ApplyID: 0, // uint64 申请ID
+            LadingBillId: 0, // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
+            SubNum: 0, // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
+            WRFactorTypeId: Long.fromString(props.selectedRow.wrfactortypeid), // uint64 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写
+            TradeDate: moment().format('YYYYMMDD'), // string 交易日
+            DeliveryMonth: '', // string 交收月
+            HasWr: 1, // uint32 是否有仓单-0:没有仓单 1:有仓单
+            IsFinancing: 0, // uint32 是否融资购买(买摘牌时有效)-0:否 1:是
+            ProductDetailID: res.caseId, // uint64 金融机构产品组合ID(融资购买时有效)
+          };
+          // 摘买方向
+          if (isBuy()) {
+            param.BuyOrSell = BuyOrSell.sell;
+            param.LadingBillId = Long.fromString(res.LadingBillId);
+            const item = wrHoldList.value.find((el) => el.id === res.LadingBillId);
+            if (item) {
+              param.SubNum = +item.subnum;
+            }
+          } else {
+            param.BuyOrSell = BuyOrSell.buy;
+          }
+
+          requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
+            cancel(true);
+            Bus.$emit('blocsTrade', true);
+          });
+        }
+      });
+    }
+    return {
+      submit,
+      cancel,
+      visible,
+      accountList,
+      rules,
+      formState,
+      formRef,
+      getSelectedAccount,
+      getCanUseMoney,
+      getMoney,
+      isBuy,
+      isBargin,
+      wrHoldList,
+      loading,
+      getMaxNum,
+      isCanpart,
+      getMargin,
+    };
+  },
+});
+</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>

+ 0 - 0
src/views/market/spot_trade/warehouse_receipt_trade/warehouse_receipt_trade_blocs/components/delisting/interface.ts → src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/interface.ts


+ 1 - 1
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/setup.ts → src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/delisting/setup.ts

@@ -3,7 +3,7 @@ import { queryResultLoadingAndInfo } from "@/common/methods/request/resultInfo";
 import { validateCommon } from "@/common/setup/validate";
 import { queryHoldLB } from "@/services/go/wrtrade";
 import { QueryOrderQuoteMyqQsp, WrHoldLB } from "@/services/go/wrtrade/interface";
-import { Wrhold } from "@/views/market/spot_trade/spot_trade_order_transaction/components/delisting/interface";
+import { Wrhold } from "@/views/market/market-spot/spot_trade_order_transaction/components/delisting/interface";
 import { RuleObject } from "ant-design-vue/lib/form/interface";
 import { reactive, Ref, ref, UnwrapRef } from "vue";
 import { ListingForm } from "./interface";

+ 403 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/post-buying/index.vue

@@ -0,0 +1,403 @@
+<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>
+
+            <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', formState.permanceTempName ? 'white' : '']"
+                  @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', getFriendLength() ? 'white' : '']"
+                  @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>
+    </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">
+import { defineComponent, PropType, ref, UnwrapRef } from 'vue';
+import { Des } from '@/common/components/commonDes';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import Drawer from '@/common/components/drawer/index.vue';
+import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { hdWROrder } from '@/services/proto/warehousetrade';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { getUserId } from '@/services/bus/account';
+import { v3, v4 as uuidv4 } from 'uuid';
+import moment, { Moment } from 'moment';
+import { getMarketRunByTradeMode, marketIsRun } from '@/services/bus/market';
+import { validateAction } from '@/common/setup/form';
+import { getCanUseMoney } from '@/services/bus/account';
+import { TempWrOrderQuoteDetail } from '@/views/market/market-spot/components/post_buying/interface';
+import Friend from '@/common/components/friends/index.vue';
+import Permance from '@/common/components/permanceTemp/choosePermancePlanTmp.vue';
+import { message } from 'ant-design-vue';
+import { useBlocksPrice, useBlocksNumber, useBlocksAccount, useBlocksMoney, useBlocksFriends, useBlocksPermaceTemp, handleForm } from '@/common/setup/warehouse_receipt_trade/listing';
+
+import { BlocsListingForm } from '@/common/setup/warehouse_receipt_trade/interface';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { useVerifyBeginDelistingNum } from '@/hooks/form/verify';
+import { WrResultItem } from '@/views/market/futures/compoments/futures-trade/interface'
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: ModalEnum.spot_trade_warehouse_post_buying,
+  components: { Des, Drawer, PlusOutlined, MinusOutlined, Friend, Permance },
+  props: {
+    selectedRow: {
+      type: Object as PropType<TempWrOrderQuoteDetail>,
+      default: { wrResult: [], wrstandardid: 0, deliverygoodsid: 0, wrfactortypeid: 0, minivalue: 0 },
+    },
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    // 表单
+    const { rules, formState, formRef } = handleForm();
+    // 验证 起摘数量
+    const { v_beginDelistingRules } = useVerifyBeginDelistingNum(props.selectedRow.minivalue);
+    rules.delistingQty = v_beginDelistingRules;
+    // 选择朋友
+    const { friendCheck, showFriend, chooseFriend, openFriend, getFriendLength, limiteFriends } = useBlocksFriends(formState);
+    // 履约模板
+    const { showPermance, choosePermance, openPermance } = useBlocksPermaceTemp(formState);
+    // 价格
+    const { priceCheck, increasePrice, decreasePrice } = useBlocksPrice(formState);
+    const loading = ref<boolean>(false);
+    // 摘牌数量
+    const { numCheck, increaseNumber, decreaseNumber } = useBlocksNumber(formState);
+    function submit() {
+      // 判断是否开市
+      if (!marketIsRun(TradeMode.WarehouseReceiptTrade)) {
+        return;
+      }
+      const marketInfo = getMarketRunByTradeMode(TradeMode.WarehouseReceiptTrade);
+      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(), // 客户端流水号
+            // OperateSrc: 2,
+            ClientType: 4,
+            // MarketID: marketInfo.marketid,
+            LadingBillId: 0, // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
+            // LadingBillId: 'uint642081626946446000001', // 提单id(wrholdlb的LadingBillId字段),卖的时候填写 uint64
+            TradeDate: moment(marketInfo.tradedate).format('YYYYMMDD'), // 交易日 string
+            // SubNum: '0', // 提单子单号
+            SubNum: 0,
+            // WRFactorTypeId: '2121626946446000001', // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
+            WRFactorTypeId: props.selectedRow.wrfactortypeid ? props.selectedRow.wrfactortypeid : 0, // 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写 uint64
+            IsSpecified: 1, // 是否指定对手 0:不指定 1:指定 uint32
+            MatchAccIDs: res.friends, // 仓单贸易对手资金账号ID集合(指定对手时填写) uint32
+            OrderQty: res.OrderQty, // 委托数量(可挂部分数据量) ======
+            DeliveryGoodsID: props.selectedRow.deliverygoodsid, // 交割商品商品ID  // 有仓单求购
+            WRPriceType: 1, // 价格方式 1:固定价 2:浮动价
+            FixedPrice: res.FixedPrice, // 固定价格
+            PriceFactor: 1, // 价格系数(浮动价时填写)
+            PriceMove: 0, // 升贴水(浮动价时填写)
+            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, // 首付比例
+            PerformanceTemplateID: res.permaceTempId, // 履约计划模板ID
+            UserID: getUserId(),
+            OperatorID: getUserId(), // 操作员账号ID
+            BuyOrSell: 0, // 买卖方向 0买1卖
+            PriceDisplayMode: 1, // 浮动价显示方式 1:合并显示 2:分开显示
+            CanBargain: priceCheck.value ? 1 : 0, // 挂牌是否可议价0:不可1:可-摘牌是否议价
+            Attachment1: '', // 附件1
+            Attachment2: '', // 附件2
+            Remark: '', // 备注
+            ApplyID: 0, // 申请ID
+            WRTradeGoods: [],
+            CanPart: numCheck.value ? 0 : 1, // 是否允许部份摘牌0:不允许;1:允许
+            WRStandardID: props.selectedRow.wrstandardid,
+            HasWr: 1, // 无仓单挂牌  是否有无仓单
+            DeliveryMonth: '',
+            DelistMinQty: numCheck.value ? formState.delistingQty : res.delistingQty, // 起摘数量
+            MarginFlag: 1, // 挂牌是否指定保证金 0:否 1:是
+            MarginAlgorithm: 1, // 指定保证金方式 1:比率 2:固定
+            MarginValue: +(formState.margin / 100), // 指定保证金设置值
+            AllFriendsFlag: friendCheck.value ? 1 : 0, //是否全好友可见 0:否 1:是
+            FactoryItems:
+              props.selectedRow.wrResult != undefined
+                ? props.selectedRow.wrResult.map((it: WrResultItem) => {
+                  return {
+                    DGFactoryItemTypeID: it.dgfactoryitemtypeid, // uint64 要素项类型ID
+                    DGFactoryItemID: it.dgfactoryitemid, // uint64 预约要素项类型值
+                    ItemTypeMode: 1, // uint32 要素项类型模式
+                  };
+                })
+                : [], // DGFactoryItems 要素类型明细集合(没有仓单要素ID填写)
+          };
+          requestResultLoadingAndInfo(hdWROrder, param, loading, ['求购成功', '求购失败:']).then(() => {
+            cancel(true);
+          });
+        });
+      }
+    }
+    return {
+      submit,
+      cancel,
+      visible,
+      rules,
+      formState,
+      formRef,
+      getCanUseMoney,
+      priceCheck,
+      increasePrice,
+      decreasePrice,
+      ...useBlocksAccount(formState),
+      ...useBlocksMoney(formState),
+      showPermance,
+      choosePermance,
+      openPermance,
+      numCheck,
+      increaseNumber,
+      decreaseNumber,
+      friendCheck,
+      showFriend,
+      chooseFriend,
+      openFriend,
+      getFriendLength,
+      limiteFriends,
+    };
+  },
+});
+</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;
+    }
+  }
+}
+
+.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;
+}
+.ant-input-suffix {
+  position: absolute;
+  right: -25px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item .ant-form-item-label {
+  width: 80px;
+}
+.ant-form.dialogForm .ant-row.ant-form-item .ant-form-item-control-wrapper {
+  width: calc(100% - 80px);
+}
+.ant-form.dialogForm {
+  .ant-row.btnCenter.ant-form-item {
+    width: 100%;
+    .ant-col.ant-form-item-control-wrapper {
+      width: 100%;
+    }
+  }
+}
+</style>

+ 22 - 5
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/components/sell/index.vue → src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/components/sell/index.vue

@@ -1,12 +1,22 @@
 <template>
   <!-- 仓单贸易 贸易圈挂牌 买-->
   <div>
-    <a-table :columns="columns" :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom',  tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']" :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }" :pagination="false" :loading="loading" :expandedRowKeys="expandedRowKeys" :customRow="Rowclick" :rowKey="(record,index)=>index" :data-source="tableList">
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+      :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }"
+      :pagination="false"
+      :loading="loading"
+      :expandedRowKeys="expandedRowKeys"
+      :customRow="Rowclick"
+      rowKey="key"
+      :data-source="tableList"
+    >
       <template #index="{ index }">
         <span>{{ index + 1 }}</span>
       </template>
       <template #marginvalue="{ text }">
-        <span>{{ (text * 100).toFixed(2) + '%'}}</span>
+        <span>{{ (text * 100).toFixed(2) + '%' }}</span>
       </template>
       <!-- 议价 -->
       <template #canbargain="{ text }">
@@ -14,7 +24,7 @@
       </template>
       <!-- 整单 -->
       <template #canpart="{ text }">
-        <span>{{ text  === 1 ? '否' : '是' }}</span>
+        <span>{{ text === 1 ? '否' : '是' }}</span>
       </template>
       <!-- 挂牌有效期 -->
       <template #validtime="{ text }">
@@ -23,7 +33,14 @@
     </a-table>
     <!-- 右键 -->
     <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="filterBtn(firstBtn)"></contextMenu>
-    <component :is="componentId" v-if="componentId" :componentId="componentId" :selectedRow="selectedRow" :buyOrSell="BuyOrSell.sell" @cancel="closeComponent"></component>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :componentId="componentId"
+      :selectedRow="selectedRow"
+      :buyOrSell="BuyOrSell.sell"
+      @cancel="closeComponent"
+    ></component>
   </div>
 </template>
 
@@ -47,7 +64,7 @@ export default defineComponent({
     contextMenu,
     warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
     warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
-    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/spot_trade/components/detail/index.vue')),
+    warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/market-spot/components/detail/index.vue')),
   },
   setup() {
     const isBottom = getShowBottomValue();

+ 0 - 0
src/views/market/spot_trade/warehouse_pre_sale/warehouse_pre_sale_blocs/index.vue → src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/index.vue


+ 41 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_blocs/setup.ts

@@ -0,0 +1,41 @@
+import { BtnListType } from '@/common/components/btnList/interface';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { QueryOrderQuoteMyqQsp } from '@/services/go/wrtrade/interface';
+
+
+export function handleColumns() {
+    const columns = [
+        { title: '品种', key: 'deliverygoodsname', align: 'center', width: 140 },
+        { title: '商品', key: 'wrtypename', align: 'center', width: 400 },
+        { title: '仓库', key: 'warehousename', align: 'center', width: 200 },
+        { title: '交收月', key: 'deliverymonth', align: 'center', width: 120 },
+        { title: '价格', key: 'fixedprice', align: 'center', width: 120 },
+        { title: '议价', key: 'canbargain', align: 'center', width: 80 },
+        { title: '数量', key: 'orderqty', align: 'center', width: 120 },
+        { title: '整单', key: 'canpart', align: 'center', width: 80 },
+        { title: '挂牌有效期', key: 'validtime', align: 'center', width: 120 },
+        { title: '履约保证金', key: 'marginvalue', align: 'center', width: 120 },
+        { title: '履约模板', key: 'templatename', align: 'center', width: 140 },
+        { title: '挂牌方', key: 'username', align: 'center', width: 100 },
+    ];
+    function getBuyOrSellColumns(type: BuyOrSell) {
+        const title = type === BuyOrSell.buy ? '买' : '卖'
+        const result = [
+            { title, dataIndex: 'index', key: 'index', width: 80, align: 'center' },
+            ...columns
+        ]
+        return result.map(el => {
+            const slots = { customRender: el.key };
+            return { ...el, slots, dataIndex: el.key };
+        })
+    }
+    return { getBuyOrSellColumns }
+}
+
+export function filterBtn(btnList: BtnListType[], selectedRow: QueryOrderQuoteMyqQsp) {
+    let result = btnList.filter(e => e.code !== 'warehouse_receipt_trade_blocs_post_buying')
+    if (selectedRow) {
+        result = selectedRow.canbargain ? result : result.filter(e => e.code !== 'warehouse_receipt_trade_blocs_bargain_delisting')
+    }
+    return result
+}

+ 138 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_designate/components/buy/index.vue

@@ -0,0 +1,138 @@
+<template>
+  <!-- 仓单贸易 贸易圈挂牌 卖-->
+  <div>
+    <a-table
+      :columns="columns"
+      :class="['srcollYTable', isBottom ? 'condSecondTabTableHalfTop' : 'condSecondTabTableHalfTopNoBottom', 'halfBottom',  tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+      :scroll="{ x: '100%', y: isBottom ? 'calc((100vh- 443px)/2 - 14px)' : 'calc((100vh - 196px)/2 - 16px)' }"
+      :pagination="false"
+      :loading="loading"
+      :expandedRowKeys="expandedRowKeys"
+      :customRow="Rowclick"
+      rowKey="key"
+      :data-source="tableList"
+    >
+      <template #index="{ index }">
+        <span>{{ index + 1 }}</span>
+      </template>
+      <template #marginvalue="{ text }">
+        <span>{{ (text * 100).toFixed(2) + '%'}}</span>
+      </template>
+      <!-- 议价 -->
+      <template #canbargain="{ text }">
+        <span>{{ text ? '是' : '否' }}</span>
+      </template>
+      <!-- 整单 -->
+      <template #canpart="{ text }">
+        <span>{{ text === 1 ? '否' : '是' }}</span>
+      </template>
+      <!-- 挂牌有效期 -->
+      <template #validtime="{ text }">
+        <span>{{ formatTime(text, 'd') }}</span>
+      </template>
+    </a-table>
+    <!-- 右键 -->
+    <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="filterBtn(firstBtn)"></contextMenu>
+    <component
+      :is="componentId"
+      v-if="componentId"
+      :componentId="componentId"
+      :selectedRow="selectedRow"
+      :buyOrSell="BuyOrSell.Buy"
+      @cancel="closeComponent"
+    ></component>
+  </div>
+</template>
+
+<script lang="ts">
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { queryTableList, contextMenu, defineAsyncComponent, defineComponent, ModalEnum, ComposeTableParam } from '@/common/export/commonTable';
+import { QueryOrderQuoteMyqQsp, QueryOrderQuoteMyqReq, QueryOrderQuoteReq, WrOrderQuote } from '@/services/go/wrtrade/interface';
+import { queryOrderQuote, queryQueryOrderQuoteMyq } from '@/services/go/wrtrade';
+import { handleComposeTable } from '@/common/setup/table/compose';
+import Filter from '../../components/filter/index.vue';
+import { Goods } from '@/services/go/ermcp/goodsInfo/interface';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { handleColumns, filterBtn } from '../../setup';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { formatTime } from '@/common/methods';
+import Bus from '@/utils/eventBus/index';
+
+export default defineComponent({
+    name: 'warehouse_receipt_trade_blocs_buy',
+    components: {
+        contextMenu,
+        warehouse_receipt_trade_blocs_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+        warehouse_receipt_trade_blocs_bargain_delisting: defineAsyncComponent(() => import('../delisting/index.vue')),
+        warehouse_receipt_trade_blocs_detail: defineAsyncComponent(() => import('@/views/market/market-spot/components/detail/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        // 表头
+        const { getBuyOrSellColumns } = handleColumns();
+        const columns = getBuyOrSellColumns(BuyOrSell.buy);
+
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<QueryOrderQuoteMyqQsp>();
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteMyqReq = {
+                buyorsell: BuyOrSell.buy,
+                haswr: 0,
+            };
+            queryTable(queryQueryOrderQuoteMyq, param);
+        };
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: EnumRouterName.warehouse_receipt_trade_blocs,
+            tableFilterKey: [],
+            isDetail: false,
+        };
+        const {
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent,
+            openComponent, // 控制异步组件
+            firstBtn,
+            secondBtn, // 表格按钮
+        } = handleComposeTable<QueryOrderQuoteMyqQsp>(param);
+        function search(value: Object) {
+            // const param: QueryOrderQuoteReq = {
+            //     wrpricetype: 2,
+            //     haswr: 1,
+            // };
+            // Object.assign(param, value);
+            // queryTable(queryOrderQuote, param);
+        }
+        // 单据挂牌成功 刷新数据
+        Bus.$on('spotTrade', queryTableAction);
+        return {
+            isBottom,
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            columns,
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent, // 控制异步组件
+            firstBtn, // 表格按钮
+            loading,
+            tableList,
+            search,
+            formatTime,
+            filterBtn,
+            BuyOrSell,
+        };
+    },
+});
+</script>
+<style lang="less">
+</style>

+ 512 - 0
src/views/market/market-spot/warehouse_pre_sale/warehouse_pre_sale_designate/components/delisting/index.vue

@@ -0,0 +1,512 @@
+<template>
+  <!--仓单贸易 贸易圈挂牌 摘牌-->
+  <Drawer
+    :title="isBargin() ? '议价摘牌' : '摘牌'"
+    :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-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="挂牌方">
+                <span class="white ml8">{{ selectedRow.username }}</span>
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="挂牌数量">
+                <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-col :span="24" v-if="isBargin()">
+            <a-form-item label="摘牌价格" name="price">
+              <a-input-number
+                class="commonInput"
+                style="width: 260px"
+                :min="0"
+                v-model:value="formState.price"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24" v-else>
+            <a-form-item label="摘牌价格">
+              <span class="white ml8">{{ selectedRow.fixedprice }}</span>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24" v-if="isBuy()">
+            <a-form-item label="现货仓单" name="LadingBillId">
+              <a-select
+                class="inlineFormSelect"
+                style="width: 260px"
+                v-model:value="formState.LadingBillId"
+                placeholder="请选择"
+              >
+                <a-select-option
+                  v-for="item in wrHoldList"
+                  :value="item.id"
+                  :key="item.id"
+                >{{ item.name }}</a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+
+          <a-row :gutter="24" v-if="isCanpart()">
+            <a-col :span="24">
+              <a-form-item label="摘牌数量" class="relative" name="num">
+                <a-input-number
+                  class="dialogInput yellowInput"
+                  style="width: 260px"
+                  :min="0"
+                  :max="getMaxNum()"
+                  v-model:value="formState.num"
+                />
+                <span class="input-enumdicname-absolute">{{ selectedRow.enumdicname }}</span>
+                <div class="labelTip">({{ selectedRow.delistminqty }}{{ selectedRow.enumdicname }}起)</div>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24" v-if="isCanpart()">
+            <a-col :span="24" class="mt-20">
+              <a-form-item>
+                <a-slider
+                  :min="0"
+                  v-model:value="formState.num"
+                  :max="selectedRow.orderqty"
+                  class="formSlider"
+                  style="width: 260px"
+                />
+                <div class="unit">
+                  <span>0</span>
+                  <span>{{ getMaxNum() }}{{ selectedRow.enumdicname }}</span>
+                </div>
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">&nbsp;</a-col>
+          </a-row>
+          <a-col :span="24" v-if="!isCanpart()">
+            <a-form-item label="摘牌数量">
+              <span class="white ml8">{{ selectedRow.orderqty }}{{ selectedRow.enumdicname }}</span>
+            </a-form-item>
+          </a-col>
+          <a-row :gutter="24">
+            <a-col :span="24" class="mt-20">
+              <a-form-item label="摘牌金额">
+                <span class="white ml8">{{ getMoney() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <a-col :span="24">
+              <a-form-item label="履约保证金">
+                <span class="white ml8">{{ getMargin() }}</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="24">
+            <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"
+                :loading="loading"
+                :disabled="loading"
+                @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 { defineComponent, PropType, ref } from 'vue';
+import { Des } from '@/common/components/commonDes';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import Drawer from '@/common/components/drawer/index.vue';
+import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
+import { hdWROrder } from '@/services/proto/warehousetrade';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { DGFactoryItems, HdWRDealOrderReq, WrBargainApplyReq, WRGoodsInfo } from '@/services/proto/warehousetrade/interface';
+import { getAccountTypeList, getSelectedAccountId, getUserId } from '@/services/bus/account';
+import { v4 as uuidv4 } from 'uuid';
+import moment, { Moment } from 'moment';
+import { getMarketRunByTradeMode, marketIsRun } from '@/services/bus/market';
+import { QueryOrderQuoteMyqQsp, WrOrderQuote } from '@/services/go/wrtrade/interface';
+
+import { validateAction } from '@/common/setup/form';
+
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+
+import { BuyOrSell, TradeMode } from '@/common/constants/enumCommon';
+import { getCanUseMoney } from '@/services/bus/account';
+import { TempWrOrderQuoteDetail } from '@/views/market/market-spot/components/post_buying/interface';
+import { handleForm, handleSpotWarrant } from './setup';
+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'],
+  name: 'warehouse_receipt_trade_blocs_delisting_tab',
+  components: { Des, Drawer, PlusOutlined, MinusOutlined },
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryOrderQuoteMyqQsp>,
+      default: {},
+    },
+    buyOrSell: {
+      type: Number as PropType<BuyOrSell>,
+      default: BuyOrSell.buy,
+    },
+    componentId: {
+      type: String,
+      default: '',
+    },
+  },
+  setup(props, context) {
+    const { visible, cancel } = _closeModal(context);
+    const { rules, formState, formRef } = handleForm();
+    const loading = ref<boolean>(false);
+    const accountList = getAccountTypeList([2]);
+    // 现货仓单
+    const { wrHoldList, allWrHoldList } = handleSpotWarrant(props.buyOrSell, props.selectedRow, loading);
+    if (accountList.length) {
+      formState.accountid = accountList[0].accountid;
+    }
+
+    function getSelectedAccount() {
+      return accountList.find((e) => e.accountid === formState.accountid)!;
+    }
+    function getPrice() {
+      return isBargin() ? formState.price : props.selectedRow.fixedprice;
+    }
+    function getNum() {
+      return isCanpart() ? formState.num : props.selectedRow.orderqty;
+    }
+    // 摘牌金额
+    function getMoney() {
+      const price = getPrice();
+      const num = getNum();
+      if (price) {
+        return (price * num).toFixed(2);
+      } else {
+        return '--';
+      }
+    }
+    // 履约保证金
+    function getMargin() {
+      const price = getPrice();
+      const num = getNum();
+      let result = 0;
+      const { marginvalue } = props.selectedRow;
+      if (price && num && marginvalue) {
+        result = price * num * marginvalue;
+      }
+      return result ? Math.floor(2) : '--';
+    }
+    function getMaxNum() {
+      const qty = props.selectedRow.orderqty;
+      let result = 0;
+      if (!isBuy()) {
+        // 交易规则
+        const rules = getRules();
+        const { buymarginvalue } = rules.length ? rules[0] : { buymarginvalue: 0 };
+        const canUseMoney = Number(getCanUseMoney(getSelectedAccount()));
+        if (canUseMoney && !isNaN(canUseMoney)) {
+          const num = +(canUseMoney / buymarginvalue).toFixed(0);
+          // 买 最大可摘数量=min{挂牌数量,可用资金/(履约保证金比例)}
+          result = Math.min(qty, num);
+        }
+      } else {
+        // 卖出 最大可摘数量=min{挂牌数量,仓单可用数量}
+        const id = formState.LadingBillId;
+        if (id) {
+          const item = allWrHoldList.value.find((el) => el.ladingbillid === id)!;
+          result = Math.min(qty, item.enableqty);
+        }
+      }
+      return result;
+    }
+    function isBuy() {
+      return props.buyOrSell === BuyOrSell.buy;
+    }
+    // 是否部分摘牌
+    function isCanpart() {
+      return props.selectedRow.canpart === 1;
+    }
+    // 是否议价 摘牌
+    function isBargin() {
+      return props.componentId === 'warehouse_receipt_trade_blocs_bargain_delisting';
+    }
+    if (isBargin()) {
+      formState.price = props.selectedRow.fixedprice;
+    }
+
+    function submit() {
+      // 判断是否开市
+      if (!marketIsRun(TradeMode.WarehouseReceiptTrade)) {
+        return;
+      }
+      validateAction<ListingForm>(formRef, formState).then((res) => {
+        const price = getPrice();
+        const num = getNum();
+        if (isBargin()) {
+          // 议价摘牌
+          const param: WrBargainApplyReq = {
+            WRTradeOrderID: Long.fromString(props.selectedRow.wrtradeorderid),
+            ApplyQty: num,
+            UserID: getUserId().toString(),
+            AccountID: getSelectedAccountId().toString(),
+            BuyOrSell: (isBuy() ? BuyOrSell.sell : BuyOrSell.buy).toString(),
+            ApplyPrice: price.toString(),
+            ApplyRemark: '',
+          };
+          requestResultLoadingAndInfo(wrBargainApply, param, loading, ['议价摘牌成功', '议价摘牌失败:']).then(() => {
+            cancel(true);
+            Bus.$emit('blocsTrade', true);
+          });
+        } else {
+          // 首先确定  这是仓单贸易的有仓单挂摘牌 HasWr = 1
+          // 其次判断  摘牌 1。摘买 (需要通过自己的仓单进行摘买)  2。摘卖 (不需要通过仓单)
+          const param = {
+            UserID: getUserId(), // uint32 用户ID
+            AccountID: getSelectedAccountId(), // uint64 资金账号
+            RelatedWRTradeOrderID: props.selectedRow.wrtradeorderid, // uint64 关联委托单号(摘牌委托关联挂牌委托单ID)
+            WRTransferUserID: props.selectedRow.userid, // uint32 仓单受让用户
+            OrderQty: num, // uint64 委托数量
+            OrderSrc: 0, // uint32 委托来源
+            ClientSerialNo: uuidv4(), // string 客户端流水号
+            ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // string 客户端委托时间
+            ClientType: 4, // uint32 终端类型
+            OperatorID: getUserId(), // uint64 操作员账号ID
+            BuyOrSell: 0, // uint32 买卖方向
+            ApplyID: 0, // uint64 申请ID
+            LadingBillId: 0, // uint64 提单id(wrholdlb的LadingBillId字段),卖的时候填写
+            SubNum: 0, // uint64 提单子单号(wrholdlb的SubNum字段),卖的时候填写
+            WRFactorTypeId: Long.fromString(props.selectedRow.wrfactortypeid), // uint64 仓单要素ID(wrholdlb的WRFactorTypeId字段),卖的时候填写
+            TradeDate: moment().format('YYYYMMDD'), // string 交易日
+            DeliveryMonth: '', // string 交收月
+            HasWr: 1, // uint32 是否有仓单-0:没有仓单 1:有仓单
+            IsFinancing: 0, // uint32 是否融资购买(买摘牌时有效)-0:否 1:是
+            ProductDetailID: res.caseId, // uint64 金融机构产品组合ID(融资购买时有效)
+          };
+          // 摘买方向
+          if (isBuy()) {
+            param.BuyOrSell = BuyOrSell.sell;
+            param.LadingBillId = Long.fromString(res.LadingBillId);
+            const item = wrHoldList.value.find((el) => el.id === res.LadingBillId);
+            if (item) {
+              param.SubNum = +item.subnum;
+            }
+          } else {
+            param.BuyOrSell = BuyOrSell.buy;
+          }
+
+          requestResultLoadingAndInfo(HdWRDealOrder, param, loading, ['摘牌成功', '摘牌失败:']).then(() => {
+            cancel(true);
+            Bus.$emit('blocsTrade', true);
+          });
+        }
+      });
+    }
+    return {
+      submit,
+      cancel,
+      visible,
+      accountList,
+      rules,
+      formState,
+      formRef,
+      getSelectedAccount,
+      getCanUseMoney,
+      getMoney,
+      isBuy,
+      isBargin,
+      wrHoldList,
+      loading,
+      getMaxNum,
+      isCanpart,
+      getMargin,
+    };
+  },
+});
+</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>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません