li.shaoyi 3 周之前
父节点
当前提交
6f245a9ceb

+ 19 - 14
src/packages/digital/views/contract/components/position/list/index.vue

@@ -2,7 +2,7 @@
     <app-pull-refresh ref="pullRefreshRef" class="g-detail-table" v-model:loading="positionStore.loading"
         @refresh="onRefresh">
         <table cellspacing="0" cellpadding="0" v-for="(item, index) in dataList" :key="index">
-            <tbody @click="showComponent('Detail', item)">
+            <tbody @click="showComponent('Detail', index)">
                 <tr>
                     <th colspan="2">
                         <span>{{ item.goodscode }}/{{ item.goodsname }}</span>
@@ -13,7 +13,8 @@
                 </tr>
                 <tr>
                     <td colspan="2">
-                        <span class="text-small">{{ $t('account.profitLoss')+`(${ enumName(item.currencyid) })` }}</span>
+                        <span class="text-small">{{ $t('account.profitLoss') + `(${enumName(item.currencyid)})`
+                            }}</span>
                         <span :class="item.profitLossClass">
                             {{ item.profitLoss.toFixed(item.decimalplace) }}
                         </span>
@@ -26,27 +27,30 @@
                 </tr>
                 <tr>
                     <td>
-                        <span class="text-small">{{ $t('quote.spot.enableqty')+`(${item.goodscode})` }}</span>
+                        <span class="text-small">{{ $t('quote.spot.enableqty') + `(${item.goodscode})` }}</span>
                         <span>
                             {{ item.enableqty }}
                         </span>
                     </td>
                     <td>
-                        <span class="text-small">{{ $t('position.goods.curpositionqty')+`(${ item.goodscode })` }}</span>
+                        <span class="text-small">{{ $t('position.goods.curpositionqty') + `(${item.goodscode})`
+                            }}</span>
                         <span>{{ item.curpositionqty }}</span>
                     </td>
                     <td>
-                        <span class="text-small">{{ $t('position.goods.frozenqty')+`(${ item.goodscode })` }}</span>
+                        <span class="text-small">{{ $t('position.goods.frozenqty') + `(${item.goodscode})` }}</span>
                         <span>{{ item.frozenqty }}</span>
                     </td>
                 </tr>
                 <tr>
                     <td>
-                        <span class="text-small">{{ $t('position.goods.holderprice')+`(${ enumName(item.currencyid) })` }}</span>
+                        <span class="text-small">{{ $t('position.goods.holderprice') + `(${enumName(item.currencyid)})`
+                            }}</span>
                         <span>{{ item.averageprice }}</span>
                     </td>
                     <td>
-                        <span class="text-small">{{ $t('position.goods.holderamount')+`(${ enumName(item.currencyid) })` }}</span>
+                        <span class="text-small">{{ $t('position.goods.holderamount') + `(${enumName(item.currencyid)})`
+                            }}</span>
                         <span>{{ item.curholderamount }}</span>
                     </td>
                     <td></td>
@@ -55,14 +59,15 @@
             <tfoot>
                 <tr>
                     <td colspan="3">
-                        <Button size="small" @click="showComponent('Close', item)">{{ $t('operation.close') }}</Button>
-                        <Button size="small" @click="showComponent('MarketClose', item)">{{ $t('digital.marketclose') }}</Button>
-                        <Button size="small" @click="showComponent('TPSL', item)">止盈止损</Button>
+                        <Button size="small" @click="showComponent('Close', index)">{{ $t('operation.close') }}</Button>
+                        <Button size="small" @click="showComponent('MarketClose', index)">{{ $t('digital.marketclose')
+                            }}</Button>
+                        <Button size="small" @click="showComponent('TPSL', index)">止盈止损</Button>
                     </td>
                 </tr>
             </tfoot>
         </table>
-        <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)"
+        <component ref="componentRef" v-bind="{ selectedRow: dataList[rowIndex] }" :is="componentMap.get(componentId)"
             @closed="closeComponent" v-if="componentId" />
     </app-pull-refresh>
 </template>
@@ -93,7 +98,7 @@ const { componentRef, componentId, openComponent, closeComponent } = useComponen
 
 const positionStore = usePositionStore()
 const pullRefreshRef = shallowRef()
-const selectedRow = shallowRef<Model.TradePositionRsp>()
+const rowIndex = shallowRef(-1)
 
 const dataList = computed(() => positionStore.filterPositionList(props.params))
 
@@ -101,8 +106,8 @@ const enumName = (id: number) => {
     return getGoodsCurrencyItemName(id)
 }
 
-const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
-    selectedRow.value = row
+const showComponent = (componentName: string, index: number) => {
+    rowIndex.value = index
     openComponent(componentName)
 }
 

