Files
shensheshou/app/api/users/route.ts
v0 9bb0ee2758 fix: resolve homepage 404 and add mock data for user portrait
Add landing page, fix type errors, mark dynamic API route, and refactor user portrait page.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2025-08-09 03:04:39 +00:00

227 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse, NextRequest } from "next/server"
import type { TrafficUser } from "@/types/traffic"
import { addUser, filterUsers, getDistinctTags, getUserById, queryUsers, type UserStatus, MOCK_USERS } from "@/lib/mock-users"
// 中文名字生成器数据
const familyNames = [
"张",
"王",
"李",
"赵",
"陈",
"刘",
"杨",
"黄",
"周",
"吴",
"朱",
"孙",
"马",
"胡",
"郭",
"林",
"何",
"高",
"梁",
"郑",
"罗",
"宋",
"谢",
"唐",
"韩",
"曹",
"许",
"邓",
"萧",
"冯",
]
const givenNames1 = [
"志",
"建",
"文",
"明",
"永",
"春",
"秀",
"金",
"水",
"玉",
"国",
"立",
"德",
"海",
"和",
"荣",
"伟",
"新",
"英",
"佳",
]
const givenNames2 = [
"华",
"平",
"军",
"强",
"辉",
"敏",
"峰",
"磊",
"超",
"艳",
"娜",
"霞",
"燕",
"娟",
"静",
"丽",
"涛",
"洋",
"勇",
"龙",
]
// 生成固定的用户数据池
const userPool: TrafficUser[] = Array.from({ length: 1610 }, (_, i) => {
const familyName = familyNames[Math.floor(Math.random() * familyNames.length)]
const givenName1 = givenNames1[Math.floor(Math.random() * givenNames1.length)]
const givenName2 = givenNames2[Math.floor(Math.random() * givenNames2.length)]
const fullName = Math.random() > 0.5 ? familyName + givenName1 + givenName2 : familyName + givenName1
// 生成随机时间在过去7天内
const date = new Date()
date.setDate(date.getDate() - Math.floor(Math.random() * 7))
return {
id: `${Date.now()}-${i}`,
avatar: `/placeholder.svg?height=40&width=40&text=${fullName[0]}`,
nickname: fullName,
wechatId: `wxid_${Math.random().toString(36).substr(2, 8)}`,
phone: `1${["3", "5", "7", "8", "9"][Math.floor(Math.random() * 5)]}${Array.from({ length: 9 }, () => Math.floor(Math.random() * 10)).join("")}`,
region: [
"广东深圳",
"浙江杭州",
"江苏苏州",
"北京",
"上海",
"四川成都",
"湖北武汉",
"福建厦门",
"山东青岛",
"河南郑州",
][Math.floor(Math.random() * 10)],
note: [
"咨询产品价格",
"对产品很感兴趣",
"准备购买",
"需要更多信息",
"想了解优惠活动",
"询问产品规格",
"要求产品demo",
"索要产品目录",
"询问售后服务",
"要求上门演示",
][Math.floor(Math.random() * 10)],
status: ["pending", "added", "failed"][Math.floor(Math.random() * 3)] as TrafficUser["status"],
addTime: date.toISOString(),
source: ["抖音直播", "小红书", "微信朋友圈", "视频号", "公众号", "个人主页"][Math.floor(Math.random() * 6)],
assignedTo: "",
category: ["potential", "customer", "lost"][Math.floor(Math.random() * 3)] as TrafficUser["category"],
tags: [],
}
})
// 计算今日新增数量
const todayStart = new Date()
todayStart.setHours(0, 0, 0, 0)
const todayUsers = userPool.filter((user) => new Date(user.addTime) >= todayStart)
// 生成微信好友数据池
const generateWechatFriends = (wechatId: string, count: number) => {
return Array.from({ length: count }, (_, i) => {
const familyName = familyNames[Math.floor(Math.random() * familyNames.length)]
const givenName1 = givenNames1[Math.floor(Math.random() * givenNames1.length)]
const givenName2 = givenNames2[Math.floor(Math.random() * givenNames2.length)]
const fullName = Math.random() > 0.5 ? familyName + givenName1 + givenName2 : familyName + givenName1
// 生成随机时间在过去30天内
const date = new Date()
date.setDate(date.getDate() - Math.floor(Math.random() * 30))
return {
id: `wechat-${wechatId}-${i}`,
avatar: `/placeholder.svg?height=40&width=40&text=${fullName[0]}`,
nickname: fullName,
wechatId: `wxid_${Math.random().toString(36).substr(2, 8)}`,
phone: `1${["3", "5", "7", "8", "9"][Math.floor(Math.random() * 5)]}${Array.from({ length: 9 }, () => Math.floor(Math.random() * 10)).join("")}`,
region: [
"广东深圳",
"浙江杭州",
"江苏苏州",
"北京",
"上海",
"四川成都",
"湖北武汉",
"福建厦门",
"山东青岛",
"河南郑州",
][Math.floor(Math.random() * 10)],
note: [
"咨询产品价格",
"对产品很感兴趣",
"准备购买",
"需要更多信息",
"想了解优惠活动",
"询问产品规格",
"要求产品demo",
"索要产品目录",
"询问售后服务",
"要求上门演示",
][Math.floor(Math.random() * 10)],
status: ["pending", "added", "failed"][Math.floor(Math.random() * 3)] as TrafficUser["status"],
addTime: date.toISOString(),
source: ["抖音直播", "小红书", "微信朋友圈", "视频号", "公众号", "个人主页", "微信好友"][
Math.floor(Math.random() * 7)
],
assignedTo: "",
category: ["potential", "customer", "lost"][Math.floor(Math.random() * 3)] as TrafficUser["category"],
tags: [],
}
})
}
// 微信好友数据缓存
const wechatFriendsCache = new Map<string, TrafficUser[]>()
function parseArrayParam(v: string | null) {
if (!v) return []
return v.split(",").map((s) => s.trim()).filter(Boolean)
}
export const dynamic = "force-dynamic"
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const keyword = (searchParams.get("q") || "").trim()
const filtered = keyword
? MOCK_USERS.filter(
(u) =>
u.name.includes(keyword) ||
(u.nickname && u.nickname.includes(keyword)) ||
u.tags.some((t) => t.includes(keyword)),
)
: MOCK_USERS
return NextResponse.json({
success: true,
total: filtered.length,
items: filtered,
})
}
export async function POST(req: NextRequest) {
const body = await req.json().catch(() => ({}))
const created = addUser(body ?? {})
return NextResponse.json({ data: created }, { status: 201 })
}