Bläddra i källkod

处理设备信息

wangbin 2 år sedan
förälder
incheckning
cdc0a38c58

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

@@ -605,6 +605,62 @@ func (e *ApiLoging) GetDeviceInfoLog(c *gin.Context) {
 }
 
 // @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.GetDeviceInfoLogRequest
+	_ = c.ShouldBindJSON(&paramsInfo)
+	list, total, err := ServiceStatisticsLog.GetDeviceIdErr(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 导出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.DeviceStatistics, 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

+ 33 - 0
model/log/device_log.go

@@ -1,5 +1,7 @@
 package log
 
+import "time"
+
 type DeviceLog struct {
 	Id                 uint   `json:"id"`
 	SimulatorCode      string `json:"simulator_code"`
@@ -20,6 +22,8 @@ type DeviceLog struct {
 	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"`
 }
 
 func (DeviceLog) TableName() string {
@@ -48,3 +52,32 @@ type DeviceHex struct {
 	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
+}
+
+func (ScriptDeviceErr) TableName() string {
+	return "script_device_err"
+}

+ 32 - 10
model/log/device_statistics.go

@@ -1,18 +1,40 @@
 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"`
+	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"`
 }
 
 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"`
+}

+ 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,"

+ 10 - 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.DeviceStatistics
+		PageInfo
+		OrderKey string `json:"orderKey"` // 排序
+		Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+	} `json:"infoList"`
+}
+
 //导出ip列表
 type ExcelIpInfo struct {
 	FileName string `json:"fileName"` // 文件名

+ 1 - 0
model/log/request/loging.go

@@ -31,6 +31,7 @@ type AddLogRequest struct {
 	DeviceMac          string `json:"device_mac"`
 	DeviceNumber       string `json:"device_number"`
 	DeviceIp           string `json:"device_ip"`
+	ScriptDeviceId     string `json:"script_device_id"`
 }
 
 type ReportPointsData struct {

+ 2 - 0
router/log/loging.go

@@ -31,5 +31,7 @@ func (e *LogingRouter) InitLogingRouter(Router *gin.RouterGroup) {
 		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)
 	}
 }

+ 123 - 7
service/log/log_statistics.go

@@ -1376,6 +1376,8 @@ func (s *ServiceStatisticsLog) DeviceStatistics() {
 	if len(devices) == 0 {
 		return
 	}
+	retainedDeviceErr := s.DeviceIdStatistics(date, 1)
+	newDeviceErr := s.DeviceIdStatistics(date, 2)
 	completeData, _ := s.GameTargetComplete.CompleteTaskData(date)
 	ctx := context.Background()
 	for _, game := range devices {
@@ -1397,6 +1399,23 @@ func (s *ServiceStatisticsLog) DeviceStatistics() {
 			deviceLog.AccountErrRate = utils.Decimal(float64(deviceLog.AccountErrNum) / float64(deviceLog.NewComplete) * 100)
 		}
 		deviceLog.CreateDate = date
+
+		if _, ok := retainedDeviceErr[game.GameId]; ok {
+			if retainedDeviceErr[game.GameId].Count != 0 {
+				deviceLog.RetainedDeviceIdErr = retainedDeviceErr[game.GameId].Count
+				deviceLog.RetainedDeviceIdRate = utils.Decimal(float64(deviceLog.RetainedDeviceIdErr) / float64(deviceLog.RetainedComplete) * 100)
+			}
+			delete(retainedDeviceErr, game.GameId)
+		}
+
+		if _, ok := newDeviceErr[game.GameId]; ok {
+			if newDeviceErr[game.GameId].Count != 0 {
+				deviceLog.NewDeviceIdErr = newDeviceErr[game.GameId].Count
+				deviceLog.NewDeviceIdRate = utils.Decimal(float64(deviceLog.NewDeviceIdErr) / float64(deviceLog.NewComplete) * 100)
+			}
+			delete(newDeviceErr, game.GameId)
+		}
+
 		if !errors.Is(global.GVA_DB.Where("create_date = ?", date).Where("game_id = ?", game.GameId).First(&log.DeviceStatistics{}).Error, gorm.ErrRecordNotFound) {
 			global.GVA_DB.Where("create_date = ?", date).Where("game_id = ?", game.GameId).Omit("create_date,game_id").Updates(deviceLog)
 			continue
@@ -1405,33 +1424,88 @@ func (s *ServiceStatisticsLog) DeviceStatistics() {
 	}
 }
 
-func (s *ServiceStatisticsLog) GetDeviceStatistics(ctx context.Context, api log.DeviceStatistics, info request.PageInfo, order string, desc bool) (statistics []*log.DeviceStatistics, total int64, err error) {
+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 (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.DeviceStatistics, 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.Model(&log.DeviceStatistics{})
-	db = db.Where("create_date = ?", api.CreateDate)
+	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("game_id = ?", api.GameId)
+		db = db.Where("ds.game_id = ?", api.GameId)
 	}
 	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, 3)
+		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 = order + " desc"
+				OrderStr = "ds." + order + " desc"
 			} else {
-				OrderStr = order
+				OrderStr = "ds." + order
 			}
 		} else { // didn't matched any order key in `orderMap`
 			global.GVA_LOG.Error("获取失败!", zap.Error(err))
@@ -1494,6 +1568,48 @@ func (s *ServiceStatisticsLog) GetDeviceInfo(ctx context.Context, api log.Device
 	return
 }
 
+func (s *ServiceStatisticsLog) GetDeviceIdErr(ctx context.Context, api log.DeviceLog, 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)
+	}
+	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

