Skip to content

Commit 76df0ef

Browse files
author
杨纲
committed
fix(frontend): 对齐 apiRequest 调用与类型推断
- apiRequest 默认保留 OpenAPI 返回的 data 类型,减少 resp.data 属性报错 - 统一按 extrax(路径参数数组) 在前、params 在后的调用顺序,修复多处重载不匹配 - 收敛 provider/forward_id 等可选字段类型并补充必要的防御性校验 Made-with: Cursor
1 parent 682a9f5 commit 76df0ef

31 files changed

Lines changed: 248 additions & 171 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { createContext, useContext } from 'react';
2+
import type {
3+
DomainGitIdentity,
4+
DomainHost,
5+
DomainImage,
6+
DomainModel,
7+
DomainProject,
8+
DomainProjectTask,
9+
DomainUser,
10+
DomainVirtualMachine,
11+
} from '@/api/Api';
12+
13+
export type CommonData = {
14+
user: DomainUser;
15+
reloadUser: () => void;
16+
17+
hosts: DomainHost[];
18+
vms: DomainVirtualMachine[];
19+
loadingHosts: boolean;
20+
hostsInited: boolean;
21+
reloadHosts: () => void;
22+
23+
models: DomainModel[];
24+
loadingModels: boolean;
25+
reloadModels: () => void;
26+
27+
images: DomainImage[];
28+
loadingImages: boolean;
29+
reloadImages: () => void;
30+
31+
identities: DomainGitIdentity[];
32+
loadingIdentities: boolean;
33+
reloadIdentities: () => void;
34+
35+
balance: number;
36+
bonus: number;
37+
reloadWallet: () => void;
38+
39+
members: DomainUser[];
40+
loadingMembers: boolean;
41+
reloadMembers: () => void;
42+
43+
projects: DomainProject[];
44+
loadingProjects: boolean;
45+
reloadProjects: () => void;
46+
47+
/** 未关联项目的任务(quick_start),用于侧边栏「默认」分组展示 */
48+
unlinkedTasks: DomainProjectTask[];
49+
loadingUnlinkedTasks: boolean;
50+
reloadUnlinkedTasks: () => void;
51+
};
52+
53+
export const DataContext = createContext<CommonData | null>(null);
54+
55+
export const useCommonData = () => {
56+
const ctx = useContext(DataContext);
57+
if (!ctx) throw new Error('useCommonData must be used within DataProvider');
58+
return ctx;
59+
};

frontend/src/components/console/data-provider.tsx

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,10 @@
1-
import { ConstsGitPlatform, ConstsOwnerType, type DomainGitIdentity, type DomainHost, type DomainImage, type DomainModel, type DomainProject, type DomainProjectTask, type DomainUser, type DomainVirtualMachine } from '@/api/Api';
1+
import { ConstsGitPlatform, ConstsOwnerType, type DomainGitIdentity, type DomainHost, type DomainImage, type DomainModel, type DomainProject, type DomainProjectTask, type DomainUser } from '@/api/Api';
22
import { getImageShortName } from '@/utils/common';
33
import { apiRequest } from '@/utils/requestUtils';
4-
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
4+
import { DataContext } from '@/components/console/common-data';
5+
import React, { useEffect, useMemo, useState } from 'react';
56
import { toast } from 'sonner';
67

7-
type CommonData = {
8-
user: DomainUser;
9-
reloadUser: () => void;
10-
11-
hosts: DomainHost[];
12-
vms: DomainVirtualMachine[];
13-
loadingHosts: boolean;
14-
hostsInited: boolean;
15-
reloadHosts: () => void;
16-
17-
models: DomainModel[];
18-
loadingModels: boolean;
19-
reloadModels: () => void;
20-
21-
images: DomainImage[];
22-
loadingImages: boolean;
23-
reloadImages: () => void;
24-
25-
identities: DomainGitIdentity[];
26-
loadingIdentities: boolean;
27-
reloadIdentities: () => void;
28-
29-
balance: number;
30-
bonus: number;
31-
reloadWallet: () => void;
32-
33-
members: DomainUser[];
34-
loadingMembers: boolean;
35-
reloadMembers: () => void;
36-
37-
projects: DomainProject[];
38-
loadingProjects: boolean;
39-
reloadProjects: () => void;
40-
41-
/** 未关联项目的任务(quick_start),用于侧边栏「默认」分组展示 */
42-
unlinkedTasks: DomainProjectTask[];
43-
loadingUnlinkedTasks: boolean;
44-
reloadUnlinkedTasks: () => void;
45-
};
46-
47-
const DataContext = createContext<CommonData | null>(null);
48-
498
export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
509
const [userInfo, setUserInfo] = useState<DomainUser>({});
5110

