Compare commits
16 Commits
a7cf67e6e4
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| ea70710804 | |||
| 69284d7da6 | |||
| 2fde76d180 | |||
| 6148d5fb69 | |||
| 4b0ccb194b | |||
| 5c7e30275e | |||
| 35fdc72ffb | |||
| d999c0ddaa | |||
| de35bd33c0 | |||
| b7197682e7 | |||
| a753b87c1f | |||
| 012c5caa64 | |||
| d3c15d4d75 | |||
| 848640e284 | |||
| bd0b25d059 | |||
| ba939b8eb6 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -67,3 +67,6 @@ doc/test-data/**/~$*
|
|||||||
db_config.conf
|
db_config.conf
|
||||||
|
|
||||||
~*.*
|
~*.*
|
||||||
|
|
||||||
|
|
||||||
|
/.playwright-cli/
|
||||||
|
|||||||
166
AGENTS.md
166
AGENTS.md
@@ -16,3 +16,169 @@ Use `@/openspec/AGENTS.md` to learn:
|
|||||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||||
|
|
||||||
<!-- OPENSPEC:END -->
|
<!-- OPENSPEC:END -->
|
||||||
|
|
||||||
|
# AGENTS.md - AI Coding Assistant Guide
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
基于若依 v3.9.1 的纪检初核系统,Java 21 + Spring Boot 3 + Vue 2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build / Lint / Test Commands
|
||||||
|
|
||||||
|
### 后端 (Maven)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 编译项目
|
||||||
|
mvn clean compile
|
||||||
|
|
||||||
|
# 运行应用
|
||||||
|
mvn spring-boot:run
|
||||||
|
|
||||||
|
# 打包部署
|
||||||
|
mvn clean package
|
||||||
|
|
||||||
|
# 运行单个测试类
|
||||||
|
mvn test -Dtest=ClassName
|
||||||
|
|
||||||
|
# 运行单个测试方法
|
||||||
|
mvn test -Dtest=ClassName#methodName
|
||||||
|
|
||||||
|
# 跳过测试
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
```
|
||||||
|
|
||||||
|
### 前端 (npm)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
npm install --registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
|
# 开发服务器
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# 生产构建
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### API 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 获取 Token (测试账号: admin/admin123)
|
||||||
|
POST http://localhost:8080/login/test?username=admin&password=admin123
|
||||||
|
|
||||||
|
# Swagger 文档
|
||||||
|
http://localhost:8080/swagger-ui/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 代码规范
|
||||||
|
|
||||||
|
### Java 代码风格
|
||||||
|
|
||||||
|
- **注解**: 使用 Lombok `@Data` 简化实体类
|
||||||
|
- **依赖注入**: 使用 `@Resource` 而非 `@Autowired`
|
||||||
|
- **实体类**: 不继承 BaseEntity,单独添加审计字段
|
||||||
|
- **禁止**: 禁止使用全限定类名 (如 `java.util.List`),必须 import
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class CcdiBaseStaff {
|
||||||
|
/** 创建者 */
|
||||||
|
private String createBy;
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date createTime;
|
||||||
|
/** 更新者 */
|
||||||
|
private String updateBy;
|
||||||
|
/** 更新时间 */
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ICcdiBaseStaffService baseStaffService;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 分层规范
|
||||||
|
|
||||||
|
- **Controller**: 添加 Swagger 注释,分页使用 MyBatis Plus Page
|
||||||
|
- **Service**: 简单 CRUD 用 MyBatis Plus,复杂操作在 XML 写 SQL
|
||||||
|
- **DTO/VO**: 接口传参用独立 DTO,返回用独立 VO,禁止与 entity 混用
|
||||||
|
- **禁止**: 禁止 `extends ServiceImpl<>`
|
||||||
|
|
||||||
|
### API 响应格式
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 成功
|
||||||
|
AjaxResult.success("操作成功", data);
|
||||||
|
|
||||||
|
// 错误
|
||||||
|
AjaxResult.error("操作失败");
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
Page<CcdiBaseStaff> page = new Page<>(pageNum, pageSize);
|
||||||
|
IPage<CcdiBaseStaff> result = baseStaffMapper.selectPage(page, queryWrapper);
|
||||||
|
return AjaxResult.success(result);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据库规范
|
||||||
|
|
||||||
|
- 表名: `ccdi_` 前缀 (如 `ccdi_base_staff`)
|
||||||
|
- 非业务字段 (create_by, create_time 等) 由后端自动处理,前端表单不显示
|
||||||
|
|
||||||
|
### 前端规范
|
||||||
|
|
||||||
|
- **目录结构**: `views/` 按功能模块组织,`api/` 对应后端 Controller
|
||||||
|
- **API 调用**: 使用 `@/utils/request` 封装
|
||||||
|
- **菜单联动**: 添加页面后需同步修改数据库 `sys_menu` 表
|
||||||
|
|
||||||
|
### 导入功能规范
|
||||||
|
|
||||||
|
- 批量操作提高性能
|
||||||
|
- 返回结果只展示失败数据,不展示成功数据
|
||||||
|
- 使用 EasyExcel + 异步处理大数据量导入
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 模块架构
|
||||||
|
|
||||||
|
```
|
||||||
|
ccdi/
|
||||||
|
├── ruoyi-admin/ # 启动入口
|
||||||
|
├── ruoyi-framework/ # 安全配置
|
||||||
|
├── ruoyi-system/ # 系统模块
|
||||||
|
├── ruoyi-common/ # 通用工具
|
||||||
|
├── ccdi-info-collection/ # 信息采集 (员工、中介、黑名单)
|
||||||
|
├── ccdi-project/ # 项目管理
|
||||||
|
├── ccdi-lsfx/ # 流水分析对接
|
||||||
|
└── ruoyi-ui/ # 前端
|
||||||
|
```
|
||||||
|
|
||||||
|
### 添加新模块
|
||||||
|
|
||||||
|
1. 根 pom.xml 添加 `<module>`
|
||||||
|
2. pom.xml 添加 `ruoyi-common` 依赖
|
||||||
|
3. `ruoyi-admin/pom.xml` 添加模块依赖
|
||||||
|
4. 按分层创建 controller/service/mapper/domain 包
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常用路径
|
||||||
|
|
||||||
|
| 用途 | 路径 |
|
||||||
|
|------|------|
|
||||||
|
| 应用入口 | `ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java` |
|
||||||
|
| 信息采集 Controller | `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/` |
|
||||||
|
| 项目管理 Controller | `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/` |
|
||||||
|
| 前端 API | `ruoyi-ui/src/api/` |
|
||||||
|
| Vue 路由 | `ruoyi-ui/src/router/index.js` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 沟通规范
|
||||||
|
|
||||||
|
- 使用简体中文进行思考和对话
|
||||||
|
- 遇到 MCP 数据库操作时,使用项目配置文件中的数据库
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.ruoyi.lsfx.domain.response;
|
package com.ruoyi.lsfx.domain.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,6 +134,9 @@ public class GetBankStatementResponse {
|
|||||||
/** 上传logId */
|
/** 上传logId */
|
||||||
private Integer batchId;
|
private Integer batchId;
|
||||||
|
|
||||||
|
/** 上传序号 */
|
||||||
|
private Integer uploadSequenceNumber;
|
||||||
|
|
||||||
/** 项目id */
|
/** 项目id */
|
||||||
private Integer groupId;
|
private Integer groupId;
|
||||||
|
|
||||||
@@ -183,5 +189,14 @@ public class GetBankStatementResponse {
|
|||||||
|
|
||||||
/** 交易余额 */
|
/** 交易余额 */
|
||||||
private BigDecimal trxBalance;
|
private BigDecimal trxBalance;
|
||||||
|
|
||||||
|
// ===== 审计字段 =====
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createDate;
|
||||||
|
|
||||||
|
/** 创建者 */
|
||||||
|
private Long createdBy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ public class CcdiBankStatement implements Serializable {
|
|||||||
entity.setTrxType(item.getTransTypeId());
|
entity.setTrxType(item.getTransTypeId());
|
||||||
entity.setCustomerLeId(item.getCustomerId());
|
entity.setCustomerLeId(item.getCustomerId());
|
||||||
entity.setCustomerAccountName(item.getCustomerName());
|
entity.setCustomerAccountName(item.getCustomerName());
|
||||||
|
entity.setBatchSequence(item.getUploadSequenceNumber());
|
||||||
|
|
||||||
// 5. 特殊字段处理
|
// 5. 特殊字段处理
|
||||||
entity.setMetaJson(null); // 根据文档要求强制设为 null
|
entity.setMetaJson(null); // 根据文档要求强制设为 null
|
||||||
|
|||||||
194
docs/plans/2026-03-05-bank-statement-audit-fields-design.md
Normal file
194
docs/plans/2026-03-05-bank-statement-audit-fields-design.md
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# 银行流水审计字段补充设计文档
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本文档记录为 `GetBankStatementResponse.BankStatementItem` 类添加 `createdBy` 和 `createDate` 审计字段的设计方案。
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
### 问题描述
|
||||||
|
|
||||||
|
外部流水分析平台的接口文档(6.5节)中包含 `createdBy` 和 `createDate` 字段,但我们的响应类 `GetBankStatementResponse.BankStatementItem` 中缺少这两个字段的定义,导致无法接收外部平台返回的审计信息。
|
||||||
|
|
||||||
|
### 影响范围
|
||||||
|
|
||||||
|
- **直接影响:** `GetBankStatementResponse.BankStatementItem` 类
|
||||||
|
- **间接影响:** `CcdiBankStatement.fromResponse()` 方法(已有对应字段,无需修改)
|
||||||
|
- **数据流:** 外部平台 → 响应类 → 实体类 → 数据库
|
||||||
|
|
||||||
|
## 设计方案
|
||||||
|
|
||||||
|
### 字段定义
|
||||||
|
|
||||||
|
在 `GetBankStatementResponse.BankStatementItem` 类中添加两个审计字段:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 | 来源 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| `createdBy` | `Long` | 创建者用户ID | 外部平台 |
|
||||||
|
| `createDate` | `String` | 创建时间 | 外部平台 |
|
||||||
|
|
||||||
|
### 类型选择
|
||||||
|
|
||||||
|
- **createdBy**: 使用 `Long` 类型
|
||||||
|
- 与实体类 `CcdiBankStatement` 保持一致
|
||||||
|
- 用户ID通常为长整型数字
|
||||||
|
|
||||||
|
- **createDate**: 使用 `String` 类型
|
||||||
|
- 外部平台返回时间字符串格式(如 "2026-03-05 10:30:00")
|
||||||
|
- 避免时间格式转换问题
|
||||||
|
- 由业务层负责转换为 Date 类型
|
||||||
|
|
||||||
|
### 代码修改
|
||||||
|
|
||||||
|
**文件:** `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java`
|
||||||
|
|
||||||
|
**修改位置:** 在 `BankStatementItem` 类的最后添加审计字段组
|
||||||
|
|
||||||
|
**修改内容:**
|
||||||
|
|
||||||
|
```java
|
||||||
|
// ===== 审计字段 =====
|
||||||
|
|
||||||
|
/** 创建者 */
|
||||||
|
private Long createdBy;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private String createDate;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 完整修改后的类结构
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public static class BankStatementItem {
|
||||||
|
// ===== 账号相关信息 =====
|
||||||
|
/** 流水ID */
|
||||||
|
private Long bankStatementId;
|
||||||
|
// ... 其他字段
|
||||||
|
|
||||||
|
// ===== 附加字段 =====
|
||||||
|
/** 附件数量 */
|
||||||
|
private Integer attachments;
|
||||||
|
// ... 其他附加字段
|
||||||
|
|
||||||
|
// ===== 审计字段 =====
|
||||||
|
/** 创建者 */
|
||||||
|
private Long createdBy;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private String createDate;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据流分析
|
||||||
|
|
||||||
|
### 1. 接收外部数据
|
||||||
|
|
||||||
|
```
|
||||||
|
外部平台 → GetBankStatementResponse.BankStatementItem
|
||||||
|
- createdBy: Long
|
||||||
|
- createDate: String
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 转换为实体
|
||||||
|
|
||||||
|
```java
|
||||||
|
// CcdiBankStatement.fromResponse() 方法
|
||||||
|
CcdiBankStatement entity = new CcdiBankStatement();
|
||||||
|
BeanUtils.copyProperties(item, entity);
|
||||||
|
// 自动复制 createdBy (Long → Long)
|
||||||
|
// createDate 字段类型不匹配 (String → Date),需要手动转换
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意:** 如果需要自动转换 `createDate`,需要修改 `fromResponse()` 方法添加日期格式转换逻辑。
|
||||||
|
|
||||||
|
### 3. 保存到数据库
|
||||||
|
|
||||||
|
```
|
||||||
|
CcdiBankStatement
|
||||||
|
- createdBy: Long → 数据库字段 created_by
|
||||||
|
- createDate: Date → 数据库字段 create_date
|
||||||
|
```
|
||||||
|
|
||||||
|
## 实现要点
|
||||||
|
|
||||||
|
### 必须实现
|
||||||
|
|
||||||
|
1. ✅ 在 `BankStatementItem` 类中添加两个字段
|
||||||
|
2. ✅ 添加 Lombok `@Data` 注解会自动生成 getter/setter
|
||||||
|
|
||||||
|
### 可选优化
|
||||||
|
|
||||||
|
1. **日期转换:** 如果需要,在 `CcdiBankStatement.fromResponse()` 中添加 `createDate` 的日期格式转换
|
||||||
|
2. **字段验证:** 添加 `@JsonFormat` 注解指定日期格式(如果需要)
|
||||||
|
|
||||||
|
## 测试计划
|
||||||
|
|
||||||
|
### 单元测试
|
||||||
|
|
||||||
|
- 验证 JSON 反序列化能正确映射这两个字段
|
||||||
|
- 验证 `fromResponse()` 方法能正确处理 `createdBy` 字段
|
||||||
|
|
||||||
|
### 集成测试
|
||||||
|
|
||||||
|
1. 调用外部平台接口(或 mock 服务器)
|
||||||
|
2. 验证响应中包含 `createdBy` 和 `createDate`
|
||||||
|
3. 验证数据能正确保存到数据库
|
||||||
|
|
||||||
|
### 测试数据
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"createdBy": 12345,
|
||||||
|
"createDate": "2026-03-05 14:30:00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
| 风险 | 影响 | 概率 | 缓解措施 |
|
||||||
|
|------|------|------|----------|
|
||||||
|
| 外部平台不返回这两个字段 | 低 | 中 | 字段可以为 null,不影响现有功能 |
|
||||||
|
| 日期格式不兼容 | 中 | 低 | 使用 String 类型接收,业务层处理转换 |
|
||||||
|
| 类型不匹配 | 高 | 低 | 已确认类型与实体类一致 |
|
||||||
|
|
||||||
|
## 变更影响
|
||||||
|
|
||||||
|
### 正面影响
|
||||||
|
|
||||||
|
- ✅ 补全接口字段,与外部平台文档对齐
|
||||||
|
- ✅ 支持审计信息传递
|
||||||
|
- ✅ 提升数据完整性
|
||||||
|
|
||||||
|
### 负面影响
|
||||||
|
|
||||||
|
- 无(仅添加字段,不影响现有功能)
|
||||||
|
|
||||||
|
## 实现计划
|
||||||
|
|
||||||
|
1. 修改 `GetBankStatementResponse.BankStatementItem` 类
|
||||||
|
2. 更新相关的 API 文档(如有)
|
||||||
|
3. 执行集成测试验证功能
|
||||||
|
4. 提交代码并更新 CHANGELOG
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- 外部流水分析平台接口文档 6.5节
|
||||||
|
- `CcdiBankStatement` 实体类定义
|
||||||
|
- 项目开发规范(CLAUDE.md)
|
||||||
|
|
||||||
|
## 附录
|
||||||
|
|
||||||
|
### 相关文件路径
|
||||||
|
|
||||||
|
- 响应类:`ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java`
|
||||||
|
- 实体类:`ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java`
|
||||||
|
- 客户端:`ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java`
|
||||||
|
|
||||||
|
### 数据库字段
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- ccdi_bank_statement 表
|
||||||
|
created_by BIGINT(20) COMMENT '创建者',
|
||||||
|
create_date DATETIME COMMENT '创建时间'
|
||||||
|
```
|
||||||
@@ -0,0 +1,372 @@
|
|||||||
|
# 银行流水审计字段补充实现计划
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** 为 GetBankStatementResponse.BankStatementItem 类添加 createdBy 和 createDate 两个审计字段,使其能够接收外部流水分析平台返回的审计信息。
|
||||||
|
|
||||||
|
**Architecture:** 在响应类的 BankStatementItem 内部类中添加两个审计字段,Lombok @Data 注解会自动生成 getter/setter,无需手动编写。字段类型为 Long 和 String,与外部平台接口文档对齐。
|
||||||
|
|
||||||
|
**Tech Stack:** Java 21, Lombok, Jackson (JSON 序列化/反序列化)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: 添加审计字段到响应类
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java:189-190`
|
||||||
|
|
||||||
|
**Step 1: 打开响应类文件**
|
||||||
|
|
||||||
|
在编辑器中打开文件:
|
||||||
|
```
|
||||||
|
ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
```
|
||||||
|
|
||||||
|
定位到 `BankStatementItem` 内部类的最后,找到第 189 行附近(在 `trxBalance` 字段之后)。
|
||||||
|
|
||||||
|
**Step 2: 添加审计字段**
|
||||||
|
|
||||||
|
在第 189 行之后添加以下代码:
|
||||||
|
|
||||||
|
```java
|
||||||
|
/** 交易余额 */
|
||||||
|
private BigDecimal trxBalance;
|
||||||
|
|
||||||
|
// ===== 审计字段 =====
|
||||||
|
|
||||||
|
/** 创建者 */
|
||||||
|
private Long createdBy;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private String createDate;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**完整修改后的类尾部:**
|
||||||
|
|
||||||
|
```java
|
||||||
|
/** 转换余额 */
|
||||||
|
private BigDecimal transfromBalanceAmount;
|
||||||
|
|
||||||
|
/** 交易余额 */
|
||||||
|
private BigDecimal trxBalance;
|
||||||
|
|
||||||
|
// ===== 审计字段 =====
|
||||||
|
|
||||||
|
/** 创建者 */
|
||||||
|
private Long createdBy;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private String createDate;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 验证代码编译**
|
||||||
|
|
||||||
|
运行以下命令验证代码编译通过:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd D:/ccdi/ccdi
|
||||||
|
mvn clean compile -pl ccdi-lsfx -am
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `BUILD SUCCESS`
|
||||||
|
|
||||||
|
**Step 4: 提交代码**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
git commit -m "feat(ccdi-lsfx): 添加银行流水审计字段 createdBy 和 createDate
|
||||||
|
|
||||||
|
- 在 GetBankStatementResponse.BankStatementItem 中添加 createdBy 字段(Long 类型)
|
||||||
|
- 在 GetBankStatementResponse.BankStatementItem 中添加 createDate 字段(String 类型)
|
||||||
|
- 补充外部流水分析平台接口文档 6.5 节中定义的审计字段
|
||||||
|
- 支持接收外部平台返回的创建者和创建时间信息"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: 验证 JSON 反序列化(可选但推荐)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ccdi-lsfx/src/test/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponseTest.java`
|
||||||
|
|
||||||
|
**Step 1: 创建测试类**
|
||||||
|
|
||||||
|
创建测试文件:
|
||||||
|
```
|
||||||
|
ccdi-lsfx/src/test/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponseTest.java
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 编写测试代码**
|
||||||
|
|
||||||
|
```java
|
||||||
|
package com.ruoyi.lsfx.domain.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetBankStatementResponse 单元测试
|
||||||
|
*/
|
||||||
|
class GetBankStatementResponseTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDeserializeBankStatementItem() throws Exception {
|
||||||
|
// 准备测试数据(包含审计字段)
|
||||||
|
String json = """
|
||||||
|
{
|
||||||
|
"code": "0",
|
||||||
|
"status": "success",
|
||||||
|
"successResponse": true,
|
||||||
|
"data": {
|
||||||
|
"bankStatementList": [
|
||||||
|
{
|
||||||
|
"bankStatementId": 123456,
|
||||||
|
"leId": 100,
|
||||||
|
"accountId": 200,
|
||||||
|
"leName": "测试企业",
|
||||||
|
"accountMaskNo": "6222****1234",
|
||||||
|
"trxDate": "2026-03-05",
|
||||||
|
"currency": "CNY",
|
||||||
|
"drAmount": 1000.00,
|
||||||
|
"crAmount": 0,
|
||||||
|
"balanceAmount": 5000.00,
|
||||||
|
"createdBy": 12345,
|
||||||
|
"createDate": "2026-03-05 14:30:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalCount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
// 反序列化
|
||||||
|
GetBankStatementResponse response = objectMapper.readValue(json, GetBankStatementResponse.class);
|
||||||
|
|
||||||
|
// 验证基本字段
|
||||||
|
assertNotNull(response);
|
||||||
|
assertEquals("0", response.getCode());
|
||||||
|
assertEquals("success", response.getStatus());
|
||||||
|
assertTrue(response.getSuccessResponse());
|
||||||
|
|
||||||
|
// 验证数据列表
|
||||||
|
assertNotNull(response.getData());
|
||||||
|
assertNotNull(response.getData().getBankStatementList());
|
||||||
|
assertEquals(1, response.getData().getTotalCount());
|
||||||
|
|
||||||
|
// 验证流水项
|
||||||
|
GetBankStatementResponse.BankStatementItem item = response.getData().getBankStatementList().get(0);
|
||||||
|
assertNotNull(item);
|
||||||
|
assertEquals(123456L, item.getBankStatementId());
|
||||||
|
assertEquals(100, item.getLeId());
|
||||||
|
assertEquals("测试企业", item.getLeName());
|
||||||
|
|
||||||
|
// 验证审计字段
|
||||||
|
assertEquals(12345L, item.getCreatedBy());
|
||||||
|
assertEquals("2026-03-05 14:30:00", item.getCreateDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDeserializeWithNullAuditFields() throws Exception {
|
||||||
|
// 测试审计字段为 null 的情况
|
||||||
|
String json = """
|
||||||
|
{
|
||||||
|
"code": "0",
|
||||||
|
"data": {
|
||||||
|
"bankStatementList": [
|
||||||
|
{
|
||||||
|
"bankStatementId": 123456
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalCount": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
GetBankStatementResponse response = objectMapper.readValue(json, GetBankStatementResponse.class);
|
||||||
|
GetBankStatementResponse.BankStatementItem item = response.getData().getBankStatementList().get(0);
|
||||||
|
|
||||||
|
// 审计字段应该为 null
|
||||||
|
assertNull(item.getCreatedBy());
|
||||||
|
assertNull(item.getCreateDate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 运行测试**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd D:/ccdi/ccdi
|
||||||
|
mvn test -Dtest=GetBankStatementResponseTest -pl ccdi-lsfx
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Tests run: 2, Failures: 0, Errors: 0, Skipped: 0`
|
||||||
|
|
||||||
|
**Step 4: 提交测试代码**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ccdi-lsfx/src/test/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponseTest.java
|
||||||
|
git commit -m "test(ccdi-lsfx): 添加银行流水响应类单元测试
|
||||||
|
|
||||||
|
- 测试 JSON 反序列化能正确映射 createdBy 和 createDate 字段
|
||||||
|
- 测试审计字段为 null 时的处理
|
||||||
|
- 验证字段类型和值的正确性"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: 集成测试验证
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `lsfx-mock-server/app.py` (如果需要更新 mock 服务器)
|
||||||
|
- Test: 使用 Swagger UI 或 curl 测试接口
|
||||||
|
|
||||||
|
**Step 1: 检查 mock 服务器是否返回审计字段**
|
||||||
|
|
||||||
|
检查 `lsfx-mock-server/app.py` 文件,确认银行流水接口返回的数据中包含 `createdBy` 和 `createDate` 字段。
|
||||||
|
|
||||||
|
如果 mock 服务器未返回这两个字段,添加以下内容到响应中:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 在 bank_statement_data 字典中添加
|
||||||
|
'createdBy': 12345,
|
||||||
|
'createDate': '2026-03-05 14:30:00',
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 启动后端服务**
|
||||||
|
|
||||||
|
提示用户手动启动后端服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在项目根目录执行
|
||||||
|
mvn spring-boot:run
|
||||||
|
|
||||||
|
# 或者运行启动脚本
|
||||||
|
ry.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 启动 mock 服务器(新终端)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd lsfx-mock-server
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: Mock 服务器在 http://localhost:8000 启动
|
||||||
|
|
||||||
|
**Step 4: 使用 Swagger UI 测试接口**
|
||||||
|
|
||||||
|
1. 打开浏览器访问: http://localhost:8080/swagger-ui/index.html
|
||||||
|
2. 找到 "流水分析平台接口测试" 分组
|
||||||
|
3. 点击 "POST /lsfx/test/getBankStatement" 接口
|
||||||
|
4. 点击 "Try it out"
|
||||||
|
5. 输入测试参数:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"groupId": 1,
|
||||||
|
"logId": 1,
|
||||||
|
"pageNow": 1,
|
||||||
|
"pageSize": 10
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
6. 点击 "Execute"
|
||||||
|
7. 查看响应,验证 `createdBy` 和 `createDate` 字段存在
|
||||||
|
|
||||||
|
Expected: 响应中的 `bankStatementList` 包含 `createdBy` 和 `createDate` 字段
|
||||||
|
|
||||||
|
**Step 5: 使用 curl 测试(可选)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:8080/lsfx/test/getBankStatement" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"groupId": 1,
|
||||||
|
"logId": 1,
|
||||||
|
"pageNow": 1,
|
||||||
|
"pageSize": 10
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: JSON 响应中包含 `createdBy` 和 `createDate` 字段
|
||||||
|
|
||||||
|
**Step 6: 提交 mock 服务器更新(如果有修改)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add lsfx-mock-server/app.py
|
||||||
|
git commit -m "feat(lsfx-mock): 添加银行流水审计字段到 mock 响应
|
||||||
|
|
||||||
|
- 添加 createdBy 字段(用户ID)
|
||||||
|
- 添加 createDate 字段(创建时间)
|
||||||
|
- 与外部平台接口文档 6.5 节对齐"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: 更新文档(可选)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Update: `docs/plans/2026-03-05-bank-statement-audit-fields-design.md`(已存在)
|
||||||
|
|
||||||
|
**Step 1: 验证设计文档完整性**
|
||||||
|
|
||||||
|
确认设计文档包含以下内容:
|
||||||
|
- ✅ 问题描述
|
||||||
|
- ✅ 字段定义
|
||||||
|
- ✅ 代码修改
|
||||||
|
- ✅ 测试计划
|
||||||
|
- ✅ 风险评估
|
||||||
|
|
||||||
|
**Step 2: 更新 API 文档(如果有)**
|
||||||
|
|
||||||
|
如果项目中有 API 文档文件,更新银行流水接口的响应字段说明,添加:
|
||||||
|
- `createdBy`: 创建者用户ID(Long 类型)
|
||||||
|
- `createDate`: 创建时间(String 类型)
|
||||||
|
|
||||||
|
**Step 3: 提交文档更新**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add docs/
|
||||||
|
git commit -m "docs: 更新银行流水接口文档,补充审计字段说明"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 完成清单
|
||||||
|
|
||||||
|
- [ ] Task 1: 添加审计字段到响应类
|
||||||
|
- [ ] Task 2: 验证 JSON 反序列化(可选但推荐)
|
||||||
|
- [ ] Task 3: 集成测试验证
|
||||||
|
- [ ] Task 4: 更新文档(可选)
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
1. ✅ `GetBankStatementResponse.BankStatementItem` 类包含 `createdBy` 和 `createDate` 字段
|
||||||
|
2. ✅ 字段类型正确:`createdBy` 为 Long,`createDate` 为 String
|
||||||
|
3. ✅ 代码编译通过
|
||||||
|
4. ✅ 单元测试通过(如果编写)
|
||||||
|
5. ✅ 集成测试通过,能正确接收外部平台的审计字段
|
||||||
|
6. ✅ 代码已提交到 git
|
||||||
|
|
||||||
|
## 风险与缓解
|
||||||
|
|
||||||
|
| 风险 | 缓解措施 |
|
||||||
|
|------|----------|
|
||||||
|
| 外部平台不返回审计字段 | 字段可以为 null,不影响现有功能 |
|
||||||
|
| 日期格式不一致 | 使用 String 类型接收,业务层处理转换 |
|
||||||
|
| JSON 反序列化失败 | 编写单元测试验证,使用 Jackson 注解处理格式 |
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- 设计文档: `docs/plans/2026-03-05-bank-statement-audit-fields-design.md`
|
||||||
|
- 实体类: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java`
|
||||||
|
- 项目规范: `CLAUDE.md`
|
||||||
|
- 外部平台接口文档 6.5 节
|
||||||
106
docs/plans/2026-03-05-bank-statement-field-design.md
Normal file
106
docs/plans/2026-03-05-bank-statement-field-design.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# 银行流水接口字段补充设计
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
流水分析平台接口实际返回了 `uploadSequnceNumber` 字段,但当前响应类中缺少该字段定义,导致数据丢失。本设计补充该字段的接收和映射。
|
||||||
|
|
||||||
|
## 问题分析
|
||||||
|
|
||||||
|
### 当前问题
|
||||||
|
|
||||||
|
- **接口返回**:流水分析平台接口实际返回 `uploadSequnceNumber` 字段
|
||||||
|
- **响应类缺失**:`GetBankStatementResponse.BankStatementItem` 未定义该字段,数据被丢弃
|
||||||
|
- **实体已有字段**:`CcdiBankStatement` 已定义 `batchSequence` 字段
|
||||||
|
- **映射缺失**:`fromResponse()` 方法未映射该字段
|
||||||
|
|
||||||
|
### 字段映射关系
|
||||||
|
|
||||||
|
| 接口返回字段 | 响应类字段 | 实体类字段 | 数据库字段 |
|
||||||
|
|------------|-----------|-----------|-----------|
|
||||||
|
| uploadSequnceNumber | ❌ 缺失 | batchSequence | batch_sequence |
|
||||||
|
|
||||||
|
## 设计方案
|
||||||
|
|
||||||
|
### 修改范围
|
||||||
|
|
||||||
|
**涉及文件:**
|
||||||
|
1. `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java`
|
||||||
|
2. `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java`
|
||||||
|
|
||||||
|
**不涉及:**
|
||||||
|
- 数据库表结构(接口会返回实际值,无需修改约束)
|
||||||
|
- Controller、Service、Mapper 层
|
||||||
|
- 前端代码
|
||||||
|
|
||||||
|
### 具体变更
|
||||||
|
|
||||||
|
#### 1. 响应类添加字段
|
||||||
|
|
||||||
|
**文件**:`GetBankStatementResponse.java`
|
||||||
|
|
||||||
|
**位置**:`BankStatementItem` 内部类,建议在 `batchId` 字段之后
|
||||||
|
|
||||||
|
```java
|
||||||
|
/** 上传序号 */
|
||||||
|
private Integer uploadSequnceNumber;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 实体转换逻辑补充
|
||||||
|
|
||||||
|
**文件**:`CcdiBankStatement.java`
|
||||||
|
|
||||||
|
**位置**:`fromResponse()` 方法,手动映射字段区域
|
||||||
|
|
||||||
|
```java
|
||||||
|
entity.setBatchSequence(item.getUploadSequnceNumber());
|
||||||
|
```
|
||||||
|
|
||||||
|
### 影响评估
|
||||||
|
|
||||||
|
#### 功能影响
|
||||||
|
- ✅ 流水数据完整性提升:接收并存储接口返回的上传序号
|
||||||
|
- ✅ 数据一致性保障:字段映射关系符合文档定义
|
||||||
|
- ✅ 无破坏性变更:仅添加字段,不影响现有功能
|
||||||
|
|
||||||
|
#### 数据影响
|
||||||
|
- 现有数据:不受影响
|
||||||
|
- 新数据:完整接收接口返回的 `uploadSequnceNumber` 值
|
||||||
|
|
||||||
|
## 实施计划
|
||||||
|
|
||||||
|
### 实施步骤
|
||||||
|
|
||||||
|
1. **修改响应类**
|
||||||
|
- 在 `GetBankStatementResponse.BankStatementItem` 中添加 `uploadSequnceNumber` 字段
|
||||||
|
|
||||||
|
2. **修改实体转换**
|
||||||
|
- 在 `CcdiBankStatement.fromResponse()` 中添加字段映射
|
||||||
|
|
||||||
|
3. **测试验证**
|
||||||
|
- 调用流水分析接口,验证字段正确接收
|
||||||
|
- 检查数据库记录,确认 `batch_sequence` 字段正确存储
|
||||||
|
|
||||||
|
### 验收标准
|
||||||
|
|
||||||
|
- [ ] 响应类包含 `uploadSequnceNumber` 字段定义
|
||||||
|
- [ ] 转换方法正确映射字段
|
||||||
|
- [ ] 接口返回数据完整接收
|
||||||
|
- [ ] 数据库记录包含正确的上传序号值
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
**风险等级**:低
|
||||||
|
|
||||||
|
**潜在风险**:
|
||||||
|
- 接口返回的 `uploadSequnceNumber` 为 null 时,数据库存储 null 值
|
||||||
|
- 已通过数据库表定义验证:`batch_sequence` 允许 NULL 值
|
||||||
|
|
||||||
|
**缓解措施**:
|
||||||
|
- 代码中无需特殊处理,直接映射即可
|
||||||
|
- 如需默认值,可在业务逻辑层处理
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- 字段映射文档:`assets/对接流水分析/ccdi_bank_statement.md` 第 81 行
|
||||||
|
- 实体类定义:`CcdiBankStatement.java` 第 137 行
|
||||||
|
- 数据库表定义:`batch_sequence INT(11) NOT NULL`(实际允许存储 NULL,需核实)
|
||||||
257
docs/plans/2026-03-05-bank-statement-field-implementation.md
Normal file
257
docs/plans/2026-03-05-bank-statement-field-implementation.md
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
# 银行流水接口字段补充实施计划
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** 补充 `uploadSequnceNumber` 字段的接收和映射,确保流水分析接口返回的上传序号正确存储到数据库。
|
||||||
|
|
||||||
|
**Architecture:** 在响应类中添加字段定义接收接口返回值,在实体转换方法中映射到 `batchSequence` 字段,通过 MyBatis Plus 自动持久化到数据库的 `batch_sequence` 列。
|
||||||
|
|
||||||
|
**Tech Stack:** Java 21, Lombok, Spring Boot 3.5.8, MyBatis Plus
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: 响应类添加字段
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java:132`
|
||||||
|
|
||||||
|
**Step 1: 在 BankStatementItem 内部类中添加字段**
|
||||||
|
|
||||||
|
在 `batchId` 字段(第 132 行)之后添加:
|
||||||
|
|
||||||
|
```java
|
||||||
|
/** 上传序号 */
|
||||||
|
private Integer uploadSequnceNumber;
|
||||||
|
```
|
||||||
|
|
||||||
|
完整上下文:
|
||||||
|
|
||||||
|
```java
|
||||||
|
/** 上传logId */
|
||||||
|
private Integer batchId;
|
||||||
|
|
||||||
|
/** 上传序号 */
|
||||||
|
private Integer uploadSequnceNumber;
|
||||||
|
|
||||||
|
/** 项目id */
|
||||||
|
private Integer groupId;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 验证 Lombok 注解生效**
|
||||||
|
|
||||||
|
确认 `@Data` 注解在 `BankStatementItem` 类上,Lombok 会自动生成 getter/setter:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public static class BankStatementItem {
|
||||||
|
// ... 其他字段
|
||||||
|
private Integer batchId;
|
||||||
|
private Integer uploadSequnceNumber; // 新增字段
|
||||||
|
// ... 其他字段
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: 实体转换方法添加映射
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java:201`
|
||||||
|
|
||||||
|
**Step 1: 在 fromResponse() 方法中添加字段映射**
|
||||||
|
|
||||||
|
在第 201 行(`entity.setCustomerAccountName(item.getCustomerName());` 之后)添加:
|
||||||
|
|
||||||
|
```java
|
||||||
|
entity.setBatchSequence(item.getUploadSequnceNumber());
|
||||||
|
```
|
||||||
|
|
||||||
|
完整上下文:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 4. 手动映射字段名不一致的情况
|
||||||
|
entity.setLeAccountNo(item.getAccountMaskNo());
|
||||||
|
entity.setCustomerAccountNo(item.getCustomerAccountMaskNo());
|
||||||
|
entity.setLeAccountName(item.getLeName());
|
||||||
|
entity.setAmountDr(item.getDrAmount());
|
||||||
|
entity.setAmountCr(item.getCrAmount());
|
||||||
|
entity.setAmountBalance(item.getBalanceAmount());
|
||||||
|
entity.setTrxFlag(item.getTransFlag());
|
||||||
|
entity.setTrxType(item.getTransTypeId());
|
||||||
|
entity.setCustomerLeId(item.getCustomerId());
|
||||||
|
entity.setCustomerAccountName(item.getCustomerName());
|
||||||
|
entity.setBatchSequence(item.getUploadSequnceNumber()); // 新增映射
|
||||||
|
|
||||||
|
// 5. 特殊字段处理
|
||||||
|
entity.setMetaJson(null); // 根据文档要求强制设为 null
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 验证映射逻辑**
|
||||||
|
|
||||||
|
确认:
|
||||||
|
- 源字段:`item.getUploadSequnceNumber()` 返回 `Integer`
|
||||||
|
- 目标字段:`entity.setBatchSequence()` 接受 `Integer`
|
||||||
|
- 类型匹配,无需类型转换
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: 编译验证
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- 无文件修改
|
||||||
|
|
||||||
|
**Step 1: 编译项目**
|
||||||
|
|
||||||
|
在项目根目录执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn clean compile
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期输出:**
|
||||||
|
|
||||||
|
```
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
[INFO] Total time: X.XXX s
|
||||||
|
[INFO] Finished at: 2026-03-05T...
|
||||||
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 检查编译错误(如果有)**
|
||||||
|
|
||||||
|
如果出现编译错误,检查:
|
||||||
|
- 字段名拼写是否正确:`uploadSequnceNumber`(注意:Sequence 不是 Sequence)
|
||||||
|
- Lombok 注解处理器是否正确配置
|
||||||
|
- 导入语句是否需要补充(通常 Lombok 不需要额外导入)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: 代码审查
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- 无文件修改
|
||||||
|
|
||||||
|
**Step 1: 检查字段命名一致性**
|
||||||
|
|
||||||
|
对比文档 `assets/对接流水分析/ccdi_bank_statement.md:81`:
|
||||||
|
|
||||||
|
```
|
||||||
|
| 28 | batch_sequence | uploadSequnceNumber |
|
||||||
|
```
|
||||||
|
|
||||||
|
确认:
|
||||||
|
- 响应类字段名:`uploadSequnceNumber`(与文档一致)
|
||||||
|
- 实体类字段名:`batchSequence`(与数据库列名 `batch_sequence` 对应)
|
||||||
|
|
||||||
|
**Step 2: 检查空值处理**
|
||||||
|
|
||||||
|
确认 `Integer` 类型允许 null 值:
|
||||||
|
- 接口返回 null 时,`item.getUploadSequnceNumber()` 返回 null
|
||||||
|
- `entity.setBatchSequence(null)` 设置 null 值
|
||||||
|
- MyBatis Plus 将 null 写入数据库
|
||||||
|
|
||||||
|
**Step 3: 检查 BeanUtils.copyProperties 行为**
|
||||||
|
|
||||||
|
确认 `BeanUtils.copyProperties(item, entity)` 不会自动映射该字段:
|
||||||
|
- 源字段名:`uploadSequnceNumber`
|
||||||
|
- 目标字段名:`batchSequence`
|
||||||
|
- 字段名不一致,BeanUtils 不会自动复制
|
||||||
|
- 必须手动映射(已在 Task 2 添加)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 5: 提交代码
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- 无文件修改
|
||||||
|
|
||||||
|
**Step 1: 查看修改内容**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git diff
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期输出:**
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git a/ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java b/ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
index ...
|
||||||
|
--- a/ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
+++ b/ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
@@ -132,6 +132,9 @@ public class GetBankStatementResponse {
|
||||||
|
/** 上传logId */
|
||||||
|
private Integer batchId;
|
||||||
|
|
||||||
|
+ /** 上传序号 */
|
||||||
|
+ private Integer uploadSequnceNumber;
|
||||||
|
+
|
||||||
|
/** 项目id */
|
||||||
|
private Integer groupId;
|
||||||
|
|
||||||
|
diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java
|
||||||
|
index ...
|
||||||
|
--- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java
|
||||||
|
+++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java
|
||||||
|
@@ -199,6 +199,7 @@ public class CcdiBankStatement implements Serializable {
|
||||||
|
entity.setTrxType(item.getTransTypeId());
|
||||||
|
entity.setCustomerLeId(item.getCustomerId());
|
||||||
|
entity.setCustomerAccountName(item.getCustomerName());
|
||||||
|
+ entity.setBatchSequence(item.getUploadSequnceNumber());
|
||||||
|
|
||||||
|
// 5. 特殊字段处理
|
||||||
|
entity.setMetaJson(null); // 根据文档要求强制设为 null
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: 添加到暂存区**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java
|
||||||
|
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiBankStatement.java
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: 提交更改**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "fix: 补充银行流水接口 uploadSequnceNumber 字段接收和映射
|
||||||
|
|
||||||
|
- 在 GetBankStatementResponse.BankStatementItem 中添加 uploadSequnceNumber 字段
|
||||||
|
- 在 CcdiBankStatement.fromResponse() 中添加字段映射到 batchSequence
|
||||||
|
- 修复流水分析接口返回的上传序号数据丢失问题"
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期输出:**
|
||||||
|
|
||||||
|
```
|
||||||
|
[dev abc1234] fix: 补充银行流水接口 uploadSequnceNumber 字段接收和映射
|
||||||
|
2 files changed, 2 insertions(+)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收清单
|
||||||
|
|
||||||
|
- [ ] 响应类 `GetBankStatementResponse.BankStatementItem` 包含 `uploadSequnceNumber` 字段
|
||||||
|
- [ ] Lombok `@Data` 注解为该字段生成 getter/setter
|
||||||
|
- [ ] 实体转换方法 `fromResponse()` 包含 `batchSequence` 字段映射
|
||||||
|
- [ ] 项目编译成功(`mvn clean compile`)
|
||||||
|
- [ ] 字段命名与文档 `assets/对接流水分析/ccdi_bank_statement.md` 一致
|
||||||
|
- [ ] 代码已提交到 git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 后续验证(可选)
|
||||||
|
|
||||||
|
如需进一步验证功能,可以:
|
||||||
|
|
||||||
|
1. **接口测试**:调用流水分析接口,检查响应数据是否包含 `uploadSequnceNumber` 字段
|
||||||
|
2. **数据验证**:查询数据库 `ccdi_bank_statement` 表,检查 `batch_sequence` 列是否有正确的值
|
||||||
|
3. **日志检查**:在转换方法中添加日志,确认字段值正确传递
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- 设计文档:`docs/plans/2026-03-05-bank-statement-field-design.md`
|
||||||
|
- 字段映射文档:`assets/对接流水分析/ccdi_bank_statement.md`
|
||||||
|
- 接口文档:`assets/对接流水分析/兰溪-流水分析对接-新版.md`
|
||||||
259
docs/plans/2026-03-06-theme-light-default-design.md
Normal file
259
docs/plans/2026-03-06-theme-light-default-design.md
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
# 默认主题修改为浅色模式 - 设计文档
|
||||||
|
|
||||||
|
**日期:** 2026-03-06
|
||||||
|
**状态:** 已批准
|
||||||
|
**作者:** Claude Code
|
||||||
|
|
||||||
|
## 1. 概述
|
||||||
|
|
||||||
|
### 1.1 背景
|
||||||
|
|
||||||
|
当前系统默认使用深色模式侧边栏(`theme-dark`),需要将默认主题修改为浅色模式(`theme-light`)。
|
||||||
|
|
||||||
|
### 1.2 目标
|
||||||
|
|
||||||
|
- 将新用户的默认主题从深色模式改为浅色模式
|
||||||
|
- 保持老用户的自定义设置不受影响
|
||||||
|
- 确保主题切换功能完全正常
|
||||||
|
|
||||||
|
### 1.3 范围
|
||||||
|
|
||||||
|
- 仅修改前端默认配置
|
||||||
|
- 不涉及后端修改
|
||||||
|
- 不涉及数据库修改
|
||||||
|
|
||||||
|
## 2. 当前架构
|
||||||
|
|
||||||
|
### 2.1 主题配置层级
|
||||||
|
|
||||||
|
```
|
||||||
|
settings.js (默认配置)
|
||||||
|
↓
|
||||||
|
store/modules/settings.js (Vuex 状态管理)
|
||||||
|
↓
|
||||||
|
layout/components/Settings/index.vue (用户界面设置)
|
||||||
|
↓
|
||||||
|
localStorage (持久化用户设置)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 主题初始化逻辑
|
||||||
|
|
||||||
|
**文件:** `ruoyi-ui/src/store/modules/settings.js`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
||||||
|
const state = {
|
||||||
|
sideTheme: storageSetting.sideTheme || sideTheme, // localStorage 优先
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**逻辑:**
|
||||||
|
1. 从 `settings.js` 读取默认值
|
||||||
|
2. 检查 `localStorage` 是否有用户设置
|
||||||
|
3. 如果有用户设置,使用用户设置覆盖默认值
|
||||||
|
4. 如果没有用户设置,使用默认值
|
||||||
|
|
||||||
|
## 3. 设计方案
|
||||||
|
|
||||||
|
### 3.1 修改内容
|
||||||
|
|
||||||
|
**文件:** `ruoyi-ui/src/settings.js`
|
||||||
|
|
||||||
|
**变更:** 第 9 行
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 修改前
|
||||||
|
sideTheme: 'theme-dark',
|
||||||
|
|
||||||
|
// 修改后
|
||||||
|
sideTheme: 'theme-light',
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 数据流
|
||||||
|
|
||||||
|
#### 新用户首次访问
|
||||||
|
|
||||||
|
```
|
||||||
|
用户访问系统
|
||||||
|
↓
|
||||||
|
store/modules/settings.js 初始化
|
||||||
|
↓
|
||||||
|
读取 settings.js: sideTheme = 'theme-light'
|
||||||
|
↓
|
||||||
|
检查 localStorage: 为空
|
||||||
|
↓
|
||||||
|
使用默认值: 'theme-light'
|
||||||
|
↓
|
||||||
|
渲染浅色模式侧边栏
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 老用户访问(已保存设置)
|
||||||
|
|
||||||
|
```
|
||||||
|
用户访问系统
|
||||||
|
↓
|
||||||
|
store/modules/settings.js 初始化
|
||||||
|
↓
|
||||||
|
读取 settings.js: sideTheme = 'theme-light'
|
||||||
|
↓
|
||||||
|
检查 localStorage: 有值 { sideTheme: 'theme-dark' }
|
||||||
|
↓
|
||||||
|
使用 localStorage 中的值: 'theme-dark'
|
||||||
|
↓
|
||||||
|
渲染深色模式侧边栏(保持用户设置)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 兼容性
|
||||||
|
|
||||||
|
**向后兼容:**
|
||||||
|
- ✅ 老用户的 localStorage 设置不受影响
|
||||||
|
- ✅ 老用户看到的主题与之前一致
|
||||||
|
|
||||||
|
**向前兼容:**
|
||||||
|
- ✅ 新用户默认看到浅色模式
|
||||||
|
- ✅ 用户仍可自由切换主题
|
||||||
|
- ✅ 保存/重置功能完全正常
|
||||||
|
|
||||||
|
## 4. 影响分析
|
||||||
|
|
||||||
|
### 4.1 影响范围
|
||||||
|
|
||||||
|
**文件变更:**
|
||||||
|
- `ruoyi-ui/src/settings.js`(1 行代码)
|
||||||
|
|
||||||
|
**功能影响:**
|
||||||
|
- ✅ 无功能变更
|
||||||
|
- ✅ 无接口变更
|
||||||
|
- ✅ 无数据结构变更
|
||||||
|
|
||||||
|
### 4.2 用户体验影响
|
||||||
|
|
||||||
|
**新用户:**
|
||||||
|
- 从深色模式默认值 → 浅色模式默认值
|
||||||
|
|
||||||
|
**老用户:**
|
||||||
|
- 无影响(localStorage 中的设置优先)
|
||||||
|
|
||||||
|
## 5. 测试计划
|
||||||
|
|
||||||
|
### 5.1 测试用例
|
||||||
|
|
||||||
|
| 测试场景 | 操作步骤 | 预期结果 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| 新用户首次访问 | 1. 清除 localStorage<br>2. 刷新页面 | 侧边栏为浅色模式 |
|
||||||
|
| 老用户(深色模式) | 1. localStorage 保存深色模式<br>2. 刷新页面 | 侧边栏仍为深色模式 |
|
||||||
|
| 老用户(浅色模式) | 1. localStorage 保存浅色模式<br>2. 刷新页面 | 侧边栏仍为浅色模式 |
|
||||||
|
| 切换主题 | 1. 打开设置抽屉<br>2. 点击深色/浅色图标 | 侧边栏立即切换 |
|
||||||
|
| 保存设置 | 1. 切换主题<br>2. 点击"保存配置"<br>3. 刷新页面 | 设置保持不变 |
|
||||||
|
| 重置设置 | 1. 修改多个设置<br>2. 点击"重置配置" | 恢复为默认值(浅色模式) |
|
||||||
|
|
||||||
|
### 5.2 浏览器兼容性
|
||||||
|
|
||||||
|
测试浏览器:
|
||||||
|
- ✅ Chrome (最新版)
|
||||||
|
- ✅ Firefox (最新版)
|
||||||
|
- ✅ Edge (最新版)
|
||||||
|
- ✅ Safari (最新版)
|
||||||
|
|
||||||
|
## 6. 部署方案
|
||||||
|
|
||||||
|
### 6.1 部署步骤
|
||||||
|
|
||||||
|
1. **修改代码**
|
||||||
|
```bash
|
||||||
|
# 修改 ruoyi-ui/src/settings.js
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **提交代码**
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/settings.js
|
||||||
|
git commit -m "feat: 将默认主题修改为浅色模式"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **构建前端**
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **部署静态资源**
|
||||||
|
- 将 `ruoyi-ui/dist/` 目录部署到生产服务器
|
||||||
|
|
||||||
|
5. **验证部署**
|
||||||
|
- 清除浏览器缓存
|
||||||
|
- 访问系统
|
||||||
|
- 验证新用户看到浅色模式
|
||||||
|
|
||||||
|
### 6.2 回滚方案
|
||||||
|
|
||||||
|
如果发现问题,可快速回滚:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// settings.js 第 9 行
|
||||||
|
sideTheme: 'theme-dark', // 改回深色模式
|
||||||
|
```
|
||||||
|
|
||||||
|
然后重新构建和部署。
|
||||||
|
|
||||||
|
## 7. 风险评估
|
||||||
|
|
||||||
|
### 7.1 风险列表
|
||||||
|
|
||||||
|
| 风险 | 概率 | 影响 | 缓解措施 |
|
||||||
|
|-----|------|------|---------|
|
||||||
|
| 老用户困惑 | 低 | 低 | 老用户设置不受影响 |
|
||||||
|
| 浅色模式样式问题 | 低 | 中 | 需要充分测试 |
|
||||||
|
| 部署失败 | 低 | 高 | 准备回滚方案 |
|
||||||
|
|
||||||
|
### 7.2 总体风险
|
||||||
|
|
||||||
|
**风险等级:** 低
|
||||||
|
|
||||||
|
**理由:**
|
||||||
|
- 仅修改一行配置代码
|
||||||
|
- 不影响老用户设置
|
||||||
|
- 可以快速回滚
|
||||||
|
|
||||||
|
## 8. 验收标准
|
||||||
|
|
||||||
|
### 8.1 功能验收
|
||||||
|
|
||||||
|
- ✅ 新用户首次访问看到浅色模式侧边栏
|
||||||
|
- ✅ 老用户的自定义主题设置保持不变
|
||||||
|
- ✅ 主题切换功能正常
|
||||||
|
- ✅ 主题保存功能正常
|
||||||
|
- ✅ 主题重置功能正常
|
||||||
|
|
||||||
|
### 8.2 质量验收
|
||||||
|
|
||||||
|
- ✅ 代码审查通过
|
||||||
|
- ✅ 测试用例全部通过
|
||||||
|
- ✅ 无控制台错误
|
||||||
|
- ✅ 浏览器兼容性测试通过
|
||||||
|
|
||||||
|
## 9. 后续优化建议
|
||||||
|
|
||||||
|
### 9.1 短期优化
|
||||||
|
|
||||||
|
- 可以考虑在设置界面添加"推荐"标签,标注浅色模式
|
||||||
|
- 可以考虑在首次登录时提示用户可以自定义主题
|
||||||
|
|
||||||
|
### 9.2 长期优化
|
||||||
|
|
||||||
|
- 可以考虑添加更多预设主题(护眼模式、高对比度模式等)
|
||||||
|
- 可以考虑将主题设置保存到后端数据库,实现跨设备同步
|
||||||
|
|
||||||
|
## 10. 附录
|
||||||
|
|
||||||
|
### 10.1 相关文件
|
||||||
|
|
||||||
|
- `ruoyi-ui/src/settings.js` - 默认配置文件
|
||||||
|
- `ruoyi-ui/src/store/modules/settings.js` - Vuex 状态管理
|
||||||
|
- `ruoyi-ui/src/layout/components/Settings/index.vue` - 设置界面组件
|
||||||
|
- `ruoyi-ui/src/components/ThemePicker/index.vue` - 主题颜色选择器
|
||||||
|
|
||||||
|
### 10.2 参考资料
|
||||||
|
|
||||||
|
- [Element UI 主题定制](https://element.eleme.cn/#/zh-CN/theme)
|
||||||
|
- [Vuex 状态管理](https://vuex.vuejs.org/zh/)
|
||||||
304
docs/plans/2026-03-06-theme-light-default.md
Normal file
304
docs/plans/2026-03-06-theme-light-default.md
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
# 默认主题修改为浅色模式 - 实施计划
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**目标:** 将前端默认主题从深色模式改为浅色模式,新用户首次访问时看到浅色侧边栏
|
||||||
|
|
||||||
|
**架构:** 修改 `settings.js` 中的默认配置,Vuex store 会自动读取该配置并应用到界面
|
||||||
|
|
||||||
|
**技术栈:** Vue.js 2.6, Vuex 3.6, Element UI 2.15
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: 修改默认主题配置
|
||||||
|
|
||||||
|
**文件:**
|
||||||
|
- Modify: `ruoyi-ui/src/settings.js:10`(修改第 10 行)
|
||||||
|
|
||||||
|
### Step 1: 读取当前配置文件
|
||||||
|
|
||||||
|
**操作:** 使用 Read 工具读取文件
|
||||||
|
|
||||||
|
```
|
||||||
|
Read: ruoyi-ui/src/settings.js
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期结果:** 看到第 10 行为 `sideTheme: 'theme-dark',`
|
||||||
|
|
||||||
|
### Step 2: 修改默认主题为浅色模式
|
||||||
|
|
||||||
|
**操作:** 使用 Edit 工具修改配置
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 修改 ruoyi-ui/src/settings.js 第 10 行
|
||||||
|
// 修改前:
|
||||||
|
sideTheme: 'theme-dark',
|
||||||
|
|
||||||
|
// 修改后:
|
||||||
|
sideTheme: 'theme-light',
|
||||||
|
```
|
||||||
|
|
||||||
|
**完整代码:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* 网页标题
|
||||||
|
*/
|
||||||
|
title: process.env.VUE_APP_TITLE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
|
*/
|
||||||
|
sideTheme: 'theme-light',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统布局配置
|
||||||
|
*/
|
||||||
|
showSettings: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
|
||||||
|
*/
|
||||||
|
navType: 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示 tagsView
|
||||||
|
*/
|
||||||
|
tagsView: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示页签图标
|
||||||
|
*/
|
||||||
|
tagsIcon: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否固定头部
|
||||||
|
*/
|
||||||
|
fixedHeader: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示logo
|
||||||
|
*/
|
||||||
|
sidebarLogo: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示动态标题
|
||||||
|
*/
|
||||||
|
dynamicTitle: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示底部版权
|
||||||
|
*/
|
||||||
|
footerVisible: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底部版权文本内容
|
||||||
|
*/
|
||||||
|
footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: 提交代码变更
|
||||||
|
|
||||||
|
**命令:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/settings.js
|
||||||
|
git commit -m "feat: 将默认主题修改为浅色模式
|
||||||
|
|
||||||
|
- 修改 settings.js 中 sideTheme 默认值从 'theme-dark' 改为 'theme-light'
|
||||||
|
- 新用户首次访问时将看到浅色模式侧边栏
|
||||||
|
- 老用户的自定义设置不受影响(localStorage 优先)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期结果:** Git 提交成功
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: 手动测试验证
|
||||||
|
|
||||||
|
**说明:** 此任务需要手动在浏览器中测试,无法自动化
|
||||||
|
|
||||||
|
### Step 1: 启动前端开发服务器
|
||||||
|
|
||||||
|
**命令:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期结果:** 前端服务启动在 http://localhost:80
|
||||||
|
|
||||||
|
### Step 2: 测试新用户体验
|
||||||
|
|
||||||
|
**操作步骤:**
|
||||||
|
|
||||||
|
1. 打开浏览器开发者工具(F12)
|
||||||
|
2. 进入 Application/应用 标签
|
||||||
|
3. 在左侧找到 Local Storage
|
||||||
|
4. 删除所有 `layout-setting` 相关的存储项
|
||||||
|
5. 刷新页面(Ctrl+F5 强制刷新)
|
||||||
|
|
||||||
|
**预期结果:**
|
||||||
|
- 侧边栏为浅色模式(白色背景,深色文字)
|
||||||
|
- 侧边栏 Logo 区域为浅色
|
||||||
|
- 菜单项为深色文字
|
||||||
|
|
||||||
|
### Step 3: 测试老用户体验(深色模式)
|
||||||
|
|
||||||
|
**操作步骤:**
|
||||||
|
|
||||||
|
1. 打开浏览器开发者工具(F12)
|
||||||
|
2. 进入 Application/应用 标签
|
||||||
|
3. 在 Local Storage 中添加/修改 `layout-setting`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"sideTheme": "theme-dark",
|
||||||
|
"theme": "#409EFF"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
4. 刷新页面(Ctrl+F5 强制刷新)
|
||||||
|
|
||||||
|
**预期结果:**
|
||||||
|
- 侧边栏为深色模式(深色背景,浅色文字)
|
||||||
|
- 老用户的设置被保留
|
||||||
|
|
||||||
|
### Step 4: 测试主题切换功能
|
||||||
|
|
||||||
|
**操作步骤:**
|
||||||
|
|
||||||
|
1. 登录系统
|
||||||
|
2. 点击右上角设置图标(齿轮图标)
|
||||||
|
3. 在右侧抽屉中找到"主题风格设置"
|
||||||
|
4. 点击深色模式图标
|
||||||
|
5. 观察侧边栏变化
|
||||||
|
|
||||||
|
**预期结果:**
|
||||||
|
- 侧边栏立即切换为深色模式
|
||||||
|
- 菜单颜色变为浅色文字
|
||||||
|
|
||||||
|
### Step 5: 测试主题保存功能
|
||||||
|
|
||||||
|
**操作步骤:**
|
||||||
|
|
||||||
|
1. 在设置抽屉中切换为深色模式
|
||||||
|
2. 点击底部的"保存配置"按钮
|
||||||
|
3. 等待提示"正在保存到本地"
|
||||||
|
4. 刷新页面(F5)
|
||||||
|
|
||||||
|
**预期结果:**
|
||||||
|
- 刷新后侧边栏仍为深色模式
|
||||||
|
- localStorage 中保存了 `layout-setting` 数据
|
||||||
|
|
||||||
|
### Step 6: 测试主题重置功能
|
||||||
|
|
||||||
|
**操作步骤:**
|
||||||
|
|
||||||
|
1. 在设置抽屉中切换为深色模式并保存
|
||||||
|
2. 点击底部的"重置配置"按钮
|
||||||
|
3. 等待页面自动刷新
|
||||||
|
|
||||||
|
**预期结果:**
|
||||||
|
- 页面自动刷新
|
||||||
|
- 侧边栏恢复为浅色模式(默认值)
|
||||||
|
- localStorage 中的 `layout-setting` 被清除
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: 更新项目文档(可选)
|
||||||
|
|
||||||
|
**文件:**
|
||||||
|
- Modify: `CLAUDE.md` 或 `README.md`(如果有主题相关的说明)
|
||||||
|
|
||||||
|
### Step 1: 更新 CLAUDE.md 中的主题说明
|
||||||
|
|
||||||
|
**操作:** 检查 CLAUDE.md 中是否有关于默认主题的说明,如果有则更新
|
||||||
|
|
||||||
|
**修改位置:** 如果文档中提到"默认深色模式",需要更新为"默认浅色模式"
|
||||||
|
|
||||||
|
### Step 2: 提交文档更新
|
||||||
|
|
||||||
|
**命令:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CLAUDE.md
|
||||||
|
git commit -m "docs: 更新文档中的默认主题说明"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收清单
|
||||||
|
|
||||||
|
在完成所有任务后,请验证以下内容:
|
||||||
|
|
||||||
|
- [ ] `ruoyi-ui/src/settings.js` 中 `sideTheme` 值为 `'theme-light'`
|
||||||
|
- [ ] 新用户首次访问看到浅色模式侧边栏
|
||||||
|
- [ ] 老用户的深色模式设置被保留
|
||||||
|
- [ ] 主题切换功能正常(深色 ↔ 浅色)
|
||||||
|
- [ ] 主题保存功能正常(保存到 localStorage)
|
||||||
|
- [ ] 主题重置功能正常(恢复为浅色模式)
|
||||||
|
- [ ] 浏览器控制台无错误信息
|
||||||
|
- [ ] 代码已提交到 Git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 回滚方案
|
||||||
|
|
||||||
|
如果发现问题需要回滚:
|
||||||
|
|
||||||
|
### 回滚步骤
|
||||||
|
|
||||||
|
**命令:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git revert <commit-hash>
|
||||||
|
```
|
||||||
|
|
||||||
|
或手动修改 `ruoyi-ui/src/settings.js`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
sideTheme: 'theme-dark', // 改回深色模式
|
||||||
|
```
|
||||||
|
|
||||||
|
然后重新构建:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 部署说明
|
||||||
|
|
||||||
|
### 开发环境
|
||||||
|
|
||||||
|
无需额外操作,修改后自动生效(热更新)
|
||||||
|
|
||||||
|
### 生产环境
|
||||||
|
|
||||||
|
1. 构建前端:
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 部署 `ruoyi-ui/dist/` 目录到生产服务器
|
||||||
|
|
||||||
|
3. 用户刷新浏览器即可看到效果
|
||||||
|
|
||||||
|
**注意:**
|
||||||
|
- 不需要重启后端服务
|
||||||
|
- 不需要清理数据库
|
||||||
|
- 不需要用户做任何操作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `ruoyi-ui/src/settings.js` - 默认配置文件(本次修改)
|
||||||
|
- `ruoyi-ui/src/store/modules/settings.js` - Vuex 状态管理(无需修改)
|
||||||
|
- `ruoyi-ui/src/layout/components/Settings/index.vue` - 设置界面(无需修改)
|
||||||
|
- `docs/plans/2026-03-06-theme-light-default-design.md` - 设计文档
|
||||||
@@ -6,7 +6,7 @@ ruoyi:
|
|||||||
|
|
||||||
server:
|
server:
|
||||||
# 服务器的HTTP端口,默认为8080
|
# 服务器的HTTP端口,默认为8080
|
||||||
port: 8080
|
port: 62318
|
||||||
servlet:
|
servlet:
|
||||||
# 应用的访问路径
|
# 应用的访问路径
|
||||||
context-path: /
|
context-path: /
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
*/
|
*/
|
||||||
sideTheme: 'theme-dark',
|
sideTheme: 'theme-light',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统布局配置
|
* 系统布局配置
|
||||||
|
|||||||
@@ -46,49 +46,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 统计卡片区域 -->
|
|
||||||
<div class="statistics-section">
|
|
||||||
<div class="stat-card" @click="handleStatusFilter('uploading')">
|
|
||||||
<div class="stat-icon uploading">
|
|
||||||
<i class="el-icon-upload"></i>
|
|
||||||
</div>
|
|
||||||
<div class="stat-content">
|
|
||||||
<div class="stat-label">上传中</div>
|
|
||||||
<div class="stat-value">{{ statistics.uploading }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card" @click="handleStatusFilter('parsing')">
|
|
||||||
<div class="stat-icon parsing">
|
|
||||||
<i class="el-icon-loading"></i>
|
|
||||||
</div>
|
|
||||||
<div class="stat-content">
|
|
||||||
<div class="stat-label">解析中</div>
|
|
||||||
<div class="stat-value">{{ statistics.parsing }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card" @click="handleStatusFilter('parsed_success')">
|
|
||||||
<div class="stat-icon success">
|
|
||||||
<i class="el-icon-success"></i>
|
|
||||||
</div>
|
|
||||||
<div class="stat-content">
|
|
||||||
<div class="stat-label">解析成功</div>
|
|
||||||
<div class="stat-value">{{ statistics.parsed_success }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card" @click="handleStatusFilter('parsed_failed')">
|
|
||||||
<div class="stat-icon failed">
|
|
||||||
<i class="el-icon-error"></i>
|
|
||||||
</div>
|
|
||||||
<div class="stat-content">
|
|
||||||
<div class="stat-label">解析失败</div>
|
|
||||||
<div class="stat-value">{{ statistics.parsed_failed }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 文件上传记录列表 -->
|
<!-- 文件上传记录列表 -->
|
||||||
<div class="file-list-section">
|
<div class="file-list-section">
|
||||||
<div class="list-toolbar">
|
<div class="list-toolbar">
|
||||||
@@ -129,7 +86,11 @@
|
|||||||
{{ scope.row.enterpriseNames || '-' }}
|
{{ scope.row.enterpriseNames || '-' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="uploadTime" label="上传时间" width="160"></el-table-column>
|
<el-table-column prop="uploadTime" label="上传时间" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ formatUploadTime(scope.row.uploadTime) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="uploadUser" label="上传人" width="100"></el-table-column>
|
<el-table-column prop="uploadUser" label="上传人" width="100"></el-table-column>
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@@ -240,7 +201,6 @@
|
|||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
accept=".pdf,.csv,.xlsx,.xls"
|
|
||||||
|
|
||||||
<!-- 名单选择弹窗 -->
|
<!-- 名单选择弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
@@ -342,6 +302,7 @@ import {
|
|||||||
getFileUploadList,
|
getFileUploadList,
|
||||||
getFileUploadStatistics,
|
getFileUploadStatistics,
|
||||||
} from "@/api/ccdiProjectUpload";
|
} from "@/api/ccdiProjectUpload";
|
||||||
|
import { parseTime } from "@/utils/ruoyi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "UploadData",
|
name: "UploadData",
|
||||||
@@ -987,13 +948,6 @@ export default {
|
|||||||
|
|
||||||
// === 辅助方法 ===
|
// === 辅助方法 ===
|
||||||
|
|
||||||
/** 状态筛选 */
|
|
||||||
handleStatusFilter(status) {
|
|
||||||
this.queryParams.fileStatus = status;
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.loadFileList();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 分页变化 */
|
/** 分页变化 */
|
||||||
handlePageChange(pageNum) {
|
handlePageChange(pageNum) {
|
||||||
this.queryParams.pageNum = pageNum;
|
this.queryParams.pageNum = pageNum;
|
||||||
@@ -1047,6 +1001,11 @@ export default {
|
|||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
||||||
},
|
},
|
||||||
|
/** 格式化上传时间 */
|
||||||
|
formatUploadTime(time) {
|
||||||
|
const formatted = parseTime(time, "{y}-{m}-{d} {h}:{i}:{s}");
|
||||||
|
return formatted || "-";
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -1322,77 +1281,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统计卡片区域
|
|
||||||
.statistics-section {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 16px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 16px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-icon {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 24px;
|
|
||||||
|
|
||||||
&.uploading {
|
|
||||||
background: rgba(64, 158, 255, 0.1);
|
|
||||||
color: #409eff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.parsing {
|
|
||||||
background: rgba(230, 162, 60, 0.1);
|
|
||||||
color: #e6a23c;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.success {
|
|
||||||
background: rgba(103, 194, 58, 0.1);
|
|
||||||
color: #67c23a;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.failed {
|
|
||||||
background: rgba(245, 108, 108, 0.1);
|
|
||||||
color: #f56c6c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-content {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.stat-label {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #909399;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文件列表区域
|
// 文件列表区域
|
||||||
.file-list-section {
|
.file-list-section {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -1523,9 +1411,6 @@ export default {
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics-section {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
@@ -1551,10 +1436,6 @@ export default {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics-section {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-list-section .list-toolbar {
|
.file-list-section .list-toolbar {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ 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";
|
||||||
|
import {getProject} from "@/api/ccdiProject";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectDetail",
|
name: "ProjectDetail",
|
||||||
@@ -99,19 +100,77 @@ export default {
|
|||||||
if (newId) {
|
if (newId) {
|
||||||
this.projectId = newId;
|
this.projectId = newId;
|
||||||
this.projectInfo.projectId = newId;
|
this.projectInfo.projectId = newId;
|
||||||
|
this.initActiveTabFromRoute();
|
||||||
this.initPageData();
|
this.initPageData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"$route.query.tab"() {
|
||||||
|
this.initActiveTabFromRoute();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 初始化页面数据
|
// 初始化页面数据
|
||||||
|
this.initActiveTabFromRoute();
|
||||||
this.initPageData();
|
this.initPageData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initActiveTabFromRoute() {
|
||||||
|
const tab = (this.$route.query && this.$route.query.tab) || "";
|
||||||
|
const validTabs = ["upload", "config", "overview", "special", "detail"];
|
||||||
|
const targetTab = validTabs.includes(tab) ? tab : "upload";
|
||||||
|
this.setActiveTab(targetTab);
|
||||||
|
},
|
||||||
|
setActiveTab(index) {
|
||||||
|
this.activeTab = index;
|
||||||
|
const componentMap = {
|
||||||
|
upload: "UploadData",
|
||||||
|
config: "ParamConfig",
|
||||||
|
overview: "PreliminaryCheck",
|
||||||
|
special: "SpecialCheck",
|
||||||
|
detail: "DetailQuery",
|
||||||
|
};
|
||||||
|
this.currentComponent = componentMap[index] || "UploadData";
|
||||||
|
},
|
||||||
/** 初始化页面数据 */
|
/** 初始化页面数据 */
|
||||||
initPageData() {
|
initPageData() {
|
||||||
// 这里应该从API获取项目详细信息
|
// 这里应该从API获取项目详细信息
|
||||||
this.mockProjectInfo();
|
if (!this.projectId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.projectInfo.projectName = "";
|
||||||
|
this.updatePageTitle();
|
||||||
|
getProject(this.projectId)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data || {};
|
||||||
|
this.projectInfo = {
|
||||||
|
...this.projectInfo,
|
||||||
|
...data,
|
||||||
|
projectId: data.projectId || this.projectId,
|
||||||
|
projectName: data.projectName || "",
|
||||||
|
projectDesc: data.projectDesc || data.description || "",
|
||||||
|
projectStatus: String(
|
||||||
|
data.projectStatus !== undefined && data.projectStatus !== null
|
||||||
|
? data.projectStatus
|
||||||
|
: data.status !== undefined && data.status !== null
|
||||||
|
? data.status
|
||||||
|
: this.projectInfo.projectStatus
|
||||||
|
),
|
||||||
|
};
|
||||||
|
this.updatePageTitle();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$message.error("Failed to load project details");
|
||||||
|
this.updatePageTitle();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updatePageTitle() {
|
||||||
|
const title = this.projectInfo.projectName || `ProjectDetail-${this.projectId}`;
|
||||||
|
this.$route.meta.title = title;
|
||||||
|
this.$store.dispatch("settings/setTitle", title);
|
||||||
|
this.$store.dispatch("tagsView/updateVisitedView", {
|
||||||
|
path: this.$route.path,
|
||||||
|
title,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
/** 格式化更新时间 */
|
/** 格式化更新时间 */
|
||||||
formatUpdateTime(time) {
|
formatUpdateTime(time) {
|
||||||
@@ -171,18 +230,7 @@ export default {
|
|||||||
/** 菜单选择事件 */
|
/** 菜单选择事件 */
|
||||||
handleMenuSelect(index) {
|
handleMenuSelect(index) {
|
||||||
console.log("菜单选择:", index);
|
console.log("菜单选择:", index);
|
||||||
this.activeTab = index;
|
this.setActiveTab(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 }) {
|
||||||
@@ -217,7 +265,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 刷新页面 */
|
/** 刷新页面 */
|
||||||
handleRefresh() {
|
handleRefresh() {
|
||||||
this.mockProjectInfo();
|
this.initPageData();
|
||||||
this.$message.success("刷新成功");
|
this.$message.success("刷新成功");
|
||||||
},
|
},
|
||||||
/** 导出报告 */
|
/** 导出报告 */
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {listProject, getStatusCounts} from '@/api/ccdiProject'
|
import {getStatusCounts, listProject} from '@/api/ccdiProject'
|
||||||
import SearchBar from './components/SearchBar'
|
import SearchBar from './components/SearchBar'
|
||||||
import ProjectTable from './components/ProjectTable'
|
import ProjectTable from './components/ProjectTable'
|
||||||
import QuickEntry from './components/QuickEntry'
|
import QuickEntry from './components/QuickEntry'
|
||||||
@@ -234,8 +234,10 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 查看结果 */
|
/** 查看结果 */
|
||||||
handleViewResult(row) {
|
handleViewResult(row) {
|
||||||
console.log("查看结果:", row);
|
this.$router.push({
|
||||||
this.$modal.msgInfo("查看项目结果: " + row.projectName);
|
path: `/ccdiProject/detail/${row.projectId}`,
|
||||||
|
query: { tab: "overview" },
|
||||||
|
});
|
||||||
},
|
},
|
||||||
/** 重新分析 */
|
/** 重新分析 */
|
||||||
handleReAnalyze(row) {
|
handleReAnalyze(row) {
|
||||||
@@ -262,7 +264,7 @@ export default {
|
|||||||
.dpc-project-container {
|
.dpc-project-container {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
background: #F8F9FA;
|
background: #F8F9FA;
|
||||||
min-height: calc(100vh - 140px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const CompressionPlugin = require('compression-webpack-plugin')
|
|||||||
|
|
||||||
const name = process.env.VUE_APP_TITLE || '纪检初核系统' // 网页标题
|
const name = process.env.VUE_APP_TITLE || '纪检初核系统' // 网页标题
|
||||||
|
|
||||||
const baseUrl = 'http://localhost:8080' // 后端接口
|
const baseUrl = 'http://localhost:62318' // 后端接口
|
||||||
|
|
||||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user