diff --git a/.obsidian/plugins/remember-cursor-position/cursor-positions.json b/.obsidian/plugins/remember-cursor-position/cursor-positions.json index 63badeb..c730f08 100644 --- a/.obsidian/plugins/remember-cursor-position/cursor-positions.json +++ b/.obsidian/plugins/remember-cursor-position/cursor-positions.json @@ -1 +1 @@ -{"月度/8月/8月.md":{"scroll":150.7352,"cursor":{"from":{"ch":20,"line":164},"to":{"ch":20,"line":164}}},"材料/服务器.md":{"scroll":20.5975,"cursor":{"from":{"ch":17,"line":31},"to":{"ch":29,"line":31}}},"月度/9月/9月.md":{"scroll":378.1023,"cursor":{"from":{"ch":26,"line":389},"to":{"ch":26,"line":389}}},"月度/7月/7月.md":{"scroll":0,"cursor":{"from":{"ch":29,"line":147},"to":{"ch":29,"line":147}}},"月度/6月/6月.md":{"scroll":0,"cursor":{"from":{"ch":23,"line":120},"to":{"ch":23,"line":120}}},"月度/5月/5月.md":{"scroll":93.1957,"cursor":{"from":{"ch":20,"line":105},"to":{"ch":20,"line":105}}},"月度/4月/4月.md":{"scroll":120.1806,"cursor":{"from":{"ch":20,"line":139},"to":{"ch":20,"line":139}}},"月度/3月/3月.md":{"scroll":31.0412,"cursor":{"from":{"ch":6,"line":39},"to":{"ch":6,"line":39}}},"月度/7月/7月工作总结及8月工作计划.md":{"scroll":0,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/6月/6月份晨午检bug修复.md":{"scroll":307.9981,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/7月/设备管理中心研发记录.md":{"scroll":108.9598,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/8月/CA身份认证app/CA身份认证app流程图.md":{"scroll":5.8654,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/常见病/20250903常见病优化沟通.md":{"scroll":0.7205,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/对接主机/不登录模式接口文档.md":{"scroll":0,"cursor":{"from":{"ch":5,"line":8},"to":{"ch":5,"line":8}}},"月度/9月/汇海/对接主机/登录算法和密钥.md":{"scroll":0,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/对接主机/华夏汇海接口文档.md":{"scroll":1133.8083,"cursor":{"from":{"ch":96,"line":1670},"to":{"ch":96,"line":1670}}},"材料/配置/Obsidian快捷键.md":{"scroll":0,"cursor":{"from":{"ch":18,"line":16},"to":{"ch":18,"line":16}}},"材料/配置/工具.md":{"scroll":0,"cursor":{"from":{"ch":50,"line":0},"to":{"ch":50,"line":0}}},"月度/9月/石榴籽-家校通/家校通需求.md":{"scroll":22.9513,"cursor":{"from":{"ch":13,"line":37},"to":{"ch":13,"line":37}}},"月度/9月/汇海/体质测试数据上传接口文档.md":{"scroll":64.4749,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/解析汇海设备请求.md":{"scroll":1331.4598,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/156中 中考模拟 初三.md":{"scroll":8.0497,"cursor":{"from":{"ch":0,"line":20},"to":{"ch":0,"line":20}}},"月度/10月/10月.md":{"scroll":0,"cursor":{"from":{"ch":12,"line":0},"to":{"ch":0,"line":0}}},"月度/11月/11月.md":{"scroll":579.7556,"cursor":{"from":{"ch":7,"line":600},"to":{"ch":7,"line":600}}},"月度/10月/第86届中国教育装备展/智慧体育.md":{"scroll":0.0271,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/11月/家校协同/11.11家校协同会议.md":{"scroll":49.3825,"cursor":{"from":{"ch":0,"line":77},"to":{"ch":0,"line":77}}}} \ No newline at end of file +{"月度/8月/8月.md":{"scroll":150.7352,"cursor":{"from":{"ch":20,"line":164},"to":{"ch":20,"line":164}}},"材料/服务器.md":{"scroll":20.5975,"cursor":{"from":{"ch":17,"line":31},"to":{"ch":29,"line":31}}},"月度/9月/9月.md":{"scroll":378.1023,"cursor":{"from":{"ch":26,"line":389},"to":{"ch":26,"line":389}}},"月度/7月/7月.md":{"scroll":0,"cursor":{"from":{"ch":29,"line":147},"to":{"ch":29,"line":147}}},"月度/6月/6月.md":{"scroll":0,"cursor":{"from":{"ch":23,"line":120},"to":{"ch":23,"line":120}}},"月度/5月/5月.md":{"scroll":93.1957,"cursor":{"from":{"ch":20,"line":105},"to":{"ch":20,"line":105}}},"月度/4月/4月.md":{"scroll":120.1806,"cursor":{"from":{"ch":20,"line":139},"to":{"ch":20,"line":139}}},"月度/3月/3月.md":{"scroll":31.0412,"cursor":{"from":{"ch":6,"line":39},"to":{"ch":6,"line":39}}},"月度/7月/7月工作总结及8月工作计划.md":{"scroll":0,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/6月/6月份晨午检bug修复.md":{"scroll":307.9981,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/7月/设备管理中心研发记录.md":{"scroll":108.9598,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/8月/CA身份认证app/CA身份认证app流程图.md":{"scroll":5.8654,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/常见病/20250903常见病优化沟通.md":{"scroll":0.7205,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/对接主机/不登录模式接口文档.md":{"scroll":0,"cursor":{"from":{"ch":5,"line":8},"to":{"ch":5,"line":8}}},"月度/9月/汇海/对接主机/登录算法和密钥.md":{"scroll":0,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/对接主机/华夏汇海接口文档.md":{"scroll":1133.8083,"cursor":{"from":{"ch":96,"line":1670},"to":{"ch":96,"line":1670}}},"材料/配置/Obsidian快捷键.md":{"scroll":0,"cursor":{"from":{"ch":18,"line":16},"to":{"ch":18,"line":16}}},"材料/配置/工具.md":{"scroll":0,"cursor":{"from":{"ch":50,"line":0},"to":{"ch":50,"line":0}}},"月度/9月/石榴籽-家校通/家校通需求.md":{"scroll":22.9513,"cursor":{"from":{"ch":13,"line":37},"to":{"ch":13,"line":37}}},"月度/9月/汇海/体质测试数据上传接口文档.md":{"scroll":64.4749,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/汇海/解析汇海设备请求.md":{"scroll":1331.4598,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/9月/156中 中考模拟 初三.md":{"scroll":8.0497,"cursor":{"from":{"ch":0,"line":20},"to":{"ch":0,"line":20}}},"月度/10月/10月.md":{"scroll":0,"cursor":{"from":{"ch":12,"line":0},"to":{"ch":0,"line":0}}},"月度/11月/11月.md":{"scroll":639.0128,"cursor":{"from":{"ch":33,"line":659},"to":{"ch":33,"line":659}}},"月度/10月/第86届中国教育装备展/智慧体育.md":{"scroll":0.0271,"cursor":{"from":{"ch":0,"line":0},"to":{"ch":0,"line":0}}},"月度/11月/家校协同/11.11家校协同会议.md":{"scroll":49.3825,"cursor":{"from":{"ch":0,"line":77},"to":{"ch":0,"line":77}}}} \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 204ef41..accec0a 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -190,32 +190,32 @@ }, "active": "d042930aea8ec533", "lastOpenFiles": [ - "月度/11月/家校协同/方老师谈技术部运营与团队建设.docx", - "月度/11月/家校协同/石榴籽家校协同平台上线总结.docx", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603.png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(2).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(1).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602.png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(2).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(1).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601.png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(2).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(1).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi", + "月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603.png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(2).png", + "月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi", + "月度/11月/家校协同/晨午检_slices/mipmap-mdpi", + "月度/11月/家校协同/晨午检_slices/mipmap-xhdpi", + "月度/11月/家校协同/晨午检_slices/mipmap-hdpi", + "月度/11月/家校协同/晨午检_slices", + "月度/11月/家校协同/晨午检_slices.zip", + "月度/11月/晨午检脚本/oom_monitor.sh", + "月度/11月/晨午检脚本/新建 文本文档.sh", + "月度/11月/晨午检脚本/新建 文本文档.txt", "月度/11月/11月.md", "材料/服务器.md", - "月度/11月/家校协同/静态资源/积分图片/书包.png", - "月度/11月/家校协同/静态资源/积分图片/a2b56bd9e659e81e5e2f885874eb1343.png", - "月度/11月/家校协同/静态资源/积分图片/笔记本.png", - "月度/11月/家校协同/静态资源/积分图片/07bd0ac6326212be1805bd13eb56c034.png", - "月度/11月/家校协同/静态资源/积分图片/笔记本.jpg", - "月度/11月/家校协同/静态资源/积分图片/5ab4d653712a5dace75499f357586b32.jpg", - "月度/11月/家校协同/静态资源/积分图片/书包.jpg", - "月度/11月/家校协同/静态资源/积分图片/8cbd0acc7aa5f88c9a70866c68988193(1).jpg", - "月度/11月/家校协同/静态资源/积分图片/水杯.jpg", - "月度/11月/家校协同/静态资源/积分图片/1dc829b8fa3ed234288b053bc67343e2(1).jpg", - "月度/11月/家校协同/静态资源/积分图片", - "月度/11月/家校协同/静态资源/新建文件夹", "月度/11月/家校协同/11.11家校协同会议.md", "月度/8月/8月.md", "月度/9月/9月.md", - "月度/11月/家校协同/静态资源/轮播图", - "月度/11月/家校协同/静态资源/首页图标", - "月度/11月/家校协同/静态资源", - "月度/11月/家校协同/新建文件夹", - "月度/11月/家校协同/家校协同功能列表~C7D9E.tmp", - "月度/11月/家校协同/数据要素获奖名单.pdf", - "月度/11月/家校协同/25年“数据要素×”大赛新疆分赛闭幕式通知.pdf", "月度/9月/156中 中考模拟 初三.md", "月度/7月/设备管理中心研发记录.md", "月度/8月/8.8技术部研讨会议纪要.md", diff --git a/月度/11月/11月.md b/月度/11月/11月.md index 161ee0e..f9e3b4c 100644 --- a/月度/11月/11月.md +++ b/月度/11月/11月.md @@ -613,4 +613,55 @@ feat(food): 新增菜谱推荐功能 - 完善食材与步骤的显示逻辑 - 添加小贴士展示功能 - 优化菜谱描述文本清理逻辑 -- 更新页面标题文字统一为“食物营养查询” \ No newline at end of file +- 更新页面标题文字统一为“食物营养查询” + +2.巴州常见病手动导入学生 + + +2.石榴籽 +feat(yyjk): 新增学生菜谱推荐及详情页面 +- 新增菜谱详情页面 (pages/yyjk/detail.vue),展示三餐详情及饮食建议 +- 实现菜谱数据获取接口 (getRecipe) 并在首页集成 +- 新增菜谱详情页路由配置及页面结构 +- 移除食谱推荐中的图片展示,简化UI并增加加载状态 +- 增加AI生成菜谱的异步处理与缓存逻辑 +- 完成菜谱数据结构解析与前端展示适配 +- 引入fastjson2依赖以支持菜谱数据解析 +- 添加菜谱服务端缓存机制,提升性能与用户体验 +- 修复学生数据查询空指针异常 + + +# 11.20 +1.巴州常见病手动导入学生进行修复 +[[和硕县幼儿园学生信息导入模板 (修改名单)110120.xls]] + + +2.优化晨午检启动脚本 +![[tomcat.sh]] + 增加晨午检oom监测脚本 +![[oom_monitor.sh]] + + +3.石榴籽 +**小程序** +食物营养查询底部按钮增加图标 +feat(components): 添加全局底部导航组件并集成到食物相关页面 +- 创建 BottomNav 组件,包含分类、搜索、推荐三个导航项 +- 为导航项添加激活状态样式及图标切换逻辑 +- 在 food 相关页面中引入并使用 BottomNav 组件 +- 移除原有重复的底部导航代码 +- 调整搜索页面列表高度以适配底部导航 + +**后端前端** +feat(ops): 新增书籍管理功能模块 +- 添加书籍实体类 Book 及其相关字段和方法 +- 添加章节实体类 BookChapter 及其相关字段和方法 +- 添加小节实体类 BookSection 及其相关字段和方法 +- 添加文本内容实体类 SectionText 及其相关字段和方法 +- 创建书籍、章节、小节和文本内容的 Mapper 接口 +- 实现书籍完整数据查询服务 selectBookWithDetails +- 添加事务支持以确保数据一致性 +- 配置 MyBatis 映射文件及 SQL 查询逻辑 + + + diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(1).png new file mode 100644 index 0000000..d97a128 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(2).png new file mode 100644 index 0000000..cf84efc Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601.png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601.png new file mode 100644 index 0000000..7559f3b Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319601.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(1).png new file mode 100644 index 0000000..aab6134 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(2).png new file mode 100644 index 0000000..b4b77ae Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602.png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602.png new file mode 100644 index 0000000..6c7e498 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319602.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(1).png new file mode 100644 index 0000000..7cf3544 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(2).png new file mode 100644 index 0000000..ac6e437 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603.png b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603.png new file mode 100644 index 0000000..76f81ad Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-hdpi/Frame_427319603.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601(1).png new file mode 100644 index 0000000..6c24a65 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601.png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601.png new file mode 100644 index 0000000..2de4a5a Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319601.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602(1).png new file mode 100644 index 0000000..e78b4c6 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602.png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602.png new file mode 100644 index 0000000..c01a1af Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319602.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603(2).png new file mode 100644 index 0000000..93335aa Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603.png b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603.png new file mode 100644 index 0000000..ac7f69d Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-mdpi/Frame_427319603.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(1).png new file mode 100644 index 0000000..ec71041 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(2).png new file mode 100644 index 0000000..c762c18 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601.png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601.png new file mode 100644 index 0000000..3c82139 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319601.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(1).png new file mode 100644 index 0000000..b13a29d Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(2).png new file mode 100644 index 0000000..36f9af6 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602.png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602.png new file mode 100644 index 0000000..0b2412e Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319602.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(1).png new file mode 100644 index 0000000..e745cd5 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(2).png new file mode 100644 index 0000000..730ae36 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603.png b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603.png new file mode 100644 index 0000000..13b9a60 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xhdpi/Frame_427319603.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(1).png new file mode 100644 index 0000000..49cd8af Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(2).png new file mode 100644 index 0000000..c60292e Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601.png new file mode 100644 index 0000000..c60292e Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319601.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(1).png new file mode 100644 index 0000000..900777f Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(2).png new file mode 100644 index 0000000..900777f Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602.png new file mode 100644 index 0000000..1cbca55 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319602.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(1).png new file mode 100644 index 0000000..3f3a499 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(2).png new file mode 100644 index 0000000..f212427 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603.png new file mode 100644 index 0000000..3f3a499 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxhdpi/Frame_427319603.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(1).png new file mode 100644 index 0000000..5d3acc1 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(2).png new file mode 100644 index 0000000..3d516dd Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601.png new file mode 100644 index 0000000..3d516dd Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319601.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(1).png new file mode 100644 index 0000000..66c9011 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(2).png new file mode 100644 index 0000000..66c9011 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602.png new file mode 100644 index 0000000..3071a44 Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319602.png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(1).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(1).png new file mode 100644 index 0000000..0a4cd9e Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(1).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(2).png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(2).png new file mode 100644 index 0000000..11a705d Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603(2).png differ diff --git a/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603.png b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603.png new file mode 100644 index 0000000..0a4cd9e Binary files /dev/null and b/月度/11月/家校协同/晨午检_slices/mipmap-xxxhdpi/Frame_427319603.png differ diff --git a/月度/11月/巴州常见病需求/和硕县幼儿园学生信息导入模板 (修改名单)110120.xls b/月度/11月/巴州常见病需求/和硕县幼儿园学生信息导入模板 (修改名单)110120.xls new file mode 100644 index 0000000..54e1791 Binary files /dev/null and b/月度/11月/巴州常见病需求/和硕县幼儿园学生信息导入模板 (修改名单)110120.xls differ diff --git a/月度/11月/晨午检脚本/oom_monitor.sh b/月度/11月/晨午检脚本/oom_monitor.sh new file mode 100644 index 0000000..d21a6ed --- /dev/null +++ b/月度/11月/晨午检脚本/oom_monitor.sh @@ -0,0 +1,512 @@ +#!/bin/bash + +# OOM监控配置 +readonly MONITOR_INTERVAL=30 # 检查间隔(秒) +readonly OOM_KEYWORDS=("java.lang.OutOfMemoryError" "OutOfMemoryError" "java.lang.OutOfMemory") +readonly MAX_RESTART_ATTEMPTS=3 # 最大重启尝试次数 +readonly RESTART_COOLDOWN=300 # 重启冷却时间(秒) + +# 内存阈值配置(根据您的实际情况调整) +readonly MEMORY_THRESHOLD_GB=6 # 内存阈值(GB),超过此值才认为是内存使用过高 +readonly MEMORY_THRESHOLD_KB=$((MEMORY_THRESHOLD_GB * 1024 * 1024)) # 转换为KB + +# 日志配置 +readonly LOG_FILE="/home/chenwujian2/script/logs/oom_monitor.log" +readonly STATUS_FILE="/home/chenwujian2/script/logs/oom_status.json" + +# Tomcat实例配置 (端口:基础路径) +declare -A TOMCAT_INSTANCES=( + [90105]="/home/chenwujian" + [90106]="/home/chenwujian" + [90107]="/home/chenwujian2" + [90108]="/home/chenwujian2" +) + +# 颜色定义 +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly NC='\033[0m' + +# 获取Tomcat完整路径 +get_tomcat_path() { + local port=$1 + local base_path="${TOMCAT_INSTANCES[$port]}" + echo "${base_path}/tomcat${port}" +} + +# 获取所有监控的端口 +get_monitor_ports() { + echo "${!TOMCAT_INSTANCES[@]}" +} + +# 日志函数 +log() { + local message="$1" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "${GREEN}[${timestamp}] $message${NC}" + echo "[${timestamp}] $message" >> "$LOG_FILE" +} + +warn() { + local message="$1" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "${YELLOW}[${timestamp}] 警告: $message${NC}" + echo "[${timestamp}] 警告: $message" >> "$LOG_FILE" +} + +error() { + local message="$1" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "${RED}[${timestamp}] 错误: $message${NC}" + echo "[${timestamp}] 错误: $message" >> "$LOG_FILE" +} + +info() { + local message="$1" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "${BLUE}[${timestamp}] $message${NC}" + echo "[${timestamp}] $message" >> "$LOG_FILE" +} + +# 初始化状态文件 +init_status_file() { + if [ ! -f "$STATUS_FILE" ]; then + cat > "$STATUS_FILE" << EOF +{ + "monitor_start_time": "$(date '+%Y-%m-%d %H:%M:%S')", + "restart_records": {} +} +EOF + fi + + # 创建日志目录 + local log_dir=$(dirname "$LOG_FILE") + mkdir -p "$log_dir" +} + +# 获取Tomcat进程PID +get_tomcat_pid() { + local port=$1 + local tomcat_path=$(get_tomcat_path "$port") + + # 方法1: 通过catalina.base路径查找 + local pid=$(ps -ef | grep java | grep "catalina.base=${tomcat_path}" | grep -v grep | awk '{print $2}') + + # 方法2: 如果方法1没找到,通过端口查找 + if [ -z "$pid" ]; then + pid=$(netstat -tlnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f1 | grep -v '^-$' | grep -v '^$') + fi + + echo "$pid" +} + +# 检查Tomcat是否运行 +is_tomcat_running() { + local port=$1 + local pid=$(get_tomcat_pid "$port") + if [ -n "$pid" ] && ps -p "$pid" > /dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +# 检查OOM错误 +check_oom_error() { + local port=$1 + local tomcat_path=$(get_tomcat_path "$port") + local log_file="${tomcat_path}/logs/catalina.out" + + if [ ! -f "$log_file" ]; then + return 1 + fi + + # 检查最近的日志中是否有OOM错误(最近1000行) + for keyword in "${OOM_KEYWORDS[@]}"; do + if tail -n 1000 "$log_file" | grep -i "$keyword" > /dev/null 2>&1; then + # 获取OOM错误的具体信息 + local oom_line=$(tail -n 1000 "$log_file" | grep -i "$keyword" | tail -1) + log "检测到Tomcat $port OOM错误: $oom_line" + return 0 + fi + done + + return 1 +} + +# 检查系统dmesg中的OOM killer +check_dmesg_oom() { + local port=$1 + local pid=$(get_tomcat_pid "$port") + + if [ -n "$pid" ]; then + # 检查dmesg中是否有该进程被OOM killer杀死的记录 + if dmesg | grep -i "killed process.*java.*$pid" > /dev/null 2>&1; then + local oom_info=$(dmesg | grep -i "killed process.*java.*$pid" | tail -1) + log "检测到系统OOM Killer杀死了Tomcat $port (PID: $pid): $oom_info" + return 0 + fi + fi + + return 1 +} + +# 检查内存使用情况(改进版) +check_memory_usage() { + local port=$1 + local pid=$(get_tomcat_pid "$port") + + if [ -z "$pid" ]; then + return 1 + fi + + # 获取Java进程内存使用情况 + local mem_info=$(ps -o pid,rss,vsz,pmem,comm -p "$pid" 2>/dev/null | grep java) + if [ -n "$mem_info" ]; then + local rss=$(echo "$mem_info" | awk '{print $2}') # 物理内存(KB) + local vsz=$(echo "$mem_info" | awk '{print $3}') # 虚拟内存(KB) + local rss_gb=$((rss / 1024 / 1024)) + local vsz_gb=$((vsz / 1024 / 1024)) + + # 记录内存使用情况(不触发重启) + info "Tomcat $port 内存使用: RSS=${rss_gb}GB (${rss}KB) VSZ=${vsz_gb}GB (${vsz}KB)" + + # 如果RSS超过阈值,认为内存使用过高 + if [ "$rss" -gt "$MEMORY_THRESHOLD_KB" ]; then + warn "Tomcat $port 内存使用过高: RSS=${rss_gb}GB (超过${MEMORY_THRESHOLD_GB}GB阈值)" + return 0 + fi + fi + + return 1 +} + +# 重启Tomcat +restart_tomcat() { + local port=$1 + local reason="$2" + local tomcat_path=$(get_tomcat_path "$port") + + log "准备重启Tomcat $port,原因: $reason" + log "Tomcat路径: $tomcat_path" + + # 停止Tomcat + if [ -f "${tomcat_path}/bin/shutdown.sh" ]; then + info "停止Tomcat $port..." + if sh "${tomcat_path}/bin/shutdown.sh"; then + log "Tomcat $port 停止命令已发送" + else + warn "Tomcat $port 停止过程中可能出现问题" + fi + else + error "Tomcat $port 停止脚本不存在: ${tomcat_path}/bin/shutdown.sh" + return 1 + fi + + # 等待停止 + sleep 5 + + # 强制杀死残留进程 + local pid=$(get_tomcat_pid "$port") + if [ -n "$pid" ]; then + warn "强制杀死Tomcat $port 残留进程: $pid" + kill -9 "$pid" 2>/dev/null + sleep 2 + fi + + # 备份OOM日志(只有在真正OOM时才备份) + if [ "$reason" = "应用层OOM错误" ] || [ "$reason" = "系统OOM Killer" ]; then + local log_file="${tomcat_path}/logs/catalina.out" + if [ -f "$log_file" ]; then + local backup_name="${log_file}.oom.$(date +%Y%m%d_%H%M%S)" + cp "$log_file" "$backup_name" + log "OOM日志已备份: $backup_name" + + # 清空原日志文件 + > "$log_file" + fi + fi + + # 启动Tomcat + if [ -f "${tomcat_path}/bin/startup.sh" ]; then + info "启动Tomcat $port..." + if sh "${tomcat_path}/bin/startup.sh"; then + log "Tomcat $port 启动命令已执行" + + # 等待启动 + sleep 10 + + # 验证是否启动成功 + if is_tomcat_running "$port"; then + log "Tomcat $port 重启成功" + return 0 + else + error "Tomcat $port 启动后未运行" + return 1 + fi + else + error "Tomcat $port 启动失败" + return 1 + fi + else + error "Tomcat $port 启动脚本不存在" + return 1 + fi +} + +# 更新重启记录 +update_restart_record() { + local port=$1 + local reason="$2" + local success="$3" + + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local temp_file="${STATUS_FILE}.tmp" + + # 使用jq更新JSON文件,如果没有jq则使用sed + if command -v jq >/dev/null 2>&1; then + jq --arg port "$port" \ + --arg timestamp "$timestamp" \ + --arg reason "$reason" \ + --arg success "$success" \ + '.restart_records[$port] += [{"time": $timestamp, "reason": $reason, "success": $success}]' \ + "$STATUS_FILE" > "$temp_file" && mv "$temp_file" "$STATUS_FILE" + else + # 简单的文本处理(如果没有jq) + echo "重启记录 - 端口: $port, 时间: $timestamp, 原因: $reason, 成功: $success" >> "$LOG_FILE" + fi +} + +# 检查重启频率 +can_restart() { + local port=$1 + local current_time=$(date +%s) + + # 检查冷却时间 + if [ -f "/tmp/tomcat_${port}_restart_time" ]; then + local last_restart=$(cat "/tmp/tomcat_${port}_restart_time") + local time_diff=$((current_time - last_restart)) + + if [ $time_diff -lt $RESTART_COOLDOWN ]; then + local remaining=$((RESTART_COOLDOWN - time_diff)) + warn "Tomcat $port 在冷却期内,${remaining}秒后可重启" + return 1 + fi + fi + + # 检查重启次数 + local restart_count_file="/tmp/tomcat_${port}_restart_count" + local restart_count=0 + if [ -f "$restart_count_file" ]; then + restart_count=$(cat "$restart_count_file") + fi + + # 每天重置计数 + local today=$(date +%Y%m%d) + local count_date_file="/tmp/tomcat_${port}_restart_date" + if [ -f "$count_date_file" ]; then + local last_date=$(cat "$count_date_file") + if [ "$last_date" != "$today" ]; then + restart_count=0 + echo "$restart_count" > "$restart_count_file" + echo "$today" > "$count_date_file" + fi + else + echo "$today" > "$count_date_file" + fi + + if [ $restart_count -ge $MAX_RESTART_ATTEMPTS ]; then + error "Tomcat $port 今日重启次数已达上限($MAX_RESTART_ATTEMPTS次),不再自动重启" + return 1 + fi + + return 0 +} + +# 更新重启计数 +update_restart_count() { + local port=$1 + local restart_count_file="/tmp/tomcat_${port}_restart_count" + local restart_count=0 + + if [ -f "$restart_count_file" ]; then + restart_count=$(cat "$restart_count_file") + fi + + restart_count=$((restart_count + 1)) + echo "$restart_count" > "$restart_count_file" + echo "$(date +%s)" > "/tmp/tomcat_${port}_restart_time" +} + +# 监控单个Tomcat实例 +monitor_tomcat() { + local port=$1 + + if ! is_tomcat_running "$port"; then + warn "Tomcat $port 未运行" + return + fi + + local oom_detected=false + local oom_reason="" + + # 检查OOM错误(最高优先级) + if check_oom_error "$port"; then + oom_detected=true + oom_reason="应用层OOM错误" + elif check_dmesg_oom "$port"; then + oom_detected=true + oom_reason="系统OOM Killer" + elif check_memory_usage "$port"; then + oom_detected=true + oom_reason="内存使用过高" + fi + + if [ "$oom_detected" = true ]; then + warn "检测到Tomcat $port 需要重启: $oom_reason" + + if can_restart "$port"; then + info "开始重启Tomcat $port..." + if restart_tomcat "$port" "$oom_reason"; then + log "Tomcat $port 重启成功" + update_restart_record "$port" "$oom_reason" "true" + update_restart_count "$port" + else + error "Tomcat $port 重启失败" + update_restart_record "$port" "$oom_reason" "false" + fi + fi + fi +} + +# 显示监控状态 +show_monitor_status() { + log "=== Tomcat OOM监控状态 ===" + log "监控节点: $(get_monitor_ports | tr '\n' ' ')" + log "检查间隔: ${MONITOR_INTERVAL}秒" + log "内存阈值: ${MEMORY_THRESHOLD_GB}GB" + log "日志文件: $LOG_FILE" + log "状态文件: $STATUS_FILE" + echo + + for port in $(get_monitor_ports); do + local base_path="${TOMCAT_INSTANCES[$port]}" + if is_tomcat_running "$port"; then + local pid=$(get_tomcat_pid "$port") + # 显示内存使用情况 + local mem_info=$(ps -o rss -p "$pid" 2>/dev/null | tail -1) + local rss_gb=$((mem_info / 1024 / 1024)) + echo -e "${GREEN}Tomcat $port: 运行中 (PID: $pid, 内存: ~${rss_gb}GB, 路径: ${base_path}/tomcat${port})${NC}" + else + echo -e "${RED}Tomcat $port: 未运行 (路径: ${base_path}/tomcat${port})${NC}" + fi + done + echo +} + +# 主监控循环 +start_monitor() { + log "启动Tomcat OOM监控服务..." + log "监控端口: $(get_monitor_ports | tr '\n' ' ')" + log "检查间隔: ${MONITOR_INTERVAL}秒" + log "内存阈值: ${MEMORY_THRESHOLD_GB}GB" + log "按 Ctrl+C 停止监控" + echo + + # 显示初始状态 + show_monitor_status + + # 主循环 + while true; do + for port in $(get_monitor_ports); do + monitor_tomcat "$port" + done + + # 等待下一次检查 + sleep $MONITOR_INTERVAL + done +} + +# 停止监控 +stop_monitor() { + log "停止Tomcat OOM监控服务..." + pkill -f "tomcat.*oom.*monitor" || true +} + +# 显示帮助 +show_usage() { + echo "使用方法: $0 {start|stop|status|restart|once}" + echo + echo "命令说明:" + echo " start 启动OOM监控服务" + echo " stop 停止OOM监控服务" + echo " status 查看监控状态" + echo " restart 重启监控服务" + echo " once 执行一次检查(不持续监控)" + echo + echo "监控配置:" + echo " 监控端口和路径:" + for port in $(get_monitor_ports); do + local base_path="${TOMCAT_INSTANCES[$port]}" + echo " $port -> ${base_path}/tomcat${port}" + done + echo " 检查间隔: ${MONITOR_INTERVAL}秒" + echo " 内存阈值: ${MEMORY_THRESHOLD_GB}GB" + echo " 日志文件: $LOG_FILE" +} + +# 执行单次检查 +run_once() { + log "执行单次OOM检查..." + for port in $(get_monitor_ports); do + monitor_tomcat "$port" + done + log "单次检查完成" +} + +# 主函数 +main() { + local command="${1:-start}" + + # 初始化 + init_status_file + + case "$command" in + start) + start_monitor + ;; + stop) + stop_monitor + ;; + status) + show_monitor_status + ;; + restart) + stop_monitor + sleep 2 + start_monitor + ;; + once) + run_once + ;; + help|--help|-h) + show_usage + ;; + *) + error "未知命令: $command" + show_usage + exit 1 + ;; + esac +} + +# 脚本入口 +if [ $# -eq 0 ]; then + show_usage + exit 1 +fi + +main "$@" \ No newline at end of file diff --git a/月度/11月/晨午检脚本/tomcat.sh b/月度/11月/晨午检脚本/tomcat.sh new file mode 100644 index 0000000..f2a50f6 --- /dev/null +++ b/月度/11月/晨午检脚本/tomcat.sh @@ -0,0 +1,616 @@ +#!/bin/bash + +# 配置区域 - 便于修改 +readonly TOMCAT_PORTS=(90107 90108) +readonly TOMCAT_BASE_PATH="/home/chenwujian2" +readonly DIST_PATH="/home/stxt/cwj2/" +readonly CONFIG_SOURCE_PATH="/home/chenwujian/tomcat90105/webapps" +readonly CLEANUP_PATHS=( + "/home/chenwujian2/script/2025/" + "/home/chenwujian2/script/logs/app.log" +) + +# 颜色定义 +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly PURPLE='\033[0;35m' +readonly NC='\033[0m' # No Color + +# 获取Tomcat完整路径 +get_tomcat_path() { + local port=$1 + echo "${TOMCAT_BASE_PATH}/tomcat${port}" +} + +# 日志函数 +log() { + echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}" +} + +warn() { + echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] 警告: $1${NC}" +} + +error() { + echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] 错误: $1${NC}" +} + +info() { + echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}" +} + +# 显示菜单 +show_menu() { + clear + echo -e "${CYAN}" + echo "================================================" + echo " Tomcat 服务管理菜单" + echo "================================================" + echo -e "${NC}" + echo -e "${GREEN}1. 启动 Tomcat 服务${NC}" + echo -e "${GREEN}2. 停止 Tomcat 服务${NC}" + echo -e "${GREEN}3. 重启 Tomcat 服务${NC}" + echo -e "${YELLOW}4. 部署应用到 Tomcat${NC}" + echo -e "${YELLOW}5. 分发配置文件${NC}" + echo -e "${BLUE}6. 查看服务状态${NC}" + echo -e "${PURPLE}7. 查看 Tomcat 日志${NC}" + echo -e "${RED}8. 清理所有文件(包括日志)${NC}" + echo -e "${RED}9. 仅清理 Tomcat 日志${NC}" + echo -e "${CYAN}a. 完整部署流程${NC}" + echo -e "${RED}0. 退出脚本${NC}" + echo "================================================" +} + +# 检查必要目录是否存在 +check_dependencies() { + if [ ! -d "$TOMCAT_BASE_PATH" ]; then + error "基础路径不存在: $TOMCAT_BASE_PATH" + return 1 + fi + + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + if [ ! -d "$tomcat_path" ]; then + error "Tomcat实例路径不存在: $tomcat_path" + return 1 + fi + done + + return 0 +} + +# 显示Tomcat日志(实时输出) +show_tomcat_logs() { + local port=$1 + local tomcat_path=$(get_tomcat_path "$port") + local log_file="${tomcat_path}/logs/catalina.out" + + if [ ! -f "$log_file" ]; then + warn "日志文件不存在: $log_file" + echo "可能的原因:" + echo "1. Tomcat 尚未启动" + echo "2. 日志文件路径不正确" + echo "3. 没有读取权限" + return 1 + fi + + info "开始显示 Tomcat $port 日志 (按 Ctrl+C 退出)..." + echo -e "${CYAN}================================================${NC}" + echo -e "${CYAN}日志文件: $log_file${NC}" + echo -e "${CYAN}================================================${NC}" + + # 显示文件大小 + local file_size=$(du -h "$log_file" | cut -f1) + echo -e "${BLUE}日志文件大小: $file_size${NC}" + echo "" + + # 使用 trap 来捕获 Ctrl+C 信号 + trap 'kill $tail_pid $stat_pid 2>/dev/null; echo ""; info "已退出日志查看"; exit 0' INT TERM + + # 显示最后50行日志,然后实时跟踪新日志 + tail -n 50 -f "$log_file" & + local tail_pid=$! + + # 等待 tail 进程结束 + wait $tail_pid 2>/dev/null + trap - INT TERM # 清理 trap +} + +# 查看日志菜单 +view_logs_menu() { + local choice + while true; do + clear + echo -e "${PURPLE}" + echo "================================================" + echo " 查看 Tomcat 日志" + echo "================================================" + echo -e "${NC}" + + # 显示各Tomcat状态 + for i in "${!TOMCAT_PORTS[@]}"; do + local port="${TOMCAT_PORTS[$i]}" + local tomcat_path=$(get_tomcat_path "$port") + local log_file="${tomcat_path}/logs/catalina.out" + + if [ -f "$log_file" ]; then + local file_size=$(du -h "$log_file" | cut -f1) + local line_count=$(wc -l < "$log_file" 2>/dev/null || echo "0") + echo -e "${CYAN}$((i+1)). Tomcat $port 日志${NC}" + echo -e " 文件: $log_file" + echo -e " 大小: $file_size, 行数: $line_count" + else + echo -e "${YELLOW}$((i+1)). Tomcat $port 日志${NC}" + echo -e " 状态: ${RED}日志文件不存在${NC}" + fi + echo "" + done + + echo -e "${CYAN}c. 查看所有 Tomcat 日志(多窗口)${NC}" + echo -e "${CYAN}b. 返回主菜单${NC}" + echo "================================================" + + read -p "请选择要查看的日志 (1-${#TOMCAT_PORTS[@]}/c/b): " choice + + case $choice in + [1-9]) + local index=$((choice-1)) + if [ $index -lt ${#TOMCAT_PORTS[@]} ]; then + local port="${TOMCAT_PORTS[$index]}" + show_tomcat_logs "$port" + read -p "按回车键继续..." dummy + else + error "无效选择,请重新输入!" + sleep 1 + fi + ;; + c|C) + view_all_logs + ;; + b|B) + return + ;; + *) + error "无效选择,请重新输入!" + sleep 1 + ;; + esac + done +} + +# 查看所有Tomcat日志(多窗口方式) +view_all_logs() { + info "即将在新窗口中打开所有Tomcat日志..." + echo "这将为每个Tomcat打开一个独立的终端窗口查看日志" + echo "关闭日志窗口后,按回车键返回菜单" + echo "" + + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + local log_file="${tomcat_path}/logs/catalina.out" + + if [ -f "$log_file" ]; then + info "为 Tomcat $port 打开日志窗口..." + # 使用 gnome-terminal, xterm 或 screen 来打开新窗口 + if command -v gnome-terminal >/dev/null 2>&1; then + gnome-terminal --title="Tomcat $port 日志" -- bash -c "echo '正在显示 Tomcat $port 日志...'; echo '文件: $log_file'; echo '按 Ctrl+C 退出'; echo '================================'; tail -n 50 -f '$log_file'; exec bash" + elif command -v xterm >/dev/null 2>&1; then + xterm -title "Tomcat $port 日志" -e bash -c "echo '正在显示 Tomcat $port 日志...'; echo '文件: $log_file'; echo '按 Ctrl+C 退出'; echo '================================'; tail -n 50 -f '$log_file'; read -p '按回车键关闭...'" + else + warn "未找到可用的终端程序,无法打开多窗口" + info "将在当前终端依次显示日志..." + show_tomcat_logs "$port" + fi + else + warn "Tomcat $port 日志文件不存在: $log_file" + fi + done + + read -p "所有日志窗口已启动,按回车键返回菜单..." dummy +} + +# 启动Tomcat并显示日志 +start_tomcats_with_logs() { + log "启动Tomcat服务..." + + # 首先启动所有Tomcat + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + if [ -f "${tomcat_path}/bin/startup.sh" ]; then + info "启动Tomcat $port..." + if sh "${tomcat_path}/bin/startup.sh"; then + log "Tomcat $port 启动命令执行完成" + else + error "Tomcat $port 启动失败" + fi + else + error "启动脚本不存在: ${tomcat_path}/bin/startup.sh" + fi + done + + # 等待一段时间让Tomcat开始启动 + info "等待Tomcat启动..." + sleep 5 + + # 显示启动状态 + show_tomcat_status + + # 询问是否查看日志 + echo + read -p "是否查看Tomcat启动日志?(y/n, 默认y): " view_logs + view_logs=${view_logs:-y} + + if [[ $view_logs =~ ^[Yy]$ ]]; then + for port in "${TOMCAT_PORTS[@]}"; do + echo + read -p "是否查看 Tomcat $port 的启动日志?(y/n): " view_single + if [[ $view_single =~ ^[Yy]$ ]]; then + show_tomcat_logs "$port" + fi + done + fi +} + +# 清理Tomcat日志 +clean_tomcat_logs() { + log "开始清理Tomcat日志..." + + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + local logs_path="${tomcat_path}/logs" + + if [ -d "$logs_path" ]; then + info "清理Tomcat $port 日志..." + + # 清理catalina.out(清空内容而不是删除文件) + if [ -f "${logs_path}/catalina.out" ]; then + > "${logs_path}/catalina.out" + log "Tomcat $port - 已清空 catalina.out" + fi + + # 删除旧的日志文件,但保留最近的一些 + local log_files=("catalina." "localhost." "manager." "host-manager." "localhost_access_log.") + + for log_prefix in "${log_files[@]}"; do + # 删除7天前的日志文件 + find "$logs_path" -name "${log_prefix}*" -type f -mtime +7 -delete 2>/dev/null + + # 统计清理结果 + local remaining_count=$(find "$logs_path" -name "${log_prefix}*" -type f | wc -l) + log "Tomcat $port - ${log_prefix}* 剩余文件: $remaining_count" + done + + # 清理temp目录 + local temp_path="${tomcat_path}/temp" + if [ -d "$temp_path" ]; then + rm -rf "${temp_path}"/* + log "Tomcat $port - 已清空 temp 目录" + fi + else + warn "Tomcat $port 日志路径不存在: $logs_path" + fi + done +} + +# 清理文件函数 +cleanup_files() { + log "开始清理文件..." + + for path in "${CLEANUP_PATHS[@]}"; do + if [[ "$path" == */ ]]; then + # 如果是目录,删除目录下所有文件但保留目录 + if [ -d "$path" ]; then + rm -rf "${path}"* + log "已清空目录: $path" + else + warn "目录不存在: $path" + fi + else + # 如果是文件,清空内容或删除 + if [ -f "$path" ]; then + > "$path" # 清空文件内容 + log "已清空文件: $path" + else + warn "文件不存在: $path" + fi + fi + done + + # 清理Tomcat日志 + clean_tomcat_logs +} + +# 启动Tomcat +start_tomcats() { + log "启动Tomcat服务..." + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + if [ -f "${tomcat_path}/bin/startup.sh" ]; then + info "启动Tomcat $port..." + if sh "${tomcat_path}/bin/startup.sh"; then + log "Tomcat $port 启动完成" + else + error "Tomcat $port 启动失败" + fi + else + error "启动脚本不存在: ${tomcat_path}/bin/startup.sh" + fi + done + show_tomcat_status +} + +# 停止Tomcat(精确停止指定端口的Tomcat) +stop_tomcats() { + log "停止Tomcat服务..." + + # 首先使用正常关闭方式 + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + if [ -f "${tomcat_path}/bin/shutdown.sh" ]; then + info "停止Tomcat $port..." + if sh "${tomcat_path}/bin/shutdown.sh"; then + log "Tomcat $port 已发送停止命令" + else + warn "Tomcat $port 停止过程中可能出现问题" + fi + else + error "停止脚本不存在: ${tomcat_path}/bin/shutdown.sh" + fi + done + + # 等待正常关闭 + info "等待正常关闭..." + sleep 5 + + # 精确杀死指定端口的进程 + for port in "${TOMCAT_PORTS[@]}"; do + # 查找监听指定端口的Java进程 + local pids=$(netstat -tlnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f1 | grep -v '^-$' | grep -v '^$') + if [ -n "$pids" ]; then + warn "发现端口 $port 的残留进程,强制杀死: $pids" + kill -9 $pids 2>/dev/null + fi + + # 另外通过进程参数查找对应的Tomcat进程 + local tomcat_pids=$(ps -ef | grep java | grep "catalina.base=/home/chenwujian2/tomcat${port}" | grep -v grep | awk '{print $2}') + if [ -n "$tomcat_pids" ]; then + warn "发现Tomcat${port}的残留进程,强制杀死: $tomcat_pids" + kill -9 $tomcat_pids 2>/dev/null + fi + done + + show_tomcat_status +} + +# 重启Tomcat +restart_tomcats() { + log "重启Tomcat服务..." + stop_tomcats + sleep 2 + start_tomcats_with_logs +} + +# 分发配置文件 +distribute_config() { + log "分发配置文件..." + + if [ ! -d "$CONFIG_SOURCE_PATH" ]; then + error "配置文件源路径不存在: $CONFIG_SOURCE_PATH" + return 1 + fi + + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + local target_path="${tomcat_path}/webapps/ROOT/WEB-INF/classes" + + # 创建目标目录(如果不存在) + mkdir -p "${target_path}/properties" + + # 复制配置文件 + if \cp -rf "${CONFIG_SOURCE_PATH}/jeeplus.properties" "${target_path}/properties/"; then + log "Tomcat $port - jeeplus.properties 复制完成" + else + error "Tomcat $port - jeeplus.properties 复制失败" + fi + + if \cp -rf "${CONFIG_SOURCE_PATH}/fdfs_client.conf" "${target_path}/"; then + log "Tomcat $port - fdfs_client.conf 复制完成" + else + error "Tomcat $port - fdfs_client.conf 复制失败" + fi + done +} + +# 显示Tomcat状态 +show_tomcat_status() { + log "Tomcat进程状态:" + + # 精确显示指定Tomcat的进程(通过catalina.base路径匹配) + local found_process=0 + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + local process=$(ps -ef | grep java | grep "catalina.base=${tomcat_path}" | grep -v grep) + if [ -n "$process" ]; then + echo -e "${GREEN}Tomcat $port 运行中:${NC}" + echo -e "${GREEN}$process${NC}" + echo "" + found_process=1 + else + echo -e "${YELLOW}Tomcat $port: 未运行${NC}" + echo "" + fi + done + + if [ $found_process -eq 0 ]; then + info "所有指定的Tomcat实例均未运行" + fi + + # 显示端口占用情况(更精确的端口检测) + log "端口占用情况:" + for port in "${TOMCAT_PORTS[@]}"; do + # 使用更精确的端口检测 + if ss -tlnp 2>/dev/null | grep ":${port} " >/dev/null || \ + netstat -tlnp 2>/dev/null | grep ":${port} " >/dev/null; then + # 获取占用该端口的进程信息 + local port_info="" + if command -v ss >/dev/null 2>&1; then + port_info=$(ss -tlnp | grep ":${port} " | head -1) + local pid=$(echo "$port_info" | grep -o 'pid=[0-9]*' | cut -d= -f2) + else + port_info=$(netstat -tlnp 2>/dev/null | grep ":${port} " | head -1) + local pid=$(echo "$port_info" | awk '{print $7}' | cut -d'/' -f1) + fi + + if [ -n "$pid" ] && [ "$pid" != "-" ]; then + # 检查该进程是否是我们管理的Tomcat + local tomcat_path=$(get_tomcat_path "$port") + if ps -p "$pid" -o command= 2>/dev/null | grep -q "catalina.base=${tomcat_path}"; then + echo -e "${GREEN}端口 $port: 被本脚本管理的Tomcat占用 (PID: $pid)${NC}" + else + echo -e "${YELLOW}端口 $port: 被其他进程占用 (PID: $pid)${NC}" + fi + else + echo -e "${YELLOW}端口 $port: 被占用 (无法获取PID)${NC}" + fi + else + echo -e "${RED}端口 $port: 未被占用${NC}" + fi + done +} + +# 部署应用 +deploy_app() { + log "开始部署应用..." + local today=$(date +"%Y%m%d%H%M") + + if [ ! -f "${DIST_PATH}ROOT.tar.gz" ]; then + error "部署包不存在: ${DIST_PATH}ROOT.tar.gz" + return 1 + fi + + for port in "${TOMCAT_PORTS[@]}"; do + local tomcat_path=$(get_tomcat_path "$port") + local webapps_path="${tomcat_path}/webapps" + + # 停止当前Tomcat + info "停止Tomcat $port..." + sh "${tomcat_path}/bin/shutdown.sh" 2>/dev/null + sleep 2 + + # 清理旧应用 + rm -f "${webapps_path}/ROOT.tar.gz" + rm -rf "${webapps_path}/ROOT" + + # 部署新应用 + if cp "${DIST_PATH}ROOT.tar.gz" "${webapps_path}/"; then + if tar -zxf "${webapps_path}/ROOT.tar.gz" -C "${webapps_path}/"; then + log "Tomcat $port 部署完成" + else + error "Tomcat $port 解压失败" + fi + else + error "Tomcat $port 复制部署包失败" + fi + done + + # 备份部署包 + if mv "${DIST_PATH}/ROOT.tar.gz" "${DIST_PATH}/ROOT.${today}.tar.gz"; then + log "部署包已备份: ${DIST_PATH}/ROOT.${today}.tar.gz" + else + error "部署包备份失败" + fi +} + +# 完整流程 +full_process() { + log "开始执行完整流程..." + cleanup_files + stop_tomcats + deploy_app + distribute_config + start_tomcats_with_logs + log "完整流程执行完毕!" +} + +# 执行选择的操作 +execute_choice() { + local choice=$1 + + case $choice in + 1) + start_tomcats_with_logs + ;; + 2) + stop_tomcats + ;; + 3) + restart_tomcats + ;; + 4) + deploy_app + read -p "部署完成,是否启动Tomcat服务?(y/n, 默认y): " start_after_deploy + start_after_deploy=${start_after_deploy:-y} + if [[ $start_after_deploy =~ ^[Yy]$ ]]; then + start_tomcats_with_logs + fi + ;; + 5) + distribute_config + ;; + 6) + show_tomcat_status + ;; + 7) + view_logs_menu + ;; + 8) + cleanup_files + ;; + 9) + clean_tomcat_logs + ;; + a|A) + full_process + ;; + 0) + log "再见!" + exit 0 + ;; + *) + error "无效选择,请重新输入!" + ;; + esac +} + +# 主函数 +main() { + # 检查依赖 + if ! check_dependencies; then + error "环境检查失败,请检查配置" + exit 1 + fi + + while true; do + show_menu + echo + read -p "请选择操作 (0-9/a): " choice + + case $choice in + [0-9aA]) + execute_choice "$choice" + ;; + *) + error "无效输入,请输入数字 0-9 或 a" + ;; + esac + + echo + read -p "按回车键继续..." dummy + done +} + +# 脚本入口 +main "$@" \ No newline at end of file diff --git a/材料/frp/frpc.toml b/材料/frp/frpc.toml index 257f91f..77d833c 100644 --- a/材料/frp/frpc.toml +++ b/材料/frp/frpc.toml @@ -10,8 +10,8 @@ auth.token = "token123456" [[proxies]] name = "web-tcp" # 代理名称(自定义,唯一即可) type = "tcp" # 类型为 tcp -localIP = "127.0.0.1" # 本地服务 IP -localPort = 802 # 本地服务端口(您要暴露的服务) +localIP = "192.168.2.40" # 本地服务 IP +localPort = 80 # 本地服务端口(您要暴露的服务) remotePort = 8081 # 服务器映射端口 # 2.http://frps.binghuai.xyz:8088/