Parcourir la source

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

li.shaoyi il y a 1 mois
Parent
commit
da5b4e02eb

+ 9 - 3
src/packages/digital/views/contract/components/order/index.vue

@@ -39,7 +39,7 @@
                     </tr>
                     <tr>
                         <td>
-                            <span class="text-small">委托价格(USDT)</span>
+                            <span class="text-small">委托价格({{ enumName(item.goodsid) }})</span>
                             <span>{{ formatDecimal(item.orderprice, item.decimalplace) }}</span>
                         </td>
                         <td>
@@ -84,7 +84,7 @@
                     </tr>
                     <tr>
                         <td>
-                            <span class="text-small">委托价格(USDT)</span>
+                            <span class="text-small">委托价格({{ enumName(item.goodsid) }})</span>
                             <span>{{ formatDecimal(item.orderprice, item.decimalplace) }}</span>
                         </td>
                         <td>
@@ -114,11 +114,12 @@ import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
 import { queryTradeOrderDetail, queryHisTradeOrderDetail } from '@/services/api/order'
 import { formatDate, formatDecimal } from '@/filters'
-import { getBuyOrSellName, getWRTradeOrderStatusName } from '@/constants/order'
+import { getBuyOrSellName, getGoodsCurrencyItemName, getWRTradeOrderStatusName } from '@/constants/order'
 import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
 import AppSelect from '@mobile/components/base/select/index.vue'
 import AppCalendar from '@mobile/components/base/calendar/index.vue'
 import eventBus from '@/services/bus'
+import { useFuturesStore } from '@/stores'
 
 const props = defineProps({
     goodsId: Number
@@ -173,6 +174,11 @@ const { loading: hisLoading, pageIndex: hisPageIndex, pageCount: hisPageCount, r
     }
 })
 
