li.shaoyi 2 سال پیش
والد
کامیت
00ecfba272
31فایلهای تغییر یافته به همراه220 افزوده شده و 509 حذف شده
  1. 6 3
      src/business/login/index.ts
  2. 26 0
      src/business/position/index.ts
  3. 6 5
      src/packages/gstj/components/base/pull-refresh/index.vue
  4. 4 15
      src/packages/gstj/views/goods/detail/Index.vue
  5. 4 16
      src/packages/gstj/views/goods/detail/components/listing/Index.vue
  6. 4 17
      src/packages/gstj/views/goods/trade/components/delisting/index.vue
  7. 17 50
      src/packages/gstj/views/order/position/components/goods/list/Index.vue
  8. 6 5
      src/packages/mobile/components/base/pull-refresh/index.vue
  9. 4 15
      src/packages/mobile/views/goods/detail/Index.vue
  10. 4 16
      src/packages/mobile/views/goods/detail/components/listing/Index.vue
  11. 4 17
      src/packages/mobile/views/goods/trade/components/delisting/index.vue
  12. 17 50
      src/packages/mobile/views/order/position/components/goods/list/Index.vue
  13. 9 23
      src/packages/mobile/views/order/position/components/pricing/list/Index.vue
  14. 14 35
      src/packages/mobile/views/order/position/components/swap/list/Index.vue
  15. 4 21
      src/packages/pc/components/modules/listing/index.vue
  16. 6 6
      src/packages/pc/components/modules/quote/price/index.less
  17. 2 2
      src/packages/pc/views/footer/goods/position/components/transfer/index.vue
  18. 14 32
      src/packages/pc/views/footer/goods/position/index.vue
  19. 4 17
      src/packages/pc/views/market/trade/goods/detail/components/order/delisting/index.vue
  20. 6 5
      src/packages/qxst/components/base/pull-refresh/index.vue
  21. 4 15
      src/packages/qxst/views/goods/detail/Index.vue
  22. 4 16
      src/packages/qxst/views/goods/detail/components/listing/Index.vue
  23. 4 17
      src/packages/qxst/views/goods/trade/components/delisting/index.vue
  24. 17 50
      src/packages/qxst/views/order/position/components/goods/list/Index.vue
  25. 6 5
      src/packages/sbyj/components/base/pull-refresh/index.vue
  26. 1 1
      src/services/http/index.ts
  27. 2 1
      src/stores/index.ts
  28. 17 17
      src/stores/modules/login.ts
  29. 2 21
      src/stores/modules/position.ts
  30. 1 1
      src/utils/h5plus/index.ts
  31. 1 15
      src/utils/vant/index.ts

+ 6 - 3
src/business/login/index.ts

@@ -1,7 +1,7 @@
 import { shallowRef, reactive } from 'vue'
 import { timerTask } from '@/utils/timer'
 import { login, logout } from '@/services/api/account'
-import { useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore } from '@/stores'
+import { useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore, usePositionStore } from '@/stores'
 import service from '@/services'
 import tradeSocket from '@/services/websocket/trade'
 import quoteSocket from '@/services/websocket/quote'
@@ -21,14 +21,15 @@ export function useLogin(persist = false) {
     const userStore = useUserStore()
     const accountStore = useAccountStore()
     const futuresStore = useFuturesStore()
+    const positionStore = usePositionStore()
 
-    const { logining, token, clientType } = loginStore.$toRefs()
+    const { logining, token } = loginStore.$toRefs()
 
     const remember = shallowRef(true) // 记住账号
     const formData = reactive<Model.LoginReq>({
         userName: localStorage.getItem('muchinfo_loginId') ?? '',
         password: '',
-        clientType: clientType.value,
+        clientType: 0,
     })
 
     const loadBaseData = async () => {
@@ -46,6 +47,7 @@ export function useLogin(persist = false) {
             accountStore.getAccountList(),
         ])
         futuresStore.getGoodsList()
+        positionStore.getTradePosition()
         tradeSocket.connect()
         quoteSocket.connect()
         checkTokenLoop()
@@ -66,6 +68,7 @@ export function useLogin(persist = false) {
                     }
                 } else {
                     const params = { ...formData }
+                    params.clientType = loginStore.getClientType()
                     params.password = encryptBody(formData.password)
                     resolve(params)
                 }

+ 26 - 0
src/business/position/index.ts

@@ -0,0 +1,26 @@
+import { computed } from 'vue'
+import { BuyOrSell } from '@/constants/order'
+import { usePositionStore } from '@/stores'
+
+/**
+ * 持仓业务
+ * @param tradeMode 交易模式
+ * @returns 
+ */
+export const usePosition = (tradeMode = 0) => {
+    const store = usePositionStore()
+
+    const positionList = computed(() => store.orderPositionComputedList.filter((e) => tradeMode ? e.trademode === tradeMode : true))
+
+    // 获取持仓数量
+    const getOrderQty = (buyOrSell: BuyOrSell, code?: string | number) => {
+        const item = positionList.value.find((e) => (e.goodscode === code || e.goodsid === code) && e.buyorsell === buyOrSell)
+        return item?.enableqty ?? 0
+    }
+
+    return {
+        ...store.$toRefs(),
+        positionList,
+        getOrderQty
+    }
+}

+ 6 - 5
src/packages/gstj/components/base/pull-refresh/index.vue

