This commit is contained in:
panda
2024-06-06 20:36:50 +08:00
parent 14c5b453b6
commit 41b61ebf1e
19 changed files with 41 additions and 288 deletions

View File

@@ -11,9 +11,9 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
"pandax/kit/utils"
"pandax/pkg/cache"
"pandax/pkg/global"
model2 "pandax/pkg/global/model"
"pandax/pkg/shadow"
"strings"
"time"
@@ -184,7 +184,7 @@ func (p *DeviceApi) InsertDevice(rc *restfulx.ReqCtx) {
data.OrgId = rc.LoginAccount.OrganizationId
list, _ := p.DeviceApp.FindList(entity.Device{Name: data.Name})
biz.IsTrue(!(list != nil && len(*list) > 0), fmt.Sprintf("名称%s已存在设置其他命名", data.Name))
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
data.LinkStatus = global.INACTIVE
data.LastAt = time.Now()
data.Protocol = product.ProtocolName

View File

@@ -7,8 +7,8 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
"pandax/kit/utils"
"pandax/pkg/global"
model2 "pandax/pkg/global/model"
"strings"
"time"
@@ -50,7 +50,7 @@ func (p *DeviceCmdLogApi) InsertDeviceCmdLog(rc *restfulx.ReqCtx) {
err := json.Unmarshal([]byte(data.CmdContent), &ms)
biz.ErrIsNil(err, "指令格式不正确")
biz.IsTrue(len(ms) > 0, "指令格式不正确")
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
data.State = "2"
data.RequestTime = time.Now().Format("2006-01-02 15:04:05")
go func() {

View File

@@ -5,7 +5,7 @@ import (
"pandax/apps/device/services"
"pandax/kit/biz"
"pandax/kit/restfulx"
"pandax/pkg/global/model"
"pandax/kit/utils"
"strings"
)
@@ -80,7 +80,7 @@ func (p *DeviceGroupApi) GetDeviceGroup(rc *restfulx.ReqCtx) {
func (p *DeviceGroupApi) InsertDeviceGroup(rc *restfulx.ReqCtx) {
var data entity.DeviceGroup
restfulx.BindJsonAndValid(rc, &data)
data.Id = model.GenerateID()
data.Id = utils.GenerateID()
data.Owner = rc.LoginAccount.UserName
data.OrgId = rc.LoginAccount.OrganizationId
p.DeviceGroupApp.Insert(data)

View File

@@ -10,9 +10,9 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
"pandax/kit/utils"
"pandax/pkg/cache"
"pandax/pkg/global"
model2 "pandax/pkg/global/model"
"strings"
"pandax/apps/device/entity"
@@ -107,7 +107,7 @@ func (p *ProductApi) GetProduct(rc *restfulx.ReqCtx) {
func (p *ProductApi) InsertProduct(rc *restfulx.ReqCtx) {
var data entity.Product
restfulx.BindJsonAndValid(rc, &data)
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
data.Owner = rc.LoginAccount.UserName
data.OrgId = rc.LoginAccount.OrganizationId
// 如果未设置规则链,默认为主链

View File

@@ -5,7 +5,7 @@ import (
"pandax/apps/device/services"
"pandax/kit/biz"
"pandax/kit/restfulx"
"pandax/pkg/global/model"
"pandax/kit/utils"
"strings"
)
@@ -66,7 +66,7 @@ func (p *ProductCategoryApi) GetProductCategory(rc *restfulx.ReqCtx) {
func (p *ProductCategoryApi) InsertProductCategory(rc *restfulx.ReqCtx) {
var data entity.ProductCategory
restfulx.BindJsonAndValid(rc, &data)
data.Id = model.GenerateID()
data.Id = utils.GenerateID()
data.Owner = rc.LoginAccount.UserName
data.OrgId = rc.LoginAccount.OrganizationId
p.ProductCategoryApp.Insert(data)

View File

@@ -5,7 +5,7 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
model2 "pandax/pkg/global/model"
"pandax/kit/utils"
"pandax/pkg/tool"
"path"
"strings"
@@ -53,7 +53,7 @@ func (p *ProductOtaApi) InsertProductOta(rc *restfulx.ReqCtx) {
// 生成文件MD5值
md5, err := tool.GetFileMd5(path.Join(filePath, data.Url))
biz.ErrIsNil(err, "读取文件md5校验值错误")
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
data.Check = md5
p.ProductOtaApp.Insert(data)
}

View File

@@ -4,8 +4,8 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
"pandax/kit/utils"
"pandax/pkg/global"
model2 "pandax/pkg/global/model"
"strings"
"pandax/apps/device/entity"
@@ -58,7 +58,7 @@ func (p *ProductTemplateApi) GetProductTemplate(rc *restfulx.ReqCtx) {
func (p *ProductTemplateApi) InsertProductTemplate(rc *restfulx.ReqCtx) {
var data entity.ProductTemplate
restfulx.BindJsonAndValid(rc, &data)
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
if data.Classify == entity.ATTRIBUTES_TSL || data.Classify == entity.TELEMETRY_TSL {
// 向超级表及子表中添加字段
len := 100

View File

@@ -8,7 +8,7 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
model2 "pandax/pkg/global/model"
"pandax/kit/utils"
"strings"
)
@@ -19,7 +19,7 @@ type JobApi struct {
func (j *JobApi) CreateJob(rc *restfulx.ReqCtx) {
var job entity.SysJob
restfulx.BindQuery(rc, &job)
job.Id = model2.GenerateID()
job.Id = utils.GenerateID()
job.Owner = rc.LoginAccount.UserName
job.OrgId = rc.LoginAccount.OrganizationId
_, err := j.JobApp.Insert(job)

View File

@@ -6,8 +6,8 @@ import (
logEntity "pandax/apps/job/entity"
"pandax/apps/job/services"
logServices "pandax/apps/job/services"
"pandax/kit/utils"
"pandax/pkg/global"
"pandax/pkg/global/model"
"sync"
"time"
@@ -52,7 +52,7 @@ type ExecJob struct {
func (e *ExecJob) Run() {
startTime := time.Now()
jobLog := logEntity.JobLog{Name: e.Name, EntryId: e.EntryId, TargetInvoke: e.InvokeTarget, Status: "0"}
jobLog.Id = model.GenerateID()
jobLog.Id = utils.GenerateID()
jobLog.OrgId = e.OrgId
jobLog.Owner = e.Owner
var obj = jobList[e.InvokeTarget]

View File

@@ -6,7 +6,7 @@ import (
"pandax/kit/biz"
"pandax/kit/model"
"pandax/kit/restfulx"
model2 "pandax/pkg/global/model"
"pandax/kit/utils"
"pandax/pkg/rule_engine"
"strings"
)
@@ -81,7 +81,7 @@ func (p *RuleChainApi) GetRuleChain(rc *restfulx.ReqCtx) {
func (p *RuleChainApi) InsertRuleChain(rc *restfulx.ReqCtx) {
var data entity.RuleChain
restfulx.BindJsonAndValid(rc, &data)
data.Id = model2.GenerateID()
data.Id = utils.GenerateID()
data.Owner = rc.LoginAccount.UserName
data.OrgId = rc.LoginAccount.OrganizationId
_, err := p.RuleChainApp.Insert(data)
@@ -112,7 +112,7 @@ func (p *RuleChainApi) CloneRuleChain(rc *restfulx.ReqCtx) {
one, err := p.RuleChainApp.FindOne(id)
biz.ErrIsNil(err, "规则链不存在")
one.RuleName = one.RuleName + "-克隆"
one.Id = model2.GenerateID()
one.Id = utils.GenerateID()
one.Root = "0"
_, err = p.RuleChainApp.Insert(*one)
biz.ErrIsNil(err, "克隆规则链失败")

View File

@@ -5,6 +5,7 @@ import (
"pandax/apps/device/entity"
"pandax/apps/device/services"
"pandax/iothub/server/emqxserver/protobuf"
"pandax/kit/utils"
"pandax/pkg/cache"
"pandax/pkg/global"
"pandax/pkg/global/model"
@@ -111,7 +112,7 @@ func CreateSubTableField(productId, ty string, fields map[string]interface{}) {
}
tsl := entity.ProductTemplate{}
tsl.Pid = productId
tsl.Id = model.GenerateID()
tsl.Id = utils.GenerateID()
tsl.Name = key
tsl.Type = interfaceType
tsl.Key = key

View File

@@ -1,96 +0,0 @@
package ginx
import (
"encoding/json"
"net/http"
"pandax/kit/biz"
"pandax/kit/logger"
"pandax/kit/model"
"strconv"
"github.com/gin-gonic/gin"
)
// 绑定并校验请求结构体参数 结构体添加 例如: binding:"required" 或binding:"required,gt=10"
func BindJsonAndValid(g *gin.Context, data any) {
if err := g.ShouldBindJSON(data); err != nil {
panic(any(biz.NewBizErr("传参格式错误:" + err.Error())))
}
}
// 绑定查询字符串到
func BindQuery(g *gin.Context, data any) {
if err := g.ShouldBindQuery(data); err != nil {
panic(any(biz.NewBizErr(err.Error())))
}
}
func ParamsToAny(g *gin.Context, in any) {
vars := make(map[string]any)
for _, v := range g.Params {
vars[v.Key] = v.Value
}
marshal, _ := json.Marshal(vars)
err := json.Unmarshal(marshal, in)
biz.ErrIsNil(err, "error get path value encoding unmarshal")
return
}
// 获取分页参数
func GetPageParam(g *gin.Context) *model.PageParam {
return &model.PageParam{PageNum: QueryInt(g, "pageNum", 1), PageSize: QueryInt(g, "pageSize", 10)}
}
// 获取查询参数中指定参数值并转为int
func QueryInt(g *gin.Context, qm string, defaultInt int) int {
qv := g.Query(qm)
if qv == "" {
return defaultInt
}
qvi, err := strconv.Atoi(qv)
biz.ErrIsNil(err, "query param not int")
return qvi
}
// 获取路径参数
func PathParamInt(g *gin.Context, pm string) int {
value, _ := strconv.Atoi(g.Param(pm))
return value
}
// 文件下载
func Download(g *gin.Context, filename string) {
g.Writer.Header().Add("success", "true")
g.Writer.Header().Set("Content-Length", "-1")
g.Writer.Header().Set("Content-Disposition", "attachment; filename="+filename)
g.File(filename)
}
// 返回统一成功结果
func SuccessRes(g *gin.Context, data any) {
g.JSON(http.StatusOK, model.Success(data))
}
// 返回失败结果集
func ErrorRes(g *gin.Context, err any) {
if err != nil {
}
switch t := err.(type) {
case *biz.BizError:
g.JSON(http.StatusOK, model.Error(t))
break
case error:
g.JSON(http.StatusOK, model.ServerError())
logger.Log.Error(t)
// panic(err)
break
case string:
g.JSON(http.StatusOK, model.ServerError())
logger.Log.Error(t)
// panic(err)
break
default:
logger.Log.Error(t)
}
}

View File

@@ -1,15 +0,0 @@
package ginx
type LogInfo struct {
LogResp bool // 是否记录返回结果
Description string // 请求描述
}
func NewLogInfo(description string) *LogInfo {
return &LogInfo{Description: description, LogResp: false}
}
func (i *LogInfo) WithLogResp(logResp bool) *LogInfo {
i.LogResp = logResp
return i
}

View File

@@ -1,16 +0,0 @@
package ginx
type Permission struct {
NeedToken bool // 是否需要token
NeedCasbin bool // 是否进行权限 api路径权限验证
}
func (p *Permission) WithNeedToken(needToken bool) *Permission {
p.NeedToken = needToken
return p
}
func (p *Permission) WithNeedCasBin(needCasBin bool) *Permission {
p.NeedCasbin = needCasBin
return p
}

View File

@@ -1,124 +0,0 @@
package ginx
import (
"pandax/kit/biz"
"pandax/kit/token"
"time"
"github.com/gin-gonic/gin"
)
// 处理函数
type HandlerFunc func(*ReqCtx)
type ReqCtx struct {
GinCtx *gin.Context // gin context
// NeedToken bool // 是否需要token
RequiredPermission *Permission // 需要的权限信息默认为nil需要校验token
LoginAccount *token.Claims // 登录账号信息只有校验token后才会有值
LogInfo *LogInfo // 日志相关信息
ReqParam any // 请求参数,主要用于记录日志
ResData any // 响应结果
Err any // 请求错误
Timed int64 // 执行时间
noRes bool // 无需返回结果,即文件下载等
}
func (rc *ReqCtx) Handle(handler HandlerFunc) {
ginCtx := rc.GinCtx
defer func() {
var err any
err = recover()
if err != nil {
rc.Err = err
ErrorRes(ginCtx, err)
}
// 应用所有请求后置处理器
ApplyHandlerInterceptor(afterHandlers, rc)
}()
biz.IsTrue(ginCtx != nil, "ginContext == nil")
// 默认为不记录请求参数可在handler回调函数中覆盖赋值
rc.ReqParam = 0
// 默认响应结果为nil可在handler中赋值
rc.ResData = nil
// 调用请求前所有处理器
err := ApplyHandlerInterceptor(beforeHandlers, rc)
if err != nil {
panic(err)
}
begin := time.Now()
handler(rc)
rc.Timed = time.Now().Sub(begin).Milliseconds()
if !rc.noRes {
SuccessRes(ginCtx, rc.ResData)
}
}
func (rc *ReqCtx) Download(filename string) {
rc.noRes = true
Download(rc.GinCtx, filename)
}
// 新建请求上下文默认需要校验token
func NewReqCtx(g *gin.Context) *ReqCtx {
return &ReqCtx{GinCtx: g, LogInfo: NewLogInfo("默认日志信息"), RequiredPermission: &Permission{NeedToken: true, NeedCasbin: true}}
}
// 调用该方法设置请求描述,则默认记录日志,并不记录响应结果
func (r *ReqCtx) WithLog(model string) *ReqCtx {
r.LogInfo.Description = model
return r
}
// 设置请求上下文需要的权限信息
func (r *ReqCtx) WithRequiredPermission(permission *Permission) *ReqCtx {
r.RequiredPermission = permission
return r
}
// 是否需要token
func (r *ReqCtx) WithNeedToken(needToken bool) *ReqCtx {
r.RequiredPermission.NeedToken = needToken
return r
}
// 是否需要Casbin
func (r *ReqCtx) WithNeedCasbin(needCasbin bool) *ReqCtx {
r.RequiredPermission.NeedCasbin = needCasbin
return r
}
// 处理器拦截器函数
type HandlerInterceptorFunc func(*ReqCtx) error
type HandlerInterceptors []HandlerInterceptorFunc
var (
beforeHandlers HandlerInterceptors
afterHandlers HandlerInterceptors
)
// 使用前置处理器函数
func UseBeforeHandlerInterceptor(b HandlerInterceptorFunc) {
beforeHandlers = append(beforeHandlers, b)
}
// 使用后置处理器函数
func UseAfterHandlerInterceptor(b HandlerInterceptorFunc) {
afterHandlers = append(afterHandlers, b)
}
// 应用指定处理器拦截器,如果有一个错误则直接返回错误
func ApplyHandlerInterceptor(his HandlerInterceptors, rc *ReqCtx) any {
for _, handler := range his {
if err := handler(rc); err != nil {
return err
}
}
return nil
}

View File

@@ -2,9 +2,12 @@ package utils
import (
"bytes"
"encoding/base64"
"github.com/kakuilan/kgo"
"math/rand"
"strings"
"text/template"
"time"
)
func UnicodeIndex(str, substr string) int {
@@ -154,3 +157,13 @@ func OrganizationPCIds(orgIds []string, id int64, isP bool) []int64 {
return cRes
}
}
func GenerateID() string {
rand.Seed(time.Now().UnixNano())
id := make([]byte, 7) // 由于base64编码会增加字符数这里使用7个字节生成10位ID
_, err := rand.Read(id)
if err != nil {
panic(err) // 错误处理,根据实际情况进行处理
}
return base64.URLEncoding.EncodeToString(id)[:10]
}

View File

@@ -7,13 +7,11 @@ import (
"errors"
"github.com/google/uuid"
"gorm.io/gorm"
"math/rand"
"pandax/apps/system/entity"
"pandax/apps/system/services"
"pandax/pkg/cache"
"strconv"
"strings"
"time"
)
type DeviceAuth struct {
@@ -44,6 +42,7 @@ func (token *DeviceAuth) MD5ID() string {
access = strings.TrimRight(access, "=")
return access
}
func (token *DeviceAuth) GetMarshal() string {
marshal, _ := json.Marshal(*token)
return string(marshal)
@@ -82,12 +81,3 @@ func OrgAuthSet(tx *gorm.DB, roleId int64, owner string) error {
return nil
}
func GenerateID() string {
rand.Seed(time.Now().UnixNano())
id := make([]byte, 7) // 由于base64编码会增加字符数这里使用7个字节生成10位ID
_, err := rand.Read(id)
if err != nil {
panic(err) // 错误处理,根据实际情况进行处理
}
return base64.URLEncoding.EncodeToString(id)[:10]
}

View File

@@ -4,8 +4,8 @@ import (
"encoding/json"
"pandax/apps/device/entity"
"pandax/apps/device/services"
"pandax/kit/utils"
"pandax/pkg/global"
"pandax/pkg/global/model"
"pandax/pkg/rule_engine/message"
"time"
)
@@ -48,7 +48,7 @@ func (n *createAlarmNode) Handle(msg *message.Message) error {
}
} else {
alarm = &entity.DeviceAlarm{}
alarm.Id = model.GenerateID()
alarm.Id = utils.GenerateID()
alarm.DeviceId = msg.Metadata.GetValue("deviceId").(string)
alarm.ProductId = msg.Metadata.GetValue("productId").(string)
alarm.Name = msg.Metadata.GetValue("deviceName").(string)

View File

@@ -1,7 +1,7 @@
package tool
import (
"pandax/pkg/global/model"
"pandax/kit/utils"
"testing"
)
@@ -11,7 +11,7 @@ func TestToCamelCase(t *testing.T) {
}
func TestGenerateID(t *testing.T) {
id := model.GenerateID()
id := utils.GenerateID()
t.Log(id)
}