+const enumName = (id: string) => {
+    const { currencyid = 0 } = useFuturesStore().getGoods(id) ?? {}
+    return getGoodsCurrencyItemName(currencyid)
+}
+
 // 撤销
 const cancelOrder = (item: Model.TradeOrderDetailRsp) => {
     selectedRow.value = item

+ 173 - 4
src/packages/digital/views/contract/goods/detail/index.vue

@@ -61,6 +61,60 @@
                 <Cell title="可开数量" :value="calculations.sellQty" />
                 <Cell title="预估手续费" :value="formatDecimal(serivcefee)" />
             </CellGroup>
+            <!-- 任务 #7130 -->
+            <div class="order-tpsl" v-if="quote?.tpslflag">
+                <div class="order-tpsl__tp">
+                    <div class="left">
+                        <Checkbox v-model="formData.TPFlag" :disabled="!!quote.tpslforceflag">{{
+                            $t('tss.tpspforceflag') }}
+                        </Checkbox>
+                    </div>
+                    <div class="right">
+                        <div class="right-top">
+                            <span>{{ $t('tss.stopLossSpread') }}{{ (tpsl.takeProfitSpread > 0 ? '+' : '')
+                                + tpsl.takeProfitSpread.toFixed(quote.decimalplace) }}</span>
+                            <span class="g-price-up">[{{ takeProfitRatio.toFixed(2) }}%]</span>
+                            <span class="g-price-up">+{{ tpsl.takeProfit.toFixed(2) }}</span>
+                        </div>
+                        <div class="right-bottom">
+                            <Button size="small" icon="minus"
+                                :disabled="!formData.TPFlag || takeProfitRatio <= profitLossLimits.minProfitRatio" round
+                                @click="sliderDecrease()" />
+                            <Slider v-model="takeProfitRatio" :bar-height="6" :min="profitLossLimits.minProfitRatio"
+                                :max="profitLossLimits.maxProfitRatio" :step="sliderStep"
+                                :disabled="!formData.TPFlag" />
+                            <Button size="small" icon="plus"
+                                :disabled="!formData.TPFlag || takeProfitRatio >= profitLossLimits.maxProfitRatio" round
+                                @click="sliderIncrease()" />
+                        </div>
+                    </div>
+                </div>
+                <div class="order-tpsl__sl">
+                    <div class="left">
+                        <Checkbox v-model="formData.SLFlag" :disabled="!!quote?.tpslforceflag">{{
+                            $t('tss.tpslforceflag') }}
+                        </Checkbox>
+                    </div>
+                    <div class="right">
+                        <div class="right-top">
+                            <span>{{ $t('tss.stopLossSpread') }}{{ (tpsl.stopLossSpread > 0 ? '+' : '')
+                                + tpsl.stopLossSpread.toFixed(quote.decimalplace) }}</span>
+                            <span class="g-price-down">[{{ stopLossRatio.toFixed(2) }}%]</span>
+                            <span class="g-price-down">{{ tpsl.stopLoss.toFixed(2) }}</span>
+                        </div>
+                        <div class="right-bottom">
+                            <Button size="small" icon="minus"
+                                :disabled="!formData.SLFlag || stopLossRatio <= profitLossLimits.minLossRatio" round
+                                @click="sliderDecrease('sl')" />
+                            <Slider v-model="stopLossRatio" :bar-height="6" :min="profitLossLimits.minLossRatio"
+                                :max="profitLossLimits.maxLossRatio" :step="sliderStep" :disabled="!formData.SLFlag" />
+                            <Button size="small" icon="plus"
+                                :disabled="!formData.SLFlag || stopLossRatio >= profitLossLimits.maxLossRatio" round
+                                @click="sliderIncrease('sl')" />
+                        </div>
+                    </div>
+                </div>
+            </div>
         </Form>
         <Row class="g-layout-block g-layout-block--inset">
             <Col span="24">
@@ -83,7 +137,7 @@
 
 <script lang="ts" setup>
 import { shallowRef, computed, onMounted } from 'vue'
-import { Form, FormInstance, Button, CellGroup, Field, Cell, Tab, Tabs, FieldRule, Col, Row } from 'vant'
+import { Form, FormInstance, Button, CellGroup, Field, Cell, Tab, Tabs, FieldRule, Col, Row, Slider, Checkbox } from 'vant'
 import { EPriceMode, EValidType, EOrderOperateType, EBuildType } from '@/constants/client'
 import { formatDecimal, parsePercent } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
@@ -105,10 +159,14 @@ const tabIndex = shallowRef(0)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 
+const accountStore = useAccountStore()
 const userStore = useUserStore()
-const taAccountStore = useAccountStore()
 
 const { formData, formSubmit } = useOrder()
+const takeProfitRatio = shallowRef(0) // 止盈比例
+const stopLossRatio = shallowRef(0) // 止损比例
+const sliderStep = 0.01 // 滑块步长
+
 const { getSBYJMyOrders } = useSBYJOrderStore()
 const quote = computed(() => futuresStore.getQuoteInfo({ goodsid: goodsId }))
 const goods = computed(() => futuresStore.getGoods(goodsId ?? 0 )) ?? {}
@@ -125,6 +183,100 @@ const enumName = computed(() => {
     return getGoodsCurrencyItemName(quote.value?.currencyid ?? 0)
 })
 
+// 计算市价
+const marketPrice = computed(() => {
+    const { ask = 0, bid = 0 } = quote.value ?? {}
+    return formData.BuyOrSell === BuyOrSell.Buy ? ask : bid
+})
+
+// 预付款
+const usedMargin = computed(() => {
+    const { avaiableBalance = 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 * marketPrice.value
+
+    if (fixed && ratio) {
+        const { OrderQty = 0 } = formData
+        if (marketmarginalgorithm === 1) {
+            const qty = Math.trunc(avaiableBalance / ratio)
+            result.deposit = OrderQty * ratio
+            result.enableQty = qty > 0 ? qty : 0
+        }
+        if (marketmarginalgorithm === 2) {
+            const qty = Math.trunc(avaiableBalance / fixed)
+            result.deposit = OrderQty * fixed
+            result.enableQty = qty > 0 ? qty : 0
+        }
+    }
+    return result
+})
+
+// 计算盈亏 
+const calcProfitLoss = (ratio: number, profitLoss: 1 | -1) => usedMargin.value.deposit * (ratio / 100) * profitLoss
+
+// 计算价差
+const calcSpread = (value: number, profitLoss: 1 | -1) => {
+    const { agreeunit = 0, decimalplace = 0 } = quote.value ?? {}
+    const { OrderQty = 0 } = formData
+    const spread = value / (OrderQty * agreeunit)
+    const multiplier = Math.pow(10, decimalplace) // 小数位n次方
+    const roundedSpread = profitLoss === 1 ? Math.ceil(spread * multiplier) : Math.floor(spread * multiplier) // 取整
+    return roundedSpread / multiplier // * (props.orderType === 2 ? 1 : -1)
+}
+
+// 盈亏比限制
+const profitLossLimits = computed(() => {
+    const { tpratioup = 0, tpratiodown = 0, slratioup = 0, slratiodown = 0 } = quote.value ?? {}
+    return {
+        maxProfitRatio: tpratioup * 100,
+        minProfitRatio: tpratiodown * 100,
+        maxLossRatio: slratioup * 100,
+        minLossRatio: slratiodown * 100
+    }
+})
+
+// 滑块增加
+const sliderIncrease = (actionName = 'tp') => {
+    if (actionName === 'tp') {
+        takeProfitRatio.value += sliderStep
+    } else {
+        stopLossRatio.value += sliderStep
+    }
+
+}
+
+// 滑块减少
+const sliderDecrease = (actionName = 'tp') => {
+    if (actionName === 'tp') {
+        takeProfitRatio.value -= sliderStep
+    } else {
+        stopLossRatio.value -= sliderStep
+    }
+}
+
+// 止盈止损
+const tpsl = computed(() => {
+    const takeProfit = calcProfitLoss(takeProfitRatio.value, 1) // 盈利
+    const takeProfitSpread = calcSpread(takeProfit, 1) // 止盈价差
+    const stopLoss = calcProfitLoss(stopLossRatio.value, -1) // 亏损
+    const stopLossSpread = calcSpread(stopLoss, -1) // 止损价差
+
+    return {
+        takeProfit,
+        takeProfitSpread,
+        stopLoss,
+        stopLossSpread
+    }
+})
+
 // const spotAccountStore = useSpotAccountStore()
 // const baseAccount = computed(() => spotAccountStore.getAccountItem({ currencyid: quote.value?.goodscurrencyid })) // 基础货币账户
 // const quoteAccount = computed(() => spotAccountStore.getAccountItem({ currencyid: quote.value?.currencyid })) // 计价货币账户
@@ -152,7 +304,7 @@ const calculations = computed(() => {
     const { last = 0, agreeunit = 0 } = quote.value ?? {}
     const { OrderPrice = 0, OrderQty = 0 } = formData
 
-    const { balance = 0.0 } = taAccountStore.currentAccount
+    const { balance = 0.0 } = accountStore.currentAccount
 
     const price = formData.PriceMode === EPriceMode.PRICEMODE_MARKET ? last : OrderPrice
 
@@ -246,7 +398,7 @@ const onSubmit = () => {
     // const margin = `预付定金:${formatDecimal(marginalgorithm === 1 ? totalamount*transferdepositratio : orderQty.value*transferdepositratio)}\n`
     // const message = orderPrice + qty + orderamount + margin
 
-    const { marketid = 0, goodsid = 0 } = quote.value ?? {}
+    const { marketid = 0, goodsid = 0, tpslflag = 0 } = quote.value ?? {}
     dialog({
         message: '确认要提交吗?',
         showCancelButton: true,
@@ -260,6 +412,14 @@ const onSubmit = () => {
         const param112 = userStore.getSystemParamValue('112')
         formData.MarketMaxSub = Number(param112) || 100
 
+        // 止盈止损
+        if (tpslflag) {
+            formData.TPRatio = formData.TPFlag ? takeProfitRatio.value / 100 : 0
+            formData.SLRatio = formData.SLFlag ? stopLossRatio.value / 100 : 0
+            formData.TPFlag = Number(formData.TPFlag)
+            formData.SLFlag = Number(formData.SLFlag)
+        }
+
         fullloading((hideLoading) => {
             formSubmit().then(() => {
                 hideLoading('提交成功。', 'success')
@@ -274,10 +434,19 @@ const onSubmit = () => {
 
 onMounted(() => {
     if (quote.value) {
+        const { tpslflag = 0, tpratiodefault = 0, slratiodefault = 0 } = quote.value ?? {}
+
         formData.BuyOrSell = BuyOrSell.Buy
         formData.PriceMode = EPriceMode.PRICEMODE_MARKET
         formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? quote.value.ask : quote.value.bid
         formData.PriceMode = EPriceMode.PRICEMODE_MARKET
+
+        if (tpslflag) {
+            formData.TPFlag = 1
+            formData.SLFlag = 1
+            takeProfitRatio.value = tpratiodefault * 100
+            stopLossRatio.value = slratiodefault * 100
+        }
     }
 })
 </script>