@@ -49,6 +49,7 @@ const emit = defineEmits(['update:loading', 'update:pageIndex', 'update:error',
 const listRef = shallowRef<ListInstance>()
 const refreshing = shallowRef(false) // 是否处于下拉加载状态
 const finished = shallowRef(false) // 是否已加载完成所有数据
+const currentPage = shallowRef(props.pageIndex)
 
 const showLoading = computed({
     get: () => props.loading,
@@ -60,13 +61,9 @@ const showError = computed({
     set: (val) => emit('update:error', val)
 })
 
-const currentPage = computed({
-    get: () => props.pageIndex,
-    set: (val) => emit('update:pageIndex', val)
-})
-
 // 上拉加载
 const onLoad = () => {
+    showLoading.value = false
     if (refreshing.value) {
         currentPage.value = 1
     }
@@ -99,6 +96,10 @@ watch(showLoading, (status) => {
     }
 })
 
+watch(currentPage, (val) => {
+    emit('update:pageIndex', val)
+})
+
 // 暴露组件属性给父组件调用
 defineExpose({
     refresh: () => {

+ 4 - 15
src/packages/gstj/views/goods/detail/Index.vue

@@ -25,9 +25,8 @@ import { Button } from 'vant'
 import { useNavigation } from '../../../router/navigation'
 import { useComponent } from '@/hooks/component'
 import { EBuildType } from '@/constants/client'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import { useFuturesStore } from '@/stores'
+import { usePosition } from '@/business/position'
 
 const Price = defineAsyncComponent(() => import('../../../components/modules/quote/price/index.vue'))
 const Chart = defineAsyncComponent(() => import('../../../components/modules/quote/chart/index.vue'))
@@ -38,14 +37,15 @@ const componentMap = new Map<string, unknown>([
     ['listing', defineAsyncComponent(() => import('./components/listing/Index.vue'))],
 ])
 
+const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
 const quote = futuresStore.getQuoteInfo(goodsid)
+const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')
-const buildType = shallowRef<EBuildType>() // 挂牌类型
-const isDisabledClose = shallowRef(true)
+const isDisabledClose = computed(() => !positionList.value.some((e) => e.goodsid === goodsid))
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
@@ -53,15 +53,4 @@ const onListing = (type: EBuildType) => {
     buildType.value = type
     openComponent('listing')
 }
-
-useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (res.data.some((e) => e.goodsid === goodsid)) {
-            isDisabledClose.value = false
-        }
-    }
-})
 </script>

+ 4 - 16
src/packages/gstj/views/goods/detail/components/listing/Index.vue

@@ -64,8 +64,7 @@ import { Form, FormInstance, Button, CellGroup, FieldRule, Field, Stepper, Radio
 import { fullloading, dialog } from '@/utils/vant'
 import { BuyOrSell } from '@/constants/order'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EPriceMode, EListingSelectType, EDelistingType, EBuildType, EValidType, EOrderOperateType } from '@/constants/client'
 import AppModal from '@/components/base/modal/index.vue'
@@ -84,6 +83,7 @@ const props = defineProps({
     }
 })
 
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
@@ -94,12 +94,6 @@ const refresh = shallowRef(true) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 价格步长
 const priceStep = computed(() => {
     const { quoteminunit = 0, decimalplace = 0 } = quote.value ?? {}
@@ -110,16 +104,10 @@ const priceStep = computed(() => {
 })
 
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.goodsCode))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.goodsCode))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {

+ 4 - 17
src/packages/gstj/views/goods/trade/components/delisting/index.vue

@@ -82,8 +82,7 @@ import { BuyOrSell, getBuyOrSellName } from '@/constants/order'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EBuildType, EDelistingType, EListingSelectType, EOrderOperateType, EPriceMode, EValidType } from '@/constants/client'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import AppModal from '@/components/base/modal/index.vue'
 
 const props = defineProps({
@@ -95,6 +94,7 @@ const props = defineProps({
 
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
 const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
@@ -104,23 +104,11 @@ const refresh = shallowRef(false) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.selectedRow.goodsid))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.selectedRow.goodsid))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
@@ -142,7 +130,6 @@ const onSubmit = () => {
         message: '确认要提交吗?',
         showCancelButton: true,
     }).then(() => {
-
         const { goodsid, orderid, orderprice, buyorsell } = props.selectedRow
         const { marketid = 0 } = quote.value ?? {}
 

+ 17 - 50
src/packages/gstj/views/order/position/components/goods/list/Index.vue

@@ -1,23 +1,20 @@
 <!-- 我的持仓-订单持仓 -->
 <template>
-    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-        :page-count="pageCount" @refresh="run">
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" @refresh="onRefresh">
         <div class="g-order-list">
-            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+            <div class="g-order-list__box" v-for="(item, index) in positionList" :key="index">
                 <div class="g-order-list__titlebar">
                     <div class="left">
                         <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
                     </div>
                     <div class="right">
-                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">{{ getBuyOrSellName(item.buyorsell)
-                        }}</span>
+                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">
+                            {{ getBuyOrSellName(item.buyorsell) }}
+                        </span>
                     </div>
                 </div>
                 <div class="g-order-list__content">
                     <ul>
-                        <li :class="lastColor(item.goodscode)">{{ last(item.goodscode) }}</li>
-                    </ul>
-                    <ul>
                         <li>
                             <span>持有数量</span>
                             <span>{{ formatDecimal(item.curpositionqty) }}</span>
@@ -40,8 +37,9 @@
                         </li>
                         <li>
                             <span>参考损益</span>
-                            <span :class="getAmountColor(closepl(item))">{{ formatDecimal(closepl(item))
-                            }}</span>
+                            <span :class="handlePriceColor(item.closepl, 0)">
+                                {{ formatDecimal(item.closepl) }}
+                            </span>
                         </li>
                     </ul>
                 </div>
@@ -60,60 +58,29 @@
 import { shallowRef, defineAsyncComponent } from 'vue'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import AppPullRefresh from '../../../../../../components/base/pull-refresh/index.vue'
-import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
-import { formatDecimal, handleNumberValue } from '@/filters'
-import { useFuturesStore } from '@/stores'
-import { getAmountColor } from '@/utils/vant';
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, handleNumberValue, handlePriceColor } from '@/filters'
+import { usePosition } from '@/business/position'
+import eventBus from '@/services/bus'
 
 const componentMap = new Map<string, unknown>([
     ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
     ['delivery', defineAsyncComponent(() => import('../delivery/Index.vue'))]
 ])
 
