li.shaoyi 3 minggu lalu
induk
melakukan
3c0d098620

+ 109 - 26
public/proto/mtp.js

@@ -9884,6 +9884,86 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
       }
     }
   },
+  HolderTPSLSetReq: {
+    fields: {
+      Header: {
+        type: "MessageHead",
+        id: 1
+      },
+      ClientSerialNo: {
+        type: "string",
+        id: 2
+      },
+      TradeID: {
+        type: "uint64",
+        id: 3
+      },
+      AccountID: {
+        type: "uint64",
+        id: 4
+      },
+      BuyOrSell: {
+        type: "uint32",
+        id: 5
+      },
+      GoodsID: {
+        type: "uint32",
+        id: 6
+      },
+      TPFlag: {
+        type: "uint32",
+        id: 7
+      },
+      TPPrice: {
+        type: "double",
+        id: 8
+      },
+      SLFlag: {
+        type: "uint32",
+        id: 9
+      },
+      SLPrice: {
+        type: "double",
+        id: 10
+      },
+      clientordertime: {
+        type: "string",
+        id: 11
+      },
+      clienttype: {
+        type: "uint32",
+        id: 12
+      }
+    }
+  },
+  HolderTPSLSetRsp: {
+    fields: {
+      Header: {
+        type: "MessageHead",
+        id: 1
+      },
+      RetCode: {
+        type: "int32",
+        id: 2
+      },
+      RetDesc: {
+        type: "string",
+        id: 3
+      },
+      TradeID: {
+        type: "uint64",
+        id: 4
+      },
+      AccountID: {
+        type: "uint64",
+        id: 5
+      },
+      BuyOrSell: {
+        type: "uint32",
+        id: 6
+      }
+    }
+  },
   SubCommand: {
     fields: {
       CommandCode: {
@@ -52122,33 +52202,28 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "uint32",
         id: 3
       },
-      WalletID: {
-        rule: "required",
-        type: "uint32",
-        id: 4
-      },
       Amount: {
         rule: "required",
         type: "double",
-        id: 5
+        id: 4
       },
       OperateSrc: {
         rule: "required",
         type: "uint32",
-        id: 6
+        id: 5
       },
       ClientTicket: {
         rule: "required",
         type: "string",
-        id: 7
+        id: 6
       },
       Remark: {
         type: "string",
-        id: 8
+        id: 7
       },
       ExtendInfo: {
         type: "string",
-        id: 9
+        id: 8
       }
     }
   },
@@ -52205,19 +52280,19 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "uint32",
         id: 3
       },
-      WalletID: {
-        rule: "required",
-        type: "uint32",
-        id: 4
-      },
       DigitalAccountID: {
         rule: "required",
         type: "uint64",
-        id: 5
+        id: 4
       },
       Amount: {
         rule: "required",
         type: "double",
+        id: 5
+      },
+      Address: {
+        rule: "required",
+        type: "string",
         id: 6
       },
       OperateSrc: {
@@ -52685,7 +52760,7 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "MessageHead",
         id: 1
       },
-      DigitalAccountID: {
+      UserID: {
         rule: "required",
         type: "uint64",
         id: 2
@@ -52700,22 +52775,26 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "string",
         id: 4
       },
+      Tag: {
+        type: "string",
+        id: 5
+      },
       AddrType: {
         type: "uint32",
-        id: 5
+        id: 6
       },
       Address: {
         type: "string",
-        id: 6
+        id: 7
       },
       Memo: {
         type: "string",
-        id: 7
+        id: 8
       },
       SerialNumber: {
         rule: "required",
         type: "uint64",
-        id: 8
+        id: 9
       }
     }
   },
@@ -52733,7 +52812,7 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "string",
         id: 3
       },
-      DigitalAccountID: {
+      UserID: {
         rule: "required",
         type: "uint64",
         id: 4
@@ -52748,22 +52827,26 @@ var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $pr
         type: "string",
         id: 6
       },
+      Tag: {
+        type: "string",
+        id: 7
+      },
       AddrType: {
         type: "uint32",
-        id: 7
+        id: 8
       },
       Address: {
         type: "string",
-        id: 8
+        id: 9
       },
       Memo: {
         type: "string",
-        id: 9
+        id: 10
       },
       SerialNumber: {
         rule: "required",
         type: "uint64",
-        id: 10
+        id: 11
       }
     }
   }

+ 44 - 19
public/proto/mtp.proto

@@ -2991,6 +2991,30 @@ message DigitalOrderRsp {
 		optional uint64 OrderID = 4; // 一级生成的订单号
 		optional string OrderTime = 5; // 接收委托交易的时间
 }
