refactor: 重构代码减少any类型使用,增加类型定义 fix: 修复TypeScript编译错误和类型不匹配问题 docs: 更新代码审查修复总结文档 style: 优化代码格式和注释 perf: 添加性能优化工具函数和虚拟滚动组件 test: 完善测试相关配置和类型定义 build: 更新package-lock.json文件
2242 lines
226 KiB
JSON
2242 lines
226 KiB
JSON
{
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"pkg": {
|
||
"name": "dashboard",
|
||
"version": "1.0.0",
|
||
"private": true,
|
||
"scripts": {
|
||
"dev": "umi dev",
|
||
"build": "umi build",
|
||
"postinstall": "umi setup",
|
||
"setup": "umi setup",
|
||
"start": "npm run dev"
|
||
},
|
||
"dependencies": {
|
||
"@ant-design/charts": "^2.6.7",
|
||
"@ant-design/icons": "^5.2.6",
|
||
"@ant-design/plots": "^2.6.8",
|
||
"@antv/g6": "^5.0.51",
|
||
"@antv/l7": "^2.25.2",
|
||
"@antv/l7-react": "^2.4.3",
|
||
"antd": "^5.12.2",
|
||
"axios": "^1.13.6",
|
||
"moment": "^2.30.1",
|
||
"react": "^18.2.0",
|
||
"react-dom": "^18.2.0",
|
||
"react-responsive": "^10.0.1",
|
||
"recharts": "^3.8.0",
|
||
"umi": "^4.0.0"
|
||
},
|
||
"devDependencies": {
|
||
"@types/react": "^18.2.0",
|
||
"@types/react-dom": "^18.2.0",
|
||
"msw": "^2.12.13",
|
||
"typescript": "^5.9.3"
|
||
}
|
||
},
|
||
"pkgPath": "D:\\trae_projects\\makemd\\makemd\\dashboard\\package.json",
|
||
"plugins": {
|
||
"./node_modules/@umijs/core/dist/service/servicePlugin": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "preset",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/core/dist/service/servicePlugin.js",
|
||
"id": "./node_modules/@umijs/core/dist/service/servicePlugin",
|
||
"key": "servicePlugin",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"@umijs/preset-umi": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "preset",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/index.js",
|
||
"id": "@umijs/preset-umi",
|
||
"key": "umi",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 21
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/registerMethods": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/registerMethods.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/registerMethods",
|
||
"key": "registerMethods",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"onStart": [
|
||
0
|
||
]
|
||
},
|
||
"register": 5
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"@umijs/did-you-know": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/did-you-know/dist/plugin.js",
|
||
"id": "@umijs/did-you-know",
|
||
"key": "umijsDidYouKnow",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"onStart": [
|
||
3
|
||
]
|
||
},
|
||
"register": 3
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/404/404": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/404/404.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/404/404",
|
||
"key": "404",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"modifyRoutes": [
|
||
0
|
||
]
|
||
},
|
||
"register": 0
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/aiDev/aiDev": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/aiDev/aiDev.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/aiDev/aiDev",
|
||
"key": "aiDev",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 4
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/appData/appData": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/appData/appData.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/appData/appData",
|
||
"key": "appData",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"modifyAppData": [
|
||
25
|
||
]
|
||
},
|
||
"register": 37
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/appData/umiInfo": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/appData/umiInfo.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/appData/umiInfo",
|
||
"key": "umiInfo",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/check/check": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/check/check.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/check/check",
|
||
"key": "check",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"onCheckConfig": [
|
||
0
|
||
],
|
||
"onCheck": [
|
||
0
|
||
]
|
||
},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/check/babel722": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/check/babel722.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/check/babel722",
|
||
"key": "babel722",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"onCheck": [
|
||
1
|
||
]
|
||
},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/codeSplitting/codeSplitting": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/codeSplitting/codeSplitting.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/codeSplitting/codeSplitting",
|
||
"key": "codeSplitting",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/configPlugins/configPlugins": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/configPlugins/configPlugins.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/configPlugins/configPlugins",
|
||
"key": "configPlugins",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"modifyConfig": [
|
||
0
|
||
]
|
||
},
|
||
"register": 16
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"virtual: config-title": {
|
||
"id": "virtual: config-title",
|
||
"key": "title",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-styles": {
|
||
"id": "virtual: config-styles",
|
||
"key": "styles",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-scripts": {
|
||
"id": "virtual: config-scripts",
|
||
"key": "scripts",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-routes": {
|
||
"id": "virtual: config-routes",
|
||
"key": "routes",
|
||
"config": {
|
||
"onChange": "regenerateTmpFiles"
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-routeLoader": {
|
||
"id": "virtual: config-routeLoader",
|
||
"key": "routeLoader",
|
||
"config": {
|
||
"default": {
|
||
"moduleType": "esm"
|
||
}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-reactRouter5Compat": {
|
||
"id": "virtual: config-reactRouter5Compat",
|
||
"key": "reactRouter5Compat",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-presets": {
|
||
"id": "virtual: config-presets",
|
||
"key": "presets",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-plugins": {
|
||
"id": "virtual: config-plugins",
|
||
"key": "plugins",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-npmClient": {
|
||
"id": "virtual: config-npmClient",
|
||
"key": "npmClient",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-mountElementId": {
|
||
"id": "virtual: config-mountElementId",
|
||
"key": "mountElementId",
|
||
"config": {
|
||
"default": "root"
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-metas": {
|
||
"id": "virtual: config-metas",
|
||
"key": "metas",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-links": {
|
||
"id": "virtual: config-links",
|
||
"key": "links",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-historyWithQuery": {
|
||
"id": "virtual: config-historyWithQuery",
|
||
"key": "historyWithQuery",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-history": {
|
||
"id": "virtual: config-history",
|
||
"key": "history",
|
||
"config": {
|
||
"default": {
|
||
"type": "browser"
|
||
}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-headScripts": {
|
||
"id": "virtual: config-headScripts",
|
||
"key": "headScripts",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-esbuildMinifyIIFE": {
|
||
"id": "virtual: config-esbuildMinifyIIFE",
|
||
"key": "esbuildMinifyIIFE",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-conventionRoutes": {
|
||
"id": "virtual: config-conventionRoutes",
|
||
"key": "conventionRoutes",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-conventionLayout": {
|
||
"id": "virtual: config-conventionLayout",
|
||
"key": "conventionLayout",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-base": {
|
||
"id": "virtual: config-base",
|
||
"key": "base",
|
||
"config": {
|
||
"default": "/"
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-analyze": {
|
||
"id": "virtual: config-analyze",
|
||
"key": "analyze",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-writeToDisk": {
|
||
"id": "virtual: config-writeToDisk",
|
||
"key": "writeToDisk",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-transformRuntime": {
|
||
"id": "virtual: config-transformRuntime",
|
||
"key": "transformRuntime",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-theme": {
|
||
"id": "virtual: config-theme",
|
||
"key": "theme",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-targets": {
|
||
"id": "virtual: config-targets",
|
||
"key": "targets",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-svgr": {
|
||
"id": "virtual: config-svgr",
|
||
"key": "svgr",
|
||
"config": {
|
||
"default": {}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-svgo": {
|
||
"id": "virtual: config-svgo",
|
||
"key": "svgo",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-stylusLoader": {
|
||
"id": "virtual: config-stylusLoader",
|
||
"key": "stylusLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-styleLoader": {
|
||
"id": "virtual: config-styleLoader",
|
||
"key": "styleLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-srcTranspilerOptions": {
|
||
"id": "virtual: config-srcTranspilerOptions",
|
||
"key": "srcTranspilerOptions",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-srcTranspiler": {
|
||
"id": "virtual: config-srcTranspiler",
|
||
"key": "srcTranspiler",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-sassLoader": {
|
||
"id": "virtual: config-sassLoader",
|
||
"key": "sassLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-runtimePublicPath": {
|
||
"id": "virtual: config-runtimePublicPath",
|
||
"key": "runtimePublicPath",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-purgeCSS": {
|
||
"id": "virtual: config-purgeCSS",
|
||
"key": "purgeCSS",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-publicPath": {
|
||
"id": "virtual: config-publicPath",
|
||
"key": "publicPath",
|
||
"config": {
|
||
"default": "/"
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-proxy": {
|
||
"id": "virtual: config-proxy",
|
||
"key": "proxy",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-postcssLoader": {
|
||
"id": "virtual: config-postcssLoader",
|
||
"key": "postcssLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-outputPath": {
|
||
"id": "virtual: config-outputPath",
|
||
"key": "outputPath",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-normalCSSLoaderModules": {
|
||
"id": "virtual: config-normalCSSLoaderModules",
|
||
"key": "normalCSSLoaderModules",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-mfsu": {
|
||
"id": "virtual: config-mfsu",
|
||
"key": "mfsu",
|
||
"config": {
|
||
"default": {
|
||
"strategy": "eager"
|
||
}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-mdx": {
|
||
"id": "virtual: config-mdx",
|
||
"key": "mdx",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-manifest": {
|
||
"id": "virtual: config-manifest",
|
||
"key": "manifest",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-lessLoader": {
|
||
"id": "virtual: config-lessLoader",
|
||
"key": "lessLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-jsMinifierOptions": {
|
||
"id": "virtual: config-jsMinifierOptions",
|
||
"key": "jsMinifierOptions",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-jsMinifier": {
|
||
"id": "virtual: config-jsMinifier",
|
||
"key": "jsMinifier",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-inlineLimit": {
|
||
"id": "virtual: config-inlineLimit",
|
||
"key": "inlineLimit",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-ignoreMomentLocale": {
|
||
"id": "virtual: config-ignoreMomentLocale",
|
||
"key": "ignoreMomentLocale",
|
||
"config": {
|
||
"default": true
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-https": {
|
||
"id": "virtual: config-https",
|
||
"key": "https",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-hash": {
|
||
"id": "virtual: config-hash",
|
||
"key": "hash",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-forkTSChecker": {
|
||
"id": "virtual: config-forkTSChecker",
|
||
"key": "forkTSChecker",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-fastRefresh": {
|
||
"id": "virtual: config-fastRefresh",
|
||
"key": "fastRefresh",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-extraPostCSSPlugins": {
|
||
"id": "virtual: config-extraPostCSSPlugins",
|
||
"key": "extraPostCSSPlugins",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-extraBabelPresets": {
|
||
"id": "virtual: config-extraBabelPresets",
|
||
"key": "extraBabelPresets",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-extraBabelPlugins": {
|
||
"id": "virtual: config-extraBabelPlugins",
|
||
"key": "extraBabelPlugins",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-extraBabelIncludes": {
|
||
"id": "virtual: config-extraBabelIncludes",
|
||
"key": "extraBabelIncludes",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-externals": {
|
||
"id": "virtual: config-externals",
|
||
"key": "externals",
|
||
"config": {
|
||
"default": {}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-esm": {
|
||
"id": "virtual: config-esm",
|
||
"key": "esm",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-devtool": {
|
||
"id": "virtual: config-devtool",
|
||
"key": "devtool",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-depTranspiler": {
|
||
"id": "virtual: config-depTranspiler",
|
||
"key": "depTranspiler",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-define": {
|
||
"id": "virtual: config-define",
|
||
"key": "define",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-deadCode": {
|
||
"id": "virtual: config-deadCode",
|
||
"key": "deadCode",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cssPublicPath": {
|
||
"id": "virtual: config-cssPublicPath",
|
||
"key": "cssPublicPath",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cssMinifierOptions": {
|
||
"id": "virtual: config-cssMinifierOptions",
|
||
"key": "cssMinifierOptions",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cssMinifier": {
|
||
"id": "virtual: config-cssMinifier",
|
||
"key": "cssMinifier",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cssLoaderModules": {
|
||
"id": "virtual: config-cssLoaderModules",
|
||
"key": "cssLoaderModules",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cssLoader": {
|
||
"id": "virtual: config-cssLoader",
|
||
"key": "cssLoader",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-copy": {
|
||
"id": "virtual: config-copy",
|
||
"key": "copy",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-checkDepCssModules": {
|
||
"id": "virtual: config-checkDepCssModules",
|
||
"key": "checkDepCssModules",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-chainWebpack": {
|
||
"id": "virtual: config-chainWebpack",
|
||
"key": "chainWebpack",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-cacheDirectoryPath": {
|
||
"id": "virtual: config-cacheDirectoryPath",
|
||
"key": "cacheDirectoryPath",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-babelLoaderCustomize": {
|
||
"id": "virtual: config-babelLoaderCustomize",
|
||
"key": "babelLoaderCustomize",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-autoprefixer": {
|
||
"id": "virtual: config-autoprefixer",
|
||
"key": "autoprefixer",
|
||
"config": {},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-autoCSSModules": {
|
||
"id": "virtual: config-autoCSSModules",
|
||
"key": "autoCSSModules",
|
||
"config": {
|
||
"default": true
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"virtual: config-alias": {
|
||
"id": "virtual: config-alias",
|
||
"key": "alias",
|
||
"config": {
|
||
"default": {
|
||
"umi": "@@/exports",
|
||
"react": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react",
|
||
"react-dom": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-dom",
|
||
"react-router": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-router",
|
||
"react-router-dom": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-router-dom"
|
||
}
|
||
},
|
||
"type": "plugin",
|
||
"enableBy": "register",
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 0
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/crossorigin/crossorigin": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/crossorigin/crossorigin.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/crossorigin/crossorigin",
|
||
"key": "crossorigin",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/depsOnDemand/depsOnDemand": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/depsOnDemand/depsOnDemand.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/depsOnDemand/depsOnDemand",
|
||
"key": "depsOnDemand",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"onStart": [
|
||
1
|
||
]
|
||
},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/devTool/devTool": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/devTool/devTool.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/devTool/devTool",
|
||
"key": "devTool",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/esbuildHelperChecker/esbuildHelperChecker": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/esbuildHelperChecker/esbuildHelperChecker.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/esbuildHelperChecker/esbuildHelperChecker",
|
||
"key": "esbuildHelperChecker",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 128
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/esmi/esmi": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/esmi/esmi.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/esmi/esmi",
|
||
"key": "esmi",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 83
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/exportStatic/exportStatic": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/exportStatic/exportStatic.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/exportStatic/exportStatic",
|
||
"key": "exportStatic",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 37
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/favicons/favicons": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/favicons/favicons.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/favicons/favicons",
|
||
"key": "favicons",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"modifyAppData": [
|
||
0
|
||
]
|
||
},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/helmet/helmet": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/helmet/helmet.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/helmet/helmet",
|
||
"key": "helmet",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/icons/icons": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/icons/icons.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/icons/icons",
|
||
"key": "icons",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 7
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/mock/mock": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/mock/mock.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/mock/mock",
|
||
"key": "mock",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 72
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/mpa/mpa": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/mpa/mpa.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/mpa/mpa",
|
||
"key": "mpa",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/okam/okam": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/okam/okam.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/okam/okam",
|
||
"key": "okam",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/overrides/overrides": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/overrides/overrides.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/overrides/overrides",
|
||
"key": "overrides",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/phantomDependency/phantomDependency": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/phantomDependency/phantomDependency.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/phantomDependency/phantomDependency",
|
||
"key": "phantomDependency",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/polyfill/polyfill": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/polyfill/polyfill.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/polyfill/polyfill",
|
||
"key": "polyfill",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"modifyConfig": [
|
||
1
|
||
]
|
||
},
|
||
"register": 5
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/polyfill/publicPathPolyfill": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/polyfill/publicPathPolyfill.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/polyfill/publicPathPolyfill",
|
||
"key": "publicPathPolyfill",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/prepare/prepare": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/prepare/prepare.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/prepare/prepare",
|
||
"key": "prepare",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 15
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/routePrefetch/routePrefetch": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/routePrefetch/routePrefetch.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/routePrefetch/routePrefetch",
|
||
"key": "routePrefetch",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/stagewise/stagewise": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/stagewise/stagewise.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/stagewise/stagewise",
|
||
"key": "stagewise",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/terminal/terminal": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/terminal/terminal.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/terminal/terminal",
|
||
"key": "terminal",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/tmpFiles/tmpFiles": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/tmpFiles/tmpFiles.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/tmpFiles/tmpFiles",
|
||
"key": "tmpFiles",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 11
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/clientLoader/clientLoader": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/clientLoader/clientLoader.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/clientLoader/clientLoader",
|
||
"key": "clientLoader",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/routeProps/routeProps": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/routeProps/routeProps.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/routeProps/routeProps",
|
||
"key": "routeProps",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/ssr/ssr": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/ssr/ssr.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/ssr/ssr",
|
||
"key": "ssr",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 9
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/tmpFiles/configTypes": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/tmpFiles/configTypes.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/tmpFiles/configTypes",
|
||
"key": "configTypes",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 6
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/transform/transform": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/transform/transform.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/transform/transform",
|
||
"key": "transform",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 25
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/lowImport/lowImport": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/lowImport/lowImport.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/lowImport/lowImport",
|
||
"key": "lowImport",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 6
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/vite/vite": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/vite/vite.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/vite/vite",
|
||
"key": "vite",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/apiRoute/apiRoute": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/apiRoute/apiRoute.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/apiRoute/apiRoute",
|
||
"key": "apiRoute",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 17
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/monorepo/redirect": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/monorepo/redirect.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/monorepo/redirect",
|
||
"key": "monorepoRedirect",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 75
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/test/test": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/test/test.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/test/test",
|
||
"key": "test",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 4
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/clickToComponent/clickToComponent": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/clickToComponent/clickToComponent.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/clickToComponent/clickToComponent",
|
||
"key": "clickToComponent",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/legacy/legacy": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/legacy/legacy.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/legacy/legacy",
|
||
"key": "legacy",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 4
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/classPropertiesLoose/classPropertiesLoose": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/classPropertiesLoose/classPropertiesLoose.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/classPropertiesLoose/classPropertiesLoose",
|
||
"key": "classPropertiesLoose",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/webpack/webpack": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/webpack/webpack.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/webpack/webpack",
|
||
"key": "preset-umi:webpack",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/swc/swc": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/swc/swc.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/swc/swc",
|
||
"key": "swc",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {
|
||
"addOnDemandDeps": [
|
||
0
|
||
]
|
||
},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/ui/ui": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/ui/ui.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/ui/ui",
|
||
"key": "ui",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 8
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/mako/mako": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/mako/mako.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/mako/mako",
|
||
"key": "mako",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/utoopack/utoopack": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/utoopack/utoopack.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/utoopack/utoopack",
|
||
"key": "utoopack",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/hmrGuardian/hmrGuardian": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/hmrGuardian/hmrGuardian.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/hmrGuardian/hmrGuardian",
|
||
"key": "hmrGuardian",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 5
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/routePreloadOnLoad/routePreloadOnLoad": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/routePreloadOnLoad/routePreloadOnLoad.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/routePreloadOnLoad/routePreloadOnLoad",
|
||
"key": "routePreloadOnLoad",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 61
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/forget/forget": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/forget/forget.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/forget/forget",
|
||
"key": "forget",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "config"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/features/bundler/bundler": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/features/bundler/bundler.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/features/bundler/bundler",
|
||
"key": "preset-umi:bundler",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 5
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/build": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/build.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/build",
|
||
"key": "build",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 9
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/config/config": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/config/config.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/config/config",
|
||
"key": "config",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 78
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/dev/dev": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/dev/dev.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/dev/dev",
|
||
"key": "dev",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 144
|
||
}
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/help": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/help.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/help",
|
||
"key": "help",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/lint": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/lint.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/lint",
|
||
"key": "lint",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/setup": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/setup.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/setup",
|
||
"key": "setup",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/deadcode": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/deadcode.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/deadcode",
|
||
"key": "deadcode",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/version": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/version.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/version",
|
||
"key": "version",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/page": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/page.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/page",
|
||
"key": "generator:page",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 4
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/prettier": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/prettier.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/prettier",
|
||
"key": "generator:prettier",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/tsconfig": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/tsconfig.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/tsconfig",
|
||
"key": "generator:tsconfig",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 3
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/jest": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/jest.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/jest",
|
||
"key": "generator:jest",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/tailwindcss": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/tailwindcss.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/tailwindcss",
|
||
"key": "generator:tailwindcss",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/dva": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/dva.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/dva",
|
||
"key": "generator:dva",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/component": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/component.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/component",
|
||
"key": "generator:component",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/mock": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/mock.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/mock",
|
||
"key": "generator:mock",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/cypress": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/cypress.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/cypress",
|
||
"key": "generator:cypress",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/api": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/api.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/api",
|
||
"key": "generator:api",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/generators/precommit": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/generators/precommit.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/generators/precommit",
|
||
"key": "generator:precommit",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/plugin": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/plugin.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/plugin",
|
||
"key": "command:plugin",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/verify-commit": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/verify-commit.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/verify-commit",
|
||
"key": "verifyCommit",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/preview": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/preview.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/preview",
|
||
"key": "preview",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 40
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/preset-umi/dist/commands/mfsu/mfsu": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/preset-umi/dist/commands/mfsu/mfsu.js",
|
||
"id": "./node_modules/@umijs/preset-umi/dist/commands/mfsu/mfsu",
|
||
"key": "mfsu-cli",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 2
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"@umijs/plugin-run": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/plugin-run/dist/index.js",
|
||
"id": "@umijs/plugin-run",
|
||
"key": "run",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 7
|
||
},
|
||
"enableBy": "register"
|
||
},
|
||
"./node_modules/@umijs/core/dist/service/generatePlugin": {
|
||
"cwd": "D:\\trae_projects\\makemd\\makemd\\dashboard",
|
||
"type": "plugin",
|
||
"path": "D:/trae_projects/makemd/makemd/dashboard/node_modules/@umijs/core/dist/service/generatePlugin.js",
|
||
"id": "./node_modules/@umijs/core/dist/service/generatePlugin",
|
||
"key": "generatePlugin",
|
||
"config": {},
|
||
"time": {
|
||
"hooks": {},
|
||
"register": 1
|
||
},
|
||
"enableBy": "register"
|
||
}
|
||
},
|
||
"presets": [],
|
||
"name": "setup",
|
||
"args": {
|
||
"_": []
|
||
},
|
||
"userConfig": {
|
||
"routes": [
|
||
{
|
||
"path": "/",
|
||
"component": "@/pages/Homepage",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/pricing",
|
||
"component": "@/pages/Pricing",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/case-study",
|
||
"component": "@/pages/CaseStudy",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/case-study/:id",
|
||
"component": "@/pages/CaseStudy",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/auth",
|
||
"layout": false,
|
||
"routes": [
|
||
{
|
||
"path": "login",
|
||
"component": "@/pages/Auth/LoginPage"
|
||
},
|
||
{
|
||
"path": "register",
|
||
"component": "@/pages/Auth/RegisterPage"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"path": "/dashboard",
|
||
"layout": "@/layouts/index",
|
||
"routes": [
|
||
{
|
||
"path": "",
|
||
"component": "@/pages/OperationAgent"
|
||
},
|
||
{
|
||
"path": "operation-agent",
|
||
"component": "@/pages/OperationAgent"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"fastRefresh": true
|
||
},
|
||
"mainConfigFile": "D:\\trae_projects\\makemd\\makemd\\dashboard\\.umirc.ts",
|
||
"config": {
|
||
"routeLoader": {
|
||
"moduleType": "esm"
|
||
},
|
||
"mountElementId": "root",
|
||
"history": {
|
||
"type": "browser"
|
||
},
|
||
"base": "/",
|
||
"svgr": {},
|
||
"publicPath": "/",
|
||
"mfsu": {
|
||
"strategy": "eager"
|
||
},
|
||
"ignoreMomentLocale": true,
|
||
"externals": {},
|
||
"autoCSSModules": true,
|
||
"alias": {
|
||
"umi": "@@/exports",
|
||
"react": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react",
|
||
"react-dom": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-dom",
|
||
"react-router": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-router",
|
||
"react-router-dom": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-router-dom",
|
||
"@": "D:/trae_projects/makemd/makemd/dashboard/src",
|
||
"@@": "D:/trae_projects/makemd/makemd/dashboard/src/.umi",
|
||
"regenerator-runtime": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\regenerator-runtime"
|
||
},
|
||
"routes": [
|
||
{
|
||
"path": "/",
|
||
"component": "@/pages/Homepage",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/pricing",
|
||
"component": "@/pages/Pricing",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/case-study",
|
||
"component": "@/pages/CaseStudy",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/case-study/:id",
|
||
"component": "@/pages/CaseStudy",
|
||
"layout": false
|
||
},
|
||
{
|
||
"path": "/auth",
|
||
"layout": false,
|
||
"routes": [
|
||
{
|
||
"path": "login",
|
||
"component": "@/pages/Auth/LoginPage"
|
||
},
|
||
{
|
||
"path": "register",
|
||
"component": "@/pages/Auth/RegisterPage"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"path": "/dashboard",
|
||
"layout": "@/layouts/index",
|
||
"routes": [
|
||
{
|
||
"path": "",
|
||
"component": "@/pages/OperationAgent"
|
||
},
|
||
{
|
||
"path": "operation-agent",
|
||
"component": "@/pages/OperationAgent"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"fastRefresh": true,
|
||
"targets": {
|
||
"chrome": 80
|
||
}
|
||
},
|
||
"routes": {
|
||
"1": {
|
||
"path": "/",
|
||
"layout": false,
|
||
"file": "@/pages/Homepage.tsx",
|
||
"id": "1",
|
||
"absPath": "/",
|
||
"__content": "import React, { useState, useEffect } from 'react';\nimport { Link, useNavigate } from 'umi';\nimport { Button, Typography, Row, Col, Card, Divider } from 'antd';\nimport { ArrowRightOutlined, CheckCircleOutlined, MenuOutlined, XOutlined, TwitterOutlined, LinkedinOutlined, GithubOutlined } from '@ant-design/icons';\nimport Navbar from '@/components/Navbar';\n\nconst { Title, Paragraph, Text } = Typography;\n\nconst Homepage: React.FC = () => {\n const navigate = useNavigate();\n const [isScrolled, setIsScrolled] = useState(false);\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n\n useEffect(() => {\n const handleScroll = () => {\n setIsScrolled(window.scrollY > 50);\n };\n window.addEventListener('scroll', handleScroll);\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n const features = [\n {\n title: '智能选品系统',\n description: '基于AI的商品推荐,自动识别高潜力商品,提升选品效率',\n },\n {\n title: 'AI动态定价',\n description: '实时市场分析,优化定价策略,最大化利润',\n },\n {\n title: '自动上架系统',\n description: '一键批量上架,节省人工成本,提高运营效率',\n },\n {\n title: '跨平台套利',\n description: '发现价格差异,实现利润最大化,降低运营风险',\n },\n {\n title: 'AI店铺托管',\n description: '24/7智能运营,解放人力,提升店铺表现',\n },\n {\n title: '多商户管理',\n description: '集中管理多店铺,数据一目了然,简化管理流程',\n },\n ];\n\n const stats = [\n { title: '平均提升', value: '30%', suffix: '运营效率' },\n { title: '平均提升', value: '25%', suffix: '利润率' },\n { title: '支持商户', value: '1000+', suffix: '同时在线' },\n ];\n\n return (\n <div className=\"homepage\" style={{ \n fontFamily: '-apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, \\'Helvetica Neue\\', Arial, sans-serif',\n overflowX: 'hidden'\n }}>\n <Navbar />\n\n {/* 英雄区 */}\n <section className=\"hero\" style={{ \n padding: '180px 0 120px', \n background: 'linear-gradient(135deg, #0a192f 0%, #172a45 100%)',\n position: 'relative',\n overflow: 'hidden'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: 'radial-gradient(circle at 25% 25%, rgba(24, 144, 255, 0.15) 0%, transparent 50%), radial-gradient(circle at 75% 75%, rgba(54, 207, 201, 0.15) 0%, transparent 50%)',\n zIndex: 1\n }} />\n {/* 网格背景 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: 'linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px)',\n backgroundSize: '40px 40px',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <Row align=\"middle\" gutter={[48, 48]}>\n <Col xs={24} md={12} style={{ textAlign: 'left' }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(24, 144, 255, 0.15)', \n color: '#1890ff', \n padding: '10px 20px', \n borderRadius: '25px', \n fontSize: '14px', \n fontWeight: '600',\n marginBottom: '32px',\n boxShadow: '0 4px 12px rgba(24, 144, 255, 0.15)'\n }}>\n AI驱动 · 智能运营\n </div>\n <Title level={1} style={{ \n color: '#fff', \n marginBottom: '32px', \n fontSize: '56px', \n fontWeight: 'bold',\n lineHeight: '1.1'\n }}>\n 重新定义跨境电商\n </Title>\n <Paragraph style={{ \n color: 'rgba(255, 255, 255, 0.8)', \n marginBottom: '48px', \n fontSize: '20px',\n lineHeight: '1.6'\n }}>\n 利用人工智能和自动化技术,帮助您实现从选品到运营的全流程智能化,提升效率,降低成本,实现业务增长\n </Paragraph>\n <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>\n <Button \n type=\"primary\" \n size=\"large\" \n onClick={() => navigate('/auth/register')}\n style={{\n padding: '16px 40px', \n fontSize: '18px',\n borderRadius: '30px',\n boxShadow: '0 8px 24px rgba(24, 144, 255, 0.4)',\n transition: 'all 0.3s ease',\n '&:hover': {\n transform: 'translateY(-3px)',\n boxShadow: '0 12px 32px rgba(24, 144, 255, 0.5)'\n }\n }}\n >\n 免费注册\n </Button>\n <Button \n size=\"large\" \n onClick={() => navigate('/pricing')}\n style={{\n padding: '16px 40px', \n fontSize: '18px',\n borderRadius: '30px',\n background: 'rgba(255, 255, 255, 0.1)',\n color: '#fff',\n border: '1px solid rgba(255, 255, 255, 0.3)',\n transition: 'all 0.3s ease',\n '&:hover': {\n background: 'rgba(255, 255, 255, 0.2)',\n transform: 'translateY(-3px)'\n }\n }}\n >\n 了解更多\n </Button>\n </div>\n </Col>\n <Col xs={24} md={12}>\n <div style={{ \n textAlign: 'center',\n position: 'relative',\n perspective: '1000px'\n }}>\n <div style={{\n position: 'absolute',\n top: '-30px',\n left: '-30px',\n right: '-30px',\n bottom: '-30px',\n background: 'linear-gradient(45deg, #1890ff, #36cfc9)',\n borderRadius: '20px',\n filter: 'blur(60px)',\n opacity: 0.7,\n zIndex: -1,\n animation: 'pulse 3s ease-in-out infinite'\n }} />\n <img \n src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='450' viewBox='0 0 800 450'%3E%3Crect width='800' height='450' fill='%231890ff'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='24' fill='white'%3E智能电商平台%3C/text%3E%3C/svg%3E\" \n alt=\"智能电商平台\" \n style={{ \n maxWidth: '100%', \n borderRadius: '16px', \n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.4)',\n transition: 'all 0.3s ease',\n transformStyle: 'preserve-3d',\n '&:hover': {\n transform: 'scale(1.05) rotateY(5deg)',\n boxShadow: '0 24px 72px rgba(0, 0, 0, 0.5)'\n }\n }}\n />\n </div>\n </Col>\n </Row>\n </div>\n </section>\n\n {/* 核心功能区 */}\n <section className=\"features\" style={{ \n padding: '140px 0', \n background: '#fafafa',\n position: 'relative'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n right: 0,\n width: '50%',\n height: '100%',\n backgroundImage: 'radial-gradient(circle at 100% 50%, rgba(24, 144, 255, 0.05) 0%, transparent 50%)',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <div style={{ textAlign: 'center', marginBottom: '96px' }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(24, 144, 255, 0.1)', \n color: '#1890ff', \n padding: '10px 20px', \n borderRadius: '25px', \n fontSize: '14px', \n fontWeight: '600',\n marginBottom: '32px',\n boxShadow: '0 4px 12px rgba(24, 144, 255, 0.15)'\n }}>\n 核心功能\n </div>\n <Title level={2} style={{ \n fontSize: '48px', \n fontWeight: 'bold', \n marginBottom: '24px', \n color: '#333',\n lineHeight: '1.1'\n }}>全方位跨境电商解决方案</Title>\n <Paragraph style={{ \n fontSize: '20px', \n color: '#666', \n maxWidth: '800px', \n margin: '0 auto',\n lineHeight: '1.6'\n }}>\n 我们提供从选品到运营的完整解决方案,帮助您实现业务增长和利润最大化\n </Paragraph>\n </div>\n <Row gutter={[48, 48]}>\n {features.map((feature, index) => (\n <Col key={index} xs={24} sm={12} md={8}>\n <Card \n hoverable \n style={{ \n borderRadius: '16px', \n overflow: 'hidden', \n transition: 'all 0.4s ease',\n border: '1px solid #e8e8e8',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.08)',\n height: '100%',\n '&:hover': {\n transform: 'translateY(-12px)',\n boxShadow: '0 16px 48px rgba(0, 0, 0, 0.15)',\n borderColor: '#1890ff'\n }\n }}\n >\n <div style={{ marginBottom: '32px', paddingTop: '32px' }}>\n <span style={{ \n display: 'inline-flex', \n width: '84px', \n height: '84px', \n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '32px', \n fontWeight: 'bold', \n background: 'linear-gradient(135deg, #1890ff 0%, #36cfc9 100%)', \n color: '#fff', \n borderRadius: '20px',\n boxShadow: '0 6px 20px rgba(24, 144, 255, 0.4)',\n transition: 'all 0.3s ease',\n '&:hover': {\n transform: 'scale(1.1)',\n boxShadow: '0 8px 24px rgba(24, 144, 255, 0.5)'\n }\n }}>{feature.title.charAt(0)}</span>\n </div>\n <Title level={4} style={{ \n marginBottom: '20px',\n color: '#333',\n fontWeight: 'bold',\n fontSize: '20px'\n }}>{feature.title}</Title>\n <Paragraph style={{ \n marginBottom: '32px',\n color: '#666',\n lineHeight: '1.6',\n fontSize: '16px'\n }}>{feature.description}</Paragraph>\n <Button \n type=\"text\" \n style={{\n color: '#1890ff',\n fontWeight: '600',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n transition: 'all 0.3s ease',\n fontSize: '16px',\n '&:hover': {\n color: '#40a9ff',\n transform: 'translateX(6px)'\n }\n }}\n >\n 了解更多 <ArrowRightOutlined />\n </Button>\n </Card>\n </Col>\n ))}\n </Row>\n </div>\n </section>\n\n {/* 价值主张区 */}\n <section className=\"value-proposition\" style={{ \n padding: '140px 0', \n background: '#fff',\n position: 'relative'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '50%',\n height: '100%',\n backgroundImage: 'radial-gradient(circle at 0% 50%, rgba(24, 144, 255, 0.05) 0%, transparent 50%)',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <Row align=\"middle\" gutter={[64, 64]}>\n <Col xs={24} md={12}>\n <div style={{ \n textAlign: 'center',\n position: 'relative',\n perspective: '1000px'\n }}>\n <div style={{\n position: 'absolute',\n top: '-30px',\n left: '-30px',\n right: '-30px',\n bottom: '-30px',\n background: 'linear-gradient(45deg, #1890ff, #36cfc9)',\n borderRadius: '20px',\n filter: 'blur(80px)',\n opacity: 0.15,\n zIndex: -1\n }} />\n <img \n src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='450' viewBox='0 0 800 450'%3E%3Crect width='800' height='450' fill='%2336cfc9'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='24' fill='white'%3E业务增长%3C/text%3E%3C/svg%3E\" \n alt=\"业务增长\" \n style={{ \n maxWidth: '100%', \n borderRadius: '16px', \n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.15)',\n transition: 'all 0.4s ease',\n transformStyle: 'preserve-3d',\n '&:hover': {\n transform: 'scale(1.05) rotateY(-5deg)',\n boxShadow: '0 24px 72px rgba(0, 0, 0, 0.2)'\n }\n }}\n />\n </div>\n </Col>\n <Col xs={24} md={12}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(24, 144, 255, 0.1)', \n color: '#1890ff', \n padding: '10px 20px', \n borderRadius: '25px', \n fontSize: '14px', \n fontWeight: '600',\n marginBottom: '32px',\n boxShadow: '0 4px 12px rgba(24, 144, 255, 0.15)'\n }}>\n 为什么选择我们\n </div>\n <Title level={2} style={{ \n fontSize: '44px',\n fontWeight: 'bold',\n marginBottom: '36px', \n color: '#333',\n lineHeight: '1.1'\n }}>为什么选择 Crawlful Hub</Title>\n <div style={{ marginBottom: '48px' }}>\n <div style={{ \n display: 'flex', \n alignItems: 'flex-start', \n marginBottom: '32px', \n gap: '24px',\n padding: '24px',\n background: '#fafafa',\n borderRadius: '16px',\n transition: 'all 0.4s ease',\n '&:hover': {\n background: 'rgba(24, 144, 255, 0.05)',\n transform: 'translateX(12px)',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.08)'\n }\n }}>\n <div style={{\n width: '56px',\n height: '56px',\n borderRadius: '14px',\n background: 'linear-gradient(135deg, #1890ff 0%, #36cfc9 100%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n boxShadow: '0 4px 16px rgba(24, 144, 255, 0.3)'\n }}>\n <CheckCircleOutlined style={{ color: '#fff', fontSize: '28px' }} />\n </div>\n <div>\n <h3 style={{ \n marginBottom: '12px', \n color: '#333',\n fontSize: '20px',\n fontWeight: 'bold'\n }}>AI驱动决策</h3>\n <p style={{ \n color: '#666', \n margin: 0,\n lineHeight: '1.6',\n fontSize: '16px'\n }}>基于人工智能的数据分析和预测,帮助您做出更明智的业务决策</p>\n </div>\n </div>\n <div style={{ \n display: 'flex', \n alignItems: 'flex-start', \n marginBottom: '32px', \n gap: '24px',\n padding: '24px',\n background: '#fafafa',\n borderRadius: '16px',\n transition: 'all 0.4s ease',\n '&:hover': {\n background: 'rgba(24, 144, 255, 0.05)',\n transform: 'translateX(12px)',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.08)'\n }\n }}>\n <div style={{\n width: '56px',\n height: '56px',\n borderRadius: '14px',\n background: 'linear-gradient(135deg, #1890ff 0%, #36cfc9 100%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n boxShadow: '0 4px 16px rgba(24, 144, 255, 0.3)'\n }}>\n <CheckCircleOutlined style={{ color: '#fff', fontSize: '28px' }} />\n </div>\n <div>\n <h3 style={{ \n marginBottom: '12px', \n color: '#333',\n fontSize: '20px',\n fontWeight: 'bold'\n }}>全流程自动化</h3>\n <p style={{ \n color: '#666', \n margin: 0,\n lineHeight: '1.6',\n fontSize: '16px'\n }}>从选品到上架,从定价到运营,全流程自动化管理,节省人力成本</p>\n </div>\n </div>\n <div style={{ \n display: 'flex', \n alignItems: 'flex-start', \n marginBottom: '32px', \n gap: '24px',\n padding: '24px',\n background: '#fafafa',\n borderRadius: '16px',\n transition: 'all 0.4s ease',\n '&:hover': {\n background: 'rgba(24, 144, 255, 0.05)',\n transform: 'translateX(12px)',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.08)'\n }\n }}>\n <div style={{\n width: '56px',\n height: '56px',\n borderRadius: '14px',\n background: 'linear-gradient(135deg, #1890ff 0%, #36cfc9 100%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n boxShadow: '0 4px 16px rgba(24, 144, 255, 0.3)'\n }}>\n <CheckCircleOutlined style={{ color: '#fff', fontSize: '28px' }} />\n </div>\n <div>\n <h3 style={{ \n marginBottom: '12px', \n color: '#333',\n fontSize: '20px',\n fontWeight: 'bold'\n }}>多平台整合</h3>\n <p style={{ \n color: '#666', \n margin: 0,\n lineHeight: '1.6',\n fontSize: '16px'\n }}>支持主流电商平台,一站式管理多店铺,提高运营效率</p>\n </div>\n </div>\n <div style={{ \n display: 'flex', \n alignItems: 'flex-start', \n marginBottom: '32px', \n gap: '24px',\n padding: '24px',\n background: '#fafafa',\n borderRadius: '16px',\n transition: 'all 0.4s ease',\n '&:hover': {\n background: 'rgba(24, 144, 255, 0.05)',\n transform: 'translateX(12px)',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.08)'\n }\n }}>\n <div style={{\n width: '56px',\n height: '56px',\n borderRadius: '14px',\n background: 'linear-gradient(135deg, #1890ff 0%, #36cfc9 100%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n boxShadow: '0 4px 16px rgba(24, 144, 255, 0.3)'\n }}>\n <CheckCircleOutlined style={{ color: '#fff', fontSize: '28px' }} />\n </div>\n <div>\n <h3 style={{ \n marginBottom: '12px', \n color: '#333',\n fontSize: '20px',\n fontWeight: 'bold'\n }}>专业团队支持</h3>\n <p style={{ \n color: '#666', \n margin: 0,\n lineHeight: '1.6',\n fontSize: '16px'\n }}>7x24小时技术支持,专业团队为您保驾护航,确保业务稳定运行</p>\n </div>\n </div>\n </div>\n </Col>\n </Row>\n </div>\n </section>\n\n {/* 成功案例区 */}\n <section className=\"case-studies\" style={{ \n padding: '140px 0', \n background: '#fafafa',\n position: 'relative'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n right: 0,\n width: '50%',\n height: '100%',\n backgroundImage: 'radial-gradient(circle at 100% 50%, rgba(24, 144, 255, 0.05) 0%, transparent 50%)',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <div style={{ textAlign: 'center', marginBottom: '96px' }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(24, 144, 255, 0.1)', \n color: '#1890ff', \n padding: '10px 20px', \n borderRadius: '25px', \n fontSize: '14px', \n fontWeight: '600',\n marginBottom: '32px',\n boxShadow: '0 4px 12px rgba(24, 144, 255, 0.15)'\n }}>\n 成功案例\n </div>\n <Title level={2} style={{ \n fontSize: '48px', \n fontWeight: 'bold', \n marginBottom: '24px', \n color: '#333',\n lineHeight: '1.1'\n }}>我们的客户成功故事</Title>\n <Paragraph style={{ \n fontSize: '20px', \n color: '#666', \n maxWidth: '800px', \n margin: '0 auto',\n lineHeight: '1.6'\n }}>\n 看看我们的客户如何使用 Crawlful Hub 实现业务增长\n </Paragraph>\n </div>\n <Row gutter={[48, 48]}>\n <Col xs={24} md={8}>\n <Card \n hoverable \n style={{ \n borderRadius: '20px', \n overflow: 'hidden', \n transition: 'all 0.4s ease',\n border: '1px solid #e8e8e8',\n boxShadow: '0 12px 32px rgba(0, 0, 0, 0.1)',\n height: '100%',\n '&:hover': {\n transform: 'translateY(-16px)',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.18)',\n borderColor: '#1890ff'\n }\n }}\n >\n <div style={{ \n marginBottom: '0',\n position: 'relative',\n overflow: 'hidden',\n height: '280px'\n }}>\n <img \n src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='800' viewBox='0 0 800 800'%3E%3Crect width='800' height='800' fill='%231890ff'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='24' fill='white'%3E成功案例1%3C/text%3E%3C/svg%3E\" \n alt=\"成功案例1\" \n style={{ \n width: '100%', \n height: '100%', \n objectFit: 'cover',\n transition: 'all 0.4s ease',\n '&:hover': {\n transform: 'scale(1.1)'\n }\n }}\n />\n <div style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'linear-gradient(transparent, rgba(0, 0, 0, 0.8))',\n padding: '24px',\n color: '#fff'\n }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(255, 255, 255, 0.25)', \n color: '#fff', \n padding: '6px 16px', \n borderRadius: '16px', \n fontSize: '12px', \n fontWeight: '600',\n marginBottom: '12px'\n }}>\n 跨境电商\n </div>\n </div>\n </div>\n <div style={{ padding: '36px' }}>\n <Title level={4} style={{ \n marginBottom: '20px',\n color: '#333',\n fontWeight: 'bold',\n fontSize: '20px'\n }}>某跨境电商企业</Title>\n <Paragraph style={{ \n marginBottom: '32px',\n color: '#666',\n lineHeight: '1.6',\n fontSize: '16px'\n }}>通过智能选品和动态定价,3个月内销售额提升45%</Paragraph>\n <Button \n type=\"text\" \n onClick={() => navigate('/case-study/1')}\n style={{\n color: '#1890ff',\n fontWeight: '600',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n transition: 'all 0.3s ease',\n fontSize: '16px',\n '&:hover': {\n color: '#40a9ff',\n transform: 'translateX(6px)'\n }\n }}\n >\n 查看详情 <ArrowRightOutlined />\n </Button>\n </div>\n </Card>\n </Col>\n <Col xs={24} md={8}>\n <Card \n hoverable \n style={{ \n borderRadius: '20px', \n overflow: 'hidden', \n transition: 'all 0.4s ease',\n border: '1px solid #e8e8e8',\n boxShadow: '0 12px 32px rgba(0, 0, 0, 0.1)',\n height: '100%',\n '&:hover': {\n transform: 'translateY(-16px)',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.18)',\n borderColor: '#1890ff'\n }\n }}\n >\n <div style={{ \n marginBottom: '0',\n position: 'relative',\n overflow: 'hidden',\n height: '280px'\n }}>\n <img \n src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='800' viewBox='0 0 800 800'%3E%3Crect width='800' height='800' fill='%2336cfc9'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='24' fill='white'%3E成功案例2%3C/text%3E%3C/svg%3E\" \n alt=\"成功案例2\" \n style={{ \n width: '100%', \n height: '100%', \n objectFit: 'cover',\n transition: 'all 0.4s ease',\n '&:hover': {\n transform: 'scale(1.1)'\n }\n }}\n />\n <div style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'linear-gradient(transparent, rgba(0, 0, 0, 0.8))',\n padding: '24px',\n color: '#fff'\n }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(255, 255, 255, 0.25)', \n color: '#fff', \n padding: '6px 16px', \n borderRadius: '16px', \n fontSize: '12px', \n fontWeight: '600',\n marginBottom: '12px'\n }}>\n 品牌零售\n </div>\n </div>\n </div>\n <div style={{ padding: '36px' }}>\n <Title level={4} style={{ \n marginBottom: '20px',\n color: '#333',\n fontWeight: 'bold',\n fontSize: '20px'\n }}>某品牌零售商</Title>\n <Paragraph style={{ \n marginBottom: '32px',\n color: '#666',\n lineHeight: '1.6',\n fontSize: '16px'\n }}>利用AI店铺托管,运营成本降低30%,效率提升50%</Paragraph>\n <Button \n type=\"text\" \n onClick={() => navigate('/case-study/2')}\n style={{\n color: '#1890ff',\n fontWeight: '600',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n transition: 'all 0.3s ease',\n fontSize: '16px',\n '&:hover': {\n color: '#40a9ff',\n transform: 'translateX(6px)'\n }\n }}\n >\n 查看详情 <ArrowRightOutlined />\n </Button>\n </div>\n </Card>\n </Col>\n <Col xs={24} md={8}>\n <Card \n hoverable \n style={{ \n borderRadius: '20px', \n overflow: 'hidden', \n transition: 'all 0.4s ease',\n border: '1px solid #e8e8e8',\n boxShadow: '0 12px 32px rgba(0, 0, 0, 0.1)',\n height: '100%',\n '&:hover': {\n transform: 'translateY(-16px)',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.18)',\n borderColor: '#1890ff'\n }\n }}\n >\n <div style={{ \n marginBottom: '0',\n position: 'relative',\n overflow: 'hidden',\n height: '280px'\n }}>\n <img \n src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='800' viewBox='0 0 800 800'%3E%3Crect width='800' height='800' fill='%23722ed1'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='24' fill='white'%3E成功案例3%3C/text%3E%3C/svg%3E\" \n alt=\"成功案例3\" \n style={{ \n width: '100%', \n height: '100%', \n objectFit: 'cover',\n transition: 'all 0.4s ease',\n '&:hover': {\n transform: 'scale(1.1)'\n }\n }}\n />\n <div style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n background: 'linear-gradient(transparent, rgba(0, 0, 0, 0.8))',\n padding: '24px',\n color: '#fff'\n }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(255, 255, 255, 0.25)', \n color: '#fff', \n padding: '6px 16px', \n borderRadius: '16px', \n fontSize: '12px', \n fontWeight: '600',\n marginBottom: '12px'\n }}>\n 多渠道运营\n </div>\n </div>\n </div>\n <div style={{ padding: '36px' }}>\n <Title level={4} style={{ \n marginBottom: '20px',\n color: '#333',\n fontWeight: 'bold',\n fontSize: '20px'\n }}>某多渠道卖家</Title>\n <Paragraph style={{ \n marginBottom: '32px',\n color: '#666',\n lineHeight: '1.6',\n fontSize: '16px'\n }}>通过跨平台套利,6个月内利润率提升35%</Paragraph>\n <Button \n type=\"text\" \n onClick={() => navigate('/case-study/3')}\n style={{\n color: '#1890ff',\n fontWeight: '600',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n transition: 'all 0.3s ease',\n fontSize: '16px',\n '&:hover': {\n color: '#40a9ff',\n transform: 'translateX(6px)'\n }\n }}\n >\n 查看详情 <ArrowRightOutlined />\n </Button>\n </div>\n </Card>\n </Col>\n </Row>\n <div style={{ textAlign: 'center', marginTop: '72px' }}>\n <Button \n type=\"primary\" \n onClick={() => navigate('/case-study')}\n style={{\n padding: '16px 40px', \n fontSize: '18px',\n borderRadius: '30px',\n boxShadow: '0 6px 18px rgba(24, 144, 255, 0.4)',\n transition: 'all 0.3s ease',\n '&:hover': {\n transform: 'translateY(-3px)',\n boxShadow: '0 8px 24px rgba(24, 144, 255, 0.5)'\n }\n }}\n >\n 查看更多案例\n </Button>\n </div>\n </div>\n </section>\n\n {/* 行动召唤区 */}\n <section className=\"cta\" style={{ \n padding: '160px 0', \n background: 'linear-gradient(135deg, #0a192f 0%, #172a45 100%)', \n color: '#fff', \n textAlign: 'center',\n position: 'relative',\n overflow: 'hidden'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: 'radial-gradient(circle at 25% 25%, rgba(24, 144, 255, 0.15) 0%, transparent 50%), radial-gradient(circle at 75% 75%, rgba(54, 207, 201, 0.15) 0%, transparent 50%)',\n zIndex: 1\n }} />\n {/* 网格背景 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: 'linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px)',\n backgroundSize: '40px 40px',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <div style={{ maxWidth: '800px', margin: '0 auto' }}>\n <div style={{ \n display: 'inline-block', \n background: 'rgba(24, 144, 255, 0.15)', \n color: '#1890ff', \n padding: '10px 20px', \n borderRadius: '25px', \n fontSize: '14px', \n fontWeight: '600',\n marginBottom: '32px',\n boxShadow: '0 4px 12px rgba(24, 144, 255, 0.2)'\n }}>\n 立即开始\n </div>\n <Title level={2} style={{ \n color: '#fff', \n marginBottom: '32px',\n fontSize: '48px',\n fontWeight: 'bold',\n lineHeight: '1.1'\n }}>准备好开始您的电商增长之旅了吗?</Title>\n <Paragraph style={{ \n color: 'rgba(255, 255, 255, 0.8)', \n marginBottom: '64px', \n fontSize: '22px',\n lineHeight: '1.6'\n }}>\n 立即注册,享受14天免费试用,体验AI驱动的跨境电商解决方案,开启您的业务增长之路\n </Paragraph>\n <Button \n type=\"primary\" \n size=\"large\" \n onClick={() => navigate('/auth/register')}\n style={{\n padding: '18px 56px', \n fontSize: '20px',\n borderRadius: '35px',\n boxShadow: '0 8px 24px rgba(24, 144, 255, 0.4)',\n transition: 'all 0.3s ease',\n '&:hover': {\n transform: 'translateY(-3px)',\n boxShadow: '0 12px 32px rgba(24, 144, 255, 0.5)'\n }\n }}\n >\n 免费注册\n </Button>\n <div style={{ marginTop: '32px', color: 'rgba(255, 255, 255, 0.6)', fontSize: '16px' }}>\n 无需信用卡 · 14天免费试用 · 随时取消\n </div>\n </div>\n </div>\n </section>\n\n {/* 页脚 */}\n <footer style={{ \n padding: '120px 0 80px', \n background: '#0a192f', \n color: '#fff',\n position: 'relative',\n overflow: 'hidden'\n }}>\n {/* 背景装饰 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: 'radial-gradient(circle at 50% 50%, rgba(24, 144, 255, 0.05) 0%, transparent 70%)',\n zIndex: 1\n }} />\n <div className=\"container\" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', position: 'relative', zIndex: 2 }}>\n <Row gutter={[48, 48]}>\n <Col xs={24} md={6}>\n <div style={{ \n fontSize: '32px', \n fontWeight: 'bold', \n marginBottom: '28px',\n color: '#1890ff',\n letterSpacing: '1px'\n }}>Crawlful Hub</div>\n <Paragraph style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n marginBottom: '36px',\n lineHeight: '1.6',\n fontSize: '16px'\n }}>\n 智能驱动跨境电商增长,为您的业务提供全方位解决方案\n </Paragraph>\n <div style={{ display: 'flex', gap: '16px' }}>\n <a href=\"#\" style={{ \n display: 'inline-flex', \n alignItems: 'center', \n justifyContent: 'center',\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n background: 'rgba(255, 255, 255, 0.08)',\n color: 'rgba(255, 255, 255, 0.6)',\n transition: 'all 0.3s ease',\n '&:hover': {\n background: '#1890ff',\n color: '#fff',\n transform: 'translateY(-2px)'\n }\n }}>\n <TwitterOutlined />\n </a>\n <a href=\"#\" style={{ \n display: 'inline-flex', \n alignItems: 'center', \n justifyContent: 'center',\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n background: 'rgba(255, 255, 255, 0.08)',\n color: 'rgba(255, 255, 255, 0.6)',\n transition: 'all 0.3s ease',\n '&:hover': {\n background: '#1890ff',\n color: '#fff',\n transform: 'translateY(-2px)'\n }\n }}>\n <LinkedinOutlined />\n </a>\n <a href=\"#\" style={{ \n display: 'inline-flex', \n alignItems: 'center', \n justifyContent: 'center',\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n background: 'rgba(255, 255, 255, 0.08)',\n color: 'rgba(255, 255, 255, 0.6)',\n transition: 'all 0.3s ease',\n '&:hover': {\n background: '#1890ff',\n color: '#fff',\n transform: 'translateY(-2px)'\n }\n }}>\n <GithubOutlined />\n </a>\n </div>\n </Col>\n <Col xs={24} md={6}>\n <h3 style={{ \n fontSize: '20px', \n fontWeight: 'bold', \n marginBottom: '28px', \n color: '#fff',\n letterSpacing: '0.5px'\n }}>产品</h3>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n <li style={{ marginBottom: '20px' }}><Link to=\"/pricing\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>定价方案</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/case-study\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>成功案例</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>功能介绍</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>API文档</Link></li>\n </ul>\n </Col>\n <Col xs={24} md={6}>\n <h3 style={{ \n fontSize: '20px', \n fontWeight: 'bold', \n marginBottom: '28px', \n color: '#fff',\n letterSpacing: '0.5px'\n }}>公司</h3>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>关于我们</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>联系我们</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>招贤纳士</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>新闻资讯</Link></li>\n </ul>\n </Col>\n <Col xs={24} md={6}>\n <h3 style={{ \n fontSize: '20px', \n fontWeight: 'bold', \n marginBottom: '28px', \n color: '#fff',\n letterSpacing: '0.5px'\n }}>支持</h3>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>帮助中心</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>常见问题</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>联系支持</Link></li>\n <li style={{ marginBottom: '20px' }}><Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.6)', \n transition: 'all 0.3s ease',\n textDecoration: 'none',\n fontSize: '16px',\n '&:hover': {\n color: '#1890ff',\n transform: 'translateX(4px)'\n }\n }}>API文档</Link></li>\n </ul>\n </Col>\n </Row>\n <Divider style={{ \n backgroundColor: 'rgba(255, 255, 255, 0.1)', \n margin: '80px 0 40px',\n height: '1px'\n }} />\n <div style={{ textAlign: 'center', color: 'rgba(255, 255, 255, 0.4)', fontSize: '14px' }}>\n <div style={{ marginBottom: '16px' }}>\n <Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.4)', \n transition: 'color 0.3s ease',\n textDecoration: 'none',\n margin: '0 16px',\n '&:hover': {\n color: '#1890ff'\n }\n }}>隐私政策</Link>\n <Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.4)', \n transition: 'color 0.3s ease',\n textDecoration: 'none',\n margin: '0 16px',\n '&:hover': {\n color: '#1890ff'\n }\n }}>服务条款</Link>\n <Link to=\"/\" style={{ \n color: 'rgba(255, 255, 255, 0.4)', \n transition: 'color 0.3s ease',\n textDecoration: 'none',\n margin: '0 16px',\n '&:hover': {\n color: '#1890ff'\n }\n }}>Cookie政策</Link>\n </div>\n © 2025 Crawlful Hub. All rights reserved.\n </div>\n </div>\n </footer>\n </div>\n );\n};\n\nexport default Homepage;",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/Homepage.tsx"
|
||
},
|
||
"2": {
|
||
"path": "/pricing",
|
||
"layout": false,
|
||
"file": "@/pages/Pricing.tsx",
|
||
"id": "2",
|
||
"absPath": "/pricing",
|
||
"__content": "import React, { useState } from 'react';\nimport { Link, useNavigate } from 'umi';\nimport { Card, Button, Typography, Divider, Radio, Row, Col, Tag, Alert } from 'antd';\nimport { CheckCircleOutlined, CloseCircleOutlined, ArrowRightOutlined, DollarOutlined, UsersOutlined, ShieldOutlined, BarChartOutlined, ZapOutlined, GlobeOutlined, StarOutlined } from '@ant-design/icons';\nimport Navbar from '@/components/Navbar';\n\nconst { Title, Paragraph, Text } = Typography;\n\nconst Pricing: React.FC = () => {\n const navigate = useNavigate();\n const [billingCycle, setBillingCycle] = useState<'monthly' | 'yearly'>('monthly');\n\n const plans = [\n {\n name: '免费版',\n price: 0,\n billing: '永久免费',\n features: [\n '基础功能',\n '最多1个店铺',\n '500条商品数据',\n '邮件支持',\n '基础报表',\n '手动操作',\n ],\n cta: '开始免费使用',\n popular: false,\n buttonType: 'primary',\n onClick: () => navigate('/auth/register'),\n },\n {\n name: '专业版',\n price: billingCycle === 'monthly' ? 999 : 9990,\n billing: billingCycle === 'monthly' ? '每月' : '每年',\n features: [\n '所有核心功能',\n '最多10个店铺',\n '5000条商品数据',\n '优先邮件支持',\n '高级报表',\n 'AI智能选品',\n '自动上架',\n '动态定价',\n '跨平台套利',\n ],\n cta: '选择专业版',\n popular: true,\n buttonType: 'primary',\n onClick: () => navigate('/checkout?plan=professional'),\n },\n {\n name: '企业版',\n price: 0,\n billing: '定制',\n features: [\n '完整功能',\n '无限店铺',\n '无限商品数据',\n '24/7专属支持',\n '定制化报表',\n 'AI店铺托管',\n '定制化开发',\n 'API接入',\n '专属客户经理',\n ],\n cta: '联系销售',\n popular: false,\n buttonType: 'default',\n onClick: () => navigate('/contact'),\n },\n ];\n\n const compareFeatures = [\n { feature: '核心功能', free: true, professional: true, enterprise: true },\n { feature: '店铺数量', free: '1个', professional: '10个', enterprise: '无限' },\n { feature: '商品数据', free: '500条', professional: '5000条', enterprise: '无限' },\n { feature: 'AI智能选品', free: false, professional: true, enterprise: true },\n { feature: '自动上架', free: false, professional: true, enterprise: true },\n { feature: '动态定价', free: false, professional: true, enterprise: true },\n { feature: '跨平台套利', free: false, professional: true, enterprise: true },\n { feature: 'AI店铺托管', free: false, professional: false, enterprise: true },\n { feature: '技术支持', free: '邮件', professional: '优先邮件', enterprise: '24/7专属' },\n { feature: '定制化开发', free: false, professional: false, enterprise: true },\n { feature: 'API接入', free: false, professional: false, enterprise: true },\n ];\n\n return (\n <div className=\"pricing-page\">\n <Navbar />\n {/* 页面头部 */}\n <section className=\"pricing-header\">\n <div className=\"container\">\n <Title level={1}>选择适合您的方案</Title>\n <Paragraph className=\"subtitle\">\n 无论您是个人卖家还是大型企业,我们都有适合您的解决方案\n </Paragraph>\n <div className=\"billing-cycle\">\n <Text>月付</Text>\n <Radio.Group value={billingCycle} onChange={(e) => setBillingCycle(e.target.value)}>\n <Radio.Button value=\"monthly\">月付</Radio.Button>\n <Radio.Button value=\"yearly\">年付 <Tag color=\"green\">省16%</Tag></Radio.Button>\n </Radio.Group>\n <Text>年付</Text>\n </div>\n </div>\n </section>\n\n {/* 定价方案 */}\n <section className=\"pricing-plans\">\n <div className=\"container\">\n <Row gutter={[32, 32]}>\n {plans.map((plan, index) => (\n <Col key={index} xs={24} md={8}>\n <Card className={`plan-card ${plan.popular ? 'popular' : ''}`}>\n {plan.popular && (\n <div className=\"popular-badge\">\n <StarOutlined /> 推荐\n </div>\n )}\n <div className=\"plan-header\">\n <Title level={3}>{plan.name}</Title>\n <div className=\"price\">\n <DollarOutlined />\n <span className=\"price-value\">{plan.price}</span>\n <span className=\"price-unit\">/{plan.billing === '永久免费' ? '' : plan.billing === '每月' ? '月' : '年'}</span>\n </div>\n {plan.billing === '永久免费' && (\n <Text type=\"secondary\">{plan.billing}</Text>\n )}\n </div>\n <Divider />\n <div className=\"plan-features\">\n {plan.features.map((feature, idx) => (\n <div key={idx} className=\"feature-item\">\n <CheckCircleOutlined className=\"feature-icon\" />\n <Text>{feature}</Text>\n </div>\n ))}\n </div>\n <Button \n type={plan.buttonType as 'primary' | 'default' | 'dashed' | 'text' | 'link'} \n size=\"large\" \n className=\"plan-button\" \n onClick={plan.onClick}\n >\n {plan.cta}\n </Button>\n </Card>\n </Col>\n ))}\n </Row>\n </div>\n </section>\n\n {/* 功能对比 */}\n <section className=\"feature-comparison\">\n <div className=\"container\">\n <Title level={2}>功能对比</Title>\n <div className=\"comparison-table\">\n <div className=\"table-header\">\n <div className=\"feature-cell\">功能</div>\n <div className=\"plan-cell\">免费版</div>\n <div className=\"plan-cell\">专业版</div>\n <div className=\"plan-cell\">企业版</div>\n </div>\n {compareFeatures.map((item, index) => (\n <div key={index} className=\"table-row\">\n <div className=\"feature-cell\">{item.feature}</div>\n <div className=\"plan-cell\">\n {typeof item.free === 'boolean' ? (\n item.free ? \n <CheckCircleOutlined className=\"check-icon\" /> : \n <CloseCircleOutlined className=\"close-icon\" />\n ) : (\n <Text>{item.free}</Text>\n )}\n </div>\n <div className=\"plan-cell\">\n {typeof item.professional === 'boolean' ? (\n item.professional ? \n <CheckCircleOutlined className=\"check-icon\" /> : \n <CloseCircleOutlined className=\"close-icon\" />\n ) : (\n <Text>{item.professional}</Text>\n )}\n </div>\n <div className=\"plan-cell\">\n {typeof item.enterprise === 'boolean' ? (\n item.enterprise ? \n <CheckCircleOutlined className=\"check-icon\" /> : \n <CloseCircleOutlined className=\"close-icon\" />\n ) : (\n <Text>{item.enterprise}</Text>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* 常见问题 */}\n <section className=\"faq\">\n <div className=\"container\">\n <Title level={2}>常见问题</Title>\n <Row gutter={[32, 32]}>\n <Col xs={24} md={12}>\n <Card className=\"faq-card\">\n <Title level={4}>如何选择适合我的方案?</Title>\n <Paragraph>\n 根据您的店铺数量、商品数据量和功能需求来选择。如果您是个人卖家或刚刚起步,免费版是个不错的选择。如果您有多个店铺需要管理,专业版会更适合您。如果您是大型企业,需要定制化解决方案,建议选择企业版。\n </Paragraph>\n </Card>\n <Card className=\"faq-card\">\n <Title level={4}>可以随时升级或降级方案吗?</Title>\n <Paragraph>\n 是的,您可以随时升级或降级您的方案。升级会立即生效,降级会在下一个 billing cycle 开始时生效。\n </Paragraph>\n </Card>\n <Card className=\"faq-card\">\n <Title level={4}>如何取消订阅?</Title>\n <Paragraph>\n 您可以在账户设置中取消订阅。取消后,您的服务会持续到当前 billing cycle 结束,之后不会再收费。\n </Paragraph>\n </Card>\n </Col>\n <Col xs={24} md={12}>\n <Card className=\"faq-card\">\n <Title level={4}>年付和月付有什么区别?</Title>\n <Paragraph>\n 年付可以享受16%的折扣,相当于免费使用2个月。其他功能和服务都是一样的。\n </Paragraph>\n </Card>\n <Card className=\"faq-card\">\n <Title level={4}>提供发票吗?</Title>\n <Paragraph>\n 是的,我们会为所有付费用户提供正规发票。您可以在账户设置中下载发票。\n </Paragraph>\n </Card>\n <Card className=\"faq-card\">\n <Title level={4}>有试用期吗?</Title>\n <Paragraph>\n 是的,专业版和企业版都提供14天的免费试用期。试用期内您可以体验所有功能,无需信用卡。\n </Paragraph>\n </Card>\n </Col>\n </Row>\n </div>\n </section>\n\n {/* 行动召唤 */}\n <section className=\"cta\">\n <div className=\"container\">\n <Title level={2}>准备好开始了吗?</Title>\n <Paragraph>选择适合您的方案,开始您的电商增长之旅</Paragraph>\n <Button type=\"primary\" size=\"large\" onClick={() => navigate('/auth/register')}>\n 免费注册\n </Button>\n </div>\n </section>\n\n <style jsx>{`\n .pricing-page {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n }\n\n .pricing-header {\n padding: 140px 0 40px;\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n text-align: center;\n }\n\n @media (max-width: 768px) {\n .pricing-header {\n padding: 120px 0 30px;\n }\n }\n\n .subtitle {\n font-size: 18px;\n color: #666;\n margin: 16px 0 32px;\n }\n\n .billing-cycle {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 16px;\n margin-top: 32px;\n }\n\n .pricing-plans {\n padding: 60px 0;\n background: #fff;\n }\n\n .plan-card {\n border-radius: 8px;\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n\n .plan-card:hover {\n transform: translateY(-8px);\n box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);\n }\n\n .plan-card.popular {\n border: 2px solid #1890ff;\n transform: scale(1.05);\n }\n\n .plan-card.popular:hover {\n transform: scale(1.05) translateY(-8px);\n }\n\n .popular-badge {\n position: absolute;\n top: 0;\n right: 0;\n background: #1890ff;\n color: #fff;\n padding: 4px 16px;\n border-radius: 0 8px 0 8px;\n font-size: 12px;\n font-weight: bold;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .plan-header {\n text-align: center;\n margin-bottom: 24px;\n }\n\n .price {\n display: flex;\n align-items: baseline;\n justify-content: center;\n margin: 16px 0;\n }\n\n .price-value {\n font-size: 36px;\n font-weight: bold;\n color: #1890ff;\n margin: 0 4px;\n }\n\n .price-unit {\n font-size: 16px;\n color: #666;\n }\n\n .plan-features {\n margin: 24px 0;\n }\n\n .feature-item {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .feature-icon {\n color: #52c41a;\n }\n\n .plan-button {\n width: 100%;\n margin-top: 24px;\n }\n\n .feature-comparison {\n padding: 80px 0;\n background: #f5f7fa;\n }\n\n .comparison-table {\n background: #fff;\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n }\n\n .table-header {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr 1fr;\n background: #f0f2f5;\n padding: 16px;\n font-weight: bold;\n border-bottom: 1px solid #e8e8e8;\n }\n\n .table-row {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr 1fr;\n padding: 16px;\n border-bottom: 1px solid #e8e8e8;\n }\n\n .table-row:last-child {\n border-bottom: none;\n }\n\n .feature-cell {\n font-weight: 500;\n }\n\n .plan-cell {\n text-align: center;\n }\n\n .check-icon {\n color: #52c41a;\n font-size: 18px;\n }\n\n .close-icon {\n color: #ff4d4f;\n font-size: 18px;\n }\n\n .faq {\n padding: 80px 0;\n background: #fff;\n }\n\n .faq-card {\n padding: 24px;\n border-radius: 8px;\n transition: all 0.3s ease;\n }\n\n .faq-card:hover {\n box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);\n }\n\n .cta {\n padding: 80px 0;\n background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);\n color: #fff;\n text-align: center;\n }\n\n .cta .ant-btn {\n margin-top: 24px;\n }\n\n @media (max-width: 768px) {\n .pricing-header {\n padding: 60px 0 30px;\n }\n\n .pricing-plans {\n padding: 40px 0;\n }\n\n .feature-comparison {\n padding: 60px 0;\n }\n\n .table-header,\n .table-row {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n\n .plan-cell {\n text-align: left;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .faq {\n padding: 60px 0;\n }\n\n .cta {\n padding: 60px 0;\n }\n }\n `}</style>\n </div>\n );\n};\n\nexport default Pricing;",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/Pricing.tsx"
|
||
},
|
||
"3": {
|
||
"path": "/case-study",
|
||
"layout": false,
|
||
"file": "@/pages/CaseStudy.tsx",
|
||
"id": "3",
|
||
"absPath": "/case-study",
|
||
"__content": "import React, { useState } from 'react';\nimport { Link, useNavigate } from 'umi';\nimport { Card, Button, Typography, Row, Col, Tag, Carousel, Pagination } from 'antd';\nimport { ArrowRightOutlined, CheckCircleOutlined, DollarOutlined, BarChartOutlined, ZapOutlined, GlobeOutlined, StarOutlined, UserOutlined, CompanyOutlined, TrendingUpOutlined } from '@ant-design/icons';\nimport Navbar from '@/components/Navbar';\n\nconst { Title, Paragraph, Text } = Typography;\n\nconst CaseStudy: React.FC = () => {\n const navigate = useNavigate();\n const [activeCategory, setActiveCategory] = useState('all');\n const [currentPage, setCurrentPage] = useState(1);\n\n const caseStudies = [\n {\n id: 1,\n title: '中小商户案例:月销售额提升45%',\n category: 'small',\n company: '广州某跨境电商公司',\n industry: '电子产品',\n challenge: '手动选品效率低,定价策略单一,运营成本高',\n solution: '使用智能选品系统和AI动态定价,实现自动化运营',\n results: [\n '月销售额提升45%',\n '运营成本降低30%',\n '选品效率提升60%',\n ],\n testimonial: '\"Crawlful Hub帮助我们实现了店铺的自动化运营,节省了大量人力成本,销售额提升了40%。\"',\n author: '张总',\n position: 'CEO',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 2,\n title: '大型企业案例:多店铺管理效率提升60%',\n category: 'enterprise',\n company: '深圳某品牌电商',\n industry: '服装行业',\n challenge: '多店铺管理复杂,数据分散,难以统一运营',\n solution: '使用多店铺管理系统,实现数据集中管理和统一运营',\n results: [\n '管理效率提升60%',\n '数据处理时间减少70%',\n '运营成本降低25%',\n ],\n testimonial: '\"多店铺管理功能让我们能够集中管理所有店铺,数据一目了然,大大提高了管理效率。\"',\n author: '李经理',\n position: '运营总监',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 3,\n title: '跨境电商案例:利润率提升30%',\n category: 'crossborder',\n company: '杭州某跨境电商平台',\n industry: '家居用品',\n challenge: '跨平台价格差异难以把握,利润空间小',\n solution: '使用跨平台套利系统,发现价格差异,优化定价策略',\n results: [\n '利润率提升30%',\n '价格优化效率提升80%',\n '市场竞争力增强',\n ],\n testimonial: '\"跨平台套利系统帮助我们发现了很多价格差异,利润率提高了30%,市场竞争力大大增强。\"',\n author: '王女士',\n position: '业务经理',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 4,\n title: '新手卖家案例:快速启动电商业务',\n category: 'small',\n company: '上海某个人卖家',\n industry: '美妆产品',\n challenge: '缺乏电商运营经验,选品困难,运营成本高',\n solution: '使用智能选品系统和自动上架功能,快速启动业务',\n results: [\n '业务启动时间缩短50%',\n '选品准确率提升70%',\n '首月销售额达到预期目标',\n ],\n testimonial: '\"作为新手卖家,Crawlful Hub帮助我快速启动了电商业务,选品和上架都变得非常简单。\"',\n author: '陈先生',\n position: '个人卖家',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 5,\n title: '传统企业转型案例:线上销售额占比提升至60%',\n category: 'enterprise',\n company: '北京某传统制造企业',\n industry: '机械设备',\n challenge: '线上业务占比低,数字化转型困难',\n solution: '使用全功能电商管理系统,实现线上线下一体化运营',\n results: [\n '线上销售额占比提升至60%',\n '客户获取成本降低40%',\n '品牌知名度提升',\n ],\n testimonial: '\"Crawlful Hub帮助我们成功实现了数字化转型,线上销售额占比从10%提升到了60%。\"',\n author: '赵总',\n position: '总经理',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 6,\n title: '多平台运营案例:管理效率提升70%',\n category: 'crossborder',\n company: '厦门某跨境电商公司',\n industry: '玩具产品',\n challenge: '多平台运营管理复杂,数据不同步,运营效率低',\n solution: '使用多平台集成管理系统,实现数据同步和统一运营',\n results: [\n '管理效率提升70%',\n '数据同步时间减少90%',\n '运营成本降低35%',\n ],\n testimonial: '\"多平台集成管理系统让我们能够统一管理所有平台的店铺,效率大大提升。\"',\n author: '刘经理',\n position: '运营主管',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n ];\n\n const filteredCases = activeCategory === 'all' \n ? caseStudies \n : caseStudies.filter(caseStudy => caseStudy.category === activeCategory);\n\n const itemsPerPage = 3;\n const totalPages = Math.ceil(filteredCases.length / itemsPerPage);\n const currentCases = filteredCases.slice(\n (currentPage - 1) * itemsPerPage,\n currentPage * itemsPerPage\n );\n\n const categories = [\n { value: 'all', label: '全部案例' },\n { value: 'small', label: '中小商户' },\n { value: 'enterprise', label: '大型企业' },\n { value: 'crossborder', label: '跨境电商' },\n ];\n\n return (\n <div className=\"case-study-page\">\n <Navbar />\n {/* 页面头部 */}\n <section className=\"case-header\">\n <div className=\"container\">\n <Title level={1}>成功案例</Title>\n <Paragraph className=\"subtitle\">\n 看看我们如何帮助客户实现业务增长\n </Paragraph>\n </div>\n </section>\n\n {/* 分类筛选 */}\n <section className=\"category-filter\">\n <div className=\"container\">\n <div className=\"categories\">\n {categories.map(category => (\n <Button\n key={category.value}\n type={activeCategory === category.value ? 'primary' : 'default'}\n onClick={() => {\n setActiveCategory(category.value);\n setCurrentPage(1);\n }}\n >\n {category.label}\n </Button>\n ))}\n </div>\n </div>\n </section>\n\n {/* 案例列表 */}\n <section className=\"case-list\">\n <div className=\"container\">\n <Row gutter={[32, 32]}>\n {currentCases.map(caseStudy => (\n <Col key={caseStudy.id} xs={24} md={8}>\n <Card hoverable className=\"case-card\">\n <div className=\"case-image\">\n <img src={caseStudy.image} alt={caseStudy.title} />\n </div>\n <div className=\"case-content\">\n <div className=\"case-meta\">\n <Tag color=\"blue\">{caseStudy.industry}</Tag>\n <Tag color=\"green\">{caseStudy.company}</Tag>\n </div>\n <Title level={4}>{caseStudy.title}</Title>\n <Paragraph className=\"case-challenge\">\n <Text strong>挑战:</Text>{caseStudy.challenge}\n </Paragraph>\n <Paragraph className=\"case-solution\">\n <Text strong>解决方案:</Text>{caseStudy.solution}\n </Paragraph>\n <div className=\"case-results\">\n <Title level={5}>成果:</Title>\n <ul>\n {caseStudy.results.map((result, index) => (\n <li key={index}>\n <CheckCircleOutlined className=\"result-icon\" />\n {result}\n </li>\n ))}\n </ul>\n </div>\n <div className=\"case-testimonial\">\n <div className=\"testimonial-content\">\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <Paragraph>{caseStudy.testimonial}</Paragraph>\n </div>\n <div className=\"testimonial-author\">\n <UserOutlined className=\"author-icon\" />\n <div>\n <Text strong>{caseStudy.author}</Text>\n <Text type=\"secondary\">{caseStudy.position}</Text>\n </div>\n </div>\n </div>\n <Button type=\"primary\" className=\"case-button\" onClick={() => navigate(`/case-study/${caseStudy.id}`)}>\n 查看详情\n <ArrowRightOutlined />\n </Button>\n </div>\n </Card>\n </Col>\n ))}\n </Row>\n \n {/* 分页 */}\n {totalPages > 1 && (\n <div className=\"pagination\">\n <Pagination\n current={currentPage}\n total={filteredCases.length}\n pageSize={itemsPerPage}\n onChange={setCurrentPage}\n showSizeChanger={false}\n />\n </div>\n )}\n </div>\n </section>\n\n {/* 客户评价轮播 */}\n <section className=\"testimonial-carousel\">\n <div className=\"container\">\n <Title level={2}>客户评价</Title>\n <Carousel autoplay className=\"carousel\">\n {caseStudies.map(caseStudy => (\n <div key={caseStudy.id} className=\"carousel-item\">\n <Card className=\"testimonial-card\">\n <div className=\"testimonial-rating\">\n {[1, 2, 3, 4, 5].map(star => (\n <StarOutlined key={star} className=\"star\" />\n ))}\n </div>\n <Paragraph>{caseStudy.testimonial}</Paragraph>\n <div className=\"testimonial-author\">\n <UserOutlined className=\"author-icon\" />\n <div>\n <Text strong>{caseStudy.author}</Text>\n <Text type=\"secondary\">{caseStudy.position},{caseStudy.company}</Text>\n </div>\n </div>\n </Card>\n </div>\n ))}\n </Carousel>\n </div>\n </section>\n\n {/* 行动召唤 */}\n <section className=\"cta\">\n <div className=\"container\">\n <Title level={2}>准备好实现您的业务增长了吗?</Title>\n <Paragraph>加入我们的成功客户行列,开始您的电商增长之旅</Paragraph>\n <Button type=\"primary\" size=\"large\" onClick={() => navigate('/auth/register')}>\n 免费注册\n </Button>\n </div>\n </section>\n\n <style jsx>{`\n .case-study-page {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n }\n\n .case-header {\n padding: 140px 0 40px;\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n text-align: center;\n }\n\n @media (max-width: 768px) {\n .case-header {\n padding: 120px 0 30px;\n }\n }\n\n .subtitle {\n font-size: 18px;\n color: #666;\n margin: 16px 0;\n }\n\n .category-filter {\n padding: 40px 0;\n background: #fff;\n }\n\n .categories {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .case-list {\n padding: 40px 0 80px;\n background: #f5f7fa;\n }\n\n .case-card {\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.3s ease;\n }\n\n .case-card:hover {\n transform: translateY(-8px);\n box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);\n }\n\n .case-image {\n height: 200px;\n overflow: hidden;\n }\n\n .case-image img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.3s ease;\n }\n\n .case-card:hover .case-image img {\n transform: scale(1.05);\n }\n\n .case-content {\n padding: 24px;\n }\n\n .case-meta {\n margin-bottom: 16px;\n }\n\n .case-challenge,\n .case-solution {\n margin: 12px 0;\n }\n\n .case-results {\n margin: 24px 0;\n }\n\n .case-results ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n\n .case-results li {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n }\n\n .result-icon {\n color: #52c41a;\n }\n\n .case-testimonial {\n margin: 24px 0;\n padding: 16px;\n background: #f0f2f5;\n border-radius: 8px;\n }\n\n .testimonial-rating {\n color: #faad14;\n margin-bottom: 16px;\n }\n\n .testimonial-author {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n }\n\n .author-icon {\n font-size: 24px;\n color: #1890ff;\n }\n\n .case-button {\n margin-top: 16px;\n }\n\n .pagination {\n margin-top: 40px;\n display: flex;\n justify-content: center;\n }\n\n .testimonial-carousel {\n padding: 80px 0;\n background: #fff;\n }\n\n .carousel {\n margin-top: 40px;\n }\n\n .carousel-item {\n padding: 0 16px;\n }\n\n .testimonial-card {\n padding: 32px;\n border-radius: 8px;\n text-align: center;\n }\n\n .star {\n color: #faad14;\n margin-right: 4px;\n }\n\n .cta {\n padding: 80px 0;\n background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);\n color: #fff;\n text-align: center;\n }\n\n .cta .ant-btn {\n margin-top: 24px;\n }\n\n @media (max-width: 768px) {\n .case-header {\n padding: 60px 0 30px;\n }\n\n .category-filter {\n padding: 30px 0;\n }\n\n .case-list {\n padding: 30px 0 60px;\n }\n\n .testimonial-carousel {\n padding: 60px 0;\n }\n\n .cta {\n padding: 60px 0;\n }\n }\n `}</style>\n </div>\n );\n};\n\nexport default CaseStudy;",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/CaseStudy.tsx"
|
||
},
|
||
"4": {
|
||
"path": "/case-study/:id",
|
||
"layout": false,
|
||
"file": "@/pages/CaseStudy.tsx",
|
||
"id": "4",
|
||
"absPath": "/case-study/:id",
|
||
"__content": "import React, { useState } from 'react';\nimport { Link, useNavigate } from 'umi';\nimport { Card, Button, Typography, Row, Col, Tag, Carousel, Pagination } from 'antd';\nimport { ArrowRightOutlined, CheckCircleOutlined, DollarOutlined, BarChartOutlined, ZapOutlined, GlobeOutlined, StarOutlined, UserOutlined, CompanyOutlined, TrendingUpOutlined } from '@ant-design/icons';\nimport Navbar from '@/components/Navbar';\n\nconst { Title, Paragraph, Text } = Typography;\n\nconst CaseStudy: React.FC = () => {\n const navigate = useNavigate();\n const [activeCategory, setActiveCategory] = useState('all');\n const [currentPage, setCurrentPage] = useState(1);\n\n const caseStudies = [\n {\n id: 1,\n title: '中小商户案例:月销售额提升45%',\n category: 'small',\n company: '广州某跨境电商公司',\n industry: '电子产品',\n challenge: '手动选品效率低,定价策略单一,运营成本高',\n solution: '使用智能选品系统和AI动态定价,实现自动化运营',\n results: [\n '月销售额提升45%',\n '运营成本降低30%',\n '选品效率提升60%',\n ],\n testimonial: '\"Crawlful Hub帮助我们实现了店铺的自动化运营,节省了大量人力成本,销售额提升了40%。\"',\n author: '张总',\n position: 'CEO',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 2,\n title: '大型企业案例:多店铺管理效率提升60%',\n category: 'enterprise',\n company: '深圳某品牌电商',\n industry: '服装行业',\n challenge: '多店铺管理复杂,数据分散,难以统一运营',\n solution: '使用多店铺管理系统,实现数据集中管理和统一运营',\n results: [\n '管理效率提升60%',\n '数据处理时间减少70%',\n '运营成本降低25%',\n ],\n testimonial: '\"多店铺管理功能让我们能够集中管理所有店铺,数据一目了然,大大提高了管理效率。\"',\n author: '李经理',\n position: '运营总监',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 3,\n title: '跨境电商案例:利润率提升30%',\n category: 'crossborder',\n company: '杭州某跨境电商平台',\n industry: '家居用品',\n challenge: '跨平台价格差异难以把握,利润空间小',\n solution: '使用跨平台套利系统,发现价格差异,优化定价策略',\n results: [\n '利润率提升30%',\n '价格优化效率提升80%',\n '市场竞争力增强',\n ],\n testimonial: '\"跨平台套利系统帮助我们发现了很多价格差异,利润率提高了30%,市场竞争力大大增强。\"',\n author: '王女士',\n position: '业务经理',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 4,\n title: '新手卖家案例:快速启动电商业务',\n category: 'small',\n company: '上海某个人卖家',\n industry: '美妆产品',\n challenge: '缺乏电商运营经验,选品困难,运营成本高',\n solution: '使用智能选品系统和自动上架功能,快速启动业务',\n results: [\n '业务启动时间缩短50%',\n '选品准确率提升70%',\n '首月销售额达到预期目标',\n ],\n testimonial: '\"作为新手卖家,Crawlful Hub帮助我快速启动了电商业务,选品和上架都变得非常简单。\"',\n author: '陈先生',\n position: '个人卖家',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 5,\n title: '传统企业转型案例:线上销售额占比提升至60%',\n category: 'enterprise',\n company: '北京某传统制造企业',\n industry: '机械设备',\n challenge: '线上业务占比低,数字化转型困难',\n solution: '使用全功能电商管理系统,实现线上线下一体化运营',\n results: [\n '线上销售额占比提升至60%',\n '客户获取成本降低40%',\n '品牌知名度提升',\n ],\n testimonial: '\"Crawlful Hub帮助我们成功实现了数字化转型,线上销售额占比从10%提升到了60%。\"',\n author: '赵总',\n position: '总经理',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n {\n id: 6,\n title: '多平台运营案例:管理效率提升70%',\n category: 'crossborder',\n company: '厦门某跨境电商公司',\n industry: '玩具产品',\n challenge: '多平台运营管理复杂,数据不同步,运营效率低',\n solution: '使用多平台集成管理系统,实现数据同步和统一运营',\n results: [\n '管理效率提升70%',\n '数据同步时间减少90%',\n '运营成本降低35%',\n ],\n testimonial: '\"多平台集成管理系统让我们能够统一管理所有平台的店铺,效率大大提升。\"',\n author: '刘经理',\n position: '运营主管',\n image: 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27600%27 height=%27400%27 viewBox=%270 0 600 400%27%3E%3Crect width=%27600%27 height=%27400%27 fill=%27%23f0f2f5%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 dominant-baseline=%27middle%27 text-anchor=%27middle%27 font-family=%27Arial%27 font-size=%2716%27 fill=%27%231890ff%27%3E成功案例展示%3C/text%3E%3C/svg%3E',\n },\n ];\n\n const filteredCases = activeCategory === 'all' \n ? caseStudies \n : caseStudies.filter(caseStudy => caseStudy.category === activeCategory);\n\n const itemsPerPage = 3;\n const totalPages = Math.ceil(filteredCases.length / itemsPerPage);\n const currentCases = filteredCases.slice(\n (currentPage - 1) * itemsPerPage,\n currentPage * itemsPerPage\n );\n\n const categories = [\n { value: 'all', label: '全部案例' },\n { value: 'small', label: '中小商户' },\n { value: 'enterprise', label: '大型企业' },\n { value: 'crossborder', label: '跨境电商' },\n ];\n\n return (\n <div className=\"case-study-page\">\n <Navbar />\n {/* 页面头部 */}\n <section className=\"case-header\">\n <div className=\"container\">\n <Title level={1}>成功案例</Title>\n <Paragraph className=\"subtitle\">\n 看看我们如何帮助客户实现业务增长\n </Paragraph>\n </div>\n </section>\n\n {/* 分类筛选 */}\n <section className=\"category-filter\">\n <div className=\"container\">\n <div className=\"categories\">\n {categories.map(category => (\n <Button\n key={category.value}\n type={activeCategory === category.value ? 'primary' : 'default'}\n onClick={() => {\n setActiveCategory(category.value);\n setCurrentPage(1);\n }}\n >\n {category.label}\n </Button>\n ))}\n </div>\n </div>\n </section>\n\n {/* 案例列表 */}\n <section className=\"case-list\">\n <div className=\"container\">\n <Row gutter={[32, 32]}>\n {currentCases.map(caseStudy => (\n <Col key={caseStudy.id} xs={24} md={8}>\n <Card hoverable className=\"case-card\">\n <div className=\"case-image\">\n <img src={caseStudy.image} alt={caseStudy.title} />\n </div>\n <div className=\"case-content\">\n <div className=\"case-meta\">\n <Tag color=\"blue\">{caseStudy.industry}</Tag>\n <Tag color=\"green\">{caseStudy.company}</Tag>\n </div>\n <Title level={4}>{caseStudy.title}</Title>\n <Paragraph className=\"case-challenge\">\n <Text strong>挑战:</Text>{caseStudy.challenge}\n </Paragraph>\n <Paragraph className=\"case-solution\">\n <Text strong>解决方案:</Text>{caseStudy.solution}\n </Paragraph>\n <div className=\"case-results\">\n <Title level={5}>成果:</Title>\n <ul>\n {caseStudy.results.map((result, index) => (\n <li key={index}>\n <CheckCircleOutlined className=\"result-icon\" />\n {result}\n </li>\n ))}\n </ul>\n </div>\n <div className=\"case-testimonial\">\n <div className=\"testimonial-content\">\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <StarOutlined className=\"star\" />\n <Paragraph>{caseStudy.testimonial}</Paragraph>\n </div>\n <div className=\"testimonial-author\">\n <UserOutlined className=\"author-icon\" />\n <div>\n <Text strong>{caseStudy.author}</Text>\n <Text type=\"secondary\">{caseStudy.position}</Text>\n </div>\n </div>\n </div>\n <Button type=\"primary\" className=\"case-button\" onClick={() => navigate(`/case-study/${caseStudy.id}`)}>\n 查看详情\n <ArrowRightOutlined />\n </Button>\n </div>\n </Card>\n </Col>\n ))}\n </Row>\n \n {/* 分页 */}\n {totalPages > 1 && (\n <div className=\"pagination\">\n <Pagination\n current={currentPage}\n total={filteredCases.length}\n pageSize={itemsPerPage}\n onChange={setCurrentPage}\n showSizeChanger={false}\n />\n </div>\n )}\n </div>\n </section>\n\n {/* 客户评价轮播 */}\n <section className=\"testimonial-carousel\">\n <div className=\"container\">\n <Title level={2}>客户评价</Title>\n <Carousel autoplay className=\"carousel\">\n {caseStudies.map(caseStudy => (\n <div key={caseStudy.id} className=\"carousel-item\">\n <Card className=\"testimonial-card\">\n <div className=\"testimonial-rating\">\n {[1, 2, 3, 4, 5].map(star => (\n <StarOutlined key={star} className=\"star\" />\n ))}\n </div>\n <Paragraph>{caseStudy.testimonial}</Paragraph>\n <div className=\"testimonial-author\">\n <UserOutlined className=\"author-icon\" />\n <div>\n <Text strong>{caseStudy.author}</Text>\n <Text type=\"secondary\">{caseStudy.position},{caseStudy.company}</Text>\n </div>\n </div>\n </Card>\n </div>\n ))}\n </Carousel>\n </div>\n </section>\n\n {/* 行动召唤 */}\n <section className=\"cta\">\n <div className=\"container\">\n <Title level={2}>准备好实现您的业务增长了吗?</Title>\n <Paragraph>加入我们的成功客户行列,开始您的电商增长之旅</Paragraph>\n <Button type=\"primary\" size=\"large\" onClick={() => navigate('/auth/register')}>\n 免费注册\n </Button>\n </div>\n </section>\n\n <style jsx>{`\n .case-study-page {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n }\n\n .case-header {\n padding: 140px 0 40px;\n background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n text-align: center;\n }\n\n @media (max-width: 768px) {\n .case-header {\n padding: 120px 0 30px;\n }\n }\n\n .subtitle {\n font-size: 18px;\n color: #666;\n margin: 16px 0;\n }\n\n .category-filter {\n padding: 40px 0;\n background: #fff;\n }\n\n .categories {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .case-list {\n padding: 40px 0 80px;\n background: #f5f7fa;\n }\n\n .case-card {\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.3s ease;\n }\n\n .case-card:hover {\n transform: translateY(-8px);\n box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);\n }\n\n .case-image {\n height: 200px;\n overflow: hidden;\n }\n\n .case-image img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.3s ease;\n }\n\n .case-card:hover .case-image img {\n transform: scale(1.05);\n }\n\n .case-content {\n padding: 24px;\n }\n\n .case-meta {\n margin-bottom: 16px;\n }\n\n .case-challenge,\n .case-solution {\n margin: 12px 0;\n }\n\n .case-results {\n margin: 24px 0;\n }\n\n .case-results ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n\n .case-results li {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n }\n\n .result-icon {\n color: #52c41a;\n }\n\n .case-testimonial {\n margin: 24px 0;\n padding: 16px;\n background: #f0f2f5;\n border-radius: 8px;\n }\n\n .testimonial-rating {\n color: #faad14;\n margin-bottom: 16px;\n }\n\n .testimonial-author {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n }\n\n .author-icon {\n font-size: 24px;\n color: #1890ff;\n }\n\n .case-button {\n margin-top: 16px;\n }\n\n .pagination {\n margin-top: 40px;\n display: flex;\n justify-content: center;\n }\n\n .testimonial-carousel {\n padding: 80px 0;\n background: #fff;\n }\n\n .carousel {\n margin-top: 40px;\n }\n\n .carousel-item {\n padding: 0 16px;\n }\n\n .testimonial-card {\n padding: 32px;\n border-radius: 8px;\n text-align: center;\n }\n\n .star {\n color: #faad14;\n margin-right: 4px;\n }\n\n .cta {\n padding: 80px 0;\n background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);\n color: #fff;\n text-align: center;\n }\n\n .cta .ant-btn {\n margin-top: 24px;\n }\n\n @media (max-width: 768px) {\n .case-header {\n padding: 60px 0 30px;\n }\n\n .category-filter {\n padding: 30px 0;\n }\n\n .case-list {\n padding: 30px 0 60px;\n }\n\n .testimonial-carousel {\n padding: 60px 0;\n }\n\n .cta {\n padding: 60px 0;\n }\n }\n `}</style>\n </div>\n );\n};\n\nexport default CaseStudy;",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/CaseStudy.tsx"
|
||
},
|
||
"5": {
|
||
"path": "/auth",
|
||
"layout": false,
|
||
"id": "5",
|
||
"absPath": "/auth"
|
||
},
|
||
"6": {
|
||
"path": "login",
|
||
"file": "@/pages/Auth/LoginPage.tsx",
|
||
"parentId": "5",
|
||
"id": "6",
|
||
"absPath": "/auth/login",
|
||
"__content": "import React, { useState } from 'react';\nimport { useNavigate } from 'umi';\nimport {\n Card,\n Form,\n Input,\n Button,\n Checkbox,\n Space,\n Divider,\n Typography,\n Alert,\n message,\n Row,\n Col,\n Image,\n} from 'antd';\nimport {\n UserOutlined,\n LockOutlined,\n SafetyOutlined,\n EyeInvisibleOutlined,\n EyeTwoTone,\n LoginOutlined,\n GoogleOutlined,\n GithubOutlined,\n} from '@ant-design/icons';\n\nconst { Title, Text, Link } = Typography;\n\ninterface LoginFormValues {\n username: string;\n password: string;\n remember: boolean;\n captcha?: string;\n}\n\nexport const LoginPage: React.FC = () => {\n const [form] = Form.useForm();\n const [loading, setLoading] = useState(false);\n const [loginError, setLoginError] = useState<string | null>(null);\n const [captchaCode, setCaptchaCode] = useState('');\n const navigate = useNavigate();\n\n const generateCaptcha = () => {\n const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\n let result = '';\n for (let i = 0; i < 4; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n setCaptchaCode(result);\n };\n\n React.useEffect(() => {\n generateCaptcha();\n }, []);\n\n const handleLogin = async (values: LoginFormValues) => {\n setLoading(true);\n setLoginError(null);\n\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n\n if (values.captcha?.toUpperCase() !== captchaCode) {\n setLoginError('Invalid verification code');\n generateCaptcha();\n setLoading(false);\n return;\n }\n\n message.success('Login successful! Redirecting...');\n setTimeout(() => {\n navigate('/dashboard');\n }, 1000);\n } catch (error) {\n setLoginError('Login failed. Please check your credentials.');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n padding: 24,\n }}>\n <Row gutter={[48, 0]} align=\"middle\" style={{ maxWidth: 1000, width: '100%' }}>\n <Col xs={0} md={12}>\n <div style={{ color: 'white', paddingRight: 48 }}>\n <Title level={1} style={{ color: 'white', marginBottom: 24 }}>\n Crawlful Hub\n </Title>\n <Text style={{ color: 'rgba(255,255,255,0.9)', fontSize: 18, display: 'block', marginBottom: 32 }}>\n Your all-in-one cross-border e-commerce management platform\n </Text>\n <Space direction=\"vertical\" size=\"large\" style={{ color: 'rgba(255,255,255,0.8)' }}>\n <div>✓ Multi-platform integration</div>\n <div>✓ Automated operations</div>\n <div>✓ Real-time analytics</div>\n <div>✓ Compliance management</div>\n </Space>\n </div>\n </Col>\n\n <Col xs={24} md={12}>\n <Card\n style={{\n borderRadius: 16,\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n bodyStyle={{ padding: 40 }}\n >\n <div style={{ textAlign: 'center', marginBottom: 32 }}>\n <Title level={3}>Welcome Back</Title>\n <Text type=\"secondary\">Sign in to your account</Text>\n </div>\n\n {loginError && (\n <Alert\n message={loginError}\n type=\"error\"\n showIcon\n style={{ marginBottom: 24 }}\n closable\n onClose={() => setLoginError(null)}\n />\n )}\n\n <Form\n form={form}\n layout=\"vertical\"\n onFinish={handleLogin}\n initialValues={{ remember: true }}\n >\n <Form.Item\n name=\"username\"\n rules={[\n { required: true, message: 'Please enter your username' },\n { min: 3, message: 'Username must be at least 3 characters' },\n ]}\n >\n <Input\n prefix={<UserOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Username or Email\"\n size=\"large\"\n />\n </Form.Item>\n\n <Form.Item\n name=\"password\"\n rules={[\n { required: true, message: 'Please enter your password' },\n { min: 6, message: 'Password must be at least 6 characters' },\n ]}\n >\n <Input.Password\n prefix={<LockOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Password\"\n size=\"large\"\n iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}\n />\n </Form.Item>\n\n <Form.Item>\n <Row gutter={8} align=\"middle\">\n <Col flex=\"auto\">\n <Form.Item\n name=\"captcha\"\n noStyle\n rules={[{ required: true, message: 'Please enter verification code' }]}\n >\n <Input\n prefix={<SafetyOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Verification Code\"\n size=\"large\"\n maxLength={4}\n />\n </Form.Item>\n </Col>\n <Col>\n <div\n onClick={generateCaptcha}\n style={{\n width: 100,\n height: 40,\n background: '#f0f2f5',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: 'monospace',\n fontSize: 20,\n letterSpacing: 4,\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: 4,\n color: '#1890ff',\n fontWeight: 'bold',\n }}\n >\n {captchaCode}\n </div>\n </Col>\n </Row>\n </Form.Item>\n\n <Form.Item>\n <Row justify=\"space-between\" align=\"middle\">\n <Col>\n <Form.Item name=\"remember\" valuePropName=\"checked\" noStyle>\n <Checkbox>Remember me</Checkbox>\n </Form.Item>\n </Col>\n <Col>\n <Link href=\"/auth/reset-password\">Forgot password?</Link>\n </Col>\n </Row>\n </Form.Item>\n\n <Form.Item>\n <Button\n type=\"primary\"\n htmlType=\"submit\"\n size=\"large\"\n block\n loading={loading}\n icon={<LoginOutlined />}\n >\n Sign In\n </Button>\n </Form.Item>\n\n <Divider>Or continue with</Divider>\n\n <Space style={{ width: '100%', justifyContent: 'center' }}>\n <Button icon={<GoogleOutlined />} size=\"large\">\n Google\n </Button>\n <Button icon={<GithubOutlined />} size=\"large\">\n GitHub\n </Button>\n </Space>\n\n <div style={{ textAlign: 'center', marginTop: 24 }}>\n <Text type=\"secondary\">\n Don't have an account? <Link href=\"/auth/register\">Sign up</Link>\n </Text>\n </div>\n </Form>\n </Card>\n </Col>\n </Row>\n </div>\n );\n};\n\nexport default LoginPage;\n",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/Auth/LoginPage.tsx"
|
||
},
|
||
"7": {
|
||
"path": "register",
|
||
"file": "@/pages/Auth/RegisterPage.tsx",
|
||
"parentId": "5",
|
||
"id": "7",
|
||
"absPath": "/auth/register",
|
||
"__content": "import React, { useState } from 'react';\nimport {\n Card,\n Form,\n Input,\n Button,\n Checkbox,\n Space,\n Divider,\n Typography,\n Alert,\n message,\n Steps,\n Row,\n Col,\n Select,\n} from 'antd';\nimport {\n UserOutlined,\n LockOutlined,\n MailOutlined,\n SafetyOutlined,\n EyeInvisibleOutlined,\n EyeTwoTone,\n UserAddOutlined,\n CheckCircleOutlined,\n ArrowLeftOutlined,\n ArrowRightOutlined,\n BankOutlined,\n PhoneOutlined,\n} from '@ant-design/icons';\n\nconst { Title, Text, Link } = Typography;\nconst { Step } = Steps;\nconst { Option } = Select;\n\ninterface RegisterFormValues {\n username: string;\n email: string;\n password: string;\n confirmPassword: string;\n companyName: string;\n phone: string;\n businessType: string;\n agreeTerms: boolean;\n captcha: string;\n}\n\nexport const RegisterPage: React.FC = () => {\n const [form] = Form.useForm();\n const [currentStep, setCurrentStep] = useState(0);\n const [loading, setLoading] = useState(false);\n const [registerError, setRegisterError] = useState<string | null>(null);\n const [captchaCode, setCaptchaCode] = useState('');\n const [registrationComplete, setRegistrationComplete] = useState(false);\n\n const generateCaptcha = () => {\n const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\n let result = '';\n for (let i = 0; i < 4; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n setCaptchaCode(result);\n };\n\n React.useEffect(() => {\n generateCaptcha();\n }, []);\n\n const steps = [\n { title: 'Account', description: 'Basic info' },\n { title: 'Business', description: 'Company details' },\n { title: 'Verify', description: 'Confirmation' },\n ];\n\n const nextStep = async () => {\n try {\n if (currentStep === 0) {\n await form.validateFields(['username', 'email', 'password', 'confirmPassword']);\n } else if (currentStep === 1) {\n await form.validateFields(['companyName', 'phone', 'businessType']);\n }\n setCurrentStep(currentStep + 1);\n } catch (error) {\n // Validation failed\n }\n };\n\n const prevStep = () => {\n setCurrentStep(currentStep - 1);\n };\n\n const handleRegister = async (values: RegisterFormValues) => {\n setLoading(true);\n setRegisterError(null);\n\n try {\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n if (values.captcha?.toUpperCase() !== captchaCode) {\n setRegisterError('Invalid verification code');\n generateCaptcha();\n setLoading(false);\n return;\n }\n\n setRegistrationComplete(true);\n message.success('Registration successful!');\n } catch (error) {\n setRegisterError('Registration failed. Please try again.');\n } finally {\n setLoading(false);\n }\n };\n\n if (registrationComplete) {\n return (\n <div style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n padding: 24,\n }}>\n <Card style={{ maxWidth: 500, width: '100%', textAlign: 'center', borderRadius: 16 }}>\n <CheckCircleOutlined style={{ fontSize: 80, color: '#52c41a', marginBottom: 24 }} />\n <Title level={3}>Registration Complete!</Title>\n <Text type=\"secondary\" style={{ display: 'block', marginBottom: 24 }}>\n Your account has been created successfully. Please check your email to verify your account.\n </Text>\n <Button type=\"primary\" size=\"large\" href=\"/auth/login\">\n Go to Login\n </Button>\n </Card>\n </div>\n );\n }\n\n return (\n <div style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n padding: 24,\n }}>\n <Card\n style={{\n maxWidth: 600,\n width: '100%',\n borderRadius: 16,\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n bodyStyle={{ padding: 40 }}\n >\n <div style={{ textAlign: 'center', marginBottom: 32 }}>\n <Title level={3}>Create Account</Title>\n <Text type=\"secondary\">Join Crawlful Hub today</Text>\n </div>\n\n <Steps current={currentStep} style={{ marginBottom: 32 }}>\n {steps.map(step => (\n <Step key={step.title} title={step.title} description={step.description} />\n ))}\n </Steps>\n\n {registerError && (\n <Alert\n message={registerError}\n type=\"error\"\n showIcon\n style={{ marginBottom: 24 }}\n closable\n onClose={() => setRegisterError(null)}\n />\n )}\n\n <Form\n form={form}\n layout=\"vertical\"\n onFinish={handleRegister}\n >\n {currentStep === 0 && (\n <>\n <Form.Item\n name=\"username\"\n rules={[\n { required: true, message: 'Please enter username' },\n { min: 3, message: 'Username must be at least 3 characters' },\n { pattern: /^[a-zA-Z0-9_]+$/, message: 'Only letters, numbers and underscores allowed' },\n ]}\n >\n <Input\n prefix={<UserOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Username\"\n size=\"large\"\n />\n </Form.Item>\n\n <Form.Item\n name=\"email\"\n rules={[\n { required: true, message: 'Please enter email' },\n { type: 'email', message: 'Please enter valid email' },\n ]}\n >\n <Input\n prefix={<MailOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Email\"\n size=\"large\"\n />\n </Form.Item>\n\n <Form.Item\n name=\"password\"\n rules={[\n { required: true, message: 'Please enter password' },\n { min: 8, message: 'Password must be at least 8 characters' },\n { pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)/, message: 'Must contain uppercase, lowercase and number' },\n ]}\n >\n <Input.Password\n prefix={<LockOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Password\"\n size=\"large\"\n iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}\n />\n </Form.Item>\n\n <Form.Item\n name=\"confirmPassword\"\n dependencies={['password']}\n rules={[\n { required: true, message: 'Please confirm password' },\n ({ getFieldValue }) => ({\n validator(_, value) {\n if (!value || getFieldValue('password') === value) {\n return Promise.resolve();\n }\n return Promise.reject(new Error('Passwords do not match'));\n },\n }),\n ]}\n >\n <Input.Password\n prefix={<LockOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Confirm Password\"\n size=\"large\"\n iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}\n />\n </Form.Item>\n </>\n )}\n\n {currentStep === 1 && (\n <>\n <Form.Item\n name=\"companyName\"\n rules={[{ required: true, message: 'Please enter company name' }]}\n >\n <Input\n prefix={<BankOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Company Name\"\n size=\"large\"\n />\n </Form.Item>\n\n <Form.Item\n name=\"phone\"\n rules={[\n { required: true, message: 'Please enter phone number' },\n { pattern: /^\\+?[\\d\\s-()]+$/, message: 'Please enter valid phone number' },\n ]}\n >\n <Input\n prefix={<PhoneOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Phone Number\"\n size=\"large\"\n />\n </Form.Item>\n\n <Form.Item\n name=\"businessType\"\n rules={[{ required: true, message: 'Please select business type' }]}\n >\n <Select placeholder=\"Business Type\" size=\"large\">\n <Option value=\"manufacturer\">Manufacturer</Option>\n <Option value=\"trading\">Trading Company</Option>\n <Option value=\"wholesaler\">Wholesaler</Option>\n <Option value=\"retailer\">Retailer</Option>\n <Option value=\"other\">Other</Option>\n </Select>\n </Form.Item>\n </>\n )}\n\n {currentStep === 2 && (\n <>\n <Form.Item\n name=\"captcha\"\n rules={[{ required: true, message: 'Please enter verification code' }]}\n >\n <Row gutter={8} align=\"middle\">\n <Col flex=\"auto\">\n <Input\n prefix={<SafetyOutlined style={{ color: '#bfbfbf' }} />}\n placeholder=\"Verification Code\"\n size=\"large\"\n maxLength={4}\n />\n </Col>\n <Col>\n <div\n onClick={generateCaptcha}\n style={{\n width: 100,\n height: 40,\n background: '#f0f2f5',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: 'monospace',\n fontSize: 20,\n letterSpacing: 4,\n cursor: 'pointer',\n userSelect: 'none',\n borderRadius: 4,\n color: '#1890ff',\n fontWeight: 'bold',\n }}\n >\n {captchaCode}\n </div>\n </Col>\n </Row>\n </Form.Item>\n\n <Form.Item\n name=\"agreeTerms\"\n valuePropName=\"checked\"\n rules={[\n {\n validator: (_, value) =>\n value ? Promise.resolve() : Promise.reject(new Error('Please agree to terms')),\n },\n ]}\n >\n <Checkbox>\n I agree to the <Link href=\"/terms\">Terms of Service</Link> and{' '}\n <Link href=\"/privacy\">Privacy Policy</Link>\n </Checkbox>\n </Form.Item>\n </>\n )}\n\n <Form.Item>\n <Row justify=\"space-between\">\n <Col>\n {currentStep > 0 && (\n <Button icon={<ArrowLeftOutlined />} onClick={prevStep}>\n Previous\n </Button>\n )}\n </Col>\n <Col>\n {currentStep < 2 ? (\n <Button type=\"primary\" icon={<ArrowRightOutlined />} onClick={nextStep}>\n Next\n </Button>\n ) : (\n <Button\n type=\"primary\"\n htmlType=\"submit\"\n loading={loading}\n icon={<UserAddOutlined />}\n >\n Create Account\n </Button>\n )}\n </Col>\n </Row>\n </Form.Item>\n </Form>\n\n <Divider />\n\n <div style={{ textAlign: 'center' }}>\n <Text type=\"secondary\">\n Already have an account? <Link href=\"/auth/login\">Sign in</Link>\n </Text>\n </div>\n </Card>\n </div>\n );\n};\n\nexport default RegisterPage;\n",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/Auth/RegisterPage.tsx"
|
||
},
|
||
"8": {
|
||
"path": "/dashboard",
|
||
"layout": "@/layouts/index",
|
||
"parentId": "@@/global-layout",
|
||
"id": "8",
|
||
"absPath": "/dashboard"
|
||
},
|
||
"9": {
|
||
"path": "",
|
||
"file": "@/pages/OperationAgent.tsx",
|
||
"parentId": "8",
|
||
"id": "9",
|
||
"absPath": "/dashboard",
|
||
"__content": "import React, { useState, useEffect } from 'react';\nimport { Button, Table, Form, Input, Select, Modal, message, Card, Tabs, Space, Tag, Divider, Alert } from 'antd';\nimport { PlusOutlined, SyncOutlined, EditOutlined, DeleteOutlined, CheckOutlined, CloseOutlined, LoadingOutlined } from '@ant-design/icons';\nimport { operationAgentService, Store, StoreBindingData } from '../services/operationAgentService';\n\nconst { Option } = Select;\nconst { TabPane } = Tabs;\nconst { TextArea } = Input;\n\nconst platforms = [\n { value: 'amazon', label: 'Amazon' },\n { value: 'shopee', label: 'Shopee' },\n { value: 'aliexpress', label: 'AliExpress' },\n { value: 'tiktok', label: 'TikTok' },\n { value: 'ebay', label: 'Ebay' },\n { value: 'lazada', label: 'Lazada' },\n { value: 'wish', label: 'Wish' },\n { value: 'shein', label: 'Shein' },\n { value: 'jd_worldwide', label: 'JD Worldwide' },\n { value: 'walmart', label: 'Walmart' },\n { value: 'etsy', label: 'Etsy' },\n { value: 'target', label: 'Target' },\n { value: 'newegg', label: 'Newegg' },\n { value: 'cdiscount', label: 'Cdiscount' },\n { value: 'allegro', label: 'Allegro' },\n { value: 'otto', label: 'Otto' },\n { value: 'rakuten', label: 'Rakuten' },\n { value: 'qoo10', label: 'Qoo10' },\n];\n\nconst statusMap = {\n active: { color: 'green', text: '活跃' },\n inactive: { color: 'red', text: '停用' },\n pending: { color: 'orange', text: '待处理' },\n suspended: { color: 'gray', text: '暂停' },\n};\n\nconst OperationAgent: React.FC = () => {\n const [stores, setStores] = useState<Store[]>([]);\n const [loading, setLoading] = useState(false);\n const [bindingModalVisible, setBindingModalVisible] = useState(false);\n const [currentStore, setCurrentStore] = useState<Store | null>(null);\n const [merchantId, setMerchantId] = useState('merchant-1'); // 默认商户ID\n const [form] = Form.useForm();\n\n // 加载店铺列表\n const loadStores = async () => {\n setLoading(true);\n try {\n const data = await operationAgentService.getStores(merchantId);\n setStores(data);\n } catch (error) {\n message.error('加载店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 初始加载\n useEffect(() => {\n loadStores();\n }, [merchantId]);\n\n // 绑定店铺\n const handleBindStore = async (values: any) => {\n setLoading(true);\n try {\n const bindingData: StoreBindingData = {\n merchantId: values.merchantId,\n platform: values.platform,\n platformShopId: values.platformShopId,\n name: values.name,\n description: values.description,\n authInfo: {\n ...(values.platform === 'amazon' && {\n accessKey: values.accessKey,\n secretKey: values.secretKey,\n sellerId: values.sellerId,\n marketplaceId: values.marketplaceId,\n }),\n ...(values.platform === 'shopee' && {\n partnerId: values.partnerId,\n partnerKey: values.partnerKey,\n shopId: values.shopId,\n }),\n ...(values.platform === 'aliexpress' && {\n appKey: values.appKey,\n appSecret: values.appSecret,\n accessToken: values.accessToken,\n }),\n ...(values.platform === 'tiktok' && {\n appId: values.appId,\n appSecret: values.appSecret,\n accessToken: values.accessToken,\n }),\n ...(values.platform === 'ebay' && {\n clientId: values.clientId,\n clientSecret: values.clientSecret,\n refreshToken: values.refreshToken,\n }),\n ...(values.platform && !['amazon', 'shopee', 'aliexpress', 'tiktok', 'ebay'].includes(values.platform) && {\n apiKey: values.apiKey,\n apiSecret: values.apiSecret,\n }),\n },\n };\n\n await operationAgentService.bindStore(bindingData);\n message.success('店铺绑定成功');\n setBindingModalVisible(false);\n form.resetFields();\n loadStores();\n } catch (error) {\n message.error('店铺绑定失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 同步商品\n const handleSyncProducts = async (storeId: string) => {\n setLoading(true);\n try {\n const result = await operationAgentService.syncProducts(storeId);\n if (result.success) {\n message.success(`商品同步成功,共 ${result.count} 个商品`);\n } else {\n message.error('商品同步失败');\n }\n } catch (error) {\n message.error('商品同步失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 同步订单\n const handleSyncOrders = async (storeId: string) => {\n setLoading(true);\n try {\n const result = await operationAgentService.syncOrders(storeId);\n if (result.success) {\n message.success(`订单同步成功,共 ${result.count} 个订单`);\n } else {\n message.error('订单同步失败');\n }\n } catch (error) {\n message.error('订单同步失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 停用店铺\n const handleDeactivateStore = async (storeId: string) => {\n setLoading(true);\n try {\n await operationAgentService.deactivateStore(storeId);\n message.success('店铺已停用');\n loadStores();\n } catch (error) {\n message.error('停用店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 重新激活店铺\n const handleReactivateStore = async (storeId: string) => {\n setLoading(true);\n try {\n await operationAgentService.reactivateStore(storeId);\n message.success('店铺已重新激活');\n loadStores();\n } catch (error) {\n message.error('激活店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 查看店铺详情\n const handleViewStore = async (storeId: string) => {\n setLoading(true);\n try {\n const store = await operationAgentService.getStore(storeId);\n setCurrentStore(store);\n } catch (error) {\n message.error('获取店铺详情失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 渲染平台特定的授权信息表单\n const renderAuthInfoForm = (platform: string) => {\n switch (platform) {\n case 'amazon':\n return (\n <>\n <Form.Item name=\"accessKey\" label=\"Access Key\" rules={[{ required: true, message: '请输入Access Key' }]}>\n <Input placeholder=\"请输入Access Key\" />\n </Form.Item>\n <Form.Item name=\"secretKey\" label=\"Secret Key\" rules={[{ required: true, message: '请输入Secret Key' }]}>\n <Input.Password placeholder=\"请输入Secret Key\" />\n </Form.Item>\n <Form.Item name=\"sellerId\" label=\"Seller ID\" rules={[{ required: true, message: '请输入Seller ID' }]}>\n <Input placeholder=\"请输入Seller ID\" />\n </Form.Item>\n <Form.Item name=\"marketplaceId\" label=\"Marketplace ID\" rules={[{ required: true, message: '请输入Marketplace ID' }]}>\n <Input placeholder=\"请输入Marketplace ID\" />\n </Form.Item>\n </>\n );\n case 'shopee':\n return (\n <>\n <Form.Item name=\"partnerId\" label=\"Partner ID\" rules={[{ required: true, message: '请输入Partner ID' }]}>\n <Input placeholder=\"请输入Partner ID\" />\n </Form.Item>\n <Form.Item name=\"partnerKey\" label=\"Partner Key\" rules={[{ required: true, message: '请输入Partner Key' }]}>\n <Input.Password placeholder=\"请输入Partner Key\" />\n </Form.Item>\n <Form.Item name=\"shopId\" label=\"Shop ID\" rules={[{ required: true, message: '请输入Shop ID' }]}>\n <Input placeholder=\"请输入Shop ID\" />\n </Form.Item>\n </>\n );\n case 'aliexpress':\n return (\n <>\n <Form.Item name=\"appKey\" label=\"App Key\" rules={[{ required: true, message: '请输入App Key' }]}>\n <Input placeholder=\"请输入App Key\" />\n </Form.Item>\n <Form.Item name=\"appSecret\" label=\"App Secret\" rules={[{ required: true, message: '请输入App Secret' }]}>\n <Input.Password placeholder=\"请输入App Secret\" />\n </Form.Item>\n <Form.Item name=\"accessToken\" label=\"Access Token\" rules={[{ required: true, message: '请输入Access Token' }]}>\n <Input placeholder=\"请输入Access Token\" />\n </Form.Item>\n </>\n );\n case 'tiktok':\n return (\n <>\n <Form.Item name=\"appId\" label=\"App ID\" rules={[{ required: true, message: '请输入App ID' }]}>\n <Input placeholder=\"请输入App ID\" />\n </Form.Item>\n <Form.Item name=\"appSecret\" label=\"App Secret\" rules={[{ required: true, message: '请输入App Secret' }]}>\n <Input.Password placeholder=\"请输入App Secret\" />\n </Form.Item>\n <Form.Item name=\"accessToken\" label=\"Access Token\" rules={[{ required: true, message: '请输入Access Token' }]}>\n <Input placeholder=\"请输入Access Token\" />\n </Form.Item>\n </>\n );\n case 'ebay':\n return (\n <>\n <Form.Item name=\"clientId\" label=\"Client ID\" rules={[{ required: true, message: '请输入Client ID' }]}>\n <Input placeholder=\"请输入Client ID\" />\n </Form.Item>\n <Form.Item name=\"clientSecret\" label=\"Client Secret\" rules={[{ required: true, message: '请输入Client Secret' }]}>\n <Input.Password placeholder=\"请输入Client Secret\" />\n </Form.Item>\n <Form.Item name=\"refreshToken\" label=\"Refresh Token\" rules={[{ required: true, message: '请输入Refresh Token' }]}>\n <Input placeholder=\"请输入Refresh Token\" />\n </Form.Item>\n </>\n );\n default:\n return (\n <>\n <Form.Item name=\"apiKey\" label=\"API Key\" rules={[{ required: true, message: '请输入API Key' }]}>\n <Input placeholder=\"请输入API Key\" />\n </Form.Item>\n <Form.Item name=\"apiSecret\" label=\"API Secret\" rules={[{ required: true, message: '请输入API Secret' }]}>\n <Input.Password placeholder=\"请输入API Secret\" />\n </Form.Item>\n </>\n );\n }\n };\n\n return (\n <div style={{ padding: '20px' }}>\n <Card title=\"Operation-Agent 管理\" extra={<Button type=\"primary\" icon={<PlusOutlined />} onClick={() => setBindingModalVisible(true)}>绑定店铺</Button>}>\n <Alert\n message=\"操作说明\"\n description=\"本页面用于管理Operation-Agent平台集成,包括店铺绑定、商品/订单同步等功能。\"\n type=\"info\"\n style={{ marginBottom: '20px' }}\n />\n\n <Form layout=\"inline\" onFinish={(values) => setMerchantId(values.merchantId)} style={{ marginBottom: '20px' }}>\n <Form.Item name=\"merchantId\" initialValue={merchantId} label=\"商户ID\">\n <Input placeholder=\"请输入商户ID\" />\n </Form.Item>\n <Form.Item>\n <Button type=\"primary\" htmlType=\"submit\">查询</Button>\n </Form.Item>\n </Form>\n\n <Table\n loading={loading}\n dataSource={stores}\n rowKey=\"id\"\n columns={[\n {\n title: '店铺名称',\n dataIndex: 'name',\n key: 'name',\n },\n {\n title: '平台',\n dataIndex: 'platform',\n key: 'platform',\n render: (platform: string) => {\n const platformInfo = platforms.find(p => p.value === platform);\n return platformInfo ? platformInfo.label : platform;\n },\n },\n {\n title: '平台店铺ID',\n dataIndex: 'platformShopId',\n key: 'platformShopId',\n },\n {\n title: '状态',\n dataIndex: 'status',\n key: 'status',\n render: (status: string) => {\n const statusInfo = statusMap[status as keyof typeof statusMap];\n return statusInfo ? (\n <Tag color={statusInfo.color}>{statusInfo.text}</Tag>\n ) : (\n <Tag color=\"default\">{status}</Tag>\n );\n },\n },\n {\n title: '创建时间',\n dataIndex: 'created_at',\n key: 'created_at',\n },\n {\n title: '操作',\n key: 'action',\n render: (_: any, record: Store) => (\n <Space size=\"middle\">\n <Button icon={<SyncOutlined />} onClick={() => handleSyncProducts(record.id)}>同步商品</Button>\n <Button icon={<SyncOutlined />} onClick={() => handleSyncOrders(record.id)}>同步订单</Button>\n {record.status === 'active' ? (\n <Button danger icon={<CloseOutlined />} onClick={() => handleDeactivateStore(record.id)}>停用</Button>\n ) : (\n <Button type=\"primary\" icon={<CheckOutlined />} onClick={() => handleReactivateStore(record.id)}>激活</Button>\n )}\n </Space>\n ),\n },\n ]}\n />\n </Card>\n\n {/* 绑定店铺模态框 */}\n <Modal\n title=\"绑定店铺\"\n visible={bindingModalVisible}\n onCancel={() => setBindingModalVisible(false)}\n footer={null}\n >\n <Form form={form} layout=\"vertical\" onFinish={handleBindStore}>\n <Form.Item name=\"merchantId\" label=\"商户ID\" rules={[{ required: true, message: '请输入商户ID' }]} initialValue={merchantId}>\n <Input placeholder=\"请输入商户ID\" />\n </Form.Item>\n <Form.Item name=\"platform\" label=\"平台\" rules={[{ required: true, message: '请选择平台' }]}>\n <Select placeholder=\"请选择平台\" onChange={() => form.resetFields(['accessKey', 'secretKey', 'sellerId', 'marketplaceId', 'partnerId', 'partnerKey', 'shopId', 'appKey', 'appSecret', 'accessToken', 'appId', 'clientId', 'clientSecret', 'refreshToken', 'apiKey', 'apiSecret'])}>\n {platforms.map(platform => (\n <Option key={platform.value} value={platform.value}>{platform.label}</Option>\n ))}\n </Select>\n </Form.Item>\n <Form.Item name=\"platformShopId\" label=\"平台店铺ID\" rules={[{ required: true, message: '请输入平台店铺ID' }]}>\n <Input placeholder=\"请输入平台店铺ID\" />\n </Form.Item>\n <Form.Item name=\"name\" label=\"店铺名称\" rules={[{ required: true, message: '请输入店铺名称' }]}>\n <Input placeholder=\"请输入店铺名称\" />\n </Form.Item>\n <Form.Item name=\"description\" label=\"店铺描述\">\n <TextArea placeholder=\"请输入店铺描述\" rows={3} />\n </Form.Item>\n <Divider orientation=\"left\">授权信息</Divider>\n <Form.Item name=\"platform\" noStyle shouldUpdate>\n {({ getFieldValue }) => {\n const platform = getFieldValue('platform');\n return platform ? renderAuthInfoForm(platform) : null;\n }}\n </Form.Item>\n <Form.Item>\n <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n <Button onClick={() => setBindingModalVisible(false)}>取消</Button>\n <Button type=\"primary\" htmlType=\"submit\" loading={loading}>\n 绑定\n </Button>\n </Space>\n </Form.Item>\n </Form>\n </Modal>\n\n {/* 店铺详情模态框 */}\n {currentStore && (\n <Modal\n title=\"店铺详情\"\n visible={!!currentStore}\n onCancel={() => setCurrentStore(null)}\n footer={null}\n >\n <Card>\n <Card.Meta title={currentStore.name} description={`平台: ${platforms.find(p => p.value === currentStore.platform)?.label || currentStore.platform}`} />\n <Divider />\n <p><strong>商户ID:</strong> {currentStore.merchantId}</p>\n <p><strong>平台店铺ID:</strong> {currentStore.platformShopId}</p>\n <p><strong>状态:</strong> <Tag color={statusMap[currentStore.status as keyof typeof statusMap]?.color || 'default'}>{statusMap[currentStore.status as keyof typeof statusMap]?.text || currentStore.status}</Tag></p>\n <p><strong>描述:</strong> {currentStore.description || '无'}</p>\n <p><strong>创建时间:</strong> {currentStore.created_at}</p>\n <p><strong>更新时间:</strong> {currentStore.updated_at}</p>\n <Divider />\n <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n <Button onClick={() => setCurrentStore(null)}>关闭</Button>\n </Space>\n </Card>\n </Modal>\n )}\n </div>\n );\n};\n\nexport default OperationAgent;\n",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/OperationAgent.tsx"
|
||
},
|
||
"10": {
|
||
"path": "operation-agent",
|
||
"file": "@/pages/OperationAgent.tsx",
|
||
"parentId": "8",
|
||
"id": "10",
|
||
"absPath": "/dashboard/operation-agent",
|
||
"__content": "import React, { useState, useEffect } from 'react';\nimport { Button, Table, Form, Input, Select, Modal, message, Card, Tabs, Space, Tag, Divider, Alert } from 'antd';\nimport { PlusOutlined, SyncOutlined, EditOutlined, DeleteOutlined, CheckOutlined, CloseOutlined, LoadingOutlined } from '@ant-design/icons';\nimport { operationAgentService, Store, StoreBindingData } from '../services/operationAgentService';\n\nconst { Option } = Select;\nconst { TabPane } = Tabs;\nconst { TextArea } = Input;\n\nconst platforms = [\n { value: 'amazon', label: 'Amazon' },\n { value: 'shopee', label: 'Shopee' },\n { value: 'aliexpress', label: 'AliExpress' },\n { value: 'tiktok', label: 'TikTok' },\n { value: 'ebay', label: 'Ebay' },\n { value: 'lazada', label: 'Lazada' },\n { value: 'wish', label: 'Wish' },\n { value: 'shein', label: 'Shein' },\n { value: 'jd_worldwide', label: 'JD Worldwide' },\n { value: 'walmart', label: 'Walmart' },\n { value: 'etsy', label: 'Etsy' },\n { value: 'target', label: 'Target' },\n { value: 'newegg', label: 'Newegg' },\n { value: 'cdiscount', label: 'Cdiscount' },\n { value: 'allegro', label: 'Allegro' },\n { value: 'otto', label: 'Otto' },\n { value: 'rakuten', label: 'Rakuten' },\n { value: 'qoo10', label: 'Qoo10' },\n];\n\nconst statusMap = {\n active: { color: 'green', text: '活跃' },\n inactive: { color: 'red', text: '停用' },\n pending: { color: 'orange', text: '待处理' },\n suspended: { color: 'gray', text: '暂停' },\n};\n\nconst OperationAgent: React.FC = () => {\n const [stores, setStores] = useState<Store[]>([]);\n const [loading, setLoading] = useState(false);\n const [bindingModalVisible, setBindingModalVisible] = useState(false);\n const [currentStore, setCurrentStore] = useState<Store | null>(null);\n const [merchantId, setMerchantId] = useState('merchant-1'); // 默认商户ID\n const [form] = Form.useForm();\n\n // 加载店铺列表\n const loadStores = async () => {\n setLoading(true);\n try {\n const data = await operationAgentService.getStores(merchantId);\n setStores(data);\n } catch (error) {\n message.error('加载店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 初始加载\n useEffect(() => {\n loadStores();\n }, [merchantId]);\n\n // 绑定店铺\n const handleBindStore = async (values: any) => {\n setLoading(true);\n try {\n const bindingData: StoreBindingData = {\n merchantId: values.merchantId,\n platform: values.platform,\n platformShopId: values.platformShopId,\n name: values.name,\n description: values.description,\n authInfo: {\n ...(values.platform === 'amazon' && {\n accessKey: values.accessKey,\n secretKey: values.secretKey,\n sellerId: values.sellerId,\n marketplaceId: values.marketplaceId,\n }),\n ...(values.platform === 'shopee' && {\n partnerId: values.partnerId,\n partnerKey: values.partnerKey,\n shopId: values.shopId,\n }),\n ...(values.platform === 'aliexpress' && {\n appKey: values.appKey,\n appSecret: values.appSecret,\n accessToken: values.accessToken,\n }),\n ...(values.platform === 'tiktok' && {\n appId: values.appId,\n appSecret: values.appSecret,\n accessToken: values.accessToken,\n }),\n ...(values.platform === 'ebay' && {\n clientId: values.clientId,\n clientSecret: values.clientSecret,\n refreshToken: values.refreshToken,\n }),\n ...(values.platform && !['amazon', 'shopee', 'aliexpress', 'tiktok', 'ebay'].includes(values.platform) && {\n apiKey: values.apiKey,\n apiSecret: values.apiSecret,\n }),\n },\n };\n\n await operationAgentService.bindStore(bindingData);\n message.success('店铺绑定成功');\n setBindingModalVisible(false);\n form.resetFields();\n loadStores();\n } catch (error) {\n message.error('店铺绑定失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 同步商品\n const handleSyncProducts = async (storeId: string) => {\n setLoading(true);\n try {\n const result = await operationAgentService.syncProducts(storeId);\n if (result.success) {\n message.success(`商品同步成功,共 ${result.count} 个商品`);\n } else {\n message.error('商品同步失败');\n }\n } catch (error) {\n message.error('商品同步失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 同步订单\n const handleSyncOrders = async (storeId: string) => {\n setLoading(true);\n try {\n const result = await operationAgentService.syncOrders(storeId);\n if (result.success) {\n message.success(`订单同步成功,共 ${result.count} 个订单`);\n } else {\n message.error('订单同步失败');\n }\n } catch (error) {\n message.error('订单同步失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 停用店铺\n const handleDeactivateStore = async (storeId: string) => {\n setLoading(true);\n try {\n await operationAgentService.deactivateStore(storeId);\n message.success('店铺已停用');\n loadStores();\n } catch (error) {\n message.error('停用店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 重新激活店铺\n const handleReactivateStore = async (storeId: string) => {\n setLoading(true);\n try {\n await operationAgentService.reactivateStore(storeId);\n message.success('店铺已重新激活');\n loadStores();\n } catch (error) {\n message.error('激活店铺失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 查看店铺详情\n const handleViewStore = async (storeId: string) => {\n setLoading(true);\n try {\n const store = await operationAgentService.getStore(storeId);\n setCurrentStore(store);\n } catch (error) {\n message.error('获取店铺详情失败');\n console.error(error);\n } finally {\n setLoading(false);\n }\n };\n\n // 渲染平台特定的授权信息表单\n const renderAuthInfoForm = (platform: string) => {\n switch (platform) {\n case 'amazon':\n return (\n <>\n <Form.Item name=\"accessKey\" label=\"Access Key\" rules={[{ required: true, message: '请输入Access Key' }]}>\n <Input placeholder=\"请输入Access Key\" />\n </Form.Item>\n <Form.Item name=\"secretKey\" label=\"Secret Key\" rules={[{ required: true, message: '请输入Secret Key' }]}>\n <Input.Password placeholder=\"请输入Secret Key\" />\n </Form.Item>\n <Form.Item name=\"sellerId\" label=\"Seller ID\" rules={[{ required: true, message: '请输入Seller ID' }]}>\n <Input placeholder=\"请输入Seller ID\" />\n </Form.Item>\n <Form.Item name=\"marketplaceId\" label=\"Marketplace ID\" rules={[{ required: true, message: '请输入Marketplace ID' }]}>\n <Input placeholder=\"请输入Marketplace ID\" />\n </Form.Item>\n </>\n );\n case 'shopee':\n return (\n <>\n <Form.Item name=\"partnerId\" label=\"Partner ID\" rules={[{ required: true, message: '请输入Partner ID' }]}>\n <Input placeholder=\"请输入Partner ID\" />\n </Form.Item>\n <Form.Item name=\"partnerKey\" label=\"Partner Key\" rules={[{ required: true, message: '请输入Partner Key' }]}>\n <Input.Password placeholder=\"请输入Partner Key\" />\n </Form.Item>\n <Form.Item name=\"shopId\" label=\"Shop ID\" rules={[{ required: true, message: '请输入Shop ID' }]}>\n <Input placeholder=\"请输入Shop ID\" />\n </Form.Item>\n </>\n );\n case 'aliexpress':\n return (\n <>\n <Form.Item name=\"appKey\" label=\"App Key\" rules={[{ required: true, message: '请输入App Key' }]}>\n <Input placeholder=\"请输入App Key\" />\n </Form.Item>\n <Form.Item name=\"appSecret\" label=\"App Secret\" rules={[{ required: true, message: '请输入App Secret' }]}>\n <Input.Password placeholder=\"请输入App Secret\" />\n </Form.Item>\n <Form.Item name=\"accessToken\" label=\"Access Token\" rules={[{ required: true, message: '请输入Access Token' }]}>\n <Input placeholder=\"请输入Access Token\" />\n </Form.Item>\n </>\n );\n case 'tiktok':\n return (\n <>\n <Form.Item name=\"appId\" label=\"App ID\" rules={[{ required: true, message: '请输入App ID' }]}>\n <Input placeholder=\"请输入App ID\" />\n </Form.Item>\n <Form.Item name=\"appSecret\" label=\"App Secret\" rules={[{ required: true, message: '请输入App Secret' }]}>\n <Input.Password placeholder=\"请输入App Secret\" />\n </Form.Item>\n <Form.Item name=\"accessToken\" label=\"Access Token\" rules={[{ required: true, message: '请输入Access Token' }]}>\n <Input placeholder=\"请输入Access Token\" />\n </Form.Item>\n </>\n );\n case 'ebay':\n return (\n <>\n <Form.Item name=\"clientId\" label=\"Client ID\" rules={[{ required: true, message: '请输入Client ID' }]}>\n <Input placeholder=\"请输入Client ID\" />\n </Form.Item>\n <Form.Item name=\"clientSecret\" label=\"Client Secret\" rules={[{ required: true, message: '请输入Client Secret' }]}>\n <Input.Password placeholder=\"请输入Client Secret\" />\n </Form.Item>\n <Form.Item name=\"refreshToken\" label=\"Refresh Token\" rules={[{ required: true, message: '请输入Refresh Token' }]}>\n <Input placeholder=\"请输入Refresh Token\" />\n </Form.Item>\n </>\n );\n default:\n return (\n <>\n <Form.Item name=\"apiKey\" label=\"API Key\" rules={[{ required: true, message: '请输入API Key' }]}>\n <Input placeholder=\"请输入API Key\" />\n </Form.Item>\n <Form.Item name=\"apiSecret\" label=\"API Secret\" rules={[{ required: true, message: '请输入API Secret' }]}>\n <Input.Password placeholder=\"请输入API Secret\" />\n </Form.Item>\n </>\n );\n }\n };\n\n return (\n <div style={{ padding: '20px' }}>\n <Card title=\"Operation-Agent 管理\" extra={<Button type=\"primary\" icon={<PlusOutlined />} onClick={() => setBindingModalVisible(true)}>绑定店铺</Button>}>\n <Alert\n message=\"操作说明\"\n description=\"本页面用于管理Operation-Agent平台集成,包括店铺绑定、商品/订单同步等功能。\"\n type=\"info\"\n style={{ marginBottom: '20px' }}\n />\n\n <Form layout=\"inline\" onFinish={(values) => setMerchantId(values.merchantId)} style={{ marginBottom: '20px' }}>\n <Form.Item name=\"merchantId\" initialValue={merchantId} label=\"商户ID\">\n <Input placeholder=\"请输入商户ID\" />\n </Form.Item>\n <Form.Item>\n <Button type=\"primary\" htmlType=\"submit\">查询</Button>\n </Form.Item>\n </Form>\n\n <Table\n loading={loading}\n dataSource={stores}\n rowKey=\"id\"\n columns={[\n {\n title: '店铺名称',\n dataIndex: 'name',\n key: 'name',\n },\n {\n title: '平台',\n dataIndex: 'platform',\n key: 'platform',\n render: (platform: string) => {\n const platformInfo = platforms.find(p => p.value === platform);\n return platformInfo ? platformInfo.label : platform;\n },\n },\n {\n title: '平台店铺ID',\n dataIndex: 'platformShopId',\n key: 'platformShopId',\n },\n {\n title: '状态',\n dataIndex: 'status',\n key: 'status',\n render: (status: string) => {\n const statusInfo = statusMap[status as keyof typeof statusMap];\n return statusInfo ? (\n <Tag color={statusInfo.color}>{statusInfo.text}</Tag>\n ) : (\n <Tag color=\"default\">{status}</Tag>\n );\n },\n },\n {\n title: '创建时间',\n dataIndex: 'created_at',\n key: 'created_at',\n },\n {\n title: '操作',\n key: 'action',\n render: (_: any, record: Store) => (\n <Space size=\"middle\">\n <Button icon={<SyncOutlined />} onClick={() => handleSyncProducts(record.id)}>同步商品</Button>\n <Button icon={<SyncOutlined />} onClick={() => handleSyncOrders(record.id)}>同步订单</Button>\n {record.status === 'active' ? (\n <Button danger icon={<CloseOutlined />} onClick={() => handleDeactivateStore(record.id)}>停用</Button>\n ) : (\n <Button type=\"primary\" icon={<CheckOutlined />} onClick={() => handleReactivateStore(record.id)}>激活</Button>\n )}\n </Space>\n ),\n },\n ]}\n />\n </Card>\n\n {/* 绑定店铺模态框 */}\n <Modal\n title=\"绑定店铺\"\n visible={bindingModalVisible}\n onCancel={() => setBindingModalVisible(false)}\n footer={null}\n >\n <Form form={form} layout=\"vertical\" onFinish={handleBindStore}>\n <Form.Item name=\"merchantId\" label=\"商户ID\" rules={[{ required: true, message: '请输入商户ID' }]} initialValue={merchantId}>\n <Input placeholder=\"请输入商户ID\" />\n </Form.Item>\n <Form.Item name=\"platform\" label=\"平台\" rules={[{ required: true, message: '请选择平台' }]}>\n <Select placeholder=\"请选择平台\" onChange={() => form.resetFields(['accessKey', 'secretKey', 'sellerId', 'marketplaceId', 'partnerId', 'partnerKey', 'shopId', 'appKey', 'appSecret', 'accessToken', 'appId', 'clientId', 'clientSecret', 'refreshToken', 'apiKey', 'apiSecret'])}>\n {platforms.map(platform => (\n <Option key={platform.value} value={platform.value}>{platform.label}</Option>\n ))}\n </Select>\n </Form.Item>\n <Form.Item name=\"platformShopId\" label=\"平台店铺ID\" rules={[{ required: true, message: '请输入平台店铺ID' }]}>\n <Input placeholder=\"请输入平台店铺ID\" />\n </Form.Item>\n <Form.Item name=\"name\" label=\"店铺名称\" rules={[{ required: true, message: '请输入店铺名称' }]}>\n <Input placeholder=\"请输入店铺名称\" />\n </Form.Item>\n <Form.Item name=\"description\" label=\"店铺描述\">\n <TextArea placeholder=\"请输入店铺描述\" rows={3} />\n </Form.Item>\n <Divider orientation=\"left\">授权信息</Divider>\n <Form.Item name=\"platform\" noStyle shouldUpdate>\n {({ getFieldValue }) => {\n const platform = getFieldValue('platform');\n return platform ? renderAuthInfoForm(platform) : null;\n }}\n </Form.Item>\n <Form.Item>\n <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n <Button onClick={() => setBindingModalVisible(false)}>取消</Button>\n <Button type=\"primary\" htmlType=\"submit\" loading={loading}>\n 绑定\n </Button>\n </Space>\n </Form.Item>\n </Form>\n </Modal>\n\n {/* 店铺详情模态框 */}\n {currentStore && (\n <Modal\n title=\"店铺详情\"\n visible={!!currentStore}\n onCancel={() => setCurrentStore(null)}\n footer={null}\n >\n <Card>\n <Card.Meta title={currentStore.name} description={`平台: ${platforms.find(p => p.value === currentStore.platform)?.label || currentStore.platform}`} />\n <Divider />\n <p><strong>商户ID:</strong> {currentStore.merchantId}</p>\n <p><strong>平台店铺ID:</strong> {currentStore.platformShopId}</p>\n <p><strong>状态:</strong> <Tag color={statusMap[currentStore.status as keyof typeof statusMap]?.color || 'default'}>{statusMap[currentStore.status as keyof typeof statusMap]?.text || currentStore.status}</Tag></p>\n <p><strong>描述:</strong> {currentStore.description || '无'}</p>\n <p><strong>创建时间:</strong> {currentStore.created_at}</p>\n <p><strong>更新时间:</strong> {currentStore.updated_at}</p>\n <Divider />\n <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n <Button onClick={() => setCurrentStore(null)}>关闭</Button>\n </Space>\n </Card>\n </Modal>\n )}\n </div>\n );\n};\n\nexport default OperationAgent;\n",
|
||
"__isJSFile": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/pages/OperationAgent.tsx"
|
||
},
|
||
"@@/global-layout": {
|
||
"id": "@@/global-layout",
|
||
"path": "/",
|
||
"file": "D:/trae_projects/makemd/makemd/dashboard/src/layouts/index.tsx",
|
||
"absPath": "/",
|
||
"isLayout": true,
|
||
"__absFile": "D:/trae_projects/makemd/makemd/dashboard/src/layouts/index.tsx"
|
||
}
|
||
},
|
||
"apiRoutes": {},
|
||
"hasSrcDir": true,
|
||
"npmClient": "cnpm",
|
||
"umi": {
|
||
"version": "4.6.31",
|
||
"name": "Umi",
|
||
"importSource": "umi",
|
||
"cliName": "umi"
|
||
},
|
||
"bundleStatus": {
|
||
"done": false
|
||
},
|
||
"mfsuBundleStatus": {
|
||
"done": false
|
||
},
|
||
"react": {
|
||
"version": "18.3.1",
|
||
"path": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react"
|
||
},
|
||
"react-dom": {
|
||
"version": "18.3.1",
|
||
"path": "D:\\trae_projects\\makemd\\makemd\\dashboard\\node_modules\\react-dom"
|
||
},
|
||
"appJS": {
|
||
"path": "D:\\trae_projects\\makemd\\makemd\\dashboard\\src\\app.ts",
|
||
"exports": [
|
||
"render"
|
||
]
|
||
},
|
||
"locale": "zh-CN",
|
||
"globalCSS": [],
|
||
"globalJS": [],
|
||
"overridesCSS": [],
|
||
"bundler": "webpack",
|
||
"git": {
|
||
"originUrl": "https://github.com/Ansonfishing/makemd.git"
|
||
},
|
||
"framework": "react",
|
||
"typescript": {
|
||
"tsVersion": "5.9.3",
|
||
"tslibVersion": "2.8.1"
|
||
},
|
||
"faviconFiles": []
|
||
}
|