-const futuresStore = useFuturesStore()
-
-const dataList = shallowRef<Model.TradePositionRsp[]>([])
+const { positionList, loading } = usePosition(50)
 const selectedRow = shallowRef<Model.TradePositionRsp>()
-const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 
-const last = (goodsCode: string) => {
-    return futuresStore.getQuotePrice(goodsCode)
-}
-
-const lastColor = (goodsCode: string) => {
-    return futuresStore.getQuoteInfo(goodsCode).value?.lastColor
-}
-
-/// 计算参考损益
-const closepl = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    const { curpositionqty, curholderamount, agreeunit, buyorsell } = item
-    return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
-}
-
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
     pullRefreshRef.value?.refresh()
 })
 
-const { loading, pageIndex, pageCount, run } = useRequest(queryTradePosition, {
-    params: {
-        pagesize: 20,
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
+// 通知持仓列表刷新
+const onRefresh = () => {
+    eventBus.$emit('PosChangedNtf')
+}
 
 const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
     selectedRow.value = row

+ 6 - 5
src/packages/mobile/components/base/pull-refresh/index.vue

@@ -49,6 +49,7 @@ const emit = defineEmits(['update:loading', 'update:pageIndex', 'update:error',
 const listRef = shallowRef<ListInstance>()
 const refreshing = shallowRef(false) // 是否处于下拉加载状态
 const finished = shallowRef(false) // 是否已加载完成所有数据
+const currentPage = shallowRef(props.pageIndex)
 
 const showLoading = computed({
     get: () => props.loading,
@@ -60,13 +61,9 @@ const showError = computed({
     set: (val) => emit('update:error', val)
 })
 
-const currentPage = computed({
-    get: () => props.pageIndex,
-    set: (val) => emit('update:pageIndex', val)
-})
-
 // 上拉加载
 const onLoad = () => {
+    showLoading.value = false
     if (refreshing.value) {
         currentPage.value = 1
     }
@@ -99,6 +96,10 @@ watch(showLoading, (status) => {
     }
 })
 
+watch(currentPage, (val) => {
+    emit('update:pageIndex', val)
+})
+
 // 暴露组件属性给父组件调用
 defineExpose({
     refresh: () => {

+ 4 - 15
src/packages/mobile/views/goods/detail/Index.vue

@@ -25,9 +25,8 @@ import { Button } from 'vant'
 import { useNavigation } from '../../../router/navigation'
 import { useComponent } from '@/hooks/component'
 import { EBuildType } from '@/constants/client'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import { useFuturesStore } from '@/stores'
+import { usePosition } from '@/business/position'
 
 const Price = defineAsyncComponent(() => import('../../../components/modules/quote/price/index.vue'))
 const Chart = defineAsyncComponent(() => import('../../../components/modules/quote/chart/index.vue'))
@@ -38,14 +37,15 @@ const componentMap = new Map<string, unknown>([
     ['listing', defineAsyncComponent(() => import('./components/listing/Index.vue'))],
 ])
 
+const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
 const quote = futuresStore.getQuoteInfo(goodsid)
+const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')
-const buildType = shallowRef<EBuildType>() // 挂牌类型
-const isDisabledClose = shallowRef(true)
+const isDisabledClose = computed(() => !positionList.value.some((e) => e.goodsid === goodsid))
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
@@ -53,15 +53,4 @@ const onListing = (type: EBuildType) => {
     buildType.value = type
     openComponent('listing')
 }
-
-useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (res.data.some((e) => e.goodsid === goodsid)) {
-            isDisabledClose.value = false
-        }
-    }
-})
 </script>

+ 4 - 16
src/packages/mobile/views/goods/detail/components/listing/Index.vue

@@ -64,8 +64,7 @@ import { Form, FormInstance, Button, CellGroup, FieldRule, Field, Stepper, Radio
 import { fullloading, dialog } from '@/utils/vant'
 import { BuyOrSell } from '@/constants/order'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EPriceMode, EListingSelectType, EDelistingType, EBuildType, EValidType, EOrderOperateType } from '@/constants/client'
 import AppModal from '@/components/base/modal/index.vue'
@@ -84,6 +83,7 @@ const props = defineProps({
     }
 })
 
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
@@ -94,12 +94,6 @@ const refresh = shallowRef(true) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 价格步长
 const priceStep = computed(() => {
     const { quoteminunit = 0, decimalplace = 0 } = quote.value ?? {}
@@ -110,16 +104,10 @@ const priceStep = computed(() => {
 })
 
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.goodsCode))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.goodsCode))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {

+ 4 - 17
src/packages/mobile/views/goods/trade/components/delisting/index.vue

@@ -82,8 +82,7 @@ import { BuyOrSell, getBuyOrSellName } from '@/constants/order'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EBuildType, EDelistingType, EListingSelectType, EOrderOperateType, EPriceMode, EValidType } from '@/constants/client'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import AppModal from '@/components/base/modal/index.vue'
 
 const props = defineProps({
@@ -95,6 +94,7 @@ const props = defineProps({
 
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
 const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
@@ -104,23 +104,11 @@ const refresh = shallowRef(false) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.selectedRow.goodsid))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.selectedRow.goodsid))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
@@ -142,7 +130,6 @@ const onSubmit = () => {
         message: '确认要提交吗?',
         showCancelButton: true,
     }).then(() => {
-
         const { goodsid, orderid, orderprice, buyorsell } = props.selectedRow
         const { marketid = 0 } = quote.value ?? {}
 

+ 17 - 50
src/packages/mobile/views/order/position/components/goods/list/Index.vue

@@ -1,23 +1,20 @@
 <!-- 我的持仓-订单持仓 -->
 <template>
-    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-        :page-count="pageCount" @refresh="run">
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" @refresh="onRefresh">
         <div class="g-order-list">
-            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+            <div class="g-order-list__box" v-for="(item, index) in positionList" :key="index">
                 <div class="g-order-list__titlebar">
                     <div class="left">
                         <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
                     </div>
                     <div class="right">
-                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">{{ getBuyOrSellName(item.buyorsell)
-                        }}</span>
+                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">
+                            {{ getBuyOrSellName(item.buyorsell) }}
+                        </span>
                     </div>
                 </div>
                 <div class="g-order-list__content">
                     <ul>
-                        <li :class="lastColor(item.goodscode)">{{ last(item.goodscode) }}</li>
-                    </ul>
-                    <ul>
                         <li>
                             <span>持有数量</span>
                             <span>{{ formatDecimal(item.curpositionqty) }}</span>
@@ -40,8 +37,9 @@
                         </li>
                         <li>
                             <span>参考损益</span>
-                            <span :class="getAmountColor(closepl(item))">{{ formatDecimal(closepl(item))
-                            }}</span>
+                            <span :class="handlePriceColor(item.closepl, 0)">
+                                {{ formatDecimal(item.closepl) }}
+                            </span>
                         </li>
                     </ul>
                 </div>
@@ -60,60 +58,29 @@
 import { shallowRef, defineAsyncComponent } from 'vue'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import AppPullRefresh from '../../../../../../components/base/pull-refresh/index.vue'
-import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
-import { formatDecimal, handleNumberValue } from '@/filters'
-import { useFuturesStore } from '@/stores'
-import { getAmountColor } from '@/utils/vant';
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, handleNumberValue, handlePriceColor } from '@/filters'
+import { usePosition } from '@/business/position'
+import eventBus from '@/services/bus'
 
 const componentMap = new Map<string, unknown>([
     ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
     ['delivery', defineAsyncComponent(() => import('../delivery/Index.vue'))]
 ])
 
-const futuresStore = useFuturesStore()
-
-const dataList = shallowRef<Model.TradePositionRsp[]>([])
+const { positionList, loading } = usePosition(50)
 const selectedRow = shallowRef<Model.TradePositionRsp>()
-const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 
-const last = (goodsCode: string) => {
-    return futuresStore.getQuotePrice(goodsCode)
-}
-
-const lastColor = (goodsCode: string) => {
-    return futuresStore.getQuoteInfo(goodsCode).value?.lastColor
-}
-
-/// 计算参考损益
-const closepl = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    const { curpositionqty, curholderamount, agreeunit, buyorsell } = item
-    return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
-}
-
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
     pullRefreshRef.value?.refresh()
 })
 
