Prechádzať zdrojové kódy

Merge branch 'master' of http://10.8.230.114:3000/wangbin/log-server

倚楼听风雨 2 rokov pred
rodič
commit
8e8b927b35
57 zmenil súbory, kde vykonal 2527 pridanie a 142 odobranie
  1. 2 1
      .gitignore
  2. 22 2
      api/v1/log/log_ip.go
  3. 128 0
      api/v1/log/loging.go
  4. 124 0
      api/v1/task/central_control_conf.go
  5. 6 2
      api/v1/task/enter.go
  6. 40 1
      api/v1/task/game_task.go
  7. 3 3
      api/v1/task/task_conf.go
  8. 162 0
      api/v1/task/urgent_task_conf.go
  9. 1 0
      config.yaml
  10. 4 1
      initialize/router.go
  11. 7 1
      initialize/timer.go
  12. 17 0
      model/log/computer_status.go
  13. 86 0
      model/log/device_log.go
  14. 42 0
      model/log/device_statistics.go
  15. 25 0
      model/log/err_log.go
  16. 52 0
      model/log/log_ip.go
  17. 2 2
      model/log/loging.go
  18. 8 0
      model/log/request/log_ip.go
  19. 31 0
      model/log/request/log_statistics.go
  20. 29 18
      model/log/request/loging.go
  21. 7 0
      model/log/response/loging.go
  22. 31 0
      model/task/central_control_conf.go
  23. 17 1
      model/task/game_target_complete.go
  24. 2 1
      model/task/game_task.go
  25. 11 2
      model/task/request/game_task.go
  26. 14 0
      model/task/request/search_central_control_conf_params.go
  27. 13 0
      model/task/request/search_urgent_task_params.go
  28. 53 25
      model/task/response/game_task.go
  29. 3 3
      model/task/response/upload_file.go
  30. 1 1
      model/task/search_script_params.go
  31. 5 4
      model/task/task_conf.go
  32. 40 0
      model/task/urgent_task_conf.go
  33. 2 0
      router/enter.go
  34. 1 0
      router/log/log_ip.go
  35. 5 1
      router/log/loging.go
  36. 29 0
      router/task/central_control_conf.go
  37. 3 2
      router/task/game_task.go
  38. 29 0
      router/task/urgent_task_conf.go
  39. 4 0
      service/cache/cache.go
  40. 15 7
      service/card/id_card.go
  41. 4 0
      service/log/deviceInfo.go
  42. 261 34
      service/log/log_ip.go
  43. 3 0
      service/log/log_list.go
  44. 349 1
      service/log/log_statistics.go
  45. 1 0
      service/log/loging/game_start_log.go
  46. 286 1
      service/log/loging/logical_log.go
  47. 7 0
      service/log/loging/simulator_start_log.go
  48. 143 0
      service/system/sys_robot.go
  49. 111 0
      service/task/central_control_conf.go
  50. 2 0
      service/task/enter.go
  51. 53 13
      service/task/game_task.go
  52. 11 4
      service/task/sync_data.go
  53. 3 2
      service/task/task_conf.go
  54. 186 0
      service/task/urgent_task_conf.go
  55. 11 0
      utils/common.go
  56. 9 0
      utils/hash.go
  57. 11 9
      utils/verify.go

+ 2 - 1
.gitignore

@@ -43,4 +43,5 @@ _test
 log-server
 config.docker.yaml
 config.yaml
-/test
+/test
+/config.yaml

+ 22 - 2
api/v1/log/log_ip.go

@@ -44,8 +44,6 @@ func (s *ApiIpLog) GetIpLogList(c *gin.Context) {
 	}
 }
 
-
-
 //根据gameId分组获取ip
 func (s *ApiIpLog) GetGameIPList(c *gin.Context) {
 	var paramsInfo request.GameIpRequest
@@ -131,6 +129,28 @@ func (s *ApiIpLog) GetGameIp(c *gin.Context) {
 	}
 }
 
+//获取异常租机ip
+func (s *ApiIpLog) GetAbnormalIpLogList(c *gin.Context) {
+	var paramsInfo request.AbnormalIpLogListRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	if err := utils.Verify(paramsInfo.PageInfo, utils.PageInfoVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := ServiceIpLog.GetAbnormalIpLogList(paramsInfo.AbnormalIpLogRequest, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     paramsInfo.Page,
+			PageSize: paramsInfo.PageSize,
+		}, "获取成功", c)
+	}
+}
+
 //导出列表
 func (s *ApiIpLog) GameIpExport(c *gin.Context) {
 	var excelInfo request.ExcelIpInfo

+ 128 - 0
api/v1/log/loging.go

@@ -553,3 +553,131 @@ func (e *ApiLoging) ComputerSevenRate(c *gin.Context) {
 		}, "获取成功", c)
 	}
 }
+
+// @Tags loging
+// @Summary 设备统计接口
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce  application/json
+// @Param data body request.GetDeviceStatisticsRequest true "设备统计接口"
+// @Success 200
+// @Router /loging/getDeviceStatistics [post]
+func (e *ApiLoging) GetDeviceStatistics(c *gin.Context) {
+	var paramsInfo request.GetDeviceStatisticsRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	list, total, err := ServiceStatisticsLog.GetDeviceStatistics(c, paramsInfo.DeviceStatisticsReply, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     paramsInfo.Page,
+			PageSize: paramsInfo.PageSize,
+		}, "获取成功", c)
+	}
+}
+
+// @Tags loging
+// @Summary 设备统计接口
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce  application/json
+// @Param data body request.GetDeviceStatisticsRequest true "设备统计接口"
+// @Success 200
+// @Router /loging/getDeviceInfoLog [post]
+func (e *ApiLoging) GetDeviceInfoLog(c *gin.Context) {
+	var paramsInfo request.GetDeviceInfoLogRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	list, total, err := ServiceStatisticsLog.GetDeviceInfo(c, paramsInfo.DeviceLog, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     paramsInfo.Page,
+			PageSize: paramsInfo.PageSize,
+		}, "获取成功", c)
+	}
+}
+
+// @Tags loging
+// @Summary 设备id异常数据
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce  application/json
+// @Param data body request.GetDeviceStatisticsRequest true "设备id异常数据"
+// @Success 200
+// @Router /loging/getDeviceIdErr [post]
+func (e *ApiLoging) GetDeviceIdErr(c *gin.Context) {
+	var paramsInfo request.GetDeviceIdErrRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	list, total, err := ServiceStatisticsLog.GetDeviceIdErr(c, paramsInfo.ScriptDeviceErr, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     paramsInfo.Page,
+			PageSize: paramsInfo.PageSize,
+		}, "获取成功", c)
+	}
+}
+
+// @Tags loging
+// @Summary 导出Excel
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce  application/octet-stream
+// @Param data body request.GetStatisticsComputerRequest true "导出Excel文件信息"
+// @Success 200
+// @Router /loging/deviceErrRateExcel [post]
+func (e *ApiLoging) DeviceErrRateExcel(c *gin.Context) {
+	var excelInfo request.ExcelDeviceErrRate
+	_ = c.ShouldBindJSON(&excelInfo)
+	paramsInfo := excelInfo.InfoList
+	paramsInfo.PageSize = 1000
+	paramsInfo.Page = 1
+	list, _, err := ServiceStatisticsLog.GetDeviceStatistics(c, paramsInfo.DeviceStatisticsReply, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取电脑数据失败!", zap.Error(err))
+		response.FailWithMessage("获取电脑数据失败", c)
+		return
+	}
+	filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
+	err = ServiceStatisticsLog.DeviceErrRateExcel(list, filePath)
+	if err != nil {
+		global.GVA_LOG.Error("转换Excel失败!", zap.Error(err))
+		response.FailWithMessage("转换Excel失败", c)
+		return
+	}
+	c.Writer.Header().Add("success", "true")
+	c.File(filePath)
+}
+
+// @Tags loging
+// @Summary 设备异常数据接口
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce  application/json
+// @Param data body log2.DeviceLog true "设备异常数据接口"
+// @Success 200
+// @Router /loging/getErrDeviceLog [post]
+func (e *ApiLoging) GetErrDeviceLog(c *gin.Context) {
+	var paramsInfo log2.DeviceLog
+	_ = c.ShouldBindJSON(&paramsInfo)
+	list, err := ServiceStatisticsLog.GetDeviceContrastInfo(c, paramsInfo)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List: list,
+		}, "获取成功", c)
+	}
+}

+ 124 - 0
api/v1/task/central_control_conf.go

