feat: expand redeem duration options (hours/days/months/year)
- Add 6h, 12h, 1d, 3d, 7d, 14d, 1mo, 3mo, 6mo, 1yr presets - Add formatDuration helper for smart display (分钟/小时/天/月/年) - Fix custom value handling when editing items with non-preset durations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
这个提交包含在:
@@ -62,6 +62,23 @@ function fmtTs(v: number | null | undefined): string {
|
|||||||
return new Date(v * 1000).toLocaleString();
|
return new Date(v * 1000).toLocaleString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatDuration(mins: number): string {
|
||||||
|
if (mins >= 525600) {
|
||||||
|
const y = mins / 525600;
|
||||||
|
return Number.isInteger(y) ? `${y}年` : `${(mins / 1440).toFixed(0)}天`;
|
||||||
|
}
|
||||||
|
if (mins >= 43200) {
|
||||||
|
const m = mins / 43200;
|
||||||
|
return Number.isInteger(m) ? `${m}个月` : `${(mins / 1440).toFixed(0)}天`;
|
||||||
|
}
|
||||||
|
if (mins >= 1440) return `${(mins / 1440).toFixed(0)}天`;
|
||||||
|
if (mins >= 60) {
|
||||||
|
const h = mins / 60;
|
||||||
|
return Number.isInteger(h) ? `${h}小时` : `${h.toFixed(1)}小时`;
|
||||||
|
}
|
||||||
|
return `${mins}分钟`;
|
||||||
|
}
|
||||||
|
|
||||||
export default function AdminRedeemPage() {
|
export default function AdminRedeemPage() {
|
||||||
const { tx } = useI18nText();
|
const { tx } = useI18nText();
|
||||||
const [token, setToken] = useState("");
|
const [token, setToken] = useState("");
|
||||||
@@ -224,7 +241,12 @@ export default function AdminRedeemPage() {
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<select
|
<select
|
||||||
className="rounded border px-3 py-2 text-sm flex-1"
|
className="rounded border px-3 py-2 text-sm flex-1"
|
||||||
value={form.duration_minutes === 0 ? "0" : String(form.duration_minutes)}
|
value={
|
||||||
|
form.duration_minutes === 0 ? "0"
|
||||||
|
: form.duration_minutes === -1 ? "-1"
|
||||||
|
: [15,30,60,90,120,180,360,720,1440,4320,10080,20160,43200,129600,259200,525600].includes(form.duration_minutes)
|
||||||
|
? String(form.duration_minutes) : "-1"
|
||||||
|
}
|
||||||
onChange={(e) => setForm((prev) => ({ ...prev, duration_minutes: Number(e.target.value) }))}
|
onChange={(e) => setForm((prev) => ({ ...prev, duration_minutes: Number(e.target.value) }))}
|
||||||
>
|
>
|
||||||
<option value="0">{tx("永久有效 ♾️", "Permanent ♾️")}</option>
|
<option value="0">{tx("永久有效 ♾️", "Permanent ♾️")}</option>
|
||||||
@@ -234,14 +256,25 @@ export default function AdminRedeemPage() {
|
|||||||
<option value="90">1.5 {tx("小时", "hours")}</option>
|
<option value="90">1.5 {tx("小时", "hours")}</option>
|
||||||
<option value="120">2 {tx("小时", "hours")}</option>
|
<option value="120">2 {tx("小时", "hours")}</option>
|
||||||
<option value="180">3 {tx("小时", "hours")}</option>
|
<option value="180">3 {tx("小时", "hours")}</option>
|
||||||
|
<option value="360">6 {tx("小时", "hours")}</option>
|
||||||
|
<option value="720">12 {tx("小时", "hours")}</option>
|
||||||
|
<option value="1440">1 {tx("天", "day")}</option>
|
||||||
|
<option value="4320">3 {tx("天", "days")}</option>
|
||||||
|
<option value="10080">7 {tx("天", "days")}</option>
|
||||||
|
<option value="20160">14 {tx("天", "days")}</option>
|
||||||
|
<option value="43200">1 {tx("个月", "month")}</option>
|
||||||
|
<option value="129600">3 {tx("个月", "months")}</option>
|
||||||
|
<option value="259200">6 {tx("个月", "months")}</option>
|
||||||
|
<option value="525600">1 {tx("年", "year")}</option>
|
||||||
<option value="-1">{tx("自定义", "Custom")}</option>
|
<option value="-1">{tx("自定义", "Custom")}</option>
|
||||||
</select>
|
</select>
|
||||||
{form.duration_minutes === -1 && (
|
{(form.duration_minutes === -1 || (form.duration_minutes > 0 && ![15,30,60,90,120,180,360,720,1440,4320,10080,20160,43200,129600,259200,525600].includes(form.duration_minutes))) && (
|
||||||
<input
|
<input
|
||||||
className="rounded border px-3 py-2 text-sm w-24"
|
className="rounded border px-3 py-2 text-sm w-24"
|
||||||
type="number"
|
type="number"
|
||||||
min={1}
|
min={1}
|
||||||
placeholder={tx("分钟", "min")}
|
placeholder={tx("分钟", "min")}
|
||||||
|
defaultValue={form.duration_minutes > 0 ? form.duration_minutes : ""}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const v = Math.max(1, Number(e.target.value) || 1);
|
const v = Math.max(1, Number(e.target.value) || 1);
|
||||||
setForm((prev) => ({ ...prev, duration_minutes: v }));
|
setForm((prev) => ({ ...prev, duration_minutes: v }));
|
||||||
@@ -325,9 +358,7 @@ export default function AdminRedeemPage() {
|
|||||||
{item.unit_label}
|
{item.unit_label}
|
||||||
{" · "}
|
{" · "}
|
||||||
{item.duration_minutes > 0
|
{item.duration_minutes > 0
|
||||||
? (item.duration_minutes >= 60
|
? `⏱️ ${formatDuration(item.duration_minutes)}`
|
||||||
? `⏱️ ${item.duration_minutes / 60}${tx("小时", "h")}`
|
|
||||||
: `⏱️ ${item.duration_minutes}${tx("分钟", "min")}`)
|
|
||||||
: `♾️ ${tx("永久", "Permanent")}`}
|
: `♾️ ${tx("永久", "Permanent")}`}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-zinc-600">
|
<p className="text-xs text-zinc-600">
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户