-const { loading, pageIndex, pageCount, run } = useRequest(queryTradePosition, {
-    params: {
-        pagesize: 20,
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
+// 通知持仓列表刷新
+const onRefresh = () => {
+    eventBus.$emit('PosChangedNtf')
+}
 
 const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
     selectedRow.value = row

+ 9 - 23
src/packages/mobile/views/order/position/components/pricing/list/Index.vue

@@ -1,9 +1,8 @@
 <!-- 我的持仓-挂牌点价持仓 -->
 <template>
-    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-        :page-count="pageCount" @refresh="run">
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" @refresh="onRefresh">
         <div class="g-order-list">
-            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+            <div class="g-order-list__box" v-for="(item, index) in positionList" :key="index">
                 <div class="g-order-list__titlebar">
                     <div class="left">
                         <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
@@ -57,13 +56,13 @@
 import { shallowRef } from 'vue'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import AppPullRefresh from '../../../../../../components/base/pull-refresh/index.vue'
 import { getBuyOrSellName } from '@/constants/order'
 import { formatDecimal } from '@/filters'
 import { useNavigation } from '../../../../../../router/navigation'
 import { BuyOrSell, BuildType } from '@/constants/order'
+import { usePosition } from '@/business/position'
+import eventBus from '@/services/bus'
 
 const componentMap = new Map<string, unknown>([
     // ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
@@ -71,35 +70,22 @@ const componentMap = new Map<string, unknown>([
 ])
 
 const { router } = useNavigation()
-const dataList = shallowRef<Model.TradePositionRsp[]>([])
+const { positionList, loading } = usePosition(10)
 const selectedRow = shallowRef<Model.TradePositionRsp>()
-const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 
 const { componentRef, componentId, closeComponent } = useComponent(() => {
     pullRefreshRef.value?.refresh()
 })
 
-const { loading, pageIndex, pageCount, run } = useRequest(queryTradePosition, {
-    params: {
-        pagesize: 20,
-        tradeMode: '10'
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = 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 } })
 }
 
+// 通知持仓列表刷新
+const onRefresh = () => {
+    eventBus.$emit('PosChangedNtf')
+}
 </script>

+ 14 - 35
src/packages/mobile/views/order/position/components/swap/list/Index.vue

@@ -1,9 +1,8 @@
 <!-- 我的持仓-掉期持仓 -->
 <template>
-    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-        :page-count="pageCount" @refresh="run">
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" @refresh="onRefresh">
         <div class="g-order-list">
-            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+            <div class="g-order-list__box" v-for="(item, index) in positionList" :key="index">
                 <div class="g-order-list__titlebar">
                     <div class="left">
                         <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
@@ -39,8 +38,8 @@
                         </li>
                         <li>
                             <span>参考损益:</span>
-                            <span :class="closepl(item) ? 'g-price-up' : 'g-price-down'">
-                                {{ formatDecimal(closepl(item)) }}
+                            <span :class="handlePriceColor(item.closepl, 0)">
+                                {{ formatDecimal(item.closepl) }}
                             </span>
                         </li>
                     </ul>
@@ -59,22 +58,20 @@
 import { shallowRef, defineAsyncComponent } from 'vue'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import AppPullRefresh from '../../../../../../components/base/pull-refresh/index.vue'
-import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
-import { formatDecimal, handleNumberValue } from '@/filters'
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, handleNumberValue, handlePriceColor } from '@/filters'
+import { usePosition } from '@/business/position'
 import { useFuturesStore } from '@/stores'
+import eventBus from '@/services/bus'
 
 const componentMap = new Map<string, unknown>([
     ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
 ])
 
 const futuresStore = useFuturesStore()
-
-const dataList = shallowRef<Model.TradePositionRsp[]>([])
+const { positionList, loading } = usePosition(46)
 const selectedRow = shallowRef<Model.TradePositionRsp>()
-const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 
 const last = (goodsCode: string) => {
@@ -85,35 +82,17 @@ const lastColor = (goodsCode: string) => {
     return futuresStore.getQuoteInfo(goodsCode).value?.lastColor
 }
 
-/// 计算参考损益
-const closepl = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    const { curpositionqty, curholderamount, agreeunit, buyorsell } = item
-    return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
-}
-
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
     pullRefreshRef.value?.refresh()
 })
 
-const { loading, pageIndex, pageCount, run } = useRequest(queryTradePosition, {
-    params: {
-        pagesize: 20,
-        tradeMode: '46'
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
-
 const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
     selectedRow.value = row
     openComponent(componentName)
 }
+
+// 通知持仓列表刷新
+const onRefresh = () => {
+    eventBus.$emit('PosChangedNtf')
+}
 </script>

+ 4 - 21
src/packages/pc/components/modules/listing/index.vue

@@ -64,27 +64,19 @@ import { shallowRef, computed, watch } from 'vue'
 import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus'
 import { EPriceMode, EListingSelectType, EDelistingType, EBuildType, EValidType, EOrderOperateType } from '@/constants/client'
 import { BuyOrSell, getBuyOrSellList } from '@/constants/order'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import { useOrder } from '@/business/trade'
+import { usePosition } from '@/business/position'
 import { useGoodsStore, useFuturesStore } from '@/stores'
-import eventBus from '@/services/bus'
 import Forex from '@pc/components/modules/quote/forex/index.vue'
 
 const goodsStore = useGoodsStore()
 const futuresStore = useFuturesStore()
 const { formData, loading, formSubmit } = useOrder()
+const { getOrderQty } = usePosition(50)
 const formRef = shallowRef<FormInstance>()
 const qtyStepList = [1, 10, 100] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-// 持仓列表
-const { dataList: positionList, run: getTradePosition } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 商品盘面
 const quote = computed(() => futuresStore.getQuoteInfo(goodsStore.goodsCode).value)
 
@@ -98,16 +90,10 @@ const priceStep = computed(() => {
 })
 
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === goodsStore.goodsCode && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, goodsStore.goodsCode))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === goodsStore.goodsCode && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, goodsStore.goodsCode))
 
 const formRules: FormRules = {
     OrderPrice: [{
@@ -183,9 +169,6 @@ watch(() => goodsStore.goodsId, () => {
 }, {
     immediate: true
 })
-
-// 接收持仓变化通知
-eventBus.$on('PosChangedNtf', () => getTradePosition())
 </script>
 
 <style lang="less">

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

@@ -31,12 +31,6 @@
                     font-size: 18px;
                     text-align: center;
                     margin-right: 20px;
-
-                    span.g-price-up {
-                        &::before {
-                            content: '+';
-                        }
-                    }
                 }
 
                 &-right {
@@ -46,6 +40,12 @@
                     span {
                         font-size: 12px;
                         line-height: normal;
+
+                        &.g-price-up {
+                            &::before {
+                                content: '+';
+                            }
+                        }
                     }
                 }
             }

+ 2 - 2
src/packages/pc/views/footer/goods/position/components/transfer/index.vue

@@ -127,11 +127,11 @@ const onCloseSumit = () => {
                 ElMessage.error('挂牌失败:' + err)
             })
         }