+ 199 - 0
src/packages/digital/views/contract/components/position/list/tpsl/index.vue

@@ -0,0 +1,199 @@
+<!-- 任务 #7273 -->
+<template>
+    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal">
+        <app-view class="g-form">
+            <template #header>
+                <app-navbar title="汇总平仓" @back="closed" />
+            </template>
+            <Form ref="formRef" class="g-form__container" @submit="onCloseSumit">
+                <CellGroup title="持仓信息" inset>
+                    <Cell title="代码/名称" :value="`${selectedRow.goodscode}/${selectedRow.goodsname}`" />
+                    <Cell title="持仓方向" :value="getBuyOrSellName(selectedRow.buyorsell, 1)" />
+                    <Cell :title="`持仓价格(${getGoodsCurrencyItemName(selectedRow.currencyid)})`"
+                        :value="selectedRow.averageprice" />
+                    <Cell :title="`持仓量(${selectedRow.goodscode})`" :value="selectedRow.curpositionqty" />
+                    <Cell :title="`冻结量(${selectedRow.goodscode})`" :value="selectedRow.frozenqty" />
+                    <Cell :title="`行情价格(${getGoodsCurrencyItemName(selectedRow.currencyid)})`">
+                        <template #value>
+                            <span :class="selectedRow.lastPriceClass">
+                                {{ selectedRow.lastPrice.toFixed(selectedRow.decimalplace) }}
+                            </span>
+                        </template>
+                    </Cell>
+                    <Cell :title="`浮动盈亏(${getGoodsCurrencyItemName(selectedRow.currencyid)})`">
+                        <template #value>
+                            <span :class="selectedRow.profitLossClass">
+                                {{ selectedRow.profitLoss.toFixed(selectedRow.decimalplace) }}
+                            </span>
+                        </template>
+                    </Cell>
+                </CellGroup>
+                <CellGroup title="止盈止损" inset>
+                    <Cell :value="`价格 (>=${pricePoints.takeProfit.toFixed(selectedRow.decimalplace)})`">
+                        <template #title>
+                            <Checkbox v-model="formData.TPFlag">止盈</Checkbox>
+                        </template>
+                    </Cell>
+                    <Field name="SpPrice" :rules="formRules.SpPrice">
+                        <template #input>
+                            <app-stepper v-model="formData.SpPrice" :min="pricePoints.takeProfit"
+                                :decimal-length="quote?.decimalplace" :step="quote?.decimalvalue" :button-size="32"
+                                :disabled="!formData.TPFlag" />
+                        </template>
+                    </Field>
+                </CellGroup>
+                <CellGroup inset>
+                    <Cell :value="`价格 (>=${pricePoints.stopLoss.toFixed(selectedRow.decimalplace)})`">
+                        <template #title>
+                            <Checkbox v-model="formData.SLFlag">止损</Checkbox>
+                        </template>
+                    </Cell>
+                    <Field name="SlPrice" :rules="formRules.SlPrice">
+                        <template #input>
+                            <app-stepper v-model="formData.SlPrice" :max="pricePoints.stopLoss"
+                                :decimal-length="quote?.decimalplace" :step="quote?.decimalvalue" :button-size="32"
+                                :disabled="!formData.SLFlag" />
+                        </template>
+                    </Field>
+                </CellGroup>
+            </Form>
+            <div class="g-form__footer inset">
+                <Button type="primary" @click="formRef?.submit()" block>提交</Button>
+            </div>
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, PropType, onMounted, computed } from 'vue'
+import { CellGroup, Cell, Button, FieldRule, Form, Field, FormInstance, Checkbox } from 'vant'
+import { dialog, fullloading } from '@/utils/vant'
+import { getBuyOrSellName, getGoodsCurrencyItemName, BuyOrSell } from '@/constants/order'
+import { useOrder } from '@/business/trade'
+import { useFuturesStore, useUserStore } from '@/stores'
+import { EBuildType, EDelistingType, EOrderOperateType, EListingSelectType, EPriceMode, EValidType } from '@/constants/client'
+import AppModal from '@/components/base/modal/index.vue'
+import AppStepper from '@mobile/components/base/stepper/index.vue'
+
+const props = defineProps({
+    selectedRow: {
+        type: Object as PropType<Model.TradePositionRsp & {
+            lastPrice: number;
+            lastPriceClass: string;
+            profitLoss: number;
+            profitLossClass: string;
+        }>,
+        required: true,
+    }
+})
+
+const userStore = useUserStore()
+const futuresStore = useFuturesStore()
+const formRef = shallowRef<FormInstance>()
+const showModal = shallowRef(true)
+
+const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedRow.goodsid }))
+
+const { formSubmit, formData } = useOrder()
+
+const pricePoints = computed(() => {
+    const { decimalplace = 0, buyslpoint, buytppoint, sellslpoint, selltppoint } = quote.value ?? {}
+    const { lastPrice, buyorsell } = props.selectedRow
+    const multiplier = Math.pow(10, decimalplace)
+
+    const price = {
+        takeProfit: lastPrice,
+        stopLoss: lastPrice,
+    }
+
+    if (buyorsell === BuyOrSell.Buy) {
+        if (buytppoint) {
+            const profitPoint = buytppoint / multiplier
+            price.takeProfit = lastPrice + profitPoint // 买止盈
+        }
+        if (buyslpoint) {
+            const lossPoint = buyslpoint / multiplier
+            price.stopLoss = lastPrice - lossPoint // 买止损
+        }
+    }
+
+    if (buyorsell === BuyOrSell.Sell) {
+        if (selltppoint) {
+            const profitPoint = selltppoint / multiplier
+            price.takeProfit = lastPrice - profitPoint // 卖止盈
+        }
+        if (sellslpoint) {
+            const lossPoint = sellslpoint / multiplier
+            price.stopLoss = lastPrice - lossPoint // 卖止损
+        }
+    }
+
+    return price
+})
+
+// 表单验证规则
+const formRules: { [key: string]: FieldRule[] } = {
+    SpPrice: [{
+        message: '请输入止盈价格',
+        validator: () => {
+            return !!formData.SpPrice
+        }
+    }],
+    SlPrice: [{
+        message: '请输入止损价格',
+        validator: () => {
+            return !!formData.SlPrice
+        }
+    }],
+}
+
+const onCloseSumit = () => {
+    dialog({
+        message: '确认要平仓吗?',
+        showCancelButton: true,
+    }).then(() => {
+
+        const { marketid, goodsid, buyorsell } = props.selectedRow
+        /// 市场ID
+        formData.Header = { GoodsID: goodsid }
+        formData.MarketID = marketid
+        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 = EOrderOperateType.ORDEROPERATETYPE_NORMAL
+        const param112 = userStore.getSystemParamValue('112')
+        formData.MarketMaxSub = Number(param112) || 100
+
+        /// loding....
+        fullloading((hideLoading) => {
+            formSubmit().then(() => {
+                hideLoading('提交成功', 'success')
+                closed()
+            }).catch((err) => {
+                hideLoading(err, 'fail')
+            })
+        })
+    })
+}
+
+// 关闭弹窗
+const closed = () => {
+    showModal.value = false
+}
+
+onMounted(() => {
+    formData.PriceMode = EPriceMode.PRICEMODE_MARKET
+    formData.OrderPrice = props.selectedRow.lastPrice
+    formData.OrderQty = props.selectedRow.enableqty
+    formData.SpPrice = pricePoints.value.takeProfit
+    formData.SlPrice = pricePoints.value.stopLoss
+})
+
+// 暴露组件属性给父组件调用
+defineExpose({
+    closed,
+})
+</script>

