更新前端项目

This commit is contained in:
2025-11-17 16:49:03 +08:00
parent 638e152cff
commit 033890742d
16 changed files with 862 additions and 130 deletions

View File

@@ -0,0 +1,422 @@
# 前端样式 / 布局 / UI 修改操作指南
> 面向二次开发前端,告诉你:**改样式 / 改布局 / 改 UI 具体要动哪些文件、怎么改**。
>
> 项目技术栈Vite + Vue 3 + TypeScript + Ant Design Vue + Pinia + Vue Router + SCSS
---
## 🧭 速查表
- **改全局颜色 / 按钮 / 弹窗风格**:看第 1 章「整体样式体系总览」(`src/styles/index.scss` + `src/styles/variables.scss`
- **改管理端整体布局(侧边栏、头部、内容区排版)**:看 2.1「管理端整体布局」(`src/views/admin_page/index.vue`
- **改用户端整体布局(顶部导航 + 内容容器)」**:看 2.2「用户端整体布局」(`src/views/user_pages/index.vue`
- **改 YOLO 检测排版 / 三种布局 / 卡片样式**:看第 3 章「YOLO 检测页面修改指南」(`src/views/user_pages/YoloDetection.vue`
- **改 AI 助手聊天布局**:看第 4 章「修改 AI 助手页面」(`src/views/user_pages/AiChat.vue`
---
## 1. 整体样式体系总览
### 1.1 全局样式入口
- 入口文件:`src/styles/index.scss`
-`src/main.ts` 中全局引入:
- `import './styles/index.scss'`
- 主要职责:
- 重置 margin / padding / box-sizing
- 全局字体、`html, body, #app` 基础样式
- 自定义 `.btn` / `.card` 等通用类
- 全局 Ant Design Vue 主题风格覆盖(如 `.ant-modal`, `.ant-btn` 等)
**如果你要改全局的按钮、弹窗、表单、输入框等基础风格:**
1. 打开 `src/styles/index.scss`
2. 找对应的选择器:
- 按钮:`.ant-btn` 下的几种状态(`&.ant-btn-default` / `&.ant-btn-primary` / `&.ant-btn-dangerous` 等)
- 弹窗:`.ant-modal` 内的 `.ant-modal-content` / `.ant-modal-header` / `.ant-modal-footer`
- 输入/选择等:`.ant-input`, `.ant-select-selector`, `.ant-input-number`, `.ant-picker`
3. 直接在这里调整颜色、圆角、阴影、间距。
4. 样式会作用于所有页面,无需在每个 `.vue` 里重复写。
> 建议:全局 Design System 统一改在这里,不要在业务页面里到处改 AntD 默认样式。
### 1.2 变量和混合(主题基础)
- 文件:`src/styles/variables.scss`
- 主要内容:
- 颜色:`$primary-color``$success-color``$gray-xxx`
- 间距:`$spacing-1 ~ $spacing-20`
- 圆角:`$radius-md``$radius-lg`
- 阴影:`$shadow-sm` / `$shadow-md` / `$shadow-lg`
- 常用 mixin`@mixin card-style``@mixin button-style`
**改全局配色 / 圆角 / 阴影的操作方式:**
1. 打开 `src/styles/variables.scss`
2. 修改对应变量:
- 主色:`$primary-color` / `$primary-light` / `$primary-dark`
- 背景:`$bg-primary` / `$bg-secondary`
- 阴影:`$shadow-md` / `$shadow-lg`
3. 不需要修改业务页面,使用这些变量的地方会统一生效。
> 如果要在页面里复用统一卡片/按钮样式,可以直接:
>
> ```scss
> .my-card {
> @include card-style;
> }
>
> .my-primary-button {
> @include button-style($primary-color, #fff);
> }
> ```
### 1.3 主题 store 与 CSS 变量
- 文件:`src/stores/hertz_theme.ts`
- 作用:
- 定义 `ThemeConfig`(导航栏背景、页面背景、卡片背景、主色、文字颜色)
- 使用 `document.documentElement.style.setProperty` 写入 CSS 变量:
- `--theme-header-bg`, `--theme-page-bg`, `--theme-card-bg`, `--theme-primary`, `--theme-text-primary`
- 使用方式:
- 在页面/组件的 SCSS 中,通过 `var(--theme-primary)` 等变量引用主题色:
- 示例:`color: var(--theme-text-primary, #1e293b);`
**修改主题默认值**
1. 打开 `src/stores/hertz_theme.ts`
2. 修改 `defaultTheme` 对象里的颜色值即可:
- 如:`primaryColor: '#FF4D4F'` 改成你的品牌色
3. 调用 `themeStore.loadTheme()` 时会自动应用到全局。
**页面内如何用这些主题变量?**
- 在 SCSS 中使用:
```scss
.some-block {
background: var(--theme-card-bg, #fff);
color: var(--theme-text-primary, #1e293b);
border-color: var(--theme-card-border, #e5e7eb);
}
```
---
## 2. 布局结构:管理端 / 用户端
### 2.1 管理端整体布局
- 入口布局:`src/views/admin_page/index.vue`
- 结构:
- 外层 `.admin-layout`
- 使用 `a-layout` + `a-layout-sider` + `a-layout-header` + `a-layout-content` + `a-layout-footer`
- 侧边菜单:`a-layout-sider` 内的 `a-menu`,使用 `admin_menu.ts` 生成菜单项
**修改管理端整体布局方式(比如侧边栏宽度、顶部高度):**
1. 打开 `src/views/admin_page/index.vue`
2. 找到模板部分:
- 侧边栏:`<a-layout-sider ... class="admin-sider">`
- 顶部:`<a-layout-header class="header">`
- 内容:`<a-layout-content class="content">`
3. 在同文件底部的 `<style scoped lang="scss">` 中调整:
- `.admin-layout``.admin-sider``.header``.content` 的 padding / background / shadow 等。
4. 如果要改变菜单布局(比如改成顶部导航):需要同时更新 template 结构和对应的 SCSS。
### 2.2 用户端整体布局
- 入口布局:`src/views/user_pages/index.vue`
- 结构:
- 顶部 `a-layout-header.user-header`:包含 logo + 顶部菜单 + 面包屑 + 布局切换按钮 + 主题按钮 + 用户下拉
- 主体 `a-layout.main-layout`,内部 `a-layout-content.user-content` 作为页面内容容器
- 中间区域通过 `currentComponent` 动态切换不同业务页YOLO 检测、AI 助手等)
**修改用户端整体布局(例如 header 高度、主内容宽度):**
1. 打开 `src/views/user_pages/index.vue`
2. 在 template 里找到:
- `<a-layout-header class="user-header">`
- `<a-layout class="main-layout">`
- `<a-layout-content class="user-content">`
3. 在同文件的 `<style scoped lang="scss">` 中调整:
- `.user-layout``.user-header``.main-layout``.user-content``.content-wrapper`
4. 你也可以在这里添加全局背景图(比如 `.user-layout` 里加 background只作用于用户端。
> 所有用户端的业务页面(`YoloDetection.vue`、`AiChat.vue` 等)都是渲染在 `user-content` 容器里,尽量保持这里的 padding / 背景一致,具体视觉再在业务页内做细化。
---
## 3. YOLO 检测页面修改指南(排版 / 布局 / 样式 / UI
文件路径:`src/views/user_pages/YoloDetection.vue`
这个页面已经内置了 **三种布局模式**,并且使用了大量局部 SCSS + AntD 组件。下面分步骤说明如何操作。
### 3.1 布局模式classic / vertical / grid
关键代码:
- 布局枚举与状态:
```ts
const layoutMode = ref<'classic' | 'vertical' | 'grid'>('classic')
const layoutKey = ref(0)
```
- 模板中的三个布局分支:
```vue
<!-- 经典两列布局 -->
<div v-if="layoutMode === 'classic'" class="detection-content classic-layout" :key="`classic-${layoutKey}`">
...
</div>
<!-- 上下布局 -->
<div v-if="layoutMode === 'vertical'" class="detection-content vertical-layout" :key="`vertical-${layoutKey}`">
...
</div>
<!-- 侧边栏详情布局 -->
<div v-if="layoutMode === 'grid'" class="detection-content sidebar-layout" :key="`grid-${layoutKey}`">
...
</div>
```
`layoutMode` 的切换来自用户端首页布局弹窗(`user_pages/index.vue`),会写入 `localStorage('yoloDetectionLayout')`
**如果你要改某一种布局的排版:**
1.`YoloDetection.vue` 模板里定位对应的 `div`
- 经典两列:`.classic-layout`
- 上下布局:`.vertical-layout`
- 侧边栏布局:`.sidebar-layout`
2. 在同文件的 `<style scoped lang="scss">` 中搜索这些 class例如搜索 `.classic-layout`
- 调整其中的 `a-row` / `a-col` 排布、卡片宽度、高度等。
3. 如果你只想保留一种布局,比如只保留经典两列:
- 可以在 template 中暂时注释掉 `vertical``grid` 这两段。
- 或者在 script 中将 `layoutMode` 的类型改小,只允许 `'classic'`
### 3.2 修改上传区域(左侧卡片)
上传部分主结构classic 布局示例):
```vue
<a-card title="文件上传" class="upload-card">
<div class="upload-area">
<a-upload-dragger ... class="beautiful-upload">
...
</a-upload-dragger>
<div v-if="fileList.length > 0" class="compact-preview">...
</div>
</div>
<div class="detection-params" v-if="fileList.length > 0">...
</div>
<div class="upload-actions" v-if="fileList.length > 0">...
</div>
</a-card>
```
对应样式(节选):
```scss
.yolo-detection-page {
.upload-card { ... }
.upload-area { ... }
.beautiful-upload { ... }
.compact-preview { ... }
.upload-actions { ... }
}
// 深度作用 AntD Upload
:deep(.ant-upload-dragger) {
border: 2px dashed #d1d5db;
border-radius: 12px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
...
}
```
**具体改法示例:**
- **想调整拖拽区域高度 / 圆角 / 背景:**
1.`<style scoped lang="scss">` 中搜索 `:deep(.ant-upload-dragger)`
2. 修改其中的 `border-radius``min-height``background` 等。
- **想改变已上传文件的缩略图排列方式:**
1. 搜索 `.compact-preview``.preview-grid``.preview-card` 等 class。
2. 例如,将 `display: grid` 的列数从 `3` 改为 `4`
- 修改 `grid-template-columns: repeat(3, 1fr);``repeat(4, 1fr);`
- **想给“开始检测”按钮加一个 loading 状态颜色:**
1. 上传按钮使用的是 `<a-button type="primary" :loading="detecting">`,全局颜色来自 `.ant-btn-primary`
2. 如果想只在该页面定制:
```scss
.yolo-detection-page {
.upload-actions {
:deep(.ant-btn-primary) {
background: #22c55e; // 单独改为绿色
}
}
}
```
### 3.3 修改检测结果区域排版
经典布局右侧结果卡片结构:
```vue
<a-card title="检测结果" class="result-card">
<div v-if="detectionResults.length === 0" class="no-results">...</div>
<div v-else class="results-list">
<div class="results-grid">
<div v-for="result in sortedDetectionResults" class="result-item">
<div class="image-comparison">...
<div class="result-details">...
</div>
</div>
</div>
</a-card>
```
对应样式关键点:
- `.results-list`:控制滚动区域、高度和滚动条样式
- `.result-item`:单个结果卡片的背景、边框、阴影
- `.image-comparison` / `.image-pair` / `.image-wrapper`:左右对比图/视频布局
- `.result-details` / `.detection-stats` / `.detection-tags`:文本统计信息
**操作示例:**
- **改结果区域整体高度 / 是否滚动:**
1. 在 SCSS 中搜索 `.results-list`
2. 调整 `max-height` 或移除 `overflow-y: scroll !important;`,就可以变成自适应高度。
- **把“原图/检测结果”改成上下叠加而不是左右:**
1. 找到 `.image-pair`
```scss
.image-pair {
display: flex;
gap: 16px;
}
```
2. 改为列方向:
```scss
.image-pair {
display: flex;
flex-direction: column; // 上下排列
gap: 16px;
}
```
- **调整图片容器比例 / 加圆角阴影:**
1. 修改 `.image-wrapper``height: 160px;` 改为你想要的高度或使用 `aspect-ratio`
2. 修改 `border-radius` / `box-shadow` 实现更柔和的卡片效果。
### 3.4 深度选择器 `:deep` 使用说明
`YoloDetection.vue` 中多次使用了 `:deep(...)` 来覆盖 AntD 子组件样式,例如:
```scss
:deep(.ant-card-body) {
flex: 1;
display: flex;
flex-direction: column;
}
:deep(.ant-upload-list) {
display: none !important;
}
```
**规则:**
- 页面级样式修改尽量写在该 `.vue``<style scoped>` 中,用 `:deep` 定位到 AntD 的 DOM 结构。
- 全局通用样式统一放在 `src/styles/index.scss`,不要在页面里频繁写过多全局覆盖。
**如何找到 AntD 的 class 名称?**
1. 浏览器打开页面F12 查看对应组件 DOM 结构。
2. 复制最内层需要修改的 class`.ant-card-head`)。
3. 在该页面样式中写:
```scss
.my-custom-card {
:deep(.ant-card-head) {
// 自定义头部样式
}
}
```
---
## 4. 修改 AI 助手页面(整体方法类似)
AI 助手页面:`src/views/user_pages/AiChat.vue`
- 也有多种布局:`default`(左右)、`compact`(上下)、`wide`(全屏消息 + 浮动侧边栏)。
- 样式组织方式与 YOLO 检测类似:
- 外层 `.ai-chat-page`
- 内部 `.chat-container` / `.chat-sidebar` / `.chat-main` / `.messages-wrapper` / `.composer`
- 使用 `:deep` 覆盖 AntD 的 `a-card``a-input-search``a-list` 等组件
**如果你已经掌握了上面 YOLO 页面改法:**
- 改 AI 助手排版时只需:
1. 找到对应布局分支(`currentLayout === 'default' | 'compact' | 'wide'`
2.`<style scoped lang="scss">` 中编辑对应 class 的样式即可。
---
## 5. 实战建议:改 UI 的基本步骤
1. **先确认层级:**
- 是全局都要变?(颜色、按钮、弹窗 -> `styles/index.scss`, `styles/variables.scss`, `hertz_theme.ts`
- 只改某个模块YOLO / AI / 管理端 / 用户端布局 -> 各自 `.vue` 的 scoped 样式)
2. **用浏览器开发者工具查 DOM 和 class**
- 看清楚 AntD 组件最终渲染出的结构和 class
- 再决定用 `:deep(.ant-xxx)` 还是自定义的 `.my-block` 去写样式
3. **在对应 `.vue` 文件底部 `<style scoped lang="scss">` 中改局部样式:**
- 保持 class 命名有语义:`.yolo-detection-page``.upload-area``.results-list`
4. **共用样式尽量抽到全局:**
- 例如卡片风格在 `variables.scss` + `index.scss` 抽成 mixin 或全局 class
5. **改完后检查响应式:**
- `YoloDetection.vue` 和 AI 助手都内置了 `@media` 段,记得同步修改,以免移动端错位。
---
## 6. 如果要新增一个“风格类似 YOLO 的新页面”
1.`src/views/user_pages/` 下新建 `MyFeature.vue`
2. 参考 `YoloDetection.vue` 的结构:
- 顶部 `.page-header`
- 中间 `a-row` + `a-col` 做主布局
- 底部 `<style scoped lang="scss">` 里用 `.my-feature-page { ... }` 包裹所有样式
3. 使用全局变量和 mixin
```scss
.my-feature-page {
background: var(--theme-page-bg, #f5f5f5);
.my-card {
@include card-style;
}
}
```
4.`src/router/user_menu_ai.ts` 中为用户端菜单新增一项,对应 `MyFeature.vue`
---