Przeglądaj źródła

Merge branch 'feature/eta2.5.9_api_stat' of eta_server/eta_api into master

xyxie 1 tydzień temu
rodzic
commit
ab9d3819d8
30 zmienionych plików z 2589 dodań i 74 usunięć
  1. 394 0
      controllers/data_manage/edb_inspection.go
  2. 96 0
      controllers/data_manage/edb_inspection_message.go
  3. 65 12
      controllers/data_stat/edb_source_stat.go
  4. 238 7
      controllers/data_stat/edb_terminal.go
  5. 13 8
      controllers/edb_monitor/edb_monitor_message.go
  6. 19 2
      controllers/message.go
  7. 38 0
      global/websocket.go
  8. 176 0
      models/data_manage/edb_inspection/edb_inspection_config.go
  9. 112 0
      models/data_manage/edb_inspection/edb_inspection_dashboard.go
  10. 114 0
      models/data_manage/edb_inspection/edb_inspection_date_config.go
  11. 170 0
      models/data_manage/edb_inspection/edb_inspection_message.go
  12. 112 0
      models/data_manage/edb_inspection/edb_inspection_record.go
  13. 117 6
      models/data_manage/edb_terminal.go
  14. 2 0
      models/data_manage/mysteel_chemical_index.go
  15. 1 0
      models/data_stat/edb_info_update_stat.go
  16. 7 0
      models/message.go
  17. 117 0
      routers/commentsRouter.go
  18. 2 0
      routers/router.go
  19. 397 0
      services/data/edb_inspection.go
  20. 114 0
      services/data/edb_inspection_message.go
  21. 35 39
      services/edb_monitor/edb_monitor_message.go
  22. 211 0
      services/websocket_msg.go
  23. BIN
      static/wind指标刷新失败处理.pdf
  24. BIN
      static/同花顺指标API方式刷新失败处理.pdf
  25. BIN
      static/钢联指标API对接刷新失败处理.pdf
  26. BIN
      static/钢联指标终端对接刷新失败处理.pdf
  27. 1 0
      utils/constants.go
  28. 1 0
      utils/redis.go
  29. 19 0
      utils/redis/cluster_redis.go
  30. 18 0
      utils/redis/standalone_redis.go

+ 394 - 0
controllers/data_manage/edb_inspection.go

@@ -0,0 +1,394 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage/edb_inspection"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+	"time"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type EdbInspectionController struct {
+	controllers.BaseAuthController
+}
+
+// InspectionSourceList
+// @Title 获取巡检配置的来源接口
+// @Description 获取巡检配置的来源接口
+// @Success Ret=200 获取成功
+// @router /edb_inspection/source_list [get]
+func (c *EdbInspectionController) InspectionSourceList() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	// 这里可以添加获取巡检来源的逻辑
+	// 目前暂时返回空列表
+	list := make([]interface{}, 0)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// InspectionConfigList
+// @Title 获取巡检配置列表接口
+// @Description 获取巡检配置列表接口
+// @Param   Source   query   int  true       "来源"
+// @Param   TerminalCode   query   string  false       "终端编码"
+// @Success Ret=200 获取成功
+// @router /edb_inspection/config/list [get]
+func (c *EdbInspectionController) InspectionConfigList() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	source, _ := c.GetInt("Source")
+	terminalCode := c.GetString("TerminalCode")
+
+	list, err, errMsg, isSendEmail := data.GetConfigList(source, terminalCode)
+	if err != nil {
+		br.Msg = errMsg
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// SaveInspectionConfig
+// @Title 设置巡检配置接口
+// @Description 设置巡检配置接口
+// @Param	request	body edb_inspection.EdbInspectionConfigAddReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_inspection/config/save [post]
+func (c *EdbInspectionController) SaveInspectionConfig() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req edb_inspection.EdbInspectionConfigAddReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 保存
+	err, errMsg, isSendEmail := data.SaveEdbInspectionConfig(&req)
+	if err != nil {
+		br.Msg = errMsg
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// UpdateInspectionConfigStatus
+// @Title 更新巡检配置状态接口
+// @Description 更新巡检配置状态接口
+// @Param   ConfigId   query   int64  true       "配置ID"
+// @Param   Status   query   int8  true       "状态"
+// @Success Ret=200 更新成功
+// @router /edb_inspection/config/status/update [post]
+func (c *EdbInspectionController) UpdateInspectionConfigStatus() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req edb_inspection.EdbInspectionConfigStatusReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	configId := req.ConfigId
+	status := req.Status
+	if status != 1 && status != 0 {
+		br.Msg = "状态错误"
+		br.ErrMsg = "状态错误,请输入1或0"
+		br.IsSendEmail = false
+		return
+	}
+
+	if configId <= 0 {
+		br.Msg = "配置ID不能为空"
+		br.IsSendEmail = false
+		return
+	}
+
+	config := &edb_inspection.EdbInspectionConfig{
+		ConfigId: configId,
+	}
+
+	err = config.UpdateStatus(status)
+	if err != nil {
+		br.Msg = "更新失败"
+		br.ErrMsg = "更新失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "更新成功"
+}
+
+// DeleteInspectionConfig
+// @Title 删除巡检配置接口
+// @Description 删除巡检配置接口
+// @Param   ConfigId   query   int64  true       "配置ID"
+// @Success Ret=200 删除成功
+// @router /edb_inspection/config/delete [post]
+func (c *EdbInspectionController) DeleteInspectionConfig() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req edb_inspection.EdbInspectionConfigDeleteReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	configId := req.ConfigId
+	if configId <= 0 {
+		br.Msg = "配置ID不能为空"
+		br.IsSendEmail = false
+		return
+	}
+
+	config := &edb_inspection.EdbInspectionConfig{
+		ConfigId: configId,
+	}
+
+	err = config.Delete()
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	_ = edb_inspection.DeleteEdbInspectionDateConfigByConfigId(configId)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "删除成功"
+}
+
+// GetInspectionConfigDetail
+// @Title 获取巡检配置详情接口
+// @Description 获取巡检配置详情接口
+// @Param   ConfigId   query   int64  true       "配置ID"
+// @Success Ret=200 获取成功
+// @router /edb_inspection/config/detail [get]
+func (c *EdbInspectionController) GetInspectionConfigDetail() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	configId, _ := c.GetInt64("ConfigId")
+
+	if configId <= 0 {
+		br.Msg = "配置ID不能为空"
+		br.IsSendEmail = false
+		return
+	}
+
+	detail, err := data.GetConfigDetail(configId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = detail
+} 
+
+// 查询看板列表
+// @Title 查询看板列表接口
+// @Description 查询看板列表接口
+// @Success Ret=200 获取成功
+// @router /edb_inspection/dashboard [get]
+func (c *EdbInspectionController) GetDashboardList() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	list, err := edb_inspection.GetDashboardList()
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// 查询看板详情
+// @Title 查询看板详情接口
+// @Description 查询看板详情接口
+// @Success Ret=200 获取成功
+// @router /edb_inspection/record [get]
+func (c *EdbInspectionController) GetInspectionRecordDetail() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	// 根据source和terminalCode查询巡检记录
+	source, _ := c.GetInt("Source")
+	terminalCode := c.GetString("TerminalCode")
+	startDate := c.GetString("StartDate")
+	endDate := c.GetString("EndDate")
+
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize := utils.StartIndex(currentIndex, pageSize)
+
+	condition := ``
+	var pars []interface{}
+
+	if source > 0 {
+		condition += " AND r.source = ?"
+		pars = append(pars, source)
+	}
+	if terminalCode != "" {
+		condition += " AND r.terminal_code = ?"
+		pars = append(pars, terminalCode)
+	}
+	if startDate != "" {
+		// 检查是否是时间格式
+		_, err := time.Parse(utils.FormatDate, startDate)
+		if err != nil {
+			br.Msg = "开始时间格式错误"
+			br.ErrMsg = "开始时间格式错误,请输入正确的时间格式"
+			return
+		}
+		condition += " AND r.inspection_time >= ?"
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		// 检查是否是时间格式
+		_, err := time.Parse(utils.FormatDate, endDate)
+		if err != nil {
+			br.Msg = "结束时间格式错误"
+			br.ErrMsg = "结束时间格式错误,请输入正确的时间格式"
+			return
+		}
+		endTime := endDate + " 23:59:59"
+		condition += " AND r.inspection_time <= ?"
+		pars = append(pars, endTime)
+	}
+
+	list, err := edb_inspection.GetInspectionRecordListByCondition(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	// 查询总数
+	count, err := edb_inspection.GetInspectionRecordCountByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(count))
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = map[string]interface{}{
+		"List": list,
+		"Paging": page,
+	}
+	
+}
+
+// HelpWordDownload
+// @Title 下载错误处理文档
+// @Description 下载错误处理文档
+// @Success 200 {object} models.EdbdataClassifyResp
+// @Param   Source   query   int  false       "来源:1:同花顺;2:wind;34:钢联"
+// @Param   IsApi   query   int  false       "是否api:1:是;0:否"
+// @router /edb_inspection/help_word [get]
+func (c *EdbInspectionController) HelpWordDownload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	source, _ := c.GetInt("Source")
+	isApi, _ := c.GetInt("IsApi")
+	switch source {
+	case utils.DATA_SOURCE_THS:
+		if isApi == 1 {
+			c.Ctx.Output.Download("./static/同花顺指标API方式刷新失败处理.pdf", "同花顺指标API方式刷新失败处理.pdf")
+		}
+	case utils.DATA_SOURCE_WIND:
+		c.Ctx.Output.Download("./static/wind指标刷新失败处理.pdf", "wind指标刷新失败处理.pdf")
+	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL:
+		if isApi == 1 {
+			c.Ctx.Output.Download("./static/钢联指标API对接刷新失败处理.pdf", "钢联指标API对接刷新失败处理.pdf")
+		}else {
+			c.Ctx.Output.Download("./static/钢联指标终端对接刷新失败处理.pdf", "钢联指标终端对接刷新失败处理.pdf")
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "下载成功"
+}

+ 96 - 0
controllers/data_manage/edb_inspection_message.go

@@ -0,0 +1,96 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage/edb_inspection"
+	"eta/eta_api/services/data"
+)
+
+type EdbInspectionMessageController struct {
+	controllers.BaseAuthController
+}
+
+
+// List
+// @Title 巡检消息列表
+// @Description 巡检消息列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} response.EdbInspectionMessageListResp
+// @router /edb_inspection/message/list [get]
+func (c *EdbInspectionMessageController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")	
+	resp, err := data.GetInspectionMessageList(sysUser.AdminId, currentIndex, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	br.Data = resp
+	br.Msg = "获取成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// Read
+// @Title 巡检消息已读
+// @Description 巡检消息已读
+// @Param   request body request.EdbInspectionMessageReadReq  true  "消息ID"
+// @Success 200 {object} models.BaseResponse
+// @router /edb_inspection/message/read [post]
+func (m *EdbInspectionMessageController) Read() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		m.Data["json"] = br
+		m.ServeJSON()
+	}()
+
+	sysUser := m.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req edb_inspection.EdbInspectionMessageReadReq
+	if err := json.Unmarshal(m.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,err:" + err.Error()
+		return
+	}
+	if req.MessageId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	msg, err := data.ReadEdbInspectionMessage(req.MessageId, sysUser.AdminId)
+	if err != nil {
+		if msg == "" {
+			msg = "系统错误"
+		}
+		br.Msg = msg
+		br.ErrMsg = "读取消息失败,err:" + err.Error()
+		return
+	}
+
+	br.Msg = "已读成功"
+	br.Ret = 200
+	br.Success = true
+}

+ 65 - 12
controllers/data_stat/edb_source_stat.go

@@ -41,6 +41,7 @@ func (this *EdbSourceStatController) Column() {
 		br.Msg = "请选择表类型"
 		return
 	}
