Browse Source

xxxxxxxxx

Handy_Cao 2 năm trước cách đây
mục cha
commit
424b7564f6

+ 147 - 0
src/packages/pc/views/footer/goods/detail/components/transfer/index.vue

@@ -0,0 +1,147 @@
+<!-- 商品订单-持仓明细-转让 -->
+<template>
+    <app-drawer title="转让" :width="800" v-model:show="show" :loading="loading" :refresh="refresh">
+        <el-form ref="formRef" class="el-form--horizontal" label-width="120px" label-position="left" :model="formData"
+            :rules="formRules">
+            <el-form-item label="商品代码/名称">
+                <span>{{ selectedRow.goodscode }}/{{ selectedRow.goodsname }}</span>
+            </el-form-item>
+            <el-form-item label="持仓方向">
+                <span>{{ getBuyOrSellName(selectedRow.buyorsell) }}</span>
+            </el-form-item>
+            <el-form-item label="持仓金额">
+                <span>{{ formatDecimal(selectedRow.holderamount) }}</span>
+            </el-form-item>
+            <el-form-item label="持仓数量">
+                <span>{{ selectedRow.holderqty }}</span>
+            </el-form-item>
+            <el-form-item label="持仓价">
+                <span>{{ formatDecimal(selectedRow.holderprice, selectedRow.decimalplace) }}</span>
+            </el-form-item>
+            <el-form-item label="参考损益">
+                <span :class="handlePriceColor(closepl)">{{ formatDecimal(closepl) }}</span>
+            </el-form-item>
+            <el-form-item prop="OrderQty" label="转让数量">
+                <div class="g-qty-group">
+                    <el-input-number placeholder="请输入数量" v-model="formData.OrderQty" :precision="0"
+                        :max="selectedRow.holderqty" :min="0" />
+                    <el-radio-group size="small" v-model="qtyStep" @change="onRadioChange">
+                        <el-radio v-for="(value, index) in qtyStepList" :key="index" :label="value" border
+                            style="width: 25%;">
+                            {{ parsePercent(value, 0) }}
+                        </el-radio>
+                    </el-radio-group>
+                </div>
+            </el-form-item>
+            <el-form-item prop="OrderPrice" label="转让价格">
+                <el-input-number placeholder="请输入价格" v-model="formData.OrderPrice"
+                    :decimal-length="selectedRow.decimalplace" />
+            </el-form-item>
+        </el-form>
+        <template #footer>
+            <el-button type="info" @click="onCancel(false)">取消</el-button>
+            <el-button type="primary" @click="onCloseSumit">提交</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { ref, PropType, computed, onMounted } from 'vue'
+import { ElMessage, FormInstance, FormRules } from 'element-plus'
+import { useOrder } from '@/business/trade'
+import { formatDecimal, handlePriceColor, parsePercent } from '@/filters'
+import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
+import { useFuturesStore } from '@/stores'
+import { EBuildType, EDelistingType, EListingSelectType, EOrderOperateType, EPriceMode, EValidType } from '@/constants/client'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+
+const props = defineProps({
+    selectedRow: {
+        type: Object as PropType<Model.TradeHolderDetailRsp>,
+        required: true
+    }
+})
+
+const futuresStore = useFuturesStore()
+const quote = futuresStore.getGoodsQuote(props.selectedRow.goodscode)
+// 损益
+const closepl = computed(() => {
+    const { last = 0 } = quote.value ?? {}
+    const { holderqty, holderamount, agreeunit, buyorsell } = props.selectedRow
+    return (last * holderqty * agreeunit - holderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
+})
+
+const { formSubmit, formData, loading } = useOrder()
+const show = ref(true)
+const refresh = ref(false)
+const formRef = ref<FormInstance>()
+const qtyStepList = [0.25, 0.5, 0.75, 1] // 数量步长列表
+const qtyStep = ref<number>() // 数量步长
+
+const formRules: FormRules = {
+    OrderPrice: [{
+        message: '请输入转让价格',
+        validator: () => {
+            return !!formData.OrderPrice
+        }
+    }],
+    OrderQty: [{
+        message: '请输入转让数量',
+        validator: () => {
+            return !!formData.OrderQty
+        }
+    }],
+}
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+const onCloseSumit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            const { marketid, goodsid, buyorsell, tradeid } = props.selectedRow
+            /// 市场ID
+            formData.Header = { GoodsID: goodsid }
+            formData.MarketID = marketid
+            formData.PriceMode = EPriceMode.PRICEMODE_LIMIT
+            formData.BuyOrSell = buyorsell === BuyOrSell.Buy ? BuyOrSell.Sell : BuyOrSell.Buy
+            formData.GoodsID = goodsid
+            formData.ListingSelectType = EListingSelectType.LISTINGSELECTTYPE_DELISTINGTHENLISTING
+            formData.DelistingType = EDelistingType.DELISTINGTYPE_PRICE
+            formData.BuildType = EBuildType.BUILDTYPE_CLOSE
+            formData.TimevalidType = EValidType.VALIDTYPE_DR
+            formData.OperateType = EOrderOperateType.ORDEROPERATETYPE_NORMAL
+            formData.RelatedID = tradeid
+
+            formSubmit().then(() => {
+                ElMessage.success('挂牌成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('挂牌失败:' + err)
+            })
+        }
+    })
+}
+
+const onRadioChange = (value: number) => {
+    const { holderqty, freezeqty } = props.selectedRow
+    formData.OrderQty = Math.trunc((holderqty-freezeqty) * value) || 1
+}
+
+onMounted(() => {
+    const { bid, ask, presettle = 0 } = quote.value ?? {}
+    switch (props.selectedRow.buyorsell) {
+        case BuyOrSell.Buy:
+            formData.OrderPrice = ask || presettle
+            break
+        case BuyOrSell.Sell:
+            formData.OrderPrice = bid || presettle
+            break
+        default:
+            formData.OrderPrice = presettle
+    }
+    formData.OrderQty = props.selectedRow.holderqty
+})
+</script>

