Compare commits
17 Commits
301fa6c85c
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
| a5a3e36d48 | |||
| 9ffcb22929 | |||
| 5ac8d0bb99 | |||
| 5e85533062 | |||
| 4678f2cd44 | |||
| 9f2a2b7c17 | |||
| 6d322ea7da | |||
| 38adbaed90 | |||
| b0f5422593 | |||
| bf68f5e7ee | |||
| bd2d7b80dc | |||
| 1feb295a93 | |||
| c7b140c5db | |||
| 6e30a0ccf4 | |||
| 33994531b0 | |||
| e43d2ac0f6 | |||
| 4a2d993a91 |
@@ -50,6 +50,9 @@ public class CcdiProject implements Serializable {
|
|||||||
/** 低风险人数 */
|
/** 低风险人数 */
|
||||||
private Integer lowRiskCount;
|
private Integer lowRiskCount;
|
||||||
|
|
||||||
|
/** 流水分析平台项目ID */
|
||||||
|
private Integer lsfxProjectId;
|
||||||
|
|
||||||
/** 删除标志:0-存在,2-删除 */
|
/** 删除标志:0-存在,2-删除 */
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ public class CcdiProjectVO {
|
|||||||
/** 低风险人数 */
|
/** 低风险人数 */
|
||||||
private Integer lowRiskCount;
|
private Integer lowRiskCount;
|
||||||
|
|
||||||
|
/** 流水分析平台项目ID */
|
||||||
|
private Integer lsfxProjectId;
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
|
|||||||
334
docs/plans/2026-03-04-project-detail-navigation-menu-design.md
Normal file
334
docs/plans/2026-03-04-project-detail-navigation-menu-design.md
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
# 项目详情页面导航菜单改造设计文档
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
将项目详情页面(detail.vue)右侧的按钮组改为水平导航菜单,使用 Element UI Menu 组件实现简洁链接风格。
|
||||||
|
|
||||||
|
## 当前问题
|
||||||
|
|
||||||
|
项目详情页面右侧的操作按钮(上传数据、参数配置、初核结果)占用空间较大,视觉层级不够清晰,交互方式不够统一。
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 核心设计
|
||||||
|
- 使用 Element UI 的 `el-menu` 组件(水平模式)
|
||||||
|
- 菜单放在标题右侧,右对齐
|
||||||
|
- "上传数据"和"参数配置"作为普通菜单项
|
||||||
|
- "初核结果"保留下拉菜单结构,包含三个子项:结果总览、专项排查、流水明细查询
|
||||||
|
- 采用简洁链接风格:透明背景 + 底部下划线激活效果
|
||||||
|
|
||||||
|
### 视觉风格
|
||||||
|
- 默认状态:灰色文字(#606266),透明背景
|
||||||
|
- Hover 状态:浅灰背景(#f5f7fa),深色文字(#303133)
|
||||||
|
- 激活状态:蓝色文字(#1890ff)+ 底部 2px 蓝色下划线
|
||||||
|
- 下拉菜单:白色背景,激活项浅蓝背景(#e6f7ff)
|
||||||
|
|
||||||
|
## 技术设计
|
||||||
|
|
||||||
|
### 1. 组件结构
|
||||||
|
|
||||||
|
#### detail.vue 模板改造
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<div class="header-right">
|
||||||
|
<el-menu
|
||||||
|
:default-active="activeTab"
|
||||||
|
mode="horizontal"
|
||||||
|
@select="handleMenuSelect"
|
||||||
|
class="nav-menu"
|
||||||
|
>
|
||||||
|
<el-menu-item index="upload">上传数据</el-menu-item>
|
||||||
|
<el-menu-item index="config">参数配置</el-menu-item>
|
||||||
|
<el-submenu index="result">
|
||||||
|
<template slot="title">初核结果</template>
|
||||||
|
<el-menu-item index="overview">结果总览</el-menu-item>
|
||||||
|
<el-menu-item index="special">专项排查</el-menu-item>
|
||||||
|
<el-menu-item index="detail">流水明细查询</el-menu-item>
|
||||||
|
</el-submenu>
|
||||||
|
</el-menu>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 动态组件渲染区域 -->
|
||||||
|
<component
|
||||||
|
:is="currentComponent"
|
||||||
|
:project-id="projectId"
|
||||||
|
:project-info="projectInfo"
|
||||||
|
@menu-change="handleMenuChange"
|
||||||
|
@data-uploaded="handleDataUploaded"
|
||||||
|
@name-selected="handleNameSelected"
|
||||||
|
@generate-report="handleGenerateReport"
|
||||||
|
@fetch-bank-info="handleFetchBankInfo"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 数据结构
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeTab: 'upload', // 当前激活的菜单项索引
|
||||||
|
currentComponent: 'UploadData', // 当前显示的组件名称
|
||||||
|
// ... 其他现有数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 交互逻辑
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
methods: {
|
||||||
|
/** 菜单选择事件 */
|
||||||
|
handleMenuSelect(index) {
|
||||||
|
this.activeTab = index;
|
||||||
|
|
||||||
|
// 组件映射
|
||||||
|
const componentMap = {
|
||||||
|
'upload': 'UploadData',
|
||||||
|
'config': 'ParamConfig',
|
||||||
|
'overview': 'PreliminaryCheck',
|
||||||
|
'special': 'SpecialCheck',
|
||||||
|
'detail': 'DetailQuery'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.currentComponent = componentMap[index] || 'UploadData';
|
||||||
|
},
|
||||||
|
|
||||||
|
// ... 其他现有方法
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 组件导入
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import UploadData from "./components/detail/UploadData";
|
||||||
|
import ParamConfig from "./components/detail/ParamConfig";
|
||||||
|
import PreliminaryCheck from "./components/detail/PreliminaryCheck";
|
||||||
|
import SpecialCheck from "./components/detail/SpecialCheck";
|
||||||
|
import DetailQuery from "./components/detail/DetailQuery";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProjectDetail",
|
||||||
|
components: {
|
||||||
|
UploadData,
|
||||||
|
ParamConfig,
|
||||||
|
PreliminaryCheck,
|
||||||
|
SpecialCheck,
|
||||||
|
DetailQuery,
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 样式设计
|
||||||
|
|
||||||
|
### 1. 导航菜单样式
|
||||||
|
|
||||||
|
```scss
|
||||||
|
.header-right {
|
||||||
|
.nav-menu {
|
||||||
|
// 移除默认背景色和边框
|
||||||
|
background-color: transparent;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
// 菜单项基础样式
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu__title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
padding: 0 16px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 激活状态:底部下划线 + 蓝色文字
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单激活状态
|
||||||
|
.el-submenu.is-active > .el-submenu__title {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单图标
|
||||||
|
.el-submenu__icon-arrow {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 下拉菜单弹窗样式
|
||||||
|
|
||||||
|
```scss
|
||||||
|
::v-deep .el-menu--popup {
|
||||||
|
min-width: 140px;
|
||||||
|
|
||||||
|
.el-menu-item {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 响应式适配
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.detail-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
.nav-menu {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 组件规范
|
||||||
|
|
||||||
|
### Props 接口
|
||||||
|
|
||||||
|
所有子组件应接收相同的 props:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
### Events 接口
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
this.$emit('data-uploaded', { type: 'xxx' });
|
||||||
|
this.$emit('generate-report');
|
||||||
|
this.$emit('fetch-bank-info');
|
||||||
|
this.$emit('menu-change', { key, route });
|
||||||
|
this.$emit('name-selected', nameList);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 实施步骤
|
||||||
|
|
||||||
|
### 第一步:修改 detail.vue 文件
|
||||||
|
1. 替换 header-right 中的按钮为 el-menu 组件
|
||||||
|
2. 添加 activeTab 和 currentComponent 数据字段
|
||||||
|
3. 实现 handleMenuSelect 方法
|
||||||
|
4. 添加动态组件渲染区域
|
||||||
|
5. 导入所有子组件
|
||||||
|
|
||||||
|
### 第二步:添加样式
|
||||||
|
1. 添加导航菜单的自定义样式
|
||||||
|
2. 添加下拉菜单样式
|
||||||
|
3. 添加响应式样式
|
||||||
|
|
||||||
|
### 第三步:创建占位组件
|
||||||
|
为未实现的功能创建占位组件:
|
||||||
|
- ParamConfig.vue
|
||||||
|
- PreliminaryCheck.vue
|
||||||
|
- SpecialCheck.vue
|
||||||
|
- DetailQuery.vue
|
||||||
|
|
||||||
|
### 第四步:测试验证
|
||||||
|
- 功能测试:菜单切换、下拉菜单交互
|
||||||
|
- 视觉测试:样式符合设计要求
|
||||||
|
- 响应式测试:移动端布局正常
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- Element UI Menu 组件(`el-menu`, `el-menu-item`, `el-submenu`)
|
||||||
|
- Vue 动态组件(`<component :is="...">`)
|
||||||
|
- Scoped CSS 样式覆盖
|
||||||
|
- Vue 2.6.12
|
||||||
|
- Element UI 2.15.14
|
||||||
|
|
||||||
|
## 预期效果
|
||||||
|
|
||||||
|
### 视觉效果
|
||||||
|
- 菜单项横向排列在标题右侧,右对齐
|
||||||
|
- 简洁链接风格,无背景色和边框
|
||||||
|
- 激活项显示蓝色文字和底部下划线
|
||||||
|
- 下拉菜单样式统一
|
||||||
|
|
||||||
|
### 交互效果
|
||||||
|
- 点击菜单项切换组件,URL 不变
|
||||||
|
- 下拉菜单点击外部区域可关闭
|
||||||
|
- 组件切换流畅,数据正确传递
|
||||||
|
- 响应式布局在移动端自适应
|
||||||
|
|
||||||
|
## 代码改动量估算
|
||||||
|
|
||||||
|
- detail.vue 文件改动:约 80-100 行(模板 + 脚本 + 样式)
|
||||||
|
- 占位组件创建:4 个文件,每个约 20 行
|
||||||
|
- 总代码量:约 150-180 行
|
||||||
|
|
||||||
|
## 风险与注意事项
|
||||||
|
|
||||||
|
1. **组件文件不存在**:ParamConfig、PreliminaryCheck 等组件需要创建占位组件
|
||||||
|
2. **样式覆盖**:Element UI 默认样式覆盖需要使用 `::v-deep` 或 `/deep/`
|
||||||
|
3. **事件传递**:确保所有子组件的事件正确向上传递
|
||||||
|
4. **路由监听**:移除原有路由相关的逻辑,改为组件状态管理
|
||||||
|
|
||||||
|
## 后续优化建议
|
||||||
|
|
||||||
|
1. 添加菜单切换动画效果
|
||||||
|
2. 为占位组件实现完整功能
|
||||||
|
3. 添加面包屑导航支持
|
||||||
|
4. 支持菜单项权限控制
|
||||||
|
5. 添加快捷键支持(Ctrl+Tab 切换)
|
||||||
|
|
||||||
|
## 测试清单
|
||||||
|
|
||||||
|
- [ ] 点击"上传数据"菜单,显示 UploadData 组件
|
||||||
|
- [ ] 点击"参数配置"菜单,显示占位组件或 ParamConfig 组件
|
||||||
|
- [ ] 点击"初核结果"菜单,展开下拉菜单
|
||||||
|
- [ ] 点击下拉菜单子项,切换到对应组件
|
||||||
|
- [ ] 激活菜单项显示底部下划线
|
||||||
|
- [ ] Hover 菜单项显示浅灰背景
|
||||||
|
- [ ] 下拉菜单点击外部区域关闭
|
||||||
|
- [ ] 组件切换时 projectId 和 projectInfo 正确传递
|
||||||
|
- [ ] 移动端菜单响应式布局正常
|
||||||
|
- [ ] 现有功能不受影响(返回按钮、项目信息显示等)
|
||||||
960
docs/plans/2026-03-04-project-detail-navigation-menu.md
Normal file
960
docs/plans/2026-03-04-project-detail-navigation-menu.md
Normal file
@@ -0,0 +1,960 @@
|
|||||||
|
# 项目详情页面导航菜单改造实施计划
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** 将项目详情页面右侧的按钮组改为水平导航菜单,使用 Element UI Menu 组件实现简洁链接风格,支持菜单切换组件内容。
|
||||||
|
|
||||||
|
**Architecture:** 使用 Element UI 的 `el-menu` 组件(水平模式)替换现有的按钮组,通过 Vue 动态组件(`<component :is="...">`)实现内容切换。菜单项包括"上传数据"、"参数配置"和"初核结果"下拉菜单(含三个子项)。采用简洁链接风格,激活状态显示底部下划线。
|
||||||
|
|
||||||
|
**Tech Stack:** Vue 2.6.12, Element UI 2.15.14, Scoped CSS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 前置检查
|
||||||
|
|
||||||
|
**验证当前项目状态:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd D:/ccdi/ccdi
|
||||||
|
git status
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:工作目录干净,或只有 CLAUDE.md 修改
|
||||||
|
|
||||||
|
**验证文件存在:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
ls ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:两个文件都存在
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: 创建占位组件 ParamConfig
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue`
|
||||||
|
|
||||||
|
**Step 1: 创建 ParamConfig 占位组件**
|
||||||
|
|
||||||
|
创建文件 `ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div class="param-config-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-setting"></i>
|
||||||
|
<p>参数配置功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ParamConfig",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.param-config-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 提交 ParamConfig 组件**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue
|
||||||
|
git commit -m "feat(ccdiProject): 添加参数配置占位组件"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: 创建占位组件 PreliminaryCheck
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue`
|
||||||
|
|
||||||
|
**Step 1: 创建 PreliminaryCheck 占位组件**
|
||||||
|
|
||||||
|
创建文件 `ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div class="preliminary-check-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-data-analysis"></i>
|
||||||
|
<p>结果总览功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "PreliminaryCheck",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.preliminary-check-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 提交 PreliminaryCheck 组件**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue
|
||||||
|
git commit -m "feat(ccdiProject): 添加结果总览占位组件"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: 创建占位组件 SpecialCheck
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-ui/src/views/ccdiProject/components/detail/SpecialCheck.vue`
|
||||||
|
|
||||||
|
**Step 1: 创建 SpecialCheck 占位组件**
|
||||||
|
|
||||||
|
创建文件 `ruoyi-ui/src/views/ccdiProject/components/detail/SpecialCheck.vue`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div class="special-check-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-search"></i>
|
||||||
|
<p>专项排查功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SpecialCheck",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.special-check-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 提交 SpecialCheck 组件**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/SpecialCheck.vue
|
||||||
|
git commit -m "feat(ccdiProject): 添加专项排查占位组件"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: 创建占位组件 DetailQuery
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||||||
|
|
||||||
|
**Step 1: 创建 DetailQuery 占位组件**
|
||||||
|
|
||||||
|
创建文件 `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div class="detail-query-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-document"></i>
|
||||||
|
<p>流水明细查询功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailQuery",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.detail-query-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 提交 DetailQuery 组件**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
|
||||||
|
git commit -m "feat(ccdiProject): 添加流水明细查询占位组件"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 5: 修改 detail.vue - 添加数据字段和导入组件
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 添加组件导入**
|
||||||
|
|
||||||
|
在 `detail.vue` 的 `<script>` 部分,找到 import 语句(第 72 行附近),替换为:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import UploadData from "./components/detail/UploadData";
|
||||||
|
import ParamConfig from "./components/detail/ParamConfig";
|
||||||
|
import PreliminaryCheck from "./components/detail/PreliminaryCheck";
|
||||||
|
import SpecialCheck from "./components/detail/SpecialCheck";
|
||||||
|
import DetailQuery from "./components/detail/DetailQuery";
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 注册组件**
|
||||||
|
|
||||||
|
在 `components` 对象中(第 81-88 行),替换为:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
components: {
|
||||||
|
UploadData,
|
||||||
|
ParamConfig,
|
||||||
|
PreliminaryCheck,
|
||||||
|
SpecialCheck,
|
||||||
|
DetailQuery,
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 添加数据字段**
|
||||||
|
|
||||||
|
在 `data()` 函数中(第 89-110 行),在 `activeTab: "data"` 之后添加:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 当前激活的菜单项索引
|
||||||
|
activeTab: "upload",
|
||||||
|
// 当前显示的组件名称
|
||||||
|
currentComponent: "UploadData",
|
||||||
|
// 项目ID
|
||||||
|
projectId: this.$route.params.projectId,
|
||||||
|
// ... 其他现有数据保持不变
|
||||||
|
projectInfo: {
|
||||||
|
projectId: this.$route.params.projectId,
|
||||||
|
projectName: "",
|
||||||
|
projectDesc: "",
|
||||||
|
createTime: "",
|
||||||
|
updateTime: "",
|
||||||
|
startDate: "",
|
||||||
|
endDate: "",
|
||||||
|
targetCount: 0,
|
||||||
|
warningCount: 0,
|
||||||
|
warningThreshold: 60,
|
||||||
|
projectStatus: "0",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4: 验证文件语法正确**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint -- --fix src/views/ccdiProject/detail.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无语法错误
|
||||||
|
|
||||||
|
**Step 5: 提交组件导入修改**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
git commit -m "feat(ccdiProject): 导入子组件并添加菜单状态数据"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 6: 修改 detail.vue - 替换模板中的按钮为菜单
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 替换 header-right 中的按钮组**
|
||||||
|
|
||||||
|
找到 `<div class="header-right">` 部分(第 27-55 行),替换为:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<div class="header-right">
|
||||||
|
<el-menu
|
||||||
|
:default-active="activeTab"
|
||||||
|
mode="horizontal"
|
||||||
|
@select="handleMenuSelect"
|
||||||
|
class="nav-menu"
|
||||||
|
>
|
||||||
|
<el-menu-item index="upload">上传数据</el-menu-item>
|
||||||
|
<el-menu-item index="config">参数配置</el-menu-item>
|
||||||
|
<el-submenu index="result">
|
||||||
|
<template slot="title">初核结果</template>
|
||||||
|
<el-menu-item index="overview">结果总览</el-menu-item>
|
||||||
|
<el-menu-item index="special">专项排查</el-menu-item>
|
||||||
|
<el-menu-item index="detail">流水明细查询</el-menu-item>
|
||||||
|
</el-submenu>
|
||||||
|
</el-menu>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 替换 UploadData 为动态组件**
|
||||||
|
|
||||||
|
找到 `<UploadData>` 组件(第 59-67 行),替换为:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<!-- 动态组件渲染区域 -->
|
||||||
|
<component
|
||||||
|
:is="currentComponent"
|
||||||
|
:project-id="projectId"
|
||||||
|
:project-info="projectInfo"
|
||||||
|
@menu-change="handleMenuChange"
|
||||||
|
@data-uploaded="handleDataUploaded"
|
||||||
|
@name-selected="handleNameSelected"
|
||||||
|
@generate-report="handleGenerateReport"
|
||||||
|
@fetch-bank-info="handleFetchBankInfo"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 验证模板语法**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint -- --fix src/views/ccdiProject/detail.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无语法错误
|
||||||
|
|
||||||
|
**Step 4: 提交模板修改**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
git commit -m "feat(ccdiProject): 替换按钮组为导航菜单并使用动态组件"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 7: 修改 detail.vue - 添加菜单选择处理方法
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 添加菜单选择处理方法**
|
||||||
|
|
||||||
|
在 `methods` 对象中(第 124 行),在 `handleBack()` 方法之后添加新方法:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/** 菜单选择事件 */
|
||||||
|
handleMenuSelect(index) {
|
||||||
|
console.log("菜单选择:", index);
|
||||||
|
this.activeTab = index;
|
||||||
|
|
||||||
|
// 组件映射
|
||||||
|
const componentMap = {
|
||||||
|
upload: "UploadData",
|
||||||
|
config: "ParamConfig",
|
||||||
|
overview: "PreliminaryCheck",
|
||||||
|
special: "SpecialCheck",
|
||||||
|
detail: "DetailQuery",
|
||||||
|
};
|
||||||
|
|
||||||
|
this.currentComponent = componentMap[index] || "UploadData";
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 删除废弃的方法**
|
||||||
|
|
||||||
|
删除以下不再使用的方法(第 226-251 行):
|
||||||
|
- `handleUploadData()`
|
||||||
|
- `handleParamConfig()`
|
||||||
|
- `handleCheckResultCommand()`
|
||||||
|
|
||||||
|
**Step 3: 更新 handleMenuChange 方法**
|
||||||
|
|
||||||
|
修改 `handleMenuChange` 方法(第 185-205 行),简化为:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/** UploadData 组件:菜单切换 */
|
||||||
|
handleMenuChange({ key, route }) {
|
||||||
|
console.log("切换到菜单:", key, route);
|
||||||
|
// 直接触发菜单选择
|
||||||
|
this.handleMenuSelect(route);
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4: 验证方法逻辑**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint -- --fix src/views/ccdiProject/detail.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无语法错误,未使用的方法已删除
|
||||||
|
|
||||||
|
**Step 5: 提交方法修改**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
git commit -m "feat(ccdiProject): 添加菜单选择处理方法并清理废弃代码"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 8: 修改 detail.vue - 添加导航菜单样式
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 添加导航菜单样式**
|
||||||
|
|
||||||
|
在 `<style lang="scss" scoped>` 部分(第 306 行之后),在 `.header-right` 样式块内部添加:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
.header-right {
|
||||||
|
.nav-menu {
|
||||||
|
// 移除默认背景色和边框
|
||||||
|
background-color: transparent;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
// 菜单项基础样式
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu__title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
padding: 0 16px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 激活状态:底部下划线 + 蓝色文字
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单激活状态
|
||||||
|
.el-submenu.is-active > .el-submenu__title {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单图标
|
||||||
|
.el-submenu__icon-arrow {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 添加下拉菜单弹窗样式**
|
||||||
|
|
||||||
|
在样式末尾(第 496 行之后),添加深度选择器样式:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
// 下拉菜单弹窗样式
|
||||||
|
::v-deep .el-menu--popup {
|
||||||
|
min-width: 140px;
|
||||||
|
|
||||||
|
.el-menu-item {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 验证样式语法**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint -- --fix src/views/ccdiProject/detail.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无语法错误
|
||||||
|
|
||||||
|
**Step 4: 提交导航菜单样式**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
git commit -m "style(ccdiProject): 添加导航菜单简洁链接风格样式"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 9: 修改 detail.vue - 添加响应式样式
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 添加响应式样式**
|
||||||
|
|
||||||
|
在现有的 `@media (max-width: 768px)` 媒体查询中(第 464 行),找到 `.detail-header` 样式块,添加响应式菜单样式:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.dpc-detail-container {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
.nav-menu {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... 其他现有响应式样式保持不变
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 验证响应式样式**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint -- --fix src/views/ccdiProject/detail.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无语法错误
|
||||||
|
|
||||||
|
**Step 3: 提交响应式样式**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/views/ccdiProject/detail.vue
|
||||||
|
git commit -m "style(ccdiProject): 添加导航菜单响应式布局支持"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 10: 手动测试验证
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Test: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||||
|
|
||||||
|
**Step 1: 启动前端开发服务器**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:服务启动成功,监听 http://localhost:80
|
||||||
|
|
||||||
|
**Step 2: 访问项目详情页面**
|
||||||
|
|
||||||
|
在浏览器中访问:`http://localhost/ccdiProject`,点击任意项目进入详情页面
|
||||||
|
|
||||||
|
预期:页面正常加载,右侧显示导航菜单
|
||||||
|
|
||||||
|
**Step 3: 测试菜单切换功能**
|
||||||
|
|
||||||
|
测试步骤:
|
||||||
|
1. 点击"上传数据"菜单项
|
||||||
|
- 预期:激活状态显示蓝色文字和底部下划线,显示 UploadData 组件
|
||||||
|
|
||||||
|
2. 点击"参数配置"菜单项
|
||||||
|
- 预期:激活状态切换,显示 ParamConfig 占位组件("参数配置功能开发中...")
|
||||||
|
|
||||||
|
3. 点击"初核结果"菜单,展开下拉菜单
|
||||||
|
- 预期:下拉菜单展开,显示三个子项
|
||||||
|
|
||||||
|
4. 点击"结果总览"子菜单项
|
||||||
|
- 预期:激活状态切换,显示 PreliminaryCheck 占位组件
|
||||||
|
|
||||||
|
5. 点击"专项排查"子菜单项
|
||||||
|
- 预期:显示 SpecialCheck 占位组件
|
||||||
|
|
||||||
|
6. 点击"流水明细查询"子菜单项
|
||||||
|
- 预期:显示 DetailQuery 占位组件
|
||||||
|
|
||||||
|
**Step 4: 测试样式效果**
|
||||||
|
|
||||||
|
测试步骤:
|
||||||
|
1. Hover 菜单项
|
||||||
|
- 预期:显示浅灰背景(#f5f7fa)
|
||||||
|
|
||||||
|
2. 检查激活菜单项
|
||||||
|
- 预期:蓝色文字(#1890ff)+ 底部 2px 蓝色下划线
|
||||||
|
|
||||||
|
3. 点击下拉菜单外部区域
|
||||||
|
- 预期:下拉菜单关闭
|
||||||
|
|
||||||
|
4. 调整浏览器窗口宽度至 768px 以下
|
||||||
|
- 预期:菜单项平均分配宽度,布局自适应
|
||||||
|
|
||||||
|
**Step 5: 测试数据传递**
|
||||||
|
|
||||||
|
测试步骤:
|
||||||
|
1. 切换到"参数配置"组件
|
||||||
|
2. 在浏览器控制台检查组件 props
|
||||||
|
- 预期:projectId 和 projectInfo 正确传递
|
||||||
|
|
||||||
|
3. 点击"上传数据"中的功能按钮
|
||||||
|
- 预期:事件正常触发,原有功能不受影响
|
||||||
|
|
||||||
|
**Step 6: 记录测试结果**
|
||||||
|
|
||||||
|
创建测试报告文件 `docs/test-reports/2026-03-04-navigation-menu-test.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# 项目详情页面导航菜单改造测试报告
|
||||||
|
|
||||||
|
## 测试环境
|
||||||
|
- 浏览器: [记录浏览器名称和版本]
|
||||||
|
- 测试时间: 2026-03-04
|
||||||
|
- 测试人员: [你的名字]
|
||||||
|
|
||||||
|
## 功能测试
|
||||||
|
|
||||||
|
### 菜单切换
|
||||||
|
- [x] 点击"上传数据",显示 UploadData 组件
|
||||||
|
- [x] 点击"参数配置",显示 ParamConfig 占位组件
|
||||||
|
- [x] 点击"初核结果",下拉菜单展开
|
||||||
|
- [x] 点击"结果总览",显示 PreliminaryCheck 占位组件
|
||||||
|
- [x] 点击"专项排查",显示 SpecialCheck 占位组件
|
||||||
|
- [x] 点击"流水明细查询",显示 DetailQuery 占位组件
|
||||||
|
|
||||||
|
### 样式测试
|
||||||
|
- [x] 默认状态:灰色文字,透明背景
|
||||||
|
- [x] Hover 状态:浅灰背景,深色文字
|
||||||
|
- [x] 激活状态:蓝色文字 + 底部下划线
|
||||||
|
- [x] 下拉菜单样式统一
|
||||||
|
|
||||||
|
### 交互测试
|
||||||
|
- [x] 下拉菜单点击外部区域关闭
|
||||||
|
- [x] 菜单切换流畅无闪烁
|
||||||
|
- [x] 组件切换数据正确传递
|
||||||
|
|
||||||
|
### 响应式测试
|
||||||
|
- [x] 移动端菜单布局正常
|
||||||
|
- [x] 菜单项平均分配宽度
|
||||||
|
|
||||||
|
## 问题记录
|
||||||
|
[记录发现的任何问题]
|
||||||
|
|
||||||
|
## 测试结论
|
||||||
|
[通过/需要修复]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 7: 提交测试报告**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add docs/test-reports/2026-03-04-navigation-menu-test.md
|
||||||
|
git commit -m "test(ccdiProject): 添加导航菜单改造测试报告"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 11: 清理和最终提交
|
||||||
|
|
||||||
|
**Step 1: 检查所有修改文件**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:所有修改已提交
|
||||||
|
|
||||||
|
**Step 2: 查看提交历史**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git log --oneline -10
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:看到 10 个新提交:
|
||||||
|
1. feat(ccdiProject): 添加参数配置占位组件
|
||||||
|
2. feat(ccdiProject): 添加结果总览占位组件
|
||||||
|
3. feat(ccdiProject): 添加专项排查占位组件
|
||||||
|
4. feat(ccdiProject): 添加流水明细查询占位组件
|
||||||
|
5. feat(ccdiProject): 导入子组件并添加菜单状态数据
|
||||||
|
6. feat(ccdiProject): 替换按钮组为导航菜单并使用动态组件
|
||||||
|
7. feat(ccdiProject): 添加菜单选择处理方法并清理废弃代码
|
||||||
|
8. style(ccdiProject): 添加导航菜单简洁链接风格样式
|
||||||
|
9. style(ccdiProject): 添加导航菜单响应式布局支持
|
||||||
|
10. test(ccdiProject): 添加导航菜单改造测试报告
|
||||||
|
|
||||||
|
**Step 3: 验证无遗留问题**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:无 lint 错误
|
||||||
|
|
||||||
|
**Step 4: 推送到远程分支**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
预期:推送成功
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实施后检查清单
|
||||||
|
|
||||||
|
- [ ] 所有 4 个占位组件已创建
|
||||||
|
- [ ] detail.vue 已修改完成(模板、脚本、样式)
|
||||||
|
- [ ] 导航菜单样式符合简洁链接风格
|
||||||
|
- [ ] 菜单切换功能正常
|
||||||
|
- [ ] 下拉菜单交互正常
|
||||||
|
- [ ] 响应式布局正常
|
||||||
|
- [ ] 所有修改已提交到 git
|
||||||
|
- [ ] 测试报告已完成
|
||||||
|
- [ ] 代码已推送到远程仓库
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 预期成果
|
||||||
|
|
||||||
|
### 文件创建
|
||||||
|
- `ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue`
|
||||||
|
- `ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue`
|
||||||
|
- `ruoyi-ui/src/views/ccdiProject/components/detail/SpecialCheck.vue`
|
||||||
|
- `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||||||
|
- `docs/test-reports/2026-03-04-navigation-menu-test.md`
|
||||||
|
|
||||||
|
### 文件修改
|
||||||
|
- `ruoyi-ui/src/views/ccdiProject/detail.vue`(模板、脚本、样式)
|
||||||
|
|
||||||
|
### Git 提交
|
||||||
|
- 10 个功能清晰的提交记录
|
||||||
|
|
||||||
|
### 功能实现
|
||||||
|
- ✅ 水平导航菜单替代按钮组
|
||||||
|
- ✅ 简洁链接风格样式
|
||||||
|
- ✅ 菜单切换组件内容
|
||||||
|
- ✅ 下拉菜单支持
|
||||||
|
- ✅ 响应式布局
|
||||||
|
- ✅ 原有功能不受影响
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 潜在问题和解决方案
|
||||||
|
|
||||||
|
### 问题 1: 组件切换时状态丢失
|
||||||
|
**解决方案:** 使用 `<keep-alive>` 包裹动态组件(可选优化)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<keep-alive>
|
||||||
|
<component :is="currentComponent" ... />
|
||||||
|
</keep-alive>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题 2: 下拉菜单样式不生效
|
||||||
|
**解决方案:** 检查 `::v-deep` 是否被正确编译,可能需要使用 `/deep/` 或 `>>>`
|
||||||
|
|
||||||
|
### 问题 3: 移动端菜单换行
|
||||||
|
**解决方案:** 调整响应式断点或使用折叠菜单(el-menu 的 collapse 模式)
|
||||||
|
|
||||||
|
### 问题 4: 原有事件未触发
|
||||||
|
**解决方案:** 检查动态组件的事件绑定是否完整,确保所有事件都有对应的处理方法
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 后续优化建议
|
||||||
|
|
||||||
|
1. **添加组件切换动画**
|
||||||
|
```vue
|
||||||
|
<transition name="fade" mode="out-in">
|
||||||
|
<component :is="currentComponent" ... />
|
||||||
|
</transition>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **实现占位组件的完整功能**
|
||||||
|
- ParamConfig: 模型参数配置界面
|
||||||
|
- PreliminaryCheck: 结果总览数据展示
|
||||||
|
- SpecialCheck: 专项排查功能
|
||||||
|
- DetailQuery: 流水明细查询和筛选
|
||||||
|
|
||||||
|
3. **添加菜单权限控制**
|
||||||
|
- 根据用户权限显示/隐藏菜单项
|
||||||
|
- 使用 `v-if` 或动态生成菜单配置
|
||||||
|
|
||||||
|
4. **添加面包屑导航**
|
||||||
|
- 在页面顶部显示当前位置
|
||||||
|
- 支持快速返回上级页面
|
||||||
|
|
||||||
|
5. **添加快捷键支持**
|
||||||
|
- Ctrl+Tab: 切换到下一个菜单
|
||||||
|
- Ctrl+Shift+Tab: 切换到上一个菜单
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关技能参考
|
||||||
|
|
||||||
|
- @superpowers:brainstorming - 需求分析和设计
|
||||||
|
- @superpowers:test-driven-development - TDD 开发流程
|
||||||
|
- @superpowers:verification-before-completion - 完成前验证
|
||||||
|
- @superpowers:requesting-code-review - 代码审查
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 文档参考
|
||||||
|
|
||||||
|
- 设计文档: `docs/plans/2026-03-04-project-detail-navigation-menu-design.md`
|
||||||
|
- Element UI Menu 文档: https://element.eleme.cn/#/zh-CN/component/menu
|
||||||
|
- Vue 动态组件: https://cn.vuejs.org/v2/guide/components.html#动态组件
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="detail-query-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-document"></i>
|
||||||
|
<p>流水明细查询功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailQuery",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.detail-query-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="param-config-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-setting"></i>
|
||||||
|
<p>参数配置功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ParamConfig",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.param-config-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="preliminary-check-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-data-analysis"></i>
|
||||||
|
<p>结果总览功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "PreliminaryCheck",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.preliminary-check-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="special-check-container">
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<i class="el-icon-search"></i>
|
||||||
|
<p>专项排查功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SpecialCheck",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
projectInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
projectName: "",
|
||||||
|
updateTime: "",
|
||||||
|
projectStatus: "0",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.special-check-container {
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -25,38 +25,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<div class="action-buttons">
|
<el-menu
|
||||||
<el-button
|
:default-active="activeTab"
|
||||||
size="small"
|
mode="horizontal"
|
||||||
type="primary"
|
@select="handleMenuSelect"
|
||||||
icon="el-icon-upload2"
|
class="nav-menu"
|
||||||
@click="handleUploadData"
|
|
||||||
>
|
>
|
||||||
上传数据
|
<el-menu-item index="upload">上传数据</el-menu-item>
|
||||||
</el-button>
|
<el-menu-item index="config">参数配置</el-menu-item>
|
||||||
<el-button
|
<el-menu-item index="overview">结果总览</el-menu-item>
|
||||||
size="small"
|
<el-menu-item index="special">专项排查</el-menu-item>
|
||||||
icon="el-icon-setting"
|
<el-menu-item index="detail">流水明细查询</el-menu-item>
|
||||||
@click="handleParamConfig"
|
</el-menu>
|
||||||
>
|
|
||||||
参数配置
|
|
||||||
</el-button>
|
|
||||||
<el-dropdown @command="handleCheckResultCommand" trigger="click">
|
|
||||||
<el-button size="small" icon="el-icon-document">
|
|
||||||
初核结果<i class="el-icon-arrow-down el-icon--right"></i>
|
|
||||||
</el-button>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="overview">结果总览</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="special">专项排查</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="detail">流水明细查询</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 数据上传页面 -->
|
<!-- 动态组件渲染区域 -->
|
||||||
<UploadData
|
<component
|
||||||
|
:is="currentComponent"
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
:project-info="projectInfo"
|
:project-info="projectInfo"
|
||||||
@menu-change="handleMenuChange"
|
@menu-change="handleMenuChange"
|
||||||
@@ -70,26 +56,26 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import UploadData from "./components/detail/UploadData";
|
import UploadData from "./components/detail/UploadData";
|
||||||
// import UploadParams from "./components/detail/UploadParams";
|
import ParamConfig from "./components/detail/ParamConfig";
|
||||||
// import ParamConfig from "./components/detail/ParamConfig";
|
import PreliminaryCheck from "./components/detail/PreliminaryCheck";
|
||||||
// import PreliminaryCheck from "./components/detail/PreliminaryCheck";
|
import SpecialCheck from "./components/detail/SpecialCheck";
|
||||||
// import SpecialCheck from "./components/detail/SpecialCheck";
|
import DetailQuery from "./components/detail/DetailQuery";
|
||||||
// import DetailQuery from './components/detail/DetailQuery'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectDetail",
|
name: "ProjectDetail",
|
||||||
components: {
|
components: {
|
||||||
UploadData,
|
UploadData,
|
||||||
// UploadParams,
|
ParamConfig,
|
||||||
// ParamConfig,
|
PreliminaryCheck,
|
||||||
// PreliminaryCheck,
|
SpecialCheck,
|
||||||
// SpecialCheck,
|
DetailQuery,
|
||||||
// DetailQuery,
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 当前标签页
|
// 当前激活的菜单项索引
|
||||||
activeTab: "data",
|
activeTab: "upload",
|
||||||
|
// 当前显示的组件名称
|
||||||
|
currentComponent: "UploadData",
|
||||||
// 项目ID
|
// 项目ID
|
||||||
projectId: this.$route.params.projectId,
|
projectId: this.$route.params.projectId,
|
||||||
// 项目信息
|
// 项目信息
|
||||||
@@ -182,26 +168,27 @@ export default {
|
|||||||
handleBack() {
|
handleBack() {
|
||||||
this.$router.push("/ccdiProject");
|
this.$router.push("/ccdiProject");
|
||||||
},
|
},
|
||||||
|
/** 菜单选择事件 */
|
||||||
|
handleMenuSelect(index) {
|
||||||
|
console.log("菜单选择:", index);
|
||||||
|
this.activeTab = index;
|
||||||
|
|
||||||
|
// 组件映射
|
||||||
|
const componentMap = {
|
||||||
|
upload: "UploadData",
|
||||||
|
config: "ParamConfig",
|
||||||
|
overview: "PreliminaryCheck",
|
||||||
|
special: "SpecialCheck",
|
||||||
|
detail: "DetailQuery",
|
||||||
|
};
|
||||||
|
|
||||||
|
this.currentComponent = componentMap[index] || "UploadData";
|
||||||
|
},
|
||||||
/** UploadData 组件:菜单切换 */
|
/** UploadData 组件:菜单切换 */
|
||||||
handleMenuChange({ key, route }) {
|
handleMenuChange({ key, route }) {
|
||||||
console.log("切换到菜单:", key, route);
|
console.log("切换到菜单:", key, route);
|
||||||
// 根据不同的菜单项跳转到不同的组件或页面
|
// 直接触发菜单选择
|
||||||
switch (route) {
|
this.handleMenuSelect(route);
|
||||||
case "config":
|
|
||||||
this.$message.info("参数配置功能开发中");
|
|
||||||
break;
|
|
||||||
case "overview":
|
|
||||||
this.$message.info("结果总览功能开发中");
|
|
||||||
break;
|
|
||||||
case "special":
|
|
||||||
this.$message.info("专项排查功能开发中");
|
|
||||||
break;
|
|
||||||
case "detail":
|
|
||||||
this.$message.info("流水明细查询功能开发中");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/** UploadData 组件:数据上传完成 */
|
/** UploadData 组件:数据上传完成 */
|
||||||
handleDataUploaded({ type }) {
|
handleDataUploaded({ type }) {
|
||||||
@@ -223,33 +210,6 @@ export default {
|
|||||||
console.log("拉取本行信息");
|
console.log("拉取本行信息");
|
||||||
this.$message.info("拉取本行信息功能开发中");
|
this.$message.info("拉取本行信息功能开发中");
|
||||||
},
|
},
|
||||||
/** 上传数据 (原方法,已由UploadData组件处理) */
|
|
||||||
handleUploadData() {
|
|
||||||
console.log("上传数据");
|
|
||||||
this.$message.info("上传数据功能已迁移至上传页面");
|
|
||||||
},
|
|
||||||
/** 参数配置 (原方法) */
|
|
||||||
handleParamConfig() {
|
|
||||||
console.log("参数配置");
|
|
||||||
this.$message.info("参数配置功能开发中");
|
|
||||||
},
|
|
||||||
/** 初核结果下拉菜单命令 */
|
|
||||||
handleCheckResultCommand(command) {
|
|
||||||
console.log("初核结果命令:", command);
|
|
||||||
switch (command) {
|
|
||||||
case "overview":
|
|
||||||
this.$message.info("结果总览功能开发中");
|
|
||||||
break;
|
|
||||||
case "special":
|
|
||||||
this.$message.info("专项排查功能开发中");
|
|
||||||
break;
|
|
||||||
case "detail":
|
|
||||||
this.$message.info("流水明细查询功能开发中");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/** 数据上传完成 */
|
/** 数据上传完成 */
|
||||||
handleDataUploaded() {
|
handleDataUploaded() {
|
||||||
console.log("数据上传完成");
|
console.log("数据上传完成");
|
||||||
@@ -353,21 +313,51 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-right {
|
.header-right {
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
.el-button {
|
.nav-menu {
|
||||||
padding: 8px 16px;
|
// 移除默认背景色和边框
|
||||||
|
background-color: transparent;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
// 菜单项基础样式
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu__title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
padding: 0 16px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
|
||||||
.el-icon--right {
|
&:hover {
|
||||||
margin-left: 4px;
|
background-color: #f5f7fa;
|
||||||
|
color: #303133;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-tag {
|
// 子菜单容器高度统一
|
||||||
|
.el-submenu {
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 激活状态:底部下划线 + 蓝色文字
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单激活状态
|
||||||
|
.el-submenu.is-active > .el-submenu__title {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉菜单图标
|
||||||
|
.el-submenu__icon-arrow {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,6 +461,25 @@ export default {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
.nav-menu {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.el-menu-item,
|
||||||
|
.el-submenu {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-content {
|
.info-content {
|
||||||
@@ -494,4 +503,22 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下拉菜单弹窗样式
|
||||||
|
::v-deep .el-menu--popup {
|
||||||
|
min-width: 140px;
|
||||||
|
|
||||||
|
.el-menu-item {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
color: #1890ff;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user