家谱卡片重做 / 首页控制台 / 名册改列表 / 重复日程与旅程公开
用户 2026-10-03 提的四条:
① 家谱卡片重做
· 去掉「⇄ 姻亲」按钮,改成**每个人**卡片右下角都有「以 TA 为中心」
(点了以他重画一张家谱,涵盖原来的姻亲场景)。
· 头像外框改**长方形**(96×72,宽度贴合头像),object-fit: contain 不裁切,
姓名/称呼在头像下方。
· 修「点右下角按钮误进成员页」:卡片不再整张是 <a>,
只有姓名是链接,右下角是独立的 <button>(物理上分开,不抢点击)。
② 家谱文案与按钮清理
· 去掉副标题与下方图例说明;整块去掉「看全部 / 回到我 / 回到我的家谱」
(顺带消掉"出现两个回到我的家谱")。镜头由库自动 fit,拖拽/滚轮即可。
③ 首页控制台
· 标题下显示个人 slogan;去掉右侧三个统计;「我的资料/我的家谱」换成图标按钮;
去掉与导航条重复的「名册」按钮。
· 去掉「接下来的日子」(生日归到"未来七天"里,不再重复)。
· 新增统计信息块:按时段随机问候 + 今日天气(Open-Meteo,免 key,可留空不显示)
+ 近七天日程/待办/逾期数。
· 新增各模块小结卡(任务/日程/纪念日/观影/旅程/财务/名册/家谱/资源)。
· 个人设置新增「首页上的模块」:可勾选与拖动排序(每人一份,存 user_settings)。
· 保留「往年的今天」。
④ 名册改列表
· 卡片网格 → **竖向列表**:左头像、中间姓名+与我的关系+手机号+生日。
· 修拖动「只能往后不能往前」:落点改为显式记录"插到谁前面/后面",
并排除被拖元素自身。
· 去掉那句拖动提示(能力保留)。
· 搜索新增**姓名首字母**检索(y / yy / yyq 都命中「杨永全」):
新 app/Pinyin.php,intl 优先 + 内置常用字表兜底(本地无 intl 也能测);
纯字母/数字查询词不走 SQL LIKE(拼音与加密手机号在库里都比不了)。
附带上两轮的收尾:
· 菜单点外部自动关闭(全局事件委托,覆盖所有 details.menu)。
· 旅程 is_public:列表与日历只显示公开的;详情页不拦(不丢数据)。
· 重复日程:新 app/Repeat.php(RRULE 解析/生成/展开,含"工作日"),
新表 calendar_event_skips(RFC 的 EXDATE);日历按规则展开;
编辑支持三档「全部 / 这一次及以后 / 仅此一次」。
· 结束时间可添加/去掉,并随开始时间联动。
验证:端到端 772 项通过 / 0 失败;几何 368、交互 97、移动端 516、家谱 26、
升级 123 全绿;SQL 列名静态校验 0 处可疑;部署 11 条线上探针全过。
This commit is contained in:
+40
-61
@@ -147,19 +147,11 @@ $datumJson = json_encode(
|
||||
);
|
||||
?>
|
||||
|
||||
<?php /* 用户 2026-10-03 第 2 条:标题下的那句说明**去掉**;
|
||||
右下角的「返回我的家谱」也去掉 —— 与页面里那个工具条重复,
|
||||
会出现两个"回到我的家谱"(用户明确点名)。现在整页只有标题。 */ ?>
|
||||
<div class="page-head">
|
||||
<h1><?= $focusId === (int)$meId ? '我的家谱' : e((string)($people[$focusId]['name'] ?? '') . ' 的家谱') ?></h1>
|
||||
<span class="sub">
|
||||
<?= $focusId === (int)$meId
|
||||
? '以我为中心 · 夫妻并排,子女从两人之间的连线连出'
|
||||
: '以 TA 为中心(这样 TA 那一侧的姻亲才露得出来)' ?>
|
||||
</span>
|
||||
<div class="actions">
|
||||
<?php if ($focusId !== (int)$meId): ?>
|
||||
<?php /* v24 第 12 条:从姻亲入口进来的,给一个返回,回到「我的家谱」 */ ?>
|
||||
<a class="btn btn-ghost" href="<?= e(url('kin')) ?>">← 返回我的家谱</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!$canChart): ?>
|
||||
@@ -170,11 +162,12 @@ $datumJson = json_encode(
|
||||
</div>
|
||||
<?php else: ?>
|
||||
|
||||
<div class="kin-tools">
|
||||
<button type="button" class="btn btn-ghost btn-sm" id="kinFit">看全部</button>
|
||||
<?php /* 中心是别人时这颗按钮是"跳回我的家谱"(不是在本图里找我的坐标) */ ?>
|
||||
<button type="button" class="btn btn-ghost btn-sm" id="kinMe"><?= $focusId === (int)$meId ? '回到我' : '回到我的家谱' ?></button>
|
||||
</div>
|
||||
<?php /* 用户 2026-10-03 第 2 条:「看全部 / 回到我 / 回到我的家谱」这些按钮
|
||||
全部去掉。镜头由库自动 fit(updateTree 的 tree_position: 'fit'),
|
||||
用户要调整时直接拖拽/滚轮即可,不需要常驻按钮。 */
|
||||
/* ⚠️ 顺带说明:品牌名「家谱」已从导航条撤走,但**模块本身还在** ——
|
||||
个人设置里能勾回来,且 URL 直接访问 r=kin 永远有效。
|
||||
这一点写在这里是为了防止有人"顺手把 kin 路由删掉"。 */ ?>
|
||||
|
||||
<!-- ⚠️ `f3` 这个类名是**库的 CSS 作用域**,不是我们起的名字。
|
||||
官方示例就是 `<div id="FamilyChart" class="f3">` + 引 family-chart.css;
|
||||
@@ -184,14 +177,7 @@ $datumJson = json_encode(
|
||||
<div class="kin-chart f3" id="kinChart" data-datum="<?= e($datumJson) ?>"
|
||||
data-focus="<?= e((string)$focusId) ?>" data-me-viewer="<?= e((string)$meId) ?>"></div>
|
||||
|
||||
<p class="tree-legend">
|
||||
每代一行;<b>一对夫妻之间有一条短横线</b>,
|
||||
<b>他们的子女一律从这条横线的正中间垂下来</b>(不管是谁登录,孩子都挂在这对夫妻上)。
|
||||
「待确认」= 只填了称呼、还没对应到真实的人(虚线卡片)。
|
||||
可以**拖拽平移**、**滚轮缩放**;点「回到我」把镜头挪回你自己,点卡片进对应成员页。
|
||||
<br><span class="muted">注:本图由 family-chart 绘制。免费版只画「同一位祖先的血脉后代 + 各人配偶」,
|
||||
妻子那侧的岳父母、舅子等姻亲不在图内(在名册与成员详情页仍可看到)。</span>
|
||||
</p>
|
||||
|
||||
|
||||
<!-- 官方用法是「容器带 class="f3" + 引 family-chart.css」(见 family-chart 官方示例)。
|
||||
之前没引这份 CSS,靠自己在 app.css 里手补 `.kin-chart svg.main_svg{width/height:100%}`
|
||||
@@ -227,30 +213,35 @@ $datumJson = json_encode(
|
||||
// 会跳过深度截断,等于**不限代数**,有多少画多少。
|
||||
// 之前写死了具体代数,真实家庭一超过就被砍掉。
|
||||
// 用户要求「全部取出来」,所以这里也不设。
|
||||
.setCardXSpacing(190)
|
||||
.setCardXSpacing(160)
|
||||
.setCardYSpacing(180);
|
||||
|
||||
chart.setCardHtml()
|
||||
.setStyle('rect')
|
||||
.setCardDim({ w: 148, h: 138, mini_tree: false })
|
||||
.setCardDim({ w: 118, h: 132, mini_tree: false })
|
||||
.setCardInnerHtmlCreator(function (d) {
|
||||
var p = (d.data && d.data.data) || {};
|
||||
var id = (d.data && d.data.id) || '';
|
||||
var cls = 'kin-card' + (p.me ? ' is-me' : '') + (p.ph ? ' is-ph' : '');
|
||||
// v24 第 12 条:头像改**方形**(原来是圆角矩形 + cover,把脸裁掉了)。
|
||||
// 卡片本身是 <a> 进成员页;有姻亲没画出来的,再叠一个独立的小按钮
|
||||
// (用 <span role=button> 而不是 <a>:<a> 不能套 <a>)。
|
||||
return '<a class="' + cls + '" data-kin-id="' + esc(id) + '" href="/index.php?r=people/show&id='
|
||||
+ encodeURIComponent(id) + '">'
|
||||
/* 用户 2026-10-03 第 1 条:
|
||||
① 卡片**不再整张是链接** —— 原来整卡是 <a>,右下角那个小按钮也在
|
||||
<a> 里,手指/鼠标稍偏一点就先触发外层链接跳去成员页(用户反馈
|
||||
"容易误触"的根因)。现在卡片是 <div>,只有「姓名」那一块是链接,
|
||||
右下角按钮是独立的 <button>,两者物理上分开,不会互相抢点击。
|
||||
② 头像外框改**长方形**、宽度贴合头像本身(CSS 里 .kin-ph 定宽,
|
||||
img 用 object-fit: contain 不裁切),信息在头像**下方**。
|
||||
③ 右下角按钮:每个人都有一个 → 以他为中心重画一张家谱
|
||||
(原来只有"姻亲不在图上"的人才有,现在人人都有)。 */
|
||||
return '<div class="' + cls + '" data-kin-id="' + esc(id) + '">'
|
||||
+ '<span class="kin-ph"><img src="' + esc(p.avatar) + '" alt=""></span>'
|
||||
+ '<span class="kin-nm">' + esc(p.name) + '</span>'
|
||||
+ '<a class="kin-nm" href="/index.php?r=people/show&id='
|
||||
+ encodeURIComponent(id) + '" title="打开 ' + esc(p.name) + ' 的资料">'
|
||||
+ esc(p.name) + '</a>'
|
||||
+ '<span class="kin-lb">' + esc(p.label) + '</span>'
|
||||
+ (p.ph ? '<span class="kin-mark">待确认</span>' : '')
|
||||
+ (p.branch
|
||||
? '<span class="kin-branch" role="button" tabindex="0" title="看看 '
|
||||
+ esc(p.branch) + ' 那一侧的家谱" data-branch-id="' + esc(id) + '">⇄ 姻亲</span>'
|
||||
: '')
|
||||
+ '</a>';
|
||||
+ '<button type="button" class="kin-focus" data-focus-id="' + esc(id) + '"'
|
||||
+ ' title="以 ' + esc(p.name) + ' 为中心看家谱">以 TA 为中心</button>'
|
||||
+ '</div>';
|
||||
});
|
||||
|
||||
chart.editTree().setCanAdd(false);
|
||||
@@ -304,41 +295,29 @@ $datumJson = json_encode(
|
||||
setTimeout(function () { centerOn(focusId); }, 1400);
|
||||
}
|
||||
|
||||
var btnFit = document.getElementById('kinFit');
|
||||
var btnMe = document.getElementById('kinMe');
|
||||
if (btnFit) {
|
||||
btnFit.addEventListener('click', function () {
|
||||
chart.updateTree({ tree_position: 'fit' });
|
||||
});
|
||||
}
|
||||
/* v24 第 12 条:卡片右下角的「⇄ 姻亲」按钮 —— 以那个人为中心重画一张家谱。
|
||||
⚠️ 这个 span 在卡片的 <a> 里,必须 preventDefault + stopPropagation,
|
||||
否则会先触发外面那个链接跳去成员页。 */
|
||||
Array.prototype.forEach.call(root.querySelectorAll('.kin-branch'), function (btn) {
|
||||
/* 用户 2026-10-03 第 2 条:工具条三个按钮(看全部/回到我/回到我的家谱)已撤。
|
||||
镜头由库自动 fit;下面只保留卡片右下角那个「以他为中心」的入口。 */
|
||||
|
||||
/* 用户第 1 条:每张卡片右下角一个「以他为中心」的按钮 —— 点了就以他重画一张家谱。
|
||||
⚠️ 这个元素在卡片的 <a> 里,必须 preventDefault + stopPropagation,
|
||||
否则会先触发外面那个链接跳去成员页(用户反馈"容易误触"就是这个)。
|
||||
另外用 mousedown/pointerdown/click 三处都拦,触摸设备上才稳。 */
|
||||
Array.prototype.forEach.call(root.querySelectorAll('.kin-focus'), function (btn) {
|
||||
function go(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var bid = btn.getAttribute('data-branch-id') || '';
|
||||
var bid = btn.getAttribute('data-focus-id') || '';
|
||||
if (bid) { window.location.href = '/index.php?r=kin&focus=' + encodeURIComponent(bid); }
|
||||
}
|
||||
btn.addEventListener('click', go);
|
||||
btn.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter' || e.key === ' ') { go(e); }
|
||||
});
|
||||
// 键盘/触摸都别让它冒泡到外层链接
|
||||
btn.addEventListener('mousedown', function (e) { e.stopPropagation(); });
|
||||
['mousedown', 'pointerdown', 'touchstart'].forEach(function (ev) {
|
||||
btn.addEventListener(ev, function (e) { e.stopPropagation(); }, { passive: true });
|
||||
});
|
||||
});
|
||||
|
||||
if (btnMe && meId) {
|
||||
btnMe.addEventListener('click', function () {
|
||||
// 图是别人的家谱时,先跳回「我的家谱」再居中
|
||||
if (focusId !== meId) {
|
||||
window.location.href = '/index.php?r=kin';
|
||||
return;
|
||||
}
|
||||
centerOn(centerTarget);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user