Initial commit
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
13
.idea/compiler.xml
generated
Normal file
13
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<module name="svn-log-tool" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/svn-log-tool/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/svn-log-tool/src/main/resources" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
20
.idea/jarRepositories.xml
generated
Normal file
20
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Central Repository" />
|
||||||
|
<option name="url" value="https://maven.aliyun.com/repository/central" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
26
.idea/misc.xml
generated
Normal file
26
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="KubernetesApiProvider"><![CDATA[{}]]></component>
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/svn-log-tool/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||||
|
<entry key="Project Default">
|
||||||
|
<profile-state>
|
||||||
|
<selected-state>
|
||||||
|
<State>
|
||||||
|
<id>用户定义</id>
|
||||||
|
</State>
|
||||||
|
</selected-state>
|
||||||
|
</profile-state>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/日志.iml" filepath="$PROJECT_DIR$/.idea/日志.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/日志.iml
generated
Normal file
9
.idea/日志.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
1
.iflow/settings.json
Normal file
1
.iflow/settings.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"mcpServers": {"context7": {"command": "npx", "args": ["-y", "@iflow-mcp/context7-mcp@1.0.0"]}, "excel-edit-server": {"command": "uvx", "args": ["--python", "3.12.q7", "iflow-mcp_excel-edit-server@latest", "--workspace-path", "."]}}}
|
||||||
BIN
202601工作量统计_刘靖.xlsx
Normal file
BIN
202601工作量统计_刘靖.xlsx
Normal file
Binary file not shown.
467
md/svn_log_PRS-7050场站智慧管控_20260130_102309.md
Normal file
467
md/svn_log_PRS-7050场站智慧管控_20260130_102309.md
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
|
||||||
|
- **SVN地址**: `https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7050场站智慧管控/01_开发库/V1.00/src_java`
|
||||||
|
- **版本范围**: r249400 - r249935
|
||||||
|
- **过滤用户**: `liujing2`
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r249935
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-27 17:33:43
|
||||||
|
**版本**: r249935
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(utils): 修复导入到处相机用途异常问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249934
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-27 17:17:22
|
||||||
|
**版本**: r249934
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(initStatus): 优化设备状态检测定时任务实现,修复启动mould启动慢的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249929
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-27 16:27:10
|
||||||
|
**版本**: r249929
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(pipeline): 修复点位导入超时问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249843
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-23 17:08:29
|
||||||
|
**版本**: r249843
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(pipeline): 修复设备点流水线中的依赖注入问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249841
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-23 15:19:46
|
||||||
|
**版本**: r249841
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(pipeline): 导入更新不处理syscode
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249830
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-22 15:56:11
|
||||||
|
**版本**: r249830
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent-helper): 过滤掉空名称条目避免空指针异常
|
||||||
|
|
||||||
|
- 对站点名称列表增加非空过滤确保stationName不为null
|
||||||
|
- 对组件名称列表增加非空过滤确保componentName不为null
|
||||||
|
- 对监控类型列表增加非空过滤确保sceneType不为null
|
||||||
|
- 对缺陷类型列表增加非空过滤确保defectDesc不为null
|
||||||
|
- 对设备类型字典增加非空过滤确保dictDesc不为null
|
||||||
|
- 优化各类映射生成的稳定性和正确性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249811
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-21 15:02:55
|
||||||
|
**版本**: r249811
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(monitor): 遥控配置获取结合平台接口,修复控制服务pom.xml依赖异常问题
|
||||||
|
|
||||||
|
- 添加 YKOperateService 依赖注入到 FullViewMonitorController
|
||||||
|
- 集成 YKDictateOperateVo 响应对象用于遥控信息查询
|
||||||
|
- 在获取控制类信号配置时调用遥控服务验证并设置操作类型
|
||||||
|
- 添加 sunri-service-control-spi 依赖到 cygbusiness-model 模块
|
||||||
|
- 添加 sunri-service-control-yk 依赖到 control-starter 模块
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249802
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-20 16:40:39
|
||||||
|
**版本**: r249802
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024版本244507 fix(linkage-task):手动处理瀚高数据库更新后顺序改变的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249797
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-20 16:06:19
|
||||||
|
**版本**: r249797
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(pom): 调整模块顺序并更新模块名称
|
||||||
|
|
||||||
|
- 将 sunri-mybatisplus-starter 模块重命名为 04_sunri-mybatisplus-starter
|
||||||
|
- 将 sunri-rds-migration 模块重命名为 11_sunri-rds-migration
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249795
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-20 14:45:27
|
||||||
|
**版本**: r249795
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244546版本
|
||||||
|
优化 MyBatis 映射文件中的 SQL 语句
|
||||||
|
|
||||||
|
- 移除了多处 SQL 语句中不必要的反引号
|
||||||
|
- 统一了表名和字段名的命名风格
|
||||||
|
- 提高了 SQL语句的可读性和一致性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249794
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-20 14:40:14
|
||||||
|
**版本**: r249794
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244398版本 处理动态SQL包含问号的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249793
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-20 14:22:25
|
||||||
|
**版本**: r249793
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244359版本处理mysql函数last_insert_id()在瀚高报错的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249764
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 17:59:22
|
||||||
|
**版本**: r249764
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent): 同步2024的243464
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249763
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 17:51:03
|
||||||
|
**版本**: r249763
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent): 同步2024的243573
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249756
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 16:22:57
|
||||||
|
**版本**: r249756
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
默认取二次设备协议
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249754
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 15:38:01
|
||||||
|
**版本**: r249754
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
依赖异常修复
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249752
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 14:52:04
|
||||||
|
**版本**: r249752
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
移除单体项目
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249751
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 14:51:04
|
||||||
|
**版本**: r249751
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
删除私有仓库10.1.105.49:8081
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249748
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-19 14:36:25
|
||||||
|
**版本**: r249748
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
删除私有仓库10.1.105.49:8081
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249654
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-14 16:25:54
|
||||||
|
**版本**: r249654
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent): 简化设备类型处理逻辑
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249652
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-14 16:22:33
|
||||||
|
**版本**: r249652
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(service): 静默支持机器人和无人机设备类型
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249632
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-13 11:47:19
|
||||||
|
**版本**: r249632
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(scheduler): 现场新需求:不同的设备类型任务可以同时执行巡视任务核心类提交
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249631
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-13 11:28:10
|
||||||
|
**版本**: r249631
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(scheduler): 现场新需求:不同的设备类型任务可以同时执行巡视任务配置提交
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249628
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-13 10:30:56
|
||||||
|
**版本**: r249628
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(patrol): 现场需求需要下发重复任务名不同编码任务 删除名称重复校验
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249626
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-13 09:54:49
|
||||||
|
**版本**: r249626
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(client): 修复 ThriftProxyClient 连接协议初始化问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249541
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-09 16:42:19
|
||||||
|
**版本**: r249541
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(devops-patrol): 优化超期逻辑
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249539
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-09 15:55:13
|
||||||
|
**版本**: r249539
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(devops-patrol): 调整任务超期时间
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249412
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 17:08:07
|
||||||
|
**版本**: r249412
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(websocket): 根据连接协议支持ws和wss启动UE进程
|
||||||
|
|
||||||
|
- 在MultiPlayerWebSocket中传递连接是否安全的标志给UEProcessManager
|
||||||
|
- 修改UEProcessManager的startUEProcess方法,新增isSecure参数
|
||||||
|
- 根据isSecure参数选择使用ws或wss协议构造启动命令
|
||||||
|
- 记录并执行包含正确协议的启动命令,确保连接协议匹配
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249407
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 16:03:12
|
||||||
|
**版本**: r249407
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(multiprocess): 延长UE进程启动成功轮询时间
|
||||||
|
|
||||||
|
- 将轮询时间从15秒增加到20秒
|
||||||
|
- 提高获取engineConnections中连接的成功率
|
||||||
|
- 优化了UE进程启动判断逻辑
|
||||||
|
- 减少启动失败的误判情况
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249400
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 13:56:54
|
||||||
|
**版本**: r249400
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(UEProcessManager): 防止ShenFei进程泄漏,增加残留进程清理
|
||||||
|
|
||||||
|
- 在removeUEProcess方法中添加killShenFeiProcess调用,确保ShenFei进程被终止
|
||||||
|
- 使用@PostConstruct注解新增init方法,服务启动时清理所有残留ShenFei进程
|
||||||
|
- 实现cleanupAllShenFeiProcesses方法,通过bash命令杀死所有匹配engineWebSocket的进程
|
||||||
|
- 增加异常捕获,确保清理进程时日志正确记录错误信息
|
||||||
|
- 注释掉MultiPlayerWebSocket中关闭UE进程的代码,避免重复关闭造成问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
259
md/svn_log_PRS-7950在线巡视_20260130_102437.md
Normal file
259
md/svn_log_PRS-7950在线巡视_20260130_102437.md
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
|
||||||
|
- **SVN地址**: `https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7950在线巡视/01_开发库/V2.00/src_java`
|
||||||
|
- **版本范围**: r249404 - r250002
|
||||||
|
- **过滤用户**: `liujing2`
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r250002
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-29 16:29:08
|
||||||
|
**版本**: r250002
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
chore(pom): 更新项目依赖配置
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r250001
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-29 16:14:54
|
||||||
|
**版本**: r250001
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(twins): 数字孪生相关功能迁移至svn巡视代码下
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249995
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-29 13:58:44
|
||||||
|
**版本**: r249995
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
chore(deps): 更新 pagehelper 版本至 5.3.2
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249977
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 17:00:49
|
||||||
|
**版本**: r249977
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024版本244507 fix(linkage-task):手动处理瀚高数据库更新后顺序改变的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249976
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 16:59:11
|
||||||
|
**版本**: r249976
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244546版本
|
||||||
|
优化 MyBatis 映射文件中的 SQL 语句
|
||||||
|
|
||||||
|
- 移除了多处 SQL 语句中不必要的反引号
|
||||||
|
- 统一了表名和字段名的命名风格
|
||||||
|
- 提高了 SQL语句的可读性和一致性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249975
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 16:57:44
|
||||||
|
**版本**: r249975
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244398版本 处理动态SQL包含问号的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249974
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 16:56:37
|
||||||
|
**版本**: r249974
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
同步2024的的244359版本处理mysql函数last_insert_id()在瀚高报错的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249973
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 16:50:28
|
||||||
|
**版本**: r249973
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent): 同步2024的243464
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249972
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 16:48:17
|
||||||
|
**版本**: r249972
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(silent): 同步2024的243573
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249938
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-27 17:55:15
|
||||||
|
**版本**: r249938
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(export): 添加相机用途字段及其映射支持
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249715
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-17 00:26:56
|
||||||
|
**版本**: r249715
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(devops): 修复巡视时间未更新的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249677
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-15 16:45:46
|
||||||
|
**版本**: r249677
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(analyse): 单独适配2.00设备外观查看显示
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249666
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-15 11:58:58
|
||||||
|
**版本**: r249666
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(analyse-patrol): 优化设备外观查看巡视结果展示效果
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249446
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-06 13:59:09
|
||||||
|
**版本**: r249446
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 添加巡检联动任务更新状态字段
|
||||||
|
|
||||||
|
- 在PatrolLinkageTask实体中添加isUpdate字段
|
||||||
|
- 更新PatrolLinkageTaskMapper.xml映射文件,添加isUpdate字段映射
|
||||||
|
- 在insert语句中添加isUpdate字段的条件更新逻辑
|
||||||
|
- 在查询语句中添加isUpdate字段到返回结果中
|
||||||
|
- 添加按isUpdate降序和ID排序的排序规则
|
||||||
|
- 修改queryLinkageConfigChange查询条件,使用isUpdate = 1替代原条件
|
||||||
|
- 在PatrolLinkageConfigDto和PatrolLinkageVo中同步添加isUpdate字段
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249419
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 19:19:50
|
||||||
|
**版本**: r249419
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(linkage): 添加联动配置变更查询功能
|
||||||
|
|
||||||
|
- 在 PatrolLinkageConfigController 中新增 queryChange 接口用于查询信号配置变更
|
||||||
|
- 在 PatrolLinkageTaskMapper 中添加 queryLinkageConfigChange 方法和 old_source_name 字段映射
|
||||||
|
- 在 PatrolLinkageTaskMapper.xml 中更新 resultMap 和 insert/update 语句以支持 old_source_name
|
||||||
|
- 在 PatrolLinkageConfiguration 中实现 queryLinkageConfigChange 业务逻辑
|
||||||
|
- 在 PatrolLinkageService 和 PatrolLinkageServiceImpl 中添加 queryChange 方法
|
||||||
|
- 在 PatrolLinkageVo 中添加 oldSourceName 字段用于存储原始信号名称
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249404
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 15:07:32
|
||||||
|
**版本**: r249404
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(linkage): 新增oldSourceName字段以保存原始数据
|
||||||
|
|
||||||
|
- 在PatrolLinkageTask类中添加oldSourceName字段
|
||||||
|
- 在PatrolLinkageConfigDto类中添加oldSourceName字段
|
||||||
|
- 在PatrolLinkageVo类相关位置添加oldSourceName字段
|
||||||
|
- 各新增字段用于存储原始数据,便于后续数据处理与追踪
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
356
md/svn_log_PRS-7950在线巡视电科院测试版_20260130_102600.md
Normal file
356
md/svn_log_PRS-7950在线巡视电科院测试版_20260130_102600.md
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
|
||||||
|
- **SVN地址**: `https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7950在线巡视/01_开发库/V1.00_2024/src_java`
|
||||||
|
- **版本范围**: r249390 - r249969
|
||||||
|
- **过滤用户**: `liujing2`
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r249969
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 15:11:59
|
||||||
|
**版本**: r249969
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(patrol): 不添加value到redis
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249965
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 14:53:41
|
||||||
|
**版本**: r249965
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): value值也存redis,上报主站用
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249958
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 13:29:37
|
||||||
|
**版本**: r249958
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(patrol): 数据存redis 上报主站用
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249950
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 12:03:06
|
||||||
|
**版本**: r249950
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(rtdb): 修正hash键的命名错误
|
||||||
|
|
||||||
|
- 将MeterOverlimit中获取hash的key由"meter_overlimit_"改为"jufang_overlimit_"
|
||||||
|
- 将PatrolTaskManager中添加hash的key改为"jufang_overlimit_"加任务记录ID
|
||||||
|
- 修复因hash键错误导致的数据读取和写入问题
|
||||||
|
- 确保hash操作统一使用正确的前缀标识符,提高数据一致性和可维护性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249949
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-28 11:56:39
|
||||||
|
**版本**: r249949
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 新增redis信息设置方法优化分析结果存储
|
||||||
|
|
||||||
|
- 引入RtdbBasicService依赖用于redis操作
|
||||||
|
- 在识别类型处理逻辑中调用setRedisInfo方法
|
||||||
|
- 实现setRedisInfo方法,校验参数并拆分valueType和value
|
||||||
|
- 将value拆分后的键值对存入redis hash结构
|
||||||
|
- 添加异常情况日志打印,确保数据一致性和错误排查
|
||||||
|
- 保持原有分析结果发送逻辑不变
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249909
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-26 20:52:35
|
||||||
|
**版本**: r249909
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(core): 图片尺寸前端传
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249905
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-26 20:10:57
|
||||||
|
**版本**: r249905
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(PatrolTaskService): 处理点线矿返回到前端的图片路径为相对路径
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249890
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-26 15:29:31
|
||||||
|
**版本**: r249890
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(devops-patrol): 修复PatrolTaskServiceImpl中request设置异常
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249879
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-26 11:20:39
|
||||||
|
**版本**: r249879
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(task): 人工巡视红外测温图异常,新增红外测温功能以获取正常图. 新增点/线/框
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249824
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-22 14:22:36
|
||||||
|
**版本**: r249824
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(patrol): 修复最后一个点位结果未统计导致前端状态显示异常问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249653
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-14 16:25:23
|
||||||
|
**版本**: r249653
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 静默分析支持机器人和无人机设备类型处理
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249651
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-14 15:54:02
|
||||||
|
**版本**: r249651
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(sunri-service-alarm-patrol): 优化静默任务图片路径处理逻辑
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249642
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-13 15:32:23
|
||||||
|
**版本**: r249642
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(AnalyseResultConvert): 部件表面油污和表计外壳破损 特殊适配后调整点位状态值更新
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249588
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-11 13:46:28
|
||||||
|
**版本**: r249588
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 支持仪表读数类型使用外观查看类标签.目前仅支持配一种算法
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249576
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-10 17:12:47
|
||||||
|
**版本**: r249576
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(patrol): 上送联动配置时过滤掉未启用的配置
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249575
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-10 16:48:27
|
||||||
|
**版本**: r249575
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
fix(patrol): 过滤掉未启用的阈值告警配置
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249574
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-10 16:31:17
|
||||||
|
**版本**: r249574
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(patrol): 修复巡视结果上送valueunit如果是红外测试带单位可能异常问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249538
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-09 15:12:29
|
||||||
|
**版本**: r249538
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(patrol): 告警阈值模型关联点位未配置算法直接过滤掉
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249535
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-09 13:47:49
|
||||||
|
**版本**: r249535
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 调整联动配置关联的巡视任务删除逻辑
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249530
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-09 10:27:28
|
||||||
|
**版本**: r249530
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(linkage): 修复删除联动配置没有删除任务,导致下发的时候判断没有联动配置,新增任务插入失败问题
|
||||||
|
|
||||||
|
- 统一updatePatrolPlan方法处理新增与更新任务逻辑,避免重复代码
|
||||||
|
- 修正方法参数前后空格格式,提升代码一致性
|
||||||
|
- 删除冗余注释,明确使用updatePatrolPlan替代addLinkagePlan调用
|
||||||
|
- 调整方法调用处括号与逗号间的空格,规范代码格式
|
||||||
|
- 增加对sourceCode空值的参数校验保障代码健壮性
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249506
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-08 13:51:05
|
||||||
|
**版本**: r249506
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(linkage): 下发联动时支持所有设备不在进行机器人-无人机-摄像机过滤
|
||||||
|
|
||||||
|
- 移除对数据类型的过滤条件检查
|
||||||
|
- 直接使用原始设备点列表替代过滤后的列表
|
||||||
|
- 简化集合判空逻辑并统一处理流程
|
||||||
|
- 删除冗余的设备类型判断相关代码
|
||||||
|
- 优化流式处理的链式调用结构
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249488
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-07 16:24:30
|
||||||
|
**版本**: r249488
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
refactor(core): 修复区域边缘存在时差且刚好区域不再时间执行范围内 边缘刚好在执行时间时间范围内的定时任务执行无视频问题
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r249390
|
||||||
|
|
||||||
|
**作者**: `liujing2@SZNARI`
|
||||||
|
**时间**: 2026-01-05 11:12:19
|
||||||
|
**版本**: r249390
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(patrol): 修复批量下发异常问题.调整为根据变电站ID进行下发
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
121
svn-log-tool/README_DeepSeek.md
Normal file
121
svn-log-tool/README_DeepSeek.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# SVN日志工作量统计工具(DeepSeek版)
|
||||||
|
|
||||||
|
## 功能说明
|
||||||
|
|
||||||
|
这个工具可以根据SVN日志的markdown文件,调用DeepSeek API分析日志内容,并生成符合格式要求的工作量统计Excel文件。
|
||||||
|
|
||||||
|
## 使用步骤
|
||||||
|
|
||||||
|
### 1. 准备SVN日志markdown文件
|
||||||
|
|
||||||
|
使用原有的SVN日志工具生成markdown文件:
|
||||||
|
```bash
|
||||||
|
java -jar svn-log-tool-1.0.0-jar-with-dependencies.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
按照提示输入SVN仓库地址、账号、密码等信息,生成markdown格式的日志文件。
|
||||||
|
|
||||||
|
### 2. 运行DeepSeek日志处理工具
|
||||||
|
|
||||||
|
```bash
|
||||||
|
java -cp target/svn-log-tool-1.0.0-jar-with-dependencies.jar com.svnlog.DeepSeekLogProcessor
|
||||||
|
```
|
||||||
|
|
||||||
|
或者使用Maven运行:
|
||||||
|
```bash
|
||||||
|
mvn exec:java -Dexec.mainClass="com.svnlog.DeepSeekLogProcessor"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 按照提示输入信息
|
||||||
|
|
||||||
|
程序会依次提示输入:
|
||||||
|
- **markdown日志文件路径**:可以直接回车使用当前目录下最新的`svn_log_*.md`文件
|
||||||
|
- **DeepSeek API Key**:请提供有效的DeepSeek API Key(也可以直接在代码中修改`API_KEY`常量)
|
||||||
|
- **输出Excel文件名**:可以直接回车使用默认文件名(格式:`YYYYMM工作量统计.xlsx`)
|
||||||
|
|
||||||
|
### 4. 等待处理完成
|
||||||
|
|
||||||
|
程序会自动:
|
||||||
|
1. 读取markdown日志文件
|
||||||
|
2. 调用DeepSeek API分析日志内容
|
||||||
|
3. 根据分析结果生成Excel文件
|
||||||
|
|
||||||
|
生成的Excel文件格式与`202512工作量统计_刘靖.xlsx`保持一致。
|
||||||
|
|
||||||
|
## Excel文件格式说明
|
||||||
|
|
||||||
|
生成的Excel文件包含以下列:
|
||||||
|
- 序号
|
||||||
|
- 所属班组
|
||||||
|
- 技术对接
|
||||||
|
- 开发人员
|
||||||
|
- 工作周期
|
||||||
|
- 开发项目名称
|
||||||
|
- 具体工作内容
|
||||||
|
- 空列(4个)
|
||||||
|
|
||||||
|
## DeepSeek API配置
|
||||||
|
|
||||||
|
在`DeepSeekLogProcessor.java`中,可以修改以下配置:
|
||||||
|
|
||||||
|
```java
|
||||||
|
private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/chat/completions";
|
||||||
|
private static final String API_KEY = "YOUR_DEEPSEEK_API_KEY"; // 请替换为实际的API Key
|
||||||
|
```
|
||||||
|
|
||||||
|
## 提示词说明
|
||||||
|
|
||||||
|
工具会向DeepSeek发送以下提示词,要求AI以JSON格式返回工作量统计:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"team": "所属班组",
|
||||||
|
"contact": "技术对接人",
|
||||||
|
"developer": "开发人员",
|
||||||
|
"period": "工作周期 (例如: 2025年12月)",
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"sequence": 1,
|
||||||
|
"project": "项目名称",
|
||||||
|
"content": "具体工作内容"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **API Key安全**:请妥善保管您的DeepSeek API Key,不要将其提交到代码仓库中
|
||||||
|
2. **网络连接**:需要能够访问DeepSeek API服务器
|
||||||
|
3. **日志格式**:markdown文件需要由SVN日志工具生成,包含完整的日志信息
|
||||||
|
4. **成本控制**:DeepSeek API可能产生费用,请注意控制使用频率
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
### 编译错误
|
||||||
|
```bash
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
```
|
||||||
|
|
||||||
|
### 运行时找不到主类
|
||||||
|
确保使用正确的jar文件:
|
||||||
|
```bash
|
||||||
|
java -cp target/svn-log-tool-1.0.0-jar-with-dependencies.jar com.svnlog.DeepSeekLogProcessor
|
||||||
|
```
|
||||||
|
|
||||||
|
### API调用失败
|
||||||
|
- 检查API Key是否正确
|
||||||
|
- 检查网络连接是否正常
|
||||||
|
- 检查DeepSeek API服务是否可用
|
||||||
|
|
||||||
|
## 依赖说明
|
||||||
|
|
||||||
|
项目使用以下主要依赖:
|
||||||
|
- SVNKit 1.10.11:SVN操作
|
||||||
|
- Apache POI 5.2.5:Excel文件读写
|
||||||
|
- OkHttp 4.12.0:HTTP客户端
|
||||||
|
- Gson 2.10.1:JSON处理
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
本工具仅供内部使用。
|
||||||
164
svn-log-tool/example_log.md
Normal file
164
svn-log-tool/example_log.md
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
|
||||||
|
- **SVN地址**: `https://svn.example.com/project`
|
||||||
|
- **账号**: `testuser`
|
||||||
|
- **版本范围**: r1000 - r1050
|
||||||
|
- **生成时间**: 2025-01-30 10:00:00
|
||||||
|
|
||||||
|
## 统计信息
|
||||||
|
|
||||||
|
- **总记录数**: 5 条
|
||||||
|
|
||||||
|
### 按作者统计
|
||||||
|
|
||||||
|
| 作者 | 提交次数 |
|
||||||
|
|------|----------|
|
||||||
|
| `zhangsan` | 3 |
|
||||||
|
| `lisi` | 2 |
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r1050
|
||||||
|
|
||||||
|
**作者**: `zhangsan`
|
||||||
|
**时间**: 2025-01-30 09:30:00
|
||||||
|
**版本**: r1050
|
||||||
|
|
||||||
|
**变更文件**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/src/main/java/com/example/Service.java
|
||||||
|
/src/test/java/com/example/ServiceTest.java
|
||||||
|
```
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
修复用户登录时的空指针异常问题
|
||||||
|
|
||||||
|
1. 修复用户服务中的空指针检查
|
||||||
|
2. 添加单元测试验证修复
|
||||||
|
3. 更新相关文档
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r1049
|
||||||
|
|
||||||
|
**作者**: `zhangsan`
|
||||||
|
**时间**: 2025-01-29 16:45:00
|
||||||
|
**版本**: r1049
|
||||||
|
|
||||||
|
**变更文件**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/src/main/java/com/example/Controller.java
|
||||||
|
```
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
优化API接口响应速度
|
||||||
|
|
||||||
|
# 性能优化
|
||||||
|
1. 添加数据库查询缓存
|
||||||
|
2. 优化SQL查询语句
|
||||||
|
3. 减少不必要的对象创建
|
||||||
|
|
||||||
|
# 测试验证
|
||||||
|
- 响应时间从500ms降低到200ms
|
||||||
|
- 通过所有单元测试
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r1048
|
||||||
|
|
||||||
|
**作者**: `lisi`
|
||||||
|
**时间**: 2025-01-29 14:20:00
|
||||||
|
**版本**: r1048
|
||||||
|
|
||||||
|
**变更文件**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/src/main/java/com/example/Dao.java
|
||||||
|
/src/main/resources/mapper/UserMapper.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
实现用户数据批量导入功能
|
||||||
|
|
||||||
|
# 核心功能
|
||||||
|
1. 支持Excel文件上传
|
||||||
|
2. 数据验证和错误处理
|
||||||
|
3. 批量插入数据库
|
||||||
|
|
||||||
|
# 配置变更
|
||||||
|
- 添加文件上传大小限制
|
||||||
|
- 配置批量插入批次大小
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r1047
|
||||||
|
|
||||||
|
**作者**: `zhangsan`
|
||||||
|
**时间**: 2025-01-28 11:00:00
|
||||||
|
**版本**: r1047
|
||||||
|
|
||||||
|
**变更文件**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/src/main/java/com/example/Util.java
|
||||||
|
/src/main/resources/application.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
添加日志记录功能
|
||||||
|
|
||||||
|
# 新增功能
|
||||||
|
1. 集成Log4j2日志框架
|
||||||
|
2. 配置日志输出格式
|
||||||
|
3. 添加关键操作日志记录
|
||||||
|
|
||||||
|
# 配置更新
|
||||||
|
- 设置日志级别为INFO
|
||||||
|
- 配置日志文件滚动策略
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### r1046
|
||||||
|
|
||||||
|
**作者**: `lisi`
|
||||||
|
**时间**: 2025-01-27 15:30:00
|
||||||
|
**版本**: r1046
|
||||||
|
|
||||||
|
**变更文件**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/src/main/java/com/example/Model.java
|
||||||
|
```
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
|
||||||
|
```
|
||||||
|
重构数据模型类
|
||||||
|
|
||||||
|
# 重构内容
|
||||||
|
1. 优化字段命名规范
|
||||||
|
2. 添加数据验证注解
|
||||||
|
3. 实现序列化接口
|
||||||
|
|
||||||
|
# 兼容性
|
||||||
|
- 保持向后兼容
|
||||||
|
- 更新相关测试用例
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
109
svn-log-tool/pom.xml
Normal file
109
svn-log-tool/pom.xml
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.svnlog</groupId>
|
||||||
|
<artifactId>svn-log-tool</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>SVN Log Tool</name>
|
||||||
|
<description>SVN日志查询工具,支持版本范围过滤和用户名过滤,可导出Markdown格式</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- SVNKit for SVN operations -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.tmatesoft.svnkit</groupId>
|
||||||
|
<artifactId>svnkit</artifactId>
|
||||||
|
<version>1.10.11</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Apache POI for Excel operations -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
<version>5.2.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>5.2.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- HTTP Client for API calls -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>okhttp</artifactId>
|
||||||
|
<version>4.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON parsing -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.10.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.svnlog.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.svnlog.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
587
svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java
Normal file
587
svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
package com.svnlog;
|
||||||
|
|
||||||
|
import okhttp3.*;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用DeepSeek API处理SVN日志并生成工作量统计Excel
|
||||||
|
*/
|
||||||
|
public class DeepSeekLogProcessor {
|
||||||
|
private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/chat/completions";
|
||||||
|
private static final String API_KEY = "sk-48c59012c93b43a08fecbaf3e74799e7"; // 用户需要替换为实际的API Key
|
||||||
|
private static final OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
|
||||||
|
.readTimeout(300, java.util.concurrent.TimeUnit.SECONDS) // 5分钟读取超时
|
||||||
|
.writeTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
System.out.println("===========================================");
|
||||||
|
System.out.println(" SVN日志工作量统计工具(DeepSeek版)");
|
||||||
|
System.out.println(" 支持多项目汇总分析");
|
||||||
|
System.out.println("===========================================");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 读取markdown日志文件目录
|
||||||
|
System.out.print("请输入markdown日志文件所在目录路径 (回车使用当前目录): ");
|
||||||
|
String dirPath = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
File dir;
|
||||||
|
if (dirPath.isEmpty()) {
|
||||||
|
dir = new File(".");
|
||||||
|
} else {
|
||||||
|
dir = new File(dirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dir.exists() || !dir.isDirectory()) {
|
||||||
|
System.err.println("错误: 目录不存在或不是有效目录!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扫描目录中的所有 .md 文件
|
||||||
|
File[] mdFiles = dir.listFiles((d, name) -> name.endsWith(".md"));
|
||||||
|
if (mdFiles == null || mdFiles.length == 0) {
|
||||||
|
System.err.println("错误: 目录中未找到任何 .md 文件!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("找到 " + mdFiles.length + " 个日志文件:");
|
||||||
|
for (File file : mdFiles) {
|
||||||
|
System.out.println(" - " + file.getName());
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 输入工作周期
|
||||||
|
SimpleDateFormat periodSdf = new SimpleDateFormat("yyyy年MM月");
|
||||||
|
String defaultPeriod = periodSdf.format(new Date());
|
||||||
|
System.out.print("请输入工作周期 (例如: 2025年12月,回车使用默认: " + defaultPeriod + "): ");
|
||||||
|
String period = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
if (period.isEmpty()) {
|
||||||
|
period = defaultPeriod;
|
||||||
|
System.out.println("使用默认工作周期: " + period);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取并合并所有markdown文件
|
||||||
|
String combinedContent = readAndCombineMarkdownFiles(mdFiles);
|
||||||
|
System.out.println("成功读取并合并 " + mdFiles.length + " 个日志文件,总长度: " + combinedContent.length() + " 字符");
|
||||||
|
|
||||||
|
// 提示API Key
|
||||||
|
System.out.print("请输入DeepSeek API Key (留空使用代码中预设的): ");
|
||||||
|
String inputApiKey = scanner.nextLine().trim();
|
||||||
|
String apiKey = inputApiKey.isEmpty() ? API_KEY : inputApiKey;
|
||||||
|
|
||||||
|
if (apiKey.equals("YOUR_DEEPSEEK_API_KEY")) {
|
||||||
|
System.err.println("错误: 请提供有效的DeepSeek API Key!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 询问输出文件名
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
|
||||||
|
String defaultOutput = sdf.format(new Date()) + "工作量统计.xlsx";
|
||||||
|
System.out.print("请输入输出Excel文件名 (回车使用默认: " + defaultOutput + "): ");
|
||||||
|
String outputPath = scanner.nextLine().trim();
|
||||||
|
if (outputPath.isEmpty()) {
|
||||||
|
outputPath = defaultOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("正在调用DeepSeek API分析日志...");
|
||||||
|
|
||||||
|
// 调用DeepSeek API处理日志
|
||||||
|
String prompt = buildPrompt(combinedContent, period);
|
||||||
|
String aiResponse = callDeepSeekAPI(apiKey, prompt);
|
||||||
|
|
||||||
|
if (aiResponse == null) {
|
||||||
|
System.err.println("DeepSeek API调用失败!请检查网络连接和API Key。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aiResponse.isEmpty()) {
|
||||||
|
System.err.println("DeepSeek API返回空响应!请重试或联系技术支持。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("DeepSeek分析完成,正在生成Excel...");
|
||||||
|
|
||||||
|
// 生成Excel
|
||||||
|
generateExcel(outputPath, aiResponse);
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Excel文件生成成功: " + outputPath);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("发生错误: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件内容
|
||||||
|
*/
|
||||||
|
private static String readFile(String path) throws IOException {
|
||||||
|
return new String(Files.readAllBytes(new File(path).toPath()), "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取并合并多个markdown文件的内容
|
||||||
|
*/
|
||||||
|
private static String readAndCombineMarkdownFiles(File[] mdFiles) throws IOException {
|
||||||
|
StringBuilder combinedContent = new StringBuilder();
|
||||||
|
|
||||||
|
for (File file : mdFiles) {
|
||||||
|
String projectName = extractProjectName(file.getName());
|
||||||
|
String content = readFile(file.getAbsolutePath());
|
||||||
|
|
||||||
|
combinedContent.append("\n\n");
|
||||||
|
combinedContent.append("=== 项目: ").append(projectName).append(" ===\n");
|
||||||
|
combinedContent.append(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinedContent.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从文件名中提取项目名称
|
||||||
|
* 例如: svn_log_PRS-7050场站智慧管控_20260130_093348.md -> PRS-7050场站智慧管控
|
||||||
|
*/
|
||||||
|
private static String extractProjectName(String fileName) {
|
||||||
|
// 去掉 svn_log_ 前缀
|
||||||
|
if (fileName.startsWith("svn_log_")) {
|
||||||
|
fileName = fileName.substring(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉 .md 后缀
|
||||||
|
if (fileName.endsWith(".md")) {
|
||||||
|
fileName = fileName.substring(0, fileName.length() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉时间戳部分 (格式: _YYYYMMDD_HHMMSS)
|
||||||
|
int lastUnderscore = fileName.lastIndexOf('_');
|
||||||
|
if (lastUnderscore > 0) {
|
||||||
|
// 检查是否是时间戳格式
|
||||||
|
String timestampPart = fileName.substring(lastUnderscore + 1);
|
||||||
|
if (timestampPart.matches("\\d{8}_\\d{6}")) {
|
||||||
|
fileName = fileName.substring(0, lastUnderscore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建发送给DeepSeek的提示词
|
||||||
|
*/
|
||||||
|
private static String buildPrompt(String markdownContent, String period) {
|
||||||
|
return "你是一个专业的项目管理助手。请分析以下多个项目的SVN日志,并生成工作量统计数据。\n\n" +
|
||||||
|
"日志内容包含多个项目,每个项目之间用 === 项目: xxx === 标识。\n" +
|
||||||
|
"工作周期: " + period + "\n\n" +
|
||||||
|
"SVN日志内容:\n" + markdownContent + "\n\n" +
|
||||||
|
"请按照以下JSON格式返回工作量统计数据:\n" +
|
||||||
|
"{\n" +
|
||||||
|
" \"team\": \"所属班组\",\n" +
|
||||||
|
" \"contact\": \"技术对接人\",\n" +
|
||||||
|
" \"developer\": \"开发人员\",\n" +
|
||||||
|
" \"period\": \"" + period + "\",\n" +
|
||||||
|
" \"records\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"sequence\": 1,\n" +
|
||||||
|
" \"project\": \"项目1/项目2/项目3\",\n" +
|
||||||
|
" \"content\": \"# 项目1\\n1.工作内容1\\n2.工作内容2\\n\\n# 项目2\\n1.工作内容1\\n2.工作内容2\\n\\n# 项目3\\n1.工作内容1\\n2.工作内容2\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
"}\n\n" +
|
||||||
|
"重要要求:\n" +
|
||||||
|
"1. 根据日志作者确定开发人员\n" +
|
||||||
|
"2. 将所有项目的工作内容合并到一条记录中\n" +
|
||||||
|
"3. 项目名称字段(project):使用 / 分隔多个项目,例如:\"PRS7050场站系统/PRS7950智能巡视现场问题/PRS7950电科院测试\"\n" +
|
||||||
|
"4. 具体工作内容字段(content):使用 # 作为项目分类标识,格式为:\"# 项目名称\\n1.工作内容\\n2.工作内容\\n\\n# 下一个项目\\n1.工作内容\"\n" +
|
||||||
|
"5. 不同项目之间用空行分隔\n" +
|
||||||
|
"6. 只返回JSON,不要有其他文字\n" +
|
||||||
|
"7. 提取具体工作内容,要详细和有条理\n" +
|
||||||
|
"8. 项目名称要简洁明确,去掉多余的前缀和后缀";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用DeepSeek API(流式输出)
|
||||||
|
*/
|
||||||
|
private static String callDeepSeekAPI(String apiKey, String prompt) throws IOException {
|
||||||
|
JSONObject requestBody = new JSONObject();
|
||||||
|
requestBody.put("model", "deepseek-chat");
|
||||||
|
|
||||||
|
// 创建消息对象,包含 role 和 content 字段
|
||||||
|
JSONObject messageObj = new JSONObject();
|
||||||
|
messageObj.put("role", "user");
|
||||||
|
messageObj.put("content", prompt);
|
||||||
|
|
||||||
|
// 创建消息数组
|
||||||
|
com.google.gson.JsonArray messagesArray = new com.google.gson.JsonArray();
|
||||||
|
messagesArray.add(messageObj.jsonObject);
|
||||||
|
requestBody.put("messages", messagesArray);
|
||||||
|
|
||||||
|
requestBody.put("temperature", 0.7);
|
||||||
|
requestBody.put("max_tokens", 4000);
|
||||||
|
requestBody.put("stream", true); // 启用流式输出
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(DEEPSEEK_API_URL)
|
||||||
|
.addHeader("Authorization", "Bearer " + apiKey)
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.post(RequestBody.create(requestBody.toString(), MediaType.parse("application/json")))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
StringBuilder fullResponse = new StringBuilder();
|
||||||
|
int chunkCount = 0;
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
System.err.println("API调用失败: " + response.code() + " " + response.message());
|
||||||
|
String errorResponse = response.body().string();
|
||||||
|
System.err.println("响应: " + errorResponse);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取流式响应
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body().byteStream()))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.startsWith("data: ")) {
|
||||||
|
String data = line.substring(6);
|
||||||
|
if (data.equals("[DONE]")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject chunk = new JSONObject(data);
|
||||||
|
if (chunk.has("choices") && chunk.getJSONArray("choices").size() > 0) {
|
||||||
|
JSONObject choice = chunk.getJSONArray("choices").get(0);
|
||||||
|
if (choice.has("delta")) {
|
||||||
|
JSONObject delta = choice.getJSONObject("delta");
|
||||||
|
if (delta.has("content")) {
|
||||||
|
String content = delta.optString("content", "");
|
||||||
|
fullResponse.append(content);
|
||||||
|
chunkCount++;
|
||||||
|
// 实时打印处理进度
|
||||||
|
System.out.print(content);
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 忽略解析错误,继续处理下一行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("API调用过程中发生异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(); // 换行
|
||||||
|
System.out.println("收到 " + chunkCount + " 个数据块");
|
||||||
|
|
||||||
|
if (fullResponse.length() == 0) {
|
||||||
|
System.err.println("警告: 未收到任何响应内容");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullResponse.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从响应中提取纯 JSON 内容
|
||||||
|
*/
|
||||||
|
private static String extractJson(String response) {
|
||||||
|
String trimmed = response.trim();
|
||||||
|
|
||||||
|
// 去除 ```json 标记
|
||||||
|
if (trimmed.startsWith("```json")) {
|
||||||
|
trimmed = trimmed.substring(7);
|
||||||
|
} else if (trimmed.startsWith("```")) {
|
||||||
|
trimmed = trimmed.substring(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除 ``` 结束标记
|
||||||
|
if (trimmed.endsWith("```")) {
|
||||||
|
trimmed = trimmed.substring(0, trimmed.length() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trimmed.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成Excel文件
|
||||||
|
*/
|
||||||
|
private static void generateExcel(String outputPath, String jsonResponse) throws IOException {
|
||||||
|
// 提取纯 JSON 内容(去除 ```json 和 ``` 标记)
|
||||||
|
String cleanJson = extractJson(jsonResponse);
|
||||||
|
|
||||||
|
// 解析JSON响应
|
||||||
|
JSONObject data = new JSONObject(cleanJson);
|
||||||
|
|
||||||
|
// 创建工作簿
|
||||||
|
Workbook workbook = new XSSFWorkbook();
|
||||||
|
Sheet sheet = workbook.createSheet("工作表1");
|
||||||
|
|
||||||
|
// 创建样式
|
||||||
|
CellStyle headerStyle = createHeaderStyle(workbook);
|
||||||
|
CellStyle contentStyle = createContentStyle(workbook);
|
||||||
|
CellStyle workContentStyle = createWorkContentStyle(workbook);
|
||||||
|
|
||||||
|
// 创建表头(7列,与参考文件一致)
|
||||||
|
Row headerRow = sheet.createRow(0);
|
||||||
|
headerRow.setHeightInPoints(14.25f); // 表头行高
|
||||||
|
String[] headers = {"序号", "所属班组", "技术对接", "开发人员", "工作周期", "开发项目名称", "具体工作内容"};
|
||||||
|
for (int i = 0; i < headers.length; i++) {
|
||||||
|
Cell cell = headerRow.createCell(i);
|
||||||
|
cell.setCellValue(headers[i]);
|
||||||
|
cell.setCellStyle(headerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置固定列宽(与参考文件一致)
|
||||||
|
sheet.setColumnWidth(0, 2048); // 序号:8.00字符
|
||||||
|
sheet.setColumnWidth(1, 3328); // 所属班组:13.00字符
|
||||||
|
sheet.setColumnWidth(2, 4608); // 技术对接:18.00字符
|
||||||
|
sheet.setColumnWidth(3, 3840); // 开发人员:15.00字符
|
||||||
|
sheet.setColumnWidth(4, 5888); // 工作周期:23.00字符
|
||||||
|
sheet.setColumnWidth(5, 14080); // 开发项目名称:55.00字符
|
||||||
|
sheet.setColumnWidth(6, 43991); // 具体工作内容:171.84字符
|
||||||
|
|
||||||
|
// 获取记录
|
||||||
|
String team = data.optString("team", "");
|
||||||
|
String contact = data.optString("contact", "");
|
||||||
|
String developer = data.optString("developer", "");
|
||||||
|
String period = data.optString("period", "");
|
||||||
|
|
||||||
|
if (data.has("records")) {
|
||||||
|
JSONArray recordsArray = data.getJSONArray("records");
|
||||||
|
int rowNum = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < recordsArray.size(); i++) {
|
||||||
|
JSONObject record = recordsArray.get(i);
|
||||||
|
Row row = sheet.createRow(rowNum++);
|
||||||
|
row.setHeightInPoints(16.50f); // 内容行高
|
||||||
|
|
||||||
|
// 序号
|
||||||
|
Cell cell0 = row.createCell(0);
|
||||||
|
cell0.setCellValue(record.optDouble("sequence", i + 1));
|
||||||
|
cell0.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 所属班组
|
||||||
|
Cell cell1 = row.createCell(1);
|
||||||
|
cell1.setCellValue(team);
|
||||||
|
cell1.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 技术对接
|
||||||
|
Cell cell2 = row.createCell(2);
|
||||||
|
cell2.setCellValue(contact);
|
||||||
|
cell2.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 开发人员
|
||||||
|
Cell cell3 = row.createCell(3);
|
||||||
|
cell3.setCellValue(developer);
|
||||||
|
cell3.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 工作周期
|
||||||
|
Cell cell4 = row.createCell(4);
|
||||||
|
cell4.setCellValue(period);
|
||||||
|
cell4.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 项目名称(多个项目用 / 分隔)
|
||||||
|
Cell cell5 = row.createCell(5);
|
||||||
|
cell5.setCellValue(record.optString("project", ""));
|
||||||
|
cell5.setCellStyle(contentStyle);
|
||||||
|
|
||||||
|
// 工作内容(支持换行,用 # 标识不同项目)
|
||||||
|
Cell cell6 = row.createCell(6);
|
||||||
|
cell6.setCellValue(record.optString("content", ""));
|
||||||
|
cell6.setCellStyle(workContentStyle); // 使用工作内容样式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入文件
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
|
||||||
|
workbook.write(fos);
|
||||||
|
}
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建表头样式
|
||||||
|
*/
|
||||||
|
private static CellStyle createHeaderStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setFontName("SimSun"); // 字体名称:SimSun
|
||||||
|
font.setFontHeightInPoints((short) 11); // 字体大小:11磅
|
||||||
|
font.setBold(false); // 不粗体
|
||||||
|
font.setColor(IndexedColors.BLACK.getIndex()); // 黑色
|
||||||
|
style.setFont(font);
|
||||||
|
style.setAlignment(HorizontalAlignment.GENERAL); // 水平对齐:常规
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直对齐:居中
|
||||||
|
style.setFillPattern(FillPatternType.NO_FILL); // 无填充
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setWrapText(false); // 不换行
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建普通内容样式(列A-F)
|
||||||
|
*/
|
||||||
|
private static CellStyle createContentStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setFontName("宋体"); // 字体名称:宋体
|
||||||
|
font.setFontHeightInPoints((short) 11); // 字体大小:11磅
|
||||||
|
font.setBold(false); // 不粗体
|
||||||
|
style.setFont(font);
|
||||||
|
style.setAlignment(HorizontalAlignment.GENERAL); // 水平对齐:常规
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直对齐:居中
|
||||||
|
style.setFillPattern(FillPatternType.NO_FILL); // 无填充
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.NONE);
|
||||||
|
style.setBorderLeft(BorderStyle.NONE);
|
||||||
|
style.setBorderRight(BorderStyle.NONE);
|
||||||
|
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setWrapText(false); // 不换行
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建工作内容样式(列G)
|
||||||
|
*/
|
||||||
|
private static CellStyle createWorkContentStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setFontName("NSimSun"); // 字体名称:新宋体
|
||||||
|
font.setFontHeightInPoints((short) 14); // 字体大小:14磅
|
||||||
|
font.setBold(true); // 粗体
|
||||||
|
font.setColor(IndexedColors.BLACK.getIndex()); // 黑色
|
||||||
|
style.setFont(font);
|
||||||
|
style.setAlignment(HorizontalAlignment.LEFT); // 水平对齐:左对齐
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.TOP); // 垂直对齐:顶部
|
||||||
|
style.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); // 黄色背景
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 实心填充
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.NONE);
|
||||||
|
style.setBorderLeft(BorderStyle.NONE);
|
||||||
|
style.setBorderRight(BorderStyle.NONE);
|
||||||
|
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setWrapText(true); // 自动换行
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单的JSON工具类
|
||||||
|
*/
|
||||||
|
static class JSONObject {
|
||||||
|
private final com.google.gson.JsonObject jsonObject;
|
||||||
|
|
||||||
|
public JSONObject() {
|
||||||
|
this.jsonObject = new com.google.gson.JsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject(String jsonString) {
|
||||||
|
com.google.gson.Gson gson = new com.google.gson.Gson();
|
||||||
|
this.jsonObject = gson.fromJson(jsonString, com.google.gson.JsonObject.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject(String key, String value) {
|
||||||
|
this();
|
||||||
|
put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String key, String value) {
|
||||||
|
jsonObject.addProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String key, int value) {
|
||||||
|
jsonObject.addProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String key, double value) {
|
||||||
|
jsonObject.addProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String key, Object value) {
|
||||||
|
com.google.gson.Gson gson = new com.google.gson.Gson();
|
||||||
|
jsonObject.add(key, gson.toJsonTree(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String optString(String key, String defaultValue) {
|
||||||
|
if (jsonObject.has(key) && !jsonObject.get(key).isJsonNull()) {
|
||||||
|
return jsonObject.get(key).getAsString();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double optDouble(String key, double defaultValue) {
|
||||||
|
if (jsonObject.has(key) && !jsonObject.get(key).isJsonNull()) {
|
||||||
|
return jsonObject.get(key).getAsDouble();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean has(String key) {
|
||||||
|
return jsonObject.has(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray getJSONArray(String key) {
|
||||||
|
return new JSONArray(jsonObject.get(key).getAsJsonArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getJSONObject(String key) {
|
||||||
|
return new JSONObject(jsonObject.get(key).getAsJsonObject().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return jsonObject.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单的JSONArray工具类
|
||||||
|
*/
|
||||||
|
static class JSONArray {
|
||||||
|
private final com.google.gson.JsonArray jsonArray;
|
||||||
|
|
||||||
|
public JSONArray(com.google.gson.JsonArray jsonArray) {
|
||||||
|
this.jsonArray = jsonArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return jsonArray.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject get(int index) {
|
||||||
|
return new JSONObject(jsonArray.get(index).getAsJsonObject().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> java.util.List<JSONObject> toList() {
|
||||||
|
java.util.List<JSONObject> list = new ArrayList<>();
|
||||||
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
list.add(get(i));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java
Normal file
84
svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package com.svnlog;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 临时工具类,用于分析现有Excel文件格式
|
||||||
|
*/
|
||||||
|
public class ExcelAnalyzer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String excelPath = "/home/liumangmang/opencode/日志/202512工作量统计_刘靖.xlsx";
|
||||||
|
|
||||||
|
try (FileInputStream fis = new FileInputStream(excelPath);
|
||||||
|
Workbook workbook = new XSSFWorkbook(fis)) {
|
||||||
|
|
||||||
|
System.out.println("工作表数量: " + workbook.getNumberOfSheets());
|
||||||
|
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
|
||||||
|
System.out.println("工作表 " + i + ": " + workbook.getSheetName(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
System.out.println("\n工作表名称: " + sheet.getSheetName());
|
||||||
|
System.out.println("总行数: " + sheet.getPhysicalNumberOfRows());
|
||||||
|
System.out.println("最后一行索引: " + sheet.getLastRowNum());
|
||||||
|
|
||||||
|
// 读取前20行数据
|
||||||
|
System.out.println("\n前20行数据:");
|
||||||
|
for (int i = 0; i <= Math.min(19, sheet.getLastRowNum()); i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row != null) {
|
||||||
|
System.out.print("第" + (i + 1) + "行: ");
|
||||||
|
for (Cell cell : row) {
|
||||||
|
String value = getCellValueAsString(cell);
|
||||||
|
System.out.print("[" + value + "] ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取表头
|
||||||
|
Row headerRow = sheet.getRow(0);
|
||||||
|
if (headerRow != null) {
|
||||||
|
System.out.println("\n表头列数: " + headerRow.getLastCellNum());
|
||||||
|
System.out.print("表头: ");
|
||||||
|
for (Cell cell : headerRow) {
|
||||||
|
System.out.print("[" + getCellValueAsString(cell) + "] ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("读取Excel文件出错: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getCellValueAsString(Cell cell) {
|
||||||
|
if (cell == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
case STRING:
|
||||||
|
return cell.getStringCellValue().trim();
|
||||||
|
case NUMERIC:
|
||||||
|
if (DateUtil.isCellDateFormatted(cell)) {
|
||||||
|
return cell.getDateCellValue().toString();
|
||||||
|
} else {
|
||||||
|
return String.valueOf(cell.getNumericCellValue());
|
||||||
|
}
|
||||||
|
case BOOLEAN:
|
||||||
|
return String.valueOf(cell.getBooleanCellValue());
|
||||||
|
case FORMULA:
|
||||||
|
return cell.getCellFormula();
|
||||||
|
case BLANK:
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
71
svn-log-tool/src/main/java/com/svnlog/LogEntry.java
Normal file
71
svn-log-tool/src/main/java/com/svnlog/LogEntry.java
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package com.svnlog;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class LogEntry {
|
||||||
|
private long revision;
|
||||||
|
private String author;
|
||||||
|
private Date date;
|
||||||
|
private String message;
|
||||||
|
private String[] changedPaths;
|
||||||
|
|
||||||
|
public LogEntry() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogEntry(long revision, String author, Date date, String message) {
|
||||||
|
this.revision = revision;
|
||||||
|
this.author = author;
|
||||||
|
this.date = date;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRevision(long revision) {
|
||||||
|
this.revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getChangedPaths() {
|
||||||
|
return changedPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChangedPaths(String[] changedPaths) {
|
||||||
|
this.changedPaths = changedPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LogEntry{" +
|
||||||
|
"revision=" + revision +
|
||||||
|
", author='" + author + '\'' +
|
||||||
|
", date=" + date +
|
||||||
|
", message='" + message + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
215
svn-log-tool/src/main/java/com/svnlog/Main.java
Normal file
215
svn-log-tool/src/main/java/com/svnlog/Main.java
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
package com.svnlog;
|
||||||
|
|
||||||
|
import org.tmatesoft.svn.core.SVNException;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
private static final Scanner scanner = new Scanner(System.in);
|
||||||
|
private static final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||||
|
|
||||||
|
// 预设项目列表
|
||||||
|
private static final Project[] PRESET_PROJECTS = {
|
||||||
|
new Project("PRS-7050场站智慧管控", "https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7050场站智慧管控/01_开发库/V1.00/src_java"),
|
||||||
|
new Project("PRS-7950在线巡视", "https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7950在线巡视/01_开发库/V2.00/src_java"),
|
||||||
|
new Project("PRS-7950在线巡视电科院测试版", "https://10.6.220.216:48080/svn/houtai/001_后台软件/PRS-7950在线巡视/01_开发库/V1.00_2024/src_java")
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("===========================================");
|
||||||
|
System.out.println(" SVN 日志查询工具 v1.0");
|
||||||
|
System.out.println("===========================================");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 创建 md 目录
|
||||||
|
File mdDir = new File("md");
|
||||||
|
if (!mdDir.exists()) {
|
||||||
|
boolean created = mdDir.mkdir();
|
||||||
|
if (created) {
|
||||||
|
System.out.println("已创建 md 目录用于存放日志文件");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 选择项目
|
||||||
|
Project selectedProject = selectProject();
|
||||||
|
String url = selectedProject.getUrl();
|
||||||
|
System.out.println("已选择项目: " + selectedProject.getName());
|
||||||
|
System.out.println("SVN地址: " + url);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
String username = readInput("请输入SVN账号: ");
|
||||||
|
String password = readPassword("请输入SVN密码: ");
|
||||||
|
|
||||||
|
System.out.println("正在连接SVN仓库...");
|
||||||
|
SVNLogFetcher fetcher = new SVNLogFetcher(url, username, password);
|
||||||
|
fetcher.testConnection();
|
||||||
|
System.out.println("连接成功!");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
long latestRevision = fetcher.getLatestRevision();
|
||||||
|
System.out.println("最新版本号: " + latestRevision);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
long startRevision = readLongInput("请输入开始版本号 (回车使用最新版本): ", latestRevision);
|
||||||
|
long endRevision = readLongInput("请输入结束版本号 (回车使用最新版本): ", latestRevision);
|
||||||
|
String filterUser = readInput("请输入过滤用户名 (包含匹配,回车跳过过滤): ");
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("正在获取日志...");
|
||||||
|
List<LogEntry> logs = fetcher.fetchLogs(startRevision, endRevision, filterUser);
|
||||||
|
|
||||||
|
if (logs.isEmpty()) {
|
||||||
|
System.out.println("没有找到符合条件的日志记录。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("获取到 " + logs.size() + " 条日志记录。");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 生成Markdown文件(保存到 md 目录)
|
||||||
|
String fileName = "md/svn_log_" + selectedProject.getName() + "_" + fileNameDateFormat.format(new Date()) + ".md";
|
||||||
|
generateMarkdown(fileName, url, username, startRevision, endRevision, filterUser, logs, fetcher);
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("日志已成功导出到: " + fileName);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
} catch (SVNException e) {
|
||||||
|
System.err.println("SVN错误: " + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("发生错误: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 让用户选择项目
|
||||||
|
*/
|
||||||
|
private static Project selectProject() {
|
||||||
|
System.out.println("请选择SVN项目:");
|
||||||
|
for (int i = 0; i < PRESET_PROJECTS.length; i++) {
|
||||||
|
System.out.println(" " + (i + 1) + ". " + PRESET_PROJECTS[i].getName());
|
||||||
|
}
|
||||||
|
System.out.println(" 0. 自定义SVN地址");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
System.out.print("请输入项目编号 (1-" + PRESET_PROJECTS.length + ", 0为自定义): ");
|
||||||
|
String input = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
int choice = Integer.parseInt(input);
|
||||||
|
|
||||||
|
if (choice == 0) {
|
||||||
|
String customUrl = readInput("请输入SVN仓库地址: ");
|
||||||
|
return new Project("自定义项目", customUrl);
|
||||||
|
} else if (choice >= 1 && choice <= PRESET_PROJECTS.length) {
|
||||||
|
return PRESET_PROJECTS[choice - 1];
|
||||||
|
} else {
|
||||||
|
System.out.println("输入无效,请重新选择!");
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.out.println("输入无效,请输入数字!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readInput(String prompt) {
|
||||||
|
System.out.print(prompt);
|
||||||
|
return scanner.nextLine().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readPassword(String prompt) {
|
||||||
|
if (System.console() != null) {
|
||||||
|
char[] password = System.console().readPassword("%s", prompt);
|
||||||
|
return new String(password);
|
||||||
|
} else {
|
||||||
|
System.out.print(prompt);
|
||||||
|
return scanner.nextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long readLongInput(String prompt, long defaultValue) {
|
||||||
|
System.out.print(prompt);
|
||||||
|
String input = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
if (input.isEmpty()) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Long.parseLong(input);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.out.println("输入无效,使用默认值: " + defaultValue);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateMarkdown(String fileName, String url, String username,
|
||||||
|
long startRevision, long endRevision, String filterUser,
|
||||||
|
List<LogEntry> logs, SVNLogFetcher fetcher) throws IOException {
|
||||||
|
StringBuilder markdown = new StringBuilder();
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
markdown.append("# SVN 日志报告\n\n");
|
||||||
|
|
||||||
|
// 查询条件(简化版)
|
||||||
|
markdown.append("## 查询条件\n\n");
|
||||||
|
markdown.append("- **SVN地址**: `").append(url).append("`\n");
|
||||||
|
markdown.append("- **版本范围**: r").append(startRevision).append(" - r").append(endRevision).append("\n");
|
||||||
|
if (filterUser != null && !filterUser.isEmpty()) {
|
||||||
|
markdown.append("- **过滤用户**: `").append(filterUser).append("`\n");
|
||||||
|
}
|
||||||
|
markdown.append("\n");
|
||||||
|
|
||||||
|
// 日志详情(简化版,只包含作者、时间、版本、提交信息)
|
||||||
|
markdown.append("## 日志详情\n\n");
|
||||||
|
|
||||||
|
for (LogEntry entry : logs) {
|
||||||
|
markdown.append("### r").append(entry.getRevision()).append("\n\n");
|
||||||
|
markdown.append("**作者**: `").append(entry.getAuthor()).append("` \n");
|
||||||
|
markdown.append("**时间**: ").append(fetcher.formatDate(entry.getDate())).append(" \n");
|
||||||
|
markdown.append("**版本**: r").append(entry.getRevision()).append("\n\n");
|
||||||
|
|
||||||
|
String message = entry.getMessage();
|
||||||
|
if (message != null && !message.isEmpty()) {
|
||||||
|
markdown.append("**提交信息**:\n\n");
|
||||||
|
markdown.append("```\n").append(message).append("\n```\n\n");
|
||||||
|
} else {
|
||||||
|
markdown.append("**提交信息**: (无)\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown.append("---\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入文件
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
|
||||||
|
writer.write(markdown.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目信息类
|
||||||
|
*/
|
||||||
|
private static class Project {
|
||||||
|
private String name;
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
public Project(String name, String url) {
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
98
svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java
Normal file
98
svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package com.svnlog;
|
||||||
|
|
||||||
|
import org.tmatesoft.svn.core.*;
|
||||||
|
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||||
|
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
|
||||||
|
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||||
|
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
|
||||||
|
import org.tmatesoft.svn.core.wc.SVNWCUtil;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SVNLogFetcher {
|
||||||
|
private String url;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private SVNRepository repository;
|
||||||
|
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public SVNLogFetcher(String url, String username, String password) throws SVNException {
|
||||||
|
this.url = url;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
|
||||||
|
SVNRepositoryFactoryImpl.setup();
|
||||||
|
this.repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
|
||||||
|
|
||||||
|
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password.toCharArray());
|
||||||
|
repository.setAuthenticationManager(authManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LogEntry> fetchLogs(long startRevision, long endRevision) throws SVNException {
|
||||||
|
return fetchLogs(startRevision, endRevision, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LogEntry> fetchLogs(long startRevision, long endRevision, String filterUser) throws SVNException {
|
||||||
|
List<LogEntry> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
if (startRevision < 0) {
|
||||||
|
startRevision = repository.getLatestRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endRevision < 0) {
|
||||||
|
endRevision = repository.getLatestRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startRevision > endRevision) {
|
||||||
|
long temp = startRevision;
|
||||||
|
startRevision = endRevision;
|
||||||
|
endRevision = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<SVNLogEntry> logEntries = repository.log(new String[]{""}, null, startRevision, endRevision, true, true);
|
||||||
|
|
||||||
|
for (SVNLogEntry logEntry : logEntries) {
|
||||||
|
String author = logEntry.getAuthor();
|
||||||
|
|
||||||
|
// 如果设置了用户名过滤器,则跳过不匹配的记录(包含匹配,不区分大小写)
|
||||||
|
if (filterUser != null && !filterUser.isEmpty() && (author == null || !author.toLowerCase().contains(filterUser.toLowerCase()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogEntry entry = new LogEntry();
|
||||||
|
entry.setRevision(logEntry.getRevision());
|
||||||
|
entry.setAuthor(author != null ? author : "(无作者)");
|
||||||
|
entry.setDate(logEntry.getDate());
|
||||||
|
entry.setMessage(logEntry.getMessage() != null ? logEntry.getMessage().trim() : "");
|
||||||
|
|
||||||
|
// 获取变更的文件路径
|
||||||
|
if (logEntry.getChangedPaths() != null) {
|
||||||
|
List<String> paths = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, SVNLogEntryPath> pathEntry : logEntry.getChangedPaths().entrySet()) {
|
||||||
|
paths.add(pathEntry.getKey());
|
||||||
|
}
|
||||||
|
entry.setChangedPaths(paths.toArray(new String[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按版本号降序排序
|
||||||
|
entries.sort((e1, e2) -> Long.compare(e2.getRevision(), e1.getRevision()));
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLatestRevision() throws SVNException {
|
||||||
|
return repository.getLatestRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatDate(Date date) {
|
||||||
|
return dateFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConnection() throws SVNException {
|
||||||
|
repository.testConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer$1.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer$1.class
Normal file
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer.class
Normal file
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/LogEntry.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/LogEntry.class
Normal file
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/Main$Project.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/Main$Project.class
Normal file
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/Main.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/Main.class
Normal file
Binary file not shown.
BIN
svn-log-tool/target/classes/com/svnlog/SVNLogFetcher.class
Normal file
BIN
svn-log-tool/target/classes/com/svnlog/SVNLogFetcher.class
Normal file
Binary file not shown.
3
svn-log-tool/target/maven-archiver/pom.properties
Normal file
3
svn-log-tool/target/maven-archiver/pom.properties
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
artifactId=svn-log-tool
|
||||||
|
groupId=com.svnlog
|
||||||
|
version=1.0.0
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
com/svnlog/DeepSeekLogProcessor.class
|
||||||
|
com/svnlog/ExcelAnalyzer.class
|
||||||
|
com/svnlog/DeepSeekLogProcessor$JSONArray.class
|
||||||
|
com/svnlog/SVNLogFetcher.class
|
||||||
|
com/svnlog/Main$Project.class
|
||||||
|
com/svnlog/DeepSeekLogProcessor$JSONObject.class
|
||||||
|
com/svnlog/Main.class
|
||||||
|
com/svnlog/LogEntry.class
|
||||||
|
com/svnlog/ExcelAnalyzer$1.class
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/home/liumangmang/opencode/日志/svn-log-tool/src/main/java/com/svnlog/LogEntry.java
|
||||||
|
/home/liumangmang/opencode/日志/svn-log-tool/src/main/java/com/svnlog/Main.java
|
||||||
|
/home/liumangmang/opencode/日志/svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java
|
||||||
|
/home/liumangmang/opencode/日志/svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java
|
||||||
|
/home/liumangmang/opencode/日志/svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java
|
||||||
BIN
svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar
Normal file
BIN
svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar
Normal file
Binary file not shown.
BIN
svn-log-tool/target/svn-log-tool-1.0.0.jar
Normal file
BIN
svn-log-tool/target/svn-log-tool-1.0.0.jar
Normal file
Binary file not shown.
BIN
test_excel_generation.class
Normal file
BIN
test_excel_generation.class
Normal file
Binary file not shown.
106
test_multifile_processor.sh
Executable file
106
test_multifile_processor.sh
Executable file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 测试多文件处理功能
|
||||||
|
# 注意:此脚本需要有效的 DeepSeek API Key 才能完成测试
|
||||||
|
|
||||||
|
cd /home/liumangmang/opencode/日志
|
||||||
|
|
||||||
|
echo "==========================================="
|
||||||
|
echo " 测试 DeepSeek 日志分析工具"
|
||||||
|
echo "==========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查是否有日志文件
|
||||||
|
md_files=$(find . -maxdepth 1 -name "svn_log_*.md" | wc -l)
|
||||||
|
|
||||||
|
if [ "$md_files" -eq 0 ]; then
|
||||||
|
echo "警告: 当前目录没有找到 svn_log_*.md 文件"
|
||||||
|
echo "请先使用 Main.java 生成日志文件"
|
||||||
|
echo ""
|
||||||
|
echo "或者手动创建测试文件..."
|
||||||
|
# 创建测试文件
|
||||||
|
cat > test_project1.md << 'EOF'
|
||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
- **SVN地址**: `https://test.svn.com/project1`
|
||||||
|
- **账号**: `testuser`
|
||||||
|
- **版本范围**: r1 - r10
|
||||||
|
- **生成时间**: 2026-01-30
|
||||||
|
|
||||||
|
## 统计信息
|
||||||
|
- **总记录数**: 2 条
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r10
|
||||||
|
**作者**: `liujing@SZNARI`
|
||||||
|
**时间**: 2026-01-27 10:00:00
|
||||||
|
**版本**: r10
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
feat: 添加用户登录功能
|
||||||
|
|
||||||
|
### r9
|
||||||
|
**作者**: `liujing@SZNARI`
|
||||||
|
**时间**: 2026-01-26 15:00:00
|
||||||
|
**版本**: r9
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
fix: 修复登录页面样式问题
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > test_project2.md << 'EOF'
|
||||||
|
# SVN 日志报告
|
||||||
|
|
||||||
|
## 查询条件
|
||||||
|
- **SVN地址**: `https://test.svn.com/project2`
|
||||||
|
- **账号**: `testuser`
|
||||||
|
- **版本范围**: r1 - r10
|
||||||
|
- **生成时间**: 2026-01-30
|
||||||
|
|
||||||
|
## 统计信息
|
||||||
|
- **总记录数**: 1 条
|
||||||
|
|
||||||
|
## 日志详情
|
||||||
|
|
||||||
|
### r8
|
||||||
|
**作者**: `liujing@SZNARI`
|
||||||
|
**时间**: 2026-01-25 14:00:00
|
||||||
|
**版本**: r8
|
||||||
|
|
||||||
|
**提交信息**:
|
||||||
|
refactor: 优化数据库查询性能
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "已创建测试文件: test_project1.md, test_project2.md"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "当前目录下的日志文件:"
|
||||||
|
ls -lh svn_log_*.md test_*.md 2>/dev/null || echo " (无文件)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "==========================================="
|
||||||
|
echo " 程序使用说明"
|
||||||
|
echo "==========================================="
|
||||||
|
echo ""
|
||||||
|
echo "要运行 DeepSeek 日志分析工具,请执行:"
|
||||||
|
echo ""
|
||||||
|
echo " cd /home/liumangmang/opencode/日志"
|
||||||
|
echo " java -jar svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar"
|
||||||
|
echo ""
|
||||||
|
echo "然后按提示输入:"
|
||||||
|
echo " 1. 日志文件所在目录路径(回车使用当前目录)"
|
||||||
|
echo " 2. 工作周期(例如:2025年12月)"
|
||||||
|
echo " 3. DeepSeek API Key"
|
||||||
|
echo " 4. 输出 Excel 文件名(回车使用默认)"
|
||||||
|
echo ""
|
||||||
|
echo "程序将自动读取目录中的所有 .md 文件,合并后发送给 DeepSeek API 分析,"
|
||||||
|
echo "并生成包含多项目工作内容的 Excel 文件。"
|
||||||
|
echo ""
|
||||||
|
echo "Excel 输出格式(与参考文件一致):"
|
||||||
|
echo " - 7列:序号、所属班组、技术对接、开发人员、工作周期、开发项目名称、具体工作内容"
|
||||||
|
echo " - 项目名称用 / 分隔(如:PRS7050/PRS7950)"
|
||||||
|
echo " - 工作内容用 # 标识不同项目"
|
||||||
|
echo ""
|
||||||
Reference in New Issue
Block a user