+	isApi, _ := this.GetInt("IsApi", 0)
 	tmpList, err := data_stat.GetStatColumn(columnType)
 	if err != nil {
 		br.Msg = "获取自定义列失败"
@@ -49,6 +50,9 @@ func (this *EdbSourceStatController) Column() {
 	}
 	var list []*data_stat.EdbInfoStatColumnListItem
 	for _, v := range tmpList {
+		if isApi == 1 && v.ColumnKey == "InitSourceName" {
+			continue
+		}
 		tmp := new(data_stat.EdbInfoStatColumnListItem)
 		tmp.ColumnKey = v.ColumnKey
 		tmp.IsShow = v.IsShow
@@ -165,7 +169,11 @@ func (this *EdbSourceStatController) EdbDeleteLog() {
 		br.Ret = 408
 		return
 	}
-
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 	sortParamReq := this.GetString("SortParam", "")
 	sortType := this.GetString("SortType", "desc")
 	createTime := this.GetString("CreateTime", "")
@@ -185,7 +193,7 @@ func (this *EdbSourceStatController) EdbDeleteLog() {
 
 	condition := " and source = ?"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL)
+	pars = append(pars, source)
 
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)
@@ -314,7 +322,11 @@ func (this *EdbSourceStatController) EdbUpdateLog() {
 		br.Ret = 408
 		return
 	}
-
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 	sortParamReq := this.GetString("SortParam", "")
 	sortType := this.GetString("SortType", "desc")
 	createTime := this.GetString("CreateTime", "")
@@ -335,7 +347,7 @@ func (this *EdbSourceStatController) EdbUpdateLog() {
 
 	condition := " and source = ? and (data_update_result=1 or data_update_result=0)"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL)
+	pars = append(pars, source)
 
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)
@@ -469,6 +481,11 @@ func (this *EdbSourceStatController) EdbUpdateStat() {
 
 	sortParamReq := this.GetString("SortParam", "")
 	sortType := this.GetString("SortType", "desc")
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 	terminalCode := this.GetString("TerminalCode", "")
 	sysUserId := this.GetString("SysUserId", "")
 	frequency := this.GetString("Frequency", "")
@@ -478,7 +495,17 @@ func (this *EdbSourceStatController) EdbUpdateStat() {
 
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
+	isApi, _ := this.GetInt("IsApi", 0)
 
+	// 区分终端和API的统计
+	// 查询类型为API的终端编码
+	terminalCodeList, err := data_manage.GetTerminalCodeBySourceAndIsApi(source, isApi)
+	if err != nil {
+		br.Msg = "获取终端编码失败"
+		br.ErrMsg = "获取终端编码失败,Err:" + err.Error()
+		return
+	}
+	
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -489,9 +516,10 @@ func (this *EdbSourceStatController) EdbUpdateStat() {
 
 	startSize = paging.StartIndex(currentIndex, pageSize)
 
-	condition := " and source = ?"
+	condition := " and source = ? and terminal_code in (" + utils.GetOrmInReplace(len(terminalCodeList)) + ")"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL)
+	pars = append(pars, source)
+	pars = append(pars, terminalCodeList)
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)
 		if err != nil {
@@ -666,14 +694,18 @@ func (this *EdbSourceStatController) EdbSourceStat() {
 		br.Ret = 408
 		return
 	}
-
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 	sortParamReq := this.GetString("SortParam", "")
 	sortType := this.GetString("SortType", "desc")
 	createTime := this.GetString("CreateTime", "")
 
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
-
+	isApi, _ := this.GetInt("IsApi", 0)
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -684,9 +716,20 @@ func (this *EdbSourceStatController) EdbSourceStat() {
 
 	startSize = paging.StartIndex(currentIndex, pageSize)
 
-	condition := " and source = ?"
+	// 区分终端和API的统计
+	// 查询类型为API的终端编码
+	terminalCodeList, err := data_manage.GetTerminalCodeBySourceAndIsApi(source, isApi)
+	if err != nil {
+		br.Msg = "获取终端编码失败"
+		br.ErrMsg = "获取终端编码失败,Err:" + err.Error()
+		return
+	}
+	
+
+	condition := " and source = ? and terminal_code in (" + utils.GetOrmInReplace(len(terminalCodeList)) + ")"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL)
+	pars = append(pars, source)
+	pars = append(pars, terminalCodeList)
 
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)
@@ -801,13 +844,18 @@ func (this *EdbSourceStatController) EdbUpdateFailedList() {
 		br.Ret = 408
 		return
 	}
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 
 	terminalCode := this.GetString("TerminalCode", "")
 	createTime := this.GetString("CreateTime", "")
 
 	condition := " and source = ? and terminal_code = ?"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, terminalCode)
+	pars = append(pars, source, terminalCode)
 
 	terminalName := ""
 	terminalDir := ""
@@ -889,6 +937,11 @@ func (this *EdbSourceStatController) EdbUpdateFailedDetailList() {
 		br.Ret = 408
 		return
 	}
+	source, _ := this.GetInt("Source", -1)
+	if source < 0 {
+		br.Msg = "请选择数据源"
+		return
+	}
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 
@@ -919,7 +972,7 @@ func (this *EdbSourceStatController) EdbUpdateFailedDetailList() {
 
 	condition := " and source = ? AND terminal_code = ? and frequency=? and data_update_failed_reason=? and data_update_result = 2"
 	var pars []interface{}
-	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, terminalCode, frequency, sourceUpdateFailedReason)
+	pars = append(pars, source, terminalCode, frequency, sourceUpdateFailedReason)
 
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)

+ 238 - 7
controllers/data_stat/edb_terminal.go

