2026-04-08 15:41:32 +08:00
|
|
|
|
import type { ChangeEvent } from "react"
|
|
|
|
|
|
import {
|
|
|
|
|
|
type Control,
|
|
|
|
|
|
type Path,
|
|
|
|
|
|
type UseControllerReturn,
|
|
|
|
|
|
useController,
|
|
|
|
|
|
} from "react-hook-form"
|
|
|
|
|
|
import { ProductCode } from "@/lib/base"
|
|
|
|
|
|
import {
|
|
|
|
|
|
Field,
|
|
|
|
|
|
FieldError,
|
|
|
|
|
|
FieldGroup,
|
|
|
|
|
|
FieldLabel,
|
|
|
|
|
|
FieldLegend,
|
|
|
|
|
|
} from "../ui/field"
|
|
|
|
|
|
import { Input } from "../ui/input"
|
|
|
|
|
|
import {
|
|
|
|
|
|
Select,
|
|
|
|
|
|
SelectContent,
|
|
|
|
|
|
SelectItem,
|
|
|
|
|
|
SelectTrigger,
|
|
|
|
|
|
SelectValue,
|
|
|
|
|
|
} from "../ui/select"
|
|
|
|
|
|
|
|
|
|
|
|
export function ProductCodeField<
|
|
|
|
|
|
T extends {
|
|
|
|
|
|
code: string
|
|
|
|
|
|
},
|
|
|
|
|
|
>(props: { control: Control<T>; name: Path<T>; code: ProductCode }) {
|
|
|
|
|
|
const rt = useController(props)
|
|
|
|
|
|
|
|
|
|
|
|
switch (props.code) {
|
|
|
|
|
|
case ProductCode.Short:
|
|
|
|
|
|
return <ProductShortCode {...rt} />
|
|
|
|
|
|
case ProductCode.Long:
|
|
|
|
|
|
return <ProductLongCode {...rt} />
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function ProductShortCode<T extends { code: string }>(
|
|
|
|
|
|
props: UseControllerReturn<T>,
|
|
|
|
|
|
) {
|
|
|
|
|
|
const { field, fieldState } = props
|
|
|
|
|
|
|
|
|
|
|
|
const params = new URLSearchParams(field.value)
|
2026-04-15 17:15:40 +08:00
|
|
|
|
const mode = params.get("mode") || "quota"
|
|
|
|
|
|
const live = params.get("live") || "0"
|
|
|
|
|
|
const expire = params.get("expire") || "0"
|
|
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const setParams = (data: {
|
|
|
|
|
|
mode?: string
|
|
|
|
|
|
live?: string
|
|
|
|
|
|
expire?: string
|
|
|
|
|
|
}) => {
|
2026-04-15 17:15:40 +08:00
|
|
|
|
const newParams = new URLSearchParams()
|
|
|
|
|
|
newParams.set("mode", data.mode || mode)
|
|
|
|
|
|
newParams.set("live", data.live || live)
|
|
|
|
|
|
newParams.set("expire", data.expire || expire)
|
|
|
|
|
|
console.log(newParams.toString())
|
|
|
|
|
|
field.onChange(newParams.toString())
|
2026-04-08 15:41:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onModeChange = (value: string) => {
|
|
|
|
|
|
setParams({ mode: value })
|
|
|
|
|
|
}
|
2026-04-15 17:15:40 +08:00
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const onLiveChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
|
let value = e.target.value || "0"
|
|
|
|
|
|
if (value.length > 1 && value[0] === "0") {
|
|
|
|
|
|
value = value.substring(1, value.length)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!/^([0-9]+)$/.test(value)) return
|
|
|
|
|
|
setParams({ live: value })
|
|
|
|
|
|
}
|
2026-04-15 17:15:40 +08:00
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const onExpireChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
|
let value = e.target.value || "0"
|
|
|
|
|
|
if (value.length > 1 && value[0] === "0") {
|
|
|
|
|
|
value = value.substring(1, value.length)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!/^([0-9]+)$/.test(value)) return
|
|
|
|
|
|
setParams({ expire: value })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<FieldLegend>
|
|
|
|
|
|
<FieldLegend>短效套餐详情</FieldLegend>
|
|
|
|
|
|
<FieldGroup>
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>套餐类型</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Select defaultValue={mode} onValueChange={onModeChange}>
|
2026-04-08 15:41:32 +08:00
|
|
|
|
<SelectTrigger>
|
|
|
|
|
|
<SelectValue placeholder="请选择套餐类型" />
|
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
<SelectContent>
|
|
|
|
|
|
<SelectItem value="time">包时</SelectItem>
|
|
|
|
|
|
<SelectItem value="quota">包量</SelectItem>
|
|
|
|
|
|
</SelectContent>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>有效期(分钟)</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Input type="number" value={live} onChange={onLiveChange} />
|
2026-04-08 15:41:32 +08:00
|
|
|
|
</Field>
|
|
|
|
|
|
{params.get("mode") === "time" && (
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>过期时间(天)</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Input type="number" value={expire} onChange={onExpireChange} />
|
2026-04-08 15:41:32 +08:00
|
|
|
|
</Field>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{fieldState.error && <FieldError errors={[fieldState.error]} />}
|
|
|
|
|
|
</FieldGroup>
|
|
|
|
|
|
</FieldLegend>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function ProductLongCode<T extends { code: string }>(
|
|
|
|
|
|
props: UseControllerReturn<T>,
|
|
|
|
|
|
) {
|
|
|
|
|
|
const { field, fieldState } = props
|
|
|
|
|
|
|
|
|
|
|
|
const params = new URLSearchParams(field.value)
|
2026-04-15 17:15:40 +08:00
|
|
|
|
const mode = params.get("mode") || "quota"
|
|
|
|
|
|
const live = params.get("live") || "0"
|
|
|
|
|
|
const expire = params.get("expire") || "0"
|
|
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const setParams = (data: {
|
|
|
|
|
|
mode?: string
|
|
|
|
|
|
live?: string
|
|
|
|
|
|
expire?: string
|
|
|
|
|
|
}) => {
|
2026-04-15 17:15:40 +08:00
|
|
|
|
const newParams = new URLSearchParams()
|
|
|
|
|
|
newParams.set("mode", data.mode || mode)
|
|
|
|
|
|
newParams.set("live", data.live || live)
|
|
|
|
|
|
newParams.set("expire", data.expire || expire)
|
|
|
|
|
|
console.log(newParams.toString())
|
|
|
|
|
|
field.onChange(newParams.toString())
|
2026-04-08 15:41:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onModeChange = (value: string) => {
|
2026-04-13 16:22:33 +08:00
|
|
|
|
if (value === "quota") {
|
|
|
|
|
|
setParams({ mode: value, expire: "0" })
|
|
|
|
|
|
} else {
|
|
|
|
|
|
setParams({ mode: value })
|
|
|
|
|
|
}
|
2026-04-08 15:41:32 +08:00
|
|
|
|
}
|
2026-04-13 16:22:33 +08:00
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const onLiveChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
|
let value = e.target.value || "0"
|
|
|
|
|
|
if (value.length > 1 && value[0] === "0") {
|
|
|
|
|
|
value = value.substring(1, value.length)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!/^([0-9]+)$/.test(value)) return
|
|
|
|
|
|
setParams({ live: value })
|
|
|
|
|
|
}
|
2026-04-13 16:22:33 +08:00
|
|
|
|
|
2026-04-08 15:41:32 +08:00
|
|
|
|
const onExpireChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
|
let value = e.target.value || "0"
|
|
|
|
|
|
if (value.length > 1 && value[0] === "0") {
|
|
|
|
|
|
value = value.substring(1, value.length)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!/^([0-9]+)$/.test(value)) return
|
|
|
|
|
|
setParams({ expire: value })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<FieldLegend>
|
|
|
|
|
|
<FieldLegend>长效套餐详情</FieldLegend>
|
|
|
|
|
|
<FieldGroup>
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>套餐类型</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Select defaultValue={mode} onValueChange={onModeChange}>
|
2026-04-08 15:41:32 +08:00
|
|
|
|
<SelectTrigger>
|
|
|
|
|
|
<SelectValue placeholder="请选择套餐类型" />
|
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
<SelectContent>
|
|
|
|
|
|
<SelectItem value="time">包时</SelectItem>
|
|
|
|
|
|
<SelectItem value="quota">包量</SelectItem>
|
|
|
|
|
|
</SelectContent>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>有效期(分钟)</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Input type="number" value={live} onChange={onLiveChange} />
|
2026-04-08 15:41:32 +08:00
|
|
|
|
</Field>
|
|
|
|
|
|
{params.get("mode") === "time" && (
|
|
|
|
|
|
<Field>
|
|
|
|
|
|
<FieldLabel>过期时间(天)</FieldLabel>
|
2026-04-15 17:15:40 +08:00
|
|
|
|
<Input type="number" value={expire} onChange={onExpireChange} />
|
2026-04-08 15:41:32 +08:00
|
|
|
|
</Field>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{fieldState.error && <FieldError errors={[fieldState.error]} />}
|
|
|
|
|
|
</FieldGroup>
|
|
|
|
|
|
</FieldLegend>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|