@@ -228,8 +187,8 @@ export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children
228187
const fetchWallet = () => {
229188
apiRequest('v1UsersWalletList', {}, [], (resp) => {
230189
if (resp.code === 0) {
231-
setBalance(resp.data?.balance / 1000);
232-
setBonus(resp.data?.bonus / 1000);
190+
setBalance((resp.data?.balance || 0) / 1000);
191+
setBonus((resp.data?.bonus || 0) / 1000);
233192
} else {
234193
toast.error("获取余额失败: " + resp.message);
235194
}
@@ -267,7 +226,7 @@ export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children
267226

268227
const fetchUnlinkedTasks = async () => {
269228
setLoadingUnlinkedTasks(true)
270-
await apiRequest('v1UsersTasksList', { page: 1, size: UNLINKED_TASKS_FETCH_SIZE, quick_start: true }, [], (resp) => {
229+
await apiRequest('v1UsersTasksList', [], { page: 1, size: UNLINKED_TASKS_FETCH_SIZE, quick_start: true }, (resp) => {
271230
if (resp.code === 0) {
272231
const allTasks = resp.data?.tasks || []
273232
const unlinked = allTasks
@@ -334,9 +293,3 @@ export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children
334293
</DataContext.Provider>
335294
);
336295
};
337-
338-
export const useCommonData = () => {
339-
const ctx = useContext(DataContext);
340-
if (!ctx) throw new Error('useCommonData must be used within DataProvider');
341-
return ctx;
342-
};

frontend/src/components/console/git-bot/create-git-bot-dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { toast } from "sonner"
2222
import type { DomainGitBot, DomainHost } from "@/api/Api"
2323
import Icon from "@/components/common/Icon"
2424
import { Badge } from "@/components/ui/badge"
25-
import { useCommonData } from "../data-provider"
25+
import { useCommonData } from "../common-data"
2626
import { getHostBadges } from "@/utils/common"
2727

2828
interface CreateGitBotDialogProps {

frontend/src/components/console/git-bot/edit-git-bot-dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import type { DomainGitBot } from "@/api/Api"
2222
import { ConstsGitPlatform, ConstsHostStatus } from "@/api/Api"
2323
import Icon from "@/components/common/Icon"
2424
import { Badge } from "@/components/ui/badge"
25-
import { useCommonData } from "../data-provider"
25+
import { useCommonData } from "../common-data"
2626
import { getHostBadges } from "@/utils/common"
2727

2828
interface EditGitBotDialogProps {

frontend/src/components/console/git-bot/edit-git-bot-permission-dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { toast } from "sonner"
88
import { IconLoader } from "@tabler/icons-react"
99
import { ChevronDown } from "lucide-react"
1010
import { cn } from "@/lib/utils"
11-
import { useCommonData } from "../data-provider"
11+
import { useCommonData } from "../common-data"
1212

1313
interface EditGitBotPermissionDialogProps {
1414
open: boolean

frontend/src/components/console/nav/nav-balance.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { Item, ItemContent, ItemGroup, ItemTitle } from "@/components/ui/item";
1616
import dayjs from "dayjs";
1717
import { cn } from "@/lib/utils";
1818
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
19-
import { useCommonData } from "../data-provider";
19+
import { useCommonData } from "../common-data";
2020

2121
interface NavBalanceProps {
2222
variant?: "sidebar" | "header";

frontend/src/components/console/nav/nav-project.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1+
import { useEffect, useState } from "react"
12
import { Link, useLocation, useNavigate } from "react-router-dom"
2-
import { useState, useEffect } from "react"
33

4-
import {
5-
SidebarGroup,
6-
SidebarGroupLabel,
7-
SidebarMenu,
8-
SidebarMenuButton,
9-
SidebarMenuItem,
10-
SidebarMenuSub,
11-
SidebarMenuSubButton,
12-
SidebarMenuSubItem,
13-
} from "@/components/ui/sidebar"
4+
import { type DomainProjectTask } from "@/api/Api"
145
import {
156
AlertDialog,
167
AlertDialogAction,
@@ -21,21 +12,30 @@ import {
2112
AlertDialogHeader,
2213
AlertDialogTitle,
2314
} from "@/components/ui/alert-dialog"
15+
import { Button } from "@/components/ui/button"
2416
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
2517
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
26-
import { useCommonData } from "../data-provider"
27-
import { IconChevronDown, IconChevronRight, IconCircleMinus, IconDotsVertical, IconLoader, IconPlus, IconReload, IconTrash } from "@tabler/icons-react"
28-
import { Button } from "@/components/ui/button"
29-
import AddProjectDialog from "../project/add-project"
30-
import StartDevelopTaskDialog from "../project/start-develop-task-dialog"
31-
import { isProjectRepoUnbound } from "@/utils/project"
3218
import { Label } from "@/components/ui/label"
33-
import { type DomainProjectTask } from "@/api/Api"
34-
import { stripMarkdown } from "@/utils/common"
35-
import { cn } from "@/lib/utils"
19+
import {
20+
SidebarGroup,
21+
SidebarGroupLabel,
22+
SidebarMenu,
23+
SidebarMenuButton,
24+
SidebarMenuItem,
25+
SidebarMenuSub,
26+
SidebarMenuSubButton,
27+
SidebarMenuSubItem,
28+
} from "@/components/ui/sidebar"
3629
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
30+
import { cn } from "@/lib/utils"
31+
import { stripMarkdown } from "@/utils/common"
32+
import { isProjectRepoUnbound } from "@/utils/project"
3733
import { apiRequest } from "@/utils/requestUtils"
34+
import { IconChevronDown, IconChevronRight, IconCircleMinus, IconDotsVertical, IconLoader, IconPlus, IconReload, IconTrash } from "@tabler/icons-react"
3835
import { toast } from "sonner"
36+
import { useCommonData } from "../common-data"
37+
import AddProjectDialog from "../project/add-project"
38+
import StartDevelopTaskDialog from "../project/start-develop-task-dialog"
3939

4040
const STORAGE_KEY = "nav-project-expanded"
4141
const UNLINKED_KEY = "__unlinked__"

frontend/src/components/console/nav/nav-user.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { Spinner } from "@/components/ui/spinner"
4747
import { Button } from "@/components/ui/button"
4848
import { toast } from "sonner"
4949
import { IconLockCode, IconLogout, IconUserHexagon, IconUpload } from "@tabler/icons-react"
50-
import { useCommonData } from "@/components/console/data-provider"
50+
import { useCommonData } from "@/components/console/common-data"
5151

5252
export default function NavUser() {
5353
const { isMobile } = useSidebar()
@@ -69,7 +69,7 @@ export default function NavUser() {
6969

7070
const handleLogout = () => {
7171
apiRequest('v1UsersLogoutCreate', {}, [], (resp) => {
72-
if (resp.code === 0) {
72+
if (Number(resp.code) === 0) {
7373
navigate('/');
7474
} else {
7575
toast.error('登出失败: ' + resp.message);
@@ -91,11 +91,10 @@ export default function NavUser() {
9191
}
9292

9393
setChangingPassword(true);
94-
await apiRequest('v1UsersPasswordsChangeUpdate', {
94+
await apiRequest('v1UsersPasswordsChangeUpdate', [], {
9595
current_password: currentPassword,
9696
new_password: newPassword,
97-
confirm_password: confirmPassword,
98-
}, [], (resp) => {
97+
}, (resp) => {
9998
if (resp?.code === 0) {
10099
toast.success('密码修改成功');
101100
setShowChangePasswordDialog(false);

frontend/src/components/console/project/add-project.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { useNavigate } from "react-router-dom"
3838
import { useSettingsDialog } from "@/pages/console/user/page"
3939
import { toast } from "sonner"
4040
import { Spinner } from "@/components/ui/spinner"
41-
import { useCommonData } from "@/components/console/data-provider"
41+
import { useCommonData } from "@/components/console/common-data"
4242

4343
interface RepoOption {
4444
gitIdentityId: string

frontend/src/components/console/project/edit-project-image.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "
33
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
44
import type { DomainImage, DomainProject } from "@/api/Api"
55
import Icon from "@/components/common/Icon"
6-
import { useCommonData } from "@/components/console/data-provider"
6+
import { useCommonData } from "@/components/console/common-data"
77
import { apiRequest } from "@/utils/requestUtils"
88
import { getImageShortName, getOSFromImageName } from "@/utils/common"
99
import { useEffect, useState } from "react"

0 commit comments

Comments
 (0)