+ 2 - 3
src/packages/digital/views/wallet/components/spot/index.vue

@@ -1,7 +1,6 @@
 <!-- 现货-账户 -->
 <template>
     <div class="spot-account">
-        <Search shape="round" :placeholder="t('digital.search')" />
         <template v-for="(item, index) in spotAccountStore.dataList" :key="index">
             <div class="card" @click="onClick(item)">
                 <div class="card-section">
@@ -20,7 +19,7 @@
                 <div class="card-section">
                     <div class="card-section__balance">
                         <span>
-                            {{ t('digital.balance')+`(${item.currencycode})` }}
+                            {{ t('digital.balance') + `(${item.currencycode})` }}
                         </span>
                         <span class="text-small">
                             {{ formatDecimal(item.currentbalance, item.currencydecimalplace) }}
@@ -36,7 +35,7 @@
 </template>
 
 <script lang="ts" setup>
-import { Icon, Search } from 'vant'
+import { Icon } from 'vant'
 import { formatDecimal } from '@/filters'
 import { getDigitalCurrencyName } from '@/constants/order'
 import { useSpotAccountStore } from './composables'

+ 3 - 3
src/packages/digital/views/wallet/currency/index.vue

@@ -2,9 +2,9 @@
     <app-view>
         <template #header>
             <app-navbar :title="title">
-                <!-- <template #footer>
+                <template #footer>
                     <Search shape="round" :placeholder="t('digital.search')" />
-                </template> -->
+                </template>
             </app-navbar>
         </template>
         <spot-account @click="navigateTo" />
@@ -12,7 +12,7 @@
 </template>
 
 <script lang="ts" setup>
-// import { Search } from 'vant'
+import { Search } from 'vant'
 import { useNavigation } from '@mobile/router/navigation'
 import SpotAccount from '../components/spot/index.vue'
 import { i18n } from '@/stores'