-    })  
+    })
 }
 
 const onRadioChange = (value: number) => {
-    formData.OrderQty = Math.trunc(props.selectedRow.enableqty * value)
+    formData.OrderQty = Math.trunc(props.selectedRow.enableqty * value) || 1
 }
 
 onMounted(() => {

+ 14 - 32
src/packages/pc/views/footer/goods/position/index.vue

@@ -1,6 +1,6 @@
 <!-- 商品订单-合约汇总 -->
 <template>
-    <app-table :data="dataList" v-model:columns="tableColumns" :loading="loading" :row-key="rowKey"
+    <app-table :data="positionList" v-model:columns="tableColumns" :loading="loading" :row-key="rowKey"
         :expand-row-keys="expandKeys" @row-click="rowClick">
         <!-- 挂牌类型 -->
         <template #buyorsell="{ value }">
@@ -23,24 +23,30 @@
                 <el-button type="danger" size="small" @click="showComponent('transfer', row)">转让</el-button>
             </div>
         </template>
+        <template #footer>
+            <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)"
+                @closed="closeComponent" v-if="componentId" />
+        </template>
     </app-table>
-    <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)" @closed="closeComponent"
-        v-if="componentId" />
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, defineAsyncComponent, onUnmounted } from 'vue'
-import { useRequest } from '@/hooks/request'
+import { shallowRef, defineAsyncComponent } from 'vue'
 import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
 import { useComponent } from '@/hooks/component'
 import { useComposeTable } from '@pc/components/base/table'
-import { queryTradePosition } from '@/services/api/order'
 import { useFuturesStore } from '@/stores'
+import { usePosition } from '@/business/position'
 import AppTable from '@pc/components/base/table/index.vue'
 import { handlePriceColor } from '@/filters'
-import eventBus from '@/services/bus'
+
+const componentMap = new Map<string, unknown>([
+    ['delivery', defineAsyncComponent(() => import('./components/delivery/index.vue'))],
+    ['transfer', defineAsyncComponent(() => import('./components/transfer/index.vue'))],
+])
 
 const futuresStore = useFuturesStore()
