feat(checkin): open reference-parity details modal from signed buttons

- Rebuild checkin details modal HTML 1:1 with reference theme:
  colorful header c-blue, user card (points/level), daily reward
  card and 7-day continuous mini cards
- Signed entry buttons (header dropdown, user-card badge, user
  center) become clickable checkin-details-link modal triggers
  instead of disabled buttons
- Swap data-signin-btn to details link in place after successful
  signin (reference .initiate-checkin replacement behavior)
- Add aksrt-checkin-details-modal runtime shell (modal-mini 400px)
- Remove dead code: legacy lite modal, admin-ajax details handler,
  /signin/history route, signin calendar; rebuild public bundles
- Update contract tests to the new checkin modal contract
This commit is contained in:
2026-09-19 14:49:58 +08:00
parent c289016324
commit 4653128a18
15 changed files with 211 additions and 266 deletions
+19 -39
View File
@@ -3046,10 +3046,8 @@ main.container,
}
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
* 仅禁用指针交互;此前的灰底灰字覆盖是与参考主题的偏差。 */
.aksrt-header-checkin.is-done,
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
.aksrt-header-checkin:disabled,
.aksrt-header-checkin.is-done:hover,
.aksrt-header-checkin:disabled:hover {
cursor: default;
opacity: .85;
@@ -6269,42 +6267,7 @@ body.aksrt-body-scroll .aksrt-show-on-scroll {
}
/* ============================================================
* 18. 签到日历可视化
* ============================================================ */
.aksrt-signin-calendar__grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 4px;
}
.aksrt-signin-calendar__day {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
background: var(--surface-2, #F4F5F7);
font-size: 12px;
color: var(--color-ink-3);
transition: all 0.2s;
}
.aksrt-signin-calendar__day.is-signed {
background: var(--color-success, #10B981);
color: #fff;
}
.aksrt-signin-calendar__day.is-today {
border: 2px solid var(--color-primary, var(--color-primary));
}
.aksrt-signin-calendar__day.is-signed.is-today {
background: var(--color-primary, var(--color-primary));
border-color: var(--color-primary, var(--color-primary));
}
/* ============================================================
* 19. VIP 等级标识
* 18. VIP 等级标识
* ============================================================ */
.aksrt-vip-badge {
display: inline-flex;
@@ -7180,6 +7143,23 @@ body.aksrt-modal-runtime-open {
color: var(--color-on-primary, #fff);
}
/* ---- 签到详情弹窗(参考主题 refresh_modal modal-mini 同构壳) ----
内容为服务端 HTML(modal-colorful-header + modal-body),与参考主题
.modal-dialog.modal-mini 几何 1:1:宽 400px、圆角 var(--main-radius)。 */
.aksrt-modal-runtime.aksrt-checkin-details-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
width: min(400px, calc(100vw - 32px));
border-radius: var(--main-radius, 8px);
background: var(--main-bg-color, #fff);
}
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__content {
padding: 0;
}
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__skeleton {
padding: 24px 18px;
}
/* ---- ajax list ---- */
.ajaxpager.is-ajax-loading {
position: relative;
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -356,42 +356,7 @@
}
/* ============================================================
* 18. 签到日历可视化
* ============================================================ */
.aksrt-signin-calendar__grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 4px;
}
.aksrt-signin-calendar__day {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
background: var(--surface-2, #F4F5F7);
font-size: 12px;
color: var(--color-ink-3);
transition: all 0.2s;
}
.aksrt-signin-calendar__day.is-signed {
background: var(--color-success, #10B981);
color: #fff;
}
.aksrt-signin-calendar__day.is-today {
border: 2px solid var(--color-primary, var(--color-primary));
}
.aksrt-signin-calendar__day.is-signed.is-today {
background: var(--color-primary, var(--color-primary));
border-color: var(--color-primary, var(--color-primary));
}
/* ============================================================
* 19. VIP 等级标识
* 18. VIP 等级标识
* ============================================================ */
.aksrt-vip-badge {
display: inline-flex;
+1 -3
View File
@@ -327,10 +327,8 @@
}
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
* 仅禁用指针交互;此前的灰底灰字覆盖是与参考主题的偏差。 */
.aksrt-header-checkin.is-done,
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
.aksrt-header-checkin:disabled,
.aksrt-header-checkin.is-done:hover,
.aksrt-header-checkin:disabled:hover {
cursor: default;
opacity: .85;
+17
View File
@@ -223,6 +223,23 @@ body.aksrt-modal-runtime-open {
color: var(--color-on-primary, #fff);
}
/* ---- 签到详情弹窗(参考主题 refresh_modal modal-mini 同构壳) ----
内容为服务端 HTML(modal-colorful-header + modal-body),与参考主题
.modal-dialog.modal-mini 几何 1:1:宽 400px、圆角 var(--main-radius)。 */
.aksrt-modal-runtime.aksrt-checkin-details-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
width: min(400px, calc(100vw - 32px));
border-radius: var(--main-radius, 8px);
background: var(--main-bg-color, #fff);
}
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__content {
padding: 0;
}
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__skeleton {
padding: 24px 18px;
}
/* ---- ajax list ---- */
.ajaxpager.is-ajax-loading {
position: relative;
-36
View File
@@ -241,41 +241,6 @@
});
}
/* ============================================================
* 8. 签到日历可视化
* ============================================================ */
function initSigninCalendar() {
var calendar = document.querySelector('[data-aksrt-signin-calendar]');
if (!calendar) return;
var data = [];
try {
data = JSON.parse(calendar.dataset.aksrtSigninCalendar || '[]');
} catch (e) {}
// 生成最近 30 天的格子
var today = new Date();
var html = '<div class="aksrt-signin-calendar__grid">';
for (var i = 29; i >= 0; i--) {
var d = new Date(today);
d.setDate(d.getDate() - i);
var dateStr = d.toISOString().split('T')[0];
var isSigned = data.indexOf(dateStr) !== -1;
var isToday = i === 0;
html += '<div class="aksrt-signin-calendar__day' +
(isSigned ? ' is-signed' : '') +
(isToday ? ' is-today' : '') +
'" title="' + dateStr + (isSigned ? ' ✓' : '') + '">' +
'<span>' + d.getDate() + '</span>' +
'</div>';
}
html += '</div>';
calendar.innerHTML = html;
}
/* ============================================================
* 初始化入口 — 先执行一次,随后监听 auto_fun 重扫(各 init 幂等)
* ============================================================ */
@@ -286,7 +251,6 @@
initSticky();
initParallax();
initFloatLabels();
initSigninCalendar();
}
if (document.readyState === 'loading') {
+1 -1
View File
File diff suppressed because one or more lines are too long
+22
View File
@@ -72,6 +72,26 @@
});
}
// 签到成功后,入口按钮就地替换为「已签到」详情弹窗触发链接
// (参考主题:.initiate-checkin → details_link 的替换行为)。
function swapButtonsToDetailsLink() {
var url = window.aksrtData && window.aksrtData.signinDetailsUrl;
if (!url) return;
currentButtons().forEach(function (button) {
var link = document.createElement('a');
link.href = 'javascript:;';
link.className = (button.className || '') + ' checkin-details-link';
link.setAttribute('data-aksrt-modal', 'remote');
link.setAttribute('data-aksrt-modal-url', url);
link.setAttribute('data-aksrt-modal-class', 'aksrt-checkin-details-modal modal-mini');
link.setAttribute('data-aksrt-modal-height', '240');
link.setAttribute('data-aksrt-modal-mobile-bottom', 'true');
link.setAttribute('data-aksrt-modal-cache', 'false');
link.innerHTML = button.innerHTML;
button.replaceWith(link);
});
}
function refresh() {
api('/signin/today').then(function (result) {
if (!result.ok) {
@@ -90,6 +110,7 @@
if (data.signed) {
setStatusHtml('已签到 <strong>' + data.streak + '</strong> 天 +' + data.reward_today);
setButtonState('done');
swapButtonsToDetailsLink();
return;
}
setStatusHtml('连续 <strong>' + data.streak + '</strong> 天,+' + data.reward_if_signin);
@@ -120,6 +141,7 @@
element.title = element.textContent;
});
setButtonState('done');
swapButtonsToDetailsLink();
refresh();
}).finally(function () {
if (window.AKSRTCaptcha) window.AKSRTCaptcha.reset('signin', captchaMount());