diff --git a/.drone.yml b/.drone.yml index e62ab19..9eafeec 100644 --- a/.drone.yml +++ b/.drone.yml @@ -2,9 +2,9 @@ kind: pipeline type: docker name: default -#trigger: -# event: -# - manual +trigger: + event: + - manual steps: - name: build diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml deleted file mode 100644 index e011ced..0000000 --- a/.gitea/workflows/ci.yaml +++ /dev/null @@ -1,314 +0,0 @@ -name: Epic UI Build & Deploy -run-name: ${{ gitea.actor }} 正在构建 Epic UI 前端项目 🚀 -on: - push: - branches: [ main, master, develop ] - pull_request: - branches: [ main, master ] - -jobs: - build: - runs-on: gitea_labels - container: - image: gitea-ci-bash:latest - env: - # 指定容器将工具缓存路径存放到 /opt/hostedtoolcache,该目录是Gitea Runner的标准工具缓存目录 - RUNNER_TOOL_CACHE: /opt/hostedtoolcache - volumes: - # 直接挂载到指定的宿主机路径 - # 挂载生产环境目录 - - /opt/1panel/apps/openresty/openresty/www/sites/epic7/index:/opt/1panel/apps/openresty/openresty/www/sites/epic7/index - steps: - - name: 检出代码 - shell: bash - run: | - echo "📥 检出代码到工作目录..." - - # 解析分支名 - BRANCH_NAME=$(echo "${{ gitea.ref }}" | sed 's#refs/heads/##') - - # 拉取代码(使用token鉴权) - git clone --depth=1 -b "$BRANCH_NAME" "http://1c18ee1ab9a9cb291506d0c5c016a33be7d59e8c:x-oauth-basic@gitea.htoop.cn/${{ gitea.repository }}.git" . - - echo "✅ 代码检出成功" - - - name: 安装Node.js环境 - shell: bash - run: | - echo "🔧 安装Node.js环境..." - if command -v node &> /dev/null; then - echo "✅ Node.js已安装: $(node --version)" - else - echo "📥 下载并安装Node.js..." - NODE_VERSION="18.19.0" - NODE_ARCH="linux-x64" - MIRRORS=( - "https://mirrors.aliyun.com/nodejs-release/v${NODE_VERSION}/node-v${NODE_VERSION}-${NODE_ARCH}.tar.xz" - "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${NODE_ARCH}.tar.xz" - ) - DOWNLOAD_SUCCESS=false - for mirror in "${MIRRORS[@]}"; do - echo "尝试从镜像下载: $mirror" - if wget -q --timeout=30 --tries=3 "$mirror" -O node.tar.xz; then - echo "✅ 下载成功: $mirror" - DOWNLOAD_SUCCESS=true - break - else - echo "❌ 下载失败: $mirror" - continue - fi - done - if [ "$DOWNLOAD_SUCCESS" = false ]; then - echo "❌ 所有镜像源下载失败" - exit 1 - fi - echo "解压Node.js到/usr/local..." - tar -C /usr/local -xJf node.tar.xz --strip-components=1 - export PATH=$PATH:/usr/local/bin - rm node.tar.xz - echo "✅ Node.js安装完成" - fi - - - name: 安装pnpm - shell: bash - run: | - echo "📦 安装pnpm包管理器..." - export PATH=$PATH:/usr/local/bin - - if command -v pnpm &> /dev/null; then - echo "✅ pnpm已安装: $(pnpm --version)" - else - echo "📥 安装pnpm..." - npm install -g pnpm - echo "✅ pnpm安装完成: $(pnpm --version)" - fi - - - name: 配置pnpm缓存 - shell: bash - run: | - echo "📦 配置pnpm缓存..." - export PATH=$PATH:/usr/local/bin - - # 配置pnpm缓存目录 - PNPM_STORE_DIR="/opt/hostedtoolcache/pnpm-store" - mkdir -p "$PNPM_STORE_DIR" - - # 设置pnpm使用缓存目录 - pnpm config set store-dir "$PNPM_STORE_DIR" - pnpm config set cache-dir "/opt/hostedtoolcache/pnpm-cache" - - echo "✅ pnpm缓存配置完成" - - - name: 恢复依赖缓存 - shell: bash - run: | - echo "📦 检查并恢复依赖缓存..." - export PATH=$PATH:/usr/local/bin - - # 生成缓存键 - CACHE_KEY=$(md5sum pnpm-lock.yaml | cut -d' ' -f1) - echo "缓存键: $CACHE_KEY" - - # 使用 /opt/hostedtoolcache 目录 - CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz" - echo "📁 检查缓存文件: $CACHE_FILE" - - if [ -f "$CACHE_FILE" ]; then - echo "✅ 找到缓存文件: $CACHE_FILE" - echo "📦 缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)" - echo "正在恢复缓存..." - - if tar -xzf "$CACHE_FILE"; then - echo "✅ 缓存恢复成功" - echo "📦 恢复的 node_modules 大小:" - du -sh node_modules 2>/dev/null || echo "node_modules 目录不存在" - else - echo "❌ 缓存恢复失败" - echo "📥 将重新安装依赖" - fi - else - echo "📥 未找到缓存文件,将重新安装依赖" - fi - - - name: 安装项目依赖 - shell: bash - run: | - echo "📦 安装项目依赖..." - export PATH=$PATH:/usr/local/bin - - # 检查是否已有node_modules - if [ -d "node_modules" ] && [ -f "node_modules/.pnpm-debug.log" ]; then - echo "✅ 检测到已存在的依赖,跳过安装" - else - echo "📥 安装项目依赖..." - pnpm install --frozen-lockfile --prefer-offline - echo "✅ 依赖安装完成" - fi - - - name: 保存依赖缓存 - shell: bash - run: | - echo "💾 保存依赖缓存..." - export PATH=$PATH:/usr/local/bin - - # 生成缓存键 - CACHE_KEY=$(md5sum pnpm-lock.yaml | cut -d' ' -f1) - echo "缓存键: $CACHE_KEY" - - # 检查node_modules是否存在 - if [ ! -d "node_modules" ]; then - echo "❌ node_modules 目录不存在,跳过缓存保存" - exit 0 - fi - - # 检查缓存文件是否已存在且是最新的 - CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz" - if [ -f "$CACHE_FILE" ]; then - echo "✅ 缓存文件已存在且是最新的,跳过创建: $CACHE_FILE" - echo "📦 现有缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)" - exit 0 - fi - - # 缓存文件不存在,需要创建 - echo "📦 正在创建缓存文件: $CACHE_FILE" - - if tar -czf "$CACHE_FILE" node_modules; then - echo "✅ 缓存已保存到: $CACHE_FILE" - echo "📦 缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)" - else - echo "❌ 缓存保存失败" - exit 1 - fi - - - - - name: 构建项目 - shell: bash - run: | - echo "🔨 构建 Epic UI 前端项目..." - export PATH=$PATH:/usr/local/bin - - # 执行构建 - pnpm build - - echo "✅ 构建完成" - - - name: 检查构建产物 - shell: bash - run: | - echo "📦 构建产物信息:" - if [ -d "dist" ]; then - echo "✅ 找到dist目录" - ls -la dist/ - echo "dist目录大小: $(du -sh dist | cut -f1)" - else - echo "❌ 未找到dist目录" - exit 1 - fi - - - name: 显示项目信息 - shell: bash - run: | - echo "📋 项目信息:" - export PATH=$PATH:/usr/local/bin - echo "Node.js 版本: $(node --version)" - echo "npm 版本: $(npm --version)" - echo "pnpm 版本: $(pnpm --version)" - echo "构建时间: $(date)" - echo "分支: ${{ gitea.ref }}" - echo "提交: ${{ gitea.sha }}" - - - name: 部署到生产环境 - shell: bash - run: | - echo "🚀 部署到生产环境..." - - # 生产环境目录(容器内路径,直接映射到nginx静态文件目录) - PROD_DIR="/opt/1panel/apps/openresty/openresty/www/sites/epic7/index" - - # 检查构建产物 - if [ ! -d "dist" ]; then - echo "❌ 构建产物不存在" - exit 1 - fi - - echo "📦 构建产物内容:" - ls -la dist/ - - # 检查生产目录挂载 - echo "📁 检查生产目录挂载状态..." - if [ -d "$PROD_DIR" ]; then - echo "✅ 生产目录已存在: $PROD_DIR" - echo "📁 当前生产目录内容:" - ls -la "$PROD_DIR" 2>/dev/null || echo "目录为空或无法访问" - else - echo "📁 生产目录不存在,将创建: $PROD_DIR" - fi - - # 备份当前生产环境 - if [ -d "$PROD_DIR" ] && [ "$(ls -A "$PROD_DIR" 2>/dev/null)" ]; then - BACKUP_DIR="/opt/prod_backup_$(date +%Y%m%d_%H%M%S)" - echo "📦 备份当前生产环境到: $BACKUP_DIR" - cp -r "$PROD_DIR" "$BACKUP_DIR" - fi - - # 确保生产目录存在并清空 - echo "📤 部署构建产物到nginx静态文件目录..." - mkdir -p "$PROD_DIR" - rm -rf "$PROD_DIR"/* - - # 复制构建产物到生产环境 - echo "📦 复制构建产物..." - if cp -r dist/* "$PROD_DIR/"; then - echo "✅ 构建产物复制成功" - else - echo "❌ 构建产物复制失败" - echo "📁 检查目标目录权限和空间..." - df -h "$PROD_DIR" 2>/dev/null || echo "无法检查磁盘空间" - ls -ld "$PROD_DIR" 2>/dev/null || echo "无法检查目录权限" - exit 1 - fi - - # 设置权限 - chmod -R 755 "$PROD_DIR" - - # 强制同步文件系统 - 确保文件写入到宿主机 - echo "🔄 同步文件系统..." - sync - - # 等待文件系统同步完成 - echo "⏳ 等待文件系统同步..." - sleep 3 - - # 再次强制同步 - sync - - # 验证文件是否真的写入到宿主机 - echo "🔍 验证文件同步状态..." - if [ -f "$PROD_DIR/index.html" ]; then - echo "✅ 确认index.html已同步到宿主机" - echo "📋 文件大小: $(ls -lh "$PROD_DIR/index.html" | awk '{print $5}')" - echo "📋 文件时间: $(ls -l "$PROD_DIR/index.html" | awk '{print $6, $7, $8}')" - else - echo "❌ index.html未同步到宿主机" - exit 1 - fi - - echo "✅ 部署完成" - echo "📁 生产环境目录: $PROD_DIR (直接映射到宿主机)" - echo "📦 部署的文件:" - ls -la "$PROD_DIR" - - # 验证部署结果 - echo "🔍 验证部署结果..." - echo "📋 文件数量: $(find "$PROD_DIR" -type f | wc -l)" - echo "📋 目录数量: $(find "$PROD_DIR" -type d | wc -l)" - echo "📋 总大小: $(du -sh "$PROD_DIR" | cut -f1)" - - # 检查关键文件 - if [ -f "$PROD_DIR/index.html" ]; then - echo "✅ index.html 存在" - echo "📋 index.html 大小: $(ls -lh "$PROD_DIR/index.html" | awk '{print $5}')" - else - echo "❌ index.html 不存在" - fi \ No newline at end of file diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 8bbc382..0000000 --- a/.npmrc +++ /dev/null @@ -1,5 +0,0 @@ -# pnpm 性能优化配置 -registry=https://registry.npmmirror.com/ -prefer-offline=true -auto-install-peers=true -shamefully-hoist=true \ No newline at end of file diff --git a/src/pages/Characters.tsx b/src/pages/Characters.tsx index 604b19a..632e899 100644 --- a/src/pages/Characters.tsx +++ b/src/pages/Characters.tsx @@ -2,7 +2,7 @@ import React, {useEffect, useState} from "react"; import {useNavigate} from 'react-router-dom'; -import {Select} from 'antd'; +import {Input} from 'antd'; import type {Hero} from '@/api/index'; import * as EpicApi from '@/api/index'; @@ -14,60 +14,31 @@ type ExtendedHero = Hero & { }; // 自定义样式覆盖 Ant Design 默认样式 -const selectStyles = ` - .ant-select { - background-color: #1A1412 !important; - border-color: #C17F59 !important; - color: #E6B17E !important; - } - - .ant-select .ant-select-selector { - background-color: #1A1412 !important; - border-color: #C17F59 !important; - color: #E6B17E !important; - } - - .ant-select-focused .ant-select-selector { - border-color: #C17F59 !important; - box-shadow: 0 0 0 2px rgba(193, 127, 89, 0.2) !important; - } - - .ant-select-dropdown { - background-color: #1A1412 !important; - border-color: #C17F59 !important; - } - - .ant-select-item { - background-color: #1A1412 !important; - color: #E6B17E !important; - } - - .ant-select-item-option-selected { - background-color: #2A211E !important; - color: #E6B17E !important; - } - - .ant-select-item-option-active { - background-color: #2A211E !important; - color: #E6B17E !important; - } - - .ant-select-selection-placeholder { - color: #9B8579 !important; - } - - .ant-select-selection-item { - color: #E6B17E !important; - } - - .ant-select-arrow { - color: #E6B17E !important; - } - - .ant-select-clear { - background-color: #1A1412 !important; - color: #E6B17E !important; - } +const inputStyles = ` + .ant-input, .ant-input-affix-wrapper, .ant-input-affix-wrapper input { + background-color: #1A1412 !important; + border-color: rgba(193, 127, 89, 0.3) !important; + color: #E6B17E !important; + border-radius: 0.5rem !important; + box-shadow: none !important; + } + .ant-input:focus, .ant-input-affix-wrapper:focus, .ant-input-affix-wrapper-focused, .ant-input:active { + background-color: #1A1412 !important; + border-color: #C17F59 !important; + color: #E6B17E !important; + box-shadow: 0 0 0 2px rgba(193, 127, 89, 0.2) !important; + } + .ant-input::placeholder, .ant-input-affix-wrapper input::placeholder { + color: #9B8579 !important; + opacity: 1 !important; + } + .ant-input-clear-icon { + color: #E6B17E !important; + background: transparent !important; + } + .ant-input-clear-icon:hover { + color: #C17F59 !important; + } `; const ELEMENTS = [ @@ -157,15 +128,15 @@ const Characters: React.FC = () => { return {role}; }; - // 处理英雄选择 - const handleHeroSelect = (value: string) => { - setSearchTerm(value); + // 处理搜索输入 + const handleSearchChange = (e: React.ChangeEvent) => { + setSearchTerm(e.target.value); }; return (
{/* 注入自定义样式 */} -