@@ -0,0 +1,124 @@
+package task
+
+import (
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"log-server/global"
+	"log-server/model/common/request"
+	"log-server/model/common/response"
+	"log-server/model/task"
+	taskRequest "log-server/model/task/request"
+	"log-server/utils"
+)
+
+type CentralControlApi struct {
+
+}
+
+//创建中控配置
+func (a *CentralControlApi) CreateCentralControlConf (c *gin.Context)  {
+	var conf task.CentralControlConf
+	_ = c.ShouldBindJSON(&conf)
+	if conf.Mirror == "" {
+		response.FailWithMessage("请传入镜像名称", c)
+		return
+	}
+	if conf.Script == "" {
+		response.FailWithMessage("请传入脚本名称", c)
+		return
+	}
+	if err := utils.Verify(conf, utils.CentralControlConfVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if err := centralControlService.CreateCentralControlConf(conf);err != nil {
+		global.GVA_LOG.Error("创建失败!", zap.Error(err))
+		response.FailWithMessage("创建失败", c)
+	} else {
+		response.OkWithMessage("创建成功", c)
+	}
+}
+
+//删除配置列表
+func (a *CentralControlApi) DeleteCentralControlConf(c *gin.Context) {
+	var conf task.CentralControlConf
+	 _ = c.ShouldBindJSON(&conf)
+
+	 //数据校验
+	 if err := utils.Verify(conf, utils.CentralControlConfVerify); err != nil {
+		 response.FailWithMessage(err.Error(), c)
+		 return
+	 }
+	if err := centralControlService.DeleteCentralControlConf(conf); err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+//批量删除配置列表
+func (a *CentralControlApi) DeleteCentralControlConfByIds(c *gin.Context) {
+	var ids request.IdsReq
+	_ = c.ShouldBindJSON(&ids)
+	if err := centralControlService.DeleteCentralControlConfByIds(ids.Ids); err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+//更新中控配置
+func (a *CentralControlApi) UpdateCentralControlConf (c *gin.Context)  {
+	var conf task.CentralControlConf
+	_ = c.ShouldBindJSON(&conf)
+	if err := utils.Verify(conf, utils.CentralControlConfVerify); err != nil{
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if err := centralControlService.UpdateCentralControlConf(conf); err != nil{
+		global.GVA_LOG.Error("更新失败!", zap.Error(err))
+		response.FailWithMessage("更新失败", c)
+	} else {
+		response.OkWithMessage("更新成功", c)
+	}
+}
+
+func (a *CentralControlApi) GetCentralControlConfById (c *gin.Context)  {
+	var id request.GetById
+	_ = c.ShouldBindJSON(&id)
+	if err := utils.Verify(id, utils.IdVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if conf, err := centralControlService.GetCentralControlConfById(id.ID); err != nil{
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(conf, "获取成功", c)
+	}
+}
+
+//获取中控配置列表
+func (a *CentralControlApi) GetCentralControlConfList (c *gin.Context)  {
+	//获取前端传值并校验
+	var pageInfo taskRequest.SearchCentralControlConfParams
+	_ = c.ShouldBindJSON(&pageInfo)
+	//页面信息校验
+	if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil{
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if list, total, err := centralControlService.GetCentralControlConfList(pageInfo.CentralControlConf, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil{
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     pageInfo.Page,
+			PageSize: pageInfo.PageSize,
+		}, "获取成功", c)
+	}
+}

+ 6 - 2
api/v1/task/enter.go

@@ -5,9 +5,13 @@ import "log-server/service"
 type GroupTask struct {
 	GameTaskApi
 	TaskConfApi
+	CentralControlApi
+	UrgentTaskApi
 }
 
 var (
-	taskService = service.ServiceGroupApp.TaskServiceGroup.GameTask
-	taskConfService = service.ServiceGroupApp.TaskServiceGroup.TaskConfService
+	taskService           = service.ServiceGroupApp.TaskServiceGroup.GameTask
+	taskConfService       = service.ServiceGroupApp.TaskServiceGroup.TaskConfService
+	centralControlService = service.ServiceGroupApp.TaskServiceGroup.CentralControlService
+	urgentTaskService     = service.ServiceGroupApp.TaskServiceGroup.UrgentTaskService
 )

+ 40 - 1
api/v1/task/game_task.go

@@ -67,6 +67,32 @@ func (s *GameTaskApi) GetGameTaskList(c *gin.Context) {
 	}
 }
 
+// @Tags gameTask
+// @Summary 小绵羊任务列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.GetXmyTaskListRequest true "小绵羊任务列表"
+// @Success 200 {object} response.Response{data=response.GetXmyTaskListReply,msg=string} "分页小绵羊任务列表,返回包括列表,总数,页码,每页数量"
+// @Router /gameTask/getXmyTaskList [post]
+func (s *GameTaskApi) GetXmyTaskList(c *gin.Context) {
+	var paramsInfo request.GetXmyGameListRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	startDay := time.Now().Format("2006-01-02")
+	endDay := time.Now().Format("2006-01-02")
+	if len(paramsInfo.Date) != 0 {
+		startDay = paramsInfo.Date[0]
+		endDay = paramsInfo.Date[1]
+	}
+
+	if list, err := taskService.GetXmyTaskList(startDay, endDay); err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败"+err.Error(), c)
+	} else {
+		response.OkWithDetailed(list, "获取成功", c)
+	}
+}
+
 //获取启用状态的任务
 func (s *GameTaskApi) GetUsedGameTaskList(c *gin.Context) {
 	var paramsInfo request.GetGameTaskListRequest
@@ -89,7 +115,6 @@ func (s *GameTaskApi) GetUsedGameTaskList(c *gin.Context) {
 	}
 }
 
-
 // @Tags gameTask
 // @Summary 根据id获取游戏任务信息
 // @Security ApiKeyAuth
@@ -507,3 +532,17 @@ func (e *GameTaskApi) TaskTargetExport(c *gin.Context) {
 	c.Writer.Header().Add("success", "true")
 	c.File(filePath)
 }
+
+func (e *GameTaskApi) TemporaryTask(c *gin.Context) {
+	var params request.GetTemporaryTaskRequest
+	_ = c.ShouldBindJSON(&params)
+	if params.PcCode == "" {
+		response.FailWithMessage("参数错误", c)
+		return
+	}
+	if data, err := taskService.TemporaryTask(c, params.PcCode); err != nil {
+		response.FailWithMessage("获取失败 "+err.Error(), c)
+	} else {
+		response.OkWithDetailed(data, "获取成功", c)
+	}
+}

+ 3 - 3
api/v1/task/task_conf.go

@@ -56,9 +56,9 @@ func (b *TaskConfApi) DownloadFile(c *gin.Context) {
 	downloadFile, err := taskConfService.DownloadFile(taskId, md5String)
 	if err != nil {
 		global.GVA_LOG.Error("查询失败!", zap.Error(err))
-		response.FailWithMessage("查询失败,无对应脚本", c)
+		response.FailWithMessage(err.Error(), c)
 	} else {
-		response.OkWithDetailed(taskRes.DownloadInfoResponse{downloadFile}, "查询成功", c)
+		response.OkWithDetailed(downloadFile, "查询成功", c)
 	}
 
 }
@@ -67,7 +67,7 @@ func (b *TaskConfApi) DownloadFile(c *gin.Context) {
 //获取所有游戏脚本列表
 func (b *TaskConfApi) GetScriptList(c *gin.Context)  {
 	//获取前端传值并校验
-	var pageInfo task.SearchAccountTypeParams
+	var pageInfo task.SearchGameScriptParams
 	_ = c.ShouldBindJSON(&pageInfo)
 	//页面信息校验
 	if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil{

+ 162 - 0
api/v1/task/urgent_task_conf.go

@@ -0,0 +1,162 @@
+package task
+
+import (
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"log-server/global"
+	"log-server/model/common/response"
+	"log-server/model/task"
+	"log-server/model/task/request"
+	"log-server/utils"
+)
+
+type UrgentTaskApi struct {
+}
+
+//查询空闲租机
+func (a *UrgentTaskApi) GetUnusedPc (c *gin.Context)  {
+	if pcList,err := urgentTaskService.GetUnusedPc(); err != nil {
+		global.GVA_LOG.Error("创建失败!", zap.Error(err))
+		response.FailWithMessage(err.Error(), c)
+	} else {
+		response.OkWithDetailed(pcList, "获取成功", c)
+	}
+}
+
+//创建紧急任务
+func (a *UrgentTaskApi) CreateUrgentTask (c *gin.Context)  {
+	var task1 task.CreateAndUpdateUrgentTaskConf
+	_ = c.ShouldBindJSON(&task1)
+	var pcCodeString string
+	if task1.TaskId == 0 {
+		response.FailWithMessage("请传入任务id", c)
+		return
+	}
+	if len(task1.PcCode) == 0 {
+		response.FailWithMessage("请传入租机列表", c)
+		return
+	}
+	//处理pc_code数组
+	for k,pcCode := range task1.PcCode{
+		if k != len(task1.PcCode) - 1 {
+			pcCodeString = pcCodeString + pcCode + ","
+		} else {
+			pcCodeString = pcCodeString + pcCode
+		}
+	}
+	//创建实体
+	entity := task.UrgentTaskConf {
+		Id: task1.Id,
+		TaskId: task1.TaskId,
+		PcCode: pcCodeString,
+	}
+	if err := urgentTaskService.CreateUrgentTask(entity); err != nil {
+		global.GVA_LOG.Error("创建失败!", zap.Error(err))
+		response.FailWithMessage(err.Error(), c)
+	} else {
+		response.OkWithMessage("创建成功", c)
+	}
+}
+
+//删除单个紧急任务
+func (a *UrgentTaskApi) DeleteUrgentTask(c *gin.Context) {
+	var task1 task.UrgentTaskConf
+	_ = c.ShouldBindJSON(&task1)
+	if err := utils.Verify(task1, utils.UrgentTaskVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if err := urgentTaskService.DeleteUrgentTask(task1); err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+//批量删除紧急任务
+func (a *UrgentTaskApi) DeleteUrgentTaskByIds (c *gin.Context) {
+	var ids request.IdsReq
+	_ = c.ShouldBindJSON(&ids)
+	if err := urgentTaskService.DeleteUrgentTaskByIds(ids.Ids); err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+//更新紧急任务
+func (a *UrgentTaskApi) UpdateUrgentTask (c *gin.Context)  {
+	var task1 task.CreateAndUpdateUrgentTaskConf
+	_ = c.ShouldBindJSON(&task1)
+	var pcCodeString string
+	if task1.TaskId == 0 {
+		response.FailWithMessage("请传入任务id", c)
+		return
+	}
+	if len(task1.PcCode) == 0 {
+		response.FailWithMessage("请传入租机列表", c)
+		return
+	}
+	//处理pc_code数组
+	for k,pcCode := range task1.PcCode{
+		if k != len(task1.PcCode) - 1 {
+			pcCodeString = pcCodeString + pcCode + ","
+		} else {
+			pcCodeString = pcCodeString + pcCode
+		}
+	}
+	//创建实体
+	entity := task.UrgentTaskConf {
+		Id: task1.Id,
+		TaskId: task1.TaskId,
+		PcCode: pcCodeString,
+		CreateDate: task1.CreateDate[:10],
+	}
+
+	if err := urgentTaskService.UpdateUrgentTask(entity); err != nil{
+		global.GVA_LOG.Error("更新失败!", zap.Error(err))
+		response.FailWithMessage("更新失败", c)
+	} else {
+		response.OkWithMessage("更新成功", c)
+	}
+}
+
+//id获取紧急任务
+func (a *UrgentTaskApi) GetUrgentTaskById(c *gin.Context){
+	var id request.GetById
+	_ = c.ShouldBindJSON(&id)
+	if err := utils.Verify(id, utils.IdVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if task1, err := urgentTaskService.GetUrgentTaskById(id.ID); err != nil{
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(task1, "获取成功", c)
+	}
+}
+
+//获取紧急任务列表
+func (a *UrgentTaskApi) GetUrgentTaskList(c *gin.Context) {
+	var paramsInfo request.SearchUrgentTaskParams
+	_ = c.ShouldBindJSON(&paramsInfo)
+	if err := utils.Verify(paramsInfo.PageInfo, utils.PageInfoVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := urgentTaskService.GetUrgentTaskList(paramsInfo.UrgentTaskConfRequest, paramsInfo.PageInfo, paramsInfo.OrderKey, paramsInfo.Desc)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+	} else {
+		response.OkWithDetailed(response.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     paramsInfo.Page,
+			PageSize: paramsInfo.PageSize,
+		}, "获取成功", c)
+	}
+}

+ 1 - 0
config.yaml

@@ -160,6 +160,7 @@ zap:
   log-in-console: true
 send-url:
   computer-send-url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=7d095d5b-8240-45fd-a68c-baff3628d83b111"
+#  computer-send-url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=89460a48-e1a1-4181-86c0-533bad342628"
   keyword-send-url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=34cbfa5a-c31d-464f-baf8-8363d6f4ac6a111"
   send-url-one: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5ccfb180-c062-48b5-ae18-0c96f7c19f0b111" #深圳群
   get-url-arpu: "http://sy.8888888.com/v2/optimize/arpu"

+ 4 - 1
initialize/router.go

@@ -22,7 +22,8 @@ func Routers() *gin.Engine {
 	computerRouter := router.RouterGroupApp.Computer
 	taskRouter := router.RouterGroupApp.Task
 	uploadFileRouter := router.RouterGroupApp.UploadFile
-
+	centralControlRouter := router.RouterGroupApp.CentralControl
+	urgentTaskRouter := router.RouterGroupApp.UrgentTask
 	ipLogRouter := router.RouterGroupApp.IpLog
 	idCardRouter := router.RouterGroupApp.IdCard
 	typeManageRouter := router.RouterGroupApp.TypeManage
@@ -71,6 +72,8 @@ func Routers() *gin.Engine {
 		idCardRouter.InitIdCardRouter(PublicGroup)                //身份证路由
 		taskRouter.InitGameTaskRouter(PublicGroup)
 		uploadFileRouter.InitUploadFileRouter(PublicGroup)
+		centralControlRouter.InitCentralControlRouter(PublicGroup) //中控配置
+		urgentTaskRouter.InitUrgentTaskRouter(PublicGroup)         //紧急任务
 		rentComputerRouter.InitRentComputerRouter(PublicGroup)     //租机管理
 		rentComputerRouter.InitRentComputerShopRouter(PublicGroup) // 租机供应商管理
 		rentComputerRouter.InitRentSetMealRouter(PublicGroup)

+ 7 - 1
initialize/timer.go

@@ -200,8 +200,14 @@ func Timer() {
 	//	fmt.Println("add RemindSendOne timer error:", err)
 	//}
 
+	//一小时同步一次IP信息,播报是否有异常
+	_, err := global.GVA_Timer.AddTaskByFunc("SyncIPMessage", "0 0 * * * ? ", robotService.SyncIPMessage)
+	if err != nil {
+		fmt.Println("add SyncIPMessage timer error:", err)
+	}
+
 	//定时查看延迟更新的镜像是否到期
-	_, err := global.GVA_Timer.AddTaskByFunc("CheckPushTime", "35 0/2 * * * *", serviceFileQiniu.CheckPushTime)
+	_, err = global.GVA_Timer.AddTaskByFunc("CheckPushTime", "35 0/2 * * * *", serviceFileQiniu.CheckPushTime)
 	if err != nil {
 		fmt.Println("add CheckPushTime timer error:", err)
 	}

+ 17 - 0
model/log/computer_status.go

@@ -0,0 +1,17 @@
+package log
+
+import (
+	"time"
+)
+
+type ComputerStatus struct {
+	Id         uint      `json:"id"`
+	PcCode     string    `json:"pc_code"`
+	Status     int       `json:"status"`
+	UpdateTime time.Time `json:"update_time"` // 更新时间
+	CreateDate time.Time `json:"create_date"`
+}
+
+func (ComputerStatus) TableName() string {
+	return "computer_status"
+}

+ 86 - 0
model/log/device_log.go

@@ -0,0 +1,86 @@
+package log
+
+import "time"
+
+type DeviceLog struct {
+	Id                 uint   `json:"id"`
+	SimulatorCode      string `json:"simulator_code"`
+	DeviceManufacturer string `json:"device_manufacturer"`
+	DeviceModel        string `json:"device_model"`
+	DeviceImei         string `json:"device_imei"`
+	DeviceSdk          string `json:"device_sdk"`
+	DeviceMac          string `json:"device_mac"`
+	DeviceNumber       string `json:"device_number"`
+	DeviceIp           string `json:"device_ip"`
+	DeviceId           string `json:"device_id"`
+	Account            string `json:"account"`
+	GameId             int    `json:"game_id"`
+	CreateDate         string `json:"create_date"`
+	CreateTime         string `json:"create_time"` // 创建时间
+	IsErr              int8   `json:"is_err"`
+	ErrStatus          uint8  `json:"err_status"`
+	DeviceHex          string `json:"device_hex"`
+	AccountHex         string `json:"account_hex"`
+	LogUuid            string `json:"log_uuid"` //日志UUID
+	ScriptDeviceId     string `json:"script_device_id"`
+	PcCode             string `json:"pc_code"`
+	SimulatorIpCity    string `json:"simulator_ip_city"`
+}
+
+func (DeviceLog) TableName() string {
+	return "device_log"
+}
+
+type AccountHex struct {
+	DeviceManufacturer string `json:"device_manufacturer"`
+	DeviceModel        string `json:"device_model"`
+	DeviceImei         string `json:"device_imei"`
+	DeviceSdk          string `json:"device_sdk"`
+	DeviceMac          string `json:"device_mac"`
+	DeviceNumber       string `json:"device_number"`
+	DeviceId           string `json:"device_id"`
+	GameId             int    `json:"game_id"`
+	Account            string `json:"account"`
+}
+
+type DeviceHex struct {
+	DeviceManufacturer string `json:"device_manufacturer"`
+	DeviceModel        string `json:"device_model"`
+	DeviceImei         string `json:"device_imei"`
+	DeviceSdk          string `json:"device_sdk"`
+	DeviceMac          string `json:"device_mac"`
+	DeviceNumber       string `json:"device_number"`
+	DeviceId           string `json:"device_id"`
+	GameId             int    `json:"game_id"`
+}
+
+type GameAccount struct {
+	Id             uint      `json:"id"`
+	GameId         int       `json:"game_id"`
+	Account        string    `json:"account"`
+	ScriptDeviceId string    `json:"script_device_id"`
+	CreateTime     time.Time `json:"create_time"` // 创建时间
+}
+
+func (GameAccount) TableName() string {
+	return "game_account"
+}
+
+type ScriptDeviceErr struct {
+	Id              uint      `json:"id"`
+	GameId          int       `json:"game_id"`
+	Account         string    `json:"account"`
+	FirstDeviceId   string    `json:"first_device_id"`
+	CurrentDeviceId string    `json:"current_device_id"`
+	CurrentGameId   int       `json:"current_game_id"`
+	CurrentAccount  string    `json:"current_account"`
+	CreateTime      time.Time `json:"create_time"` // 创建时间
+	CreateDate      string    `json:"create_date"`
+	Status          uint      `json:"status"` // 1是同一账号不同设备id,2新增出现同一设备id
+	PcCode          string    `json:"pc_code"`
+	Operator        string    `json:"operator"`
+}
+
+func (ScriptDeviceErr) TableName() string {
+	return "script_device_err"
+}

+ 42 - 0
model/log/device_statistics.go

@@ -0,0 +1,42 @@
+package log
+
+type DeviceStatistics struct {
+	Id                   uint    `json:"id"`
+	GameId               int     `json:"game_id"`
+	DeviceErrNum         int     `json:"device_err_num"`
+	DeviceErrRate        float64 `json:"device_err_rate"`
+	AccountErrNum        int     `json:"account_err_num"`
+	AccountErrRate       float64 `json:"account_err_rate"`
+	SimulatorStartNum    int     `json:"simulator_start_num"`
+	CreateDate           string  `json:"create_date"`
+	NewComplete          int     `json:"new_complete"`
+	RetainedComplete     int     `json:"retained_complete"`
+	NewDeviceIdErr       int     `json:"new_device_id_err"`
+	NewDeviceIdRate      float64 `json:"new_device_id_rate"`
+	RetainedDeviceIdErr  int     `json:"retained_device_id_err"`
+	RetainedDeviceIdRate float64 `json:"retained_device_id_rate"`
+	DefinedErr           int     `json:"defined_err"`
+	UndefinedErr         int     `json:"undefined_err"`
+}
+
+func (DeviceStatistics) TableName() string {
+	return "device_statistics"
+}
+
+type DeviceStatisticsReply struct {
+	Id                   uint    `json:"id"`
+	User                 string  `json:"user"`
+	GameId               int     `json:"game_id"`
+	DeviceErrNum         int     `json:"device_err_num"`
+	DeviceErrRate        float64 `json:"device_err_rate"`
+	AccountErrNum        int     `json:"account_err_num"`
+	AccountErrRate       float64 `json:"account_err_rate"`
+	SimulatorStartNum    int     `json:"simulator_start_num"`
+	CreateDate           string  `json:"create_date"`
+	NewComplete          int     `json:"new_complete"`
+	RetainedComplete     int     `json:"retained_complete"`
+	NewDeviceIdErr       int     `json:"new_device_id_err"`
+	NewDeviceIdRate      float64 `json:"new_device_id_rate"`
+	RetainedDeviceIdErr  int     `json:"retained_device_id_err"`
+	RetainedDeviceIdRate float64 `json:"retained_device_id_rate"`
+}

+ 25 - 0
model/log/err_log.go

@@ -0,0 +1,25 @@
+package log
+
+import (
+	"log-server/global"
+	"time"
+)
+
+type DeviceErrLog struct {
+	Id         uint      `json:"id"`
+	Content    string    `json:"content"`
+	GameId     int       `json:"game_id"`
+	PcCode     string    `json:"pc_code"`
+	CreateDate time.Time `json:"create_date"`
+	CreateTime time.Time `json:"create_time"`
+	Err        string    `json:"err"`
+	Status     uint      `json:"status"`
+}
+
+func (DeviceErrLog) TableName() string {
+	return "device_err_log"
+}
+
+func (m *DeviceErrLog) Create() error {
+	return global.GVA_DB.Create(m).Error
+}

+ 52 - 0
model/log/log_ip.go

@@ -11,6 +11,19 @@ type IpLog struct {
 	CreateTime string `json:"create_time"` // 创建时间
 }
 
+//播报处理的iplog
+type IpLogBroadcast struct {
+	Id         uint   `json:"id"`
+	Ip         string `json:"ip"`          //模拟器ip
+	User       string `json:"user"`        //负责人
+	LogUuid    string `json:"log_uuid"`    //日志UUID
+	GameId     int    `json:"game_id"`     //游戏id
+	Account    string `json:"account"`     //账号
+	PcCode     string `json:"pc_code"`     //电脑编号
+	CreateDate string `json:"create_date"` // 创建日期
+	CreateTime string `json:"create_time"` // 创建时间
+}
+
 type IpLogRequest struct {
 	Id         uint     `json:"id"`
 	Ip         string   `json:"ip"` //模拟器ip
@@ -64,6 +77,45 @@ type QueryIpList struct {
 	Count int    `json:"count"`
 }
 
+type AbnormalMachineIp struct {
+	Id         uint   `json:"id"`
+	Ip         string `json:"ip"`          //模拟器ip
+	Count      int    `json:"count"`       //ip数量
+	GameId     int    `json:"game_id"`     //游戏id
+	User       string `json:"user"`        //负责人
+	TaskName   string `json:"task_name"`   //任务名称
+	PcCode     string `json:"pc_code"`     //电脑编号
+	CreateDate string `json:"create_date"` // 创建日期
+}
+
+type AbnormalIpLogRequest struct {
+	Id         uint     `json:"id"`
+	Ip         string   `json:"ip"` //模拟器ip
+	Date       []string `json:"date"`
+	GameId     int      `json:"game_id"`     //游戏id
+	PcCode     string   `json:"pc_code"`     //电脑编号
+	CreateDate string   `json:"create_date"` // 创建日期
+}
+
+type TodayAbnormalMachineIp struct {
+	Id         uint   `json:"id"`
+	Ip         string `json:"ip"`          //模拟器ip
+	Count      int    `json:"count"`       //ip数量
+	GameId     int    `json:"game_id"`     //游戏id
+	PcCode     string `json:"pc_code"`     //电脑编号
+	User       string `json:"user"`        //负责人名称
+	TaskName   string `json:"task_name"`   //任务名称
+	CreateDate string `json:"create_date"` // 创建日期
+}
+
 func (IpLog) TableName() string {
 	return "ip_log"
 }
+
+func (AbnormalMachineIp) TableName() string {
+	return "abnormal_machine_ip"
+}
+
+func (GameIpResponse) TableName() string {
+	return "game_ip_list"
+}

+ 2 - 2
model/log/loging.go

@@ -26,7 +26,7 @@ type Loging struct {
 	Status       int    `json:"status"` // 1成功2失败
 	AccountType  int    `json:"account_type"`
 	Remarks      string `json:"remarks"`
-	TaskType     int    `json:"task_type"`
+	TaskType     int    `json:"task_type"` //新增0 活跃1
 	ScriptType   int    `json:"script_type"`
 	CreateDate   string `json:"create_date"`
 	CreateTime   string `json:"create_time"` // 创建时间
@@ -65,7 +65,7 @@ func (Loging) CreateLogingTable() (err error) {
 	sql += " `operator` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '脚本开发员',"
 	sql += " `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',"
 	sql += " `create_date` date DEFAULT NULL COMMENT '创建日期',"
-	sql += " `task_type` tinyint(1) DEFAULT '0' COMMENT '新增1 活跃2',"
+	sql += " `task_type` tinyint(1) DEFAULT '0' COMMENT '新增0 活跃1',"
 	sql += " `script_type` tinyint(1) DEFAULT '0',"
 	sql += " PRIMARY KEY (`id`) USING BTREE,"
 	sql += " KEY `log_uuid` (`log_uuid`) USING BTREE,"

+ 8 - 0
model/log/request/log_ip.go

@@ -15,3 +15,11 @@ type GameIpRequest struct {
 	OrderKey string `json:"orderKey"` // 排序
 	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
 }
+
+//异常租机ip列表获取
+type AbnormalIpLogListRequest struct {
+	log.AbnormalIpLogRequest
+	PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}

+ 31 - 0
model/log/request/log_statistics.go

@@ -70,6 +70,16 @@ type ExcelInfo struct {
 	} `json:"infoList"`
 }
 
+type ExcelDeviceErrRate struct {
+	FileName string `json:"fileName"` // 文件名
+	InfoList struct {
+		log.DeviceStatisticsReply
+		PageInfo
+		OrderKey string `json:"orderKey"` // 排序
+		Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+	} `json:"infoList"`
+}
+
 //导出ip列表
 type ExcelIpInfo struct {
 	FileName string `json:"fileName"` // 文件名
@@ -99,3 +109,24 @@ type LogScanningRequest struct {
 	CreateDate string `json:"create_date"`
 	CreateTime string `json:"create_time"` // 创建时间
 }
+
+type GetDeviceStatisticsRequest struct {
+	log.DeviceStatisticsReply
+	PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}
+
+type GetDeviceInfoLogRequest struct {
+	log.DeviceLog
+	PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}
+
+type GetDeviceIdErrRequest struct {
+	log.ScriptDeviceErr
+	PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}

+ 29 - 18
model/log/request/loging.go

@@ -5,24 +5,35 @@ import (
 )
 
 type AddLogRequest struct {
-	SimulatorIp      string `json:"simulator_ip"`
-	SimulatorMac     string `json:"simulator_mac"`
-	PcCode           string `json:"pc_code"`
-	PcIp             string `json:"pc_ip"`
-	PcMac            string `json:"pc_mac"`
-	DeviceId         string `json:"device_id"`
-	Account          string `json:"account"`
-	GameId           int    `json:"game_id"`
-	Coding           int    `json:"coding"`
-	ComputerType     int    `json:"computer_type"`
-	EnvCode          int    `json:"env_code"`
-	LogUuid          string `json:"log_uuid"`
-	Operator         string `json:"operator"`
-	AccountType      int    `json:"account_type"`
-	ReportPointsData string `json:"report_points_data"`
-	Remarks          string `json:"remarks"`
-	TaskType         int    `json:"task_type"`   // 新增1,活跃2
-	ScriptType       int    `json:"script_type"` // 中控1,脚本2
+	SimulatorIp        string `json:"simulator_ip"`
+	SimulatorMac       string `json:"simulator_mac"`
+	PcCode             string `json:"pc_code"`
+	PcIp               string `json:"pc_ip"`
+	PcMac              string `json:"pc_mac"`
+	DeviceId           string `json:"device_id"`
+	Account            string `json:"account"`
+	GameId             int    `json:"game_id"`
+	Coding             int    `json:"coding"`
+	ComputerType       int    `json:"computer_type"`
+	EnvCode            int    `json:"env_code"`
+	LogUuid            string `json:"log_uuid"`
+	Operator           string `json:"operator"`
+	AccountType        int    `json:"account_type"`
+	ReportPointsData   string `json:"report_points_data"`
+	Remarks            string `json:"remarks"`
+	TaskType           int    `json:"task_type"`   // 新增1,活跃2
+	ScriptType         int    `json:"script_type"` // 中控1,脚本2
+	SimulatorCode      string `json:"simulator_code"`
+	DeviceManufacturer string `json:"device_manufacturer"`
+	DeviceModel        string `json:"device_model"`
+	DeviceImei         string `json:"device_imei"`
+	DeviceSdk          string `json:"device_sdk"`
+	DeviceMac          string `json:"device_mac"`
+	DeviceNumber       string `json:"device_number"`
+	DeviceIp           string `json:"device_ip"`
+	ScriptDeviceId     string `json:"script_device_id"`
+	Err                string `json:"err"` // 0或不传表示没有异常,其他表示异常,脚本端自定义
+	SimulatorIpCity    string `json:"simulator_ip_city"`
 }
 
 type ReportPointsData struct {

+ 7 - 0
model/log/response/loging.go

@@ -91,3 +91,10 @@ type LogScanningReply struct {
 	CreateDate string `json:"create_date"`
 	CreateTime string `json:"create_time"` // 创建时间
 }
+
+type DeviceInfoReply struct {
+	DeviceErrNum  uint8  `json:"device_err_num"`
+	GameId        int    `json:"game_id"`
+	AccountErrNum uint8  `json:"account_err_num"`
+	CreateDate    string `json:"create_date"`
+}

+ 31 - 0
model/task/central_control_conf.go

@@ -0,0 +1,31 @@
+package task
+
+import "log-server/model/typeManage"
+
+type CentralControlConf struct {
+	Id            int                  `json:"id"`
+	Mirror        string               `json:"mirror"`         //镜像
+	Script        string               `json:"script"`         //脚本
+	CloneMode     int                  `json:"clone_mode"`     //克隆模式
+	SimulatorType int                  `json:"simulator_type"` //模拟器类型
+	Resolution    string               `json:"resolution"`     //分辨率
+	Zoom          string               `json:"zoom"`           //缩放
+	Timeout       int                  `json:"timeout"`        //超时时间
+	Cpu           int                  `json:"cpu"`            //cpu
+	MemorySize    int                  `json:"memory_size"`    //内存
+	TaskId        int                  `json:"task_id"`        //任务id
+	GameId        int                  `json:"game_id"`        //游戏id
+	Priority      string               `json:"priority"`       //优先级
+	GameType      int                  `json:"game_type"`      //任务类型
+	TxChannel     string               `json:"tx_channel"`     //'腾讯渠道号',
+	TxGameId      string               `json:"tx_game_id"`     //'腾讯游戏id',
+	MzChannel     string               `json:"mz_channel"`     //'魅族渠道号',
+	MzGameId      string               `json:"mz_game_id"`     //'魅族游戏id',
+	PayPrice      int                  `json:"pay_price"`      //'付费单价',
+	CreateTime    typeManage.LocalTime `json:"create_time"`
+	UpdateTime    typeManage.LocalTime `json:"update_time"`
+}
+
+func (CentralControlConf) TableName() string {
+	return "central_control_conf"
+}

+ 17 - 1
model/task/game_target_complete.go

@@ -1,6 +1,9 @@
 package task
 
-import "time"
+import (
+	"log-server/global"
+	"time"
+)
 
 type GameTargetComplete struct {
 	Id                   uint      `json:"id"`
@@ -25,3 +28,16 @@ type GameTargetComplete struct {
 func (GameTargetComplete) TableName() string {
 	return "game_target_complete"
 }
+
+// 获取任务完成数据
+func (s *GameTargetComplete) CompleteTaskData(date string) (mps map[int]GameTargetComplete, err error) {
+	db := global.GVA_DB.Table("game_target_complete")
+	db = db.Where("create_date = ?", date)
+	var apiList []GameTargetComplete
+	mps = map[int]GameTargetComplete{}
+	err = db.Order("id desc").Find(&apiList).Error
+	for _, api := range apiList {
+		mps[api.TaskId] = api
+	}
+	return
+}

+ 2 - 1
model/task/game_task.go

@@ -34,13 +34,14 @@ type GameTask struct {
 	StopTime        time.Time `json:"stop_time"`
 }
 
-//添加加付费提醒字段
+//添加加付费提醒字段和模拟器类型字段
 type GameTaskUnion struct {
 	Id              uint      `json:"id"`
 	TaskId          int       `json:"task_id"`
 	TaskName        string    `json:"task_name"`
 	User            string    `json:"user"`
 	AddFeeNotice    int       `json:"add_fee_notice"`
+	SimulatorType   int       `json:"simulator_type"`
 	NewRetained     string    `json:"new_retained"`
 	GameName        string    `json:"game_name"`
 	GameId          int       `json:"game_id"`

+ 11 - 2
model/task/request/game_task.go

@@ -36,6 +36,11 @@ type GetGameTaskListRequest struct {
 	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
 }
 
+//获取小绵羊游戏数据列表
+type GetXmyGameListRequest struct {
+	Date []string `json:"date"`
+}
+
 type UpdateGameTaskStatusRequest struct {
 	TaskId int `json:"task_id"`
 	Status int `json:"status"` // 状态-1关闭,1开启
@@ -78,7 +83,7 @@ type GameTargetCompleteRequest struct {
 	Date             []string `json:"date"`
 	GamePortId       int      `json:"game_port_id"`
 	Aupr             int      `json:"aupr"`
-	TotalAmount      float64      `json:"total_amount"`
+	TotalAmount      float64  `json:"total_amount"`
 }
 
 type GetGameTaskTargetByIdRequest struct {
@@ -103,7 +108,7 @@ type UpdateGameTaskTargetRequest struct {
 	IsUploadXjf          int        `json:"is_upload_xjf"`
 
 	//添加字段
-	Aupr        int `json:"aupr"`
+	Aupr        int     `json:"aupr"`
 	TotalAmount float64 `json:"total_amount"`
 }
 
@@ -122,3 +127,7 @@ type GameListRequest struct {
 	Date       string `json:"date"`
 	GamePortId int    `json:"game_port_id"`
 }
+
+type GetTemporaryTaskRequest struct {
+	PcCode string `json:"pc_code"`
+}

+ 14 - 0
model/task/request/search_central_control_conf_params.go

@@ -0,0 +1,14 @@
+package request
+
+import (
+	"log-server/model/common/request"
+	"log-server/model/task"
+)
+
+type SearchCentralControlConfParams struct {
+	task.CentralControlConf
+	request.PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}
+

+ 13 - 0
model/task/request/search_urgent_task_params.go

@@ -0,0 +1,13 @@
+package request
+
+import (
+	"log-server/model/common/request"
+	"log-server/model/task"
+)
+
+type SearchUrgentTaskParams struct {
+	task.UrgentTaskConfRequest
+	request.PageInfo
+	OrderKey string `json:"orderKey"`
+	Desc     bool   `json:"desc"`
+}

+ 53 - 25
model/task/response/game_task.go

@@ -1,6 +1,8 @@
 package response
 
-import "time"
+import (
+	"time"
+)
 
 type GetGameTaskListReply struct {
 	TaskId          int    `json:"task_id"`
@@ -23,7 +25,7 @@ type GetGameTaskListReply struct {
 	StopTime        string `json:"stop_time"`
 }
 
-//增加加付费提醒字段
+//增加加付费提醒字段和模拟器类型字段
 type GetGameTaskListUnionReply struct {
 	TaskId          int    `json:"task_id"`
 	TaskName        string `json:"task_name"`
@@ -31,6 +33,7 @@ type GetGameTaskListUnionReply struct {
 	GameName        string `json:"game_name"`
 	Date            string `json:"date"`
 	AddFeeNotice    int    `json:"add_fee_notice"`
+	SimulatorType   int    `json:"simulator_type"`
 	GamePort        string `json:"game_port"`
 	AccountType     string `json:"account_type"`
 	LoginMethod     string `json:"login_method"`
@@ -47,29 +50,29 @@ type GetGameTaskListUnionReply struct {
 }
 
 type GetGameTargetComplete struct {
-	Id                   uint   `json:"id"`
-	TaskId               int    `json:"task_id"`
-	TaskName             string `json:"task_name"`
-	User                 string `json:"user"`
-	LoginMethod          string `json:"login_method"`
-	NewComplete          int    `json:"new_complete"`
-	PayComplete          int    `json:"pay_complete"`
-	RetainedComplete     int    `json:"retained_complete"`
-	NewTarget            int    `json:"new_target"`
-	PayTarget            int    `json:"pay_target"`
-	RetainedTarget       int    `json:"retained_target"`
-	Amount               int    `json:"amount"`
-	CreateDate           string `json:"create_date"`
-	UpdateTime           string `json:"update_time"` // 更新时间
-	GameRate             string `json:"game_rate"`
-	IsComplete           int    `json:"is_complete"`
-	HandNewComplete      int    `json:"hand_new_complete"`
-	HandRetainedComplete int    `json:"hand_retained_complete"`
-	HandPayComplete      int    `json:"hand_pay_complete"`
-	HandAmountTotal      int    `json:"hand_amount_total"`
-	GameIdXmy            string `json:"game_id_xmy"`
-	Aupr                 int    `json:"aupr"`
-	TotalAmount          float64    `json:"total_amount"`
+	Id                   uint    `json:"id"`
+	TaskId               int     `json:"task_id"`
+	TaskName             string  `json:"task_name"`
+	User                 string  `json:"user"`
+	LoginMethod          string  `json:"login_method"`
+	NewComplete          int     `json:"new_complete"`
+	PayComplete          int     `json:"pay_complete"`
+	RetainedComplete     int     `json:"retained_complete"`
+	NewTarget            int     `json:"new_target"`
+	PayTarget            int     `json:"pay_target"`
+	RetainedTarget       int     `json:"retained_target"`
+	Amount               int     `json:"amount"`
+	CreateDate           string  `json:"create_date"`
+	UpdateTime           string  `json:"update_time"` // 更新时间
+	GameRate             string  `json:"game_rate"`
+	IsComplete           int     `json:"is_complete"`
+	HandNewComplete      int     `json:"hand_new_complete"`
+	HandRetainedComplete int     `json:"hand_retained_complete"`
+	HandPayComplete      int     `json:"hand_pay_complete"`
+	HandAmountTotal      int     `json:"hand_amount_total"`
+	GameIdXmy            string  `json:"game_id_xmy"`
+	Aupr                 int     `json:"aupr"`
+	TotalAmount          float64 `json:"total_amount"`
 }
 
 type GameTargetStatistics struct {
@@ -122,3 +125,28 @@ type GameStatisticsListReply struct {
 	CreateDate string `json:"create_date"`
 	GameName   string `json:"game_name"`
 }
+
+//小绵羊接口返回数据
+type XmyGameDataReply struct {
+	Data   XmyGameList `json:"data"`
+	Status bool        `json:"status"`
+	Msg    string      `json:"msg"`
+}
+
+//小绵羊数据列表
+type XmyGameList struct {
+	StartDay string            `json:"start_day"`
+	EndDay   string            `json:"end_day"`
+	List     []XmyGameResponse `json:"list"`
+}
+
+//小绵羊数据
+type XmyGameResponse struct {
+	ActiveUserNum string `json:"active_user_num"`
+	GameId        string `json:"game_id"`
+	Date          string `json:"date"`
+	UserNum       string `json:"user_num"`
+	Amount        string `json:"amount"` //付费金额
+	Cnt           string `json:"cnt"`
+	Name          string `json:"name"`
+}

+ 3 - 3
model/task/response/upload_file.go

@@ -16,6 +16,6 @@ type InfoResponse struct {
 	File UploadFileResponse `json:"file"`
 }
 
-type DownloadInfoResponse struct {
-	Info DownloadFile `json:"info"`
-}
+//type DownloadInfoResponse struct {
+//	Info DownloadFile `json:"info"`
+//}

+ 1 - 1
model/task/search_script_params.go

@@ -3,7 +3,7 @@ package task
 import "log-server/model/common/request"
 
 // script分页条件查询及排序结构体
-type SearchAccountTypeParams struct {
+type SearchGameScriptParams struct {
 	GameScriptResponse
 	request.PageInfo
 	OrderKey string `json:"orderKey"` // 排序

+ 5 - 4
model/task/task_conf.go

@@ -5,10 +5,11 @@ import (
 )
 
 type TaskConf struct {
-	Id           int    `json:"id"`
-	TaskId       int    `json:"task_id"`
-	User         string `json:"user"`
-	AddFeeNotice int    `json:"add_fee_notice"`
+	Id            int    `json:"id"`
+	TaskId        int    `json:"task_id"`
+	User          string `json:"user"`
+	AddFeeNotice  int    `json:"add_fee_notice"`
+	SimulatorType int    `json:"simulator_type"`
 }
 
 func (TaskConf) TableName() string {

+ 40 - 0
model/task/urgent_task_conf.go

@@ -0,0 +1,40 @@
+package task
+
+import "log-server/model/typeManage"
+
+type UrgentTaskConf struct {
+	Id         int                  `json:"id"`
+	TaskId     int                  `json:"task_id"`     //任务id
+	PcCode     string               `json:"pc_code"`     //电脑编号
+	CreateDate string               `json:"create_date"` //创建日期
+	CreateTime typeManage.LocalTime `json:"create_time"`
+	UpdateTime typeManage.LocalTime `json:"update_time"`
+}
+
+type CreateAndUpdateUrgentTaskConf struct {
+	Id         int                  `json:"id"`
+	TaskId     int                  `json:"task_id"`     //任务id
+	PcCode     []string             `json:"pc_code"`     //电脑编号
+	CreateDate string               `json:"create_date"` //创建日期
+	CreateTime typeManage.LocalTime `json:"create_time"`
+	UpdateTime typeManage.LocalTime `json:"update_time"`
+}
+
+//紧急任务请求
+type UrgentTaskConfRequest struct {
+	Id         int                  `json:"id"`
+	TaskId     int                  `json:"task_id"` //任务id
+	Date       []string             `json:"date"`
+	PcCode     string               `json:"pc_code"`     //电脑编号
+	CreateDate string               `json:"create_date"` //创建日期
+	CreateTime typeManage.LocalTime `json:"create_time"`
+	UpdateTime typeManage.LocalTime `json:"update_time"`
+}
+
+type UnusedPc struct {
+	PcCode string `json:"pc_code"`
+}
+
+func (UrgentTaskConf) TableName() string {
+	return "urgent_task_conf"
+}

+ 2 - 0
router/enter.go

@@ -20,6 +20,8 @@ type RouterGroup struct {
 	TypeManage     typeManage.RouterGroup
 	Task           task.GameTaskRouter
 	UploadFile     task.UploadFileRouter
+	CentralControl task.CentralControlRouter
+	UrgentTask     task.UrgentTaskRouter
 	RentComputer   rentComputer.RouterGroup
 	DataStatistics dataStatistics.RouterGroup
 	FileManager    fileManager.RouterGroup

+ 1 - 0
router/log/log_ip.go

@@ -16,6 +16,7 @@ func (e *IpLogRouter) InitIpLogRouter(Router *gin.RouterGroup) {
 		ipLogRouter.POST("getIpLogList", logApi.GetIpLogList)	//获取ip日志列表
 		ipLogRouter.POST("getIp", logApi.GetIp)	//获取ip
 		ipLogRouter.POST("getGameIpList", logApi.GetGameIPList)	//获取ip日志列表
+		ipLogRouter.POST("getAbnormalIpLogList", logApi.GetAbnormalIpLogList)	//获取异常租机ip列表
 		ipLogRouter.POST("getGameIp", logApi.GetGameIp)	//获取游戏ip
 		ipLogRouter.POST("gameIpExport", logApi.GameIpExport)	//导出游戏ip列表
 	}

+ 5 - 1
router/log/loging.go

@@ -28,6 +28,10 @@ func (e *LogingRouter) InitLogingRouter(Router *gin.RouterGroup) {
 		excelRouter.POST("getLogScanningList", logApi.GetLogScanningList)
 		excelRouter.POST("computerRateExport", logApi.ComputerRateExport)
 		excelRouter.POST("computerSevenRate", logApi.ComputerSevenRate)
-
+		excelRouter.POST("getDeviceStatistics", logApi.GetDeviceStatistics)
+		excelRouter.POST("getDeviceInfoLog", logApi.GetDeviceInfoLog)
+		excelRouter.POST("getErrDeviceLog", logApi.GetErrDeviceLog)
+		excelRouter.POST("getDeviceIdErr", logApi.GetDeviceIdErr)
+		excelRouter.POST("deviceErrRateExcel", logApi.DeviceErrRateExcel)
 	}
 }

+ 29 - 0
router/task/central_control_conf.go

@@ -0,0 +1,29 @@
+package task
+
+import (
+"github.com/gin-gonic/gin"
+v1 "log-server/api/v1"
+	"log-server/middleware"
+)
+
+type CentralControlRouter struct {
+
+}
+
+func (r *CentralControlRouter) InitCentralControlRouter(Router *gin.RouterGroup) {
+	GameTaskRouter := Router.Group("gameTask")
+	centralControlConfApi := v1.ApiGroupApp.GroupTask.CentralControlApi
+	{
+		GameTaskRouter.POST("getCentralControlConfList", centralControlConfApi.GetCentralControlConfList)  //获取配置列表
+		GameTaskRouter.POST("getCentralControlConfById", centralControlConfApi.GetCentralControlConfById)  //通过id获取单个配置
+
+	}
+
+	centralControlConfApi1 := Router.Group("gameTask").Use(middleware.OperationRecord())
+	{
+		centralControlConfApi1.POST("createCentralControlConf", centralControlConfApi.CreateCentralControlConf)   //创建中控配置
+		centralControlConfApi1.POST("deleteCentralControlConf", centralControlConfApi.DeleteCentralControlConf)   //单个删除中控配置
+		centralControlConfApi1.DELETE("deleteCentralControlConfByIds", centralControlConfApi.DeleteCentralControlConfByIds)   //批量删除中控配置
+		centralControlConfApi1.POST("updateCentralControlConf", centralControlConfApi.UpdateCentralControlConf)   //更新中控配置
+	}
+}

+ 3 - 2
router/task/game_task.go

@@ -14,7 +14,7 @@ func (e *GameTaskRouter) InitGameTaskRouter(Router *gin.RouterGroup) {
 	GameTaskApi := v1.ApiGroupApp.GroupTask.GameTaskApi
 	{
 		GameTaskRouter.POST("getGameTaskList", GameTaskApi.GetGameTaskList)
-		GameTaskRouter.POST("getUsedGameTaskList", GameTaskApi.GetUsedGameTaskList)		//获取启用状态的任务
+		GameTaskRouter.POST("getUsedGameTaskList", GameTaskApi.GetUsedGameTaskList) //获取启用状态的任务
 		GameTaskRouter.POST("getGameTaskById", GameTaskApi.GetGameTaskById)
 		GameTaskRouter.POST("getGameTaskTargetList", GameTaskApi.GetGameTaskTargetList)
 		GameTaskRouter.POST("getGameTaskTargetById", GameTaskApi.GetGameTaskTargetById)
@@ -26,7 +26,8 @@ func (e *GameTaskRouter) InitGameTaskRouter(Router *gin.RouterGroup) {
 		GameTaskRouter.POST("getGameTxTaskList", GameTaskApi.GetGameTxTaskList)
 		GameTaskRouter.POST("getFeeAccountList", GameTaskApi.GetFeeAccountList)
 		GameTaskRouter.POST("taskTargetExport", GameTaskApi.TaskTargetExport)
-
+		GameTaskRouter.POST("getXmyTaskList", GameTaskApi.GetXmyTaskList) //获取小绵羊任务列表
+		GameTaskRouter.POST("temporaryTask", GameTaskApi.TemporaryTask)
 	}
 	GameTaskRouter1 := Router.Group("gameTask").Use(middleware.OperationRecord())
 	{

+ 29 - 0
router/task/urgent_task_conf.go

@@ -0,0 +1,29 @@
+package task
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "log-server/api/v1"
+	"log-server/middleware"
+)
+
+type UrgentTaskRouter struct {
+}
+
+func (r *UrgentTaskRouter) InitUrgentTaskRouter(Router *gin.RouterGroup) {
+	GameTaskRouter := Router.Group("gameTask")
+	urgentTaskApi := v1.ApiGroupApp.GroupTask.UrgentTaskApi
+	{
+		GameTaskRouter.POST("getUrgentTaskList", urgentTaskApi.GetUrgentTaskList) //获取紧急任务列表
+		GameTaskRouter.POST("getUrgentTaskById", urgentTaskApi.GetUrgentTaskById) //通过id单个获取紧急任务
+		GameTaskRouter.POST("getUnusedPc", urgentTaskApi.GetUnusedPc)             //获取空闲租机列表
+
+	}
+
+	urgentTaskApi1 := Router.Group("gameTask").Use(middleware.OperationRecord())
+	{
+		urgentTaskApi1.POST("createUrgentTask", urgentTaskApi.CreateUrgentTask)             //创建紧急任务
+		urgentTaskApi1.POST("deleteUrgentTask", urgentTaskApi.DeleteUrgentTask)             //单个删除紧急任务
+		urgentTaskApi1.DELETE("deleteUrgentTaskByIds", urgentTaskApi.DeleteUrgentTaskByIds) //批量删除紧急任务
+		urgentTaskApi1.POST("updateUrgentTask", urgentTaskApi.UpdateUrgentTask)             //更新紧急任务
+	}
+}

+ 4 - 0
service/cache/cache.go

@@ -7,6 +7,10 @@ import (
 	"time"
 )
 
+const (
+	TemporaryTaskPcCode = "%s:temporaryTaskPcCode:%s"
+)
+
 type Cache struct {
 }
 

+ 15 - 7
service/card/id_card.go

@@ -6,6 +6,7 @@ import (
 	"log-server/model/card"
 	cardReq "log-server/model/card/request"
 	"math/rand"
+	"strconv"
 	"time"
 )
 
@@ -22,8 +23,6 @@ func (s *IdCardService) GetIdCard(idCard cardReq.IdCardRequest) (list []card.IdC
 	//取一个0-1000的随机数作为偏移值
 	//将时间戳设置成种子数
 	rand.Seed(time.Now().UnixNano())
-	//生成10个0-99之间的随机数
-	randomOffset := rand.Intn(1000)
 	limit := idCard.Rows
 	//联合查询符合条件的身份证信息
 	//查找channel != channel 的表单信息
@@ -31,12 +30,21 @@ func (s *IdCardService) GetIdCard(idCard cardReq.IdCardRequest) (list []card.IdC
 	db = db.Select("a.id, id_name, a.id_number, flag, IFNULL(use_count, 0) as use_count, b.id as usage_id, channel")
 	db = db.Joins("left JOIN shuyou_id_card_usage as b on b.id_idCard = a.id")
 	db.Count(&total)
-	db = db.Order("use_count").Limit(limit).Offset(randomOffset)
-	err = db.Find(&unionIdCardList).Error
-	if err != nil {
-		return nil, err
+
+	if total > 0 {
+		//将total转化为int
+		strInt64 := strconv.FormatInt(total, 10)
+		countInt, _ := strconv.Atoi(strInt64)
+		//生成1个0-total之间的随机数
+		randomOffset := rand.Intn(countInt)
+
+		db = db.Order("use_count").Limit(limit).Offset(randomOffset)
+		err = db.Find(&unionIdCardList).Error
+		if err != nil {
+			return nil, err
+		}
+		fmt.Println(unionIdCardList)
 	}
-	fmt.Println(unionIdCardList)
 	//没有非这个渠道的记录
 	if total == 0 {
 		dbFail := global.GVA_DB.Table("shuyou_id_card as a")

+ 4 - 0
service/log/deviceInfo.go

@@ -0,0 +1,4 @@
+package log
+
+type DeviceInfo struct {
+}

+ 261 - 34
service/log/log_ip.go

@@ -1,9 +1,11 @@
 package log
 
 import (
+	"errors"
 	"fmt"
 	"github.com/xuri/excelize/v2"
 	"go.uber.org/zap"
+	"gorm.io/gorm"
 	"log-server/global"
 	"log-server/model/log"
 	"log-server/model/log/request"
@@ -78,45 +80,146 @@ func (s *ServiceIpLog) GetIpLogList(api log.IpLogRequest, info request.PageInfo,
 	return apiList, total, err
 }
 
+//获取异常租机ip列表
+func (s *ServiceIpLog) GetAbnormalIpLogList(api log.AbnormalIpLogRequest, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	db := global.GVA_DB.Model(&log.AbnormalMachineIp{})
+	var apiList []log.AbnormalMachineIp
+	startDate := time.Now().Format("2006-01-02")
+	endDate := time.Now().Format("2006-01-02")
+	if len(api.Date) == 2 {
+		startDate = api.Date[0]
+		endDate = api.Date[1]
+	}
+	db = db.Select("abnormal_machine_ip.*, game_task.task_name, game_task.user")
+	db = db.Joins("left join game_task on game_task.task_id = abnormal_machine_ip.game_id")
+	db = db.Where("create_date >= ? and create_date <= ?", startDate, endDate)
+	if api.GameId != 0 {
+		db = db.Where("game_id = ?", api.GameId)
+	}
+	if api.PcCode != "" {
+		db = db.Where("pc_code = ?", api.PcCode)
+	}
+	if api.Ip != "" {
+		db = db.Where("ip = ?", api.Ip)
+	}
+
+	err = db.Count(&total).Error
+	if err != nil {
+		return apiList, total, err
+	} else {
+		db = db.Limit(limit).Offset(offset)
+		if order != "" {
+			var OrderStr string
+			// 设置有效排序key 防止sql注入
+			// 感谢 Tom4t0 提交漏洞信息
+			orderMap := make(map[string]bool, 5)
+			orderMap["game_id"] = true
+			orderMap["count"] = true
+			orderMap["create_date"] = true
+			orderMap["user"] = true
+			orderMap["task_name"] = true
+			if orderMap[order] {
+				if desc {
+					OrderStr = order + " desc"
+				} else {
+					OrderStr = order
+				}
+			} else { // didn't matched any order key in `orderMap`
+				global.GVA_LOG.Error("获取失败!", zap.Error(err))
+				return apiList, total, err
+			}
+
+			err = db.Order(OrderStr).Find(&apiList).Error
+		} else {
+			err = db.Order("id desc").Find(&apiList).Error
+		}
+	}
+	//遍历更改日期格式
+	for i, _ := range apiList {
+		apiList[i].CreateDate = apiList[i].CreateDate[:10]
+	}
+	return apiList, total, err
+}
+
+//获取今日异常租机ip(ip播报使用)
+func (s *ServiceIpLog) GetTodayAbnormalIpLogList() (list map[string]string, err error) {
+	var total int64
+	var apiList []log.TodayAbnormalMachineIp
+	pcCodeList := make(map[string]string)
+	usePcCode := make(map[string]string)
+	date := time.Now().Format("2006-01-02")
+	//1个半小时前的时间
+	effectiveTime := time.Now().Add(-time.Minute * 90).Format("2006-01-02 15:04:05")
+
+	db := global.GVA_DB.Table("abnormal_machine_ip as ami")
+	db = db.Select("ami.*, gt.task_name, gt.user")
+	db = db.Joins("left join game_task as gt on gt.task_id = ami.game_id")
+	db = db.Where("create_date", date)
+	err = db.Count(&total).Error
+	if total == 0 {
+		return usePcCode, err
+	}
+	if err != nil {
+		return usePcCode, err
+	} else {
+		err = db.Order("id").Find(&apiList).Error
+	}
+	//遍历更改日期格式
+	for i, _ := range apiList {
+		apiList[i].CreateDate = apiList[i].CreateDate[:10]
+		//得到{编号【负责人名称类似结构】}
+		pcCodeList[apiList[i].PcCode] = apiList[i].User
+	}
+
+	//遍历列表中的租机,查询数据库(租机编号,和本日时间),得到记录集合,通过ip作为map的key,判断是否需要播报
+	//遍历租机编号列表
+	for k, _ := range pcCodeList {
+		var ipList []log.IpLogBroadcast
+		ipSet := make(map[string]int)
+		db1 := global.GVA_DB.Model(&log.IpLog{}).Select("ip_log.*, game_task.user")
+		db1 = db1.Joins("left join game_task on game_task.task_id = ip_log.game_id")
+		db1.Where("create_date = ? and pc_code = ? and ip_log.create_time > ? ", date, k, effectiveTime).Limit(5).Order("id desc").Find(&ipList)
+		//fmt.Println(ipList)
+		//fmt.Println(len(ipList))
+		//样本太少,不做处理
+		if len(ipList) <= 1 {
+			return usePcCode, err
+		}
+		//遍历ipList,查找
+		for _, v := range ipList {
+			ipSet[v.Ip] = 1
+			//fmt.Println(ipSet)
+			//fmt.Println(len(ipSet))
+		}
+		if len(ipSet) == 1 {
+			usePcCode[ipList[0].PcCode] = ipList[0].User
+		}
+	}
+	return usePcCode, err
+}
+
 //根据gameId获取ip
 func (s *ServiceIpLog) GetGameIpList(api log.GameIpRequest, info request.PageInfo, order string, desc bool) (apiList []log.GameIpResponse, total int64, err error) {
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
-	db := global.GVA_DB.Model(&log.IpLog{})
-
+	db := global.GVA_DB.Model(&log.GameIpResponse{})
 	startDate := time.Now().Format("2006-01-02")
 	endDate := time.Now().Format("2006-01-02")
 	if len(api.Date) == 2 {
 		startDate = api.Date[0]
 		endDate = api.Date[1]
 	}
-
 	//筛选负责人
 	if api.User != "" {
 		db = db.Where("user = ?", api.User)
 	}
-
 	//筛选日期
-	db = db.Where("ip_log.create_date >= ? and ip_log.create_date <= ?", startDate, endDate)
+	db = db.Where("create_date >= ? and create_date <= ?", startDate, endDate)
 	if api.GameId != 0 {
-		db = db.Where("ip_log.game_id = ?", api.GameId)
-		//查找总ip上报次数
-		db = db.Joins("left join" + "(select count(*) as count, game_id, create_date from ip_log where game_id = ? and create_date >= ? and create_date <= ? group by game_id, create_date)" + " as late on late.game_id = ip_log.game_id and late.create_date = ip_log.create_date", api.GameId, startDate, endDate)
-	} else {
-		//查找总ip上报次数
-		db = db.Joins("left join" + "(select count(*) as count, game_id, create_date from ip_log where create_date >= ? and create_date <= ? group by game_id, create_date)" + " as late on late.game_id = ip_log.game_id and late.create_date = ip_log.create_date",  startDate, endDate)
+		db = db.Where("game_id = ?", api.GameId)
 	}
-
-	db = db.Where("ip_log.status = 2")
-
-	db = db.Select("ip_log.create_date,ip_log.game_id,late.count as count_total, task_name, user,  count(*) as success_ip , retained_complete as task_count, count(distinct(ip)) as count_distinct_ip")
-	//拼接任务完成表
-	db = db.Joins("left join game_target_complete as gtc on gtc.task_id = ip_log.game_id and gtc.create_date = ip_log.create_date")
-	//拼接game_task表获取任务名称和负责人名称
-	db = db.Joins("left join game_task as gt on gt.task_id = ip_log.game_id")
-	db = db.Group("ip_log.game_id, ip_log.create_date")
-	//db.Select("count(*)").Count(&countTotal)
-	//db.Select("count(distinct(ip))").Count(&countDistinctIp)
 	err = db.Count(&total).Error
 	if err != nil {
 		return apiList, total, err
@@ -126,13 +229,16 @@ func (s *ServiceIpLog) GetGameIpList(api log.GameIpRequest, info request.PageInf
 			var OrderStr string
 			// 设置有效排序key 防止sql注入
 			// 感谢 Tom4t0 提交漏洞信息
-			orderMap := make(map[string]bool, 5)
+			orderMap := make(map[string]bool, 8)
 			//orderMap["game_id"] = true
 			orderMap["count_distinct_ip"] = true
 			orderMap["count_total"] = true
 			orderMap["success_ip"] = true
 			orderMap["task_count"] = true
 			orderMap["create_date"] = true
+			orderMap["exceed_three"] = true
+			orderMap["ip_repetition_rate"] = true
+			orderMap["average_ip_repetition_rate"] = true
 			if orderMap[order] {
 				if desc {
 					OrderStr = order + " desc"
@@ -146,25 +252,26 @@ func (s *ServiceIpLog) GetGameIpList(api log.GameIpRequest, info request.PageInf
 
 			err = db.Order(OrderStr).Find(&apiList).Error
 		} else {
-			err = db.Order("ip_log.id").Find(&apiList).Error
+			err = db.Order("id").Find(&apiList).Error
 		}
 	}
 	//遍历更改日期格式
 	for i, _ := range apiList {
 		apiList[i].CreateDate = apiList[i].CreateDate[:10]
-		err = global.GVA_DB.Model(&log.IpLog{}).Select("COUNT(1) as max_count").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Order("max_count desc").Limit(1).Find(&apiList[i]).Error
-		global.GVA_DB.Model(&log.IpLog{}).Select("id,ip,count(*) ").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Having("count(*) > 4").Count(&apiList[i].ExceedThree)
-		//获取平均重复率和ip重复率 并保留小数点后两位
-		countDistinctIp := float64(apiList[i].CountDistinctIp)
-		successIp := float64(apiList[i].SuccessIp)
-		taskCount := float64(apiList[i].TaskCount)
-		apiList[i].IpRepetitionRate, _ =  strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp/ successIp) *100), 64)
-		apiList[i].AverageIpRepetitionRate, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp / taskCount) *100), 64)
+		//err = global.GVA_DB.Model(&log.IpLog{}).Select("COUNT(1) as max_count").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Order("max_count desc").Limit(1).Find(&apiList[i]).Error
+		//global.GVA_DB.Model(&log.IpLog{}).Select("id,ip,count(*) ").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Having("count(*) > 4").Count(&apiList[i].ExceedThree)
+		////获取平均重复率和ip重复率 并保留小数点后两位
+		//countDistinctIp := float64(apiList[i].CountDistinctIp)
+		//successIp := float64(apiList[i].SuccessIp)
+		//taskCount := float64(apiList[i].TaskCount)
+		//apiList[i].IpRepetitionRate, _ =  strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp/ successIp) *100), 64)
+		//if taskCount != 0 {
+		//	apiList[i].AverageIpRepetitionRate, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp / taskCount) *100), 64)
+		//}
 	}
 	return apiList, total, err
 }
 
-
 //展示ip
 func (s *ServiceIpLog) GetIp(iplog log.IpLogResponse) (list interface{}, total int64, err error) {
 	var ipList []log.QueryIpList
@@ -218,4 +325,124 @@ func (s *ServiceIpLog) GameIpListExcel(infoList []log.GameIpResponse, filePath s
 	}
 	err := excel.SaveAs(filePath)
 	return err
-}
+}
+
+//获取异常ip数据
+func (s *ServiceIpLog) GetAbnormalIp() (list map[string]string, err error) {
+	db := global.GVA_DB.Model(&log.GameIpResponse{})
+	date := time.Now().Format("2006-01-02")
+	var apiList []log.GameIpResponse
+	//筛选日期
+	db = db.Where("create_date = ?", date)
+	err = db.Order("id").Find(&apiList).Error
+	var abnormalIpList = map[string]string{}
+	//遍历更改日期格式
+	for i, _ := range apiList {
+		//apiList[i].CreateDate = apiList[i].CreateDate[:10]
+		if apiList[i].IpRepetitionRate < 30 && apiList[i].CountTotal > 10 {
+			abnormalIpList[apiList[i].User] = apiList[i].TaskName
+		}
+	}
+	return abnormalIpList, err
+}
+
+//更新租机异常ip数据
+func (s *ServiceIpLog) UpdateAbnormalMachineIp() (err error) {
+	//首先获取今天的时间
+	var abnormalIpList []log.AbnormalMachineIp
+	date := time.Now().Format("2006-01-02")
+	//然后查找租机异常ip记录,并且添加至数据库中
+	db := global.GVA_DB.Table("ip_log").Select("ip, create_date, game_id, pc_code, count(ip) as count")
+	db = db.Where("create_date", date)
+	db = db.Group("pc_code, ip, game_id")
+	err = db.Find(&abnormalIpList).Error
+	//fmt.Println(abnormalIpList)
+	if err != nil {
+		return err
+	}
+	//将异常ip存储至abnormal_machine_ip数据库中
+	for i, _ := range abnormalIpList {
+		var entity log.AbnormalMachineIp
+		ip := abnormalIpList[i].Ip
+		gameId := abnormalIpList[i].GameId
+		pcCode := abnormalIpList[i].PcCode
+		createDate := abnormalIpList[i].CreateDate[:10]
+		count := abnormalIpList[i].Count
+
+		//根据count判断,如果count < 9, continue继续做下一条记录的处理
+		if count < 6 {
+			continue
+		}
+
+		if !errors.Is(global.GVA_DB.Model(&log.AbnormalMachineIp{}).Where("ip = ? and game_id = ? and pc_code = ? and create_date = ?", ip, gameId, pcCode, createDate).First(&entity).Error, gorm.ErrRecordNotFound) {
+			//存在相同的ip、租机、gameid、创建日期记录,那么更新数量即可
+			err = global.GVA_DB.Model(&log.AbnormalMachineIp{}).Where("ip = ? and game_id = ? and pc_code = ? and create_date = ?", ip, gameId, pcCode, createDate).Update("count", count).Error
+			if err != nil {
+				return errors.New("更新ip数量失败")
+			}
+			continue
+		}
+		//如果数据库中没有相同的记录,则创建相对应的记录
+		err = global.GVA_DB.Model(&log.AbnormalMachineIp{}).Omit("user", "task_name").Create(&abnormalIpList[i]).Error
+		if err != nil {
+			return err
+		}
+	}
+	return err
+}
+
+//定时更新ip列表数据
+func (s *ServiceIpLog) UpdateGameIpList() (err error) {
+	var total int64
+	var apiList []log.GameIpResponse
+	db := global.GVA_DB.Model(&log.IpLog{})
+	date := time.Now().Format("2006-01-02")
+	//筛选日期
+	db = db.Where("ip_log.create_date = ?", date)
+	//查找总ip上报次数
+	db = db.Joins("left join"+"(select count(*) as count, game_id, create_date from ip_log where create_date = ? group by game_id, create_date)"+" as late on late.game_id = ip_log.game_id and late.create_date = ip_log.create_date", date)
+
+	db = db.Where("ip_log.status = 2")
+
+	db = db.Select("ip_log.create_date,ip_log.game_id,late.count as count_total, task_name, user,  count(*) as success_ip , retained_complete as task_count, count(distinct(ip)) as count_distinct_ip")
+	//拼接任务完成表
+	db = db.Joins("left join game_target_complete as gtc on gtc.task_id = ip_log.game_id and gtc.create_date = ip_log.create_date")
+	//拼接game_task表获取任务名称和负责人名称
+	db = db.Joins("left join game_task as gt on gt.task_id = ip_log.game_id")
+	db = db.Group("ip_log.game_id, ip_log.create_date")
+	err = db.Count(&total).Error
+	if err != nil {
+		return err
+	}
+	err = db.Order("ip_log.id").Find(&apiList).Error
+	//遍历更改日期格式
+	for i, _ := range apiList {
+		var entity log.GameIpResponse
+		apiList[i].CreateDate = apiList[i].CreateDate[:10]
+		err = global.GVA_DB.Model(&log.IpLog{}).Select("COUNT(1) as max_count").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Order("max_count desc").Limit(1).Find(&apiList[i]).Error
+		global.GVA_DB.Model(&log.IpLog{}).Select("id,ip,count(*) ").Where("game_id = ? and create_date = ? and status = 2", apiList[i].GameId, apiList[i].CreateDate).Group("ip").Having("count(*) > 4").Count(&apiList[i].ExceedThree)
+		//获取平均重复率和ip重复率 并保留小数点后两位
+		countDistinctIp := float64(apiList[i].CountDistinctIp)
+		successIp := float64(apiList[i].SuccessIp)
+		taskCount := float64(apiList[i].TaskCount)
+		apiList[i].IpRepetitionRate, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp/successIp)*100), 64)
+		if taskCount != 0 {
+			apiList[i].AverageIpRepetitionRate, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (countDistinctIp/taskCount)*100), 64)
+		}
+		//查找数据库中是否有这条记录(game_id, create_date)
+		if !errors.Is(global.GVA_DB.Model(&log.GameIpResponse{}).Where("game_id = ? and create_date = ?", apiList[i].GameId, apiList[i].CreateDate).First(&entity).Error, gorm.ErrRecordNotFound) {
+			//如果有,更新
+			err = global.GVA_DB.Model(&log.GameIpResponse{}).Where("game_id = ? and create_date = ?", apiList[i].GameId, apiList[i].CreateDate).Save(&apiList[i]).Error
+			if err != nil {
+				return errors.New("更新ip列表失败")
+			}
+			continue
+		}
+		//如果数据库中没有相同的记录,则创建相对应的记录
+		err = global.GVA_DB.Model(&log.GameIpResponse{}).Create(&apiList[i]).Error
+		if err != nil {
+			return err
+		}
+	}
+	return err
+}

+ 3 - 0
service/log/log_list.go

@@ -147,6 +147,9 @@ func (s *ServiceLogList) CreateLog(c context.Context, request request.AddLogRequ
 	if request.Coding == 4301001 || request.Coding == 4501001 {
 		return
 	}
+	if request.Err != "" {
+		return
+	}
 	if err != nil {
 		body, _ := json.Marshal(request)
 		current := time.Now().Format("2006-01-02")

+ 349 - 1
service/log/log_statistics.go

@@ -24,7 +24,8 @@ import (
 
 type ServiceStatisticsLog struct {
 	loging2.LogicalLog
-	Person typeManage.ResponsiblePerson
+	Person             typeManage.ResponsiblePerson
+	GameTargetComplete task.GameTargetComplete
 }
 
 var StatisticsCompletedKey = "%s:StatisticsCompleted"
@@ -1361,3 +1362,350 @@ func (s *ServiceStatisticsLog) ComputerSevenStatistics(ctx context.Context, api
 	}
 	return statisticsLogsComputer, total, err
 }
+
+// 定时统计设备信息
+func (s *ServiceStatisticsLog) DeviceStatistics() {
+	date := time.Now().Format("2006-01-02")
+	db := global.GVA_DB.Model(&task.GameTask{})
+	var apiList []task.GameTask
+	db = db.Where("is_del = ?", -1)
+	db = db.Where("status = ?", 1)
+	db.Order("id desc").Find(&apiList)
+	if len(apiList) == 0 {
+		return
+	}
+	retainedDeviceErr := s.DeviceIdStatistics(date, 1)
+	newDeviceErr := s.DeviceIdStatistics(date, 2)
+	undefinedErr := s.DeviceErrLogStatistics(date, 1)
+	DefinedErr := s.DeviceErrLogStatistics(date, 2)
+	completeData, _ := s.GameTargetComplete.CompleteTaskData(date)
+	ctx := context.Background()
+	for _, game := range apiList {
+		deviceLog := new(log.DeviceStatistics)
+		gameId := game.TaskId
+		deviceLog.GameId = gameId
+		gameDeviceAccountErrKey := fmt.Sprintf(loging2.GameDeviceAccountErrKey, date, gameId)
+		gameDeviceErrKey := fmt.Sprintf(loging2.GameDeviceErrKey, date, gameId)
+		deviceLog.AccountErrNum, _ = s.GetCacheNum(ctx, gameDeviceAccountErrKey)
+		deviceLog.DeviceErrNum, _ = s.GetCacheNum(ctx, gameDeviceErrKey)
+		n, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameId, "4300000", loging2.OkStatus, 0)
+		r, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameId, "4300000", loging2.OkStatus, 1)
+		deviceLog.SimulatorStartNum = n + r
+		deviceLog.NewComplete = completeData[gameId].NewComplete
+		deviceLog.RetainedComplete = completeData[gameId].RetainedComplete
+		if deviceLog.DeviceErrNum != 0 {
+			deviceLog.DeviceErrRate = utils.Decimal(float64(deviceLog.DeviceErrNum) / float64(deviceLog.RetainedComplete) * 100)
+		}
+		if deviceLog.AccountErrNum != 0 {
+			deviceLog.AccountErrRate = utils.Decimal(float64(deviceLog.AccountErrNum) / float64(deviceLog.NewComplete) * 100)
+		}
+		deviceLog.CreateDate = date
+		if _, ok := retainedDeviceErr[gameId]; ok {
+			if retainedDeviceErr[gameId].Count != 0 {
+				deviceLog.RetainedDeviceIdErr = retainedDeviceErr[gameId].Count
+				deviceLog.RetainedDeviceIdRate = utils.Decimal(float64(deviceLog.RetainedDeviceIdErr) / float64(deviceLog.RetainedComplete) * 100)
+			}
+		}
+
+		if _, ok := newDeviceErr[gameId]; ok {
+			if newDeviceErr[gameId].Count != 0 {
+				deviceLog.NewDeviceIdErr = newDeviceErr[gameId].Count
+				deviceLog.NewDeviceIdRate = utils.Decimal(float64(deviceLog.NewDeviceIdErr) / float64(deviceLog.NewComplete) * 100)
+			}
+		}
+		if _, ok := undefinedErr[gameId]; ok {
+			if undefinedErr[gameId].Count != 0 {
+				deviceLog.UndefinedErr = undefinedErr[gameId].Count
+			}
+		}
+		if _, ok := DefinedErr[gameId]; ok {
+			if DefinedErr[gameId].Count != 0 {
+				deviceLog.DefinedErr = DefinedErr[gameId].Count
+			}
+		}
+
+		if !errors.Is(global.GVA_DB.Where("create_date = ?", date).Where("game_id = ?", gameId).First(&log.DeviceStatistics{}).Error, gorm.ErrRecordNotFound) {
+			global.GVA_DB.Where("create_date = ?", date).Where("game_id = ?", gameId).Omit("create_date,game_id").Updates(&deviceLog)
+			continue
+		}
+		global.GVA_DB.Create(&deviceLog)
+	}
+}
+
+type DeviceErr struct {
+	GameId int `json:"game_id"`
+	Count  int `json:"count"`
+}
+
+func (s *ServiceStatisticsLog) DeviceIdStatistics(date string, status int) map[int]DeviceErr {
+	var devicesErr []DeviceErr
+	db := global.GVA_DB.Model(&log.ScriptDeviceErr{})
+	db.Where("create_date = ?", date)
+	db.Where("status = ?", status)
+	db.Group("current_game_id")
+	db.Select("current_game_id game_id, count(*) count")
+	db.Find(&devicesErr)
+	if len(devicesErr) == 0 {
+		return nil
+	}
+	devicesErrMaps := make(map[int]DeviceErr, len(devicesErr))
+	for _, game := range devicesErr {
+		devicesErrMaps[game.GameId] = game
+	}
+	return devicesErrMaps
+}
+
+func (s *ServiceStatisticsLog) DeviceErrLogStatistics(date string, status int) map[int]DeviceErr {
+	var devicesErr []DeviceErr
+	db := global.GVA_DB.Model(&log.DeviceErrLog{})
+	db.Where("create_date = ?", date)
+	db.Where("status = ?", status)
+	db.Group("game_id")
+	db.Select("game_id, count(*) count")
+	db.Find(&devicesErr)
+	if len(devicesErr) == 0 {
+		return nil
+	}
+	devicesErrMaps := make(map[int]DeviceErr, len(devicesErr))
+	for _, game := range devicesErr {
+		devicesErrMaps[game.GameId] = game
+	}
+	return devicesErrMaps
+}
+
+func (exa *ServiceStatisticsLog) DeviceErrRateExcel(statistics []*log.DeviceStatisticsReply, filePath string) error {
+	excel := excelize.NewFile()
+	excel.SetSheetRow("Sheet1", "A1", &[]string{"游戏ID", "负责人", "留存设备异常", "留存设备id异常", "留存完成目标", "留存异常率", "留存设备id异常率", "新增设备异常", "新增设备id异常", "新增完成目标", "新增异常率", "新增设备id异常率", "统计日期"})
+	for i, statisticsLog := range statistics {
+		axis := fmt.Sprintf("A%d", i+2)
+		excel.SetSheetRow("Sheet1", axis, &[]interface{}{
+			statisticsLog.GameId,
+			statisticsLog.User,
+			statisticsLog.DeviceErrNum,
+			statisticsLog.RetainedDeviceIdErr,
+			statisticsLog.RetainedComplete,
+			statisticsLog.DeviceErrRate,
+			statisticsLog.RetainedDeviceIdRate,
+			statisticsLog.AccountErrNum,
+			statisticsLog.NewDeviceIdErr,
+			statisticsLog.NewComplete,
+			statisticsLog.AccountErrRate,
+			statisticsLog.NewDeviceIdRate,
+			statisticsLog.CreateDate[:10],
+		})
+	}
+	err := excel.SaveAs(filePath)
+	return err
+}
+
+func (s *ServiceStatisticsLog) GetDeviceStatistics(ctx context.Context, api log.DeviceStatisticsReply, info request.PageInfo, order string, desc bool) (statistics []*log.DeviceStatisticsReply, total int64, err error) {
+	if api.CreateDate == "" {
+		api.CreateDate = time.Now().Format("2006-01-02")
+	}
+	db := global.GVA_DB.Table("device_statistics ds")
+
+	db = db.Joins("left join game_task gt on gt.task_id = ds.game_id")
+	db = db.Where("ds.create_date = ?", api.CreateDate)
+	if api.GameId != 0 {
+		db = db.Where("ds.game_id = ?", api.GameId)
+	}
+	if api.User != "" {
+		db = db.Where("gt.user = ?", api.User)
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return nil, 0, err
+	}
+	db = db.Select("ds.*,user")
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	db = db.Limit(limit).Offset(offset)
+	if order != "" {
+		var OrderStr string
+		orderMap := make(map[string]bool, 7)
+		orderMap["device_err_num"] = true
+		orderMap["game_id"] = true
+		orderMap["account_err_num"] = true
+		orderMap["device_err_rate"] = true
+		orderMap["account_err_rate"] = true
+		orderMap["retained_device_id_rate"] = true
+		orderMap["new_device_id_rate"] = true
+		if orderMap[order] {
+			if desc {
+				OrderStr = "ds." + order + " desc"
+			} else {
+				OrderStr = "ds." + order
+			}
+		} else { // didn't matched any order key in `orderMap`
+			global.GVA_LOG.Error("获取失败!", zap.Error(err))
+			return statistics, total, err
+		}
+		err = db.Order(OrderStr).Find(&statistics).Error
+	} else {
+		err = db.Order("id").Find(&statistics).Error
+	}
+	for _, statistic := range statistics {
+		statistic.CreateDate = api.CreateDate
+	}
+	return
+}
+
+func (s *ServiceStatisticsLog) GetDeviceInfo(ctx context.Context, api log.DeviceLog, info request.PageInfo, order string, desc bool) (deviceLogs []*log.DeviceLog, total int64, err error) {
+	if api.CreateDate == "" {
+		api.CreateDate = time.Now().Format("2006-01-02")
+	}
+	db := global.GVA_DB.Model(&log.DeviceLog{})
+	if api.GameId != 0 {
+		db = db.Where("game_id = ?", api.GameId)
+	} else {
+		return
+	}
+	db = db.Where("create_date = ?", api.CreateDate)
+	if api.IsErr != 0 {
+		db = db.Where("is_err = ?", api.IsErr)
+	}
+	if api.PcCode != "" {
+		db = db.Where("pc_code = ?", api.PcCode)
+	}
+
+	if api.SimulatorCode != "" {
+		db = db.Where("simulator_code = ?", api.SimulatorCode)
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return nil, 0, err
+	}
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	db = db.Limit(limit).Offset(offset)
+	if order != "" {
+		var OrderStr string
+		// 设置有效排序key 防止sql注入
+		// 感谢 Tom4t0 提交漏洞信息
+		orderMap := make(map[string]bool, 3)
+		orderMap["game_id"] = true
+		if orderMap[order] {
+			if desc {
+				OrderStr = order + " desc"
+			} else {
+				OrderStr = order
+			}
+		} else { // didn't matched any order key in `orderMap`
+			global.GVA_LOG.Error("获取失败!", zap.Error(err))
+			return deviceLogs, total, err
+		}
+		err = db.Order(OrderStr).Find(&deviceLogs).Error
+	} else {
+		err = db.Order("id").Find(&deviceLogs).Error
+	}
+	for _, statistic := range deviceLogs {
+		statistic.CreateDate = api.CreateDate
+	}
+	return
+}
+
+func (s *ServiceStatisticsLog) GetDeviceIdErr(ctx context.Context, api log.ScriptDeviceErr, info request.PageInfo, order string, desc bool) (deviceLogs []*log.ScriptDeviceErr, total int64, err error) {
+	if api.CreateDate == "" {
+		api.CreateDate = time.Now().Format("2006-01-02")
+	}
+	db := global.GVA_DB.Model(&log.ScriptDeviceErr{})
+	if api.GameId != 0 {
+		db = db.Where("current_game_id = ?", api.GameId)
+	}
+	if api.Operator != "" {
+		db = db.Where("operator = ?", api.Operator)
+	}
+	if api.Status != 0 {
+		db = db.Where("status = ?", api.Status)
+	}
+	db = db.Where("create_date = ?", api.CreateDate)
+	err = db.Count(&total).Error
+	if err != nil {
+		return nil, 0, err
+	}
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	db = db.Limit(limit).Offset(offset)
+	if order != "" {
+		var OrderStr string
+		// 设置有效排序key 防止sql注入
+		// 感谢 Tom4t0 提交漏洞信息
+		orderMap := make(map[string]bool, 3)
+		orderMap["game_id"] = true
+		if orderMap[order] {
+			if desc {
+				OrderStr = order + " desc"
+			} else {
+				OrderStr = order
+			}
+		} else { // didn't matched any order key in `orderMap`
+			global.GVA_LOG.Error("获取失败!", zap.Error(err))
+			return deviceLogs, total, err
+		}
+		err = db.Order(OrderStr).Find(&deviceLogs).Error
+	} else {
+		err = db.Order("id").Find(&deviceLogs).Error
+	}
+	for _, statistic := range deviceLogs {
+		statistic.CreateDate = api.CreateDate
+	}
+	return
+}
+
+func (s *ServiceStatisticsLog) GetDeviceContrastInfo(ctx context.Context, api log.DeviceLog) (deviceLogs []log.DeviceLog, err error) {
+	db := global.GVA_DB.Model(&log.DeviceLog{})
+	var device log.DeviceLog
+	err = db.Where("id = ?", api.Id).First(&device).Error
+	if err != nil {
+		return nil, err
+	}
+	if device.ErrStatus == 3 {
+		err = global.GVA_DB.Where("game_id = ?", device.GameId).Where("account = ?", device.Account).Where("id < ?", device.Id).Order("id desc").First(&deviceLogs).Error
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		err = global.GVA_DB.Where("create_date = ?", device.CreateDate).Where("game_id = ?", device.GameId).Where("device_hex = ?", device.DeviceHex).Where("id < ?", device.Id).Order("id desc").Limit(10).Find(&deviceLogs).Error
+	}
+	deviceLogs = append(deviceLogs, device)
+	for _, statistic := range deviceLogs {
+		statistic.CreateDate = api.CreateDate
+	}
+	return
+}
+
+func (s *ServiceStatisticsLog) ComputerUpdateStatus() {
+	var computer log.Computer
+	logComputers, err := computer.OnlinePcCodeCache()
+	if err != nil {
+		global.GVA_LOG.Error("ComputerUpdateStatus LogComputer 获取失败!", zap.Error(err))
+		return
+	}
+	date := s.CurrentDate()
+	ctx := context.Background()
+	for pcCode, _ := range logComputers {
+		// 检测5分钟内电脑是否上报了数据
+		num := s.LogicalLog.CheckPcReportingLog(ctx, pcCode, 60*1000*8)
+		status := -1
+		if num != 0 {
+			status = 1
+		}
+		var computerStatus log.ComputerStatus
+		result := global.GVA_DB.Where("create_date = ?", date).Where("pc_code = ?", pcCode).First(&computerStatus)
+		if result.Error != nil {
+			if result.Error == gorm.ErrRecordNotFound {
+				// 数据不存在,执行创建操作
+				computerStatus.Status = status
+				computerStatus.CreateDate = time.Now()
+				computerStatus.PcCode = pcCode
+				result = global.GVA_DB.Omit("update_time").Create(&computerStatus)
+			} else {
+				// 其他错误
+				global.GVA_LOG.Error("ComputerUpdateStatus computerStatus 获取失败!", zap.Error(err))
+				return
+			}
+		} else {
+			global.GVA_DB.Model(&log.ComputerStatus{}).Where("create_date = ?", date).Where("pc_code = ?", pcCode).Omit("update_time").Update("status", status)
+		}
+	}
+}

+ 1 - 0
service/log/loging/game_start_log.go

@@ -27,6 +27,7 @@ func (s *GameStartLog) SuccessLog(ctx context.Context, request request.AddLogReq
 	} else {
 		_ = s.logical.SetUuidCodeCache(context.Background(), s.logical.CurrentDate(), s.logical.Request.LogUuid, s.logical.Request.Coding, s.logical.Request.GameId)
 	}
+	go s.logical.CheckDeviceId(s.logical.Request)
 	code := strconv.Itoa(request.Coding)
 	err = s.logical.PartTypeLogSetNum(ctx, s.logical.CurrentDate(), s.logical.Request.GameId, code, OkStatus, s.logical.Request.TaskType)
 	if err != nil {

+ 286 - 1
service/log/loging/logical_log.go

@@ -7,9 +7,11 @@ import (
 	"fmt"
 	"github.com/go-redis/redis/v8"
 	"go.uber.org/zap"
+	"gorm.io/gorm"
 	"log-server/global"
 	"log-server/model/log"
 	"log-server/model/log/request"
+	"log-server/model/typeManage"
 	"log-server/service/cache"
 	"log-server/utils"
 	"strconv"
@@ -34,6 +36,9 @@ var (
 	GamePcFeeRateCacheKey       = "%s:gamePc:gameFeeRate:%d:%s"
 	OnLineComputerNum           = "%s:OnLineComputerNum:"
 	PcReportingLog              = "%s:pc:Reporting:%s"
+	GameDeviceErrKey            = "%s:device:%d"
+	GameDeviceAccountErrKey     = "%s:deviceAccount:%d"
+	GameDeviceUuidKey           = "%s:GameDeviceUuid:%s"
 )
 
 type LogicalLog struct {
@@ -41,6 +46,7 @@ type LogicalLog struct {
 	Request    request.AddLogRequest
 	cache      cache.Cache
 	ScriptType int
+	Person     typeManage.ResponsiblePerson
 }
 
 func (s *LogicalLog) CurrentDate() (current string) {
@@ -764,7 +770,31 @@ func (s *LogicalLog) GetPcReportingLog(ctx context.Context, pcCode string) (num
 		return
 	}
 	end := time.Now().UnixNano()/1e6 + 60*1000*2
-	start := end - (60*60*1000 + 60*1000)
+	start := end - (60*60*1000 + 60*1000*4)
+	op := redis.ZRangeBy{
+		Min: strconv.Itoa(int(start)),
+		Max: strconv.Itoa(int(end)),
+	}
+	i, err := global.GVA_REDIS.ZRangeByScore(ctx, key, &op).Result()
+	if err != nil {
+		return
+	}
+	num = len(i)
+	return
+}
+
+// 获取电脑上报的次数
+func (s *LogicalLog) CheckPcReportingLog(ctx context.Context, pcCode string, timeInterval int64) (num int) {
+	key := fmt.Sprintf(PcReportingLog, s.CurrentDate(), pcCode)
+	z, err := global.GVA_REDIS.ZRangeWithScores(ctx, key, -1, -1).Result()
+	if err != nil {
+		return
+	}
+	if len(z) == 0 {
+		return
+	}
+	end := time.Now().UnixNano()/1e6 + 60*1000*2
+	start := end - timeInterval
 	op := redis.ZRangeBy{
 		Min: strconv.Itoa(int(start)),
 		Max: strconv.Itoa(int(end)),
@@ -886,3 +916,258 @@ func (s *LogicalLog) UpdateIpLogStatus(logUuid string, createDate string) {
 		global.GVA_LOG.Error("create LogScanningCode fail", zap.Error(err))
 	}
 }
+
+// 记录设备信息
+func (s *LogicalLog) AddDeviceLog(request request.AddLogRequest) {
+
+	logSC := new(log.DeviceLog)
+	logSC.GameId = request.GameId
+	logSC.LogUuid = request.LogUuid
+	logSC.Account = request.Account
+	logSC.DeviceId = request.DeviceId
+	logSC.DeviceImei = request.DeviceImei
+	logSC.DeviceIp = request.SimulatorIp
+	logSC.DeviceMac = request.DeviceMac
+	logSC.DeviceManufacturer = request.DeviceManufacturer
+	logSC.DeviceModel = request.DeviceModel
+	logSC.DeviceSdk = request.DeviceSdk
+	logSC.DeviceNumber = request.DeviceNumber
+	logSC.SimulatorCode = request.SimulatorCode
+	logSC.IsErr = -1
+	logSC.ErrStatus = 1
+	logSC.DeviceHex = s.DeviceHexLog(request)
+	logSC.AccountHex = s.AccountHexLog(request)
+	logSC.CreateDate = time.Now().Format("2006-01-02")
+	logSC.PcCode = request.PcCode
+	logSC.SimulatorIpCity = request.SimulatorIpCity
+	ctx := context.Background()
+	if request.TaskType == 1 {
+		var deviceLog = log.DeviceLog{}
+		if !errors.Is(global.GVA_DB.Where("account = ?", request.Account).Where("game_id = ?", request.GameId).Order("id desc").First(&deviceLog).Error, gorm.ErrRecordNotFound) {
+			if deviceLog.AccountHex != logSC.AccountHex {
+				logSC.IsErr = 1
+				logSC.ErrStatus = 3
+				gameDeviceErrKey := fmt.Sprintf(GameDeviceErrKey, logSC.CreateDate, request.GameId)
+				s.cache.SetCacheNum(ctx, gameDeviceErrKey)
+			}
+		}
+	} else {
+		var deviceLogs []log.DeviceLog
+		if !errors.Is(global.GVA_DB.Where("create_date = ?", logSC.CreateDate).Where("game_id = ?", request.GameId).Where("device_hex = ?", logSC.DeviceHex).Order("id desc").Limit(10).Find(&deviceLogs).Error, gorm.ErrRecordNotFound) {
+			mps := make(map[string]int, 10)
+			for _, dl := range deviceLogs {
+				mps[dl.Account] = 1
+			}
+			if len(mps) > 2 {
+				logSC.IsErr = 1
+				logSC.ErrStatus = 2
+				gameDeviceAccountErrKey := fmt.Sprintf(GameDeviceAccountErrKey, logSC.CreateDate, request.GameId)
+				s.cache.SetCacheNum(ctx, gameDeviceAccountErrKey)
+			}
+		}
+	}
+	logSC.CreateDate = time.Now().Format("2006-01-02")
+	err := global.GVA_DB.Omit("create_time").Create(&logSC).Error
+	if err != nil {
+		global.GVA_LOG.Error("create LogScanningCode fail", zap.Error(err))
+	}
+}
+
+func (s *LogicalLog) DeviceHexLog(request request.AddLogRequest) string {
+	logSC := new(log.DeviceHex)
+	logSC.GameId = request.GameId
+	logSC.DeviceId = request.DeviceId
+	logSC.DeviceImei = request.DeviceImei
+	logSC.DeviceMac = request.DeviceMac
+	logSC.DeviceManufacturer = request.DeviceManufacturer
+	logSC.DeviceModel = request.DeviceModel
+	logSC.DeviceSdk = request.DeviceSdk
+	logSC.DeviceNumber = request.DeviceNumber
+	dh, _ := json.Marshal(logSC)
+	return utils.ByteToHex(dh)
+}
+
+func (s *LogicalLog) AccountHexLog(request request.AddLogRequest) string {
+	logSC := new(log.AccountHex)
+	logSC.GameId = request.GameId
+	logSC.DeviceId = request.DeviceId
+	logSC.DeviceImei = request.DeviceImei
+	logSC.DeviceMac = request.DeviceMac
+	logSC.DeviceManufacturer = request.DeviceManufacturer
+	logSC.DeviceModel = request.DeviceModel
+	logSC.DeviceSdk = request.DeviceSdk
+	logSC.DeviceNumber = request.DeviceNumber
+	logSC.Account = request.Account
+	dh, _ := json.Marshal(logSC)
+	return utils.ByteToHex(dh)
+}
+
+// 修改设备信息状态
+func (s *LogicalLog) UpdateDeviceLogStatus(logUuid string, createDate string) {
+	err := global.GVA_DB.Table("device_log").Where("create_date = ?", createDate).Where("log_uuid = ?", logUuid).Update("status", 1).Error
+	if err != nil {
+		global.GVA_LOG.Error("update UpdateDeviceLogStatus fail", zap.Error(err))
+	}
+}
+
+// 修改设备信息状态
+func (s *LogicalLog) UpdateDeviceLogScriptId(logUuid string, scriptDeviceId string, createDate string) {
+	err := global.GVA_DB.Table("device_log").Where("create_date = ?", createDate).Where("log_uuid = ?", logUuid).Update("script_device_id", scriptDeviceId).Update("status", 1).Error
+	if err != nil {
+		global.GVA_LOG.Error("create LogScanningCode fail", zap.Error(err))
+	}
+}
+
+func (s *LogicalLog) AddAccount(request request.AddLogRequest) {
+
+	gameAccount := new(log.GameAccount)
+	gameAccount.GameId = request.GameId
+	gameAccount.ScriptDeviceId = request.ScriptDeviceId
+	gameAccount.Account = request.Account
+	err := global.GVA_DB.Omit("create_time").Create(&gameAccount).Error
+	if err != nil {
+		global.GVA_LOG.Error("create AddAccount fail", zap.Error(err))
+	}
+}
+
+func (s *LogicalLog) AddScriptDeviceErr(gameId int, account, firstDeviceId, currentDeviceId string, firstAccount string, firstGameId int, status uint, pcCode string, operator string) {
+	scriptDeviceErr := new(log.ScriptDeviceErr)
+	scriptDeviceErr.GameId = firstGameId
+	scriptDeviceErr.Account = firstAccount
+	scriptDeviceErr.CurrentAccount = account
+	scriptDeviceErr.CurrentGameId = gameId
+	scriptDeviceErr.FirstDeviceId = firstDeviceId
+	scriptDeviceErr.CurrentDeviceId = currentDeviceId
+	scriptDeviceErr.CreateDate = time.Now().Format("2006-01-02")
+	scriptDeviceErr.Status = status
+	scriptDeviceErr.PcCode = pcCode
+	scriptDeviceErr.Operator = operator
+	err := global.GVA_DB.Omit("create_time").Create(&scriptDeviceErr).Error
+	if err != nil {
+		global.GVA_LOG.Error("create AddScriptDeviceErr fail", zap.Error(err))
+	}
+}
+
+func (s *LogicalLog) CheckDeviceId(request request.AddLogRequest) {
+	if request.ScriptDeviceId == "" {
+		// 通知异常逻辑
+		global.GVA_LOG.Error("get CheckDeviceId fail", zap.Error(errors.New("没有获取到设备id")))
+		return
+	}
+	s.UpdateDeviceLogScriptId(request.LogUuid, request.ScriptDeviceId, time.Now().Format("2006-01-02"))
+	global.GVA_LOG.Warn("进入 CheckDeviceId")
+	if request.TaskType == 0 {
+		b, deviceLog := s.CheckDeviceIdErr(request.ScriptDeviceId, request.LogUuid, request.GameId)
+		// 有异常处理
+		if b && len(deviceLog) >= 3 {
+			s.AddScriptDeviceErr(request.GameId, request.Account, request.ScriptDeviceId, request.ScriptDeviceId, deviceLog[0].Account, deviceLog[0].GameId, 2, request.PcCode, request.Operator)
+			//ct := fmt.Sprintf("<font color=\"warning\">%s:%d, 相同设备id</font>", request.PcCode, request.GameId)
+			//s.SendDeviceMsg(ct, request.Operator)
+		}
+		s.AddAccount(request)
+		return
+	}
+	var gameAccount log.GameAccount
+	result := global.GVA_DB.Where("game_id = ?", request.GameId).Where("account = ?", request.Account).First(&gameAccount)
+	if result.Error != nil {
+		if result.Error == gorm.ErrRecordNotFound {
+			// 数据不存在,执行创建操作
+			s.AddAccount(request)
+			return
+		} else {
+			// 其他错误
+			global.GVA_LOG.Error("Select GameAccount fail", zap.Error(result.Error))
+			return
+		}
+	}
+	if gameAccount.ScriptDeviceId != request.ScriptDeviceId {
+		s.AddScriptDeviceErr(request.GameId, request.Account, gameAccount.ScriptDeviceId, request.ScriptDeviceId, gameAccount.Account, gameAccount.GameId, 1, request.PcCode, request.Operator)
+		//ct := fmt.Sprintf("<font color=\"warning\">%s:%d, 设备id出现不同</font>", request.PcCode, request.GameId)
+		//s.SendDeviceMsg(ct, request.Operator)
+		gameAccount.ScriptDeviceId = request.ScriptDeviceId
+		global.GVA_DB.Save(&gameAccount)
+	}
+}
+
+func (s *LogicalLog) SendDeviceMsg(content string, operator string) {
+	c := "# 设备异常"
+	c += "\n"
+	ct := content
+	ct = c + ct
+	fmt.Println(ct)
+	mpsPerson, _ := s.Person.GetUserInfoData()
+	if operator != "" {
+		s.SendContent(ct, mpsPerson[operator].Url)
+		url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
+		s.SendContent(ct, url)
+		var sendTextData SendTextMsg
+		sendTextData.MsgType = "text"
+		sendTextData.Text.MentionedMobileList = []string{mpsPerson[operator].MobilePhoneNumber}
+		_, _ = s.SendMsgData(url, sendTextData)
+	}
+}
+
+type SendMsg struct {
+	MsgType  string `json:"msgtype"`
+	Markdown struct {
+		Content string `json:"content"`
+	} `json:"markdown"`
+}
+
+type SendTextMsg struct {
+	MsgType string `json:"msgtype"`
+	Text    struct {
+		MentionedMobileList []string `json:"mentioned_mobile_list"`
+	} `json:"text"`
+}
+
+func (s *LogicalLog) SendContent(content, url string) {
+	var sendMsg SendMsg
+	sendMsg.MsgType = "markdown"
+	sendMsg.Markdown.Content = content
+	_, _ = s.SendMsgData(url, sendMsg)
+}
+
+func (s *LogicalLog) SendMsgData(url string, params interface{}) (result []byte, err error) {
+	result, err = utils.HttpPost(url, params)
+	return
+}
+
+func (s *LogicalLog) CheckDeviceIdErr(scriptDeviceId string, uuid string, gameId int) (bool, []log.GameAccount) {
+	var deviceLog []log.GameAccount
+	// result := global.GVA_DB.Where("create_date <= ?", time.Now().Format("2006-01-02")).Where("create_date >= ?", time.Now().Add(-time.Hour*24).Format("2006-01-02")).Where("game_id = ?", gameId).Where("script_device_id = ?", scriptDeviceId).Find(&deviceLog)
+	result := global.GVA_DB.Where("game_id = ?", gameId).Where("script_device_id = ?", scriptDeviceId).Find(&deviceLog)
+	if result.Error != nil {
+		if result.Error == gorm.ErrRecordNotFound {
+			return false, deviceLog
+		}
+	}
+	return true, deviceLog
+}
+
+func (s *LogicalLog) AddDeviceErrLog(request request.AddLogRequest, st uint) {
+	if request.Err == "" {
+		return
+	}
+	ctx := context.Background()
+	key := fmt.Sprintf(GameDeviceUuidKey, time.Now().Format("2006-01-02"), request.LogUuid)
+	status, _ := s.ExistsKey(ctx, key)
+	if status {
+		return
+	}
+	errLog := new(log.DeviceErrLog)
+	errLog.GameId = request.GameId
+	errLog.CreateDate = time.Now()
+	errLog.CreateTime = time.Now()
+	errLog.Err = request.Err
+	errLog.PcCode = request.PcCode
+	content, _ := json.Marshal(request)
+	errLog.Content = string(content)
+	errLog.Status = st
+	err := errLog.Create()
+	if err != nil {
+		global.GVA_LOG.Error("create AddAccount fail", zap.Error(err))
+		return
+	}
+	global.GVA_REDIS.Set(ctx, key, 1, time.Hour)
+}

+ 7 - 0
service/log/loging/simulator_start_log.go

@@ -15,7 +15,13 @@ func (s *SimulatorStartLog) SuccessLog(ctx context.Context, request request.AddL
 	s.logical.Request = request
 	s.logical.ScriptType = request.ScriptType
 	err = s.logical.DataAdd()
+	s.logical.AddDeviceErrLog(s.logical.Request, 2)
 	if err != nil {
+		if s.logical.Request.SimulatorIp == "" {
+			return
+		}
+		s.logical.Request.Err = s.logical.Request.SimulatorIp[:3]
+		s.logical.AddDeviceErrLog(s.logical.Request, 1)
 		return
 	}
 	code := strconv.Itoa(request.Coding)
@@ -26,6 +32,7 @@ func (s *SimulatorStartLog) SuccessLog(ctx context.Context, request request.AddL
 		_ = s.logical.SetUuidCodeCache(context.Background(), s.logical.CurrentDate(), s.logical.Request.LogUuid, s.logical.Request.Coding, s.logical.Request.GameId)
 	}
 	s.logical.AddIpLog(s.logical.Request)
+	s.logical.AddDeviceLog(s.logical.Request)
 	err = s.logical.PartTypeLogSetNum(ctx, s.logical.CurrentDate(), s.logical.Request.GameId, code, OkStatus, s.logical.Request.TaskType)
 	if err != nil {
 		return

+ 143 - 0
service/system/sys_robot.go

@@ -2,7 +2,10 @@ package system
 
 import (
 	"encoding/json"
+	"fmt"
 	"log-server/global"
+	"log-server/service/log"
+	"log-server/service/task"
 	"log-server/utils"
 	"strconv"
 	"time"
@@ -122,3 +125,143 @@ func (robotService *RobotService) RequestJfXmyNewAccount() (result []byte, err e
 	result, err = utils.HttpGet(jfUrl, jfParams)
 	return
 }
+
+// SyncIPMessage 定时判断ip
+func (robotService *RobotService) SyncIPMessage() {
+
+	//if keyWord != "" {
+	//	content += keyWord
+	//	url := global.GVA_CONFIG.SendUrl.KeyWordSendUrl
+	//	_, _ = robotService.PostRobotToEnterpriseWeChatByMarkdown(url, content)
+	//}
+	fmt.Println("ip定时任务")
+	msg := "# IP异常播报 \n"
+	personMsg := "# IP异常播报 \n"
+	var syncData task.SyncData
+	var ipService log.ServiceIpLog
+
+	//首先更新ip列表
+	err := ipService.UpdateGameIpList()
+	if err != nil {
+		global.GVA_LOG.Info("定时更新ip列表失败:" + err.Error() + time.Now().Format("2006-01-02 15:04:05"))
+	}
+
+	//然后更新异常列表
+	err = ipService.UpdateAbnormalMachineIp()
+	if err != nil {
+		global.GVA_LOG.Info("更新租机异常信息失败:" + err.Error() + time.Now().Format("2006-01-02 15:04:05"))
+	}
+	//获取异常游戏名称和负责人
+	//abnormalIpList, _ := ipService.GetAbnormalIp()
+	//获取异常租机编号和负责人
+	abnormalTodayIpList, _ := ipService.GetTodayAbnormalIpLogList()
+	//如果没有异常列表,直接返回
+	//if len(abnormalIpList) == 0 && len(abnormalTodayIpList) == 0 {
+	//	return
+	//}
+	if len(abnormalTodayIpList) == 0 {
+		return
+	}
+	var mobile []string
+	mpsPerson, _ := syncData.Person.GetUserInfoData()
+	fmt.Println(abnormalTodayIpList)
+	personMsgData := make(map[string]string, len(mpsPerson))
+	ipMsgData := make(map[string]string, len(mpsPerson))
+
+	//如果if len(abnormalIpList) != 0
+	//将游戏名称添加至数组
+	//if len(abnormalIpList) != 0 {
+	//	for k, _ := range abnormalIpList {
+	//		ipMsgData[k] += fmt.Sprintf("<font color=\"warning\">%s</font>", abnormalIpList[k]) + "\n"
+	//	}
+	//}
+	//if len(abnormalTodayIpList) != 0
+	//将租机编号添加至消息体
+	for k, v := range abnormalTodayIpList {
+		ipMsgData[v] += fmt.Sprintf("<font color=\"warning\">%s</font>", k ) + "\n"
+		//if k != len(abnormalTodayIpList) - 1 {
+		//	ipMsgData[v.User] +=  "\n"
+		//}
+	}
+
+	for k, _ := range ipMsgData {
+		mobile = append(mobile, mpsPerson[k].MobilePhoneNumber)
+		msg += k + " " + "\n"
+		msg += fmt.Sprintf("<font color=\"warning\">%s</font>", ipMsgData[k])
+		personMsgData[k] += fmt.Sprintf("<font color=\"warning\">%s</font>", ipMsgData[k]) + "\n"
+	}
+	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
+	var sendData SendMsg
+	sendData.MsgType = "markdown"
+	sendData.Markdown.Content = msg
+	syncData.SendMsgData(url, sendData)
+	//企微机器人基于电话号码@
+	if len(mobile) != 0 {
+		var sendTextData task.SendTextMsg
+		sendTextData.MsgType = "text"
+		sendTextData.Text.MentionedMobileList = mobile
+		//fmt.Println(mobile)
+		//b ,_ := json.Marshal(sendTextData)
+		//global.GVA_LOG.Warn(string(b))
+		syncData.SendMsgData(url, sendTextData)
+	}
+	for person, personData := range personMsgData {
+		var sendPersonData SendMsg
+		sendPersonMsg := personMsg + personData
+		sendPersonData.MsgType = "markdown"
+		sendPersonData.Markdown.Content = sendPersonMsg
+		syncData.SendMsgData(mpsPerson[person].Url, sendPersonData)
+	}
+	return
+}
+
+// SyncMachineIPMessage 定时判断机器ip
+//func (robotService *RobotService) SyncMachineIPMessage() {
+//	fmt.Println("租机ip定时检查")
+//	msg := "# IP租机异常播报 \n "
+//	personMsg := "# IP租机异常播报 \n "
+//	var syncData task.SyncData
+//	var ipService log.ServiceIpLog
+//	//首先更新异常列表
+//	err := ipService.UpdateAbnormalMachineIp()
+//	if err != nil {
+//		global.GVA_LOG.Info("更新租机异常信息失败:" + err.Error() + time.Now().Format("2006-01-02 15:04:05"))
+//	}
+//	abnormalTodayIpList, _ := ipService.GetTodayAbnormalIpLogList()
+//	if len(abnormalTodayIpList) == 0 {
+//		return
+//	}
+//	var mobile []string
+//	mpsPerson, _ := syncData.Person.GetUserInfoData()
+//	personMsgData := make(map[string]string, len(mpsPerson))
+//	//fmt.Println(mpsPerson)
+//	for _, v := range abnormalTodayIpList {
+//		mobile = append(mobile, mpsPerson[v.User].MobilePhoneNumber)
+//		msg += "# " + v.User + " " + "\n"
+//		msg += fmt.Sprintf("<font color=\"warning\">%s</font>", v.PcCode+" "+v.TaskName) + "\n"
+//		personMsgData[v.User] += fmt.Sprintf("<font color=\"warning\">%s</font>", v.PcCode+" "+v.TaskName) + "\n"
+//	}
+//	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
+//	var sendData SendMsg
+//	sendData.MsgType = "markdown"
+//	sendData.Markdown.Content = msg
+//	syncData.SendMsgData(url, sendData)
+//
+//	if len(mobile) != 0 {
+//		var sendTextData task.SendTextMsg
+//		sendTextData.MsgType = "text"
+//		sendTextData.Text.MentionedMobileList = mobile
+//		//fmt.Println(mobile)
+//		//b ,_ := json.Marshal(sendTextData)
+//		//global.GVA_LOG.Warn(string(b))
+//		syncData.SendMsgData(url, sendTextData)
+//	}
+//	for person, personData := range personMsgData {
+//		var sendPersonData SendMsg
+//		sendPersonMsg := personMsg + personData
+//		sendPersonData.MsgType = "markdown"
+//		sendPersonData.Markdown.Content = sendPersonMsg
+//		syncData.SendMsgData(mpsPerson[person].Url, sendPersonData)
+//	}
+//	return
+//}

+ 111 - 0
service/task/central_control_conf.go

@@ -0,0 +1,111 @@
+package task
+
+import (
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+	"log-server/global"
+	"log-server/model/common/request"
+	"log-server/model/task"
+)
+
+type CentralControlService struct {
+
+}
+
+//创建配置记录
+func (s *CentralControlService) CreateCentralControlConf(conf task.CentralControlConf) (err error) {
+	//查找是否有这个taskId的记录
+	var entity task.CentralControlConf
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("task_id", conf.TaskId).First(&entity).Error
+	//如果有,报错返回
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("已有配置记录,请勿重复添加")
+	}
+	//如果没有,直接创建
+	return global.GVA_DB.Model(&task.CentralControlConf{}).Omit("create_time", "update_time").Create(&conf).Error
+}
+
+//删除中控配置记录
+func (s *CentralControlService) DeleteCentralControlConf(conf task.CentralControlConf) (err error)  {
+	var entity task.CentralControlConf
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("id", conf.Id).First(&entity).Error
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("此配置不存在,无法删除")
+	}
+	return global.GVA_DB.Model(&task.CentralControlConf{}).Delete(&entity).Error
+}
+
+//批量删除中控配置记录
+func (s *CentralControlService) DeleteCentralControlConfByIds(ids []int) (err error) {
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Delete("id in ?", ids).Error
+	return err
+}
+
+//更新中控配置列表
+func (s *CentralControlService) UpdateCentralControlConf(conf task.CentralControlConf) (err error) {
+	var entity task.CentralControlConf
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("task_id = ? and id != ?", conf.TaskId, conf.Id).First(&entity).Error
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("已存在相同的task_id,无法更改")
+	}
+	return global.GVA_DB.Model(&task.CentralControlConf{}).Where("id", conf.Id).Save(&conf).Error
+}
+
+//通过id获取单条配置
+func (s *CentralControlService) GetCentralControlConfById(id int) (conf task.CentralControlConf, err error) {
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("id", id).First(&conf).Error
+	return conf, err
+}
+
+//获取配置列表
+func (s *CentralControlService) GetCentralControlConfList(conf task.CentralControlConf, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error){
+	//获取limit和offset
+	limit := info.PageSize
+	offset := (info.Page - 1) * info.PageSize
+	db := global.GVA_DB.Model(&task.CentralControlConf{})
+	var confList []task.CentralControlConf
+
+	//先条件过滤
+	if conf.TaskId != 0 {
+		//条件过滤记录数
+		db = db.Where("task_id", conf.TaskId)
+	}
+
+	err = db.Count(&total).Error
+	if err != nil{
+		//如果出错直接返回
+		return confList, total, err
+	} else {
+		//先分页再排序
+		db = db.Limit(limit).Offset(offset)
+		if order != ""{
+			//传入排序字段,进行排序
+			//定义orderStr存储完整的排序字段
+			var  orderStr string
+			//为了避免sql注入,自己创建数组匹配
+			orderMap := make(map[string]bool, 3)
+			orderMap["task_id"] = true
+			orderMap["create_time"] = true
+			orderMap["update_time"] = true
+			if orderMap[order] {
+				if desc {
+					orderStr = order + " desc"
+				} else {
+					orderStr = order
+				}
+			} else {
+				//传入非法字段,不能排序
+				err = fmt.Errorf("传入非法字段 %v", order)
+				return confList, total, err
+			}
+			//排序
+			err = db.Order(orderStr).Find(&confList).Error
+		} else {
+			//没有传入排序字段,默认按照类型名称降序排序
+			err = db.Order("id desc").Find(&confList).Error
+		}
+	}
+	//是因为只有切片能排序,model没办法排序;还是说为了将数组返回至前端才find扫描至切片呢?
+	return confList, total, err
+}

+ 2 - 0
service/task/enter.go

@@ -3,4 +3,6 @@ package task
 type ServiceGroup struct {
 	GameTask
 	TaskConfService
+	CentralControlService
+	UrgentTaskService
 }

+ 53 - 13
service/task/game_task.go

@@ -8,6 +8,7 @@ import (
 	"github.com/xuri/excelize/v2"
 	"go.uber.org/zap"
 	"gorm.io/gorm"
+	"io/ioutil"
 	"log-server/global"
 	"log-server/model/task"
 	"log-server/model/task/control"
@@ -18,6 +19,7 @@ import (
 	"log-server/utils"
 	"math"
 	"math/rand"
+	"net/http"
 	"strconv"
 	"strings"
 	"time"
@@ -348,7 +350,7 @@ func (apiService *GameTask) GetUsedGameTaskInfoList(api task.GameTask, info requ
 	offset := info.PageSize * (info.Page - 1)
 	db := global.GVA_DB.Model(&task.GameTask{})
 	var apiList []task.GameTaskUnion
-	db = db.Select("game_task.*, task_conf.add_fee_notice")
+	db = db.Select("game_task.*, task_conf.add_fee_notice, task_conf.simulator_type")
 	db = db.Joins("left join task_conf on task_conf.task_id = game_task.task_id")
 	db = db.Where("is_del = ?", -1)
 	if api.TaskName != "" {
@@ -364,7 +366,7 @@ func (apiService *GameTask) GetUsedGameTaskInfoList(api task.GameTask, info requ
 	}
 
 	if api.TaskId != 0 {
-		db = db.Where("task_id = ?", api.TaskId)
+		db = db.Where("game_task.task_id = ?", api.TaskId)
 	}
 
 	//获取启用状态的任务
@@ -413,6 +415,7 @@ func (apiService *GameTask) GetUsedGameTaskInfoList(api task.GameTask, info requ
 			var apiReply = new(response.GetGameTaskListUnionReply)
 			apiReply.Status = apiInfo.Status
 			apiReply.TaskId = apiInfo.TaskId
+			apiReply.SimulatorType = apiInfo.SimulatorType
 			apiReply.TaskName = apiInfo.TaskName
 			apiReply.AddFeeNotice = apiInfo.AddFeeNotice
 			apiReply.GamePort = gamePortMp[apiInfo.GamePortId].ChannelName
@@ -885,6 +888,9 @@ func (s *GameTask) UpdateGameTaskTarget(requestData request.UpdateGameTaskTarget
 	})
 	if gameTask.CreateDate.Format("2006-01-02") == date {
 		if gameTask.PayTarget < requestData.PayTarget {
+			if taskData.GamePortId != 1 {
+				return errors.New("不是腾讯任务,不能更付费")
+			}
 			global.GVA_LOG.Warn("进入修改add update")
 			lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, gameTask.TaskId)
 			_ = s.cache.SetCacheStr(context.Background(), lastPayAddUpdateTimeKey, time.Now().Unix())
@@ -903,17 +909,17 @@ func (s *GameTask) UpdateGameTaskTarget(requestData request.UpdateGameTaskTarget
 				_ = s.cache.SetCacheStr(context.Background(), payErrAddNumKey, requestData.PayTarget-gameTask.PayTarget+n)
 			}
 			go s.common.FreeSendMsg(requestData.PayTarget-gameTask.PayTarget, requestData.PayTarget, taskData.TaskId, taskData.TaskName, taskData.User)
-			msg := "# 监控报警 " + time.Now().Format("2006-01-02 15:04:05")
-			msg += "\n"
-			msg += "**" + taskData.User + "**"
-			msg += "\n"
-			msg += taskData.TaskName + ", 付费目标改为" + strconv.Itoa(requestData.PayTarget)
-			//url := "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5ccfb180-c062-48b5-ae18-0c96f7c19f0b"
-			url := global.GVA_CONFIG.SendUrl.SendUrlOne
-			var sendData SendMsg
-			sendData.MsgType = "markdown"
-			sendData.Markdown.Content = msg
-			s.common.SendMsgData(url, sendData)
+			//msg := "# 监控报警 " + time.Now().Format("2006-01-02 15:04:05")
+			//msg += "\n"
+			//msg += "**" + taskData.User + "**"
+			//msg += "\n"
+			//msg += taskData.TaskName + ", 付费目标改为" + strconv.Itoa(requestData.PayTarget)
+			////url := "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5ccfb180-c062-48b5-ae18-0c96f7c19f0b"
+			//url := global.GVA_CONFIG.SendUrl.SendUrlOne
+			//var sendData SendMsg
+			//sendData.MsgType = "markdown"
+			//sendData.Markdown.Content = msg
+			//s.common.SendMsgData(url, sendData)
 		}
 	}
 	return
@@ -1157,6 +1163,29 @@ func (s *GameTask) GetFeeAccountList(taskId int) (fa []FeeAccount, err error) {
 	return
 }
 
+//从小绵羊后台获取数据并返回
+func (apiService *GameTask) GetXmyTaskList(startDay string, endDay string) (list interface{}, err error) {
+	var apisReply *response.XmyGameDataReply
+	client := &http.Client{}
+	url := "http://api.sheepsdk.17xmy.com/foreign/api/get_youhua_data.php?start_day=" + startDay + "&end_day=" + endDay
+	req, err := http.NewRequest("GET", url, nil) //GET大写
+	if err != nil {
+		return
+	}
+	rep, err := client.Do(req) //发起请求
+	if err != nil {
+		return
+	}
+	data, err := ioutil.ReadAll(rep.Body)
+	rep.Body.Close()
+	json.Unmarshal(data, &apisReply)
+	if err != nil {
+		return
+	}
+	//fmt.Printf("%s", apisReply)
+	return apisReply.Data, err
+}
+
 func (exa *GameTask) TaskStatisticsList2Excel(infoList []response.GetGameTargetComplete, filePath string) error {
 	excel := excelize.NewFile()
 	excel.SetSheetRow("Sheet1", "A1", &[]string{
@@ -1220,3 +1249,14 @@ func (exa *GameTask) TaskStatisticsList2Excel(infoList []response.GetGameTargetC
 	err := excel.SaveAs(filePath)
 	return err
 }
+
+func (apiService *GameTask) TemporaryTask(ctx context.Context, pcCode string) (temporaryConf task.CentralControlConf, err error) {
+	date := time.Now().Format("2006-01-02")
+	key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, pcCode)
+	taskId, _ := apiService.cache.GetCacheStr(ctx, key)
+	if taskId == "" {
+		return temporaryConf, errors.New("没有任务数据")
+	}
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("task_id", taskId).First(&temporaryConf).Error
+	return temporaryConf, err
+}

+ 11 - 4
service/task/sync_data.go

@@ -223,10 +223,17 @@ func (s *SyncData) SyncTaskData() {
 			}
 		}
 		gameTarget.GameRate = roomData.GameRate
-		if gameTask.GamePortId == 5 && gameTask.LoginMethod == 2 {
-			mzGameId := gameTask.MzGameId + "-" + gameTask.MzChannel
-			if _, ok := wslData[mzGameId]; ok {
-				gameTarget.PayTarget = wslData[mzGameId]
+		if (gameTask.GamePortId == 5 && gameTask.LoginMethod == 2) || gameTask.LoginMethod == 7 {
+			// 魅族游戏id处理
+			GameId := gameTask.MzGameId + "-" + gameTask.MzChannel
+			// 青雀账号游戏id处理
+			if gameTask.LoginMethod == 7 {
+				taskId := strconv.Itoa(gameTask.TaskId)
+				GameId = "rose-" + taskId
+				gameTarget.PayComplete = roomData.PayComplete
+			}
+			if _, ok := wslData[GameId]; ok {
+				gameTarget.PayTarget = wslData[GameId]
 				if gameTarget.PayTarget > completeTaskData[gameTask.TaskId].PayTarget {
 					lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, gameTask.TaskId)
 					_ = s.cache.SetCacheStr(context.Background(), lastPayAddUpdateTimeKey, time.Now().Unix())

+ 3 - 2
service/task/task_conf.go

@@ -189,7 +189,7 @@ func (e *TaskConfService) DownloadFile(taskId int, md5String string) (info respo
 	//改由存储至数据库的时候拼接前缀
 	//var prefix string = global.GVA_CONFIG.PrefixUrl.PrefixLocal
 	//数据库中无记录,即不需要更新
-	err = global.GVA_DB.Table("upload_file").Where("task_id = ? and state = 1", taskId).Order("id desc").Limit(1).Find(&file).Error
+	err = global.GVA_DB.Table("upload_file").Where("task_id = ? and state = 1", taskId).Order("id desc").First(&file).Error
 	if errors.Is(err, gorm.ErrRecordNotFound) {
 		info = response.DownloadFile{
 			Url: "",
@@ -205,6 +205,7 @@ func (e *TaskConfService) DownloadFile(taskId int, md5String string) (info respo
 			Md5String: "",
 			Flag: false,
 		}
+		return info, errors.New("不需要更新")
 	} else {
 		fullUrl := file.Url
 		info = response.DownloadFile{
@@ -290,5 +291,5 @@ func (e *TaskConfService) JudgeOperate(taskConf task.TaskConf) (err error) {
 		return global.GVA_DB.Model(&task.TaskConf{}).Create(&taskConf).Error
 	}
 	//如果有,更新
-	return global.GVA_DB.Model(&task.TaskConf{}).Where("task_id = ?", taskConf.TaskId).Omit("task_id", "user").Updates(&taskConf).Error
+	return global.GVA_DB.Model(&task.TaskConf{}).Where("task_id = ?", taskConf.TaskId).Omit("task_id", "user").Updates(map[string]interface{}{"add_fee_notice": taskConf.AddFeeNotice, "simulator_type": taskConf.SimulatorType}).Error
 }

+ 186 - 0
service/task/urgent_task_conf.go

@@ -0,0 +1,186 @@
+package task
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"go.uber.org/zap"
+	"gorm.io/gorm"
+	"log-server/global"
+	"log-server/model/common/request"
+	"log-server/model/task"
+	"log-server/service/cache"
+	"strings"
+	"time"
+)
+
+type UrgentTaskService struct {
+}
+
+func (s *UrgentTaskService) CreateUrgentTask(task1 task.UrgentTaskConf) (err error) {
+	//根据平均期望,将故障较大的放前面可以减少查询次数。那么需要先查是否有task_id以及create_date相等的
+	var urgentEntity task.UrgentTaskConf
+	var centralEntity task.CentralControlConf
+	date := time.Now().Format("2006-01-02")
+	task1.CreateDate = date
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("task_id = ? and create_date = ?", task1.TaskId, date).First(&urgentEntity).Error
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("任务已存在,请勿重复添加")
+	}
+	//查找中控配置是否存在
+	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("task_id", task1.TaskId).First(&centralEntity).Error
+	//若记录不存在,则报错返回
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("请先添加此任务中控配置")
+	}
+	//创建紧急任务
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Omit("create_time", "update_time").Create(&task1).Error
+	if err != nil {
+		return err
+	}
+	codeSplit := strings.Split(task1.PcCode, ",")
+	ctx := context.Background()
+	for _, code := range codeSplit {
+		key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
+		global.GVA_REDIS.Set(ctx, key, task1.TaskId, time.Hour*6)
+	}
+	return
+}
+
+func (s *UrgentTaskService) DeleteUrgentTask(task1 task.UrgentTaskConf) (err error) {
+	//查找此任务是否存在
+	var entity task.UrgentTaskConf
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", task1.Id).First(&entity).Error
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("此任务不存在")
+	}
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Delete(&entity).Error
+	if err != nil {
+		return err
+	}
+	codeSplit := strings.Split(entity.PcCode, ",")
+	date := entity.CreateDate[:10]
+	ctx := context.Background()
+	for _, code := range codeSplit {
+		key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
+		global.GVA_REDIS.Del(ctx, key)
+	}
+	return
+}
+
+//批量删除
+func (s *UrgentTaskService) DeleteUrgentTaskByIds(ids []int) (err error) {
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Delete("id in ?", ids).Error
+	return err
+}
+
+func (s *UrgentTaskService) UpdateUrgentTask(task1 task.UrgentTaskConf) (err error) {
+	//查找此task_id是否存在,如果存在不更新,否则更新
+	var entity task.UrgentTaskConf
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("task_id = ? and id != ? and create_date = ?", task1.TaskId, task1.Id, task1.CreateDate).First(&entity).Error
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		return errors.New("已存在此task_id的任务,更新失败")
+	}
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", task1.Id).Updates(&task1).Error
+	if err != nil {
+		return err
+	}
+	date := entity.CreateDate[:10]
+	if entity.PcCode != task1.PcCode {
+		codeSplit := strings.Split(entity.PcCode, ",")
+		ctx := context.Background()
+		for _, code := range codeSplit {
+			key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
+			global.GVA_REDIS.Del(ctx, key)
+		}
+		upCodeSplit := strings.Split(task1.PcCode, ",")
+		for _, upCode := range upCodeSplit {
+			key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, upCode)
+			global.GVA_REDIS.Set(ctx, key, task1.TaskId, time.Hour*6)
+		}
+	}
+	return
+}
+
+func (s *UrgentTaskService) GetUrgentTaskById(id int) (task1 task.UrgentTaskConf, err error) {
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", id).First(&task1).Error
+	return task1, err
+}
+
+//查询空闲租机
+func (s *UrgentTaskService) GetUnusedPc() (unusedPcList []task.UnusedPc, err error) {
+	//获取当日日期
+	date := time.Now().Format("2006-01-02")
+	db := global.GVA_DB.Table("computer_status").Where("status = ? and create_date = ?", -1, date)
+	pcCodes, err := s.GetTemporaryTaskId(date)
+	if pcCodes != "" {
+		db.Not("pc_code", strings.Split(pcCodes, ","))
+	}
+	err = db.Order("pc_code").Find(&unusedPcList).Error
+	return unusedPcList, err
+}
+
+func (s *UrgentTaskService) GetTemporaryTaskId(date string) (pcCodes string, err error) {
+	var urgentTaskConf []task.UrgentTaskConf
+	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("create_date = ?", date).Find(&urgentTaskConf).Error
+	if len(urgentTaskConf) == 0 {
+		return pcCodes, errors.New("没有任务数据")
+	}
+	for _, conf := range urgentTaskConf {
+		pcCodes += conf.PcCode + ","
+	}
+	pcCodes = strings.Trim(pcCodes, ",")
+	return
+}
+
+//获取紧急任务列表
+func (s *UrgentTaskService) GetUrgentTaskList(conf task.UrgentTaskConfRequest, info request.PageInfo, order string, desc bool) (confList []task.UrgentTaskConf, total int64, err error) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	db := global.GVA_DB.Model(&task.UrgentTaskConf{})
+	startDate := time.Now().Format("2006-01-02")
+	endDate := time.Now().Format("2006-01-02")
+	if len(conf.Date) == 2 {
+		startDate = conf.Date[0]
+		endDate = conf.Date[1]
+	}
+	//筛选日期
+	db = db.Where("create_date >= ? and create_date <= ?", startDate, endDate)
+	if conf.TaskId != 0 {
+		db = db.Where("task_id = ?", conf.TaskId)
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return confList, total, err
+	} else {
+		db = db.Limit(limit).Offset(offset)
+		if order != "" {
+			var OrderStr string
+			// 设置有效排序key 防止sql注入
+			// 感谢 Tom4t0 提交漏洞信息
+			orderMap := make(map[string]bool, 4)
+			orderMap["task_id"] = true
+			orderMap["create_date"] = true
+			orderMap["create_time"] = true
+			orderMap["update_time"] = true
+			if orderMap[order] {
+				if desc {
+					OrderStr = order + " desc"
+				} else {
+					OrderStr = order
+				}
+			} else { // didn't matched any order key in `orderMap`
+				global.GVA_LOG.Error("获取失败!", zap.Error(err))
+				return confList, total, err
+			}
+			err = db.Order(OrderStr).Find(&confList).Error
+		} else {
+			err = db.Order("id desc").Find(&confList).Error
+		}
+	}
+	//遍历更改日期格式
+	for i, _ := range confList {
+		confList[i].CreateDate = confList[i].CreateDate[:10]
+	}
+	return confList, total, err
+}

+ 11 - 0
utils/common.go

@@ -0,0 +1,11 @@
+package utils
+
+import (
+	"fmt"
+	"strconv"
+)
+
+func Decimal(num float64) float64 {
+	num, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", num), 64)
+	return num
+}

+ 9 - 0
utils/hash.go

@@ -1,6 +1,8 @@
 package utils
 
 import (
+	"crypto/md5"
+	"encoding/hex"
 	"golang.org/x/crypto/bcrypt"
 )
 
@@ -15,3 +17,10 @@ func BcryptCheck(password, hash string) bool {
 	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
 	return err == nil
 }
+
+func ByteToHex(bt []byte) string {
+	m := md5.New()
+	m.Write(bt)
+	res := hex.EncodeToString(m.Sum(nil))
+	return res
+}

+ 11 - 9
utils/verify.go

@@ -21,13 +21,15 @@ var (
 	PcVerify               = Rules{"PcCode": {NotEmpty()}, "User": {NotEmpty()}, "Supplier": {NotEmpty()}}
 
 	//自己添加的校验
-	GameChannelVerify       = Rules{"ChannelName": {NotEmpty()}, "ChannelDesc": {NotEmpty()}, "DisplaySequence": {NotEmpty()}}
-	GameListVerify          = Rules{"GameName": {NotEmpty()}, "GamePort": {NotEmpty()}, "LoginType": {NotEmpty()}}
-	LoginTypeVerify         = Rules{"LoginName": {NotEmpty()}, "LoginDesc": {NotEmpty()}}
-	ResponsiblePersonVerify = Rules{"Name": {NotEmpty()} }
-	AccountTypeVerify       = Rules{"TypeName": {NotEmpty()}}
-	GameTaskVerify          = Rules{"TaskId": {NotEmpty()}, "TaskName": {NotEmpty()}, "User": {NotEmpty()}, "NewRetained": {NotEmpty()}, "GamePortId": {NotEmpty()}}
-	TaskIdVerify            = Rules{"TaskId": {NotEmpty()}}
-	UpdateTargetVerify      = Rules{"TaskId": {NotEmpty()}, "CreateDate": {NotEmpty()}}
-	TaskConfVerify          = Rules{"User": {NotEmpty()}}
+	GameChannelVerify        = Rules{"ChannelName": {NotEmpty()}, "ChannelDesc": {NotEmpty()}, "DisplaySequence": {NotEmpty()}}
+	GameListVerify           = Rules{"GameName": {NotEmpty()}, "GamePort": {NotEmpty()}, "LoginType": {NotEmpty()}}
+	LoginTypeVerify          = Rules{"LoginName": {NotEmpty()}, "LoginDesc": {NotEmpty()}}
+	ResponsiblePersonVerify  = Rules{"Name": {NotEmpty()}}
+	AccountTypeVerify        = Rules{"TypeName": {NotEmpty()}}
+	GameTaskVerify           = Rules{"TaskId": {NotEmpty()}, "TaskName": {NotEmpty()}, "User": {NotEmpty()}, "NewRetained": {NotEmpty()}, "GamePortId": {NotEmpty()}}
+	TaskIdVerify             = Rules{"TaskId": {NotEmpty()}}
+	UpdateTargetVerify       = Rules{"TaskId": {NotEmpty()}, "CreateDate": {NotEmpty()}}
+	TaskConfVerify           = Rules{"User": {NotEmpty()}}
+	CentralControlConfVerify = Rules{"Cpu": {NotEmpty()}, "MemorySize": {NotEmpty()}, "TaskId": {NotEmpty()}, "GameId": {NotEmpty()}} //中控配置校验
+	UrgentTaskVerify         = Rules{"TaskId": {NotEmpty()}, "PcCode": {NotEmpty()}}                                                  //紧急任务校验
 )