|
|
@@ -1,87 +1,139 @@
|
|
|
<template>
|
|
|
- <app-popup class="goods-listing" :title="'挂牌'" v-model:show="showModal" :refresh="refresh">
|
|
|
- <Form class="goods-listing__form" ref="formRef" @submit="onSubmit">
|
|
|
- <Tabs class="van-tabs--list" v-model:active="formData.BuyOrSell" :swipe-threshold="2" @change="onTabChange">
|
|
|
- <Tab title="挂牌买入" :name="BuyOrSell.Buy" />
|
|
|
- <Tab title="挂牌卖出" :name="BuyOrSell.Sell" />
|
|
|
- </Tabs>
|
|
|
- <Field label="交易账户">
|
|
|
- <template #input>
|
|
|
- <span>{{ accountStore.accountId }}</span>
|
|
|
- </template>
|
|
|
- </Field>
|
|
|
- <Field label="订单商品" v-if="quote">
|
|
|
- <template #input>
|
|
|
- <span>{{ quote.goodscode }}/{{ quote.goodsname }}</span>
|
|
|
- </template>
|
|
|
- </Field>
|
|
|
- <Field label="挂牌类型">
|
|
|
- <template #input>
|
|
|
- <RadioGroup v-model="buildType" direction='horizontal'>
|
|
|
- <Radio :name="1">订立</Radio>
|
|
|
- <Radio :name="2">转让</Radio>
|
|
|
- </RadioGroup>
|
|
|
- </template>
|
|
|
- </Field>
|
|
|
- <Field name="OrderPrice" :rules="formRules.OrderPrice" label="价格">
|
|
|
- <template #input>
|
|
|
- <Stepper v-model="formData.OrderPrice" input-width="100" theme="round" button-size="22"
|
|
|
- :auto-fixed="false" :decimal-length="quote?.decimalplace" />
|
|
|
- </template>
|
|
|
- </Field>
|
|
|
- <Field name="OrderQty" :rules="formRules.OrderQty" label="数量">
|
|
|
- <template #input>
|
|
|
- <Stepper v-model="formData.OrderQty" input-width="100" theme="round" button-size="22"
|
|
|
- :auto-fixed="false" integer />
|
|
|
- </template>
|
|
|
- </Field>
|
|
|
- </Form>
|
|
|
- <template #footer>
|
|
|
- <Button type="primary" block round @click="formRef?.submit">确定</Button>
|
|
|
- </template>
|
|
|
- </app-popup>
|
|
|
+ <app-modal direction="right" height="100%" v-model:show="showModal" :refresh="refresh">
|
|
|
+ <app-view class="g-form">
|
|
|
+ <template #header>
|
|
|
+ <app-navbar title="挂牌" @back="closed" />
|
|
|
+ </template>
|
|
|
+ <component :is="Price" v-bind="{ goodsCode }" />
|
|
|
+ <component :is="Forex" v-bind="{ goodsCode, showMore: false }" />
|
|
|
+ <Form ref="formRef" class="g-form__container" @submit="onSubmit">
|
|
|
+ <CellGroup inset>
|
|
|
+ <Field name="OrderPrice" :rules="formRules.OrderPrice" label="价格">
|
|
|
+ <template #input>
|
|
|
+ <Stepper v-model="formData.OrderPrice" input-width="100" theme="round" button-size="22"
|
|
|
+ :auto-fixed="false" :decimal-length="quote?.decimalplace" :step="priceStep" />
|
|
|
+ </template>
|
|
|
+ </Field>
|
|
|
+ <Field name="OrderQty" :rules="formRules.OrderQty"
|
|
|
+ :label="`数量(${getGoodsUnitName(quote?.goodunitid)})`">
|
|
|
+ <template #input>
|
|
|
+ <div>
|
|
|
+ <Stepper v-model="orderQty" input-width="100" theme="round" button-size="22"
|
|
|
+ :auto-fixed="false" :step="qtyStep" integer />
|
|
|
+ <RadioGroup v-model="qtyStep" direction="horizontal">
|
|
|
+ <Radio v-for="(value, index) in qtyStepList" :key="index" :name="value">{{ value }}
|
|
|
+ </Radio>
|
|
|
+ </RadioGroup>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </Field>
|
|
|
+ </CellGroup>
|
|
|
+ </Form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="g-form__footer">
|
|
|
+ <template v-if="buildType === EBuildType.BUILDTYPE_OPEN">
|
|
|
+ <Button type="primary" block round @click="onBeforeSubmit(BuyOrSell.Buy)">订立买入</Button>
|
|
|
+ <Button type="primary" block round @click="onBeforeSubmit(BuyOrSell.Sell)">订立卖出</Button>
|
|
|
+ </template>
|
|
|
+ <template v-if="buildType === EBuildType.BUILDTYPE_CLOSE">
|
|
|
+ <Button type="primary" block round @click="onBeforeSubmit(BuyOrSell.Buy)">转让买入</Button>
|
|
|
+ <Button type="primary" block round @click="onBeforeSubmit(BuyOrSell.Sell)">转让卖出</Button>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </app-view>
|
|
|
+ </app-modal>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { shallowRef, onMounted } from 'vue'
|
|
|
-import { Form, FormInstance, Button, FieldRule, Field, Tab, Tabs, Stepper, Radio, RadioGroup } from 'vant'
|
|
|
+import { shallowRef, defineAsyncComponent, onMounted, computed } from 'vue'
|
|
|
+import { Form, FormInstance, Button, CellGroup, FieldRule, Field, Stepper, RadioGroup, Radio } from 'vant'
|
|
|
+import { getGoodsUnitName } from '@/constants/unit'
|
|
|
import { BuyOrSell } from '@/constants/order'
|
|
|
import { useOrder } from '@/business/trade'
|
|
|
import { fullloading, dialog } from '@/utils/vant'
|
|
|
-import { useAccountStore, useFuturesStore } from '@/stores'
|
|
|
+import { useFuturesStore } from '@/stores'
|
|
|
import { EPriceMode, EListingSelectType, EDelistingType, EBuildType, EValidType, EOrderOperateType } from '@/constants/client'
|
|
|
-import AppPopup from '@mobile/components/base/popup/index.vue'
|
|
|
+import AppModal from '@/components/base/modal/index.vue'
|
|
|
+
|
|
|
+const Price = defineAsyncComponent(() => import('@mobile/components/modules/quote/price/index.vue'))
|
|
|
+const Forex = defineAsyncComponent(() => import('@mobile/components/modules/quote/forex/index.vue'))
|
|
|
|
|
|
const props = defineProps({
|
|
|
- goodsid: {
|
|
|
- type: Number,
|
|
|
+ goodsCode: {
|
|
|
+ type: String,
|
|
|
required: true
|
|
|
},
|
|
|
+ buildType: {
|
|
|
+ type: Number,
|
|
|
+ required: true
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
-const accountStore = useAccountStore()
|
|
|
+const { formData, formSubmit } = useOrder()
|
|
|
const futuresStore = useFuturesStore()
|
|
|
-const quote = futuresStore.getQuoteInfo(props.goodsid)
|
|
|
+const quote = futuresStore.getQuoteInfo(props.goodsCode)
|
|
|
const formRef = shallowRef<FormInstance>()
|
|
|
const showModal = shallowRef(true)
|
|
|
const refresh = shallowRef(true) // 是否刷新父组件数据
|
|
|
-/// 挂牌类型
|
|
|
-const buildType = shallowRef(EBuildType.BUILDTYPE_OPEN)
|
|
|
-const { formData, formSubmit } = useOrder()
|
|
|
+const orderQty = shallowRef(1) // 数量
|
|
|
+const qtyStep = shallowRef(1) // 数量步长
|
|
|
+
|
|
|
+// 价格步长
|
|
|
+const priceStep = computed(() => {
|
|
|
+ const { quoteminunit = 0, decimalplace = 0 } = quote.value ?? {}
|
|
|
+ if (quoteminunit) {
|
|
|
+ return quoteminunit / Math.pow(10, decimalplace * -1)
|
|
|
+ }
|
|
|
+ return 1
|
|
|
+})
|
|
|
+
|
|
|
+// 数量步长列表
|
|
|
+const qtyStepList = computed(() => {
|
|
|
+ const { agreeunit = 0 } = quote.value ?? {}
|
|
|
+ return [
|
|
|
+ agreeunit * 1,
|
|
|
+ agreeunit * 5,
|
|
|
+ agreeunit * 10,
|
|
|
+ agreeunit * 20,
|
|
|
+ agreeunit * 30,
|
|
|
+ agreeunit * 50,
|
|
|
+ ]
|
|
|
+})
|
|
|
+
|
|
|
+// 表单验证规则
|
|
|
+const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
|
|
|
+ OrderPrice: [{
|
|
|
+ message: '请输入价格',
|
|
|
+ validator: () => {
|
|
|
+ return !!formData.OrderPrice
|
|
|
+ }
|
|
|
+ }],
|
|
|
+ OrderQty: [{
|
|
|
+ validator: () => {
|
|
|
+ if (orderQty.value) {
|
|
|
+ const { agreeunit = 0 } = quote.value ?? {}
|
|
|
+ return orderQty.value % agreeunit === 0 ? true : '只能输入合约乘数的整数倍'
|
|
|
+ }
|
|
|
+ return '请输入数量'
|
|
|
+ }
|
|
|
+ }],
|
|
|
+}
|
|
|
|
|
|
// 提交挂牌
|
|
|
const onSubmit = () => {
|
|
|
- const { marketid = 0 } = quote.value ?? {}
|
|
|
+ const { marketid = 0, goodsid = 0, agreeunit = 0 } = quote.value ?? {}
|
|
|
/// 获取对应的市场ID
|
|
|
formData.MarketID = marketid
|
|
|
formData.PriceMode = EPriceMode.PRICEMODE_LIMIT
|
|
|
- formData.GoodsID = props.goodsid
|
|
|
+ formData.GoodsID = goodsid
|
|
|
formData.ListingSelectType = EListingSelectType.LISTINGSELECTTYPE_DELISTINGTHENLISTING
|
|
|
formData.DelistingType = EDelistingType.DELISTINGTYPE_PRICE
|
|
|
formData.BuildType = EBuildType.BUILDTYPE_OPEN
|
|
|
formData.ValidType = EValidType.VALIDTYPE_DR
|
|
|
formData.OperateType = EOrderOperateType.ORDEROPERATETYPE_NORMAL
|
|
|
- formData.BuildType = buildType.value
|
|
|
+ formData.BuildType = props.buildType
|
|
|
+ formData.OrderQty = orderQty.value / agreeunit // 数量÷合约乘数
|
|
|
|
|
|
fullloading((hideLoading) => {
|
|
|
formSubmit().then(() => {
|
|
|
@@ -93,34 +145,9 @@ const onSubmit = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 表单验证规则
|
|
|
-const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
|
|
|
- OrderPrice: [{
|
|
|
- message: '请输入价格',
|
|
|
- validator: () => {
|
|
|
- return !!formData.OrderPrice
|
|
|
- }
|
|
|
- }],
|
|
|
- OrderQty: [{
|
|
|
- message: '请输入挂牌数量',
|
|
|
- validator: () => {
|
|
|
- return !!formData.OrderQty
|
|
|
- }
|
|
|
- }],
|
|
|
-}
|
|
|
-
|
|
|
-const onTabChange = () => {
|
|
|
- const { ask = 0, bid = 0, presettle = 0 } = quote.value ?? {}
|
|
|
- switch (formData.BuyOrSell) {
|
|
|
- case BuyOrSell.Buy:
|
|
|
- formData.OrderPrice = ask || presettle
|
|
|
- break
|
|
|
- case BuyOrSell.Sell:
|
|
|
- formData.OrderPrice = bid || presettle
|
|
|
- break
|
|
|
- default:
|
|
|
- formData.OrderPrice = presettle
|
|
|
- }
|
|
|
+const onBeforeSubmit = (buyOrSell: BuyOrSell) => {
|
|
|
+ formData.BuyOrSell = buyOrSell
|
|
|
+ formRef.value?.submit()
|
|
|
}
|
|
|
|
|
|
// 关闭弹窗
|
|
|
@@ -130,8 +157,9 @@ const closed = (isRefresh = true) => {
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- formData.BuyOrSell = BuyOrSell.Buy
|
|
|
- onTabChange()
|
|
|
+ const { last = 0, agreeunit = 0 } = quote.value ?? {}
|
|
|
+ formData.OrderPrice = last
|
|
|
+ orderQty.value = agreeunit
|
|
|
})
|
|
|
|
|
|
// 暴露组件属性给父组件调用
|