421 lines
13 KiB
Go
421 lines
13 KiB
Go
package service
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"git.hpds.cc/Component/logging"
|
|
"hpds-iot-web/internal/proto"
|
|
"hpds-iot-web/model"
|
|
"hpds-iot-web/mq"
|
|
"image"
|
|
"net/http"
|
|
"strconv"
|
|
"xorm.io/xorm"
|
|
|
|
"github.com/360EntSecGroup-Skylar/excelize"
|
|
)
|
|
|
|
type ReportService interface {
|
|
ReportList(ctx context.Context, req proto.ReportRequest) (rsp *proto.BaseResponse, err error)
|
|
GenerateReport(ctx context.Context, req proto.ReportRequest) (rsp *excelize.File, err error)
|
|
}
|
|
|
|
func NewReportService(engine *xorm.Engine, logger *logging.Logger) ReportService {
|
|
return &repo{
|
|
engine: engine,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (rp *repo) ReportList(ctx context.Context, req proto.ReportRequest) (rsp *proto.BaseResponse, err error) {
|
|
rsp = new(proto.BaseResponse)
|
|
select {
|
|
case <-ctx.Done():
|
|
err = fmt.Errorf("超时/取消")
|
|
rsp.Code = http.StatusInternalServerError
|
|
rsp.Status = http.StatusText(http.StatusInternalServerError)
|
|
rsp.Message = "超时/取消"
|
|
rsp.Err = ctx.Err()
|
|
return rsp, ctx.Err()
|
|
default:
|
|
data := make([]model.Report, 0)
|
|
count, err := rp.engine.
|
|
Where("(? = 0 or m.report_id = ?)", req.ReportId, req.ReportId).
|
|
And("t.status > 0").Limit(int(req.Size), int(((req.Page)-1)*req.Size)).
|
|
FindAndCount(&data)
|
|
if err != nil {
|
|
goto ReturnPoint
|
|
}
|
|
rsp.Code = http.StatusOK
|
|
rsp.Status = http.StatusText(http.StatusOK)
|
|
rsp.Message = "成功"
|
|
rsp = FillPaging(count, req.Page, req.Size, data, rsp)
|
|
rsp.Err = err
|
|
return rsp, err
|
|
}
|
|
ReturnPoint:
|
|
if err != nil {
|
|
rsp.Code = http.StatusInternalServerError
|
|
rsp.Status = http.StatusText(http.StatusInternalServerError)
|
|
rsp.Err = err
|
|
rsp.Message = "失败"
|
|
}
|
|
return rsp, err
|
|
}
|
|
|
|
func (rp *repo) GenerateReport(ctx context.Context, req proto.ReportRequest) (rsp *excelize.File, err error) {
|
|
//rsp = new(proto.BaseResponse)
|
|
select {
|
|
case <-ctx.Done():
|
|
err = fmt.Errorf("超时/取消")
|
|
//rsp.Code = http.StatusInternalServerError
|
|
//rsp.Status = http.StatusText(http.StatusInternalServerError)
|
|
//rsp.Message = "超时/取消"
|
|
//rsp.Err = ctx.Err()
|
|
return rsp, ctx.Err()
|
|
default:
|
|
taskResultList := make([]model.TaskResult, 0)
|
|
err = rp.engine.Where("task_id = ?", req.TaskId).
|
|
Find(&taskResultList)
|
|
if err != nil {
|
|
err = fmt.Errorf("未能找到对应的结果")
|
|
goto ReturnPoint
|
|
}
|
|
list := make([]proto.TaskResultItem, 0)
|
|
for _, v := range taskResultList {
|
|
var h bool
|
|
file := new(model.FileManager)
|
|
h, err = rp.engine.ID(v.FileId).Get(file)
|
|
if err != nil || !h {
|
|
continue
|
|
}
|
|
md := new(model.Model)
|
|
h, err = rp.engine.ID(v.ModelId).Get(md)
|
|
if err != nil || !h {
|
|
continue
|
|
}
|
|
var (
|
|
mr mq.ModelResult
|
|
mrList []string
|
|
fileDiscern string
|
|
memo string
|
|
diseaseType int64
|
|
diseaseLevel int
|
|
length float64
|
|
area float64
|
|
width float64
|
|
diseaseTypeName string
|
|
diseaseLevelName string
|
|
)
|
|
if len(v.Result) > 0 && v.Result[0] == '[' {
|
|
mrList = make([]string, 0)
|
|
if err := json.Unmarshal([]byte(v.Result), &mrList); err != nil {
|
|
continue
|
|
}
|
|
for _, str := range mrList {
|
|
if err := json.Unmarshal([]byte(str), &mr); err != nil {
|
|
continue
|
|
}
|
|
switch mr.Code {
|
|
case 0: //轻量化模型返回
|
|
lr := new(mq.LightweightResult)
|
|
if err := json.Unmarshal([]byte(v.Result), lr); err != nil {
|
|
continue
|
|
}
|
|
//for _, val := range lrList {
|
|
if lr.Crack || lr.Pothole {
|
|
if lr.Crack {
|
|
memo = "检测到裂缝"
|
|
} else {
|
|
memo = "检测到坑洼"
|
|
}
|
|
fileDiscern = lr.ImgDiscern
|
|
diseaseLevel = 3
|
|
diseaseLevelName = "重度"
|
|
switch md.BizType {
|
|
case 2:
|
|
diseaseType = 8
|
|
diseaseTypeName = "结构裂缝"
|
|
case 3:
|
|
diseaseType = 15
|
|
diseaseTypeName = "衬砌裂缝"
|
|
default:
|
|
diseaseType = 4
|
|
diseaseTypeName = "横向裂缝"
|
|
}
|
|
}
|
|
fn, _ := base64.StdEncoding.DecodeString(fileDiscern)
|
|
buff := bytes.NewBuffer(fn)
|
|
_, imgType, _ := image.Decode(buff)
|
|
fileDiscern = fmt.Sprintf("data:image/%s;base64,%s", imgType, fileDiscern)
|
|
item := proto.TaskResultItem{
|
|
FileId: v.FileId,
|
|
FileName: v.SrcPath,
|
|
SrcFile: file.AccessUrl,
|
|
DistFile: fileDiscern,
|
|
DiseaseType: int(diseaseType),
|
|
DiseaseTypeName: diseaseTypeName,
|
|
DiseaseLevel: diseaseLevel,
|
|
DiseaseLevelName: diseaseLevelName,
|
|
KPile: "",
|
|
UpDown: 0,
|
|
LineNum: 0,
|
|
Length: length,
|
|
Width: width,
|
|
Area: area,
|
|
HorizontalPositions: 0,
|
|
Memo: memo,
|
|
Stat: false,
|
|
}
|
|
list = append(list, item)
|
|
//}
|
|
case 2000:
|
|
ir := new(mq.InsigmaResult)
|
|
if err := json.Unmarshal([]byte(str), &ir); err != nil {
|
|
continue
|
|
}
|
|
fileDiscern = ir.Image
|
|
fn, _ := base64.StdEncoding.DecodeString(fileDiscern)
|
|
buff := bytes.NewBuffer(fn)
|
|
_, imgType, _ := image.Decode(buff)
|
|
fileDiscern = fmt.Sprintf("data:image/%s;base64,%s", imgType, fileDiscern)
|
|
item := proto.TaskResultItem{
|
|
FileId: v.FileId,
|
|
FileName: v.SrcPath,
|
|
SrcFile: file.AccessUrl,
|
|
DistFile: fileDiscern,
|
|
DiseaseType: int(diseaseType),
|
|
DiseaseTypeName: diseaseTypeName,
|
|
DiseaseLevel: diseaseLevel,
|
|
DiseaseLevelName: diseaseLevelName,
|
|
KPile: "",
|
|
UpDown: 0,
|
|
LineNum: 0,
|
|
Length: length,
|
|
Width: width,
|
|
Area: area,
|
|
HorizontalPositions: 0,
|
|
Memo: memo,
|
|
Stat: false,
|
|
}
|
|
list = append(list, item)
|
|
|
|
case 2001:
|
|
ir := new(mq.InsigmaResult)
|
|
if err := json.Unmarshal([]byte(str), &ir); err != nil {
|
|
continue
|
|
}
|
|
fileDiscern = ir.Image
|
|
for _, value := range ir.Diseases {
|
|
diseaseType = model.GetDiseaseType(value.Type, md.BizType)
|
|
if len(value.Param.MaxWidth) > 0 && width == 0 {
|
|
width, _ = strconv.ParseFloat(value.Param.MaxWidth, 64)
|
|
}
|
|
length = value.Param.Length
|
|
area = value.Param.Area
|
|
diseaseLevelName = value.Level
|
|
diseaseTypeName = value.Type
|
|
switch value.Level {
|
|
case "重度":
|
|
diseaseLevel = 3
|
|
case "中度":
|
|
diseaseLevel = 2
|
|
case "轻度":
|
|
diseaseLevel = 1
|
|
}
|
|
memo += fmt.Sprintf("发现[%s],等级[%s],长度[%f],最大宽度[%s],面积[%f];\n", value.Type, value.Level, value.Param.Length, value.Param.MaxWidth, value.Param.Area)
|
|
}
|
|
fn, _ := base64.StdEncoding.DecodeString(fileDiscern)
|
|
buff := bytes.NewBuffer(fn)
|
|
_, imgType, _ := image.Decode(buff)
|
|
fileDiscern = fmt.Sprintf("data:image/%s;base64,%s", imgType, fileDiscern)
|
|
item := proto.TaskResultItem{
|
|
FileId: v.FileId,
|
|
FileName: v.SrcPath,
|
|
SrcFile: file.AccessUrl,
|
|
DistFile: fileDiscern,
|
|
DiseaseType: int(diseaseType),
|
|
DiseaseTypeName: diseaseTypeName,
|
|
DiseaseLevel: diseaseLevel,
|
|
DiseaseLevelName: diseaseLevelName,
|
|
KPile: "",
|
|
UpDown: 0,
|
|
LineNum: 0,
|
|
Length: length,
|
|
Width: width,
|
|
Area: area,
|
|
HorizontalPositions: 0,
|
|
Memo: memo,
|
|
Stat: false,
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
}
|
|
|
|
} else {
|
|
if err := json.Unmarshal([]byte(v.Result), &mr); err != nil {
|
|
continue
|
|
}
|
|
switch mr.Code {
|
|
case 0: //轻量化模型返回
|
|
lr := new(mq.LightweightResult)
|
|
if err := json.Unmarshal([]byte(v.Result), &lr); err != nil {
|
|
continue
|
|
}
|
|
if lr.Crack || lr.Pothole {
|
|
if lr.Crack {
|
|
memo = "检测到裂缝"
|
|
} else {
|
|
memo = "检测到坑洼"
|
|
}
|
|
fileDiscern = lr.ImgDiscern
|
|
diseaseLevel = 3
|
|
diseaseLevelName = "重度"
|
|
switch md.BizType {
|
|
case 2:
|
|
diseaseType = 8
|
|
diseaseTypeName = "结构裂缝"
|
|
case 3:
|
|
diseaseType = 15
|
|
diseaseTypeName = "衬砌裂缝"
|
|
default:
|
|
diseaseType = 4
|
|
diseaseTypeName = "横向裂缝"
|
|
}
|
|
}
|
|
//
|
|
case 2000: //网新返回没有病害
|
|
ir := new(mq.InsigmaResult)
|
|
if err := json.Unmarshal([]byte(v.Result), &ir); err != nil {
|
|
continue
|
|
}
|
|
fileDiscern = ir.Image
|
|
case 2001: //网新返回有病害
|
|
ir := new(mq.InsigmaResult)
|
|
if err := json.Unmarshal([]byte(v.Result), &ir); err != nil {
|
|
continue
|
|
}
|
|
fileDiscern = ir.Image
|
|
for _, val := range ir.Diseases {
|
|
diseaseType = model.GetDiseaseType(val.Type, md.BizType)
|
|
if len(val.Param.MaxWidth) > 0 && width == 0 {
|
|
width, _ = strconv.ParseFloat(val.Param.MaxWidth, 64)
|
|
}
|
|
length = val.Param.Length
|
|
area = val.Param.Area
|
|
diseaseLevelName = val.Level
|
|
diseaseTypeName = val.Type
|
|
switch val.Level {
|
|
case "重度":
|
|
diseaseLevel = 3
|
|
case "中度":
|
|
diseaseLevel = 2
|
|
case "轻度":
|
|
diseaseLevel = 1
|
|
}
|
|
memo += fmt.Sprintf("发现[%s],等级[%s],长度[%f],最大宽度[%s],面积[%f];\n", val.Type, val.Level, val.Param.Length, val.Param.MaxWidth, val.Param.Area)
|
|
}
|
|
}
|
|
fn, _ := base64.StdEncoding.DecodeString(fileDiscern)
|
|
buff := bytes.NewBuffer(fn)
|
|
_, imgType, _ := image.Decode(buff)
|
|
fileDiscern = fmt.Sprintf("data:image/%s;base64,%s", imgType, fileDiscern)
|
|
item := proto.TaskResultItem{
|
|
FileId: v.FileId,
|
|
FileName: v.SrcPath,
|
|
SrcFile: file.AccessUrl,
|
|
DistFile: fileDiscern,
|
|
DiseaseType: int(diseaseType),
|
|
DiseaseTypeName: diseaseTypeName,
|
|
DiseaseLevel: diseaseLevel,
|
|
DiseaseLevelName: diseaseLevelName,
|
|
KPile: "",
|
|
UpDown: 0,
|
|
LineNum: 0,
|
|
Length: length,
|
|
Width: width,
|
|
Area: area,
|
|
HorizontalPositions: 0,
|
|
Memo: memo,
|
|
Stat: false,
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
}
|
|
disTypeList := make([]model.DiseaseType, 0)
|
|
err = model.DB.Find(&disTypeList)
|
|
if err != nil {
|
|
goto ReturnPoint
|
|
}
|
|
diseaseTypeList := make(map[int64]string)
|
|
for _, v := range disTypeList {
|
|
diseaseTypeList[v.TypeId] = v.TypeName
|
|
}
|
|
diseaseLevelList := make(map[int]string)
|
|
diseaseLevelList[1] = "轻度"
|
|
diseaseLevelList[2] = "中度"
|
|
diseaseLevelList[3] = "重度"
|
|
|
|
xlsx := excelize.NewFile()
|
|
xlsx.MergeCell("Sheet1", "A1", "L1")
|
|
xlsx.MergeCell("Sheet1", "A2", "L2")
|
|
xlsx.MergeCell("Sheet1", "A3", "L3")
|
|
xlsx.MergeCell("Sheet1", "A4", "L4")
|
|
xlsx.SetCellValue("Sheet1", "A4", "病害明细")
|
|
//序号 路线编码 方向 桩号 车道 病害名称 程度 长度(m) 宽度(m) 面积(㎡) 横向位置 备注
|
|
|
|
xlsx.SetCellValue("Sheet1", "A5", "序号")
|
|
xlsx.SetCellValue("Sheet1", "B5", "路线编码")
|
|
xlsx.SetCellValue("Sheet1", "C5", "方向")
|
|
xlsx.SetCellValue("Sheet1", "D5", "桩号")
|
|
xlsx.SetCellValue("Sheet1", "E5", "车道")
|
|
xlsx.SetCellValue("Sheet1", "F5", "病害名称")
|
|
xlsx.SetCellValue("Sheet1", "G5", "程度")
|
|
xlsx.SetCellValue("Sheet1", "H5", "长度(m)")
|
|
xlsx.SetCellValue("Sheet1", "I5", "宽度(m)")
|
|
xlsx.SetCellValue("Sheet1", "J5", "面积(㎡)")
|
|
xlsx.SetCellValue("Sheet1", "K5", "横向位置")
|
|
xlsx.SetCellValue("Sheet1", "L5", "备注")
|
|
for k, v := range list {
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("A%d", k+6), k+1)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("B%d", k+6), v.KPile)
|
|
switch v.UpDown {
|
|
case 1:
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("C%d", k+6), "上行")
|
|
case 2:
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("C%d", k+6), "下行")
|
|
}
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("D%d", k+6), v.KPile)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("E%d", k+6), v.LineNum)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("F%d", k+6), diseaseTypeList[int64(v.DiseaseType)])
|
|
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("G%d", k+6), diseaseLevelList[v.DiseaseLevel])
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("H%d", k+6), v.Length)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("I%d", k+6), v.Width)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("J%d", k+6), v.Area)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("K%d", k+6), v.HorizontalPositions)
|
|
xlsx.SetCellValue("Sheet1", fmt.Sprintf("K%d", k+6), v.Memo)
|
|
|
|
}
|
|
//rsp = xlsx
|
|
//rsp.Code = http.StatusOK
|
|
//rsp.Status = http.StatusText(http.StatusOK)
|
|
//rsp.Message = "成功"
|
|
//rsp.Data = xlsx
|
|
//rsp.Err = err
|
|
return xlsx, err
|
|
}
|
|
ReturnPoint:
|
|
if err != nil {
|
|
rsp = nil
|
|
//rsp.Code = http.StatusInternalServerError
|
|
//rsp.Status = http.StatusText(http.StatusInternalServerError)
|
|
//rsp.Err = err
|
|
//rsp.Message = "失败"
|
|
}
|
|
return rsp, err
|
|
}
|