This commit is contained in:
2025-07-07 20:11:59 +08:00
parent ab0fdbc447
commit 06e3aa2eb3
2009 changed files with 193082 additions and 0 deletions

162
api/project/index_count.go Normal file
View File

@ -0,0 +1,162 @@
package project
import (
"context"
"encoding/json"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/glog"
)
// PvModuleStatsReq 用于查询统计信息的请求结构体
type PvModuleStatsReq struct {
g.Meta `path:"moduleStats" method:"get" tags:"项目首页相关" summary:"获取模块的统计信息"`
SubProjectId string `json:"subProjectId"`
FangzhenId string `json:"fangzhenId"`
}
// PvModuleStatsRes 用于封装统计结果的响应结构体,调整为使用字符串描述类型
type PvModuleStatsRes struct {
Data []struct {
TypeDesc string `json:"typeDesc"`
Total int `json:"total"`
Complete int `json:"complete"`
} `json:"data"`
}
func (p Project) QueryPvModuleStats(ctx context.Context, req *PvModuleStatsReq) (res *PvModuleStatsRes, err error) {
model := g.Model("pv_module").Fields("type, COUNT(*) as total, SUM(CASE WHEN status='2' THEN 1 ELSE 0 END) as complete").Group("type")
if req.SubProjectId != "" {
model = model.Where("sub_projectid", req.SubProjectId)
}
if req.FangzhenId != "" {
model = model.Where("fangzhen_id", req.FangzhenId)
}
var stats []struct {
Type int `json:"type"`
Total int `json:"total"`
Complete int `json:"complete"`
}
err = model.Scan(&stats)
if err != nil {
glog.Error(ctx, "查询 pv_module 统计信息失败:", err)
return nil, err
}
var resultStats []struct {
TypeDesc string `json:"typeDesc"`
Total int `json:"total"`
Complete int `json:"complete"`
}
for _, stat := range stats {
typeDesc, exists := ConstMap[stat.Type]
if !exists {
glog.Error(ctx, "未知的 type", stat.Type)
continue // 或者处理未知类型
}
resultStats = append(resultStats, struct {
TypeDesc string `json:"typeDesc"`
Total int `json:"total"`
Complete int `json:"complete"`
}{TypeDesc: typeDesc, Total: stat.Total, Complete: stat.Complete})
}
return &PvModuleStatsRes{Data: resultStats}, nil
}
// 修改请求结构体以接收类型切片
type PvModuleQueryReq struct {
g.Meta `path:"indexCount" method:"get" tags:"项目首页相关" summary:"根据子项目ID、方针ID和类型来获取数据"`
SubProjectId string `json:"subProjectId"`
FangzhenId string `json:"fangzhenId"`
Types []int `json:"types"` // 新增字段,用于指定需要查询的类型
}
// 修改返回结果结构体,去除 total 和 complete
type PvModuleQueryRes struct {
Data map[int][]PVModule `json:"data"`
View string `json:"view" orm:"view"`
}
func (p Project) QueryPVModule(ctx context.Context, req *PvModuleQueryReq) (res *PvModuleQueryRes, err error) {
res = new(PvModuleQueryRes)
// 查询对应方针的 View 值
g.Model("qianqi_fangzhen").Where("id", req.FangzhenId).Scan(&res)
// 准备存储每种 type 对应的数据
data := make(map[int][]PVModule)
// 仅针对请求中指定的 type 进行查询
for _, t := range req.Types {
var modules []PVModule
queryModel := g.Model("pv_module").Where("type", t)
if req.SubProjectId != "" {
queryModel = queryModel.Where("sub_projectid", req.SubProjectId)
}
if req.FangzhenId != "" {
queryModel = queryModel.Where("fangzhen_id", req.FangzhenId)
}
err = queryModel.Scan(&modules)
if err != nil {
continue // 或处理错误
}
// 对 modules 进行处理,比如反序列化 Detail 字段、添加倾角和方位角等
var processedModules []PVModule
for _, m := range modules {
// 反序列化 Detail 字段
var detailMap map[string]interface{}
err = json.Unmarshal([]byte(m.Detail), &detailMap)
if err != nil {
continue
}
// 为其添加倾角和方位角
//detailMap["roll"] = m.Tilt
//detailMap["heading"] = m.Azimuth
// 重新序列化
serializedDetail, _ := json.Marshal(detailMap)
processedModules = append(processedModules, PVModule{
ID: m.ID,
FangzhenID: m.FangzhenID,
SubProjectID: m.SubProjectID,
WorkID: m.WorkID,
Name: m.Name,
Status: m.Status,
DoneTime: m.DoneTime,
Detail: string(serializedDetail),
Type: t,
DeviceID: m.DeviceID,
EquipmentSn: "",
})
}
// 遍历processedModules中那些DeviceID不为空的值取出数据然后查询equipment表根据设备id查询equipment表得到设备sn赋值给EquipmentSn
for i, mod := range processedModules {
if mod.DeviceID != "" {
var equipment struct {
EquipmentSn string
}
// 使用g.DB模型查询equipment表中的SN字段假定设备的序列号字段为SN
err := g.Model("equipment").Fields("equipmentSn").Where("id", mod.DeviceID).Scan(&equipment)
if err != nil {
// 处理查询错误,例如记录日志或跳过
continue
}
// 更新模块的EquipmentSn字段
processedModules[i].EquipmentSn = equipment.EquipmentSn
}
}
// 更新数据存储结构
data[t] = processedModules
}
res.Data = data
return res, nil
}

