feat: 组合详情页添加编辑功能,支持修改名称/策略/状态
This commit is contained in:
parent
69cf5a614a
commit
32e8e8b5eb
@ -128,9 +128,15 @@
|
|||||||
<view class="section-container pb-0">
|
<view class="section-container pb-0">
|
||||||
<view class="section-header">
|
<view class="section-header">
|
||||||
<text class="section-title">当前逻辑模型</text>
|
<text class="section-title">当前逻辑模型</text>
|
||||||
<view class="flex-row items-center" @click="goStrategyConfig">
|
<view class="flex-row items-center gap-2">
|
||||||
<text class="section-sub text-brand">参数配置</text>
|
<view class="edit-btn" @click="openEditModal">
|
||||||
<uni-icons type="right" size="12" color="#064E3B"></uni-icons>
|
<uni-icons type="compose" size="14" color="#064E3B"></uni-icons>
|
||||||
|
<text class="edit-text">编辑</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-row items-center" @click="goStrategyConfig" v-if="portfolioData.logicModel">
|
||||||
|
<text class="section-sub text-brand">参数配置</text>
|
||||||
|
<uni-icons type="right" size="12" color="#064E3B"></uni-icons>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -163,6 +169,28 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</u-card>
|
</u-card>
|
||||||
|
|
||||||
|
<!-- 未绑定策略提示 -->
|
||||||
|
<u-card
|
||||||
|
v-else
|
||||||
|
:border="false"
|
||||||
|
:shadow="false"
|
||||||
|
:show-head="false"
|
||||||
|
:show-foot="false"
|
||||||
|
class="strategy-info-card"
|
||||||
|
>
|
||||||
|
<template #body>
|
||||||
|
<view class="st-left">
|
||||||
|
<view class="st-icon-box bg-gray-100">
|
||||||
|
<text class="st-icon-text text-gray">—</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-col gap-1">
|
||||||
|
<text class="st-name">未绑定策略</text>
|
||||||
|
<text class="st-tag">点击编辑可绑定策略</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</u-card>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="section-container">
|
<view class="section-container">
|
||||||
@ -441,6 +469,84 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 编辑组合弹窗 -->
|
||||||
|
<view v-if="showEditModal" class="transaction-modal" @click="showEditModal = false">
|
||||||
|
<view class="modal-content" @click.stop>
|
||||||
|
<view class="modal-header">
|
||||||
|
<text class="modal-title">编辑组合</text>
|
||||||
|
<view class="close-btn" @click="showEditModal = false">
|
||||||
|
<uni-icons type="close" size="20" color="#6B7280"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-content">
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-label">组合名称</text>
|
||||||
|
<input
|
||||||
|
v-model="editForm.name"
|
||||||
|
class="form-input"
|
||||||
|
placeholder="请输入组合名称"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-label">绑定策略</text>
|
||||||
|
<picker :range="strategyOptions" range-key="name" @change="onStrategyChange">
|
||||||
|
<view class="form-select">
|
||||||
|
<text>{{ editForm.strategyName || '不绑定策略' }}</text>
|
||||||
|
<uni-icons type="bottom" size="14" color="#9CA3AF"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-label">状态</text>
|
||||||
|
<picker :range="statusOptions" range-key="label" @change="onStatusChange">
|
||||||
|
<view class="form-select">
|
||||||
|
<text>{{ statusOptions.find(s => s.value === editForm.status)?.label || '运行中' }}</text>
|
||||||
|
<uni-icons type="bottom" size="14" color="#9CA3AF"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="modal-footer">
|
||||||
|
<u-button
|
||||||
|
class="btn-cancel"
|
||||||
|
@click="showEditModal = false"
|
||||||
|
:customStyle="{
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
color: '#6B7280',
|
||||||
|
fontWeight: '600',
|
||||||
|
borderRadius: '16rpx',
|
||||||
|
height: '80rpx',
|
||||||
|
fontSize: '28rpx',
|
||||||
|
flex: '1',
|
||||||
|
border: '2rpx solid #E5E7EB'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</u-button>
|
||||||
|
<u-button
|
||||||
|
class="btn-confirm"
|
||||||
|
@click="submitEdit"
|
||||||
|
:customStyle="{
|
||||||
|
backgroundColor: '#064E3B',
|
||||||
|
color: '#FFFFFF',
|
||||||
|
fontWeight: '600',
|
||||||
|
borderRadius: '16rpx',
|
||||||
|
height: '80rpx',
|
||||||
|
fontSize: '28rpx',
|
||||||
|
flex: '1',
|
||||||
|
border: 'none'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -638,6 +744,98 @@ const transactionForm = ref({
|
|||||||
|
|
||||||
const maxSellAmount = ref(0);
|
const maxSellAmount = ref(0);
|
||||||
|
|
||||||
|
// 编辑弹窗相关
|
||||||
|
const showEditModal = ref(false);
|
||||||
|
const editForm = ref({
|
||||||
|
name: '',
|
||||||
|
strategyId: null,
|
||||||
|
strategyName: '',
|
||||||
|
status: '运行中'
|
||||||
|
});
|
||||||
|
const strategyOptions = ref([{ id: null, name: '不绑定策略' }]);
|
||||||
|
const statusOptions = ref([
|
||||||
|
{ label: '运行中', value: '运行中' },
|
||||||
|
{ label: '已暂停', value: '已暂停' },
|
||||||
|
{ label: '已清仓', value: '已清仓' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 打开编辑弹窗
|
||||||
|
const openEditModal = async () => {
|
||||||
|
editForm.value = {
|
||||||
|
name: portfolioData.value.name || '',
|
||||||
|
strategyId: portfolioData.value.strategy?.id || null,
|
||||||
|
strategyName: portfolioData.value.strategy?.name || '不绑定策略',
|
||||||
|
status: portfolioData.value.status || '运行中'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取策略列表
|
||||||
|
try {
|
||||||
|
const res = await api.strategies.getStrategies();
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
strategyOptions.value = [
|
||||||
|
{ id: null, name: '不绑定策略' },
|
||||||
|
...res.data.map(s => ({ id: s.id, name: s.name }))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取策略列表失败:', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
showEditModal.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStrategyChange = (e) => {
|
||||||
|
const idx = e.detail.value;
|
||||||
|
const selected = strategyOptions.value[idx];
|
||||||
|
editForm.value.strategyId = selected.id;
|
||||||
|
editForm.value.strategyName = selected.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStatusChange = (e) => {
|
||||||
|
const idx = e.detail.value;
|
||||||
|
editForm.value.status = statusOptions.value[idx].value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitEdit = async () => {
|
||||||
|
if (!editForm.value.name?.trim()) {
|
||||||
|
proxy?.$refs.uToastRef?.show({
|
||||||
|
type: 'warning',
|
||||||
|
message: '请输入组合名称',
|
||||||
|
icon: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.showLoading({ title: '保存中...', mask: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.assets.updatePortfolio(portfolioId.value, {
|
||||||
|
name: editForm.value.name,
|
||||||
|
strategyId: editForm.value.strategyId,
|
||||||
|
status: editForm.value.status
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
uni.hideLoading();
|
||||||
|
proxy?.$refs.uToastRef?.show({
|
||||||
|
type: 'success',
|
||||||
|
message: '保存成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
showEditModal.value = false;
|
||||||
|
await fetchPortfolioData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('更新组合失败:', error);
|
||||||
|
uni.hideLoading();
|
||||||
|
proxy?.$refs.uToastRef?.show({
|
||||||
|
type: 'error',
|
||||||
|
message: '保存失败,请重试',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 股票搜索相关
|
// 股票搜索相关
|
||||||
const searchResults = ref([]);
|
const searchResults = ref([]);
|
||||||
const searchTimer = ref(null);
|
const searchTimer = ref(null);
|
||||||
@ -1054,6 +1252,24 @@ const deletePortfolio = async () => {
|
|||||||
.bg-green-100 { background-color: #ECFDF5; }
|
.bg-green-100 { background-color: #ECFDF5; }
|
||||||
.bg-red { background-color: #EF4444; }
|
.bg-red { background-color: #EF4444; }
|
||||||
.bg-green { background-color: #10B981; }
|
.bg-green { background-color: #10B981; }
|
||||||
|
.bg-gray-100 { background-color: #F3F4F6; }
|
||||||
|
.text-gray { color: #9CA3AF; }
|
||||||
|
|
||||||
|
/* 编辑按钮 */
|
||||||
|
.edit-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4rpx;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
background-color: #D1FAE5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #064E3B;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.header-section { padding: 20rpx 32rpx; }
|
.header-section { padding: 20rpx 32rpx; }
|
||||||
.asset-card {
|
.asset-card {
|
||||||
|
|||||||
10
utils/api.js
10
utils/api.js
@ -353,6 +353,16 @@ export const api = {
|
|||||||
console.log('📤 发起 createPortfolio 请求:', data);
|
console.log('📤 发起 createPortfolio 请求:', data);
|
||||||
return post('/api/v1/portfolio', data);
|
return post('/api/v1/portfolio', data);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 更新投资组合
|
||||||
|
* @param {string|number} id - 投资组合ID
|
||||||
|
* @param {object} data - 更新数据 {name, strategyId, status}
|
||||||
|
* @returns {Promise} 返回更新结果
|
||||||
|
*/
|
||||||
|
updatePortfolio: (id, data) => {
|
||||||
|
console.log('📤 发起 updatePortfolio 请求:', id, data);
|
||||||
|
return put(`/api/v1/portfolio/${id}`, data);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 获取投资组合策略信号
|
* 获取投资组合策略信号
|
||||||
* @param {string|number} id - 投资组合ID
|
* @param {string|number} id - 投资组合ID
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user