Optimized the root .gitignore to exclude virtual environments, node modules, and temp folders to ensure clean and lightweight version tracking. Co-authored-by: Cursor <cursoragent@cursor.com>
767 lines
48 KiB
JavaScript
767 lines
48 KiB
JavaScript
// 【重要】必须使用 const Component 作为组件变量名
|
||
// ONEOS-web - CRM 客户管理(建档字段、列表、标签、筛选)
|
||
|
||
const Component = function () {
|
||
var useState = React.useState;
|
||
|
||
var antd = window.antd;
|
||
var Table = antd.Table;
|
||
var Button = antd.Button;
|
||
var Space = antd.Space;
|
||
var Input = antd.Input;
|
||
var Select = antd.Select;
|
||
var DatePicker = antd.DatePicker;
|
||
var Form = antd.Form;
|
||
var Row = antd.Row;
|
||
var Col = antd.Col;
|
||
var Divider = antd.Divider;
|
||
var Breadcrumb = antd.Breadcrumb;
|
||
var Layout = antd.Layout;
|
||
var message = antd.message;
|
||
var Tag = antd.Tag;
|
||
var Tooltip = antd.Tooltip;
|
||
var Card = antd.Card;
|
||
var Modal = antd.Modal;
|
||
var Tabs = antd.Tabs;
|
||
var Cascader = antd.Cascader;
|
||
var Radio = antd.Radio;
|
||
|
||
var Content = Layout.Content;
|
||
var _modalOpen = useState(false);
|
||
var modalOpen = _modalOpen[0];
|
||
var setModalOpen = _modalOpen[1];
|
||
|
||
/** 筛选默认 2 行(每行 3 个 span:8);超出部分展开/收起 */
|
||
var _filterExpand = useState(false);
|
||
var filterExpanded = _filterExpand[0];
|
||
var setFilterExpanded = _filterExpand[1];
|
||
var FILTER_COLS_PER_ROW = 3;
|
||
var FILTER_VISIBLE_ROWS = 2;
|
||
var filterFieldCount = 8;
|
||
var filterRowCount = Math.ceil(filterFieldCount / FILTER_COLS_PER_ROW);
|
||
var showFilterExpandToggle = filterRowCount > FILTER_VISIBLE_ROWS;
|
||
|
||
var _form = Form.useForm();
|
||
var customerForm = _form[0];
|
||
|
||
var _filterFormInst = Form.useForm();
|
||
var filterForm = _filterFormInst[0];
|
||
|
||
var _filterDeptSel = useState([]);
|
||
var filterDeptSelection = _filterDeptSel[0];
|
||
var setFilterDeptSelection = _filterDeptSel[1];
|
||
|
||
/**
|
||
* 客户编号规则(集团多子公司)
|
||
* - 总长度 7,仅含大写字母 A–Z 与数字 0–9。
|
||
* - 结构:第 1 位 = 签约/归属子公司代码;第 2–7 位 = 6 位数字流水号(000001–999999,不足左补 0)。
|
||
* - 流水号在「同一子公司代码」下递增;不同字母下可各自从 000001 起编。
|
||
* - 校验正则:/^[A-Z][0-9]{6}$/
|
||
* 示例映射(可按主数据调整):A华东 B华南 C华北 D西南 E华中 F西北 G集团总部 …
|
||
*/
|
||
|
||
/** 客户标签枚举(筛选 + 列表展示,多选) */
|
||
var customerLabelOptions = [
|
||
{ label: '逾期预警', value: '逾期预警' },
|
||
{ label: '严重拖欠', value: '严重拖欠' },
|
||
{ label: '频繁改账期', value: '频繁改账期' },
|
||
{ label: '资质存疑', value: '资质存疑' },
|
||
{ label: '涉诉/仲裁', value: '涉诉/仲裁' },
|
||
{ label: '制裁/高风险地区', value: '制裁/高风险地区' },
|
||
{ label: '频繁争议', value: '频繁争议' },
|
||
{ label: '车辆/资产高风险', value: '车辆/资产高风险' },
|
||
{ label: '信息不实', value: '信息不实' },
|
||
{ label: '开票异常', value: '开票异常' },
|
||
{ label: '多头签约', value: '多头签约' }
|
||
];
|
||
|
||
var customerLabelTagStyle = {
|
||
margin: 0,
|
||
background: '#fff',
|
||
border: '1px solid #f77234',
|
||
color: '#1d2129',
|
||
borderRadius: 4,
|
||
lineHeight: '20px',
|
||
padding: '0 7px'
|
||
};
|
||
var customerLabelCountTagStyle = {
|
||
margin: 0,
|
||
background: '#fff',
|
||
border: '1px solid #c9cdd4',
|
||
color: '#4e5969',
|
||
borderRadius: 4,
|
||
lineHeight: '20px',
|
||
padding: '0 7px',
|
||
cursor: 'default'
|
||
};
|
||
|
||
/** PDF:区域 — 省-市级联(示例数据,可对接字典) */
|
||
var regionOptions = [
|
||
{ value: 'zj', label: '浙江省', children: [
|
||
{ value: 'zj-hz', label: '杭州市' },
|
||
{ value: 'zj-jx', label: '嘉兴市' },
|
||
{ value: 'zj-nb', label: '宁波市' }
|
||
] },
|
||
{ value: 'sh', label: '上海市', children: [
|
||
{ value: 'sh-pu', label: '上海市' }
|
||
] },
|
||
{ value: 'js', label: '江苏省', children: [
|
||
{ value: 'js-nj', label: '南京市' },
|
||
{ value: 'js-sz', label: '苏州市' }
|
||
] }
|
||
];
|
||
|
||
// 自定义 SVG 图标(高保真还原 Arco 风格)
|
||
var SearchIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z' })); };
|
||
var ResetIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M793 242H366v-74c0-6.7-7.7-10.4-12.9-6.3l-142 112a8 8 0 000 12.6l142 112c5.2 4.1 12.9.4 12.9-6.3v-74h415v470H175c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h618c35.3 0 64-28.7 64-64V306c0-35.3-28.7-64-64-64z' })); };
|
||
var PlusIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z' }), React.createElement('path', { d: 'M192 474h672q8 0 8 8v60q0 8-8 8H192q-8 0-8-8v-60q0-8 8-8z' })); };
|
||
var DownloadIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 16, height: 16, fill: 'currentColor' }, React.createElement('path', { d: 'M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z' })); };
|
||
var ListIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4, strokeLinecap: 'butt', strokeLinejoin: 'miter' }, React.createElement('path', { d: 'M17 12H42' }), React.createElement('path', { d: 'M17 24H42' }), React.createElement('path', { d: 'M17 36H42' }), React.createElement('path', { d: 'M8 12H9' }), React.createElement('path', { d: 'M8 24H9' }), React.createElement('path', { d: 'M8 36H9' })); };
|
||
|
||
/** 与 Ant Design Select 后缀箭头同形(DownOutlined 路径,收起态旋转 180° 与展开动画一致) */
|
||
var SelectSuffixArrowIcon = function (props) {
|
||
var up = props && props.up;
|
||
return React.createElement('span', {
|
||
className: 'ant-select-arrow',
|
||
style: {
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
lineHeight: 0,
|
||
marginLeft: 4,
|
||
flexShrink: 0,
|
||
color: 'inherit',
|
||
fontSize: 12,
|
||
transform: up ? 'rotate(180deg)' : 'none',
|
||
transformOrigin: '50% 50%',
|
||
transition: 'transform 0.3s'
|
||
},
|
||
'aria-hidden': true
|
||
},
|
||
React.createElement('svg', {
|
||
viewBox: '64 64 896 896',
|
||
focusable: 'false',
|
||
width: '1em',
|
||
height: '1em',
|
||
fill: 'currentColor'
|
||
},
|
||
React.createElement('path', { d: 'M884 256h-75c-5.1 0-9.9 2.5-12.6 6.5L512 654.6 227.9 262.6c-2.7-4-7.5-6.5-12.6-6.5h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z' })
|
||
)
|
||
);
|
||
};
|
||
|
||
var renderLabelTooltipContent = function (tags) {
|
||
return React.createElement(Space, { direction: 'vertical', size: 6, style: { padding: '2px 0' } },
|
||
tags.map(function (t) {
|
||
return React.createElement(Tag, { key: t, style: customerLabelTagStyle }, t);
|
||
})
|
||
);
|
||
};
|
||
|
||
/** 多标签:仅展示第一个 +「+N」;悬浮数量展示全部 */
|
||
var renderCustomerLabels = function (tags) {
|
||
if (!tags || !tags.length) return React.createElement('span', { style: { color: '#86909c' } }, '—');
|
||
if (tags.length === 1) {
|
||
return React.createElement(Space, { size: 4, wrap: false, style: { maxWidth: '100%', overflow: 'hidden' } },
|
||
React.createElement(Tag, { style: customerLabelTagStyle }, tags[0])
|
||
);
|
||
}
|
||
var rest = tags.length - 1;
|
||
var countEl = React.createElement(Tag, { style: customerLabelCountTagStyle }, '+' + String(rest));
|
||
return React.createElement(Space, { size: 4, wrap: false, style: { maxWidth: '100%', overflow: 'hidden' } },
|
||
React.createElement(Tag, { style: customerLabelTagStyle }, tags[0]),
|
||
React.createElement(Tooltip, { title: renderLabelTooltipContent(tags) },
|
||
React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', verticalAlign: 'middle' } }, countEl)
|
||
)
|
||
);
|
||
};
|
||
|
||
var renderCustomerStatus = function (text) {
|
||
var dot = '#86909c';
|
||
if (text === '正常') dot = '#00b42a';
|
||
else if (text === '黑名单') dot = '#f53f3f';
|
||
return React.createElement(Space, { size: 6 },
|
||
React.createElement('span', { style: { display: 'inline-block', width: 6, height: 6, borderRadius: '50%', backgroundColor: dot } }),
|
||
React.createElement('span', null, text)
|
||
);
|
||
};
|
||
|
||
var columns = [
|
||
{ title: '客户编号', dataIndex: 'code', key: 'code', width: 132, fixed: 'left' },
|
||
{ title: '客户名称', dataIndex: 'name', key: 'name', width: 200, ellipsis: true },
|
||
{ title: '标签', dataIndex: 'labels', key: 'labels', width: 120, className: 'customer-col-labels', render: renderCustomerLabels },
|
||
{ title: '客户区域', dataIndex: 'region', key: 'region', width: 100, ellipsis: true },
|
||
{ title: '客户状态', dataIndex: 'status', key: 'status', width: 100, render: renderCustomerStatus },
|
||
{ title: '业务部门', dataIndex: 'department', key: 'department', width: 110, ellipsis: true },
|
||
{ title: '业务负责人', dataIndex: 'manager', key: 'manager', width: 110, ellipsis: true },
|
||
{ title: '客户类型', dataIndex: 'customerType', key: 'customerType', width: 100 },
|
||
{ title: '所属行业', dataIndex: 'industry', key: 'industry', width: 100, ellipsis: true },
|
||
{ title: '统一社会信用代码', dataIndex: 'creditCode', key: 'creditCode', width: 200, ellipsis: true },
|
||
{ title: '法人', dataIndex: 'legalPerson', key: 'legalPerson', width: 88 },
|
||
{ title: '注册资本', dataIndex: 'regCapital', key: 'regCapital', width: 104 },
|
||
{ title: '经营状态', dataIndex: 'operateStatus', key: 'operateStatus', width: 88 },
|
||
{ title: '详细地址', dataIndex: 'address', key: 'address', width: 240, ellipsis: true },
|
||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 176, className: 'customer-col-create-time', ellipsis: true },
|
||
{
|
||
title: '操作',
|
||
key: 'action',
|
||
fixed: 'right',
|
||
width: 168,
|
||
render: function (_, record) {
|
||
return React.createElement(Space, { size: 0, split: React.createElement('span', { style: { color: '#e5e6eb' } }, '|') },
|
||
React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { message.info('详情:' + record.name); } }, '详情'),
|
||
React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { message.info('编辑:' + record.name); } }, '编辑'),
|
||
React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { message.info('删除:' + record.name); } }, '删除')
|
||
);
|
||
}
|
||
}
|
||
];
|
||
|
||
var data = [
|
||
{ key: '1', code: 'C000001', name: '北京华宇科技有限公司', labels: ['资质存疑'], region: '华北地区', status: '正常', department: '销售一部', manager: '张伟', customerType: '企业客户', industry: '互联网', creditCode: '91110108MA01D2XY89', legalPerson: '李明', regCapital: '1000万元', operateStatus: '在业', address: '北京市海淀区中关村大街18号科创大厦8层', createTime: '2023-10-25 14:30:00' },
|
||
{ key: '2', code: 'A000001', name: '上海诚新贸易有限公司', labels: ['频繁改账期'], region: '华东地区', status: '正常', department: '销售一部', manager: '王芳', customerType: '企业客户', industry: '零售', creditCode: '91310115MA1K3NBC12', legalPerson: '陈强', regCapital: '500万元', operateStatus: '在业', address: '上海市浦东新区张江路1288号科技园3号楼', createTime: '2023-11-02 09:15:00' },
|
||
{ key: '3', code: 'B000001', name: '深圳智联信息技术有限公司', labels: [], region: '华南地区', status: '正常', department: '市场开拓部', manager: '刘洋', customerType: '企业客户', industry: '互联网', creditCode: '91440300MA5F8QWE45', legalPerson: '赵敏', regCapital: '2000万元', operateStatus: '在业', address: '广东省深圳市南山区科技园南区科苑路15号', createTime: '2023-11-18 16:20:00' },
|
||
{ key: '4', code: 'A000002', name: '杭州云帆智能制造股份有限公司', labels: ['逾期预警'], region: '华东地区', status: '正常', department: '大客户部', manager: '李强', customerType: '企业客户', industry: '制造业', creditCode: '91330106MA2B7HJK01', legalPerson: '周杰', regCapital: '5000万元', operateStatus: '存续', address: '浙江省杭州市滨江区物联网街451号', createTime: '2023-12-05 11:00:00' },
|
||
{ key: '5', code: 'D000001', name: '成都天府医疗健康集团', labels: ['信息不实'], region: '西南地区', status: '正常', department: '大客户部', manager: '陈静', customerType: '企业客户', industry: '医疗保健', creditCode: '91510100MA6C9RST78', legalPerson: '吴磊', regCapital: '3000万元', operateStatus: '在业', address: '四川省成都市高新区天府大道北段966号', createTime: '2024-01-08 10:45:00' },
|
||
{ key: '6', code: 'B000002', name: '广州粤海金融服务有限公司', labels: ['严重拖欠', '多头签约'], region: '华南地区', status: '黑名单', department: '销售二部', manager: '孙丽', customerType: '企业客户', industry: '金融', creditCode: '91440101MA5D1UVW23', legalPerson: '郑华', regCapital: '8000万元', operateStatus: '在业', address: '广东省广州市天河区珠江东路30号金融中心16层', createTime: '2024-01-22 13:10:00' },
|
||
{ key: '7', code: 'E000001', name: '武汉长江物流供应链有限公司', labels: [], region: '华中地区', status: '正常', department: '销售一部', manager: '张伟', customerType: '企业客户', industry: '物流', creditCode: '91420100MA4K2PQR56', legalPerson: '冯涛', regCapital: '1500万元', operateStatus: '在业', address: '湖北省武汉市东西湖区物流大道88号', createTime: '2024-02-01 08:50:00' },
|
||
{ key: '8', code: 'A000003', name: '南京金陵软件科技有限公司', labels: [], region: '华东地区', status: '正常', department: '市场开拓部', manager: '王芳', customerType: '企业客户', industry: '互联网', creditCode: '91320105MA1P5XYZ99', legalPerson: '韩雪', regCapital: '800万元', operateStatus: '在业', address: '江苏省南京市雨花台区软件大道101号', createTime: '2024-02-14 15:25:00' },
|
||
{ key: '9', code: 'C000002', name: '天津市滨海新区港口设备制造厂', labels: ['涉诉/仲裁'], region: '华北地区', status: '正常', department: '销售二部', manager: '刘洋', customerType: '企业客户', industry: '制造业', creditCode: '91120116MA07NMLM34', legalPerson: '曹阳', regCapital: '2200万元', operateStatus: '存续', address: '天津市滨海新区临港经济区渤海路36号', createTime: '2024-03-03 09:40:00' },
|
||
{ key: '10', code: 'B000003', name: '厦门海峡跨境电商有限公司', labels: [], region: '华南地区', status: '正常', department: '市场开拓部', manager: '赵敏', customerType: '企业客户', industry: '零售', creditCode: '91350200MA8F3CDE77', legalPerson: '许晴', regCapital: '600万元', operateStatus: '在业', address: '福建省厦门市湖里区象屿路97号国际航运中心', createTime: '2024-03-20 14:05:00' },
|
||
{ key: '11', code: 'F000001', name: '西安市教育局机关服务中心', labels: [], region: '西北地区', status: '正常', department: '大客户部', manager: '李强', customerType: '政府机构', industry: '公共服务', creditCode: '91610103MB1T2ABC88', legalPerson: '何伟', regCapital: '—', operateStatus: '在业', address: '陕西省西安市碑林区盐店街28号', createTime: '2024-04-02 11:30:00' },
|
||
{ key: '12', code: 'A000004', name: '青岛海洋生物医药研究院有限公司', labels: ['开票异常'], region: '华东地区', status: '正常', department: '销售一部', manager: '陈静', customerType: '企业客户', industry: '医疗保健', creditCode: '91370212MA3U5FGH22', legalPerson: '罗斌', regCapital: '3500万元', operateStatus: '在业', address: '山东省青岛市崂山区松岭路238号', createTime: '2024-04-18 16:00:00' },
|
||
{ key: '13', code: 'E000002', name: '郑州中原新能源汽车销售有限公司', labels: ['严重拖欠', '涉诉/仲裁', '多头签约'], region: '华中地区', status: '黑名单', department: '销售二部', manager: '孙丽', customerType: '企业客户', industry: '制造业', creditCode: '91410105MA9L6NOP44', legalPerson: '丁凯', regCapital: '1200万元', operateStatus: '注销', address: '河南省郑州市金水区经三路66号(已迁出)', createTime: '2024-05-06 10:15:00' },
|
||
{ key: '14', code: 'A000005', name: '个体工商户·林晓峰五金经营部', labels: [], region: '华东地区', status: '正常', department: '销售一部', manager: '周杰', customerType: '个人客户', industry: '零售', creditCode: '92330102MA2HY67890', legalPerson: '林晓峰', regCapital: '50万元', operateStatus: '在业', address: '浙江省温州市鹿城区车站大道789号', createTime: '2024-05-22 09:20:00' },
|
||
{ key: '15', code: 'D000002', name: '重庆山城火锅餐饮管理有限公司', labels: [], region: '西南地区', status: '正常', department: '市场开拓部', manager: '吴磊', customerType: '企业客户', industry: '零售', creditCode: '91500105MA60QRS111', legalPerson: '黄丽', regCapital: '300万元', operateStatus: '在业', address: '重庆市渝中区解放碑民族路188号', createTime: '2024-06-01 12:45:00' },
|
||
{ key: '16', code: 'A000006', name: '苏州工业园区精密模具厂', labels: ['车辆/资产高风险', '制裁/高风险地区'], region: '华东地区', status: '黑名单', department: '大客户部', manager: '郑华', customerType: '企业客户', industry: '制造业', creditCode: '91320594MA1W2TUV55', legalPerson: '马军', regCapital: '1800万元', operateStatus: '在业', address: '江苏省苏州市工业园区星龙街428号', createTime: '2024-06-15 15:50:00' },
|
||
{ key: '17', code: 'E000003', name: '长沙湘江科创投资基金(有限合伙)', labels: ['频繁争议'], region: '华中地区', status: '正常', department: '大客户部', manager: '冯涛', customerType: '企业客户', industry: '金融', creditCode: '91430100MA4L8XYZ66', legalPerson: '谢文', regCapital: '10000万元', operateStatus: '在业', address: '湖南省长沙市岳麓区麓谷大道658号', createTime: '2024-07-03 08:30:00' },
|
||
{ key: '18', code: 'C000003', name: '石家庄市桥西区智慧城市运营中心', labels: [], region: '华北地区', status: '正常', department: '市场开拓部', manager: '韩雪', customerType: '政府机构', industry: '互联网', creditCode: '91130104MB0X9DEF12', legalPerson: '邓伟', regCapital: '—', operateStatus: '在业', address: '河北省石家庄市桥西区中华南大街172号', createTime: '2024-07-20 14:10:00' },
|
||
{ key: '19', code: 'A000007', name: '合肥徽风电子元器件有限公司', labels: ['频繁改账期'], region: '华东地区', status: '正常', department: '销售二部', manager: '曹阳', customerType: '企业客户', industry: '制造业', creditCode: '91340100MA2U1BCD33', legalPerson: '蒋欣', regCapital: '900万元', operateStatus: '在业', address: '安徽省合肥市高新区望江西路800号', createTime: '2024-08-08 11:55:00' },
|
||
{ key: '20', code: 'D000003', name: '昆明滇池生态旅游开发有限公司', labels: ['制裁/高风险地区', '多头签约', '开票异常'], region: '西南地区', status: '正常', department: '销售一部', manager: '许晴', customerType: '企业客户', industry: '公共服务', creditCode: '91530100MA6N7KLM88', legalPerson: '潘越', regCapital: '4500万元', operateStatus: '存续', address: '云南省昆明市西山区滇池路1318号', createTime: '2024-08-25 17:00:00' }
|
||
];
|
||
|
||
var deptManagerMap = {};
|
||
data.forEach(function (r) {
|
||
if (!r.department) return;
|
||
if (!deptManagerMap[r.department]) deptManagerMap[r.department] = [];
|
||
if (r.manager && deptManagerMap[r.department].indexOf(r.manager) < 0) {
|
||
deptManagerMap[r.department].push(r.manager);
|
||
}
|
||
});
|
||
|
||
var departmentOptions = [];
|
||
var seenDept = {};
|
||
data.forEach(function (r) {
|
||
if (r.department && !seenDept[r.department]) {
|
||
seenDept[r.department] = true;
|
||
departmentOptions.push({ label: r.department, value: r.department });
|
||
}
|
||
});
|
||
|
||
var customerCodeFilterOptions = [];
|
||
var seenCode = {};
|
||
data.forEach(function (r) {
|
||
if (r.code && !seenCode[r.code]) {
|
||
seenCode[r.code] = true;
|
||
customerCodeFilterOptions.push({ label: r.code + ' · ' + r.name, value: r.code });
|
||
}
|
||
});
|
||
|
||
var customerNameFilterOptions = [];
|
||
var seenName = {};
|
||
data.forEach(function (r) {
|
||
if (r.name && !seenName[r.name]) {
|
||
seenName[r.name] = true;
|
||
customerNameFilterOptions.push({ label: r.name, value: r.name });
|
||
}
|
||
});
|
||
|
||
var fuzzyFilterOption = function (input, option) {
|
||
if (input == null || String(input).trim() === '') return true;
|
||
var s = String(input).toLowerCase();
|
||
var label = (option && option.label != null ? String(option.label) : '') + '';
|
||
var value = (option && option.value != null ? String(option.value) : '') + '';
|
||
return label.toLowerCase().indexOf(s) >= 0 || value.toLowerCase().indexOf(s) >= 0;
|
||
};
|
||
|
||
var getManagerFilterOptions = function (deptVals) {
|
||
if (!deptVals || deptVals.length === 0) {
|
||
var all = {};
|
||
Object.keys(deptManagerMap).forEach(function (d) {
|
||
(deptManagerMap[d] || []).forEach(function (m) { all[m] = true; });
|
||
});
|
||
return Object.keys(all).sort().map(function (m) { return { label: m, value: m }; });
|
||
}
|
||
var pick = {};
|
||
deptVals.forEach(function (d) {
|
||
(deptManagerMap[d] || []).forEach(function (m) { pick[m] = true; });
|
||
});
|
||
return Object.keys(pick).sort().map(function (m) { return { label: m, value: m }; });
|
||
};
|
||
|
||
var handleFilterDeptChange = function (vals) {
|
||
var v = vals || [];
|
||
setFilterDeptSelection(v);
|
||
var allowed = getManagerFilterOptions(v).map(function (o) { return o.value; });
|
||
var curM = filterForm.getFieldValue('filterManagers') || [];
|
||
filterForm.setFieldsValue({
|
||
filterManagers: curM.filter(function (m) { return allowed.indexOf(m) >= 0; })
|
||
});
|
||
};
|
||
|
||
var formItemLayout = {
|
||
labelAlign: 'left',
|
||
colon: false,
|
||
labelCol: { flex: '0 0 100px' },
|
||
wrapperCol: { flex: '1 1 0' }
|
||
};
|
||
|
||
var TextArea = Input.TextArea;
|
||
|
||
var tabCustomerBase = React.createElement(Row, { gutter: 16 },
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '客户类型', name: 'customerType', rules: [{ required: true, message: '请选择客户类型' }] },
|
||
React.createElement(Radio.Group, null,
|
||
React.createElement(Radio, { value: '企业' }, '企业'),
|
||
React.createElement(Radio, { value: '个人' }, '个人'),
|
||
React.createElement(Radio, { value: '事业单位' }, '事业单位')
|
||
)
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '客户分级', name: 'abcLevel', rules: [{ required: true, message: '请选择分级' }] },
|
||
React.createElement(Radio.Group, null,
|
||
React.createElement(Radio, { value: 'A' }, 'A'),
|
||
React.createElement(Radio, { value: 'B' }, 'B'),
|
||
React.createElement(Radio, { value: 'C' }, 'C')
|
||
)
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '客户全称', name: 'name', rules: [{ required: true, message: '请输入客户全称' }] },
|
||
React.createElement(Input, { placeholder: '与客户证照一致' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '客户简称', name: 'shortName' },
|
||
React.createElement(Input, { placeholder: '选填' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '所属城市', name: 'region', rules: [{ required: true, message: '请选择省-市' }] },
|
||
React.createElement(Cascader, { options: regionOptions, placeholder: '省 - 市(级联)', style: { width: '100%' } })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '通讯地址', name: 'address' },
|
||
React.createElement(TextArea, { rows: 2, placeholder: '通讯地址' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '业务部门', name: 'department', rules: [{ required: true, message: '请填写业务部门' }] },
|
||
React.createElement(Input, { placeholder: '业务部门' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '业务负责人', name: 'manager', rules: [{ required: true, message: '请填写业务负责人' }] },
|
||
React.createElement(Input, { placeholder: '业务负责人' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '备注', name: 'remark' },
|
||
React.createElement(TextArea, { rows: 2, placeholder: '备注' })
|
||
)
|
||
)
|
||
);
|
||
|
||
var tabContact = React.createElement(Row, { gutter: 16 },
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { label: '姓名', name: 'contactName' },
|
||
React.createElement(Input, { placeholder: '联系人姓名' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { label: '手机号', name: 'contactPhone' },
|
||
React.createElement(Input, { placeholder: '手机号' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { label: '职位', name: 'contactTitle' },
|
||
React.createElement(Input, { placeholder: '职位' })
|
||
)
|
||
)
|
||
);
|
||
|
||
var tabInvoice = React.createElement(Row, { gutter: 16 },
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, {
|
||
label: '发票抬头',
|
||
name: 'invoiceTitle',
|
||
rules: [{ required: true, message: '请填写发票抬头' }],
|
||
extra: '建议与客户全称保持一致'
|
||
},
|
||
React.createElement(Input, { placeholder: '与客户名称一致' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '纳税人识别号', name: 'taxId', rules: [{ required: true, message: '请填写纳税人识别号' }] },
|
||
React.createElement(Input, { placeholder: '纳税人识别号' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '注册电话', name: 'regPhone' },
|
||
React.createElement(Input, { placeholder: '注册电话' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 24 },
|
||
React.createElement(Form.Item, { label: '注册地址', name: 'regAddress' },
|
||
React.createElement(TextArea, { rows: 2, placeholder: '注册地址' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '开户银行', name: 'bankName', rules: [{ required: true, message: '请填写开户银行' }] },
|
||
React.createElement(Input, { placeholder: '开户银行' })
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement(Form.Item, { label: '账号', name: 'bankAccount', rules: [{ required: true, message: '请填写银行账号' }] },
|
||
React.createElement(Input, { placeholder: '银行账号' })
|
||
)
|
||
)
|
||
);
|
||
|
||
var customerModal = React.createElement(Modal, {
|
||
title: '新增客户',
|
||
open: modalOpen,
|
||
width: 720,
|
||
onCancel: function () { setModalOpen(false); },
|
||
onOk: function () {
|
||
customerForm.validateFields().then(function () {
|
||
message.success('已保存(示例,请对接保存接口)');
|
||
setModalOpen(false);
|
||
}).catch(function () {});
|
||
},
|
||
okText: '保存',
|
||
cancelText: '取消',
|
||
destroyOnClose: true
|
||
},
|
||
React.createElement(Form, {
|
||
form: customerForm,
|
||
layout: 'vertical',
|
||
style: { marginTop: 4 },
|
||
initialValues: { customerType: '企业', abcLevel: 'B' }
|
||
},
|
||
React.createElement(Tabs, {
|
||
defaultActiveKey: 'base',
|
||
items: [
|
||
{ key: 'base', label: '客户信息', children: tabCustomerBase },
|
||
{ key: 'contact', label: '联系人信息', children: tabContact },
|
||
{ key: 'invoice', label: '付款及开票信息', children: tabInvoice }
|
||
]
|
||
})
|
||
)
|
||
);
|
||
|
||
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#f2f3f5', fontFamily: 'Inter, Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' } },
|
||
// 内联 CSS 以实现最高保真度的 Arco UI
|
||
React.createElement('style', null, `
|
||
.arco-theme-overrides .ant-btn { border-radius: 4px; }
|
||
.arco-theme-overrides .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
|
||
.arco-theme-overrides .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
|
||
.arco-theme-overrides .ant-btn-link { color: #165dff; }
|
||
.arco-theme-overrides .ant-btn-link:hover { background-color: transparent; color: #4080ff; }
|
||
/* 表头对齐 Arco .arco-table-th-title:14px / #909399,标题区 22px 行高,整行仍 40px */
|
||
.arco-theme-overrides .ant-table-thead > tr > th {
|
||
background-color: #f2f3f5;
|
||
color: #909399;
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
height: 40px;
|
||
padding: 9px 16px;
|
||
line-height: 22px;
|
||
box-sizing: border-box;
|
||
border-bottom: 1px solid #e5e6eb;
|
||
border-top: none;
|
||
vertical-align: middle;
|
||
}
|
||
.arco-theme-overrides .ant-table-thead > tr > th .ant-table-column-title {
|
||
font-size: 14px;
|
||
color: #909399;
|
||
line-height: 22px;
|
||
min-height: 22px;
|
||
white-space: nowrap;
|
||
}
|
||
.arco-theme-overrides .ant-table-thead > tr > th::before { display: none !important; }
|
||
.arco-theme-overrides .ant-table-tbody > tr > td { border-bottom: 1px solid #e5e6eb; padding: 13px 16px; color: #4e5969; vertical-align: middle; line-height: 22px; }
|
||
.arco-theme-overrides .ant-table-tbody > tr { height: 52px; }
|
||
.arco-theme-overrides .ant-table-cell.customer-col-create-time { white-space: nowrap; }
|
||
.arco-theme-overrides .ant-table-cell.customer-col-labels .ant-space { max-width: 100%; }
|
||
.arco-theme-overrides .customer-table-scroll-wrap { width: 100%; min-width: 0; max-width: 100%; }
|
||
.arco-theme-overrides .ant-table-wrapper { border: none; }
|
||
.arco-theme-overrides .ant-table { border: none; }
|
||
.arco-theme-overrides .ant-table-container { border: none; }
|
||
.arco-theme-overrides .ant-table-pagination.ant-pagination { margin: 16px 0 0 0; }
|
||
.arco-theme-overrides .ant-card { border: none; border-radius: 4px; }
|
||
.arco-theme-overrides .customer-page-card.ant-card { border: 1px solid #e5e6eb !important; border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,0.06); background: #fff; }
|
||
.arco-theme-overrides .customer-page-card .ant-card-body { padding: 20px 24px 24px; }
|
||
/* 筛选组件(Input/Select/DatePicker)的默认、Hover、Focus样式复刻 */
|
||
.arco-theme-overrides .ant-input, .arco-theme-overrides .ant-select-selector, .arco-theme-overrides .ant-picker { border-radius: 2px; border: 1px solid #e5e6eb; background-color: #fff; transition: all 0.1s cubic-bezier(0, 0, 1, 1); }
|
||
.arco-theme-overrides .ant-input:hover, .arco-theme-overrides .ant-select:not(.ant-select-disabled):hover .ant-select-selector, .arco-theme-overrides .ant-picker:hover { background-color: #fff; border-color: #165dff; }
|
||
.arco-theme-overrides .ant-input:focus, .arco-theme-overrides .ant-input-focused, .arco-theme-overrides .ant-select-focused .ant-select-selector, .arco-theme-overrides .ant-picker-focused { background-color: #fff; border: 1px solid #165dff !important; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; outline: 0; }
|
||
.arco-theme-overrides .ant-input-affix-wrapper:focus, .arco-theme-overrides .ant-input-affix-wrapper-focused { background-color: #fff; border-color: #165dff !important; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; }
|
||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input,
|
||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input:focus,
|
||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input:hover { height: 100%; padding: 0; border: none !important; box-shadow: none !important; outline: none !important; background-color: transparent !important; }
|
||
|
||
/* 日期选择器展开面板(Dropdown/Panel)的样式复刻 */
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-panel-container { border-radius: 4px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); border: 1px solid #e5e6eb; background: #fff; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-header { border-bottom: 1px solid #e5e6eb; color: #1d2129; padding: 0 8px; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-content th { color: #86909c; font-weight: 400; font-size: 14px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-selected .ant-picker-cell-inner { background: #165dff; color: #fff; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-range-start .ant-picker-cell-inner,
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-range-end .ant-picker-cell-inner { background: #165dff; color: #fff; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-in-range::before { background: #e8f3ff; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today .ant-picker-cell-inner::before { border: 1px solid transparent; border-radius: 2px; position: relative; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today .ant-picker-cell-inner::after { content: ""; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: 50%; background-color: #165dff; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today.ant-picker-cell-selected .ant-picker-cell-inner::after { background-color: #fff; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-cell:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end) .ant-picker-cell-inner { background: #f2f3f5; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-inner { border-radius: 2px; font-size: 14px; color: #4e5969; width: 24px; height: 24px; line-height: 24px; }
|
||
|
||
/* 日期选择器展开面板(Dropdown/Panel)的样式复刻 */
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-panel-container { border-radius: 4px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); border: 1px solid #e5e6eb; background: #fff; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-header { border-bottom: 1px solid #e5e6eb; color: #1d2129; padding: 0 8px; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-content th { color: #86909c; font-weight: 400; font-size: 14px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-selected .ant-picker-cell-inner { background: #165dff; color: #fff; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-range-start .ant-picker-cell-inner,
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-range-end .ant-picker-cell-inner { background: #165dff; color: #fff; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-in-range::before { background: #e8f3ff; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today .ant-picker-cell-inner::before { border: 1px solid transparent; border-radius: 2px; position: relative; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today .ant-picker-cell-inner::after { content: ""; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: 50%; background-color: #165dff; }
|
||
.arco-theme-overrides .ant-picker-cell-in-view.ant-picker-cell-today.ant-picker-cell-selected .ant-picker-cell-inner::after { background-color: #fff; }
|
||
.arco-theme-overrides .ant-picker-dropdown .ant-picker-cell:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end) .ant-picker-cell-inner { background: #f2f3f5; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-picker-cell-inner { border-radius: 2px; font-size: 14px; color: #4e5969; width: 24px; height: 24px; line-height: 24px; }
|
||
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; white-space: nowrap; flex-shrink: 0; }
|
||
.arco-theme-overrides .customer-page-header-row { display: flex; align-items: center; flex-wrap: nowrap; gap: 0; margin-bottom: 20px; }
|
||
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
|
||
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
|
||
.arco-theme-overrides .ant-form-item-label { padding: 0 16px 0 0 !important; line-height: 32px; height: 32px; display: flex; align-items: center; }
|
||
.arco-theme-overrides .ant-form-item-control { display: flex; align-items: center; line-height: 32px; min-height: 32px; }
|
||
.arco-theme-overrides .ant-form-item-control-input { min-height: 32px; width: 100%; display: flex; align-items: center; }
|
||
.arco-theme-overrides .ant-form-item-control-input-content { display: flex; align-items: center; width: 100%; height: 100%; }
|
||
.arco-theme-overrides .ant-select { width: 100%; height: 32px; }
|
||
.arco-theme-overrides .ant-select-selector { height: 32px !important; min-height: 32px !important; display: flex; align-items: center; width: 100%; padding: 0 12px; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-selector { padding: 0 4px; align-items: center; }
|
||
.arco-theme-overrides .ant-select-selection-item { line-height: 30px !important; margin-top: 0 !important; margin-bottom: 0 !important; }
|
||
.arco-theme-overrides .ant-select-selection-overflow { align-items: center; }
|
||
.arco-theme-overrides .customer-filter-manager-select.ant-select-multiple .ant-select-selector { overflow: hidden; }
|
||
.arco-theme-overrides .customer-filter-manager-select.ant-select-multiple .ant-select-selection-overflow { flex-wrap: nowrap; overflow: hidden; }
|
||
.arco-theme-overrides .ant-input { height: 32px; padding: 4px 12px; }
|
||
.arco-theme-overrides .ant-picker { height: 32px !important; min-height: 32px !important; display: flex; align-items: center; padding: 4px 12px; width: 100%; }
|
||
.arco-theme-overrides .ant-form-item-label > label { color: #4e5969; white-space: nowrap; }
|
||
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
|
||
|
||
/* 多选标签及下拉菜单 Checkbox 样式复刻 (模拟 Arco) */
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-selection-item { background: #f2f3f5; border: none; border-radius: 2px; }
|
||
.arco-theme-overrides .ant-select-multiple.ant-select-show-arrow .ant-select-selection-item { padding-inline-end: 24px; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-item-option { padding-left: 36px; position: relative; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-item-option::before { content: ""; position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; border: 1px solid #e5e6eb; border-radius: 2px; transition: all 0.1s; background: #fff; box-sizing: border-box; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-item-option-selected::before { background-color: #165dff; border-color: #165dff; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-item-option-selected::after { content: ""; position: absolute; left: 16px; top: 50%; transform: translateY(-70%) rotate(45deg); width: 4px; height: 8px; border: 2px solid #fff; border-top: 0; border-left: 0; box-sizing: content-box; z-index: 1; }
|
||
.arco-theme-overrides .ant-select-multiple .ant-select-item-option-state { display: none; }
|
||
`),
|
||
// 仅保留客户管理主内容区(无顶栏、无侧栏);面包屑在卡片外,标题+筛选+列表在白卡片内
|
||
React.createElement(Content, { style: { marginLeft: 0, padding: '16px 20px 24px', minHeight: '100vh', display: 'flex', flexDirection: 'column', background: '#f2f3f5' } },
|
||
React.createElement('div', { className: 'customer-page-header-row', style: { marginBottom: 12, flexShrink: 0 } },
|
||
React.createElement(Breadcrumb, {
|
||
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
|
||
items: [
|
||
{ title: React.createElement(ListIcon, { style: { display: 'inline-flex', alignItems: 'center', fontSize: 14, transform: 'translate(-2px, 1px)' } }) },
|
||
{ title: '业务管理' }
|
||
]
|
||
})
|
||
),
|
||
React.createElement(Card, { className: 'customer-page-card', bordered: false },
|
||
React.createElement('div', { style: { fontSize: 18, fontWeight: 600, color: '#1d2129', lineHeight: '26px', marginBottom: 20 } }, '客户管理'),
|
||
// 搜索表单区域
|
||
React.createElement('div', { style: { marginBottom: 0 } },
|
||
React.createElement(Row, { style: { flexWrap: 'nowrap', alignItems: 'stretch' } },
|
||
React.createElement(Col, { flex: 1, style: { minWidth: 0, paddingRight: 40 } },
|
||
React.createElement(Form, Object.assign({ layout: 'horizontal', form: filterForm }, formItemLayout),
|
||
React.createElement(Row, { gutter: 24, style: { rowGap: 0 } },
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterCode', label: '客户编号', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
allowClear: true,
|
||
showSearch: true,
|
||
filterOption: fuzzyFilterOption,
|
||
placeholder: '请选择或搜索客户编号',
|
||
options: customerCodeFilterOptions
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterName', label: '客户名称', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
allowClear: true,
|
||
showSearch: true,
|
||
filterOption: fuzzyFilterOption,
|
||
placeholder: '请选择或搜索客户名称',
|
||
options: customerNameFilterOptions
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterTags', label: '标签', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
mode: 'multiple',
|
||
allowClear: true,
|
||
maxTagCount: 'responsive',
|
||
placeholder: '请选择标签',
|
||
options: customerLabelOptions
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterRegion', label: '区域', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Cascader, {
|
||
style: { width: '100%' },
|
||
options: regionOptions,
|
||
placeholder: '请选择客户区域',
|
||
changeOnSelect: false
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterStatus', label: '客户状态', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
mode: 'multiple',
|
||
allowClear: true,
|
||
maxTagCount: 'responsive',
|
||
placeholder: '请选择客户状态',
|
||
options: [
|
||
{ label: '正常', value: '正常' },
|
||
{ label: '黑名单', value: '黑名单' }
|
||
]
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterDepts', label: '业务部门', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
mode: 'multiple',
|
||
allowClear: true,
|
||
maxTagCount: 'responsive',
|
||
placeholder: '请选择业务部门',
|
||
options: departmentOptions,
|
||
onChange: handleFilterDeptChange
|
||
})
|
||
)
|
||
)
|
||
),
|
||
filterExpanded
|
||
? React.createElement(Row, { gutter: 24, style: { rowGap: 0, marginTop: 0 } },
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterManagers', label: '业务负责人', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(Select, {
|
||
mode: 'multiple',
|
||
allowClear: true,
|
||
maxTagCount: 'responsive',
|
||
className: 'customer-filter-manager-select',
|
||
placeholder: '请选择业务负责人',
|
||
options: getManagerFilterOptions(filterDeptSelection)
|
||
})
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 8 },
|
||
React.createElement(Form.Item, { name: 'filterDateRange', label: '创建时间', style: { marginBottom: 16, height: 32 } },
|
||
React.createElement(DatePicker.RangePicker, {
|
||
style: { width: '100%' },
|
||
placeholder: ['开始时间', '结束时间']
|
||
})
|
||
)
|
||
)
|
||
)
|
||
: null
|
||
)
|
||
),
|
||
React.createElement(Divider, {
|
||
type: 'vertical',
|
||
style: {
|
||
alignSelf: 'stretch',
|
||
height: 'auto',
|
||
minHeight: filterExpanded ? 132 : 100,
|
||
borderLeftColor: 'rgb(229, 230, 235)',
|
||
borderLeftStyle: 'dashed',
|
||
marginLeft: 20,
|
||
marginRight: 20
|
||
}
|
||
}),
|
||
React.createElement(Col, { flex: 'none', style: { textAlign: 'right', display: 'flex', flexDirection: 'column', alignItems: 'flex-end', minWidth: 100, maxWidth: 168 } },
|
||
React.createElement(Space, { direction: 'vertical', size: 12, style: { width: '100%', alignItems: 'flex-end' } },
|
||
React.createElement(Button, { type: 'primary', icon: React.createElement(SearchIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center', width: 86 } }, '查询'),
|
||
React.createElement(Button, {
|
||
icon: React.createElement(ResetIcon, null),
|
||
style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center', width: 86 },
|
||
onClick: function () {
|
||
filterForm.resetFields();
|
||
setFilterDeptSelection([]);
|
||
}
|
||
}, '重置'),
|
||
showFilterExpandToggle
|
||
? React.createElement(Button, {
|
||
type: 'link',
|
||
size: 'small',
|
||
style: { padding: '0 4px', height: 'auto', lineHeight: 1.4, color: '#165dff', whiteSpace: 'normal', textAlign: 'right' },
|
||
onClick: function () { setFilterExpanded(!filterExpanded); }
|
||
},
|
||
React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', justifyContent: 'flex-end', width: '100%' } },
|
||
filterExpanded ? '收起' : '更多筛选',
|
||
React.createElement(SelectSuffixArrowIcon, { up: filterExpanded })
|
||
)
|
||
)
|
||
: null
|
||
)
|
||
)
|
||
)
|
||
),
|
||
React.createElement(Divider, { style: { margin: '16px 0 20px', borderColor: '#e5e6eb' } }),
|
||
// 工具栏 + 表格
|
||
React.createElement('div', { style: { display: 'flex', flexDirection: 'column', flex: 1, minWidth: 0 } },
|
||
React.createElement(Row, { justify: 'space-between', align: 'middle', style: { marginBottom: 16 } },
|
||
React.createElement(Col, null,
|
||
React.createElement(Space, { size: 12 },
|
||
React.createElement(Button, { type: 'primary', icon: React.createElement(PlusIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6 }, onClick: function () { customerForm.resetFields(); setModalOpen(true); } }, '新增客户'),
|
||
React.createElement(Button, null, '批量导入')
|
||
)
|
||
),
|
||
React.createElement(Col, null,
|
||
React.createElement(Button, {
|
||
style: { padding: '4px 10px', height: 32, display: 'flex', alignItems: 'center', gap: 6, color: '#4e5969' },
|
||
title: '批量导出',
|
||
onClick: function () { message.info('批量导出(示例)'); }
|
||
}, React.createElement(DownloadIcon, null), React.createElement('span', null, '批量导出'))
|
||
)
|
||
),
|
||
// 表格区域(横向超出出现滚动条;操作列 fixed 右侧)
|
||
React.createElement('div', { className: 'customer-table-scroll-wrap', style: { flex: 1, minHeight: 0, minWidth: 0 } },
|
||
React.createElement(Table, {
|
||
rowSelection: { type: 'checkbox', columnWidth: 48 },
|
||
columns: columns,
|
||
dataSource: data,
|
||
pagination: {
|
||
defaultPageSize: 10,
|
||
showSizeChanger: true,
|
||
pageSizeOptions: ['10', '20', '50', '100'],
|
||
showTotal: function (total) { return '共 ' + total + ' 条'; }
|
||
},
|
||
scroll: { x: 2242 }
|
||
})
|
||
)
|
||
)
|
||
)
|
||
),
|
||
customerModal
|
||
);
|
||
};
|
||
|
||
if (typeof module !== 'undefined' && module.exports) module.exports = Component;
|