Browse Source

新增股票平仓和全平功能,更新订单列表以支持平仓操作,并添加相应的对话框和逻辑处理。

master
TorsenLi 5 days ago
parent
commit
0135e61379
  1. 10
      src/api/exchange.js
  2. 283
      src/views/exchangeStock/order-list.vue

10
src/api/exchange.js

@ -41,6 +41,16 @@ class Exchange {
static stockholdPosition(data, config) { static stockholdPosition(data, config) {
return server.get('/stock/holdPosition', {params:data,config} ) return server.get('/stock/holdPosition', {params:data,config} )
} }
// 股票平仓(部分/指定数量)
static stockClosePosition(data, config) {
return server.post('/stock/closePosition', data, config);
}
// 股票市价全平
static stockCloseAllPosition(data, config) {
return server.post('/stock/closeAllPosition', data, config);
}
} }
export default Exchange; export default Exchange;

283
src/views/exchangeStock/order-list.vue

@ -92,6 +92,7 @@
<th>{{$t("exchange.a8")}}</th> <th>{{$t("exchange.a8")}}</th>
<th>{{$t("exchange.a9")}}</th> <th>{{$t("exchange.a9")}}</th>
<th>{{$t("exchange.a10")}}</th> <th>{{$t("exchange.a10")}}</th>
<th class="text-right">{{ $t("common.action") }}</th>
</tr> </tr>
</thead> </thead>
<tbody class="order-tbody"> <tbody class="order-tbody">
@ -104,6 +105,12 @@
<td :class="item.dayProfit>0?'increace':item.dayProfit<0?'decreace':''">{{item.dayProfit}}</td> <td :class="item.dayProfit>0?'increace':item.dayProfit<0?'decreace':''">{{item.dayProfit}}</td>
<td :class="item.unRealProfit>0?'increace':item.unRealProfit<0?'decreace':''">{{item.unRealProfit}}</td> <td :class="item.unRealProfit>0?'increace':item.unRealProfit<0?'decreace':''">{{item.unRealProfit}}</td>
<td :class="item.profitRate>0?'increace':item.profitRate<0?'decreace':''">{{item.profitRate}}</td> <td :class="item.profitRate>0?'increace':item.profitRate<0?'decreace':''">{{item.profitRate}}</td>
<td class="text-nowrap text-right">
<button type="button" class="btn btn-sm btn-danger mb-1"
@click="openCloseDialog(item)">{{ $t("contract.d6") }}</button>
<button type="button" class="btn btn-sm btn-outline-danger mb-1"
@click="closeAllPosition(item)">{{ $t("contract.h1") }}</button>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -242,11 +249,54 @@
</div> </div>
</div> </div>
</div> </div>
<el-dialog
:title="$t('contract.d6')"
:visible.sync="closeDialogVisible"
width="420px"
custom-class="stock-close-dialog"
>
<el-form label-width="72px" size="small" class="stock-close-form">
<el-form-item :label="$t('contract.d8')">
<div class="close-price-row">
<el-input
v-if="closeForm.type == 1"
v-model="closeForm.entrust_price"
type="number"
/>
<el-input v-else disabled :value="$t('contract.d9')" />
<el-button @click="closeForm.type = closeForm.type == 1 ? 2 : 1">
{{ closeForm.type == 1 ? $t('contract.d9') : $t('contract.e0') }}
</el-button>
</div>
</el-form-item>
<el-form-item :label="$t('contract.e1')">
<el-input v-model="closeForm.amount" type="number" />
</el-form-item>
<el-form-item label="">
<div class="close-available">
{{ $t('contract.e9') }} {{ activePosition.usable_balance }}
</div>
<el-slider
:value="closeSliderStep"
@input="closeSliderChange"
:format-tooltip="closeSliderTooltip"
:step="25"
show-stops
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialogVisible = false">{{ $t('contract.c4') }}</el-button>
<el-button type="primary" @click="submitClosePosition">{{ $t('contract.c5') }}</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import Order from "@/api/order"; import Order from "@/api/order";
import Exchange from "@/api/exchange";
import math from "@/utils/class/math.js"; import math from "@/utils/class/math.js";
export default { export default {
@ -264,11 +314,105 @@
data() { data() {
return { return {
currentTab: "stockholdPosition", currentTab: "stockholdPosition",
activeItems: [] activeItems: [],
closeDialogVisible: false,
activePosition: {},
closeForm: {
type: 2,
entrust_price: "",
amount: ""
}
}; };
}, },
computed: {
closeSliderStep() {
if (!this.closeForm.amount || !this.activePosition.usable_balance) return 0;
return math.multiple(
math.division(this.closeForm.amount, this.activePosition.usable_balance),
100
);
}
},
methods: { methods: {
omitTo: math.omitTo, omitTo: math.omitTo,
closeSliderTooltip(val) {
return Math.round(val) + "%";
},
openCloseDialog(item) {
if (!this.isLogin) {
this.$confirm(this.$t('nav.login'), {
confirmButtonText: this.$t('common.confirmBtn'),
cancelButtonText: this.$t('common.cancelBtn'),
type: 'warning'
}).then(() => {
this.$router.push('/sign-in');
}).catch(() => {});
return;
}
this.activePosition = item;
this.closeForm = {
type: 2,
entrust_price: item.realtimePrice || item.cost_price || "",
amount: item.usable_balance
};
this.closeDialogVisible = true;
},
closeSliderChange(val) {
this.closeForm.amount = math.omitTo(
math.multiple(this.activePosition.usable_balance, val / 100),
this.qtyDecimals
);
},
submitClosePosition() {
const amount = Number(this.closeForm.amount);
if (!amount || amount <= 0) {
this.$message.warning(this.$t('nav.a2'));
return;
}
if (this.closeForm.type == 1 && !this.closeForm.entrust_price) {
this.$message.warning(this.$t('nav.a1'));
return;
}
const data = {
symbol: this.activePosition.pair_name,
type: this.closeForm.type,
amount
};
if (this.closeForm.type == 1) {
data.entrust_price = this.closeForm.entrust_price;
}
Exchange.stockClosePosition(data).then(() => {
this.$message.success(this.$t('contract.f6'));
this.closeDialogVisible = false;
this.update();
}).catch(() => {});
},
closeAllPosition(item) {
if (!this.isLogin) {
this.$confirm(this.$t('nav.login'), {
confirmButtonText: this.$t('common.confirmBtn'),
cancelButtonText: this.$t('common.cancelBtn'),
type: 'warning'
}).then(() => {
this.$router.push('/sign-in');
}).catch(() => {});
return;
}
this.$confirm(
`${this.$t('contract.h1')} ${item.pair_name}?`,
this.$t('contract.d6'),
{
confirmButtonText: this.$t('common.confirmBtn'),
cancelButtonText: this.$t('common.cancelBtn'),
type: 'warning'
}
).then(() => {
Exchange.stockCloseAllPosition({ symbol: item.pair_name }).then(() => {
this.$message.success(this.$t('contract.f6'));
this.update();
}).catch(() => {});
}).catch(() => {});
},
toggle(name) { toggle(name) {
this.currentTab = name; this.currentTab = name;
// //
@ -355,4 +499,141 @@
float: none; float: none;
} }
} }
.stock-close-dialog.el-dialog {
background: #fff !important;
border: 1px solid #ebeef5;
border-radius: 4px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
overflow: hidden;
.el-dialog__header {
background: #fff !important;
border-bottom: 1px solid #ebeef5;
padding: 16px 20px 12px;
}
.el-dialog__title {
color: #303133;
font-size: 16px;
font-weight: 500;
line-height: 24px;
}
.el-dialog__headerbtn .el-dialog__close {
color: #909399;
}
.el-dialog__body {
background: #fff !important;
padding: 20px 20px 10px;
color: #606266;
}
.el-dialog__footer {
background: #fff !important;
border-top: 1px solid #ebeef5;
padding: 12px 20px 16px;
}
.el-input__inner {
background-color: #fff !important;
border: 1px solid #dcdfe6;
color: #606266 !important;
}
.stock-close-form {
.el-form-item {
display: flex;
margin-bottom: 18px;
}
.el-form-item__label {
color: #606266;
line-height: 32px;
}
.el-form-item__content {
flex: 1;
min-width: 0;
}
}
.close-price-row {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
.el-input {
flex: 1;
}
.el-button {
flex-shrink: 0;
padding: 9px 12px !important;
background: #fff !important;
border-color: #dcdfe6;
color: #606266;
}
}
.close-available {
margin-bottom: 12px;
color: #909399;
font-size: 13px;
line-height: 1.5;
}
.el-slider {
padding: 0 6px;
}
.dialog-footer {
text-align: right;
}
}
.dark-app .stock-close-dialog.el-dialog,
#dark .stock-close-dialog.el-dialog {
background: #1c2030 !important;
border-color: #2a2e39;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
.el-dialog__header,
.el-dialog__body,
.el-dialog__footer {
background: #1c2030 !important;
border-color: #2a2e39;
color: #fff;
}
.el-dialog__title {
color: #fff;
}
.el-dialog__headerbtn .el-dialog__close {
color: #c0c4cc;
}
.stock-close-form .el-form-item__label {
color: #c0c4cc !important;
}
.el-input__inner {
background-color: #2a2e39 !important;
border-color: #2a2e39 !important;
color: #fff !important;
}
.close-price-row .el-button {
background: #2a2e39 !important;
border-color: #2a2e39 !important;
color: #fff !important;
}
.close-available {
color: #909399;
}
}
</style> </style>
Loading…
Cancel
Save