li.shaoyi před 3 týdny
rodič
revize
1ba954ef25

+ 11 - 0
src/packages/digital/index.html

@@ -67,6 +67,17 @@
     </div>
   </div>
   <!-- built files will be auto injected -->
+  <!-- Start of LiveChat (www.livechat.com) code -->
+  <script>
+    window.__lc = window.__lc || {};
+    window.__lc.license = 19268010;
+    window.__lc.integration_name = "manual_channels";
+    window.__lc.product_name = "livechat";
+    ; (function (n, t, c) { function i(n) { return e._h ? e._h.apply(null, n) : e._q.push(n) } var e = { _q: [], _h: null, _v: "2.0", on: function () { i(["on", c.call(arguments)]) }, once: function () { i(["once", c.call(arguments)]) }, off: function () { i(["off", c.call(arguments)]) }, get: function () { if (!e._h) throw new Error("[LiveChatWidget] You can't use getters before load."); return i(["get", c.call(arguments)]) }, call: function () { i(["call", c.call(arguments)]) }, init: function () { var n = t.createElement("script"); n.async = !0, n.type = "text/javascript", n.src = "https://cdn.livechatinc.com/tracking.js", t.head.appendChild(n) } }; !n.__lc.asyncInit && e.init(), n.LiveChatWidget = n.LiveChatWidget || e }(window, document, [].slice))
+  </script>
+  <noscript><a href="https://www.livechat.com/chat-with/19268010/" rel="nofollow">Chat with us</a>, powered by <a
+      href="https://www.livechat.com/?welcome" rel="noopener nofollow" target="_blank">LiveChat</a></noscript>
+  <!-- End of LiveChat code -->
 </body>
 
 </html>

+ 3 - 1
src/packages/digital/views/contract/components/position/list/index.vue

@@ -29,7 +29,7 @@
                         <span class="text-small">{{ $t('quote.spot.enableqty')+`(${item.goodscode})` }}</span>
                         <span>
                             {{ item.enableqty }}
-                        </span>.
+                        </span>
                     </td>
                     <td>
                         <span class="text-small">{{ $t('position.goods.curpositionqty')+`(${ item.goodscode })` }}</span>
@@ -57,6 +57,7 @@
                     <td colspan="3">
                         <Button size="small" @click="showComponent('Close', item)">平仓</Button>
                         <Button size="small" @click="showComponent('MarketClose', item)">市价平仓</Button>
+                        <Button size="small" @click="showComponent('TPSL', item)">止盈止损</Button>
                     </td>
                 </tr>
             </tfoot>
@@ -84,6 +85,7 @@ const props = defineProps({
 const componentMap = new Map<string, unknown>([
     ['Close', defineAsyncComponent(() => import('./close/index.vue'))], // 平仓
     ['MarketClose', defineAsyncComponent(() => import('./market-close/index.vue'))], // 市价平仓
+    ['TPSL', defineAsyncComponent(() => import('./tpsl/index.vue'))], // 止盈止损
     ['Detail', defineAsyncComponent(() => import('../detail/index.vue'))], // 详情
 ])
 

+ 2 - 171
src/packages/digital/views/contract/goods/detail/index.vue

@@ -59,60 +59,6 @@
                 <Cell title="可开数量" :value="handleNoneValue(formatDecimal(calculations.maxBuyQty, 0))" />
                 <Cell title="预估手续费" :value="formatDecimal(calculations.buyEstimatedFee)" />
             </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">
@@ -137,7 +83,7 @@
 
 <script lang="ts" setup>
 import { shallowRef, computed, onMounted, onActivated } from 'vue'
-import { Form, FormInstance, Button, CellGroup, Field, Cell, Tab, Tabs, FieldRule, Col, Row, Slider, Checkbox } from 'vant'
+import { Form, FormInstance, Button, CellGroup, Field, Cell, Tab, Tabs, FieldRule, Col, Row } from 'vant'
 import { EValidType, EOrderOperateType, EBuildType } from '@/constants/client'
 import { formatDecimal, handleNoneValue, handleNumberValue, parsePercent } from '@/filters'
 import { useNavigation } from '@mobile/router/navigation'
@@ -161,13 +107,8 @@ const { global: { t } } = i18n
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 
-const accountStore = useAccountStore()
 const userStore = useUserStore()
-
 const { formData, formSubmit } = useOrder()
-const takeProfitRatio = shallowRef(0) // 止盈比例
-const stopLossRatio = shallowRef(0) // 止损比例
-const sliderStep = 0.01 // 滑块步长
 
 const { getSBYJMyOrders } = useSBYJOrderStore()
 const goods = computed(() => futuresStore.getGoods(goodsId ?? 0)) ?? {}
@@ -186,99 +127,6 @@ 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
-    }
-})
-
 // 可开数量(整数,向下取整):
 // 保证金设置(固定) 时:可开数量 = 可用余额 / (合约乘数 * 固定值)
 // 保证金设置(比率) 时:可开数量 = 可用余额 / (价格 * 合约乘数 * 比率值)
