feat: 前端对接销售数据API
- TopData组件对接/api/sales/year-data获取年度数据 - GroupRanking组件对接/api/sales/group-ranking获取小组排名 - PersonRanking组件对接/api/sales/person-ranking获取个人排名 - 添加.env配置文件,设置API_BASE_URL 🤖 Generated with Claude Code https://claude.com/claude-code
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_BASE_URL=http://localhost:8000/api
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
function GroupRanking() {
|
function GroupRanking() {
|
||||||
@@ -7,14 +7,36 @@ function GroupRanking() {
|
|||||||
|
|
||||||
const MOBILE_BREAKPOINT = 768
|
const MOBILE_BREAKPOINT = 768
|
||||||
|
|
||||||
// 小组数据
|
// 小组数据(从 API 获取)
|
||||||
const groupData = [
|
const [groupData, setGroupData] = useState([
|
||||||
{ name: '华东一组', target: 50000000000, actual: 62000000000 },
|
{ name: '华东一组', target: 50000000000, actual: 62000000000 },
|
||||||
{ name: '华南二组', target: 45000000000, actual: 51000000000 },
|
{ name: '华南二组', target: 45000000000, actual: 51000000000 },
|
||||||
{ name: '华北三组', target: 40000000000, actual: 43500000000 },
|
{ name: '华北三组', target: 40000000000, actual: 43500000000 },
|
||||||
{ name: '西南四组', target: 35000000000, actual: 28000000000 },
|
{ name: '西南四组', target: 35000000000, actual: 28000000000 },
|
||||||
{ name: '东北五组', target: 30000000000, actual: 26500000000 }
|
{ name: '东北五组', target: 30000000000, actual: 26500000000 }
|
||||||
]
|
])
|
||||||
|
|
||||||
|
// 获取小组排名数据
|
||||||
|
const fetchGroupRanking = async () => {
|
||||||
|
try {
|
||||||
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api'
|
||||||
|
const response = await fetch(`${API_BASE_URL}/sales/group-ranking?year=2024`)
|
||||||
|
const result = await response.json()
|
||||||
|
console.log('小组排名 API 响应:', result)
|
||||||
|
|
||||||
|
// 转换单位:API 返回的是万元,需要转换为元
|
||||||
|
const rankings = result.rankings.map(item => ({
|
||||||
|
name: item.name,
|
||||||
|
target: item.target * 10000, // 万元转元
|
||||||
|
actual: item.actual * 10000
|
||||||
|
}))
|
||||||
|
|
||||||
|
setGroupData(rankings)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取小组排名失败:', error)
|
||||||
|
// 保持默认数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化数字(万元)
|
// 格式化数字(万元)
|
||||||
const formatNumber = (num) => {
|
const formatNumber = (num) => {
|
||||||
@@ -203,6 +225,12 @@ function GroupRanking() {
|
|||||||
chartInstance.current.setOption(option)
|
chartInstance.current.setOption(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始加载数据
|
||||||
|
useEffect(() => {
|
||||||
|
fetchGroupRanking()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 数据变化时重新渲染图表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
renderChart()
|
renderChart()
|
||||||
@@ -226,7 +254,7 @@ function GroupRanking() {
|
|||||||
chartInstance.current.dispose()
|
chartInstance.current.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [groupData])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="group-ranking">
|
<div className="group-ranking">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
function PersonRanking() {
|
function PersonRanking() {
|
||||||
@@ -7,8 +7,8 @@ function PersonRanking() {
|
|||||||
|
|
||||||
const MOBILE_BREAKPOINT = 768
|
const MOBILE_BREAKPOINT = 768
|
||||||
|
|
||||||
// 个人数据
|
// 个人数据(从 API 获取)
|
||||||
const personData = [
|
const [personData, setPersonData] = useState([
|
||||||
{ name: '张伟', target: 5000000000, actual: 7200000000 },
|
{ name: '张伟', target: 5000000000, actual: 7200000000 },
|
||||||
{ name: '李娜', target: 4500000000, actual: 5800000000 },
|
{ name: '李娜', target: 4500000000, actual: 5800000000 },
|
||||||
{ name: '王强', target: 4000000000, actual: 4900000000 },
|
{ name: '王强', target: 4000000000, actual: 4900000000 },
|
||||||
@@ -16,7 +16,29 @@ function PersonRanking() {
|
|||||||
{ name: '陈静', target: 3500000000, actual: 3600000000 },
|
{ name: '陈静', target: 3500000000, actual: 3600000000 },
|
||||||
{ name: '杨明', target: 3200000000, actual: 2800000000 },
|
{ name: '杨明', target: 3200000000, actual: 2800000000 },
|
||||||
{ name: '赵丽', target: 3000000000, actual: 2500000000 }
|
{ name: '赵丽', target: 3000000000, actual: 2500000000 }
|
||||||
]
|
])
|
||||||
|
|
||||||
|
// 获取个人排名数据
|
||||||
|
const fetchPersonRanking = async () => {
|
||||||
|
try {
|
||||||
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api'
|
||||||
|
const response = await fetch(`${API_BASE_URL}/sales/person-ranking?year=2024`)
|
||||||
|
const result = await response.json()
|
||||||
|
console.log('个人排名 API 响应:', result)
|
||||||
|
|
||||||
|
// 转换单位:API 返回的是万元,需要转换为元
|
||||||
|
const rankings = result.rankings.map(item => ({
|
||||||
|
name: item.name,
|
||||||
|
target: item.target * 10000, // 万元转元
|
||||||
|
actual: item.actual * 10000
|
||||||
|
}))
|
||||||
|
|
||||||
|
setPersonData(rankings)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取个人排名失败:', error)
|
||||||
|
// 保持默认数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化数字(万元)
|
// 格式化数字(万元)
|
||||||
const formatNumber = (num) => {
|
const formatNumber = (num) => {
|
||||||
@@ -202,6 +224,12 @@ function PersonRanking() {
|
|||||||
chartInstance.current.setOption(option)
|
chartInstance.current.setOption(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始加载数据
|
||||||
|
useEffect(() => {
|
||||||
|
fetchPersonRanking()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 数据变化时重新渲染图表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
renderChart()
|
renderChart()
|
||||||
@@ -225,7 +253,7 @@ function PersonRanking() {
|
|||||||
chartInstance.current.dispose()
|
chartInstance.current.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [personData])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="person-ranking">
|
<div className="person-ranking">
|
||||||
|
|||||||
@@ -28,12 +28,21 @@ function TopData({ onProgressRate }) {
|
|||||||
// 获取年度数据
|
// 获取年度数据
|
||||||
const fetchYearData = async () => {
|
const fetchYearData = async () => {
|
||||||
console.log('正在获取年度数据...')
|
console.log('正在获取年度数据...')
|
||||||
// TODO: 替换为实际的API调用
|
try {
|
||||||
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api'
|
||||||
|
const response = await fetch(`${API_BASE_URL}/sales/year-data?year=2024`)
|
||||||
|
const result = await response.json()
|
||||||
|
console.log('API 响应:', result)
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取年度数据失败:', error)
|
||||||
|
// 返回默认数据
|
||||||
return {
|
return {
|
||||||
target: 3500,
|
target: 3500,
|
||||||
actual: 2750
|
actual: 2750
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化大数字
|
// 格式化大数字
|
||||||
const formatLargeNumber = (num) => {
|
const formatLargeNumber = (num) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user