feat: 实现业务首页(三栏布局 + 轮播图)
## 首页整体架构
- 新增 src/pages/home/ — 完整首页模块(10 个组件)
- HomePage / HomeContent:三栏弹性布局,拖动分隔条调整列宽
- BannerCarousel:顶部轮播图(antd Carousel,2280×90 长条图片适配)
- LeftPanel:模型选择器(Menu 分组) + 任务记录(Table 分页),纵向拖拽调整比例
- CenterPanel / ModelInputForm:动态表单,根据模型 param_schema/ui_config 渲染控件
- RightPanel / OutputPreview:任务输出预览(Image/Video)
- 新增 Layout 组件:h-screen flex 布局,首页 Banner + NavBar + Outlet
## 数据层(数据与视图分离)
- 新增 src/services/modules/ — API 模块(banner/models/task/auth)
- TaskAPI 静态方法,TaskInfoItemResponseBody 判别联合类型
- ModelAPI / BannerAPI,const 断言路由常量
- 新增 src/hooks/use-async.ts — 通用异步 Hook
- useAsyncData:竞态处理、条件请求(enabled)、自动错误日志
- useAsyncMutation:数据变更,onSuccess/onError
- getErrorMessage():RequestErrorType → 可读错误信息
- 新增 src/hooks/use-api.ts — 业务 Hook
- useBannerList / useModelList / useTaskList / useTaskDetail / useSubmitTask
## 主题与交互
- 重写暗色令牌:科技感蓝紫(#080C24 底 / #0F1340 面板 / #2A3278 边框)
- 三栏分隔线:token.colorBorderSecondary 常驻 + 手柄竖线 hover 高亮
- 左面板纵向拖拽:模型区/任务区可调比例,ResizeObserver 自适应
- 暗色/亮色同步:tokens.ts + antd-theme.ts + globals.css 三处一致
## 基础设施
- EventBus 新增 TASK_SUBMITTED 事件(替代 Context 数字递增 hack)
- HomeContext 状态管理(选中模型、任务分页、折叠状态)
- 所有组件边框使用 token.colorBorderSecondary(主题自适应)
- Table 滚动高度 ResizeObserver 动态计算(修复分页器遮挡)
This commit is contained in:
163
vite.config.ts
163
vite.config.ts
@@ -1,10 +1,10 @@
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
import path from 'node:path';
|
||||
import electron from 'vite-plugin-electron/simple';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import renderer from 'vite-plugin-electron-renderer';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
import {visualizer} from 'rollup-plugin-visualizer';
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
|
||||
@@ -17,80 +17,91 @@ const __dirname = import.meta.dirname;
|
||||
// 如需避免,可把仅渲染进程用的类型放到 src/types/
|
||||
// ============================================================
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
// 加载 .env.development / .env.production 中的环境变量
|
||||
const env = loadEnv(mode, __dirname, '');
|
||||
export default defineConfig(({mode}) => {
|
||||
// 加载 .env.development / .env.production 中的环境变量
|
||||
const env = loadEnv(mode, __dirname, '');
|
||||
|
||||
return {
|
||||
plugins: [
|
||||
react(),
|
||||
tailwindcss(),
|
||||
electron({
|
||||
main: {
|
||||
// 主进程入口
|
||||
entry: 'electron/main.ts',
|
||||
// 只监听 electron/ 目录,避免 shared/ 变更误触重启
|
||||
// (默认会监听 entry 文件的所有依赖,包括 shared/)
|
||||
},
|
||||
preload: {
|
||||
input: path.join(__dirname, 'electron/preload.ts'),
|
||||
},
|
||||
}),
|
||||
renderer(),
|
||||
// 打包体积分析(仅 ANALYZE=true 时生成 stats.html)
|
||||
process.env.ANALYZE &&
|
||||
visualizer({
|
||||
open: true,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
filename: 'dist/stats.html',
|
||||
return {
|
||||
plugins: [
|
||||
react(),
|
||||
tailwindcss(),
|
||||
electron({
|
||||
main: {
|
||||
// 主进程入口
|
||||
entry: 'electron/main.ts',
|
||||
// 只监听 electron/ 目录,避免 shared/ 变更误触重启
|
||||
// (默认会监听 entry 文件的所有依赖,包括 shared/)
|
||||
},
|
||||
preload: {
|
||||
input: path.join(__dirname, 'electron/preload.ts'),
|
||||
},
|
||||
}),
|
||||
].filter(Boolean),
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
'@shared': path.resolve(__dirname, 'shared'),
|
||||
},
|
||||
},
|
||||
// ============================================================
|
||||
// 编译时注入环境变量到主进程
|
||||
// 主进程中的 process.env.xxx 会在编译时被替换为实际值
|
||||
// 这样无需在 OS 环境中设置这些变量
|
||||
// ============================================================
|
||||
define: {
|
||||
'process.env.UPDATE_API_URL': JSON.stringify(env.UPDATE_API_URL || 'https://www.heixiu.com'),
|
||||
'process.env.EDITION': JSON.stringify(env.EDITION || 'personal'),
|
||||
},
|
||||
// ============================================================
|
||||
// 开发服务器 & HMR 配置
|
||||
// ============================================================
|
||||
server: {
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
host: 'localhost',
|
||||
// 文件监听(Windows 优化)
|
||||
watch: {
|
||||
// Windows 上默认的 fs.watch 有时不稳定,
|
||||
// 如果文件保存后界面无反应,可临时开启 usePolling
|
||||
// usePolling: true,
|
||||
// interval: 100,
|
||||
// 忽略不需要监听的目录,减少 CPU 占用
|
||||
ignored: ['**/node_modules/**', '**/dist/**', '**/dist-electron/**', '**/release/**', '**/test-server/**'],
|
||||
},
|
||||
// HMR 配置
|
||||
hmr: {
|
||||
// 在浏览器控制台显示 HMR 覆盖层(错误/警告时)
|
||||
overlay: true,
|
||||
// 协议默认 ws://,localhost 下无需额外配置
|
||||
},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {},
|
||||
},
|
||||
},
|
||||
preview: {
|
||||
port: 5173,
|
||||
},
|
||||
};
|
||||
renderer(),
|
||||
// 打包体积分析(仅 ANALYZE=true 时生成 stats.html)
|
||||
process.env.ANALYZE &&
|
||||
visualizer({
|
||||
open: true,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
filename: 'dist/stats.html',
|
||||
}),
|
||||
].filter(Boolean),
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
'@shared': path.resolve(__dirname, 'shared'),
|
||||
},
|
||||
},
|
||||
// ============================================================
|
||||
// 编译时注入环境变量到主进程
|
||||
// 主进程中的 process.env.xxx 会在编译时被替换为实际值
|
||||
// 这样无需在 OS 环境中设置这些变量
|
||||
// ============================================================
|
||||
define: {
|
||||
'process.env.UPDATE_API_URL': JSON.stringify(env.UPDATE_API_URL || 'https://www.heixiu.com'),
|
||||
'process.env.EDITION': JSON.stringify(env.EDITION || 'personal'),
|
||||
},
|
||||
// ============================================================
|
||||
// 开发服务器 & HMR 配置
|
||||
// ============================================================
|
||||
server: {
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
host: "0.0.0.0",
|
||||
watch: {
|
||||
// Windows 上默认的 fs.watch 有时不稳定,
|
||||
// 如果文件保存后界面无反应,可临时开启 usePolling
|
||||
// usePolling: true,
|
||||
// interval: 100,
|
||||
// 忽略不需要监听的目录,减少 CPU 占用
|
||||
ignored: ['**/node_modules/**', '**/dist/**', '**/dist-electron/**', '**/release/**', '**/test-server/**'],
|
||||
},
|
||||
// HMR 配置
|
||||
hmr: {
|
||||
// 在浏览器控制台显示 HMR 覆盖层(错误/警告时)
|
||||
overlay: true,
|
||||
},
|
||||
proxy: mode === "development" ? {
|
||||
"/api": {
|
||||
target: env.VITE_API_BASE_URL || "http://192.168.110.84:8000", // 从环境变量读取,默认为本地后端
|
||||
changeOrigin: true,
|
||||
bypass: (req) => {
|
||||
if (req.headers.accept?.includes('text/html')) return '/index.html'
|
||||
},
|
||||
},
|
||||
'/uploads': {
|
||||
target: env.VITE_API_BASE_URL ?? 'http://192.168.110.84:8000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
} : undefined, // 生产环境不启用代理
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {},
|
||||
},
|
||||
},
|
||||
preview: {
|
||||
port: 5173,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user