|
|
@@ -42,16 +42,18 @@
|
|
|
</a-form>
|
|
|
</div>
|
|
|
<div class="futures_trade__submit">
|
|
|
- <a-button :loading="loading" @click="submit('buy')">
|
|
|
+ <!--如果是采购合同隐藏按钮-->
|
|
|
+ <a-button class="buy" :loading="loading" @click="submit('buy')" v-if="!isHedging || selectedRow.contracttype === -1">
|
|
|
<span>{{buyPrice}}</span>
|
|
|
<span>买入</span>
|
|
|
</a-button>
|
|
|
- <a-button :loading="loading" @click="submit('sell')">
|
|
|
+ <!--如果是销售合同隐藏按钮-->
|
|
|
+ <a-button class="sell" :loading="loading" @click="submit('sell')" v-if="!isHedging || selectedRow.contracttype === 1">
|
|
|
<span>{{sellPrice}}</span>
|
|
|
<span>卖出</span>
|
|
|
</a-button>
|
|
|
- <!--如果有持仓则显示按钮-->
|
|
|
- <a-button :loading="loading" @click="submit('close')" :disabled="positionList.length === 0 || isHedging">
|
|
|
+ <!--如果是套保交易隐藏按钮-->
|
|
|
+ <a-button class="close" :loading="loading" @click="submit('close')" :disabled="positionList.length === 0" v-if="!isHedging">
|
|
|
<!--根据持仓方向显示平仓价格-->
|
|
|
<span v-if="selectedPosition">{{selectedPosition.buyorsell === BuyOrSell.buy ? sellPrice : buyPrice}}</span>
|
|
|
<span>平仓</span>
|
|
|
@@ -86,249 +88,259 @@ import { getGoodsQuoteList } from '@/services/bus/goods';
|
|
|
import { message } from 'ant-design-vue';
|
|
|
|
|
|
export default defineComponent({
|
|
|
- emits: ['cancel', 'update'],
|
|
|
- name: 'trader',
|
|
|
- components: { Des, Drawer, PlusOutlined, MinusOutlined },
|
|
|
- props: {
|
|
|
- selectedRow: {
|
|
|
- type: Object as PropType<GoodsQuote & QueryErmcpTradePositionRsp & Ermcp3SellBuyContract>,
|
|
|
- default: () => {},
|
|
|
- },
|
|
|
+ emits: ['cancel', 'update'],
|
|
|
+ name: 'trader',
|
|
|
+ components: { Des, Drawer, PlusOutlined, MinusOutlined },
|
|
|
+ props: {
|
|
|
+ selectedRow: {
|
|
|
+ type: Object as PropType<GoodsQuote & QueryErmcpTradePositionRsp & Ermcp3SellBuyContract>,
|
|
|
+ default: () => ({}),
|
|
|
},
|
|
|
- setup(props, context) {
|
|
|
- // 是否套保交易 (根据参数 spotcontractid 来判断)
|
|
|
- const isHedging = Boolean(props.selectedRow.spotcontractid);
|
|
|
+ },
|
|
|
+ setup(props, context) {
|
|
|
+ // 是否套保交易 (根据参数 spotcontractid 来判断)
|
|
|
+ const isHedging = Boolean(props.selectedRow.spotcontractid);
|
|
|
|
|
|
- const goodsList = getGoodsQuoteList();
|
|
|
- const getGoods = (id: number) => goodsList.find((item) => item.goodsid === id)!;
|
|
|
- // 当前选中的商品合约
|
|
|
- const selectedGoods = ref<GoodsQuote>(getGoods(props.selectedRow.goodsid));
|
|
|
+ const goodsList = getGoodsQuoteList();
|
|
|
+ const getGoods = (id: number) => goodsList.find((item) => item.goodsid === id)!;
|
|
|
+ // 当前选中的商品合约
|
|
|
+ const selectedGoods = ref<GoodsQuote>(getGoods(props.selectedRow.goodsid));
|
|
|
|
|
|
- const { visible, cancel } = _closeModal(context);
|
|
|
- const { rules, formData, accountList, allPositionList, getPositionList } = handleForm(selectedGoods.value);
|
|
|
- const formRef = ref();
|
|
|
- const loading = ref<boolean>(false);
|
|
|
+ const { visible, cancel } = _closeModal(context);
|
|
|
+ const { rules, formData, accountList, allPositionList, getPositionList } = handleForm(selectedGoods.value);
|
|
|
+ const formRef = ref();
|
|
|
+ const loading = ref<boolean>(false);
|
|
|
|
|
|
- // 表格选中的 rowKey 数据 :rowKey="(record,index)=>index"
|
|
|
- const selectedRowKeys = ref<number[]>([]);
|
|
|
- // 当前选择的持仓单据
|
|
|
- const selectedPosition = ref<QueryErmcpTradePositionRsp>();
|
|
|
- // 选择持仓
|
|
|
- const onSelectChange = (keys: number[], record: QueryErmcpTradePositionRsp[]) => {
|
|
|
- selectedRowKeys.value = keys;
|
|
|
- selectedPosition.value = record[0];
|
|
|
- const { enableqty, positionaverageprice } = record[0];
|
|
|
- // 更新价格和数量
|
|
|
- formData.OrderPrice = positionaverageprice;
|
|
|
- formData.OrderQty = enableqty;
|
|
|
- };
|
|
|
+ // 表格选中的 rowKey 数据 :rowKey="(record,index)=>index"
|
|
|
+ const selectedRowKeys = ref<number[]>([]);
|
|
|
+ // 当前选择的持仓单据
|
|
|
+ const selectedPosition = ref<QueryErmcpTradePositionRsp>();
|
|
|
+ // 选择持仓
|
|
|
+ const onSelectChange = (keys: number[], record: QueryErmcpTradePositionRsp[]) => {
|
|
|
+ selectedRowKeys.value = keys;
|
|
|
+ selectedPosition.value = record[0];
|
|
|
+ const { enableqty, positionaverageprice } = record[0];
|
|
|
+ // 更新价格和数量
|
|
|
+ formData.OrderPrice = positionaverageprice;
|
|
|
+ formData.OrderQty = enableqty;
|
|
|
+ };
|
|
|
|
|
|
- // 持仓列表
|
|
|
- const positionList = computed(() => allPositionList.value.filter((item) => item.goodsid === selectedGoods.value.goodsid));
|
|
|
- // 选中的价格类型
|
|
|
- const selectedPriceType = ref(1);
|
|
|
- // 价格类型列表
|
|
|
- const priceTypeList = [
|
|
|
- // {
|
|
|
- // priceType: 0,
|
|
|
- // priceName: '最新价',
|
|
|
- // },
|
|
|
- {
|
|
|
- priceType: 1,
|
|
|
- priceName: '市价',
|
|
|
- },
|
|
|
- // {
|
|
|
- // priceType: 2,
|
|
|
- // priceName: '对手价',
|
|
|
- // },
|
|
|
- {
|
|
|
- priceType: 3,
|
|
|
- priceName: '限价',
|
|
|
- },
|
|
|
- // {
|
|
|
- // priceType: 4,
|
|
|
- // priceName: '超价',
|
|
|
- // },
|
|
|
- ];
|
|
|
+ // 持仓列表
|
|
|
+ const positionList = computed(() => {
|
|
|
+ const result = allPositionList.value.filter((item) => item.goodsid === selectedGoods.value.goodsid);
|
|
|
+ const { goodscode, goodsid, buyorsell } = props.selectedRow;
|
|
|
+ // 查找选中的持仓单据
|
|
|
+ const index = result.findIndex((item) => item.goodscode === goodscode && item.goodsid === goodsid && item.buyorsell === buyorsell);
|
|
|
+ if (index > -1) {
|
|
|
+ onSelectChange([index], [result[index]])
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ });
|
|
|
+ // 选中的价格类型
|
|
|
+ const selectedPriceType = ref(1);
|
|
|
+ // 价格类型列表
|
|
|
+ const priceTypeList = [
|
|
|
+ // {
|
|
|
+ // priceType: 0,
|
|
|
+ // priceName: '最新价',
|
|
|
+ // },
|
|
|
+ {
|
|
|
+ priceType: 1,
|
|
|
+ priceName: '市价',
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // priceType: 2,
|
|
|
+ // priceName: '对手价',
|
|
|
+ // },
|
|
|
+ {
|
|
|
+ priceType: 3,
|
|
|
+ priceName: '限价',
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // priceType: 4,
|
|
|
+ // priceName: '超价',
|
|
|
+ // },
|
|
|
+ ];
|
|
|
|
|
|
- // 买价
|
|
|
- const buyPrice = computed(() => getPrice(BuyOrSell.buy));
|
|
|
- // 卖价
|
|
|
- const sellPrice = computed(() => getPrice(BuyOrSell.sell));
|
|
|
- // 根据买卖方向返回价格
|
|
|
- function getPrice(direction: BuyOrSell): number {
|
|
|
- const { last, bid, ask, decimalplace, quoteminunit } = selectedGoods.value;
|
|
|
- switch (selectedPriceType.value) {
|
|
|
- // 最新价
|
|
|
- case 0: {
|
|
|
- return last;
|
|
|
- }
|
|
|
- // 市价
|
|
|
- case 1: {
|
|
|
- return direction === BuyOrSell.buy ? bid : ask;
|
|
|
- }
|
|
|
- // 对手价
|
|
|
- case 2: {
|
|
|
- return direction === BuyOrSell.buy ? ask : bid;
|
|
|
- }
|
|
|
- // 限价
|
|
|
- case 3: {
|
|
|
- return formData.OrderPrice;
|
|
|
- }
|
|
|
- // 超价
|
|
|
- case 4: {
|
|
|
- if (ask && bid) {
|
|
|
- // 系统参数
|
|
|
- const paramValue = APP.get('systemParams').find((el: Systemparam) => el.paramcode === '148')?.paramvalue ?? '0';
|
|
|
- // 点数
|
|
|
- const point = decimalplace > 0 ? -decimalplace * quoteminunit * Number(paramValue) : 1;
|
|
|
- const num = Math.pow(10, point);
|
|
|
- return direction === BuyOrSell.buy ? ask + num : bid - num;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
- default: {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ // 买价
|
|
|
+ const buyPrice = computed(() => getPrice(BuyOrSell.buy));
|
|
|
+ // 卖价
|
|
|
+ const sellPrice = computed(() => getPrice(BuyOrSell.sell));
|
|
|
+ // 根据买卖方向返回价格
|
|
|
+ function getPrice(direction: BuyOrSell): number {
|
|
|
+ const { last, bid, ask, decimalplace, quoteminunit } = selectedGoods.value;
|
|
|
+ switch (selectedPriceType.value) {
|
|
|
+ // 最新价
|
|
|
+ case 0: {
|
|
|
+ return last;
|
|
|
}
|
|
|
-
|
|
|
- // 搜索商品合约
|
|
|
- function filterOption(input: string, option: any) {
|
|
|
- return option.children[0].children.includes(input);
|
|
|
+ // 市价
|
|
|
+ case 1: {
|
|
|
+ return direction === BuyOrSell.buy ? bid : ask;
|
|
|
}
|
|
|
-
|
|
|
- // 选择商品合约
|
|
|
- function goodsChange(id: number) {
|
|
|
- formData.OrderPrice = 0;
|
|
|
- formData.OrderQty = 1;
|
|
|
- selectedRowKeys.value = [];
|
|
|
- selectedGoods.value = getGoods(id);
|
|
|
+ // 对手价
|
|
|
+ case 2: {
|
|
|
+ return direction === BuyOrSell.buy ? ask : bid;
|
|
|
}
|
|
|
-
|
|
|
- // 选择价格类型
|
|
|
- function priceTypeChange(priceType: number) {
|
|
|
- // 除了市价,其它价格类型都属于限价
|
|
|
- if (priceType === 1) {
|
|
|
- formData.PriceMode = PriceType.market;
|
|
|
- } else {
|
|
|
- formData.PriceMode = PriceType.limit;
|
|
|
- }
|
|
|
+ // 限价
|
|
|
+ case 3: {
|
|
|
+ return formData.OrderPrice;
|
|
|
}
|
|
|
-
|
|
|
- // 减少交易数量
|
|
|
- function minusQty() {
|
|
|
- if (formData.OrderQty > 1) {
|
|
|
- formData.OrderQty--;
|
|
|
- }
|
|
|
+ // 超价
|
|
|
+ case 4: {
|
|
|
+ if (ask && bid) {
|
|
|
+ // 系统参数
|
|
|
+ const paramValue = APP.get('systemParams').find((el: Systemparam) => el.paramcode === '148')?.paramvalue ?? '0';
|
|
|
+ // 点数
|
|
|
+ const point = decimalplace > 0 ? -decimalplace * quoteminunit * Number(paramValue) : 1;
|
|
|
+ const num = Math.pow(10, point);
|
|
|
+ return direction === BuyOrSell.buy ? ask + num : bid - num;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
}
|
|
|
-
|
|
|
- // 增加交易数量
|
|
|
- function plusQty() {
|
|
|
- formData.OrderQty++;
|
|
|
+ default: {
|
|
|
+ return 0;
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- function submit(submitType: 'buy' | 'sell' | 'close') {
|
|
|
- let successMsg = '成功';
|
|
|
- let failMsg = '失败';
|
|
|
+ // 搜索商品合约
|
|
|
+ function filterOption(input: string, option: any) {
|
|
|
+ return option.children[0].children.includes(input);
|
|
|
+ }
|
|
|
|
|
|
- const { saleuserid, spotcontractid, bizsubjectid } = props.selectedRow;
|
|
|
- // 判断是否套保交易
|
|
|
- if (isHedging) {
|
|
|
- formData.HedgeFlag = 4;
|
|
|
- formData.SaleUserID = saleuserid;
|
|
|
- formData.SpotContractID = Number(spotcontractid);
|
|
|
- formData.BizSubjectID = bizsubjectid;
|
|
|
- }
|
|
|
+ // 选择商品合约
|
|
|
+ function goodsChange(id: number) {
|
|
|
+ formData.OrderPrice = 0;
|
|
|
+ formData.OrderQty = 1;
|
|
|
+ selectedRowKeys.value = [];
|
|
|
+ selectedPosition.value = undefined;
|
|
|
+ selectedGoods.value = getGoods(id);
|
|
|
+ }
|
|
|
|
|
|
- // 按钮提交类型
|
|
|
- switch (submitType) {
|
|
|
- case 'buy': {
|
|
|
- successMsg = '买入成功';
|
|
|
- failMsg = '买入失败';
|
|
|
- formData.BuyOrSell = BuyOrSell.buy;
|
|
|
- formData.ChannelBuildType = BuildType.open;
|
|
|
- formData.OrderPrice = buyPrice.value;
|
|
|
- break;
|
|
|
- }
|
|
|
- case 'sell': {
|
|
|
- successMsg = '卖出成功';
|
|
|
- failMsg = '卖出失败';
|
|
|
- formData.BuyOrSell = BuyOrSell.sell;
|
|
|
- formData.ChannelBuildType = BuildType.open;
|
|
|
- formData.OrderPrice = sellPrice.value;
|
|
|
- break;
|
|
|
- }
|
|
|
- case 'close': {
|
|
|
- successMsg = '平仓成功';
|
|
|
- failMsg = '平仓失败';
|
|
|
+ // 选择价格类型
|
|
|
+ function priceTypeChange(priceType: number) {
|
|
|
+ // 除了市价,其它价格类型都属于限价
|
|
|
+ if (priceType === 1) {
|
|
|
+ formData.PriceMode = PriceType.market;
|
|
|
+ } else {
|
|
|
+ formData.PriceMode = PriceType.limit;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (!selectedPosition.value) {
|
|
|
- message.error('请选择需要平仓的单据');
|
|
|
- return;
|
|
|
- }
|
|
|
+ // 减少交易数量
|
|
|
+ function minusQty() {
|
|
|
+ if (formData.OrderQty > 1) {
|
|
|
+ formData.OrderQty--;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 选中的单据数据
|
|
|
- const { curpositionqty, curtdpositionenabled, buyorsell } = selectedPosition.value;
|
|
|
+ // 增加交易数量
|
|
|
+ function plusQty() {
|
|
|
+ formData.OrderQty++;
|
|
|
+ }
|
|
|
|
|
|
- // 判断平仓数量
|
|
|
- if (formData.OrderQty > curpositionqty) {
|
|
|
- message.error('交易数量不能大于持仓可用数量');
|
|
|
- return;
|
|
|
- }
|
|
|
+ function submit(submitType: 'buy' | 'sell' | 'close') {
|
|
|
+ let successMsg = '成功';
|
|
|
+ let failMsg = '失败';
|
|
|
|
|
|
- formData.BuyOrSell = buyorsell === BuyOrSell.buy ? BuyOrSell.sell : BuyOrSell.buy; // 根据持仓方向选择平仓方向
|
|
|
- formData.OrderPrice = buyorsell === BuyOrSell.buy ? sellPrice.value : buyPrice.value; // 根据持仓方向选择平仓价格
|
|
|
- formData.ChannelBuildType = BuildType.close;
|
|
|
+ const { saleuserid, spotcontractid, bizsubjectid } = props.selectedRow;
|
|
|
+ // 判断是否套保交易
|
|
|
+ if (isHedging) {
|
|
|
+ formData.HedgeFlag = 4;
|
|
|
+ formData.SaleUserID = saleuserid;
|
|
|
+ formData.SpotContractID = spotcontractid;
|
|
|
+ formData.BizSubjectID = bizsubjectid;
|
|
|
+ }
|
|
|
|
|
|
- const account = accountList.find((el) => el.accountid === formData.AccountID)!;
|
|
|
- // 判断是否母账号
|
|
|
- if (account.ismain) {
|
|
|
- if (selectedGoods.value.outerdealmode === 3 && curtdpositionenabled > 0) {
|
|
|
- formData.CloseTodayQty = curtdpositionenabled;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
+ // 按钮提交类型
|
|
|
+ switch (submitType) {
|
|
|
+ case 'buy': {
|
|
|
+ successMsg = '买入成功';
|
|
|
+ failMsg = '买入失败';
|
|
|
+ formData.BuyOrSell = BuyOrSell.buy;
|
|
|
+ formData.ChannelBuildType = BuildType.open;
|
|
|
+ formData.OrderPrice = buyPrice.value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 'sell': {
|
|
|
+ successMsg = '卖出成功';
|
|
|
+ failMsg = '卖出失败';
|
|
|
+ formData.BuyOrSell = BuyOrSell.sell;
|
|
|
+ formData.ChannelBuildType = BuildType.open;
|
|
|
+ formData.OrderPrice = sellPrice.value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 'close': {
|
|
|
+ successMsg = '平仓成功';
|
|
|
+ failMsg = '平仓失败';
|
|
|
+
|
|
|
+ if (!selectedPosition.value) {
|
|
|
+ message.error('请选择需要平仓的单据');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 选中的单据数据
|
|
|
+ const { curpositionqty, curtdpositionenabled, buyorsell } = selectedPosition.value;
|
|
|
+
|
|
|
+ // 判断平仓数量
|
|
|
+ if (formData.OrderQty > curpositionqty) {
|
|
|
+ message.error('交易数量不能大于持仓可用数量');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ formData.BuyOrSell = buyorsell === BuyOrSell.buy ? BuyOrSell.sell : BuyOrSell.buy; // 根据持仓方向选择平仓方向
|
|
|
+ formData.OrderPrice = buyorsell === BuyOrSell.buy ? sellPrice.value : buyPrice.value; // 根据持仓方向选择平仓价格
|
|
|
+ formData.ChannelBuildType = BuildType.close;
|
|
|
+
|
|
|
+ const account = accountList.find((el) => el.accountid === formData.AccountID)!;
|
|
|
+ // 判断是否母账号
|
|
|
+ if (account.ismain) {
|
|
|
+ if (selectedGoods.value.outerdealmode === 3 && curtdpositionenabled > 0) {
|
|
|
+ formData.CloseTodayQty = curtdpositionenabled;
|
|
|
}
|
|
|
- // 表单验证
|
|
|
- validateAction(formRef, formData).then((res) => {
|
|
|
- requestResultLoadingAndInfo(channelOrderReq, res, loading, [successMsg, failMsg]).then(() => {
|
|
|
- cancel(true);
|
|
|
- });
|
|
|
- });
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
- return {
|
|
|
- submit,
|
|
|
- cancel,
|
|
|
- loading,
|
|
|
- visible,
|
|
|
- accountList,
|
|
|
- positionList,
|
|
|
- rules,
|
|
|
- formRef,
|
|
|
- formData,
|
|
|
- isHedging,
|
|
|
- goodsList,
|
|
|
- buyPrice,
|
|
|
- sellPrice,
|
|
|
- selectedGoods,
|
|
|
- getPositionList,
|
|
|
- goodsChange,
|
|
|
- selectedRowKeys,
|
|
|
- selectedPosition,
|
|
|
- priceTypeList,
|
|
|
- PriceType,
|
|
|
- selectedPriceType,
|
|
|
- filterOption,
|
|
|
- priceTypeChange,
|
|
|
- getColumns,
|
|
|
- onSelectChange,
|
|
|
- minusQty,
|
|
|
- plusQty,
|
|
|
- BuyOrSell,
|
|
|
- };
|
|
|
- },
|
|
|
+ }
|
|
|
+ // 表单验证
|
|
|
+ validateAction(formRef, formData).then((res) => {
|
|
|
+ requestResultLoadingAndInfo(channelOrderReq, res, loading, [successMsg, failMsg]).then(() => {
|
|
|
+ cancel(true);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ submit,
|
|
|
+ cancel,
|
|
|
+ loading,
|
|
|
+ visible,
|
|
|
+ accountList,
|
|
|
+ positionList,
|
|
|
+ rules,
|
|
|
+ formRef,
|
|
|
+ formData,
|
|
|
+ isHedging,
|
|
|
+ goodsList,
|
|
|
+ buyPrice,
|
|
|
+ sellPrice,
|
|
|
+ selectedGoods,
|
|
|
+ getPositionList,
|
|
|
+ goodsChange,
|
|
|
+ selectedRowKeys,
|
|
|
+ selectedPosition,
|
|
|
+ priceTypeList,
|
|
|
+ PriceType,
|
|
|
+ selectedPriceType,
|
|
|
+ filterOption,
|
|
|
+ priceTypeChange,
|
|
|
+ getColumns,
|
|
|
+ onSelectChange,
|
|
|
+ minusQty,
|
|
|
+ plusQty,
|
|
|
+ BuyOrSell,
|
|
|
+ };
|
|
|
+ },
|
|
|
});
|
|
|
</script>
|
|
|
|