Files
bj_power/bj_power_mes/internal/handler/attachment_monitor.go
T
SunYF 62e45b7379 feat: 完成附件存储重构与磁盘监控功能,同步物料档案与入库单规则更新
1.  新增跨平台磁盘空间监控能力,每日7点自动检测附件目录剩余空间,触发阈值告警
2.  重构附件存储方案为年/月/日/文件类型分层结构,统一MES与WMS的附件管理逻辑
3.  对齐物料档案与入库单的质量状态校验规则,仅合格品计入库存与出库
4.  实现入库单作废功能与区域库位的多级父子结构管理
5.  删除物料简称字段,补充规格型号与单位必填项,统一系统数据口径
6.  新增附件中心与磁盘状态查询接口,完善权限控制与操作日志
2026-09-19 10:54:15 +08:00

106 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"context"
"fmt"
"net/http"
"os"
"time"
"bj_power_mes/common/httpx"
"bj_power_mes/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
// diskStatusView 磁盘空间状态视图(附件中心顶部提示 + 定时告警共用)。
type diskStatusView struct {
RootDir string `json:"rootDir"`
UsedPercent int `json:"usedPercent"`
FreeBytes uint64 `json:"freeBytes"`
TotalBytes uint64 `json:"totalBytes"`
WarnPercent int `json:"warnPercent"`
CritPercent int `json:"critPercent"`
Level string `json:"level"` // ok / warn / critical / unknown
Message string `json:"message"`
CheckedAt int64 `json:"checkedAt"`
}
// diskStatus 读取附件根目录所在磁盘剩余空间并给出告警级别。
// 剩余 < DiskCriticalPercent → critical(提示执行备份归档清理);< DiskWarnPercent → warn。
func diskStatus(svcCtx *svc.ServiceContext) diskStatusView {
cfg := svcCtx.Config.Upload
root := cfg.Dir
if root == "" {
root = "uploads"
}
v := diskStatusView{
RootDir: root, WarnPercent: cfg.DiskWarnPercent, CritPercent: cfg.DiskCriticalPercent,
Level: "ok", Message: "磁盘空间正常", CheckedAt: time.Now().Unix(),
}
used, free, total, err := diskUsage(root)
if err != nil {
_ = os.MkdirAll(root, 0o755)
used, free, total, err = diskUsage(root)
}
if err != nil {
v.Level = "unknown"
v.Message = "磁盘空间检测失败:" + err.Error()
return v
}
v.UsedPercent, v.FreeBytes, v.TotalBytes = used, free, total
freePercent := 100 - used
switch {
case freePercent < cfg.DiskCriticalPercent:
v.Level = "critical"
v.Message = fmt.Sprintf("磁盘剩余空间仅 %d%%,低于 %d%%,请立即执行备份归档清理(附件中心可一键归档)", freePercent, cfg.DiskCriticalPercent)
case freePercent < cfg.DiskWarnPercent:
v.Level = "warn"
v.Message = fmt.Sprintf("磁盘剩余空间 %d%%,低于 %d%% 告警线,请及时清理", freePercent, cfg.DiskWarnPercent)
}
return v
}
// DiskStatusHandler GET /attachment/disk-status
func DiskStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
httpx.Ok(w, diskStatus(svcCtx))
}
}
// StartDiskMonitor 启动磁盘空间监控:每天 DiskCheckHour(默认 7 点) 检测一次,
// 剩余 <20% 告警、<10% 提示清理(写服务日志 + 操作日志,附件中心顶部同步展示)。
func StartDiskMonitor(svcCtx *svc.ServiceContext) {
go func() {
hour := svcCtx.Config.Upload.DiskCheckHour
if hour < 0 || hour > 23 {
hour = 7
}
for {
now := time.Now()
next := time.Date(now.Year(), now.Month(), now.Day(), hour, 0, 0, 0, time.Local)
if !next.After(now) {
next = next.Add(24 * time.Hour)
}
time.Sleep(time.Until(next))
checkDiskOnce(svcCtx)
}
}()
}
func checkDiskOnce(svcCtx *svc.ServiceContext) {
st := diskStatus(svcCtx)
switch st.Level {
case "critical":
logx.Errorf("[磁盘监控] %s(已用 %d%%,剩余 %d%%", st.Message, st.UsedPercent, 100-st.UsedPercent)
svcCtx.EventLog.Write(context.Background(), "system.disk", "", "system", "attachment", "disk", st.Message,
map[string]any{"usedPercent": st.UsedPercent, "freeBytes": st.FreeBytes})
case "warn":
logx.Alert("[磁盘监控] " + st.Message)
svcCtx.EventLog.Write(context.Background(), "system.disk", "", "system", "attachment", "disk", st.Message,
map[string]any{"usedPercent": st.UsedPercent, "freeBytes": st.FreeBytes})
default:
logx.Infof("[磁盘监控] 正常:剩余 %d%%%s", 100-st.UsedPercent, st.RootDir)
}
}