71
api/project/index_pv.go Normal file
View File

@ -0,0 +1,71 @@
package project
import (
"context"
"encoding/json"
"unsafe"
"github.com/gogf/gf/v2/frame/g"
lop "github.com/samber/lo/parallel"
)
// 根据大项目ID去查询所有的数据
type ProjectIndexModuleReq struct {
g.Meta `path:"index" method:"get" tags:"项目首页相关" summary:"根据项目ID获取数据"`
ID int64 `json:"id"` // 项目ID
}
type ProjectIndexModuleRes struct {
Data []PVModule `json:"data"` // PVModule 切片
}
// 根据大项目ID去查询所有的 pv_module 数据
func (p Project) ProjectIndexModule(ctx context.Context, req *ProjectIndexModuleReq) (res *ProjectIndexModuleRes, err error) {
// 准备返回结果
res = &ProjectIndexModuleRes{}
// 构建查询
var modules []PVModule
err = g.Model("pv_module").As("pm").
Fields("pm.id, pm.fangzhen_id, pm.sub_projectid, pm.work_id, pm.name, pm.status, pm.done_time, pm.detail, pm.type, pm.tilt,pm.azimuth").
InnerJoin("sub_project sp", "pm.sub_projectid = sp.id").
InnerJoin("sys_project sysp", "sp.project_id = sysp.id").
Where("sysp.id", req.ID).
Where("sysp.deleted_at IS NULL").
Scan(&modules)
// 错误处理
if err != nil {
return nil, err
}
// 并行处理每个元素
lop.ForEach[PVModule](modules, func(x PVModule, i int) {
// 如果不是光伏板则不处理
if x.Type != 15 {
return
}
// 反序列化 detail 字段
var detail map[string]interface{}
if err := json.Unmarshal([]byte(x.Detail), &detail); err != nil {
return
}
// 为其添加倾角和方位角
//detail["roll"] = x.Tilt
//detail["heading"] = x.Azimuth
// 重新序列化
detailBytes, err := json.Marshal(detail)
if err != nil {
return
}
// 重新赋值给 modules[i].Detail
modules[i].Detail = *(*string)(unsafe.Pointer(&detailBytes))
})
// 将查询结果赋值给返回结构
res.Data = modules
return res, nil
}

61
api/project/model.go Normal file
View File

@ -0,0 +1,61 @@
package project
// 大项目表
type SysProject struct {
ID int64 `json:"id"` // 项目ID
ProjectName string `json:"projectName"` // 项目名称
ShortName string `json:"shortName"` // 项目简称
PID int64 `json:"pId"` // 父ID
Status string `json:"status"` // 状态0正常 1停用
PicURL string `json:"picUrl"` // 项目图片URL
Lng string `json:"lng"` // 经度
Lat string `json:"lat"` // 纬度
Remark string `json:"remark"` // 备注
Type string `json:"type"` // 项目类型
ColourRGB string `json:"colourRgb"` // 展示颜色RGB值
CreateBy string `json:"createBy"` // 创建者
UpdateBy string `json:"updateBy"` // 更新者
CreateTime string `json:"createTime"` // 创建时间
UpdateTime string `json:"updateTime"` // 更新时间
DeletedAt string `json:"deletedAt"` // 删除时间
ProjectID string `json:"projectId"` // 废弃字段项目ID
View string `json:"view"` // 项目所在地视角参数
ProjectSite string `json:"projectSite"` // 项目地址
Principal string `json:"principal"` // 负责人
PrincipalPhone string `json:"principalPhone"` // 负责人电话
PrincipalXZ string `json:"principalXz"` // 小程序薪资负责人
Actual string `json:"actual"` // 实际容量
Plan string `json:"plan"` // 计划容量
OnStreamTime string `json:"onStreamTime"` // 开工时间
PunchRange string `json:"punchRange"` // 打卡范围(默认值:"09:00,18:00"
DesignTotal int `json:"designTotal"` // 设计总量
SecurityAgreement string `json:"securityAgreement"` // 安全协议书
IsType string `json:"isType"` // 项目类型1光伏 2风电
}
// 子项目表
type SubProject struct {
ID uint `json:"id"` // 主键ID
ProjectID uint `json:"projectId"` // 项目ID
ProjectName string `json:"projectName"` // 子项目名
CreatedAt string `json:"createdAt"` // 创建时间
}
// PVModule 表示光伏模块的数据模型
type PVModule struct {
ID uint `json:"id" dc:"主键ID"` // 主键ID用于唯一标识光伏模块
FangzhenID string `json:"fangzhenId" dc:"方阵ID"` // 方阵ID指示光伏模块所属方阵的唯一标识符
SubProjectID string `json:"subProjectId" dc:"子项目ID"` // 子项目ID标识光伏模块所属子项目的唯一标识符
WorkID string `json:"workId" dc:"工作ID"` // 工作ID表示光伏模块所关联的工作的唯一标识符
Name string `json:"name" dc:"名字"` // 名字,光伏模块的名称或标识
Status string `json:"status" dc:"状态"` // 状态表示光伏模块的当前状态。可能的取值有0表示未开始1表示进行中2表示已完成
DoneTime string `json:"doneTime" dc:"完成时间"` // 完成时间,指示光伏模块完成的时间
Detail string `json:"detail" dc:"坐标详细信息"` // 坐标详细信息,包含关于光伏模块的详细描述
Type int `json:"type" dc:"类型"` // 类型,表示光伏模块的类型
Tilt float64 `json:"-" orm:"tilt" dc:"倾斜角"` // 倾斜角
Azimuth float64 `json:"-" orm:"azimuth" dc:"方位角"` // 方位角
DeviceID string `json:"deviceID" orm:"device_id" dc:"设备ID"` // 设备ID
EquipmentSn string `json:"equipmentSn" dc:"设备序列号"` // 设备序列号
//Heading float64 `json:"heading" orm:"heading" dc:"方位角"` // 方位角
//Roll float64 `json:"roll" orm:"roll" dc:"倾斜角"` // 倾斜角
}

