Procházet zdrojové kódy

Merge branch 'v20' of http://192.168.31.240:3000/MTP2.0_New/MTP20_WEB_GLOBAL into v20

li.shaoyi před 1 rokem
rodič
revize
26a338e9a8
27 změnil soubory, kde provedl 1003 přidání a 465 odebrání
  1. 6 2
      public/locales/en-US.json
  2. 5 1
      public/locales/zh-CN.json
  3. 3 1
      src/constants/funcode.ts
  4. 3 3
      src/packages/mobile/router/section.ts
  5. 4 2
      src/packages/mobile/views/mine/setting/Index.vue
  6. 3 1
      src/packages/mobile/views/order/position/Index.vue
  7. 104 0
      src/packages/mobile/views/order/position/components/pricing/detail/Index.vue
  8. 168 0
      src/packages/mobile/views/order/position/components/pricing/detail/components/transfer/Index.vue
  9. 13 15
      src/packages/mobile/views/order/position/components/pricing/list/Index.vue
  10. 0 74
      src/packages/mobile/views/pricing/detail/Index.vue
  11. 0 340
      src/packages/mobile/views/pricing/detail/components/trade/Index.vue
  12. 1 1
      src/packages/mobile/views/pricing/list/Index.vue
  13. 380 0
      src/packages/mobile/views/pricing/trade/Index.vue
  14. 104 0
      src/packages/mobile/views/pricing/trade/components/cancel/Index.vue
  15. 38 0
      src/packages/mobile/views/pricing/trade/components/detail/Index.vue
  16. 0 0
      src/packages/mobile/views/pricing/trade/components/detail/index.less
  17. 84 0
      src/packages/mobile/views/pricing/trade/holdlb/Index.vue
  18. 31 0
      src/packages/mobile/views/pricing/trade/index.less
  19. 4 3
      src/packages/mobile/views/report/components/index.vue
  20. 7 2
      src/packages/pc/components/modules/goods-detail/chart/index.vue
  21. 6 6
      src/packages/pc/components/modules/goods-detail/order/index.vue
  22. 14 4
      src/packages/pc/components/modules/quote/forex/index.vue
  23. 6 1
      src/packages/pc/components/modules/quote/price/index.vue
  24. 8 8
      src/packages/pc/views/market/trade/pricing/list/listing/index.vue
  25. 1 0
      src/services/bus/types.ts
  26. 8 0
      src/services/websocket/message.ts
  27. 2 1
      src/types/model/order.d.ts

+ 6 - 2
public/locales/en-US.json

@@ -103,7 +103,7 @@
         "goodsname": "Name/Code",
         "refgoodsname": "RefGoodsName",
         "averageprice": "Average",
-        "last": "last",
+        "last": "Last",
         "rise": "Up Down",
         "change": "Change",
         "opened": "Opened",
@@ -258,7 +258,8 @@
             "deposit": "Deposit",
             "avaiableMoney": "Avaiable Funds",
             "tips1": "Please enter the order qty",