+const { positionList, loading } = usePosition(50)
 
 const lastprice = (item: Model.TradePositionRsp) => {
     const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
@@ -58,24 +64,7 @@ const closepl = (item: Model.TradePositionRsp) => {
     return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
 }
 
-const componentMap = new Map<string, unknown>([
-    ['delivery', defineAsyncComponent(() => import('./components/delivery/index.vue'))],
-    ['transfer', defineAsyncComponent(() => import('./components/transfer/index.vue'))],
-])
-
-const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
-    run()
-})
-
-defineProps({
-    code: String
-})
-
-const { loading, dataList, run } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
 const { rowKey, expandKeys, selectedRow, rowClick } = useComposeTable<Model.TradePositionRsp>({ rowKey: 'pkid' })
 
@@ -96,11 +85,4 @@ const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
     selectedRow.value = row
     openComponent(componentName)
 }
-
-// 接收持仓变化通知
-const posChangedNtf = eventBus.$on('PosChangedNtf', () => {
-    run()
-})
-
-onUnmounted(() => posChangedNtf.cancel())
 </script>

+ 4 - 17
src/packages/pc/views/market/trade/goods/detail/components/order/delisting/index.vue

@@ -49,9 +49,8 @@ import { shallowRef, PropType, computed } from 'vue'
 import { ElMessage, FormInstance, FormRules } from 'element-plus'
 import { EBuildType, EDelistingType, EListingSelectType, EOrderOperateType, EPriceMode, EValidType } from '@/constants/client'
 import { BuyOrSell } from '@/constants/order'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import { useOrder } from '@/business/trade'
+import { usePosition } from '@/business/position'
 import { useFuturesStore } from '@/stores'
 import AppDrawer from '@pc/components/base/drawer/index.vue'
 
@@ -63,6 +62,7 @@ const props = defineProps({
 })
 
 const { formData, formSubmit, loading } = useOrder()
+const { getOrderQty } = usePosition(50)
 const futuresStore = useFuturesStore()
 const show = shallowRef(true)
 const refresh = shallowRef(false)
