用户 10 条原话要点与落地:
- ①「统计出来的不是目的地,也不是车站,而是城市…城市要聚合,有多段行程,
都有青岛作为出发地或者目的地,那么就只记一次」
→ trip_nodes 补 from_city/to_city(Schema v22),Trip::cities() 改成
「出发地 ∪ 到达地」去重、按最早时间 + 出发地优先排。
详情页信息区显示的就是这个聚合结果(第 4 条:「图片右侧显示的是聚合的城市,
而不是终点地址」)。
- ②「类型不够丰富,你看看 triplog 里面都有哪些,都拿过来」
→ NodeType::TRIPLOG_TYPES(休息/突发/购物/拜访亲友),在 all() 里读时自愈补齐。
- ③「出行方式,只有选择自驾,才让选车辆;车辆下拉框不需要出现什么财务里登记的车,
只把车辆列出来就行了」→ DRIVE_MODES 收窄成 ['drive'];
Vehicle::pickable() 只回车辆库;车辆页删掉「财务里已登记的车」那块。
- ③「飞机、铁路,只记录车次、航班号就可以…座位什么的不记录了」
→ seat_info / gate 从表单与列表**彻底移除**(列保留,老数据不丢;
saveNode 的 UPDATE 也不再写这两列,否则会抹掉迁来的数据)。
- ③「出发地和到达地,都用高德地图的接口,记录详细地址」+「参与人弹框选择」
+「给参与人标注角色这个功能去掉」
→ 新增 templates/trips/_loc_field.php(高德联想 + 详细地址 + 坐标 + 城市 +
导航链接,没配 key 也能手输);参与人改用全局弹框选人组件;
角色输入框删除,saveNodeMembers 改成差集增删(否则老 role_tag 被静默抹掉)。
- ④「triplog 中的行程花销数据,没有同步过来,需要迁移过来」
→ 新增 _tooling/_fb_b17_backfill.php:迁地址(20 条)、花销(4 笔 ¥8584)、
车辆(3 台)。线上已执行并核对(笔数与金额一分不差)。
- ④「行程中,时间明明具体到了时分秒,怎么不显示?」
→ Trip::nodeSpan():行程时间精确到时分(同一天只写一次日期、跨天写月日、
两头都没时分就不写 00:00)。
其他:
- App\Geo 扩展 cityFromPoint / cityFromText / navUrl / jsConfig。
中文地址提城市修掉四种错法(白名单→黑名单、取最后→取第一个、直辖市最先认、
离线表只能兜底),并加了「五大连池 ≠ 大连」的位置守卫。
- config.example.php 加 amap 段(key / security_js / nav_src)。
验证:
- e2e 920/0(+29 条本批断言)· 升级 149/0(+15 条 v22 断言)·
城市解析 32/32(新套件,样例全是 TripLog 线上真实地址)·
桌面几何 428/0 · 移动端 688/0 · 交互 92/0 · 窄屏溢出 24/0。
- 反向验证 5/5:城市退回读 place / 只算到达地 / 时间退回只到日期 /
打车也要车 / 类型不补 —— 五种坏法全部被断言抓住。
- 部署:服务器自检 19/19;线上 schema v22;补迁后花销 4 笔 ¥8584 与源库对齐。
105 lines
5.2 KiB
PHP
105 lines
5.2 KiB
PHP
<?php
|
||
/**
|
||
* 车辆管理(v24 第 16 批 用户第 8 条;第 17 批 第 3 条改)。
|
||
*
|
||
* 用户原话(第 16 批 第 8 条):
|
||
* 「增加一个设置按钮,用来设置车辆管理、出行方式、节点类型。
|
||
* 注意,我们在财务中,已经把车辆添加进去了…但是可以添加其他的车辆,
|
||
* 比如租的车,借别人的车。」
|
||
*
|
||
* 用户原话(**第 17 批 第 3 条 —— 本次,推翻上一批的做法**):
|
||
* 「车辆下拉框,**不需要出现什么财务里登记的车**,只把车辆列出来就行了。」
|
||
*
|
||
* ⚠️ 所以这一页现在**只有一块**:「出行用的车」(自家 / 租的 / 借的)。
|
||
* 原来那块「财务里已登记的车」整块删掉了 —— 财务里的 kind=car 是**资产账目**
|
||
* ("这台车值多少钱"),它没有车牌车型,混进选车列表只会让人发懵。
|
||
* `Vehicle::fromLedger()` 方法保留在模型层(将来按车统计油费/保养还要用它
|
||
* 跟 `vehicles.ledger_id` 对上),但**不再被任何界面调用**。
|
||
*
|
||
* @param array $mine Vehicle::all() 的结果
|
||
*/
|
||
$canWrite = \App\Auth::canWrite();
|
||
$mine = $mine ?? [];
|
||
$back = url('trips');
|
||
?>
|
||
<div class="page-head">
|
||
<h1>车辆管理</h1>
|
||
<span class="sub">出行时能挑的车:自家的、租的、借别人的</span>
|
||
<div class="actions">
|
||
<a class="btn btn-ghost" href="<?= e($back) ?>">返回旅程</a>
|
||
<?php $trSetCurrent = 'vehicles'; require __DIR__ . '/_settings_menu.php'; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card card-pad">
|
||
<h2 class="cinema-h2">
|
||
出行用的车
|
||
<span class="hint">自家车录一台方便选;租的车、借的车也录在这里</span>
|
||
</h2>
|
||
|
||
<?php if ($mine): ?>
|
||
<ul class="veh-list">
|
||
<?php foreach ($mine as $v): ?>
|
||
<li class="veh-row">
|
||
<span class="veh-ico"><?= ($v['vtype'] ?? 'own') === 'rental' ? '🔑' : (($v['vtype'] ?? 'own') === 'borrowed' ? '🤝' : '🚗') ?></span>
|
||
<?php if ($canWrite): ?>
|
||
<form class="inline-form veh-form" method="post" action="<?= e(url('trips/vehicles_save')) ?>">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="id" value="<?= (int)$v['id'] ?>">
|
||
<input class="input" name="plate" value="<?= e((string)$v['plate']) ?>"
|
||
placeholder="车牌" aria-label="车牌">
|
||
<input class="input" name="name" value="<?= e((string)$v['name']) ?>"
|
||
placeholder="车型名" required aria-label="车型名">
|
||
<select class="select" name="vtype" aria-label="来源">
|
||
<?php foreach (\App\Vehicle::TYPES as $vk => $vv): ?>
|
||
<option value="<?= e($vk) ?>"<?= (string)$v['vtype'] === $vk ? ' selected' : '' ?>>
|
||
<?= e($vv) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<input class="input" name="vendor" value="<?= e((string)($v['vendor'] ?? '')) ?>"
|
||
placeholder="租车公司 / 车主" aria-label="租车公司或车主">
|
||
<label class="veh-def">
|
||
<input type="checkbox" name="is_default" value="1"<?= (int)$v['is_default'] === 1 ? ' checked' : '' ?>>
|
||
<span>默认</span>
|
||
</label>
|
||
<button class="btn btn-sm" type="submit">保存</button>
|
||
</form>
|
||
<form class="inline-form" method="post" action="<?= e(url('trips/vehicles_del')) ?>">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="id" value="<?= (int)$v['id'] ?>">
|
||
<button class="btn btn-ghost btn-sm" type="submit"
|
||
onclick="return confirm('删掉这辆车?')">删</button>
|
||
</form>
|
||
<?php else: ?>
|
||
<span class="veh-name"><?= e(\App\Vehicle::label($v)) ?></span>
|
||
<span class="veh-tag"><?= e(\App\Vehicle::TYPES[(string)$v['vtype']] ?? '') ?></span>
|
||
<?php endif; ?>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
<?php else: ?>
|
||
<p class="empty-hint">还没有。自家车录一台,出行时能直接挑。</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($canWrite): ?>
|
||
<h3 class="set-sub">加一辆车</h3>
|
||
<form class="inline-form veh-form veh-add" method="post" action="<?= e(url('trips/vehicles_save')) ?>">
|
||
<?= csrf_field() ?>
|
||
<input class="input" name="plate" placeholder="车牌(借的车可不填)" aria-label="车牌">
|
||
<input class="input" name="name" placeholder="车型名,如「大众朗逸」" required aria-label="车型名">
|
||
<select class="select" name="vtype" aria-label="来源">
|
||
<?php foreach (\App\Vehicle::TYPES as $vk => $vv): ?>
|
||
<option value="<?= e($vk) ?>"><?= e($vv) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<input class="input" name="vendor" placeholder="租车公司 / 车主" aria-label="租车公司或车主">
|
||
<input class="input" name="order_no" placeholder="租车订单号" aria-label="租车订单号">
|
||
<label class="veh-def">
|
||
<input type="checkbox" name="is_default" value="1">
|
||
<span>设为默认</span>
|
||
</label>
|
||
<button class="btn btn-sm" type="submit">加进车辆库</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
</div>
|