This commit is contained in:
xinyu 2026-03-19 22:51:31 +08:00
parent 6fff6d35a5
commit 7fc841a3a5
12 changed files with 146 additions and 161 deletions

View File

@ -0,0 +1,3 @@
{
"deviceId": "8f56238c248b96b6f8b965c2f2f9b847422004bbab8228a7ca739364e20175e1"
}

View File

@ -65,7 +65,7 @@ func authorize() gin.HandlerFunc {
}
permissionCode := c.Request.Method + ":" + fullPath
defined, err := service.RbacPermissionDefined(permissionCode)
defined, err := service.RolePermissionDefined(permissionCode)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"data": "权限校验失败",
@ -77,27 +77,14 @@ func authorize() gin.HandlerFunc {
return
}
roleID, found, err := service.RbacUserRoleIDByUserID(u.ID)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"data": "权限校验失败",
})
return
}
if !found {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"data": "无效TOKEN, 请重新登录!",
})
return
}
if roleID == nil || *roleID == "" {
if u.RoleID == "" {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"data": "无权限访问",
})
return
}
allowed, err := service.RbacRoleHasPermission(roleID, permissionCode)
allowed, err := service.RoleHasPermission(&u.RoleID, permissionCode)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"data": "权限校验失败",

View File

@ -105,12 +105,12 @@ func ProjectCreate(c *gin.Context) {
p.CompletedAt = completedAt
}
out, err := service.ProjectCreateProject(p)
out, err := service.ProjectCreate(p)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"data": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"project": out})
c.JSON(http.StatusOK, gin.H{"data": out})
}
func ProjectUpdate(c *gin.Context) {
@ -189,7 +189,7 @@ func ProjectUpdate(c *gin.Context) {
patch.Remark = *req.Remark
}
out, err := service.ProjectUpdateProject(id, patch)
out, err := service.ProjectUpdate(id, patch)
if err != nil {
if err == service.ErrNotFound {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"data": "不存在"})
@ -198,12 +198,13 @@ func ProjectUpdate(c *gin.Context) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"data": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"project": out})
c.JSON(http.StatusOK, gin.H{"data": out})
}
func ProjectDelete(c *gin.Context) {
usr := currentUser(c)
id := c.Param("id")
if err := service.ProjectDelete(id); err != nil {
if err := service.ProjectDelete(usr, &id); err != nil {
if err == service.ErrNotFound {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"data": "不存在"})
return
@ -242,7 +243,7 @@ func ProjectList(c *gin.Context) {
kw = &keyword
}
items, total, err := service.ProjectList(oid, kw, page, size)
items, total, err := service.ProjectPage(oid, kw, page, size)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"data": "查询失败"})
return

View File