@@ -8,6 +8,9 @@ import (
 	"eta/eta_api/services/data_stat"
 	"eta/eta_api/utils"
 	"fmt"
+	"strconv"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // EdbTerminalController 数据源终端管理
@@ -49,10 +52,10 @@ func (this *EdbTerminalController) Save() {
 		br.Msg = "请输入终端地址或者token"
 		return
 	}*/
-	if req.Num <= 0 {
-		br.Msg = "请输入指标数据量"
-		return
-	}
+	// if req.Num <= 0 {
+	// 	br.Msg = "请输入指标数据量"
+	// 	return
+	// }
 	if req.Source == 0 {
 		br.Msg = "请输入终端类型"
 		return
@@ -130,7 +133,7 @@ func (this *EdbTerminalController) List() {
 	br.IsSendEmail = false
 	defer func() {
 		this.Data["json"] = br
-		this.ServeJSON()
+		this.ServeJSON()   
 	}()
 	sysUser := this.SysUser
 	if sysUser == nil {
@@ -139,13 +142,56 @@ func (this *EdbTerminalController) List() {
 		br.Ret = 408
 		return
 	}
+	source, _ := this.GetInt("Source")
 
-	list, err := data_manage.GetEdbTerminalList()
+	list, err := data_manage.GetEdbTerminalList(source)
 	if err != nil {
 		br.Msg = "获取终端列表失败"
 		br.ErrMsg = "获取终端列表失败 ErrMsg:" + err.Error()
 		return
 	}
+
+	// 计算已使用额度
+	// 根据source查找对应的终端信息,比如source为34,则查询对应的数据源里的指标
+	// 获取数据源详细信息
+	for _, v := range list {
+		num, subNumList, err := data_manage.GetIndexNumBySource(v.Source, v.TerminalCode)
+		if err != nil {
+			br.Msg = "获取终端列表失败"
+			br.ErrMsg = "获取终端列表失败 ErrMsg:" + err.Error()
+			return
+		}
+		v.UsedQuota = strconv.Itoa(num)
+		if v.Source == utils.DATA_SOURCE_THS {
+			edbNum := 0
+			dateNum := 0
+			hfNum := 0
+			for _, subNum := range subNumList {
+				if subNum.SubSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY {
+					hfNum = subNum.Num
+				} else if subNum.SubSource == utils.DATA_SUB_SOURCE_EDB {
+					edbNum = subNum.Num
+				} else if subNum.SubSource == utils.DATA_SUB_SOURCE_DATE {
+					dateNum = subNum.Num
+				}
+			}
+			v.UsedQuota = fmt.Sprintf("EDB:%d\n日期序列:%d\n高频序列:%d", edbNum, dateNum, hfNum)
+		}else if v.Source == utils.DATA_SOURCE_WIND {
+			edbNum := 0
+			dateNum := 0
+			for _, subNum := range subNumList {
+				if subNum.SubSource == utils.DATA_SUB_SOURCE_EDB {
+					edbNum = subNum.Num
+				} else if subNum.SubSource == utils.DATA_SUB_SOURCE_DATE {
+					dateNum = subNum.Num
+				}
+			}
+			v.UsedQuota = fmt.Sprintf("EDB:%d\n日期序列:%d", edbNum, dateNum)
+		}else if len(subNumList) == 1 {
+			v.UsedQuota = strconv.Itoa(subNumList[0].Num)
+		}
+	}
+
 	resp := &data_manage.EdbTerminalListResp{
 		List: list,
 	}
@@ -175,7 +221,8 @@ func (this *EdbTerminalController) TerminalCodeList() {
 		return
 	}
 	source, _ := this.GetInt("Source", utils.DATA_SOURCE_MYSTEEL_CHEMICAL)
-	list, err := data_manage.GetEdbTerminalBySource(source)
+	isApi, _ := this.GetInt("IsApi", 0)
+	list, err := data_manage.GetEdbTerminalBySourceAndIsApi(source, isApi)
 	if err != nil {
 		br.Msg = "获取终端列表失败"
 		br.ErrMsg = "获取终端列表失败 ErrMsg:" + err.Error()
@@ -240,3 +287,187 @@ func (this *EdbTerminalController) TerminalIndexDirInfo() {
 	br.Msg = "获取成功"
 	br.Data = info
 }
+
+// 查询指标列表
+// @Title 查询指标列表接口
+// @Description 查询指标列表接口
+// @Success Ret=200 获取成功
+// @router /terminal/edb_info/list [get]
+func (c *EdbTerminalController) GetEdbInfoList() {
+	br := new(models.BaseResponse).Init()
+
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	source, _ := c.GetInt("Source")
+	terminalCode := c.GetString("TerminalCode")
+	keyword := c.GetString("Keyword")
+	
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+
+	var startSize int
+	
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	if source <= 0 {
+		br.Msg = "来源不能为空"
+		br.ErrMsg = "来源不能为空"
+		br.IsSendEmail = false
+		return
+	}
+
+	condition := ``
+	var pars []interface{}
+	var list []*data_manage.EdbInfoTerminalList
+	var count int64
+	var err error
+	indexTableName := data_manage.EdbSourceIdMap[source].IndexTableName
+	if indexTableName != "" {
+		if terminalCode != "" {
+			condition += " AND e.terminal_code = ?"
+			pars = append(pars, terminalCode)
+		}
+		if keyword != "" {
+			condition += " AND (e.index_name like ? or e.index_code like ?)"
+			pars = append(pars, "%"+keyword+"%")
+			pars = append(pars, "%"+keyword+"%")
+		}
+		list, err = data_manage.GetSimpleBaseIndexListPageByCondition(indexTableName, condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		count, err = data_manage.GetSimpleBaseIndexListCountByCondition(indexTableName, condition, pars)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		
+	}else{
+		condition += " AND e.source = ?"
+		pars = append(pars, source)
+		if terminalCode != "" {
+			condition += " AND e.terminal_code = ?"
+			pars = append(pars, terminalCode)
+		}
+		if keyword != "" {
+			condition += " AND (e.edb_name like ? or e.edb_code like ?)"
+			pars = append(pars, "%"+keyword+"%")
+			pars = append(pars, "%"+keyword+"%")
+		}
+	
+		list, err = data_manage.GetSimpleEdbListPageByCondition(condition, pars, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		
+		count, err = data_manage.GetSimpleEdbListCountByCondition(condition, pars)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(count))	
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = map[string]interface{}{
+		"List": list,
+		"Paging": page,
+	}
+	return
+}
+
+
+// 设置指标终端
+// @Title 设置指标终端
+// @Description 设置指标终端
+// @Success 200 string "操作成功"
+// @router /terminal/edb_info/set [post]
+func (c *EdbTerminalController) SetEdbInfoTerminal() {
+	br := new(models.BaseResponse).Init()
+	br.IsSendEmail = false
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req *data_manage.SetEdbInfoTerminalReq
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Source <= 0 {
+		br.Msg = "来源不能为空"
+		br.ErrMsg = "来源不能为空"
+		return
+	}
+
+	if req.TerminalCode == "" {
+		br.Msg = "终端编码不能为空"
+		br.ErrMsg = "终端编码不能为空"
+		return
+	}
+
+	if len(req.EdbCodes) <= 0 {
+		br.Msg = "指标编码不能为空"
+		br.ErrMsg = "指标编码不能为空"
+		return
+	}
+	
+	// 校验终端编码是否存在
+	terminal, err := data_manage.GetEdbTerminalByTerminalCode(req.TerminalCode)
+	if err != nil {
+		br.Msg = "终端编码不存在"
+		br.ErrMsg = "终端编码不存在"
+		return
+	}
+
+	if req.Source != terminal.Source {
+		br.Msg = "终端来源不匹配"
+		br.ErrMsg = "终端来源不匹配"
+		return
+	}
+
+	edbCodeList := req.EdbCodes
+
+	
+	// 更新数据源里的终端编码
+	err = data_manage.UpdatBaseIndexTerminalCode(edbCodeList, req.TerminalCode, req.Source)
+	if err != nil {
+		br.Msg = "设置失败"
+		br.ErrMsg = "设置失败,Err:" + err.Error()
+		return
+	}
+	
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "设置成功"
+	return
+}

+ 13 - 8
controllers/edb_monitor/edb_monitor_message.go

@@ -3,8 +3,10 @@ package edb_monitor
 import (
 	"encoding/json"
 	"eta/eta_api/controllers"
+	"eta/eta_api/global"
 	"eta/eta_api/models"
 	"eta/eta_api/models/edb_monitor/request"
+	"eta/eta_api/services"
 	edbmonitor "eta/eta_api/services/edb_monitor"
 	"eta/eta_api/utils"
 	"net/http"
@@ -47,10 +49,10 @@ func (m *EdbMonitorMessageController) Connect() {
 	}
 
 	var conn *websocket.Conn
-	connKey := edbmonitor.EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(sysUser.AdminId)
+	connKey := global.EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(sysUser.AdminId)
 	ok := utils.Rc.IsExist(connKey)
 	if !ok {
-		conn = edbmonitor.MonitorMessageConn[sysUser.AdminId]
+		conn = global.MonitorMessageConn[sysUser.AdminId]
 		if conn != nil {
 			conn.Close()
 		}
@@ -69,9 +71,10 @@ func (m *EdbMonitorMessageController) Connect() {
 	}
 	defer conn.Close()
 
-	edbmonitor.MonitorMessageConn[sysUser.AdminId] = conn
+	global.MonitorMessageConn[sysUser.AdminId] = conn
 	conn.SetCloseHandler(func(code int, text string) error {
-		delete(edbmonitor.MonitorMessageConn, sysUser.AdminId)
+		utils.FileLog.Info("连接关闭SetCloseHandler, adminId:%d", sysUser.AdminId)
+		delete(global.MonitorMessageConn, sysUser.AdminId)
 		utils.Rc.Delete(connKey)
 		return nil
 	})
@@ -79,12 +82,13 @@ func (m *EdbMonitorMessageController) Connect() {
 	go func() {
 		// 心跳检测
 		for {
-			isClose, err := edbmonitor.EdbMonitorMessageHealth(sysUser.AdminId)
+			isClose, err := global.EdbMonitorMessageHealth(sysUser.AdminId)
 			if err != nil {
 				utils.FileLog.Error("指标预警信息健康检查失败,err:%s, adminId:%d", err.Error(), sysUser.AdminId)
 				return
 			}
 			if isClose {
+				conn.Close()
 				return
 			}
 		}
@@ -99,8 +103,7 @@ func (m *EdbMonitorMessageController) Connect() {
 		defer close(success)
 		for i, msg := range messageList {
 			if i == 0 {
-				// 多条消息仅发送最新一条
-				err = edbmonitor.SendMessages(sysUser.AdminId, msg.EdbInfoId, msg.EdbInfoType, msg.EdbClassifyId, msg.EdbUniqueCode, msg.Message, msg.TriggerTime)
+				err := edbmonitor.SendMessages(sysUser.AdminId, msg.EdbInfoId, msg.EdbInfoType, msg.EdbClassifyId, msg.EdbUniqueCode, msg.Message, msg.TriggerTime)
 				if err != nil {
 					utils.FileLog.Error("指标预警信息发送失败,err:%s, adminId:%d", err.Error(), sysUser.AdminId)
 				} else {
@@ -126,6 +129,8 @@ func (m *EdbMonitorMessageController) Connect() {
 		}
 	}()
 
+	// 其他消息处理
+	services.DealWebSocketMsg(sysUser.AdminId)
 	for {
 		ok = utils.Rc.IsExist(connKey)
 		if !ok {
@@ -158,7 +163,7 @@ func (m *EdbMonitorMessageController) Close() {
 		return
 	}
 
-	conn := edbmonitor.MonitorMessageConn[sysUser.AdminId]
+	conn := global.MonitorMessageConn[sysUser.AdminId]
 	if conn != nil {
 		conn.Close()
 	}

+ 19 - 2
controllers/message.go

@@ -3,6 +3,7 @@ package controllers
 import (
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage/data_manage_permission"
+	"eta/eta_api/models/data_manage/edb_inspection"
 	edbmonitor "eta/eta_api/models/edb_monitor"
 	"eta/eta_api/models/report_approve"
 	"fmt"
@@ -36,7 +37,7 @@ func (c *MessageController) UnReadMessageNum() {
 		return
 	}
 
-	var unReadReportNum, unReadDataPermissionNum, unReadEdbMonitorNum int
+	var unReadReportNum, unReadDataPermissionNum, unReadEdbMonitorNum, unReadEdbInspectionNum int
 
 	// 获取报告审批消息
 	{
@@ -93,8 +94,24 @@ func (c *MessageController) UnReadMessageNum() {
 		unReadEdbMonitorNum = unreadTotal
 	}
 
+	// 获取巡检消息
+	{
+		cond := ` AND admin_id = ? AND is_read = ?`
+		pars := make([]interface{}, 0)
+		pars = append(pars, sysUser.AdminId, 0)
+
+		messageOb := new(edb_inspection.EdbInspectionMessage)
+		unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取资产消息列表总数失败, Err: " + e.Error()
+			return
+		}
+		unReadEdbInspectionNum = int(unreadTotal)
+	}
+
 	// 汇总数
-	num := unReadReportNum + unReadDataPermissionNum + unReadEdbMonitorNum
+	num := unReadReportNum + unReadDataPermissionNum + unReadEdbMonitorNum + unReadEdbInspectionNum
 
 	br.Data = num
 	br.Ret = 200

+ 38 - 0
global/websocket.go

@@ -0,0 +1,38 @@
+package global
+
+import (
+	"errors"
+	"eta/eta_api/utils"
+	"strconv"
+	"time"
+
+	"github.com/gorilla/websocket"
+)
+
+var MonitorMessageConn = make(map[int]*websocket.Conn)
+
+var (
+	EDB_MONITOR_MESSAGE_CONNECT_CACHE = "edb_monitor_message_cache:"
+)
+
+func EdbMonitorMessageHealth(adminId int) (isClose bool, err error) {
+	conn := MonitorMessageConn[adminId]
+	if conn == nil {
+		err = errors.New("no connection")
+		isClose = true
+		return
+	}
+	_, msg, err := conn.ReadMessage()
+	if err != nil {
+		isClose = true
+		return
+	}
+	if string(msg) == "ping" {
+		healthKey := EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(adminId)
+		err = utils.Rc.Put(healthKey, "1", time.Minute*1)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 176 - 0
models/data_manage/edb_inspection/edb_inspection_config.go

@@ -0,0 +1,176 @@
+package edb_inspection
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"time"
+
+	"gorm.io/gorm"
+)
+
+// EdbInspectionConfig
+// @Description: 数据源巡检配置表
+type EdbInspectionConfig struct {
+	ConfigId          int64     `gorm:"column:config_id;primaryKey;autoIncrement"`
+	Source           int       `gorm:"column:source"`
+	TerminalCode     string    `gorm:"column:terminal_code"`
+	DateType   int8      `gorm:"column:date_type"`
+	StartTime        string    `gorm:"column:start_time"`
+	IntervalTime     int       `gorm:"column:interval_time"`
+	NotifyUsers      string    `gorm:"column:notify_users"`
+	Status           int8      `gorm:"column:status"`
+	CreateTime       time.Time `gorm:"column:create_time"`
+	ModifyTime       time.Time `gorm:"column:modify_time"`
+	InspectionTime   string    `gorm:"-"` // 用于显示巡检时间,不存储到数据库
+}
+
+// Add
+// @Description: 添加巡检配置
+// @receiver m
+// @return err error
+func (m *EdbInspectionConfig) Add() (err error) {
+	m.CreateTime = time.Now()
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Create(m).Error
+	return
+}
+
+// Update
+// @Description: 更新巡检配置
+// @receiver m
+// @param cols []string
+// @return err error
+func (m *EdbInspectionConfig) Update(cols []string) (err error) {
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Select(cols).Updates(m).Error
+	return
+}
+
+// Delete
+// @Description: 删除巡检配置
+// @receiver m
+// @return err error
+func (m *EdbInspectionConfig) Delete() (err error) {
+	sql := `DELETE FROM edb_inspection_config WHERE config_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Exec(sql, m.ConfigId).Error
+	return
+}
+
+// UpdateStatus
+// @Description: 更新巡检配置状态
+// @receiver m
+// @param status int8
+// @return err error
+func (m *EdbInspectionConfig) UpdateStatus(status int8) (err error) {
+	sql := `UPDATE edb_inspection_config SET status = ?, modify_time = ? WHERE config_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Exec(sql, status, time.Now(), m.ConfigId).Error
+	return
+}
+
+// GetListByTerminalCode
+// @Description: 根据终端编码获取巡检配置列表
+// @param terminalCode string
+// @return list []*EdbInspectionConfig
+// @return err error
+func GetListByTerminalCode(terminalCode string) (list []*EdbInspectionConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_config WHERE terminal_code = ? ORDER BY config_id ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, terminalCode).Find(&list).Error
+	return
+}
+
+// GetById
+// @Description: 根据ID获取巡检配置
+// @param configId int64
+// @return item *EdbInspectionConfig
+// @return err error
+func GetById(configId int64) (item *EdbInspectionConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_config WHERE config_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, configId).First(&item).Error
+	return
+}
+
+// GetListBySource
+// @Description: 根据来源获取巡检配置列表
+// @param source int
+// @return list []*EdbInspectionConfig
+// @return err error
+func GetListBySource(source int) (list []*EdbInspectionConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_config WHERE source = ? ORDER BY config_id ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, source).Find(&list).Error
+	return
+}
+
+func GetConfigListBySourceAndTerminalCode(source int, terminalCode string) (list []*EdbInspectionConfigItem, err error) {
+	condition := " 1=1 "
+	var pars []interface{}
+
+	if source > 0 {
+		condition += " AND c.source = ? "
+		pars = append(pars, source)
+	}
+
+	if terminalCode != "" {
+		condition += " AND c.terminal_code = ? "
+		pars = append(pars, terminalCode)
+	}
+
+	sql := `SELECT c.*, t.name AS terminal_name, s.source_name FROM edb_inspection_config c left join edb_terminal t on c.terminal_code = t.terminal_code left join edb_source s on c.source = s.edb_source_id WHERE ` + condition + ` ORDER BY c.modify_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&list).Error
+	return
+}
+func(c *EdbInspectionConfigItem) AfterFind(tx *gorm.DB) (err error) {
+	c.CreateTime = utils.GormDateStrToDateTimeStr(c.CreateTime)
+	c.ModifyTime = utils.GormDateStrToDateTimeStr(c.ModifyTime)
+	return
+}
+
+type EdbInspectionConfigAddReq struct {
+	ConfigId          int64    
+	Source           int       
+	TerminalCode     string    
+	NotifyUsers         string `description:"通知用户"`
+	//Status              int8   `description:"状态"` 
+	DateType   int8      
+	StartTime         string 
+	IntervalTime      int   
+	List      []InspectionConfigReq `description:"刷新配置项"`
+}
+
+// @Description: 刷新时间配置项
+type InspectionConfigReq struct {
+	InspectionFrequency string `description:"巡检频率"`
+	InspectionFrequencyDay        int    `description:"具体刷新的日期"`
+	InspectionDate      string `description:"巡检日期"`
+	InspectionTime      string `description:"巡检时间"`
+}
+
+type EdbInspectionConfigDetailResp struct {
+	*EdbInspectionConfig
+	List      []InspectionConfigReq `description:"刷新配置项"`
+}
+
+type EdbInspectionConfigItem struct {
+	ConfigId          int64    
+	Source           int       
+	SourceName       string
+	TerminalCode     string    
+	TerminalName     string
+	StartTime        string `description:"开始时间"`
+	IntervalTime     int    `description:"间隔时间"`
+	NotifyUsers         string `description:"通知用户"`
+	NotifyUsersName   string `description:"通知用户名称"`
+	Status              int8   `description:"状态"` 
+	DateType   int8      
+	InspectionTime   string `description:"巡检时间"`
+	CreateTime       string `description:"创建时间"`
+	ModifyTime       string `description:"修改时间"`
+}
+
+type EdbInspectionConfigStatusReq struct {
+	ConfigId int64 `description:"配置ID"`
+	Status   int8  `description:"状态"`
+}
+
+type EdbInspectionConfigDeleteReq struct {
+	ConfigId int64 `description:"配置ID"`
+}

+ 112 - 0
models/data_manage/edb_inspection/edb_inspection_dashboard.go

@@ -0,0 +1,112 @@
+package edb_inspection
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"time"
+
+	"gorm.io/gorm"
+)
+
+// EdbInspectionDashboard
+// @Description: 巡检看板表
+type EdbInspectionDashboard struct {
+	DashboardId         int64     `gorm:"column:dashboard_id;primaryKey;autoIncrement" description:"巡检看板ID"`
+	Source             int       `gorm:"column:source" description:"数据源ID"`
+	TerminalCode       string    `gorm:"column:terminal_code" description:"终端编码"`
+	InspectionRecordId int64     `gorm:"column:inspection_record_id" description:"巡检记录ID"`
+	InspectionTime     time.Time `gorm:"column:inspection_time" description:"巡检时间"`
+	InspectionResult   int8      `gorm:"column:inspection_result" description:"巡检结果(1:成功,2:失败)"`
+	ErrorReason        string    `gorm:"column:error_reason" description:"错误原因"`
+	CreateTime         time.Time `gorm:"column:create_time" description:"创建时间"`
+	ModifyTime         time.Time `gorm:"column:modify_time" description:"修改时间"`
+}
+
+// Add
+// @Description: 添加巡检看板记录
+// @receiver m
+// @return err error
+func (m *EdbInspectionDashboard) Add() (err error) {
+	m.CreateTime = time.Now()
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Create(m).Error
+	return
+}
+
+// Update
+// @Description: 更新巡检看板记录
+// @receiver m
+// @param cols []string
+// @return err error
+func (m *EdbInspectionDashboard) Update(cols []string) (err error) {
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Select(cols).Updates(m).Error
+	return
+}
+
+// GetById
+// @Description: 根据ID获取巡检看板记录
+// @param dashboardId int64
+// @return item *EdbInspectionDashboard
+// @return err error
+func GetDashboardById(dashboardId int64) (item *EdbInspectionDashboard, err error) {
+	sql := `SELECT * FROM edb_inspection_dashboard WHERE dashboard_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, dashboardId).First(&item).Error
+	return
+}
+
+// GetListByTerminalCode
+// @Description: 根据终端编码获取巡检看板记录列表
+// @param terminalCode string
+// @return list []*EdbInspectionDashboard
+// @return err error
+func GetDashboardListByTerminalCode(terminalCode string) (list []*EdbInspectionDashboard, err error) {
+	sql := `SELECT * FROM edb_inspection_dashboard WHERE terminal_code = ? ORDER BY inspection_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, terminalCode).Find(&list).Error
+	return
+}
+
+// GetListByInspectionRecordId
+// @Description: 根据巡检记录ID获取巡检看板记录列表
+// @param inspectionRecordId int64
+// @return list []*EdbInspectionDashboard
+// @return err error
+func GetDashboardListByInspectionRecordId(inspectionRecordId int64) (list []*EdbInspectionDashboard, err error) {
+	sql := `SELECT * FROM edb_inspection_dashboard WHERE inspection_record_id = ? ORDER BY inspection_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, inspectionRecordId).Find(&list).Error
+	return
+} 
+
+// GetDashboardBySourceAndTerminalCode
+// @Description: 根据源和终端编码获取巡检看板记录
+// @param source int
+// @param terminalCode string
+// @return item *EdbInspectionDashboard
+// @return err error
+func GetDashboardBySourceAndTerminalCode(source int, terminalCode string) (item *EdbInspectionDashboard, err error) {
+	sql := `SELECT * FROM edb_inspection_dashboard WHERE source = ? AND terminal_code = ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, source, terminalCode).First(&item).Error
+	return
+}
+
+type DashboardList struct {
+	DashboardId         int64     `gorm:"column:dashboard_id;primaryKey;autoIncrement"`
+	Source             int       `gorm:"column:source"`
+	TerminalCode       string    `gorm:"column:terminal_code"`
+	TerminalName       string    `gorm:"column:terminal_name"`
+	InspectionRecordId int64     `gorm:"column:inspection_record_id"`
+	InspectionTime     string    `gorm:"column:inspection_time"`
+	InspectionResult   int8      `gorm:"column:inspection_result"`
+	ErrorReason        string    `gorm:"column:error_reason"`
+}
+
+// 查询列表,安装状态排序,失败的排在前面,状态相同,按照source排序,查询终端名称
+func GetDashboardList() (list []*DashboardList, err error) {
+	sql := `SELECT edb_inspection_dashboard.*, edb_terminal.name as terminal_name FROM edb_inspection_dashboard left join edb_terminal on edb_inspection_dashboard.terminal_code = edb_terminal.terminal_code ORDER BY inspection_result DESC, source ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql).Find(&list).Error
+	return
+}
+func (m *DashboardList) AfterFind(scope *gorm.DB) (err error) {
+	m.InspectionTime = utils.GormDateStrToDateTimeStr(m.InspectionTime)
+	return
+}

+ 114 - 0
models/data_manage/edb_inspection/edb_inspection_date_config.go

@@ -0,0 +1,114 @@
+package edb_inspection
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"time"
+)
+
+// EdbInspectionDateConfig
+// @Description: 数据源巡检配置表
+type EdbInspectionDateConfig struct {
+	DateConfigId        int64     `orm:"column(date_config_id);pk" gorm:"primaryKey" `
+	InspectionFrequency string    `description:"巡检频率,枚举值:每自然日、每交易日、每周"`
+	InspectionFrequencyDay int    `description:"具体刷新的日期"`
+	InspectionDate      string    `description:"巡检日期(每周几/每月几号)"`
+	InspectionTime      string    `description:"巡检时间,具体到时分"`
+	ConfigId            int64     `description:"关联的巡检配置ID"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+}
+
+// Add
+// @Description: 添加
+// @author: Roc
+// @receiver m
+// @datetime 2024-01-10 16:11:10
+// @return err error
+func AddEdbInspectionDateConfigList(list []*EdbInspectionDateConfig, configId int64) (err error) {
+	err = global.DbMap[utils.DbNameIndex].CreateInBatches(list, utils.MultiAddNum).Error
+	return
+}
+
+// Update
+// @Description: 更新
+// @author: Roc
+// @receiver m
+// @datetime 2024-01-10 16:11:10
+// @param cols []string
+// @return err error
+func (m *EdbInspectionDateConfig) Update(cols []string) (err error) {
+	err = global.DbMap[utils.DbNameIndex].Select(cols).Updates(m).Error
+	return
+}
+
+// Delete
+// @Description: 删除
+// @author: Roc
+// @receiver m
+// @datetime 2024-01-10 16:11:10
+// @return err error
+func (m *EdbInspectionDateConfig) Delete() (err error) {
+	sql := ` DELETE FROM edb_inspection_date_config WHERE date_config_id=?`
+	err = global.DbMap[utils.DbNameIndex].Exec(sql, m.DateConfigId).Error
+	return
+}
+
+// 删除配置关联的所有巡检日期配置
+func DeleteEdbInspectionDateConfigByConfigId(configId int64) (err error) {
+	sql := `DELETE FROM edb_inspection_date_config WHERE config_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Exec(sql, configId).Error
+	return
+}
+
+// GetEdbInspectionDateConfigListByCondition
+// @Description: 根据条件获取巡检配置列表
+// @author: Roc
+// @datetime 2024-01-10 16:11:10
+// @param inspectionFrequency string
+// @param inspectionFrequencyDay int
+// @param inspectionDate string
+// @param inspectionTime string
+// @param configId int64
+// @return item *EdbInspectionDateConfig
+// @return err error
+func GetEdbInspectionDateConfigListByCondition(inspectionFrequency string, inspectionFrequencyDay int, inspectionDate, inspectionTime string, configId int64) (item *EdbInspectionDateConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_date_config
+	     WHERE inspection_frequency = ? AND inspection_frequency_day = ? AND inspection_date = ? AND inspection_time = ? AND config_id = ? ORDER BY date_config_id ASC `
+
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, inspectionFrequency, inspectionFrequencyDay, inspectionDate, inspectionTime, configId).First(&item).Error
+	return
+}
+
+// GetEdbInspectionDateConfigListByConfigId
+// @Description: 根据配置ID获取巡检日期配置列表
+// @author: Roc
+// @datetime 2024-01-10 16:11:10
+// @param configId int64
+// @return list []*EdbInspectionDateConfig
+// @return err error
+func GetEdbInspectionDateConfigListByConfigId(configId int64) (list []*EdbInspectionDateConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_date_config WHERE config_id = ? ORDER BY date_config_id ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, configId).Find(&list).Error
+	return
+}
+
+func GetEdbInspectionDateConfigListByConfigIdList(configIdList []int64) (list []*EdbInspectionDateConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_date_config WHERE config_id IN (?) ORDER BY date_config_id ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, configIdList).Find(&list).Error
+	return
+}
+
+// GetEdbInspectionDateConfigListBySourceAndTerminalCode
+// @Description: 根据来源和终端编码获取巡检日期配置列表
+// @author: Roc
+// @datetime 2024-01-10 16:11:10
+// @param source int
+// @param terminalCode string
+// @return list []*EdbInspectionDateConfig
+// @return err error
+func GetEdbInspectionDateConfigListBySourceAndTerminalCode(source int, terminalCode string) (list []*EdbInspectionDateConfig, err error) {
+	sql := `SELECT * FROM edb_inspection_date_config WHERE source = ? AND terminal_code = ? ORDER BY date_config_id ASC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, source, terminalCode).Find(&list).Error
+	return
+}	

+ 170 - 0
models/data_manage/edb_inspection/edb_inspection_message.go

@@ -0,0 +1,170 @@
+package edb_inspection
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// EdbInspectionMessage
+// @Description: 巡检消息表
+type EdbInspectionMessage struct {
+	MessageId          int64     `gorm:"column:message_id;primaryKey;autoIncrement"`
+	InspectionRecordId int64     `gorm:"column:inspection_record_id"`
+	AdminId            int64     `gorm:"column:admin_id"`
+	Message            string    `gorm:"column:message"`
+	IsRead             int8      `gorm:"column:is_read"`
+	Source             int8      `gorm:"column:source"`
+	TerminalCode       string    `gorm:"column:terminal_code"`
+	InspectionTime     time.Time `gorm:"column:inspection_time"`
+	CreateTime         time.Time `gorm:"column:create_time"`
+	ModifyTime         time.Time `gorm:"column:modify_time"`
+}
+
+// Add
+// @Description: 添加巡检消息
+// @receiver m
+// @return err error
+func (m *EdbInspectionMessage) Add() (err error) {
+	m.CreateTime = time.Now()
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Create(m).Error
+	return
+}
+
+// Update
+// @Description: 更新巡检消息
+// @receiver m
+// @param cols []string
+// @return err error
+func (m *EdbInspectionMessage) Update(cols []string) (err error) {
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Select(cols).Updates(m).Error
+	return
+}
+
+// GetById
+// @Description: 根据ID获取巡检消息
+// @param messageId int64
+// @return item *EdbInspectionMessage
+// @return err error
+func GetMessageById(messageId int64) (item *EdbInspectionMessage, err error) {
+	sql := `SELECT * FROM edb_inspection_message WHERE message_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, messageId).First(&item).Error
+	return
+}
+
+// GetListByInspectionRecordId
+// @Description: 根据巡检记录ID获取巡检消息列表
+// @param inspectionRecordId int64
+// @return list []*EdbInspectionMessage
+// @return err error
+func GetMessageListByInspectionRecordId(inspectionRecordId int64) (list []*EdbInspectionMessage, err error) {
+	sql := `SELECT * FROM edb_inspection_message WHERE inspection_record_id = ? ORDER BY create_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, inspectionRecordId).Find(&list).Error
+	return
+}
+
+// GetListBySendStatus
+// @Description: 根据发送状态获取巡检消息列表
+// @param sendStatus int8
+// @return list []*EdbInspectionMessage
+// @return err error
+func GetMessageListBySendStatus(sendStatus int8) (list []*EdbInspectionMessage, err error) {
+	sql := `SELECT * FROM edb_inspection_message WHERE send_status = ? ORDER BY create_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, sendStatus).Find(&list).Error
+	return
+}
+
+// UpdateSendStatus
+// @Description: 更新消息发送状态
+// @receiver m
+// @param sendStatus int8
+// @return err error
+func (m *EdbInspectionMessage) UpdateSendStatus(sendStatus int8) (err error) {
+	sql := `UPDATE edb_inspection_message SET send_status = ?, modify_time = ? WHERE message_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Exec(sql, sendStatus, time.Now(), m.MessageId).Error
+	return
+}
+
+// GetCountByCondition
+// @Description: 根据条件获取巡检消息数量
+// @param cond string
+// @param pars []interface{}
+// @return int64
+// @return err error
+func (m *EdbInspectionMessage) GetCountByCondition(cond string, pars []interface{}) (count int64, err error) {
+	sql := `SELECT COUNT(*) FROM edb_inspection_message WHERE 1=1` + cond
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+type EdbInspectionMessageResp struct {
+	MessageId          int64
+	AdminId            int64
+	InspectionRecordId int64
+	Content            string    
+	Remark             string    
+	IsRead             int8      
+	Source             int8
+	TerminalCode       string
+	InspectionTime     string
+}
+
+type EdbInspectionMessageListResp struct {
+	List   []*EdbInspectionMessageResp 
+	Paging *paging.PagingItem    
+	UnreadTotal int
+}
+
+type EdbInspectionMessageReadReq struct {
+	MessageId int64 
+}
+
+
+func BatchModifyEdbInspectionMessageIsRead(ids []int64, adminId int) (err error) {
+	if len(ids) == 0 {
+		return
+	}
+	o := global.DbMap[utils.DbNameIndex]
+	sql := `UPDATE edb_inspection_message SET is_read =1, modify_time = ? WHERE admin_id =? AND is_read = 0 AND message_id IN (` + utils.GetOrmInReplace(len(ids)) + `)`
+	err = o.Exec(sql, time.Now(), adminId, ids).Error
+	return
+}
+
+func GetEdbInspectionMessageById(id int) (item *EdbInspectionMessage, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := "SELECT * FROM edb_inspection_message WHERE message_id =?"
+	err = o.Raw(sql, id).First(&item).Error
+	return
+}
+
+func GetEdbInspectionMessageByAdminId(adminId int) (items []*EdbInspectionMessage, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := "SELECT * FROM edb_inspection_message WHERE admin_id =? AND is_read = 0 ORDER BY create_time DESC"
+	err = o.Raw(sql, adminId).Find(&items).Error
+	return
+}
+
+func GetEdbInspectionMessageUnreadCountByAdminId(adminId int) (count int, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := "SELECT COUNT(*) FROM edb_inspection_message WHERE admin_id =? AND is_read = 0 ORDER BY is_read ASC, create_time DESC"
+	err = o.Raw(sql, adminId).Scan(&count).Error
+	return
+}
+
+func GetEdbInspectionMessageCountByAdminId(adminId int) (count int, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := "SELECT COUNT(*) FROM edb_inspection_message WHERE admin_id =? ORDER BY is_read ASC, create_time DESC"
+	err = o.Raw(sql, adminId).Scan(&count).Error
+	return
+}
+
+func GetEdbInspectionMessagePageByAdminId(adminId, startSize, pageSize int) (items []*EdbInspectionMessage, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := "SELECT * FROM edb_inspection_message WHERE admin_id =? ORDER BY is_read ASC, create_time DESC LIMIT ?,?"
+	err = o.Raw(sql, adminId, startSize, pageSize).Find(&items).Error
+	return
+} 

+ 112 - 0
models/data_manage/edb_inspection/edb_inspection_record.go

@@ -0,0 +1,112 @@
+package edb_inspection
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/utils"
+	"time"
+
+	"gorm.io/gorm"
+)
+
+// EdbInspectionRecord
+// @Description: 巡检记录表
+type EdbInspectionRecord struct {
+	InspectionRecordId int64     `gorm:"column:inspection_record_id;primaryKey;autoIncrement"`
+	EdbInfoId         int       `gorm:"column:edb_info_id"`
+	Source            int       `gorm:"column:source"`
+	TerminalCode      string    `gorm:"column:terminal_code"`
+	InspectionTime    time.Time `gorm:"column:inspection_time"`
+	InspectionResult  int8      `gorm:"column:inspection_result"`
+	ErrorReason       string    `gorm:"column:error_reason"`
+	CreateTime        time.Time `gorm:"column:create_time"`
+	ModifyTime        time.Time `gorm:"column:modify_time"`
+}
+
+// Add
+// @Description: 添加巡检记录
+// @receiver m
+// @return err error
+func (m *EdbInspectionRecord) Add() (err error) {
+	m.CreateTime = time.Now()
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Create(m).Error
+	return
+}
+
+// Update
+// @Description: 更新巡检记录
+// @receiver m
+// @param cols []string
+// @return err error
+func (m *EdbInspectionRecord) Update(cols []string) (err error) {
+	m.ModifyTime = time.Now()
+	err = global.DbMap[utils.DbNameIndex].Select(cols).Updates(m).Error
+	return
+}
+
+// GetById
+// @Description: 根据ID获取巡检记录
+// @param inspectionRecordId int64
+// @return item *EdbInspectionRecord
+// @return err error
+func GetInspectionRecordById(inspectionRecordId int64) (item *EdbInspectionRecord, err error) {
+	sql := `SELECT * FROM edb_inspection_record WHERE inspection_record_id = ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, inspectionRecordId).First(&item).Error
+	return
+}
+
+// GetListByTerminalCode
+// @Description: 根据终端编码获取巡检记录列表
+// @param terminalCode string
+// @return list []*EdbInspectionRecord
+// @return err error
+func GetInspectionRecordListByTerminalCode(terminalCode string) (list []*EdbInspectionRecord, err error) {
+	sql := `SELECT * FROM edb_inspection_record WHERE terminal_code = ? ORDER BY inspection_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, terminalCode).Find(&list).Error
+	return
+}
+
+// GetListBySource
+// @Description: 根据来源获取巡检记录列表
+// @param source int
+// @return list []*EdbInspectionRecord
+// @return err error
+func GetInspectionRecordListBySource(source int) (list []*EdbInspectionRecord, err error) {
+	sql := `SELECT * FROM edb_inspection_record WHERE source = ? ORDER BY inspection_time DESC`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, source).Find(&list).Error
+	return
+} 
+
+type InspectionRecordList struct {
+	EdbInspectionRecord
+	TerminalName string `gorm:"column:terminal_name"`
+	InspectionTime string `gorm:"column:inspection_time"`
+	SourceName string `gorm:"column:source_name"`
+}
+
+// 创建afterfind
+func (m *InspectionRecordList) AfterFind(scope *gorm.DB) (err error) {
+	m.InspectionTime = utils.GormDateStrToDateTimeStr(m.InspectionTime)
+	return
+}
+
+func GetInspectionRecordListByCondition(condition string, pars []interface{}, startSize int, pageSize int) (list []*InspectionRecordList, err error) {
+	sql := `SELECT r.*, t.name as terminal_name, s.source_name FROM edb_inspection_record r left join edb_terminal t on r.terminal_code = t.terminal_code 
+	left join edb_source s on r.source = s.edb_source_id
+	WHERE 1=1 ` + condition + ` ORDER BY inspection_time DESC LIMIT ?,?`
+	pars = append(pars, startSize, pageSize)
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&list).Error
+	return
+}
+
+// 获取分页总数
+func GetInspectionRecordCountByCondition(condition string, pars []interface{}) (count int64, err error) {
+	sql := `SELECT COUNT(*) FROM edb_inspection_record r left join edb_terminal t on r.terminal_code = t.terminal_code 
+		left join edb_source s on r.source = s.edb_source_id
+	WHERE 1=1 ` + condition
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Count(&count).Error
+	return
+}
+
+
+

+ 117 - 6
models/data_manage/edb_terminal.go

@@ -21,11 +21,15 @@ type EdbTerminal struct {
 	Value        string    `description:"终端相关的token"`
 	ModifyTime   time.Time `description:"修改时间"`
 	CreateTime   time.Time `description:"创建时间"`
+	AccountQuota string       `description:"账号额度"`
+	IsApi        int8      `description:"获取类型(1,接口类型,0终端类型)"`
+	
 }
 
 type EdbTerminalItem struct {
 	TerminalId   int    `orm:"column(terminal_id);pk" gorm:"primaryKey"`
 	Source       int    `description:"指标来源类型"`
+	SourceName   string `description:"数据源类型名称"`
 	Name         string `description:"终端别名"`
 	TerminalCode string `description:"终端编码,用于配置在机器上"`
 	ServerUrl    string `description:"终端地址"`
@@ -35,6 +39,9 @@ type EdbTerminalItem struct {
 	Value        string `description:"终端相关的token"`
 	ModifyTime   string `description:"修改时间"`
 	CreateTime   string `description:"创建时间"`
+	AccountQuota string    `description:"账号额度"`
+	IsApi        int8   `description:"获取类型(1,接口类型,0终端类型)"`
+	UsedQuota    string    `description:"已使用额度"`
 }
 
 func (e *EdbTerminalItem) AfterFind(db *gorm.DB) (err error) {
@@ -80,6 +87,8 @@ type AddEdbTerminalListReq struct {
 	Num       int    `description:"终端最大指标数"`
 	//Status    int    `description:"状态,1启用,2禁用"`
 	Value string `description:"终端相关的token"`
+	AccountQuota string `description:"账号额度"`
+	IsApi        int8 `description:"获取类型(1,接口类型,0终端类型)"`
 }
 
 type SetEdbTerminalStatusReq struct {
@@ -110,17 +119,24 @@ func GetEdbTerminalByTerminalCode(terminalCode string) (item *EdbTerminal, err e
 	return
 }
 
-func GetEdbTerminalList() (item []*EdbTerminalItem, err error) {
+func GetEdbTerminalList(source int) (item []*EdbTerminalItem, err error) {
 	o := global.DbMap[utils.DbNameIndex]
-	sql := ` SELECT * FROM edb_terminal ORDER BY terminal_id ASC`
-	err = o.Raw(sql).Find(&item).Error
+	var sql string
+	if source == 0 {
+		sql = ` SELECT t.*, s.source_name FROM edb_terminal t left join edb_source s on t.source = s.edb_source_id ORDER BY terminal_id ASC`
+		err = o.Raw(sql).Find(&item).Error
+	} else {
+		sql = ` SELECT t.*, s.source_name FROM edb_terminal t left join edb_source s on t.source = s.edb_source_id WHERE t.source = ? ORDER BY terminal_id ASC`
+		err = o.Raw(sql, source).Find(&item).Error
+	}
 	return
+	
 }
 
-func GetEdbTerminalBySource(source int) (item []*EdbTerminalItem, err error) {
+func GetEdbTerminalBySourceAndIsApi(source int, isApi int) (item []*EdbTerminalItem, err error) {
 	o := global.DbMap[utils.DbNameIndex]
-	sql := ` SELECT * FROM edb_terminal where source=? ORDER BY terminal_id ASC`
-	err = o.Raw(sql, source).Find(&item).Error
+	sql := ` SELECT * FROM edb_terminal where source=? and is_api=? ORDER BY terminal_id ASC`
+	err = o.Raw(sql, source, isApi).Find(&item).Error
 	return
 }
 
@@ -164,3 +180,98 @@ type EdbTerminalDirInfo struct {
 	DirPath      string `description:"终端存放的文件夹路径"`
 	FilePath     string `description:"文件夹路径"`
 }
+
+type EdbInfoTerminalList struct {
+	//EdbInfoId    int    `gorm:"column:edb_info_id"`
+	EdbCode  string `gorm:"column:edb_code"`
+	EdbName  string `gorm:"column:edb_name"`
+	TerminalCode string `gorm:"column:terminal_code"`
+	TerminalName string `gorm:"column:terminal_name"`
+}
+
+func GetSimpleEdbListPageByCondition(condition string, pars []interface{}, pageIndex int, pageSize int) (list []*EdbInfoTerminalList, err error) {
+	sql := `SELECT e.*, t.name as terminal_name FROM edb_info e left join edb_terminal t on e.terminal_code = t.terminal_code WHERE 1=1 ` + condition + ` ORDER BY e.edb_info_id ASC LIMIT ?, ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, append(pars, pageIndex, pageSize)...).Find(&list).Error
+	return
+}
+
+func GetSimpleEdbListCountByCondition(condition string, pars []interface{}) (count int64, err error) {
+	sql := `SELECT COUNT(*) FROM edb_info e left join edb_terminal t on e.terminal_code = t.terminal_code WHERE 1=1 ` + condition
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Count(&count).Error
+	return
+}
+
+func GetSimpleBaseIndexListPageByCondition(indexTableName string, condition string, pars []interface{}, pageIndex int, pageSize int) (list []*EdbInfoTerminalList, err error) {
+	sql := `SELECT e.index_code as edb_code, e.index_name as edb_name, e.terminal_code, t.name as terminal_name FROM ` + indexTableName + ` e left join edb_terminal t on e.terminal_code = t.terminal_code WHERE 1=1 ` + condition + ` LIMIT ?, ?`
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, append(pars, pageIndex, pageSize)...).Find(&list).Error
+	return
+}
+
+func GetSimpleBaseIndexListCountByCondition(indexTableName string, condition string, pars []interface{}) (count int64, err error) {
+	sql := `SELECT COUNT(*) FROM ` + indexTableName + ` e left join edb_terminal t on e.terminal_code = t.terminal_code WHERE 1=1 ` + condition
+	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Count(&count).Error
+	return
+}
+
+type SetEdbInfoTerminalReq struct {
+	EdbCodes []string `description:"指标编码"`
+	TerminalCode string `description:"要更换的终端编码"`
+	Source int `description:"指标来源类型"`
+}
+
+type IndexNumBySource struct {
+	SubSource int
+	Num int
+}
+
+func GetIndexNumBySource(source int, terminalCode string) (num int, list []*IndexNumBySource, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	tableName := EdbSourceIdMap[source].IndexTableName
+	var pars []interface{}
+	if tableName != "" {
+		sql := fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE terminal_code = ?`, tableName)
+		pars = append(pars, terminalCode)
+		err = o.Raw(sql, pars...).Scan(&num).Error
+		return
+	} else {
+		sql := `SELECT COUNT(*) as num, sub_source FROM edb_info WHERE terminal_code = ? and source = ? group by sub_source`
+		pars = append(pars, terminalCode, source)
+		err = o.Raw(sql, pars...).Find(&list).Error
+		return
+	}
+	
+}
+
+// 根据source和is_api获取终端编码
+func GetTerminalCodeBySourceAndIsApi(source int, isApi int) (terminalCode []string, err error) {
+	o := global.DbMap[utils.DbNameIndex]
+	sql := `SELECT terminal_code FROM edb_terminal WHERE source = ? AND is_api = ?`
+	err = o.Raw(sql, source, isApi).Find(&terminalCode).Error
+	return
+}
+
+// 更新终端编码
+func UpdatBaseIndexTerminalCode(indexCodes []string, terminalCode string, source int) (err error) {
+	tableName := EdbSourceIdMap[source].IndexTableName
+	var sql string
+	// 通过事务更新
+	o := global.DbMap[utils.DbNameIndex].Begin()
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+			return
+		}
+		_ = o.Commit()
+	}()
+	if tableName != "" {
+		sql = ` UPDATE ` + tableName + ` SET terminal_code = ? WHERE index_code in (?) `
+		err = o.Exec(sql, terminalCode, indexCodes).Error
+		if err != nil {
+			return
+		}
+	}
+	// 更新edb_info的终端编码
+	sql = ` UPDATE edb_info SET terminal_code = ? WHERE source = ? AND edb_code in (?) `
+	err = o.Exec(sql, terminalCode, source, indexCodes).Error
+	return
+}

+ 2 - 0
models/data_manage/mysteel_chemical_index.go

@@ -793,3 +793,5 @@ func GetNoEdbMysteelChemicalIndexPageList(condition string, pars []interface{},
 	err = o.Raw(sql, pars...).Find(&items).Error
 	return
 }
+
+

+ 1 - 0
models/data_stat/edb_info_update_stat.go

@@ -50,6 +50,7 @@ func (e *EdbInfoUpdateStat) AfterFind(db *gorm.DB) (err error) {
 	e.LatestDate = utils.GormDateStrToDateStr(e.LatestDate)
 	e.StartDate = utils.GormDateStrToDateStr(e.StartDate)
 	e.EndDate = utils.GormDateStrToDateStr(e.EndDate)
+	e.UpdateTime = utils.GormDateStrToDateTimeStr(e.UpdateTime)
 	return
 }
 

+ 7 - 0
models/message.go

@@ -0,0 +1,7 @@
+package models
+
+type WebsocketMessageResponse struct {
+	MessageType int `description:"消息类型:0-预警消息;1-巡检消息"`
+	Data  interface{} `description:"消息数据"`
+}
+

+ 117 - 0
routers/commentsRouter.go

@@ -6442,6 +6442,105 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "DeleteInspectionConfig",
+            Router: `/edb_inspection/config/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "GetInspectionConfigDetail",
+            Router: `/edb_inspection/config/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "InspectionConfigList",
+            Router: `/edb_inspection/config/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "SaveInspectionConfig",
+            Router: `/edb_inspection/config/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "UpdateInspectionConfigStatus",
+            Router: `/edb_inspection/config/status/update`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "GetDashboardList",
+            Router: `/edb_inspection/dashboard`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "HelpWordDownload",
+            Router: `/edb_inspection/help_word`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "GetInspectionRecordDetail",
+            Router: `/edb_inspection/record`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionController"],
+        beego.ControllerComments{
+            Method: "InspectionSourceList",
+            Router: `/edb_inspection/source_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionMessageController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionMessageController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/edb_inspection/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionMessageController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInspectionMessageController"],
+        beego.ControllerComments{
+            Method: "Read",
+            Router: `/edb_inspection/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:FactorEdbSeriesController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:FactorEdbSeriesController"],
         beego.ControllerComments{
             Method: "Add",
@@ -7549,6 +7648,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"],
+        beego.ControllerComments{
+            Method: "GetEdbInfoList",
+            Router: `/terminal/edb_info/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"],
+        beego.ControllerComments{
+            Method: "SetEdbInfoTerminal",
+            Router: `/terminal/edb_info/set`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_stat:EdbTerminalController"],
         beego.ControllerComments{
             Method: "TerminalIndexDirInfo",

+ 2 - 0
routers/router.go

@@ -208,6 +208,8 @@ func init() {
 				&data_manage.BaseFromGprRiskController{},
 				&data_manage.BaseFromPurangController{},
 				&data_manage.BaseFromRadishResearchController{},
+				&data_manage.EdbInspectionController{},
+				&data_manage.EdbInspectionMessageController{},
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 397 - 0
services/data/edb_inspection.go

@@ -0,0 +1,397 @@
+package data
+
+import (
+	"encoding/json"
+	"errors"
+	"eta/eta_api/models/data_manage/edb_inspection"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 所有巡检配置key
+var allDefaultEdbInspectionConfigKey = `edb_inspection_config:default:all:`
+
+// GetAllDefaultEdbInspectionConfigListBySource
+// @Description: 获取默认的所有巡检配置列表
+// @author: Roc
+// @datetime 2024-01-10 15:03:36
+// @param source int
+// @return list []*edb_inspection.EdbInspectionConfig
+// @return err error
+func GetAllDefaultEdbInspectionConfigListBySource(source int) (list []*edb_inspection.EdbInspectionConfig, err error) {
+	key := getAllDefaultEdbInspectionConfigKey(source)
+	if utils.Re == nil {
+		if utils.Re == nil && utils.Rc.IsExist(key) {
+			if data, err1 := utils.Rc.RedisBytes(key); err1 == nil {
+				err = json.Unmarshal(data, &list)
+				return
+			}
+		}
+	}
+
+	list, err = edb_inspection.GetListBySource(source)
+	if err != nil {
+		return
+	}
+
+	// 将数据加入缓存
+	if utils.Re == nil {
+		data, _ := json.Marshal(list)
+		utils.Rc.Put(key, data, 2*time.Hour)
+	}
+
+	return
+}
+
+// SaveEdbInspectionConfig
+// @Description: 设置巡检配置接口
+// @author: Roc
+// @datetime 2024-01-10 15:11:19
+// @param req *edb_inspection.EdbInspectionConfigAddReq
+// @return err error
+// @return errMsg string
+// @return isSendEmail bool
+func SaveEdbInspectionConfig(req *edb_inspection.EdbInspectionConfigAddReq) (err error, errMsg string, isSendEmail bool) {
+	isSendEmail = true
+	errMsg = `保存失败`
+
+	if req.Source <= 0 {
+		errMsg = "来源不能为空"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	if req.TerminalCode == "" {
+		errMsg = "终端编码不能为空"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	// 判断终端是否存在
+	terminal, e := data_manage.GetEdbTerminalByCode(req.TerminalCode)
+	if e != nil {
+		errMsg = "终端不存在"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	if terminal.TerminalCode != "" && terminal.Source != req.Source {
+		errMsg = "数据源不匹配"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	//判断该终端配置是否已存在
+	if req.ConfigId <= 0 {
+		inspectionConfig, e := edb_inspection.GetListByTerminalCode(req.TerminalCode)
+		if e != nil && !utils.IsErrNoRow(e) {
+			errMsg = "查询终端配置失败"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+		if e == nil && len(inspectionConfig) > 0 {
+			errMsg = "终端配置已存在"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+	}
+
+	lenConf := len(req.List)
+	if req.DateType == 1 && lenConf == 0 {
+		errMsg = "至少需要一个巡检配置"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	// if req.DateType == 1 && lenConf > 5 {
+	// 	errMsg = "巡检时间设置最多不超过5个"
+	// 	err = errors.New(errMsg)
+	// 	isSendEmail = false
+	// 	return
+	// }
+
+	tmpArr := []string{"每自然日", "每交易日", "每周"}
+	// 配置的map,避免同一种类型配置同一个时间
+	configMap := make(map[string]string)
+	for _, v := range req.List {
+		if !utils.InArrayByStr(tmpArr, v.InspectionFrequency) {
+			errMsg = "巡检频率不合法"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+
+		if v.InspectionTime == "" {
+			errMsg = "请选择具体时间"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+
+		// 配置的map,避免同一种类型配置同一个时间
+		key := fmt.Sprint(v.InspectionFrequency, "_", v.InspectionDate, "_", v.InspectionTime)
+		if _, ok := configMap[key]; ok {
+			errMsg = "巡检频率和日期不能重复"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+		configMap[key] = key
+	}
+
+
+
+	configId := req.ConfigId
+	if configId > 0 {
+		// 查询配置
+		inspectionConfig, e := edb_inspection.GetById(configId)
+		if e != nil {
+			errMsg = "配置不存在"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+		inspectionConfig.ConfigId = req.ConfigId
+		updateCols := []string{"source", "terminal_code", "date_type", "start_time", "interval_time", "notify_users", "modify_time"}
+		inspectionConfig.Source = req.Source
+		inspectionConfig.TerminalCode = req.TerminalCode
+		inspectionConfig.DateType = req.DateType
+		inspectionConfig.StartTime = req.StartTime
+		inspectionConfig.IntervalTime = req.IntervalTime
+		inspectionConfig.NotifyUsers = req.NotifyUsers
+		inspectionConfig.ModifyTime = time.Now()
+		err = inspectionConfig.Update(updateCols)
+	} else {
+		// 创建巡检配置
+		inspectionConfig := &edb_inspection.EdbInspectionConfig{
+			Source:       req.Source,
+			TerminalCode: req.TerminalCode,
+			DateType:     req.DateType,
+			StartTime:    req.StartTime,
+			Status:       1,
+			IntervalTime: req.IntervalTime,
+			NotifyUsers:  req.NotifyUsers,
+			CreateTime:   time.Now(),
+			ModifyTime:   time.Now(),
+		}
+		err = inspectionConfig.Add()
+		if err != nil {
+			return
+		}
+		configId = inspectionConfig.ConfigId
+	}
+	if err != nil {
+		return
+	}
+
+	// 删除原先的配置
+	err = edb_inspection.DeleteEdbInspectionDateConfigByConfigId(configId)
+	if err != nil {
+		return
+	}
+
+	// 创建巡检日期配置
+	dateConfigList := make([]*edb_inspection.EdbInspectionDateConfig, 0)
+	if req.DateType == 1 {
+		for _, v := range req.List {
+			dateConfig := &edb_inspection.EdbInspectionDateConfig{
+				InspectionFrequency:    v.InspectionFrequency,
+				InspectionFrequencyDay: v.InspectionFrequencyDay,
+				InspectionDate:         v.InspectionDate,
+				InspectionTime:         v.InspectionTime,
+				ConfigId:              configId,
+				CreateTime:            time.Now(),
+				ModifyTime:            time.Now(),
+			}
+			dateConfigList = append(dateConfigList, dateConfig)
+		}
+
+		if len(dateConfigList) > 0 {
+			err = edb_inspection.AddEdbInspectionDateConfigList(dateConfigList, configId)
+			if err != nil {
+				return
+			}
+		}
+	}
+
+	// 清除缓存
+	{
+		key := getAllDefaultEdbInspectionConfigKey(req.Source)
+		if utils.Re == nil {
+			_ = utils.Rc.Delete(key)
+		}
+	}
+
+	return
+}
+
+// HandleInspectionTime
+// @Description: 处理巡检时间的显示
+// @author: Roc
+// @datetime 2024-01-10 17:00:03
+// @param source int
+// @param terminalCode string
+// @return list []*edb_inspection.EdbInspectionConfig
+// @return err error
+// @return errMsg string
+// @return isSendEmail bool
+func GetConfigList(source int, terminalCode string) (list []*edb_inspection.EdbInspectionConfigItem, err error, errMsg string, isSendEmail bool) {
+	isSendEmail = true
+	errMsg = "获取失败"
+
+	list, err = edb_inspection.GetConfigListBySourceAndTerminalCode(source, terminalCode)
+	if err != nil {
+		return
+	}
+	if len(list) <= 0 {
+		return
+	}
+	configIdList := make([]int64, 0)
+	adminIds := make([]int, 0)
+	for _, config := range list {
+		configIdList = append(configIdList, config.ConfigId)
+		adminIdSlice := strings.Split(config.NotifyUsers, ",")
+		for _, adminId := range adminIdSlice {
+			if adminId != "" {
+				id, _ := strconv.Atoi(adminId)
+				adminIds = append(adminIds, id)
+			}
+		}
+	}
+	adminNameMap := make(map[int]string)
+	if len(adminIds) > 0 {
+		adminList, e := system.GetAdminItemByIdList(adminIds)
+		if e != nil {
+			errMsg = "获取通知用户失败"
+			err = errors.New(errMsg+e.Error())
+			isSendEmail = false
+			return
+		}
+		for _, admin := range adminList {
+			adminNameMap[admin.AdminId] = admin.RealName
+		}
+	}
+
+	// 获取每个配置的日期配置
+	dateConfigs, tmpErr := edb_inspection.GetEdbInspectionDateConfigListByConfigIdList(configIdList)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+
+	// 处理巡检时间显示
+	inspectionTimeList := make(map[int64][]string, 0)
+	for _, dateConfig := range dateConfigs {
+		inspectionTimeList[dateConfig.ConfigId] = append(inspectionTimeList[dateConfig.ConfigId], GetInspectionStr(dateConfig.InspectionFrequency, dateConfig.InspectionFrequencyDay, dateConfig.InspectionTime))
+	}
+	for _, config := range list {
+		if config.NotifyUsers != "" {
+			adminIdSlice := strings.Split(config.NotifyUsers, ",")
+			nameList := make([]string, 0)
+			for _, adminId := range adminIdSlice {
+				if adminId != "" {
+					id, _ := strconv.Atoi(adminId)
+					nameList = append(nameList, adminNameMap[id])
+				}
+			}
+			config.NotifyUsersName = strings.Join(nameList, ",")
+		}
+		if config.DateType == 1 {
+			tmpList, ok := inspectionTimeList[config.ConfigId]
+			if ok {
+				config.InspectionTime = strings.Join(tmpList, ",")
+			}
+		} else {
+			config.InspectionTime = fmt.Sprintf("%s开始每间隔%d小时", config.StartTime, config.IntervalTime)
+		}
+	}
+
+	return
+}
+
+func GetConfigDetail(configId int64) (detail *edb_inspection.EdbInspectionConfigDetailResp, err error) {
+	item, err := edb_inspection.GetById(configId)
+	if err != nil {
+		return
+	}
+	dateConfigs, err := edb_inspection.GetEdbInspectionDateConfigListByConfigId(configId)
+	if err != nil {
+		return
+	}
+	list := make([]edb_inspection.InspectionConfigReq, 0)
+	for _, dateConfig := range dateConfigs {
+		list = append(list, edb_inspection.InspectionConfigReq{
+			InspectionFrequency: dateConfig.InspectionFrequency,
+			InspectionFrequencyDay: dateConfig.InspectionFrequencyDay,
+			InspectionDate: dateConfig.InspectionDate,
+			InspectionTime: dateConfig.InspectionTime,
+		})
+	}
+	detail = &edb_inspection.EdbInspectionConfigDetailResp{
+		EdbInspectionConfig: item,
+		List:   list,
+	}
+
+	return
+}
+
+// getAllDefaultEdbInspectionConfigKey
+// @Description: 获取默认的所有巡检配置key
+// @author: Roc
+// @datetime 2024-01-10 15:02:49
+// @param source int
+// @return string
+func getAllDefaultEdbInspectionConfigKey(source int) string {
+	return allDefaultEdbInspectionConfigKey + fmt.Sprintf("%d", source)
+}
+
+// GetInspectionStr
+// @Description: 获取巡检配置的中文字符串
+// @author: Roc
+// @datetime 2024-01-10 16:05:10
+// @param inspectionFrequency string
+// @param inspectionFrequencyDay int
+// @param inspectionTime string
+// @return string
+func GetInspectionStr(inspectionFrequency string, inspectionFrequencyDay int, inspectionTime string) string {
+	inspectionDayStr := ``
+	switch inspectionFrequency {
+	case "每自然日", "每交易日":
+	case "每周":
+		switch inspectionFrequencyDay {
+		case 0:
+			inspectionDayStr = "日"
+		case 1:
+			inspectionDayStr = "一"
+		case 2:
+			inspectionDayStr = "二"
+		case 3:
+			inspectionDayStr = "三"
+		case 4:
+			inspectionDayStr = "四"
+		case 5:
+			inspectionDayStr = "五"
+		case 6:
+			inspectionDayStr = "六"
+		case 7:
+			inspectionDayStr = "日"
+		}
+	default:
+		if inspectionFrequencyDay > 0 {
+			inspectionDayStr = fmt.Sprintf("第%d天", inspectionFrequencyDay)
+		} else {
+			inspectionDayStr = `最后一天`
+		}
+	}
+	return inspectionFrequency + inspectionDayStr + " " + inspectionTime
+}

+ 114 - 0
services/data/edb_inspection_message.go

@@ -0,0 +1,114 @@
+package data
+
+import (
+	"errors"
+	"eta/eta_api/models/data_manage/edb_inspection"
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+func ReadEdbInspectionMessage(messageId int64, adminId int) (msg string, err error) {
+	message, err := edb_inspection.GetMessageById(int64(messageId))
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			msg = "消息不存在"
+			return
+		}
+		msg = "获取消息失败"
+		return
+	}
+	if message.AdminId != int64(adminId) {
+		msg = "您没有权限查看该消息"
+		err = errors.New("no permission")
+		return
+	}
+	message.IsRead = 1
+	message.ModifyTime = time.Now()
+	err = message.Update([]string{"IsRead", "ModifyTime"})
+	if err != nil {
+		msg = "已读失败"
+		return
+	}
+	return
+}
+
+func ReadEdbInspectionMessageList(messageId []int64, adminId int) (msg string, err error) {
+	err = edb_inspection.BatchModifyEdbInspectionMessageIsRead(messageId, adminId)
+	if err != nil {
+		msg = "已读失败"
+		return
+	}
+	return
+}
+
+func SendInspectionMessages(adminId int, message *edb_inspection.EdbInspectionMessage) (data *edb_inspection.EdbInspectionMessageResp, err error) {
+	resp := edb_inspection.EdbInspectionMessageResp{
+		MessageId: message.MessageId,
+		Content: "巡检状态异常",
+		Remark: message.Message,
+		IsRead: message.IsRead,
+		Source: message.Source,
+		TerminalCode: message.TerminalCode,
+		InspectionTime: message.InspectionTime.Format(utils.FormatDateTime),
+	}
+	return &resp, nil
+}
+
+func GetHistoryInspectionMessages(adminId int) (items []*edb_inspection.EdbInspectionMessage, err error) {
+	messageList, err := edb_inspection.GetEdbInspectionMessageByAdminId(adminId)
+	if err != nil {
+		return
+	}
+
+	items = messageList
+	return
+}
+
+func GetInspectionMessageList(adminid int, currentIndex, pageSize int) (resp edb_inspection.EdbInspectionMessageListResp, err error) {
+	startSize := utils.StartIndex(currentIndex, pageSize)
+
+	total, err := edb_inspection.GetEdbInspectionMessageCountByAdminId(adminid)
+	if err != nil {
+		return
+	}
+	if total == 0 {
+		resp.List = make([]*edb_inspection.EdbInspectionMessageResp, 0)
+		resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
+		return
+	}
+
+	messageList, err := edb_inspection.GetEdbInspectionMessagePageByAdminId(adminid, startSize, pageSize)
+	if err != nil {
+		return
+	}
+
+	unreadTotal, err := edb_inspection.GetEdbInspectionMessageUnreadCountByAdminId(adminid)
+	if err != nil {
+		return
+	}
+	resp.List = toEdbInspectionMessageResp(messageList)
+	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
+	resp.UnreadTotal = unreadTotal
+	return
+}
+
+func toEdbInspectionMessageResp(items []*edb_inspection.EdbInspectionMessage) (list []*edb_inspection.EdbInspectionMessageResp) {
+	list = make([]*edb_inspection.EdbInspectionMessageResp, 0)
+	for _, message := range items {
+		item := edb_inspection.EdbInspectionMessageResp{
+			MessageId: message.MessageId,
+			InspectionRecordId: message.InspectionRecordId,
+			AdminId: message.AdminId,
+			Content: "巡检状态异常",
+			Remark: message.Message,
+			IsRead: message.IsRead,
+			Source: message.Source,
+			TerminalCode: message.TerminalCode,
+			InspectionTime: message.InspectionTime.Format(utils.FormatDateTime),
+		}
+		list = append(list, &item)
+	}
+	return
+} 

+ 35 - 39
services/edb_monitor/edb_monitor_message.go

@@ -2,22 +2,15 @@ package edbmonitor
 
 import (
 	"errors"
+	"eta/eta_api/global"
+	"eta/eta_api/models"
 	edbmonitor "eta/eta_api/models/edb_monitor"
 	"eta/eta_api/models/edb_monitor/response"
 	"eta/eta_api/utils"
-	"strconv"
 	"time"
-
-	"github.com/gorilla/websocket"
 	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
-var (
-	EDB_MONITOR_MESSAGE_CONNECT_CACHE = "edb_monitor_message_cache:"
-)
-
-var MonitorMessageConn = make(map[int]*websocket.Conn)
-
 func ReadEdbMonitorMessage(messageId, adminId int) (msg string, err error) {
 	message, err := edbmonitor.GetEdbMonitorMessageById(messageId)
 	if err != nil {
@@ -51,27 +44,27 @@ func ReadEdbMonitorMessageList(messageId []int, adminId int) (msg string, err er
 	return
 }
 
-func EdbMonitorMessageHealth(adminId int) (isClose bool, err error) {
-	conn := MonitorMessageConn[adminId]
-	if conn == nil {
-		err = errors.New("no connection")
-		isClose = true
-		return
-	}
-	_, msg, err := conn.ReadMessage()
-	if err != nil {
-		isClose = true
-		return
-	}
-	if string(msg) == "ping" {
-		healthKey := EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(adminId)
-		err = utils.Rc.Put(healthKey, "1", time.Minute*1)
-		if err != nil {
-			return
-		}
-	}
-	return
-}
+// func EdbMonitorMessageHealth(adminId int) (isClose bool, err error) {
+// 	conn := MonitorMessageConn[adminId]
+// 	if conn == nil {
+// 		err = errors.New("no connection")
+// 		isClose = true
+// 		return
+// 	}
+// 	_, msg, err := conn.ReadMessage()
+// 	if err != nil {
+// 		isClose = true
+// 		return
+// 	}
+// 	if string(msg) == "ping" {
+// 		healthKey := EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(adminId)
+// 		err = utils.Rc.Put(healthKey, "1", time.Minute*1)
+// 		if err != nil {
+// 			return
+// 		}
+// 	}
+// 	return
+// }
 
 func LogMessage(content, uniqueCode string, triggerTime time.Time, edbInfoId, edbInfoType, adminId, isRead, classifyId int) (err error) {
 	message := &edbmonitor.EdbMonitorMessage{
@@ -91,19 +84,22 @@ func LogMessage(content, uniqueCode string, triggerTime time.Time, edbInfoId, ed
 }
 
 func SendMessages(adminId, edbInfoId, edbInfoType int, classifyId int, edbUniqueCode, message string, triggerTime string) (err error) {
-	conn := MonitorMessageConn[adminId]
+	conn := global.MonitorMessageConn[adminId]
 	if conn == nil {
 		return errors.New("no connection")
 	}
-	msg := response.EdbMonitorMessageResp{
-		EdbInfoId:     edbInfoId,
-		EdbInfoType:   edbInfoType,
-		EdbUniqueCode: edbUniqueCode,
-		EdbClassifyId: classifyId,
-		Message:       message,
-		TriggerTime:   triggerTime,
+	resp := models.WebsocketMessageResponse{
+		MessageType: 0,
+		Data: response.EdbMonitorMessageResp{
+			EdbInfoId:     edbInfoId,
+			EdbInfoType:   edbInfoType,
+			EdbUniqueCode: edbUniqueCode,
+			EdbClassifyId: classifyId,
+			Message:       message,
+			TriggerTime:   triggerTime,
+		},
 	}
-	return conn.WriteJSON(msg)
+	return conn.WriteJSON(resp)
 }
 
 func GetHistoryMessages(adminId int) (items []*response.EdbMonitorMessageResp, err error) {

+ 211 - 0
services/websocket_msg.go

@@ -0,0 +1,211 @@
+package services
+
+import (
+	"eta/eta_api/global"
+	"eta/eta_api/models"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+	"fmt"
+	"runtime"
+	"sync"
+	"time"
+
+	"context"
+)
+
+func DealWebSocketMsg(adminId int) {
+	DealEdbInspectionMessageTest(adminId)
+
+	//go DealEdbInspectionMessage(adminId)
+}
+
+// 处理巡检消息
+func DealEdbInspectionMessage(adminId int) {
+	utils.FileLog.Info("创建协程, adminId:%d", adminId)
+	// 创建上下文用于控制 goroutine 生命周期
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	cacheKey := fmt.Sprintf("%s%d", utils.CACHE_EDB_INSPECTION_MESSAGE, adminId)
+
+	// 添加错误恢复机制
+	defer func() {
+		if r := recover(); r != nil {
+			utils.FileLog.Error("WebSocket handler recovered from panic: %v", r)
+			// 清理资源
+			cancel()
+		}
+	}()
+	go func() {
+		ticker := time.NewTicker(time.Minute)
+		defer ticker.Stop()
+		for {
+			select {
+			case <-ticker.C:
+				utils.FileLog.Info("Current goroutine count: %d", runtime.NumGoroutine())
+			case <-ctx.Done():
+				return
+			}
+		}
+	}()
+	for {
+		select {
+		case <-ctx.Done():
+			utils.FileLog.Info("DealEdbInspectionMessage 巡检消息处理协程结束, adminId:%d", adminId)
+			return
+		default:
+			// 检查连接状态
+			conn := global.MonitorMessageConn[adminId]
+			if conn == nil {
+				utils.FileLog.Error("检查连接状态 发送消息时发现连接已断开, adminId:%d", adminId)
+				cancel()
+				return
+			}
+			// 使用带超时的 Redis 操作
+			val := utils.Rc.Get(cacheKey)
+			if val == "" {
+				//utils.FileLog.Info("巡检信息历史为空, adminId:%d", adminId)
+				continue
+			}
+				utils.FileLog.Info("收到巡检信息开始处理, adminId:%d", adminId)
+				messageList, err := data.GetHistoryInspectionMessages(adminId)
+				if err != nil {
+					utils.FileLog.Error("获取巡检信息历史失败,err:%s, adminId:%d", err.Error(), adminId)
+					return
+				}
+				if len(messageList) == 0 {
+					utils.FileLog.Info("巡检信息历史为空, adminId:%d", adminId)
+					return
+				}
+
+				readList := make([]int64, 0)
+				// 检查连接状态
+				// conn := global.MonitorMessageConn[adminId]
+				// if conn == nil {
+				// 	utils.FileLog.Error("发送消息时发现连接已断开, adminId:%d", adminId)
+				// 	cancel()
+				// 	return
+				// }
+				// 只处理第一条消息的发送,其他消息只标记为已读
+				for i, msg := range messageList {
+					if i == 0 {
+						respData, err := data.SendInspectionMessages(adminId, msg)
+						if err != nil {
+							utils.FileLog.Error("巡检信息发送失败,err:%s, adminId:%d", err.Error(), adminId)
+							continue
+						}
+
+						resp := models.WebsocketMessageResponse{
+							MessageType: 1,
+							Data:       respData,
+						}
+
+						err, isClose := WriteWebSocketMessageAsync(ctx, adminId, resp)
+						if err != nil {
+							utils.FileLog.Error("巡检信息发送失败,err:%s, adminId:%d", err.Error(), adminId)
+							cancel()
+							continue
+						}
+						if isClose {
+							utils.FileLog.Error("巡检信息发送失败,连接已断开, adminId:%d", adminId)
+							cancel()
+							return
+						}
+
+						utils.FileLog.Info("巡检信息发送成功,adminId:%d, messageId:%d", adminId, msg.MessageId)
+					}
+					readList = append(readList, msg.MessageId)
+				}
+
+				if len(readList) > 0 {
+					_, err = data.ReadEdbInspectionMessageList(readList, adminId)
+					if err != nil {
+						utils.FileLog.Error("巡检信息已读失败,err:%s, adminId:%d", err.Error(), adminId)
+					}
+				}
+			//})
+
+			// if err != nil && err.Error() != "redis: nil" {
+			// 	utils.FileLog.Error("Redis operation failed: %v", err)
+			// 	continue
+			// }else {
+			// 	utils.FileLog.Info("巡检信息处理完成, adminId:%d", adminId)
+			// }
+		}
+	}
+}
+
+func WriteWebSocketMessageAsync(ctx context.Context, adminId int, resp interface{}) (error, bool) {
+	errChan := make(chan error, 1)
+	var wsWriteMutex sync.Mutex
+	isClose := false
+	
+	go func() {
+		wsWriteMutex.Lock()
+		defer wsWriteMutex.Unlock()
+		
+		conn := global.MonitorMessageConn[adminId]
+		if conn == nil {
+			isClose = true
+			errChan <- fmt.Errorf("connection closed for adminId: %d", adminId)
+			return
+		}
+		
+		// 设置写超时
+		//conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
+		errChan <- conn.WriteJSON(resp)
+	}()
+	
+	select {
+	case err := <-errChan:
+		utils.FileLog.Error("WriteWebSocketMessageAsync errChan: %v", err)
+		return err, isClose
+	case <-ctx.Done():
+		utils.FileLog.Error("WriteWebSocketMessageAsync ctx.Done(): %v", ctx.Err())
+		return ctx.Err(), isClose
+	}
+}
+
+func DealEdbInspectionMessageTest(adminId int) {
+	messageList, err := data.GetHistoryInspectionMessages(adminId)
+	if err != nil {
+		utils.FileLog.Error("获取巡检信息历史失败,err:%s, adminId:%d", err.Error(), adminId)
+	}
+	if len(messageList) == 0 {
+		return
+	}
+	go func() {
+		readList := make([]int64, 0)
+		for _, msg := range messageList {
+				// 多条消息仅发送最新一条
+				respData, err := data.SendInspectionMessages(adminId, msg)
+				if err != nil {
+					utils.FileLog.Error("巡检信息发送失败,err:%s, adminId:%d", err.Error(), adminId)
+					return
+				} else {
+					resp := models.WebsocketMessageResponse{
+						MessageType: 1,
+						Data: respData,
+					}
+					conn := global.MonitorMessageConn[adminId]
+					if conn == nil {
+						utils.FileLog.Error("巡检信息发送失败,连接已断开, adminId:%d", adminId)
+						return
+					}
+					err = conn.WriteJSON(resp)
+					if err != nil {
+						utils.FileLog.Error("巡检信息发送失败,err:%s, adminId:%d", err.Error(), adminId)
+						return
+					} else {
+						utils.FileLog.Info("巡检信息发送成功,adminId:%d, messageId:%d", adminId, msg.MessageId)
+					}
+				}
+				readList = append(readList, msg.MessageId)
+			}
+			_, err = data.ReadEdbInspectionMessageList(readList, adminId)
+			if err != nil {
+				utils.FileLog.Error("巡检信息已读失败,err:%s, adminId:%d", err.Error(), adminId)
+				return
+			}
+		}()
+}

BIN
static/wind指标刷新失败处理.pdf


BIN
static/同花顺指标API方式刷新失败处理.pdf


BIN
static/钢联指标API对接刷新失败处理.pdf


BIN
static/钢联指标终端对接刷新失败处理.pdf


+ 1 - 0
utils/constants.go

@@ -277,6 +277,7 @@ const (
 	CACHE_CHART_AUTH                        = "eta:chart:auth:"                       //图表数据授权
 	CACHE_REPORT_SHARE_AUTH                 = "eta:report:auth:share:"                //报告短链与报告图表授权映射key
 	CACHE_REPORT_AUTH                       = "eta:report:auth:"                      //报告图表数据授权
+	CACHE_EDB_INSPECTION_MESSAGE            = "eta:edb:inspection:message:"          //巡检消息队列
 )
 
 // 模板消息推送类型

+ 1 - 0
utils/redis.go

@@ -19,6 +19,7 @@ type RedisClient interface {
 	IsExist(key string) bool
 	LPush(key string, val interface{}) error
 	Brpop(key string, callback func([]byte))
+	BrpopWithTimeout(key string, timeout time.Duration, callback func([]byte)) error
 	LLen(key string) (int64, error)
 	GetRedisTTL(key string) time.Duration
 	Incrby(key string, num int) (interface{}, error)

+ 19 - 0
utils/redis/cluster_redis.go

@@ -249,6 +249,25 @@ func (rc *ClusterRedisClient) Brpop(key string, callback func([]byte)) {
 
 }
 
+// BrpopWithTimeout
+// @Description: 从list中读取
+// @receiver rc
+// @param key
+// @param timeout
+// @param callback
+func (rc *ClusterRedisClient) BrpopWithTimeout(key string, timeout time.Duration, callback func([]byte)) (err error) {
+	values, err := rc.redisClient.BRPop(context.TODO(), timeout, key).Result()
+	if err != nil {
+		return
+	}
+	if len(values) < 2 {
+		err = errors.New("redis brpop timeout")
+		return
+	}
+
+	callback([]byte(values[1]))
+	return
+}
 // LLen
 // @Description: 获取list中剩余的数据数
 // @author: Roc

+ 18 - 0
utils/redis/standalone_redis.go

@@ -237,6 +237,24 @@ func (rc *StandaloneRedisClient) Brpop(key string, callback func([]byte)) {
 
 }
 
+// BrpopWithTimeout
+// @Description: 从list中读取
+// @receiver rc
+// @param key
+// @param timeout
+// @param callback
+func (rc *StandaloneRedisClient) BrpopWithTimeout(key string, timeout time.Duration, callback func([]byte)) (err error) {
+	values, err := rc.redisClient.BRPop(context.TODO(), timeout, key).Result()
+	if err != nil {
+		return err
+	}
+	if len(values) < 2 {
+		err = errors.New("redis brpop timeout")
+		return
+	}
+	callback([]byte(values[1]))
+	return
+}
 // LLen
 // @Description: 获取list中剩余的数据数
 // @author: Roc