-            "tips2": "Please enter the order price"
+            "tips2": "Please enter the order price",
+            "tips3": "Please enter the market maxsub"
         },
         "spot": {
             "title": "Listing Detail",
@@ -538,6 +539,7 @@
             "matchname": "MatchName",
             "deliverylot": "DeliveryLot",
             "deliveryqty": "DeliveryQty",
+            "freezeqty": "FreezeQty",
             "address": "Address",
             "transferprice": "Price",
             "qty": "Qty",
@@ -1162,6 +1164,8 @@
         "accountinfo": "AccountInformation",
         "reckondate": "ReckonDate",
         "reportdetail": "ReportDetail",
+        "day": "DayReport",
+        "month": "MonthReport",
         "trade": {
             "tradeqty": "TradeQty",
             "tradeprice": "TradePrice",

+ 5 - 1
public/locales/zh-CN.json

@@ -259,7 +259,8 @@
             "deposit": "预扣保证金",
             "avaiableMoney": "可用资金",
             "tips1": "请输入数量",
-            "tips2": "请输入价格"
+            "tips2": "请输入价格",
+            "tips3": "请输入点差"
         },
         "spot": {
             "title": "挂牌详情",
@@ -546,6 +547,7 @@
             "tradetime": "交易时间",
             "holderprice": "持仓价格",
             "deliveryinfo": "交收信息",
+            "freezeqty": "冻结量",
             "tips1": "请输入转让价格",
             "tips2": "请输入转让量",
             "tips3": "确认要转让吗?",
@@ -1165,6 +1167,8 @@
         "accountinfo": "账户信息",
         "reckondate": "结算日期",
         "reportdetail": "报表明细",
+        "day": "日报表",
+        "month": "月报表",
         "trade": {
             "tradeqty": "数量",
             "tradeprice": "价格",

+ 3 - 1
src/constants/funcode.ts

@@ -56,7 +56,9 @@ export enum FunCode {
     PosChangedNtf = 131075, // 头寸变化通知
     RiskControlNtf = 131086, // 风控通知
     RiskToWebNtf = 131139, // 风控消息管理端通知客户端
-
+    OrderSuccessedNtf = 131152, /// 委托单委托成功通知(0, 2, 80)
+    OrderCanceledNtf = 131084, /// 委托单撤单通知(0, 2, 12)
+    
     // 行情内容
     QuoteBeat = 0x12, // 心跳
     QuoteSubscribeReq = 0x20, // 实时行情订阅请求

+ 3 - 3
src/packages/mobile/router/section.ts

@@ -58,9 +58,9 @@ const pageRoutes: RouteRecordRaw[] = [
                 }
             },
             {
-                path: 'detail',
-                name: 'pricing-detail',
-                component: () => import('@mobile/views/pricing/detail/Index.vue'),
+                path: 'trade',
+                name: 'pricing-trade',
+                component: () => import('@mobile/views/pricing/trade/Index.vue'),
             }
         ]
     },

+ 4 - 2
src/packages/mobile/views/mine/setting/Index.vue

@@ -33,6 +33,7 @@ import { Cell, CellGroup } from 'vant'
 import AppIconfont from '@/components/base/iconfont/index.vue'
 import { i18n } from '@/stores'
 import { Locale } from 'vant'
+import { localData } from '@/stores/storage'
 import enUS from 'vant/es/locale/lang/en-US'
 
 defineProps({
@@ -49,10 +50,11 @@ defineProps({
 const changeLuanguage = () => {
     if (i18n.global.locale === 'zh-CN') {
         i18n.global.locale = 'en-US'
-        Locale.use('en-US', enUS)
     } else {
         i18n.global.locale = 'zh-CN'
-        Locale.use('zh-CN', enUS)
     }
+    Locale.use(i18n.global.locale, enUS)
+    /// 设置语言
+    localData.setValue('appLanguage', i18n.global.locale)
 }
 </script>

+ 3 - 1
src/packages/mobile/views/order/position/Index.vue

@@ -12,7 +12,7 @@
         <Tabs class="van-tabs--list" v-model:active="active" :swipe-threshold="4">
             <template v-for="(item, index) in components" :key="index">
                 <Tab :title="item.title" :name="index">
-                    <component :is="item.component" />
+                    <component :is="item.component" v-bind="{ fromTrade }" />
                 </Tab>
             </template>
         </Tabs>
@@ -28,6 +28,7 @@ import { useComponent } from '@/hooks/component'
 import { i18n } from '@/stores'
 
 const { global: { t } } = i18n
+const fromTrade = false
 
 const components = [
     {
@@ -60,6 +61,7 @@ const components = [
         name: 'pricing',
         title: t('position.pricing.title'),
         component: defineAsyncComponent(() => import('./components/pricing/list/Index.vue')),
+        detail: defineAsyncComponent(() => import('./components/pricing/detail/Index.vue')),
     },
 ]
 

+ 104 - 0
src/packages/mobile/views/order/position/components/pricing/detail/Index.vue

@@ -0,0 +1,104 @@
+<!-- 我的持仓-订单明细 -->
+<template>
+    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal">
+        <app-view class="g-form">
+            <template #header>
+                <app-navbar :title="$t('position.goods.holddetail.title')" @back="closed" />
+            </template>
+            <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" @refresh="run">
+                <div class="g-order-list">
+                    <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+                        <div class="g-order-list__titlebar">
+                            <div class="left">
+                                <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
+                            </div>
+                        </div>
+                        <div class="g-order-list__content">
+                            <ul>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.tradetime') }}</span>
+                                    <span>{{ formatDate(item.tradetime, 'HH:mm:ss') }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.buyorsell') }}</span>
+                                    <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">
+                                        {{ getBuyOrSellName(item.buyorsell) }}
+                                    </span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderqty') }}</span>
+                                    <span>{{ item.holderqty }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.freezeqty') }}</span>
+                                    <span>{{ item.freezeqty }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderprice') }}</span>
+                                    <span>{{ item.holderprice }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderamount') }}</span>
+                                    <span>{{ formatDecimal(item.holderamount) }}</span>
+                                </li>
+                            </ul>
+                        </div>
+                        <div class="g-order-list__btnbar" v-if="item.trademode === 10 && item.holderqty">
+                            <Button size="small" @click="showComponent('close', item)" round>{{ $t('operation.close') }}</Button>
+                        </div>
+                    </div>
+                </div>
+            </app-pull-refresh>
+            <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)"
+                @closed="closeComponent" v-if="componentId" />
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, defineAsyncComponent } from 'vue'
+import { Button } from 'vant'
+import { useRequest } from '@/hooks/request'
+import { useComponent } from '@/hooks/component'
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, formatDate } from '@/filters'
+import { queryTradeHolderDetail } from '@/services/api/order'
+import AppModal from '@/components/base/modal/index.vue'
+import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
+
+const error = shallowRef(false)
+const showModal = shallowRef(true)
+const refresh = shallowRef(false) // 是否刷新父组件数据
+
+const componentMap = new Map<string, unknown>([
+    ['close', defineAsyncComponent(() => import('./components/transfer/Index.vue'))],
+])
+
+const { dataList, loading, run } = useRequest(queryTradeHolderDetail, {
+    params: {
+        trademodes: '10'
+    }
+})
+const selectedRow = shallowRef<Model.TradeHolderDetailRsp>()
+const pullRefreshRef = shallowRef()
+
+const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
+    pullRefreshRef.value?.refresh()
+})
+
+const showComponent = (componentName: string, row: Model.TradeHolderDetailRsp) => {
+    selectedRow.value = row
+    openComponent(componentName)
+}
+
+// 关闭弹窗
+const closed = (isRefresh = false) => {
+    refresh.value = isRefresh
+    showModal.value = false
+}
+
+// 暴露组件属性给父组件调用
+defineExpose({
+    closed,
+})
+</script>

+ 168 - 0
src/packages/mobile/views/order/position/components/pricing/detail/components/transfer/Index.vue

@@ -0,0 +1,168 @@
+<!-- 我的持仓- 明细 - 转让 -->
+<template>
+    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
+        <app-view class="g-form">
+            <template #header>
+                <app-navbar :title="$t('operation.close')" @back="closed" />
+            </template>
+            <Form ref="formRef" class="g-form__container" @submit="onCloseSumit">
+                <CellGroup :title="$t('position.goods.subtitle')" inset>
+                    <Cell :title="$t('position.goods.goodsname')" :value="`${selectedRow.goodscode}/${selectedRow.goodsname}`" />
+                    <Cell :title="$t('position.goods.buyorsell')" :value="getBuyOrSellName(selectedRow.buyorsell)" />
+                    <Cell :title="$t('position.goods.holderprice')" :value="selectedRow.holderprice" />
+                    <Cell :title="$t('position.goods.curholderamount')" :value="formatDecimal(selectedRow.holderamount)" />
+                    <Cell :title="$t('position.goods.curpositionqty')" :value="selectedRow.holderqty" />
+                    <Cell :title="$t('position.goods.freezeqty')" :value="selectedRow.freezeqty" />
+                    <Cell :title="$t('position.goods.enableqty')" :value="maxQty" />
+                    <Cell :title="$t('position.goods.closepl')">
+                        <template #value>
+                            <span :class="handlePriceColor(closepl)">
+                                {{ formatDecimal(closepl, selectedRow.decimalplace) }}
+                            </span>
+                        </template>
+                    </Cell>
+                    <Cell :title="$t('position.goods.tradetime')" :value="selectedRow.tradetime" />
+                </CellGroup>
+                <CellGroup :title="$t('position.goods.subtitle3')" inset>
+                    <Cell :title="$t('position.goods.last')" :value="handleNumberValue(quote?.last)" />
+                    <Field name="OrderPrice" :rules="formRules.OrderPrice" :label="$t('position.goods.transferprice')">
+                        <template #input>
+                            <Stepper v-model="formData.OrderPrice" theme="round" button-size="22" :min="0"
+                                :decimal-length="quote?.decimalplace" :step="quote?.decimalvalue" :auto-fixed="false" />
+                        </template>
+                    </Field>
+                    <Field name="OrderQty" :rules="formRules.OrderQty" :label="$t('position.goods.orderqty')">
+                        <template #input>
+                            <Stepper v-model="formData.OrderQty" theme="round" button-size="22" :min="0" :max="maxQty"
+                                :auto-fixed="false" integer />
+                        </template>
+                    </Field>
+                </CellGroup>
+            </Form>
+            <template #footer>
+                <Button block square type="danger" @click="formRef?.submit">{{ $t('operation.close') }}</Button>
+            </template>
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, PropType, onMounted, computed } from 'vue'
+import AppModal from '@/components/base/modal/index.vue'
+import { CellGroup, Cell, Button, FieldRule, Form, Field, Stepper, FormInstance } from 'vant'
+import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
+import { formatDecimal, handleNumberValue, handleRequestBigNumber, handlePriceColor } from '@/filters'
+import { useOrder } from '@/business/trade'
+import { dialog, fullloading } from '@/utils/vant'
+import { useFuturesStore, usePositionStore, i18n } from '@/stores'
+import { EBuildType, EDelistingType, EListingSelectType, EPriceMode, EValidType } from '@/constants/client'
+
+const props = defineProps({
+    selectedRow: {
+        type: Object as PropType<Model.TradeHolderDetailRsp>,
+        required: true,
+    }
+})
+
+const futuresStore = useFuturesStore()
+const positionStore = usePositionStore()
+const quote = futuresStore.getGoodsQuote(props.selectedRow.goodscode)
+const { global: { t } } = i18n
+// 可用数量
+const maxQty = computed(() => {
+    const record = positionStore.positionList.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === props.selectedRow.buyorsell)
+    const qty = props.selectedRow.holderqty - props.selectedRow.freezeqty
+    return Math.min(record?.enableqty ?? 0, qty)
+})
+
+// 损益
+const closepl = computed(() => {
+    const { presettle = 0, last = 0 } = quote.value ?? {}
+    const { holderqty, holderamount, agreeunit, buyorsell } = props.selectedRow
+    const price = last || presettle // 没有最新价取昨结价
+    // 计算市值 = 现价 * 数量 * 合约单位
+    const marketValue = price ? price * holderqty * agreeunit : 0
+
+    return price ? (marketValue - holderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1) : 0
+})
+
+const formRef = shallowRef<FormInstance>()
+const showModal = shallowRef(true)
+// 是否刷新父组件数据
+const refresh = shallowRef(false)
+const { formSubmit, formData } = useOrder()
+
+// 表单验证规则
+const formRules: { [key: string]: FieldRule[] } = {
+    OrderPrice: [{
+        message: t('position.goods.tips1'),
+        validator: () => {
+            return !!formData.OrderPrice
+        }
+    }],
+    OrderQty: [{
+        message: t('position.goods.tips2'),
+        validator: () => {
+            return !!formData.OrderQty
+        }
+    }],
+}
+
+const onCloseSumit = () => {
+    dialog({
+        message: t('position.goods.tips3'),
+        showCancelButton: true,
+    }).then(() => {
+
+        const { marketid, goodsid, buyorsell, tradeid } = props.selectedRow
+        /// 市场ID
+        formData.Header = { GoodsID: goodsid }
+        formData.MarketID = marketid
+        formData.PriceMode = EPriceMode.PRICEMODE_LIMIT
+        formData.BuyOrSell = buyorsell === BuyOrSell.Buy ? BuyOrSell.Sell : BuyOrSell.Buy
+        formData.GoodsID = goodsid
+        formData.ListingSelectType = EListingSelectType.LISTINGSELECTTYPE_DELISTINGTHENLISTING
+        formData.DelistingType = EDelistingType.DELISTINGTYPE_PRICE
+        formData.BuildType = EBuildType.BUILDTYPE_CLOSE
+        formData.TimevalidType = EValidType.VALIDTYPE_DR
+        formData.OperateType = 24
+        formData.RelatedID = handleRequestBigNumber(tradeid)
+
+        /// loding....
+        fullloading((hideLoading) => {
+            formSubmit().then(() => {
+                hideLoading(t('position.goods.tips4'), 'success')
+                closed(true)
+            }).catch((err) => {
+                hideLoading(err, 'fail')
+            })
+        })
+    })
+}
+
+// 关闭弹窗
+const closed = (isRefresh = false) => {
+    refresh.value = isRefresh
+    showModal.value = false
+}
+
+onMounted(() => {
+    const { bid, ask, presettle = 0 } = quote.value ?? {}
+    switch (props.selectedRow.buyorsell) {
+        case BuyOrSell.Buy:
+            formData.OrderPrice = ask || presettle
+            break
+        case BuyOrSell.Sell:
+            formData.OrderPrice = bid || presettle
+            break
+        default:
+            formData.OrderPrice = presettle
+    }
+    formData.OrderQty = maxQty.value
+})
+
+// 暴露组件属性给父组件调用
+defineExpose({
+    closed,
+})
+</script>

+ 13 - 15
src/packages/mobile/views/order/position/components/pricing/list/Index.vue

@@ -44,21 +44,17 @@
                     </ul>
                 </div>
                 <div class="g-order-list__btnbar">
-                    <!-- <Button size="small" @click="showComponent('close', item)" round>平仓</Button> -->
-                    <!-- <Button size="small" v-if="userStore.userType === 5" @click="showComponent('delivery', item)" round>交收</Button> -->
-                    <Button size="small" @click="onClosed(item)" round>平仓</Button>
+                    <Button size="small" @click="onClosed(item)" v-if="!fromTrade" round>平仓</Button>
+                    <Button size="small" @click="callBack(item)" v-if="fromTrade" round>平仓</Button>
                 </div>
             </div>
         </div>
-        <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)" @closed="closeComponent"
-            v-if="componentId" />
     </app-pull-refresh>
 </template>
 
 <script lang="ts" setup>
 import { shallowRef, computed } from 'vue'
 import { Button } from 'vant'
-import { useComponent } from '@/hooks/component'
 import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
 import { getBuyOrSellName } from '@/constants/order'
 import { formatDecimal } from '@/filters'
@@ -66,26 +62,28 @@ import { useNavigation } from '@mobile/router/navigation'
 import { BuyOrSell, BuildType } from '@/constants/order'
 import { usePositionStore } from '@/stores'
 
-const componentMap = new Map<string, unknown>([
-    // ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
-    // ['delivery', defineAsyncComponent(() => import('../delivery/Index.vue'))]
-])
-
 const { router } = useNavigation()
 const positionStore = usePositionStore()
-const selectedRow = shallowRef<Model.TradePositionRsp>()
 const pullRefreshRef = shallowRef()
 
 const positionList = computed(() => positionStore.getPositionListByTradeMode(10))
 
-const { componentRef, componentId, closeComponent } = useComponent(() => {
-    pullRefreshRef.value?.refresh()
+const emit = defineEmits(['callBack'])
+const callBack = (item: Model.TradePositionRsp) => {
+    emit('callBack', 1, item.buyorsell)
+}
+
+defineProps({
+    fromTrade: {
+        type: Boolean,
+        required: true
+    }
 })
 
 // 平仓
 const onClosed = (item: Model.TradePositionRsp) => {
     const buyOrSell = item.buyorsell === BuyOrSell.Buy ? BuyOrSell.Sell : BuyOrSell.Buy
-    router.push({ name: 'pricing-detail', query: { goodscode: item.goodscode, buyOrSell: buyOrSell, buildType: BuildType.Close } })
+    router.push({ name: 'pricing-trade', query: { goodscode: item.goodscode, buyOrSell: buyOrSell, buildType: BuildType.Close } })
 }
 
 // 持仓列表刷新

+ 0 - 74
src/packages/mobile/views/pricing/detail/Index.vue

@@ -1,74 +0,0 @@
-<template>
-    <app-view class="goods-detail g-form">
-        <template #header>
-            <app-navbar :title="quote ? quote.goodscode + '/' + quote.goodsname : $t('quote.listinghall')" />
-        </template>
-        <component :is="Price" v-bind="{ goodsCode }" />
-        <component :is="Chart" v-bind="{ goodsCode }" />
-        <component :is="Forex" v-bind="{ goodsCode }" :show-more="showMore" @more-click="onMoreClick" />
-        <component :is="Tik" v-bind="{ goodsCode }" />
-        <template #footer>
-            <div class="g-form__footer">
-                <Button block type="danger" square @click="onListing(BuyOrSell.Buy)">{{ $t('quote.buy') }}</Button>
-                <Button block color="#199e00" square @click="onListing(BuyOrSell.Sell)">{{ $t('quote.selll') }}</Button>
-            </div>
-            <component ref="componentRef" :is="componentMap.get(componentId)" v-bind="{ goodsCode, buyOrSell }"
-                @closed="closeComponent" v-if="componentId" />
-        </template>
-    </app-view>
-</template>
-
-<script lang="ts" setup>
-import { useFuturesStore } from '@/stores'
-import { useNavigation } from '@mobile/router/navigation'
-import { shallowRef, defineAsyncComponent } from 'vue'
-import { Button } from 'vant'
-import { BuyOrSell } from '@/constants/order'
-import { useComponent } from '@/hooks/component'
-
-defineProps({
-    showMore: {
-        type: Boolean,
-        default: true
-    }
-})
-
-const Price = defineAsyncComponent(() => import('@mobile/components/modules/quote/price/index.vue'))
-const Chart = defineAsyncComponent(() => import('@mobile/components/modules/hqchart/index.vue'))
-const Forex = defineAsyncComponent(() => import('@mobile/components/modules/quote/forex/index.vue'))
-const Tik = defineAsyncComponent(() => import('@mobile/components/modules/quote/tik/index.vue'))
-
-const componentMap = new Map<string, unknown>([
-    ['trade', defineAsyncComponent(() => import('./components/trade/Index.vue'))],
-])
-
-const futuresStore = useFuturesStore()
-const { router, getQueryString, getQueryStringToNumber } = useNavigation()
-
-const goodsCode = getQueryString('goodscode') ?? ''
-const goodsid = getQueryStringToNumber('goodsid')
-const quote = futuresStore.getGoodsQuote(goodsCode)
-const buyOrSell = shallowRef<BuyOrSell>()
-
-const { componentRef, componentId, openComponent, closeComponent } = useComponent()
-
-const onListing = (type: BuyOrSell) => {
-    buyOrSell.value = type
-    openComponent('trade')
-}
-
-const onMoreClick = (buyorsell: BuyOrSell) => {
-    router.push({
-        name: 'goods-trade',
-        query: {
-            goodsid,
-            buyorsell,
-        }
-    })
-}
-
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>

+ 0 - 340
src/packages/mobile/views/pricing/detail/components/trade/Index.vue

@@ -1,340 +0,0 @@
-<template>
-    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
-        <app-view class="goods-listing g-form">
-            <template #header>
-                <app-navbar :title="quote ? `${quote.goodscode}/${quote.goodsname}` : $t('quote.pricing.title')" @back="closed" />
-            </template>
-            <component :is="Price" v-bind="{ goodsCode }" />
-            <component :is="Forex" v-bind="{ goodsCode, showMore: false }" @price-click="onPriceClick" />
-            <!-- 下单 -->
-            <Form ref="formRef" class="g-form__container" @submit="onSubmit">
-                <CellGroup inset>
-                    <Field :label="$t('quote.pricing.buyorsell')">
-                        <template #input>
-                            <RadioGroup v-model="formData.BuyOrSell" direction="horizontal" @click="onBuyOrSellChanged">
-                                <Radio v-for="(item, index) in getBuyOrSellList()" :key="index" :name="item.value">{{ item.label
-                                }}</Radio>
-                            </RadioGroup>
-                        </template>
-                    </Field> 
-                    <Field :label="$t('quote.pricing.pricemode')">
-                        <template #input>
-                            <RadioGroup v-model="formData.PriceMode" direction="horizontal" @click="onPriceModeChanged">
-                                <Radio v-for="(item, index) in getPricemode2List()" :key="index" :name="item.value">{{
-                                    item.label
-                                }}</Radio>
-                            </RadioGroup>
-                        </template>
-                    </Field> 
-                    <Field name="OrderQty" :label="$t('quote.pricing.orderqty')">
-                        <template #input>
-                            <div class="g-qty-group">
-                                <div class="g-qty-group__stepper">
-                                    <Stepper v-model="formData.OrderQty" theme="round" button-size="22" :min="0"
-                                        :step="qtyStep" integer />
-                                </div>
-                                <RadioGroup v-model="qtyStep" direction="horizontal" @change="onRadioChange">
-                                    <Radio v-for="(value, index) in qtyStepList" :key="index" :name="value">{{ value }}
-                                    </Radio>
-                                </RadioGroup>
-                            </div>
-                        </template>
-                    </Field> 
-                    <!-- 市价 -->
-                    <!-- <Field label="价格" v-if="formData.PriceMode === PriceMode.Market">
-                        <template #input>
-                            <span>{{ handleNumberValue(marketPrice) }}</span>
-                        </template>
-                    </Field> -->
-                    <!-- 允许成交范围 -->
-                    <Field name="MarketMaxSub" :label="$t('quote.pricing.marketmaxsub')" v-if="formData.PriceMode === PriceMode.Market">
-                        <template #input>
-                            <Stepper v-model="formData.MarketMaxSub" theme="round" button-size="22" :auto-fixed="false"
-                                integer />
-                        </template>
-                    </Field>
-                    <!-- 限价 -->
-                    <Field name="OrderPrice" :rules="formRules.OrderPrice" :label="$t('quote.pricing.price')" v-if="formData.PriceMode === PriceMode.Limit">
-                        <template #input>
-                            <Stepper v-model="formData.OrderPrice" theme="round" button-size="22" :min="0"
-                             :auto-fixed="false" :decimal-length="decimalplace" :step="decimalvalue" />
-                        </template>
-                    </Field>
-                    <!-- <Field name="SlPrice" :rules="formRules.SlPrice"
-                        v-if="formData.PriceMode === PriceMode.Limit && formData.BuildType === BuildType.Open">
-                        <template #label>
-                            <Checkbox v-model="sl">止损</Checkbox>
-                        </template>
-                        <template #input>
-                            <Stepper v-model="formData.SlPrice" :disabled="!sl" theme="round" button-size="22" allow-empty
-                                :default-value="0" :min="0" :decimal-length="decimalplace" :step="decimalvalue" />
-                        </template>
-                    </Field> -->
-                    <!-- <Field name="SpPrice" :rules="formRules.SpPrice"
-                        v-if="formData.PriceMode === PriceMode.Limit && formData.BuildType === BuildType.Open">
-                        <template #label>
-                            <Checkbox v-model="sp">止盈</Checkbox>
-                        </template>
-                        <template #input>
-                            <Stepper v-model="formData.SpPrice" :disabled="!sp" theme="round" button-size="22" allow-empty
-                                :default-value="0" :min="0" :decimal-length="decimalplace" :step="decimalvalue" />
-                        </template>
-                    </Field> -->
-                    <template v-if="formData.BuyOrSell === BuyOrSell.Buy || quote?.tradeproperty !== 2">
-                        <Field :label="$t('quote.pricing.enableQty')">
-                            <template #input>
-                                <span>{{ total.enableQty }}</span>
-                            </template>
-                        </Field>
-                        <Field :label="$t('quote.pricing.deposit')">
-                            <template #input>
-                                <span>{{ total.deposit.toFixed(2) }}</span>
-                            </template>
-                        </Field>
-                    </template>
-                    <Field :label="$t('quote.pricing.avaiableMoney')">
-                        <template #input>
-                            <span>{{ accountStore.currentAccount.avaiableMoney?.toFixed(2) }}</span>
-                        </template>
-                    </Field>
-                </CellGroup>
-            </Form>
-            <template #footer>
-                <div class="g-form__footer">
-                    <template v-if="formData.BuyOrSell === BuyOrSell.Buy">
-                        <Button type="danger" block square :disabled="!formData.OrderQty"
-                            @click="onBeforeSubmit(BuildType.Open)" v-if="!quote?.iscannotbuy">{{ $t('quote.orderbuy') }}</Button>
-                        <Button color="#199e00" block square
-                            :disabled="!formData.OrderQty || !sellQty || (formData.OrderQty > sellQty)"
-                            @click="onBeforeSubmit(BuildType.Close)" v-if="!isTrademode16">
-                            <span>{{ $t('quote.transferbuy') }}</span>
-                            <span v-if="sellQty">(≤{{ sellQty }})</span>
-                        </Button>
-                    </template>
-                    <template v-if="formData.BuyOrSell === BuyOrSell.Sell">
-                        <Button type="danger" block square :disabled="!formData.OrderQty"
-                            @click="onBeforeSubmit(BuildType.Open)"
-                            v-if="!isTrademode16 && !quote?.iscannotsell">{{ $t('quote.ordersell') }}</Button>
-                        <Button color="#199e00" block square
-                            :disabled="!formData.OrderQty || !buyQty || (formData.OrderQty > buyQty)"
-                            @click="onBeforeSubmit(BuildType.Close)">
-                            <span>{{ $t('quote.transfersell') }}</span>
-                            <span v-if="buyQty">(≤{{ buyQty }})</span>
-                        </Button>
-                    </template>
-                </div>
-            </template>
-        </app-view>
-    </app-modal>
-</template>
-
-<script lang="ts" setup>
-import { useFuturesStore, useAccountStore, usePositionStore, i18n } from '@/stores'
-import { useNavigation } from '@mobile/router/navigation'
-import { shallowRef, onMounted, computed, defineAsyncComponent } from 'vue'
-import { Form, Field, Button, FieldRule, FormInstance, Radio, RadioGroup, CellGroup } from 'vant'
-import { useOrder } from '@/business/trade'
-import { BuyOrSell, getBuyOrSellList, BuildType, getPricemode2List, PriceMode } from '@/constants/order'
-import { fullloading, dialog } from '@/utils/vant'
-import AppModal from '@/components/base/modal/index.vue'
-import Stepper from '@mobile/components/base/stepper/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({
-    goodsCode: {
-        type: String,
-        required: true
-    },
-    buyOrSell: {
-        type: Number,
-        required: true
-    }
-})
-
-const { global: { t } } = i18n
-const { router } = useNavigation()
-const futuresStore = useFuturesStore()
-const accountStore = useAccountStore()
-const positionStore = usePositionStore()
-const formRef = shallowRef<FormInstance>()
-const { formData, formSubmit } = useOrder()
-
-const quote = futuresStore.getGoodsQuote(props.goodsCode)
-// 小数位以及步进值
-const { decimalplace = 0.0 } = quote.value ?? {}
-const quoteminunit = quote.value?.quoteminunit ?? 1.0
-const decimalvalue = Math.pow(10.0, -decimalplace)*(quoteminunit == 0 ? 1 : quoteminunit)
-
-// 计算市价
-const marketPrice = computed(() => {
-    const { ask = 0, bid = 0 } = quote.value ?? {}
-    return formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
-})
-// const sl = shallowRef(false) // 止损
-// const sp = shallowRef(false) // 止盈
-const position = shallowRef<Model.TradePositionRsp[]>([]) // 持仓汇总
-// 是否刷新父组件数据
-const refresh = shallowRef(true) 
-const showModal = shallowRef(true)
-const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
-const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
-
-const isTrademode16 = computed(() => quote.value?.trademode === 16)
-
-const total = computed(() => {
-    const { avaiableMoney = 0 } = accountStore.currentAccount
-    const { marketmarginalgorithm = 0, marketmarginvalue = 0, agreeunit = 0 } = quote.value ?? {}
-
-    const result = {
-        enableQty: 0,
-        deposit: 0
-    }
-
-    const fixed = agreeunit * marketmarginvalue
-    const ratio = fixed * (formData.OrderPrice ?? 0)
-
-    if (fixed && ratio) {
-        if (marketmarginalgorithm === 1) {
-            const qty = Math.trunc(avaiableMoney / ratio)
-            result.deposit = (formData.OrderQty ?? 0) * ratio
-            result.enableQty = qty > 0 ? qty : 0
-        }
-        if (marketmarginalgorithm === 2) {
-            const qty = Math.trunc(avaiableMoney / fixed)
-            result.deposit = (formData.OrderQty ?? 0) * fixed
-            result.enableQty = qty > 0 ? qty : 0
-        }
-    }
-    return result
-})
-
-// 买方向持仓数量
-const buyQty = computed(() => positionStore.getOrderQty(BuyOrSell.Buy, props.goodsCode))
-// 卖方向持仓数量
-const sellQty = computed(() => positionStore.getOrderQty(BuyOrSell.Sell, props.goodsCode))
-
-// 表单验证规则
-const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
-    OrderQty: [{
-        message: t('quote.pricing.tips1'),
-        validator: () => {
-            return !!formData.OrderQty
-        }
-    }],
-    // 限价
-    OrderPrice: [{
-        message: t('quote.pricing.tips2'),
-        validator: () => {
-            if (formData.PriceMode === PriceMode.Limit) {
-                return !!formData.OrderPrice
-            }
-            return true
-        }
-    }],
-    // SlPrice: [{
-    //     message: '请输入止损价',
-    //     validator: () => {
-    //         if (sl.value) {
-    //             return !!formData.SlPrice
-    //         }
-    //         return true
-    //     }
-    // }],
-    // SpPrice: [{
-    //     message: '请输入止盈价',
-    //     validator: () => {
-    //         if (sp.value) {
-    //             return !!formData.SpPrice
-    //         }
-    //         return true
-    //     }
-    // }],
-}
-
-const onBuyOrSellChanged = () => {
-    if (formData.PriceMode === PriceMode.Limit) {
-        const { ask = 0, bid = 0 } = quote.value ?? {}
-        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
-    }
-}
-
-const onPriceModeChanged = () => {
-    if (formData.PriceMode === PriceMode.Limit) {
-        const { ask = 0, bid = 0 } = quote.value ?? {}
-        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
-    }
-}
-
-const onBeforeSubmit = (buildType: BuildType) => {
-    formData.BuildType = buildType
-    if (buildType === BuildType.Close) {
-        const { ask = 0, bid = 0 } = quote.value ?? {}
-        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
-
-        const datas = position.value.filter(item => formData.BuyOrSell === BuyOrSell.Buy ? item.buyorsell === BuyOrSell.Sell : item.buyorsell === BuyOrSell.Buy) // 反方向持仓
-        if (datas.length > 0) {
-            formData.OrderQty = datas[0].enableqty
-        }
-    }
-    formRef.value?.submit()
-}
-
-// 委托下单
-const onSubmit = () => {
-    const { goodsid, marketid } = quote.value ?? {}
-    formData.GoodsID = goodsid
-    formData.MarketID = marketid
-    // 市价
-    if (formData.PriceMode === PriceMode.Market) { formData.OrderPrice = marketPrice.value }
-    // 限价
-    // if (!sl.value) { formData.SlPrice = undefined }
-    // if (!sp.value) { formData.SpPrice = undefined }
-
-    fullloading((hideLoading) => {
-        formSubmit().then(() => {
-            hideLoading()
-            dialog(t('common.submitsuccess')).then(() => {
-                router.back()
-            })
-        }).catch((err) => {
-            hideLoading(err, 'fail')
-        })
-    })
-}
-
-const onPriceClick = (buyorsell: BuyOrSell, value: number) => {
-    // 价格显示
-    formData.OrderPrice = value
-    // 方向也变化
-    formData.BuyOrSell = buyorsell === BuyOrSell.Buy ? 1 : 0
-}
-
-const onRadioChange = (value: number) => {
-    formData.OrderQty = value
-}
-
-// 关闭弹窗
-const closed = (isRefresh = true) => {
-    refresh.value = isRefresh
-    showModal.value = false
-}
-
-onMounted(() => {
-    formData.BuyOrSell = props.buyOrSell
-    formData.BuildType = BuildType.Open
-    formData.PriceMode = PriceMode.Market
-    formData.MarketMaxSub = 100.0
-    /// 默认价格和数量
-    const { last = 0, presettle = 0 } = quote.value ?? {}
-    formData.OrderPrice = last || presettle
-    formData.OrderQty = qtyStep.value
-})
-
-// 暴露组件属性给父组件调用
-defineExpose({
-    closed,
-})
-
-</script>

+ 1 - 1
src/packages/mobile/views/pricing/list/Index.vue

@@ -124,7 +124,7 @@ const columns: Model.TableColumn[] = [
 
 const rowClick = (row: Model.GoodsQuote) => {
     router.push({
-        name: 'pricing-detail',
+        name: 'pricing-trade',
         query: {
             goodsid: row.goodsid,
             goodscode: row.goodscode,

+ 380 - 0
src/packages/mobile/views/pricing/trade/Index.vue

@@ -0,0 +1,380 @@
+<template>
+    <app-view class="pricing-trade">
+        <template #header>
+            <app-navbar :title="quote ? `${quote.goodscode}/${quote.goodsname}` : $t('quote.pricing.title')" >
+                <template #right>
+                    <Icon name="bars" size="20px" @click="openComponent('detail')" />
+                </template>
+            </app-navbar>
+        </template>
+        <div class="pricing-trade__form" v-if="quote">
+            <div class="form-price">
+                <dl>
+                    <dt>买价</dt>
+                    <dd :class="quote.bidColor">{{ handleNumberValue(formatDecimal(quote.ask, quote.decimalplace)) }}
+                    </dd>
+                </dl>
+                <dl>
+                    <dt>卖价</dt>
+                    <dd :class="quote.askColor">{{ handleNumberValue(formatDecimal(quote.bid, quote.decimalplace)) }}
+                    </dd>
+                </dl>
+            </div>
+        </div>
+        <!-- 下单 -->
+        <Form ref="formRef" class="g-form__container" @submit="onSubmit">
+            <CellGroup inset>
+                <Field :label="$t('quote.pricing.buyorsell')">
+                    <template #input>
+                        <RadioGroup v-model="formData.BuyOrSell" direction="horizontal" @click="onBuyOrSellChanged">
+                            <Radio v-for="(item, index) in getBuyOrSellList()" :key="index" :name="item.value">{{ item.label
+                            }}</Radio>
+                        </RadioGroup>
+                    </template>
+                </Field> 
+                <Field :label="$t('quote.pricing.pricemode')">
+                    <template #input>
+                        <RadioGroup v-model="formData.PriceMode" direction="horizontal" @click="onPriceModeChanged">
+                            <Radio v-for="(item, index) in getPricemode2List()" :key="index" :name="item.value">{{
+                                item.label
+                            }}</Radio>
+                        </RadioGroup>
+                    </template>
+                </Field> 
+                <Field name="OrderQty" :label="$t('quote.pricing.orderqty')">
+                    <template #input>
+                        <div class="g-qty-group">
+                            <div class="g-qty-group__stepper">
+                                <Stepper v-model="formData.OrderQty" theme="round" button-size="22" :min="0"
+                                    :step="qtyStep" integer />
+                            </div>
+                            <RadioGroup v-model="qtyStep" direction="horizontal" @change="onRadioChange">
+                                <Radio v-for="(value, index) in qtyStepList" :key="index" :name="value">{{ value }}
+                                </Radio>
+                            </RadioGroup>
+                        </div>
+                    </template>
+                </Field> 
+                <!-- 市价 -->
+                <!-- <Field label="价格" v-if="formData.PriceMode === PriceMode.Market">
+                    <template #input>
+                        <span>{{ handleNumberValue(marketPrice) }}</span>
+                    </template>
+                </Field> -->
+                <!-- 允许成交范围 -->
+                <Field name="MarketMaxSub" :rules="formRules.MarketMaxSub" :label="$t('quote.pricing.marketmaxsub')" v-if="formData.PriceMode === PriceMode.Market">
+                    <template #input>
+                        <Stepper v-model="formData.MarketMaxSub" theme="round" button-size="22" :auto-fixed="false"
+                            integer />
+                    </template>
+                </Field>
+                <!-- 限价 -->
+                <Field name="OrderPrice" :rules="formRules.OrderPrice" :label="$t('quote.pricing.price')" v-if="formData.PriceMode === PriceMode.Limit">
+                    <template #input>
+                        <Stepper v-model="formData.OrderPrice" theme="round" button-size="22" :min="0"
+                            :auto-fixed="false" :decimal-length="decimalplace" :step="decimalvalue" />
+                    </template>
+                </Field>
+                <!-- <Field name="SlPrice" :rules="formRules.SlPrice"
+                    v-if="formData.PriceMode === PriceMode.Limit && formData.BuildType === BuildType.Open">
+                    <template #label>
+                        <Checkbox v-model="sl">止损</Checkbox>
+                    </template>
+                    <template #input>
+                        <Stepper v-model="formData.SlPrice" :disabled="!sl" theme="round" button-size="22" allow-empty
+                            :default-value="0" :min="0" :decimal-length="decimalplace" :step="decimalvalue" />
+                    </template>
+                </Field>
+                <Field name="SpPrice" :rules="formRules.SpPrice"
+                    v-if="formData.PriceMode === PriceMode.Limit && formData.BuildType === BuildType.Open">
+                    <template #label>
+                        <Checkbox v-model="sp">止盈</Checkbox>
+                    </template>
+                    <template #input>
+                        <Stepper v-model="formData.SpPrice" :disabled="!sp" theme="round" button-size="22" allow-empty
+                            :default-value="0" :min="0" :decimal-length="decimalplace" :step="decimalvalue" />
+                    </template>
+                </Field> -->
+                <!-- <template v-if="formData.BuyOrSell === BuyOrSell.Buy || quote?.tradeproperty !== 2">
+                    <Field :label="$t('quote.pricing.enableQty')">
+                        <template #input>
+                            <span>{{ total.enableQty }}</span>
+                        </template>
+                    </Field>
+                    <Field :label="$t('quote.pricing.deposit')">
+                        <template #input>
+                            <span>{{ total.deposit.toFixed(2) }}</span>
+                        </template>
+                    </Field>
+                </template>
+                <Field :label="$t('quote.pricing.avaiableMoney')">
+                    <template #input>
+                        <span>{{ accountStore.currentAccount.avaiableMoney?.toFixed(2) }}</span>
+                    </template>
+                </Field> -->
+            </CellGroup>
+        </Form> 
+        <div class="g-form__footer">
+            <template v-if="formData.BuyOrSell === BuyOrSell.Buy">
+                <Button type="danger" block square :disabled="!formData.OrderQty"
+                    @click="onBeforeSubmit(BuildType.Open)" v-if="!quote?.iscannotbuy">{{ $t('quote.orderbuy') }}</Button>
+                <Button color="#199e00" block square
+                    :disabled="!formData.OrderQty || !sellQty || (formData.OrderQty > sellQty)"
+                    @click="onBeforeSubmit(BuildType.Close)" v-if="!isTrademode16">
+                    <span>{{ $t('quote.transferbuy') }}</span>
+                    <span v-if="sellQty">(≤{{ sellQty }})</span>
+                </Button>
+            </template>
+            <template v-if="formData.BuyOrSell === BuyOrSell.Sell">
+                <Button type="danger" block square :disabled="!formData.OrderQty"
+                    @click="onBeforeSubmit(BuildType.Open)"
+                    v-if="!isTrademode16 && !quote?.iscannotsell">{{ $t('quote.ordersell') }}</Button>
+                <Button color="#199e00" block square
+                    :disabled="!formData.OrderQty || !buyQty || (formData.OrderQty > buyQty)"
+                    @click="onBeforeSubmit(BuildType.Close)">
+                    <span>{{ $t('quote.transfersell') }}</span>
+                    <span v-if="buyQty">(≤{{ buyQty }})</span>
+                </Button>
+            </template>
+        </div>
+        <Tabs class="van-tabs--list" v-model:active="active">
+            <template v-for="(item, index) in components" :key="index">
+                <Tab :title="item.title" :name="item.name">
+                    <component :is="item.component" v-bind="{ goodsCode, goodsid, fromTrade }" 
+                        @callBack="itemBack"/>
+                </Tab>
+            </template>
+        </Tabs>
+        <template #footer>
+            <component ref="componentRef" :is="componentMap.get(componentId)" v-bind="{ goodsCode, goodsid }"
+            @closed="closeComponent" v-if="componentId" />
+        </template> 
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { useFuturesStore, usePositionStore, i18n } from '@/stores'
+import { useNavigation } from '@mobile/router/navigation'
+import { shallowRef, onMounted, computed, defineAsyncComponent } from 'vue'
+import { Form, Field, Button, FieldRule, FormInstance, Radio, RadioGroup, CellGroup, Icon, Tab, Tabs } from 'vant'
+import { useOrder } from '@/business/trade'
+import { BuyOrSell, getBuyOrSellList, BuildType, getPricemode2List, PriceMode } from '@/constants/order'
+import { useComponent } from '@/hooks/component'
+import { fullloading, dialog } from '@/utils/vant'
+import Stepper from '@mobile/components/base/stepper/index.vue'
+import { formatDecimal, handleNumberValue, handleRequestBigNumber } from '@/filters'
+
+const { router, getQueryString, getQueryStringToNumber } = useNavigation()
+const { global: { t } } = i18n
+
+const goodsCode = getQueryString('goodscode') ?? ''
+const goodsid = getQueryStringToNumber('goodsid')
+const futuresStore = useFuturesStore()
+const quote = futuresStore.getGoodsQuote(goodsCode)
+// 小数位以及步进值
+const { decimalplace = 0.0 } = quote.value ?? {}
+const quoteminunit = quote.value?.quoteminunit ?? 1.0
+const decimalvalue = Math.pow(10.0, -decimalplace)*(quoteminunit == 0 ? 1 : quoteminunit)
+const isTrademode16 = computed(() => quote.value?.trademode === 16)
+
+const { formData, formSubmit } = useOrder()
+const formRef = shallowRef<FormInstance>()
+const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
+const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
+const fromTrade = true
+
+// const accountStore = useAccountStore()
+const positionStore = usePositionStore()
+// 持仓汇总
+const position = shallowRef<Model.TradePositionRsp[]>([]) 
+
+// 点击返回
+const itemBack = (isPosition: number, buyorsell: BuyOrSell, tradeId: string) => {
+    formData.BuyOrSell = buyorsell
+    if (isPosition === 2) { formData.RelatedID = handleRequestBigNumber(tradeId)}
+}
+
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
+const active = shallowRef('cancel')
+const components = [
+    {
+        name: 'cancel',
+        title: '订单可撤',
+        component: defineAsyncComponent(() => import('../trade/components/cancel/Index.vue')),
+    },
+    {
+        name: 'position',
+        title: '持仓汇总',
+        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/list/Index.vue')),
+    },
+    {
+        name: 'holdlb',
+        title: '持仓明细',
+        component: defineAsyncComponent(() => import('../trade/holdlb/Index.vue')),
+    }
+]
+
+const componentMap = new Map<string, unknown>([
+    ['detail', defineAsyncComponent(() => import('./components/detail/Index.vue'))],
+])
+
+// // const sl = shallowRef(false) // 止损
+// // const sp = shallowRef(false) // 止盈
+
+// const total = computed(() => {
+//     const { avaiableMoney = 0 } = accountStore.currentAccount
+//     const { marketmarginalgorithm = 0, marketmarginvalue = 0, agreeunit = 0 } = quote.value ?? {}
+
+//     const result = {
+//         enableQty: 0,
+//         deposit: 0
+//     }
+
+//     const fixed = agreeunit * marketmarginvalue
+//     const ratio = fixed * (formData.OrderPrice ?? 0)
+
+//     if (fixed && ratio) {
+//         if (marketmarginalgorithm === 1) {
+//             const qty = Math.trunc(avaiableMoney / ratio)
+//             result.deposit = (formData.OrderQty ?? 0) * ratio
+//             result.enableQty = qty > 0 ? qty : 0
+//         }
+//         if (marketmarginalgorithm === 2) {
+//             const qty = Math.trunc(avaiableMoney / fixed)
+//             result.deposit = (formData.OrderQty ?? 0) * fixed
+//             result.enableQty = qty > 0 ? qty : 0
+//         }
+//     }
+//     return result
+// })
+
+// 计算市价
+const marketPrice = computed(() => {
+    const { ask = 0, bid = 0 } = quote.value ?? {}
+    return formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
+})
+
+// 买方向持仓数量
+const buyQty = computed(() => positionStore.getOrderQty(BuyOrSell.Buy, goodsCode))
+// 卖方向持仓数量
+const sellQty = computed(() => positionStore.getOrderQty(BuyOrSell.Sell, goodsCode))
+
+// 表单验证规则
+const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
+    OrderQty: [{
+        message: t('quote.pricing.tips1'),
+        validator: () => {
+            return !!formData.OrderQty
+        }
+    }],
+    // 限价
+    MarketMaxSub: [{
+        message: t('quote.pricing.tips3'),
+        validator: () => {
+            if (formData.PriceMode === PriceMode.Market) {
+                return !!formData.MarketMaxSub
+            }
+            return true
+        }
+    }],
+    // 限价
+    OrderPrice: [{
+        message: t('quote.pricing.tips2'),
+        validator: () => {
+            if (formData.PriceMode === PriceMode.Limit) {
+                return !!formData.OrderPrice
+            }
+            return true
+        }
+    }],
+//     // SlPrice: [{
+//     //     message: '请输入止损价',
+//     //     validator: () => {
+//     //         if (sl.value) {
+//     //             return !!formData.SlPrice
+//     //         }
+//     //         return true
+//     //     }
+//     // }],
+//     // SpPrice: [{
+//     //     message: '请输入止盈价',
+//     //     validator: () => {
+//     //         if (sp.value) {
+//     //             return !!formData.SpPrice
+//     //         }
+//     //         return true
+//     //     }
+//     // }],
+}
+
+const onBuyOrSellChanged = () => {
+    if (formData.PriceMode === PriceMode.Limit) {
+        const { ask = 0, bid = 0 } = quote.value ?? {}
+        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
+    }
+}
+
+const onPriceModeChanged = () => {
+    if (formData.PriceMode === PriceMode.Limit) {
+        const { ask = 0, bid = 0 } = quote.value ?? {}
+        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
+    }
+}
+
+const onBeforeSubmit = (buildType: BuildType) => {
+    formData.BuildType = buildType
+    if (buildType === BuildType.Close) {
+        const { ask = 0, bid = 0 } = quote.value ?? {}
+        formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
+
+        const datas = position.value.filter(item => formData.BuyOrSell === BuyOrSell.Buy ? item.buyorsell === BuyOrSell.Sell : item.buyorsell === BuyOrSell.Buy) // 反方向持仓
+        if (datas.length > 0) {
+            formData.OrderQty = datas[0].enableqty
+        }
+    }
+    formRef.value?.submit()
+}
+
+// 委托下单
+const onSubmit = () => {
+    const { goodsid, marketid } = quote.value ?? {}
+    formData.GoodsID = goodsid
+    formData.MarketID = marketid
+    // 市价
+    if (formData.PriceMode === PriceMode.Market) { formData.OrderPrice = marketPrice.value }
+    // 限价
+    // if (!sl.value) { formData.SlPrice = undefined }
+    // if (!sp.value) { formData.SpPrice = undefined }
+
+    fullloading((hideLoading) => {
+        formSubmit().then(() => {
+            hideLoading()
+            dialog(t('common.submitsuccess')).then(() => {
+                // router.back()
+            })
+        }).catch((err) => {
+            hideLoading(err, 'fail')
+        })
+    })
+}
+
+const onRadioChange = (value: number) => {
+    formData.OrderQty = value
+}
+
+ onMounted(() => {
+    formData.BuyOrSell = BuyOrSell.Buy
+    formData.BuildType = BuildType.Open
+    formData.PriceMode = PriceMode.Market
+    formData.MarketMaxSub = 100.0
+    /// 默认价格和数量
+    const { last = 0, presettle = 0 } = quote.value ?? {}
+    formData.OrderPrice = last || presettle
+    formData.OrderQty = qtyStep.value
+ })
+
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 104 - 0
src/packages/mobile/views/pricing/trade/components/cancel/Index.vue

@@ -0,0 +1,104 @@
+<!-- 我的订单-订单委托 -->
+<template>
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
+        :page-count="pageCount" @refresh="run">
+        <div class="g-order-list">
+            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+                <div class="g-order-list__titlebar">
+                    <div class="left">
+                        <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
+                    </div>
+                    <div class="right">
+                        <span>{{ getWRTradeOrderStatusName(item.orderstatus) }}</span>
+                    </div>
+                </div>
+                <div class="g-order-list__content">
+                    <ul>
+                        <li>
+                            <span>{{ $t('order.pricingorder.orderdate') }}</span>
+                            <span>{{ formatDate(item.ordertime, 'YYYY-MM-DD') }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('order.pricingorder.buyorsell') }}</span>
+                            <span>{{ getBuyOrSellName(item.buyorsell) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('order.pricingorder.orderqty') }}</span>
+                            <span>{{ formatDecimal(item.orderqty) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('order.pricingorder.orderprice') }}</span>
+                            <span>{{ formatDecimal(item.orderprice) }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('order.pricingorder.tradeqty') }}</span>
+                            <span>{{ formatDecimal(item.tradeqty) }}</span>
+                        </li>
+                    </ul>
+                </div>
+                <div class="g-order-list__btnbar">
+                    <Button size="small" v-if="(item.orderstatus === 3 || item.orderstatus === 7)"
+                        @click="onCancelSumit(item)" round>{{ $t('operation.cancel2') }}</Button>
+                </div>
+            </div>
+        </div>
+    </app-pull-refresh>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef } from 'vue'
+import { Button } from 'vant'
+import { useRequest } from '@/hooks/request'
+import { queryTradeOrderDetail } from '@/services/api/order'
+import { getBuyOrSellName, getWRTradeOrderStatusName } from '@/constants/order'
+import { formatDate, formatDecimal, handleRequestBigNumber } from '@/filters'
+import { useCancelOrder } from '@/business/trade'
+import { dialog } from '@/utils/vant'
+import { fullloading } from '@/utils/vant'
+import { i18n } from '@/stores'
+import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
+
+const { global: { t } } = i18n
+const { cancelSubmit, formData } = useCancelOrder()
+const dataList = shallowRef<Model.TradeOrderDetailRsp[]>([])
+const error = shallowRef(false)
+const pullRefreshRef = shallowRef()
+
+const { loading, pageIndex, pageCount, run } = useRequest(queryTradeOrderDetail, {
+    params: {
+        pagesize: 20,
+        tradeMode: '10',
+        orderStatus: '3,7'
+    },
+    onSuccess: (res) => {
+        if (pageIndex.value === 1) {
+            dataList.value = []
+        }
+        dataList.value.push(...res.data)
+    },
+    onError: () => {
+        error.value = true
+    }
+})
+
+const onCancelSumit = (item: Model.TradeOrderDetailRsp) => {
+    dialog({
+        message: t('order.pricingorder.tips1'),
+        showCancelButton: true,
+    }).then(() => {
+        formData.Header = { MarketID: item.marketid, GoodsID: item.goodsid }
+        formData.OldOrderId = handleRequestBigNumber(item.orderid)
+
+        /// loding....
+        fullloading((hideLoading) => {
+            cancelSubmit().then(() => {
+                hideLoading(t('order.pricingorder.tips2'))
+                pullRefreshRef.value?.refresh()
+            }).catch((err) => {
+                hideLoading(err, 'fail')
+            })
+        })
+    })
+}
+
+</script>

+ 38 - 0
src/packages/mobile/views/pricing/trade/components/detail/Index.vue

@@ -0,0 +1,38 @@
+<template>
+    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
+        <app-view class="pricing-detail g-form">
+            <template #header>
+                <app-navbar :title="quote ? quote.goodscode + '/' + quote.goodsname : $t('quote.listinghall')" />
+            </template>
+            <component :is="Price" v-bind="{ goodsCode }" />
+            <component :is="Chart" v-bind="{ goodsCode }" />
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { useFuturesStore } from '@/stores'
+import { shallowRef, defineAsyncComponent } from 'vue'
+import AppModal from '@/components/base/modal/index.vue'
+
+const props = defineProps({
+    goodsCode: {
+        type: String,
+        required: true
+    }
+})
+
+// 是否刷新父组件数据
+const refresh = shallowRef(true) 
+const showModal = shallowRef(true)
+const futuresStore = useFuturesStore()
+const quote = futuresStore.getGoodsQuote(props.goodsCode)
+
+const Price = defineAsyncComponent(() => import('@mobile/components/modules/quote/price/index.vue'))
+const Chart = defineAsyncComponent(() => import('@mobile/components/modules/hqchart/index.vue'))
+
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 0 - 0
src/packages/mobile/views/pricing/detail/index.less → src/packages/mobile/views/pricing/trade/components/detail/index.less


+ 84 - 0
src/packages/mobile/views/pricing/trade/holdlb/Index.vue

@@ -0,0 +1,84 @@
+<!-- 我的持仓-订单明细 -->
+<template>
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" @refresh="run">
+        <div class="g-order-list">
+            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+                <div class="g-order-list__titlebar">
+                    <div class="left">
+                        <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
+                    </div>
+                </div>
+                <div class="g-order-list__content">
+                    <ul>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.tradetime') }}</span>
+                            <span>{{ formatDate(item.tradetime, 'HH:mm:ss') }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.buyorsell') }}</span>
+                            <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">
+                                {{ getBuyOrSellName(item.buyorsell) }}
+                            </span>
+                        </li>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.holderqty') }}</span>
+                            <span>{{ item.holderqty }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.freezeqty') }}</span>
+                            <span>{{ item.freezeqty }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.holderprice') }}</span>
+                            <span>{{ item.holderprice }}</span>
+                        </li>
+                        <li>
+                            <span>{{ $t('position.goods.holddetail.holderamount') }}</span>
+                            <span>{{ formatDecimal(item.holderamount) }}</span>
+                        </li>
+                    </ul>
+                </div>
+                <div class="g-order-list__btnbar" v-if="item.trademode === 10 && item.holderqty">
+                    <Button size="small" @click="callBack(item)" round>平仓</Button>
+                </div>
+            </div>
+        </div>
+    </app-pull-refresh>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef } from 'vue'
+import { Button } from 'vant'
+import { useRequest } from '@/hooks/request'
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, formatDate } from '@/filters'
+import { queryTradeHolderDetail } from '@/services/api/order'
+import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
+
+const error = shallowRef(false)
+const showModal = shallowRef(true)
+const refresh = shallowRef(false) // 是否刷新父组件数据
+
+const { dataList, loading, run } = useRequest(queryTradeHolderDetail, {
+    params: {
+        trademodes: '10'
+    }
+})
+const pullRefreshRef = shallowRef()
+
+const emit = defineEmits(['callBack'])
+const callBack = (item: Model.TradeHolderDetailRsp) => {
+    emit('callBack', 2, item.buyorsell, item.tradeid)
+}
+
+// 关闭弹窗
+const closed = (isRefresh = false) => {
+    refresh.value = isRefresh
+    showModal.value = false
+}
+
+// 暴露组件属性给父组件调用
+defineExpose({
+    closed,
+})
+</script>

+ 31 - 0
src/packages/mobile/views/pricing/trade/index.less

@@ -0,0 +1,31 @@
+.pricing-trade {
+    &__form {
+        background-color: #fff;
+        border-radius: 8px;
+        margin: 15px 15px 0px 15px;
+        margin-bottom: 0;
+
+        .form-price {
+            display: flex;
+            padding: 16px 0;
+
+            dl {
+                flex: 1;
+                text-align: center;
+
+                dt {
+                    margin-bottom: 5px;
+                }
+
+                dd {
+                    font-size: 28px;
+                    font-weight: bold;
+                }
+            }
+        }
+    }
+
+    .g-form__footer {
+        margin-bottom: 10px;
+    }
+}

+ 4 - 3
src/packages/mobile/views/report/components/index.vue

@@ -50,7 +50,7 @@ import { formatDecimal, handleNoneValue } from '@/filters'
 import { useComponent } from '@/hooks/component'
 import { queryMarketRun } from '@/services/api/market'
 import { queryReportMonthTaaccount, queryReportReckonDayTaaccount } from '@/services/api/report'
-import { useAccountStore, useUserStore } from '@/stores'
+import { useAccountStore, useUserStore, i18n } from '@/stores'
 import moment from 'moment'
 
 const componentMap = new Map<string, unknown>([
@@ -67,12 +67,13 @@ const showPicker = shallowRef(false)
 const marketInfo = shallowRef<Model.MarketRunRsp>()
 const currentDate = shallowRef<string[]>([])
 const taaccount = shallowRef<Model.ReportMonthTaaccountRsp | Model.ReportReckonDayTaaccountRsp>()
+const { global: { t } } = i18n
 
 const { componentRef, componentId, closeComponent, openComponent } = useComponent()
 
 const reportType = [
-    { text: '日报表', value: 1 },
-    { text: '月报表', value: 2 }
+    { text: t('report.day'), value: 1 },
+    { text: t('report.month'), value: 2 }
 ]
 
 const pickerFormat = computed(() => reportTypeValue.value === 1 ? 'YYYY-MM-DD' : 'YYYY-MM')

+ 7 - 2
src/packages/pc/components/modules/goods-detail/chart/index.vue

@@ -5,7 +5,7 @@
         </div>
         <el-scrollbar class="block-right">
             <Price v-bind="{ goodsCode }" />
-            <Forex v-bind="{ goodsCode }" />
+            <Forex v-if="quote?.trademode != 10" v-bind="{ goodsCode }" />
             <Tik v-bind="{ goodsCode }" />
         </el-scrollbar>
     </div>
@@ -16,14 +16,19 @@ import Price from '@pc/components/modules/quote/price/index.vue'
 import Chart from '@pc/components/modules/hqchart/index.vue'
 import Forex from '@pc/components/modules/quote/forex/index.vue'
 import Tik from '@pc/components/modules/quote/tik/index.vue'
+import { useFuturesStore } from '@/stores'
 
-defineProps({
+const props = defineProps({
     goodsCode: {
         type: String,
         required: true
     },
     makretId: Number
 })
+
+const futuresStore = useFuturesStore()
+const quote = futuresStore.getGoodsQuote(props.goodsCode)
+
 </script>
 
 <style lang="less">

+ 6 - 6
src/packages/pc/components/modules/goods-detail/order/index.vue

@@ -33,7 +33,7 @@ import { BuyOrSell } from '@/constants/order'
 import { useComponent } from '@/hooks/component'
 import { useComposeTable } from '@pc/components/base/table'
 import { queryWrTradeOrderDetail } from '@/services/api/transfer'
-import { useLoginStore, useFuturesStore } from '@/stores'
+import { useFuturesStore } from '@/stores'
 import AppTable from '@pc/components/base/table/index.vue'
 import service from '@/services'
 
@@ -48,7 +48,7 @@ const componentMap = new Map<string, unknown>([
     ['delisting', defineAsyncComponent(() => import('./delisting/index.vue'))], // 摘牌
 ])
 
-const loginStore = useLoginStore()
+// const loginStore = useLoginStore()
 const futuresStore = useFuturesStore()
 const quote = futuresStore.getGoodsQuote(props.goodsId)
 const oem = service.getConfig('oem')
@@ -88,10 +88,10 @@ const sellColumns = shallowRef<Model.TableColumn[]>(
                        { field: 'orderqty', label: '卖量' }]
 )
 
-const showComponent = (componentName: string, row: Model.WrTradeOrderDetailRsp) => {
-    selectedRow.value = row
-    openComponent(componentName)
-}
+// const showComponent = (componentName: string, row: Model.WrTradeOrderDetailRsp) => {
+//     selectedRow.value = row
+//     openComponent(componentName)
+// }
 
 // 监听行情变动
 if (quote.value) {

+ 14 - 4
src/packages/pc/components/modules/quote/forex/index.vue

@@ -2,20 +2,30 @@
     <div class="app-quote-forex"  v-if="quote?.marketid != 99201">
         <ul class="top">
             <template v-for="(item, index) in sellList" :key="index">
-                <li :class="active === 'sell_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Sell, index)">
+                <li v-if="quote?.trademode != 10" 
+                    :class="active === 'sell_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Sell, index)" >
                     <span>{{ item.label }}</span>
                     <span :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
                     <span>{{ handleNumberValue(item.qty) }}</span>
                 </li>
+                <li v-else :class="active === 'sell_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Sell, index)">
+                    <span style="font-size: 20px;">{{ item.label }}</span>
+                    <span style="font-size: 20px;" :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
+                </li>
             </template>
         </ul>
         <ul class="bottom" v-if="quote">
             <template v-for="(item, index) in buyList" :key="index">
-                <li :class="active === 'buy_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Buy, index)">
+                <li v-if="quote?.trademode != 10" 
+                    :class="active === 'buy_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Buy, index)">
                     <span>{{ item.label }}</span>
                     <span :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
                     <span>{{ handleNumberValue(item.qty) }}</span>
                 </li>
+                <li v-else :class="active === 'buy_' + index ? 'is-active' : ''" @click="onPriceClick(BuyOrSell.Buy, index)">
+                    <span style="font-size: 20px;">{{ item.label }}</span>
+                    <span style="font-size: 20px;" :class="item.color">{{ handleNumberValue(item.price.toFixed(quote?.decimalplace)) }}</span>
+                </li>
             </template>
         </ul>
     </div>
@@ -48,7 +58,7 @@ const buyList = computed(() => {
         if (item) {
             const result = [
                 {
-                    label: '买',
+                    label: '买',
                     price: item.ask,
                     qty: item.askvolume,
                     color: item.askColor,
@@ -103,7 +113,7 @@ const sellList = computed(() => {
         if (item) {
             const result = [
                 {
-                    label: '卖',
+                    label: '卖',
                     price: item.bid,
                     qty: item.bidvolume,
                     color: item.bidColor,

+ 6 - 1
src/packages/pc/components/modules/quote/price/index.vue

@@ -6,9 +6,14 @@
                 <span>{{ quote.goodsname }}</span>
             </div>
             <div class="block-bottom">
-                <div class="block-bottom-left">
+                <div class="block-bottom-left" v-if="quote.trademode != 10">
                     <span :class="quote.lastColor">{{ handleNumberValue(quote.last.toFixed(quote.decimalplace)) }}</span>
                 </div>
+                <div class="block-bottom-left" v-els>
+                    <span :class="quote.askColor">{{ handleNumberValue(quote.ask.toFixed(quote.decimalplace)) }}</span>
+                    <span>{{ ' / ' }}</span>
+                    <span :class="quote.bidColor">{{ handleNumberValue(quote.bid.toFixed(quote.decimalplace)) }}</span>
+                </div>
                 <div class="block-bottom-right">
                     <span :class="quote.lastColor">{{ quote.rise.toFixed(quote.decimalplace) }}</span>
                     <span :class="quote.lastColor">{{ parsePercent(quote.change) }}</span>

+ 8 - 8
src/packages/pc/views/market/trade/pricing/list/listing/index.vue

@@ -27,14 +27,6 @@
                         </el-radio>
                     </el-radio-group>
                 </el-form-item>
-                <el-form-item prop="MarketMaxSub" label="点差" v-if="formData.PriceMode === PriceMode.Market">
-                    <el-input-number ref="priceRef" placeholder="请输入" :min="0" :max="9999999999" v-model="formData.MarketMaxSub" 
-                    @keyup.enter="submitFocus" integer />
-                </el-form-item>
-                <el-form-item prop="OrderPrice" label="价格" v-if="formData.PriceMode === PriceMode.Limit">
-                    <el-input-number ref="priceRef" placeholder="请输入" :max="9999999999" :min="0" v-model="formData.OrderPrice" 
-                     :auto-fixed="false" :decimal-length="decimalplace" :step="decimalvalue" @keyup.enter="submitFocus" />
-                </el-form-item>
                 <el-form-item prop="OrderQty" label="数量">
                     <div class="g-qty-group">
                         <el-input-number ref="qtyRef" placeholder="请输入" :min="0" :max="9999999999" :precision="0" :step="qtyStep || 1"
@@ -53,6 +45,14 @@
                         </template>
                     </div>
                 </el-form-item>
+                <el-form-item prop="MarketMaxSub" label="点差" v-if="formData.PriceMode === PriceMode.Market">
+                    <el-input-number ref="priceRef" placeholder="请输入" :min="0" :max="9999999999" v-model="formData.MarketMaxSub" 
+                    @keyup.enter="submitFocus" integer />
+                </el-form-item>
+                <el-form-item prop="OrderPrice" label="价格" v-if="formData.PriceMode === PriceMode.Limit">
+                    <el-input-number ref="priceRef" placeholder="请输入" :max="9999999999" :min="0" v-model="formData.OrderPrice" 
+                     :auto-fixed="false" :decimal-length="decimalplace" :step="decimalvalue" @keyup.enter="submitFocus" />
+                </el-form-item>
                 <el-form-item class="footer-btnbar">
                     <template v-if="formData.BuyOrSell === BuyOrSell.Buy">
                         <el-button ref="submitRef" type="danger" :disabled="!selectedGoodsId || !formData.OrderQty"

+ 1 - 0
src/services/bus/types.ts

@@ -14,6 +14,7 @@ export enum EventName {
     WRTradeDealedNtf, // 仓单贸易成交通知
     ListingOrderChangeNtf, // 挂牌委托变更广播通知
     OrderDealedNtf, // 成交通知
+    OrderSuccessedNtf, // 委托成功通知
     OrderRsp, // 委托回应通知
     PosChangedNtf, // 头寸变化通知
     RiskControlNtf, // 风控通知

+ 8 - 0
src/services/websocket/message.ts

@@ -46,6 +46,14 @@ export async function pushMessage50(pkg: Package50, contentType: 'encrypted' | '
             }, delay, funCode.toString())
             break
         }
+
+        case FunCode.OrderSuccessedNtf: {
+            timerInterceptor.debounce(() => {
+                // 成交通知
+                eventBus.$emit('OrderSuccessedNtf')
+            }, delay, funCode.toString())
+            break
+        }
         // case FunCode.MarketStatusChangeNtf: {
         //     // 运行状态 - 0:初始化 1:待开市 2:开市 3:休市 4:手工休市 5:闭市 6:确认行权开始 7:确认行权结束 10:日终处理开始 11:日终处理成功 12:日终处理失败 13基础服务结算开始 14基础服务结算成功 23.资金结算开始 24.资金结算成功 25.资金结算失败 26.系统结算成功 27.系统结算失败 28.盘中处理开始 29.盘中处理成功 30.盘中处理失败 31.资金结算开始(内) 32.资金结算成功(内) 33.资金结算失败(内) 40.签到开始 41.签到成功 42.签到部份成功 43.签到失败 44.签退开始 45.签退成功 46.签退部份成功 47.签退失败 48.对账开始 49.对账成功 50.对账失败 51.清算开始 52.清算成功 53.清算失败 54.清算部分成功 55. 系统结算开始 62.今日免清算
         //     try {

+ 2 - 1
src/types/model/order.d.ts

@@ -1003,7 +1003,8 @@ declare namespace Model {
         tradeproperty: number
         /// 占用保证金[商品币种]
         usedmargin: number
-        tacurrencyid: number; // 报价货币ID - taaccount
+        /// 报价货币ID - taaccount
+        tacurrencyid: number
     }
 
     /* 查询我的订单/历史成交 请求 */