/** * 预测市场服务 - API 版本 * 调用真实的后端 API,数据存储到 MySQL 数据库 */ import axios from 'axios'; import { getApiBase } from '@utils/apiConfig'; const api = axios.create({ baseURL: getApiBase(), timeout: 10000, withCredentials: true, // 携带 Cookie(session) }); // ==================== 积分系统 API ==================== /** * 获取用户积分账户 */ export const getUserAccount = async () => { try { const response = await api.get('/api/prediction/credit/account'); return response.data; } catch (error) { console.error('获取积分账户失败:', error); throw error; } }; /** * 领取每日奖励(100积分) */ export const claimDailyBonus = async () => { try { const response = await api.post('/api/prediction/credit/daily-bonus'); return response.data; } catch (error) { console.error('领取每日奖励失败:', error); throw error; } }; // ==================== 预测话题 API ==================== /** * 创建预测话题 * @param {Object} topicData - { title, description, category, deadline } */ export const createTopic = async (topicData) => { try { const response = await api.post('/api/prediction/topics', topicData); return response.data; } catch (error) { console.error('创建预测话题失败:', error); throw error; } }; /** * 获取预测话题列表 * @param {Object} params - { status, category, sort_by, page, per_page } */ export const getTopics = async (params = {}) => { try { const response = await api.get('/api/prediction/topics', { params }); return response.data; } catch (error) { console.error('获取话题列表失败:', error); throw error; } }; /** * 获取预测话题详情 * @param {number} topicId */ export const getTopicDetail = async (topicId) => { try { const response = await api.get(`/api/prediction/topics/${topicId}`); return response.data; } catch (error) { console.error('获取话题详情失败:', error); throw error; } }; /** * 结算预测话题(仅创建者可操作) * @param {number} topicId * @param {string} result - 'yes' | 'no' | 'draw' */ export const settleTopic = async (topicId, result) => { try { const response = await api.post(`/api/prediction/topics/${topicId}/settle`, { result }); return response.data; } catch (error) { console.error('结算话题失败:', error); throw error; } }; // ==================== 交易 API ==================== /** * 买入预测份额 * @param {Object} tradeData - { topic_id, direction, shares } */ export const buyShares = async (tradeData) => { try { const response = await api.post('/api/prediction/trade/buy', tradeData); return response.data; } catch (error) { console.error('买入份额失败:', error); throw error; } }; /** * 获取用户持仓列表 */ export const getUserPositions = async () => { try { const response = await api.get('/api/prediction/positions'); return response.data; } catch (error) { console.error('获取持仓列表失败:', error); throw error; } }; // ==================== 评论 API ==================== /** * 发表话题评论 * @param {number} topicId * @param {Object} commentData - { content, parent_id } */ export const createComment = async (topicId, commentData) => { try { const response = await api.post(`/api/prediction/topics/${topicId}/comments`, commentData); return response.data; } catch (error) { console.error('发表评论失败:', error); throw error; } }; /** * 获取话题评论列表 * @param {number} topicId * @param {Object} params - { page, per_page } */ export const getComments = async (topicId, params = {}) => { try { const response = await api.get(`/api/prediction/topics/${topicId}/comments`, { params }); return response.data; } catch (error) { console.error('获取评论列表失败:', error); throw error; } }; /** * 点赞/取消点赞评论 * @param {number} commentId */ export const likeComment = async (commentId) => { try { const response = await api.post(`/api/prediction/comments/${commentId}/like`); return response.data; } catch (error) { console.error('点赞评论失败:', error); throw error; } }; // ==================== 观点IPO API ==================== /** * 投资评论(观点IPO) * @param {number} commentId - 评论ID * @param {number} shares - 投资份额 */ export const investComment = async (commentId, shares) => { try { const response = await api.post(`/api/prediction/comments/${commentId}/invest`, { shares }); return response.data; } catch (error) { console.error('投资评论失败:', error); throw error; } }; /** * 获取评论的投资列表 * @param {number} commentId - 评论ID */ export const getCommentInvestments = async (commentId) => { try { const response = await api.get(`/api/prediction/comments/${commentId}/investments`); return response.data; } catch (error) { console.error('获取投资列表失败:', error); throw error; } }; /** * 验证评论结果(仅创建者可操作) * @param {number} commentId - 评论ID * @param {string} result - 'correct' | 'incorrect' */ export const verifyComment = async (commentId, result) => { try { const response = await api.post(`/api/prediction/comments/${commentId}/verify`, { result }); return response.data; } catch (error) { console.error('验证评论失败:', error); throw error; } }; // ==================== 工具函数(价格计算保留在前端,用于实时预览)==================== export const MARKET_CONFIG = { MAX_SEATS_PER_SIDE: 5, TAX_RATE: 0.02, MIN_PRICE: 50, MAX_PRICE: 950, BASE_PRICE: 500, }; /** * 计算当前价格(简化版AMM) * @param {number} yesShares - Yes方总份额 * @param {number} noShares - No方总份额 * @returns {Object} {yes: price, no: price} */ export const calculatePrice = (yesShares, noShares) => { const totalShares = yesShares + noShares; if (totalShares === 0) { return { yes: MARKET_CONFIG.BASE_PRICE, no: MARKET_CONFIG.BASE_PRICE, }; } const yesProb = yesShares / totalShares; const noProb = noShares / totalShares; let yesPrice = yesProb * 1000; let noPrice = noProb * 1000; yesPrice = Math.max(MARKET_CONFIG.MIN_PRICE, Math.min(MARKET_CONFIG.MAX_PRICE, yesPrice)); noPrice = Math.max(MARKET_CONFIG.MIN_PRICE, Math.min(MARKET_CONFIG.MAX_PRICE, noPrice)); return { yes: Math.round(yesPrice), no: Math.round(noPrice) }; }; /** * 计算交易税 * @param {number} amount - 交易金额 * @returns {number} 税费 */ export const calculateTax = (amount) => { return Math.floor(amount * MARKET_CONFIG.TAX_RATE); }; /** * 计算买入成本(用于前端预览) * @param {number} currentShares - 当前方总份额 * @param {number} otherShares - 对手方总份额 * @param {number} buyAmount - 买入数量 * @returns {Object} { amount, tax, total } */ export const calculateBuyCost = (currentShares, otherShares, buyAmount) => { const currentPrice = calculatePrice(currentShares, otherShares); const afterShares = currentShares + buyAmount; const afterPrice = calculatePrice(afterShares, otherShares); const avgPrice = (currentPrice.yes + afterPrice.yes) / 2; const amount = avgPrice * buyAmount; const tax = calculateTax(amount); const total = amount + tax; return { amount: Math.round(amount), tax: Math.round(tax), total: Math.round(total), avgPrice: Math.round(avgPrice), }; }; export default { // 积分系统 getUserAccount, claimDailyBonus, // 话题管理 createTopic, getTopics, getTopicDetail, settleTopic, // 交易 buyShares, getUserPositions, // 评论 createComment, getComments, likeComment, // 观点IPO investComment, getCommentInvestments, verifyComment, // 工具函数 calculatePrice, calculateTax, calculateBuyCost, MARKET_CONFIG, };