浏览代码

feat: 新增掉期 挂牌功能

huangbin 4 年之前
父节点
当前提交
9b20b42c8b

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

@@ -116,6 +116,7 @@ export enum TradeMode {
     Bidding_large = 21, // 受托竞价
     EntrustedBidding = 21, // 受托竞价
     Wrtrade = 45, // 供应链金融
+    DiaoQi = 46, // 掉期
     Platinum = 69, // 铂金宝
     quote99 = 99,
 }

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

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

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

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

+ 4 - 3
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/buy/index.vue

@@ -51,6 +51,7 @@ import { QueryTjmdTradeOrderDetailReq, QueryTjmdTradeOrderDetailRsp } from '@/se
 import { getUserId } from '@/services/bus/account';
 import { getUserAccountType } from '@/services/bus/user';
 import { useBuyOrSellBtnList } from '../setup';
+import { findItemGoods } from '../../setup';
 
 const columns = [
     {
@@ -65,11 +66,11 @@ const columns = [
     },
     {
         key: '1th',
-        dataIndex: 'fixedprice',
+        dataIndex: 'orderprice',
         title: '买价',
         align: 'center',
         slots: {
-            customRender: 'fixedprice',
+            customRender: 'orderprice',
         },
         width: 120,
     },
@@ -121,7 +122,7 @@ export default defineComponent({
                 buyorsell: 0,
                 userid: getUserId(),
                 usertype: getUserAccountType(),
-                goodsid: props.parantSelectedRow.goodsid,
+                goodsid: findItemGoods(props.parantSelectedRow.goodscode)?.goodsid,
             };
             queryTable(queryTjmdTradeOrderDetail, param);
         };

+ 67 - 54
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/index.vue

@@ -1,11 +1,12 @@
 <template>
   <!-- 挂牌求购 -->
-  <Drawer :title="'挂牌求购'"
+  <Drawer :title="isBuy() ? '挂牌求购' : '挂牌卖出' "
           :placement="'right'"
           :visible="visible"
           @cancel="cancel"
           class="top">
     <div class="post_buying">
+      <span @click="changeDirection">{{isBuy() ? '卖出' : '求购'}}</span>
       <a-form class="inlineForm dialogForm"
               ref="formRef"
               :model="formState"
@@ -30,8 +31,8 @@
                            name>
                 <a-radio-group class="commonRadioGroup"
                                v-model:value="formState.priceType">
-                  <a-radio :value="1">固定价</a-radio>
-                  <a-radio :value="2">浮动价</a-radio>
+                  <a-radio :value="2">固定价</a-radio>
+                  <a-radio :value="3">浮动价</a-radio>
                 </a-radio-group>
               </a-form-item>
             </a-col>
@@ -110,7 +111,7 @@
                  class="fixedBtns">
             <a-form-item class="btnCenter">
               <a-button class="listedBtn"
-                        @click="submit">买入</a-button>
+                        @click="submit">{{isBuy() ? '买入' : '卖出'}}</a-button>
               <a-button class="ml10 cancelBtn"
                         @click="cancel">取消</a-button>
             </a-form-item>
@@ -136,7 +137,7 @@ import { v4 as uuidv4 } from 'uuid';
 import moment, { Moment } from 'moment';
 import { getMarketByTradeMode, getMarketRunByTradeMode, getMarketsByTradeMode } from '@/services/bus/market';
 import { WrOrderQuote } from '@/services/go/wrtrade/interface';
-import { handleForm, handleNumAndPrice, isFloat } from './setup';
+import { handleForm, handleNumAndPrice, isFloat, useBuySellDirection } from './setup';
 import { validateAction } from '@/common/setup/form';
 import { FormParam, TempWrOrderQuoteDetail } from './interface';
 import { EnumRouterName } from '@/common/constants/enumRouterName';
@@ -145,7 +146,10 @@ import { getCanUseMoney } from '@/services/bus/account';
 import { geLoginID_number } from '@/services/bus/login';
 import { OrderReq } from '@/services/socket/order/interface';
 import { QueryQuoteGoodsListRsp } from '@/services/go/Tjmd/interface';
-import { Order } from '@/services/socket/order';
+import { diaoQiOrder } from '@/services/socket/order';
+import Long from 'long';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { getGoodsByCode, getQuoteDayInfoByCodeFindPrice } from '@/services/bus/goods';
 
 export default defineComponent({
     emits: ['cancel', 'update'],
@@ -153,16 +157,12 @@ export default defineComponent({
     components: { Des, Drawer, PlusOutlined, MinusOutlined },
     props: {
         selectedRow: {
-            type: Object as PropType<TempWrOrderQuoteDetail>,
+            type: Object as PropType<QueryQuoteDayRsp>,
             default: {},
         },
-        enumName: {
-            default: '',
-            type: String as PropType<EnumRouterName>,
-        },
         refGoods: {
-            type: Object as PropType<QueryQuoteGoodsListRsp>,
-            default: {},
+            type: Object as PropType<QueryQuoteGoodsListRsp[]>,
+            default: [],
         },
     },
     setup(props, context) {
@@ -180,48 +180,58 @@ export default defineComponent({
             return accountList.find((e) => e.accountid === formState.accountid);
         }
 
-        const { getMaxNum, getMoney, getMargin, getPrice, canUseMoney } = handleNumAndPrice(props.enumName, props.selectedRow);
+        const { direction, changeDirection, isBuy } = useBuySellDirection();
+
+        const { getMaxNum, getMoney, getMargin, getPrice, canUseMoney } = handleNumAndPrice(props.selectedRow);
         function submit() {
-            // 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.selectedRow.goodsid, // 商品ID
-            //     MarketID: getMarketByTradeMode(TradeMode.ListingAndSelection)?.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);
-            // });
+            validateAction<FormParam>(formRef, formState).then((res) => {
+                const { goodscode, orderid } = props.selectedRow;
+                const param: OrderReq = {
+                    ClientSerialNo: uuidv4(), // 客户端流水号
+                    ClientOrderTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), // 客户端委托时间
+                    ClientType: 4, // 终端类型
+                    LoginID: geLoginID_number()!, // 登陆账号
+                    AccountID: getSelectedAccountId(), // 交易账号
+                    GoodsID: getGoodsByCode(goodscode)?.goodsid, // 商品ID
+                    MarketID: getMarketByTradeMode(TradeMode.DiaoQi)?.marketid, // 市场ID
+                    ValidType: 1, // 校验类型 当日有效
+                    OperateType: 1, // 操作类型: 申请
+                    OrderSrc: 1, // 单据来源: 客户端下单
+                    RelatedID: orderid, // 操作员账号ID
+                    OrderPrice: res.FixedPrice, // 委托价格
+                    OperatorID: Number(geLoginID_number()),
+                    // MarketMaxSub: number // 市价允许最大偏差(做市)
+                    OrderQty: res.OrderQty, // 委托数量
+                    BuyOrSell: direction.value, // 买卖方向  0 买 1 卖
+                    BuildType: 1, // 下单类型  1 建 2 平
+                    // CurtQuotePrice: 0, // 保留,计算冻结金额使用
+                    // SpPrice: 0 ,// 止盈价格
+                    // SlPrice: 0 , // 止损价格
+                    PriceMode: res.priceType, // 取价方式
+                    TimevalidType: 1, // 时间有效类型 单日有效
+                    TriggerType: 1, // 预埋单触发类型
+                    // TriggerPrice: number // 预埋单触发价格
+                    ListingSelectType: 1, // 挂牌点选类型 1:挂牌 2:摘牌 3:先摘后挂
+                    DelistingType: 2, // 摘牌类型 2:点选成交
+                    // RelatedID: number // 关联单号
+                    OptionType: 1, // 期权类型(1:认购(看涨)2:认沽(看跌))
+                    // Premium: number // 权利金
+                    // TriggerOperator: number // 触发条件(1:大于等于2:小于等于)
+                    // ServiceTime: string // 服务端时间
+                    // CouponTypeID: number // 优惠券类型ID(买方)
+                    // UsedQty: number // 使用数量
+                    // ValidTime: string // 指定有效日期
+                    // ReceiveInfoID: number // 收货地址ID
+                };
+                if (isFloat()) {
+                    // 浮动价
+                    param.MarketMaxSub = res.PriceMove; // 基差
+                    param.OrderPrice = +getQuoteDayInfoByCodeFindPrice(goodscode)!;
+                }
+                requestResultLoadingAndInfo(diaoQiOrder, param, loading, ['挂牌求购成功', '挂牌求购失败:']).then(() => {
+                    cancel(true);
+                });
+            });
         }
         return {
             submit,
@@ -238,6 +248,9 @@ export default defineComponent({
             getSelectedAccount,
             canUseMoney,
             getPrice,
+            direction,
+            changeDirection,
+            isBuy,
         };
     },
 });

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

@@ -3,7 +3,7 @@ import { WrOrderQuote } from "@/services/go/wrtrade/interface";
 export interface FormParam {
     accountid: undefined | number,
     FixedPrice: number,
-    priceType: 1 | 2,
+    priceType: 2 | 3,
     OrderQty: number,
     PriceMove: number,
 }

+ 42 - 10
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/post_buying/setup.ts

@@ -1,27 +1,44 @@
-import { EnumRouterName } from "@/common/constants/enumRouterName";
+import { BuyOrSell } from "@/common/constants/enumCommon";
+import { validateCommon } from "@/common/setup/validate";
 import { getAccountTypeList, getCanUseMoney } from "@/services/bus/account";
 import { getQuoteDayInfoByCodeFindPrice } from "@/services/bus/goods";
 import { getRules } from '@/services/bus/rules';
 import { AccountListItem } from "@/services/dataCenter/interafce/account";
-import { WrOrderQuote } from "@/services/go/wrtrade/interface";
-import { reactive, ref, UnwrapRef } from "vue";
+import { QueryQuoteDayRsp } from "@/services/go/quote/interface";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { onBeforeUnmount, reactive, ref, UnwrapRef } from "vue";
 import { FormParam } from "./interface";
 
+
 const formState: UnwrapRef<FormParam> = reactive({
     accountid: undefined,
     FixedPrice: 0,
     OrderQty: 0,
     PriceMove: 0,
-    priceType: 1,
+    priceType: 2,
 })
+
+function initForm() {
+    formState.FixedPrice = 0
+    formState.OrderQty = 0
+    formState.PriceMove = 0
+    formState.priceType = 2
+}
 export function handleForm() {
+    const v_price = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入挂牌价格');
+    };
     const formRef = ref();
     const rules = {
-        FixedPrice: [{ required: true, message: '请输入挂牌价格', trigger: 'blur', type: 'number', }],
+        FixedPrice: [{ required: true, message: '请输入挂牌价格', trigger: 'blur', type: 'number', validator: v_price }],
         OrderQty: [{ required: true, message: '请输入挂牌数量', trigger: 'blur', type: 'number', min: 1 }],
         PriceMove: [{ required: true, message: '请输入基差', trigger: 'blur', type: 'number' }],
         accountid: [{ required: true, message: '请输入交易账号' }],
     }
+    onBeforeUnmount(() => {
+        initForm()
+        formRef.value.resetFields()
+    })
     return { rules, formState, formRef }
 }
 
@@ -34,10 +51,10 @@ export function useSelectedAccount() {
     return { getSelectedAccount }
 }
 // 是否是浮动价
-export function isFloat() { return formState.priceType === 2 }
+export function isFloat() { return formState.priceType === 3 }
 
 
-export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrderQuote) {
+export function handleNumAndPrice(selectedRow: QueryQuoteDayRsp) {
     const { goodscode } = selectedRow
     // 获取选中的资金账号
     const { getSelectedAccount } = useSelectedAccount();
@@ -94,11 +111,26 @@ export function handleNumAndPrice(enumName: EnumRouterName, selectedRow: WrOrder
     }
     function getPrice() {
         let result = '--'
-        const goodsPrice = getQuoteDayInfoByCodeFindPrice(goodscode)
-        if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
-            result = ((goodsPrice as number) + formState.PriceMove).toFixed(2)
+        if (formState.OrderQty) {
+            const goodsPrice = getQuoteDayInfoByCodeFindPrice(goodscode)
+            if (goodsPrice && goodsPrice !== '--') {   // 有实时行情价格
+                result = ((goodsPrice as number) * formState.OrderQty + formState.PriceMove * formState.OrderQty).toFixed(2)
+            }
         }
         return result
     }
     return { getMaxNum, getMoney, getMargin, getPrice, canUseMoney }
+}
+
+// 挂牌买卖方向
+export function useBuySellDirection() {
+    const direction = ref<BuyOrSell>(BuyOrSell.buy)
+    function changeDirection() {
+        initForm()
+        direction.value = direction.value === BuyOrSell.buy ? BuyOrSell.sell : BuyOrSell.buy
+    }
+    function isBuy() {
+        return direction.value === BuyOrSell.buy
+    }
+    return { direction, changeDirection, isBuy }
 }

+ 2 - 1
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/components/sell/index.vue

@@ -49,6 +49,7 @@ import { getUserId } from '@/services/bus/account';
 import { getUserAccountType } from '@/services/bus/user';
 import { queryTjmdTradeOrderDetail } from '@/services/go/Tjmd';
 import { QueryTjmdTradeOrderDetailReq } from '@/services/go/Tjmd/interface';
+import { findItemGoods } from '../../setup';
 
 const columns = [
     {
@@ -121,7 +122,7 @@ export default defineComponent({
                 buyorsell: 1,
                 userid: getUserId(),
                 usertype: getUserAccountType(),
-                goodsid: props.parantSelectedRow.goodsid,
+                goodsid: findItemGoods(props.parantSelectedRow.goodscode)?.goodsid,
             };
             queryTable(queryTjmdTradeOrderDetail, param);
         };

+ 1 - 3
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/index.vue

@@ -73,7 +73,6 @@
     <component :is="componentId"
                v-if="componentId"
                :selectedRow="selectedRow"
-               :refGoods="findItemGoods(selectedRow?.goodscode)"
                @cancel="closeComponent"></component>
   </div>
 </template>
@@ -105,7 +104,7 @@ export default defineComponent({
     },
     setup() {
         const isBottom = getShowBottomValue();
-        const { loading, goodsList, getRefGoodsList, filterGoodsList, findItemGoods } = useSwapList();
+        const { loading, goodsList, getRefGoodsList, filterGoodsList } = useSwapList();
 
         const param: TableParam = {
             columnsList,
@@ -135,7 +134,6 @@ export default defineComponent({
             goodsList,
             loading,
             goodsChange,
-            findItemGoods,
         };
     },
 });

+ 12 - 8
src/views/market/spot_trade/spot_trade_order_transaction/spot_trade_order_transaction_swap/setup.ts

@@ -10,14 +10,19 @@ import { QueryQuoteGoodsListReq, QueryQuoteGoodsListRsp } from "@/services/go/Tj
 import { ref } from "vue"
 import { RefGoodsList } from './interface'
 
+const refGoods = ref<QueryQuoteGoodsListRsp[]>([])
+
+export function findItemGoods(goodscode: string) {
+    return refGoods.value.find(el => el.goodscode === goodscode)!
+}
 // 获取 商品掉期 商品列表
 export const useSwapList = () => {
-    const { loading, tableList, queryTable } = queryTableList<QueryQuoteGoodsListRsp>();
+    const { loading, queryTable } = queryTableList<QueryQuoteGoodsListRsp>();
     // 行情商品
     const goodsList = ref<RefGoodsList[]>([])
     initData(() => {
         // 组装 参数
-        const marketids = getMarketIdsByTradeMode(TradeMode.ListingAndSelection)
+        const marketids = getMarketIdsByTradeMode(TradeMode.DiaoQi)
         const param: QueryQuoteGoodsListReq = {
             usertype: getUserAccountType(),
         }
@@ -26,6 +31,7 @@ export const useSwapList = () => {
         }
         // 开始查询 商品掉期
         queryTable(queryQuoteGoodsList, param).then(res => {
+            refGoods.value = res
             goodsList.value.length = 0
             res.forEach(el => {
                 // 找到盘面数据
@@ -43,7 +49,7 @@ export const useSwapList = () => {
     // 获取标记商品列表
     function getRefGoodsList(): string[] {
         const result = new Set<string>(['全部标的合约'])
-        tableList.value.forEach(el => {
+        refGoods.value.forEach(el => {
             result.add(el.refgoodsname)
         })
         return [...result]
@@ -58,10 +64,8 @@ export const useSwapList = () => {
         }
         return result
     }
-    function findItemGoods(goodscode: string) {
-        return tableList.value.find(el => el.goodscode === goodscode)!
-    }
-    return { loading, goodsList, getRefGoodsList, filterGoodsList, findItemGoods }
+
+    return { loading, goodsList, getRefGoodsList, filterGoodsList }
 }
 
 export const columnsList = [
@@ -98,7 +102,7 @@ export const columnsList = [
 // 获取按钮列表
 export function getBtnList(isBuyAndSell: boolean) {
     const btnList: BtnListType[] = [
-        { lable: '挂牌求购', code: 'PostBuying', className: 'btnDeafault' },
+        { lable: '挂牌求购', code: 'PostBuying', className: 'operBtn' },
         { lable: '详情', code: 'Detail', className: 'btnDeafault' },
     ];
     if (isBuyAndSell) {