+ 29 - 6
src/packages/pc/views/footer/goods/detail/index.vue

@@ -1,30 +1,47 @@
 <!-- 商品订单-持仓明细 -->
 <template>
-    <app-table :data="dataList" v-model:columns="tableColumns" :loading="loading" :row-key="rowKey"
-        :expand-row-keys="expandKeys" @row-click="rowClick">
+    <app-table :data="dataList" v-model:columns="tableColumns">
         <!-- 方向 -->
         <template #buyorsell="{ value }">
             {{ getBuyOrSellName(value) }}
         </template>
+        <!-- 操作 -->
+        <template #operate="{ row }">
+            <div class="buttonbar">
+                <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>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, onUnmounted } from 'vue'
+import { shallowRef, onUnmounted, defineAsyncComponent } from 'vue'
 import { getBuyOrSellName } from '@/constants/order'
 import { useRequest } from '@/hooks/request'
-import { useComposeTable } from '@pc/components/base/table'
+import { useComponent } from '@/hooks/component'
 import { queryTradeHolderDetail } from '@/services/api/order'
 import AppTable from '@pc/components/base/table/index.vue'
 import eventBus from '@/services/bus'
 
-const { loading, dataList, run } = useRequest(queryTradeHolderDetail, {
+const { dataList, run } = useRequest(queryTradeHolderDetail, {
     params: {
         trademodes: '50,16'
     }
 })
 
-const { rowKey, expandKeys, rowClick } = useComposeTable<Model.TradeHolderDetailRsp>({ rowKey: 'tradeid' })
+const componentMap = new Map<string, unknown>([
+    ['transfer', defineAsyncComponent(() => import('./components/transfer/index.vue'))],
+])
+
+const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
+    run()
+})
+
+const selectedRow = shallowRef<Model.TradeHolderDetailRsp>()
 
 const tableColumns = shallowRef<Model.TableColumn[]>([
     { prop: 'tradeid', label: '成交单号' },
@@ -35,10 +52,16 @@ const tableColumns = shallowRef<Model.TableColumn[]>([
     { prop: 'holderprice', label: '持仓价格' },
     { prop: 'holderamount', label: '持仓金额' },
     { prop: 'tradetime', label: '交易时间' },
+    { prop: 'operate', label: '操作', fixed: 'right', width: 100 },
 ])
 
 // 接收头寸变化通知通知
 const posChangedNtf = eventBus.$on('PosChangedNtf', () => run())
 
+const showComponent = (componentName: string, row: Model.TradeHolderDetailRsp) => {
+    selectedRow.value = row
+    openComponent(componentName)
+}
+
 onUnmounted(() => posChangedNtf.cancel())
 </script>

+ 7 - 7
src/packages/pc/views/footer/presell/transferposition/listing/index.vue

@@ -4,10 +4,10 @@
         <el-form ref="formRef" class="el-form--horizontal" label-width="120px" label-position="left" :model="formData"
             :rules="formRules">
             <el-form-item label="商品代码/名称">
-                <span>{{ detail.goodscode }}/{{ detail.goodsname }}</span>
+                <span>{{ selectedRow.goodscode }}/{{ selectedRow.goodsname }}</span>
             </el-form-item>
             <el-form-item label="预售价">
-                <span>{{ detail.presaleprice }}</span>
+                <span>{{ selectedRow.presaleprice }}</span>
             </el-form-item>
             <el-form-item label="可用量">
                 <span>{{ enableqty }}</span>
@@ -23,7 +23,7 @@
                 <el-input-number placeholder="转让数量" v-model="formData.OrderQty" :max="enableqty" :min="0" />
             </el-form-item>
             <el-form-item prop="OrderPrice" label="转让价">
-                <el-input-number placeholder="请输入转让价格" :max="quote?.limitup" :min="quote?.limitdown" :step="Math.pow(10, -detail.decimalplace)" :precision="detail.decimalplace" v-model="formData.OrderPrice" />
+                <el-input-number placeholder="请输入转让价格" :max="quote?.limitup" :min="quote?.limitdown" :step="Math.pow(10, -selectedRow.decimalplace)" :precision="selectedRow.decimalplace" v-model="formData.OrderPrice" />
             </el-form-item>
         </el-form>
         <template #footer>
@@ -44,7 +44,7 @@ import { EPriceMode, EValidType, EListingSelectType, EBuildType } from '@/consta
 import AppDrawer from '@pc/components/base/drawer/index.vue'
 
 const props = defineProps({
-    detail: {
+    selectedRow: {
         type: Object as PropType<Model.MineTradePositionExsRsp>,
         required: true
     },
@@ -53,9 +53,9 @@ const props = defineProps({
 
 const { getGoodsQuote } = useFuturesStore()
 // 可用数量
-const enableqty = computed(() => props.detail.buycurpositionqty - props.detail.buyfrozenqty)
+const enableqty = computed(() => props.selectedRow.buycurpositionqty - props.selectedRow.buyfrozenqty)
 /// 对应的行情信息
-const quote = getGoodsQuote(props.detail.goodscode)
+const quote = getGoodsQuote(props.selectedRow.goodscode)
 
 const { formData, formSubmit, loading } = useOrder()
 const show = ref(true)
@@ -85,7 +85,7 @@ const onCancel = (isRefresh = false) => {
 const onSubmit = () => {
     formRef.value?.validate((valid) => {
         if (valid) {
-            const { goodsid } = props.detail
+            const { goodsid } = props.selectedRow
             formData.GoodsID = goodsid
             formData.MarketID = 49201
             formData.BuyOrSell = BuyOrSell.Sell