feat: sync full workspace including web modules, docs, and configurations to Gitea

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>
This commit is contained in:
王冕
2026-06-09 18:12:25 +08:00
parent 351688006e
commit a27e3b8e43
1510 changed files with 162044 additions and 1517 deletions

View File

@@ -0,0 +1,379 @@
// 【重要】必须使用 const Component 作为组件变量名
// ONEOS-web 示例项目 - CRM 供应商管理 (完美复刻 Arco Design Pro 查询表格)
const Component = function () {
var useState = React.useState;
var antd = window.antd;
var Table = antd.Table;
var Button = antd.Button;
var Card = antd.Card;
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 Menu = antd.Menu;
var Layout = antd.Layout;
var message = antd.message;
var Typography = antd.Typography;
var Avatar = antd.Avatar;
var Badge = antd.Badge;
var Header = Layout.Header;
var Content = Layout.Content;
var Sider = Layout.Sider;
var Title = Typography.Title;
var _currentMenu = useState('crm-supplier');
var currentMenu = _currentMenu[0];
var setCurrentMenu = _currentMenu[1];
var handleMenuClick = function (e) {
setCurrentMenu(e.key);
if (e.key === 'contract-list') {
message.info('跳转至 合同列表');
window.location.hash = '合同列表';
} else if (e.key === 'erp-order') {
message.info('跳转至 ERP 订单管理');
window.location.hash = '订单管理';
} else if (e.key === 'asset-overview') {
message.info('跳转至 资产概览');
window.location.hash = '资产概览';
} else if (e.key === 'crm-list') {
message.info('跳转至 客户列表');
window.location.hash = '客户列表';
}
};
// 自定义 SVG 图标(高保真还原 Arco 风格)
var SearchIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M33.072 33.071c6.248-6.248 6.248-16.379 0-22.627-6.249-6.249-16.38-6.249-22.628 0-6.248 6.248-6.248 16.379 0 22.627 6.248 6.248 16.38 6.248 22.628 0Zm0 0 8.485 8.485' })); };
var ResetIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M38.837 18C36.463 12.136 30.715 8 24 8 15.163 8 8 15.163 8 24s7.163 16 16 16c7.455 0 13.72-5.1 15.496-12M40 8v10H30' })); };
var PlusIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M5 24h38M24 5v38' })); };
var DownloadIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'm33.072 22.071-9.07 9.071-9.072-9.07M24 5v26m16 4v6H8v-6' })); };
var SettingIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 16, height: 16, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M18.797 6.732A1 1 0 0 1 19.76 6h8.48a1 1 0 0 1 .964.732l1.285 4.628a1 1 0 0 0 1.213.7l4.651-1.2a1 1 0 0 1 1.116.468l4.24 7.344a1 1 0 0 1-.153 1.2L38.193 23.3a1 1 0 0 0 0 1.402l3.364 3.427a1 1 0 0 1 .153 1.2l-4.24 7.344a1 1 0 0 1-1.116.468l-4.65-1.2a1 1 0 0 0-1.214.7l-1.285 4.628a1 1 0 0 1-.964.732h-8.48a1 1 0 0 1-.963-.732L17.51 36.64a1 1 0 0 0-1.213-.7l-4.65 1.2a1 1 0 0 1-1.116-.468l-4.24-7.344a1 1 0 0 1 .153-1.2L9.809 24.7a1 1 0 0 0 0-1.402l-3.364-3.427a1 1 0 0 1-.153-1.2l4.24-7.344a1 1 0 0 1 1.116-.468l4.65 1.2a1 1 0 0 0 1.213-.7l1.286-4.628Z' }), React.createElement('path', { d: 'M30 24a6 6 0 1 1-12 0 6 6 0 0 1 12 0Z' })); };
var NoticeIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 18, height: 18, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M39 34h3v4H6v-4h3V20.218a15 15 0 0 1 30 0V34ZM24 44a6 6 0 0 1-6-6h12a6 6 0 0 1-6 6Z' })); };
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' })); };
var columns = [
{ title: '供应商名称', dataIndex: 'name', key: 'name', width: 220 },
{ title: '类型', dataIndex: 'type', key: 'type', width: 140 },
{ title: '所属城市', dataIndex: 'city', key: 'city', width: 140 },
{ title: '业务负责部门', dataIndex: 'department', key: 'department', width: 140 },
{ title: '业务负责人员', dataIndex: 'manager', key: 'manager', width: 140 },
{ title: '状态', dataIndex: 'status', key: 'status', width: 100, render: function(text) {
var isOnline = text === '正常';
return React.createElement(Space, { size: 6 },
React.createElement('span', { style: { display: 'inline-block', width: 6, height: 6, borderRadius: '50%', backgroundColor: isOnline ? '#00b42a' : '#f53f3f' } }),
React.createElement('span', null, text)
);
} },
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
{
title: '操作',
key: 'action',
fixed: 'right',
width: 100,
render: function (_, record) {
return React.createElement(Button, { type: 'link', style: { padding: 0 }, onClick: function() { message.info('查看详情: ' + record.name); } }, '查看');
}
}
];
var data = [
{ key: '1', name: '阿里云计算有限公司', type: '其他', city: '浙江-杭州', department: '技术部', manager: '张三', status: '正常', createTime: '2023-01-10 10:00:00' },
{ key: '2', name: '腾讯云计算(北京)有限责任公司', type: '其他', city: '北京', department: '技术部', manager: '李四', status: '正常', createTime: '2023-02-15 11:30:00' },
{ key: '3', name: '中国平安财产保险股份有限公司', type: '保险公司', city: '广东-深圳', department: '法务部', manager: '王五', status: '正常', createTime: '2023-03-20 14:15:00' },
{ key: '4', name: '一汽大众汽车有限公司', type: '整车企业', city: '吉林-长春', department: '采购部', manager: '赵六', status: '停用', createTime: '2023-04-18 09:45:00' },
{ key: '5', name: '宁德时代新能源科技股份有限公司', type: '备件供应商', city: '福建-宁德', department: '采购部', manager: '孙七', status: '正常', createTime: '2023-05-12 16:20:00' }
];
var menuItems = [
{
key: 'contract',
label: '合同管理',
icon: React.createElement('span', { className: 'anticon' }, '📄'),
children: [
{ key: 'contract-list', label: '合同列表' }
]
},
{
key: 'crm',
label: 'CRM 管理',
icon: React.createElement('span', { className: 'anticon' }, '👥'),
children: [
{ key: 'crm-list', label: '客户管理' },
{ key: 'crm-supplier', label: '供应商管理' },
{ key: 'crm-analysis', label: 'CRM 分析' }
]
},
{
key: 'erp',
label: 'ERP 订单管理',
icon: React.createElement('span', { className: 'anticon' }, '📦'),
children: [
{ key: 'erp-order', label: '订单管理' }
]
},
{
key: 'asset',
label: '资产管理',
icon: React.createElement('span', { className: 'anticon' }, '🚗'),
children: [
{ key: 'asset-overview', label: '资产概览' }
]
}
];
var formItemLayout = {
labelAlign: 'left',
colon: false,
labelCol: { flex: '0 0 86px' },
wrapperCol: { flex: '1 1 0' }
};
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#fff', 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; box-shadow: none; font-size: 14px; }
.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-default { background-color: #f2f3f5; border-color: transparent; color: #4e5969; }
.arco-theme-overrides .ant-btn-default:hover { background-color: #e5e6eb; border-color: transparent; color: #4e5969; }
.arco-theme-overrides .ant-btn-link { color: #165dff; }
.arco-theme-overrides .ant-btn-link:hover { background-color: transparent; color: #4080ff; }
.arco-theme-overrides .ant-menu-light .ant-menu-item-selected { background-color: #f2f9fe; color: #165dff; }
.arco-theme-overrides .ant-menu-light .ant-menu-item-selected::after { border-right-color: #165dff; }
.arco-theme-overrides .ant-table-thead > tr > th { background-color: #f2f3f5; color: #1d2129; font-weight: 500; padding: 13px 16px; border-bottom: 1px solid #e5e6eb; border-top: none; }
.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; }
.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; }
/* 筛选组件(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; }
/* 日期选择器展开面板(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; }
.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 .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; }
.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; }
`),
// 顶部 Header
React.createElement(Header, {
style: {
background: '#fff',
padding: '0 20px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
borderBottom: '1px solid #e5e6eb',
height: 60,
position: 'fixed',
top: 0,
left: 0,
right: 0,
zIndex: 100
}
},
// 左侧 Logo
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 12 } },
React.createElement('div', { style: { width: 32, height: 32, background: '#165dff', borderRadius: 4, display: 'flex', justifyContent: 'center', alignItems: 'center', color: '#fff', fontWeight: 'bold' } }, 'A'),
React.createElement('div', { style: { fontSize: '20px', fontWeight: '600', color: '#1d2129', letterSpacing: '0.5px' } }, 'Arco Pro')
),
// 右侧工具栏
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 20 } },
React.createElement(Input.Search, { placeholder: '搜索功能', style: { width: 220, borderRadius: 16 } }),
React.createElement(Badge, { dot: true, offset: [-2, 4] },
React.createElement('span', { style: { color: '#4e5969', cursor: 'pointer', display: 'flex' }, title: '消息通知' }, React.createElement(NoticeIcon, null))
),
React.createElement('span', { style: { color: '#4e5969', cursor: 'pointer', display: 'flex' }, title: '设置' }, React.createElement(SettingIcon, null)),
React.createElement(Avatar, { size: 32, src: 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp', style: { cursor: 'pointer' } })
)
),
// 下方主体内容
React.createElement(Layout, { style: { paddingTop: 60, background: '#fff' } },
// 左侧菜单 Sider
React.createElement(Sider, {
width: 220,
style: {
background: '#fff',
borderRight: '1px solid #e5e6eb',
position: 'fixed',
top: 60,
left: 0,
height: 'calc(100vh - 60px)',
overflowY: 'auto',
zIndex: 99
}
},
React.createElement(Menu, {
mode: 'inline',
selectedKeys: [currentMenu],
defaultOpenKeys: ['crm'],
items: menuItems,
onClick: handleMenuClick,
style: { borderRight: 'none', padding: '8px', background: '#fff' }
})
),
// 右侧内容 Content
React.createElement(Content, { style: { marginLeft: 220, padding: '16px 20px 0 20px', minHeight: 'calc(100vh - 60px)', display: 'flex', flexDirection: 'column', background: '#fff' } },
React.createElement('div', { style: { padding: '16px 20px 0 20px', marginBottom: 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: '列表页' },
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '供应商管理') }
]
}),
React.createElement(Title, { level: 4, style: { marginTop: 16, marginBottom: 20, fontWeight: 700, color: '#1d2129', fontSize: 16 } }, '供应商管理')
),
React.createElement('div', { style: { padding: '0', display: 'flex', flexDirection: 'column', flex: 1, background: 'transparent' } },
// 搜索表单区域
React.createElement('div', { style: { padding: '0 20px 0 20px', marginBottom: 0, background: '#fff' } },
React.createElement(Row, { style: { flexWrap: 'nowrap' } },
React.createElement(Col, { flex: 1, style: { minWidth: 0, paddingRight: 40 } },
React.createElement(Form, Object.assign({ layout: 'horizontal' }, formItemLayout),
React.createElement(Row, { gutter: 24, style: { rowGap: 0 } },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '供应商名称', style: { marginBottom: 16, height: 32 } },
React.createElement(Input, { placeholder: '请输入供应商名称' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '类型', style: { marginBottom: 16, height: 32 } },
React.createElement(Select, {
mode: 'multiple',
allowClear: true,
maxTagCount: 'responsive',
placeholder: '请选择类型',
options: [
{ label: '整车企业', value: '整车企业' },
{ label: '车辆外租企业', value: '车辆外租企业' },
{ label: '加氢站', value: '加氢站' },
{ label: '充电站', value: '充电站' },
{ label: '维修站', value: '维修站' },
{ label: '备件供应商', value: '备件供应商' },
{ label: '保险公司', value: '保险公司' },
{ label: '救援车队', value: '救援车队' },
{ label: '其他', value: '其他' }
]
})
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '所属城市', style: { marginBottom: 16, height: 32 } },
React.createElement(Input, { placeholder: '请输入所属城市' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '业务部门', style: { marginBottom: 16, height: 32 } },
React.createElement(Input, { placeholder: '请输入部门名称' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '业务人员', style: { marginBottom: 16, height: 32 } },
React.createElement(Input, { placeholder: '请输入人员姓名' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '状态', style: { marginBottom: 16, height: 32 } },
React.createElement(Select, {
placeholder: '全部',
options: [
{ label: '全部', value: '' },
{ label: '正常', value: 'normal' },
{ label: '停用', value: 'disabled' }
]
})
)
)
)
)
),
React.createElement(Divider, { style: { height: 72, borderLeftColor: 'rgb(229, 230, 235)', borderLeftStyle: 'dashed', marginLeft: 20, marginRight: 20 }, type: 'vertical' }),
React.createElement(Col, { flex: '86px', style: { textAlign: 'right' } },
React.createElement(Space, { direction: 'vertical', size: 12 },
React.createElement(Button, { type: 'primary', icon: React.createElement(SearchIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center' } }, '查询'),
React.createElement(Button, { icon: React.createElement(ResetIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center' } }, '重置')
)
)
)
),
// 底部表格区
React.createElement('div', { style: { padding: '20px 20px 0 20px', display: 'flex', flexDirection: 'column', flex: 1, background: '#fff' } },
// 工具栏区域
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() { window.location.hash = '新建供应商'; } }, '新建'),
React.createElement(Button, null, '批量导入')
)
),
React.createElement(Col, null,
React.createElement(Space, { size: 16 },
React.createElement(Button, { style: { padding: '4px 10px', height: 32, display: 'flex', alignItems: 'center', gap: 6, color: '#4e5969' }, title: '下载' }, React.createElement(DownloadIcon, null), React.createElement('span', null, '下载'))
)
)
),
// 表格区域
React.createElement('div', { style: { flex: 1, minHeight: 0 } },
React.createElement(Table, {
rowSelection: { type: 'checkbox', columnWidth: 48 },
columns: columns,
dataSource: data,
pagination: { pageSize: 10, showTotal: function(total) { return '共 ' + total + ' 条'; } },
scroll: { x: 1000 }
})
)
)
)
)
)
);
};
if (typeof module !== 'undefined' && module.exports) module.exports = Component;

View File

@@ -0,0 +1,766 @@
// 【重要】必须使用 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仅含大写字母 AZ 与数字 09。
* - 结构:第 1 位 = 签约/归属子公司代码;第 27 位 = 6 位数字流水号000001999999不足左补 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-title14px / #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;

View File

@@ -0,0 +1,262 @@
// 【重要】必须使用 const Component 作为组件变量名
// ONEOS-web - CRM 客户管理-新增(高保真还原分组表单样式)
const Component = function () {
var antd = window.antd;
var Form = antd.Form;
var Input = antd.Input;
var Select = antd.Select;
var Button = antd.Button;
var Row = antd.Row;
var Col = antd.Col;
var Card = antd.Card;
var Layout = antd.Layout;
var Breadcrumb = antd.Breadcrumb;
var Cascader = antd.Cascader;
var Content = Layout.Content;
var _form = Form.useForm();
var form = _form[0];
/** 区域 — 省-市级联(示例数据) */
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: '苏州市' }
] },
{ value: 'gd', label: '广东省', children: [
{ value: 'gd-gz', label: '广州市' },
{ value: 'gd-sz', label: '深圳市' }
] }
];
/** 示例业务部门和负责人数据 */
var deptManagerMap = {
'销售一部': ['张伟', '王芳', '周杰', '陈静', '许晴'],
'销售二部': ['刘洋', '孙丽', '曹阳'],
'市场开拓部': ['吴磊', '赵敏', '韩雪'],
'大客户部': ['李强', '郑华', '冯涛']
};
var departmentOptions = Object.keys(deptManagerMap).map(function(dept) {
return { label: dept, value: dept };
});
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' } },
React.createElement('style', null, `
.arco-grouped-form-page { display: flex; flex-direction: column; min-height: 100vh; }
.arco-grouped-form-page-content { flex: 1; padding: 16px 20px 24px; }
.arco-grouped-form-page .ant-card { margin-bottom: 16px; border-radius: 4px; border: none; box-shadow: 0 1px 2px rgba(0,0,0,0.06); }
.arco-grouped-form-page .ant-card-head { border-bottom: none; padding: 20px 24px 0; min-height: auto; }
.arco-grouped-form-page .ant-card-head-title { font-size: 16px; font-weight: 500; color: #1d2129; padding: 0; }
.arco-grouped-form-page .ant-card-body { padding: 24px; }
/* 表单样式复刻 */
.arco-grouped-form-page .ant-form-vertical .ant-form-item-label { padding-bottom: 8px; }
.arco-grouped-form-page .ant-form-item-label > label { color: #4e5969; font-size: 14px; font-weight: 400; }
.arco-grouped-form-page .ant-form-item-label > label::after { display: none !important; }
.arco-grouped-form-page .ant-form-item { margin-bottom: 24px; }
/* 输入框和下拉框样式复刻 */
.arco-grouped-form-page .ant-input,
.arco-grouped-form-page .ant-select-selector { border-radius: 2px; border-color: #e5e6eb; height: 32px; transition: all 0.1s cubic-bezier(0, 0, 1, 1); box-shadow: none !important; }
.arco-grouped-form-page .ant-input:hover,
.arco-grouped-form-page .ant-select:not(.ant-select-disabled):hover .ant-select-selector { border-color: #165dff; }
.arco-grouped-form-page .ant-input:focus,
.arco-grouped-form-page .ant-input-focused,
.arco-grouped-form-page .ant-select-focused .ant-select-selector { border-color: #165dff; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; }
.arco-grouped-form-page .ant-select-selection-item,
.arco-grouped-form-page .ant-select-selection-placeholder { line-height: 30px !important; }
/* 后缀输入框样式复刻 */
.arco-grouped-form-page .ant-input-group-addon { background-color: #f2f3f5; border: 1px solid #e5e6eb; border-left: 0; border-radius: 0 2px 2px 0; color: #4e5969; padding: 0 12px; }
.arco-grouped-form-page .ant-input-wrapper { display: flex; align-items: stretch; }
.arco-grouped-form-page .ant-input-group > .ant-input:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: 0; }
.arco-grouped-form-page .ant-input-group > .ant-input:first-child:focus,
.arco-grouped-form-page .ant-input-group > .ant-input:first-child:hover { border-right: 1px solid #165dff; z-index: 1; }
/* 底部操作栏 */
.arco-grouped-form-footer { background: #fff; padding: 16px 24px; border-top: 1px solid #e5e6eb; display: flex; justify-content: flex-end; align-items: center; gap: 12px; position: sticky; bottom: 0; z-index: 100; box-shadow: 0 -2px 10px rgba(0,0,0,0.05); }
.arco-grouped-form-footer .ant-btn { border-radius: 5px; height: 32px; padding: 4px 16px; font-size: 14px; }
.arco-grouped-form-footer .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
.arco-grouped-form-footer .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
.arco-grouped-form-page .ant-breadcrumb { color: #86909c; font-size: 14px; margin-bottom: 16px; }
.arco-grouped-form-page .ant-breadcrumb a { color: #4e5969; }
.arco-grouped-form-page .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
/* 级联选择器下拉菜单宽度一致 (强行控制宽度和两列平分) */
.customer-full-width-cascader-popup { min-width: 100% !important; }
.customer-full-width-cascader-popup .ant-cascader-menu { width: 50%; min-width: 0; }
`),
React.createElement('div', { className: 'arco-grouped-form-page' },
React.createElement('div', { className: 'arco-grouped-form-page-content' },
// 面包屑导航
React.createElement(Breadcrumb, {
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
items: [
{ title: '首页' },
{ title: '业务管理' },
{ title: '客户管理' },
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '新增') }
]
}),
// 表单主体
React.createElement(Form, { form: form, layout: 'vertical' },
// 客户信息组
React.createElement(Card, { title: '客户信息', bordered: false },
React.createElement(Row, { gutter: 24 },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '客户类型', name: 'customerType', rules: [{ required: true, message: '请选择客户类型' }] },
React.createElement(Select, { placeholder: '请选择客户类型', options: [{ label: '企业', value: '企业' }, { label: '个人', value: '个人' }, { label: '事业单位', value: '事业单位' }] })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '客户分级', name: 'customerLevel' },
React.createElement(Select, { placeholder: '请选择客户分级', options: [{ label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' }] })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '客户全称', name: 'customerName', rules: [{ required: true, message: '请输入客户全称' }] },
React.createElement(Input, {
placeholder: '请输入客户全称',
onChange: function(e) {
form.setFieldsValue({ invoiceTitle: e.target.value });
}
})
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '客户简称', name: 'customerShortName' },
React.createElement(Input, { placeholder: '请输入客户简称' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '所属城市', name: 'city', rules: [{ required: true, message: '请选择所属城市' }] },
React.createElement(Cascader, {
options: regionOptions,
placeholder: '请选择客户所属城市',
style: { width: '100%' },
getPopupContainer: function (triggerNode) { return triggerNode.parentNode; },
popupClassName: 'customer-full-width-cascader-popup'
})
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '通讯地址', name: 'address' },
React.createElement(Input, { placeholder: '请输入通讯地址' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '业务负责部门', name: 'department', rules: [{ required: true, message: '请选择业务负责部门' }] },
React.createElement(Select, {
placeholder: '请选择业务负责部门',
options: departmentOptions,
onChange: function() { form.setFieldsValue({ manager: undefined }); }
})
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, {
noStyle: true,
shouldUpdate: function(prev, cur) { return prev.department !== cur.department; }
}, function() {
var curDept = form.getFieldValue('department');
var managerOptions = [];
if (curDept && deptManagerMap[curDept]) {
managerOptions = deptManagerMap[curDept].map(function(m) { return { label: m, value: m }; });
}
return React.createElement(Form.Item, { label: '业务负责人员', name: 'manager', rules: [{ required: true, message: '请选择业务负责人员' }] },
React.createElement(Select, {
placeholder: '请选择业务负责人员',
options: managerOptions,
disabled: !curDept
})
);
})
),
React.createElement(Col, { span: 24 },
React.createElement(Form.Item, { label: '备注', name: 'remark' },
React.createElement(Input.TextArea, { placeholder: '请输入备注', style: { height: 52, minHeight: 52, resize: 'none' } })
)
)
)
),
// 联系人信息组
React.createElement(Card, { title: '联系人信息', bordered: false },
React.createElement(Row, { gutter: 24 },
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: 'contactPosition' },
React.createElement(Input, { placeholder: '请输入职位' })
)
)
)
),
// 付款及开票信息组
React.createElement(Card, { title: '付款及开票信息', bordered: false },
React.createElement(Row, { gutter: 24 },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '发票抬头', name: 'invoiceTitle', rules: [{ required: true, message: '请先输入客户全称' }] },
React.createElement(Input, { placeholder: '自动带入客户全称', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '纳税人识别号', name: 'taxId', rules: [{ required: true, message: '请输入纳税人识别号' }] },
React.createElement(Input, { placeholder: '请输入纳税人识别号' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '注册地址', name: 'regAddress' },
React.createElement(Input, { placeholder: '请输入注册地址' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '注册电话', name: 'regPhone' },
React.createElement(Input, { placeholder: '请输入注册电话' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '开户银行', name: 'bankName', rules: [{ required: true, message: '请输入开户银行' }] },
React.createElement(Input, { placeholder: '请输入开户银行' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '账号', name: 'bankAccount' },
React.createElement(Input, { placeholder: '请输入账号' })
)
)
)
)
)
),
// 底部操作栏
React.createElement('div', { className: 'arco-grouped-form-footer' },
React.createElement(Button, { onClick: function () { form.resetFields(); } }, '重置'),
React.createElement(Button, { type: 'primary', onClick: function () { form.submit(); } }, '提交')
)
)
);
};
if (typeof module !== 'undefined' && module.exports) module.exports = Component;

