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 含新规则。
62 lines
2.7 KiB
PHP
62 lines
2.7 KiB
PHP
<div class="page-header">
|
|
<div>
|
|
<h1><?= e($activity['title']) ?></h1>
|
|
<p class="muted"><?= e($activity['description'] ?: '暂无简介') ?></p>
|
|
</div>
|
|
<div class="actions" style="display:flex; gap:8px; flex-wrap:wrap;">
|
|
<a href="<?= url('nodes/create', ['activity_id' => $activity['id'], 'category' => 'plan']) ?>" class="btn">+ 计划节点</a>
|
|
<a href="<?= url('nodes/create', ['activity_id' => $activity['id'], 'category' => 'reality']) ?>" class="btn-primary">+ 执行节点</a>
|
|
<a href="<?= url('activities/edit', ['id' => $activity['id']]) ?>" class="btn">编辑活动</a>
|
|
<form method="post" action="<?= url('activities/destroy') ?>" style="display:inline;"
|
|
onsubmit="return confirm('确定删除活动「<?= e($activity['title']) ?>」?\n该活动下的所有节点、附件、评论都会一并删除,且不可恢复。');">
|
|
<input type="hidden" name="_csrf" value="<?= e(csrf_token()) ?>">
|
|
<input type="hidden" name="id" value="<?= (int)$activity['id'] ?>">
|
|
<button type="submit" class="btn btn-danger">删除活动</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($activity['cover_image'])): ?>
|
|
<div class="activity-cover">
|
|
<img src="<?= e(media_cover((int)$activity['id'])) ?>" alt="">
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php $expenseSummary = $expenseSummary ?? ['total' => 0.0, 'count' => 0]; ?>
|
|
<?php if ((int)$expenseSummary['count'] > 0): ?>
|
|
<div class="activity-stats">
|
|
<span class="activity-stat">💰 共 <?= (int)$expenseSummary['count'] ?> 笔</span>
|
|
<span class="activity-stat">总计 ¥<?= number_format((float)$expenseSummary['total'], 2) ?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="timeline-grid">
|
|
<section class="timeline-col">
|
|
<h2>📋 计划 (<?= count($planNodes) ?>)</h2>
|
|
<?php if (empty($planNodes)): ?>
|
|
<p class="muted">暂无计划节点</p>
|
|
<?php else: ?>
|
|
<?php foreach ($planNodes as $n): ?>
|
|
<?php $cardCategory = 'plan'; require __DIR__ . '/_node_card.php'; ?>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<section class="timeline-col">
|
|
<h2>🎬 实际 (<?= count($realityNodes) ?>)</h2>
|
|
<?php if (empty($realityNodes)): ?>
|
|
<p class="muted">暂无执行节点</p>
|
|
<?php else: ?>
|
|
<?php foreach ($realityNodes as $n): ?>
|
|
<?php $cardCategory = 'reality'; require __DIR__ . '/_node_card.php'; ?>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</section>
|
|
</div>
|
|
|
|
<?php
|
|
$commentTargetType = \App\Comments::TARGET_ACTIVITY;
|
|
$commentTargetId = (int)$activity['id'];
|
|
require dirname(__DIR__) . '/comments/_block.php';
|
|
?>
|