diff --git a/.cloud-dev/Dockerfile b/.cloud-dev/Dockerfile index 288edf1..ff44178 100644 --- a/.cloud-dev/Dockerfile +++ b/.cloud-dev/Dockerfile @@ -48,6 +48,7 @@ RUN apt-get update && apt-get install -y \ potrace \ imagemagick \ zsh \ + vim \ && rm -rf /var/lib/apt/lists/* # 安装 Python 3.12 @@ -112,7 +113,8 @@ RUN code-server --install-extension ms-ceintl.vscode-language-pack-zh-hans \ && code-server --install-extension dbaeumer.vscode-eslint \ && code-server --install-extension prisma.prisma \ && code-server --install-extension ecmel.vscode-html-css \ - && code-server --install-extension cweijan.vscode-redis-client + && code-server --install-extension cweijan.vscode-redis-client \ + && code-server --install-extension anthropic.claude-code # 配置 code-server (密码将在启动时设置) RUN mkdir -p /root/.config/code-server && \ diff --git a/.cloud-dev/docker-compose.yml b/.cloud-dev/docker-compose.yml index c65d38c..541448d 100644 --- a/.cloud-dev/docker-compose.yml +++ b/.cloud-dev/docker-compose.yml @@ -17,6 +17,12 @@ services: - code-server-config:/root/.config/code-server # Code Server 数据(插件、用户设置、扩展数据) - code-server-data:/root/.local/share/code-server + # Claude Code 配置和保存数据 + - claude:/root/.claude + # Claude Code Router 配置和保存数据 + - claude-code-router:/root/.claude-code-router + # SSH 配置 + - ssh:/root/.ssh environment: - NODE_ENV=development - TZ=Asia/Shanghai diff --git a/quickstart.sh b/quickstart.sh index 6304e78..0b376fb 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -232,6 +232,7 @@ main() { DEV_PORT=$(read_input "开发服务器端口" "3000") DEV_TERMINAL_PORT=$(read_input "开发终端默认端口" "7681") + DEV_TERMINAL_URL=$(read_input "开发终端 URL" "" "true") DEV_TERMINAL=$(read_input "开发终端 tmux session 名称" "nextdev") echo "" @@ -284,6 +285,7 @@ EOF # 仅在开发环境加载 PORT=${DEV_PORT} NEXT_PUBLIC_DEV_TERMINAL_DEFAULT_PORT=${DEV_TERMINAL_PORT} +NEXT_PUBLIC_DEV_TERMINAL_URL=${DEV_TERMINAL_URL} DEV_TERMINAL=${DEV_TERMINAL} EOF print_success ".env.development 文件已创建" @@ -393,8 +395,8 @@ EOF echo "" print_info "设置 Git 全局配置..." - git config --global user.email "$GIT_USER_EMAIL" - git config --global user.name "$GIT_USER_NAME" + git config user.email "$GIT_USER_EMAIL" + git config user.name "$GIT_USER_NAME" print_success "Git 全局配置已设置" # 初始化新的 git 仓库 diff --git a/src/app/(main)/dev/panel/dev-tools.tsx b/src/app/(main)/dev/panel/dev-tools.tsx index 6dd040c..85d1d51 100644 --- a/src/app/(main)/dev/panel/dev-tools.tsx +++ b/src/app/(main)/dev/panel/dev-tools.tsx @@ -126,8 +126,7 @@ export function DevTools() { variant="outline" size="sm" onClick={() => { - const port = process.env.NEXT_PUBLIC_DEV_TERMINAL_DEFAULT_PORT || '7681' - window.open(`http://localhost:${port}`, '_blank') + window.open(process.env.NEXT_PUBLIC_DEV_TERMINAL_URL || `http://localhost:${process.env.NEXT_PUBLIC_DEV_TERMINAL_DEFAULT_PORT || '7681'}`, '_blank') }} disabled={!terminalLoaded} className="gap-1.5" diff --git a/src/server/minio.ts b/src/server/minio.ts index 966e0dc..008a2d6 100644 --- a/src/server/minio.ts +++ b/src/server/minio.ts @@ -12,6 +12,33 @@ export const minioClient = new Client({ export const BUCKET_NAME = process.env.MINIO_BUCKET || 'app-files'; +/** + * 获取客户端访问的基础 URL + * 优先使用 MINIO_SERVER_URL(公网地址),否则使用内部地址 + */ +function getClientBaseUrl(): string { + if (process.env.MINIO_SERVER_URL) { + return process.env.MINIO_SERVER_URL; + } + const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http'; + const endpoint = process.env.MINIO_ENDPOINT || 'localhost'; + const port = process.env.MINIO_API_PORT || '9000'; + return `${protocol}://${endpoint}:${port}`; +} + +/** + * 替换预签名 URL 中的内部地址为客户端可访问的地址 + */ +function replaceUrlBase(originalUrl: string): string { + const clientBase = getClientBaseUrl(); + const url = new URL(originalUrl); + const clientUrl = new URL(clientBase); + url.protocol = clientUrl.protocol; + url.hostname = clientUrl.hostname; + url.port = clientUrl.port; // 空字符串表示使用协议默认端口 + return url.toString(); +} + // 桶初始化标志 let bucketInitialized = false; @@ -150,7 +177,7 @@ export async function generatePresignedPostPolicy( const presignedData = await minioClient.presignedPostPolicy(policy); return { - postURL: presignedData.postURL, + postURL: replaceUrlBase(presignedData.postURL), formData: presignedData.formData, objectName, }; @@ -237,7 +264,7 @@ export async function generatePresignedGetObject( ); return { - url, + url: replaceUrlBase(url), expiresIn: expirySeconds, }; } catch (error) { @@ -343,9 +370,5 @@ export async function getObjectMetadata(objectName: string) { * @returns 公开访问 URL */ export function getPublicUrl(objectName: string): string { - const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http'; - const endpoint = process.env.MINIO_ENDPOINT || 'localhost'; - const port = process.env.MINIO_API_PORT || '9000'; - - return `${protocol}://${endpoint}:${port}/${BUCKET_NAME}/${objectName}`; + return `${getClientBaseUrl()}/${BUCKET_NAME}/${objectName}`; } \ No newline at end of file diff --git a/src/server/service/dev/terminal.ts b/src/server/service/dev/terminal.ts index e1406ce..f5c8fdc 100644 --- a/src/server/service/dev/terminal.ts +++ b/src/server/service/dev/terminal.ts @@ -46,7 +46,8 @@ export function startTerminalService() { '-p', port, '-t', 'titleFixed=开发终端', '-t', 'fontSize=14', - '-i', '127.0.0.1', + '-c', `super_admin:${process.env.SUPER_ADMIN_PASSWORD}`, + '-i', process.env.SUPER_ADMIN_PASSWORD ? '0.0.0.0' : "127.0.0.1", '--writable', 'tmux', 'new', '-A', '-s', process.env.DEV_TERMINAL || 'nextdev',