View File

@@ -0,0 +1,348 @@
// 【重要】必须使用 const Component 作为组件变量名
// ONEOS-web 示例项目 - CRM 新建供应商 (完美复刻 Arco Design Pro 分组表单)
const Component = function () {
var useState = React.useState;
var antd = window.antd;
var Button = antd.Button;
var Space = antd.Space;
var Input = antd.Input;
var Select = antd.Select;
var Cascader = antd.Cascader;
var Form = antd.Form;
var Row = antd.Row;
var Col = antd.Col;
var Breadcrumb = antd.Breadcrumb;
var Menu = antd.Menu;
var Layout = antd.Layout;
var message = antd.message;
var Typography = antd.Typography;
var Avatar = antd.Avatar;
var Badge = antd.Badge;
var Card = antd.Card;
var Header = Layout.Header;
var Content = Layout.Content;
var Sider = Layout.Sider;
var Title = Typography.Title;
var _currentMenu = useState('crm-supplier');
var currentMenu = _currentMenu[0];
var setCurrentMenu = _currentMenu[1];
var handleMenuClick = function (e) {
setCurrentMenu(e.key);
if (e.key === 'contract-list') {
message.info('跳转至 合同列表');
window.location.hash = '合同列表';
} else if (e.key === 'erp-order') {
message.info('跳转至 ERP 订单管理');
window.location.hash = '订单管理';
} else if (e.key === 'asset-overview') {
message.info('跳转至 资产概览');
window.location.hash = '资产概览';
} else if (e.key === 'crm-list') {
message.info('跳转至 客户列表');
window.location.hash = '客户列表';
} else if (e.key === 'crm-supplier') {
message.info('跳转至 供应商管理');
window.location.hash = '供应商管理';
}
};
// 自定义 SVG 图标(高保真还原 Arco 风格)
var SettingIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 16, height: 16, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M18.797 6.732A1 1 0 0 1 19.76 6h8.48a1 1 0 0 1 .964.732l1.285 4.628a1 1 0 0 0 1.213.7l4.651-1.2a1 1 0 0 1 1.116.468l4.24 7.344a1 1 0 0 1-.153 1.2L38.193 23.3a1 1 0 0 0 0 1.402l3.364 3.427a1 1 0 0 1 .153 1.2l-4.24 7.344a1 1 0 0 1-1.116.468l-4.65-1.2a1 1 0 0 0-1.214.7l-1.285 4.628a1 1 0 0 1-.964.732h-8.48a1 1 0 0 1-.963-.732L17.51 36.64a1 1 0 0 0-1.213-.7l-4.65 1.2a1 1 0 0 1-1.116-.468l-4.24-7.344a1 1 0 0 1 .153-1.2L9.809 24.7a1 1 0 0 0 0-1.402l-3.364-3.427a1 1 0 0 1-.153-1.2l4.24-7.344a1 1 0 0 1 1.116-.468l4.65 1.2a1 1 0 0 0 1.213-.7l1.286-4.628Z' }), React.createElement('path', { d: 'M30 24a6 6 0 1 1-12 0 6 6 0 0 1 12 0Z' })); };
var NoticeIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 18, height: 18, fill: 'none', stroke: 'currentColor', strokeWidth: 4 }, React.createElement('path', { d: 'M39 34h3v4H6v-4h3V20.218a15 15 0 0 1 30 0V34ZM24 44a6 6 0 0 1-6-6h12a6 6 0 0 1-6 6Z' })); };
var FormIcon = 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: 'M18.797 6.732A1 1 0 0 1 19.76 6h8.48a1 1 0 0 1 .964.732l1.285 4.628a1 1 0 0 0 1.213.7l4.651-1.2a1 1 0 0 1 1.116.468l4.24 7.344a1 1 0 0 1-.153 1.2L38.193 23.3a1 1 0 0 0 0 1.402l3.364 3.427a1 1 0 0 1 .153 1.2l-4.24 7.344a1 1 0 0 1-1.116.468l-4.65-1.2a1 1 0 0 0-1.214.7l-1.285 4.628a1 1 0 0 1-.964.732h-8.48a1 1 0 0 1-.963-.732L17.51 36.64a1 1 0 0 0-1.213-.7l-4.65 1.2a1 1 0 0 1-1.116-.468l-4.24-7.344a1 1 0 0 1 .153-1.2L9.809 24.7a1 1 0 0 0 0-1.402l-3.364-3.427a1 1 0 0 1-.153-1.2l4.24-7.344a1 1 0 0 1 1.116-.468l4.65 1.2a1 1 0 0 0 1.213-.7l1.286-4.628Z' }), React.createElement('path', { d: 'M30 24a6 6 0 1 1-12 0 6 6 0 0 1 12 0Z' })); };
var menuItems = [
{
key: 'contract',
label: '合同管理',
icon: React.createElement('span', { className: 'anticon' }, '📄'),
children: [
{ key: 'contract-list', label: '合同列表' }
]
},
{
key: 'crm',
label: 'CRM 管理',
icon: React.createElement('span', { className: 'anticon' }, '👥'),
children: [
{ key: 'crm-list', label: '客户列表' },
{ key: 'crm-supplier', label: '供应商管理' },
{ key: 'crm-analysis', label: 'CRM 分析' }
]
},
{
key: 'erp',
label: 'ERP 订单管理',
icon: React.createElement('span', { className: 'anticon' }, '📦'),
children: [
{ key: 'erp-order', label: '订单管理' }
]
},
{
key: 'asset',
label: '资产管理',
icon: React.createElement('span', { className: 'anticon' }, '🚗'),
children: [
{ key: 'asset-overview', label: '资产概览' }
]
}
];
// 供应商类型下拉选项
var supplierTypeOptions = [
{ label: '整车企业', value: '整车企业' },
{ label: '车辆外租企业', value: '车辆外租企业' },
{ label: '加氢站', value: '加氢站' },
{ label: '充电站', value: '充电站' },
{ label: '维修站', value: '维修站' },
{ label: '备件供应商', value: '备件供应商' },
{ label: '保险公司', value: '保险公司' },
{ label: '救援车队', value: '救援车队' },
{ label: '其他', value: '其他' }
];
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; box-shadow: none; font-size: 14px; }
.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-default { background-color: #f2f3f5; border-color: transparent; color: #4e5969; }
.arco-theme-overrides .ant-btn-default:hover { background-color: #e5e6eb; border-color: transparent; color: #4e5969; }
.arco-theme-overrides .ant-menu-light .ant-menu-item-selected { background-color: #f2f9fe; color: #165dff; }
.arco-theme-overrides .ant-menu-light .ant-menu-item-selected::after { border-right-color: #165dff; }
/* 输入组件默认、Hover、Focus样式复刻 */
.arco-theme-overrides .ant-input, .arco-theme-overrides .ant-select-selector, .arco-theme-overrides .ant-cascader { border-radius: 2px; border: 1px solid #e5e6eb; background-color: #f2f3f5; 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-cascader:hover { background-color: #e5e6eb; border-color: transparent; }
.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-cascader-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-form-vertical .ant-form-item-label { padding: 0 0 8px; line-height: 1.5715; }
.arco-theme-overrides .ant-form-vertical .ant-form-item-label > label { color: #1d2129; font-weight: 400; height: auto; }
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
.arco-theme-overrides .ant-form-item { margin-bottom: 24px; }
/* 卡片样式复刻 */
.arco-theme-overrides .ant-card { border: none; border-radius: 4px; margin-bottom: 16px; background: transparent; }
.arco-theme-overrides .ant-card-body { padding: 20px 20px 0 20px; background: #fff; }
/* 标题样式复刻 */
.arco-theme-overrides .arco-section-title { font-size: 16px; font-weight: 500; color: #1d2129; margin-bottom: 20px; }
/* 输入框高度统一 */
.arco-theme-overrides .ant-input, .arco-theme-overrides .ant-select-selector, .arco-theme-overrides .ant-cascader .ant-select-selector { height: 32px !important; min-height: 32px !important; display: flex; align-items: center; padding: 0 12px; }
.arco-theme-overrides .ant-input { padding: 4px 12px; }
.arco-theme-overrides .ant-select-selection-item { line-height: 30px !important; }
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; }
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
`),
// 顶部 Header
React.createElement(Header, {
style: {
background: '#fff',
padding: '0 20px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
borderBottom: '1px solid #e5e6eb',
height: 60,
position: 'fixed',
top: 0,
left: 0,
right: 0,
zIndex: 100
}
},
// 左侧 Logo
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 12 } },
React.createElement('div', { style: { width: 32, height: 32, background: '#165dff', borderRadius: 4, display: 'flex', justifyContent: 'center', alignItems: 'center', color: '#fff', fontWeight: 'bold' } }, 'A'),
React.createElement('div', { style: { fontSize: '20px', fontWeight: '600', color: '#1d2129', letterSpacing: '0.5px' } }, 'Arco Pro')
),
// 右侧工具栏
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 20 } },
React.createElement(Input.Search, { placeholder: '搜索功能', style: { width: 220, borderRadius: 16 } }),
React.createElement(Badge, { dot: true, offset: [-2, 4] },
React.createElement('span', { style: { color: '#4e5969', cursor: 'pointer', display: 'flex' }, title: '消息通知' }, React.createElement(NoticeIcon, null))
),
React.createElement('span', { style: { color: '#4e5969', cursor: 'pointer', display: 'flex' }, title: '设置' }, React.createElement(SettingIcon, null)),
React.createElement(Avatar, { size: 32, src: 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp', style: { cursor: 'pointer' } })
)
),
// 下方主体内容
React.createElement(Layout, { style: { paddingTop: 60 } },
// 左侧菜单 Sider
React.createElement(Sider, {
width: 220,
style: {
background: '#fff',
borderRight: '1px solid #e5e6eb',
position: 'fixed',
top: 60,
left: 0,
height: 'calc(100vh - 60px)',
overflowY: 'auto',
zIndex: 99
}
},
React.createElement(Menu, {
mode: 'inline',
selectedKeys: [currentMenu],
defaultOpenKeys: ['crm'],
items: menuItems,
onClick: handleMenuClick,
style: { borderRight: 'none', padding: '8px', background: '#fff' }
})
),
// 右侧内容 Content
React.createElement(Content, { style: { marginLeft: 220, padding: '16px 20px 60px 20px', minHeight: 'calc(100vh - 60px)', display: 'flex', flexDirection: 'column' } },
React.createElement('div', { style: { padding: '16px 20px 0 20px', marginBottom: 0, background: '#fff' } },
React.createElement(Breadcrumb, {
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
items: [
{ title: React.createElement(FormIcon, { style: { display: 'inline-flex', alignItems: 'center', fontSize: 14, transform: 'translate(-2px, 1px)' } }) },
{ title: '表单页' },
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '分组表单') }
]
}),
React.createElement(Title, { level: 4, style: { marginTop: 16, marginBottom: 20, fontWeight: 700, color: '#1d2129', fontSize: 16 } }, '新建供应商')
),
React.createElement('div', { style: { padding: '0', display: 'flex', flexDirection: 'column', flex: 1 } },
React.createElement(Form, { layout: 'vertical' },
// 供应商信息分组
React.createElement(Card, { bordered: false, bodyStyle: { padding: '20px 20px 0 20px' } },
React.createElement('div', { className: 'arco-section-title' }, '供应商信息'),
React.createElement(Row, { gutter: 24 },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '供应商名称', required: true },
React.createElement(Input, { placeholder: '请输入供应商名称' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '类型', required: true },
React.createElement(Select, { placeholder: '请选择类型', options: supplierTypeOptions })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '所属城市' },
React.createElement(Cascader, { placeholder: '请选择省-市', options: [{ value: 'zhejiang', label: '浙江', children: [{ value: 'hangzhou', label: '杭州' }, { value: 'ningbo', label: '宁波' }] }, { value: 'jiangsu', label: '江苏', children: [{ value: 'nanjing', label: '南京' }] }] })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '所在地址' },
React.createElement(Input, { placeholder: '请输入所在地址' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '区域' },
React.createElement(Input, { placeholder: '请输入区域' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '业务负责部门' },
React.createElement(Input, { placeholder: '请输入业务负责部门' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '业务负责人员' },
React.createElement(Input, { placeholder: '请输入业务负责人员' })
)
),
React.createElement(Col, { span: 24 },
React.createElement(Form.Item, { label: '备注' },
React.createElement(Input.TextArea, { placeholder: '请输入备注', autoSize: { minRows: 3, maxRows: 5 }, style: { height: 'auto', minHeight: 'auto' } })
)
)
)
),
// 联系人信息分组
React.createElement(Card, { bordered: false, bodyStyle: { padding: '20px 20px 0 20px' } },
React.createElement('div', { className: 'arco-section-title' }, '联系人信息'),
React.createElement(Row, { gutter: 24 },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '姓名' },
React.createElement(Input, { placeholder: '请输入姓名' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '手机号' },
React.createElement(Input, { placeholder: '请输入手机号' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '职位' },
React.createElement(Input, { placeholder: '请输入职位' })
)
)
)
),
// 付款及开票信息分组
React.createElement(Card, { bordered: false, bodyStyle: { padding: '20px 20px 0 20px', marginBottom: 16 } },
React.createElement('div', { className: 'arco-section-title' }, '付款及开票信息'),
React.createElement(Row, { gutter: 24 },
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '纳税人识别号' },
React.createElement(Input, { placeholder: '请输入纳税人识别号' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '注册地址' },
React.createElement(Input, { placeholder: '请输入注册地址' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '注册电话' },
React.createElement(Input, { placeholder: '请输入注册电话' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '开户行' },
React.createElement(Input, { placeholder: '请输入开户行' })
)
),
React.createElement(Col, { span: 8 },
React.createElement(Form.Item, { label: '账号' },
React.createElement(Input, { placeholder: '请输入账号' })
)
)
)
)
)
)
)
),
// 底部固定操作栏
React.createElement('div', {
style: {
position: 'fixed',
bottom: 0,
right: 0,
width: 'calc(100% - 220px)',
padding: '16px 20px',
background: '#fff',
borderTop: '1px solid #e5e6eb',
textAlign: 'right',
zIndex: 100
}
},
React.createElement(Space, { size: 16 },
React.createElement(Button, { size: 'large', onClick: function() { message.info('重置成功'); } }, '重置'),
React.createElement(Button, { type: 'primary', size: 'large', onClick: function() { message.success('提交成功'); } }, '提交')
)
)
);
};
if (typeof module !== 'undefined' && module.exports) module.exports = Component;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
// 【重要】必须使用 const Component 作为组件变量名
// ONEOS-web 示例项目 - ERP 订单管理
const Component = function () {
var useState = React.useState;
var antd = window.antd;
var Table = antd.Table;
var Button = antd.Button;
var Card = antd.Card;
var Space = antd.Space;
var Input = antd.Input;
var Breadcrumb = antd.Breadcrumb;
var Menu = antd.Menu;
var Layout = antd.Layout;
var message = antd.message;
var Tag = antd.Tag;
var Header = Layout.Header;
var Content = Layout.Content;
var _currentMenu = useState('erp');
var currentMenu = _currentMenu[0];
var setCurrentMenu = _currentMenu[1];
var handleMenuClick = function (e) {
setCurrentMenu(e.key);
if (e.key === 'contract') {
message.info('跳转至 合同列表');
window.location.hash = '合同列表';
} else if (e.key === 'crm') {
message.info('跳转至 CRM 客户管理');
window.location.hash = '客户列表';
} else if (e.key === 'asset') {
message.info('跳转至 资产概览');
window.location.hash = '资产概览';
}
};
var columns = [
{ title: '订单编号', dataIndex: 'orderNo', key: 'orderNo' },
{ title: '关联客户', dataIndex: 'customer', key: 'customer' },
{ title: '产品/服务', dataIndex: 'product', key: 'product' },
{ title: '数量', dataIndex: 'quantity', key: 'quantity' },
{ title: '总金额(元)', dataIndex: 'amount', key: 'amount' },
{ title: '状态', dataIndex: 'status', key: 'status', render: function(text) {
var color = text === '已发货' ? 'blue' : text === '已完成' ? 'green' : 'orange';
return React.createElement(Tag, { color: color }, text);
} },
{
title: '操作',
key: 'action',
render: function (_, record) {
return React.createElement(Space, null,
React.createElement(Button, { type: 'link', size: 'small', onClick: function() { message.info('查看订单: ' + record.orderNo); } }, '详情'),
React.createElement(Button, { type: 'link', size: 'small', onClick: function() { message.success('更新发货状态'); } }, '更新状态')
);
}
}
];
var data = [
{ key: '1', orderNo: 'ORD-20260401', customer: '嘉兴某物流公司', product: '氢能重卡租赁(月)', quantity: 5, amount: '150,000.00', status: '待发货' },
{ key: '2', orderNo: 'ORD-20260405', customer: '上海某科技公司', product: '氢燃料补给服务', quantity: 1, amount: '12,000.00', status: '已完成' },
{ key: '3', orderNo: 'ORD-20260410', customer: '杭州某实业公司', product: '氢能轻卡租赁(年)', quantity: 2, amount: '240,000.00', status: '已发货' }
];
var layoutStyle = { minHeight: '100vh', background: '#f5f5f5' };
var headerStyle = { background: '#fff', padding: '0 24px', display: 'flex', alignItems: 'center', boxShadow: '0 2px 8px rgba(0,0,0,0.06)', zIndex: 1 };
var logoStyle = { fontSize: '20px', fontWeight: 'bold', color: '#1677ff', marginRight: '48px' };
var menuItems = [
{ key: 'contract', label: '合同管理' },
{ key: 'crm', label: 'CRM 客户管理' },
{ key: 'erp', label: 'ERP 订单管理' },
{ key: 'asset', label: '资产管理' }
];
return React.createElement(Layout, { style: layoutStyle },
React.createElement(Header, { style: headerStyle },
React.createElement('div', { style: logoStyle }, 'ONEOS 运管平台'),
React.createElement(Menu, { mode: 'horizontal', selectedKeys: [currentMenu], items: menuItems, onClick: handleMenuClick, style: { flex: 1, borderBottom: 'none' } })
),
React.createElement(Content, { style: { padding: '24px 48px' } },
React.createElement(Breadcrumb, { style: { marginBottom: '16px' }, items: [{ title: '系统应用' }, { title: 'ERP' }, { title: '订单管理' }] }),
React.createElement(Card, { title: '业务订单', style: { borderRadius: '8px' } },
React.createElement('div', { style: { marginBottom: 16, display: 'flex', gap: 16 } },
React.createElement(Input, { placeholder: '输入订单编号搜索', style: { width: 200 } }),
React.createElement(Button, { type: 'primary' }, '查询'),
React.createElement('div', { style: { flex: 1 } }),
React.createElement(Button, { type: 'primary', onClick: function() { message.info('新建订单(打开抽屉)'); } }, '新建订单')
),
React.createElement(Table, { columns: columns, dataSource: data, pagination: { pageSize: 10 } })
)
)
);
};
if (typeof module !== 'undefined' && module.exports) module.exports = Component;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,668 @@
// 【重要】必须使用 const Component 作为组件变量名
// ONEOS-web - 加氢站数字孪生监控大屏1920×1080 设计稿级布局,高对比科技风)
const Component = function () {
var useState = React.useState;
var useEffect = React.useEffect;
var _now = useState(function () { return new Date(); });
var now = _now[0];
var setNow = _now[1];
useEffect(function () {
var t = setInterval(function () { setNow(new Date()); }, 1000);
return function () { clearInterval(t); };
}, []);
var pad = function (n) { return n < 10 ? '0' + n : '' + n; };
var timeStr = now.getFullYear() + '-' + pad(now.getMonth() + 1) + '-' + pad(now.getDate()) + ' ' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
var h2PanelTitle = {
margin: 0,
fontSize: 15,
fontWeight: 600,
letterSpacing: '0.06em',
color: '#e8f4ff',
textShadow: '0 0 12px rgba(0, 242, 255, 0.35)',
display: 'flex',
alignItems: 'center',
gap: 8
};
var panelShell = {
background: 'linear-gradient(145deg, rgba(6, 28, 58, 0.88) 0%, rgba(4, 15, 35, 0.92) 100%)',
border: '1px solid rgba(0, 242, 255, 0.22)',
borderRadius: 4,
boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.04), 0 8px 32px rgba(0,0,0,0.45)',
backdropFilter: 'blur(8px)',
overflow: 'hidden',
position: 'relative'
};
var panelHead = {
height: 40,
padding: '0 14px',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
background: 'linear-gradient(90deg, rgba(0, 242, 255, 0.12) 0%, transparent 55%)',
borderBottom: '1px solid rgba(0, 242, 255, 0.15)'
};
var kpiCard = function (label, value, unit, sub) {
return React.createElement('div', {
key: label,
style: {
flex: 1,
minWidth: 0,
padding: '12px 16px',
background: 'linear-gradient(180deg, rgba(10, 40, 72, 0.75) 0%, rgba(4, 18, 40, 0.85) 100%)',
border: '1px solid rgba(0, 242, 255, 0.2)',
borderRadius: 4,
position: 'relative',
overflow: 'hidden'
}
},
React.createElement('div', { style: { position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 80% 50% at 0% 0%, rgba(0,242,255,0.12), transparent 55%)', pointerEvents: 'none' } }),
React.createElement('div', { style: { fontSize: 12, color: '#7a9bb8', marginBottom: 6, letterSpacing: '0.04em' } }, label),
React.createElement('div', { style: { display: 'flex', alignItems: 'baseline', gap: 6 } },
React.createElement('span', { style: { fontSize: 26, fontWeight: 700, color: '#00f2ff', fontFamily: '"DIN Alternate", "Roboto Mono", monospace', textShadow: '0 0 20px rgba(0,242,255,0.45)' } }, value),
React.createElement('span', { style: { fontSize: 12, color: '#5a8aad' } }, unit)
),
sub && React.createElement('div', { style: { marginTop: 6, fontSize: 11, color: '#4a7a9c' } }, sub)
);
};
var navItem = function (label, active) {
return React.createElement('div', {
key: label,
style: {
padding: '6px 14px',
fontSize: 12,
color: active ? '#00f2ff' : '#6a8faf',
border: active ? '1px solid rgba(0,242,255,0.5)' : '1px solid transparent',
borderRadius: 2,
background: active ? 'rgba(0,242,255,0.08)' : 'transparent',
cursor: 'pointer',
letterSpacing: '0.05em',
whiteSpace: 'nowrap'
}
}, label);
};
var subNavBtn = function (label, icon) {
return React.createElement('div', {
key: label,
style: {
width: 72,
height: 64,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 6,
background: 'linear-gradient(180deg, rgba(0,40,80,0.5) 0%, rgba(4,20,45,0.8) 100%)',
border: '1px solid rgba(0, 242, 255, 0.18)',
borderRadius: 4,
fontSize: 11,
color: '#9ec8e8',
cursor: 'pointer'
}
},
React.createElement('div', { style: { width: 28, height: 28, borderRadius: 4, border: '1px solid rgba(0,242,255,0.35)', background: 'rgba(0,242,255,0.06)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, color: '#00f2ff' } }, icon),
label
);
};
var alarmRows = [
{ t: '10:28:06', lv: '紧急', name: '压缩机出口压力超限', loc: '压缩单元-A' },
{ t: '10:15:42', lv: '一般', name: '储罐液位波动提醒', loc: '储氢区-3#' },
{ t: '09:52:11', lv: '重要', name: '加氢枪通讯短时中断', loc: '加氢岛-2' }
];
return React.createElement('div', {
className: 'h2-station-screen-root',
style: {
width: 1920,
height: 1080,
margin: '0 auto',
position: 'relative',
background: '#040b1a',
color: '#e8f4ff',
fontFamily: '"Inter", "PingFang SC", "Microsoft YaHei", sans-serif',
overflow: 'hidden',
boxSizing: 'border-box',
textRendering: 'geometricPrecision',
WebkitFontSmoothing: 'antialiased'
}
},
React.createElement('style', null, `
.h2-station-screen-root * { box-sizing: border-box; }
@keyframes h2-pulse-border {
0%, 100% { box-shadow: 0 0 0 1px rgba(0,242,255,0.15), 0 0 24px rgba(0,242,255,0.08); }
50% { box-shadow: 0 0 0 1px rgba(0,242,255,0.35), 0 0 36px rgba(0,242,255,0.15); }
}
.h2-station-screen-root .h2-center-stage {
animation: h2-pulse-border 4s ease-in-out infinite;
}
@keyframes h2-scan {
0% { transform: translateY(-100%); opacity: 0; }
10% { opacity: 0.06; }
90% { opacity: 0.06; }
100% { transform: translateY(100%); opacity: 0; }
}
.h2-station-screen-root .h2-scanline::after {
content: '';
position: absolute;
left: 0; right: 0; top: 0;
height: 120px;
background: linear-gradient(180deg, transparent, rgba(0,242,255,0.04), transparent);
animation: h2-scan 8s linear infinite;
pointer-events: none;
}
`),
/* 背景网格与光晕 */
React.createElement('div', {
style: {
position: 'absolute',
inset: 0,
backgroundImage: `
linear-gradient(rgba(0, 242, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 242, 255, 0.03) 1px, transparent 1px)
`,
backgroundSize: '48px 48px',
pointerEvents: 'none'
}
}),
React.createElement('div', {
style: {
position: 'absolute',
width: 900,
height: 900,
left: '50%',
top: '42%',
transform: 'translate(-50%, -50%)',
background: 'radial-gradient(circle, rgba(22, 93, 255, 0.12) 0%, transparent 65%)',
pointerEvents: 'none'
}
}),
/* 顶栏 */
React.createElement('header', {
style: {
position: 'absolute',
left: 24,
right: 24,
top: 16,
height: 56,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
zIndex: 20
}
},
React.createElement('div', { style: { fontSize: 13, color: '#7a9bb8', letterSpacing: '0.02em' } },
timeStr, React.createElement('span', { style: { margin: '0 12px', color: 'rgba(0,242,255,0.35)' } }, '|'),
'24°C 晴', React.createElement('span', { style: { margin: '0 12px', color: 'rgba(0,242,255,0.35)' } }, '|'),
'空气质量:优'
),
React.createElement('div', {
style: {
fontSize: 28,
fontWeight: 700,
letterSpacing: '0.12em',
color: '#f0f8ff',
textShadow: '0 0 24px rgba(0, 242, 255, 0.55), 0 0 60px rgba(22, 93, 255, 0.35)'
}
}, '加氢站数字孪生监控平台'),
React.createElement('div', { style: { display: 'flex', gap: 8 } },
['首页', '三维监控', '设备管理', '告警管理', '运营报表', '系统设置'].map(function (x, i) {
return React.createElement('div', {
key: x,
style: {
padding: '6px 10px',
fontSize: 12,
color: i === 1 ? '#00f2ff' : '#6a8faf',
borderBottom: i === 1 ? '2px solid #00f2ff' : '2px solid transparent'
}
}, x);
})
)
),
/* KPI 行 */
React.createElement('div', {
style: {
position: 'absolute',
left: 24,
right: 24,
top: 84,
display: 'flex',
gap: 12,
zIndex: 15
}
},
kpiCard('氢气最高压力', '35.0', 'MPa', '设计上限 45 MPa'),
kpiCard('氢气平均温度', '22.5', '°C', '管束区均值'),
kpiCard('储罐液位', '85', '%', '5 座储罐加权'),
kpiCard('瞬时流量', '120', 'Nm³/h', '加氢岛合计'),
kpiCard('H₂ 浓度', '0', 'ppm', '站区环测'),
kpiCard('安全等级', '一级', '', '连续安全运行 337 天')
),
/* 左列 */
React.createElement('aside', {
style: {
position: 'absolute',
left: 24,
top: 168,
width: 400,
bottom: 200,
display: 'flex',
flexDirection: 'column',
gap: 10,
zIndex: 12
}
},
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 auto' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '站点概况')
),
React.createElement('div', { style: { padding: '14px 16px', fontSize: 12, lineHeight: 2, color: '#9ec8e8' } },
React.createElement('div', null, '投运日期:', React.createElement('span', { style: { color: '#00f2ff' } }, '2023-06-18')),
React.createElement('div', null, '接入设备:', React.createElement('span', { style: { color: '#00f2ff' } }, '28'), ' 台'),
React.createElement('div', null, '累计加氢量:', React.createElement('span', { style: { color: '#00f2ff' } }, '385,621'), ' kg'),
React.createElement('div', null, '安全运行:', React.createElement('span', { style: { color: '#00f2ff' } }, '337'), ' 天')
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '1 1 0', minHeight: 0 }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '加氢量统计'),
React.createElement('div', { style: { display: 'flex', gap: 4 } }, navItem('日', true), navItem('月', false), navItem('年', false))
),
React.createElement('div', { style: { padding: '8px 12px 4px', fontSize: 11, color: '#5a8aad' } }, '较昨日 ', React.createElement('span', { style: { color: '#52c41a' } }, '+12.5%')),
React.createElement('div', { style: { padding: '0 8px 8px', height: 140 } },
React.createElement('svg', { width: '100%', height: '100%', viewBox: '0 0 360 120', preserveAspectRatio: 'none' },
React.createElement('defs', null,
React.createElement('linearGradient', { id: 'h2lg1', x1: '0', y1: '0', x2: '0', y2: '1' },
React.createElement('stop', { offset: '0%', stopColor: 'rgba(0,242,255,0.45)' }),
React.createElement('stop', { offset: '100%', stopColor: 'rgba(0,242,255,0)' })
)
),
React.createElement('polyline', { fill: 'none', stroke: 'rgba(0,242,255,0.35)', strokeWidth: '1', points: '0,100 360,100' }),
React.createElement('polygon', { fill: 'url(#h2lg1)', points: '0,100 0,70 40,55 80,62 120,40 160,48 200,35 240,50 280,38 320,45 360,30 360,100' }),
React.createElement('polyline', { fill: 'none', stroke: '#00f2ff', strokeWidth: '2', points: '0,70 40,55 80,62 120,40 160,48 200,35 240,50 280,38 320,45 360,30' })
)
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 160px' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '设备状态统计')
),
React.createElement('div', { style: { display: 'flex', alignItems: 'center', padding: '8px 16px', gap: 16 } },
React.createElement('svg', { width: 100, height: 100, viewBox: '0 0 100 100' },
React.createElement('circle', { cx: 50, cy: 50, r: 38, fill: 'none', stroke: 'rgba(0,242,255,0.15)', strokeWidth: 10 }),
React.createElement('circle', { cx: 50, cy: 50, r: 38, fill: 'none', stroke: '#00f2ff', strokeWidth: 10, strokeDasharray: '80 159', strokeLinecap: 'round', transform: 'rotate(-90 50 50)' }),
React.createElement('circle', { cx: 50, cy: 50, r: 38, fill: 'none', stroke: '#165dff', strokeWidth: 10, strokeDasharray: '50 159', strokeDashoffset: -80, strokeLinecap: 'round', transform: 'rotate(-90 50 50)' }),
React.createElement('text', { x: 50, y: 54, textAnchor: 'middle', fill: '#e8f4ff', fontSize: 14, fontWeight: 700 }, '28')
),
React.createElement('div', { style: { fontSize: 11, lineHeight: 1.8, color: '#7a9bb8' } },
React.createElement('div', null, React.createElement('span', { style: { color: '#00f2ff' } }, '●'), ' 运行 22'),
React.createElement('div', null, React.createElement('span', { style: { color: '#165dff' } }, '●'), ' 待机 4'),
React.createElement('div', null, React.createElement('span', { style: { color: '#faad14' } }, '●'), ' 维护 2')
)
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 140px' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '能耗统计'),
React.createElement('div', { style: { display: 'flex', gap: 4 } }, navItem('时', true), navItem('日', false))
),
React.createElement('div', { style: { padding: '12px 16px', display: 'flex', alignItems: 'flex-end', gap: 6, height: 88 } },
[40, 65, 55, 80, 48, 72, 60, 90, 52, 68, 75, 58].map(function (h, i) {
return React.createElement('div', {
key: i,
style: {
flex: 1,
height: h + '%',
background: 'linear-gradient(180deg, #00f2ff 0%, rgba(22,93,255,0.4) 100%)',
borderRadius: 2,
opacity: 0.85
}
});
})
)
)
),
/* 右列 */
React.createElement('aside', {
style: {
position: 'absolute',
right: 24,
top: 168,
width: 400,
bottom: 200,
display: 'flex',
flexDirection: 'column',
gap: 10,
zIndex: 12
}
},
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 200px' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#ff4d4f', borderRadius: 1 } }), '实时报警')
),
React.createElement('div', { style: { display: 'flex', gap: 8, padding: '8px 12px', fontSize: 11 } },
React.createElement('span', { style: { color: '#ff4d4f' } }, '紧急 1'),
React.createElement('span', { style: { color: '#faad14' } }, '重要 1'),
React.createElement('span', { style: { color: '#52c41a' } }, '一般 1')
),
React.createElement('div', { style: { padding: '0 8px 8px', overflow: 'auto', maxHeight: 120 } },
React.createElement('table', { style: { width: '100%', fontSize: 11, borderCollapse: 'collapse', color: '#9ec8e8' } },
React.createElement('thead', null,
React.createElement('tr', { style: { color: '#5a8aad' } },
React.createElement('th', { style: { textAlign: 'left', padding: '4px 4px', borderBottom: '1px solid rgba(0,242,255,0.12)' } }, '时间'),
React.createElement('th', { style: { textAlign: 'left', padding: '4px 4px', borderBottom: '1px solid rgba(0,242,255,0.12)' } }, '级别'),
React.createElement('th', { style: { textAlign: 'left', padding: '4px 4px', borderBottom: '1px solid rgba(0,242,255,0.12)' } }, '事件')
)
),
React.createElement('tbody', null,
alarmRows.map(function (r) {
return React.createElement('tr', { key: r.t },
React.createElement('td', { style: { padding: '6px 4px', borderBottom: '1px solid rgba(255,255,255,0.04)' } }, r.t),
React.createElement('td', { style: { padding: '6px 4px', borderBottom: '1px solid rgba(255,255,255,0.04)', color: r.lv === '紧急' ? '#ff4d4f' : r.lv === '重要' ? '#faad14' : '#52c41a' } }, r.lv),
React.createElement('td', { style: { padding: '6px 4px', borderBottom: '1px solid rgba(255,255,255,0.04)' } }, r.name)
);
})
)
)
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 160px' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '储氢系统监控')
),
React.createElement('div', { style: { padding: '12px 16px', display: 'flex', gap: 10, alignItems: 'flex-end' } },
[88, 92, 76, 85, 79].map(function (pct, i) {
return React.createElement('div', { key: i, style: { flex: 1, textAlign: 'center' } },
React.createElement('div', { style: { height: 72, background: 'rgba(0,30,60,0.6)', borderRadius: 2, position: 'relative', border: '1px solid rgba(0,242,255,0.15)' } },
React.createElement('div', { style: { position: 'absolute', bottom: 0, left: 2, right: 2, height: pct + '%', background: 'linear-gradient(180deg, #00f2ff, #165dff)', borderRadius: '0 0 2px 2px' } })
),
React.createElement('div', { style: { fontSize: 10, marginTop: 4, color: '#6a8faf' } }, (i + 1) + '#')
);
})
),
React.createElement('div', { style: { padding: '0 16px 10px', fontSize: 11, color: '#7a9bb8', display: 'flex', justifyContent: 'space-between' } },
React.createElement('span', null, '管汇压力 ', React.createElement('b', { style: { color: '#00f2ff' } }, '35.2'), ' MPa'),
React.createElement('span', null, '可用氢量 ', React.createElement('b', { style: { color: '#00f2ff' } }, '4,250'), ' kg')
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '0 0 120px' }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '安全环境监测')
),
React.createElement('div', { style: { padding: '10px 12px', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8, fontSize: 10 } },
['氢浓度', '可燃气体', '温度', '湿度', '风速', '风向'].map(function (lab) {
return React.createElement('div', { key: lab, style: { background: 'rgba(0,40,70,0.4)', padding: '6px 8px', borderRadius: 2, border: '1px solid rgba(0,242,255,0.1)' } },
React.createElement('div', { style: { color: '#5a8aad' } }, lab),
React.createElement('div', { style: { color: '#52c41a', marginTop: 2 } }, '正常')
);
})
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: '1 1 0', minHeight: 0 }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '当日关键指标')
),
React.createElement('div', { style: { display: 'flex', justifyContent: 'space-around', padding: '16px 8px' } },
[{ v: 78, l: '完成率' }, { v: 92, l: '能效' }, { v: 100, l: '安全' }].map(function (g) {
return React.createElement('div', { key: g.l, style: { textAlign: 'center' } },
React.createElement('svg', { width: 72, height: 72, viewBox: '0 0 72 72' },
React.createElement('circle', { cx: 36, cy: 36, r: 30, fill: 'none', stroke: 'rgba(0,242,255,0.12)', strokeWidth: 8 }),
React.createElement('circle', {
cx: 36, cy: 36, r: 30, fill: 'none', stroke: '#00f2ff', strokeWidth: 8,
strokeDasharray: (g.v / 100 * 188) + ' 188',
strokeLinecap: 'round',
transform: 'rotate(-90 36 36)'
}),
React.createElement('text', { x: 36, y: 40, textAnchor: 'middle', fill: '#e8f4ff', fontSize: 14, fontWeight: 700 }, g.v + '%')
),
React.createElement('div', { style: { fontSize: 11, color: '#7a9bb8', marginTop: 6 } }, g.l)
);
})
)
)
),
/* 中央孪生区 */
React.createElement('div', {
className: 'h2-center-stage',
style: {
position: 'absolute',
left: 448,
right: 448,
top: 168,
bottom: 288,
borderRadius: 6,
border: '1px solid rgba(0, 242, 255, 0.28)',
background: 'linear-gradient(165deg, rgba(6, 22, 48, 0.92) 0%, rgba(2, 8, 22, 0.96) 100%)',
zIndex: 10,
overflow: 'hidden'
}
},
React.createElement('div', { className: 'h2-scanline', style: { position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none' } }),
/* 模拟夜景站场视觉 */
React.createElement('div', {
style: {
position: 'absolute',
inset: 0,
background: `
radial-gradient(ellipse 70% 45% at 50% 55%, rgba(0, 80, 120, 0.35) 0%, transparent 60%),
linear-gradient(180deg, #020810 0%, #061a32 40%, #02060c 100%)
`
}
}),
React.createElement('div', {
style: {
position: 'absolute',
left: '8%',
top: '42%',
width: 120,
height: 48,
border: '1px solid rgba(0,242,255,0.45)',
borderRadius: 4,
background: 'rgba(0,20,40,0.5)',
fontSize: 11,
color: '#00f2ff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
boxShadow: '0 0 20px rgba(0,242,255,0.2)'
}
}, '制氢单元'),
React.createElement('div', {
style: {
position: 'absolute',
left: '38%',
top: '28%',
width: 100,
height: 44,
border: '1px solid rgba(22,93,255,0.5)',
borderRadius: 4,
background: 'rgba(10,30,60,0.45)',
fontSize: 11,
color: '#7ab6ff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}, '压缩系统'),
React.createElement('div', {
style: {
position: 'absolute',
right: '18%',
top: '38%',
width: 110,
height: 52,
border: '1px solid rgba(0,242,255,0.4)',
borderRadius: 4,
background: 'rgba(0,30,55,0.5)',
fontSize: 11,
color: '#00f2ff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}, '储氢罐组'),
React.createElement('div', {
style: {
position: 'absolute',
left: '42%',
bottom: '22%',
width: 140,
height: 56,
border: '1px solid rgba(0,242,255,0.55)',
borderRadius: 4,
background: 'rgba(0,40,70,0.55)',
fontSize: 11,
color: '#e8f4ff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
boxShadow: '0 0 24px rgba(0,242,255,0.25)'
}
}, '加氢岛 · 数字孪生'),
React.createElement('div', {
style: {
position: 'absolute',
right: 16,
top: 16,
width: 56,
height: 56,
borderRadius: '50%',
border: '2px solid rgba(0,242,255,0.35)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 10,
color: '#7a9bb8'
}
}, 'N'),
React.createElement('div', {
style: {
position: 'absolute',
left: 16,
bottom: 72,
fontSize: 11,
color: 'rgba(0,242,255,0.6)',
letterSpacing: '0.08em'
}
}, '视角:鸟瞰 · LOD 高 · 实时数据叠加'),
React.createElement('div', {
style: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 76,
padding: '10px 12px',
background: 'linear-gradient(0deg, rgba(4,12,28,0.95) 0%, transparent 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: 10
}
},
subNavBtn('总览', '◎'),
subNavBtn('压缩', '▣'),
subNavBtn('储氢', '◉'),
subNavBtn('加氢', '⬡'),
subNavBtn('安全', '⚠'),
subNavBtn('能耗', '⌁'),
subNavBtn('管网', '⊞'),
subNavBtn('报表', '≡')
)
),
/* 底栏三图表面板 */
React.createElement('footer', {
style: {
position: 'absolute',
left: 448,
right: 448,
bottom: 24,
height: 160,
display: 'flex',
gap: 12,
zIndex: 12
}
},
React.createElement('div', { style: Object.assign({}, panelShell, { flex: 1 }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '加氢车辆统计')
),
React.createElement('div', { style: { display: 'flex', alignItems: 'center', padding: '12px 20px', gap: 20 } },
React.createElement('svg', { width: 100, height: 100, viewBox: '0 0 100 100' },
React.createElement('circle', { cx: 50, cy: 50, r: 36, fill: 'none', stroke: 'rgba(0,242,255,0.12)', strokeWidth: 14 }),
React.createElement('circle', { cx: 50, cy: 50, r: 36, fill: 'none', stroke: '#00f2ff', strokeWidth: 14, strokeDasharray: '90 226', strokeLinecap: 'round', transform: 'rotate(-90 50 50)' }),
React.createElement('circle', { cx: 50, cy: 50, r: 36, fill: 'none', stroke: '#165dff', strokeWidth: 14, strokeDasharray: '55 226', strokeDashoffset: -90, strokeLinecap: 'round', transform: 'rotate(-90 50 50)' }),
React.createElement('circle', { cx: 50, cy: 50, r: 36, fill: 'none', stroke: '#52c41a', strokeWidth: 14, strokeDasharray: '40 226', strokeDashoffset: -145, strokeLinecap: 'round', transform: 'rotate(-90 50 50)' })
),
React.createElement('div', { style: { fontSize: 11, lineHeight: 1.9, color: '#7a9bb8' } },
React.createElement('div', null, React.createElement('span', { style: { color: '#00f2ff' } }, '●'), ' 重卡 38%'),
React.createElement('div', null, React.createElement('span', { style: { color: '#165dff' } }, '●'), ' 物流 28%'),
React.createElement('div', null, React.createElement('span', { style: { color: '#52c41a' } }, '●'), ' 公交 22%'),
React.createElement('div', null, React.createElement('span', { style: { color: '#8b9bb5' } }, '●'), ' 其他 12%')
)
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: 1.2 }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '累计加氢量趋势')
),
React.createElement('div', { style: { padding: '8px 12px', height: 108 } },
React.createElement('svg', { width: '100%', height: '100%', viewBox: '0 0 400 100', preserveAspectRatio: 'none' },
React.createElement('polyline', { fill: 'none', stroke: 'rgba(0,242,255,0.25)', strokeWidth: '1', points: '0,80 400,80' }),
React.createElement('polyline', { fill: 'none', stroke: '#00f2ff', strokeWidth: '2', points: '0,85 40,78 80,72 120,65 160,58 200,50 240,45 280,38 320,32 360,28 400,22' }),
React.createElement('polyline', { fill: 'none', stroke: 'rgba(122,155,184,0.6)', strokeWidth: '1.5', strokeDasharray: '4 3', points: '0,90 40,88 80,86 120,82 160,78 200,75 240,72 280,68 320,65 360,62 400,58' })
)
),
React.createElement('div', { style: { padding: '0 12px 8px', fontSize: 10, color: '#5a8aad', display: 'flex', gap: 16 } },
React.createElement('span', null, '━━ 本年累计'),
React.createElement('span', null, '- - 去年同期')
)
),
React.createElement('div', { style: Object.assign({}, panelShell, { flex: 1 }) },
React.createElement('div', { style: panelHead },
React.createElement('h2', { style: h2PanelTitle }, React.createElement('span', { style: { width: 3, height: 14, background: '#00f2ff', borderRadius: 1 } }), '运行时长统计')
),
React.createElement('div', { style: { padding: '16px 20px', display: 'flex', flexDirection: 'column', gap: 10, justifyContent: 'center', height: 108 } },
[
{ n: '加氢系统', p: 92 },
{ n: '压缩系统', p: 88 },
{ n: '冷却循环', p: 76 },
{ n: '站控 PLC', p: 100 }
].map(function (row) {
return React.createElement('div', { key: row.n, style: { display: 'flex', alignItems: 'center', gap: 10 } },
React.createElement('div', { style: { width: 72, fontSize: 10, color: '#7a9bb8' } }, row.n),
React.createElement('div', { style: { flex: 1, height: 8, background: 'rgba(0,40,70,0.5)', borderRadius: 4, overflow: 'hidden' } },
React.createElement('div', { style: { width: row.p + '%', height: '100%', background: 'linear-gradient(90deg, #165dff, #00f2ff)', borderRadius: 4 } })
),
React.createElement('div', { style: { width: 36, fontSize: 10, color: '#00f2ff', textAlign: 'right' } }, row.p + '%')
);
})
)
)
),
/* 四角装饰线 */
React.createElement('div', { style: { position: 'absolute', left: 12, top: 12, width: 48, height: 48, borderLeft: '2px solid #00f2ff', borderTop: '2px solid #00f2ff', opacity: 0.6, pointerEvents: 'none' } }),
React.createElement('div', { style: { position: 'absolute', right: 12, top: 12, width: 48, height: 48, borderRight: '2px solid #00f2ff', borderTop: '2px solid #00f2ff', opacity: 0.6, pointerEvents: 'none' } }),
React.createElement('div', { style: { position: 'absolute', left: 12, bottom: 12, width: 48, height: 48, borderLeft: '2px solid #00f2ff', borderBottom: '2px solid #00f2ff', opacity: 0.6, pointerEvents: 'none' } }),
React.createElement('div', { style: { position: 'absolute', right: 12, bottom: 12, width: 48, height: 48, borderRight: '2px solid #00f2ff', borderBottom: '2px solid #00f2ff', opacity: 0.6, pointerEvents: 'none' } })
);
};
if (typeof module !== 'undefined' && module.exports) module.exports = Component;