v24 第 9 批:名册九条(分组按钮/加入名册/生日月日/地址四级/千人性能/拖动修复/删除人员/返回名册/Semi DatePicker)

- #131 名册卡片加「分组」按钮(details+radio,显示当前分组,选中即改)
- #132 修复「从已有人里加入名册」无反应
- #133 生日只显示月和日(阳历 MM-DD / 农历中文名),PersonQuery::birthdaysOf 取代 birthdayOf
- #134 地址结构化为 国家/省/市/区+详细:regions 表(3429 行全国区划)+ Region.php +
  ?r=regions 级联接口 + 表单 .addr-grid + 老地址回填(Schema v16)
- #135 千人名册性能:.person content-visibility:auto + 名册页 ob_gzhandler
  (实测 服务端 1.15s/3.8MB → 0.17s/87KB;客户端导航→load 1.35s → 0.37s)
- #136 拖动排序改 Pointer Events(Chrome 下 HTML5 DnD 在 DOM 变动时断)
- #137 个人详情页底部「删除人员」
- #138 编辑资料页加「返回名册」
- #139 所有日期选择换 Semi Design DatePicker(渐进增强:原生四字段保 POST 契约,
  懒加载 vendor semi UMD,值回写原字段;工作经历 type=month 一并升级;宣纸主题对齐)

验证:e2e 785/0、batch9 37/0、upgrade 126/0、picker 28/0、mobile 688/0、interact 97/0、
batch_e 91/0、import 21/0、douban 22/0、drag 5/0、semi-integrate 28/0、semi-probe 17/0、
geom 5/5;部署后线上自检 16/16(含 4 个 semi 资源 200 + regions 路由)。
This commit is contained in:
2026-10-04 08:56:40 +08:00
parent 864e281265
commit 52cc1ecccb
19 changed files with 1629 additions and 154 deletions
+35 -5
View File
@@ -165,9 +165,10 @@ final class Person
$sql = 'INSERT INTO persons
(family_id, kind, name, gender, birth_rank, birthday,
birthday_id_card, birthday_lunar, birthday_lunar_leap, slogan, avatar,
phone_hash, phone_encrypted, id_card_encrypted, email, address, org, title, note,
is_placeholder)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
phone_hash, phone_encrypted, id_card_encrypted, email, address,
addr_country, addr_province, addr_city, addr_district,
org, title, note, is_placeholder)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
$st = Database::get()->prepare($sql);
$st->execute([
$familyId,
@@ -186,6 +187,10 @@ final class Person
($d['id_card'] ?? '') !== '' ? Crypto::encrypt($d['id_card']) : null,
($d['email'] ?? '') !== '' ? $d['email'] : null,
($d['address'] ?? '') !== '' ? $d['address'] : null,
self::addrOrNull($d, 'addr_country'),
self::addrOrNull($d, 'addr_province'),
self::addrOrNull($d, 'addr_city'),
self::addrOrNull($d, 'addr_district'),
($d['org'] ?? '') !== '' ? mb_substr(trim((string)$d['org']), 0, 120, 'UTF-8') : null,
($d['title'] ?? '') !== '' ? mb_substr(trim((string)$d['title']), 0, 120, 'UTF-8') : null,
($d['note'] ?? '') !== '' ? $d['note'] : null,
@@ -202,7 +207,9 @@ final class Person
name = ?, gender = ?, birth_rank = ?, birthday = ?,
birthday_id_card = ?, birthday_lunar = ?, birthday_lunar_leap = ?, slogan = ?, avatar = ?,
phone_hash = ?, phone_encrypted = ?, id_card_encrypted = ?,
email = ?, address = ?, org = ?, title = ?, note = ?, is_placeholder = ?
email = ?, address = ?,
addr_country = ?, addr_province = ?, addr_city = ?, addr_district = ?,
org = ?, title = ?, note = ?, is_placeholder = ?
WHERE id = ?';
Database::get()->prepare($sql)->execute([
$d['name'],
@@ -219,6 +226,10 @@ final class Person
($d['id_card'] ?? '') !== '' ? Crypto::encrypt($d['id_card']) : null,
($d['email'] ?? '') !== '' ? $d['email'] : null,
($d['address'] ?? '') !== '' ? $d['address'] : null,
self::addrOrNull($d, 'addr_country'),
self::addrOrNull($d, 'addr_province'),
self::addrOrNull($d, 'addr_city'),
self::addrOrNull($d, 'addr_district'),
($d['org'] ?? '') !== '' ? mb_substr(trim((string)$d['org']), 0, 120, 'UTF-8') : null,
($d['title'] ?? '') !== '' ? mb_substr(trim((string)$d['title']), 0, 120, 'UTF-8') : null,
($d['note'] ?? '') !== '' ? $d['note'] : null,
@@ -227,6 +238,19 @@ final class Person
]);
}
/**
* 地址四段:空串一律存 NULL。
*
* 为什么不用 `$d[$k] ?? null` 直接塞:表单里四个下拉没选时提交的是**空串**,
* 存进去就变成"国家 = ''",页面上判断"有没有填"永远为真,
* 于是每个没填地址的人都显示一个空的国家名(看着像数据坏了)。
*/
private static function addrOrNull(array $d, string $key): ?string
{
$v = trim((string)($d[$key] ?? ''));
return $v === '' ? null : mb_substr($v, 0, 60, 'UTF-8');
}
/**
* 自助改自己的资料。
*
@@ -244,7 +268,9 @@ final class Person
'UPDATE persons SET
name = ?, gender = ?, birthday = ?,
birthday_id_card = ?, birthday_lunar = ?, birthday_lunar_leap = ?, slogan = ?, avatar = ?,
email = ?, address = ?, org = ?, title = ?, note = ?
email = ?, address = ?,
addr_country = ?, addr_province = ?, addr_city = ?, addr_district = ?,
org = ?, title = ?, note = ?
WHERE id = ?'
)->execute([
$d['name'],
@@ -257,6 +283,10 @@ final class Person
($d['avatar'] ?? '') !== '' ? $d['avatar'] : null,
($d['email'] ?? '') !== '' ? $d['email'] : null,
($d['address'] ?? '') !== '' ? $d['address'] : null,
self::addrOrNull($d, 'addr_country'),
self::addrOrNull($d, 'addr_province'),
self::addrOrNull($d, 'addr_city'),
self::addrOrNull($d, 'addr_district'),
($d['org'] ?? '') !== '' ? mb_substr(trim((string)$d['org']), 0, 120, 'UTF-8') : null,
($d['title'] ?? '') !== '' ? mb_substr(trim((string)$d['title']), 0, 120, 'UTF-8') : null,
($d['note'] ?? '') !== '' ? $d['note'] : null,