From 284b5a526034e5fcf0ddc4d126453d10531c38b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A0=91=E8=90=8C=E8=8A=BD?= <3205788256@qq.com> Date: Wed, 1 Apr 2026 22:03:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/README.md | 18 + InfoGenie-frontend/.env.development | 12 +- InfoGenie-frontend/.env.production | 12 +- InfoGenie-frontend/{public => }/index.html | 14 +- InfoGenie-frontend/package-lock.json | 20851 ++-------------- InfoGenie-frontend/package.json | 35 +- .../public/aimodelapp/shared/ai-chat.js | 221 +- .../png和jpg格式互转/png和jpg相互转化.html | 342 + .../图片加文字水印/图片加文字水印.html | 728 + .../图片处理/图片压缩处理/图片压缩处理.html | 359 + .../实用工具/C语言编译器/网页C语言编译器.html | 46 + .../{JavaScript编译器 => JavaScript解释器}/app.js | 0 .../index.html | 0 .../styles.css | 0 InfoGenie-frontend/src/App.js | 54 +- InfoGenie-frontend/src/components/Footer.js | 85 +- .../src/components/FullscreenEmbed.js | 264 +- InfoGenie-frontend/src/components/Header.js | 652 +- .../src/components/LoginRequired.js | 77 +- .../src/components/Navigation.js | 259 +- .../src/components/ParticleEffect.js | 146 +- .../src/components/RandomSiteBackground.js | 58 + InfoGenie-frontend/src/config/env.js | 28 +- .../src/config/featureCardSections.js | 7 + .../src/hooks/useFeatureCardClickStats.js | 39 + InfoGenie-frontend/src/pages/AdminPage.js | 890 +- InfoGenie-frontend/src/pages/AiModelPage.js | 108 +- .../src/pages/Api60sItemPage.js | 2 +- InfoGenie-frontend/src/pages/Api60sPage.js | 132 +- .../src/pages/AuthCallbackPage.js | 56 +- InfoGenie-frontend/src/pages/HomePage.js | 79 +- InfoGenie-frontend/src/pages/LoginPage.js | 131 +- InfoGenie-frontend/src/pages/SmallGamePage.js | 102 +- InfoGenie-frontend/src/pages/ToolboxPage.js | 191 +- .../src/pages/UserProfilePage.js | 666 +- InfoGenie-frontend/src/styles/global.css | 23 - InfoGenie-frontend/src/styles/index.css | 108 +- InfoGenie-frontend/src/styles/shared.js | 502 +- InfoGenie-frontend/src/utils/api.js | 6 +- .../src/utils/featureCardClicks.js | 28 + InfoGenie-frontend/vite.config.js | 32 + InfoGenie-frontend/前端文档.md | 169 + README.md | 612 +- .../internal/database/mysql.go | 1 + .../internal/handler/aimodel.go | 92 +- .../internal/handler/feature_card_clicks.go | 95 + .../internal/handler/siteconfig.go | 13 + .../internal/model/site_feature_card_click.go | 13 + .../internal/router/router.go | 76 +- infogenie-backend-go/internal/service/ai.go | 160 +- infogenie-backend-go/后端文档.md | 117 + infogenie-backend-java/后端文档.md | 0 ... 萌芽账户认证中心-第三方应用API接入文档.md | 194 +- 53 files changed, 6240 insertions(+), 22665 deletions(-) create mode 100644 .claude/README.md rename InfoGenie-frontend/{public => }/index.html (90%) mode change 100755 => 100644 create mode 100644 InfoGenie-frontend/public/toolbox/图片处理/png和jpg格式互转/png和jpg相互转化.html create mode 100644 InfoGenie-frontend/public/toolbox/图片处理/图片加文字水印/图片加文字水印.html create mode 100644 InfoGenie-frontend/public/toolbox/图片处理/图片压缩处理/图片压缩处理.html create mode 100644 InfoGenie-frontend/public/toolbox/实用工具/C语言编译器/网页C语言编译器.html rename InfoGenie-frontend/public/toolbox/实用工具/{JavaScript编译器 => JavaScript解释器}/app.js (100%) rename InfoGenie-frontend/public/toolbox/实用工具/{JavaScript编译器 => JavaScript解释器}/index.html (100%) rename InfoGenie-frontend/public/toolbox/实用工具/{JavaScript编译器 => JavaScript解释器}/styles.css (100%) create mode 100644 InfoGenie-frontend/src/components/RandomSiteBackground.js create mode 100644 InfoGenie-frontend/src/config/featureCardSections.js create mode 100644 InfoGenie-frontend/src/hooks/useFeatureCardClickStats.js delete mode 100755 InfoGenie-frontend/src/styles/global.css create mode 100644 InfoGenie-frontend/src/utils/featureCardClicks.js create mode 100644 InfoGenie-frontend/vite.config.js create mode 100644 InfoGenie-frontend/前端文档.md create mode 100644 infogenie-backend-go/internal/handler/feature_card_clicks.go create mode 100644 infogenie-backend-go/internal/model/site_feature_card_click.go create mode 100644 infogenie-backend-go/后端文档.md create mode 100644 infogenie-backend-java/后端文档.md rename SPROUT_GATE_API_DOCS.md => 萌芽账户认证中心-第三方应用API接入文档.md (51%) diff --git a/.claude/README.md b/.claude/README.md new file mode 100644 index 00000000..83719146 --- /dev/null +++ b/.claude/README.md @@ -0,0 +1,18 @@ +# InfoGenie 仓库 — Claude / Cursor 工作区说明 + +本目录用于存放与 **Cursor / Claude Code** 等工具相关的本地配置(如 `settings.local.json`),**不放业务代码**。 + +## 与文档的关系 + +| 文档 | 路径 | 内容 | +|------|------|------| +| Go 后端 | [`infogenie-backend-go/后端文档.md`](../infogenie-backend-go/后端文档.md) | API、MySQL、AI 流式、站点配置、功能卡片统计 | +| React 前端 | [`infogenie-frontend/前端文档.md`](../infogenie-frontend/前端文档.md) | 路由、构建、环境变量、静态 AI 小应用 | + +## 仓库结构(与开发相关) + +- **`infogenie-backend-go/`**:万象口袋 **主后端**(Gin + GORM + MySQL)。生产环境前端默认请求此服务提供的 API。 +- **`infogenie-frontend/`**:**主站 SPA**(Create React App),`public/` 下含大量静态页(`aimodelapp/`、`smallgame/`、`toolbox/` 等)。 +- **`infogenie-backend-java/`**:Java 后端(若部署需与本仓库 Go 文档中的接口约定自行对齐)。 + +给助手或协作者改需求时,优先阅读上表两份 **后端文档 / 前端文档**,再下钻到具体源码路径。 diff --git a/InfoGenie-frontend/.env.development b/InfoGenie-frontend/.env.development index da2550ea..1d89ce1b 100644 --- a/InfoGenie-frontend/.env.development +++ b/InfoGenie-frontend/.env.development @@ -1,7 +1,7 @@ # 复制为 .env.local 后可按需覆盖本地开发值 -REACT_APP_API_URL=http://127.0.0.1:5002 -REACT_APP_AUTH_URL=https://auth.shumengya.top -REACT_APP_AUTH_API_URL=https://auth.api.shumengya.top -REACT_APP_NAME=InfoGenie -REACT_APP_VERSION=1.0.0 -REACT_APP_DEBUG=true +VITE_API_URL=http://127.0.0.1:5002 +VITE_AUTH_URL=https://auth.shumengya.top +VITE_AUTH_API_URL=https://auth.api.shumengya.top +VITE_NAME=InfoGenie +VITE_VERSION=1.0.0 +VITE_DEBUG=true diff --git a/InfoGenie-frontend/.env.production b/InfoGenie-frontend/.env.production index 33b98de6..5b26b406 100644 --- a/InfoGenie-frontend/.env.production +++ b/InfoGenie-frontend/.env.production @@ -1,7 +1,7 @@ # 生产前端环境变量 -REACT_APP_API_URL=https://infogenie.api.shumengya.top -REACT_APP_AUTH_URL=https://auth.shumengya.top -REACT_APP_AUTH_API_URL=https://auth.api.shumengya.top -REACT_APP_NAME=InfoGenie -REACT_APP_VERSION=1.0.0 -REACT_APP_DEBUG=false +VITE_API_URL=https://infogenie.api.shumengya.top +VITE_AUTH_URL=https://auth.shumengya.top +VITE_AUTH_API_URL=https://auth.api.shumengya.top +VITE_NAME=InfoGenie +VITE_VERSION=1.0.0 +VITE_DEBUG=false diff --git a/InfoGenie-frontend/public/index.html b/InfoGenie-frontend/index.html old mode 100755 new mode 100644 similarity index 90% rename from InfoGenie-frontend/public/index.html rename to InfoGenie-frontend/index.html index 55dcd0f0..63191cc8 --- a/InfoGenie-frontend/public/index.html +++ b/InfoGenie-frontend/index.html @@ -15,7 +15,7 @@ - + @@ -28,14 +28,14 @@ - - + + - + - + @@ -183,7 +183,7 @@
- +
@@ -199,6 +199,8 @@
+ + + + + +
+ +
+
+
🖼️
+

PNG ↔ JPG 转换器

+
+

纯浏览器本地转换 • 零上传 • 安全隐私 • 秒级处理

+
+ +
+
+ +
+ +
+ + + +
+

点击或拖拽图片到此区域

+

支持 PNG / JPG 格式,最大 50MB

+
+ + + +
+ + + +
+ +
+ 完全本地运行 • 无需联网 • 图片不会离开您的浏览器 +
+
+ + + + + + diff --git a/InfoGenie-frontend/public/toolbox/图片处理/图片加文字水印/图片加文字水印.html b/InfoGenie-frontend/public/toolbox/图片处理/图片加文字水印/图片加文字水印.html new file mode 100644 index 00000000..8911187b --- /dev/null +++ b/InfoGenie-frontend/public/toolbox/图片处理/图片加文字水印/图片加文字水印.html @@ -0,0 +1,728 @@ + + + + + +水印工具 · WaterMark + + + + + +
+ + + + + WM + +
+
WaterMark
+
图片文字水印工具
+
+
+ +
+ + + +
+
+
+
🖼️
+

上传图片后
在左侧调整参数
即可预览水印效果

+
+
+ 预览 +
+ +
尺寸:  |  文件:
+
+
+ + + + \ No newline at end of file diff --git a/InfoGenie-frontend/public/toolbox/图片处理/图片压缩处理/图片压缩处理.html b/InfoGenie-frontend/public/toolbox/图片处理/图片压缩处理/图片压缩处理.html new file mode 100644 index 00000000..066cec3a --- /dev/null +++ b/InfoGenie-frontend/public/toolbox/图片处理/图片压缩处理/图片压缩处理.html @@ -0,0 +1,359 @@ + + + + + + 在线图片压缩工具 + + + + +
+

图片压缩工具

+ +
+

点击这里或将图片拖拽到此处上传

+

支持 JPG, PNG, WebP 等常见格式

+ +
+ +
+
+ + +
数值越小,体积越小,画质越低
+
+
+ + +
+
+ +
+
+

原图

+
等待上传...
+ +
+
+

压缩后

+
等待处理...
+ +
+
+ + 下载压缩后的图片 +
+ + + + + diff --git a/InfoGenie-frontend/public/toolbox/实用工具/C语言编译器/网页C语言编译器.html b/InfoGenie-frontend/public/toolbox/实用工具/C语言编译器/网页C语言编译器.html new file mode 100644 index 00000000..a525801c --- /dev/null +++ b/InfoGenie-frontend/public/toolbox/实用工具/C语言编译器/网页C语言编译器.html @@ -0,0 +1,46 @@ + + + + + Wasmer Clang in Browser + + +

浏览器里直接编译 C → WASM

+ +
+ +

+
+  
+
+
\ No newline at end of file
diff --git a/InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/app.js b/InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/app.js
similarity index 100%
rename from InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/app.js
rename to InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/app.js
diff --git a/InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/index.html b/InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/index.html
similarity index 100%
rename from InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/index.html
rename to InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/index.html
diff --git a/InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/styles.css b/InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/styles.css
similarity index 100%
rename from InfoGenie-frontend/public/toolbox/实用工具/JavaScript编译器/styles.css
rename to InfoGenie-frontend/public/toolbox/实用工具/JavaScript解释器/styles.css
diff --git a/InfoGenie-frontend/src/App.js b/InfoGenie-frontend/src/App.js
index 53d1301f..98bef650 100755
--- a/InfoGenie-frontend/src/App.js
+++ b/InfoGenie-frontend/src/App.js
@@ -1,9 +1,7 @@
 import React from 'react';
 import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
 import { Toaster } from 'react-hot-toast';
