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