@@ -363,7 +211,7 @@ const onSubmit = () => {
         message: '确认要提交吗?',
         showCancelButton: true,
     }).then(() => {
-        const { marketid = 0, goodsid = 0, tpslflag = 0 } = quote.value ?? {}
+        const { marketid = 0, goodsid = 0 } = quote.value ?? {}
         /// 获取对应的市场ID
         formData.MarketID = marketid
         formData.GoodsID = goodsid
@@ -373,14 +221,6 @@ 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')
@@ -395,18 +235,9 @@ const onSubmit = () => {
 
 onMounted(() => {
     if (quote.value) {
-        const { tpslflag = 0, tpratiodefault = 0, slratiodefault = 0 } = quote.value ?? {}
-
         formData.BuyOrSell = BuyOrSell.Buy
         formData.PriceMode = PriceMode.Market
         formData.OrderPrice = formData.BuyOrSell === BuyOrSell.Buy ? quote.value.ask : quote.value.bid
-
-        if (tpslflag) {
-            formData.TPFlag = 1
-            formData.SLFlag = 1
-            takeProfitRatio.value = tpratiodefault * 100
-            stopLossRatio.value = slratiodefault * 100
-        }
     }
 
     onActivated(() => {

+ 1 - 3
src/packages/digital/views/setting/index.vue

@@ -48,13 +48,12 @@
 import { Cell, CellGroup } from 'vant'
 import { dialog } from '@/utils/vant'
 import { AuthStatus } from '@/constants/account'
-import { useUserStore, useLoginStore, useGlobalStore, i18n } from '@/stores'
+import { useUserStore, useGlobalStore, i18n } from '@/stores'
 import eventBus from '@/services/bus'
 import AppIconfont from '@/components/base/iconfont/index.vue'
 import AppLuanguage from '@mobile/components/modules/luanguage/index.vue'
 
 const globalStore = useGlobalStore()
-const loginStore = useLoginStore()
 const userStore = useUserStore()
 
 const { t } = i18n.global
@@ -64,7 +63,6 @@ const userLogout = () => {
         message: t('banksign.tips5'),
         showCancelButton: true,
     }).then(() => {
-        loginStore.clearAutoLoginData()
         eventBus.$emit('LogoutNotify')
     })
 }

+ 0 - 0
src/packages/mobile/components/modules/tpsl/index.less


+ 110 - 0
src/packages/mobile/components/modules/tpsl/index.vue

@@ -0,0 +1,110 @@
+<!-- 止盈止损 -->
+<template>
+    <div class="order-tpsl">
+        <div class="order-tpsl__tp">
+            <div class="left">
+                <Checkbox v-model="state.tpEnabled" :disabled="!!quote.tpslforceflag">{{
+                    $t('tss.tpspforceflag') }}
+                </Checkbox>
+            </div>
+            <div class="right">
+                <div class="right-top">
+                    <slot name="tp"></slot>
+                </div>
+                <div class="right-bottom">
+                    <Button size="small" icon="minus"
+                        :disabled="!state.tpEnabled || state.tpRatio <= profitLossLimits.minProfitRatio" round
+                        @click="sliderDecrease()" />
+                    <Slider v-model="state.tpRatio" :bar-height="6" :min="profitLossLimits.minProfitRatio"
+                        :max="profitLossLimits.maxProfitRatio" :step="state.sliderStep" :disabled="!state.tpEnabled" />
+                    <Button size="small" icon="plus"
+                        :disabled="!state.tpEnabled || state.tpRatio >= profitLossLimits.maxProfitRatio" round
+                        @click="sliderIncrease()" />
+                </div>
+            </div>
+        </div>
+        <div class="order-tpsl__sl">
+            <div class="left">
+                <Checkbox v-model="state.slEnabled" :disabled="!!quote.tpslforceflag">{{
+                    $t('tss.tpslforceflag') }}
+                </Checkbox>
+            </div>
+            <div class="right">
+                <div class="right-top">
+                    <slot name="sl"></slot>
+                </div>
+                <div class="right-bottom">
+                    <Button size="small" icon="minus"
+                        :disabled="!state.slEnabled || state.slRatio <= profitLossLimits.minLossRatio" round
+                        @click="sliderDecrease('sl')" />
+                    <Slider v-model="state.slRatio" :bar-height="6" :min="profitLossLimits.minLossRatio"
+                        :max="profitLossLimits.maxLossRatio" :step="state.sliderStep" :disabled="!state.slEnabled" />
+                    <Button size="small" icon="plus"
+                        :disabled="!state.slEnabled || state.slRatio >= profitLossLimits.maxLossRatio" round
+                        @click="sliderIncrease('sl')" />
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, PropType, computed } from 'vue'
+import { Button, Slider, Checkbox } from 'vant'
+import { TPSL } from './types'
+
+const props = defineProps({
+    modelValue: {
+        type: Object as PropType<TPSL>,
+        required: true
+    },
+    quote: {
+        type: Object as PropType<Model.GoodsQuote>,
+        required: true
+    }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const state = reactive<TPSL>({
+    tpEnabled: true,
+    tpRatio: 0, // 止盈比例
+    slEnabled: true,
+    slRatio: 0, // 止损比例
+    sliderStep: 0.01 // 滑块步长
+})
+
+// 盈亏比限制
+const profitLossLimits = computed(() => {
+    const { tpratioup, tpratiodown, slratioup, slratiodown } = props.quote
+    return {
+        maxProfitRatio: tpratioup * 100,
+        minProfitRatio: tpratiodown * 100,
+        maxLossRatio: slratioup * 100,
+        minLossRatio: slratiodown * 100
+    }
+})
+
+// 滑块增加
+const sliderIncrease = (actionName = 'tp') => {
+    if (actionName === 'tp') {
+        state.tpRatio += state.sliderStep
+    } else {
+        state.slRatio += state.sliderStep
+    }
+
+}
+
+// 滑块减少
+const sliderDecrease = (actionName = 'tp') => {
+    if (actionName === 'tp') {
+        state.tpRatio -= state.sliderStep
+    } else {
+        state.slRatio -= state.sliderStep
+    }
+}
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 7 - 0
src/packages/mobile/components/modules/tpsl/types.ts

@@ -0,0 +1,7 @@
+export interface TPSL {
+    tpEnabled: boolean, // 是否启用止盈
+    tpRatio: number, // 止盈比例
+    slEnabled: boolean, // 是否启用止损
+    slRatio: number, // 止损比例
+    sliderStep: number // 滑块步长
+}

+ 5 - 2
src/packages/mobile/views/user/cancel/Index.vue

@@ -23,7 +23,8 @@
 import { showFailToast, Button } from 'vant'
 import { fullloading, dialog } from '@/utils/vant'
 import { useAccountCancellation } from '@/business/user'
-import { i18n } from '@/stores';
+import { i18n } from '@/stores'
+import eventBus from '@/services/bus'
 
 const { formSubmit } = useAccountCancellation()
 
@@ -39,7 +40,9 @@ const onSubmit = () => {
         fullloading((hideLoading) => {
             formSubmit().then(() => {
                 hideLoading()
-                dialog(t('user.cancel.tips_7'))
+                dialog(t('user.cancel.tips_7')).then(() => {
+                    eventBus.$emit('LogoutNotify')
+                })
             }).catch((err) => {
                 showFailToast(err)
             })

+ 10 - 0
src/stores/modules/futures.ts

@@ -364,6 +364,11 @@ export const useFuturesStore = defineStore(() => {
             tpratioup: 1,
             basecurrencycode: '',
             quotecurrencycode: '',
+            buyslpoint: 0,
+            buytppoint: 0,
+            sellslpoint: 0,
+            selltppoint: 0,
+            riskcontrolmode: 1,
             traderules: [],
             tradefees: []
         }
@@ -418,6 +423,11 @@ export const useFuturesStore = defineStore(() => {
                     tpratioup: item.tpratioup,
                     basecurrencycode: item.basecurrencycode,
                     quotecurrencycode: item.quotecurrencycode,
+                    buyslpoint: item.buyslpoint,
+                    buytppoint: item.buytppoint,
+                    sellslpoint: item.sellslpoint,
+                    selltppoint: item.selltppoint,
+                    riskcontrolmode: item.riskcontrolmode
                 } = goods)
 
                 item.iscannotbuy = goods.iscannotbuy ?? 0

+ 4 - 0
src/types/model/goods.d.ts

@@ -18,6 +18,8 @@ declare namespace Model {
         buypricemovevalue: number; // 买交收升贴水值
         buyshippingfeealgorithm: number; // 买交收运费算法
         buyshippingfeevalue: number; // 买交收运费值
+        buyslpoint: number; // 买止损点差(按账户风控)
+        buytppoint: number; // 买止盈点差(按账户风控)
         canautoadddeposit: number; // 是否允许自动追加定金: 0-否 1-是(52)
         canautorefunddeposit: number; // 是否允许自动退还定金: 0-否 1-是(52)
         closepricemode: number; // 强平价格方式 - 1:市价 2:最新价 3:涨跌停(未实现)
@@ -70,6 +72,8 @@ declare namespace Model {
         sellpricemovevalue: number; // 卖交收升贴水值
         sellshippingfeealgorithm: number; // 卖交收运费算法
         sellshippingfeevalue: number; // 卖交收运费值
+        sellslpoint: number; // 卖止损点差(按账户风控)
+        selltppoint: number; // 卖止盈点差(按账户风控)
         slratiodefault: number; // 止损默认比例
         slratiodown: number; // 止损比例下限
         slratioup: number; // 止损比例上限

+ 5 - 0
src/types/model/market.d.ts

@@ -157,6 +157,11 @@ declare namespace Model {
         tpslforceflag: number; // 是否强制止盈止损 - 0:不强制 1:强制
         basecurrencycode: string; // 基础货币代码(80:Goodscurrencyid)
         quotecurrencycode: string; // 计价货币代码(80:currencyid)
+        buyslpoint: number; // 买止损点差(按账户风控)
+        buytppoint: number; // 买止盈点差(按账户风控)
+        sellslpoint: number; // 卖止损点差(按账户风控)
+        selltppoint: number; // 卖止盈点差(按账户风控)
+        riskcontrolmode: number; // 风控方式(52、10模式) 1:按单风控 2:按账户风控
         traderules: Proto.TradeRuleInfoStruct['TradeRules'] // 交易规则
         tradefees: Proto.TradeFeeInfoStruct['TradeFees'] // 交易费用
     }