commit af02989ecbf74b00640e7715405d02f7618bee3c Author: liumangmang Date: Wed Feb 4 16:03:17 2026 +0800 Initial commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..9120440 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..6560bd8 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..b074d70 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..af45d64 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + 用户定义 + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..10456db --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/日志.iml b/.idea/日志.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/日志.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.iflow/settings.json b/.iflow/settings.json new file mode 100644 index 0000000..bf363a1 --- /dev/null +++ b/.iflow/settings.json @@ -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", "."]}}} \ No newline at end of file diff --git a/202601工作量统计_刘靖.xlsx b/202601工作量统计_刘靖.xlsx new file mode 100644 index 0000000..662d28b Binary files /dev/null and b/202601工作量统计_刘靖.xlsx differ diff --git a/md/svn_log_PRS-7050场站智慧管控_20260130_102309.md b/md/svn_log_PRS-7050场站智慧管控_20260130_102309.md new file mode 100644 index 0000000..7e85d3d --- /dev/null +++ b/md/svn_log_PRS-7050场站智慧管控_20260130_102309.md @@ -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进程的代码,避免重复关闭造成问题 +``` + +--- + diff --git a/md/svn_log_PRS-7950在线巡视_20260130_102437.md b/md/svn_log_PRS-7950在线巡视_20260130_102437.md new file mode 100644 index 0000000..afd811f --- /dev/null +++ b/md/svn_log_PRS-7950在线巡视_20260130_102437.md @@ -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字段 +- 各新增字段用于存储原始数据,便于后续数据处理与追踪 +``` + +--- + diff --git a/md/svn_log_PRS-7950在线巡视电科院测试版_20260130_102600.md b/md/svn_log_PRS-7950在线巡视电科院测试版_20260130_102600.md new file mode 100644 index 0000000..3d20c63 --- /dev/null +++ b/md/svn_log_PRS-7950在线巡视电科院测试版_20260130_102600.md @@ -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进行下发 +``` + +--- + diff --git a/svn-log-tool/README_DeepSeek.md b/svn-log-tool/README_DeepSeek.md new file mode 100644 index 0000000..e62b135 --- /dev/null +++ b/svn-log-tool/README_DeepSeek.md @@ -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处理 + +## 许可证 + +本工具仅供内部使用。 \ No newline at end of file diff --git a/svn-log-tool/example_log.md b/svn-log-tool/example_log.md new file mode 100644 index 0000000..5ec127e --- /dev/null +++ b/svn-log-tool/example_log.md @@ -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. 实现序列化接口 + +# 兼容性 +- 保持向后兼容 +- 更新相关测试用例 +``` + +--- \ No newline at end of file diff --git a/svn-log-tool/pom.xml b/svn-log-tool/pom.xml new file mode 100644 index 0000000..863f19f --- /dev/null +++ b/svn-log-tool/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + com.svnlog + svn-log-tool + 1.0.0 + jar + + SVN Log Tool + SVN日志查询工具,支持版本范围过滤和用户名过滤,可导出Markdown格式 + + + UTF-8 + 1.8 + 1.8 + + + + + + org.tmatesoft.svnkit + svnkit + 1.10.11 + + + + + org.apache.poi + poi + 5.2.5 + + + org.apache.poi + poi-ooxml + 5.2.5 + + + + + com.squareup.okhttp3 + okhttp + 4.12.0 + + + + + com.google.code.gson + gson + 2.10.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + com.svnlog.Main + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + jar-with-dependencies + + + + com.svnlog.Main + + + + + + make-assembly + package + + single + + + + + + + \ No newline at end of file diff --git a/svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java b/svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java new file mode 100644 index 0000000..bd47ec8 --- /dev/null +++ b/svn-log-tool/src/main/java/com/svnlog/DeepSeekLogProcessor.java @@ -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 java.util.List toList() { + java.util.List list = new ArrayList<>(); + for (int i = 0; i < jsonArray.size(); i++) { + list.add(get(i)); + } + return list; + } + } +} diff --git a/svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java b/svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java new file mode 100644 index 0000000..12b39eb --- /dev/null +++ b/svn-log-tool/src/main/java/com/svnlog/ExcelAnalyzer.java @@ -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 ""; + } + } +} \ No newline at end of file diff --git a/svn-log-tool/src/main/java/com/svnlog/LogEntry.java b/svn-log-tool/src/main/java/com/svnlog/LogEntry.java new file mode 100644 index 0000000..58054ad --- /dev/null +++ b/svn-log-tool/src/main/java/com/svnlog/LogEntry.java @@ -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 + '\'' + + '}'; + } +} diff --git a/svn-log-tool/src/main/java/com/svnlog/Main.java b/svn-log-tool/src/main/java/com/svnlog/Main.java new file mode 100644 index 0000000..70a8552 --- /dev/null +++ b/svn-log-tool/src/main/java/com/svnlog/Main.java @@ -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 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 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; + } + } +} \ No newline at end of file diff --git a/svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java b/svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java new file mode 100644 index 0000000..5e0875a --- /dev/null +++ b/svn-log-tool/src/main/java/com/svnlog/SVNLogFetcher.java @@ -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 fetchLogs(long startRevision, long endRevision) throws SVNException { + return fetchLogs(startRevision, endRevision, null); + } + + public List fetchLogs(long startRevision, long endRevision, String filterUser) throws SVNException { + List 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 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 paths = new ArrayList<>(); + for (Map.Entry 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(); + } +} \ No newline at end of file diff --git a/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONArray.class b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONArray.class new file mode 100644 index 0000000..a68758d Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONArray.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONObject.class b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONObject.class new file mode 100644 index 0000000..9638776 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor$JSONObject.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor.class b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor.class new file mode 100644 index 0000000..2301955 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/DeepSeekLogProcessor.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer$1.class b/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer$1.class new file mode 100644 index 0000000..3ff52af Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer$1.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer.class b/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer.class new file mode 100644 index 0000000..1c30e74 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/ExcelAnalyzer.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/LogEntry.class b/svn-log-tool/target/classes/com/svnlog/LogEntry.class new file mode 100644 index 0000000..65cd463 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/LogEntry.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/Main$Project.class b/svn-log-tool/target/classes/com/svnlog/Main$Project.class new file mode 100644 index 0000000..149e773 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/Main$Project.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/Main.class b/svn-log-tool/target/classes/com/svnlog/Main.class new file mode 100644 index 0000000..a151163 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/Main.class differ diff --git a/svn-log-tool/target/classes/com/svnlog/SVNLogFetcher.class b/svn-log-tool/target/classes/com/svnlog/SVNLogFetcher.class new file mode 100644 index 0000000..0d59a44 Binary files /dev/null and b/svn-log-tool/target/classes/com/svnlog/SVNLogFetcher.class differ diff --git a/svn-log-tool/target/maven-archiver/pom.properties b/svn-log-tool/target/maven-archiver/pom.properties new file mode 100644 index 0000000..bb24917 --- /dev/null +++ b/svn-log-tool/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=svn-log-tool +groupId=com.svnlog +version=1.0.0 diff --git a/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..40b612b --- /dev/null +++ b/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -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 diff --git a/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..6569bce --- /dev/null +++ b/svn-log-tool/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -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 diff --git a/svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar b/svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar new file mode 100644 index 0000000..8d4a643 Binary files /dev/null and b/svn-log-tool/target/svn-log-tool-1.0.0-jar-with-dependencies.jar differ diff --git a/svn-log-tool/target/svn-log-tool-1.0.0.jar b/svn-log-tool/target/svn-log-tool-1.0.0.jar new file mode 100644 index 0000000..d0ae40f Binary files /dev/null and b/svn-log-tool/target/svn-log-tool-1.0.0.jar differ diff --git a/test_excel_generation.class b/test_excel_generation.class new file mode 100644 index 0000000..080e301 Binary files /dev/null and b/test_excel_generation.class differ diff --git a/test_multifile_processor.sh b/test_multifile_processor.sh new file mode 100755 index 0000000..af76d06 --- /dev/null +++ b/test_multifile_processor.sh @@ -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 "" \ No newline at end of file