@@ -70,27 +70,14 @@ const formRef = shallowRef<FormInstance>()
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-// 持仓列表
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 商品盘面
 const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
 
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.selectedRow.goodsid))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.selectedRow.goodsid))
 
 const formRules: FormRules = {
     OrderQty: [{

+ 6 - 5
src/packages/qxst/components/base/pull-refresh/index.vue

@@ -49,6 +49,7 @@ const emit = defineEmits(['update:loading', 'update:pageIndex', 'update:error',
 const listRef = shallowRef<ListInstance>()
 const refreshing = shallowRef(false) // 是否处于下拉加载状态
 const finished = shallowRef(false) // 是否已加载完成所有数据
+const currentPage = shallowRef(props.pageIndex)
 
 const showLoading = computed({
     get: () => props.loading,
@@ -60,13 +61,9 @@ const showError = computed({
     set: (val) => emit('update:error', val)
 })
 
-const currentPage = computed({
-    get: () => props.pageIndex,
-    set: (val) => emit('update:pageIndex', val)
-})
-
 // 上拉加载
 const onLoad = () => {
+    showLoading.value = false
     if (refreshing.value) {
         currentPage.value = 1
     }
@@ -99,6 +96,10 @@ watch(showLoading, (status) => {
     }
 })
 
+watch(currentPage, (val) => {
+    emit('update:pageIndex', val)
+})
+
 // 暴露组件属性给父组件调用
 defineExpose({
     refresh: () => {

+ 4 - 15
src/packages/qxst/views/goods/detail/Index.vue

@@ -25,9 +25,8 @@ import { Button } from 'vant'
 import { useNavigation } from '../../../router/navigation'
 import { useComponent } from '@/hooks/component'
 import { EBuildType } from '@/constants/client'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import { useFuturesStore } from '@/stores'
+import { usePosition } from '@/business/position'
 
 const Price = defineAsyncComponent(() => import('../../../components/modules/quote/price/index.vue'))
 const Chart = defineAsyncComponent(() => import('../../../components/modules/quote/chart/index.vue'))
@@ -38,14 +37,15 @@ const componentMap = new Map<string, unknown>([
     ['listing', defineAsyncComponent(() => import('./components/listing/Index.vue'))],
 ])
 
+const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
 const quote = futuresStore.getQuoteInfo(goodsid)
+const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')
-const buildType = shallowRef<EBuildType>() // 挂牌类型
-const isDisabledClose = shallowRef(true)
+const isDisabledClose = computed(() => !positionList.value.some((e) => e.goodsid === goodsid))
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
@@ -53,15 +53,4 @@ const onListing = (type: EBuildType) => {
     buildType.value = type
     openComponent('listing')
 }
-
-useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (res.data.some((e) => e.goodsid === goodsid)) {
-            isDisabledClose.value = false
-        }
-    }
-})
 </script>

+ 4 - 16
src/packages/qxst/views/goods/detail/components/listing/Index.vue

@@ -64,8 +64,7 @@ import { Form, FormInstance, Button, CellGroup, FieldRule, Field, Stepper, Radio
 import { fullloading, dialog } from '@/utils/vant'
 import { BuyOrSell } from '@/constants/order'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EPriceMode, EListingSelectType, EDelistingType, EBuildType, EValidType, EOrderOperateType } from '@/constants/client'
 import AppModal from '@/components/base/modal/index.vue'
@@ -84,6 +83,7 @@ const props = defineProps({
     }
 })
 
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
@@ -94,12 +94,6 @@ const refresh = shallowRef(true) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 价格步长
 const priceStep = computed(() => {
     const { quoteminunit = 0, decimalplace = 0 } = quote.value ?? {}
@@ -110,16 +104,10 @@ const priceStep = computed(() => {
 })
 
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.goodsCode))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodscode === props.goodsCode && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.goodsCode))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {

+ 4 - 17
src/packages/qxst/views/goods/trade/components/delisting/index.vue

@@ -82,8 +82,7 @@ import { BuyOrSell, getBuyOrSellName } from '@/constants/order'
 import { useAccountStore, useFuturesStore } from '@/stores'
 import { EBuildType, EDelistingType, EListingSelectType, EOrderOperateType, EPriceMode, EValidType } from '@/constants/client'
 import { useOrder } from '@/business/trade'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
+import { usePosition } from '@/business/position'
 import AppModal from '@/components/base/modal/index.vue'
 
 const props = defineProps({
@@ -95,6 +94,7 @@ const props = defineProps({
 
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
+const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
 const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
@@ -104,23 +104,11 @@ const refresh = shallowRef(false) // 是否刷新父组件数据
 const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
-const { dataList: positionList } = useRequest(queryTradePosition, {
-    params: {
-        tradeMode: '50'
-    },
-})
-
 // 买方向持仓数量
-const buyQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Buy)
-    return item?.enableqty ?? 0
-})
+const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.selectedRow.goodsid))
 
 // 卖方向持仓数量
-const sellQty = computed(() => {
-    const item = positionList.value.find((e) => e.goodsid === props.selectedRow.goodsid && e.buyorsell === BuyOrSell.Sell)
-    return item?.enableqty ?? 0
-})
+const sellQty = computed(() => getOrderQty(BuyOrSell.Sell, props.selectedRow.goodsid))
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {
@@ -142,7 +130,6 @@ const onSubmit = () => {
         message: '确认要提交吗?',
         showCancelButton: true,
     }).then(() => {
-
         const { goodsid, orderid, orderprice, buyorsell } = props.selectedRow
         const { marketid = 0 } = quote.value ?? {}
 

+ 17 - 50
src/packages/qxst/views/order/position/components/goods/list/Index.vue

@@ -1,23 +1,20 @@
 <!-- 我的持仓-订单持仓 -->
 <template>
-    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error" v-model:pageIndex="pageIndex"
-        :page-count="pageCount" @refresh="run">
+    <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" @refresh="onRefresh">
         <div class="g-order-list">
-            <div class="g-order-list__box" v-for="(item, index) in dataList" :key="index">
+            <div class="g-order-list__box" v-for="(item, index) in positionList" :key="index">
                 <div class="g-order-list__titlebar">
                     <div class="left">
                         <h4>{{ item.goodscode }}/{{ item.goodsname }}</h4>
                     </div>
                     <div class="right">
-                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">{{ getBuyOrSellName(item.buyorsell)
-                        }}</span>
+                        <span :class="!item.buyorsell ? 'g-price-up' : 'g-price-down'">
+                            {{ getBuyOrSellName(item.buyorsell) }}
+                        </span>
                     </div>
                 </div>
                 <div class="g-order-list__content">
                     <ul>
-                        <li :class="lastColor(item.goodscode)">{{ last(item.goodscode) }}</li>
-                    </ul>
-                    <ul>
                         <li>
                             <span>持有数量</span>
                             <span>{{ formatDecimal(item.curpositionqty) }}</span>
@@ -40,8 +37,9 @@
                         </li>
                         <li>
                             <span>参考损益</span>
-                            <span :class="getAmountColor(closepl(item))">{{ formatDecimal(closepl(item))
-                            }}</span>
+                            <span :class="handlePriceColor(item.closepl, 0)">
+                                {{ formatDecimal(item.closepl) }}
+                            </span>
                         </li>
                     </ul>
                 </div>
@@ -60,60 +58,29 @@
 import { shallowRef, defineAsyncComponent } from 'vue'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { useRequest } from '@/hooks/request'
-import { queryTradePosition } from '@/services/api/order'
 import AppPullRefresh from '../../../../../../components/base/pull-refresh/index.vue'
-import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
-import { formatDecimal, handleNumberValue } from '@/filters'
-import { useFuturesStore } from '@/stores'
-import { getAmountColor } from '@/utils/vant';
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, handleNumberValue, handlePriceColor } from '@/filters'
+import { usePosition } from '@/business/position'
+import eventBus from '@/services/bus'
 
 const componentMap = new Map<string, unknown>([
     ['close', defineAsyncComponent(() => import('../close/Index.vue'))],
     ['delivery', defineAsyncComponent(() => import('../delivery/Index.vue'))]
 ])
 
-const futuresStore = useFuturesStore()
-
-const dataList = shallowRef<Model.TradePositionRsp[]>([])
+const { positionList, loading } = usePosition(50)
 const selectedRow = shallowRef<Model.TradePositionRsp>()
-const error = shallowRef(false)
 const pullRefreshRef = shallowRef()
 
-const last = (goodsCode: string) => {
-    return futuresStore.getQuotePrice(goodsCode)
-}
-
-const lastColor = (goodsCode: string) => {
-    return futuresStore.getQuoteInfo(goodsCode).value?.lastColor
-}
-
-/// 计算参考损益
-const closepl = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    const { curpositionqty, curholderamount, agreeunit, buyorsell } = item
-    return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
-}
-
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
     pullRefreshRef.value?.refresh()
 })
 
