Initial commit
This commit is contained in:
Generated
+8
@@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
Generated
+13
@@ -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>
|
||||
Generated
+7
@@ -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>
|
||||
Generated
+20
@@ -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>
|
||||
Generated
+26
@@ -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>
|
||||
Generated
+8
@@ -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>
|
||||
Generated
+9
@@ -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>
|
||||
@@ -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", "."]}}}
|
||||
Binary file not shown.
@@ -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进程的代码,避免重复关闭造成问题
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -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字段
|
||||
- 各新增字段用于存储原始数据,便于后续数据处理与追踪
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -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进行下发
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -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处理
|
||||
|
||||
## 许可证
|
||||
|
||||
本工具仅供内部使用。
|
||||
@@ -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. 实现序列化接口
|
||||
|
||||
# 兼容性
|
||||
- 保持向后兼容
|
||||
- 更新相关测试用例
|
||||
```
|
||||
|
||||
---
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
artifactId=svn-log-tool
|
||||
groupId=com.svnlog
|
||||
version=1.0.0
|
||||
+9
@@ -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
|
||||
+5
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+106
@@ -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