fix: prod login + env-file driven config + scroll-snap bounce
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6m54s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6m54s
- env: 解封 .env / .env.production 提交, 仅忽略 .env.local 系列; .env.production 承载 DATABASE_URL / AUTH_SECRET / AUTH_URL / SMS_* / NEXT_PUBLIC_TOS_DOMAIN, Dockerfile runner 阶段 COPY 进 运行时镜像, Next.js standalone 启动自动加载 - ci: 移除 kubectl 注入 secret 步骤(env 已烧入镜像), 保留占位避免 envFrom optional 引用告警, 修复 /api/auth/providers 500 (缺 AUTH_SECRET) - auth: signIn 失败透传 NextAuth 真实错误码, 不再被"验证码错误"一刀切掩盖 - home: 首页 scroll-snap-type 由 mandatory 改 proximity, 修复滚动到 底部被强制吸回候选区顶部的回弹 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f6177fc542
commit
7168e50a6e
@ -6,8 +6,8 @@ npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
.env
|
||||
.env.*
|
||||
.env.local
|
||||
.env.*.local
|
||||
!.env.example
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
23
.env.production
Normal file
23
.env.production
Normal file
@ -0,0 +1,23 @@
|
||||
# =============================================================
|
||||
# CYBER STAR · 生产环境变量
|
||||
# 仅在 NODE_ENV=production 时被 Next.js 加载 (部署容器里)
|
||||
# 本机开发请用 .env.local 覆盖
|
||||
# =============================================================
|
||||
|
||||
# ── 数据库 · 火山 RDS VPC 内网 (从 K8s Pod 访问) ──
|
||||
DATABASE_URL=mysql://zyc:Zyc188208@mysql8351f937d637.rds.ivolces.com:3306/cyberstar?charset=utf8mb4
|
||||
|
||||
# ── Auth.js JWT 签名密钥 ──
|
||||
# 用 `openssl rand -base64 32` 重新生成 (不要复用本机 .env.local 那把)
|
||||
AUTH_SECRET=eI6svHTg/Uj2EfyP5r0Dt0DbpJDhiX26lRqkC+EylUM=
|
||||
AUTH_URL=https://cyberstar.airlabs.art
|
||||
AUTH_TRUST_HOST=true
|
||||
|
||||
# ── 火山 TOS 静态资源前缀 (build 时需要,因为 NEXT_PUBLIC_* 会被烧进 client bundle) ──
|
||||
NEXT_PUBLIC_TOS_DOMAIN=https://cyber-star.tos-cn-shanghai.volces.com
|
||||
|
||||
# ── 阿里云短信 ──
|
||||
SMS_SIGN_NAME=广州气元科技
|
||||
SMS_TEMPLATE_CODE=SMS_506210397
|
||||
SMS_ACCESS_KEY=LTAI5t7jGzFH4ExkJ9TSmQyd
|
||||
SMS_SECRET_KEY=u0d3OyTWe9BjnNjK81bvEElky4xcHk
|
||||
@ -94,13 +94,12 @@ jobs:
|
||||
--docker-password="${{ env.CR_PASSWORD_ACTIVE }}" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
# 2) 应用运行时 Secret(DB 连接串 + 阿里云短信凭据)
|
||||
# 2) 运行时 env 已通过 .env.production 烧入镜像,不再需要 K8s Secret 注入
|
||||
# (Next.js standalone server 启动时从 cwd 自动加载 .env.production)
|
||||
# 保留一个空的 cyberstar-env 占位,避免 web-deployment.yaml 的
|
||||
# envFrom: optional=true 在首次部署时找不到引用而告警
|
||||
kubectl create secret generic cyberstar-env \
|
||||
--from-literal=DATABASE_URL='mysql://zyc:Zyc188208@mysql8351f937d637.rds.ivolces.com:3306/cyberstar?charset=utf8mb4' \
|
||||
--from-literal=SMS_SIGN_NAME='广州气元科技' \
|
||||
--from-literal=SMS_TEMPLATE_CODE='SMS_506210397' \
|
||||
--from-literal=SMS_ACCESS_KEY='LTAI5t7jGzFH4ExkJ9TSmQyd' \
|
||||
--from-literal=SMS_SECRET_KEY='u0d3OyTWe9BjnNjK81bvEElky4xcHk' \
|
||||
--from-literal=_PLACEHOLDER='env values live in .env.production' \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
# 3) Apply manifests
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@ -30,9 +30,11 @@ yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env.example
|
||||
# env files
|
||||
# 提交: .env (开发默认 / 占位)、.env.production (部署用真实值)、.env.example
|
||||
# 不提交: .env.local 系列 —— 本机个人覆盖,避免顶掉提交值
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
@ -61,6 +61,10 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
|
||||
|
||||
# 运行时 env: Next.js standalone server.js 启动时从 cwd 加载 .env.production
|
||||
# (next build 已经把 NEXT_PUBLIC_* 烧进 bundle, 这里管的是服务端 env 如 DATABASE_URL / AUTH_SECRET)
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.env.production ./.env.production
|
||||
|
||||
USER nextjs
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@ -71,7 +71,12 @@ export default function LoginForm() {
|
||||
redirect: false,
|
||||
});
|
||||
if (result?.error) {
|
||||
setError("验证码错误或已失效");
|
||||
console.error("[login] signIn 返回错误:", result);
|
||||
setError(
|
||||
result.error === "CredentialsSignin"
|
||||
? "验证码错误或已失效"
|
||||
: `登录失败:${result.error}`,
|
||||
);
|
||||
} else {
|
||||
router.push(callbackUrl);
|
||||
router.refresh();
|
||||
|
||||
@ -39,12 +39,13 @@ export default function Home() {
|
||||
return sortArtists(list, sortKey);
|
||||
}, [artists, tagFilter, sortKey]);
|
||||
|
||||
// 仅在首页启用 scroll-snap mandatory:用户下滑就立即切换到下一个 snap 点
|
||||
// (Hero → Top12 → 候选区)。卸载时还原。
|
||||
// 仅在首页启用 scroll-snap:用户接近 Hero/Top12/候选区时自然吸附。
|
||||
// 用 proximity 而不是 mandatory —— mandatory 会把"滚到底部"强制吸回到最后一个
|
||||
// snap 点的 start(候选区顶部),表现为回弹;proximity 只在靠近时吸,远离不干预。
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
const prev = root.style.scrollSnapType;
|
||||
root.style.scrollSnapType = "y mandatory";
|
||||
root.style.scrollSnapType = "y proximity";
|
||||
return () => {
|
||||
root.style.scrollSnapType = prev;
|
||||
};
|
||||
|
||||
@ -109,7 +109,14 @@ export default function LoginModal({ open, onClose, onSuccess }: LoginModalProps
|
||||
redirect: false,
|
||||
});
|
||||
if (result?.error) {
|
||||
setError("验证码错误或已失效");
|
||||
console.error("[login] signIn 返回错误:", result);
|
||||
// 把 NextAuth 真实错误透出来,避免被"验证码错误或已失效"一刀切掩盖
|
||||
// (例如 server config 错误时,会显示 Configuration 而不是误导成验证码问题)
|
||||
setError(
|
||||
result.error === "CredentialsSignin"
|
||||
? "验证码错误或已失效"
|
||||
: `登录失败:${result.error}`,
|
||||
);
|
||||
} else {
|
||||
onClose();
|
||||
if (onSuccess) onSuccess();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user