v24 第 5 轮:十条清单(天气填城市 / 输入即筛选 / 看板列=看板 / 账本盘点折线图 / 纪念日分类)
用户 2026-10-03 的十条,逐条落点: 1. 天气改为**个人设置里填城市**(每人一份):新增 app/Geo.php,内置 197 个 地级市坐标(离线、逐条核对,生成脚本 _tooling/_fb_geo_gen.py)。填坐标仍 作为内置表没有时的出口;老的家庭级坐标保留为兜底,升级当天天气不会凭空消失。 2. 所有"找个人"的地方**输入即筛选**:新增 assets/js/filter.js(纯前端显隐, 不发请求、回车不刷新)+ app/PersonQuery.php 把服务端判据收敛成一份 (名册 / 挑人 / 高级搜索共用,避免三处实现漂移)。 3. 名册列表:有昵称就不重复显示本名、行变矮、补齐手机/阴历阳历生日(带年份)/ 邮箱/工作单位;「清除」与「搜索」同款同尺寸。 4/5. 日程:撤掉左侧日历本栏改满宽,功能(显隐/颜色/导入/默认视图)全收进 右侧 ☰;**色块高度改为按起止时长**(旧实现一律 30 分钟,三小时的会跟 十五分钟的同高);点日历空白处即建日程,开始时间=点的那一格。 6/10. 资源:搜索提到最上;按"最近改动/最新新增"排序,默认只显示最新 10 条并 给「显示全部」出口。 7. 任务:看板的**列=用户自定义的看板**(不再是写死的待办/进行中), 拖动/左右键=换看板(改 board_id,不动 status)。 8. 财务:概览在上账目在下、记一笔改右侧按钮、账本设置(共享/改名/新建/删除) 收进 ☰、默认账本名「xxx的账本」、"挂在谁名下"默认自己且用标准选人框; **新增盘点**(新增 ledger_entry_snapshots 只增不改的历史表,旧值不被清空) + 上面画金额变化折线图(app/chart.php 服务端画 SVG,零依赖)。 9. 纪念日:手动添加的与名册生日派生的**分两块**、手动的在上;右侧设置可增删 分类(家庭级,删分类不强改已用的历史)。 本轮另外修掉/加固的四类问题(都由新增的静态或运行时守卫兜住): - index.php 少写 2 个 use 导入(Pinyin / UserSetting)→ 名册与个人设置 返回 200 但正文是 Fatal;顺带修了一处早已存在的 Attachment 未导入。 → 新增 _fb_import_check.py(1f 段)。 - 一次不精确替换弄丢了 app/Calendar.php 开头的 `<?php`,整份源码被当 HTML 吐给浏览器,而 `php -l` 报"无语法错误"(纯文本输出确实合法)。 → 新增 _fb_php_open_check.py(1e 段)。 - 模板片段 unset 了宿主模板的变量(账本片段 unset($canWrite))→ 正文里一片 Undefined variable 而 HTTP 仍 200。同 _datetime.php 早年 $t 的坑。 → 新增 _fb_fragment_scope_check.py(1g 段)+ _fb_batch_e.py 的 26 页无告警巡检。 - 窄屏下页头动作区不换行 → 周视图横向溢出且按钮被挤成三种高度(用户提过三次 "按钮要同高")→ .page-head .actions 加 flex-wrap。 验证战绩(全绿): e2e 773/0 · 第 5 轮专项 91/0 · 结构升级 126/0 · 几何 428/0 · 移动端 684/0 · 交互 97/0 · 家谱 26/0 · 按钮 60/0;三轮反向验证各 3/3 抓到,还原后复绿。 线上:schema v14、指纹一致(9df6c9fccc6796db)、snapshots 表已建、197 城、 8 个关键文件 md5 与本地逐字节一致、app/ 403 无源码泄漏、错误日志无新增。
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* 账本模块的「设置」下拉(v24 用户 2026-10-03 第 7 条)
|
||||
*
|
||||
* 用户原话:「共享账本,改名等内容,都放在账本的设置中,也是一样的,
|
||||
* 在新建账目按钮旁边,加一个设置按钮,在里面对账本进行设置、共享等。」
|
||||
*
|
||||
* 所以原来那个「共享与账本」大卡片撤了,里面的东西全搬进这个 ☰:
|
||||
* 共享给谁 / 取消共享 / 账本改名 / 新建账本 / 删除这本账。
|
||||
* 外观与观影、任务的设置下拉一致(只留图标、排最右、条目带小图标)。
|
||||
*
|
||||
* ⚠️⚠️ 本片段是 `require` 进**另一个模板**里的,而 PHP 的 require 共享同一个作用域 ——
|
||||
* 所以这里**绝不能**定义 / 覆盖 / unset 宿主模板用到的名字(`$canWrite` / `$curId`…)。
|
||||
* 本条已实测踩到:片段结尾写了 `unset($canWrite, $curId)`,把宿主模板的
|
||||
* `$canWrite` 一起干掉了 → 后面每一行 `<?php if ($canWrite): ?>` 都变成
|
||||
* "Undefined variable"(页面在 debug 下会**直接把 Warning 打进正文**,
|
||||
* 看着像排版坏了一小段,其实是变量被偷走)。
|
||||
* 同理,_datetime.php 早年在任务页覆盖过 $t —— 同一个坑,别再踩第三次。
|
||||
* 所以下面所有局部变量一律加 `$ledSet` 前缀,并且只 unset **自己定义**的那些。
|
||||
*
|
||||
* 用法(require 前 set 好):
|
||||
* $cur 当前账本(含 name / my_perm)
|
||||
* $shares 当前账本的共享列表
|
||||
* $people 名册(共享给谁)
|
||||
*/
|
||||
$ledSetCanWrite = \App\Auth::canWrite() && \App\Ledger::canWrite($cur ?? []);
|
||||
$ledSetCurId = (int)($cur['id'] ?? 0);
|
||||
$ledSetIcon = static function (string $name): string {
|
||||
$paths = [
|
||||
'share' => '<circle cx="6" cy="6.2" r="2.4"/><circle cx="12.4" cy="9.6" r="2"/><path d="M2.2 13.4c0-1.9 1.7-3 3.8-3s3.8 1.1 3.8 3M9.6 13.4c0-1.5 1.3-2.4 2.8-2.4s2.8.9 2.8 2.4"/>',
|
||||
'rename'=> '<path d="M2.6 13.4l.6-3 7.4-7.4 2.4 2.4-7.4 7.4zM9.6 4l2.4 2.4"/>',
|
||||
'add' => '<path d="M8 3.2v9.6M3.2 8h9.6"/>',
|
||||
'del' => '<path d="M3.4 4.6h9.2M6.6 4.6V3.2h2.8v1.4M4.8 4.6l.7 8.8h5l.7-8.8"/>',
|
||||
];
|
||||
$d = $paths[$name] ?? '';
|
||||
if ($d === '') { return ''; }
|
||||
return '<svg class="mi" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"'
|
||||
. ' fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"'
|
||||
. ' stroke-linejoin="round">' . $d . '</svg>';
|
||||
};
|
||||
?>
|
||||
<details class="movie-set menu led-set">
|
||||
<summary class="btn btn-icon" title="账本设置" aria-label="账本设置"><svg viewBox="0 0 16 16" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11"/></svg></summary>
|
||||
<div class="menu-list led-set-list">
|
||||
|
||||
<?php if (!$ledSetCanWrite): ?>
|
||||
<div class="led-set-block">
|
||||
<p class="small muted" style="margin:0">这本账你只有只读权限,能看不能改。</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
|
||||
<?php /* ---- 共享:给谁 + 权限 + 取消 ---- */ ?>
|
||||
<div class="led-set-block">
|
||||
<div class="cal-set-h">共享给谁(对方就能记能看)</div>
|
||||
<?php if (!empty($shares)): ?>
|
||||
<ul class="led-set-shares">
|
||||
<?php foreach ($shares as $s): ?>
|
||||
<li>
|
||||
<?= person_chip([
|
||||
'id' => (int)$s['person_id'], 'name' => (string)$s['name'],
|
||||
'avatar' => $s['avatar'] ?? null, 'avatar_color' => $s['avatar_color'] ?? null,
|
||||
]) ?>
|
||||
<span class="node-badge"><?= ($s['perm'] ?? 'read') === 'write' ? '可写' : '只读' ?></span>
|
||||
<form method="post" action="<?= e(url('ledger/unshare')) ?>" class="res-inline">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $ledSetCurId ?>">
|
||||
<input type="hidden" name="person_id" value="<?= (int)$s['person_id'] ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit">取消</button>
|
||||
</form>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<p class="small muted" style="margin:0 0 6px">还没有共享给任何人。</p>
|
||||
<?php endif; ?>
|
||||
<form method="post" action="<?= e(url('ledger/share')) ?>" class="led-set-form-in">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $ledSetCurId ?>">
|
||||
<?php
|
||||
$ppName = 'person_id';
|
||||
$ppPeople = $people;
|
||||
$ppSelected = [];
|
||||
$ppMode = 'single';
|
||||
$ppOpenBtn = '选择共享给谁';
|
||||
$ppTitle = '账本共享给谁';
|
||||
$ppEmptyText= '未选择';
|
||||
require __DIR__ . '/../_person_picker.php';
|
||||
?>
|
||||
<select class="select" name="perm">
|
||||
<?php foreach (\App\Ledger::PERM as $pk => $pv): ?>
|
||||
<option value="<?= e($pk) ?>"><?= e($pv) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button class="btn btn-sm" type="submit">共享</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php /* ---- 改名 ---- */ ?>
|
||||
<div class="led-set-block">
|
||||
<div class="cal-set-h">账本名字</div>
|
||||
<form method="post" action="<?= e(url('ledger/book_rename')) ?>" class="led-set-form-in">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $ledSetCurId ?>">
|
||||
<input class="input" name="name" value="<?= e((string)($cur['name'] ?? '')) ?>" required>
|
||||
<button class="btn btn-sm" type="submit">改名</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php /* ---- 新建 / 删除 ---- */ ?>
|
||||
<div class="led-set-block">
|
||||
<form method="post" action="<?= e(url('ledger/book_add')) ?>" class="led-set-form-in">
|
||||
<?= csrf_field() ?>
|
||||
<input class="input" name="name" placeholder="新账本名,如:孩子的教育金" required>
|
||||
<button class="btn btn-sm" type="submit">新建账本</button>
|
||||
</form>
|
||||
<form method="post" action="<?= e(url('ledger/book_del')) ?>" class="led-set-form-in" style="margin-top:6px">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $ledSetCurId ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit"
|
||||
onclick="return confirm('删掉这本账?里面的账目会一起删掉。')">删除这本账</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</details>
|
||||
<?php
|
||||
unset($ledSetCanWrite, $ledSetCurId, $ledSetIcon);
|
||||
+148
-98
@@ -1,33 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* 财务 / 账本(v24 用户第 15 条)
|
||||
* 财务 / 账本(v24 用户第 15 条;2026-10-03 第 7、8 条重排)。
|
||||
*
|
||||
* 用户原话:「先创建一个家庭,或者说,创建一个账本,这个账本,可以共享给某个人,
|
||||
* 共享后,这个人就可以往这个账本加入账目,这样,双方都可以看到所有的账目,
|
||||
* 最后计算出总数,这就是一个家庭的总账目。」
|
||||
* 用户要求的页面结构(第 7 条原话):
|
||||
* 「上面是概览,下面就是具体账目,添加账目的功能和新增日程之类的一样,
|
||||
* 放在右侧的按钮。……共享账本,改名等内容,都放在账本的设置中,
|
||||
* 也是一样的,在新建账目按钮旁边,加一个设置按钮,在里面对账本进行设置、共享等。
|
||||
* 挂在谁名下,应该默认是自己,如果要更改,点一下,弹出选人框。」
|
||||
*
|
||||
* 页面结构就是照着这句话来的:
|
||||
* 顶上一排账本(切换 / 新建)→ 汇总卡(资产 / 负债 / 净资产)→ 账目表 → 共享设置。
|
||||
* 第 8 条(盘点):
|
||||
* 「我点击盘点,让我对一个账目的金额进行重新输入,但是盘点之前的账目数目不能清空,
|
||||
* 要记住,这样的话,每个账目的变化,就知道了……然后把这种变化,每个账目的
|
||||
* 金额变化,还有总金额的变化,在账本列表上面,画出一个图,折线图这样的。」
|
||||
* → 所以「账目」这块的最上面是**图**(整本账 + 每条有盘点记录的账目),
|
||||
* 下面是账目表,每行带一个「盘点」入口。
|
||||
*
|
||||
* ⚠️ 金额全程以**分**参与计算(Ledger 里做的),这里只负责显示成元。
|
||||
* 任何地方都不要拿元去加总。
|
||||
*
|
||||
* @param array $books 我能看到的账本(带 my_perm / entry_count)
|
||||
* @param array $cur 当前账本
|
||||
* @param array $entries 当前账本的账目
|
||||
* @param array $summary ['asset','debt','net','by_kind','count'](单位:分)
|
||||
* @param array $shares 当前账本的共享列表
|
||||
* @param array $people 名册
|
||||
* @param array $books 我能看到的账本(带 my_perm / entry_count)
|
||||
* @param array $cur 当前账本
|
||||
* @param array $entries 当前账本的账目
|
||||
* @param array $summary ['asset','debt','net','by_kind','count'](单位:分)
|
||||
* @param array $shares 当前账本的共享列表
|
||||
* @param array $charts 有盘点历史的账目 → ['entry'=>行, 'series'=>[…] ]
|
||||
* @param array $timeline 整本账的净资产时间线
|
||||
* @param array $people 名册
|
||||
*/
|
||||
$canWrite = \App\Auth::canWrite() && \App\Ledger::canWrite($cur);
|
||||
$curId = (int)$cur['id'];
|
||||
$money = static fn($c): string => \App\Ledger::money($c);
|
||||
$charts = $charts ?? [];
|
||||
$timeline = $timeline ?? [];
|
||||
// 用户第 8 条:「挂在谁名下,应该默认是自己」。这里的 $me 由 index.php 传进来(当前登录者)。
|
||||
// ⚠️ 别用 `$me ?? 0` 再判 0 —— 那样一旦没传进来就会静默变成"不选",看着像默认值丢了。
|
||||
$ledMe = (int)($me ?? 0);
|
||||
?>
|
||||
<div class="page-head">
|
||||
<h1>财务</h1>
|
||||
<span class="sub">家庭的账 · 共享后双方都能记、都能看</span>
|
||||
<span class="sub"><?= e((string)$cur['name']) ?> · 共享后双方都能记、都能看</span>
|
||||
<div class="actions">
|
||||
<a class="btn btn-ghost" href="<?= e(url('ledger', ['book' => $curId])) ?>">刷新</a>
|
||||
<?php /* 用户第 7 条:加账目 = 右侧按钮(与「新建日程」同一套) */ ?>
|
||||
<?php if ($canWrite): ?>
|
||||
<button class="btn" type="button" id="ledAddBtn">记一笔</button>
|
||||
<?php else: ?>
|
||||
<span class="link-quiet">只读</span>
|
||||
<?php endif; ?>
|
||||
<?php /* 用户第 7 条:共享 / 改名 / 新建 / 删除 全在账本设置里(☰) */ ?>
|
||||
<?php $setCurrent = 'book'; require __DIR__ . '/_settings_menu.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,6 +62,7 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* ==================== ① 概览 ==================== */ ?>
|
||||
<div class="card card-pad led-sum">
|
||||
<div class="led-sum-head">
|
||||
<h2 class="cinema-h2" style="margin:0"><?= e((string)$cur['name']) ?></h2>
|
||||
@@ -79,7 +100,7 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
</div>
|
||||
|
||||
<?php if ($canWrite): ?>
|
||||
<div class="card card-pad">
|
||||
<div class="card card-pad led-add" id="ledAddCard" hidden>
|
||||
<h2 class="cinema-h2">记一笔</h2>
|
||||
<form method="post" action="<?= e(url('ledger/entry_add')) ?>">
|
||||
<?= csrf_field() ?>
|
||||
@@ -104,13 +125,22 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
<span class="tip">负债(贷款/信用卡)也填正数,系统按类别算成负债。</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="le-person">挂在谁名下</label>
|
||||
<select class="select" id="le-person" name="person_id">
|
||||
<option value="0">不指定</option>
|
||||
<?php foreach ($people as $p): ?>
|
||||
<option value="<?= (int)$p['id'] ?>"><?= e(person_name($p)) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php /* 用户第 7 条:「挂在谁名下,应该默认是自己,如果要更改,点一下,弹出选人框」
|
||||
—— 用全局选人组件(与观影选人同一套,含拼音首字母联想)。 */ ?>
|
||||
<label>挂在谁名下</label>
|
||||
<?php
|
||||
$ppName = 'person_id';
|
||||
$ppPeople = $people;
|
||||
// 默认就是**我自己**(用户第 8 条)。单选组件按 $ppSelected 勾选并渲染 chip,
|
||||
// 传 [0] 的话会渲染成"未选择"——所以必须传真实 id。
|
||||
$ppSelected = $ledMe > 0 ? [$ledMe] : [];
|
||||
$ppMode = 'single';
|
||||
$ppOpenBtn = '更换归属人';
|
||||
$ppTitle = '这笔账挂在谁名下';
|
||||
$ppEmptyText= '不指定';
|
||||
$ppAllowEmpty = true;
|
||||
require __DIR__ . '/../_person_picker.php';
|
||||
?>
|
||||
</div>
|
||||
<div class="field full">
|
||||
<label for="le-note">备注</label>
|
||||
@@ -122,6 +152,46 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* ==================== ② 变化图(用户第 8 条)==================== */ ?>
|
||||
<?php if ($charts || count($timeline) > 1): ?>
|
||||
<div class="card card-pad led-charts">
|
||||
<h2 class="cinema-h2">
|
||||
金额变化
|
||||
<span class="hint">每次「盘点」记一个点,旧数字不会被清掉</span>
|
||||
</h2>
|
||||
<div class="ck-grid">
|
||||
<?php if (count($timeline) > 1): ?>
|
||||
<div class="ck-card">
|
||||
<div class="ck-head">
|
||||
<b>整本账 · 净资产</b>
|
||||
<span class="small muted"><?= count($timeline) ?> 个时间点</span>
|
||||
</div>
|
||||
<?= chart_line($timeline, '净资产', 'asset', 320) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($charts as $ch): ?>
|
||||
<?php $en = $ch['entry']; $ek = (string)$en['kind']; ?>
|
||||
<div class="ck-card">
|
||||
<div class="ck-head">
|
||||
<b><?= e((string)$en['title']) ?></b>
|
||||
<span class="small muted">
|
||||
<?= \App\Ledger::kindIcon($ek) ?> <?= e(\App\Ledger::kindWord($ek)) ?>
|
||||
· <?= count($ch['series']) ?> 个点
|
||||
</span>
|
||||
</div>
|
||||
<?= chart_line($ch['series'], (string)$en['title'], \App\Ledger::isDebt($ek) ? 'debt' : 'asset', 320) ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (!$charts): ?>
|
||||
<p class="small muted" style="margin:8px 2px 0">
|
||||
还没有任何盘点记录 —— 下面账目表里每行都有「盘点」,盘过之后这里就会出现它自己的曲线。
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* ==================== ③ 账目 ==================== */ ?>
|
||||
<div class="card card-pad">
|
||||
<h2 class="cinema-h2">账目(<?= count($entries) ?>)</h2>
|
||||
<?php if (!$entries): ?>
|
||||
@@ -134,7 +204,7 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($entries as $en): ?>
|
||||
<?php $ek = (string)$en['kind']; $debt = \App\Ledger::isDebt($ek); ?>
|
||||
<?php $ek = (string)$en['kind']; $debt = \App\Ledger::isDebt($ek); $eid = (int)$en['id']; ?>
|
||||
<tr>
|
||||
<td class="nowrap">
|
||||
<span class="led-kind-chip<?= $debt ? ' is-debt' : '' ?>">
|
||||
@@ -158,11 +228,50 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
<td class="nowrap">
|
||||
<?php if ($canWrite): ?>
|
||||
<details class="led-edit">
|
||||
<summary class="link-quiet">改</summary>
|
||||
<summary class="link-quiet">操作</summary>
|
||||
|
||||
<?php /* ---- 盘点(用户第 8 条):重新输一个金额,旧值进历史 ---- */ ?>
|
||||
<form method="post" action="<?= e(url('ledger/reconcile')) ?>" class="node-form led-recon">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<input type="hidden" name="id" value="<?= $eid ?>">
|
||||
<h4 class="led-form-h">盘点这笔(旧金额会记进历史)</h4>
|
||||
<div class="nf-grid">
|
||||
<div class="field">
|
||||
<label>盘点后的金额(元)</label>
|
||||
<input class="input" name="amount" inputmode="decimal" required
|
||||
value="<?= e(\App\Ledger::amountYuan((int)$en['amount_cents'])) ?>">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>盘点备注</label>
|
||||
<input class="input" name="note" placeholder="如:2026 年初盘点">
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-row"><button class="btn btn-sm" type="submit">盘点</button></div>
|
||||
<?php if (\App\Ledger::history($eid)): ?>
|
||||
<details class="led-hist">
|
||||
<summary class="link-quiet">看历史(<?= count(\App\Ledger::history($eid)) ?> 次)</summary>
|
||||
<ul class="led-hist-list">
|
||||
<?php foreach (\App\Ledger::history($eid) as $hs): ?>
|
||||
<li>
|
||||
<span class="nowrap"><?= e(substr((string)$hs['created_at'], 0, 10)) ?></span>
|
||||
<b><?= e($money((int)$hs['amount_cents'])) ?></b>
|
||||
<?php if (($hs['note'] ?? '') !== ''): ?>
|
||||
<span class="muted small"><?= e((string)$hs['note']) ?></span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</details>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
|
||||
<?php /* ---- 改 / 删(改 = 修正录错了,与"盘点"是两件事,见 Ledger::reconcile)---- */ ?>
|
||||
<form method="post" action="<?= e(url('ledger/entry_update')) ?>" class="node-form">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<input type="hidden" name="id" value="<?= (int)$en['id'] ?>">
|
||||
<input type="hidden" name="id" value="<?= $eid ?>">
|
||||
<h4 class="led-form-h">更正这笔(当作当初就录错了,不留历史)</h4>
|
||||
<div class="nf-grid">
|
||||
<div class="field">
|
||||
<label>类别</label>
|
||||
@@ -188,12 +297,12 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
<input class="input" name="note" value="<?= e((string)($en['note'] ?? '')) ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-row"><button class="btn btn-sm" type="submit">保存</button></div>
|
||||
<div class="btn-row"><button class="btn btn-sm" type="submit">保存更正</button></div>
|
||||
</form>
|
||||
<form method="post" action="<?= e(url('ledger/entry_del')) ?>" class="res-inline">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<input type="hidden" name="id" value="<?= (int)$en['id'] ?>">
|
||||
<input type="hidden" name="id" value="<?= $eid ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit"
|
||||
onclick="return confirm('删掉这笔账目?')">删除</button>
|
||||
</form>
|
||||
@@ -215,74 +324,15 @@ $money = static fn($c): string => \App\Ledger::money($c);
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card card-pad">
|
||||
<h2 class="cinema-h2">共享与账本</h2>
|
||||
<div class="led-shares">
|
||||
<span class="res-label">已共享给</span>
|
||||
<?php if (!$shares): ?>
|
||||
<span class="small muted">还没有共享给任何人。</span>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($shares as $s): ?>
|
||||
<span class="led-share-chip">
|
||||
<?= person_chip([
|
||||
'id' => (int)$s['person_id'], 'name' => (string)$s['name'],
|
||||
'avatar' => $s['avatar'] ?? null, 'avatar_color' => $s['avatar_color'] ?? null,
|
||||
]) ?>
|
||||
<span class="node-badge"><?= ($s['perm'] ?? 'read') === 'write' ? '可写' : '只读' ?></span>
|
||||
<?php if ($canWrite): ?>
|
||||
<form method="post" action="<?= e(url('ledger/unshare')) ?>" class="res-inline">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<input type="hidden" name="person_id" value="<?= (int)$s['person_id'] ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit">取消</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($canWrite): ?>
|
||||
<div class="led-ops">
|
||||
<?php
|
||||
$ppName = 'person_id';
|
||||
$ppPeople = $people;
|
||||
$ppSelected = [];
|
||||
$ppMode = 'single';
|
||||
$ppOpenBtn = '选择共享给谁';
|
||||
$ppTitle = '账本共享给谁';
|
||||
$ppEmptyText = '未选择';
|
||||
?>
|
||||
<form class="inline-form" method="post" action="<?= e(url('ledger/share')) ?>">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<?php require __DIR__ . '/../_person_picker.php'; ?>
|
||||
<select class="select" name="perm">
|
||||
<?php foreach (\App\Ledger::PERM as $pk => $pv): ?>
|
||||
<option value="<?= e($pk) ?>"><?= e($pv) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button class="btn btn-sm" type="submit">共享</button>
|
||||
</form>
|
||||
|
||||
<form class="inline-form" method="post" action="<?= e(url('ledger/book_rename')) ?>">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<input class="input" name="name" value="<?= e((string)$cur['name']) ?>" required>
|
||||
<button class="btn btn-ghost btn-sm" type="submit">账本改名</button>
|
||||
</form>
|
||||
|
||||
<form class="inline-form" method="post" action="<?= e(url('ledger/book_add')) ?>">
|
||||
<?= csrf_field() ?>
|
||||
<input class="input" name="name" placeholder="新账本名,如:孩子的教育金" required>
|
||||
<button class="btn btn-ghost btn-sm" type="submit">新建账本</button>
|
||||
</form>
|
||||
|
||||
<form class="inline-form" method="post" action="<?= e(url('ledger/book_del')) ?>">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit"
|
||||
onclick="return confirm('删掉这本账?里面的账目会一起删掉。')">删除这本账</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById('ledAddBtn');
|
||||
var card = document.getElementById('ledAddCard');
|
||||
if (!btn || !card) return;
|
||||
btn.addEventListener('click', function () {
|
||||
card.hidden = !card.hidden;
|
||||
btn.textContent = card.hidden ? '记一笔' : '收起';
|
||||
if (!card.hidden) { card.scrollIntoView({ block: 'nearest' }); }
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user