You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.1 KiB
168 lines
5.1 KiB
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
|
|
|
// 后端API基础URL
|
|
const API_BASE_URL = 'http://localhost:3005/api';
|
|
|
|
// 异步获取期货概览数据
|
|
export const fetchFuturesOverview = createAsyncThunk(
|
|
'futures/fetchOverview',
|
|
async () => {
|
|
const response = await fetch(`${API_BASE_URL}/market/overview`);
|
|
if (!response.ok) {
|
|
throw new Error('获取市场概览失败');
|
|
}
|
|
const data = await response.json();
|
|
return data.data;
|
|
}
|
|
);
|
|
|
|
// 异步获取单个期货详情
|
|
export const fetchFutureDetail = createAsyncThunk(
|
|
'futures/fetchDetail',
|
|
async ({ code, name }) => {
|
|
const response = await fetch(`${API_BASE_URL}/market/detail/${code}`);
|
|
if (!response.ok) {
|
|
throw new Error('获取品种详情失败');
|
|
}
|
|
const data = await response.json();
|
|
return data.data;
|
|
}
|
|
);
|
|
|
|
// 异步获取风险预警
|
|
export const fetchRiskAlerts = createAsyncThunk(
|
|
'futures/fetchRiskAlerts',
|
|
async () => {
|
|
const response = await fetch(`${API_BASE_URL}/market/alerts`);
|
|
if (!response.ok) {
|
|
throw new Error('获取风险预警失败');
|
|
}
|
|
const data = await response.json();
|
|
return data.data;
|
|
}
|
|
);
|
|
|
|
// 异步获取AI市场分析
|
|
export const fetchAIMarketAnalysis = createAsyncThunk(
|
|
'futures/fetchAIMarketAnalysis',
|
|
async () => {
|
|
// 由于后端没有专门的市场分析接口,我们使用模拟数据
|
|
return {
|
|
overallTrend: '震荡偏弱',
|
|
keyFactors: ['原油价格波动', '宏观经济数据', '政策面变化'],
|
|
recommendations: ['控制仓位', '关注原油走势', '做好止损'],
|
|
confidence: 75
|
|
};
|
|
}
|
|
);
|
|
|
|
const futuresSlice = createSlice({
|
|
name: 'futures',
|
|
initialState: {
|
|
overview: [],
|
|
selectedFuture: null,
|
|
riskAlerts: [],
|
|
aiAnalysis: null,
|
|
loading: false,
|
|
error: null,
|
|
watchlist: []
|
|
},
|
|
reducers: {
|
|
selectFuture: (state, action) => {
|
|
state.selectedFuture = action.payload;
|
|
},
|
|
clearSelectedFuture: (state) => {
|
|
state.selectedFuture = null;
|
|
},
|
|
toggleWatchlist: (state, action) => {
|
|
const code = action.payload;
|
|
const index = state.watchlist.indexOf(code);
|
|
if (index > -1) {
|
|
state.watchlist.splice(index, 1);
|
|
} else {
|
|
state.watchlist.push(code);
|
|
}
|
|
// 更新overview中每个合约的自选状态
|
|
state.overview = state.overview.map(item => ({
|
|
...item,
|
|
isInWatchlist: state.watchlist.includes(item.code)
|
|
}));
|
|
// 更新selectedFuture的自选状态
|
|
if (state.selectedFuture && state.selectedFuture.code === code) {
|
|
state.selectedFuture.isInWatchlist = state.watchlist.includes(code);
|
|
}
|
|
}
|
|
},
|
|
extraReducers: (builder) => {
|
|
builder
|
|
// 处理fetchFuturesOverview
|
|
.addCase(fetchFuturesOverview.pending, (state) => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(fetchFuturesOverview.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
// 更新overview数据并添加自选状态
|
|
state.overview = action.payload.map(item => ({
|
|
...item,
|
|
isInWatchlist: state.watchlist.includes(item.code)
|
|
}));
|
|
})
|
|
.addCase(fetchFuturesOverview.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.error.message;
|
|
})
|
|
|
|
// 处理fetchFutureDetail
|
|
.addCase(fetchFutureDetail.pending, (state) => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(fetchFutureDetail.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
// 更新selectedFuture数据并添加自选状态
|
|
state.selectedFuture = {
|
|
...action.payload,
|
|
isInWatchlist: state.watchlist.includes(action.payload.code)
|
|
};
|
|
console.log('fetchFutureDetail fulfilled with:', action.payload);
|
|
})
|
|
.addCase(fetchFutureDetail.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.error.message;
|
|
console.log('fetchFutureDetail rejected with error:', action.error.message);
|
|
})
|
|
|
|
// 处理fetchRiskAlerts
|
|
.addCase(fetchRiskAlerts.pending, (state) => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(fetchRiskAlerts.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
state.riskAlerts = action.payload;
|
|
})
|
|
.addCase(fetchRiskAlerts.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.error.message;
|
|
})
|
|
|
|
// 处理fetchAIMarketAnalysis
|
|
.addCase(fetchAIMarketAnalysis.pending, (state) => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(fetchAIMarketAnalysis.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
state.aiAnalysis = action.payload;
|
|
})
|
|
.addCase(fetchAIMarketAnalysis.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.error.message;
|
|
});
|
|
}
|
|
});
|
|
|
|
export const { selectFuture, clearSelectedFuture, toggleWatchlist } = futuresSlice.actions;
|
|
export default futuresSlice.reducer;
|