超管后台 - 调整所有的fetch 请求为后封装的 apiRequest,实现cookie 跨域
This commit is contained in:
@@ -7,6 +7,7 @@ import { toast } from "sonner"
|
||||
import useAuthCheck from "@/hooks/useAuthCheck"
|
||||
import { getAdminInfo, getGreeting } from "@/lib/utils"
|
||||
import ClientOnly from "@/components/ClientOnly"
|
||||
import { apiRequest } from '@/lib/api-utils'
|
||||
|
||||
interface DashboardStats {
|
||||
companyCount: number
|
||||
@@ -28,16 +29,14 @@ export default function DashboardPage() {
|
||||
useAuthCheck()
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true)
|
||||
const fetchDashboardData = async () => {
|
||||
try {
|
||||
// 获取统计信息
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/dashboard/base`)
|
||||
const data = await response.json()
|
||||
if (data.code === 200) {
|
||||
setStats(data.data)
|
||||
setIsLoading(true)
|
||||
const result = await apiRequest('/dashboard/base')
|
||||
if (result.code === 200 && result.data) {
|
||||
setStats(result.data)
|
||||
} else {
|
||||
toast.error(data.msg || "获取统计信息失败")
|
||||
toast.error(result.msg || "获取仪表盘数据失败")
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
@@ -49,13 +48,14 @@ export default function DashboardPage() {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
console.error("获取仪表盘数据失败:", error)
|
||||
toast.error("网络错误,请稍后再试")
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fetchData()
|
||||
fetchDashboardData()
|
||||
}, [])
|
||||
|
||||
// 单独处理问候语,避免依赖问题
|
||||
|
||||
@@ -13,6 +13,7 @@ import Link from "next/link"
|
||||
import { toast, Toaster } from "sonner"
|
||||
import Image from "next/image"
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog"
|
||||
import { apiRequest } from "@/lib/api-utils"
|
||||
|
||||
// 为React.use添加类型声明
|
||||
declare module 'react' {
|
||||
@@ -69,30 +70,14 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
|
||||
useEffect(() => {
|
||||
const fetchProject = async () => {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/detail/${id}`)
|
||||
const result = await apiRequest(`/company/detail/${id}`)
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
toast.error(`获取失败: ${response.status} ${response.statusText}`);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查内容类型是否为JSON
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
toast.error("服务器返回了非JSON格式的数据");
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
setProject(data.data)
|
||||
if (result.code === 200) {
|
||||
setProject(result.data)
|
||||
} else {
|
||||
toast.error(data.msg || "获取项目信息失败")
|
||||
toast.error(result.msg || "获取项目信息失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
@@ -106,54 +91,25 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (password && password !== confirmPassword) {
|
||||
toast.error("两次输入的密码不一致")
|
||||
return
|
||||
}
|
||||
|
||||
setIsSubmitting(true)
|
||||
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/update`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: parseInt(id),
|
||||
name: project?.name,
|
||||
account: project?.account,
|
||||
memo: project?.memo,
|
||||
phone: project?.phone,
|
||||
username: project?.username,
|
||||
status: project?.status,
|
||||
...(password && { password })
|
||||
}),
|
||||
const result = await apiRequest('/company/update', 'POST', {
|
||||
id: id,
|
||||
name: project?.name,
|
||||
account: project?.account,
|
||||
password: password,
|
||||
memo: project?.memo,
|
||||
phone: project?.phone,
|
||||
username: project?.username,
|
||||
status: project?.status.toString(),
|
||||
})
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
toast.error(`更新失败: ${response.status} ${response.statusText}`);
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查内容类型是否为JSON
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
toast.error("服务器返回了非JSON格式的数据");
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
toast.success("更新成功")
|
||||
if (result.code === 200) {
|
||||
toast.success("项目更新成功")
|
||||
router.push("/dashboard/projects")
|
||||
} else {
|
||||
toast.error(data.msg)
|
||||
toast.error(result.msg || "更新失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
@@ -177,33 +133,12 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
pollingCountRef.current = 0;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/v1/api/device/add`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
accountId: project.s2_accountId
|
||||
}),
|
||||
const result = await apiRequest('/v1/api/device/add', 'POST', {
|
||||
accountId: project.s2_accountId
|
||||
})
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
toast.error(`请求失败: ${response.status} ${response.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查内容类型是否为JSON
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
toast.error("服务器返回了非JSON格式的数据");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200 && data.data?.qrCode) {
|
||||
setQrCodeData(data.data.qrCode)
|
||||
if (result.code === 200 && result.data?.qrCode) {
|
||||
setQrCodeData(result.data.qrCode)
|
||||
setIsModalOpen(true)
|
||||
|
||||
// 五秒后开始轮询
|
||||
@@ -211,7 +146,7 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
startPolling();
|
||||
}, 5000);
|
||||
} else {
|
||||
toast.error(data.msg || "获取设备二维码失败")
|
||||
toast.error(result.msg || "获取设备二维码失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
@@ -248,33 +183,11 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
}
|
||||
|
||||
try {
|
||||
const accountId = project.s2_accountId;
|
||||
// 通过URL参数传递accountId
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/devices/add-results?accountId=${accountId}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
const result = await apiRequest(`/devices/add-results?accountId=${project.s2_accountId}`)
|
||||
|
||||
// 检查响应状态和内容类型
|
||||
if (!response.ok) {
|
||||
console.error("轮询请求失败:", response.status, response.statusText);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查内容类型是否为JSON
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
console.error("轮询请求返回的不是JSON格式:", contentType);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.code === 200) {
|
||||
if (result.code === 200) {
|
||||
// 检查是否最后一次轮询且设备未添加
|
||||
if (pollingCountRef.current >= MAX_POLLING_COUNT && !data.added) {
|
||||
if (pollingCountRef.current >= MAX_POLLING_COUNT && !result.data.added) {
|
||||
setPollingStatus("error");
|
||||
setIsQrCodeBroken(true);
|
||||
stopPolling();
|
||||
@@ -282,9 +195,9 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
}
|
||||
|
||||
// 检查设备是否已添加成功
|
||||
if (data.added) {
|
||||
if (result.data.added) {
|
||||
setPollingStatus("success");
|
||||
setAddedDevice(data.device);
|
||||
setAddedDevice(result.data.device);
|
||||
stopPolling();
|
||||
|
||||
// 刷新设备列表
|
||||
@@ -293,7 +206,7 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
}
|
||||
} else {
|
||||
// 请求失败但继续轮询
|
||||
console.error("轮询请求失败:", data.msg);
|
||||
console.error("轮询请求失败:", result.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("轮询请求出错:", error);
|
||||
@@ -304,27 +217,12 @@ export default function EditProjectPage({ params }: { params: { id: string } })
|
||||
// 刷新项目数据的方法
|
||||
const refreshProjectData = async () => {
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/detail/${id}`)
|
||||
const result = await apiRequest(`/company/detail/${id}`)
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
toast.error(`刷新失败: ${response.status} ${response.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查内容类型是否为JSON
|
||||
const contentType = response.headers.get("content-type");
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
toast.error("服务器返回了非JSON格式的数据");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
setProject(data.data)
|
||||
if (result.code === 200) {
|
||||
setProject(result.data)
|
||||
} else {
|
||||
toast.error(data.msg || "刷新项目信息失败")
|
||||
toast.error(result.msg || "刷新项目信息失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
|
||||
@@ -13,6 +13,7 @@ import { toast } from "sonner"
|
||||
import { use } from "react"
|
||||
import Image from "next/image"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { apiRequest } from '@/lib/api-utils'
|
||||
|
||||
interface ProjectProfile {
|
||||
id: number
|
||||
@@ -69,75 +70,68 @@ export default function ProjectDetailPage({ params }: ProjectDetailPageProps) {
|
||||
const [subUsers, setSubUsers] = useState<SubUser[]>([])
|
||||
const [activeTab, setActiveTab] = useState("overview")
|
||||
|
||||
useEffect(() => {
|
||||
const fetchProjectProfile = async () => {
|
||||
const fetchProject = async () => {
|
||||
try {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/profile/${id}`)
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
setProfile(data.data)
|
||||
} else {
|
||||
toast.error(data.msg || "获取项目信息失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
const result = await apiRequest(`/company/profile/${id}`)
|
||||
if (result.code === 200 && result.data) {
|
||||
setProfile(result.data)
|
||||
} else {
|
||||
toast.error(result.msg || "获取项目信息失败")
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取项目信息失败:", error)
|
||||
toast.error("网络错误,请稍后再试")
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fetchProjectProfile()
|
||||
useEffect(() => {
|
||||
fetchProject()
|
||||
}, [id])
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDevices = async () => {
|
||||
if (activeTab === "devices") {
|
||||
setIsDevicesLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/devices?companyId=${id}`)
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
setDevices(data.data)
|
||||
} else {
|
||||
toast.error(data.msg || "获取设备列表失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
} finally {
|
||||
setIsDevicesLoading(false)
|
||||
}
|
||||
const fetchDevices = async () => {
|
||||
try {
|
||||
setIsDevicesLoading(true)
|
||||
const result = await apiRequest(`/company/devices?companyId=${id}`)
|
||||
if (result.code === 200 && result.data) {
|
||||
setDevices(result.data)
|
||||
} else {
|
||||
toast.error(result.msg || "获取设备列表失败")
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取设备列表失败:", error)
|
||||
toast.error("网络错误,请稍后再试")
|
||||
} finally {
|
||||
setIsDevicesLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchDevices()
|
||||
}, [activeTab, id])
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSubUsers = async () => {
|
||||
if (activeTab === "accounts") {
|
||||
setIsSubUsersLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/subusers?companyId=${id}`)
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
setSubUsers(data.data)
|
||||
} else {
|
||||
toast.error(data.msg || "获取子账号列表失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
} finally {
|
||||
setIsSubUsersLoading(false)
|
||||
setIsSubUsersLoading(true)
|
||||
try {
|
||||
const result = await apiRequest(`/company/subusers?companyId=${id}`)
|
||||
|
||||
if (result.code === 200) {
|
||||
setSubUsers(result.data)
|
||||
} else {
|
||||
toast.error(result.msg || "获取子账号列表失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
} finally {
|
||||
setIsSubUsersLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fetchSubUsers()
|
||||
}, [activeTab, id])
|
||||
}, [id])
|
||||
|
||||
if (isLoading) {
|
||||
return <div className="flex items-center justify-center min-h-screen">加载中...</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
import { toast, Toaster } from "sonner"
|
||||
import { apiRequest } from "@/lib/api-utils"
|
||||
|
||||
export default function NewProjectPage() {
|
||||
const router = useRouter()
|
||||
@@ -53,29 +54,21 @@ export default function NewProjectPage() {
|
||||
setIsSubmitting(true)
|
||||
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/add`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: formData.name,
|
||||
account: formData.account,
|
||||
password: formData.password,
|
||||
memo: formData.description,
|
||||
phone: formData.phone,
|
||||
username: formData.nickname,
|
||||
status: parseInt(formData.status),
|
||||
}),
|
||||
const result = await apiRequest('/company/add', 'POST', {
|
||||
name: formData.name,
|
||||
account: formData.account,
|
||||
password: formData.password,
|
||||
memo: formData.description,
|
||||
phone: formData.phone,
|
||||
username: formData.nickname,
|
||||
status: parseInt(formData.status),
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
toast.success("创建成功")
|
||||
if (result.code === 200) {
|
||||
toast.success("项目创建成功")
|
||||
router.push("/dashboard/projects")
|
||||
} else {
|
||||
toast.error(data.msg)
|
||||
toast.error(result.msg || "创建失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { PaginationControls } from "@/components/ui/pagination-controls"
|
||||
import { useTabContext } from "@/app/dashboard/layout"
|
||||
import { apiRequest } from "@/lib/api-utils"
|
||||
|
||||
interface Project {
|
||||
id: number
|
||||
@@ -73,15 +74,14 @@ export default function ProjectsPage() {
|
||||
const fetchProjects = async () => {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/list?page=${currentPage}&limit=${pageSize}`)
|
||||
const data = await response.json()
|
||||
const result = await apiRequest(`/company/list?page=${currentPage}&limit=${pageSize}`)
|
||||
|
||||
if (data.code === 200) {
|
||||
setProjects(data.data.list)
|
||||
setTotalItems(data.data.total)
|
||||
setTotalPages(Math.ceil(data.data.total / pageSize))
|
||||
if (result.code === 200) {
|
||||
setProjects(result.data.list)
|
||||
setTotalItems(result.data.total)
|
||||
setTotalPages(Math.ceil(result.data.total / pageSize))
|
||||
} else {
|
||||
toast.error(data.msg || "获取项目列表失败")
|
||||
toast.error(result.msg || "获取项目列表失败")
|
||||
setProjects([])
|
||||
setTotalItems(0)
|
||||
setTotalPages(0)
|
||||
@@ -124,33 +124,24 @@ export default function ProjectsPage() {
|
||||
|
||||
setIsDeleting(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/delete`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: deletingProjectId
|
||||
}),
|
||||
const result = await apiRequest('/company/delete', 'POST', {
|
||||
id: deletingProjectId
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.code === 200) {
|
||||
if (result.code === 200) {
|
||||
toast.success("删除成功")
|
||||
|
||||
// Fetch projects again after delete
|
||||
const fetchProjects = async () => {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/company/list?page=${currentPage}&limit=${pageSize}`)
|
||||
const data = await response.json()
|
||||
if (data.code === 200) {
|
||||
setProjects(data.data.list)
|
||||
setTotalItems(data.data.total)
|
||||
setTotalPages(Math.ceil(data.data.total / pageSize))
|
||||
if (currentPage > Math.ceil(data.data.total / pageSize) && Math.ceil(data.data.total / pageSize) > 0) {
|
||||
setCurrentPage(Math.ceil(data.data.total / pageSize));
|
||||
const result = await apiRequest(`/company/list?page=${currentPage}&limit=${pageSize}`)
|
||||
if (result.code === 200) {
|
||||
setProjects(result.data.list)
|
||||
setTotalItems(result.data.total)
|
||||
setTotalPages(Math.ceil(result.data.total / pageSize))
|
||||
if (currentPage > Math.ceil(result.data.total / pageSize) && Math.ceil(result.data.total / pageSize) > 0) {
|
||||
setCurrentPage(Math.ceil(result.data.total / pageSize));
|
||||
}
|
||||
} else {
|
||||
setProjects([]); setTotalItems(0); setTotalPages(0);
|
||||
@@ -160,7 +151,7 @@ export default function ProjectsPage() {
|
||||
}
|
||||
fetchProjects();
|
||||
} else {
|
||||
toast.error(data.msg || "删除失败")
|
||||
toast.error(result.msg || "删除失败")
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("网络错误,请稍后重试")
|
||||
|
||||
Reference in New Issue
Block a user