+ 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 {

+ 137 - 4
service/log/loging/logical_log.go

@@ -11,6 +11,7 @@ import (
 	"log-server/global"
 	"log-server/model/log"
 	"log-server/model/log/request"
+	"log-server/model/typeManage"
 	"log-server/service/cache"
 	"log-server/utils"
 	"strconv"
@@ -44,6 +45,7 @@ type LogicalLog struct {
 	Request    request.AddLogRequest
 	cache      cache.Cache
 	ScriptType int
+	Person     typeManage.ResponsiblePerson
 }
 
 func (s *LogicalLog) CurrentDate() (current string) {
@@ -892,9 +894,7 @@ func (s *LogicalLog) UpdateIpLogStatus(logUuid string, createDate string) {
 
 // 记录设备信息
 func (s *LogicalLog) AddDeviceLog(request request.AddLogRequest) {
-	if request.DeviceId == "" {
-		return
-	}
+
 	logSC := new(log.DeviceLog)
 	logSC.GameId = request.GameId
 	logSC.LogUuid = request.LogUuid
@@ -913,6 +913,7 @@ func (s *LogicalLog) AddDeviceLog(request request.AddLogRequest) {
 	logSC.DeviceHex = s.DeviceHexLog(request)
 	logSC.AccountHex = s.AccountHexLog(request)
 	logSC.CreateDate = time.Now().Format("2006-01-02")
+	logSC.PcCode = request.PcCode
 	ctx := context.Background()
 	if request.TaskType == 1 {
 		var deviceLog = log.DeviceLog{}
@@ -977,8 +978,140 @@ func (s *LogicalLog) AccountHexLog(request request.AddLogRequest) string {
 
 // 修改设备信息状态
 func (s *LogicalLog) UpdateDeviceLogStatus(logUuid string, createDate string) {
-	err := global.GVA_DB.Table("ip_log").Where("create_date = ?", createDate).Where("log_uuid = ?", logUuid).Update("status", 2).Error
+	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) {
+	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
+	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 {
+			s.AddScriptDeviceErr(request.GameId, request.Account, request.ScriptDeviceId, request.ScriptDeviceId, deviceLog.Account, deviceLog.GameId, 2)
+			//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)
+		//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.DeviceLog) {
+	var deviceLog log.DeviceLog
+	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).Where("log_uuid != ?", uuid).First(&deviceLog)
+	if result.Error != nil {
+		if result.Error == gorm.ErrRecordNotFound {
+			return false, deviceLog
+		}
+	}
+	return true, deviceLog
+}