-const { loading, pageIndex, pageCount, run } = useRequest(queryTradePosition, {
-    params: {
-        pagesize: 20,
-        tradeMode: '50'
-    },
-    onSuccess: (res) => {
-        if (pageIndex.value === 1) {
-            dataList.value = []
-        }
-        dataList.value.push(...res.data)
-    },
-    onError: () => {
-        error.value = true
-    }
-})
+// 通知持仓列表刷新
+const onRefresh = () => {
+    eventBus.$emit('PosChangedNtf')
+}
 
 const showComponent = (componentName: string, row: Model.TradePositionRsp) => {
     selectedRow.value = row

+ 6 - 5
src/packages/sbyj/components/base/pull-refresh/index.vue

@@ -49,6 +49,7 @@ const emit = defineEmits(['update:loading', 'update:pageIndex', 'update:error',
 const listRef = shallowRef<ListInstance>()
 const refreshing = shallowRef(false) // 是否处于下拉加载状态
 const finished = shallowRef(false) // 是否已加载完成所有数据
+const currentPage = shallowRef(props.pageIndex)
 
 const showLoading = computed({
     get: () => props.loading,
@@ -60,13 +61,9 @@ const showError = computed({
     set: (val) => emit('update:error', val)
 })
 
-const currentPage = computed({
-    get: () => props.pageIndex,
-    set: (val) => emit('update:pageIndex', val)
-})
-
 // 上拉加载
 const onLoad = () => {
+    showLoading.value = false
     if (refreshing.value) {
         currentPage.value = 1
     }
@@ -99,6 +96,10 @@ watch(showLoading, (status) => {
     }
 })
 
+watch(currentPage, (val) => {
+    emit('update:pageIndex', val)
+})
+
 // 暴露组件属性给父组件调用
 defineExpose({
     refresh: () => {

+ 1 - 1
src/services/http/index.ts

@@ -32,7 +32,7 @@ export default new (class {
                 config.headers = {
                     Authorization: sign.token,
                     LoginID: loginStore.loginId,
-                    Group: loginStore.clientType,
+                    Group: loginStore.getClientType(),
                     'x-token': sign.token,
                     //Signid: 'eecd3f37625f4501b88e9f0fa14b4b51',
                     //Sign: cryptojs.SHA256(qs.stringify(sign)).toString(),

+ 2 - 1
src/stores/index.ts

@@ -8,4 +8,5 @@ export { useFuturesStore } from './modules/futures'
 export { useEnumStore } from './modules/enum'
 export { useErrorInfoStore } from './modules/errorInfo'
 export { useNoticeStore } from './modules/notice'
-export { useGoodsStore } from './modules/goods'
+export { useGoodsStore } from './modules/goods'
+export { usePositionStore } from './modules/position'

+ 17 - 17
src/stores/modules/login.ts

@@ -15,22 +15,6 @@ function initLoginInfo(): Model.LoginRsp {
     }
 }
 
-// 获取终端类型
-const getClientType = () => {
-    const os = plus.getSystemInfo('os')
-    switch (os) {
-        case 'Android': {
-            return ClientType.Android
-        }
-        case 'iOS': {
-            return ClientType.IOS
-        }
-        default: {
-            return ClientType.Web
-        }
-    }
-}
-
 /**
  * 登录存储对象
  */
@@ -40,7 +24,6 @@ export const useLoginStore = defineStore(() => {
 
     const state = reactive({
         logining: false,
-        clientType: getClientType(),
         loginInfo: localLoginInfo || sessionLoginInfo || initLoginInfo()
     })
 
@@ -53,6 +36,22 @@ export const useLoginStore = defineStore(() => {
     // 登录ID
     const loginId = computed(() => state.loginInfo.loginId)
 
+    // 获取终端类型
+    const getClientType = () => {
+        const os = plus.getSystemInfo('os')
+        switch (os) {
+            case 'Android': {
+                return ClientType.Android
+            }
+            case 'iOS': {
+                return ClientType.IOS
+            }
+            default: {
+                return ClientType.Web
+            }
+        }
+    }
+
     // 更新登录信息
     const setLoginInfo = (data: Model.LoginRsp, persist = false) => {
         state.loginInfo = data
@@ -100,6 +99,7 @@ export const useLoginStore = defineStore(() => {
         token,
         userId,
         loginId,
+        getClientType,
         setLoginInfo,
         getAutoLoginData,
         setAutoLoginData,

+ 2 - 21
src/stores/modules/position.ts

@@ -8,7 +8,7 @@ import eventBus from '@/services/bus'
 /**
  * 持仓存储对象
  */
-const useStore = defineStore(() => {
+export const usePositionStore = defineStore(() => {
     const futuresStore = useFuturesStore()
     const state = reactive({
         loading: false,
@@ -56,23 +56,4 @@ const useStore = defineStore(() => {
         orderPositionComputedList,
         posChangedNtf,
     }
-})
-
-export const usePositionStore = (tradeMode = 0) => {
-    const store = useStore()
-
-    const positionList = computed(() => store.orderPositionList.filter((e) => tradeMode ? e.trademode === tradeMode : true))
-
-    // 获取持仓数量
-    const getOrderQty = (buyOrSell: BuyOrSell, goodsCode: string) => {
-        return computed(() => {
-            const item = positionList.value.find((e) => e.goodscode === goodsCode && e.buyorsell === buyOrSell)
-            return item?.enableqty ?? 0
-        })
-    }
-
-    return {
-        positionList,
-        getOrderQty
-    }
-}
+})

+ 1 - 1
src/utils/h5plus/index.ts

@@ -244,7 +244,7 @@ export default new (class {
                 retry: 1,
             }, (d: any, status: number) => {
                 if (status !== 200) {
-                    plus.nativeUI.toast('下载失败')
+                    plus.nativeUI.toast('下载失败,请稍后再试')
                 }
             })
             // 监听下载状态

+ 1 - 15
src/utils/vant/index.ts

@@ -64,18 +64,4 @@ export function dialog(options: string | DialogOptions) {
         })
     }
     return showDialog(options)
-}
-
-/**
- * 对应数值取得颜色
- * @param 数值 
- */
-export const getAmountColor = (num: number) => {
-    if (num === 0.0) {
-        return 'g-price-normal'
-    } else if(num > 0.0) {
-        return 'g-price-up'
-    } else {
-        return 'g-price-down'
-    }
-}
+}