diff --git a/src/assets/business_basic/recent_bg.png b/src/assets/business_basic/recent_bg.png
new file mode 100644
index 0000000..73c491a
Binary files /dev/null and b/src/assets/business_basic/recent_bg.png differ
diff --git a/src/assets/business_basic/top_icon1.svg b/src/assets/business_basic/top_icon1.svg
new file mode 100644
index 0000000..ecbf192
--- /dev/null
+++ b/src/assets/business_basic/top_icon1.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/assets/business_basic/top_icon2.svg b/src/assets/business_basic/top_icon2.svg
new file mode 100644
index 0000000..cd00919
--- /dev/null
+++ b/src/assets/business_basic/top_icon2.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/assets/business_basic/top_icon3.svg b/src/assets/business_basic/top_icon3.svg
new file mode 100644
index 0000000..d3c9243
--- /dev/null
+++ b/src/assets/business_basic/top_icon3.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/assets/business_basic/top_icon4.svg b/src/assets/business_basic/top_icon4.svg
new file mode 100644
index 0000000..1a34110
--- /dev/null
+++ b/src/assets/business_basic/top_icon4.svg
@@ -0,0 +1,13 @@
+
diff --git a/src/pages/business_basic/components/CustomerInfoManagement.js b/src/pages/business_basic/components/CustomerInfoManagement.js
index 4dcec02..0e66b33 100644
--- a/src/pages/business_basic/components/CustomerInfoManagement.js
+++ b/src/pages/business_basic/components/CustomerInfoManagement.js
@@ -1,16 +1,25 @@
-import React, { useState, useEffect, useRef } from 'react';
+import React, { useState, useEffect, useRef, useMemo, useLayoutEffect } from 'react';
import * as echarts from 'echarts';
import styles from './CustomerInfoManagement.less';
+import { Select, Space, Button, Input } from 'antd';
+import { PlusOutlined, SearchOutlined, ReloadOutlined } from '@ant-design/icons';
+import StandardTable from '@/components/StandardTable';
+import topIcon from '@/assets/business_basic/top_icon1.svg';
+import topIcon2 from '@/assets/business_basic/top_icon2.svg';
+import topIcon3 from '@/assets/business_basic/top_icon3.svg';
+import topIcon4 from '@/assets/business_basic/top_icon4.svg';
import CustomerInfoManagementDetail from './CustomerInfoManagementDetail';
-
const CustomerInfoManagement = () => {
const [searchKeyword, setSearchKeyword] = useState('');
- const [customerType, setCustomerType] = useState('全部');
- const [customerLevel, setCustomerLevel] = useState('全部');
- const [cooperationStatus, setCooperationStatus] = useState('全部');
const [selectedRows, setSelectedRows] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
+ // 列表筛选与数据(演示数据,可替换为接口)
+ const [filters, setFilters] = useState({
+ customerType: '',
+ customerGrade: '',
+ cooperationStatus: '',
+ });
// 新增:详情页面切换状态
const [showDetail, setShowDetail] = useState(false);
const [detailData, setDetailData] = useState(null);
@@ -32,21 +41,27 @@ const CustomerInfoManagement = () => {
// 客户类型分布图表配置
const customerTypeChartOption = {
- title: {
- text: '客户类型分布',
- left: 'left',
- textStyle: {
- fontSize: 16,
- fontWeight: 600,
- },
- },
+ // title: {
+ // text: '客户类型分布',
+ // left: 'left',
+ // textStyle: {
+ // fontSize: 16,
+ // fontWeight: 600,
+ // color: '#333',
+ // },
+ // },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
+ backgroundColor: 'rgba(255,255,255,0.95)',
+ borderColor: '#e0e0e0',
+ borderWidth: 1,
+ textStyle: { color: '#333' },
},
grid: {
+ top: 16,
left: '3%',
right: '4%',
bottom: '3%',
@@ -57,23 +72,44 @@ const CustomerInfoManagement = () => {
data: ['客户', '供应商', '第3周', '第4周'],
axisLabel: {
rotate: 0,
+ color: '#4E5856',
},
+ axisLine: {
+ lineStyle: { color: '#C9E3DE' },
+ },
+ axisTick: { show: false },
},
yAxis: {
type: 'value',
max: 100,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: { color: '#4E5856' },
+ splitLine: {
+ show: true,
+ lineStyle: { color: '#E9F3F1', type: 'dashed' },
+ },
},
series: [
{
name: '数量',
type: 'bar',
data: [56, 32, 85, 15],
+ barWidth: 26,
itemStyle: {
- color: '#1890ff',
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: '#7FC8B6' },
+ { offset: 1, color: '#008F8E' },
+ ]),
+ // barBorderRadius: [6, 6, 0, 0],
+ shadowColor: 'rgba(0,0,0,0.08)',
+ shadowBlur: 6,
+ shadowOffsetY: 2,
},
label: {
show: true,
position: 'top',
+ color: '#4E5856',
},
},
],
@@ -81,81 +117,113 @@ const CustomerInfoManagement = () => {
// 客户价值分布环形图配置
const customerValueChartOption = {
- title: {
- text: '客户价值分布',
- left: 'left',
- textStyle: {
- fontSize: 16,
- fontWeight: 600,
- },
- },
+ // title: {
+ // text: '客户价值分布',
+ // left: 'left',
+ // textStyle: {
+ // fontSize: 16,
+ // fontWeight: 600,
+ // },
+ // },
tooltip: {
trigger: 'item',
formatter: '{a}
{b}: {c} ({d}%)',
},
legend: {
orient: 'vertical',
- left: 'right',
- top: 'middle',
+ right: '6%',
+ top: '32%',
+ itemWidth: 16,
+ itemHeight: 4,
+ itemGap: 16,
+ textStyle: {
+ fontSize: 12,
+ color: '#666',
+ fontWeight: 'normal'
+ }
},
series: [
{
name: '客户价值',
type: 'pie',
- radius: ['40%', '70%'],
- avoidLabelOverlap: false,
+ radius: ['40%', '65%'],
+ center: ['30%', '50%'],
+ // avoidLabelOverlap: false,
itemStyle: {
- borderRadius: 10,
- borderColor: '#fff',
- borderWidth: 2,
+ // borderRadius: 10,
+ // borderColor: '#fff',
+ // borderWidth: 2,
},
label: {
show: false,
},
- emphasis: {
- label: {
- show: true,
- fontSize: 16,
- fontWeight: 'bold',
- },
- },
+ // emphasis: {
+ // label: {
+ // show: true,
+ // fontSize: 16,
+ // fontWeight: 'bold',
+ // },
+ // },
data: [
- { value: 180, name: '高价值客户', itemStyle: { color: '#5B9BD5' } },
- { value: 120, name: '中等客户', itemStyle: { color: '#FFC000' } },
- { value: 89, name: '小客户', itemStyle: { color: '#9E7CC1' } },
+ { value: 180, name: '高价值客户', itemStyle: { color: '#5CB3FF' } },
+ { value: 120, name: '中等客户', itemStyle: { color: '#FFDE73' } },
+ { value: 89, name: '小客户', itemStyle: { color: '#A990EA' } },
],
},
],
};
- // 初始化图表
+ // 图表初始化与销毁:根据详情模式切换,返回列表后重新初始化
useEffect(() => {
- // 初始化客户类型分布图表
- if (customerTypeChartRef.current) {
- customerTypeChartInstance.current = echarts.init(customerTypeChartRef.current);
- customerTypeChartInstance.current.setOption(customerTypeChartOption);
- }
-
- // 初始化客户价值分布图表
- if (customerValueChartRef.current) {
- customerValueChartInstance.current = echarts.init(customerValueChartRef.current);
- customerValueChartInstance.current.setOption(customerValueChartOption);
- }
+ if (!showDetail) {
+ if (customerTypeChartRef.current) {
+ customerTypeChartInstance.current = echarts.init(customerTypeChartRef.current);
+ customerTypeChartInstance.current.setOption(customerTypeChartOption);
+ // 额外一次 resize,确保初始化后尺寸正确
+ requestAnimationFrame(() => {
+ customerTypeChartInstance.current?.resize();
+ });
+ }
+ if (customerValueChartRef.current) {
+ customerValueChartInstance.current = echarts.init(customerValueChartRef.current);
+ customerValueChartInstance.current.setOption(customerValueChartOption);
+ // 额外一次 resize,确保初始化后尺寸正确
+ requestAnimationFrame(() => {
+ customerValueChartInstance.current?.resize();
+ });
+ }
- // 响应式调整
- const handleResize = () => {
- customerTypeChartInstance.current?.resize();
- customerValueChartInstance.current?.resize();
- };
- window.addEventListener('resize', handleResize);
+ const handleResize = () => {
+ customerTypeChartInstance.current?.resize();
+ customerValueChartInstance.current?.resize();
+ };
+ window.addEventListener('resize', handleResize);
- // 清理函数
- return () => {
- window.removeEventListener('resize', handleResize);
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ customerTypeChartInstance.current?.dispose();
+ customerTypeChartInstance.current = null;
+ customerValueChartInstance.current?.dispose();
+ customerValueChartInstance.current = null;
+ };
+ } else {
+ // 进入详情时,释放实例以避免无容器绑定
customerTypeChartInstance.current?.dispose();
+ customerTypeChartInstance.current = null;
customerValueChartInstance.current?.dispose();
- };
- }, []);
+ customerValueChartInstance.current = null;
+ }
+ }, [showDetail]);
+
+ // 返回列表时恢复滚动位置,确保布局稳定后再滚动
+ useLayoutEffect(() => {
+ if (!showDetail) {
+ // 等待本帧布局完成
+ requestAnimationFrame(() => {
+ window.scrollTo(0, prevScrollY || 0);
+ });
+ }
+ }, [showDetail]);
// 最近活动数据
const recentActivities = [
@@ -239,6 +307,48 @@ const CustomerInfoManagement = () => {
},
];
+ // 列配置(用于 StandardTable)
+ const columns = useMemo(() => {
+ return [
+ { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 220 },
+ { title: '联系人', dataIndex: 'contact', key: 'contact', width: 120 },
+ { title: '联系电话', dataIndex: 'phone', key: 'phone', width: 140 },
+ {
+ title: '分类', dataIndex: 'classification', key: 'classification', width: 110,
+ render: (val) => (
+ {val}
+ )
+ },
+ {
+ title: '交易额度(月)', dataIndex: 'monthlyAmount', key: 'monthlyAmount', width: 150,
+ render: (v) => `¥${Number(v).toLocaleString()}`
+ },
+ {
+ title: '合作状态', dataIndex: 'cooperationStatus', key: 'cooperationStatus', width: 110,
+ render: (val) => (
+ {val}
+ )
+ },
+ {
+ title: '满意度', dataIndex: 'satisfaction', key: 'satisfaction', width: 120,
+ },
+ {
+ title: '操作', key: 'action', fixed: 'right', width: 200,
+ render: (_, row) => (
+
| - - | -客户名称 | -联系人 | -联系电话 | -分类 | -交易额度(月) | -合作状态 | -满意度 | -操作 | -
|---|---|---|---|---|---|---|---|---|
| - handleSelectRow(row.id)} - /> - | -{row.customerName} | -{row.contact} | -{row.phone} | -- - {row.classification} - - | -¥{row.monthlyAmount.toLocaleString()} | -- - {row.cooperationStatus} - - | -
-
- {renderStars(row.satisfaction)}
-
- |
-
-
-
-
-
-
- |
-