This commit is contained in:
parent
a93f476e46
commit
8e0b0ed369
|
|
@ -1,7 +1,6 @@
|
||||||
import { Container } from "@/components/landing/container";
|
import { Container } from "@/components/landing/container";
|
||||||
import { FadeIn } from "@/components/landing/fade-in";
|
import { FadeIn } from "@/components/landing/fade-in";
|
||||||
import { MdxContent } from "@/components/landing/mdx-content";
|
import { MdxContent } from "@/components/landing/mdx-content";
|
||||||
// import { PageLinks } from "@/components/landing/page-links";
|
|
||||||
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||||
import { authors } from "@/content/blog/authors";
|
import { authors } from "@/content/blog/authors";
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ export default async function RootLayout({
|
||||||
resources={resources}>
|
resources={resources}>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<Providers attribute="class" defaultTheme="system" enableSystem>
|
<Providers attribute="class" defaultTheme="system" enableSystem>
|
||||||
<ConsoleSilencer />
|
{/* <ConsoleSilencer /> */}
|
||||||
<div className="flex min-h-screen flex-col">
|
<div className="flex min-h-screen flex-col">
|
||||||
<main className="flex flex-1 flex-col bg-muted/0.3">
|
<main className="flex flex-1 flex-col bg-muted/0.3">
|
||||||
{/* <Header /> */}
|
{/* <Header /> */}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,15 @@
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
export function ConsoleSilencer() {
|
export function ConsoleSilencer() {
|
||||||
|
if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {
|
||||||
|
// 全局替换 console 方法(同步执行)
|
||||||
|
console.log = () => {}
|
||||||
|
console.debug = () => {}
|
||||||
|
console.info = () => {}
|
||||||
|
console.warn = () => {}
|
||||||
|
console.error = () => {}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
console.log = () => {};
|
console.log = () => {};
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import Image from 'next/image';
|
||||||
import logoImage from '@/components/images/logo.png';
|
import logoImage from '@/components/images/logo.png';
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
// import { Button } from './ui/button'
|
|
||||||
import { Flex, Text } from '@radix-ui/themes';
|
import { Flex, Text } from '@radix-ui/themes';
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
@ -43,8 +42,6 @@ import { Trash2 } from "lucide-react";
|
||||||
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
// import { getRuntimeEnv } from "@/lib/ipconfig";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BadgeInfo,
|
BadgeInfo,
|
||||||
Tags,
|
Tags,
|
||||||
|
|
@ -74,7 +71,7 @@ export function Header() {
|
||||||
const soonFunc = () => {
|
const soonFunc = () => {
|
||||||
message.info(t("soon"))
|
message.info(t("soon"))
|
||||||
}
|
}
|
||||||
//w-11/12 sm:w-5/6 md:w-3/4 lg:w-2/3 xl:w-3/5 2xl:w-1/2
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 flex shrink-0 items-center justify-between bg-background px-4 py-[1.5rem] w-[80%] mx-auto">
|
<header className="sticky top-0 z-50 flex shrink-0 items-center justify-between bg-background px-4 py-[1.5rem] w-[80%] mx-auto">
|
||||||
|
|
||||||
|
|
@ -117,63 +114,6 @@ export function Header() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// export async function getWsBase() {
|
|
||||||
// let ip = await getRuntimeEnv("SUPABASE_URL");
|
|
||||||
// if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 wsBase");
|
|
||||||
|
|
||||||
// // 判断协议
|
|
||||||
// let wsProtocol = "ws";
|
|
||||||
// if (
|
|
||||||
// typeof window !== "undefined" &&
|
|
||||||
// window.location &&
|
|
||||||
// window.location.protocol === "https:"
|
|
||||||
// ) {
|
|
||||||
// wsProtocol = "wss";
|
|
||||||
// // ✅ HTTPS + 浏览器环境下用 hostname 避免 TLS 报错
|
|
||||||
// ip = window.location.hostname;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 拼接最终 ws 地址
|
|
||||||
// return `${wsProtocol}://${ip}/api/v1/deploy/ws`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// import { getRuntimeEnv } from "@/lib/ipconfig";
|
|
||||||
// //import { headers } from "next/headers";
|
|
||||||
|
|
||||||
// export async function getWsBase() {
|
|
||||||
// let ip = await getRuntimeEnv("SUPABASE_URL");
|
|
||||||
// if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 wsBase");
|
|
||||||
|
|
||||||
// let wsProtocol = "ws";
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// typeof window !== "undefined" &&
|
|
||||||
// window.location &&
|
|
||||||
// window.location.protocol === "https:"
|
|
||||||
// ) {
|
|
||||||
// wsProtocol = "wss";
|
|
||||||
// ip = window.location.hostname; // ✅ 浏览器下安全替换为域名
|
|
||||||
// } else {
|
|
||||||
// // ✅ SSR 场景
|
|
||||||
// const hdrs = headers();
|
|
||||||
// const forwardedProto = hdrs.get("x-forwarded-proto");
|
|
||||||
// const hostHeader = hdrs.get("host");
|
|
||||||
|
|
||||||
// if (forwardedProto === "https") {
|
|
||||||
// wsProtocol = "wss";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (hostHeader) {
|
|
||||||
// ip = hostHeader.includes(":") ? hostHeader.split(":")[0] : hostHeader;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 拼接最终 ws 地址
|
|
||||||
// return `${wsProtocol}://${ip}/api/v1/deploy/ws`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
import { getRuntimeEnv } from "@/lib/ipconfig";
|
import { getRuntimeEnv } from "@/lib/ipconfig";
|
||||||
|
|
||||||
export async function getWsBase() {
|
export async function getWsBase() {
|
||||||
|
|
@ -222,6 +162,10 @@ export function DetailPageHeader({ data }: { data: any }) {
|
||||||
const [hasWSConnected, setHasWSConnected] = useState(false);
|
const [hasWSConnected, setHasWSConnected] = useState(false);
|
||||||
const [statusLoaded, setStatusLoaded] = useState(false);
|
const [statusLoaded, setStatusLoaded] = useState(false);
|
||||||
const [canDeploy, setCanDeploy] = useState(true);
|
const [canDeploy, setCanDeploy] = useState(true);
|
||||||
|
|
||||||
|
const [currentStatus, setCurrentStatus] = useState(""); // 当前部署状态:running / stopped
|
||||||
|
const [switchLoading, setSwitchLoading] = useState(false); // 控制按钮 loading 状态
|
||||||
|
|
||||||
const socketRef = useRef<WebSocket | null>(null);
|
const socketRef = useRef<WebSocket | null>(null);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
@ -388,6 +332,7 @@ export function DetailPageHeader({ data }: { data: any }) {
|
||||||
|
|
||||||
const code = result?.header?.code;
|
const code = result?.header?.code;
|
||||||
const status = result?.data?.data?.status;
|
const status = result?.data?.data?.status;
|
||||||
|
setCurrentStatus(status || ""); //...............................................
|
||||||
const userData = JSON.parse(localStorage.getItem("UserData") || "null");
|
const userData = JSON.parse(localStorage.getItem("UserData") || "null");
|
||||||
const userName = userData?.user_name;
|
const userName = userData?.user_name;
|
||||||
const id = data?.id;
|
const id = data?.id;
|
||||||
|
|
@ -436,79 +381,49 @@ export function DetailPageHeader({ data }: { data: any }) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleSwitchStatus = async () => {
|
||||||
|
if (!data?.id) return;
|
||||||
|
|
||||||
|
setSwitchLoading(true);
|
||||||
|
const userData = JSON.parse(localStorage.getItem("UserData") || "null");
|
||||||
|
const userName = userData?.user_name;
|
||||||
|
|
||||||
|
if (!userName) {
|
||||||
|
setStatusText("未登录,跳转中...");
|
||||||
|
window.location.href = "/auth/sign-in/";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endpoint = currentStatus === "running" ? "/api/v1/deploy/stop" : "/api/v1/deploy/start";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ user_name: userName, id: data.id }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await res.json();
|
||||||
|
if (json?.header?.code === 0) {
|
||||||
|
setStatusText(currentStatus === "running" ? "已停止" : "已启动");
|
||||||
|
fetchDeployStatus(); // ✅ 状态切换成功后刷新
|
||||||
|
} else {
|
||||||
|
setStatusText(json?.header?.message || "操作失败(后端)");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("切换请求失败:", err);
|
||||||
|
setStatusText("网络异常");
|
||||||
|
} finally {
|
||||||
|
setSwitchLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchDeployStatus();
|
fetchDeployStatus();
|
||||||
}, [data?.id]);
|
}, [data?.id]);
|
||||||
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// const fetchDeployStatus = async () => {
|
|
||||||
// try {
|
|
||||||
// const result = await fetch("/api/v1/deploy/status", {
|
|
||||||
// method: "POST",
|
|
||||||
// headers: { "Content-Type": "application/json" },
|
|
||||||
// body: JSON.stringify({ id: data?.id }),
|
|
||||||
// }).then((res) => res.json());
|
|
||||||
|
|
||||||
// console.log("====> deploy status result:", result);
|
|
||||||
// setStatusLoaded(true);
|
|
||||||
|
|
||||||
// if (!result) {
|
|
||||||
// setStatusText("接口响应为空");
|
|
||||||
// setShowDelete(false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const code = result?.header?.code;
|
|
||||||
// const status = result?.data?.data?.status;
|
|
||||||
// const userData = JSON.parse(localStorage.getItem("UserData") || "null");
|
|
||||||
// const userName = userData?.user_name;
|
|
||||||
// const id = data?.id;
|
|
||||||
|
|
||||||
// console.log("🟡 状态码 code =", code, "状态 status =", status);
|
|
||||||
|
|
||||||
// if (code === 1006) {
|
|
||||||
// setStatusText("尚未部署");
|
|
||||||
// setShowDelete(false);
|
|
||||||
// setProgress("0%");
|
|
||||||
// setShowProgressBar(false)
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (status === "deploying" && userName && id && !hasWSConnected) {
|
|
||||||
// setStatusText("检测到正在部署,连接中...");
|
|
||||||
// initWebSocket(userName, id);
|
|
||||||
// setShowProgressBar(true)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (status === "running" || status === "stopped") {
|
|
||||||
// console.log("✅ 允许删除(status =", status, ")");
|
|
||||||
// setShowDelete(true);
|
|
||||||
// setProgress("100%");
|
|
||||||
// setShowProgressBar(true)
|
|
||||||
|
|
||||||
// if (status === "running") {
|
|
||||||
// setStatusText("运行中");
|
|
||||||
// setProgressBarColor("bg-green-500");
|
|
||||||
// } else if (status === "stopped") {
|
|
||||||
// setStatusText("已停止");
|
|
||||||
// setProgressBarColor("bg-gray-400");
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// console.log("❌ 不允许删除(status =", status, ")");
|
|
||||||
// setShowDelete(false);
|
|
||||||
// setProgressBarColor("bg-blue-500"); // 回到默认蓝色
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error("获取状态失败:", err);
|
|
||||||
// setStatusText("状态拉取失败");
|
|
||||||
// setShowDelete(false);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// fetchDeployStatus();
|
|
||||||
// }, [data?.id]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (socketRef.current) {
|
if (socketRef.current) {
|
||||||
|
|
@ -563,6 +478,24 @@ export function DetailPageHeader({ data }: { data: any }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{statusLoaded && (currentStatus === "running" || currentStatus === "stopped") && (
|
||||||
|
<button
|
||||||
|
onClick={handleSwitchStatus}
|
||||||
|
disabled={switchLoading || loading}
|
||||||
|
className="hover:text-gray-700 transition self-end mr-2 text-sm border border-gray-300 rounded px-2 py-1 bg-white"
|
||||||
|
title={currentStatus === "running" ? "停止运行" : "启动运行"}
|
||||||
|
>
|
||||||
|
{switchLoading
|
||||||
|
? "处理中..."
|
||||||
|
: currentStatus === "running"
|
||||||
|
? "⏹ 停止"
|
||||||
|
: "▶️ 启动"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{statusLoaded && showDelete && (
|
{statusLoaded && showDelete && (
|
||||||
<button
|
<button
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,5 @@
|
||||||
// import { getRuntimeEnv } from "@/lib/ipconfig";
|
|
||||||
|
|
||||||
// export async function getBaseUrl() {
|
|
||||||
// let ip = await getRuntimeEnv("SUPABASE_URL");
|
|
||||||
// if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 baseUrl");
|
|
||||||
|
|
||||||
// let protocol = "http";
|
|
||||||
// if (
|
|
||||||
// typeof window !== "undefined" &&
|
|
||||||
// window.location &&
|
|
||||||
// window.location.protocol === "https:"
|
|
||||||
// ) {
|
|
||||||
// protocol = "https";
|
|
||||||
// ip = window.location.hostname;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return `${protocol}://${ip}`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// import { getRuntimeEnv } from "@/lib/ipconfig";
|
|
||||||
// import { headers } from 'next/headers'
|
|
||||||
|
|
||||||
// export async function getBaseUrl() {
|
|
||||||
// let ip = await getRuntimeEnv("SUPABASE_URL");
|
|
||||||
// if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 baseUrl");
|
|
||||||
|
|
||||||
// let protocol = "http";
|
|
||||||
// let port = 80;
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// typeof window !== "undefined" &&
|
|
||||||
// window.location &&
|
|
||||||
// window.location.protocol === "https:"
|
|
||||||
// ) {
|
|
||||||
// protocol = "https";
|
|
||||||
// ip = window.location.hostname;
|
|
||||||
// port = 443;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return `${protocol}://${ip}:${port}`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
import { getRuntimeEnv } from "@/lib/ipconfig";
|
import { getRuntimeEnv } from "@/lib/ipconfig";
|
||||||
|
|
||||||
|
|
||||||
// export async function getBaseUrl() {
|
|
||||||
// let ip = await getRuntimeEnv("SUPABASE_URL");
|
|
||||||
// if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 baseUrl");
|
|
||||||
|
|
||||||
// let protocol = "http";
|
|
||||||
// let port = 80;
|
|
||||||
|
|
||||||
// if (typeof window !== "undefined") {
|
|
||||||
// // ✅ CSR 模式
|
|
||||||
// if (window.location.protocol === "https:") {
|
|
||||||
// protocol = "https";
|
|
||||||
// ip = window.location.hostname;
|
|
||||||
// port = 443;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // ✅ SSR 模式,补充逻辑
|
|
||||||
// const hdrs = headers();
|
|
||||||
// const forwardedProto = hdrs.get("x-forwarded-proto");
|
|
||||||
// const hostHeader = hdrs.get("host");
|
|
||||||
|
|
||||||
// if (forwardedProto) {
|
|
||||||
// protocol = forwardedProto;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (hostHeader) {
|
|
||||||
// ip = hostHeader;
|
|
||||||
// if (hostHeader.includes(":")) {
|
|
||||||
// const parts = hostHeader.split(":");
|
|
||||||
// ip = parts[0];
|
|
||||||
// port = parseInt(parts[1]);
|
|
||||||
// } else {
|
|
||||||
// port = (protocol === "https") ? 443 : 80;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return `${protocol}://${ip}:${port}`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
export async function getBaseUrl() {
|
export async function getBaseUrl() {
|
||||||
let ip = await getRuntimeEnv("SUPABASE_URL");
|
let ip = await getRuntimeEnv("SUPABASE_URL");
|
||||||
if (!ip) throw new Error("SUPABASE_URL 获取失败");
|
if (!ip) throw new Error("SUPABASE_URL 获取失败");
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ const nextConfig = {
|
||||||
esmExternals: "loose",
|
esmExternals: "loose",
|
||||||
},
|
},
|
||||||
compiler: {
|
compiler: {
|
||||||
//removeConsole: false, // 保留所有模式中的 console.log
|
removeConsole: false, // 保留所有模式中的 console.log
|
||||||
removeConsole: process.env.NODE_ENV === 'production' ? { exclude: ['error'] } : false, // ✅ 用 NODE_ENV
|
//removeConsole: process.env.NODE_ENV === 'production' ? { exclude: ['error'] } : false, // ✅ 用 NODE_ENV
|
||||||
emotion: true,
|
emotion: true,
|
||||||
},
|
},
|
||||||
webpack: (config, { isServer }) => {
|
webpack: (config, { isServer }) => {
|
||||||
|
|
@ -26,25 +26,6 @@ const nextConfig = {
|
||||||
type: "memory",
|
type: "memory",
|
||||||
});
|
});
|
||||||
|
|
||||||
// if (!isServer) {
|
|
||||||
// config.resolve.fallback = {
|
|
||||||
// fs: false,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// config.devServer = {
|
|
||||||
// ...config.devServer,
|
|
||||||
// proxy: {
|
|
||||||
// ...config.devServer.proxy,
|
|
||||||
// '/ws': {
|
|
||||||
// target: 'ws://116.213.39.234:8083/ws', // WebSocket服务器地址
|
|
||||||
// changeOrigin: true,
|
|
||||||
// ws: true, // 确保WebSocket连接也被代理
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
|
|
@ -52,9 +33,6 @@ const nextConfig = {
|
||||||
// your project has ESLint errors.
|
// your project has ESLint errors.
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
// experimental: {
|
|
||||||
// esmExternals: true,
|
|
||||||
// },
|
|
||||||
images: {
|
images: {
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue