diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 26b9c6af..ebfc6cfa 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -21,7 +21,7 @@ "plugins": ["react", "@typescript-eslint", "prettier", "unused-imports"], "rules": { "react/react-in-jsx-scope": "off", - "prettier/prettier": "error", + "prettier/prettier": "off", "@typescript-eslint/no-explicit-any": "warn", "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "off", diff --git a/frontend/.gitignore b/frontend/.gitignore index d5e4b5bf..6f8231be 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -6,7 +6,7 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* - +.next/ node_modules dist market_dist diff --git a/frontend/cleanup-submodules.js b/frontend/cleanup-submodules.js new file mode 100644 index 00000000..ddee3d61 --- /dev/null +++ b/frontend/cleanup-submodules.js @@ -0,0 +1,42 @@ +const fs = require('fs'); +const path = require('path'); + +const srcDir = path.join(__dirname, 'src'); + +const filesToDelete = [ + 'package.json', + 'tsconfig.json', + 'tsconfig.node.json', + 'vite.config.ts', + 'postcss.config.js', + 'tailwind.config.js', + '.eslintrc.cjs', + 'index.html', + 'start-vite.js' +]; + +function walkDirAndClean(dir) { + if (!fs.existsSync(dir)) return; + + fs.readdirSync(dir).forEach(f => { + let dirPath = path.join(dir, f); + try { + let stat = fs.statSync(dirPath); + if (stat.isDirectory() && f !== 'node_modules') { + // If it's a top-level module directory like src/core, src/common + if (dir === srcDir) { + filesToDelete.forEach(file => { + const fileToDelete = path.join(dirPath, file); + if (fs.existsSync(fileToDelete)) { + fs.unlinkSync(fileToDelete); + console.log(`Deleted: ${fileToDelete}`); + } + }); + } + } + } catch(e) {} + }); +} + +walkDirAndClean(srcDir); +console.log('Cleanup completed!'); diff --git a/frontend/fix-css.js b/frontend/fix-css.js new file mode 100644 index 00000000..764270da --- /dev/null +++ b/frontend/fix-css.js @@ -0,0 +1,50 @@ +const fs = require('fs'); +const path = require('path'); + +const srcDir = path.join(__dirname, 'src'); + +function walkDir(dir, callback) { + if (dir.includes('node_modules')) return; + fs.readdirSync(dir).forEach(f => { + let dirPath = path.join(dir, f); + try { + let isDirectory = fs.statSync(dirPath).isDirectory(); + isDirectory ? walkDir(dirPath, callback) : callback(path.join(dir, f)); + } catch(e) {} + }); +} + +const filesToRename = []; +const filesToUpdate = []; + +walkDir(srcDir, (filePath) => { + if (filePath.endsWith('.module.css')) { + filesToRename.push(filePath); + } else if (filePath.endsWith('.tsx') || filePath.endsWith('.ts')) { + filesToUpdate.push(filePath); + } +}); + +filesToRename.forEach(oldPath => { + const newPath = oldPath.replace(/\.module\.css$/, '.css'); + + // Read and remove :global wrappers entirely + let content = fs.readFileSync(oldPath, 'utf8'); + content = content.replace(/:global\(([^)]+)\)/g, '$1'); // replace :global(.foo) with .foo + content = content.replace(/:global\s+/g, ''); // replace :global .foo with .foo + + fs.writeFileSync(oldPath, content); + fs.renameSync(oldPath, newPath); + console.log(`Renamed and cleaned: ${path.basename(oldPath)} -> ${path.basename(newPath)}`); +}); + +filesToUpdate.forEach(filePath => { + let content = fs.readFileSync(filePath, 'utf8'); + if (content.includes('.module.css')) { + content = content.replace(/\.module\.css/g, '.css'); + fs.writeFileSync(filePath, content); + console.log(`Updated imports in: ${path.basename(filePath)}`); + } +}); + +console.log('Done!'); diff --git a/frontend/lerna.json b/frontend/lerna.json deleted file mode 100644 index d4b5da5f..00000000 --- a/frontend/lerna.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "packages": [ - "packages/*" - ], - "version": "independent" - -} \ No newline at end of file diff --git a/frontend/migrate-to-next.js b/frontend/migrate-to-next.js new file mode 100644 index 00000000..3289e07f --- /dev/null +++ b/frontend/migrate-to-next.js @@ -0,0 +1,144 @@ +const fs = require('fs'); +const path = require('path'); + +const rootDir = __dirname; +const packagesDir = path.join(rootDir, 'packages'); +const srcDir = path.join(rootDir, 'src'); +const appDir = path.join(srcDir, 'app'); + +console.log('🚀 开始拆除 Lerna 并迁移至 Next.js...'); + +// 1. 创建基础目录 +if (!fs.existsSync(srcDir)) fs.mkdirSync(srcDir); +if (!fs.existsSync(appDir)) fs.mkdirSync(appDir); + +// 2. 读取并合并 package.json +const rootPkgPath = path.join(rootDir, 'package.json'); +const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, 'utf8')); + +const mergedDeps = { ...rootPkg.dependencies }; +const mergedDevDeps = { ...rootPkg.devDependencies }; + +if (fs.existsSync(packagesDir)) { + const packages = fs.readdirSync(packagesDir); + for (const pkg of packages) { + const pkgPath = path.join(packagesDir, pkg); + if (fs.statSync(pkgPath).isDirectory()) { + // 合并依赖 + const childPkgPath = path.join(pkgPath, 'package.json'); + if (fs.existsSync(childPkgPath)) { + const childPkg = JSON.parse(fs.readFileSync(childPkgPath, 'utf8')); + Object.assign(mergedDeps, childPkg.dependencies || {}); + Object.assign(mergedDevDeps, childPkg.devDependencies || {}); + } + // 移动目录到 src 下 + const destPath = path.join(srcDir, pkg); + if (!fs.existsSync(destPath)) { + fs.renameSync(pkgPath, destPath); + console.log(`📦 已迁移模块: packages/${pkg} -> src/${pkg}`); + } + } + } + // 删除空的 packages 文件夹 + try { fs.rmdirSync(packagesDir); } catch (e) { console.error('Failed to remove packages dir, skipping', e) } +} + +// 3. 清理并更新根 package.json +delete rootPkg.workspaces; // 移除 lerna workspaces +rootPkg.scripts = { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" +}; + +// 移除 Vite 和 Lerna 相关依赖 +const removeDeps = ['lerna', 'vite', '@originjs/vite-plugin-federation', '@vitejs/plugin-react', 'vite-tsconfig-paths']; +removeDeps.forEach(dep => { + delete mergedDeps[dep]; + delete mergedDevDeps[dep]; +}); + +// 添加 Next.js 和 React 最新核心依赖 (与 xroute-ui 对齐) +mergedDeps['next'] = "15.4.5"; +mergedDeps['react'] = "19.1.0"; +mergedDeps['react-dom'] = "19.1.0"; +mergedDevDeps['@types/react'] = "^19"; +mergedDevDeps['@types/react-dom'] = "^19"; + +rootPkg.dependencies = mergedDeps; +rootPkg.devDependencies = mergedDevDeps; + +fs.writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2)); +console.log('✅ package.json 依赖已合并并重写'); + +// 4. 生成 tsconfig.json (配置路径别名) +const tsconfigPath = path.join(rootDir, 'tsconfig.json'); +const tsconfig = { + compilerOptions: { + target: "es5", + lib: ["dom", "dom.iterable", "esnext"], + allowJs: true, + skipLibCheck: true, + strict: false, + noEmit: true, + esModuleInterop: true, + module: "esnext", + moduleResolution: "bundler", + resolveJsonModule: true, + isolatedModules: true, + jsx: "preserve", + incremental: true, + plugins: [{ name: "next" }], + baseUrl: ".", + paths: { + "@/*": ["src/*"], + // 欺骗原有代码,使其能找到拍平后的新路径 + "@apipark/common/*": ["src/common/src/*"], + "@apipark/core/*": ["src/core/src/*"], + "@apipark/dashboard/*": ["src/dashboard/src/*"], + "@apipark/market/*": ["src/market/src/*"], + "@apipark/openApi/*": ["src/openApi/src/*"], + "@apipark/systemRunning/*": ["src/systemRunning/src/*"] + } + }, + include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + exclude: ["node_modules"] +}; +fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2)); +console.log('✅ tsconfig.json 别名映射已配置'); + +// 5. 创建 Next.js App Router 挂载点 +const layoutCode = `export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +}`; +fs.writeFileSync(path.join(appDir, 'layout.tsx'), layoutCode); + +const slugDir = path.join(appDir, '[[...slug]]'); +if (!fs.existsSync(slugDir)) fs.mkdirSync(slugDir, { recursive: true }); + +const pageCode = `"use client"; +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; + +// 动态导入原有的 Vite SPA 根组件,禁用 SSR 避免 window 报错 +const ApiParkApp = dynamic(() => import('@/core/src/App'), { + ssr: false, + loading: () =>
Loading APIPark...
+}); + +export default function Page() { + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + + if (!mounted) return null; + return ; +}`; +fs.writeFileSync(path.join(slugDir, 'page.tsx'), pageCode); + +console.log('✅ Next.js 路由挂载点创建完毕!'); +console.log('🎉 迁移完成!请执行 pnpm install 重新安装依赖。'); \ No newline at end of file diff --git a/frontend/next-env.d.ts b/frontend/next-env.d.ts new file mode 100644 index 00000000..d5b60022 --- /dev/null +++ b/frontend/next-env.d.ts @@ -0,0 +1,4 @@ +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/frontend/next.config.js b/frontend/next.config.js new file mode 100644 index 00000000..2abbb07c --- /dev/null +++ b/frontend/next.config.js @@ -0,0 +1,42 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + images: { + disableStaticImages: true, + }, + experimental: { + optimizePackageImports: ["@heroui/react"], + }, + transpilePackages: ['@heroui/react', '@heroui/theme', '@ant-design', 'antd', 'rc-util', 'rc-pagination', 'rc-picker', 'rc-tree', 'rc-table'], + async rewrites() { + return [ + { + source: '/api/v1/:path*', + destination: 'http://172.18.166.219:8288/api/v1/:path*', // Proxy to backend + }, + { + source: '/api2/v1/:path*', + destination: 'http://172.18.166.219:8288/api2/v1/:path*', // Proxy to backend 2 + } + ]; + }, + webpack: (config) => { + config.module.rules.push({ + test: /\.(svg|png|jpe?g|gif|webp)$/i, + type: 'asset/resource', + generator: { + filename: 'static/media/[name].[hash][ext]' + } + }); + + // 解决一些 Node.js polyfill 在浏览器端缺失的问题 + config.resolve.fallback = { + ...config.resolve.fallback, + fs: false, + path: false, + os: false, + }; + return config; + }, +}; + +module.exports = nextConfig; diff --git a/frontend/package.json b/frontend/package.json index ac2f91d0..9a9c7f9b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,20 +2,12 @@ "name": "frontend", "version": "1.0.0", "private": true, - "workspaces": [ - "packages/*" - ], "description": "", "scripts": { - "test": "jest", - "build": "set NODE_OPTIONS=--max-old-space-size=8192 && lerna run build --scope=core --stream --verbose ", - "serve": "lerna run preview --parallel", - "serve:remotes": "lerna run serve --scope=remote --parallel", - "dev": "lerna run dev --scope=core --stream", - "stop": "kill-port --port 5000", - "scan": "i18next-scanner --config i18next-scanner.config.js", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix", - "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix && prettier --write ." + "dev": "next dev -p 5000", + "build": "next build", + "start": "next start -p 5000", + "lint": "next lint" }, "keywords": [], "author": "", @@ -23,51 +15,88 @@ "dependencies": { "@ant-design/icons": "^5.2.6", "@ant-design/pro-components": "2.7.19", - "@originjs/vite-plugin-federation": "^1.3.3", + "@emotion/react": "^11.14.0", + "@floating-ui/react": "^0.26.24", + "@formkit/auto-animate": "^0.8.1", + "@heroui/react": "^3.0.3", + "@heroui/styles": "^3.0.3", + "@heroui/theme": "^2.4.20", + "@lexical/code": "^0.17.1", + "@lexical/react": "^0.17.1", + "@lexical/selection": "^0.17.1", + "@lexical/text": "^0.17.1", + "@lexical/utils": "^0.17.1", + "@modelcontextprotocol/sdk": "^1.9.0", + "@mui/icons-material": "^5.15.6", + "@mui/lab": "5.0.0-alpha.150", + "@mui/material": "5.14.14", + "@mui/x-data-grid-pro": "6.18.1", "@rollup/plugin-dynamic-import-vars": "^2.1.2", + "@tinymce/tinymce-react": "^4.3.2", + "@types/dompurify": "^3.0.5", "@types/lodash-es": "^4.17.12", "@types/uuid": "^9.0.7", - "@vitejs/plugin-react": "^4.2.0", + "@xyflow/react": "^12.3.6", + "ahooks": "^3.8.1", + "allotment": "^1.20.0", "autoprefixer": "^10.4.16", + "copy-to-clipboard": "^3.3.3", "crc": "^4.3.2", "dayjs": "^1.11.10", "dompurify": "^3.1.6", + "echarts": "^5.5.0", + "echarts-for-react": "^3.0.2", + "framer-motion": "^10.16.4", + "fs-extra": "^11.2.0", + "highlight.js": "^11.9.0", "i18next": "^23.12.2", "i18next-browser-languagedetector": "^8.0.0", "js-base64": "^3.7.5", + "lexical": "^0.17.1", + "mockjs": "^1.1.0", + "next": "15.4.5", "postcss": "^8.4.31", "postcss-import": "^16.1.0", "postcss-nesting": "^12.1.5", - "react": "^18.2.0", + "rc-picker": "^4.1.1", + "react": "19.1.0", "react-ace": "^10.1.0", - "react-dom": "^18.2.0", + "react-dom": "19.1.0", + "react-dropzone": "^14.2.3", + "react-hook-form": "^7.49.3", "react-i18next": "^15.0.1", "react-joyride": "^2.8.2", - "react-router-dom": "6.20.0", - "swagger-ui-react": "^5.17.14", - "tailwindcss": "^3.3.5", - "uuid": "^9.0.1", - "vite-tsconfig-paths": "^4.3.2", "react-json-view": "^1.21.3", - "zod": "^3.23.8", - "@modelcontextprotocol/sdk": "^1.9.0", - "echarts-for-react": "^3.0.2" + "react-router-dom": "6.20.0", + "react-virtuoso": "^4.7.11", + "swagger-ui-react": "^5.17.14", + "tailwindcss": "^4.2.1", + "tinymce": "^6.8.1", + "use-context-selector": "^2.0.0", + "uuid": "^9.0.1", + "zod": "^3.23.8" }, "devDependencies": { "@ant-design/cssinjs": "^1.18.2", "@antv/g6": "^4.8.24", + "@formily/antd-v5": "^1.2.1", + "@formily/core": "^2.2.13", + "@formily/react": "^2.2.13", + "@formily/reactive": "^2.2.13", "@iconify/react": "^5.0.2", + "@monaco-editor/react": "^4.6.0", + "@tailwindcss/postcss": "^4.2.1", + "lightningcss": "^1.32.0", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/react-hooks": "^8.0.1", "@types/file-saver": "^2.0.7", "@types/jest": "^29.5.12", "@types/node": "^20.10.5", - "@types/react": "^18.2.37", - "@types/react-dom": "^18.2.15", + "@types/react": "^19", + "@types/react-dom": "^19", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", - "@vitejs/plugin-react": "^4.2.0", "antd": "^5.19.4", "babel-jest": "^29.7.0", "eslint": "^8.53.0", @@ -77,22 +106,22 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", "eslint-plugin-unused-imports": "^4.1.4", + "exceljs": "^4.4.0", "file-saver": "^2.0.5", "i18next-scanner": "^4.5.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", "jsdom": "^24.0.0", - "lerna": "^8.1.3", "less": "^4.2.0", "lodash": "^4.17.21", "lodash-es": "^4.17.21", + "monaco-editor": "^0.45.0", "postcss-nested": "^6.0.1", "prettier": "^3.1.1", "react-test-renderer": "^18.3.1", "ts-jest": "^29.1.2", "typescript": "^5.2.2", - "vite": "^5.0.0", "vite-jest": "^0.1.4" } -} +} \ No newline at end of file diff --git a/frontend/packages/common/package.json b/frontend/packages/common/package.json deleted file mode 100644 index 10dd7d44..00000000 --- a/frontend/packages/common/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "common", - "version": "1.0.0", - "description": "Common library for AO Platform", - "scripts": { - "dev": "vite", - "build": "vite build", - "test": "node ./__tests__/common.test.js" - }, - "dependencies": { - "@floating-ui/react": "^0.26.24", - "@formkit/auto-animate": "^0.8.1", - "@lexical/code": "^0.17.1", - "@lexical/react": "^0.17.1", - "@lexical/selection": "^0.17.1", - "@lexical/text": "^0.17.1", - "@lexical/utils": "^0.17.1", - "@mui/icons-material": "^5.15.6", - "@mui/lab": "5.0.0-alpha.150", - "@mui/material": "5.14.14", - "@mui/x-data-grid-pro": "6.18.1", - "ahooks": "^3.8.1", - "allotment": "^1.20.0", - "echarts": "^5.5.0", - "lexical": "^0.17.1", - "mockjs": "^1.1.0", - "rc-picker": "^4.1.1", - "react-dropzone": "^14.2.3", - "react-hook-form": "^7.49.3", - "use-context-selector": "^2.0.0" - }, - "devDependencies": { - "@formily/antd-v5": "^1.2.1", - "@formily/core": "^2.2.13", - "@formily/react": "^2.2.13", - "@formily/reactive": "^2.2.13", - "@monaco-editor/react": "^4.6.0", - "exceljs": "^4.4.0", - "monaco-editor": "^0.45.0" - } -} diff --git a/frontend/packages/common/postcss.config.js b/frontend/packages/common/postcss.config.js deleted file mode 100644 index 8610d836..00000000 --- a/frontend/packages/common/postcss.config.js +++ /dev/null @@ -1,10 +0,0 @@ - -export default { - plugins: { - 'postcss-import': {}, - 'tailwindcss/nesting': {}, - tailwindcss: {}, - autoprefixer: {} - }, - } - \ No newline at end of file diff --git a/frontend/packages/common/src/index.css b/frontend/packages/common/src/index.css deleted file mode 100644 index 79ce83c2..00000000 --- a/frontend/packages/common/src/index.css +++ /dev/null @@ -1,4 +0,0 @@ - -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file diff --git a/frontend/packages/common/src/monacoConfig.ts b/frontend/packages/common/src/monacoConfig.ts deleted file mode 100644 index 5ecafca1..00000000 --- a/frontend/packages/common/src/monacoConfig.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as monaco from 'monaco-editor' -import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' -import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' -import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' -import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' -import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' - -self.MonacoEnvironment = { - getWorker(_, label) { - if (label === 'json') { - return new jsonWorker() - } - if (label === 'css' || label === 'scss' || label === 'less') { - return new cssWorker() - } - if (label === 'html' || label === 'handlebars' || label === 'razor') { - return new htmlWorker() - } - if (label === 'typescript' || label === 'javascript') { - return new tsWorker() - } - return new editorWorker() - } -} - -export { monaco } diff --git a/frontend/packages/common/tailwind.config.js b/frontend/packages/common/tailwind.config.js deleted file mode 100644 index 5b8c5102..00000000 --- a/frontend/packages/common/tailwind.config.js +++ /dev/null @@ -1,98 +0,0 @@ - -/** @type {import('tailwindcss').Config} */ -module.exports = { - important:true, - content: [ - `../*/src/**/*.{js,ts,jsx,tsx}`, - ] - , - theme: { - extend: { - width: { - INPUT_NORMAL: '100%', - // INPUT_NORMAL: '346px', - INPUT_LARGE: '508px', - GROUP: '240px', - SEARCH: '276px', - LOG: '254px' - }, - minHeight:{ - TEXTAREA:'68px' - }, - borderRadius: { - DEFAULT: 'var(--border-radius)', - SEARCH_RADIUS: '50px' - }, - boxShadow:{ - SCROLL: '0 2px 2px #0000000d', - SCROLL_TOP:' 0 -2px 2px -2px var(--border-color)' - }, - colors: { - DISABLE_BG: 'var(--disabled-background-color)', - MAIN_TEXT: 'var(--text-color)', - MAIN_HOVER_TEXT: 'var(--text-hover-color)', - SECOND_TEXT:'var(--disabled-text-color)', - MAIN_BG: 'var(--background-color)', - MENU_BG:'var(--MENU-BG-COLOR)', - 'bar-theme': 'var(--bar-background-color)', - BORDER: 'var(--border-color)', - NAVBAR_BTN_BG: 'var(--item-active-background-color)', - MAIN_DISABLED_BG: 'var(--disabled-background-color)', - theme: 'var(--primary-color)', - DESC_TEXT: 'var(--TITLE_TEXT)', - HOVER_BG: 'var(--item-hover-background-color)', - guide_cluster: '#ee6760', - guide_upstream: '#f9a429', - guide_api: '#71d24d', - guide_publishApi: '#5884ff', - guide_final: '#915bf9', - table_text: 'var(--table-text-color)', - status_success:'#138913', - status_fail:"#ff3b30", - status_update:"#03a9f4", - status_pending:"#ffa500", - status_offline:"#8f8e93", - A_HOVER:'var(--button-primary-hover-background-color)' - }, - backgroundImage:{ - LAYOUT_BG:'linear-gradient(107.97deg, rgba(32,41,117,1) 4.41%,rgba(16,13,27,1) 86.11%)', - LAYOUT_BG_DARK:'#fff', - }, - spacing: { - mbase: 'var(--FORM_SPAN)', - label: '12px', // 选择器和label之间的间距,待删 - btnbase: 'var(--LAYOUT_MARGIN)', // x方向的间距 - btnybase: 'var(--LAYOUT_MARGIN)', // y轴方向的间距 - btnrbase: '20px', // 页面最右侧边距20px - formtop: 'var(--FORM_SPAN)', - icon: '5px', - blockbase: '40px', - DEFAULT_BORDER_RADIUS: 'var(--border-radius)', - TREE_TITLE:'var(--small-padding) var(--LAYOUT_PADDING);', - 'navbar-height': 'var(--layout-header-height)', - TAG_LEFT:'10px', - PAGE_INSIDE_X:'40px', - PAGE_INSIDE_T:'30px', - PAGE_INSIDE_B:'20px', - }, - borderColor: { - 'color-base': 'var(--border-color)' - } - } - }, - plugins: [ - function({ addUtilities }) { - addUtilities({ - '.h-calc-100vh-minus-navbar': { - height: 'calc(100vh - var(--layout-header-height))', - }, - '.w-calc-100vw-minus-padding-r': { - width: 'calc(100% - 40px)', - }, - }, ['responsive', 'hover']); - } - ], - corePlugins: { - preflight: false, - }, -} \ No newline at end of file diff --git a/frontend/packages/common/tsconfig.json b/frontend/packages/common/tsconfig.json deleted file mode 100644 index c121206d..00000000 --- a/frontend/packages/common/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - /* Linting */ - "strict": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noFallthroughCasesInSwitch": true, - "paths": { - "@common/*": ["./src/*"], - "@core/*": ["../core/src/*"], - "@market/*": ["../market/src/*"] - }, - }, - "references": [{ "path": "./tsconfig.node.json" }] -} diff --git a/frontend/packages/common/tsconfig.node.json b/frontend/packages/common/tsconfig.node.json deleted file mode 100644 index 42872c59..00000000 --- a/frontend/packages/common/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/frontend/packages/common/vite.config.ts b/frontend/packages/common/vite.config.ts deleted file mode 100644 index 76151496..00000000 --- a/frontend/packages/common/vite.config.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import path from 'path' -import dynamicImportVars from '@rollup/plugin-dynamic-import-vars' - -export default defineConfig({ - css: { - preprocessorOptions: { - less: { - javascriptEnabled: true - } - }, - modules: { - localsConvention: 'camelCase', - generateScopedName: '[local]_[hash:base64:2]' - } - }, - plugins: [ - react(), - dynamicImportVars({ - include: ['src'], - exclude: [], - warnOnError: false - }) - ], - resolve: { - alias: [ - { find: /^~/, replacement: '' }, - { find: '@common', replacement: path.resolve(__dirname, './src') }, - { find: '@market', replacement: path.resolve(__dirname, '/./market/src') }, - { find: '@core', replacement: path.resolve(__dirname, '../core/src') } - ] - }, - server: { - proxy: { - '/api/v1': { - // target: 'http://uat.apikit.com:11204/mockApi/aoplatform/', - target: 'http://172.18.166.219:8288/', - changeOrigin: true - }, - '/api2/v1': { - // target: 'http://uat.apikit.com:11204/mockApi/aoplatform/', - target: 'http://172.18.166.219:8288/', - changeOrigin: true - } - } - }, - logLevel: 'info' -}) diff --git a/frontend/packages/core/.env b/frontend/packages/core/.env deleted file mode 100644 index de1f4bed..00000000 --- a/frontend/packages/core/.env +++ /dev/null @@ -1 +0,0 @@ -VITE_APP_MODE=openSource \ No newline at end of file diff --git a/frontend/packages/core/.eslintrc.cjs b/frontend/packages/core/.eslintrc.cjs deleted file mode 100644 index 87e6dac6..00000000 --- a/frontend/packages/core/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs','public','code-snippet','ace-editor'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} diff --git a/frontend/packages/core/index.html b/frontend/packages/core/index.html deleted file mode 100644 index 1d0cbe88..00000000 --- a/frontend/packages/core/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
- - - - diff --git a/frontend/packages/core/package.json b/frontend/packages/core/package.json deleted file mode 100644 index 3e399c96..00000000 --- a/frontend/packages/core/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "core", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": " vite --mode open --port 5000 --strictPort", - "dev:pro": " vite --config ./vite.pro.config.ts --mode pro --port 5000 --strictPort ", - "build": "vite build --mode open", - "build:pro": "vite --config ./vite.pro.config.ts build --mode pro", - "postinstall": "node scripts/moveTinymce.js", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview --port 5000 --strictPort", - "serve": "vite preview --port 5000 --strictPort" - }, - "dependencies": { - "@tinymce/tinymce-react": "^4.3.2", - "@xyflow/react": "^12.3.6", - "fs-extra": "^11.2.0", - "highlight.js": "^11.9.0", - "tinymce": "^6.8.1" - } -} diff --git a/frontend/packages/core/postcss.config.js b/frontend/packages/core/postcss.config.js deleted file mode 100644 index 8610d836..00000000 --- a/frontend/packages/core/postcss.config.js +++ /dev/null @@ -1,10 +0,0 @@ - -export default { - plugins: { - 'postcss-import': {}, - 'tailwindcss/nesting': {}, - tailwindcss: {}, - autoprefixer: {} - }, - } - \ No newline at end of file diff --git a/frontend/packages/core/src/App.css b/frontend/packages/core/src/App.css deleted file mode 100644 index e5f6c0b2..00000000 --- a/frontend/packages/core/src/App.css +++ /dev/null @@ -1,309 +0,0 @@ -@tailwind base; -@tailwind components; - -@layer components { - .button-bottom-default { - @apply border-[0px] border-b-[1px] border-solid border-BORDER; - } -} - -@tailwind utilities; - - -#root { - width: 100vw; - height:100vh; -} - -:global.ant-tree-node-content-wrapper{ - overflow: hidden; -} -.tree-title-hover{ - display: flex; - justify-content: space-between; - align-items:center; - .tree-title-span{ - text-overflow: ellipsis; - } - .tree-title-more{ - display: none; - } - - &:hover .tree-title-more{ - display: flex; - height:22px; - width:22px; - } -} - - -.ant-layout-content.apipark-layout-layout-content{ - border-radius:10px 0 0 0 ; - overflow:hidden; - background-color:'transparent' -} - - -.apipark-layout-global-header-collapsed-button{ - color:hsl(0, 0%, 100%); -} - -.apipark-layout-top-nav-header-main{ - display: flex; - align-items: center; -} -.apipark-layout-top-nav-header-menu { - height:50px; - line-height:50px; - - .ant-menu-item.apipark-layout-base-menu-horizontal-menu-item.ant-menu-item-selected::after{ - border-bottom:2px solid #fff !important; - } - .ant-menu-item.apipark-layout-base-menu-horizontal-menu-item.ant-menu-item-active:not(.ant-menu-item-selected)::after{ - border-bottom:2px solid transparent !important; - } -} -.apipark-layout-base-menu-inline-group .ant-menu-item-group-title{ - color:rgb(255 255 255 / 70%) !important; -} -.avatar-dom > div{ - display: flex; - flex-direction: row-reverse; - align-items: center; - gap:8px; -} - -.apipark-layout-layout{ - - .apipark-layout-layout-bg-list{ - background-image: radial-gradient(circle farthest-corner at 450px 350px, #050eb7, #17163e 500px); - } - .ant-layout-header.apipark-layout-layout-header{ - backdrop-filter: unset !important; - height:var(--layout-header-height); - line-height: var(--layout-header-height); - background-color: transparent; - - li.apipark-layout-base-menu-horizontal-menu-item{ - color:rgb(255 255 255 / 70%) !important; - - &.ant-menu-item-selected{ - color:#fff !important; - } - &.ant-menu-item-active{ - color:#fff !important; - } - } - - li.ant-menu-submenu-horizontal.ant-menu-overflow-item-rest .ant-menu-submenu-title{ - color:#fff !important; - } - } - .ant-layout-sider.apipark-layout-sider{ - height:calc(100vh - var(--layout-header-height)) !important; - inset-block-start: var(--layout-header-height); - - .ant-menu { - .ant-menu-item-group-title{ - font-size:12px; - padding:12px 16px; - } - - .ant-menu-item{ - margin-block:0 !important; - } - .ant-menu-light:not(.ant-menu-horizontal) .ant-menu-item:not(.ant-menu-item-selected):active{ - background-color: unset; - } - } - - .apipark-layout-sider-collapsed-button{ - display: none; - } - - ul.ant-menu.ant-menu-root.ant-menu-inline, - ul.ant-menu.ant-menu-root.ant-menu-vertical{ - > li { - color:rgb(255 255 255 / 70%) !important; - /* border-radius: 10px; - background-color: rgba(255,255,255,0.1) !important; - border: 1px solid rgba(255,255,255,0.15); */ - } - > li.ant-menu-item-active { - color:#fff !important; - } - > li.ant-menu-item-selected { - background-color: #fff !important; - border: 1px solid #fff !important; - color:#333 !important; - } - } - ul.apipark-layout-sider-menu .ant-menu-item-group-list{ - > li { - color:rgb(255 255 255 / 70%) !important; - } - > li:active{ - background-color: transparent; - } - > li.ant-menu-item-active { - color:#fff !important; - } - > li.ant-menu-item-selected { - background-color: #fff !important; - border: 1px solid #fff !important; - color:#333 !important; - } - } - .ant-menu-item { - height:40px; - margin-block:10px; - } - } - .apipark-layout-drawer-sider{ - background:#17163E; - padding-top:20px; - .ant-layout-sider.apipark-layout-sider{ - height: 100% !important; - inset-block: 20px; - } - } - - .apipark-layout-layout-container{ - - >.ant-layout-header{ - height:var(--layout-header-height) !important; - line-height:var(--layout-header-height) !important; - } - - >.apipark-layout-layout-content.apipark-layout-layout-has-header{ - padding-block:0px; - padding-inline:0px; - background-color: #fff !important; - } - } - .ant-pro-global-header-header-actions-avatar > div{ - color:#fff !important; - } - - .ant-menu-item-divider.apipark-layout-base-menu-inline-divider{ - border-color: rgb(255 255 255 / 15%) !important; - } -} - -.tox-tinymce{ - border:none !important; -} - -a{ - transition:none !important; -} - -.ant-result ant-result-error{ - background-color: #fff !important; -} - -.ant-tabs-tab-btn{ - display: flex; - align-items:center; - .ant-tabs-tab-icon{ - display: inline-flex; - align-items:center; - } -} - -.eo_page_list .ant-pro-table{ - overflow: hidden; - border-radius: 10px; - border:1px solid var(--table-border-color) !important; -} - -.swagger-ui{ - width: 100%; - .model-box-control:focus,.models-control:focus, .opblock-summary-control:focus{ - outline:unset !important; - } - .information-container{ - .info{ - display: none; - } - - } -} - -.ant-pro-table .ant-popover .ant-popover-inner-content{ - .ant-form-item{ - background-color: transparent; - border:none; - } -} -.ant-menu .ant-menu-title-content{ - display:unset !important; -} - - -.ai-setting-svg-container svg{ - width: 100%; - height:100%; - display:block; -} -.ai-service-api-preview .swagger-ui h3.opblock-tag{ - display: none; -} - - /* 整个背景容器设置 */ - .background-container { - background: radial-gradient(ellipse 80% 900px at top, rgb(255 255 255 / 10%) 0%, rgb(4 0 71) 30%, rgb(13 17 23) 100%); - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100vh; - overflow: hidden; - z-index: 1; - isolate: isolate; - } - - /* SVG背景图案 */ - .background-pattern { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - stroke: rgba(255, 255, 255, 0.1); - mask-image: radial-gradient(100% 100% at top right, white, transparent); - } - - .login-block{ - background: rgba(255, 255, 255, 0.1) !important; - .login-input{ - color:#fff !important; - background: rgba(255, 255, 255, 0.1) !important; - border: 1px solid rgba(255, 255, 255, 0.1) !important; - &:hover, &:focus, &.ant-input-status-error, &.ant-input-status-error:hover, &.ant-input-status-error:focus-within{ - background: rgba(255, 255, 255, 0.2) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - } - } - - input:-webkit-autofill, - input:-webkit-autofill:focus { - transition: background-color 0s 600000s, color 0s 600000s !important; - } - } - - .ant-select-selection-overflow-item:first-child { - max-width: calc(100% - 60px); - margin-right: 4px; - } - - a[disabled]:hover { - color: #BBB; - cursor: not-allowed; - } - - .ant-input-group-addon{ - height:32px !important; - .ant-btn.ant-btn-default{ - height:32px !important; - } - } \ No newline at end of file diff --git a/frontend/packages/core/src/pages/mcpService/IntegrationAIContainer.tsx b/frontend/packages/core/src/pages/mcpService/IntegrationAIContainer.tsx deleted file mode 100644 index 55d428c1..00000000 --- a/frontend/packages/core/src/pages/mcpService/IntegrationAIContainer.tsx +++ /dev/null @@ -1,656 +0,0 @@ -import { App, Button, Card, CascaderProps, Empty, Select } from 'antd' -import { $t } from '@common/locales/index.ts' -import { Icon } from '@iconify/react/dist/iconify.js' -import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react' -import ReactJson from 'react-json-view' -import { IconButton } from '@common/components/postcat/api/IconButton' -import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const' -import { useFetch } from '@common/hooks/http' -import { useConnection } from './hook/useConnection' -import { ClientRequest, Tool, ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js' -import { z } from 'zod' -import { useNavigate } from 'react-router-dom' -import { ServiceDetailType } from '@market/const/serviceHub/type' -import useCopyToClipboard from '@common/hooks/copy' -import { useGlobalContext } from '@common/contexts/GlobalStateContext' -import { Cascader } from 'antd/lib' - -type ConfigList = { - openApi?: { - title: string - configContent: string - apiKeys: string[] - } - mcp: { - title: string - configContent: string - apiKeys: string[] - } -} - -type ApiKeyItem = { - expired: number - id: string - name: string - value: string -} -interface Option { - value: string - label: string - children?: Option[] -} - -type ServiceApiKeyList = { - id: string - name: string - apikeys: Array<{ - id: string - name: string - value: string - expired: number - }> -} - -type ConsumerParamsType = { - consumerId: string - teamId: string -} -export interface IntegrationAIContainerRef { - getServiceKeysList: () => void; -} -export interface IntegrationAIContainerProps { - type: 'global' | 'service' | 'consumer' - handleToolsChange: (value: Tool[]) => void - customClassName?: string - service?: ServiceDetailType - serviceId?: string - currentTab?: string - openModal?: (type: 'apply') => void - consumerParams?: ConsumerParamsType -} -export const IntegrationAIContainer = forwardRef( - ({ - type, - handleToolsChange, - customClassName, - service, - serviceId, - currentTab, - openModal, - consumerParams -}: IntegrationAIContainerProps, ref) => { - /** 当前激活的标签 */ - const [activeTab, setActiveTab] = useState(type === 'service' ? 'openApi' : 'mcp') - /** 弹窗组件 */ - const { message } = App.useApp() - /** 配置内容 */ - const [configContent, setConfigContent] = useState('') - /** 当前选中 API Key */ - const [apiKey, setApiKey] = useState('') - /** API Key 列表 */ - const [apiKeyList, setApiKeyList] = useState([]) - /** Cascader Key 列表 */ - const [cascaderKeyList, setCascaderKeyList] = useState([]) - /** MCP 服务器地址 */ - const [mcpServerUrl, setMcpServerUrl] = useState('') - /** 全局状态 */ - const { state } = useGlobalContext() - const navigator = useNavigate() - /** 复制组件 */ - const { copyToClipboard } = useCopyToClipboard() - /** 错误提示 */ - const [errors, setErrors] = useState>({ - resources: null, - prompts: null, - tools: null - }) - /** 标签内容 */ - const [tabContent, setTabContent] = useState({ - mcp: { - title: $t('MCP 配置'), - configContent: '', - apiKeys: [] - } - }) - /** HTTP 请求 */ - const { fetchData } = useFetch() - - /** - * 初始化标签数据 - */ - const initTabsData = () => { - const params: ConfigList = { - mcp: { - title: $t('MCP 配置'), - configContent: service?.mcpAccessConfig || '', - apiKeys: [] - } - } - if (type === 'service') { - params.openApi = { - title: $t('Open API 文档'), - configContent: service?.openapiAddress || '', - apiKeys: [] - } - } - setTabContent(params) - } - - /** - * 复制 - * @param value - * @returns - */ - const handleCopy = async (value: string): Promise => { - if (value) { - copyToClipboard(value) - message.success($t(RESPONSE_TIPS.copySuccess)) - } - } - - /** - * 选择 API Key - * @param value - */ - const handleSelectChange = (value: string) => { - setApiKey(value) - } - /** - * Cascader 选择 - * @param value - */ - const handleCascaderChange: CascaderProps