package api import ( "fmt" "net/http" "strings" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v4" ) // 需要记录操作日志的重要接口(增删改类操作) var auditableAPIMap = map[string]bool{ // 登录 "api_login": false, // 管理员管理 "api_addadminuser": true, "api_deladminuser": true, "api_updateadminuser": true, // 配置管理 "api_addconfig": true, "api_updateconfig": true, "api_delconfig": true, "api_addglobalconfigs": true, "api_updateglobalconfig": true, "api_delglobalconfigs": true, // 智能体 "api_addagent": true, "api_updateagent": true, "api_delagent": true, // 产品管理 "api_addproduct": true, "api_updateproduct": true, "api_delproduct": true, "api_addproductversion": true, "api_delproductversion": true, // 品牌商 / 生产管理 "api_addbrand": true, "api_updatebrand": true, "api_delbrand": true, "api_createauthcodes": true, "api_revokeproductionbatch": true, "api_disableauthcodes": true, "api_restfactorydevics": true, "api_resetlicensestatus": true, // 商品管理 "api_addgoods": true, "api_updategoods": true, "api_delgoods": true, // 渠道包 "api_addchannelapp": true, "api_uploadchannelapp": true, "api_delchannelapp": true, // MCP "api_addmcpservers": true, "api_updatemcpservers": true, "api_delmcpservers": true, // 模板 "api_addtemplates": true, "api_updatetemplates": true, "api_deltemplate": true, // 唤醒词 "api_addwakeupvoice": true, "api_updatewakeupvoice": true, "api_delwakeupvoice": true, // 用户管理 "api_updateuser": true, // 邮件 "api_sendsmtpemail": true, // 资源分发 "api_dispatchresource": true, "api_grantadminresource": true, // 超管→后台账号 资源点赠送 // 统计 "api_rebuildstats": true, // 全量重建统计 } // 设置跨域 func cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method origin := c.Request.Header.Get("Origin") if origin != "" { c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名 c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization") c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type") c.Header("Access-Control-Allow-Credentials", "true") } if method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) } c.Next() } } func parseToken(tokenString string, secretKey []byte) (*jwt.RegisteredClaims, error) { parsedToken, err := jwt.ParseWithClaims(tokenString, &jwt.RegisteredClaims{}, func(token *jwt.Token) (interface{}, error) { // Ensure the token method conforms to "SigningMethodHMAC" if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return secretKey, nil }) if err != nil { return nil, err } // Validate the token and extract the claims if claims, ok := parsedToken.Claims.(*jwt.RegisteredClaims); ok && parsedToken.Valid { return claims, nil } else { return nil, fmt.Errorf("invalid token") } } // 基准日期 var baseDate = time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC) // createCode 将三个整数拼接成一个15位的十五进制字符串 func createCode(devicetype int, factoryid int, timeday int, number int) string { // 转换并格式化channel为4位十五进制 deviceTsype := formatToHex(devicetype, 1) // 转换并格式化group为4位十五进制 factoryId := formatToHex(factoryid, 2) // 转换并格式化number为7位十五进制 timeDay := formatToHex(timeday, 4) // 转换并格式化number为7位十五进制 numBer := formatToHex(number, 4) return deviceTsype + factoryId + timeDay + numBer } // ConvertRelativeDaysToDate 将相对天数转换回实际日期 func ConvertRelativeDaysToDate(relativeDays uint16) uint32 { baseDate := uint32(20250101) baseYear := baseDate / 10000 baseMonth := (baseDate % 10000) / 100 baseDay := baseDate % 100 // 简化计算:假设每月30天 totalDays := baseYear*365 + baseMonth*30 + baseDay + uint32(relativeDays) // 转换回年月日格式(简化版本) year := totalDays / 365 remainingDays := totalDays % 365 month := remainingDays / 30 day := remainingDays % 30 if month == 0 { month = 1 } if day == 0 { day = 1 } return year*10000 + month*100 + day } // formatToHex 将整数转换为指定长度的十六进制字符串 func formatToHex(num, length int) string { if num < 0 { num = 0 // 处理负数情况 } // 使用标准库转换为十六进制 hexStr := fmt.Sprintf("%x", num) // 补零至指定长度 hexStr = strings.ToUpper(fmt.Sprintf("%0*s", length, hexStr)) // 截取指定长度(处理溢出情况) if len(hexStr) > length { hexStr = hexStr[len(hexStr)-length:] } return hexStr }