v44 第 44 批:界面 5 条 + 移动端 API v1 全量
界面(用户 2026-10-12 第 1~5 条) 1. 新建日程「日历本」并入 .cs 自绘下拉,颜色画进候选项,三字与下拉同行。 2. 新建日程「开始/结束」改「日期范围:」,删旧日期控件; 重复相关三行仅选重复时出现;删「(含第一次)」与「这段时间算忙碌」。 3. 条目浮层加「地点」、去掉「状态」行;首页红线按分钟定位(原只取整小时); 去掉左侧红点只留红线。 4. 任务页删掉状态说明提示(STATUS_HINT 三值清空)。 5. 新建任务:标题在前树框在后;截止时间改最新日历控件;负责人默认自己; 删冗余提示;「上面要做什么」→「任务名称」;清理括号说明。 移动端 API(用户第 6 条:导航模块除外,其余全量) - 新增 Bearer 令牌鉴权(api_tokens 表,Schema v32),与登录口令 / DAV 口令三套分立。 - Api.php 内核(鉴权/取参/信封/分页/分发 + _method 覆写)+ ApiHandler.php 17 条资源 + ApiToken.php + api.php 入口。 - 路由:router.php / .htaccess / index.php 三处 /api/ 兜底(部署脚本自动追加线上规则)。 - 个人设置新增「App 接口令牌」卡;docs/API.md 接口文档; docs/API-QUESTION-LIST.md 自主决策与待确认缺口清单。 验证:本地 e2e 1510/0、v43 真机 33/0、v43 反向 9/0、 v44 真机 41/0、v44 API 63/0、v44 反向 19/0;全流水线 PUSH_RC=0。
This commit is contained in:
@@ -32,9 +32,15 @@ $evMv = !empty($evMvStyle);
|
||||
抄两遍必然有一天两边不同步(v37 那种"改了 A 忘了 B"的坑)。
|
||||
⚠️ 「必填星号」作为**参数**传(不要用 `use` 捕获 —— 闭包定义时那个变量还没赋值,
|
||||
捕获到的是 null,星号永远不出现)。 */
|
||||
$evRowOpen = static function (string $full = '') use ($evMv): string {
|
||||
return '<div class="' . ($evMv ? 'mv-row' : 'field') . ($full !== '' ? ' ' . $full : '') . '">';
|
||||
$evRowOpen = static function (string $full = '', bool $hidden = false) use ($evMv): string {
|
||||
return '<div class="' . ($evMv ? 'mv-row' : 'field') . ($full !== '' ? ' ' . $full : '') . '"'
|
||||
. ($hidden ? ' hidden' : '') . '>';
|
||||
};
|
||||
/* 重复规则**先算好**:下面"结束条件 / 重复次数 / 重复到"三行要不要默认藏起来,
|
||||
取决于它(见 v44 第 2 条)。原来 `$rp` 是在「重复」那一行才 parse 的,
|
||||
那三行排在它后面 ⇒ 拿不到。提到最前面,只算一次。 */
|
||||
$evRp = \App\Repeat::parse((string)($evF['rrule'] ?? ''));
|
||||
$evRepeating = (string)($evRp['freq'] ?? '') !== '';
|
||||
$evLab = static function (string $text, string $for = '', bool $star = false) use ($evMv): string {
|
||||
if ($evMv) {
|
||||
// 观影式:标签是 <span class="mv-lb">,冒号由 CSS ::after 给
|
||||
@@ -107,28 +113,50 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
⇒ `$dtPlugin='antd'`(与观影/行程同一套:面板有可点的时/分列、中文「确定」),
|
||||
标签改「开始 / 结束」(并去掉那颗必填星号的位置歧义 —— 只标在开始上)。
|
||||
⚠️ 契约一字未改:隐藏字段仍是 `*_date/_hour/_minute`;antd 拉不动时
|
||||
自动退回自建下拉(渐进增强)。 */ ?>
|
||||
<div class="dt-range<?= $evMv ? ' mv-row' : '' ?>">
|
||||
<?php /* ⚠️ 标签只有**一个**,挂在范围容器上(不是各挂各的):
|
||||
自动退回自建下拉(渐进增强)。
|
||||
|
||||
🔴🔴 v44(用户 2026-10-12 第 2 条):「开始/结束,改为:日期范围:。
|
||||
之前的日期选择控件还有,需要删除。」
|
||||
—— 用户要三种东西:① 标签「日期范围」;② 标签与**最新控件同行**;
|
||||
③ 原生那套(年/月/日 + 时/分 五个下拉)**真的消失**。
|
||||
|
||||
🔴🔴 **"还在"的真根因(结构性,不是样式没写)**:
|
||||
观影那对是 `‹div.mv-row.dt-range› ‹div.dt-input›`(**直接子**),
|
||||
而日程这对是 `‹div.dt-range› ‹div.field.ev-dt› ‹div.dt-input›`
|
||||
—— `.dt-input` 是**孙子**。
|
||||
于是那条最常见的收起规则 `.dt-range.is-antd > .dt-input`(**直接子**选择器)
|
||||
**在日程上根本不命中** ⇒ antd 挂上了、原生五个下拉照样显示
|
||||
(用户看到两个控件并排,"之前的日期选择控件还有")。
|
||||
⚠️ 与 v43 纪念日那次是**同一个家族**:结构一变,直接子选择器就静默失效。
|
||||
⇒ 两手都做:① 把日程的结构改成与观影**一致**(`.dt-input` 直接子);
|
||||
② CSS 里把 `>` 放宽成后代选择器(0,2,0 → 仍高于基类),
|
||||
将来结构再变也不会又冒出第二个控件。
|
||||
|
||||
⇒ 形态:由 `_datetime.php` 的 `$dtLabel` 把「日期范围:」
|
||||
**内联在控件那一行**(不靠宿主的行结构),一个 `.mv-lb` 挂在
|
||||
`.dt-input` 里 → 三样天然同行,宽度不够时整体换行。 */ ?>
|
||||
|
||||
<div class="dt-range<?= $evMv ? ' mv-row is-tagged' : '' ?>">
|
||||
<?php /* ⚠️ 标签只有**一个**,挂在**第一个端点**上(不是各挂各的):
|
||||
升级成一个范围控件之后,"开始"与"结束"就是同一个控件的两个端点,
|
||||
两个标签会变成"看着像两个字段、其实是一个"的错觉。 */ ?>
|
||||
<?php if ($evMv): ?>
|
||||
<span class="mv-lb dt-range-label">开始 / 结束<i>*</i></span>
|
||||
<?php else: ?>
|
||||
<span class="dt-range-label">开始 / 结束 *</span>
|
||||
两个标签会变成"看着像两个字段、其实是一个"的错觉。
|
||||
⚠️ 观影式:标签由 `_datetime.php` 内联(`$dtLabel`)—— 要的是与控件同行;
|
||||
两列式(编辑整页):标签仍是 `.dt-range-label`,在两端之上。 */ ?>
|
||||
<?php if (!$evMv): ?>
|
||||
<span class="dt-range-label">日期范围 *</span>
|
||||
<?php endif; ?>
|
||||
<div class="field ev-dt" data-dt>
|
||||
<?php $dtName = 'starts_at'; $dtId = 'ev-start';
|
||||
$dtValue = $evF['starts_at'] ?? null; $dtRequired = true;
|
||||
$dtRange = 'start'; $dtPlugin = 'antd';
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
</div>
|
||||
<div class="field ev-dt" data-dt id="ev-end-field">
|
||||
<?php $dtName = 'ends_at'; $dtId = 'ev-end';
|
||||
$dtValue = $evF['ends_at'] ?? null; $dtRequired = false;
|
||||
$dtRange = 'end'; $dtPlugin = 'antd';
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
</div>
|
||||
<?php $dtName = 'starts_at'; $dtId = 'ev-start';
|
||||
$dtValue = $evF['starts_at'] ?? null; $dtRequired = true;
|
||||
$dtRange = 'start'; $dtPlugin = 'antd'; $dtClass = 'field ev-dt'; $dtFieldId = '';
|
||||
if ($evMv) { $dtLabel = '日期范围'; $dtLabelStar = true; }
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
<?php $dtName = 'ends_at'; $dtId = 'ev-end';
|
||||
$dtValue = $evF['ends_at'] ?? null; $dtRequired = false;
|
||||
$dtRange = 'end'; $dtPlugin = 'antd';
|
||||
$dtClass = 'field ev-dt'; $dtFieldId = 'ev-end-field';
|
||||
/* 结束端点不重复标签(同一个范围控件,标签已经挂在开始那一端上) */
|
||||
$dtLabel = ''; $dtLabelStar = false;
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
</div><?php /* /dt-range */ ?>
|
||||
<?php /* 🔴 v43(用户第 5 条):他要求把「结束留空即无明确结束」的那条提示去掉
|
||||
⇒ 那句 `.field-hint` 整块删除(不再输出)。 */ ?>
|
||||
@@ -149,16 +177,23 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('重复', 'ev-freq') ?>
|
||||
<select class="select" id="ev-freq" name="freq">
|
||||
<?php $rp = \App\Repeat::parse((string)($evF['rrule'] ?? '')); ?>
|
||||
<?php foreach (\App\Repeat::FREQS as $k => $w): ?>
|
||||
<option value="<?= e($k) ?>"<?= (string)$rp['freq'] === (string)$k ? ' selected' : '' ?>><?= e($w) ?></option>
|
||||
<option value="<?= e($k) ?>"<?= (string)$evRp['freq'] === (string)$k ? ' selected' : '' ?>><?= e($w) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?php /* 🔴 v44(用户 2026-10-12 第 2 条):「重复这里,只有选择重复的时候,
|
||||
下面的结束条件和重复次数、重复到,这几个选项才出现,否则就隐藏。」
|
||||
⇒ 三行**服务端**就按"是否重复"给出 `hidden`(不是只靠 JS):
|
||||
· 回填编辑(本来就有 rrule)时它们该出现;
|
||||
· 新建(默认"不重复")时它们从一开始就是隐藏的 —— 页面上不会闪一下才收起来。
|
||||
⚠️ 行**本身**也藏:原来只有行**里面**那个 box 带 hidden,
|
||||
于是标签还孤零零留在表单里(用户看到的"还在")。
|
||||
⚠️ 用户同条还要「重复次数(含第一次)」那个括号去掉 ⇒ 标签改「重复次数」。 */ ?>
|
||||
<?php echo $evRowOpen('', !$evRepeating); ?>
|
||||
<?= $evLab('结束条件', 'ev-rep-end') ?>
|
||||
<div id="ev-rep-end-box" hidden>
|
||||
<div id="ev-rep-end-box"<?= $evRepeating ? '' : ' hidden' ?>>
|
||||
<select class="select" id="ev-rep-end" name="rep_end">
|
||||
<?php foreach (\App\Repeat::ENDS as $k => $w): ?>
|
||||
<option value="<?= e($k) ?>"><?= e($w) ?></option>
|
||||
@@ -167,19 +202,19 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('重复次数(含第一次)', 'ev-rep-count') ?>
|
||||
<div id="ev-rep-count-box" hidden>
|
||||
<?php echo $evRowOpen('', !$evRepeating || (int)$evRp['count'] <= 0); ?>
|
||||
<?= $evLab('重复次数', 'ev-rep-count') ?>
|
||||
<div id="ev-rep-count-box"<?= ($evRepeating && (int)$evRp['count'] > 0) ? '' : ' hidden' ?>>
|
||||
<input class="input" type="number" min="1" max="2000" id="ev-rep-count" name="rep_count"
|
||||
value="<?= (int)($rp['count'] ?: 10) ?>">
|
||||
value="<?= (int)($evRp['count'] ?: 10) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?php echo $evRowOpen('', !$evRepeating || (string)$evRp['until'] === ''); ?>
|
||||
<?= $evLab('重复到', 'ev-rep-until') ?>
|
||||
<div id="ev-rep-until-box" hidden>
|
||||
<div id="ev-rep-until-box"<?= ($evRepeating && (string)$evRp['until'] !== '') ? '' : ' hidden' ?>>
|
||||
<input class="input" type="date" id="ev-rep-until" name="rep_until"
|
||||
value="<?= e((string)($rp['until'] ?? '')) ?>">
|
||||
value="<?= e((string)($evRp['until'] ?? '')) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -193,14 +228,12 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('这段时间算', 'ev-transp') ?>
|
||||
<select class="select" id="ev-transp" name="transp">
|
||||
<?php $tp = (int)($evF['transp'] ?? 0); ?>
|
||||
<option value="0"<?= $tp === 0 ? ' selected' : '' ?>>忙碌</option>
|
||||
<option value="1"<?= $tp === 1 ? ' selected' : '' ?>>空闲(别人还能约)</option>
|
||||
</select>
|
||||
</div>
|
||||
<?php /* 🔴 v44(用户 2026-10-12 第 2 条):「这段时间算忙碌,这一块直接给它去掉就行了,
|
||||
没有什么用。」⇒ 「这段时间算 / 忙碌 / 空闲」整块删除。
|
||||
⚠️ 服务端契约**没变**:`transp` 字段没随表单提交时,`!empty($_POST['transp'])`
|
||||
一律得 false(= 忙碌),与原来的默认值一致 —— 不会因为删了这一块
|
||||
而把已有日程的忙闲改掉(更新时传的是 `(int)($ev2['transp'] ?? 0)` 原值)。
|
||||
下方 script 里原来还有一段给 `ev-transp` 的联动,也一并删。 */ ?>
|
||||
|
||||
<?php echo $evRowOpen('full'); ?>
|
||||
<?= $evLab('备注', 'ev-note') ?>
|
||||
@@ -238,26 +271,37 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
(见 app.js 的 onRange → writeDT),服务端契约不变。 */
|
||||
|
||||
/* 重复:选了周期才显示"结束条件";结束条件选"次数"才显示次数框、选"到某天"才显示日期框。
|
||||
三个框默认都 hidden —— 不重复时一个都不该出现(少即是清楚)。 */
|
||||
三行默认都 hidden —— 不重复时一个都不该出现(少即是清楚)。
|
||||
🔴 v44(用户第 2 条):藏的是**整行**(`.mv-row` / `.field`),不是行里那个 box ——
|
||||
只藏 box 的话标签还孤零零留在表单里。行 = box 的 `closest('.mv-row, .field')`。 */
|
||||
var freq = document.getElementById('ev-freq');
|
||||
var endBox = document.getElementById('ev-rep-end-box');
|
||||
var endSel = document.getElementById('ev-rep-end');
|
||||
var cntBox = document.getElementById('ev-rep-count-box');
|
||||
var untilBox = document.getElementById('ev-rep-until-box');
|
||||
function rowOf(el) {
|
||||
return el && el.closest ? el.closest('.mv-row, .field') : null;
|
||||
}
|
||||
function toggle(el, on) {
|
||||
if (!el) { return; }
|
||||
el.hidden = !on;
|
||||
var row = rowOf(el);
|
||||
if (row) { row.hidden = !on; } // 连带整行一起显隐
|
||||
}
|
||||
function syncRep() {
|
||||
if (!freq || !endBox) return;
|
||||
if (!freq || !endBox) { return; }
|
||||
var repeating = freq.value !== '';
|
||||
endBox.hidden = !repeating;
|
||||
toggle(endBox, repeating);
|
||||
var how = endSel ? endSel.value : 'never';
|
||||
if (cntBox) { cntBox.hidden = !repeating || how !== 'count'; }
|
||||
if (untilBox) { untilBox.hidden = !repeating || how !== 'until'; }
|
||||
toggle(cntBox, repeating && how === 'count');
|
||||
toggle(untilBox, repeating && how === 'until');
|
||||
}
|
||||
if (freq) { freq.addEventListener('change', syncRep); }
|
||||
if (endSel) { endSel.addEventListener('change', syncRep); }
|
||||
// 回填:编辑一条已有的重复日程时,把结束条件按库里的值选对
|
||||
<?php if ($rp['count'] > 0): ?>
|
||||
<?php if ((int)$evRp['count'] > 0): ?>
|
||||
if (endSel) { endSel.value = 'count'; }
|
||||
<?php elseif ($rp['until'] !== ''): ?>
|
||||
<?php elseif ((string)$evRp['until'] !== ''): ?>
|
||||
if (endSel) { endSel.value = 'until'; }
|
||||
<?php endif; ?>
|
||||
syncRep();
|
||||
@@ -277,4 +321,4 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
})();
|
||||
</script>
|
||||
<?php unset($evF, $evAllDayDefault, $evIsAllDay, $evFields, $evAllDay, $evMv, $evMvStyle,
|
||||
$evRowOpen, $evLab, $evLabelStar); ?>
|
||||
$evRowOpen, $evLab, $evLabelStar, $evRp, $evRepeating); ?>
|
||||
|
||||
Reference in New Issue
Block a user