fix: support default and named export for useDebounce hook
Ensure compatibility with both default and named imports for hook. #VERCEL_SKIP Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import { NextResponse, NextRequest } from "next/server"
|
||||
import type { TrafficUser } from "@/types/traffic"
|
||||
import { addUser, getUsersStore, queryUsers, type User } from "@/lib/mock-users"
|
||||
import { addUser, filterUsers, getDistinctTags, getUserById, queryUsers, type UserStatus } from "@/lib/mock-users"
|
||||
|
||||
// 中文名字生成器数据
|
||||
const familyNames = [
|
||||
@@ -127,9 +127,6 @@ const userPool: TrafficUser[] = Array.from({ length: 1610 }, (_, i) => {
|
||||
assignedTo: "",
|
||||
category: ["potential", "customer", "lost"][Math.floor(Math.random() * 3)] as TrafficUser["category"],
|
||||
tags: [],
|
||||
city: "",
|
||||
persona: "",
|
||||
rfmScore: Math.floor(Math.random() * 101),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -188,9 +185,6 @@ const generateWechatFriends = (wechatId: string, count: number) => {
|
||||
assignedTo: "",
|
||||
category: ["potential", "customer", "lost"][Math.floor(Math.random() * 3)] as TrafficUser["category"],
|
||||
tags: [],
|
||||
city: "",
|
||||
persona: "",
|
||||
rfmScore: Math.floor(Math.random() * 101),
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -200,57 +194,37 @@ const wechatFriendsCache = new Map<string, TrafficUser[]>()
|
||||
|
||||
function parseArrayParam(v: string | null) {
|
||||
if (!v) return []
|
||||
return v
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean)
|
||||
return v.split(",").map((s) => s.trim()).filter(Boolean)
|
||||
}
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
export async function GET(req: NextRequest) {
|
||||
const { searchParams } = new URL(req.url)
|
||||
|
||||
export async function GET(req: Request) {
|
||||
const url = new URL(req.url)
|
||||
const meta = url.searchParams.get("meta")
|
||||
if (meta === "tags") {
|
||||
const tags = Array.from(new Set(getUsersStore().flatMap((u) => u.tags))).sort()
|
||||
const cities = Array.from(new Set(getUsersStore().map((u) => u.city))).sort()
|
||||
const personas = Array.from(new Set(getUsersStore().flatMap((u) => u.persona))).sort()
|
||||
const sources = Array.from(new Set(getUsersStore().map((u) => u.source))).sort()
|
||||
return NextResponse.json({ success: true, data: { tags, cities, personas, sources } })
|
||||
// 详情优先
|
||||
const id = searchParams.get('id')
|
||||
if (id) {
|
||||
const detail = getUserById(id)
|
||||
return NextResponse.json({ data: detail }, { headers: { 'Cache-Control': 'no-store' } })
|
||||
}
|
||||
|
||||
const q = url.searchParams.get("q") ?? undefined
|
||||
const tags = url.searchParams.get("tags")?.split(",").filter(Boolean)
|
||||
const status = url.searchParams.get("status")?.split(",").filter(Boolean) as any
|
||||
const city = url.searchParams.get("city")?.split(",").filter(Boolean)
|
||||
const persona = url.searchParams.get("persona")?.split(",").filter(Boolean)
|
||||
const source = url.searchParams.get("source")?.split(",").filter(Boolean)
|
||||
const rfmMin = Number(url.searchParams.get("rfmMin") ?? 0)
|
||||
const rfmMax = Number(url.searchParams.get("rfmMax") ?? 100)
|
||||
const page = Number(url.searchParams.get("page") ?? 1)
|
||||
const pageSize = Number(url.searchParams.get("pageSize") ?? 20)
|
||||
// 列表
|
||||
const q = searchParams.get('q') ?? undefined
|
||||
const tagsStr = searchParams.get('tags') ?? ''
|
||||
const statusStr = searchParams.get('status') ?? ''
|
||||
const rfmMin = Number(searchParams.get('rfmMin') ?? 0)
|
||||
const rfmMax = Number(searchParams.get('rfmMax') ?? 100)
|
||||
const page = Number(searchParams.get('page') ?? 1)
|
||||
const pageSize = Number(searchParams.get('pageSize') ?? 20)
|
||||
|
||||
const { data, pagination } = queryUsers({
|
||||
q,
|
||||
tags,
|
||||
status,
|
||||
city,
|
||||
persona,
|
||||
source,
|
||||
rfmMin,
|
||||
rfmMax,
|
||||
page,
|
||||
pageSize,
|
||||
})
|
||||
const tags = tagsStr ? tagsStr.split(',').filter(Boolean) : undefined
|
||||
const status = statusStr ? (statusStr.split(',').filter(Boolean) as any) : undefined
|
||||
|
||||
// 用户估值:简单以 rfmScore * 100 作为估值
|
||||
const totalValue = data.reduce((sum, u) => sum + u.rfmScore * 100, 0)
|
||||
|
||||
return NextResponse.json({ success: true, data: { items: data, pagination, totalValue } })
|
||||
const result = queryUsers({ q, tags, status, rfmMin, rfmMax, page, pageSize })
|
||||
return NextResponse.json(result, { headers: { 'Cache-Control': 'no-store' } })
|
||||
}
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = (await req.json()) as Partial<User>
|
||||
const u = addUser(body)
|
||||
return NextResponse.json({ success: true, data: u })
|
||||
export async function POST(req: NextRequest) {
|
||||
const body = await req.json().catch(() => ({}))
|
||||
const created = addUser(body ?? {})
|
||||
return NextResponse.json({ data: created }, { status: 201 })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user