diff --git a/web端/.DS_Store b/web端/.DS_Store index f564d86..d9b58bb 100644 Binary files a/web端/.DS_Store and b/web端/.DS_Store differ diff --git a/web端/车辆租赁合同/车辆租赁合同-附加费用.jsx b/web端/车辆租赁合同/车辆租赁合同-附加费用.jsx new file mode 100644 index 0000000..28c568f --- /dev/null +++ b/web端/车辆租赁合同/车辆租赁合同-附加费用.jsx @@ -0,0 +1,354 @@ +// 【重要】必须使用 const Component 作为组件变量名 +// 车辆租赁合同 - 附加费用(参照新增合同,除服务费项目-管理弹层可编辑外其余只读+样例数据) + +const Component = function() { + var antd = window.antd; + var Input = antd.Input; + var Select = antd.Select; + var Button = antd.Button; + var DatePicker = antd.DatePicker; + var message = antd.message; + var Option = Select.Option; + + // 样例数据(只读展示) + var detail = React.useMemo(function() { + return { + customerName: '嘉兴某某物流有限公司', + creditCode: '91330400MA2XXXXX1', + address: '浙江省嘉兴市南湖区科技大道1号', + contact: '张三', + phone: '13800138001', + email: 'zhangsan@example.com', + companyName: '嘉兴某某物流有限公司', + companyPhone: '0571-88888888', + mailingAddress: '浙江省嘉兴市南湖区科技大道1号', + bank: '中国工商银行嘉兴分行', + bankAccount: '6222021234567890123', + taxId: '91330400MA2XXXXX1', + businessDept: '业务1部', + businessOwner: '张经理', + projectName: '嘉兴城配运输项目', + contractType: '正式合同', + effectiveDate: '2026-02-16', + paymentMethod: '预付', + mainVehicleModels: '型号A1、型号B1', + endDate: '2027-02-16', + paymentPeriod: '2', + signingCompany: '嘉兴羚牛', + deliveryRegion: '浙江省 / 嘉兴市', + deliveryLocation: '嘉兴市南湖区科技大道1号', + contractOriginalName: '租赁合同-嘉兴某某物流.pdf', + remarks: '首年优惠', + authorizedList: [ + { name: '张三', phone: '13800138001', idCard: '330102199001011234' }, + { name: '李四', phone: '13800138002', idCard: '330102199002022345' } + ], + feeTemplate: '标准费用模板A', + billingMethod: 'month', + hydrogenBearer: '客户', + hydrogenPaymentMethod: '预付', + hydrogenPrepay: '5000.00', + returnHydrogenPrice: '12.50', + rentalOrders: [ + { id: 1, brand: '品牌A', model: '型号A1', plateNo: '浙A10001', vin: 'L1234567890ABCDEF', monthRent: '8000', serviceItems: [{ project: '保养费用', fee: '200.00', effectiveDate: '2026-03-01' }, { project: '清洗费', fee: '80.00', effectiveDate: '2026-03-01' }], deposit: '10000', remark: '' }, + { id: 2, brand: '品牌B', model: '型号B1', plateNo: '沪A30003', vin: 'L3234567890ABCDEF', monthRent: '7500', serviceItems: [{ project: 'ETC-客', fee: '50.00', effectiveDate: '2026-02-20' }], deposit: '8000', remark: '试用车' } + ] + }; + }, []); + + var rentalOrdersInit = detail.rentalOrders.map(function(r) { + return { id: r.id, brand: r.brand, model: r.model, plateNo: r.plateNo, vin: r.vin, monthRent: r.monthRent, serviceItems: (r.serviceItems || []).map(function(si) { return { project: si.project || '', fee: si.fee || '', effectiveDate: si.effectiveDate || '' }; }), deposit: r.deposit, remark: r.remark || '' }; + }); + var os1 = React.useState(rentalOrdersInit); + var rentalOrders = os1[0]; + var setRentalOrders = os1[1]; + var os1b = React.useState(null); + var serviceModalRowIndex = os1b[0]; + var setServiceModalRowIndex = os1b[1]; + + var serviceItemOptions = ['代处理费用', '罚款', '违章处理违约金', '未参加安全培训', '车辆出险', '年检年审违约', '停车费', '设备损坏金(包含易损件)', '清洗费', '上门收车人工费', '上门收车送车行驶费', '上门收车基础服务费', '保险上浮', '保养费用', '补办驾驶证', '补办牌照', '补办营运证', '补办加氢证', '借用备用钥匙', '补配钥匙', '租金', '氢气费-客', '退还车氢量差', '能源费补缴', '能源费退款', '送车上门人工费', '送车上门送车行驶费', '送车上门基础服务费', '保证金', '氢气预付费', '维修费用', 'ETC-客', 'ETC卡缺损费', 'ETC设备缺损费', '电费-客', '未结算保养费', '未结算维修费', '车损费', '工具损坏或丢失费', '证件费', '广告损坏费', '送车服务费', '接车服务费', '补办行驶证', '超赔险', '轮胎磨损费', '无忧包', '轮胎保', '养护保', '尾板']; + + var calcRowServiceFee = function(row) { + var sum = 0; + for (var i = 0; i < (row.serviceItems || []).length; i++) { + var fee = parseFloat(row.serviceItems[i].fee); + if (!isNaN(fee)) sum += fee; + } + return sum.toFixed(2); + }; + var rentalTotalVehicles = rentalOrders.length; + var rentalTotalRentService = rentalOrders.reduce(function(s, r) { return s + (parseFloat(r.monthRent) || 0) + (parseFloat(calcRowServiceFee(r)) || 0); }, 0); + var rentalTotalDeposit = rentalOrders.reduce(function(s, r) { return s + (parseFloat(r.deposit) || 0); }, 0); + var rentalTotalHydrogen = detail.hydrogenBearer === '客户' && detail.hydrogenPaymentMethod === '预付' ? (parseFloat(detail.hydrogenPrepay) || 0) : 0; + + var openServiceModal = function(index) { setServiceModalRowIndex(index); }; + var closeServiceModal = function() { setServiceModalRowIndex(null); }; + var addServiceItem = function() { + if (serviceModalRowIndex === null) return; + var next = rentalOrders.slice(0); + var row = next[serviceModalRowIndex]; + var items = (row.serviceItems || []).concat([{ project: '', fee: '', effectiveDate: '' }]); + var newRow = {}; + for (var k in row) { if (row.hasOwnProperty(k) && k !== 'serviceItems') newRow[k] = row[k]; } + newRow.serviceItems = items; + next[serviceModalRowIndex] = newRow; + setRentalOrders(next); + }; + var removeServiceItem = function(siIndex) { + if (serviceModalRowIndex === null) return; + var next = rentalOrders.slice(0); + var row = next[serviceModalRowIndex]; + var items = (row.serviceItems || []).slice(0); + items.splice(siIndex, 1); + if (items.length === 0) items = [{ project: '', fee: '', effectiveDate: '' }]; + var newRow = {}; + for (var k in row) { if (row.hasOwnProperty(k) && k !== 'serviceItems') newRow[k] = row[k]; } + newRow.serviceItems = items; + next[serviceModalRowIndex] = newRow; + setRentalOrders(next); + }; + var updateServiceItem = function(siIndex, field, value) { + if (serviceModalRowIndex === null) return; + var next = rentalOrders.slice(0); + var row = next[serviceModalRowIndex]; + var items = (row.serviceItems || []).slice(0); + var item = items[siIndex] || {}; + var newItem = {}; + for (var k in item) { if (item.hasOwnProperty(k)) newItem[k] = item[k]; } + newItem[field] = value; + items[siIndex] = newItem; + var newRow = {}; + for (var rk in row) { if (row.hasOwnProperty(rk) && rk !== 'serviceItems') newRow[rk] = row[rk]; } + newRow.serviceItems = items; + next[serviceModalRowIndex] = newRow; + setRentalOrders(next); + }; + + var cc1 = React.useState(false)[0]; + var setCc1 = React.useState(false)[1]; + var cc2 = React.useState(false)[0]; + var setCc2 = React.useState(false)[1]; + var cc3 = React.useState(false)[0]; + var setCc3 = React.useState(false)[1]; + var cc4 = React.useState(false)[0]; + var setCc4 = React.useState(false)[1]; + var cc5 = React.useState(false)[0]; + var setCc5 = React.useState(false)[1]; + var cc6 = React.useState(false)[0]; + var setCc6 = React.useState(false)[1]; + + var styles = { + page: { padding: '16px 24px 48px', backgroundColor: '#f5f5f5', minHeight: '100vh', fontFamily: '"PingFang SC", "苹方-简", -apple-system, BlinkMacSystemFont, "Microsoft YaHei", sans-serif', fontSize: 14 }, + breadcrumb: { marginBottom: 16, color: '#666' }, + breadcrumbSep: { margin: '0 8px', color: '#999' }, + anchorWrap: { position: 'fixed', top: 80, right: 24, zIndex: 100, backgroundColor: '#fff', borderRadius: 8, boxShadow: '0 2px 8px rgba(0,0,0,0.12)', padding: '12px 16px', minWidth: 160 }, + anchorItem: { display: 'block', padding: '6px 0', color: '#1890ff', cursor: 'pointer', border: 'none', background: 'none', width: '100%', textAlign: 'left', fontSize: 13 }, + card: { backgroundColor: '#fff', borderRadius: 8, marginBottom: 16, boxShadow: '0 1px 2px rgba(0,0,0,0.05)', overflow: 'hidden' }, + cardHeader: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '16px 20px', borderBottom: '1px solid #f0f0f0', cursor: 'pointer' }, + cardTitle: { fontSize: 16, fontWeight: 600, color: '#333' }, + cardToggle: { color: '#999', fontSize: 14 }, + cardBody: { padding: '20px 24px' }, + formRow: { display: 'flex', flexWrap: 'wrap', marginBottom: 16 }, + formCol: { flex: '0 0 33.33%', minWidth: 200, paddingRight: 16, marginBottom: 8 }, + formColFull: { flex: '0 0 100%', marginBottom: 8 }, + label: { display: 'block', marginBottom: 6, color: '#333' }, + inputDisabled: { width: '100%', padding: '8px 12px', border: '1px solid #d9d9d9', borderRadius: 4, fontSize: 14, backgroundColor: '#f5f5f5', color: 'rgba(0,0,0,0.65)' }, + summaryList: { marginBottom: 16, display: 'flex', flexWrap: 'wrap', gap: 16 }, + summaryListItem: { flex: '0 0 calc(50% - 8px)', display: 'flex', alignItems: 'center', padding: '12px 16px', border: '1px solid #e8e8e8', borderRadius: 4, backgroundColor: '#fafafa', fontSize: 14, boxSizing: 'border-box' }, + summaryListLabel: { flex: '0 0 140px', color: '#666' }, + summaryListValue: { flex: 1, fontWeight: 600, color: '#333' }, + rentalTable: { width: '100%', borderCollapse: 'collapse', fontSize: 13 }, + rentalTh: { padding: '10px 8px', textAlign: 'left', borderBottom: '1px solid #e8e8e8', backgroundColor: '#fafafa', fontWeight: 600 }, + rentalTd: { padding: '8px', borderBottom: '1px solid #f0f0f0', verticalAlign: 'top' }, + rentalTdCenter: { padding: '8px', borderBottom: '1px solid #f0f0f0', verticalAlign: 'middle' }, + rentalInput: { width: '100%', padding: '6px 10px', border: '1px solid #d9d9d9', borderRadius: 4, fontSize: 13 }, + rentalInputDisabled: { backgroundColor: '#f5f5f5', color: '#999' }, + modalMask: { position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.45)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }, + modalBox: { backgroundColor: '#fff', borderRadius: 8, width: '90%', maxWidth: 720, maxHeight: '85vh', overflow: 'hidden', display: 'flex', flexDirection: 'column', boxShadow: '0 4px 20px rgba(0,0,0,0.15)' }, + modalHeader: { padding: '16px 20px', borderBottom: '1px solid #f0f0f0', fontSize: 16, fontWeight: 600 }, + modalBody: { padding: 20, overflow: 'auto', flex: 1 }, + footer: { position: 'fixed', bottom: 0, left: 0, right: 0, padding: '12px 24px', backgroundColor: '#fff', borderTop: '1px solid #e8e8e8', display: 'flex', gap: 12, justifyContent: 'flex-start', zIndex: 99 } + }; + + var scrollToCard = function(id) { + var el = document.getElementById(id); + if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); + }; + + var CardBlock = function(props) { + return React.createElement('div', { id: props.id, style: styles.card }, + React.createElement('div', { style: styles.cardHeader, onClick: function() { props.setCollapsed(!props.collapsed); } }, + React.createElement('span', { style: styles.cardTitle }, props.title), + React.createElement('span', { style: styles.cardToggle }, props.collapsed ? '展开' : '收起') + ), + !props.collapsed ? React.createElement('div', { style: styles.cardBody }, props.children) : null + ); + }; + + var FormItem = function(props) { + var colStyle = props.fullWidth ? styles.formColFull : styles.formCol; + return React.createElement('div', { style: colStyle }, + React.createElement('label', { style: styles.label }, props.label), + props.children + ); + }; + + var customerFields = React.createElement('div', { style: styles.formRow }, + React.createElement(FormItem, { label: '客户名称' }, React.createElement(Input, { value: detail.customerName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户统一信用代码' }, React.createElement(Input, { value: detail.creditCode, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户地址' }, React.createElement(Input, { value: detail.address, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户联系人' }, React.createElement(Input, { value: detail.contact, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户电话' }, React.createElement(Input, { value: detail.phone, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户电子邮箱' }, React.createElement(Input, { value: detail.email, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '企业名称' }, React.createElement(Input, { value: detail.companyName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '企业电话' }, React.createElement(Input, { value: detail.companyPhone, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '邮寄地址' }, React.createElement(Input, { value: detail.mailingAddress, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '开户银行' }, React.createElement(Input, { value: detail.bank, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '银行账号' }, React.createElement(Input, { value: detail.bankAccount, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '纳税人识别号' }, React.createElement(Input, { value: detail.taxId, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '业务部门' }, React.createElement(Input, { value: detail.businessDept, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '业务负责人' }, React.createElement(Input, { value: detail.businessOwner, disabled: true, style: styles.inputDisabled })) + ); + + var contractFormRow1 = React.createElement('div', { style: styles.formRow }, + React.createElement(FormItem, { label: '项目名称' }, React.createElement(Input, { value: detail.projectName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '合同类型' }, React.createElement(Input, { value: detail.contractType, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '生效日期' }, React.createElement(Input, { value: detail.effectiveDate, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '付款方式' }, React.createElement(Input, { value: detail.paymentMethod, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '主要车型' }, React.createElement(Input, { value: detail.mainVehicleModels, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '结束日期' }, React.createElement(Input, { value: detail.endDate, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '付款周期' }, React.createElement(Input, { value: detail.paymentPeriod + '个月', disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '签约公司' }, React.createElement(Input, { value: detail.signingCompany, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '交车区域' }, React.createElement(Input, { value: detail.deliveryRegion, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '交车地点' }, React.createElement(Input, { value: detail.deliveryLocation, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '合同原件' }, React.createElement(Input, { value: detail.contractOriginalName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '备注', fullWidth: true }, React.createElement(Input.TextArea, { value: detail.remarks, disabled: true, style: { width: '100%', minHeight: 80, backgroundColor: '#f5f5f5' } })) + ); + + var authorizedContent = React.createElement('div', null, + detail.authorizedList.map(function(item, index) { + return React.createElement('div', { key: index, style: { display: 'flex', gap: 12, alignItems: 'flex-start', marginBottom: 12 } }, + React.createElement(Input, { value: item.name, disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled, { flex: 1 }) }), + React.createElement(Input, { value: item.phone, disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled, { flex: 1 }) }), + React.createElement(Input, { value: item.idCard, disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled, { flex: 1 }) }) + ); + }) + ); + + var rentalTableBody = rentalOrders.map(function(row, idx) { + return React.createElement('tr', { key: row.id != null ? row.id : idx }, + React.createElement('td', { style: styles.rentalTdCenter }, idx + 1), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.brand || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.model || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.plateNo || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.vin || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })), + React.createElement('td', { style: styles.rentalTd }, React.createElement('div', { style: { display: 'flex', alignItems: 'center' } }, React.createElement(Input, { value: row.monthRent || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) }), React.createElement('span', { style: { marginLeft: 4 } }, '元'))), + React.createElement('td', { style: styles.rentalTdCenter }, React.createElement(Button, { type: 'link', size: 'small', onClick: function() { openServiceModal(idx); } }, '管理')), + React.createElement('td', { style: styles.rentalTdCenter }, calcRowServiceFee(row) + ' 元'), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.deposit || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { value: row.remark || '', disabled: true, style: Object.assign({}, styles.rentalInput, styles.rentalInputDisabled) })) + ); + }); + + var rentalSummary = React.createElement('div', { style: styles.summaryList }, + React.createElement('div', { style: styles.summaryListItem }, React.createElement('span', { style: styles.summaryListLabel }, '租赁车辆数'), React.createElement('span', { style: styles.summaryListValue }, rentalTotalVehicles + ' 辆')), + React.createElement('div', { style: styles.summaryListItem }, React.createElement('span', { style: styles.summaryListLabel }, '租金及服务费合计'), React.createElement('span', { style: styles.summaryListValue }, rentalTotalRentService.toFixed(2) + ' 元')), + React.createElement('div', { style: styles.summaryListItem }, React.createElement('span', { style: styles.summaryListLabel }, '保证金总额'), React.createElement('span', { style: styles.summaryListValue }, rentalTotalDeposit.toFixed(2) + ' 元')), + React.createElement('div', { style: styles.summaryListItem }, React.createElement('span', { style: styles.summaryListLabel }, '氢气预付款金额'), React.createElement('span', { style: styles.summaryListValue }, rentalTotalHydrogen.toFixed(2) + ' 元')) + ); + + var rentalTableThead = React.createElement('thead', null, React.createElement('tr', null, + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 50 }) }, '序号'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 100 }) }, '品牌'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 100 }) }, '型号'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 120 }) }, '车牌号'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 160 }) }, '车辆识别代码'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 120 }) }, '车辆月租金'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 80 }) }, '服务费项目'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 90 }) }, '服务费'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 100 }) }, '保证金'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 80 }) }, '备注') + )); + var rentalTableEl = React.createElement('table', { style: styles.rentalTable }, rentalTableThead, React.createElement('tbody', null, rentalTableBody)); + var rentalContent = React.createElement('div', null, + rentalSummary, + React.createElement('div', { style: { overflowX: 'auto', marginBottom: 16 } }, rentalTableEl), + React.createElement('div', { style: Object.assign({}, styles.formRow, { marginTop: 20 }) }, + React.createElement(FormItem, { label: '氢费承担方' }, React.createElement(Input, { value: detail.hydrogenBearer, disabled: true, style: styles.inputDisabled })), + detail.hydrogenBearer === '客户' ? React.createElement(FormItem, { label: '付款方式' }, React.createElement(Input, { value: detail.hydrogenPaymentMethod, disabled: true, style: styles.inputDisabled })) : null, + detail.hydrogenPaymentMethod === '预付' && detail.hydrogenBearer === '客户' ? React.createElement(FormItem, { label: '氢气预付款' }, React.createElement(Input, { value: detail.hydrogenPrepay, disabled: true, style: styles.inputDisabled })) : null, + React.createElement(FormItem, { label: '退还车氢气单价' }, React.createElement(Input, { value: detail.returnHydrogenPrice, disabled: true, style: styles.inputDisabled })) + ) + ); + + var feeContent = React.createElement('div', null, + React.createElement(FormItem, { label: '选择费用模板' }, React.createElement(Input, { value: detail.feeTemplate, disabled: true, style: styles.inputDisabled })) + ); + + var billingLabel = detail.billingMethod === 'month' ? '按自然月结算' : '按付款周期天数结算'; + var billingContent = React.createElement('div', null, React.createElement(FormItem, { label: '账单计算方式' }, React.createElement(Input, { value: billingLabel, disabled: true, style: styles.inputDisabled }))); + + var serviceModalRows = serviceModalRowIndex !== null && rentalOrders[serviceModalRowIndex] ? rentalOrders[serviceModalRowIndex].serviceItems : []; + var serviceModalContent = serviceModalRowIndex !== null ? React.createElement('div', { style: styles.modalMask, onClick: function(e) { if (e.target === e.currentTarget) closeServiceModal(); } }, + React.createElement('div', { style: styles.modalBox, onClick: function(e) { e.stopPropagation(); } }, + React.createElement('div', { style: styles.modalHeader }, '服务项目'), + React.createElement('div', { style: styles.modalBody }, + React.createElement('table', { style: styles.rentalTable }, + React.createElement('thead', null, React.createElement('tr', null, + React.createElement('th', { style: styles.rentalTh }, '服务项目'), + React.createElement('th', { style: styles.rentalTh }, '费用'), + React.createElement('th', { style: styles.rentalTh }, '生效时间'), + React.createElement('th', { style: Object.assign({}, styles.rentalTh, { width: 80 }) }, '操作') + )), + React.createElement('tbody', null, serviceModalRows.map(function(si, siIdx) { + return React.createElement('tr', { key: siIdx }, + React.createElement('td', { style: styles.rentalTd }, React.createElement(Select, { style: { width: '100%' }, placeholder: '请选择服务项目', value: si.project || undefined, onChange: function(v) { updateServiceItem(siIdx, 'project', v || ''); }, showSearch: true, filterOption: function(input, opt) { return opt && opt.children && String(opt.children).toLowerCase().indexOf((input || '').toLowerCase()) >= 0; }, allowClear: true }, serviceItemOptions.map(function(opt, oi) { return React.createElement(Option, { key: oi, value: opt }, opt); }))), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Input, { placeholder: '0.00', value: si.fee || '', onChange: function(e) { updateServiceItem(siIdx, 'fee', e.target.value); }, addonAfter: '元', style: { width: '100%' } })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(DatePicker, { style: { width: '100%' }, format: 'YYYY-MM-DD', placeholder: '请选择生效时间', value: si.effectiveDate && window.moment ? window.moment(si.effectiveDate, 'YYYY-MM-DD') : null, onChange: function(d, dateStr) { updateServiceItem(siIdx, 'effectiveDate', dateStr || ''); } })), + React.createElement('td', { style: styles.rentalTd }, React.createElement(Button, { type: 'link', size: 'small', danger: true, onClick: function() { removeServiceItem(siIdx); } }, '删除')) + ); + })) + ), + React.createElement(Button, { type: 'dashed', style: { marginTop: 12, width: '100%' }, onClick: addServiceItem }, '添加一行') + ), + React.createElement('div', { style: { padding: '12px 20px', borderTop: '1px solid #f0f0f0', display: 'flex', gap: 12, justifyContent: 'flex-end' } }, + React.createElement(Button, { type: 'primary', onClick: function() { closeServiceModal(); } }, '保存'), + React.createElement(Button, { onClick: closeServiceModal }, '关闭') + ) + ) + ) : null; + + var handleSubmit = function() { + message.success('已提交审核(原型)'); + if (typeof window !== 'undefined' && window.history) window.history.back(); + }; + var handleBack = function() { + if (typeof window !== 'undefined' && window.history) window.history.back(); + else message.info('返回'); + }; + + return React.createElement('div', { style: styles.page }, + React.createElement('div', { style: { marginBottom: 16 } }, React.createElement('div', { style: styles.breadcrumb }, React.createElement('span', null, '业务管理'), React.createElement('span', { style: styles.breadcrumbSep }, ' / '), React.createElement('span', null, '车辆租赁合同'), React.createElement('span', { style: styles.breadcrumbSep }, ' / '), React.createElement('span', { style: { color: '#1890ff' } }, '附加费用'))), + React.createElement('div', { style: styles.anchorWrap }, + React.createElement('div', { style: { marginBottom: 8, fontWeight: 600, fontSize: 14 } }, '锚点导航'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-customer'); } }, '客户基本信息'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-contract'); } }, '合同基本信息'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-authorized'); } }, '被授权人信息'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-rental'); } }, '租赁订单信息'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-fee'); } }, '其他费用信息'), + React.createElement('button', { style: styles.anchorItem, onClick: function() { scrollToCard('card-billing'); } }, '账单计算方式') + ), + React.createElement('div', { id: 'card-customer' }, React.createElement(CardBlock, { id: 'card-customer', title: '客户基本信息', collapsed: cc1, setCollapsed: setCc1 }, customerFields)), + React.createElement('div', { id: 'card-contract', style: { marginTop: 16 } }, React.createElement(CardBlock, { title: '合同基本信息', collapsed: cc2, setCollapsed: setCc2 }, contractFormRow1)), + React.createElement('div', { id: 'card-authorized', style: { marginTop: 16 } }, React.createElement(CardBlock, { title: '被授权人信息', collapsed: cc3, setCollapsed: setCc3 }, authorizedContent)), + React.createElement('div', { id: 'card-rental', style: { marginTop: 16 } }, React.createElement(CardBlock, { title: '租赁订单信息', collapsed: cc4, setCollapsed: setCc4 }, rentalContent)), + React.createElement('div', { id: 'card-fee', style: { marginTop: 16 } }, React.createElement(CardBlock, { title: '其他费用信息', collapsed: cc5, setCollapsed: setCc5 }, feeContent)), + React.createElement('div', { id: 'card-billing', style: { marginTop: 16 } }, React.createElement(CardBlock, { title: '账单计算方式', collapsed: cc6, setCollapsed: setCc6 }, billingContent)), + React.createElement('div', { style: { height: 60 } }), + serviceModalContent, + React.createElement('div', { style: styles.footer }, + React.createElement(Button, { type: 'primary', onClick: handleSubmit }, '提交审核'), + React.createElement(Button, { onClick: handleBack }, '返回') + ) + ); +}; diff --git a/web端/车辆租赁合同/车辆租赁合同.jsx b/web端/车辆租赁合同/车辆租赁合同.jsx index eafcf1d..f13b042 100644 --- a/web端/车辆租赁合同/车辆租赁合同.jsx +++ b/web端/车辆租赁合同/车辆租赁合同.jsx @@ -582,21 +582,6 @@ const Component = function() { }); }, []); - // 附加费用:服务项目枚举(与需求文档一致) - var extraFeeServiceOptions = [ - { value: '代处理费用', label: '代处理费用' }, { value: '罚款', label: '罚款' }, { value: '违章处理违约金', label: '违章处理违约金' }, { value: '未参加安全培训', label: '未参加安全培训' }, { value: '车辆出险', label: '车辆出险' }, { value: '年检年审违约', label: '年检年审违约' }, { value: '停车费', label: '停车费' }, { value: '设备损坏金(包含易损件)', label: '设备损坏金(包含易损件)' }, { value: '清洗费', label: '清洗费' }, { value: '上门收车人工费', label: '上门收车人工费' }, { value: '上门收车送车行驶费', label: '上门收车送车行驶费' }, { value: '上门收车基础服务费', label: '上门收车基础服务费' }, { value: '保险上浮', label: '保险上浮' }, { value: '保养费用', label: '保养费用' }, { value: '补办驾驶证', label: '补办驾驶证' }, { value: '补办牌照', label: '补办牌照' }, { value: '补办营运证', label: '补办营运证' }, { value: '补办加氢证', label: '补办加氢证' }, { value: '借用备用钥匙', label: '借用备用钥匙' }, { value: '补配钥匙', label: '补配钥匙' }, { value: '租金', label: '租金' }, { value: '氢气费-客', label: '氢气费-客' }, { value: '退还车氢量差', label: '退还车氢量差' }, { value: '能源费补缴', label: '能源费补缴' }, { value: '能源费退款', label: '能源费退款' }, { value: '送车上门人工费', label: '送车上门人工费' }, { value: '送车上门送车行驶费', label: '送车上门送车行驶费' }, { value: '送车上门基础服务费', label: '送车上门基础服务费' }, { value: '保证金', label: '保证金' }, { value: '氢气预付费', label: '氢气预付费' }, { value: '维修费用', label: '维修费用' }, { value: 'ETC-客', label: 'ETC-客' }, { value: 'ETC卡缺损费', label: 'ETC卡缺损费' }, { value: 'ETC设备缺损费', label: 'ETC设备缺损费' }, { value: '电费-客', label: '电费-客' }, { value: '未结算保养费', label: '未结算保养费' }, { value: '未结算维修费', label: '未结算维修费' }, { value: '车损费', label: '车损费' }, { value: '工具损坏或丢失费', label: '工具损坏或丢失费' }, { value: '证件费', label: '证件费' }, { value: '广告损坏费', label: '广告损坏费' }, { value: '送车服务费', label: '送车服务费' }, { value: '接车服务费', label: '接车服务费' }, { value: '补办行驶证', label: '补办行驶证' }, { value: '超赔险', label: '超赔险' }, { value: '轮胎磨损费', label: '轮胎磨损费' }, { value: '无忧包', label: '无忧包' }, { value: '轮胎保', label: '轮胎保' }, { value: '养护保', label: '养护保' }, { value: '尾板', label: '尾板' } - ]; - var updateExtraFeeRow = useCallback(function(index, field, value) { - _extraFeeList[1](function(prev) { - var list = prev.slice(); - var row = list[index] || {}; - var next = {}; - next[field] = value; - list[index] = Object.assign({}, row, next); - return list; - }); - }, []); - var filterLabelStyle = { marginBottom: 6, fontSize: 14, color: 'rgba(0,0,0,0.65)' }; var filterItemStyle = { marginBottom: 12 }; var filterControlStyle = { width: '100%' }; diff --git a/web端/车辆管理.jsx b/web端/车辆管理.jsx index ed7c405..66df30c 100644 --- a/web端/车辆管理.jsx +++ b/web端/车辆管理.jsx @@ -44,6 +44,8 @@ const Component = function () { var _detailTab = useState('型号参数'); var _filterExpanded = useState(false); var _requirementModalVisible = useState(false); + var _inspectImportModalVisible = useState(false); + var _inspectImportResult = useState(null); // 省-市 地区数据(示例) var regionOptions = [ @@ -127,6 +129,67 @@ const Component = function () { message.info('批量导入:请上传文件(原型演示)'); }, []); + var openInspectImportModal = useCallback(function () { + _inspectImportModalVisible[1](true); + _inspectImportResult[1](null); + }, []); + var closeInspectImportModal = useCallback(function () { + _inspectImportModalVisible[1](false); + _inspectImportResult[1](null); + }, []); + var downloadInspectTemplate = useCallback(function () { + var csv = '\uFEFF\u8F66\u724C\u53F7,\u7B49\u8BC4\u65F6\u95F4\n'; + var blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); + var url = URL.createObjectURL(blob); + var a = document.createElement('a'); + a.href = url; + a.download = '\u5BFC\u5165\u6A21\u677F_\u7B49\u8BC4\u65F6\u95F4.csv'; + a.click(); + URL.revokeObjectURL(url); + message.success('模板已下载'); + }, []); + var handleInspectImportUpload = useCallback(function (file) { + var reader = new FileReader(); + reader.onload = function (e) { + var text = e.target && e.target.result ? String(e.target.result) : ''; + var lines = text.split(/\r?\n/).filter(function (line) { return line.trim(); }); + var failedList = []; + if (lines.length > 0) { + var header = lines[0]; + for (var i = 1; i < Math.min(lines.length, 6); i++) { + var parts = lines[i].split(','); + var plateNo = (parts[0] || '').trim(); + var inspectTime = (parts[1] || '').trim(); + failedList.push({ plateNo: plateNo || '-', inspectTime: inspectTime || '-', reason: '\u8F66\u724C\u53F7\u4E0D\u5B58\u5728\u6216\u683C\u5F0F\u9519\u8BEF' }); + } + } + if (failedList.length === 0) failedList.push({ plateNo: '-', inspectTime: '-', reason: '\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF' }); + _inspectImportResult[1]({ hasFailed: true, failedList: failedList }); + }; + reader.readAsText(file, 'UTF-8'); + return false; + }, []); + var downloadInspectFailedCsv = useCallback(function () { + var result = _inspectImportResult[0]; + if (!result || !result.failedList || result.failedList.length === 0) return; + var escape = function (v) { + var s = v == null ? '' : String(v); + if (s.indexOf(',') !== -1 || s.indexOf('"') !== -1 || s.indexOf('\n') !== -1) return '"' + s.replace(/"/g, '""') + '"'; + return s; + }; + var header = '\u8F66\u724C\u53F7,\u7B49\u8BC4\u65F6\u95F4,\u5931\u8D25\u539F\u56E0'; + var rows = result.failedList.map(function (r) { return escape(r.plateNo) + ',' + escape(r.inspectTime) + ',' + escape(r.reason); }); + var csv = '\uFEFF' + header + '\n' + rows.join('\n'); + var blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); + var url = URL.createObjectURL(blob); + var a = document.createElement('a'); + a.href = url; + a.download = '\u7B49\u8BC4\u65F6\u95F4\u5BFC\u5165\u5931\u8D25\u8BB0\u5F55.csv'; + a.click(); + URL.revokeObjectURL(url); + message.success('失败记录已下载'); + }, [_inspectImportResult[0]]); + var goDetail = useCallback(function (record) { _detailRecord[1](record); }, []); @@ -505,7 +568,8 @@ const Component = function () { }), React.createElement(Space, null, React.createElement(Button, { onClick: handleExport }, '导出'), - React.createElement(Button, { onClick: handleBatchImport }, '批量导入') + React.createElement(Button, { onClick: handleBatchImport }, '批量导入'), + React.createElement(Button, { onClick: openInspectImportModal }, '批量导入等评时间') ) ), @@ -585,7 +649,28 @@ const Component = function () { onCancel: function () { _requirementModalVisible[1](false); }, width: 720, footer: React.createElement(Button, { onClick: function () { _requirementModalVisible[1](false); } }, '关闭') - }, React.createElement('div', { style: { maxHeight: 560, overflow: 'auto', whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6, color: 'rgba(0,0,0,0.85)' } }, requirementText)) + }, React.createElement('div', { style: { maxHeight: 560, overflow: 'auto', whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6, color: 'rgba(0,0,0,0.85)' } }, requirementText)), + + React.createElement(Modal, { + title: '批量导入等评时间', + open: _inspectImportModalVisible[0], + onCancel: closeInspectImportModal, + width: 520, + footer: React.createElement(Button, { onClick: closeInspectImportModal }, '关闭') + }, React.createElement('div', null, + React.createElement('div', { style: { marginBottom: 16 } }, + React.createElement(Upload.Dragger, { + accept: '.csv', + showUploadList: false, + beforeUpload: function (file) { handleInspectImportUpload(file); return false; } + }, React.createElement('p', { style: { margin: 0, padding: '16px 0' } }, '点击或拖拽 CSV 文件到此区域批量上传')), + React.createElement(Button, { type: 'link', onClick: downloadInspectTemplate, style: { marginTop: 8, padding: 0 } }, '下载导入模板') + ), + _inspectImportResult[0] && _inspectImportResult[0].hasFailed ? React.createElement('div', { style: { marginTop: 16, padding: 12, background: '#fff2f0', border: '1px solid #ffccc7', borderRadius: 4 } }, + React.createElement('span', { style: { color: 'rgba(0,0,0,0.85)' } }, '上传失败,'), + React.createElement('a', { href: '#', onClick: function (e) { e.preventDefault(); downloadInspectFailedCsv(); }, style: { color: '#1890ff' } }, '查看失败记录') + ) : null + )) ) ); }; diff --git a/web端/运维管理/基本数据维护/型号参数-新增.jsx b/web端/运维管理/基本数据维护/型号参数-新增.jsx index 98ccbc2..f5ad12f 100644 --- a/web端/运维管理/基本数据维护/型号参数-新增.jsx +++ b/web端/运维管理/基本数据维护/型号参数-新增.jsx @@ -16,8 +16,9 @@ const Component = function () { var message = antd.message; // 基本情况 - var brand = useState(''); + var brand = useState(undefined); var model = useState(''); + var announcementModel = useState(''); // 公告型号,必填 var vehicleType = useState(undefined); var fuelType = useState(undefined); var plateColor = useState('绿牌'); @@ -44,6 +45,15 @@ const Component = function () { var maintenanceList = useState([{ key: '1', item: '', kmCycle: '', monthCycle: '', laborCost: '', materialCost: '', total: '' }]); var formErrors = useState({}); + // 品牌选项(与型号参数.jsx 一致) + var brandOptions = [ + { value: '苏龙', label: '苏龙' }, + { value: '东风', label: '东风' }, + { value: '福田', label: '福田' }, + { value: '江淮', label: '江淮' }, + { value: '重汽', label: '重汽' }, + { value: '陕汽', label: '陕汽' } + ]; // 车辆类型选项与备车管理.jsx 保持一致 var vehicleTypeOptions = [ { value: '轻型厢式货车', label: '轻型厢式货车' }, @@ -105,8 +115,9 @@ const Component = function () { function validate() { var err = {}; - if (!String(brand[0] || '').trim()) err.brand = '请输入品牌名称'; + if (brand[0] == null || brand[0] === '') err.brand = '请选择品牌'; if (!String(model[0] || '').trim()) err.model = '请输入型号名称'; + if (!String(announcementModel[0] || '').trim()) err.announcementModel = '请输入公告型号'; if (vehicleType[0] == null || vehicleType[0] === '') err.vehicleType = '请选择车辆类型'; formErrors[1](err); return Object.keys(err).length === 0; @@ -187,18 +198,21 @@ const Component = function () { React.createElement(Card, { title: CardTitleWithBar('型号参数'), size: 'small', style: cardStyle }, React.createElement('div', { style: formRowStyle }, React.createElement(FormItem, { label: '品牌', required: true, error: formErrors[0].brand }, - React.createElement(Input, { placeholder: '请输入品牌名称', value: brand[0], onChange: function (e) { brand[1](e.target.value); }, style: inputStyle, status: formErrors[0].brand ? 'error' : undefined }) + React.createElement(Select, { placeholder: '请选择品牌', style: inputStyle, value: brand[0], onChange: function (v) { brand[1](v); }, allowClear: true, options: brandOptions, status: formErrors[0].brand ? 'error' : undefined }) ), React.createElement(FormItem, { label: '型号', required: true, error: formErrors[0].model }, React.createElement(Input, { placeholder: '请输入型号名称', value: model[0], onChange: function (e) { model[1](e.target.value); }, style: inputStyle, status: formErrors[0].model ? 'error' : undefined }) ), + React.createElement(FormItem, { label: '公告型号', required: true, error: formErrors[0].announcementModel }, + React.createElement(Input, { placeholder: '请输入公告型号', value: announcementModel[0], onChange: function (e) { announcementModel[1](e.target.value); }, style: inputStyle, status: formErrors[0].announcementModel ? 'error' : undefined }) + ), React.createElement(FormItem, { label: '车辆类型', required: true, error: formErrors[0].vehicleType }, React.createElement(Select, { placeholder: '请选择车辆类型', style: inputStyle, value: vehicleType[0], onChange: function (v) { vehicleType[1](v); }, allowClear: true, options: vehicleTypeOptions, status: formErrors[0].vehicleType ? 'error' : undefined }) ), React.createElement(FormItem, { label: '燃料种类' }, React.createElement(Select, { placeholder: '请选择燃料种类', style: inputStyle, value: fuelType[0], onChange: function (v) { fuelType[1](v); }, allowClear: true, options: fuelTypeOptions }) ), - React.createElement(FormItem, { label: '车厢颜色' }, + React.createElement(FormItem, { label: '车牌颜色' }, React.createElement(Radio.Group, { value: plateColor[0], onChange: function (e) { plateColor[1](e.target.value); } }, React.createElement(Radio, { value: '绿牌' }, '绿牌'), React.createElement(Radio, { value: '黄牌' }, '黄牌'), diff --git a/web端/运维管理/基本数据维护/型号参数-查看.jsx b/web端/运维管理/基本数据维护/型号参数-查看.jsx index fe3ed25..cd95117 100644 --- a/web端/运维管理/基本数据维护/型号参数-查看.jsx +++ b/web端/运维管理/基本数据维护/型号参数-查看.jsx @@ -15,10 +15,19 @@ const Component = function () { var Table = antd.Table; // 只读数据(示例,与车辆管理-查看型号参数一致) + var brandOptions = [ + { value: '苏龙', label: '苏龙' }, + { value: '东风', label: '东风' }, + { value: '福田', label: '福田' }, + { value: '江淮', label: '江淮' }, + { value: '重汽', label: '重汽' }, + { value: '陕汽', label: '陕汽' } + ]; var detail = useMemo(function () { return { brand: '苏龙', model: '海格牌KLQ5180XYKFCEV', + announcementModel: 'KLQ5180XYKFCEV', vehicleType: '18吨双飞翼货车', fuelType: '氢', plateColor: '绿牌', @@ -96,18 +105,21 @@ const Component = function () { React.createElement(Card, { title: CardTitleWithBar('型号参数'), size: 'small', style: cardStyle }, React.createElement('div', { style: formRowStyle }, React.createElement(FormItem, { label: '品牌' }, - React.createElement(Input, { value: detail.brand, disabled: true, style: inputStyle }) + React.createElement(Select, { value: detail.brand, disabled: true, style: inputStyle, options: brandOptions }) ), React.createElement(FormItem, { label: '型号' }, React.createElement(Input, { value: detail.model, disabled: true, style: inputStyle }) ), + React.createElement(FormItem, { label: '公告型号' }, + React.createElement(Input, { value: detail.announcementModel, disabled: true, style: inputStyle }) + ), React.createElement(FormItem, { label: '车辆类型' }, React.createElement(Input, { value: detail.vehicleType, disabled: true, style: inputStyle }) ), React.createElement(FormItem, { label: '燃料种类' }, React.createElement(Input, { value: detail.fuelType, disabled: true, style: inputStyle }) ), - React.createElement(FormItem, { label: '车厢颜色' }, + React.createElement(FormItem, { label: '车牌颜色' }, React.createElement(Radio.Group, { value: detail.plateColor, disabled: true }, React.createElement(Radio, { value: '绿牌' }, '绿牌'), React.createElement(Radio, { value: '黄牌' }, '黄牌'), diff --git a/web端/运维管理/基本数据维护/型号参数-编辑.jsx b/web端/运维管理/基本数据维护/型号参数-编辑.jsx index 9f39cdd..b921b09 100644 --- a/web端/运维管理/基本数据维护/型号参数-编辑.jsx +++ b/web端/运维管理/基本数据维护/型号参数-编辑.jsx @@ -18,6 +18,7 @@ const Component = function () { var initialData = { brand: '苏龙', model: '海格牌KLQ5180XYKFCEV', + announcementModel: 'KLQ5180XYKFCEV', vehicleType: '18吨双飞翼货车', fuelType: '氢', plateColor: '绿牌', @@ -42,6 +43,15 @@ const Component = function () { ] }; + // 品牌选项(与型号参数-新增一致) + var brandOptions = [ + { value: '苏龙', label: '苏龙' }, + { value: '东风', label: '东风' }, + { value: '福田', label: '福田' }, + { value: '江淮', label: '江淮' }, + { value: '重汽', label: '重汽' }, + { value: '陕汽', label: '陕汽' } + ]; // 车辆类型选项需包含初始值(18吨双飞翼货车) var vehicleTypeOptions = [ { value: '18吨双飞翼货车', label: '18吨双飞翼货车' }, @@ -68,6 +78,7 @@ const Component = function () { // 基本情况 var brand = useState(initialData.brand); var model = useState(initialData.model); + var announcementModel = useState(initialData.announcementModel || ''); var vehicleType = useState(initialData.vehicleType); var fuelType = useState(initialData.fuelType); var plateColor = useState(initialData.plateColor); @@ -133,8 +144,9 @@ const Component = function () { function validate() { var err = {}; - if (!String(brand[0] || '').trim()) err.brand = '请输入品牌名称'; + if (brand[0] == null || brand[0] === '') err.brand = '请选择品牌'; if (!String(model[0] || '').trim()) err.model = '请输入型号名称'; + if (!String(announcementModel[0] || '').trim()) err.announcementModel = '请输入公告型号'; if (vehicleType[0] == null || vehicleType[0] === '') err.vehicleType = '请选择车辆类型'; formErrors[1](err); return Object.keys(err).length === 0; @@ -215,18 +227,21 @@ const Component = function () { React.createElement(Card, { title: CardTitleWithBar('型号参数'), size: 'small', style: cardStyle }, React.createElement('div', { style: formRowStyle }, React.createElement(FormItem, { label: '品牌', required: true, error: formErrors[0].brand }, - React.createElement(Input, { placeholder: '请输入品牌名称', value: brand[0], onChange: function (e) { brand[1](e.target.value); }, style: inputStyle, status: formErrors[0].brand ? 'error' : undefined }) + React.createElement(Select, { placeholder: '请选择品牌', style: inputStyle, value: brand[0], onChange: function (v) { brand[1](v); }, allowClear: true, options: brandOptions, status: formErrors[0].brand ? 'error' : undefined }) ), React.createElement(FormItem, { label: '型号', required: true, error: formErrors[0].model }, React.createElement(Input, { placeholder: '请输入型号名称', value: model[0], onChange: function (e) { model[1](e.target.value); }, style: inputStyle, status: formErrors[0].model ? 'error' : undefined }) ), + React.createElement(FormItem, { label: '公告型号', required: true, error: formErrors[0].announcementModel }, + React.createElement(Input, { placeholder: '请输入公告型号', value: announcementModel[0], onChange: function (e) { announcementModel[1](e.target.value); }, style: inputStyle, status: formErrors[0].announcementModel ? 'error' : undefined }) + ), React.createElement(FormItem, { label: '车辆类型', required: true, error: formErrors[0].vehicleType }, React.createElement(Select, { placeholder: '请选择车辆类型', style: inputStyle, value: vehicleType[0], onChange: function (v) { vehicleType[1](v); }, allowClear: true, options: vehicleTypeOptions, status: formErrors[0].vehicleType ? 'error' : undefined }) ), React.createElement(FormItem, { label: '燃料种类' }, React.createElement(Select, { placeholder: '请选择燃料种类', style: inputStyle, value: fuelType[0], onChange: function (v) { fuelType[1](v); }, allowClear: true, options: fuelTypeOptions }) ), - React.createElement(FormItem, { label: '车厢颜色' }, + React.createElement(FormItem, { label: '车牌颜色' }, React.createElement(Radio.Group, { value: plateColor[0], onChange: function (e) { plateColor[1](e.target.value); } }, React.createElement(Radio, { value: '绿牌' }, '绿牌'), React.createElement(Radio, { value: '黄牌' }, '黄牌'), diff --git a/web端/运维管理/车辆业务/交车管理-交车单.jsx b/web端/运维管理/车辆业务/交车管理-交车单.jsx new file mode 100644 index 0000000..7c65a14 --- /dev/null +++ b/web端/运维管理/车辆业务/交车管理-交车单.jsx @@ -0,0 +1,225 @@ +// 【重要】必须使用 const Component 作为组件变量名 +// 交车管理 - 交车单(运维管理-车辆业务-交车管理-交车单) + +const Component = function () { + var useState = React.useState; + var useMemo = React.useMemo; + var useCallback = React.useCallback; + + var antd = window.antd; + var Breadcrumb = antd.Breadcrumb; + var Input = antd.Input; + var Button = antd.Button; + var Select = antd.Select; + var Table = antd.Table; + var DatePicker = antd.DatePicker; + var message = antd.message; + + // 项目详情(只读,来自交车任务/租赁合同) + var projectDetail = useMemo(function () { + return { + projectName: '嘉兴氢能示范项目', + contractCode: 'HT-ZL-2025-001', + customerName: '嘉兴某某物流有限公司', + expectedDate: '2025-02-28 至 2025-03-05', + deliveryRegion: '浙江省-嘉兴市', + deliveryAddress: '嘉兴市南湖区科技大道1号', + businessDept: '业务1部', + businessOwner: '张经理' + }; + }, []); + + // 备车库车辆选项(车牌号下拉仅能选备车库中车辆) + var reservePlateOptions = useMemo(function () { + return [ + { value: '京A12345', label: '京A12345' }, + { value: '京C11111', label: '京C11111' }, + { value: '京D22222', label: '京D22222' }, + { value: '浙A10001', label: '浙A10001' }, + { value: '浙F80088', label: '浙F80088' }, + { value: '沪A30003', label: '沪A30003' } + ]; + }, []); + + // 交车明细列表(序号、品牌、型号、车牌号可编辑、实际交车日期、交车人、交车状态、操作) + var detailListState = useState([ + { key: 1, seq: 1, brand: '东风', model: 'DFH1180', plateNo: '京A12345', actualDate: '2025-02-28', deliveryPerson: '张三', status: '已签章' }, + { key: 2, seq: 2, brand: '东风', model: 'DFH1250', plateNo: '京C11111', actualDate: '2025-02-28', deliveryPerson: '张三', status: '已签章' }, + { key: 3, seq: 3, brand: '福田', model: 'BJ1180', plateNo: '浙A10001', actualDate: '2025-03-01', deliveryPerson: '李四', status: '已签章' }, + { key: 4, seq: 4, brand: '福田', model: 'BJ1250', plateNo: '浙F80088', actualDate: '2025-03-01', deliveryPerson: '李四', status: '已签章' }, + { key: 5, seq: 5, brand: '重汽', model: 'HOWO-T5G', plateNo: '沪A30003', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已签章' }, + { key: 6, seq: 6, brand: '陕汽', model: '德龙X3000', plateNo: '京D22222', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已完成' }, + { key: 7, seq: 7, brand: '解放', model: 'J6P', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' }, + { key: 8, seq: 8, brand: '欧曼', model: 'EST-A', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' }, + { key: 9, seq: 9, brand: '江淮', model: '格尔发K7', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' }, + { key: 10, seq: 10, brand: '红岩', model: '杰狮C6', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' } + ]); + var detailList = detailListState[0]; + var setDetailList = detailListState[1]; + + var allSigned = useMemo(function () { + return detailList.length > 0 && detailList.every(function (row) { return row.status === '已签章'; }); + }, [detailList]); + + var updateDetailRow = useCallback(function (index, field, value) { + setDetailList(function (prev) { + var next = prev.slice(); + var row = next[index] || {}; + next[index] = Object.assign({}, row, { [field]: value }); + return next; + }); + }, []); + + var handleSubmit = useCallback(function () { + if (!allSigned) return; + message.success('提交成功(原型)'); + if (typeof window !== 'undefined' && window.history) window.history.back(); + }, [allSigned]); + + var handleCancel = useCallback(function () { + if (typeof window !== 'undefined' && window.history) window.history.back(); + else message.info('返回交车管理列表页'); + }, []); + + var handleViewDetail = useCallback(function (record) { + message.info('跳转该车辆交车明细(原型)'); + }, []); + + var handleEditDetail = useCallback(function (record, index) { + message.info('弹出卡片至交车明细编辑页(原型)'); + }, []); + + var handleDownloadSign = useCallback(function (record) { + message.success('下载签章文件(原型)'); + }, []); + + var card1Collapsed = useState(false)[0]; + var setCard1Collapsed = useState(false)[1]; + var card2Collapsed = useState(false)[0]; + var setCard2Collapsed = useState(false)[1]; + + var styles = { + page: { padding: '16px 24px 48px', backgroundColor: '#f5f5f5', minHeight: '100vh', fontFamily: '"PingFang SC", "苹方-简", -apple-system, BlinkMacSystemFont, "Microsoft YaHei", sans-serif', fontSize: 14 }, + breadcrumb: { marginBottom: 16, color: '#666' }, + breadcrumbSep: { margin: '0 8px', color: '#999' }, + card: { backgroundColor: '#fff', borderRadius: 8, marginBottom: 16, boxShadow: '0 1px 2px rgba(0,0,0,0.05)', overflow: 'hidden' }, + cardHeader: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '16px 20px', borderBottom: '1px solid #f0f0f0', cursor: 'pointer' }, + cardTitle: { fontSize: 16, fontWeight: 600, color: '#333' }, + cardToggle: { color: '#999', fontSize: 14 }, + cardBody: { padding: '20px 24px' }, + formRow: { display: 'flex', flexWrap: 'wrap', marginBottom: 16 }, + formCol: { flex: '0 0 33.33%', minWidth: 200, paddingRight: 16, marginBottom: 8 }, + formColFull: { flex: '0 0 100%', marginBottom: 8 }, + label: { display: 'block', marginBottom: 6, color: '#333' }, + inputDisabled: { width: '100%', backgroundColor: '#f5f5f5', color: 'rgba(0,0,0,0.65)', cursor: 'not-allowed', border: '1px solid #d9d9d9', borderRadius: 4, padding: '8px 12px', fontSize: 14 }, + footer: { position: 'fixed', bottom: 0, left: 0, right: 0, padding: '12px 24px', backgroundColor: '#fff', borderTop: '1px solid #e8e8e8', display: 'flex', gap: 12, justifyContent: 'flex-start', zIndex: 99 } + }; + + var CardBlock = function (props) { + return React.createElement('div', { id: props.id, style: styles.card }, + React.createElement('div', { style: styles.cardHeader, onClick: function () { props.setCollapsed(!props.collapsed); } }, + React.createElement('span', { style: styles.cardTitle }, props.title), + React.createElement('span', { style: styles.cardToggle }, props.collapsed ? '展开' : '收起') + ), + !props.collapsed ? React.createElement('div', { style: styles.cardBody }, props.children) : null + ); + }; + + var FormItem = function (props) { + var colStyle = props.fullWidth ? styles.formColFull : styles.formCol; + return React.createElement('div', { style: colStyle }, + React.createElement('label', { style: styles.label }, props.label), + props.children + ); + }; + + var columns = [ + { title: '序号', dataIndex: 'seq', key: 'seq', width: 70, render: function (v) { return v; } }, + { title: '品牌', dataIndex: 'brand', key: 'brand', width: 100, render: function (v) { return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } }); } }, + { title: '型号', dataIndex: 'model', key: 'model', width: 110, render: function (v) { return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } }); } }, + { + title: '车牌号', + dataIndex: 'plateNo', + key: 'plateNo', + width: 120, + render: function (v, record, index) { + return React.createElement(Select, { + placeholder: '请选择或搜索', + style: { width: '100%' }, + value: v || undefined, + onChange: function (val) { updateDetailRow(index, 'plateNo', val || ''); }, + showSearch: true, + allowClear: true, + options: reservePlateOptions, + filterOption: function (input, opt) { return (opt && opt.label && String(opt.label).toLowerCase().indexOf((input || '').toLowerCase()) >= 0); } + }); + } + }, + { + title: '实际交车日期', + dataIndex: 'actualDate', + key: 'actualDate', + width: 130, + render: function (v) { return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } }); } + }, + { + title: '交车人', + dataIndex: 'deliveryPerson', + key: 'deliveryPerson', + width: 90, + render: function (v) { return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } }); } + }, + { title: '交车状态', dataIndex: 'status', key: 'status', width: 90, render: function (v) { return v || '-'; } }, + { + title: '操作', + key: 'action', + width: 200, + fixed: 'right', + render: function (_, record, index) { + return React.createElement(React.Fragment, null, + React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleViewDetail(record); } }, '查看'), + record.status === '待提交' ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleEditDetail(record, index); } }, '编辑') : null, + record.status === '已签章' ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleDownloadSign(record); } }, '下载签章文件') : null + ); + } + } + ]; + + return React.createElement('div', { style: styles.page }, + React.createElement('div', { style: styles.breadcrumb }, + React.createElement('span', null, '运维管理'), + React.createElement('span', { style: styles.breadcrumbSep }, ' / '), + React.createElement('span', null, '车辆业务'), + React.createElement('span', { style: styles.breadcrumbSep }, ' / '), + React.createElement('span', null, '交车管理'), + React.createElement('span', { style: styles.breadcrumbSep }, ' / '), + React.createElement('span', { style: { color: '#1890ff' } }, '交车单') + ), + + React.createElement('div', { id: 'card-project' }, React.createElement(CardBlock, { id: 'card-project', title: '项目详情', collapsed: card1Collapsed, setCollapsed: setCard1Collapsed }, React.createElement('div', { style: styles.formRow }, + React.createElement(FormItem, { label: '项目名称' }, React.createElement(Input, { value: projectDetail.projectName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '合同编码' }, React.createElement(Input, { value: projectDetail.contractCode, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '客户名称' }, React.createElement(Input, { value: projectDetail.customerName, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '预计交车日期' }, React.createElement(Input, { value: projectDetail.expectedDate, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '交车区域' }, React.createElement(Input, { value: projectDetail.deliveryRegion, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '交车地点' }, React.createElement(Input, { value: projectDetail.deliveryAddress, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '业务部门' }, React.createElement(Input, { value: projectDetail.businessDept, disabled: true, style: styles.inputDisabled })), + React.createElement(FormItem, { label: '业务负责人' }, React.createElement(Input, { value: projectDetail.businessOwner, disabled: true, style: styles.inputDisabled })) + ))), + + React.createElement('div', { id: 'card-detail', style: { marginTop: 16 } }, React.createElement(CardBlock, { id: 'card-detail', title: '交车明细', collapsed: card2Collapsed, setCollapsed: setCard2Collapsed }, React.createElement(Table, { + columns: columns, + dataSource: detailList, + rowKey: 'key', + pagination: false, + size: 'small', + scroll: { x: 920 } + }))), + + React.createElement('div', { style: { height: 60 } }), + React.createElement('div', { style: styles.footer }, + React.createElement(Button, { type: 'primary', disabled: !allSigned, onClick: handleSubmit }, '提交'), + React.createElement(Button, { onClick: handleCancel }, '取消') + ) + ); +}; diff --git a/web端/运维管理/车辆业务/交车管理.jsx b/web端/运维管理/车辆业务/交车管理.jsx index db935ce..55bb090 100644 --- a/web端/运维管理/车辆业务/交车管理.jsx +++ b/web端/运维管理/车辆业务/交车管理.jsx @@ -52,7 +52,7 @@ const Component = function () { var requirementModalOpen = useState(false); var setRequirementModalOpen = requirementModalOpen[1]; - var requirementDocContent = '交车管理\n\n1.面包屑:\n1.1.运维管理-车辆业务-交车管理\n\n2.筛选:\n2.1.合同编码:选择器,默认为所有合同;提示信息为:请输入或选择合同编码,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n2.2.项目名称:选择器,默认为所有项目;提示信息为:请输入或选择项目名称,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n3.3.客户名称:选择器,默认为所有客户;提示信息为:请输入或选择客户名称,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n3.4.交车区域:地区选择器,支持省-市2级筛选;\n3.5.交车时间:日期选择器,默认提示信息为:请选择交车开始时间 请选择交车结束时间,单输入框,双日历,支持时间段选择,精确至天,格式为:YYYY-MM-DD - YYYY-MM-DD;\n3.6.交车人:选择器,默认为所有交车人;提示信息为:请输入或选择交车人姓名,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n3.7.查询:点击查询,根据单个或多个筛选条件(且)联动表格进行查询;\n3.8.重置:点击清空查询条件至默认;\n\n3.列表:\n分为两个tab:待处理、历史记录\n3.1.待处理:显示以下字段:\n3.1.1.预计交车时间:支持单日及开始-结束日期两种方式,格式为:YYYY-MM-DD及YYYY-MM-DD至YYYY-MM-DD,取自对应交车任务中预计交车时间;\n3.1.2.任务发布时间:显示交车任务单生成时间,格式为:YYYY-MM-DD HH:MM;\n3.1.3.合同编码:显示租赁/自营合同编码;\n3.1.4.项目名称:显示租赁/自营合同项目名称;\n3.1.5.客户名称:显示租赁/自营合同客户名称;\n3.1.6.交车数量:显示交车数量,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号;\n 3.1.6.1.车辆类型:显示车辆类型;\n 3.1.6.2.品牌:显示车辆品牌;\n 3.1.6.3.型号:显示车辆型号;\n 3.1.6.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-;\n3.1.7.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市;\n3.1.8.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址;\n3.1.9.操作:查看、交车;\n 3.1.8.1.交车:点击跳转交车单页面;\n\n3.2.历史记录:显示以下字段:\n3.2.1.预计交车时间:支持单日及开始-结束日期两种方式,格式为:YYYY-MM-DD及YYYY-MM-DD至YYYY-MM-DD,取自对应交车任务中预计交车时间;\n3.2.2.任务发布时间:显示交车任务单生成时间,格式为:YYYY-MM-DD HH:MM;\n3.2.3.交车完成时间:显示交车单完成时间,格式为:YYYY-MM-DD HH:MM;\n3.2.4.交车人:显示交车单最终提交用户;\n3.2.5.合同编码:显示租赁/自营合同编码;\n3.2.6.项目名称:显示租赁/自营合同项目名称;\n3.2.7.客户名称:显示租赁/自营合同客户名称;\n3.2.8.交车数量:显示交车数,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号、实际交车日期、交车人;\n 3.2.8.1.车辆类型:显示车辆类型;\n 3.2.8.2.品牌:显示车辆品牌;\n 3.2.8.3.型号:显示车辆型号;\n 3.2.8.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-;\n 3.2.8.5.实际交车日期:显示实际交车日期,格式为YYYY-MM-DD,如该车还未交车则显示为-;\n 3.2.8.6.交车人:显示实际交车人用户姓名,如该车还未还车则显示为-;\n3.2.9.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市;\n3.2.10.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址;\n3.2.11.操作:查看;\n 3.2.11.1.查看:点击跳转查看交车单页面;'; + var requirementDocContent = '交车管理\n一个「数字化资产ONEOS运管平台」中的「交车管理」模块\n\n1.面包屑:\n1.1.运维管理-车辆业务-交车管理\n\n2.筛选:\n2.1.合同编码:选择器,默认为所有合同;提示信息为:请输入或选择合同编码,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n2.2.项目名称:选择器,默认为所有项目;提示信息为:请输入或选择项目名称,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n2.3.客户名称:选择器,默认为所有客户;提示信息为:请输入或选择客户名称,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n2.4.交车区域:地区选择器,支持省-市2级筛选;\n2.5.交车时间:日期选择器,默认提示信息为:请选择交车开始时间 请选择交车结束时间,单输入框,双日历,支持时间段选择,精确至天,格式为:YYYY-MM-DD - YYYY-MM-DD;\n2.6.交车人:选择器,默认为所有交车人;提示信息为:请输入或选择交车人姓名,支持从输入框输入内容进行模糊搜索,下拉显示结果;\n2.7.查询:点击查询,根据单个或多个筛选条件(且)联动表格进行查询;\n2.8.重置:点击清空查询条件至默认;\n\n3.列表:分为两个tab:待处理、历史记录,默认显示为待处理tab;\n3.1.待处理tab:列表显示预计交车时间、合同编码、项目名称、客户名称、交车区域、交车地点、交车数量(重点色,点击气泡卡片:车辆类型、品牌、型号、车牌号、交车时间、交车人员)、创建时间、创建人、最后修改时间、最后修改人、操作(查看、交车单);\n3.2.历史记录tab:同列,操作仅 查看(跳转交车管理-查看页)。'; // 交车区域:省-市 二级 var regionOptions = [ @@ -82,33 +82,33 @@ const Component = function () { { value: '王五', label: '王五' } ]; - // 待处理 mock(10条样例) + // 待处理 mock:含创建时间、创建人、最后修改时间、最后修改人;vehicleList 含交车时间、交车人员(未交车为-) var pendingListState = useState([ - { id: 'd1', expectedDate: '2025-02-28', taskPublishTime: '2025-02-20 09:00', contractCode: 'HT-ZL-2025-001', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '京A12345' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '-' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区科技大道1号' }, - { id: 'd2', expectedDate: '2025-03-01 至 2025-03-05', taskPublishTime: '2025-02-21 10:30', contractCode: 'HT-ZL-2025-002', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '-' }], deliveryRegion: '上海市-上海市', deliveryAddress: '浦东新区张江高科技园区' }, - { id: 'd3', expectedDate: '2025-02-25', taskPublishTime: '2025-02-18 14:00', contractCode: 'HT-ZL-2025-003', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 3, vehicleList: [{ vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '浙A10001' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '-' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '余杭区未来科技城' }, - { id: 'd4', expectedDate: '2025-03-08', taskPublishTime: '2025-02-25 08:15', contractCode: 'HT-ZL-2025-004', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1160', plateNo: '-' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市秀洲区洪兴西路288号' }, - { id: 'd5', expectedDate: '2025-03-10 至 2025-03-12', taskPublishTime: '2025-02-26 11:20', contractCode: 'HT-ZL-2025-005', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 2, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '-' }, { vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '-' }], deliveryRegion: '上海市-上海市', deliveryAddress: '闵行区莘庄工业区申富路669号' }, - { id: 'd6', expectedDate: '2025-03-15', taskPublishTime: '2025-03-01 09:30', contractCode: 'HT-ZL-2025-006', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 4, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '-' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '-' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '-' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '萧山区市心北路108号' }, - { id: 'd7', expectedDate: '2025-03-18', taskPublishTime: '2025-03-03 14:00', contractCode: 'HT-ZL-2025-007', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙F80088' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市经开区昌盛路1号' }, - { id: 'd8', expectedDate: '2025-03-20 至 2025-03-22', taskPublishTime: '2025-03-05 10:00', contractCode: 'HT-ZL-2025-008', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 3, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1190', plateNo: '-' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1190', plateNo: '-' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '-' }], deliveryRegion: '上海市-上海市', deliveryAddress: '宝山区沪太路5008号' }, - { id: 'd9', expectedDate: '2025-03-25', taskPublishTime: '2025-03-08 08:45', contractCode: 'HT-ZL-2025-009', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 2, vehicleList: [{ vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙A20002' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '滨江区网商路699号' }, - { id: 'd10', expectedDate: '2025-03-28', taskPublishTime: '2025-03-10 16:20', contractCode: 'HT-ZL-2025-010', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1180', plateNo: '-' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区广益路与由拳路交叉口' } + { id: 'd1', expectedDate: '2025-02-28', contractCode: 'HT-ZL-2025-001', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区科技大道1号', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '京A12345', deliveryTime: '2025-02-28', deliveryPerson: '张三' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-02-20 09:00', createBy: '系统', lastModifyTime: '2025-02-22 14:30', lastModifyBy: '李四', assignedDeliveryPerson: '张三' }, + { id: 'd2', expectedDate: '2025-03-01 至 2025-03-05', contractCode: 'HT-ZL-2025-002', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '浦东新区张江高科技园区', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-02-21 10:30', createBy: '王五', lastModifyTime: '2025-02-21 10:30', lastModifyBy: '王五', assignedDeliveryPerson: '李四' }, + { id: 'd3', expectedDate: '2025-02-25', contractCode: 'HT-ZL-2025-003', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '余杭区未来科技城', deliveryCount: 3, vehicleList: [{ vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '浙A10001', deliveryTime: '2025-02-25', deliveryPerson: '张三' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-02-18 14:00', createBy: '李四', lastModifyTime: '2025-02-24 11:00', lastModifyBy: '王五', assignedDeliveryPerson: '张三' }, + { id: 'd4', expectedDate: '2025-03-08', contractCode: 'HT-ZL-2025-004', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市秀洲区洪兴西路288号', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1160', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-02-25 08:15', createBy: '张三', lastModifyTime: '2025-02-25 08:15', lastModifyBy: '张三', assignedDeliveryPerson: '李四' }, + { id: 'd5', expectedDate: '2025-03-10 至 2025-03-12', contractCode: 'HT-ZL-2025-005', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '闵行区莘庄工业区申富路669号', deliveryCount: 2, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-02-26 11:20', createBy: '王五', lastModifyTime: '2025-02-26 11:20', lastModifyBy: '王五', assignedDeliveryPerson: '王五' }, + { id: 'd6', expectedDate: '2025-03-15', contractCode: 'HT-ZL-2025-006', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '萧山区市心北路108号', deliveryCount: 4, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-03-01 09:30', createBy: '李四', lastModifyTime: '2025-03-01 09:30', lastModifyBy: '李四', assignedDeliveryPerson: '张三' }, + { id: 'd7', expectedDate: '2025-03-18', contractCode: 'HT-ZL-2025-007', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市经开区昌盛路1号', deliveryCount: 1, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙F80088', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-03-03 14:00', createBy: '张三', lastModifyTime: '2025-03-05 10:00', lastModifyBy: '李四', assignedDeliveryPerson: '李四' }, + { id: 'd8', expectedDate: '2025-03-20 至 2025-03-22', contractCode: 'HT-ZL-2025-008', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '宝山区沪太路5008号', deliveryCount: 3, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-03-05 10:00', createBy: '王五', lastModifyTime: '2025-03-05 10:00', lastModifyBy: '王五', assignedDeliveryPerson: '王五' }, + { id: 'd9', expectedDate: '2025-03-25', contractCode: 'HT-ZL-2025-009', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '滨江区网商路699号', deliveryCount: 2, vehicleList: [{ vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙A20002', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-03-08 08:45', createBy: '李四', lastModifyTime: '2025-03-08 08:45', lastModifyBy: '李四', assignedDeliveryPerson: '张三' }, + { id: 'd10', expectedDate: '2025-03-28', contractCode: 'HT-ZL-2025-010', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区广益路与由拳路交叉口', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1180', plateNo: '-', deliveryTime: '-', deliveryPerson: '-' }], createTime: '2025-03-10 16:20', createBy: '张三', lastModifyTime: '2025-03-10 16:20', lastModifyBy: '张三', assignedDeliveryPerson: '李四' } ]); var pendingList = pendingListState[0]; - // 历史记录 mock(10条样例,含交车完成时间、交车人,vehicleList 含实际交车日期、交车人) + // 历史记录 mock:与待处理同结构,含创建时间、创建人、最后修改时间、最后修改人;vehicleList 含交车时间(actualDate)、交车人员(deliveryPerson) var historyListState = useState([ - { id: 'h1', expectedDate: '2025-02-15', taskPublishTime: '2025-02-10 09:00', completeTime: '2025-02-15 14:30', deliveryPerson: '张三', contractCode: 'HT-ZL-2024-001', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '京A12345', actualDate: '2025-02-15', deliveryPerson: '张三' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '京C11111', actualDate: '2025-02-15', deliveryPerson: '李四' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区科技大道1号' }, - { id: 'h2', expectedDate: '2025-02-10 至 2025-02-12', taskPublishTime: '2025-02-05 10:00', completeTime: '2025-02-12 11:00', deliveryPerson: '王五', contractCode: 'HT-ZL-2024-002', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '沪A20002', actualDate: '2025-02-11', deliveryPerson: '王五' }], deliveryRegion: '上海市-上海市', deliveryAddress: '浦东新区张江路100号' }, - { id: 'h3', expectedDate: '2025-02-18', taskPublishTime: '2025-02-12 08:30', completeTime: '2025-02-18 15:00', deliveryPerson: '张三', contractCode: 'HT-ZL-2024-003', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 3, vehicleList: [{ vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '浙A10001', actualDate: '2025-02-18', deliveryPerson: '张三' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '浙A10002', actualDate: '2025-02-18', deliveryPerson: '李四' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '浙A10003', actualDate: '2025-02-18', deliveryPerson: '王五' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '余杭区未来科技城' }, - { id: 'h4', expectedDate: '2025-02-20', taskPublishTime: '2025-02-14 11:00', completeTime: '2025-02-20 10:15', deliveryPerson: '李四', contractCode: 'HT-ZL-2024-004', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '浙F60001', actualDate: '2025-02-20', deliveryPerson: '李四' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市秀洲区洪兴西路288号' }, - { id: 'h5', expectedDate: '2025-02-22 至 2025-02-24', taskPublishTime: '2025-02-16 09:45', completeTime: '2025-02-24 16:30', deliveryPerson: '王五', contractCode: 'HT-ZL-2024-005', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 2, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '沪B30001', actualDate: '2025-02-23', deliveryPerson: '王五' }, { vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '沪B30002', actualDate: '2025-02-24', deliveryPerson: '张三' }], deliveryRegion: '上海市-上海市', deliveryAddress: '闵行区莘庄工业区申富路669号' }, - { id: 'h6', expectedDate: '2025-02-25', taskPublishTime: '2025-02-18 14:20', completeTime: '2025-02-25 11:00', deliveryPerson: '张三', contractCode: 'HT-ZL-2024-006', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1160', plateNo: '浙A40001', actualDate: '2025-02-25', deliveryPerson: '张三' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '萧山区市心北路108号' }, - { id: 'h7', expectedDate: '2025-02-28', taskPublishTime: '2025-02-20 10:10', completeTime: '2025-02-28 14:45', deliveryPerson: '李四', contractCode: 'HT-ZL-2024-007', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '浙F70001', actualDate: '2025-02-28', deliveryPerson: '李四' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙F70002', actualDate: '2025-02-28', deliveryPerson: '王五' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市经开区昌盛路1号' }, - { id: 'h8', expectedDate: '2025-03-02', taskPublishTime: '2025-02-22 08:00', completeTime: '2025-03-02 09:30', deliveryPerson: '王五', contractCode: 'HT-ZL-2024-008', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryCount: 1, vehicleList: [{ vehicleType: '栏板货车', brand: '江淮', model: 'HFC1160', plateNo: '沪A50001', actualDate: '2025-03-02', deliveryPerson: '王五' }], deliveryRegion: '上海市-上海市', deliveryAddress: '宝山区沪太路5008号' }, - { id: 'h9', expectedDate: '2025-03-05 至 2025-03-07', taskPublishTime: '2025-02-25 15:30', completeTime: '2025-03-07 13:20', deliveryPerson: '张三', contractCode: 'HT-ZL-2024-009', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1190', plateNo: '浙A60001', actualDate: '2025-03-06', deliveryPerson: '张三' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1190', plateNo: '浙A60002', actualDate: '2025-03-07', deliveryPerson: '李四' }], deliveryRegion: '浙江省-杭州市', deliveryAddress: '滨江区网商路699号' }, - { id: 'h10', expectedDate: '2025-03-10', taskPublishTime: '2025-03-01 11:00', completeTime: '2025-03-10 10:00', deliveryPerson: '李四', contractCode: 'HT-ZL-2024-010', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryCount: 1, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '浙F90001', actualDate: '2025-03-10', deliveryPerson: '李四' }], deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区广益路与由拳路交叉口' } + { id: 'h1', expectedDate: '2025-02-15', contractCode: 'HT-ZL-2024-001', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区科技大道1号', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '京A12345', actualDate: '2025-02-15', deliveryPerson: '张三' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '京C11111', actualDate: '2025-02-15', deliveryPerson: '李四' }], createTime: '2025-02-10 09:00', createBy: '系统', lastModifyTime: '2025-02-15 14:30', lastModifyBy: '张三' }, + { id: 'h2', expectedDate: '2025-02-10 至 2025-02-12', contractCode: 'HT-ZL-2024-002', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '浦东新区张江路100号', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '沪A20002', actualDate: '2025-02-11', deliveryPerson: '王五' }], createTime: '2025-02-05 10:00', createBy: '王五', lastModifyTime: '2025-02-12 11:00', lastModifyBy: '王五' }, + { id: 'h3', expectedDate: '2025-02-18', contractCode: 'HT-ZL-2024-003', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '余杭区未来科技城', deliveryCount: 3, vehicleList: [{ vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1180', plateNo: '浙A10001', actualDate: '2025-02-18', deliveryPerson: '张三' }, { vehicleType: '厢式货车', brand: '东风', model: 'DFH1190', plateNo: '浙A10002', actualDate: '2025-02-18', deliveryPerson: '李四' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '浙A10003', actualDate: '2025-02-18', deliveryPerson: '王五' }], createTime: '2025-02-12 08:30', createBy: '李四', lastModifyTime: '2025-02-18 15:00', lastModifyBy: '张三' }, + { id: 'h4', expectedDate: '2025-02-20', contractCode: 'HT-ZL-2024-004', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市秀洲区洪兴西路288号', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1180', plateNo: '浙F60001', actualDate: '2025-02-20', deliveryPerson: '李四' }], createTime: '2025-02-14 11:00', createBy: '张三', lastModifyTime: '2025-02-20 10:15', lastModifyBy: '李四' }, + { id: 'h5', expectedDate: '2025-02-22 至 2025-02-24', contractCode: 'HT-ZL-2024-005', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '闵行区莘庄工业区申富路669号', deliveryCount: 2, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '沪B30001', actualDate: '2025-02-23', deliveryPerson: '王五' }, { vehicleType: '栏板货车', brand: '东风', model: 'DFH1160', plateNo: '沪B30002', actualDate: '2025-02-24', deliveryPerson: '张三' }], createTime: '2025-02-16 09:45', createBy: '李四', lastModifyTime: '2025-02-24 16:30', lastModifyBy: '王五' }, + { id: 'h6', expectedDate: '2025-02-25', contractCode: 'HT-ZL-2024-006', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '萧山区市心北路108号', deliveryCount: 1, vehicleList: [{ vehicleType: '厢式货车', brand: '重汽', model: 'ZZ1160', plateNo: '浙A40001', actualDate: '2025-02-25', deliveryPerson: '张三' }], createTime: '2025-02-18 14:20', createBy: '王五', lastModifyTime: '2025-02-25 11:00', lastModifyBy: '张三' }, + { id: 'h7', expectedDate: '2025-02-28', contractCode: 'HT-ZL-2024-007', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市经开区昌盛路1号', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', plateNo: '浙F70001', actualDate: '2025-02-28', deliveryPerson: '李四' }, { vehicleType: '平板货车', brand: '福田', model: 'BJ1180', plateNo: '浙F70002', actualDate: '2025-02-28', deliveryPerson: '王五' }], createTime: '2025-02-20 10:10', createBy: '张三', lastModifyTime: '2025-02-28 14:45', lastModifyBy: '李四' }, + { id: 'h8', expectedDate: '2025-03-02', contractCode: 'HT-ZL-2024-008', projectName: '上海物流租赁项目', customerName: '上海某某运输公司', deliveryRegion: '上海市-上海市', deliveryAddress: '宝山区沪太路5008号', deliveryCount: 1, vehicleList: [{ vehicleType: '栏板货车', brand: '江淮', model: 'HFC1160', plateNo: '沪A50001', actualDate: '2025-03-02', deliveryPerson: '王五' }], createTime: '2025-02-22 08:00', createBy: '李四', lastModifyTime: '2025-03-02 09:30', lastModifyBy: '王五' }, + { id: 'h9', expectedDate: '2025-03-05 至 2025-03-07', contractCode: 'HT-ZL-2024-009', projectName: '杭州城配租赁项目', customerName: '杭州某某租赁有限公司', deliveryRegion: '浙江省-杭州市', deliveryAddress: '滨江区网商路699号', deliveryCount: 2, vehicleList: [{ vehicleType: '厢式货车', brand: '江淮', model: 'HFC1190', plateNo: '浙A60001', actualDate: '2025-03-06', deliveryPerson: '张三' }, { vehicleType: '栏板货车', brand: '重汽', model: 'ZZ1190', plateNo: '浙A60002', actualDate: '2025-03-07', deliveryPerson: '李四' }], createTime: '2025-02-25 15:30', createBy: '王五', lastModifyTime: '2025-03-07 13:20', lastModifyBy: '张三' }, + { id: 'h10', expectedDate: '2025-03-10', contractCode: 'HT-ZL-2024-010', projectName: '嘉兴氢能示范项目', customerName: '嘉兴某某物流有限公司', deliveryRegion: '浙江省-嘉兴市', deliveryAddress: '嘉兴市南湖区广益路与由拳路交叉口', deliveryCount: 1, vehicleList: [{ vehicleType: '平板货车', brand: '福田', model: 'BJ1190', plateNo: '浙F90001', actualDate: '2025-03-10', deliveryPerson: '李四' }], createTime: '2025-03-01 11:00', createBy: '张三', lastModifyTime: '2025-03-10 10:00', lastModifyBy: '李四' } ]); var historyList = historyListState[0]; @@ -120,6 +120,7 @@ const Component = function () { if (appliedFilters.deliveryRegion) list = list.filter(function (r) { return (r.deliveryRegion || '').indexOf(appliedFilters.deliveryRegion) !== -1; }); if (appliedFilters.dateStart) list = list.filter(function (r) { var d = (r.expectedDate || '').slice(0, 10); return d >= appliedFilters.dateStart; }); if (appliedFilters.dateEnd) list = list.filter(function (r) { var d = (r.expectedDate || '').slice(0, 10); return d <= appliedFilters.dateEnd; }); + if (appliedFilters.deliveryPerson) list = list.filter(function (r) { return (r.assignedDeliveryPerson || '').indexOf(appliedFilters.deliveryPerson) !== -1; }); return list; }, [pendingList, appliedFilters]); @@ -129,9 +130,9 @@ const Component = function () { if (appliedFilters.projectName) list = list.filter(function (r) { return r.projectName === appliedFilters.projectName; }); if (appliedFilters.customerName) list = list.filter(function (r) { return r.customerName === appliedFilters.customerName; }); if (appliedFilters.deliveryRegion) list = list.filter(function (r) { return (r.deliveryRegion || '').indexOf(appliedFilters.deliveryRegion) !== -1; }); - if (appliedFilters.dateStart) list = list.filter(function (r) { var d = (r.completeTime || '').slice(0, 10); return d >= appliedFilters.dateStart; }); - if (appliedFilters.dateEnd) list = list.filter(function (r) { var d = (r.completeTime || '').slice(0, 10); return d <= appliedFilters.dateEnd; }); - if (appliedFilters.deliveryPerson) list = list.filter(function (r) { return (r.deliveryPerson || '').indexOf(appliedFilters.deliveryPerson) !== -1; }); + if (appliedFilters.dateStart) list = list.filter(function (r) { var d = (r.expectedDate || '').slice(0, 10); return d >= appliedFilters.dateStart; }); + if (appliedFilters.dateEnd) list = list.filter(function (r) { var d = (r.expectedDate || '').slice(0, 10); return d <= appliedFilters.dateEnd; }); + if (appliedFilters.deliveryPerson) list = list.filter(function (r) { return (r.lastModifyBy || '').indexOf(appliedFilters.deliveryPerson) !== -1; }); return list; }, [historyList, appliedFilters]); @@ -189,18 +190,10 @@ const Component = function () { if (s.indexOf(',') !== -1 || s.indexOf('"') !== -1 || s.indexOf('\n') !== -1) return '"' + s.replace(/"/g, '""') + '"'; return s; }; - var headers; + var headers = ['预计交车时间', '合同编码', '项目名称', '客户名称', '交车区域', '交车地点', '交车数量', '创建时间', '创建人', '最后修改时间', '最后修改人']; var rowToCells = function (r) { - if (activeTab === 'pending') { - return [r.expectedDate, r.taskPublishTime, r.contractCode, r.projectName, r.customerName, r.deliveryCount, r.deliveryRegion, r.deliveryAddress]; - } - return [r.expectedDate, r.taskPublishTime, r.completeTime, r.deliveryPerson, r.contractCode, r.projectName, r.customerName, r.deliveryCount, r.deliveryRegion, r.deliveryAddress]; + return [r.expectedDate, r.contractCode, r.projectName, r.customerName, r.deliveryRegion, r.deliveryAddress, r.deliveryCount, r.createTime, r.createBy, r.lastModifyTime, r.lastModifyBy]; }; - if (activeTab === 'pending') { - headers = ['预计交车时间', '任务发布时间', '合同编码', '项目名称', '客户名称', '交车数量', '交车区域', '交车地点']; - } else { - headers = ['预计交车时间', '任务发布时间', '交车完成时间', '交车人', '合同编码', '项目名称', '客户名称', '交车数量', '交车区域', '交车地点']; - } var csv = headers.map(escapeCsv).join(',') + '\n'; rows.forEach(function (r) { csv += rowToCells(r).map(escapeCsv).join(',') + '\n'; @@ -255,9 +248,10 @@ const Component = function () { var popoverThStyle = { padding: '6px 8px', textAlign: 'left', borderBottom: '1px solid #f0f0f0', backgroundColor: '#fafafa', fontWeight: 600 }; var popoverTdStyle = { padding: '6px 8px', borderBottom: '1px solid #f0f0f0' }; + // 气泡卡片:车辆类型、品牌、型号、车牌号、交车时间、交车人员(待处理用 deliveryTime/deliveryPerson,未交车为-) function renderPendingQuantity(record) { var list = record.vehicleList || []; - var content = React.createElement('div', { style: { padding: 8, minWidth: 320 } }, + var content = React.createElement('div', { style: { padding: 8, minWidth: 420 } }, React.createElement('div', { style: { marginBottom: 8, fontWeight: 600 } }, '车辆明细'), React.createElement('table', { style: popoverTableStyle }, React.createElement('thead', null, @@ -265,7 +259,9 @@ const Component = function () { React.createElement('th', { style: popoverThStyle }, '车辆类型'), React.createElement('th', { style: popoverThStyle }, '品牌'), React.createElement('th', { style: popoverThStyle }, '型号'), - React.createElement('th', { style: popoverThStyle }, '车牌号') + React.createElement('th', { style: popoverThStyle }, '车牌号'), + React.createElement('th', { style: popoverThStyle }, '交车时间'), + React.createElement('th', { style: popoverThStyle }, '交车人员') ) ), React.createElement('tbody', null, @@ -274,7 +270,9 @@ const Component = function () { React.createElement('td', { style: popoverTdStyle }, v.vehicleType || '-'), React.createElement('td', { style: popoverTdStyle }, v.brand || '-'), React.createElement('td', { style: popoverTdStyle }, v.model || '-'), - React.createElement('td', { style: popoverTdStyle }, v.plateNo || '-') + React.createElement('td', { style: popoverTdStyle }, v.plateNo || '-'), + React.createElement('td', { style: popoverTdStyle }, (v.deliveryTime && v.deliveryTime !== '-') ? v.deliveryTime : '-'), + React.createElement('td', { style: popoverTdStyle }, v.deliveryPerson || '-') ); }) ) @@ -285,6 +283,7 @@ const Component = function () { ); } + // 气泡卡片:车辆类型、品牌、型号、车牌号、交车时间、交车人员(历史用 actualDate、deliveryPerson) function renderHistoryQuantity(record) { var list = record.vehicleList || []; var content = React.createElement('div', { style: { padding: 8, minWidth: 420 } }, @@ -296,8 +295,8 @@ const Component = function () { React.createElement('th', { style: popoverThStyle }, '品牌'), React.createElement('th', { style: popoverThStyle }, '型号'), React.createElement('th', { style: popoverThStyle }, '车牌号'), - React.createElement('th', { style: popoverThStyle }, '实际交车日期'), - React.createElement('th', { style: popoverThStyle }, '交车人') + React.createElement('th', { style: popoverThStyle }, '交车时间'), + React.createElement('th', { style: popoverThStyle }, '交车人员') ) ), React.createElement('tbody', null, @@ -319,33 +318,42 @@ const Component = function () { ); } + // 待处理:预计交车时间、合同编码、项目名称、客户名称、交车区域、交车地点、交车数量、创建时间、创建人、最后修改时间、最后修改人、操作(查看、交车单) var pendingColumns = [ - { title: '预计交车时间', dataIndex: 'expectedDate', key: 'expectedDate', width: 260, ellipsis: true }, - { title: '任务发布时间', dataIndex: 'taskPublishTime', key: 'taskPublishTime', width: 160, ellipsis: true }, - { title: '合同编码', dataIndex: 'contractCode', key: 'contractCode', width: 160, ellipsis: true }, - { title: '项目名称', dataIndex: 'projectName', key: 'projectName', width: 160, ellipsis: true }, - { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 180, ellipsis: true }, - { title: '交车数量', key: 'deliveryCount', width: 100, render: function (_, r) { return renderPendingQuantity(r); } }, - { title: '交车区域', dataIndex: 'deliveryRegion', key: 'deliveryRegion', width: 130, ellipsis: true }, - { title: '交车地点', dataIndex: 'deliveryAddress', key: 'deliveryAddress', width: 220, ellipsis: true }, - { title: '操作', key: 'action', width: 80, fixed: 'right', render: function (_, r) { - return React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('跳转查看交车单'); } }, '查看'); + { title: '预计交车时间', dataIndex: 'expectedDate', key: 'expectedDate', width: 220, ellipsis: true }, + { title: '合同编码', dataIndex: 'contractCode', key: 'contractCode', width: 150, ellipsis: true }, + { title: '项目名称', dataIndex: 'projectName', key: 'projectName', width: 150, ellipsis: true }, + { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 160, ellipsis: true }, + { title: '交车区域', dataIndex: 'deliveryRegion', key: 'deliveryRegion', width: 120, ellipsis: true }, + { title: '交车地点', dataIndex: 'deliveryAddress', key: 'deliveryAddress', width: 200, ellipsis: true }, + { title: '交车数量', key: 'deliveryCount', width: 90, render: function (_, r) { return renderPendingQuantity(r); } }, + { title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 160, ellipsis: true }, + { title: '创建人', dataIndex: 'createBy', key: 'createBy', width: 90, ellipsis: true }, + { title: '最后修改时间', dataIndex: 'lastModifyTime', key: 'lastModifyTime', width: 160, ellipsis: true }, + { title: '最后修改人', dataIndex: 'lastModifyBy', key: 'lastModifyBy', width: 90, ellipsis: true }, + { title: '操作', key: 'action', width: 120, fixed: 'right', render: function (_, r) { + return React.createElement(React.Fragment, null, + React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('跳转交车管理-查看页'); } }, '查看'), + React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('跳转交车管理-交车单'); } }, '交车单') + ); } } ]; + // 历史记录:同列,操作仅 查看 var historyColumns = [ - { title: '预计交车时间', dataIndex: 'expectedDate', key: 'expectedDate', width: 260, ellipsis: true }, - { title: '任务发布时间', dataIndex: 'taskPublishTime', key: 'taskPublishTime', width: 160, ellipsis: true }, - { title: '交车完成时间', dataIndex: 'completeTime', key: 'completeTime', width: 160, ellipsis: true }, - { title: '交车人', dataIndex: 'deliveryPerson', key: 'deliveryPerson', width: 100, ellipsis: true }, - { title: '合同编码', dataIndex: 'contractCode', key: 'contractCode', width: 160, ellipsis: true }, - { title: '项目名称', dataIndex: 'projectName', key: 'projectName', width: 160, ellipsis: true }, - { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 180, ellipsis: true }, - { title: '交车数量', key: 'deliveryCount', width: 100, render: function (_, r) { return renderHistoryQuantity(r); } }, - { title: '交车区域', dataIndex: 'deliveryRegion', key: 'deliveryRegion', width: 130, ellipsis: true }, - { title: '交车地点', dataIndex: 'deliveryAddress', key: 'deliveryAddress', width: 220, ellipsis: true }, + { title: '预计交车时间', dataIndex: 'expectedDate', key: 'expectedDate', width: 220, ellipsis: true }, + { title: '合同编码', dataIndex: 'contractCode', key: 'contractCode', width: 150, ellipsis: true }, + { title: '项目名称', dataIndex: 'projectName', key: 'projectName', width: 150, ellipsis: true }, + { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 160, ellipsis: true }, + { title: '交车区域', dataIndex: 'deliveryRegion', key: 'deliveryRegion', width: 120, ellipsis: true }, + { title: '交车地点', dataIndex: 'deliveryAddress', key: 'deliveryAddress', width: 200, ellipsis: true }, + { title: '交车数量', key: 'deliveryCount', width: 90, render: function (_, r) { return renderHistoryQuantity(r); } }, + { title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 160, ellipsis: true }, + { title: '创建人', dataIndex: 'createBy', key: 'createBy', width: 90, ellipsis: true }, + { title: '最后修改时间', dataIndex: 'lastModifyTime', key: 'lastModifyTime', width: 160, ellipsis: true }, + { title: '最后修改人', dataIndex: 'lastModifyBy', key: 'lastModifyBy', width: 90, ellipsis: true }, { title: '操作', key: 'action', width: 80, fixed: 'right', render: function () { - return React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('跳转查看交车单页面'); } }, '查看'); + return React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('跳转交车管理-查看页'); } }, '查看'); } } ]; @@ -488,7 +496,7 @@ const Component = function () { dataSource: displayPending, rowKey: 'id', pagination: tablePagination, - scroll: { x: 1490 }, + scroll: { x: 1680 }, size: 'middle' }) }, @@ -500,7 +508,7 @@ const Component = function () { dataSource: displayHistory, rowKey: 'id', pagination: tablePagination, - scroll: { x: 1650 }, + scroll: { x: 1680 }, size: 'middle' }) } diff --git a/web端/运维管理/车辆业务/新增备车.jsx b/web端/运维管理/车辆业务/备车-新增.jsx similarity index 94% rename from web端/运维管理/车辆业务/新增备车.jsx rename to web端/运维管理/车辆业务/备车-新增.jsx index f67e1aa..23a2ad0 100644 --- a/web端/运维管理/车辆业务/新增备车.jsx +++ b/web端/运维管理/车辆业务/备车-新增.jsx @@ -255,18 +255,37 @@ const Component = function () { }); }, []); + function validateForm() { + if (!form.plateNo) { message.warning('请选择车牌号'); return false; } + if (form.bodyAd && (!form.adPhotos || form.adPhotos.length < 1)) { message.warning('请上传广告照片'); return false; } + if (form.bodyAd && (!form.enlargePhotos || form.enlargePhotos.length < 1)) { message.warning('请上传放大字照片'); return false; } + if (!form.spareTirePhotos || form.spareTirePhotos.length < 1) { message.warning('请上传备胎照片'); return false; } + if (!String(form.spareTireTreadDepth || '').trim()) { message.warning('请填写备胎胎纹深度'); return false; } + var list = form.inspectionList || []; + for (var i = 0; i < list.length; i++) { + if (list[i].category === '轮胎' && !String(list[i].treadDepth || '').trim()) { + message.warning('请完善备车检查单:填写轮胎胎纹深度'); + return false; + } + if (!String(list[i].remark || '').trim()) { + message.warning('请完善备车检查单:所有项备注为必填'); + return false; + } + } + return true; + } var handleSubmit = useCallback(function () { - if (!form.plateNo) { message.warning('请选择车牌号'); return; } + if (!validateForm()) return; message.success('备车成功'); // 保存数据并跳转至备车管理-已完成(实际项目接路由) if (typeof window !== 'undefined' && window.history) window.history.back(); - }, [form.plateNo]); + }, [form.plateNo, form.spareTirePhotos, form.spareTireTreadDepth, form.inspectionList]); var handleSave = useCallback(function () { - if (!form.plateNo) { message.warning('请选择车牌号'); return; } + if (!validateForm()) return; message.success('暂存成功'); // 保存数据并跳转至备车管理-待提交 if (typeof window !== 'undefined' && window.history) window.history.back(); - }, [form.plateNo]); + }, [form.plateNo, form.spareTirePhotos, form.spareTireTreadDepth, form.inspectionList]); var handleCancel = useCallback(function () { if (typeof window !== 'undefined' && window.history) window.history.back(); else message.info('取消'); @@ -337,6 +356,8 @@ const Component = function () { } return React.createElement(Switch, { checked: record.checked !== false, + checkedChildren: '正常', + unCheckedChildren: '异常', onChange: function (checked) { updateInspection(index, 'checked', checked); } }); } @@ -349,7 +370,7 @@ const Component = function () { return React.createElement(Input, { value: val, onChange: function (e) { updateInspection(index, 'remark', e.target.value); }, - placeholder: '备注' + placeholder: '必填' }); } } @@ -417,17 +438,17 @@ const Component = function () { ) ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '车身广告及放大字' }, + React.createElement(FormItem, { label: '车身广告及放大字', required: true }, React.createElement(Switch, { checked: form.bodyAd, - checkedChildren: '开', - unCheckedChildren: '关', + checkedChildren: '有', + unCheckedChildren: '无', onChange: function (checked) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.bodyAd = checked; return n; }); } }) ), - React.createElement(FormItem, { label: '广告照片' }, + form.bodyAd ? React.createElement(FormItem, { label: '广告照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: adPhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onAdPhotoFileChange }), (form.adPhotos || []).length < 1 ? cameraIconBox(addAdPhoto) : null, @@ -446,8 +467,8 @@ const Component = function () { ); }) ) - ), - React.createElement(FormItem, { label: '放大字照片' }, + ) : null, + form.bodyAd ? React.createElement(FormItem, { label: '放大字照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: enlargePhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onEnlargePhotoFileChange }), (form.enlargePhotos || []).length < 1 ? cameraIconBox(addEnlargePhoto) : null, @@ -466,20 +487,20 @@ const Component = function () { ); }) ) - ) + ) : null ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '尾板' }, + React.createElement(FormItem, { label: '尾板', required: true }, React.createElement(Switch, { checked: form.tailboard, - checkedChildren: '开', - unCheckedChildren: '关', + checkedChildren: '有', + unCheckedChildren: '无', onChange: function (checked) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.tailboard = checked; return n; }); } }) ), - React.createElement(FormItem, { label: '备胎照片' }, + React.createElement(FormItem, { label: '备胎照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: spareTirePhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onSpareTirePhotoFileChange }), (form.spareTirePhotos || []).length < 1 ? cameraIconBox(addSpareTirePhoto) : null, @@ -499,7 +520,7 @@ const Component = function () { }) ) ), - React.createElement(FormItem, { label: '备胎胎纹深度' }, + React.createElement(FormItem, { label: '备胎胎纹深度', required: true }, React.createElement(Input, { value: form.spareTireTreadDepth, onChange: function (e) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.spareTireTreadDepth = e.target.value; return n; }); }, @@ -532,7 +553,7 @@ const Component = function () { ) ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '车辆检查', fullWidth: true }, + React.createElement(FormItem, { label: '车辆检查', fullWidth: true, required: true }, React.createElement(Button, { type: 'default', onClick: function () { drawerOpenState[1](true); } }, '备车检查单') ) ) diff --git a/web端/运维管理/车辆业务/查看备车.jsx b/web端/运维管理/车辆业务/备车-查看.jsx similarity index 97% rename from web端/运维管理/车辆业务/查看备车.jsx rename to web端/运维管理/车辆业务/备车-查看.jsx index 300c31c..b2f6c88 100644 --- a/web端/运维管理/车辆业务/查看备车.jsx +++ b/web端/运维管理/车辆业务/备车-查看.jsx @@ -130,7 +130,7 @@ const Component = function () { width: 140, render: function (_, record) { if (record.category === '轮胎') return record.treadDepth ? record.treadDepth + ' mm' : '-'; - return record.checked !== false ? '开' : '关'; + return record.checked !== false ? '正常' : '异常'; } }, { title: '备注', dataIndex: 'remark', key: 'remark', render: function (val) { return val || '-'; } } @@ -174,9 +174,9 @@ const Component = function () { ), React.createElement('div', { style: styles.formRow }, React.createElement(FormItem, { label: '车身广告及放大字' }, - React.createElement(Input, { value: form.bodyAd ? '开' : '关', disabled: true, style: { width: '100%', background: '#f5f5f5' } }) + React.createElement(Input, { value: form.bodyAd ? '有' : '无', disabled: true, style: { width: '100%', background: '#f5f5f5' } }) ), - React.createElement(FormItem, { label: '广告照片' }, + form.bodyAd ? React.createElement(FormItem, { label: '广告照片' }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, (form.adPhotos || []).map(function (url, i) { return React.createElement('img', { @@ -189,8 +189,8 @@ const Component = function () { }), (form.adPhotos || []).length === 0 ? React.createElement('span', { style: { color: '#999' } }, '无') : null ) - ), - React.createElement(FormItem, { label: '放大字照片' }, + ) : null, + form.bodyAd ? React.createElement(FormItem, { label: '放大字照片' }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, (form.enlargePhotos || []).map(function (url, i) { return React.createElement('img', { @@ -203,11 +203,11 @@ const Component = function () { }), (form.enlargePhotos || []).length === 0 ? React.createElement('span', { style: { color: '#999' } }, '无') : null ) - ) + ) : null ), React.createElement('div', { style: styles.formRow }, React.createElement(FormItem, { label: '尾板' }, - React.createElement(Input, { value: form.tailboard ? '开' : '关', disabled: true, style: { width: '100%', background: '#f5f5f5' } }) + React.createElement(Input, { value: form.tailboard ? '有' : '无', disabled: true, style: { width: '100%', background: '#f5f5f5' } }) ), React.createElement(FormItem, { label: '备胎照片' }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, diff --git a/web端/运维管理/车辆业务/备车-编辑.jsx b/web端/运维管理/车辆业务/备车-编辑.jsx index ddb052e..66279ba 100644 --- a/web端/运维管理/车辆业务/备车-编辑.jsx +++ b/web端/运维管理/车辆业务/备车-编辑.jsx @@ -250,10 +250,29 @@ const Component = function () { }); }, []); + function validateForm() { + if (form.bodyAd && (!form.adPhotos || form.adPhotos.length < 1)) { message.warning('请上传广告照片'); return false; } + if (form.bodyAd && (!form.enlargePhotos || form.enlargePhotos.length < 1)) { message.warning('请上传放大字照片'); return false; } + if (!form.spareTirePhotos || form.spareTirePhotos.length < 1) { message.warning('请上传备胎照片'); return false; } + if (!String(form.spareTireTreadDepth || '').trim()) { message.warning('请填写备胎胎纹深度'); return false; } + var list = form.inspectionList || []; + for (var i = 0; i < list.length; i++) { + if (list[i].category === '轮胎' && !String(list[i].treadDepth || '').trim()) { + message.warning('请完善备车检查单:填写轮胎胎纹深度'); + return false; + } + if (!String(list[i].remark || '').trim()) { + message.warning('请完善备车检查单:所有项备注为必填'); + return false; + } + } + return true; + } var handleSave = useCallback(function () { + if (!validateForm()) return; message.success('提交成功(原型)'); if (typeof window !== 'undefined' && window.history) window.history.back(); - }, []); + }, [form.spareTirePhotos, form.spareTireTreadDepth, form.inspectionList]); var handleSaveDraft = useCallback(function () { message.success('保存成功(原型)'); }, []); @@ -326,6 +345,8 @@ const Component = function () { } return React.createElement(Switch, { checked: record.checked !== false, + checkedChildren: '正常', + unCheckedChildren: '异常', onChange: function (checked) { updateInspection(index, 'checked', checked); } }); } @@ -338,7 +359,7 @@ const Component = function () { return React.createElement(Input, { value: val, onChange: function (e) { updateInspection(index, 'remark', e.target.value); }, - placeholder: '备注' + placeholder: '必填' }); } } @@ -390,17 +411,17 @@ const Component = function () { ) ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '车身广告及放大字' }, + React.createElement(FormItem, { label: '车身广告及放大字', required: true }, React.createElement(Switch, { checked: form.bodyAd, - checkedChildren: '开', - unCheckedChildren: '关', + checkedChildren: '有', + unCheckedChildren: '无', onChange: function (checked) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.bodyAd = checked; return n; }); } }) ), - React.createElement(FormItem, { label: '广告照片' }, + form.bodyAd ? React.createElement(FormItem, { label: '广告照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: adPhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onAdPhotoFileChange }), (form.adPhotos || []).length < 1 ? cameraIconBox(addAdPhoto) : null, @@ -419,8 +440,8 @@ const Component = function () { ); }) ) - ), - React.createElement(FormItem, { label: '放大字照片' }, + ) : null, + form.bodyAd ? React.createElement(FormItem, { label: '放大字照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: enlargePhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onEnlargePhotoFileChange }), (form.enlargePhotos || []).length < 1 ? cameraIconBox(addEnlargePhoto) : null, @@ -439,20 +460,20 @@ const Component = function () { ); }) ) - ) + ) : null ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '尾板' }, + React.createElement(FormItem, { label: '尾板', required: true }, React.createElement(Switch, { checked: form.tailboard, - checkedChildren: '开', - unCheckedChildren: '关', + checkedChildren: '有', + unCheckedChildren: '无', onChange: function (checked) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.tailboard = checked; return n; }); } }) ), - React.createElement(FormItem, { label: '备胎照片' }, + React.createElement(FormItem, { label: '备胎照片', required: true }, React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 } }, React.createElement('input', { type: 'file', ref: spareTirePhotoInputRef, accept: 'image/*', style: { display: 'none' }, onChange: onSpareTirePhotoFileChange }), (form.spareTirePhotos || []).length < 1 ? cameraIconBox(addSpareTirePhoto) : null, @@ -472,7 +493,7 @@ const Component = function () { }) ) ), - React.createElement(FormItem, { label: '备胎胎纹深度' }, + React.createElement(FormItem, { label: '备胎胎纹深度', required: true }, React.createElement(Input, { value: form.spareTireTreadDepth, onChange: function (e) { setForm(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.spareTireTreadDepth = e.target.value; return n; }); }, @@ -505,7 +526,7 @@ const Component = function () { ) ), React.createElement('div', { style: styles.formRow }, - React.createElement(FormItem, { label: '车辆检查', fullWidth: true }, + React.createElement(FormItem, { label: '车辆检查', fullWidth: true, required: true }, React.createElement(Button, { type: 'default', onClick: function () { drawerOpenState[1](true); } }, '备车检查单') ) ) diff --git a/web端/需求说明/交车管理 b/web端/需求说明/交车管理 index 9eee147..9a18167 100644 --- a/web端/需求说明/交车管理 +++ b/web端/需求说明/交车管理 @@ -14,39 +14,46 @@ 2.8.重置:点击清空查询条件至默认; 3.列表: -分为两个tab:待处理、历史记录 -3.1.待处理:显示以下字段: +分为两个tab:待处理、历史记录,默认显示为待处理tab; +3.1.待处理tab:列表显示以下字段: 3.1.1.预计交车时间:支持单日及开始-结束日期两种方式,格式为:YYYY-MM-DD及YYYY-MM-DD至YYYY-MM-DD,取自对应交车任务中预计交车时间; -3.1.2.任务发布时间:显示交车任务单生成时间,格式为:YYYY-MM-DD HH:MM; -3.1.3.合同编码:显示租赁/自营合同编码; -3.1.4.项目名称:显示租赁/自营合同项目名称; -3.1.5.客户名称:显示租赁/自营合同客户名称; -3.1.6.交车数量:显示交车数量,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号; - 3.1.6.1.车辆类型:显示车辆类型; - 3.1.6.2.品牌:显示车辆品牌; - 3.1.6.3.型号:显示车辆型号; - 3.1.6.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-; -3.1.7.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市; -3.1.8.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址; -3.1.9.操作:查看、交车; - 3.1.8.1.交车:点击跳转交车单页面; +3.1.2.合同编码:显示租赁/自营合同编码; +3.1.3.项目名称:显示租赁/自营合同项目名称; +3.1.4.客户名称:显示租赁/自营合同客户名称; +3.1.5.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市; +3.1.6.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址; +3.1.7.交车数量:显示交车数量,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号、交车时间、交车人员; + 3.1.7.1.车辆类型:显示车辆类型; + 3.1.7.2.品牌:显示车辆品牌; + 3.1.7.3.型号:显示车辆型号; + 3.1.7.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-; + 3.1.7.5.交车时间:显示实际车辆完成交车时间,格式为:YYYY-MM-DD; + 3.1.7.6.交车人员:显示实际车辆完成交车操作人姓名; +3.1.8.创建时间:显示交车任务单创建时间,格式为:YYYY-MM-DD HH:MM; +3.1.9.创建人:显示交车任务单创建人; +3.1.10.最后修改时间:显示交车任务单最后修改时间,格式为:YYYY-MM-DD HH:MM; +3.1.11.最后修改人:显示交车任务单最后修改人姓名; +3.1.12.操作:查看、交车; + 3.1.12.1.查看:跳转交车管理-查看页; + 3.1.12.2.交车单:点击跳转交车管理-交车单; 3.2.历史记录:显示以下字段: 3.2.1.预计交车时间:支持单日及开始-结束日期两种方式,格式为:YYYY-MM-DD及YYYY-MM-DD至YYYY-MM-DD,取自对应交车任务中预计交车时间; -3.2.2.任务发布时间:显示交车任务单生成时间,格式为:YYYY-MM-DD HH:MM; -3.2.3.交车完成时间:显示交车单完成时间,格式为:YYYY-MM-DD HH:MM; -3.2.4.交车人:显示交车单最终提交用户; -3.2.5.合同编码:显示租赁/自营合同编码; -3.2.6.项目名称:显示租赁/自营合同项目名称; -3.2.7.客户名称:显示租赁/自营合同客户名称; -3.2.8.交车数量:交车数量:显示交车数,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号、实际交车日期、交车人; - 3.2.8.1.车辆类型:显示车辆类型; - 3.2.8.2.品牌:显示车辆品牌; - 3.2.8.3.型号:显示车辆型号; - 3.2.8.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-; - 3.2.8.5.实际交车日期:显示实际交车日期,与列表中显示相同,格式为YYYY-MM-DD,如该车还未交车则显示为-; - 3.2.8.6.交车人:显示实际交车人用户姓名,如该车还未还车则显示为-; -3.2.9.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市; -3.2.10.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址; -3.2.11.操作:查看; - 3.2.11.1.查看:点击跳转查看交车单页面; +3.1.2.合同编码:显示租赁/自营合同编码; +3.1.3.项目名称:显示租赁/自营合同项目名称; +3.1.4.客户名称:显示租赁/自营合同客户名称; +3.1.5.交车区域:显示交车区域,交车区域来自车辆租赁合同-交车区域,格式为省-市; +3.1.6.交车地点:显示交车地点,交车地点来自车辆租赁合同-交车地点,显示详细地址; +3.1.7.交车数量:显示交车数量,重点色显示,点击弹出气泡卡片,列表显示:车辆类型、品牌、型号、车牌号、交车时间、交车人员; + 3.1.7.1.车辆类型:显示车辆类型; + 3.1.7.2.品牌:显示车辆品牌; + 3.1.7.3.型号:显示车辆型号; + 3.1.7.4.车牌号:显示交车车辆车牌号,如果该车还未交车则显示为-; + 3.1.7.5.交车时间:显示实际车辆完成交车时间,格式为:YYYY-MM-DD; + 3.1.7.6.交车人员:显示实际车辆完成交车操作人姓名; +3.1.8.创建时间:显示交车任务单创建时间,格式为:YYYY-MM-DD HH:MM; +3.1.9.创建人:显示交车任务单创建人; +3.1.10.最后修改时间:显示交车任务单最后修改时间,格式为:YYYY-MM-DD HH:MM; +3.1.11.最后修改人:显示交车任务单最后修改人姓名; +3.1.12.操作:查看、交车; + 3.1.12.1.查看:跳转交车管理-查看页;