From c7c5181decdae46390ae4cbdcbd0421025cc1dfa Mon Sep 17 00:00:00 2001 From: jiangxucong Date: Thu, 11 Dec 2025 16:57:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A2=E6=88=B7=E4=BF=A1=E6=81=AF=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=BB=9F=E8=AE=A1=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/business_basic/recent_bg.png | Bin 0 -> 6499 bytes src/assets/business_basic/top_icon1.svg | 12 + src/assets/business_basic/top_icon2.svg | 12 + src/assets/business_basic/top_icon3.svg | 18 + src/assets/business_basic/top_icon4.svg | 13 + .../components/CustomerInfoManagement.js | 684 +++++++++--------- .../components/CustomerInfoManagement.less | 618 ++++++++-------- .../second_oil_components/BasicInfo.less | 33 +- 8 files changed, 753 insertions(+), 637 deletions(-) create mode 100644 src/assets/business_basic/recent_bg.png create mode 100644 src/assets/business_basic/top_icon1.svg create mode 100644 src/assets/business_basic/top_icon2.svg create mode 100644 src/assets/business_basic/top_icon3.svg create mode 100644 src/assets/business_basic/top_icon4.svg diff --git a/src/assets/business_basic/recent_bg.png b/src/assets/business_basic/recent_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..73c491a9ed0a3edc97fd4e1e54be3e4da68f1ea2 GIT binary patch literal 6499 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 literal 0 HcmV?d00001 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) => ( + + + + + + ) + }, + ]; + }, []); + // 处理选择 const handleSelectRow = (id) => { if (selectedRows.includes(id)) { @@ -262,7 +372,7 @@ const CustomerInfoManagement = () => { const stars = []; const fullStars = Math.floor(rating); const hasHalfStar = rating % 1 !== 0; - + for (let i = 0; i < fullStars; i++) { stars.push(); } @@ -282,7 +392,7 @@ const CustomerInfoManagement = () => { if (showDetail) { return (
-
+
@@ -304,286 +414,198 @@ const CustomerInfoManagement = () => { return (
- {/* KPI卡片区域 */} -
-
-
👥
-
{kpiData.totalCustomers}
-
总客户数
-
-
-
👑
-
{kpiData.highValueCustomers}
-
高价值客户
-
-
-
🤝
-
{kpiData.inCooperation}
-
合作中
-
-
-
-
{kpiData.newThisMonth}
-
本月新增
-
-
- - {/* 图表和活动区域 */} -
- {/* 客户类型分布图表 */} -
-
-
客户类型分布
- +
+ {/* KPI卡片区域 */} +
+
+
+
{kpiData.totalCustomers}
+
总客户数
+
+ icon
-
-
- - {/* 客户价值分布图表 */} -
-
-
客户价值分布
+
+
+
{kpiData.highValueCustomers}
+
高价值客户
+
+ icon
-
-
- - {/* 最近活动列表 */} -
-
-
最近活动
+
+
+
{kpiData.inCooperation}
+
合作中
+
+ icon
-
- {recentActivities.map((activity) => ( -
-
- {activity.id === 1 && '📄'} - {activity.id === 2 && '✅'} - {activity.id === 3 && '💬'} - {activity.id === 4 && '👤'} -
-
-
{activity.title}
-
{activity.description}
-
🕐 {activity.time}
-
-
- ))} +
+
+
{kpiData.newThisMonth}
+
本月新增
+
+ icon
-
- {/* 客户列表区域 */} -
-
-
客户列表
-
+ {/* 图表和活动区域 */} +
+ {/* 客户类型分布图表 */} +
+
+
客户类型分布
+ setSearchKeyword(e.target.value)} + {/* 客户价值分布图表 */} +
+
+
客户价值分布
+
+
- - - - - - -
-
- {/* 表格 */} -
- - - - - - - - - - - - - - - - {tableData.map((row) => ( - - - - - - - - - - - + {/* 最近活动列表 */} +
+
+
最近活动
+
+
+ {recentActivities.map((activity) => ( +
+
+
{activity.title}
+
{activity.time}
+
+
{activity.description}
+
))} -
-
- - 客户名称联系人联系电话分类交易额度(月)合作状态满意度操作
- handleSelectRow(row.id)} - /> - {row.customerName}{row.contact}{row.phone} - - {row.classification} - - ¥{row.monthlyAmount.toLocaleString()} - - {row.cooperationStatus} - - -
- {renderStars(row.satisfaction)} -
-
-
- - - -
-
+
+
- {/* 分页 */} -
-
- 共85条 - + {/* 客户列表区域 */} +
+
+ + 客户列表
-
- - {currentPage > 3 && ( - <> - - ... - - )} - {Array.from({ length: Math.min(5, totalPages) }, (_, i) => { - let pageNum; - if (currentPage <= 3) { - pageNum = i + 1; - } else if (currentPage >= totalPages - 2) { - pageNum = totalPages - 4 + i; - } else { - pageNum = currentPage - 2 + i; - } - if (pageNum > totalPages) return null; - return ( - - ); - })} - {currentPage < totalPages - 2 && ( - <> - ... - - - )} - +
+
+ setSearchKeyword(e.target.value)} + onSearch={(val) => setSearchKeyword(val)} + style={{ minWidth: 150 }} + /> +
+
+ 客户类型: + setFilters({ ...filters, customerGrade: v })} + placeholder="全部" + options={[ + { label: '全部', value: '' }, + ]} + allowClear + /> +
+
+ 合作状态: +