175 lines
5.7 KiB
Go
175 lines
5.7 KiB
Go
package system
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"kra/pkg/database/migration"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Migrations returns schema steps owned by the built-in system module.
|
|
// Administrators, menus, APIs, and policies are created only by SeedSystem
|
|
// during the explicit first-install flow.
|
|
func Migrations() []migration.Step {
|
|
return []migration.Step{
|
|
{
|
|
ID: "202608200002_system_schema",
|
|
Migrate: func(db *gorm.DB) error {
|
|
return migration.CreateMissingTables(db,
|
|
&userPO{}, &authorityPO{}, &menuPO{}, &userAuthorityPO{}, &authorityMenuPO{}, &menuParameterPO{},
|
|
&apiPO{}, &ignoredAPIPO{}, &authorityAPIPO{}, &casbinRulePO{}, &menuButtonPO{}, &authorityButtonPO{},
|
|
&departmentPO{}, &positionPO{}, &userDepartmentPO{}, &userPositionPO{}, &authorityDepartmentPO{},
|
|
&dictionaryPO{}, &dictionaryDetailPO{}, ¶meterPO{}, &apiTokenPO{}, &jwtBlacklistPO{}, &SecurityConfigPO{},
|
|
&versionPO{}, &exportTemplatePO{}, &exportConditionPO{}, &exportJoinPO{},
|
|
&operationPO{}, &loginLogPO{}, &DataAccessLogPO{}, &errorRecordPO{},
|
|
&mediaPO{}, &categoryPO{}, &uploadSessionPO{}, &uploadChunkPO{},
|
|
&announcementPO{},
|
|
)
|
|
},
|
|
},
|
|
{ID: "202608210002_communication_surface", Migrate: ensureCommunicationSurface},
|
|
{ID: "202608210003_communication_test_surface", Migrate: ensureCommunicationTestSurface},
|
|
}
|
|
}
|
|
|
|
func ensureCommunicationSurface(db *gorm.DB) error {
|
|
if db == nil || !db.Migrator().HasTable(&menuPO{}) || !db.Migrator().HasTable(&apiPO{}) {
|
|
return nil
|
|
}
|
|
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
var parent menuPO
|
|
if err := tx.Where("name = ?", "extensions").First(&parent).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
menu := menuPO{
|
|
MenuLevel: 1,
|
|
ParentID: parent.ID,
|
|
Path: "integrationConfig",
|
|
Name: "integrationConfig",
|
|
Component: "view/systemTools/integration/config.vue",
|
|
Title: "通信集成",
|
|
Icon: "connection",
|
|
Sort: 8,
|
|
}
|
|
var current menuPO
|
|
err := tx.Where("name = ?", menu.Name).First(¤t).Error
|
|
switch {
|
|
case errors.Is(err, gorm.ErrRecordNotFound):
|
|
if err = tx.Create(&menu).Error; err != nil {
|
|
return err
|
|
}
|
|
case err != nil:
|
|
return err
|
|
default:
|
|
if err = tx.Model(¤t).Updates(map[string]any{
|
|
"menu_level": menu.MenuLevel,
|
|
"parent_id": menu.ParentID,
|
|
"path": menu.Path,
|
|
"component": menu.Component,
|
|
"title": menu.Title,
|
|
"icon": menu.Icon,
|
|
"sort": menu.Sort,
|
|
}).Error; err != nil {
|
|
return err
|
|
}
|
|
menu.ID = current.ID
|
|
}
|
|
|
|
apis := []apiPO{
|
|
{Path: "/integration/configs/:kind", Method: "GET", APIGroup: "集成配置", Description: "按类型获取集成配置"},
|
|
{Path: "/integration/configs/:kind/:provider", Method: "GET", APIGroup: "集成配置", Description: "获取指定集成配置"},
|
|
{Path: "/integration/configs/:kind/:provider", Method: "PUT", APIGroup: "集成配置", Description: "保存集成配置"},
|
|
{Path: "/integration/configs/:kind/:provider/test", Method: "POST", APIGroup: "集成配置", Description: "测试通信集成连接"},
|
|
{Path: "/integration/configs/:kind/:provider", Method: "DELETE", APIGroup: "集成配置", Description: "删除集成配置"},
|
|
}
|
|
for _, api := range apis {
|
|
if err := tx.Where("path = ? AND method = ?", api.Path, api.Method).FirstOrCreate(&api).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if !tx.Migrator().HasTable(&authorityPO{}) || !tx.Migrator().HasTable(&authorityMenuPO{}) || !tx.Migrator().HasTable(&casbinRulePO{}) {
|
|
return nil
|
|
}
|
|
var authority authorityPO
|
|
if err := tx.Where("authority_id = ?", 888).First(&authority).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
var linkCount int64
|
|
if err := tx.Model(&authorityMenuPO{}).Where("sys_authority_authority_id = ? AND sys_base_menu_id = ?", authority.AuthorityID, menu.ID).Count(&linkCount).Error; err != nil {
|
|
return err
|
|
}
|
|
if linkCount == 0 {
|
|
if err := tx.Create(&authorityMenuPO{SysAuthorityAuthorityID: authority.AuthorityID, SysBaseMenuID: menu.ID}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, api := range apis {
|
|
exists, err := policyExists(tx, authority.AuthorityID, api.Path, api.Method)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exists {
|
|
rule := newPolicyRule(authority.AuthorityID, api.Path, api.Method)
|
|
if err := tx.Create(&rule).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func ensureCommunicationTestSurface(db *gorm.DB) error {
|
|
if db == nil || !db.Migrator().HasTable(&menuPO{}) || !db.Migrator().HasTable(&apiPO{}) {
|
|
return nil
|
|
}
|
|
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
var existingMenus int64
|
|
if err := tx.Model(&menuPO{}).Where("name IN ?", []string{"extensions", "integrationConfig"}).Count(&existingMenus).Error; err != nil {
|
|
return err
|
|
}
|
|
if existingMenus == 0 {
|
|
return nil
|
|
}
|
|
api := apiPO{
|
|
Path: "/integration/configs/:kind/:provider/test",
|
|
Method: "POST",
|
|
APIGroup: "集成配置",
|
|
Description: "测试通信集成连接",
|
|
}
|
|
if err := tx.Where("path = ? AND method = ?", api.Path, api.Method).FirstOrCreate(&api).Error; err != nil {
|
|
return err
|
|
}
|
|
if !tx.Migrator().HasTable(&authorityPO{}) || !tx.Migrator().HasTable(&casbinRulePO{}) {
|
|
return nil
|
|
}
|
|
var authority authorityPO
|
|
if err := tx.Where("authority_id = ?", 888).First(&authority).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
exists, err := policyExists(tx, authority.AuthorityID, api.Path, api.Method)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if exists {
|
|
return nil
|
|
}
|
|
rule := newPolicyRule(authority.AuthorityID, api.Path, api.Method)
|
|
return tx.Create(&rule).Error
|
|
})
|
|
}
|