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:
@@ -738,7 +738,8 @@ switch ($r) {
|
||||
// 解密与生日格式化统一走 PersonQuery(见该类的类注释:
|
||||
// 名册 / 挑人 / 高级搜索必须**同一套判据**,否则同一句搜索在不同页面结果不同)。
|
||||
$row['phone_plain'] = PersonQuery::phonePlain($row);
|
||||
[$row['birthday_show'], $row['birthday_kind']] = PersonQuery::birthdayOf($row);
|
||||
// 用户 2026-10-04 第 3 条:阴历和阳历**都**列出来,且只显示月和日
|
||||
$row['birthdays'] = PersonQuery::birthdaysOf($row);
|
||||
// 首字母供前端"输入即筛选"用(filter.js 对 data-initials 做子序列匹配)
|
||||
$row['initials'] = Pinyin::initials((string)$row['name'] . ' ' . (string)($row['my_nickname'] ?? ''));
|
||||
}
|
||||
@@ -751,6 +752,15 @@ switch ($r) {
|
||||
$grouped[(int)($row['group_id'] ?? 0)][] = $row;
|
||||
}
|
||||
|
||||
// v24 第 9 批 #5:千人名册的 HTML 有 3~4 MB。本机 php -S 与部分虚拟机
|
||||
// 都不会替 PHP 输出开 gzip,原样吐 3.8 MB 又慢又费流量;
|
||||
// 这里在渲染前挂 ob_gzhandler(自动按 Accept-Encoding 协商,
|
||||
// 不支持 gzip 的客户端拿到的还是原文)。压 3.8 MB 约 60~90ms,
|
||||
// 换来 10 倍体积差;media.php / dav 的二进制输出不走这条路。
|
||||
if (($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '') !== ''
|
||||
&& stripos((string)$_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
|
||||
ob_start('ob_gzhandler');
|
||||
}
|
||||
View::render('people/index', [
|
||||
'title' => '家庭名册',
|
||||
'people' => $rows,
|
||||
@@ -1339,6 +1349,12 @@ switch ($r) {
|
||||
'id_card' => trim((string)($_POST['id_card'] ?? '')),
|
||||
'email' => trim((string)($_POST['email'] ?? '')),
|
||||
'address' => trim((string)($_POST['address'] ?? '')),
|
||||
// 用户 2026-10-04 第 4 条:地址是**结构化五级**(国家/省/市/区/详细),
|
||||
// 不再是一整串。四个下拉提交的是标准名而不是代码(见 Person::addrOrNull)。
|
||||
'addr_country' => trim((string)($_POST['addr_country'] ?? '')),
|
||||
'addr_province' => trim((string)($_POST['addr_province'] ?? '')),
|
||||
'addr_city' => trim((string)($_POST['addr_city'] ?? '')),
|
||||
'addr_district' => trim((string)($_POST['addr_district'] ?? '')),
|
||||
'org' => trim((string)($_POST['org'] ?? '')),
|
||||
'title' => trim((string)($_POST['title'] ?? '')),
|
||||
'note' => trim((string)($_POST['note'] ?? '')),
|
||||
@@ -1500,6 +1516,12 @@ switch ($r) {
|
||||
'id_card' => $canEditAll ? trim((string)($_POST['id_card'] ?? '')) : Crypto::decrypt((string)$p['id_card_encrypted']),
|
||||
'email' => trim((string)($_POST['email'] ?? '')),
|
||||
'address' => trim((string)($_POST['address'] ?? '')),
|
||||
// 用户 2026-10-04 第 4 条:地址是**结构化五级**(国家/省/市/区/详细),
|
||||
// 不再是一整串。四个下拉提交的是标准名而不是代码(见 Person::addrOrNull)。
|
||||
'addr_country' => trim((string)($_POST['addr_country'] ?? '')),
|
||||
'addr_province' => trim((string)($_POST['addr_province'] ?? '')),
|
||||
'addr_city' => trim((string)($_POST['addr_city'] ?? '')),
|
||||
'addr_district' => trim((string)($_POST['addr_district'] ?? '')),
|
||||
'org' => trim((string)($_POST['org'] ?? '')),
|
||||
'title' => trim((string)($_POST['title'] ?? '')),
|
||||
'note' => trim((string)($_POST['note'] ?? '')),
|
||||
@@ -1682,6 +1704,23 @@ switch ($r) {
|
||||
redirect('people');
|
||||
break;
|
||||
|
||||
/**
|
||||
* 行政区划级联数据(用户 2026-10-04 第 4 条:地址要「省 / 市 / 区」三级联动)。
|
||||
*
|
||||
* 只吐一个 JSON 列表给前端填下拉 —— 3429 条一次性塞进页面会让表单页重一百多 KB,
|
||||
* 而用户一次只会用到其中两个下拉,按级取就够了。
|
||||
* ⚠️ 必须登录才能取(虽然不是什么秘密,但没必要给匿名访客开一个能枚举全国的接口)。
|
||||
*/
|
||||
case 'regions':
|
||||
Auth::requireLogin();
|
||||
$parent = (string)($_GET['parent'] ?? '');
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode(
|
||||
['ok' => true, 'items' => \App\Region::childrenOf($parent)],
|
||||
JSON_UNESCAPED_UNICODE
|
||||
);
|
||||
exit;
|
||||
|
||||
// ==================== 账号 ====================
|
||||
case 'accounts/create':
|
||||
Auth::requireAdmin();
|
||||
|
||||
Reference in New Issue
Block a user