-import styled from 'styled-components';
 
-// 页面组件
 import HomePage from './pages/HomePage';
 import LoginPage from './pages/LoginPage';
 import AuthCallbackPage from './pages/AuthCallbackPage';
@@ -15,42 +13,27 @@ import UserProfilePage from './pages/UserProfilePage';
 import AdminPage from './pages/AdminPage';
 import ToolboxPage from './pages/ToolboxPage';
 
-// 公共组件
 import Header from './components/Header';
 import Navigation from './components/Navigation';
 import Footer from './components/Footer';
 import ParticleEffect from './components/ParticleEffect';
+import RandomSiteBackground from './components/RandomSiteBackground';
 import ScrollToTop from './components/ScrollToTop';
 
-// 上下文
 import { UserProvider } from './contexts/UserContext';
 
-// 样式
-import './styles/global.css';
-
-const AppContainer = styled.div`
-  min-height: 100vh;
-  display: flex;
-  flex-direction: column;
-  background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
-`;
-
-const MainContent = styled.main`
-  flex: 1;
-  padding: 0;
-  margin: 0;
-`;
+import './styles/index.css';
 
 function App() {
   return (
     
       
         
-        
+        
+        
- +
- {/* 主要页面 */} } /> } /> } /> @@ -61,14 +44,12 @@ function App() { } /> } /> } /> - {/* 通配符路由 - 所有未匹配的路径都重定向到首页 */} } /> - +
- - {/* 全局提示组件 */} + - - {/* 全局粒子效果 */} + - +
); diff --git a/InfoGenie-frontend/src/components/Footer.js b/InfoGenie-frontend/src/components/Footer.js index bedce638..66a679e4 100755 --- a/InfoGenie-frontend/src/components/Footer.js +++ b/InfoGenie-frontend/src/components/Footer.js @@ -1,74 +1,33 @@ import React from 'react'; -import styled from 'styled-components'; - -const FooterContainer = styled.footer` - background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); - color: white; - padding: 40px 0 80px; /* 底部留出导航栏空间 */ - margin-top: 60px; - box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); - - @media (min-width: 769px) { - padding: 40px 0 20px; - } -`; - -const FooterContent = styled.div` - max-width: 1200px; - margin: 0 auto; - padding: 0 16px; -`; - -const FooterInfo = styled.div` - text-align: center; - margin-bottom: 24px; -`; - -const FooterTitle = styled.h3` - color: white; - margin-bottom: 12px; - font-size: 20px; - font-weight: bold; -`; - -const FooterDivider = styled.div` - height: 1px; - background: rgba(255, 255, 255, 0.2); - margin: 24px 0; -`; - -const FooterBottom = styled.div` - text-align: center; - font-size: 12px; - color: rgba(255, 255, 255, 0.8); - line-height: 1.5; -`; - -const Copyright = styled.p` - margin-bottom: 8px; -`; const Footer = () => { const currentYear = new Date().getFullYear(); return ( - - - - 万象口袋 - +
+
+
+

万象口袋

+
+
- - - - - - 蜀ICP备2025151694号 | Copyright © 2025-{currentYear} - - - - +
+

+ 蜀ICP备2025151694号 | Copyright © 2025-{currentYear} +

+
+
+
); }; diff --git a/InfoGenie-frontend/src/components/FullscreenEmbed.js b/InfoGenie-frontend/src/components/FullscreenEmbed.js index 8c1db4a1..de4463f8 100644 --- a/InfoGenie-frontend/src/components/FullscreenEmbed.js +++ b/InfoGenie-frontend/src/components/FullscreenEmbed.js @@ -1,175 +1,7 @@ import React, { useState, useEffect, useCallback, useRef } from 'react'; import { createPortal } from 'react-dom'; -import styled, { keyframes, css } from 'styled-components'; import { FiArrowLeft, FiRefreshCw, FiAlertCircle } from 'react-icons/fi'; - -const slideUp = keyframes` - from { transform: translateY(100%); opacity: 0; } - to { transform: translateY(0); opacity: 1; } -`; - -const slideDown = keyframes` - from { transform: translateY(0); opacity: 1; } - to { transform: translateY(100%); opacity: 0; } -`; - -const spin = keyframes` - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } -`; - -const fadeIn = keyframes` - from { opacity: 0; } - to { opacity: 1; } -`; - -const Overlay = styled.div` - position: fixed; - inset: 0; - z-index: 999999; - display: flex; - flex-direction: column; - background: #fff; - font-family: inherit; - animation: ${({ $closing }) => $closing ? css`${slideDown} 0.25s ease-in forwards` : css`${slideUp} 0.3s ease-out`}; -`; - -const Header = styled.div` - display: flex; - align-items: center; - justify-content: space-between; - gap: 12px; - padding: 0 16px; - height: 52px; - flex-shrink: 0; - background: ${({ $color }) => $color}; - color: #fff; - box-shadow: 0 2px 8px rgba(0,0,0,0.12); - user-select: none; - -webkit-tap-highlight-color: transparent; -`; - -const HeaderTitle = styled.h1` - flex: 1; - margin: 0; - font-size: 16px; - font-weight: 600; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -`; - -const HeaderBtn = styled.button` - display: flex; - align-items: center; - justify-content: center; - gap: 5px; - height: 34px; - padding: 0 14px; - border: none; - border-radius: 8px; - background: rgba(255,255,255,0.18); - color: #fff; - font-size: 13px; - font-weight: 500; - cursor: pointer; - transition: background 0.2s; - flex-shrink: 0; - &:hover { background: rgba(255,255,255,0.3); } - &:active { background: rgba(255,255,255,0.1); } -`; - -const IframeWrapper = styled.div` - position: relative; - flex: 1; - overflow: hidden; -`; - -const StyledIframe = styled.iframe` - display: block; - width: 100%; - height: 100%; - border: none; - background: #fff; -`; - -const LoadingOverlay = styled.div` - position: absolute; - inset: 0; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 16px; - background: #fff; - animation: ${fadeIn} 0.15s ease-out; - z-index: 2; -`; - -const Spinner = styled.div` - width: 36px; - height: 36px; - border: 3px solid #e5e7eb; - border-top-color: ${({ $color }) => $color}; - border-radius: 50%; - animation: ${spin} 0.7s linear infinite; -`; - -const LoadingText = styled.p` - margin: 0; - font-size: 14px; - color: #9ca3af; -`; - -const ErrorOverlay = styled.div` - position: absolute; - inset: 0; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 16px; - background: #fff; - z-index: 2; - padding: 24px; - text-align: center; -`; - -const ErrorIcon = styled(FiAlertCircle)` - color: #ef4444; - font-size: 48px; -`; - -const ErrorTitle = styled.h2` - margin: 0; - font-size: 18px; - font-weight: 600; - color: #1f2937; -`; - -const ErrorDesc = styled.p` - margin: 0; - font-size: 14px; - color: #6b7280; - max-width: 320px; - line-height: 1.5; -`; - -const RetryButton = styled.button` - display: flex; - align-items: center; - gap: 6px; - padding: 10px 24px; - border: none; - border-radius: 10px; - background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); - color: #fff; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: transform 0.15s, box-shadow 0.15s; - &:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(74,222,128,0.35); } -`; +import clsx from 'clsx'; const LOAD_TIMEOUT_MS = 20000; @@ -255,20 +87,57 @@ const FullscreenEmbed = ({ }, [url, loading]); return createPortal( - -
- +
+ + + {/* Header */} +
+ +

+ {title} +

+
+ +
- - +