4
api/project/project.go Normal file
View File

@ -0,0 +1,4 @@
package project
type Project struct {
}

46
api/project/pv_update.go Normal file
View File

@ -0,0 +1,46 @@
package project
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
)
// 根据 ID 更新 pv_module 数据库的信息
type PvModuleUpdateBatchReq struct {
g.Meta `path:"updateBatch" method:"post" tags:"项目首页相关" summary:"批量更新数据"`
Modules []PVModule
}
type PvModuleUpdateRes struct {
}
// PvModuleUpdateBatch 根据ID批量更新对应的pv_module数据
func (p Project) PvModuleUpdateBatch(ctx context.Context, req *PvModuleUpdateBatchReq) (res *PvModuleUpdateRes, err error) {
res = &PvModuleUpdateRes{}
batchSize := 300 // 每批处理的数据量
for i := 0; i < len(req.Modules); i += batchSize {
end := i + batchSize
if end > len(req.Modules) {
end = len(req.Modules)
}
batch := req.Modules[i:end]
for _, module := range batch {
dataMap := g.Map{
"detail": module.Detail,
}
// 更新操作
if _, err := g.Model("pv_module").Data(dataMap).Where("id", module.ID).Update(); err != nil {
fmt.Printf("Error updating module ID %d: %v\n", module.ID, err)
return nil, err // 如果更新过程中出现错误,提前返回
}
}
// 可以在这里加入日志,记录这一批次的处理情况
fmt.Printf("Updated a batch of %d modules starting from ID %d\n", len(batch), batch[0].ID)
}
// 返回更新结果
return res, nil
}

12
api/project/router.go Normal file
View File

@ -0,0 +1,12 @@
package project
import "github.com/gogf/gf/v2/net/ghttp"
func InitProjectAPI(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareCORS)
group.Group("/manage", func(group *ghttp.RouterGroup) {
group.Group("/api/v1", func(group *ghttp.RouterGroup) {
group.Bind(new(Project))
})
})
}

38
api/project/type_map.go Normal file
View File

@ -0,0 +1,38 @@
package project
var ConstMap = map[int]string{
1: "防雷接地网",
2: "接地沟",
3: "接地敷设",
4: "接地检测",
5: "围栏",
6: "围栏基础",
7: "围栏安装",
8: "道路",
9: "道路路基",
10: "道路排水沟",
11: "低压部分",
12: "低压钻孔",
13: "低压桩基",
14: "低压支架",
15: "低压光伏板",
16: "低压直流电缆",
17: "低压接地线",
18: "低压逆变器安装",
19: "低压电缆沟开挖",
20: "低压敷设",
21: "低压调试",
22: "高压部分",
23: "高压箱变基础",
24: "高压箱变安装",
25: "高压电缆线开挖",
26: "高压电缆敷设",
27: "高压电缆试验",
28: "高压电缆调式试验",
29: "环网柜",
30: "环网柜基础",
31: "环网柜安装",
32: "环网柜敷设",
33: "环网柜试验",
34: "环网柜调试试验",
}