@ -1,45 +1,41 @@
package model
import "time"
import (
"time"
"gorm.io/gorm"
)
type Device struct {
ID string `json:"id" gorm:"type:varchar(32);primaryKey"`
Name string `json:"name" gorm:"type:varchar(128);not null"`
ModelID string `json:"modelId" gorm:"type:varchar(32);index"`
SerialNo string `json:"serialNo" gorm:"type:varchar(64);index"`
StatusCode string `json:"statusCode" gorm:"type:varchar(64);not null;index"`
PointID string `json:"pointId" gorm:"type:varchar(32);index"`
InstalledAt *time.Time `json:"installedAt"`
InstalledImage string `json:"installedImage" gorm:"type:text;not null"`
Channel1ParamID string `json:"channel1ParamId" gorm:"type:varchar(32);index"`
Channel2ParamID string `json:"channel2ParamId" gorm:"type:varchar(32);index"`
Channel3ParamID string `json:"channel3ParamId" gorm:"type:varchar(32);index"`
CreatorUserID string `json:"creatorUserId" gorm:"type:varchar(32);not null;index"`
Remark string `json:"remark" gorm:"type:varchar(255);default:''"`
Deleted bool `json:"deleted" gorm:"not null;default:false;index"`
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
Name string `json:"name" gorm:"type:varchar(128);not null"`
ModelID string `json:"modelId" gorm:"type:varchar(32);index"`
SerialNo string `json:"serialNo" gorm:"type:varchar(64);index"`
StatusCode string `json:"statusCode" gorm:"type:varchar(64);not null;index"`
PointID string `json:"pointId" gorm:"type:varchar(32);index"`
InstalledAt *time.Time `json:"installedAt"`
InstalledImage string `json:"installedImage" gorm:"type:text;not null"`
Channel1ParamID string `json:"channel1ParamId" gorm:"type:varchar(32);index"`
Channel2ParamID string `json:"channel2ParamId" gorm:"type:varchar(32);index"`
Channel3ParamID string `json:"channel3ParamId" gorm:"type:varchar(32);index"`
CreatorUserID string `json:"creatorUserId" gorm:"type:varchar(32);not null;index"`
Remark string `json:"remark" gorm:"type:varchar(255);default:''"`
DeletedAt gorm.DeletedAt `gorm:"index"`
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
}
type DeviceIngestData struct {
ID string `json:"id" gorm:"type:varchar(32);primaryKey"`
DeviceID string `json:"deviceId" gorm:"type:varchar(32);not null;index"`
PointID string `json:"pointId" gorm:"type:varchar(32);not null;index"`
Raw1 string `json:"raw1" gorm:"type:varchar(64);default:''"`
Raw2 string `json:"raw2" gorm:"type:varchar(64);default:''"`
Raw3 string `json:"raw3" gorm:"type:varchar(64);default:''"`
Value1 string `json:"value1" gorm:"type:varchar(64);default:''"`
Value2 string `json:"value2" gorm:"type:varchar(64);default:''"`
Value3 string `json:"value3" gorm:"type:varchar(64);default:''"`
CollectedAt time.Time `json:"collectedAt" gorm:"not null;index"`
Deleted bool `json:"deleted" gorm:"not null;default:false;index"`
ID string `json:"id" gorm:"type:varchar(32);primaryKey"`
DeviceID string `json:"deviceId" gorm:"type:varchar(32);not null;index"`
PointID string `json:"pointId" gorm:"type:varchar(32);not null;index"`
Raw1 string `json:"raw1" gorm:"type:varchar(64);default:''"`
Raw2 string `json:"raw2" gorm:"type:varchar(64);default:''"`
Raw3 string `json:"raw3" gorm:"type:varchar(64);default:''"`
Value1 string `json:"value1" gorm:"type:varchar(64);default:''"`
Value2 string `json:"value2" gorm:"type:varchar(64);default:''"`
Value3 string `json:"value3" gorm:"type:varchar(64);default:''"`
CollectedAt time.Time `json:"collectedAt" gorm:"not null;index"`
DeletedAt gorm.DeletedAt `gorm:"index"`
}

View File

@ -1,32 +1,31 @@
package model
import "time"
import (
"time"
"gorm.io/gorm"
)
type Project struct {
ID string `json:"id" gorm:"type:varchar(32);primaryKey"`
ProjectNo string `json:"projectNo" gorm:"type:varchar(32);not null;uniqueIndex"`
Name string `json:"name" gorm:"type:varchar(100);not null"`
TypeCode string `json:"typeCode" gorm:"type:varchar(64);not null;index"`
BuildingIDs string `json:"buildingIds" gorm:"type:text;not null"`
StatusCode string `json:"statusCode" gorm:"type:varchar(64);not null;index"`
ResponsibleOrgID string `json:"responsibleOrgId" gorm:"type:varchar(32);not null;index"`
ImplementOrgIDs string `json:"implementOrgIds" gorm:"type:text;not null"`
LeaderPersonID string `json:"leaderPersonId" gorm:"type:varchar(32);not null;index"`
ParticipantPersonIDs string `json:"participantPersonIds" gorm:"type:text;not null"`
StartAt time.Time `json:"startAt" gorm:"not null;index"`
EndAt time.Time `json:"endAt" gorm:"not null;index"`
CompletedAt *time.Time `json:"completedAt"`
Description string `json:"description" gorm:"type:text;not null"`
Attachments string `json:"attachments" gorm:"type:text;not null"`
OrgID string `json:"orgId" gorm:"type:varchar(32);not null;index"`
CreatorUserID string `json:"creatorUserId" gorm:"type:varchar(32);not null;index"`
Remark string `json:"remark" gorm:"type:varchar(255);default:''"`
Deleted bool `json:"deleted" gorm:"not null;default:false;index"`
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
ID string `json:"id" gorm:"type:varchar(32);primaryKey"`
ProjectNo string `json:"projectNo" gorm:"type:varchar(32);not null;uniqueIndex"`
Name string `json:"name" gorm:"type:varchar(100);not null"`
TypeCode string `json:"typeCode" gorm:"type:varchar(64);not null;index"`
BuildingIDs string `json:"buildingIds" gorm:"type:text;not null"`
StatusCode string `json:"statusCode" gorm:"type:varchar(64);not null;index"`
ResponsibleOrgID string `json:"responsibleOrgId" gorm:"type:varchar(32);not null;index"`
ImplementOrgIDs string `json:"implementOrgIds" gorm:"type:text;not null"`
LeaderPersonID string `json:"leaderPersonId" gorm:"type:varchar(32);not null;index"`
ParticipantPersonIDs string `json:"participantPersonIds" gorm:"type:text;not null"`
StartAt time.Time `json:"startAt" gorm:"not null;index"`
EndAt time.Time `json:"endAt" gorm:"not null;index"`
CompletedAt *time.Time `json:"completedAt"`
Description string `json:"description" gorm:"type:text;not null"`
Attachments string `json:"attachments" gorm:"type:text;not null"`
OrgID string `json:"orgId" gorm:"type:varchar(32);not null;index"`
CreatorUserID string `json:"creatorUserId" gorm:"type:varchar(32);not null;index"`
Remark string `json:"remark" gorm:"type:varchar(255);default:''"`
DeletedAt gorm.DeletedAt `gorm:"index"`
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
}