+// 持仓止盈止损设置请求
+message HolderTPSLSetReq {
+	optional MessageHead Header = 1;
+		optional string ClientSerialNo = 2; // 客户端流水号
+		optional uint64 TradeID = 3; // 交易单号
+		optional uint64 AccountID = 4; // 交易账号
+		optional uint32 BuyOrSell = 5; // 买卖方向
+		optional uint32 GoodsID = 6; // 商品ID
+		optional uint32 TPFlag = 7; // 止盈标识:0-未设置1-设置
+		optional double TPPrice = 8; // 止盈价格
+		optional uint32 SLFlag = 9; // 止损标识:0-未设置1-设置
+		optional double SLPrice = 10; // 止损价格
+		optional string clientordertime = 11; // 委托时间
+		optional uint32 clienttype = 12; // 客户端类型-0:保留为未填终端类型
+}
+// 持仓止盈止损设置应答
+message HolderTPSLSetRsp {
+	optional MessageHead Header = 1; // 消息头
+	optional int32 RetCode = 2; // 返回码
+	optional string RetDesc = 3; // 描述信息
+		optional uint64 TradeID = 4; // 交易单号
+		optional uint64 AccountID = 5; // 交易账号
+		optional uint32 BuyOrSell = 6; // 买卖方向
+}
 // 账户操作子指令
 message SubCommand {
 		optional uint32 CommandCode = 1; // 子指令操作码
@@ -15712,12 +15736,11 @@ message DigitalAccountDepositApplyReq {
 	optional MessageHead Header = 1;
 			required uint32 UserID = 2; // 用户ID
 		required uint32 CurrencyID = 3; // 币种ID
-		required uint32 WalletID = 4; // 钱包ID
-		required double Amount = 5; // 金额
-			required uint32 OperateSrc = 6; // 操作来源-枚举"operatesrc"(1:管理端,2:终端)
-		required string ClientTicket = 7; // 客户端流水号
-		optional string Remark = 8; // 备注
-		optional string ExtendInfo = 9; // 扩展信息(JSON串,按钱包类型区分)
+		required double Amount = 4; // 金额
+			required uint32 OperateSrc = 5; // 操作来源-枚举"operatesrc"(1:管理端,2:终端)
+		required string ClientTicket = 6; // 客户端流水号
+		optional string Remark = 7; // 备注
+		optional string ExtendInfo = 8; // 扩展信息(JSON串,按钱包类型区分)
 }
 // 数字账户充值申请应答
 message DigitalAccountDepositApplyRsp {
@@ -15735,9 +15758,9 @@ message DigitalAccountWithdrawApplyReq {
 	optional MessageHead Header = 1;
 			required uint32 UserID = 2; // 用户ID
 		required uint32 CurrencyID = 3; // 币种ID
-		required uint32 WalletID = 4; // 钱包ID
-		required uint64 DigitalAccountID = 5; // 数字账户ID
-		required double Amount = 6; // 金额(正值)
+		required uint64 DigitalAccountID = 4; // 数字账户ID
+		required double Amount = 5; // 金额(正值)
+		required string Address = 6; // 地址
 			required uint32 OperateSrc = 7; // 操作来源-枚举"operatesrc"(1:管理端,2:终端)
 		required string ClientTicket = 8; // 客户端流水号
 		optional string Remark = 9; // 备注
@@ -15871,24 +15894,26 @@ message TaAccountDigital {
 // 创建数字钱包地址请求
 message CreateDigitalWalletAddressReq {
 	optional MessageHead Header = 1;
-		required uint64 DigitalAccountID = 2; // 数字账户ID
+		required uint64 UserID = 2; // 用户ID
 		required string ChannelCode = 3; // 渠道代码
 		required string ChainID = 4; // 链ID
-		optional uint32 AddrType = 5; // 地址类型:1-充值;2-提现
-		optional string Address = 6; // 地址(提现类型必填)
-			optional string Memo = 7; // 地址备注(某些链需要)
-		required uint64 SerialNumber = 8; // 流水号
+		optional string Tag = 5; // 标示
+		optional uint32 AddrType = 6; // 地址类型:1-充值;2-提现
+		optional string Address = 7; // 地址(提现类型必填)
+			optional string Memo = 8; // 地址备注(某些链需要)
+		required uint64 SerialNumber = 9; // 流水号
 }
 // 创建数字钱包地址应答
 message CreateDigitalWalletAddressRsp {
 	optional MessageHead Header = 1; // 消息头
 	optional int32 RetCode = 2; // 返回码
 	optional string RetDesc = 3; // 描述信息
-		required uint64 DigitalAccountID = 4; // 数字账户ID
+		required uint64 UserID = 4; // 用户ID
 		required string ChannelCode = 5; // 渠道代码
 		required string ChainID = 6; // 链ID
-		optional uint32 AddrType = 7; // 地址类型:1-充值;2-提现
-		optional string Address = 8; // 地址
-			optional string Memo = 9; // 地址备注(某些链需要)
-		required uint64 SerialNumber = 10; // 流水号
+		optional string Tag = 7; // 标示
+		optional uint32 AddrType = 8; // 地址类型:1-充值;2-提现
+		optional string Address = 9; // 地址(提现类型必填)
+			optional string Memo = 10; // 地址备注(某些链需要)
+		required uint64 SerialNumber = 11; // 流水号
 }

+ 3 - 0
src/constants/funcode.ts

@@ -162,6 +162,9 @@ export enum FunCode {
     GoodsInventoryApplyReq = 196767, // 用户出入库申请请求
     GoodsInventoryApplyRsp = 196768, // 用户出入库申请应答
 
+    HolderTPSLSetReq = 196773, // 持仓止盈止损设置请求
+    HolderTPSLSetRsp = 196774, // 持仓止盈止损设置应答
+
     DigitalAccountTransferApplyReq = 3014657, // 数字账户转入转出申请请求
     DigitalAccountTransferApplyRsp = 3014658, // 数字账户转入转出申请应答
     DigitalOrderReq = 196771, // 数字交易委托请求

+ 17 - 17
src/packages/digital/views/contract/components/position/detail/close/index.vue

@@ -7,24 +7,24 @@
             </template>
             <Form ref="formRef" class="g-form__container" @submit="onCloseSumit">
                 <CellGroup title="持仓信息" inset>
-                    <Cell :title="t('digital.tradeid')" :value="selectedItem.tradeid" />
-                    <Cell :title="t('digital.goodscode')" :value="`${selectedItem.goodscode}/${selectedItem.goodsname}`" />
-                    <Cell :title="t('position.transfer.buyorsell')" :value="getBuyOrSellName(selectedItem.buyorsell, 1)" />
-                    <Cell :title="`${t('position.goods.holddetail.holderprice')}(${selectedItem.currencyname})`"
-                        :value="selectedItem.holderprice.toFixed(selectedItem.decimalplace)" />
-                    <Cell :title="`${t('quote.holdvolume')}(${selectedItem.goodscode})`" :value="selectedItem.holderqty" />
-                    <Cell :title="`${t('position.goods.frozenqty')}(${selectedItem.goodscode})`" :value="selectedItem.freezeqty" />
-                    <Cell :title="`${t('digital.quoteprice')}(${selectedItem.currencyname})`" :value="floatingPL.lastPrice">
+                    <Cell :title="t('digital.tradeid')" :value="selectedRow.tradeid" />
+                    <Cell :title="t('digital.goodscode')" :value="`${selectedRow.goodscode}/${selectedRow.goodsname}`" />
+                    <Cell :title="t('position.transfer.buyorsell')" :value="getBuyOrSellName(selectedRow.buyorsell, 1)" />
+                    <Cell :title="`${t('position.goods.holddetail.holderprice')}(${selectedRow.currencyname})`"
+                        :value="selectedRow.holderprice.toFixed(selectedRow.decimalplace)" />
+                    <Cell :title="`${t('quote.holdvolume')}(${selectedRow.goodscode})`" :value="selectedRow.holderqty" />
+                    <Cell :title="`${t('position.goods.frozenqty')}(${selectedRow.goodscode})`" :value="selectedRow.freezeqty" />
+                    <Cell :title="`${t('digital.quoteprice')}(${selectedRow.currencyname})`" :value="floatingPL.lastPrice">
                         <template #value>
                             <span :class="floatingPL.lastPriceClass">
-                                {{ floatingPL.lastPrice.toFixed(selectedItem.decimalplace) }}
+                                {{ floatingPL.lastPrice.toFixed(selectedRow.decimalplace) }}
                             </span>
                         </template>
                     </Cell>
-                    <Cell :title="`${t('position.goods.holddetail.profitLoss')}(${selectedItem.currencyname})`">
+                    <Cell :title="`${t('position.goods.holddetail.profitLoss')}(${selectedRow.currencyname})`">
                         <template #value>
                             <span :class="floatingPL.profitLossClass">
-                                {{ floatingPL.profitLoss.toFixed(selectedItem.decimalplace) }}
+                                {{ floatingPL.profitLoss.toFixed(selectedRow.decimalplace) }}
                             </span>
                         </template>
                     </Cell>
@@ -37,7 +37,7 @@
                         :rules="formRules.OrderPrice" :label="t('quote.goods.orderprice')">
                         <template #input>
                             <app-stepper v-model="formData.OrderPrice" min="0.0"
-                                :decimal-length="selectedItem.decimalplace" :step="quote?.decimalvalue"
+                                :decimal-length="selectedRow.decimalplace" :step="quote?.decimalvalue"
                                 :auto-fixed="false" />
                         </template>
                     </Field>
@@ -71,7 +71,7 @@ import AppStepper from '@mobile/components/base/stepper/index.vue'
 import AppSelect from '@mobile/components/base/select/index.vue'
 
 const props = defineProps({
-    selectedItem: {
+    selectedRow: {
         type: Object as PropType<Model.TradeHolderDetailRsp>,
         required: true,
     }
@@ -80,12 +80,12 @@ const props = defineProps({
 const userStore = useUserStore()
 const futuresStore = useFuturesStore()
 const positionStore = usePositionStore()
-const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedItem.goodsid }))
+const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedRow.goodsid }))
 const { global: { t } } = i18n
 
 // 可用数量
 const maxQty = computed(() => {
-    const { holderqty, freezeqty, goodsid, buyorsell } = props.selectedItem
+    const { holderqty, freezeqty, goodsid, buyorsell } = props.selectedRow
     const record = positionStore.positionList.find((e) => e.goodsid === goodsid && e.buyorsell === buyorsell)
     const qty = holderqty - freezeqty
     return Math.min(record?.enableqty ?? 0, qty)
@@ -93,7 +93,7 @@ const maxQty = computed(() => {
 
 // 损益
 const floatingPL = computed(() => {
-    const { holderqty, buyorsell, holderamount } = props.selectedItem
+    const { holderqty, buyorsell, holderamount } = props.selectedRow
     return futuresStore.calcFloatingPL(quote.value, buyorsell, holderqty, holderamount)
 })
 
@@ -125,7 +125,7 @@ const onCloseSumit = () => {
         showCancelButton: true,
     }).then(() => {
 
-        const { marketid, goodsid, buyorsell, tradeid } = props.selectedItem
+        const { marketid, goodsid, buyorsell, tradeid } = props.selectedRow
         /// 市场ID
         formData.Header = { GoodsID: goodsid }
         formData.MarketID = marketid

+ 90 - 90
src/packages/digital/views/contract/components/position/detail/index.vue

@@ -1,74 +1,77 @@
 <template>
-    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
-        <app-view class="g-form">
-            <template #header>
-                <app-navbar :title="t('quote.pricing.holdlb')" @back="closed" />
-            </template>
-            <app-pull-refresh ref="pullRefreshRef" class="g-detail-table" v-model:loading="loading"
-                @refresh="onRefresh">
-                <table cellspacing="0" cellpadding="0" v-for="(item, index) in tableList" :key="index">
-                    <tbody>
-                        <tr>
-                            <th colspan="2">
-                                <span>{{ item.goodscode }}/{{ item.goodsname }}</span>
-                                <time class="text-small">{{ formatDate(item.tradetime) }}</time>
-                            </th>
-                            <th>
-                                <span :class="item.buyorsell === 0 ? 'g-price-up' : 'g-price-down'">
-                                    {{ getBuyOrSellName(item.buyorsell, 1) }}
-                                </span>
-                            </th>
-                        </tr>
-                        <tr>
-                            <td colspan="3">
-                                <span class="text-small">{{ $t('account.profitLoss')+`(${currency(item.currencyid)})` }}</span>
-                                <span :class="item.profitLossClass">
-                                    {{ item.profitLoss.toFixed(item.decimalplace) }}
-                                </span>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>
-                                <span class="text-small">{{ $t('position.goods.enableqty')+`(${item.goodscode})` }}</span>
-                                <span>
-                                    {{ item.holderqty - item.freezeqty }}
-                                </span>
-                            </td>
-                            <td>
-                                <span class="text-small">{{ $t('position.goods.holderqty')+`(${item.goodscode})` }}</span>
-                                <span>{{ item.holderqty }}</span>
-                            </td>
-                            <td>
-                                <span class="text-small">{{ $t('position.goods.frozenqty')+`(${item.goodscode})` }}</span>
-                                <span>{{ item.freezeqty }}</span>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>
-                                <span class="text-small">{{ $t('position.goods.holderprice')+`(${currency(item.currencyid)})` }}</span>
-                                <span>{{ item.holderprice }}</span>
-                            </td>
-                            <td>
-                                <span class="text-small">{{ $t('position.goods.holderamount')+`(${currency(item.currencyid)})` }}</span>
-                                <span>{{ item.holderamount }}</span>
-                            </td>
-                            <td></td>
-                        </tr>
-                    </tbody>
-                    <tfoot>
-                        <tr>
-                            <td colspan="3">
-                                <Button size="small" @click="showComponent('Close', item)">{{ $t('operation.close') }}</Button>
-                                <Button size="small" @click="showComponent('MarketClose', item)">{{ $t('digital.marketclose') }}</Button>
-                            </td>
-                        </tr>
-                    </tfoot>
-                </table>
-                <component ref="componentRef" v-bind="{ selectedItem }" :is="componentMap.get(componentId)"
-                    @closed="closeComponent" v-if="componentId" />
-            </app-pull-refresh>
-        </app-view>
-    </app-modal>
+    <app-pull-refresh ref="pullRefreshRef" class="g-detail-table" v-model:loading="loading" @refresh="onRefresh">
+        <table cellspacing="0" cellpadding="0" v-for="(item, index) in tableList" :key="index">
+            <tbody>
+                <tr>
+                    <th colspan="2">
+                        <span>{{ item.goodscode }}/{{ item.goodsname }}</span>
+                        <time class="text-small">{{ formatDate(item.tradetime) }}</time>
+                    </th>
+                    <th>
+                        <span :class="item.buyorsell === 0 ? 'g-price-up' : 'g-price-down'">
+                            {{ getBuyOrSellName(item.buyorsell, 1) }}
+                        </span>
+                    </th>
+                </tr>
+                <tr>
+                    <td colspan="3">
+                        <span class="text-small">{{ $t('account.profitLoss') + `(${currency(item.currencyid)})`
+                        }}</span>
+                        <span :class="item.profitLossClass">
+                            {{ item.profitLoss.toFixed(item.decimalplace) }}
+                        </span>
+                    </td>
+                </tr>
+                <tr>
+                    <td>
+                        <span class="text-small">{{ $t('position.goods.enableqty') + `(${item.goodscode})` }}</span>
+                        <span>
+                            {{ item.holderqty - item.freezeqty }}
+                        </span>
+                    </td>
+                    <td>
+                        <span class="text-small">{{ $t('position.goods.holderqty') + `(${item.goodscode})` }}</span>
+                        <span>{{ item.holderqty }}</span>
+                    </td>
+                    <td>
+                        <span class="text-small">{{ $t('position.goods.frozenqty') + `(${item.goodscode})` }}</span>
+                        <span>{{ item.freezeqty }}</span>
+                    </td>
+                </tr>
+                <tr>
+                    <td>
+                        <span class="text-small">{{ $t('position.goods.holderprice') + `(${currency(item.currencyid)})`
+                            }}</span>
+                        <span>{{ item.holderprice }}</span>
+                    </td>
+                    <td>
+                        <span class="text-small">{{ $t('position.goods.holderamount') + `(${currency(item.currencyid)})`
+                            }}</span>
+                        <span>{{ item.holderamount }}</span>
+                    </td>
+                    <td></td>
+                </tr>
+            </tbody>
+            <tfoot>
+                <tr>
+                    <td colspan="3">
+                        <Button size="small" @click="showComponent('Close', index)">
+                            {{ $t('operation.close') }}
+                        </Button>
+                        <Button size="small" @click="showComponent('MarketClose', index)">
+                            {{ $t('digital.marketclose') }}
+                        </Button>
+                        <Button size="small" @click="showComponent('TPSL', index)"
+                            v-if="item?.tpslflag === 1 && item.riskcontrolmode === 2">
+                            {{ $t('digital.spsl') }}
+                        </Button>
+                    </td>
+                </tr>
+            </tfoot>
+        </table>
+        <component ref="componentRef" v-bind="{ selectedRow: tableList[rowIndex] }" :is="componentMap.get(componentId)"
+            @closed="closeComponent" v-if="componentId" />
+    </app-pull-refresh>
 </template>
 
 <script lang="ts" setup>
@@ -79,13 +82,12 @@ import { getBuyOrSellName, getGoodsCurrencyItemName } from '@/constants/order'
 import { useRequest } from '@/hooks/request'
 import { useComponent } from '@/hooks/component'
 import { queryTradeHolderDetail } from '@/services/api/order'
-import { i18n, useFuturesStore } from '@/stores'
-import AppModal from '@/components/base/modal/index.vue'
+import { useFuturesStore } from '@/stores'
 import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
 
 const props = defineProps({
-    selectedRow: {
-        type: Object as PropType<Model.TradePositionRsp>,
+    params: {
+        type: Object as PropType<Model.TradeHolderDetailReq>,
         required: true,
     }
 })
@@ -93,15 +95,13 @@ 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'))], // 止盈止损
 ])
 
-const { global: { t } } = i18n
+const futuresStore = useFuturesStore()
 const showModal = shallowRef(true) // 是否刷新父组件数据
 const refresh = shallowRef(false)
-const selectedItem = shallowRef<Model.TradeHolderDetailRsp>()
-
-const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedRow.goodsid }))
+const rowIndex = shallowRef(-1)
 
 const currency = (id: number) => {
     return getGoodsCurrencyItemName(id)
@@ -110,20 +110,20 @@ const currency = (id: number) => {
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => onRefresh())
 
 const { dataList, loading, run } = useRequest(queryTradeHolderDetail, {
-    defaultParams: {
-        accids: props.selectedRow.accountid.toString(),
-        goodsid: props.selectedRow.goodsid,
-        buyorsell: props.selectedRow.buyorsell
-    }
+    defaultParams: props.params
 })
 
-const tableList = computed(() => dataList.value.map((item) => ({
-    ...item,
-    ...futuresStore.calcFloatingPL(quote.value, item.buyorsell, item.holderqty, item.holderamount)
-})))
+const tableList = computed(() => dataList.value.map((item) => {
+    const quote = futuresStore.getQuoteItem({ goodsid: item.goodsid })
+
+    return {
+        ...item,
+        ...futuresStore.calcFloatingPL(quote, item.buyorsell, item.holderqty, item.holderamount)
+    }
+}))
 
-const showComponent = (componentName: string, row: Model.TradeHolderDetailRsp) => {
-    selectedItem.value = row
+const showComponent = (componentName: string, index: number) => {
+    rowIndex.value = index
     openComponent(componentName)
 }
 

+ 2 - 2
src/packages/digital/views/contract/components/position/detail/market-close/index.vue

@@ -15,7 +15,7 @@ import { BuyOrSell } from '@/constants/order'
 import { i18n, useUserStore } from '@/stores'
 
 const props = defineProps({
-    selectedItem: {
+    selectedRow: {
         type: Object as PropType<Model.TradeHolderDetailRsp>,
         required: true
     }
@@ -31,7 +31,7 @@ const userStore = useUserStore()
 const onBeforeClose = (action: string) => {
     if (action === 'confirm') {
         fullloading((hideLoading) => {
-            const { marketid, goodsid, holderqty, freezeqty, tradeid, buyorsell } = props.selectedItem ?? {}
+            const { marketid, goodsid, holderqty, freezeqty, tradeid, buyorsell } = props.selectedRow ?? {}
 
             /// 获取对应的市场ID
             formData.Header = { GoodsID: goodsid, MarketID: marketid }

+ 69 - 53
src/packages/digital/views/contract/components/position/list/tpsl/index.vue → src/packages/digital/views/contract/components/position/detail/tpsl/index.vue

@@ -3,16 +3,21 @@
     <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal">
         <app-view class="g-form">
             <template #header>
-                <app-navbar title="汇总平仓" @back="closed" />
+                <app-navbar title="止盈止损" @back="closed" />
             </template>
             <Form ref="formRef" class="g-form__container" @submit="onCloseSumit">
                 <CellGroup :title="t('position.goods.subtitle')" inset>
-                    <Cell :title="t('digital.goodscode')" :value="`${selectedRow.goodscode}/${selectedRow.goodsname}`" />
-                    <Cell :title="t('position.transfer.buyorsell')" :value="getBuyOrSellName(selectedRow.buyorsell, 1)" />
-                    <Cell :title="`${t('position.goods.holddetail.holderprice')}(${getGoodsCurrencyItemName(selectedRow.currencyid)})`"
-                        :value="selectedRow.averageprice" />
-                    <Cell :title="`${t('quote.holdvolume')}(${selectedRow.goodscode})`" :value="selectedRow.curpositionqty" />
-                    <Cell :title="`${t('position.goods.frozenqty')}(${selectedRow.goodscode})`" :value="selectedRow.frozenqty" />
+                    <Cell :title="t('digital.goodscode')"
+                        :value="`${selectedRow.goodscode}/${selectedRow.goodsname}`" />
+                    <Cell :title="t('position.transfer.buyorsell')"
+                        :value="getBuyOrSellName(selectedRow.buyorsell, 1)" />
+                    <Cell
+                        :title="`${t('position.goods.holddetail.holderprice')}(${getGoodsCurrencyItemName(selectedRow.currencyid)})`"
+                        :value="selectedRow.holderprice" />
+                    <Cell :title="`${t('quote.holdvolume')}(${selectedRow.goodscode})`"
+                        :value="selectedRow.holderqty" />
+                    <Cell :title="`${t('position.goods.frozenqty')}(${selectedRow.goodscode})`"
+                        :value="selectedRow.freezeqty" />
                     <Cell :title="`${t('digital.quoteprice')}(${getGoodsCurrencyItemName(selectedRow.currencyid)})`">
                         <template #value>
                             <span :class="selectedRow.lastPriceClass">
@@ -20,7 +25,8 @@
                             </span>
                         </template>
                     </Cell>
-                    <Cell :title="`${t('position.goods.holddetail.profitLoss')}(${getGoodsCurrencyItemName(selectedRow.currencyid)})`">
+                    <Cell
+                        :title="`${t('position.goods.holddetail.profitLoss')}(${getGoodsCurrencyItemName(selectedRow.currencyid)})`">
                         <template #value>
                             <span :class="selectedRow.profitLossClass">
                                 {{ selectedRow.profitLoss.toFixed(selectedRow.decimalplace) }}
@@ -29,30 +35,32 @@
                     </Cell>
                 </CellGroup>
                 <CellGroup :title="t('digital.spsl')" inset>
-                    <Cell :value="`${t('mine.setting.price')} (>=${pricePoints.takeProfit.toFixed(selectedRow.decimalplace)})`">
+                    <Cell
+                        :value="`${t('mine.setting.price')} (>=${pricePoints.takeProfit.toFixed(selectedRow.decimalplace)})`">
                         <template #title>
                             <Checkbox v-model="formData.TPFlag">{{ $t('digital.sp') }}</Checkbox>
                         </template>
                     </Cell>
-                    <Field name="SpPrice" :rules="formRules.SpPrice">
+                    <Field name="TPPrice" :rules="formRules.TPPrice">
                         <template #input>
-                            <app-stepper v-model="formData.SpPrice" :min="pricePoints.takeProfit"
-                                :decimal-length="quote?.decimalplace" :step="quote?.decimalvalue" :button-size="32"
-                                :disabled="!formData.TPFlag" />
+                            <app-stepper v-model="formData.TPPrice" :decimal-length="quote?.decimalplace"
+                                :step="quote?.decimalvalue" :button-size="32" :disabled="!formData.TPFlag"
+                                :auto-fixed="false" />
                         </template>
                     </Field>
                 </CellGroup>
                 <CellGroup inset>
-                    <Cell :value="`${t('mine.setting.price')} (>=${pricePoints.stopLoss.toFixed(selectedRow.decimalplace)})`">
+                    <Cell
+                        :value="`${t('mine.setting.price')} (<=${pricePoints.stopLoss.toFixed(selectedRow.decimalplace)})`">
                         <template #title>
                             <Checkbox v-model="formData.SLFlag">{{ $t('digital.sl') }}</Checkbox>
                         </template>
                     </Cell>
-                    <Field name="SlPrice" :rules="formRules.SlPrice">
+                    <Field name="SLPrice" :rules="formRules.SLPrice">
                         <template #input>
-                            <app-stepper v-model="formData.SlPrice" :max="pricePoints.stopLoss"
-                                :decimal-length="quote?.decimalplace" :step="quote?.decimalvalue" :button-size="32"
-                                :disabled="!formData.SLFlag" />
+                            <app-stepper v-model="formData.SLPrice" :decimal-length="quote?.decimalplace"
+                                :step="quote?.decimalvalue" :button-size="32" :disabled="!formData.SLFlag"
+                                :auto-fixed="false" />
                         </template>
                     </Field>
                 </CellGroup>
@@ -65,19 +73,19 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, PropType, onMounted, computed } from 'vue'
+import { shallowRef, reactive, PropType, computed, onMounted } from 'vue'
 import { CellGroup, Cell, Button, FieldRule, Form, Field, FormInstance, Checkbox } from 'vant'
 import { dialog, fullloading } from '@/utils/vant'
+import { handleRequestBigNumber } from '@/filters'
 import { getBuyOrSellName, getGoodsCurrencyItemName, BuyOrSell } from '@/constants/order'
-import { useOrder } from '@/business/trade'
-import { i18n, useFuturesStore, useUserStore } from '@/stores'
-import { EBuildType, EDelistingType, EOrderOperateType, EListingSelectType, EPriceMode, EValidType } from '@/constants/client'
+import { holderTPSLSet } from '@/services/api/trade'
+import { i18n, useFuturesStore } from '@/stores'
 import AppModal from '@/components/base/modal/index.vue'
 import AppStepper from '@mobile/components/base/stepper/index.vue'
 
 const props = defineProps({
     selectedRow: {
-        type: Object as PropType<Model.TradePositionRsp & {
+        type: Object as PropType<Model.TradeHolderDetailRsp & {
             lastPrice: number;
             lastPriceClass: string;
             profitLoss: number;
@@ -88,14 +96,24 @@ const props = defineProps({
 })
 
 const { global: { t } } = i18n
-const userStore = useUserStore()
 const futuresStore = useFuturesStore()
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 
-const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedRow.goodsid }))
+const formData = reactive<Partial<Proto.HolderTPSLSetReq>>({
+    Header: {
+        MarketID: props.selectedRow.marketid,
+        AccountID: props.selectedRow.accountid,
+    },
+    TradeID: handleRequestBigNumber(props.selectedRow.tradeid),
+    AccountID: props.selectedRow.accountid,
+    BuyOrSell: props.selectedRow.buyorsell,
+    GoodsID: props.selectedRow.goodsid,
+    TPFlag: props.selectedRow.tpsl_tpflag,
+    SLFlag: props.selectedRow.tpsl_slflag
+})
 
-const { formSubmit, formData } = useOrder()
+const quote = computed(() => futuresStore.getQuoteItem({ goodsid: props.selectedRow.goodsid }))
 
 const pricePoints = computed(() => {
     const { decimalplace = 0, buyslpoint, buytppoint, sellslpoint, selltppoint } = quote.value ?? {}
@@ -134,43 +152,44 @@ const pricePoints = computed(() => {
 
 // 表单验证规则
 const formRules: { [key: string]: FieldRule[] } = {
-    SpPrice: [{
+    TPPrice: [{
         message: '请输入止盈价格',
         validator: () => {
-            return !!formData.SpPrice
+            if (formData.TPFlag) {
+                const value = Number(formData.TPPrice)
+                if (value < pricePoints.value.takeProfit) {
+                    return '价格不在有效范围内'
+                }
+            }
+            return true
         }
     }],
-    SlPrice: [{
+    SLPrice: [{
         message: '请输入止损价格',
         validator: () => {
-            return !!formData.SlPrice
+            if (formData.SLFlag) {
+                const value = Number(formData.SLFlag)
+                if (value > pricePoints.value.stopLoss) {
+                    return '价格不在有效范围内'
+                }
+            }
+            return true
         }
     }],
 }
 
 const onCloseSumit = () => {
     dialog({
-        message: '确认要平仓吗?',
+        message: '确认提交吗?',
         showCancelButton: true,
     }).then(() => {
-
-        const { marketid, goodsid, buyorsell } = props.selectedRow
-        /// 市场ID
-        formData.Header = { GoodsID: goodsid }
-        formData.MarketID = marketid
-        formData.BuyOrSell = buyorsell === BuyOrSell.Buy ? BuyOrSell.Sell : BuyOrSell.Buy
-        formData.GoodsID = goodsid
-        formData.ListingSelectType = EListingSelectType.LISTINGSELECTTYPE_DELISTINGTHENLISTING
-        formData.DelistingType = EDelistingType.DELISTINGTYPE_PRICE
-        formData.BuildType = EBuildType.BUILDTYPE_CLOSE
-        formData.TimevalidType = EValidType.VALIDTYPE_DR
-        formData.OperateType = EOrderOperateType.ORDEROPERATETYPE_NORMAL
-        const param112 = userStore.getSystemParamValue('112')
-        formData.MarketMaxSub = Number(param112) || 100
-
-        /// loding....
         fullloading((hideLoading) => {
-            formSubmit().then(() => {
+            formData.TPFlag = Number(formData.TPFlag)
+            formData.SLFlag = Number(formData.SLFlag)
+
+            holderTPSLSet({
+                data: formData
+            }).then(() => {
                 hideLoading(t('common.submitsuccess'), 'success')
                 closed()
             }).catch((err) => {
@@ -186,11 +205,8 @@ const closed = () => {
 }
 
 onMounted(() => {
-    formData.PriceMode = EPriceMode.PRICEMODE_MARKET
-    formData.OrderPrice = props.selectedRow.lastPrice
-    formData.OrderQty = props.selectedRow.enableqty
-    formData.SpPrice = pricePoints.value.takeProfit
-    formData.SlPrice = pricePoints.value.stopLoss
+    formData.TPPrice = Number(props.selectedRow.tpsl_tpprice) || pricePoints.value.takeProfit
+    formData.SLPrice = Number(props.selectedRow.tpsl_slprice) || pricePoints.value.stopLoss
 })
 
 // 暴露组件属性给父组件调用

+ 6 - 5
src/packages/digital/views/contract/components/position/list/index.vue

@@ -59,10 +59,12 @@
             <tfoot>
                 <tr>
                     <td colspan="3">
-                        <Button size="small" @click="showComponent('Close', index)">{{ $t('operation.close') }}</Button>
-                        <Button size="small" @click="showComponent('MarketClose', index)">{{ $t('digital.marketclose')
-                            }}</Button>
-                        <Button size="small" @click="showComponent('TPSL', index)">{{ $t('digital.spsl') }}</Button>
+                        <Button size="small" @click="showComponent('Close', index)">
+                            {{ $t('operation.close') }}
+                        </Button>
+                        <Button size="small" @click="showComponent('MarketClose', index)">
+                            {{ $t('digital.marketclose') }}
+                        </Button>
                     </td>
                 </tr>
             </tfoot>
@@ -90,7 +92,6 @@ 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'))], // 详情
 ])
 

+ 17 - 9
src/packages/digital/views/contract/detail/index.vue

@@ -5,20 +5,24 @@
             <app-navbar title="合约明细" />
         </template>
         <Grid :border="false" :column-num="quotes.length ? 2 : 1">
-            <GridItem icon="peer-pay" :text="$t('digital.wallet-transfer')" :to="{ name: 'wallet-transfer', query: { id: accountid } }" />
-            <GridItem icon="chart-trending-o" :text="$t('digital.spot-goods-detail')" @click="navigateToContractDetail()" v-if="quotes.length" />
+            <GridItem icon="peer-pay" :text="$t('digital.wallet-transfer')"
+                :to="{ name: 'wallet-transfer', query: { id: accountid } }" />
+            <GridItem icon="chart-trending-o" :text="$t('digital.spot-goods-detail')"
+                @click="navigateToContractDetail()" v-if="quotes.length" />
         </Grid>
         <div class="g-detail-table" v-if="accountItem">
             <table cellspacing="0" cellpadding="0">
                 <tbody>
                     <tr>
                         <td>
-                            <span class="text-small">{{ $t('digital.currencydecimalplace')+`(${currency(accountItem.currencyid)})` }}</span>
+                            <span class="text-small">{{
+                                $t('digital.currencydecimalplace') + `(${currency(accountItem.currencyid)})` }}</span>
                             <span>{{ accountItem.balance.toFixed(accountItem.currencydecimalplace) }}</span>
                         </td>
                         <td>
                             <span class="text-small">{{ $t('account.profitLoss') }}</span>
-                            <span :class="handlePriceColor(accountItem.profitLoss)">{{ accountItem.profitLoss.toFixed(accountItem.currencydecimalplace) }}</span>
+                            <span :class="handlePriceColor(accountItem.profitLoss)">{{
+                                accountItem.profitLoss.toFixed(accountItem.currencydecimalplace) }}</span>
                         </td>
                         <td>
                             <span class="text-small">{{ $t('account.riskRate') }}</span>
@@ -29,15 +33,19 @@
                     </tr>
                     <tr>
                         <td>
-                            <span class="text-small">{{ $t('mine.availableFunds')+`(${currency(accountItem.currencyid)})` }}</span>
+                            <span class="text-small">{{
+                                $t('mine.availableFunds') + `(${currency(accountItem.currencyid)})`
+                                }}</span>
                             <span>{{ accountItem.avaiableBalance.toFixed(accountItem.currencydecimalplace) }}</span>
                         </td>
                         <td>
-                            <span class="text-small">{{ $t('account.usedMargin')+`(${currency(accountItem.currencyid)})` }}</span>
+                            <span class="text-small">{{ $t('account.usedMargin') + `(${currency(accountItem.currencyid)})`
+                                }}</span>
                             <span>{{ accountItem.usedmargin.toFixed(accountItem.currencydecimalplace) }}</span>
                         </td>
                         <td>
-                            <span class="text-small">{{ $t('account.freeze')+`(${currency(accountItem.currencyid)})` }}</span>
+                            <span class="text-small">{{ $t('account.freeze') + `(${currency(accountItem.currencyid)})`
+                                }}</span>
                             <span>{{ accountItem.freezeMargin.toFixed(accountItem.currencydecimalplace) }}</span>
                         </td>
                     </tr>
@@ -46,7 +54,7 @@
         </div>
         <Tabs>
             <Tab :title="t('digital.position')">
-                <contract-position :params="{ accountid }" />
+                <contract-position :params="{ accids: accountid.toString() }" />
             </Tab>
             <Tab :title="t('digital.order')">
                 <contract-order v-bind="{ accountid }" />
@@ -77,7 +85,7 @@ import { useNavigation } from '@mobile/router/navigation'
 import { i18n, useAccountStore, useFuturesStore } from '@/stores'
 import ContractOrder from '../components/order/index.vue'
 import ContractTrade from '../components/trade/index.vue'
-import ContractPosition from '../components/position/list/index.vue'
+import ContractPosition from '../components/position/detail/index.vue'
 import ContractStatement from '../components/statement/index.vue'
 import { getGoodsCurrencyItemName } from '@/constants/order'
 

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

@@ -93,7 +93,7 @@ import { useOrder } from '@/business/trade'
 import { BuyOrSell, getGoodsCurrencyItemName, PriceMode } from '@/constants/order'
 import AppSelect from '@mobile/components/base/select/index.vue'
 import AppStepper from '@mobile/components/base/stepper/index.vue'
-import ContractPosition from '../../components/position/list/index.vue'
+import ContractPosition from '../../components/position/detail/index.vue'
 import ContractOrder from '../../components/order/list/index.vue'
 import ContractAccount from '../../components/account/index.vue'
 
@@ -131,11 +131,8 @@ const enumName = computed(() => {
 // 保证金设置(固定) 时:可开数量 = 可用余额 / (合约乘数 * 固定值)
 // 保证金设置(比率) 时:可开数量 = 可用余额 / (价格 * 合约乘数 * 比率值)
 const calculations = computed(() => {
-
     const feeValue = futuresStore.getFeeValue(quote.value, 101)
 
-    console.log(quote.value?.tradefees)
-
     const { bid = 0, ask = 0, agreeunit = 0, currencyid = 0, goodscurrencyid = 0, marketmarginalgorithm, marketmarginvalue = 0 } = quote.value ?? {}
     const { OrderPrice = 0, OrderQty = 0, BuyOrSell } = formData
 

+ 71 - 14
src/packages/digital/views/wallet/deposit/index.vue

@@ -6,26 +6,36 @@
         </template>
         <Form ref="formRef" class="g-form__container g-layout-block" @submit="onSubmit">
             <CellGroup inset>
-                <Field name="CurrencyID" label="币种" is-link>
+                <Field name="currenty" label="币种" :rules="formRules.currenty" is-link>
+                    <template #input>
+                        <app-select v-model="state.currentyId" :options="digitalCurrentyList"
+                            @confirm="onCurrentyChange" />
+                    </template>
                 </Field>
-                <Field name="Amount" label="数量">
+                <Field name="token" label="网络" :rules="formRules.token" is-link>
+                    <template #input>
+                        <app-select v-model="state.tokenId" :options="walletTokens"
+                            :optionProps="{ label: 'chain_id', value: 'id' }" />
+                    </template>
                 </Field>
                 <Cell title="余额" :value="balance" />
             </CellGroup>
         </Form>
         <div class="g-form__footer inset">
-            <Button type="primary" @click="formRef?.submit" block>提交</Button>
+            <Button type="primary" @click="formRef?.submit" block>创建新地址</Button>
         </div>
+        {{ addressList }}
     </app-view>
 </template>
 
 <script lang="ts" setup>
 import { shallowRef, computed, reactive, onMounted } from 'vue'
-import { FormInstance, Form, Button, CellGroup, Field, Cell } from 'vant'
+import { FormInstance,FieldRule, Form, Button, CellGroup, Field, Cell } from 'vant'
 import { fullloading } from '@/utils/vant'
 import { formatDecimal } from '@/filters'
+import { getDigitalCurrencyList } from '@/constants/order'
 import { useRequest } from '@/hooks/request'
-import { queryWalletAddress, queryWalletChains, createDigitalWalletAddress } from '@/services/api/digital'
+import { queryWalletAddress, queryWalletTokens, createDigitalWalletAddress } from '@/services/api/digital'
 import { useNavigation } from '@mobile/router/navigation'
 import { useSpotAccountStore } from '../components/spot/composables'
 import AppSelect from '@mobile/components/base/select/index.vue'
@@ -36,11 +46,19 @@ const formRef = shallowRef<FormInstance>()
 const currencyId = getQueryStringToNumber('id')
 
 const spotAccountStore = useSpotAccountStore()
+const digitalCurrentyList = getDigitalCurrencyList()
 
-const formData = reactive<Partial<Proto.CreateDigitalWalletAddressReq>>({
-    DigitalAccountID: 0,
+const state = reactive({
+    currentyId: currencyId,
+    tokenId: 0
 })
 
+const addressList = computed(() => walletAddress.value.filter((e) => e.token_id === tokenItem.value?.token_id))
+
+const currentyItem = computed(() => digitalCurrentyList.find((e) => e.enumitemname === state.currentyId))
+
+const tokenItem = computed(() => walletTokens.value.find((e) => e.id === state.tokenId))
+
 const accountItem = computed(() => spotAccountStore.getAccountItem({
     currencyid: currencyId
 }))
@@ -51,14 +69,52 @@ const balance = computed(() => {
     return formatDecimal(balance, accountItem.value?.currencydecimalplace)
 })
 
-const { dataList, run } = useRequest(queryWalletAddress, { manual: true })
+const { dataList: walletAddress, run: getWalletAddress } = useRequest(queryWalletAddress, {
+    manual: true
+})
+
+const { dataList: walletTokens, run: getWalletTokens } = useRequest(queryWalletTokens, {
+    manual: true
+})
+
+// 表单验证规则
+const formRules: { [key: string]: FieldRule[] } = {
+    currenty: [{
+        message: '请选择币种',
+        validator: () => !!state.currentyId
+    }],
+    token: [{
+        message: '请选择网络',
+        validator: () => !!state.tokenId
+    }],
+}
+
+const onCurrentyChange = () => {
+    state.tokenId = 0
+
+    if (currentyItem.value) {
+        getWalletTokens({
+            currency: currentyItem.value.label
+        })
+    } else {
+        walletTokens.value = []
+    }
+}
 
 const onSubmit = () => {
+    const { channel_code, chain_id, token_id } = tokenItem.value ?? {}
+
     fullloading((hideLoading) => {
         createDigitalWalletAddress({
-            data: formData
+            data: {
+                DigitalAccountID: Number(accountItem.value?.digitalaccountid),
+                ChannelCode: channel_code,
+                ChainID: chain_id,
+                TokenID: token_id,
+                AddrType: 1
+            }
         }).then(() => {
-            hideLoading('充值成功', 'success')
+            hideLoading('创建成功', 'success')
         }).catch((err) => {
             hideLoading(err, 'fail')
         })
@@ -66,10 +122,11 @@ const onSubmit = () => {
 }
 
 onMounted(() => {
-    if (accountItem.value) {
-        run({
-            digitalaccountid: accountItem.value.digitalaccountid
-        })
+    const digitalaccountid = accountItem.value?.digitalaccountid
+    if (digitalaccountid) {
+        getWalletAddress({ digitalaccountid })
     }
+
+    onCurrentyChange()
 })
 </script>

+ 1 - 2
src/packages/digital/views/wallet/transfer/index.vue

@@ -16,8 +16,7 @@
             <CellGroup inset>
                 <Field name="CurrencyID" label="币种" :rules="formRules.CurrencyID" is-link>
                     <template #input>
-                        <app-select v-model="formData.CurrencyID" :options="currencyOptions"
-                            :optionProps="{ label: 'enumdicname', value: 'enumitemname' }" />
+                        <app-select v-model="formData.CurrencyID" :options="currencyOptions" />
                     </template>
                 </Field>
                 <Field name="Amount" label="数量" :rules="formRules.Amount">

+ 10 - 0
src/services/api/digital/index.ts

@@ -189,4 +189,14 @@ export function queryWalletChains(config: RequestConfig<Model.WalletChainsReq>)
         url: '/Wallet/QueryWalletChains',
         params: config.data,
     })
+}
+
+/**
+ * 查询代币信息
+ */
+export function queryWalletTokens(config: RequestConfig<Model.WalletTokensReq>) {
+    return http.commonRequest<Model.WalletTokensRsp[]>({
+        url: '/Wallet/QueryWalletTokens',
+        params: config.data,
+    })
 }

+ 17 - 1
src/services/api/trade/index.ts

@@ -1,7 +1,7 @@
 import { v4 } from 'uuid'
 import { formatDate } from '@/filters'
 import { RequestConfig } from '@/services/http/types'
-import { ClientType,OrderSrc } from '@/constants/client'
+import { ClientType, OrderSrc } from '@/constants/client'
 import { useLoginStore, useAccountStore } from '@/stores'
 import http from '@/services/http'
 
@@ -437,4 +437,20 @@ export function goodsInventoryApply(config: RequestConfig<Partial<Proto.GoodsInv
         requestCode: 'GoodsInventoryApplyReq',
         responseCode: 'GoodsInventoryApplyRsp',
     })
+}
+
+/**
+ * 持仓止盈止损设置
+ */
+export function holderTPSLSet(config: RequestConfig<Partial<Proto.HolderTPSLSetReq>>) {
+    return http.mqRequest<Proto.HolderTPSLSetRsp>({
+        data: {
+            ClientSerialNo: v4(),
+            clientordertime: formatDate(new Date().toISOString()),
+            clienttype: ClientType.Web, // 终端类型
+            ...config.data
+        },
+        requestCode: 'HolderTPSLSetReq',
+        responseCode: 'HolderTPSLSetRsp',
+    })
 }

+ 32 - 3
src/types/model/digital.d.ts

@@ -186,13 +186,17 @@ declare namespace Model {
 
     /** 查询钱包地址 响应 */
     interface WalletAddressRsp {
+        addr_type: number; // 地址类型:1-充值;2-提现
         address: string; // 区块链地址
-        addrtype: number; // 地址类型:1-充值;2-提现
-        chaincode: string; // 链代码(如BTC,ETH)
-        channelcode: string; // 渠道代码
+        chain_id: string; // 链代码(如BTC,ETH)
+        channel_code: string; // 渠道代码
+        create_time: string; // 创建时间
         digitalaccountid: number; // 数字账户ID
         id: number; // 地址ID
         memo: string; // 地址备注(某些链需要)
+        status: number; // 状态:0-禁用;1-启用
+        token_id: string; // 代币ID(充值类型必填)
+        update_time: string; // 修改时间
     }
 
     /** 查询钱包链 请求 */
@@ -232,4 +236,29 @@ declare namespace Model {
             token_id: string; // 代币ID
         }[];
     }
+
+    /** 查询代币信息 请求 */
+    interface WalletTokensReq {
+        currency: string; // 币种代码
+    }
+
+    /** 查询代币信息 响应 */
+    interface WalletTokensRsp {
+        asset_id: string; // 资产 ID,关联交易所账户中持有资产的唯一标识符
+        asset_model_type: string; // 模型类型
+        can_deposit: number; // 是否可以充值
+        can_withdraw: number; // 是否可以提现
+        chain_id: string; // 所属链ID
+        channel_code: string; // 渠道ID
+        deposit_threshold: string; // 最低充值金额
+        dust_threshold: string; // 最低提现金额
+        enabled: number; // 是否可用,0-不可用;1-可用
+        fee_token_id: string; // 手续费代币ID
+        icon_url: string; // 代币图标URL
+        id: number; // SEQ_WALLET_TOKENS
+        name: string; // 代币全名
+        symbol: string; // 代币符号
+        token_decimal: number; // 小数位
+        token_id: string; // 代币ID
+    }
 }

+ 54 - 90
src/types/model/order.d.ts

@@ -719,96 +719,60 @@ declare namespace Model {
 
     /*  查询我的持仓/掉期持仓-持仓明细 响应*/
     interface TradeHolderDetailRsp {
-        /// 账号ID
-        accountid: number
-        /// 合约乘数
-        agreeunit: number
-        /// 方向 - 0:买 1:卖
-        buyorsell: number
-        /// 商品币种id
-        currencyid: number
-        /// 币种名称
-        currencyname: string
-        /// 商品价格小数位
-        decimalplace: number
-        /// 商品单位名称
-        enumdicname: string
-        /// 行权周期(天) - 1:滚动行权时填写
-        expirecycle: number
-        /// 行权日(yyyyMMdd) - 到期日
-        expiredate: string
-        /// 行权日类型 - 1:滚动行权 2:固定日行权
-        expiretype: number
-        /// 冻结数量
-        freezeqty: number
-        /// 商品代码
-        goodscode: string
-        /// 商品ID
-        goodsid: number
-        /// 商品名称
-        goodsname: string
-        /// 商品单位id
-        goodunitid: number
-        /// 持仓金额
-        holderamount: number
-        /// 持仓授信金额
-        holdercredit: number
-        /// 剩余冻结天数
-        holderdays: number
-        /// 持仓价格
-        holderprice: number
-        /// 持仓数量
-        holderqty: number
-        /// 是否确认行权- 0:否 1:是
-        isconfirmexercise: number
-        /// 是否预申报- 0:否 1:是 2:不可行权
-        ispreexercise: number
-        /// 市场id
-        marketid: number
-        /// 市场名称
-        marketname: string
-        /// 建仓价格
-        openprice: number
-        /// 建仓数量
-        openqty: number
-        /// 期权类型 - 1:认购(看涨) 2:认沽(看跌)
-        optiontype: number
-        /// 预申报价格
-        preexerciseprice: number
-        /// 权利金
-        premium: number
-        /// 商品成交量小数位
-        qtydecimalplace: number
-        /// 标的合约代码
-        refgoodscode: string
-        /// 标的合约id
-        refgoodsid: number
-        /// 释放持仓金额
-        releaseamount: number
-        /// 释放持仓授信金额
-        releaseholdercredit: number
-        /// 风控方式(52模式) 1:按单风控 2:按账户风控
-        riskcontrolmode: number
-        /// 资金账号名称
-        taname: string
-        /// 成交金额
-        tradeamount: number
-        /// 交易日(yyyyMMdd)
-        tradedate: string
-        /// 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
-        tradeid: string
-        /// 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
-        trademode: number
-        /// 交易属性
-        tradeproperty: number
-        /// 交易时间
-        tradetime: string
-        /// 用户id
-        userid: number
-        /// 用户名称
-        username: string
-        /// 报价货币ID - taaccount
-        tacurrencyid: number
+        accountid: number; // 账号ID
+        agreeunit: number; // 合约乘数
+        buyorsell: number; // 方向 - 0:买 1:卖
+        currencyid: number; // 商品币种id
+        currencyname: string; // 币种名称
+        decimalplace: number; // 商品价格小数位
+        enumdicname: string; // 商品单位名称
+        expirecycle: number; // 行权周期(天) - 1:滚动行权时填写
+        expiredate: string; // 行权日(yyyyMMdd) - 到期日
+        expiretype: number; // 行权日类型 - 1:滚动行权 2:固定日行权
+        freezeqty: number; // 期初均价
+        goodscode: string; // 商品代码
+        goodsid: number; // 商品ID
+        goodsname: string; // 商品名称
+        goodunitid: number; // 商品单位id
+        holderamount: number; // 持仓金额
+        holdercredit: number; // 持仓授信金额
+        holderdays: number; // 剩余冻结天数
+        holderprice: number; // 持仓价格
+        holderqty: number; // 期初均价
+        isconfirmexercise: number; // 是否确认行权- 0:否 1:是
+        ispreexercise: number; // 是否预申报- 0:否 1:是 2:不可行权
+        marketid: number; // 市场id
+        marketname: string; // 市场名称
+        openprice: number; // 建仓价格
+        openqty: number; // 期初均价
+        optiontype: number; // 期权类型 - 1:认购(看涨) 2:认沽(看跌)
+        preexerciseprice: number; // 预申报价格
+        premium: number; // 权利金
+        qtydecimalplace: number; // 商品成交量小数位
+        refgoodscode: string; // 标的合约代码
+        refgoodsid: number; // 标的合约id
+        releaseamount: number; // 释放持仓金额
+        releaseholdercredit: number; // 释放持仓授信金额
+        riskcontrolmode: number; // 风控方式(52模式) 1:按单风控 2:按账户风控
+        tacurrencyid: number; // 报价货币ID - taaccount
+        taname: string; // 资金账号名称
+        tpsl_executeprice: string; // 执行价格(10按账户风控)
+        tpsl_executeretcode: number; // 执行错误代码(10按账户风控)
+        tpsl_executetime: string; // 执行时间(10按账户风控)
+        tpsl_orderstatus: number; // 止盈止损单状态 - 1:待执行 2:执行中 3:已执行 4:已失效 5:执行失败(10按账户风控)
+        tpsl_slflag: number; // 止损标识 - 0:未设置 1:已设置(10按账户风控)
+        tpsl_slprice: string; // 止损价格(10按账户风控)
+        tpsl_tpflag: number; // 止盈标识 - 0:未设置 1:已设置(10按账户风控)
+        tpsl_tpprice: string; // 止盈价格(10按账户风控)
+        tpslflag: number; // 是否开启止盈止损 - 0:不开启 1:开启(10 按单风控)
+        tradeamount: number; // 成交金额
+        tradedate: string; // 交易日(yyyyMMdd)
+        tradeid: string; // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
+        trademode: number; // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
+        tradeproperty: number; // 交易属性
+        tradetime: string; // 交易时间
+        userid: number; // 用户id
+        username: string; // 用户名称
     }
 
     /*   查询我的订单/掉期委托 请求*/

+ 4 - 2
src/types/proto/digital.d.ts

@@ -112,9 +112,10 @@ declare global {
         /** 创建数字钱包地址请求 */
         interface CreateDigitalWalletAddressReq {
             Header?: IMessageHead;
-            DigitalAccountID: number; // 数字账户ID
+            DigitalAccountID: number | Long; // 数字账户ID
             ChannelCode: string; // 渠道代码
             ChainID: string; // 链ID
+            TokenID: string; // 代币ID(充值类型必填)
             AddrType?: number; // 地址类型:1-充值;2-提现
             Address?: string; // 地址(提现类型必填)
             Memo?: string; // 地址备注(某些链需要)
@@ -129,6 +130,7 @@ declare global {
             DigitalAccountID: number; // 数字账户ID
             ChannelCode: string; // 渠道代码
             ChainID: string; // 链ID
+            TokenID: string; // 代币ID(充值类型必填)
             AddrType: number; // 地址类型:1-充值;2-提现
             Address: string; // 地址
             Memo: string; // 地址备注(某些链需要)
@@ -140,9 +142,9 @@ declare global {
             Header?: IMessageHead;
             UserID: number; // 用户ID
             CurrencyID: number; // 币种ID
-            WalletID: number; // 钱包ID
             DigitalAccountID: number; // 数字账户ID
             Amount: number; // 金额(正值)
+            Address: string; // 地址
             OperateSrc: number; // 操作来源-枚举"operatesrc"(1:管理端,2:终端)
             ClientTicket: string; // 客户端流水号
             Remark?: string; // 备注

+ 26 - 0
src/types/proto/trade.d.ts

@@ -850,5 +850,31 @@ declare global {
             ApplyID: number; // 申请单Id
             ApplyStatus: number; // 申请状态1:待审核
         }
+
+        /** 持仓止盈止损设置请求 */
+        interface HolderTPSLSetReq {
+            Header?: IMessageHead; // 消息头
+            ClientSerialNo: string; // 客户端流水号
+            TradeID: string | Long; // 交易单号
+            AccountID: number; // 交易账号
+            BuyOrSell: number; // 买卖方向
+            GoodsID: number; // 商品ID
+            TPFlag: number; // 止盈标识:0-未设置1-设置
+            TPPrice: number; // 止盈价格
+            SLFlag: number; // 止损标识:0-未设置1-设置
+            SLPrice: number; // 止损价格
+            clientordertime: string; // 委托时间
+            clienttype: number; // 客户端类型-0:保留为未填终端类型
+        }
+        
+        /** 持仓止盈止损设置应答 */
+        interface HolderTPSLSetRsp {
+            Header: IMessageHead; // 消息头
+            RetCode: number; // 返回码
+            RetDesc: string; // 描述信息
+            TradeID: number; // 交易单号
+            AccountID: number; // 交易账号
+            BuyOrSell: number; // 买卖方向
+        }
     }
 }