From bb923aab4da157cf2b4a0abbdcfa223f397ac0cd Mon Sep 17 00:00:00 2001 From: subtrack Date: Mon, 19 Oct 2026 19:57:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(v1.8.2):=20=E5=A5=97=E9=A4=90=E8=AE=A1?= =?UTF-8?q?=E8=B4=B9=E6=96=B9=E5=BC=8F=E5=88=87=E6=8D=A2=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E6=98=BE=E7=A4=BA/=E9=9A=90=E8=97=8F=E4=B8=8E=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按「any → 包时 / 按次 / 包赛季」规则检查后修复 3 处问题: 1) 包赛季套餐编辑时「按日」也被勾中 - 赛季套餐在库里 unit='day' + season=1,模板只判断了 unit,导致按日/赛季两个 radio 都带 checked - 修正为「unit=day 且非赛季」才勾中按日 2) 客户开通表单:选中包赛季时仍显示且必填「开始日」 - 赛季起止由套餐决定,开始日应隐藏 - 表单加 data-start-wrap,JS 在赛季模式隐藏并取消 required,切回其它模式恢复 3) 按次开通时没有带出套餐默认有效期 - 套餐选项新增 data-validity,选中按次且终止日为空时,自动按「开始日 + 默认有效期 - 1」带出到期日,仍可手改 现状(已逐项验证): - 包时:默认量单位「天」,无有效期/赛季字段 - 按次:默认量单位「次」,显示「按次默认有效期(天)」,开单自动带出到期日 - 包赛季:显示赛季开始日/结束日(必填),隐藏默认量有效期与开始日;过期套餐下拉置灰 测试: - 转换专项 10 项全过:三种模式的勾选状态、字段显示、按日→按次→赛季→按日 往返保存均正常 - 数据库未改动结构,往返保存后 unit/season/season_start/season_end 值正确 - 版本号 1.8.2 --- internal/web/static/app.js | 28 +++++++++++++++---- .../web/templates/pages/customer_detail.html | 4 +-- .../web/templates/pages/package_form.html | 2 +- main.go | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/internal/web/static/app.js b/internal/web/static/app.js index d6d23fc..9af8fba 100644 --- a/internal/web/static/app.js +++ b/internal/web/static/app.js @@ -69,20 +69,38 @@ var daysWrap = form.querySelector('[data-days-wrap]'); var countWrap = form.querySelector('[data-count-wrap]'); var endWrap = form.querySelector('[data-end-wrap]'); + var startWrap = form.querySelector('[data-start-wrap]'); + var startInput = form.querySelector('input[name="start_date"]'); if (!sel) return; function sync() { var opt = sel.options[sel.selectedIndex]; var unit = opt && opt.getAttribute('data-unit'); var amount = opt && opt.getAttribute('data-amount'); - if (unit === 'count') { - if (daysWrap) daysWrap.hidden = true; - if (countWrap) { countWrap.hidden = false; if (amount) countWrap.querySelector('input').value = amount; } - if (endWrap) endWrap.hidden = true; - } else if (unit === 'season') { + var validity = opt && parseInt(opt.getAttribute('data-validity') || '0', 10); + var endInput = endWrap && endWrap.querySelector('input'); + + if (unit === 'season') { if (daysWrap) daysWrap.hidden = true; if (countWrap) countWrap.hidden = true; if (endWrap) endWrap.hidden = true; + if (startWrap) startWrap.hidden = true; + if (startInput) startInput.required = false; + return; + } + + if (startWrap) startWrap.hidden = false; + if (startInput) startInput.required = true; + + if (unit === 'count') { + if (daysWrap) daysWrap.hidden = true; + if (countWrap) { countWrap.hidden = false; if (amount) countWrap.querySelector('input').value = amount; } + if (endWrap) endWrap.hidden = false; + if (validity > 0 && endInput && !endInput.value && startInput && startInput.value) { + var d = new Date(startInput.value + 'T00:00:00'); + d.setDate(d.getDate() + validity - 1); + endInput.value = d.toISOString().slice(0, 10); + } } else if (unit === 'day') { if (daysWrap) { daysWrap.hidden = false; if (amount) daysWrap.querySelector('input').value = amount; } if (countWrap) countWrap.hidden = true; diff --git a/internal/web/templates/pages/customer_detail.html b/internal/web/templates/pages/customer_detail.html index b4add4d..accf809 100644 --- a/internal/web/templates/pages/customer_detail.html +++ b/internal/web/templates/pages/customer_detail.html @@ -89,12 +89,12 @@ -