style: 美化用户隧道权限分配表单UI并统一代码格式

- 使用HeroUI Checkbox组件替换原生checkbox

- 重构隧道列表为card-based tile风格

- 添加选中/未选中/已分配状态视觉区分

- 应用eslint --fix代码格式统一

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
root
2026-02-04 02:22:28 +00:00
parent 72c2e28667
commit 6f6fececa8
31 changed files with 8080 additions and 5740 deletions
+67 -33
View File
@@ -1,4 +1,4 @@
import Network from './network';
import Network from "./network";
// 登陆相关接口
export interface LoginData {
@@ -14,11 +14,13 @@ export interface LoginResponse {
requirePasswordChange?: boolean;
}
export const login = (data: LoginData) => Network.post<LoginResponse>("/user/login", data);
export const login = (data: LoginData) =>
Network.post<LoginResponse>("/user/login", data);
// 用户CRUD操作 - 全部使用POST请求
export const createUser = (data: any) => Network.post("/user/create", data);
export const getAllUsers = (pageData: any = {}) => Network.post("/user/list", pageData);
export const getAllUsers = (pageData: any = {}) =>
Network.post("/user/list", pageData);
export const updateUser = (data: any) => Network.post("/user/update", data);
export const deleteUser = (id: number) => Network.post("/user/delete", { id });
export const getUserPackageInfo = () => Network.post("/user/package");
@@ -28,68 +30,100 @@ export const createNode = (data: any) => Network.post("/node/create", data);
export const getNodeList = () => Network.post("/node/list");
export const updateNode = (data: any) => Network.post("/node/update", data);
export const deleteNode = (id: number) => Network.post("/node/delete", { id });
export const getNodeInstallCommand = (id: number) => Network.post("/node/install", { id });
export const updateNodeOrder = (data: { nodes: Array<{ id: number; inx: number }> }) => Network.post("/node/update-order", data);
export const getNodeInstallCommand = (id: number) =>
Network.post("/node/install", { id });
export const updateNodeOrder = (data: {
nodes: Array<{ id: number; inx: number }>;
}) => Network.post("/node/update-order", data);
export const checkNodeStatus = (nodeId?: number) => {
const params = nodeId ? { nodeId } : {};
return Network.post("/node/check-status", params);
};
// 隧道CRUD操作 - 全部使用POST请求
export const createTunnel = (data: any) => Network.post("/tunnel/create", data);
export const getTunnelList = () => Network.post("/tunnel/list");
export const getTunnelById = (id: number) => Network.post("/tunnel/get", { id });
export const getTunnelById = (id: number) =>
Network.post("/tunnel/get", { id });
export const updateTunnel = (data: any) => Network.post("/tunnel/update", data);
export const deleteTunnel = (id: number) => Network.post("/tunnel/delete", { id });
export const diagnoseTunnel = (tunnelId: number) => Network.post("/tunnel/diagnose", { tunnelId });
export const updateTunnelOrder = (data: { tunnels: Array<{ id: number; inx: number }> }) => Network.post("/tunnel/update-order", data);
export const deleteTunnel = (id: number) =>
Network.post("/tunnel/delete", { id });
export const diagnoseTunnel = (tunnelId: number) =>
Network.post("/tunnel/diagnose", { tunnelId });
export const updateTunnelOrder = (data: {
tunnels: Array<{ id: number; inx: number }>;
}) => Network.post("/tunnel/update-order", data);
// 用户隧道权限管理操作 - 全部使用POST请求
export const assignUserTunnel = (data: any) => Network.post("/tunnel/user/assign", data);
export const batchAssignUserTunnel = (data: { userId: number; tunnels: Array<{ tunnelId: number; speedId?: number | null }> }) =>
Network.post("/tunnel/user/batch-assign", data);
export const getUserTunnelList = (queryData: any = {}) => Network.post("/tunnel/user/list", queryData);
export const removeUserTunnel = (params: any) => Network.post("/tunnel/user/remove", params);
export const updateUserTunnel = (data: any) => Network.post("/tunnel/user/update", data);
export const assignUserTunnel = (data: any) =>
Network.post("/tunnel/user/assign", data);
export const batchAssignUserTunnel = (data: {
userId: number;
tunnels: Array<{ tunnelId: number; speedId?: number | null }>;
}) => Network.post("/tunnel/user/batch-assign", data);
export const getUserTunnelList = (queryData: any = {}) =>
Network.post("/tunnel/user/list", queryData);
export const removeUserTunnel = (params: any) =>
Network.post("/tunnel/user/remove", params);
export const updateUserTunnel = (data: any) =>
Network.post("/tunnel/user/update", data);
export const userTunnel = () => Network.post("/tunnel/user/tunnel");
// 转发CRUD操作 - 全部使用POST请求
export const createForward = (data: any) => Network.post("/forward/create", data);
export const createForward = (data: any) =>
Network.post("/forward/create", data);
export const getForwardList = () => Network.post("/forward/list");
export const updateForward = (data: any) => Network.post("/forward/update", data);
export const deleteForward = (id: number) => Network.post("/forward/delete", { id });
export const forceDeleteForward = (id: number) => Network.post("/forward/force-delete", { id });
export const updateForward = (data: any) =>
Network.post("/forward/update", data);
export const deleteForward = (id: number) =>
Network.post("/forward/delete", { id });
export const forceDeleteForward = (id: number) =>
Network.post("/forward/force-delete", { id });
// 转发服务控制操作 - 通过Java后端接口
export const pauseForwardService = (forwardId: number) => Network.post("/forward/pause", { id: forwardId });
export const resumeForwardService = (forwardId: number) => Network.post("/forward/resume", { id: forwardId });
export const pauseForwardService = (forwardId: number) =>
Network.post("/forward/pause", { id: forwardId });
export const resumeForwardService = (forwardId: number) =>
Network.post("/forward/resume", { id: forwardId });
// 转发诊断操作
export const diagnoseForward = (forwardId: number) => Network.post("/forward/diagnose", { forwardId });
export const diagnoseForward = (forwardId: number) =>
Network.post("/forward/diagnose", { forwardId });
// 转发排序操作
export const updateForwardOrder = (data: { forwards: Array<{ id: number; inx: number }> }) => Network.post("/forward/update-order", data);
export const updateForwardOrder = (data: {
forwards: Array<{ id: number; inx: number }>;
}) => Network.post("/forward/update-order", data);
// 限速规则CRUD操作 - 全部使用POST请求
export const createSpeedLimit = (data: any) => Network.post("/speed-limit/create", data);
export const createSpeedLimit = (data: any) =>
Network.post("/speed-limit/create", data);
export const getSpeedLimitList = () => Network.post("/speed-limit/list");
export const updateSpeedLimit = (data: any) => Network.post("/speed-limit/update", data);
export const deleteSpeedLimit = (id: number) => Network.post("/speed-limit/delete", { id });
export const updateSpeedLimit = (data: any) =>
Network.post("/speed-limit/update", data);
export const deleteSpeedLimit = (id: number) =>
Network.post("/speed-limit/delete", { id });
// 修改密码接口
export const updatePassword = (data: any) => Network.post("/user/updatePassword", data);
export const updatePassword = (data: any) =>
Network.post("/user/updatePassword", data);
// 重置流量接口
export const resetUserFlow = (data: { id: number; type: number }) => Network.post("/user/reset", data);
export const resetUserFlow = (data: { id: number; type: number }) =>
Network.post("/user/reset", data);
// 网站配置相关接口
export const getConfigs = () => Network.post("/config/list");
export const getConfigByName = (name: string) => Network.post("/config/get", { name });
export const updateConfigs = (configMap: Record<string, string>) => Network.post("/config/update", configMap);
export const updateConfig = (name: string, value: string) => Network.post("/config/update-single", { name, value });
export const getConfigByName = (name: string) =>
Network.post("/config/get", { name });
export const updateConfigs = (configMap: Record<string, string>) =>
Network.post("/config/update", configMap);
export const updateConfig = (name: string, value: string) =>
Network.post("/config/update-single", { name, value });
// 验证码相关接口
export const checkCaptcha = () => Network.post("/captcha/check");
export const generateCaptcha = () => Network.post(`/captcha/generate`);
export const verifyCaptcha = (data: { captchaId: string; trackData: string }) => Network.post("/captcha/verify", data);
export const verifyCaptcha = (data: { captchaId: string; trackData: string }) =>
Network.post("/captcha/verify", data);
+96 -70
View File
@@ -1,41 +1,42 @@
import axios, { AxiosResponse } from 'axios';
import { getPanelAddresses, isWebViewFunc} from '@/utils/panel';
import axios, { AxiosResponse } from "axios";
import { getPanelAddresses, isWebViewFunc } from "@/utils/panel";
interface PanelAddress {
name: string;
address: string;
address: string;
inx: boolean;
}
const setPanelAddressesFunc = (newAddress: PanelAddress[]) => {
newAddress.forEach(item => {
newAddress.forEach((item) => {
if (item.inx) {
baseURL = `${item.address}/api/v1/`;
axios.defaults.baseURL = baseURL;
}
});
}
function getWebViewPanelAddress() {
(window as any).setAddresses = setPanelAddressesFunc
getPanelAddresses("setAddresses");
};
let baseURL: string = '';
function getWebViewPanelAddress() {
(window as any).setAddresses = setPanelAddressesFunc;
getPanelAddresses("setAddresses");
}
let baseURL: string = "";
export const reinitializeBaseURL = () => {
if (isWebViewFunc()) {
getWebViewPanelAddress();
} else {
baseURL = import.meta.env.VITE_API_BASE ? `${import.meta.env.VITE_API_BASE}/api/v1/` : '/api/v1/';
baseURL = import.meta.env.VITE_API_BASE
? `${import.meta.env.VITE_API_BASE}/api/v1/`
: "/api/v1/";
axios.defaults.baseURL = baseURL;
}
};
reinitializeBaseURL();
interface ApiResponse<T = any> {
code: number;
msg: string;
@@ -45,98 +46,123 @@ interface ApiResponse<T = any> {
// 处理token失效的逻辑
function handleTokenExpired() {
// 清除localStorage中的token
window.localStorage.removeItem('token');
window.localStorage.removeItem('role_id');
window.localStorage.removeItem('name');
window.localStorage.removeItem("token");
window.localStorage.removeItem("role_id");
window.localStorage.removeItem("name");
// 跳转到登录页面
if (window.location.pathname !== '/') {
window.location.href = '/';
if (window.location.pathname !== "/") {
window.location.href = "/";
}
}
// 检查响应是否为token失效
function isTokenExpired(response: ApiResponse) {
return response && response.code === 401 &&
(response.msg === '未登录或token已过期' ||
response.msg === '无效的token或token已过期' ||
response.msg === '无法获取用户权限信息');
return (
response &&
response.code === 401 &&
(response.msg === "未登录或token已过期" ||
response.msg === "无效的token或token已过期" ||
response.msg === "无法获取用户权限信息")
);
}
const Network = {
get: function<T = any>(path: string = '', data: any = {}): Promise<ApiResponse<T>> {
return new Promise(function(resolve) {
get: function <T = any>(
path: string = "",
data: any = {},
): Promise<ApiResponse<T>> {
return new Promise(function (resolve) {
// 如果baseURL是默认值且是WebView环境,说明没有设置面板地址
if (baseURL === '') {
resolve({"code": -1, "msg": " - 请先设置面板地址", "data": null as T});
if (baseURL === "") {
resolve({ code: -1, msg: " - 请先设置面板地址", data: null as T });
return;
}
axios.get(path, {
params: data,
timeout: 30000,
headers: {
"Authorization": window.localStorage.getItem('token')
}
})
.then(function(response: AxiosResponse<ApiResponse<T>>) {
axios
.get(path, {
params: data,
timeout: 30000,
headers: {
Authorization: window.localStorage.getItem("token"),
},
})
.then(function (response: AxiosResponse<ApiResponse<T>>) {
// 检查是否token失效
if (isTokenExpired(response.data)) {
handleTokenExpired();
return;
}
resolve(response.data);
})
.catch(function(error: any) {
console.error('GET请求错误:', error);
// 检查是否是401错误(token失效)
if (error.response && error.response.status === 401) {
handleTokenExpired();
return;
}
resolve({"code": -1, "msg": error.message || "网络请求失败", "data": null as T});
});
.catch(function (error: any) {
console.error("GET请求错误:", error);
// 检查是否是401错误(token失效)
if (error.response && error.response.status === 401) {
handleTokenExpired();
return;
}
resolve({
code: -1,
msg: error.message || "网络请求失败",
data: null as T,
});
});
});
},
post: function<T = any>(path: string = '', data: any = {}): Promise<ApiResponse<T>> {
return new Promise(function(resolve) {
post: function <T = any>(
path: string = "",
data: any = {},
): Promise<ApiResponse<T>> {
return new Promise(function (resolve) {
// 如果baseURL是默认值且是WebView环境,说明没有设置面板地址
if (baseURL === '') {
resolve({"code": -1, "msg": " - 请先设置面板地址", "data": null as T});
if (baseURL === "") {
resolve({ code: -1, msg: " - 请先设置面板地址", data: null as T });
return;
}
axios.post(path, data, {
timeout: 30000,
headers: {
"Authorization": window.localStorage.getItem('token'),
"Content-Type": "application/json"
}
})
.then(function(response: AxiosResponse<ApiResponse<T>>) {
axios
.post(path, data, {
timeout: 30000,
headers: {
Authorization: window.localStorage.getItem("token"),
"Content-Type": "application/json",
},
})
.then(function (response: AxiosResponse<ApiResponse<T>>) {
// 检查是否token失效
if (isTokenExpired(response.data)) {
handleTokenExpired();
return;
}
resolve(response.data);
})
.catch(function(error: any) {
console.error('POST请求错误:', error);
// 检查是否是401错误(token失效)
if (error.response && error.response.status === 401) {
handleTokenExpired();
return;
}
resolve({"code": -1, "msg": error.message || "网络请求失败", "data": null as T});
});
.catch(function (error: any) {
console.error("POST请求错误:", error);
// 检查是否是401错误(token失效)
if (error.response && error.response.status === 401) {
handleTokenExpired();
return;
}
resolve({
code: -1,
msg: error.message || "网络请求失败",
data: null as T,
});
});
});
}
},
};
export default Network;
export default Network;