View File

@ -9,4 +9,6 @@ type User struct {
RoleID string `json:"roleId" gorm:"type:varchar(32);index"`
Role Role `json:"role" gorm:"foreignKey:RoleID;references:ID"`
OrgID string `json:"orgId" gorm:"type:varchar(32);not null;index"`
CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime;"`
UpdatedAt int64 `json:"updatedAt" gorm:"autoUpdateTime;"`
}

View File

@ -20,38 +20,36 @@ func ProjectUpdate(p *model.Project) (bool, error) {
if err != nil {
return false, err
}
tx := db.Model(&model.Project{}).Where("id = ? AND deleted = false", p.ID).Updates(p)
tx := db.Model(&model.Project{}).Where("id = ? AND deleted_at = ?", p.ID).Updates(p)
if tx.Error != nil {
return false, tx.Error
}
return tx.RowsAffected > 0, nil
}
func ProjectDelete(id *string) (bool, error) {
func ProjectDelete(id *string) error {
db, err := newDB()
if err != nil {
return false, err
return err
}
tx := db.Model(&model.Project{}).Where("id = ? AND deleted = false", *id).Update("deleted", true)
if tx.Error != nil {
return false, tx.Error
if err := db.Model(&model.Project{}).Where("id = ?", *id).Delete(&model.Project{}).Error; err != nil {
return err
}
return tx.RowsAffected > 0, nil
return nil
}
func ProjectByID(id *string) (*model.Project, bool, error) {
func ProjectFirst(id *string) (*model.Project, error) {
db, err := newDB()
if err != nil {
return nil, false, err
return nil, err
}
var p model.Project
if err := db.Where("id = ? AND deleted = false", *id).First(&p).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
if err := db.Where("id = ?", *id).First(&p).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
return nil, false, err
}
return &p, true, nil
return &p, nil
}
func ProjectList(orgID, keyword *string, offset, limit *int) ([]model.Project, int64, error) {
@ -60,7 +58,7 @@ func ProjectList(orgID, keyword *string, offset, limit *int) ([]model.Project, i
return nil, 0, err
}
q := db.Model(&model.Project{}).Where("deleted = false")
q := db.Model(&model.Project{})
if orgID != nil && *orgID != "" {
q = q.Where("org_id = ?", *orgID)
}

View File

@ -1,6 +1,11 @@
package mysql
import "myschools.me/heritage/heritage-api/model"
import (
"errors"
"gorm.io/gorm"
"myschools.me/heritage/heritage-api/model"
)
func RolePermissionsList(roleID *string) ([]string, error) {
db, err := newDB()
@ -15,6 +20,21 @@ func RolePermissionsList(roleID *string) ([]string, error) {
return codes, nil
}
func RoleFirst(userID *string) (*model.User, error) {
db, err := newDB()
if err != nil {
return nil, err
}
var u model.User
if err := db.Select("id", "role_id").Where("id = ?", *userID).First(&u).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
return &u, nil
}
func RoleHasPermission(roleID, permissionCode *string) (bool, error) {
db, err := newDB()
if err != nil {

View File

@ -1,8 +1,6 @@
package mysql
import (
"errors"
"gorm.io/gorm"
"myschools.me/heritage/heritage-api/model"
)
@ -38,22 +36,6 @@ func UserFirst(userID *string) (*model.User, error) {
return &u, nil
}
func UserRoleIDByUserID(userID *string) (*string, bool, error) {
db, err := newDB()
if err != nil {
return nil, false, err
}
var u model.User
if err := db.Select("id", "role_id").Where("id = ?", *userID).First(&u).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, err
}
return &u.RoleID, true, nil
}
func UserCount() (*int64, error) {
db, err := newDB()
if err != nil {

View File

@ -9,7 +9,7 @@ import (
"myschools.me/heritage/heritage-api/mysql"
)
func ProjectCreateProject(p *model.Project) (*model.Project, error) {
func ProjectCreate(p *model.Project) (*model.Project, error) {
if p == nil {
return nil, errors.New("invalid project")
}
@ -47,29 +47,29 @@ func ProjectCreateProject(p *model.Project) (*model.Project, error) {
if err := mysql.ProjectCreate(p); err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectCreateProject",
"func": "ProjectCreate",
}).Warnf("mysql.ProjectCreate: %v", err)
return nil, err
}
return p, nil
}
func ProjectUpdateProject(idv string, patch *model.Project) (*model.Project, error) {
func ProjectUpdate(idv string, patch *model.Project) (*model.Project, error) {
pid := strings.TrimSpace(idv)
if pid == "" {
return nil, ErrNotFound
}
existing, found, err := mysql.ProjectByID(&pid)
existing, err := mysql.ProjectFirst(&pid)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectUpdateProject",
}).Warnf("mysql.ProjectByID: %v", err)
"func": "ProjectUpdate",
}).Warnf("mysql.ProjectFirst: %v", err)
return nil, err
}
if !found || existing == nil {
if existing == nil || existing.ID == "" {
logrus.WithFields(logrus.Fields{
"func": "ProjectUpdateProject",
}).Warnf("mysql.ProjectByID: not found")
"func": "ProjectUpdate",
}).Warnf("mysql.ProjectFirst: not found")
return nil, ErrNotFound
}
if patch == nil {
@ -135,37 +135,38 @@ func ProjectUpdateProject(idv string, patch *model.Project) (*model.Project, err
ok, err := mysql.ProjectUpdate(existing)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectUpdateProject",
"func": "ProjectUpdate",
}).Warnf("mysql.ProjectUpdate: %v", err)
return nil, err
}
if !ok {
logrus.WithFields(logrus.Fields{
"func": "ProjectUpdateProject",
"func": "ProjectUpdate",
}).Warnf("mysql.ProjectUpdate: not found")
return nil, ErrNotFound
}
return existing, nil
}
func ProjectDelete(idv string) error {
pid := strings.TrimSpace(idv)
if pid == "" {
return ErrNotFound
}
ok, err := mysql.ProjectDelete(&pid)
func ProjectDelete(usr *model.User, pid *string) error {
project, err := mysql.ProjectFirst(pid)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectDelete",
}).Warnf("mysql.ProjectFirst: %v", err)
return err
}
if project.OrgID != usr.OrgID {
return errors.New("not in org")
}
if err := mysql.ProjectDelete(pid); err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectDelete",
}).Warnf("mysql.ProjectDelete: %v", err)
return err
}
if !ok {
logrus.WithFields(logrus.Fields{
"func": "ProjectDelete",
}).Warnf("mysql.ProjectDelete: not found")
return ErrNotFound
}
return nil
}
@ -174,23 +175,23 @@ func ProjectGet(idv string) (*model.Project, error) {
if pid == "" {
return nil, ErrNotFound
}
p, found, err := mysql.ProjectByID(&pid)
p, err := mysql.ProjectFirst(&pid)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "ProjectGet",
}).Warnf("mysql.ProjectByID: %v", err)
}).Warnf("mysql.ProjectFirst: %v", err)
return nil, err
}
if !found || p == nil {
if p == nil || p.ID == "" {
logrus.WithFields(logrus.Fields{
"func": "ProjectGet",
}).Warnf("mysql.ProjectByID: not found")
}).Warnf("mysql.ProjectFirst: not found")
return nil, ErrNotFound
}
return p, nil
}
func ProjectList(orgID, keyword *string, page, size int) ([]model.Project, int64, error) {
func ProjectPage(orgID, keyword *string, page, size int) ([]model.Project, int64, error) {
if page < 1 {
page = 1
}

View File

@ -1,15 +0,0 @@
package service
import "myschools.me/heritage/heritage-api/mysql"
func RbacPermissionDefined(permissionCode string) (bool, error) {
return mysql.PermissionDefined(&permissionCode)
}
func RbacUserRoleIDByUserID(userID string) (*string, bool, error) {
return mysql.UserRoleIDByUserID(&userID)
}
func RbacRoleHasPermission(roleID *string, permissionCode string) (bool, error) {
return mysql.RoleHasPermission(roleID, &permissionCode)
}

11
service/role-service.go Normal file
View File

@ -0,0 +1,11 @@
package service
import "myschools.me/heritage/heritage-api/mysql"
func RolePermissionDefined(permissionCode string) (bool, error) {
return mysql.PermissionDefined(&permissionCode)
}
func RoleHasPermission(roleID *string, permissionCode string) (bool, error) {
return mysql.RoleHasPermission(roleID, &permissionCode)
}