525 lines
23 KiB
JavaScript
525 lines
23 KiB
JavaScript
// 【重要】必须使用 const Component 作为组件变量名
|
||
// 数字化资产ONEOS运管平台 - 工作台模块
|
||
const Component = function () {
|
||
var useState = React.useState;
|
||
var useMemo = React.useMemo;
|
||
var useCallback = React.useCallback;
|
||
var antd = window.antd;
|
||
|
||
var Breadcrumb = antd.Breadcrumb;
|
||
var Card = antd.Card;
|
||
var Row = antd.Row;
|
||
var Col = antd.Col;
|
||
var List = antd.List;
|
||
var Badge = antd.Badge;
|
||
var Modal = antd.Modal;
|
||
var Tabs = antd.Tabs;
|
||
var Space = antd.Space;
|
||
|
||
// 状态管理
|
||
var _approvalModalVisible = useState(false);
|
||
var _notificationModalVisible = useState(false);
|
||
var _activeRole = useState('业管');
|
||
|
||
var approvalModalVisible = _approvalModalVisible[0];
|
||
var setApprovalModalVisible = _approvalModalVisible[1];
|
||
var notificationModalVisible = _notificationModalVisible[0];
|
||
var setNotificationModalVisible = _notificationModalVisible[1];
|
||
var activeRole = _activeRole[0];
|
||
var setActiveRole = _activeRole[1];
|
||
|
||
// 样式定义
|
||
var styles = {
|
||
container: {
|
||
padding: '20px',
|
||
backgroundColor: '#f0f2f5',
|
||
minHeight: '100vh',
|
||
fontFamily: 'Arial, sans-serif'
|
||
},
|
||
breadcrumb: {
|
||
marginBottom: '20px',
|
||
fontSize: '14px'
|
||
},
|
||
metricCard: {
|
||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||
borderRadius: '8px',
|
||
padding: '20px',
|
||
color: 'white',
|
||
cursor: 'pointer',
|
||
transition: 'transform 0.3s, box-shadow 0.3s'
|
||
},
|
||
metricCardCompleted: {
|
||
background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)'
|
||
},
|
||
metricCardApproved: {
|
||
background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
|
||
},
|
||
metricCardNotification: {
|
||
background: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)'
|
||
},
|
||
metricTitle: {
|
||
fontSize: '14px',
|
||
opacity: '0.9',
|
||
marginBottom: '8px'
|
||
},
|
||
metricValue: {
|
||
fontSize: '32px',
|
||
fontWeight: 'bold'
|
||
},
|
||
metricDesc: {
|
||
fontSize: '12px',
|
||
opacity: '0.8',
|
||
marginTop: '8px'
|
||
},
|
||
sectionTitle: {
|
||
fontSize: '16px',
|
||
fontWeight: 'bold',
|
||
marginBottom: '16px',
|
||
color: '#262626',
|
||
paddingLeft: '8px',
|
||
borderLeft: '4px solid #1890ff'
|
||
},
|
||
taskList: {
|
||
maxHeight: '400px',
|
||
overflowY: 'auto'
|
||
},
|
||
taskItem: {
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
padding: '12px 0',
|
||
borderBottom: '1px solid #f0f0f0'
|
||
},
|
||
taskInfo: {
|
||
flex: 1
|
||
},
|
||
taskName: {
|
||
fontSize: '14px',
|
||
color: '#262626',
|
||
marginBottom: '4px'
|
||
},
|
||
taskTime: {
|
||
fontSize: '12px',
|
||
color: '#8c8c8c'
|
||
},
|
||
processButton: {
|
||
padding: '6px 16px',
|
||
backgroundColor: '#1890ff',
|
||
color: 'white',
|
||
border: 'none',
|
||
borderRadius: '4px',
|
||
cursor: 'pointer',
|
||
fontSize: '12px'
|
||
},
|
||
statCards: {
|
||
marginBottom: '16px'
|
||
},
|
||
statItem: {
|
||
textAlign: 'center',
|
||
padding: '16px',
|
||
backgroundColor: '#fafafa',
|
||
borderRadius: '4px',
|
||
border: '1px solid #f0f0f0'
|
||
},
|
||
statValue: {
|
||
fontSize: '24px',
|
||
fontWeight: 'bold',
|
||
color: '#1890ff',
|
||
marginBottom: '4px'
|
||
},
|
||
statLabel: {
|
||
fontSize: '12px',
|
||
color: '#8c8c8c'
|
||
},
|
||
quickEntryCard: {
|
||
textAlign: 'center',
|
||
padding: '20px',
|
||
backgroundColor: 'white',
|
||
borderRadius: '8px',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.3s',
|
||
border: '1px solid #f0f0f0'
|
||
},
|
||
quickEntryCardHover: {
|
||
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
|
||
transform: 'translateY(-2px)'
|
||
},
|
||
quickEntryIcon: {
|
||
fontSize: '32px',
|
||
marginBottom: '8px',
|
||
color: '#1890ff'
|
||
},
|
||
quickEntryName: {
|
||
fontSize: '12px',
|
||
color: '#262626'
|
||
},
|
||
modal: {
|
||
top: '20px'
|
||
},
|
||
notificationItem: {
|
||
padding: '12px',
|
||
borderBottom: '1px solid #f0f0f0'
|
||
},
|
||
notificationType: {
|
||
fontSize: '12px',
|
||
color: '#8c8c8c',
|
||
marginBottom: '4px'
|
||
},
|
||
notificationContent: {
|
||
fontSize: '14px',
|
||
color: '#262626',
|
||
marginBottom: '4px'
|
||
},
|
||
notificationTime: {
|
||
fontSize: '12px',
|
||
color: '#bfbfbf'
|
||
}
|
||
};
|
||
|
||
// 模拟数据 - 待办工作
|
||
var pendingTasks = [
|
||
{ id: 1, name: '交车任务 - 车辆管理', time: '2026-03-30 09:30', type: '运维侧' },
|
||
{ id: 2, name: '商业险到期 - 粤A12345', time: '2026-03-30 10:15', type: '业管侧' },
|
||
{ id: 3, name: '氢费审核 - 客户A项目', time: '2026-03-30 11:00', type: '业管-能源部侧' },
|
||
{ id: 4, name: '调拨任务 - 车辆V001', time: '2026-03-30 14:20', type: '运维侧' },
|
||
{ id: 5, name: '年审任务 - 沪D66666', time: '2026-03-30 15:45', type: '运维侧' }
|
||
];
|
||
|
||
// 模拟数据 - 已完成工作
|
||
var completedTasks = [
|
||
{ id: 1, name: '异动任务 - 车辆V003', time: '2026-03-29 16:30' },
|
||
{ id: 2, name: '租赁账单生成 - HT-2024-001', time: '2026-03-29 14:15' },
|
||
{ id: 3, name: '提车应收款 - 客户B', time: '2026-03-28 10:00' }
|
||
];
|
||
|
||
// 模拟数据 - 待审批任务
|
||
var pendingApprovals = [
|
||
{ id: 1, flowTime: '2026-03-30 09:00', flowType: '调拨审核', startTime: '2026-03-30 08:30', starter: '张三' },
|
||
{ id: 2, flowTime: '2026-03-30 10:30', flowType: '租赁账单审核', startTime: '2026-03-30 10:00', starter: '李四' },
|
||
{ id: 3, flowTime: '2026-03-30 11:15', flowType: '提车应收款审核', startTime: '2026-03-30 11:00', starter: '王五' },
|
||
{ id: 4, flowTime: '2026-03-30 14:00', flowType: '租赁合同审核', startTime: '2026-03-30 13:30', starter: '赵六' },
|
||
{ id: 5, flowTime: '2026-03-30 15:30', flowType: '氢费账单审核', startTime: '2026-03-30 15:00', starter: '孙七' }
|
||
];
|
||
|
||
// 模拟数据 - 已审批任务
|
||
var approvedTasks = [
|
||
{ id: 1, name: '替换车审核', time: '2026-03-29 15:00' },
|
||
{ id: 2, name: '还车应结款审核', time: '2026-03-28 14:30' }
|
||
];
|
||
|
||
// 模拟数据 - 通知消息
|
||
var notifications = [
|
||
{ id: 1, type: '保险到期提醒', content: '粤A12345商业险将在2026-04-15到期,请尽快处理', time: '2026-03-30 09:00' },
|
||
{ id: 2, type: '营运证到期提醒', content: '粤B67890营运证还有90天到期,请尽快更新营运证', time: '2026-03-30 10:30' },
|
||
{ id: 3, type: '租赁合同到期提醒', content: 'HT-2024-001 客户A项目还有30天到期,请尽快处理', time: '2026-03-30 11:00' },
|
||
{ id: 4, type: '氢费余额不足提醒', content: '客户A 项目A氢费余额已不足500元,请尽快通知客户处理', time: '2026-03-30 14:00' },
|
||
{ id: 5, type: '审批流程提醒', content: '张三 调拨流程审批节点已到达,请进行审批', time: '2026-03-30 15:30' }
|
||
];
|
||
|
||
// 模拟数据 - 车辆统计
|
||
var vehicleStats = {
|
||
total: 1250,
|
||
selfOperated: 890,
|
||
inventory: 210,
|
||
pending: 150
|
||
};
|
||
|
||
// 模拟数据 - 合同统计
|
||
var contractStats = {
|
||
total: 156,
|
||
selfOperated: 98
|
||
};
|
||
|
||
// 快速入口配置
|
||
var quickEntries = {
|
||
'业管': [
|
||
{ name: '租赁合同', icon: '📄' },
|
||
{ name: '交车任务', icon: '🚗' },
|
||
{ name: '提车应收款', icon: '💰' },
|
||
{ name: '租赁账单', icon: '📊' },
|
||
{ name: '还车应结款', icon: '💵' },
|
||
{ name: '能源账户', icon: '⚡' },
|
||
{ name: '氢费账单', icon: '🔋' },
|
||
{ name: '电费账单', icon: '⚡' },
|
||
{ name: 'ETC账单', icon: '🛣️' },
|
||
{ name: '保险管理', icon: '🛡️' },
|
||
{ name: '审批中心', icon: '✅' }
|
||
],
|
||
'业管-能源部': [
|
||
{ name: '加氢订单管理', icon: '⛽' }
|
||
],
|
||
'运维': [
|
||
{ name: '车辆管理', icon: '🚗' },
|
||
{ name: '证照管理', icon: '📋' },
|
||
{ name: '备车管理', icon: '🔧' },
|
||
{ name: '交车管理', icon: '🚀' },
|
||
{ name: '还车管理', icon: '🏠' },
|
||
{ name: '替换车管理', icon: '🔄' },
|
||
{ name: '调拨管理', icon: '📦' },
|
||
{ name: '异动管理', icon: '📊' },
|
||
{ name: '备件库管理', icon: '🔩' }
|
||
],
|
||
'财务': [
|
||
{ name: '提车应收款', icon: '💰' },
|
||
{ name: '租赁账单', icon: '📊' },
|
||
{ name: '还车应结款', icon: '💵' },
|
||
{ name: '审批中心', icon: '✅' },
|
||
{ name: '充值单管理', icon: '💳' }
|
||
],
|
||
'安全': [
|
||
{ name: '违章管理', icon: '🚦' },
|
||
{ name: '事故管理', icon: '🚨' },
|
||
{ name: '司机管理', icon: '👨✈️' },
|
||
{ name: '安全培训资料', icon: '📚' },
|
||
{ name: '安全培训记录', icon: '📝' }
|
||
],
|
||
'法务': [
|
||
{ name: '审批中心', icon: '✅' }
|
||
]
|
||
};
|
||
|
||
// 角色标签
|
||
var roleTabs = ['业管', '业管-能源部', '运维', '财务', '安全', '法务'];
|
||
|
||
// 处理待办任务
|
||
var handleProcessTask = function(task) {
|
||
console.log('处理任务:', task);
|
||
};
|
||
|
||
// 处理审批
|
||
var handleProcessApproval = function(approval) {
|
||
console.log('处理审批:', approval);
|
||
};
|
||
|
||
// 处理快速入口
|
||
var handleQuickEntry = function(entry) {
|
||
console.log('快速入口:', entry);
|
||
};
|
||
|
||
return React.createElement('div', { style: styles.container },
|
||
// 面包屑
|
||
React.createElement(Breadcrumb, { style: styles.breadcrumb },
|
||
React.createElement(Breadcrumb.Item, null, '工作台')
|
||
),
|
||
|
||
// 顶部关键指标卡片
|
||
React.createElement(Row, { gutter: 16, style: { marginBottom: '24px' } },
|
||
// 待办工作
|
||
React.createElement(Col, { span: 4 },
|
||
React.createElement('div', { style: styles.metricCard },
|
||
React.createElement('div', { style: styles.metricTitle }, '待办工作'),
|
||
React.createElement('div', { style: styles.metricValue }, '5'),
|
||
React.createElement('div', { style: styles.metricDesc }, '运维侧: 3 | 业管侧: 1 | 能源部: 1')
|
||
)
|
||
),
|
||
// 已完成工作
|
||
React.createElement(Col, { span: 4 },
|
||
React.createElement('div', { style: Object.assign({}, styles.metricCard, styles.metricCardCompleted) },
|
||
React.createElement('div', { style: styles.metricTitle }, '已完成工作'),
|
||
React.createElement('div', { style: styles.metricValue }, '3'),
|
||
React.createElement('div', { style: styles.metricDesc }, '本周完成: 3 | 本月完成: 12')
|
||
)
|
||
),
|
||
// 待审批任务
|
||
React.createElement(Col, { span: 4 },
|
||
React.createElement('div', { style: styles.metricCard, onClick: function() { setApprovalModalVisible(true); } },
|
||
React.createElement('div', { style: styles.metricTitle }, '待审批任务'),
|
||
React.createElement('div', { style: styles.metricValue }, '5'),
|
||
React.createElement('div', { style: styles.metricDesc }, '运维: 1 | 财务: 3 | 法务: 1')
|
||
)
|
||
),
|
||
// 已审批任务
|
||
React.createElement(Col, { span: 4 },
|
||
React.createElement('div', { style: Object.assign({}, styles.metricCard, styles.metricCardApproved) },
|
||
React.createElement('div', { style: styles.metricTitle }, '已审批任务'),
|
||
React.createElement('div', { style: styles.metricValue }, '2'),
|
||
React.createElement('div', { style: styles.metricDesc }, '本周审批: 2 | 本月审批: 8')
|
||
)
|
||
),
|
||
// 通知消息
|
||
React.createElement(Col, { span: 4 },
|
||
React.createElement('div', { style: Object.assign({}, styles.metricCard, styles.metricCardNotification), onClick: function() { setNotificationModalVisible(true); } },
|
||
React.createElement('div', { style: styles.metricTitle }, '通知消息'),
|
||
React.createElement('div', { style: styles.metricValue }, '5'),
|
||
React.createElement('div', { style: styles.metricDesc }, '运维: 3 | 业管: 1 | 审批: 1')
|
||
)
|
||
)
|
||
),
|
||
|
||
// 中间内容区域
|
||
React.createElement(Row, { gutter: 16 },
|
||
// 左侧 - 我的待办清单
|
||
React.createElement(Col, { span: 7 },
|
||
React.createElement(Card, { title: React.createElement('div', { style: styles.sectionTitle }, '我的待办清单'), bordered: false, style: { height: '100%' } },
|
||
React.createElement('div', { style: styles.taskList },
|
||
pendingTasks.map(function(task) {
|
||
return React.createElement('div', { key: task.id, style: styles.taskItem },
|
||
React.createElement('div', { style: styles.taskInfo },
|
||
React.createElement('div', { style: styles.taskName }, task.name),
|
||
React.createElement('div', { style: styles.taskTime }, task.time + ' | ' + task.type)
|
||
),
|
||
React.createElement('button', {
|
||
style: styles.processButton,
|
||
onClick: function() { handleProcessTask(task); }
|
||
}, '去处理')
|
||
);
|
||
})
|
||
)
|
||
)
|
||
),
|
||
|
||
// 中间 - 数据统计模块
|
||
React.createElement(Col, { span: 10 },
|
||
// 车辆数据统计
|
||
React.createElement(Card, { title: React.createElement('div', { style: styles.sectionTitle }, '车辆数据统计'), bordered: false, style: { marginBottom: '16px' } },
|
||
React.createElement(Row, { gutter: 16, style: styles.statCards },
|
||
React.createElement(Col, { span: 6 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, vehicleStats.total),
|
||
React.createElement('div', { style: styles.statLabel }, '车辆总数')
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 6 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, vehicleStats.selfOperated),
|
||
React.createElement('div', { style: styles.statLabel }, '自营车辆数')
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 6 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, vehicleStats.inventory),
|
||
React.createElement('div', { style: styles.statLabel }, '库存车辆数')
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 6 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, vehicleStats.pending),
|
||
React.createElement('div', { style: styles.statLabel }, '待运营车辆数')
|
||
)
|
||
)
|
||
),
|
||
// 近12个月运营车辆、闲置车辆双柱状图(使用Ant Design Charts)
|
||
React.createElement('div', { style: { height: '200px', marginTop: '16px', backgroundColor: '#fafafa', borderRadius: '4px', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#8c8c8c' } },
|
||
'[柱状图:近12个月运营车辆、闲置车辆统计]'
|
||
)
|
||
),
|
||
|
||
// 合同数据统计
|
||
React.createElement(Card, { title: React.createElement('div', { style: styles.sectionTitle }, '合同数据统计'), bordered: false },
|
||
React.createElement(Row, { gutter: 16, style: styles.statCards },
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, contractStats.total),
|
||
React.createElement('div', { style: styles.statLabel }, '租赁合同总数')
|
||
)
|
||
),
|
||
React.createElement(Col, { span: 12 },
|
||
React.createElement('div', { style: styles.statItem },
|
||
React.createElement('div', { style: styles.statValue }, contractStats.selfOperated),
|
||
React.createElement('div', { style: styles.statLabel }, '自营合同总数')
|
||
)
|
||
)
|
||
),
|
||
// 近12个月租赁合同、自营合同双柱状图
|
||
React.createElement('div', { style: { height: '200px', marginTop: '16px', backgroundColor: '#fafafa', borderRadius: '4px', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#8c8c8c' } },
|
||
'[柱状图:近12个月租赁合同、自营合同统计]'
|
||
)
|
||
)
|
||
),
|
||
|
||
// 右侧 - 我的通知清单
|
||
React.createElement(Col, { span: 7 },
|
||
React.createElement(Card, { title: React.createElement('div', { style: styles.sectionTitle }, '我的通知清单'), bordered: false, style: { height: '100%' } },
|
||
React.createElement('div', { style: styles.taskList },
|
||
notifications.map(function(notification) {
|
||
return React.createElement('div', { key: notification.id, style: styles.notificationItem },
|
||
React.createElement('div', { style: styles.notificationType }, notification.type),
|
||
React.createElement('div', { style: styles.notificationContent }, notification.content),
|
||
React.createElement('div', { style: styles.notificationTime }, notification.time)
|
||
);
|
||
})
|
||
)
|
||
)
|
||
)
|
||
),
|
||
|
||
// 底部快速入口
|
||
React.createElement(Card, { title: React.createElement('div', { style: styles.sectionTitle }, '快速入口'), bordered: false, style: { marginTop: '16px' } },
|
||
React.createElement(Tabs, { activeKey: activeRole, onChange: function(key) { setActiveRole(key); } },
|
||
roleTabs.map(function(role) {
|
||
return React.createElement(Tabs.TabPane, { tab: role, key: role },
|
||
React.createElement(Row, { gutter: 16 },
|
||
quickEntries[role].map(function(entry, index) {
|
||
return React.createElement(Col, { key: index, span: 4 },
|
||
React.createElement('div', {
|
||
style: styles.quickEntryCard,
|
||
onClick: function() { handleQuickEntry(entry); }
|
||
},
|
||
React.createElement('div', { style: styles.quickEntryIcon }, entry.icon),
|
||
React.createElement('div', { style: styles.quickEntryName }, entry.name)
|
||
)
|
||
);
|
||
})
|
||
)
|
||
);
|
||
})
|
||
)
|
||
),
|
||
|
||
// 待审批任务弹窗
|
||
React.createElement(Modal, {
|
||
title: '待审批任务',
|
||
visible: approvalModalVisible,
|
||
onCancel: function() { setApprovalModalVisible(false); },
|
||
footer: null,
|
||
width: 800,
|
||
style: styles.modal
|
||
},
|
||
React.createElement(List, {
|
||
dataSource: pendingApprovals,
|
||
renderItem: function(approval) {
|
||
return React.createElement(List.Item, null,
|
||
React.createElement(List.Item.Meta, {
|
||
title: approval.flowType,
|
||
description: React.createElement('div', null,
|
||
React.createElement('div', null, '流程到达时间: ' + approval.flowTime),
|
||
React.createElement('div', null, '发起时间: ' + approval.startTime),
|
||
React.createElement('div', null, '发起人: ' + approval.starter)
|
||
)
|
||
}),
|
||
React.createElement('button', {
|
||
style: styles.processButton,
|
||
onClick: function() { handleProcessApproval(approval); }
|
||
}, '去处理')
|
||
);
|
||
}
|
||
})
|
||
),
|
||
|
||
// 通知消息弹窗
|
||
React.createElement(Modal, {
|
||
title: '通知消息',
|
||
visible: notificationModalVisible,
|
||
onCancel: function() { setNotificationModalVisible(false); },
|
||
footer: null,
|
||
width: 800,
|
||
style: styles.modal
|
||
},
|
||
React.createElement(List, {
|
||
dataSource: notifications,
|
||
renderItem: function(notification) {
|
||
return React.createElement(List.Item, null,
|
||
React.createElement(List.Item.Meta, {
|
||
title: notification.type,
|
||
description: React.createElement('div', null,
|
||
React.createElement('div', { style: { fontSize: '14px', marginBottom: '4px' } }, notification.content),
|
||
React.createElement('div', { style: { fontSize: '12px', color: '#8c8c8c' } }, notification.time)
|
||
)
|
||
})
|
||
);
|
||
}
|
||
})
|
||
)
|
||
);
|
||
};
|