196 lines
5.3 KiB
Go
196 lines
5.3 KiB
Go
package upload
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"log/slog"
|
||
|
|
"net/http"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"bj_power_mes/constants"
|
||
|
|
"bj_power_mes/ent/equipmentslot"
|
||
|
|
"bj_power_mes/ent/inspectionimage"
|
||
|
|
"bj_power_mes/ent/job"
|
||
|
|
"bj_power_mes/internal/svc"
|
||
|
|
|
||
|
|
"github.com/dromara/carbon/v2"
|
||
|
|
"github.com/google/uuid"
|
||
|
|
)
|
||
|
|
|
||
|
|
// HandleInspectionUpload 内窥镜检测图片上传,自动绑定当前检测工件
|
||
|
|
func HandleInspectionUpload(svcCtx *svc.ServiceContext, w http.ResponseWriter, r *http.Request) {
|
||
|
|
|
||
|
|
if r.ContentLength == 0 {
|
||
|
|
slog.Info("内窥镜URL测试")
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
json.NewEncoder(w).Encode(map[string]any{
|
||
|
|
"code": 200,
|
||
|
|
"msg": "success",
|
||
|
|
})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
deviceId := r.FormValue("deviceId")
|
||
|
|
|
||
|
|
file, handler, err := r.FormFile("file")
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("读取文件失败", "error", err)
|
||
|
|
http.Error(w, fmt.Sprintf("读取文件失败:%s", err.Error()), http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer file.Close()
|
||
|
|
|
||
|
|
// 先查当前检测工件,避免无工件时产生孤儿文件
|
||
|
|
var jobId int
|
||
|
|
var workpieceNo string
|
||
|
|
var workOrderId int
|
||
|
|
var workOrderNo string
|
||
|
|
var palletCode string
|
||
|
|
|
||
|
|
slot, err := svcCtx.EntClient.EquipmentSlot.Query().
|
||
|
|
Where(
|
||
|
|
equipmentslot.EquipmentIdEQ(6),
|
||
|
|
equipmentslot.StatusEQ(constants.SlotStatus_Occupied),
|
||
|
|
).
|
||
|
|
Only(r.Context())
|
||
|
|
if err == nil && slot.CurrentJobId != nil && *slot.CurrentJobId > 0 {
|
||
|
|
j, err := svcCtx.EntClient.Job.Query().
|
||
|
|
Where(job.IDEQ(*slot.CurrentJobId)).
|
||
|
|
WithWorkOrder().
|
||
|
|
WithPallet().
|
||
|
|
Only(r.Context())
|
||
|
|
if err == nil {
|
||
|
|
jobId = j.ID
|
||
|
|
workpieceNo = j.WorkpieceNo
|
||
|
|
if j.Edges.WorkOrder != nil {
|
||
|
|
workOrderId = j.Edges.WorkOrder.ID
|
||
|
|
workOrderNo = j.Edges.WorkOrder.WorkOrderNo
|
||
|
|
}
|
||
|
|
if j.Edges.Pallet != nil {
|
||
|
|
palletCode = j.Edges.Pallet.PalletCode
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if jobId <= 0 {
|
||
|
|
slog.Error("当前没有检测工件,无法绑定检测图片")
|
||
|
|
http.Error(w, "当前没有检测工件,无法绑定检测图片", http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
now := carbon.Now()
|
||
|
|
dir := filepath.Join(svcCtx.Config.Upload.Dir, "inspection",
|
||
|
|
fmt.Sprintf("%04d", now.Year()),
|
||
|
|
fmt.Sprintf("%02d", now.Month()),
|
||
|
|
fmt.Sprintf("%02d", now.Day()))
|
||
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||
|
|
slog.Error("创建上传目录失败", "dir", dir, "error", err)
|
||
|
|
http.Error(w, "创建目录失败", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
ext := filepath.Ext(handler.Filename)
|
||
|
|
if ext == "" {
|
||
|
|
ext = ".jpg"
|
||
|
|
}
|
||
|
|
fileName := uuid.New().String() + ext
|
||
|
|
filePath := filepath.Join(dir, fileName)
|
||
|
|
relPath := filepath.Join("inspection",
|
||
|
|
fmt.Sprintf("%04d", now.Year()),
|
||
|
|
fmt.Sprintf("%02d", now.Month()),
|
||
|
|
fmt.Sprintf("%02d", now.Day()),
|
||
|
|
fileName)
|
||
|
|
|
||
|
|
dst, err := os.Create(filePath)
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("创建文件失败", "path", filePath, "error", err)
|
||
|
|
http.Error(w, "保存文件失败", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer dst.Close()
|
||
|
|
|
||
|
|
written, err := io.Copy(dst, file)
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("写入文件失败", "path", filePath, "error", err)
|
||
|
|
http.Error(w, "保存文件失败", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
_, err = svcCtx.EntClient.InspectionImage.Create().
|
||
|
|
SetJobId(jobId).
|
||
|
|
SetWorkpieceNo(workpieceNo).
|
||
|
|
SetWorkOrderId(workOrderId).
|
||
|
|
SetWorkOrderNo(workOrderNo).
|
||
|
|
SetPalletCode(palletCode).
|
||
|
|
SetDeviceId(deviceId).
|
||
|
|
SetFileName(handler.Filename).
|
||
|
|
SetFilePath(filepath.ToSlash(relPath)).
|
||
|
|
SetFileSize(written).
|
||
|
|
Save(r.Context())
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("创建检测图片记录失败", "jobId", jobId, "error", err)
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
http.Error(w, "创建检测图片记录失败", http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
slog.Info("检测图片上传", "file", handler.Filename, "size", written, "jobId", jobId, "deviceId", deviceId)
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
json.NewEncoder(w).Encode(map[string]any{
|
||
|
|
"code": 200,
|
||
|
|
"data": map[string]any{ // 必须返回data字段(内容无所谓),否则内窥镜会卡死
|
||
|
|
"createTime": now.Format("2006-01-02 15:04:05"),
|
||
|
|
"deviceId": deviceId,
|
||
|
|
"name": fileName,
|
||
|
|
"dirStatus": 0,
|
||
|
|
"dmCode": "",
|
||
|
|
"docPath": filePath,
|
||
|
|
//"id": 619,
|
||
|
|
"level": 2,
|
||
|
|
"parentDir": dir,
|
||
|
|
"remark": "",
|
||
|
|
"size": written,
|
||
|
|
"type": ext,
|
||
|
|
},
|
||
|
|
"msg": "success",
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// StartCleanup 定期清理过期检测图片(每天一次),RetentionDays=-1 跳过
|
||
|
|
func StartCleanup(svcCtx *svc.ServiceContext) {
|
||
|
|
if svcCtx.Config.Upload.RetentionDays == -1 {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
retention := svcCtx.Config.Upload.RetentionDays
|
||
|
|
if retention <= 0 {
|
||
|
|
retention = 30
|
||
|
|
}
|
||
|
|
go func() {
|
||
|
|
ticker := time.NewTicker(24 * time.Hour)
|
||
|
|
defer ticker.Stop()
|
||
|
|
for range ticker.C {
|
||
|
|
cutoff := time.Now().AddDate(0, 0, -retention)
|
||
|
|
images, err := svcCtx.EntClient.InspectionImage.Query().
|
||
|
|
Where(inspectionimage.CreatedAtLT(cutoff)).
|
||
|
|
All(context.Background())
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("inspection cleanup: query failed", "error", err)
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
for _, img := range images {
|
||
|
|
absPath := filepath.Join(svcCtx.Config.Upload.Dir, filepath.FromSlash(img.FilePath))
|
||
|
|
os.Remove(absPath)
|
||
|
|
_ = svcCtx.EntClient.InspectionImage.DeleteOneID(img.ID).Exec(context.Background())
|
||
|
|
}
|
||
|
|
if len(images) > 0 {
|
||
|
|
slog.Info("inspection cleanup: removed expired images", "count", len(images), "before", cutoff)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
}
|