chore(branding): 更新登录与首页标题资源及部署配置
引入新的 logo-title 资源并替换登录页与首页左上角标题展示,统一相关样式细节;同时补充 Docker 与 Gitea 部署配置,便于服务器端自动化构建发布。 Made-with: Cursor
This commit is contained in:
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
.cursor
|
||||||
|
*.log
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*.yml
|
||||||
43
.gitea/workflows/deploy.yml
Normal file
43
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Deploy To Server
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, master]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: deploy-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Deploy over SSH
|
||||||
|
env:
|
||||||
|
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
|
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||||
|
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
|
||||||
|
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
|
||||||
|
DEPLOY_WORKDIR: ${{ secrets.DEPLOY_WORKDIR }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
printf '%s\n' "$DEPLOY_SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
printf '%s\n' "$DEPLOY_SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||||
|
chmod 644 ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
SSH_PORT="${DEPLOY_PORT:-22}"
|
||||||
|
REMOTE_DIR="${DEPLOY_WORKDIR:-/opt/chat-one-web}"
|
||||||
|
|
||||||
|
ssh -p "$SSH_PORT" "$DEPLOY_USER@$DEPLOY_HOST" <<EOF
|
||||||
|
set -eu
|
||||||
|
cd "$REMOTE_DIR"
|
||||||
|
git pull --ff-only
|
||||||
|
docker compose up -d --build
|
||||||
|
docker image prune -f
|
||||||
|
EOF
|
||||||
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 先复制依赖清单,利用 Docker layer cache
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
|
# 再复制源码并构建
|
||||||
|
COPY . .
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
FROM nginx:1.27-alpine AS runner
|
||||||
|
WORKDIR /usr/share/nginx/html
|
||||||
|
|
||||||
|
# 覆盖默认站点配置,启用 SPA 回退与缓存策略
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# 仅拷贝构建产物,减小镜像体积
|
||||||
|
COPY --from=builder /app/dist ./
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
chat-one-web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: chat-one-web:latest
|
||||||
|
container_name: chat-one-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
BIN
src/assets/logo-title.png
Normal file
BIN
src/assets/logo-title.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -12,7 +12,6 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|||||||
theme={{
|
theme={{
|
||||||
algorithm: theme.defaultAlgorithm,
|
algorithm: theme.defaultAlgorithm,
|
||||||
token: {
|
token: {
|
||||||
colorPrimary: "#4A90E2",
|
|
||||||
colorBgBase: "#F7F7F8",
|
colorBgBase: "#F7F7F8",
|
||||||
colorBgContainer: "#FFFFFF",
|
colorBgContainer: "#FFFFFF",
|
||||||
colorBorder: "#E9E9EB",
|
colorBorder: "#E9E9EB",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import {
|
|||||||
import type { MenuProps } from "antd";
|
import type { MenuProps } from "antd";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import logoSrc from "../assets/logo.png";
|
import logoSrc from "../assets/logo.png";
|
||||||
|
import logoTitleSrc from "../assets/logo-title.png";
|
||||||
import { ACCESS_TOKEN_KEY, SessionExpiredError, USER_KEY, logout } from "../api/auth";
|
import { ACCESS_TOKEN_KEY, SessionExpiredError, USER_KEY, logout } from "../api/auth";
|
||||||
import {
|
import {
|
||||||
createChatSession,
|
createChatSession,
|
||||||
@@ -99,6 +100,7 @@ const DEEP_THINK_STORAGE_KEY = "chatone-deep-think-enabled";
|
|||||||
const SMART_SEARCH_STORAGE_KEY = "chatone-smart-search-enabled";
|
const SMART_SEARCH_STORAGE_KEY = "chatone-smart-search-enabled";
|
||||||
const SELECTED_MODEL_STORAGE_KEY = "chatone-selected-model";
|
const SELECTED_MODEL_STORAGE_KEY = "chatone-selected-model";
|
||||||
const LOGO_SRC = logoSrc;
|
const LOGO_SRC = logoSrc;
|
||||||
|
const TITLE_SRC = logoTitleSrc;
|
||||||
|
|
||||||
/** 展示名与请求 model 字段;需与后端实际支持的模型 id 一致 */
|
/** 展示名与请求 model 字段;需与后端实际支持的模型 id 一致 */
|
||||||
const DEFAULT_QWEN_MODEL = "qwen3.6-plus";
|
const DEFAULT_QWEN_MODEL = "qwen3.6-plus";
|
||||||
@@ -745,9 +747,12 @@ export default function HomePage() {
|
|||||||
decoding="async"
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
{!collapsed && (
|
{!collapsed && (
|
||||||
<Typography.Title level={5} className="!m-0 !truncate !text-[15px] !font-semibold">
|
<img
|
||||||
ChatOne
|
src={TITLE_SRC}
|
||||||
</Typography.Title>
|
alt="chatone"
|
||||||
|
className="h-7 w-auto max-w-[170px] object-contain object-left"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{sidebarContent}
|
{sidebarContent}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Button, Input, Typography, message } from "antd";
|
import { Button, Input, message } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import logoSrc from "../assets/logo.png";
|
import logoSrc from "../assets/logo.png";
|
||||||
|
import logoTitleSrc from "../assets/logo-title.png";
|
||||||
import {
|
import {
|
||||||
ACCESS_TOKEN_KEY,
|
ACCESS_TOKEN_KEY,
|
||||||
persistTokens,
|
persistTokens,
|
||||||
@@ -14,6 +15,7 @@ import { tw } from "../utils/tw";
|
|||||||
/** 发送验证码成功后,按钮冷却秒数 */
|
/** 发送验证码成功后,按钮冷却秒数 */
|
||||||
const SMS_RESEND_COOLDOWN_SEC = 60;
|
const SMS_RESEND_COOLDOWN_SEC = 60;
|
||||||
const LOGO_SRC = logoSrc;
|
const LOGO_SRC = logoSrc;
|
||||||
|
const LOGIN_TITLE_SRC = logoTitleSrc;
|
||||||
|
|
||||||
/** 短信验证码登录页:校验本地 token、发送验证码、提交登录 */
|
/** 短信验证码登录页:校验本地 token、发送验证码、提交登录 */
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
@@ -127,18 +129,19 @@ export default function LoginPage() {
|
|||||||
>
|
>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
<section className="w-[325px] -translate-y-6">
|
<section className="w-[325px] -translate-y-6">
|
||||||
<div className="mb-7 flex items-center justify-center gap-2">
|
<div className="mb-7 flex items-center justify-center">
|
||||||
<img
|
<img
|
||||||
src={LOGO_SRC}
|
src={LOGO_SRC}
|
||||||
alt="ChatOne Logo"
|
alt="ChatOne Logo"
|
||||||
width={28}
|
className="h-10 w-10 shrink-0 object-contain"
|
||||||
height={28}
|
decoding="async"
|
||||||
className="h-7 w-7 object-contain"
|
/>
|
||||||
|
<img
|
||||||
|
src={LOGIN_TITLE_SRC}
|
||||||
|
alt="chatone"
|
||||||
|
className="h-auto w-[150px] object-contain object-left"
|
||||||
decoding="async"
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
<Typography.Title level={3} className="mb-0! leading-none text-[#355ad9]">
|
|
||||||
ChatOne
|
|
||||||
</Typography.Title>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
@@ -201,7 +204,7 @@ export default function LoginPage() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
void onLogin();
|
void onLogin();
|
||||||
}}
|
}}
|
||||||
className="mt-1 h-[42px] rounded-full border-0 bg-[#3b5ff7]"
|
className="mt-1 h-[42px] rounded-full border-0"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user