Files
laoyang 48237c8947 节点详情:照片灯箱浏览、参与人点击编辑、花销只记总计
1) 照片与附件不再新开窗口看
   之前点缩略图直接 target=_blank 打开原始文件,看完还得切回来。
   现在统一走当前页灯箱(templates/_lightbox.php,详情页照片墙与
   照片管理页共用):左右箭头 / 键盘 ←→ / 手机滑动切上一张下一张,
   Esc 或点背景关闭,带「第几张 / 共几张」计数并预加载相邻两张。
   非图片附件(PDF 等)仍保留直接打开与下载。

2) 参与人可以直接改了
   之前加完只能移出重加。现在每个参与人旁有「编辑」,点开预填弹窗
   (角色标签 / 心情 / 签到时间),保存仍走 members/store ——
   Members::save() 本来就是 upsert(同节点同人一条),服务端零改动。
   失败回填按 user_id 精确匹配,只回填刚才没保存成的那个人。

3) 花销去掉预算,只记真实花费
   明细上移,底部一行「总计(N 笔)¥X」。表单不再有「预算」选项,
   查询一律 is_budget=0(历史预算行不再出现在列表与合计里);
   活动页统计同步改成「共 N 笔 · 总计」。列保留在库里不删数据。

已验证:本地全链 11 步全绿(php -l / 渲染 286 项 / SQL / PDO / CSS /
Mime / amap / 内联 JS×11 / 布局几何 / 表单交互 73 项);远端 e2e
296 项 0 失败(含灯箱、编辑弹窗、历史预算行排除的专项断言);
部署后双 PHP 渲染逐字节一致、60 文件哈希一致,线上 style.css 含新规则。
2026-09-23 14:59:02 +08:00

133 lines
5.8 KiB
PHP
Raw Permalink 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.
<?php
/**
* 节点花销面板
* 依赖外部变量:$node、$expenses、$expenseSummary、$familyUsers、
* $categories、$currencies(code=>中文名)、$expenseSymbols(code=>符号)、$currentUserId
*
* 用户明确反馈「预算没有意义」:只记真实花销,上面一笔一笔列出来,下面给个总计。
* (expenses.is_budget 列仍在库里,但 UI 与查询都不再使用 —— 见 Expenses 类注释。)
*/
$expenses = $expenses ?? [];
$familyUsers = $familyUsers ?? [];
$categories = $categories ?? [];
$currencies = $currencies ?? [];
$expenseSymbols = $expenseSymbols ?? [];
$expenseSummary = $expenseSummary ?? ['total' => 0.0, 'count' => 0];
$total = (float)$expenseSummary['total'];
$money = static function (float $v): string {
return number_format($v, 2);
};
?>
<section class="panel" id="expenses">
<h2 class="section-title">💰 花销 (<?= (int)$expenseSummary['count'] ?>)</h2>
<?php if (empty($expenses)): ?>
<p class="muted">还没有记账</p>
<?php else: ?>
<div class="expense-list">
<?php foreach ($expenses as $ex):
$sym = $expenseSymbols[$ex['currency']] ?? '';
$splits = [];
foreach (($ex['splits'] ?? []) as $sp) {
$sname = (string)($sp['user_name'] ?? '');
if ($sname === '') $sname = '已注销';
$splits[] = $sname . ' ' . $sym . $money((float)$sp['share_amount']);
}
?>
<div class="expense-row">
<div class="expense-main">
<span class="expense-cat"><?= e($ex['category']) ?></span>
<span class="expense-desc"><?= e($ex['description'] ?: $ex['category']) ?></span>
<span class="expense-amount"><?= e($sym) ?><?= $money((float)$ex['total_amount']) ?></span>
</div>
<div class="expense-sub">
付款:<?= e($ex['payer_name'] ?: '未知') ?>
<?php if (!empty($splits)): ?>
· 分摊:<?= e(implode(' / ', $splits)) ?>
<?php endif; ?>
<form method="post" action="<?= url('expenses/destroy') ?>" style="display:inline"
onsubmit="return confirm('删除这笔花销?');">
<input type="hidden" name="_csrf" value="<?= e(csrf_token()) ?>">
<input type="hidden" name="id" value="<?= (int)$ex['id'] ?>">
<button type="submit" class="comment-del">删除</button>
</form>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="expense-total">
<span>总计(<?= (int)$expenseSummary['count'] ?> 笔)</span>
<strong>¥<?= $money($total) ?></strong>
</div>
<?php endif; ?>
<details class="inline-panel">
<summary>+ 记一笔花销</summary>
<form method="post" action="<?= url('expenses/store') ?>" class="form form-plain">
<input type="hidden" name="_csrf" value="<?= e(csrf_token()) ?>">
<input type="hidden" name="node_id" value="<?= (int)$node['id'] ?>">
<div class="form-row two-col">
<div>
<label>金额 *</label>
<input type="text" name="total_amount" required placeholder="例如:268.50">
</div>
<div>
<label>币种</label>
<select name="currency">
<?php foreach ($currencies as $code => $label): ?>
<option value="<?= e($code) ?>"><?= e($label) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-row two-col">
<div>
<label>类别</label>
<select name="category">
<?php foreach ($categories as $cat): ?>
<option value="<?= e($cat) ?>"><?= e($cat) ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label>付款人 *</label>
<select name="payer_user_id" required>
<?php foreach ($familyUsers as $u): ?>
<option value="<?= (int)$u['id'] ?>"
<?= (int)$u['id'] === (int)$currentUserId ? ' selected' : '' ?>>
<?= e($u['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-row">
<label>说明</label>
<input type="text" name="description" maxlength="200" placeholder="例如:三人门票">
</div>
<div class="form-row">
<label>分摊人(默认全家平摊,可只勾选部分人)</label>
<div class="check-grid">
<?php foreach ($familyUsers as $u): ?>
<label class="checkbox-label">
<input type="checkbox" name="split_user_ids[]"
value="<?= (int)$u['id'] ?>" checked>
<span><?= e($u['name']) ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">保存</button>
</div>
</form>
</details>
</section>