Compare commits
No commits in common. "4ea7c5c2d08103a12beb8fe66092249b8cd420a6" and "bb09255dbd63da86a390d390237cea56e0723647" have entirely different histories.
4ea7c5c2d0
...
bb09255dbd
@ -32,13 +32,17 @@
|
||||
</view>
|
||||
|
||||
<view class="section-card">
|
||||
<view class="card-header">
|
||||
<view class="card-header justify-between">
|
||||
<view class="flex-row items-center gap-2">
|
||||
<view class="header-icon bg-blue-100">
|
||||
<uni-icons type="wallet" size="18" color="#1D4ED8"></uni-icons>
|
||||
</view>
|
||||
<text class="header-title">初始化记录</text>
|
||||
</view>
|
||||
<view class="add-btn" @click="addStockRow">
|
||||
<uni-icons type="plus" size="14" color="#064E3B"></uni-icons>
|
||||
<text class="add-text">添加单元</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="stock-list">
|
||||
@ -46,12 +50,14 @@
|
||||
|
||||
<view class="item-header">
|
||||
<text class="item-index">单元 #{{ index + 1 }}</text>
|
||||
<uni-icons type="trash" size="18" color="#EF4444" @click="removeStockRow(index)"
|
||||
v-if="form.stocks.length > 1"></uni-icons>
|
||||
</view>
|
||||
|
||||
<view class="item-grid">
|
||||
<view class="grid-col">
|
||||
<text class="sub-label">单元名称/代码</text>
|
||||
<input class="mini-input" v-model="item.name" placeholder="如 TMF" disabled />
|
||||
<input class="mini-input" v-model="item.name" placeholder="如 TMF" />
|
||||
</view>
|
||||
<view class="grid-col">
|
||||
<text class="sub-label">买入均价</text>
|
||||
@ -89,8 +95,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, getCurrentInstance } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref, computed, onMounted, getCurrentInstance } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const api = proxy.$api;
|
||||
@ -98,9 +103,6 @@ const api = proxy.$api;
|
||||
const strategies = ref([]);
|
||||
const strategyIndex = ref(-1);
|
||||
|
||||
// 防止重复请求的标志
|
||||
let isFetching = false;
|
||||
|
||||
const form = ref({
|
||||
name: '',
|
||||
stocks: [
|
||||
@ -131,8 +133,6 @@ const fetchStrategies = async () => {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
desc: item.description,
|
||||
type: item.type,
|
||||
parameters: item.config ? JSON.parse(item.config) : {},
|
||||
color: '#10B981'
|
||||
}));
|
||||
}
|
||||
@ -141,31 +141,26 @@ const fetchStrategies = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchStrategies();
|
||||
});
|
||||
|
||||
const onStrategyChange = (e) => {
|
||||
strategyIndex.value = e.detail.value;
|
||||
const strategy = strategies.value[strategyIndex.value];
|
||||
|
||||
console.log('选择的策略:', strategy);
|
||||
console.log('策略参数:', strategy?.parameters);
|
||||
|
||||
if (strategy && strategy.parameters && strategy.parameters.assets) {
|
||||
form.value.stocks = strategy.parameters.assets.map(asset => ({
|
||||
name: asset.symbol,
|
||||
price: '',
|
||||
amount: '',
|
||||
date: ''
|
||||
}));
|
||||
console.log('自动填充标的:', form.value.stocks);
|
||||
} else {
|
||||
form.value.stocks = [{ name: '', price: '', amount: '', date: '' }];
|
||||
console.log('未找到标的配置,使用默认值');
|
||||
}
|
||||
};
|
||||
|
||||
const onDateChange = (e, index) => {
|
||||
form.value.stocks[index].date = e.detail.value;
|
||||
};
|
||||
|
||||
const addStockRow = () => {
|
||||
form.value.stocks.push({ name: '', price: '', amount: '', date: '' });
|
||||
};
|
||||
|
||||
const removeStockRow = (index) => {
|
||||
form.value.stocks.splice(index, 1);
|
||||
};
|
||||
|
||||
const submitForm = async () => {
|
||||
if (!form.value.name) return uni.showToast({ title: '请输入组合名称', icon: 'none' });
|
||||
if (strategyIndex.value === -1) return uni.showToast({ title: '请选择策略', icon: 'none' });
|
||||
@ -201,12 +196,6 @@ const submitForm = async () => {
|
||||
uni.showToast({ title: '创建失败,请重试', icon: 'none' });
|
||||
}
|
||||
};
|
||||
|
||||
onShow(async () => {
|
||||
isFetching = true;
|
||||
await fetchStrategies();
|
||||
isFetching = false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -292,6 +281,22 @@ onShow(async () => {
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
/* 添加按钮 */
|
||||
.add-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #ECFDF5;
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 100rpx;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.add-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #064E3B;
|
||||
}
|
||||
|
||||
/* 表单项 */
|
||||
.form-item {
|
||||
margin-bottom: 32rpx;
|
||||
@ -414,12 +419,6 @@ onShow(async () => {
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.mini-input[disabled] {
|
||||
background-color: #F3F4F6;
|
||||
color: #6B7280;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 日期选择 */
|
||||
.date-picker-display {
|
||||
background-color: #FFFFFF;
|
||||
|
||||
@ -116,18 +116,18 @@
|
||||
<view class="timeline-box">
|
||||
<view class="timeline-item" v-for="(log, k) in logs" :key="k">
|
||||
<view class="tl-left">
|
||||
<text class="tl-date">{{ log.date }}</text>
|
||||
<text class="tl-time">{{ log.time }}</text>
|
||||
<text class="tl-date">{{ log.Date }}</text>
|
||||
<text class="tl-time">{{ log.Time }}</text>
|
||||
</view>
|
||||
|
||||
<view class="tl-line">
|
||||
<view class="tl-dot" :class="log.type === 'buy' ? 'bg-red' : 'bg-green'"></view>
|
||||
<view class="tl-dot" :class="log.Type === 'buy' ? 'bg-red' : 'bg-green'"></view>
|
||||
<view class="tl-dash" v-if="k !== logs.length - 1"></view>
|
||||
</view>
|
||||
|
||||
<view class="tl-right">
|
||||
<text class="tl-title">{{ log.title }}</text>
|
||||
<text class="tl-desc">{{ log.type === 'buy' ? '增加' : '减少' }} {{ log.amount }}</text>
|
||||
<text class="tl-title">{{ log.Title }}</text>
|
||||
<text class="tl-desc">{{ log.Type === 'buy' ? '录入增加' : '结出减少' }} {{ log.Amount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -136,11 +136,11 @@
|
||||
<view class="action-section fixed-bottom">
|
||||
<button class="action-btn btn-buy" @click="handleBuy">
|
||||
<uni-icons type="download" size="20" color="#FFFFFF"></uni-icons>
|
||||
<text class="btn-text">增加</text>
|
||||
<text class="btn-text">录入增加 / 比例校准</text>
|
||||
</button>
|
||||
<button class="action-btn btn-sell" @click="handleSell">
|
||||
<uni-icons type="upload" size="20" color="#064E3B"></uni-icons>
|
||||
<text class="btn-text">减少</text>
|
||||
<text class="btn-text">结出减少 / 调减</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
@ -148,7 +148,7 @@
|
||||
<view v-if="showTransactionForm" class="transaction-modal">
|
||||
<view class="modal-content">
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">{{ transactionType === 'buy' ? '增加' : '减少' }}</text>
|
||||
<text class="modal-title">{{ transactionType === 'buy' ? '录入增加' : '结出减少' }}</text>
|
||||
<view class="close-btn" @click="showTransactionForm = false">
|
||||
<uni-icons type="close" size="20" color="#6B7280"></uni-icons>
|
||||
</view>
|
||||
@ -302,8 +302,8 @@ onMounted(async () => {
|
||||
});
|
||||
|
||||
const goStrategyConfig = () => {
|
||||
if (portfolioData.value.strategy?.id) {
|
||||
uni.navigateTo({ url: `/pages/strategies/edit/edit?id=${portfolioData.value.strategy.id}` });
|
||||
if (portfolioData.value.strategy?.Id) {
|
||||
uni.navigateTo({ url: `/pages/strategies/edit/edit?id=${portfolioData.value.strategy.Id}` });
|
||||
}
|
||||
};
|
||||
|
||||
@ -538,16 +538,6 @@ const submitTransaction = async () => {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
flex-direction: row;
|
||||
padding: 0 16rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.btn-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.btn-buy { background-color: #064E3B; color: #FFFFFF; box-shadow: 0 8rpx 20rpx rgba(6, 78, 59, 0.2); }
|
||||
.btn-buy:active { background-color: #047857; }
|
||||
|
||||
@ -91,8 +91,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { api } from '../../utils/api';
|
||||
|
||||
// 资产数据
|
||||
@ -105,9 +104,6 @@ const assetData = ref({
|
||||
// 持仓组合数据
|
||||
const holdings = ref([]);
|
||||
|
||||
// 防止重复请求的标志
|
||||
let isFetching = false;
|
||||
|
||||
// 从后端API获取资产数据的函数
|
||||
const fetchAssetData = async () => {
|
||||
try {
|
||||
@ -117,11 +113,11 @@ const fetchAssetData = async () => {
|
||||
// 映射资产数据字段
|
||||
const data = response.data;
|
||||
assetData.value = {
|
||||
totalValue: data.totalValue,
|
||||
currency: data.currency,
|
||||
todayProfit: data.todayProfit,
|
||||
todayProfitCurrency: data.todayProfitCurrency,
|
||||
totalReturnRate: data.totalReturnRate
|
||||
totalValue: data.TotalValue,
|
||||
currency: data.Currency,
|
||||
todayProfit: data.TodayProfit,
|
||||
todayProfitCurrency: data.TodayProfitCurrency,
|
||||
totalReturnRate: data.TotalReturnRate
|
||||
};
|
||||
console.log('资产数据获取成功');
|
||||
}
|
||||
@ -139,18 +135,18 @@ const fetchHoldingsData = async () => {
|
||||
// 处理响应数据结构,获取 items 数组并映射字段
|
||||
const items = response.data.items || [];
|
||||
holdings.value = items.map(item => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
tags: item.tags,
|
||||
status: item.status,
|
||||
statusType: item.statusType,
|
||||
iconChar: item.iconChar,
|
||||
iconBgClass: item.iconBgClass,
|
||||
iconTextClass: item.iconTextClass,
|
||||
value: item.value,
|
||||
currency: item.currency,
|
||||
returnRate: item.returnRate,
|
||||
returnType: item.returnType
|
||||
id: item.Id,
|
||||
name: item.Name,
|
||||
tags: item.Tags,
|
||||
status: item.Status,
|
||||
statusType: item.StatusType,
|
||||
iconChar: item.IconChar,
|
||||
iconBgClass: item.IconBgClass,
|
||||
iconTextClass: item.IconTextClass,
|
||||
value: item.Value,
|
||||
currency: item.Currency,
|
||||
returnRate: item.ReturnRate,
|
||||
returnType: item.ReturnType
|
||||
}));
|
||||
console.log('持仓数据获取成功,items数量:', holdings.value.length);
|
||||
console.log('持仓数据:', holdings.value);
|
||||
@ -160,6 +156,16 @@ const fetchHoldingsData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时检查登录状态
|
||||
onMounted(async () => {
|
||||
console.log('首页加载,开始加载数据...');
|
||||
|
||||
await Promise.all([
|
||||
fetchAssetData(),
|
||||
fetchHoldingsData()
|
||||
]);
|
||||
});
|
||||
|
||||
const goConfig = () => {
|
||||
uni.navigateTo({ url: '/pages/config/config' });
|
||||
};
|
||||
@ -167,18 +173,6 @@ const goConfig = () => {
|
||||
const goDetail = (holdingId) => {
|
||||
uni.navigateTo({ url: `/pages/detail/detail?id=${holdingId}` });
|
||||
};
|
||||
|
||||
onShow(async () => {
|
||||
console.log('首页显示,刷新数据...');
|
||||
isFetching = true;
|
||||
|
||||
await Promise.all([
|
||||
fetchAssetData(),
|
||||
fetchHoldingsData()
|
||||
]);
|
||||
|
||||
isFetching = false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
|
||||
<view class="nav-bar">
|
||||
<view class="back-btn" @click="uni.navigateBack()">
|
||||
<uni-icons type="left" size="20" color="#374151"></uni-icons>
|
||||
</view>
|
||||
<text class="nav-title">{{ isEditMode ? '编辑策略' : '创建策略' }}</text>
|
||||
</view>
|
||||
|
||||
<view class="section-title">选择逻辑模型</view>
|
||||
<scroll-view scroll-x class="strategy-scroll" :show-scrollbar="false">
|
||||
<view class="strategy-row">
|
||||
@ -344,7 +352,7 @@ const submit = async () => {
|
||||
description: formData.value.description || currentStrategyInfo.value.description,
|
||||
riskLevel: formData.value.riskLevel,
|
||||
tags: tags,
|
||||
parameters: parameters
|
||||
config: JSON.stringify(parameters)
|
||||
};
|
||||
|
||||
console.log('保存策略:', strategyData);
|
||||
@ -390,14 +398,8 @@ const loadStrategyDetail = async (id) => {
|
||||
formData.value.tags = data.tags ? data.tags.join(', ') : '';
|
||||
|
||||
// 根据策略类型填充参数
|
||||
let params = {};
|
||||
if (data.parameters) {
|
||||
params = data.parameters;
|
||||
} else if (data.config) {
|
||||
// 兼容旧格式
|
||||
params = JSON.parse(data.config);
|
||||
}
|
||||
switch (data.type) {
|
||||
const params = data.config ? JSON.parse(data.config) : {};
|
||||
switch (data.Type) {
|
||||
case 'ma_trend':
|
||||
formData.value.maType = params.maType || 'SMA';
|
||||
formData.value.shortPeriod = params.shortPeriod?.toString() || '';
|
||||
|
||||
@ -61,17 +61,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref, onMounted, getCurrentInstance } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const api = proxy.$api;
|
||||
|
||||
const strategies = ref([]);
|
||||
|
||||
// 防止重复请求的标志
|
||||
let isFetching = false;
|
||||
|
||||
const fetchStrategies = async () => {
|
||||
try {
|
||||
const response = await api.strategies.getStrategies();
|
||||
@ -95,10 +91,8 @@ const fetchStrategies = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
onShow(async () => {
|
||||
isFetching = true;
|
||||
onMounted(async () => {
|
||||
await fetchStrategies();
|
||||
isFetching = false;
|
||||
});
|
||||
|
||||
const goToAdd = () => {
|
||||
|
||||
@ -391,7 +391,7 @@ export const api = {
|
||||
*/
|
||||
getUserInfo: () => {
|
||||
console.log('📤 发起 getUserInfo 请求');
|
||||
return get('api/v1/user/info');
|
||||
return get('/api/user/info');
|
||||
},
|
||||
/**
|
||||
* 获取用户统计数据
|
||||
@ -399,7 +399,7 @@ export const api = {
|
||||
*/
|
||||
getUserStats: () => {
|
||||
console.log('📤 发起 getUserStats 请求');
|
||||
return get('api/v1/user/stats');
|
||||
return get('/api/user/stats');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user