feat: 完成附件存储重构与磁盘监控功能,同步物料档案与入库单规则更新
1. 新增跨平台磁盘空间监控能力,每日7点自动检测附件目录剩余空间,触发阈值告警 2. 重构附件存储方案为年/月/日/文件类型分层结构,统一MES与WMS的附件管理逻辑 3. 对齐物料档案与入库单的质量状态校验规则,仅合格品计入库存与出库 4. 实现入库单作废功能与区域库位的多级父子结构管理 5. 删除物料简称字段,补充规格型号与单位必填项,统一系统数据口径 6. 新增附件中心与磁盘状态查询接口,完善权限控制与操作日志
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user