Files
ONE-OS/docs/小羚羚-交车-产品需求文档.html

553 lines
38 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>小羚羚 · 交车模块产品需求文档</title>
<style>
@page { size: A4; margin: 18mm 16mm 20mm 16mm; }
* { box-sizing: border-box; }
body {
font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
color: #1e293b; line-height: 1.65; font-size: 11pt; margin: 0; padding: 0; background: #fff;
}
.cover {
min-height: 260mm; display: flex; flex-direction: column; justify-content: center; align-items: center;
text-align: center; page-break-after: always;
background: linear-gradient(160deg, #ecfdf5 0%, #f0fdf4 45%, #fff 100%);
border-bottom: 4px solid #059669; padding: 40px 32px;
}
.cover-badge { display: inline-block; padding: 6px 14px; border-radius: 999px; background: #059669; color: #fff; font-size: 10pt; font-weight: 700; letter-spacing: 1px; margin-bottom: 24px; }
.cover h1 { font-size: 26pt; margin: 0 0 12px; color: #0f172a; font-weight: 800; }
.cover .subtitle { font-size: 14pt; color: #475569; margin-bottom: 48px; }
.cover-meta { font-size: 10pt; color: #64748b; line-height: 2; }
.cover-meta strong { color: #334155; }
h2 { font-size: 16pt; color: #0f172a; border-left: 5px solid #059669; padding-left: 12px; margin: 28px 0 14px; page-break-after: avoid; }
h3 { font-size: 12.5pt; color: #047857; margin: 20px 0 10px; page-break-after: avoid; }
h4 { font-size: 11pt; color: #334155; margin: 14px 0 8px; }
p { margin: 8px 0; }
ul, ol { margin: 8px 0; padding-left: 22px; }
li { margin: 4px 0; }
.section { page-break-inside: avoid; margin-bottom: 18px; }
.toc { page-break-after: always; padding: 20px 0; }
.toc ol { font-size: 11pt; line-height: 2.2; }
.toc a { color: #047857; text-decoration: none; }
.info-box { background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px; padding: 12px 16px; margin: 12px 0; font-size: 10.5pt; }
.warn-box { background: #fff7ed; border: 1px solid #fed7aa; border-radius: 10px; padding: 12px 16px; margin: 12px 0; font-size: 10.5pt; }
.dev-box { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 10px; padding: 12px 16px; margin: 12px 0; font-size: 10.5pt; }
table.data { width: 100%; border-collapse: collapse; font-size: 10pt; margin: 12px 0; }
table.data th, table.data td { border: 1px solid #e2e8f0; padding: 8px 10px; text-align: left; vertical-align: top; }
table.data th { background: #f8fafc; font-weight: 700; color: #334155; }
.diagram-wrap { margin: 16px 0; text-align: center; page-break-inside: avoid; }
.diagram-wrap svg { max-width: 100%; height: auto; }
.diagram-caption { font-size: 9.5pt; color: #64748b; margin-top: 6px; text-align: center; }
.step-card { border: 1px solid #e2e8f0; border-radius: 12px; overflow: hidden; margin: 16px 0; page-break-inside: avoid; }
.step-card-header { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: linear-gradient(90deg, #ecfdf5, #f8fafc); border-bottom: 1px solid #e2e8f0; }
.step-num { width: 32px; height: 32px; border-radius: 50%; background: #059669; color: #fff; font-weight: 800; display: flex; align-items: center; justify-content: center; font-size: 14pt; flex-shrink: 0; }
.step-card-header h3 { margin: 0; color: #0f172a; font-size: 12pt; }
.step-card-body { padding: 14px 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.step-text { font-size: 10.5pt; }
.ui-mock { border: 1px solid #cbd5e1; border-radius: 8px; background: #f8fafc; padding: 10px; font-size: 9pt; }
.ui-mock-title { font-weight: 700; color: #475569; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px dashed #cbd5e1; font-size: 9pt; }
.ui-btn { display: inline-block; padding: 3px 10px; border-radius: 6px; font-size: 8.5pt; font-weight: 600; margin: 2px; }
.ui-btn-primary { background: #059669; color: #fff; }
.ui-btn-ghost { background: #fff; border: 1px solid #d1d5db; color: #334155; }
.ui-tag { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 8pt; font-weight: 600; }
.ui-tag-green { background: #dcfce7; color: #166534; }
.ui-tag-blue { background: #dbeafe; color: #1e40af; }
.ui-tag-warn { background: #fef3c7; color: #b45309; }
.ui-tag-neutral { background: #f1f5f9; color: #64748b; }
.ui-section { background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px 10px; margin: 6px 0; }
.ui-section-num { display: inline-flex; width: 18px; height: 18px; border-radius: 50%; background: #059669; color: #fff; font-size: 8pt; font-weight: 700; align-items: center; justify-content: center; margin-right: 6px; }
.ui-required { color: #ef4444; font-size: 8pt; }
.ui-field { background: #fff; border: 1px solid #e2e8f0; border-radius: 4px; padding: 4px 8px; color: #64748b; font-size: 8.5pt; margin: 3px 0; }
.ui-card { border: 2px solid #e2e8f0; border-radius: 8px; padding: 8px; margin: 4px; display: inline-block; min-width: 90px; text-align: center; font-size: 8.5pt; }
.ui-card.active { border-color: #059669; background: #ecfdf5; }
.ui-stepper { display: flex; gap: 4px; align-items: center; font-size: 8pt; margin-top: 8px; }
.ui-step { padding: 4px 8px; border-radius: 6px; background: #f1f5f9; color: #64748b; }
.ui-step.active { background: #059669; color: #fff; font-weight: 700; }
.ui-step.done { background: #dcfce7; color: #166534; }
code { background: #f1f5f9; padding: 1px 5px; border-radius: 4px; font-size: 9.5pt; color: #0f766e; }
.page-break { page-break-before: always; }
.footer-note { margin-top: 32px; padding-top: 12px; border-top: 1px solid #e2e8f0; font-size: 9pt; color: #94a3b8; text-align: center; }
.status-flow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: center; margin: 12px 0; font-size: 9pt; }
.status-node { padding: 6px 12px; border-radius: 8px; font-weight: 700; border: 1px solid; }
.sn-neutral { background: #f1f5f9; border-color: #cbd5e1; color: #475569; }
.sn-warn { background: #fef3c7; border-color: #fcd34d; color: #b45309; }
.sn-info { background: #dbeafe; border-color: #93c5fd; color: #1d4ed8; }
.sn-ok { background: #dcfce7; border-color: #86efac; color: #166534; }
.shot-wrap { text-align: center; margin: 14px 0 6px; page-break-inside: avoid; }
.shot-wrap img { max-width: 260px; width: 100%; height: auto; border: 1px solid #cbd5e1; border-radius: 16px; box-shadow: 0 8px 24px rgba(15,23,42,.08); }
.shot-cap { font-size: 9pt; color: #94a3b8; margin-top: 6px; text-align: center; }
</style>
</head>
<body>
<div class="cover">
<div class="cover-badge">ONE-OS · 小羚羚小程序</div>
<h1>交车模块</h1>
<div class="subtitle">产品需求文档PRD</div>
<div class="cover-meta">
<div><strong>适用模块:</strong>小羚羚 → 业务 → 运维管理 → 交车</div>
<div><strong>文档受众:</strong>产品经理、前端/后端开发、测试</div>
<div><strong>参照:</strong>web 交车管理抽屉 + Axhub「交车完成」原型</div>
<div><strong>文档版本:</strong>V1.1 &nbsp;|&nbsp; <strong>更新日期:</strong>2026-06-09</div>
<div><strong>默认区域权限:</strong>浙江省 · 嘉兴市</div>
</div>
</div>
<div class="toc">
<h2>目录</h2>
<ol>
<li><a href="#s1">背景与目标</a></li>
<li><a href="#s2">信息架构与入口</a></li>
<li><a href="#s3">状态机与业务规则</a></li>
<li><a href="#s4">列表页需求</a></li>
<li><a href="#s5">分步表单 · 步骤一「车辆情况」</a></li>
<li><a href="#s6">分步表单 · 步骤二「交车检查项」</a></li>
<li><a href="#s7">分步表单 · 步骤三「拍摄照片」</a></li>
<li><a href="#s8">签章与被授权人</a></li>
<li><a href="#s9">校验规则与拦截逻辑</a></li>
<li><a href="#s10">数据模型与字段速查</a></li>
<li><a href="#s11">外部依赖与接口约定</a></li>
<li><a href="#s12">非功能需求与边界</a></li>
<li><a href="#s13">界面截图(原型)</a></li>
</ol>
</div>
<h2 id="s1">一、背景与目标</h2>
<div class="section">
<div class="info-box">
<strong>业务背景:</strong>运维人员需在交车现场完成车辆核验、检查单填写、照片采集与客户电子签章,形成可追溯的交车记录。小程序端承接「现场办理」场景,与 web 端交车管理数据对齐。
</div>
<table class="data">
<tr><th style="width:22%">目标</th><th>说明</th></tr>
<tr><td>现场可办</td><td>移动端分步引导,降低漏填漏拍;支持断点续办(草稿保存、连拍续拍)</td></tr>
<tr><td>数据对齐</td><td>检查单类别/项目与 web 交车检查单一致;氢量单位随车型参数自动匹配</td></tr>
<tr><td>合规留痕</td><td>照片自动上传打水印时间、地点E签宝双签运维 + 客户被授权人)</td></tr>
<tr><td>状态可追踪</td><td>未开始 → 已保存 → 待客户签章 → 客户已签章,列表可筛选</td></tr>
</table>
</div>
<h2 id="s2">二、信息架构与入口</h2>
<div class="diagram-wrap">
<svg viewBox="0 0 720 240" width="700" xmlns="http://www.w3.org/2000/svg">
<defs><marker id="arr" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#64748b"/></marker></defs>
<rect x="20" y="20" width="110" height="44" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="1.5"/>
<text x="75" y="47" text-anchor="middle" font-size="10" font-weight="700" fill="#065f46">小羚羚首页</text>
<rect x="160" y="20" width="90" height="44" rx="8" fill="#fff" stroke="#94a3b8"/>
<text x="205" y="47" text-anchor="middle" font-size="10" fill="#334155">业务 Tab</text>
<rect x="280" y="20" width="110" height="44" rx="8" fill="#fff" stroke="#94a3b8"/>
<text x="335" y="47" text-anchor="middle" font-size="10" fill="#334155">交车宫格</text>
<rect x="420" y="20" width="110" height="44" rx="8" fill="#ecfdf5" stroke="#059669"/>
<text x="475" y="47" text-anchor="middle" font-size="10" font-weight="700" fill="#065f46">交车列表</text>
<rect x="560" y="20" width="140" height="44" rx="8" fill="#dbeafe" stroke="#2563eb"/>
<text x="630" y="47" text-anchor="middle" font-size="10" font-weight="700" fill="#1e40af">分步办理表单</text>
<line x1="130" y1="42" x2="158" y2="42" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="250" y1="42" x2="278" y2="42" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="390" y1="42" x2="418" y2="42" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="530" y1="42" x2="558" y2="42" stroke="#64748b" marker-end="url(#arr)"/>
<rect x="80" y="110" width="560" height="100" rx="10" fill="#f8fafc" stroke="#e2e8f0"/>
<text x="360" y="135" text-anchor="middle" font-size="11" font-weight="700" fill="#334155">分步办理表单3 步)</text>
<rect x="110" y="150" width="140" height="44" rx="8" fill="#dcfce7" stroke="#86efac"/>
<text x="180" y="177" text-anchor="middle" font-size="10" font-weight="600" fill="#166534">① 车辆情况</text>
<rect x="290" y="150" width="140" height="44" rx="8" fill="#fff" stroke="#cbd5e1"/>
<text x="360" y="177" text-anchor="middle" font-size="10" fill="#334155">② 交车检查项</text>
<rect x="470" y="150" width="140" height="44" rx="8" fill="#fff" stroke="#cbd5e1"/>
<text x="540" y="177" text-anchor="middle" font-size="10" fill="#334155">③ 拍摄照片</text>
<line x1="250" y1="172" x2="288" y2="172" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="430" y1="172" x2="468" y2="172" stroke="#64748b" marker-end="url(#arr)"/>
</svg>
<div class="diagram-caption">图 1 · 模块入口与三步表单结构</div>
</div>
<div class="dev-box">
<strong>开发说明:</strong>交车模块内嵌于小羚羚壳(<code>DeliveryModule</code>),绿色主题与运维模块统一。表单内返回:先退出办理页 → 再退出交车模块。步骤条可点击切换,但「下一步」须通过当前步骤校验。
</div>
<h2 id="s3">三、状态机与业务规则</h2>
<div class="diagram-wrap">
<svg viewBox="0 0 700 200" width="680" xmlns="http://www.w3.org/2000/svg">
<defs><marker id="a2" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#64748b"/></marker></defs>
<rect x="20" y="70" width="90" height="40" rx="8" fill="#f1f5f9" stroke="#cbd5e1"/>
<text x="65" y="95" text-anchor="middle" font-size="10" font-weight="700" fill="#475569">未开始</text>
<rect x="140" y="70" width="90" height="40" rx="8" fill="#fef3c7" stroke="#fcd34d"/>
<text x="185" y="95" text-anchor="middle" font-size="10" font-weight="700" fill="#b45309">已保存</text>
<rect x="270" y="70" width="110" height="40" rx="8" fill="#dbeafe" stroke="#93c5fd"/>
<text x="325" y="95" text-anchor="middle" font-size="10" font-weight="700" fill="#1d4ed8">待客户签章</text>
<rect x="420" y="70" width="110" height="40" rx="8" fill="#dcfce7" stroke="#86efac"/>
<text x="475" y="95" text-anchor="middle" font-size="10" font-weight="700" fill="#166534">客户已签章</text>
<line x1="110" y1="90" x2="138" y2="90" stroke="#64748b" marker-end="url(#a2)"/><text x="124" y="84" font-size="8" fill="#64748b">保存</text>
<line x1="230" y1="90" x2="268" y2="90" stroke="#64748b" marker-end="url(#a2)"/><text x="249" y="84" font-size="8" fill="#64748b">运维签字</text>
<line x1="380" y1="90" x2="418" y2="90" stroke="#64748b" marker-end="url(#a2)"/><text x="399" y="84" font-size="8" fill="#64748b">客户签章</text>
<rect x="140" y="150" width="360" height="36" rx="8" fill="#f8fafc" stroke="#e2e8f0"/>
<text x="320" y="172" text-anchor="middle" font-size="9" fill="#64748b">实际交车时间:运维提交 E签宝 签章时系统自动写入,不在表单填写</text>
</svg>
<div class="diagram-caption">图 2 · 交车状态流转</div>
</div>
<table class="data">
<tr><th>状态</th><th>触发条件</th><th>用户可操作</th><th>编辑权限</th></tr>
<tr><td>未开始</td><td>新建任务,未保存过</td><td>去办理</td><td>可编辑</td></tr>
<tr><td>已保存</td><td>点击保存或步骤「下一步」自动保存</td><td>继续办理</td><td>可编辑</td></tr>
<tr><td>待客户签章</td><td>运维完成 E签宝 签字并发送签章文件</td><td>查看记录;清除签章后重发</td><td>只读(清除签章后可重选被授权人)</td></tr>
<tr><td>客户已签章</td><td>被授权人短信完成签章</td><td>查看、下载 PDF</td><td>只读</td></tr>
</table>
<h2 id="s4" class="page-break">四、列表页需求</h2>
<div class="step-card">
<div class="step-card-header"><div class="step-num"></div><h3>列表页结构</h3></div>
<div class="step-card-body">
<div class="step-text">
<h4>KPI 筛选</h4>
<ul>
<li>全部 / 进行中 / 已完成 — 点击切换 Tab</li>
<li>进行中 Tab 下额外 Chip全部状态、未开始、已保存、待客户签章</li>
</ul>
<h4>搜索</h4>
<p>支持车牌、项目、客户名称模糊搜索。</p>
<h4>卡片字段</h4>
<ul>
<li>车牌(未选车显示「车辆待选」)</li>
<li>交车状态 Tag、项目、客户、交车区域</li>
<li>待客户签章卡片展示实际交车时间</li>
<li>进行中展示「去办理 / 继续办理」</li>
</ul>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 列表页</div>
<div class="ui-row" style="display:flex;gap:6px;margin-bottom:8px">
<span class="ui-btn ui-btn-primary">进行中 3</span>
<span class="ui-btn ui-btn-ghost">已完成</span>
<span class="ui-btn ui-btn-ghost">全部</span>
</div>
<div class="ui-section">
<div style="display:flex;justify-content:space-between;align-items:center">
<strong>浙F88601</strong>
<span class="ui-tag ui-tag-blue">待客户签章</span>
</div>
<div style="font-size:8pt;color:#64748b;margin-top:4px">嘉兴冷链项目 · 嘉兴物流有限公司</div>
<div style="margin-top:6px;text-align:right"><span class="ui-btn ui-btn-primary">继续办理</span></div>
</div>
</div>
</div>
</div>
<h2 id="s5">五、分步表单 · 步骤一「车辆情况」</h2>
<p>Hero 区展示客户名称、项目名称、交车区域、计划交车、交车地点、业务类型与状态 Tag。下方分 5 个编号卡片区域:</p>
<div class="step-card">
<div class="step-card-header"><div class="step-num">1</div><h3>选择车辆</h3></div>
<div class="step-card-body">
<div class="step-text">
<p><strong>必填。</strong>两种方式:</p>
<ul>
<li><strong>选择车辆</strong>:打开备车列表(仅「已备车」),支持停车场筛选与车牌搜索</li>
<li><strong>识别车牌号</strong>OCR 拍照或相册选取后匹配车辆,须满足 <strong>车辆状态=已备车</strong><strong>保险状态=正常</strong><strong>证照状态=正常</strong>;不满足则报错阻断,提示文案与下方备车列表车辆卡片 readiness 提示条一致(如「交强险已到期无法交车」「商业险已到期无法交车」「交强险、商业险已到期无法交车」「行驶证已到期无法交车」;未备车「该车辆未备车,请先进行备车」)</li>
</ul>
<p>选车后展示车牌、品牌型号、停车场。</p>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 选车区</div>
<div class="ui-section"><span class="ui-section-num">1</span><strong>选择车辆</strong>
<div style="margin-top:6px"><span class="ui-btn ui-btn-primary">选择车辆</span> <span class="ui-btn ui-btn-ghost">识别车牌号</span></div>
<div class="ui-field" style="margin-top:6px;font-weight:700;color:#059669">浙F88601 · 现代 帕力安牌4.5吨冷链车</div>
</div>
</div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">2</div><h3>车辆配置</h3></div>
<div class="step-card-body">
<div class="step-text">
<table class="data" style="font-size:9pt">
<tr><th>字段</th><th>必填</th><th>规则</th></tr>
<tr><td>车身广告及放大字</td><td></td><td>开关确认有/无;选「有」须拍摄车身广告照片 + 放大字照片</td></tr>
<tr><td>尾板</td><td></td><td>开关确认有/无</td></tr>
<tr><td>备胎</td><td></td><td>仅选择有/无;备胎照片在步骤三轮胎连拍末项拍摄</td></tr>
</table>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 配置区</div>
<div class="ui-section"><span class="ui-section-num">2</span>车辆配置
<div style="margin-top:4px;font-size:8.5pt">车身广告及放大字 <span class="ui-required">必填</span> <span style="float:right">有 ◉ 无 ○</span></div>
<div style="display:flex;gap:4px;margin-top:4px"><div class="ui-field" style="flex:1;text-align:center">车身广告照片</div><div class="ui-field" style="flex:1;text-align:center">放大字照片</div></div>
<div style="margin-top:4px;font-size:8.5pt">尾板 <span class="ui-required">必填</span> <span style="float:right">有 ○ 无 ◉</span></div>
<div style="margin-top:4px;font-size:8.5pt;color:#64748b">备胎:有 ◉ 无 ○</div>
</div>
</div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">3</div><h3>驾驶培训</h3></div>
<div class="step-card-body">
<div class="step-text">
<p><strong>必填。</strong>两种模式二选一:</p>
<ul>
<li><strong>电子培训</strong>:展示培训二维码 → 司机微信扫码观看 → 运维扫描提车码完成</li>
<li><strong>手动记录(运维端)</strong>:录入司机手机号、姓名、身份证号 + 证件照片(身份证正反面、驾驶证正反面、司机正面照、从业资格证(重卡))→ 点击「生成培训码」(二维码与录入信息绑定)→ 等待司机微信扫码签字 →「刷新培训状态」确认完成</li>
</ul>
<p>司机完成签字后展示司机信息与证件缩略图,标记「已完成驾驶培训」。</p>
<p><strong>手动记录 · 司机微信端</strong>仅需求说明扫码后先阅读并同意安全培训文件10 秒倒计时后可确定)→ 展示运维登记的司机信息与证件照片 → 点击「确认签字」唤起签名板 → 签字成功后提示培训成功并同步至安全培训记录。</p>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 驾驶培训</div>
<div class="ui-section"><span class="ui-section-num">3</span>驾驶培训 <span class="ui-required">必填</span>
<div style="margin-top:6px;display:flex;gap:6px">
<div class="ui-field" style="flex:1">▣ 电子培训</div>
<div class="ui-field" style="flex:1">✎ 手动记录</div>
</div>
</div>
</div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">4</div><h3>交车数据</h3></div>
<div class="step-card-body">
<div class="step-text">
<table class="data" style="font-size:9pt">
<tr><th>字段</th><th>必填</th><th>规则</th></tr>
<tr><td>里程 (km)</td><td></td><td>2 位小数,无步进器</td></tr>
<tr><td>电量 (%)</td><td></td><td>2 位小数</td></tr>
<tr><td>氢量</td><td></td><td>2 位小数;单位按车型仪表盘参数自动匹配(%/MPa不可手动切换</td></tr>
<tr><td>送车服务费</td><td></td><td>2 位小数,单位元</td></tr>
<tr><td>备注</td><td></td><td>多行文本</td></tr>
</table>
<p><strong>不含</strong>交车时间字段(由签章提交时系统写入)。</p>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 交车数据</div>
<div class="ui-section"><span class="ui-section-num">4</span>交车数据 <span class="ui-required">必填</span>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-top:4px">
<div class="ui-field">里程 12500.00</div><div class="ui-field">电量 76.00 %</div>
<div class="ui-field">氢量 18.00 %</div><div class="ui-field">送车服务费 200.00 元</div>
</div>
</div>
</div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">5</div><h3>交车位置</h3></div>
<div class="step-card-body">
<div class="step-text">
<ul>
<li>如果车辆 GPS 在线,交车位置取车辆 GPS 当前定位;如果车辆 GPS 离线,交车位置取手机当前定位</li>
<li>GPS 在线时自动使用车辆坐标,地图蓝点标记</li>
<li>GPS 离线时须「获取当前定位」(运维手机坐标);进入步骤时自动尝试一次</li>
<li>无坐标时地图显示「暂未定位」提示</li>
</ul>
<p>步骤一「下一步」校验:非 GPS 车辆须已获取定位。</p>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 交车位置地图</div>
<div class="ui-section"><span class="ui-section-num">5</span>交车位置
<div style="height:60px;background:linear-gradient(135deg,#dbeafe,#ecfdf5);border-radius:6px;margin-top:4px;position:relative">
<div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:12px;height:12px;background:#2563eb;border-radius:50%;border:2px solid #fff"></div>
</div>
<div style="font-size:8pt;color:#64748b;margin-top:4px">嘉兴港区氢能停车场</div>
</div>
</div>
</div>
</div>
<h2 id="s6" class="page-break">六、分步表单 · 步骤二「交车检查项」</h2>
<div class="info-box">
检查单类别与项目<strong>对齐 web 交车管理抽屉「交车检查单」</strong>,含:车灯、仪表盘、驾驶室、轮胎、液位检查、外观检查、车辆外观、其他、随车工具、随车证件、整车、燃料电池系统、冷机、制动系统等。
</div>
<table class="data">
<tr><th>类别</th><th>控件类型</th><th>必填规则</th></tr>
<tr><td>轮胎(前左/前右/后左/后右/备胎)</td><td>数字输入框 (mm)</td><td>须填写胎纹深度;车辆配置「无备胎」时跳过备胎行</td></tr>
<tr><td>其余类别</td><td>开关(正常/异常)</td><td>默认「正常」可填备注≤40 字)</td></tr>
</table>
<div class="warn-box">
<strong>步骤二「下一步」校验:</strong>所有须填写的轮胎项胎纹深度不可为空。校验通过后自动保存并进入拍摄步骤。
</div>
<h2 id="s7">七、分步表单 · 步骤三「拍摄照片」</h2>
<div class="diagram-wrap">
<svg viewBox="0 0 700 160" width="680" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="50" width="100" height="44" rx="8" fill="#ecfdf5" stroke="#059669"/>
<text x="70" y="77" text-anchor="middle" font-size="10" font-weight="700" fill="#065f46">开始拍摄</text>
<rect x="150" y="50" width="100" height="44" rx="8" fill="#fff" stroke="#94a3b8"/>
<text x="200" y="72" text-anchor="middle" font-size="9" font-weight="600" fill="#334155">请准备拍摄</text>
<text x="200" y="86" text-anchor="middle" font-size="8" fill="#64748b">倒计时 3s</text>
<rect x="280" y="50" width="100" height="44" rx="8" fill="#fff" stroke="#94a3b8"/>
<text x="330" y="77" text-anchor="middle" font-size="10" fill="#334155">模拟相机页</text>
<rect x="410" y="50" width="100" height="44" rx="8" fill="#fff" stroke="#94a3b8"/>
<text x="460" y="77" text-anchor="middle" font-size="10" fill="#334155">完成+上传</text>
<rect x="540" y="50" width="140" height="44" rx="8" fill="#dcfce7" stroke="#86efac"/>
<text x="610" y="72" text-anchor="middle" font-size="10" font-weight="700" fill="#166534">分类卡片展示</text>
<text x="610" y="86" text-anchor="middle" font-size="8" fill="#64748b">可补拍/删除</text>
<line x1="120" y1="72" x2="148" y2="72" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="250" y1="72" x2="278" y2="72" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="380" y1="72" x2="408" y2="72" stroke="#64748b" marker-end="url(#arr)"/>
<line x1="510" y1="72" x2="538" y2="72" stroke="#64748b" marker-end="url(#arr)"/>
<text x="350" y="130" text-anchor="middle" font-size="9" fill="#64748b">连拍严格按 17/18 项顺序(有备胎 18 项,无备胎 17 项),不可跳过;退出后再进入自动续拍</text>
</svg>
<div class="diagram-caption">图 3 · 连拍状态机</div>
</div>
<h3>照片分类与连拍顺序</h3>
<table class="data">
<tr><th>分类</th><th>拍摄项(按顺序)</th><th>胎纹 OCR</th></tr>
<tr><td>车身情况</td><td>仪表盘、车辆正面、左前方、左后方、右后方、右前方</td><td></td></tr>
<tr><td>底盘情况</td><td>正前方底部、左侧前方底部、左侧后方底部、右侧后方底部、右侧前方底部</td><td></td></tr>
<tr><td>轮胎情况</td><td>左前轮、左后轮(内/外)、右后轮(内/外)、右前轮、备胎(有备胎时)</td><td>轮胎项须 OCR 胎纹可编辑OCR 失败禁止拍下一张</td></tr>
<tr><td>瑕疵情况</td><td>连拍完成后可补拍多张</td><td></td></tr>
<tr><td>其他情况</td><td>连拍完成后可补拍多张</td><td></td></tr>
</table>
<div class="dev-box">
<strong>上传与水印:</strong>每次点击「完成」继续时,上一张自动上传并在服务端打水印(拍摄时间 <code>watermarkTime</code>、地点 <code>watermarkAddress</code>,取自交车位置解析结果)。
</div>
<div class="info-box">
<strong>相册上传:</strong>交车模块内<strong>所有拍照环节</strong>均支持从手机相册本地上传,包括识别车牌、车辆配置拍照、手动记录证件照、交车连拍/补拍、瑕疵与其他照片、备胎拍摄等;相机页提供「拍照」「相册」按钮。
</div>
<h3>拍照调焦V1.1</h3>
<div class="info-box">
<strong>适用范围:</strong>交车模块内<strong>所有拍照场景</strong>须支持调焦,包括:步骤三连拍相机页、备胎拍摄、车辆配置(车身广告/放大字)、手动记录证件照。
</div>
<table class="data">
<tr><th style="width:22%">交互</th><th>说明</th></tr>
<tr><td>拍照 / 相册</td><td>相机页底部「拍照」调用相机;「相册」从本地上传图片(识别车牌支持底部选择「拍照识别」「相册识别」)</td></tr>
<tr><td>点击取景区域</td><td>在取景画面上点击任意位置,显示白色对焦框并以其为中心调整预览缩放原点</td></tr>
<tr><td>变焦控制</td><td>取景区右侧「− / 倍数 / +」按钮,支持 1.0×3.0× 数码变焦,步进 0.1×</td></tr>
<tr><td>提示文案</td><td>取景区底部展示「点击画面调焦」;完成拍摄后提示可隐藏</td></tr>
<tr><td>重新拍摄</td><td>点击「重新拍摄」后保留当前会话,重置对焦点与变焦倍数</td></tr>
</table>
<div class="shot-wrap">
<img src="delivery-manual-capture/screenshots/09-camera-focus.png" alt="连拍相机页-调焦" />
<div class="shot-cap">图 4 · 连拍相机页支持点击调焦与变焦(原型截图)</div>
</div>
<h2 id="s8">八、签章与被授权人</h2>
<div class="step-card">
<div class="step-card-header"><div class="step-num">6</div><h3>选择被授权人 + 发送签章</h3></div>
<div class="step-card-body">
<div class="step-text">
<ul>
<li>连拍全部完成后,底部展示「保存」「发送签章文件」</li>
<li>被授权人:多卡片展示姓名 + 手机号,选中高亮(参照账号绑定卡片交互)</li>
<li>发送前校验:必填照片齐全 + 已选被授权人</li>
<li>发送后跳转 E签宝 页完成运维签字 → 状态「待客户签章」</li>
<li>待客户签章查看页:「返回」「清除签章」;清除后可重选被授权人并重新发送</li>
<li>客户短信签章完成 →「客户已签章」,进入已完成列表,可下载 PDF</li>
</ul>
</div>
<div class="ui-mock">
<div class="ui-mock-title">界面示意 · 被授权人卡片(参照账号绑定样式)</div>
<div class="ui-section"><span class="ui-section-num">6</span>选择被授权人
<div style="margin-top:6px">
<span class="ui-card active">李晓明<br><span style="color:#64748b">138****8001</span></span>
<span class="ui-card">王芳<br><span style="color:#64748b">139****9002</span></span>
<span class="ui-card">赵强<br><span style="color:#64748b">137****7003</span></span>
</div>
<div style="margin-top:8px;text-align:right">
<span class="ui-btn ui-btn-ghost">保存</span>
<span class="ui-btn ui-btn-primary">发送签章文件</span>
</div>
</div>
</div>
</div>
</div>
<h2 id="s9" class="page-break">九、校验规则与拦截逻辑</h2>
<table class="data">
<tr><th>触发点</th><th>校验函数</th><th>校验项</th><th>失败行为</th></tr>
<tr><td>步骤一「下一步」</td><td><code>dvValidateVehicleStep</code></td><td>车牌;有广告须拍照;驾驶培训完成;里程/氢量/电量;非 GPS 须定位</td><td><code>message.warning</code>,停留当前步</td></tr>
<tr><td>步骤二「下一步」</td><td><code>dvValidateInspectionStep</code></td><td>轮胎胎纹深度(无备胎跳过备胎行)</td><td>同上</td></tr>
<tr><td>连拍下一张</td><td>相机页内校验</td><td>轮胎项 OCR 须成功(<code>treadOcrOk</code></td><td>禁止继续</td></tr>
<tr><td>发送签章文件</td><td><code>validateDeliveryBeforeSign</code></td><td>车牌;里程/氢量/电量;必填照片齐全;被授权人已选</td><td>拦截并可能跳转照片步</td></tr>
<tr><td>手动记录培训</td><td><code>generateDriverTrainingCode</code> / <code>refreshDriverTrainingStatus</code></td><td>运维录入信息齐全后生成培训码;司机签字后刷新完成</td><td>拦截</td></tr>
</table>
<div class="info-box">
步骤一、步骤二「下一步」校验通过后调用 <code>persistDeliveryDraft(true)</code> 静默保存,状态由「未开始」变为「已保存」(若尚未进入签章流程)。
</div>
<h2 id="s10">十、数据模型与字段速查</h2>
<h3>表单草稿核心字段formDraft</h3>
<table class="data">
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td>plateNo</td><td>string</td><td>交车车牌</td></tr>
<tr><td>rearEquip / hasAd / hasTailgate</td><td>object / string</td><td>后装设备配置</td></tr>
<tr><td>adPhotoUploaded / bigWordPhotoUploaded</td><td>boolean</td><td>广告/放大字照片</td></tr>
<tr><td>spareTire</td><td>'有' | '无'</td><td>是否备胎</td></tr>
<tr><td>driverTrainingDone / driverTraining</td><td>boolean / string</td><td>驾驶培训状态</td></tr>
<tr><td>deliveryMileage / deliveryH2 / deliveryElec</td><td>number|string</td><td>交车数据</td></tr>
<tr><td>deliveryH2Unit</td><td>'%' | 'MPa'</td><td>氢量单位,随车型</td></tr>
<tr><td>deliveryLocation</td><td>{lat,lng,address,source}</td><td>交车位置</td></tr>
<tr><td>inspectionList</td><td>array</td><td>检查单行 {key,category,item,checked,treadDepth,remark}</td></tr>
<tr><td>deliveryPhotos</td><td>object</td><td>照片记录 keyed by photoKey</td></tr>
<tr><td>authorizedPersonId/Name/Phone</td><td>string</td><td>被授权人</td></tr>
<tr><td>signSent</td><td>boolean</td><td>是否已发送签章</td></tr>
<tr><td>deliveryStatus</td><td>enum</td><td>交车状态</td></tr>
</table>
<h2 id="s11">十一、外部依赖与接口约定</h2>
<table class="data">
<tr><th>依赖</th><th>用途</th><th>原型阶段</th></tr>
<tr><td>车辆 GPS</td><td>在线车辆自动取坐标</td><td>按备车数据 onlineStatus 模拟</td></tr>
<tr><td>手机定位</td><td>离线车辆获取当前位置</td><td>模拟坐标写入 deliveryLocation</td></tr>
<tr><td>OCR 车牌</td><td>识别车牌匹配车辆</td><td>演示车牌轮询</td></tr>
<tr><td>OCR 胎纹</td><td>轮胎/备胎胎纹深度</td><td>演示读数;空值模拟失败</td></tr>
<tr><td>文件上传</td><td>照片上传 + 水印</td><td>simulate 上传,写入 watermark 字段</td></tr>
<tr><td>E签宝</td><td>运维签字 + 客户短信签章</td><td>内嵌签字页 + 模拟客户签章按钮</td></tr>
<tr><td>微信扫码</td><td>驾驶培训视频</td><td>静态培训二维码</td></tr>
</table>
<h2 id="s12">十二、非功能需求与边界</h2>
<ul>
<li><strong>权限:</strong>按运维人员区域权限过滤交车任务(默认嘉兴市)</li>
<li><strong>只读态:</strong>待客户签章、客户已签章进入只读浏览,步骤条可切换查看</li>
<li><strong>触控:</strong>主要按钮触控区域 ≥ 44px相机取景区支持点击调焦</li>
<li><strong>断点续办:</strong>连拍进度持久化在 deliveryPhotos退出后再进入从下一未拍项续拍</li>
<li><strong>不在范围:</strong>表单内不展示交车时间输入;不与保单/台账自动同步</li>
</ul>
<h2 id="s13" class="page-break">十三、界面截图(原型)</h2>
<p>以下截图为小羚羚交车原型实际界面,与 V1.1 需求一致,供研发与测试对照。</p>
<div class="step-card">
<div class="step-card-header"><div class="step-num">1</div><h3>入口与列表</h3></div>
<div class="step-card-body" style="grid-template-columns:1fr 1fr">
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/02-business.png" alt="业务入口" /><div class="shot-cap">业务 · 交车入口</div></div>
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/03-delivery-list.png" alt="交车列表" /><div class="shot-cap">交车任务列表</div></div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">2</div><h3>分步办理</h3></div>
<div class="step-card-body" style="grid-template-columns:1fr 1fr">
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/04-form-vehicle.png" alt="车辆情况" /><div class="shot-cap">步骤一 · 车辆情况</div></div>
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/05-form-inspection.png" alt="检查项" /><div class="shot-cap">步骤二 · 交车检查项</div></div>
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/06-form-photos.png" alt="拍摄照片" /><div class="shot-cap">步骤三 · 照片分类展示</div></div>
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/09-camera-focus.png" alt="调焦" /><div class="shot-cap">连拍相机 · 调焦</div></div>
</div>
</div>
<div class="step-card">
<div class="step-card-header"><div class="step-num">3</div><h3>签章流程</h3></div>
<div class="step-card-body" style="grid-template-columns:1fr 1fr">
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/07-authorized-person.png" alt="被授权人" /><div class="shot-cap">选择被授权人</div></div>
<div class="shot-wrap"><img src="delivery-manual-capture/screenshots/08-sign-pending.png" alt="待签章" /><div class="shot-cap">待客户签章查看</div></div>
</div>
</div>
<div class="footer-note">
ONE-OS 小羚羚 · 交车模块 PRD V1.1 · 含原型界面截图 · 仅供内部研发使用 · 2026-06-09
</div>
</body>
</html>