ip管理表格添加提取地区列 & 提取IP取消运营商字段选项 & 调整购买页价格显示问题

This commit is contained in:
Eamon-meng
2026-06-23 14:31:50 +08:00
parent 94ab3f55a8
commit dc877c3ea0
6 changed files with 26 additions and 9 deletions

View File

@@ -178,6 +178,21 @@ export default function ChannelsPage(props: ChannelsPageProps) {
header: '代理地址', header: '代理地址',
cell: ({row}) => <Addr channel={row.original}/>, cell: ({row}) => <Addr channel={row.original}/>,
}, },
{
header: '地区',
cell: ({row}) => {
const prov = row.original.filter_prov
const city = row.original.filter_city
const parts = []
if (prov && prov !== 'all') parts.push(prov)
if (city && city !== 'all') parts.push(city)
return (
<div className="text-sm">
{parts.length > 0 ? parts.join(' / ') : '不限'}
</div>
)
},
},
{ {
header: '认证方式', header: '认证方式',
cell: ({row}) => { cell: ({row}) => {

View File

@@ -26,7 +26,7 @@ const schema = z.object({
prov: z.string().optional(), prov: z.string().optional(),
city: z.string().optional(), city: z.string().optional(),
regionType: z.enum(['unlimited', 'specific']).default('unlimited'), regionType: z.enum(['unlimited', 'specific']).default('unlimited'),
isp: z.enum(['all', '1', '2', '3'], {required_error: '请选择运营商'}), // isp: z.enum(['all', '1', '2', '3'], {required_error: '请选择运营商'}),
proto: z.enum(['all', '1', '2'], {required_error: '请选择协议'}), proto: z.enum(['all', '1', '2'], {required_error: '请选择协议'}),
authType: z.enum(['1', '2'], {required_error: '请选择认证方式'}), authType: z.enum(['1', '2'], {required_error: '请选择认证方式'}),
distinct: z.enum(['1', '0'], {required_error: '请选择去重选项'}), distinct: z.enum(['1', '0'], {required_error: '请选择去重选项'}),
@@ -48,7 +48,7 @@ export default function Extract(props: ExtractProps) {
resolver: zodResolver(schema), resolver: zodResolver(schema),
defaultValues: { defaultValues: {
regionType: 'unlimited', regionType: 'unlimited',
isp: 'all', // isp: 'all',
proto: 'all', proto: 'all',
authType: '1', authType: '1',
count: 1, count: 1,
@@ -108,7 +108,7 @@ const FormFields = memo(() => {
<SelectRegion/> <SelectRegion/>
{/* 运营商筛选 */} {/* 运营商筛选 */}
<FormField name="isp" label="运营商筛选" classNames={{label: 'max-md:text-sm'}}> {/* <FormField name="isp" label="运营商筛选" classNames={{label: 'max-md:text-sm'}}>
{({id, field}) => ( {({id, field}) => (
<RadioGroup <RadioGroup
onValueChange={field.onChange} onValueChange={field.onChange}
@@ -133,7 +133,7 @@ const FormFields = memo(() => {
</FormLabel> </FormLabel>
</RadioGroup> </RadioGroup>
)} )}
</FormField> </FormField> */}
{/* 协议类型 */} {/* 协议类型 */}
<FormField name="proto" label="协议类型" classNames={{label: 'max-md:text-sm'}}> <FormField name="proto" label="协议类型" classNames={{label: 'max-md:text-sm'}}>
@@ -711,7 +711,7 @@ function ApplyLink() {
} }
function link(values: Schema) { function link(values: Schema) {
const {resource, prov, city, isp, proto, authType, distinct, format: formatType, separator, breaker, count} = values const {resource, prov, city, proto, authType, distinct, format: formatType, separator, breaker, count} = values
console.log(values, 'values') console.log(values, 'values')
const sp = new URLSearchParams() const sp = new URLSearchParams()
@@ -721,7 +721,7 @@ function link(values: Schema) {
if (prov) sp.set('b', prov) if (prov) sp.set('b', prov)
if (city) sp.set('b', city) if (city) sp.set('b', city)
if (isp != 'all') sp.set('s', isp) sp.set('s', 'all')
sp.set('d', distinct) sp.set('d', distinct)
sp.set('rt', formatType) sp.set('rt', formatType)
sp.set('rh', 'ip') sp.set('rh', 'ip')

View File

@@ -134,7 +134,7 @@ export default function Center({skuData}: {
setValue('expire', nextExpireList[0]) setValue('expire', nextExpireList[0])
} }
}} }}
className="grid grid-cols-[repeat(auto-fill,minmax(120px,1fr))] gap-4"> className="grid grid-cols-[repeat(auto-fill,minmax(150px,1fr))] gap-4">
{liveList.map((live) => { {liveList.map((live) => {
const priceExpire = type === '1' && !hasPurchaseSku(skuData, {mode: type, live, expire}) const priceExpire = type === '1' && !hasPurchaseSku(skuData, {mode: type, live, expire})
? getAvailablePurchaseExpires(skuData, {mode: type, live})[0] || '0' ? getAvailablePurchaseExpires(skuData, {mode: type, live})[0] || '0'

View File

@@ -57,7 +57,7 @@ export default function FormOption(props: FormOptionProps) {
<p className="text-sm text-gray-500">{props.description}</p> <p className="text-sm text-gray-500">{props.description}</p>
)} )}
{isValidPrice && ( {isValidPrice && (
<div className="flex items-center gap-2 flex-wrap"> <div className="flex items-center flex-col">
{hasDiscount ? ( {hasDiscount ? (
<> <>
<p className="text-sm font-medium">{formatPrice(discountedPrice!)}/IP</p> <p className="text-sm font-medium">{formatPrice(discountedPrice!)}/IP</p>

View File

@@ -135,7 +135,7 @@ export default function Center({
setValue('expire', nextExpireList[0]) setValue('expire', nextExpireList[0])
} }
}} }}
className="grid grid-cols-[repeat(auto-fill,minmax(120px,1fr))] gap-4"> className="grid grid-cols-[repeat(auto-fill,minmax(150px,1fr))] gap-4">
{liveList.map((live) => { {liveList.map((live) => {
const priceExpire = type === '1' && !hasPurchaseSku(skuData, {mode: type, live, expire}) const priceExpire = type === '1' && !hasPurchaseSku(skuData, {mode: type, live, expire})
? getAvailablePurchaseExpires(skuData, {mode: type, live})[0] || '0' ? getAvailablePurchaseExpires(skuData, {mode: type, live})[0] || '0'

View File

@@ -104,6 +104,8 @@ export type Channel = {
expired_at: Date expired_at: Date
host: string host: string
batch_no: string batch_no: string
filter_prov: string
filter_city: string
} }
export type Proxy = { export type Proxy = {
id: number id: number