From a1540e27c22091771276c6d677bb96dcfae58ce1 Mon Sep 17 00:00:00 2001 From: Wei Shaw Date: Wed, 31 Dec 2025 11:46:53 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8D=20OpenAI=20402?= =?UTF-8?q?=20=E6=8A=A5=E9=94=99=E8=87=AA=E5=8A=A8=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/openai_gateway_service.go | 6 +- backend/internal/service/ratelimit_service.go | 4 + frontend/src/components/common/Modal.vue | 120 ++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100755 frontend/src/components/common/Modal.vue diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index 2bb0bee8..912c25af 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -240,7 +240,7 @@ func (s *OpenAIGatewayService) GetAccessToken(ctx context.Context, account *Acco func (s *OpenAIGatewayService) shouldFailoverUpstreamError(statusCode int) bool { switch statusCode { - case 401, 403, 429, 529: + case 401, 402, 403, 429, 529: return true default: return statusCode >= 500 @@ -454,6 +454,10 @@ func (s *OpenAIGatewayService) handleErrorResponse(ctx context.Context, resp *ht statusCode = http.StatusBadGateway errType = "upstream_error" errMsg = "Upstream authentication failed, please contact administrator" + case 402: + statusCode = http.StatusBadGateway + errType = "upstream_error" + errMsg = "Upstream payment required: insufficient balance or billing issue" case 403: statusCode = http.StatusBadGateway errType = "upstream_error" diff --git a/backend/internal/service/ratelimit_service.go b/backend/internal/service/ratelimit_service.go index 27b6d3c8..1474ae46 100644 --- a/backend/internal/service/ratelimit_service.go +++ b/backend/internal/service/ratelimit_service.go @@ -39,6 +39,10 @@ func (s *RateLimitService) HandleUpstreamError(ctx context.Context, account *Acc // 认证失败:停止调度,记录错误 s.handleAuthError(ctx, account, "Authentication failed (401): invalid or expired credentials") return true + case 402: + // 支付要求:余额不足或计费问题,停止调度 + s.handleAuthError(ctx, account, "Payment required (402): insufficient balance or billing issue") + return true case 403: // 禁止访问:停止调度,记录错误 s.handleAuthError(ctx, account, "Access forbidden (403): account may be suspended or lack permissions") diff --git a/frontend/src/components/common/Modal.vue b/frontend/src/components/common/Modal.vue new file mode 100755 index 00000000..89304de1 --- /dev/null +++ b/frontend/src/components/common/Modal.vue @@ -0,0 +1,120 @@ + + + From db876ba75f5eece31960520f5bba5ae3bfbd506f Mon Sep 17 00:00:00 2001 From: shaw Date: Wed, 31 Dec 2025 14:21:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(ci):=20=E6=B7=BB=E5=8A=A0=20GitHub=20C?= =?UTF-8?q?ontainer=20Registry=20(GHCR)=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 15 +++++++-- .goreleaser.yaml | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19b8d8de..f8976d93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,6 +98,13 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Fetch tags with annotations run: | # 确保获取完整的 annotated tag 信息 @@ -161,6 +168,7 @@ jobs: VERSION=${TAG_NAME#v} REPO="${{ github.repository }}" DOCKER_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/sub2api" + GHCR_IMAGE="ghcr.io/${REPO}" # 获取 tag message 内容 TAG_MESSAGE='${{ steps.tag_message.outputs.message }}' @@ -181,12 +189,15 @@ jobs: MESSAGE+="🐳 *Docker 部署:*"$'\n' MESSAGE+="\`\`\`bash"$'\n' + MESSAGE+="# Docker Hub"$'\n' MESSAGE+="docker pull ${DOCKER_IMAGE}:${TAG_NAME}"$'\n' - MESSAGE+="docker pull ${DOCKER_IMAGE}:latest"$'\n' + MESSAGE+="# GitHub Container Registry"$'\n' + MESSAGE+="docker pull ${GHCR_IMAGE}:${TAG_NAME}"$'\n' MESSAGE+="\`\`\`"$'\n'$'\n' MESSAGE+="🔗 *相关链接:*"$'\n' MESSAGE+="• [GitHub Release](https://github.com/${REPO}/releases/tag/${TAG_NAME})"$'\n' - MESSAGE+="• [Docker Hub](https://hub.docker.com/r/${DOCKER_IMAGE})"$'\n'$'\n' + MESSAGE+="• [Docker Hub](https://hub.docker.com/r/${DOCKER_IMAGE})"$'\n' + MESSAGE+="• [GitHub Packages](https://github.com/${REPO}/pkgs/container/sub2api)"$'\n'$'\n' MESSAGE+="#Sub2API #Release #${TAG_NAME//./_}" # 发送消息 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index e899a40a..95b66f8f 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -78,6 +78,33 @@ dockers: - "--label=org.opencontainers.image.version={{ .Version }}" - "--label=org.opencontainers.image.revision={{ .Commit }}" + # GHCR images + - id: ghcr-amd64 + goos: linux + goarch: amd64 + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-amd64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.revision={{ .Commit }}" + - "--label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPO_OWNER }}/{{ .Env.GITHUB_REPO_NAME }}" + + - id: ghcr-arm64 + goos: linux + goarch: arm64 + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-arm64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.revision={{ .Commit }}" + - "--label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPO_OWNER }}/{{ .Env.GITHUB_REPO_NAME }}" + # Docker manifests for multi-arch support docker_manifests: - name_template: "{{ .Env.DOCKERHUB_USERNAME }}/sub2api:{{ .Version }}" @@ -100,6 +127,27 @@ docker_manifests: - "{{ .Env.DOCKERHUB_USERNAME }}/sub2api:{{ .Version }}-amd64" - "{{ .Env.DOCKERHUB_USERNAME }}/sub2api:{{ .Version }}-arm64" + # GHCR manifests + - name_template: "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-arm64" + + - name_template: "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:latest" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-arm64" + + - name_template: "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Major }}.{{ .Minor }}" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-arm64" + + - name_template: "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Major }}" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }}-arm64" + release: github: owner: "{{ .Env.GITHUB_REPO_OWNER }}" @@ -119,6 +167,15 @@ release: ## 📥 Installation + **Docker:** + ```bash + # Docker Hub + docker pull {{ .Env.DOCKERHUB_USERNAME }}/sub2api:{{ .Version }} + + # GitHub Container Registry + docker pull ghcr.io/{{ .Env.GITHUB_REPO_OWNER }}/sub2api:{{ .Version }} + ``` + **One-line install (Linux):** ```bash curl -sSL https://raw.githubusercontent.com/{{ .Env.GITHUB_REPO_OWNER }}/{{ .Env.GITHUB_REPO_NAME }}/main/deploy/install.sh | sudo bash From b18f5f8c1461bd0bbe51db2bf2aca0ed64c07372 Mon Sep 17 00:00:00 2001 From: shaw Date: Wed, 31 Dec 2025 14:25:28 +0800 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E7=9A=84=20Modal.vue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目已有 BaseDialog.vue 组件提供相同功能,此组件属于误提交。 --- frontend/src/components/common/Modal.vue | 120 ----------------------- 1 file changed, 120 deletions(-) delete mode 100755 frontend/src/components/common/Modal.vue diff --git a/frontend/src/components/common/Modal.vue b/frontend/src/components/common/Modal.vue deleted file mode 100755 index 89304de1..00000000 --- a/frontend/src/components/common/Modal.vue +++ /dev/null @@ -1,120 +0,0 @@ - - -