feat(web): 车辆租赁合同合同审批类型、法务上传盖章合同;新增数据分析页面;交车任务查看调整

- 租赁合同列表:合同审批类型筛选与列、需求说明;审批通过且未上传盖章件时法务可更多上传
- 新增/续签/转正式/查看等页同步合同审批类型及需求说明
- 新增数据分析:业务部业绩明细、物流业务月度统计、租赁客户氢费台账、租赁车辆收入明细
- 查看交车任务页面更新

Made-with: Cursor
This commit is contained in:
王冕
2026-03-25 15:50:31 +08:00
parent 826a774495
commit e1ac94bacf
13 changed files with 3654 additions and 96 deletions

View File

@@ -53,6 +53,7 @@ const Component = function() {
deliveryProvince: '浙江省',
deliveryCity: '嘉兴市',
deliveryLocation: '嘉兴市南湖区科技大道1号',
contractApprovalType: '标准合同审批',
remarks: '',
authorizedList: [{ name: '张三', phone: '13800138001', idCard: '330102199001011234' }],
rentalOrders: [
@@ -128,6 +129,9 @@ const Component = function() {
var bs11 = React.useState(prevContractSample.deliveryLocation);
var deliveryLocation = bs11[0];
var setDeliveryLocation = bs11[1];
var bs11a = React.useState(prevContractSample.contractApprovalType);
var contractApprovalType = bs11a[0];
var setContractApprovalType = bs11a[1];
var bs12 = React.useState('转正式合同自旧合同编码JXZL20260216YW101235A');
var remarks = bs12[0];
var setRemarks = bs12[1];
@@ -321,6 +325,7 @@ const Component = function() {
if (!signingCompany) errs.signingCompany = '请选择签约公司';
if (!deliveryProvince || !deliveryCity) errs.deliveryRegion = '请选择交车区域';
if (!deliveryLocation || !deliveryLocation.trim()) errs.deliveryLocation = '请输入交车地点';
if (!contractApprovalType) errs.contractApprovalType = '请选择合同审批类型';
var authInvalid = authorizedList.some(function(a) { return !a.name || !a.name.trim() || !a.phone || !a.phone.trim() || !a.idCard || !a.idCard.trim(); });
if (authInvalid) errs.authorizedList = '请完整填写被授权人姓名、联系电话、身份证';
var rentalInvalid = rentalOrders.some(function(r) { return !r.brand || !r.model || !(r.monthRent && String(r.monthRent).trim()) || !(r.deposit && String(r.deposit).trim()); });
@@ -347,7 +352,7 @@ const Component = function() {
if (!billingMethod) errs.billingMethod = '请选择账单计算方式';
setFormErrors(errs);
if (Object.keys(errs).length > 0) {
var firstId = errs.customer || errs.businessDept || errs.businessOwner ? 'card-customer' : (errs.projectName || errs.effectiveDate || errs.paymentMethod || errs.endDate || errs.paymentPeriod || errs.signingCompany || errs.deliveryRegion || errs.deliveryLocation || errs.contractOriginal) ? 'card-contract' : errs.authorizedList ? 'card-authorized' : (errs.rentalOrders || errs.serviceItems || errs.hydrogenBearer || errs.hydrogenPaymentMethod || errs.hydrogenPrepay || errs.returnHydrogenPrice) ? 'card-rental' : errs.feeTemplate ? 'card-fee' : 'card-billing';
var firstId = errs.customer || errs.businessDept || errs.businessOwner ? 'card-customer' : (errs.projectName || errs.effectiveDate || errs.paymentMethod || errs.endDate || errs.paymentPeriod || errs.signingCompany || errs.deliveryRegion || errs.deliveryLocation || errs.contractApprovalType || errs.contractOriginal) ? 'card-contract' : errs.authorizedList ? 'card-authorized' : (errs.rentalOrders || errs.serviceItems || errs.hydrogenBearer || errs.hydrogenPaymentMethod || errs.hydrogenPrepay || errs.returnHydrogenPrice) ? 'card-rental' : errs.feeTemplate ? 'card-fee' : 'card-billing';
setCc1(false); setCc2(false); setCc3(false); setCc4(false); setCc5(false); setCc6(false);
setTimeout(function() { var el = document.getElementById(firstId); if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 100);
return false;
@@ -579,7 +584,8 @@ const Component = function() {
React.createElement(FormItem, { label: '交车区域', required: true, error: formErrors.deliveryRegion }, React.createElement('div', { id: 'delivery-region-wrap', style: { position: 'relative' } }, React.createElement(Input, { style: Object.assign({}, formErrors.deliveryRegion ? { borderColor: '#ff4d4f' } : {}, { cursor: 'pointer', caretColor: 'transparent', width: '100%' }), placeholder: '请选择省-市', value: deliveryRegionDisplay, readOnly: true, onClick: function() { setDeliveryRegionOpen(!deliveryRegionOpen); } }), deliveryRegionOpen ? React.createElement('div', { style: styles.regionCascader, onMouseDown: function() { deliveryRegionClickInsideRef.current = true; } }, React.createElement('div', { style: styles.regionCascaderCol }, regionList.map(function(r, i) { var isActive = r.province === deliveryProvince; return React.createElement('div', { key: i, style: Object.assign({}, styles.regionCascaderItem, isActive ? { backgroundColor: '#e6f7ff', color: '#1890ff' } : {}), onMouseEnter: function(e) { if (!isActive) e.currentTarget.style.backgroundColor = '#f5f5f5'; }, onMouseLeave: function(e) { if (!isActive) e.currentTarget.style.backgroundColor = 'transparent'; }, onMouseDown: function(e) { e.preventDefault(); setEdited(true); setDeliveryProvince(r.province); setDeliveryCity(''); } }, r.province); })), React.createElement('div', { style: styles.regionCascaderColLast }, deliveryProvince ? (regionList.find(function(x) { return x.province === deliveryProvince; }) || { cities: [] }).cities.map(function(c, i) { var isActive = c === deliveryCity; return React.createElement('div', { key: i, style: Object.assign({}, styles.regionCascaderItem, isActive ? { backgroundColor: '#e6f7ff', color: '#1890ff' } : {}), onMouseEnter: function(e) { if (!isActive) e.currentTarget.style.backgroundColor = '#f5f5f5'; }, onMouseLeave: function(e) { if (!isActive) e.currentTarget.style.backgroundColor = 'transparent'; }, onMouseDown: function(e) { e.preventDefault(); selectDeliveryRegion(deliveryProvince, c); } }, c); }) : React.createElement('div', { style: { padding: 16, color: '#999', fontSize: 13 } }, '请先选择省'))) : null))
);
var contractFormRow4 = React.createElement('div', { style: styles.formRow },
React.createElement(FormItem, { label: '交车地点', required: true, error: formErrors.deliveryLocation }, React.createElement(Input, { placeholder: '请输入交车地点', value: deliveryLocation, onChange: function(e) { setEdited(true); setDeliveryLocation(e.target.value); }, status: formErrors.deliveryLocation ? 'error' : undefined, style: { width: '100%' } }))
React.createElement(FormItem, { label: '交车地点', required: true, error: formErrors.deliveryLocation }, React.createElement(Input, { placeholder: '请输入交车地点', value: deliveryLocation, onChange: function(e) { setEdited(true); setDeliveryLocation(e.target.value); }, status: formErrors.deliveryLocation ? 'error' : undefined, style: { width: '100%' } })),
React.createElement(FormItem, { label: '合同审批类型', required: true, error: formErrors.contractApprovalType }, React.createElement(Select, { placeholder: '请选择合同审批类型', style: { width: '100%' }, value: contractApprovalType || undefined, onChange: function(v) { setEdited(true); setContractApprovalType(v || ''); }, status: formErrors.contractApprovalType ? 'error' : undefined }, React.createElement(Option, { value: '标准合同审批' }, '标准合同审批'), React.createElement(Option, { value: '非标准合同审批' }, '非标准合同审批')))
);
var contractFormRow5 = React.createElement('div', { style: styles.formRow },
React.createElement(FormItem, { label: '合同原件', required: true, error: formErrors.contractOriginal },
@@ -759,8 +765,9 @@ const Component = function() {
3.8.签约公司:从原合同自动反写,必选项,选择器,从组织机构表中获取所有根组织机构(如嘉兴羚牛、上海羚牛、广东羚牛等),默认显示新增用户当前机构,可手动修改,后期需要考虑从签约公司维度统计合同相关数据;
3.9.交车区域:从原合同自动反写,必选项,地区选择器,支持省-市2级选择区域后该任务生成交车任务时会自动推送至该区域负责运维人员
3.10.交车地点:从原合同自动反写,必填项,输入框,支持自定义输入交车地点;
3.11.合同原件:从原合同自动反写,必填项,按钮按钮文字为上传附件支持多个附件上传doc/docx/pdf格式
3.12.备注:从原合同自动反写,如果该合同为转正式合同则自动在已填备注信息上方额外添加转正式合同自旧合同合同编码xxx文本域支持自定义输入备注信息
3.11.合同审批类型:从原合同自动反写,必填项,选择器,分为「标准合同审批」「非标准合同审批」
3.12.合同原件:从原合同自动反写,必填项按钮按钮文字为上传附件支持多个附件上传doc/docx/pdf格式
3.13.备注从原合同自动反写如果该合同为转正式合同则自动在已填备注信息上方额外添加转正式合同自旧合同合同编码xxx文本域支持自定义输入备注信息
4.被授权人信息卡片:
#用于定义租赁合同相关被授权人相关信息被授权人在交车单完成时需要选择被授权人并通过被授权人手机短信在E签宝进行签字确认