mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 优化同步逻辑
This commit is contained in:
parent
69b34e07c9
commit
8ff65af7bf
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "ddd",
|
"version": "0.1",
|
||||||
"tags": [
|
"tags": [
|
||||||
{
|
{
|
||||||
"key": "WebSite",
|
"key": "WebSite",
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"labelZh": "端口",
|
"labelZh": "端口",
|
||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 3306,
|
"default": 80,
|
||||||
"envKey": "PORT"
|
"envKey": "PORT"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import "github.com/1Panel-dev/1Panel/app/model"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/1Panel-dev/1Panel/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
type AppRes struct {
|
type AppRes struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@ -28,15 +31,22 @@ type AppList struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppDefine struct {
|
type AppDefine struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
Versions []string `json:"versions"`
|
Versions []string `json:"versions"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
ShortDesc string `json:"short_desc"`
|
ShortDesc string `json:"short_desc"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
Required []string `json:"Required"`
|
||||||
|
CrossVersionUpdate bool `json:"crossVersionUpdate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (define AppDefine) GetRequired() string {
|
||||||
|
by, _ := json.Marshal(define.Required)
|
||||||
|
return string(by)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
|
@ -2,14 +2,17 @@ package model
|
|||||||
|
|
||||||
type App struct {
|
type App struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||||
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"`
|
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"`
|
||||||
ShortDesc string `json:"shortDesc" gorm:"type:longtext;"`
|
ShortDesc string `json:"shortDesc" gorm:"type:longtext;"`
|
||||||
Icon string `json:"icon" gorm:"type:longtext;"`
|
Icon string `json:"icon" gorm:"type:longtext;"`
|
||||||
Author string `json:"author" gorm:"type:varchar(64);not null"`
|
Author string `json:"author" gorm:"type:varchar(64);not null"`
|
||||||
Source string `json:"source" gorm:"type:varchar(64);not null"`
|
Source string `json:"source" gorm:"type:varchar(64);not null"`
|
||||||
Type string `json:"type" gorm:"type:varchar(64);not null" `
|
Type string `json:"type" gorm:"type:varchar(64);not null"`
|
||||||
Details []*AppDetail `json:"-"`
|
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||||
TagsKey []string `json:"-" gorm:"-"`
|
Required string `json:"required" gorm:"type:varchar(64);not null"`
|
||||||
AppTags []AppTag `json:"-"`
|
CrossVersionUpdate bool `json:"crossVersionUpdate" gorm:"type:varchar(64);not null"`
|
||||||
|
Details []AppDetail `json:"-"`
|
||||||
|
TagsKey []string `json:"-" gorm:"-"`
|
||||||
|
AppTags []AppTag `json:"-" `
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,5 @@ type AppDetail struct {
|
|||||||
Params string `json:"-" gorm:"type:longtext;"`
|
Params string `json:"-" gorm:"type:longtext;"`
|
||||||
DockerCompose string `json:"-" gorm:"type:longtext;not null"`
|
DockerCompose string `json:"-" gorm:"type:longtext;not null"`
|
||||||
Readme string `json:"readme" gorm:"type:longtext;not null"`
|
Readme string `json:"readme" gorm:"type:longtext;not null"`
|
||||||
|
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,21 @@ func (a AppRepo) GetFirst(opts ...DBOption) (model.App, error) {
|
|||||||
return app, nil
|
return app, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppRepo) BatchCreate(ctx context.Context, apps []*model.App) error {
|
func (a AppRepo) GetBy(opts ...DBOption) ([]model.App, error) {
|
||||||
|
var apps []model.App
|
||||||
|
db := global.DB.Model(&model.App{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
if err := db.Preload("Details").Preload("AppTags").Find(&apps).Error; err != nil {
|
||||||
|
return apps, err
|
||||||
|
}
|
||||||
|
return apps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AppRepo) BatchCreate(ctx context.Context, apps []model.App) error {
|
||||||
db := ctx.Value("db").(*gorm.DB)
|
db := ctx.Value("db").(*gorm.DB)
|
||||||
return db.Omit(clause.Associations).Create(apps).Error
|
return db.Omit(clause.Associations).Create(&apps).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppRepo) GetByKey(ctx context.Context, key string) (model.App, error) {
|
func (a AppRepo) GetByKey(ctx context.Context, key string) (model.App, error) {
|
||||||
|
@ -31,7 +31,12 @@ func (a AppDetailRepo) GetAppDetail(opts ...DBOption) (model.AppDetail, error) {
|
|||||||
return detail, err
|
return detail, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppDetailRepo) BatchCreate(ctx context.Context, details []*model.AppDetail) error {
|
func (a AppDetailRepo) Update(ctx context.Context, detail model.AppDetail) error {
|
||||||
|
db := ctx.Value("db").(*gorm.DB)
|
||||||
|
return db.Save(&detail).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AppDetailRepo) BatchCreate(ctx context.Context, details []model.AppDetail) error {
|
||||||
db := ctx.Value("db").(*gorm.DB)
|
db := ctx.Value("db").(*gorm.DB)
|
||||||
return db.Model(&model.AppDetail{}).Create(&details).Error
|
return db.Model(&model.AppDetail{}).Create(&details).Error
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,11 @@ func (a AppTagRepo) DeleteByAppIds(ctx context.Context, appIds []uint) error {
|
|||||||
return db.Where("app_id in (?)", appIds).Delete(&model.AppTag{}).Error
|
return db.Where("app_id in (?)", appIds).Delete(&model.AppTag{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppTagRepo) DeleteAll(ctx context.Context) error {
|
||||||
|
db := ctx.Value("db").(*gorm.DB)
|
||||||
|
return db.Where("1 = 1").Delete(&model.AppTag{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppTagRepo) GetByAppId(appId uint) ([]model.AppTag, error) {
|
func (a AppTagRepo) GetByAppId(appId uint) ([]model.AppTag, error) {
|
||||||
var appTags []model.AppTag
|
var appTags []model.AppTag
|
||||||
if err := global.DB.Where("app_id = ?", appId).Find(&appTags).Error; err != nil {
|
if err := global.DB.Where("app_id = ?", appId).Find(&appTags).Error; err != nil {
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -136,9 +135,9 @@ func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO,
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
appDetailDTO dto.AppDetailDTO
|
appDetailDTO dto.AppDetailDTO
|
||||||
|
opts []repo.DBOption
|
||||||
)
|
)
|
||||||
|
|
||||||
var opts []repo.DBOption
|
|
||||||
opts = append(opts, appDetailRepo.WithAppId(appId), appDetailRepo.WithVersion(version))
|
opts = append(opts, appDetailRepo.WithAppId(appId), appDetailRepo.WithVersion(version))
|
||||||
detail, err := appDetailRepo.GetAppDetail(opts...)
|
detail, err := appDetailRepo.GetAppDetail(opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -152,15 +151,11 @@ func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a AppService) Operate(req dto.AppInstallOperate) error {
|
func (a AppService) Operate(req dto.AppInstallOperate) error {
|
||||||
appInstall, err := appInstallRepo.GetBy(commonRepo.WithByID(req.InstallId))
|
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(appInstall) == 0 {
|
|
||||||
return errors.New("req not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
install := appInstall[0]
|
|
||||||
dockerComposePath := install.GetComposePath()
|
dockerComposePath := install.GetComposePath()
|
||||||
|
|
||||||
switch req.Operate {
|
switch req.Operate {
|
||||||
@ -193,13 +188,10 @@ func (a AppService) Operate(req dto.AppInstallOperate) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return handleErr(install, err, out)
|
return handleErr(install, err, out)
|
||||||
}
|
}
|
||||||
out, err = compose.Rmf(dockerComposePath)
|
if err := op.DeleteDir(appDir); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return handleErr(install, err, out)
|
|
||||||
}
|
}
|
||||||
_ = op.DeleteDir(appDir)
|
return appInstallRepo.Delete(commonRepo.WithByID(install.ID))
|
||||||
_ = appInstallRepo.Delete(commonRepo.WithByID(install.ID))
|
|
||||||
return nil
|
|
||||||
case dto.Sync:
|
case dto.Sync:
|
||||||
if err := a.SyncInstalled(install.ID); err != nil {
|
if err := a.SyncInstalled(install.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -380,12 +372,17 @@ func (a AppService) SyncInstalled(installId uint) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var errorContainers []string
|
var (
|
||||||
var notFoundContainers []string
|
errorContainers []string
|
||||||
|
notFoundContainers []string
|
||||||
|
runningContainers []string
|
||||||
|
)
|
||||||
|
|
||||||
for _, n := range containers {
|
for _, n := range containers {
|
||||||
if n.State != "running" {
|
if n.State != "running" {
|
||||||
errorContainers = append(errorContainers, n.Names...)
|
errorContainers = append(errorContainers, n.Names[0])
|
||||||
|
} else {
|
||||||
|
runningContainers = append(runningContainers, n.Names[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, old := range containerNames {
|
for _, old := range containerNames {
|
||||||
@ -401,33 +398,41 @@ func (a AppService) SyncInstalled(installId uint) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(containers) == 0 {
|
containerCount := len(containers)
|
||||||
|
errCount := len(errorContainers)
|
||||||
|
notFoundCount := len(notFoundContainers)
|
||||||
|
normalCount := len(containerNames)
|
||||||
|
runningCount := len(runningContainers)
|
||||||
|
|
||||||
|
if containerCount == 0 {
|
||||||
appInstall.Status = constant.Error
|
appInstall.Status = constant.Error
|
||||||
appInstall.Message = "container is not found"
|
appInstall.Message = "container is not found"
|
||||||
return appInstallRepo.Save(appInstall)
|
return appInstallRepo.Save(appInstall)
|
||||||
}
|
}
|
||||||
|
if errCount == 0 && notFoundCount == 0 {
|
||||||
if len(errorContainers) == 0 && len(notFoundContainers) == 0 {
|
|
||||||
appInstall.Status = constant.Running
|
appInstall.Status = constant.Running
|
||||||
return appInstallRepo.Save(appInstall)
|
return appInstallRepo.Save(appInstall)
|
||||||
}
|
}
|
||||||
if len(errorContainers) == len(containerNames) {
|
if errCount == normalCount {
|
||||||
appInstall.Status = constant.Error
|
appInstall.Status = constant.Error
|
||||||
}
|
}
|
||||||
if len(notFoundContainers) == len(containerNames) {
|
if notFoundCount == normalCount {
|
||||||
appInstall.Status = constant.Stopped
|
appInstall.Status = constant.Stopped
|
||||||
}
|
}
|
||||||
|
if runningCount < normalCount {
|
||||||
|
appInstall.Status = constant.UnHealthy
|
||||||
|
}
|
||||||
|
|
||||||
var errMsg strings.Builder
|
var errMsg strings.Builder
|
||||||
if len(errorContainers) > 0 {
|
if errCount > 0 {
|
||||||
errMsg.Write([]byte(string(rune(len(errorContainers))) + " error containers:"))
|
errMsg.Write([]byte(string(rune(errCount)) + " error containers:"))
|
||||||
for _, e := range errorContainers {
|
for _, e := range errorContainers {
|
||||||
errMsg.Write([]byte(e))
|
errMsg.Write([]byte(e))
|
||||||
}
|
}
|
||||||
errMsg.Write([]byte("\n"))
|
errMsg.Write([]byte("\n"))
|
||||||
}
|
}
|
||||||
if len(notFoundContainers) > 0 {
|
if notFoundCount > 0 {
|
||||||
errMsg.Write([]byte(string(rune(len(notFoundContainers))) + " not found containers:"))
|
errMsg.Write([]byte(string(rune(notFoundCount)) + " not found containers:"))
|
||||||
for _, e := range notFoundContainers {
|
for _, e := range notFoundContainers {
|
||||||
errMsg.Write([]byte(e))
|
errMsg.Write([]byte(e))
|
||||||
}
|
}
|
||||||
@ -437,10 +442,55 @@ func (a AppService) SyncInstalled(installId uint) error {
|
|||||||
return appInstallRepo.Save(appInstall)
|
return appInstallRepo.Save(appInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
|
||||||
|
apps := make(map[string]model.App, len(oldApps))
|
||||||
|
for _, old := range oldApps {
|
||||||
|
old.Status = constant.AppTakeDown
|
||||||
|
apps[old.Key] = old
|
||||||
|
}
|
||||||
|
for _, item := range items {
|
||||||
|
app, ok := apps[item.Key]
|
||||||
|
if !ok {
|
||||||
|
app = model.App{}
|
||||||
|
}
|
||||||
|
app.Name = item.Name
|
||||||
|
app.Key = item.Key
|
||||||
|
app.ShortDesc = item.ShortDesc
|
||||||
|
app.Author = item.Author
|
||||||
|
app.Source = item.Source
|
||||||
|
app.Type = item.Type
|
||||||
|
app.CrossVersionUpdate = item.CrossVersionUpdate
|
||||||
|
app.Required = item.GetRequired()
|
||||||
|
app.Status = constant.AppNormal
|
||||||
|
apps[item.Key] = app
|
||||||
|
}
|
||||||
|
return apps
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAppDetails(details []model.AppDetail, versions []string) map[string]model.AppDetail {
|
||||||
|
appDetails := make(map[string]model.AppDetail, len(details))
|
||||||
|
for _, old := range details {
|
||||||
|
old.Status = constant.AppTakeDown
|
||||||
|
appDetails[old.Version] = old
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range versions {
|
||||||
|
detail, ok := appDetails[v]
|
||||||
|
if ok {
|
||||||
|
detail.Status = constant.AppNormal
|
||||||
|
appDetails[v] = detail
|
||||||
|
} else {
|
||||||
|
appDetails[v] = model.AppDetail{
|
||||||
|
Version: v,
|
||||||
|
Status: constant.AppNormal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return appDetails
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppService) SyncAppList() error {
|
func (a AppService) SyncAppList() error {
|
||||||
//TODO 从 oss 拉取最新列表
|
//TODO 从 oss 拉取最新列表
|
||||||
var appConfig model.AppConfig
|
|
||||||
appConfig.OssPath = global.CONF.System.AppOss
|
|
||||||
|
|
||||||
appDir := path.Join(global.CONF.System.ResourceDir, "apps")
|
appDir := path.Join(global.CONF.System.ResourceDir, "apps")
|
||||||
iconDir := path.Join(appDir, "icons")
|
iconDir := path.Join(appDir, "icons")
|
||||||
@ -454,14 +504,10 @@ func (a AppService) SyncAppList() error {
|
|||||||
if err := json.Unmarshal(content, list); err != nil {
|
if err := json.Unmarshal(content, list); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
appConfig.Version = list.Version
|
|
||||||
appConfig.CanUpdate = false
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tags []*model.Tag
|
tags []*model.Tag
|
||||||
addApps []*model.App
|
appTags []*model.AppTag
|
||||||
updateApps []*model.App
|
|
||||||
appTags []*model.AppTag
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, t := range list.Tags {
|
for _, t := range list.Tags {
|
||||||
@ -471,38 +517,29 @@ func (a AppService) SyncAppList() error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
db := global.DB
|
oldApps, err := appRepo.GetBy()
|
||||||
dbCtx := context.WithValue(context.Background(), "db", db)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appsMap := getApps(oldApps, list.Items)
|
||||||
|
|
||||||
for _, l := range list.Items {
|
for _, l := range list.Items {
|
||||||
|
|
||||||
|
app := appsMap[l.Key]
|
||||||
icon, err := os.ReadFile(path.Join(iconDir, l.Icon))
|
icon, err := os.ReadFile(path.Join(iconDir, l.Icon))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("get [%s] icon error: %s", l.Name, err.Error())
|
global.LOG.Errorf("get [%s] icon error: %s", l.Name, err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
iconStr := base64.StdEncoding.EncodeToString(icon)
|
iconStr := base64.StdEncoding.EncodeToString(icon)
|
||||||
app := &model.App{
|
app.Icon = iconStr
|
||||||
Name: l.Name,
|
|
||||||
Key: l.Key,
|
|
||||||
ShortDesc: l.ShortDesc,
|
|
||||||
Author: l.Author,
|
|
||||||
Source: l.Source,
|
|
||||||
Icon: iconStr,
|
|
||||||
Type: l.Type,
|
|
||||||
}
|
|
||||||
app.TagsKey = l.Tags
|
app.TagsKey = l.Tags
|
||||||
old, _ := appRepo.GetByKey(dbCtx, l.Key)
|
|
||||||
if reflect.DeepEqual(old, &model.App{}) {
|
|
||||||
addApps = append(addApps, app)
|
|
||||||
} else {
|
|
||||||
app.ID = old.ID
|
|
||||||
updateApps = append(updateApps, app)
|
|
||||||
}
|
|
||||||
|
|
||||||
versions := l.Versions
|
versions := l.Versions
|
||||||
|
detailsMap := getAppDetails(app.Details, versions)
|
||||||
|
|
||||||
for _, v := range versions {
|
for _, v := range versions {
|
||||||
detail := &model.AppDetail{
|
detail := detailsMap[v]
|
||||||
Version: v,
|
|
||||||
}
|
|
||||||
detailPath := path.Join(appDir, l.Key, v)
|
detailPath := path.Join(appDir, l.Key, v)
|
||||||
if _, err := os.Stat(detailPath); err != nil {
|
if _, err := os.Stat(detailPath); err != nil {
|
||||||
global.LOG.Errorf("get [%s] folder error: %s", detailPath, err.Error())
|
global.LOG.Errorf("get [%s] folder error: %s", detailPath, err.Error())
|
||||||
@ -524,13 +561,34 @@ func (a AppService) SyncAppList() error {
|
|||||||
global.LOG.Errorf("get [%s] form.json error: %s", detailPath, err.Error())
|
global.LOG.Errorf("get [%s] form.json error: %s", detailPath, err.Error())
|
||||||
}
|
}
|
||||||
detail.Params = string(paramStr)
|
detail.Params = string(paramStr)
|
||||||
app.Details = append(app.Details, detail)
|
detailsMap[v] = detail
|
||||||
|
}
|
||||||
|
var newDetails []model.AppDetail
|
||||||
|
for _, v := range detailsMap {
|
||||||
|
newDetails = append(newDetails, v)
|
||||||
|
}
|
||||||
|
app.Details = newDetails
|
||||||
|
appsMap[l.Key] = app
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
addAppArray []model.App
|
||||||
|
updateArray []model.App
|
||||||
|
)
|
||||||
|
tagMap := make(map[string]uint, len(tags))
|
||||||
|
for _, v := range appsMap {
|
||||||
|
if v.ID == 0 {
|
||||||
|
addAppArray = append(addAppArray, v)
|
||||||
|
} else {
|
||||||
|
updateArray = append(updateArray, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := global.DB.Begin()
|
tx := global.DB.Begin()
|
||||||
ctx := context.WithValue(context.Background(), "db", tx)
|
ctx := context.WithValue(context.Background(), "db", tx)
|
||||||
if len(addApps) > 0 {
|
|
||||||
if err := appRepo.BatchCreate(ctx, addApps); err != nil {
|
if len(addAppArray) > 0 {
|
||||||
|
if err := appRepo.BatchCreate(ctx, addAppArray); err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -539,34 +597,29 @@ func (a AppService) SyncAppList() error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tags) > 0 {
|
if len(tags) > 0 {
|
||||||
if err := tagRepo.BatchCreate(ctx, tags); err != nil {
|
if err := tagRepo.BatchCreate(ctx, tags); err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, t := range tags {
|
||||||
|
tagMap[t.Key] = t.ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for _, update := range updateArray {
|
||||||
tagMap := make(map[string]uint, len(tags))
|
if err := appRepo.Save(ctx, &update); err != nil {
|
||||||
|
|
||||||
for _, t := range tags {
|
|
||||||
tagMap[t.Key] = t.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, a := range updateApps {
|
|
||||||
if err := appRepo.Save(ctx, a); err != nil {
|
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apps := append(addApps, updateApps...)
|
|
||||||
|
apps := append(addAppArray, updateArray...)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
appDetails []*model.AppDetail
|
addDetails []model.AppDetail
|
||||||
appIds []uint
|
updateDetails []model.AppDetail
|
||||||
)
|
)
|
||||||
for _, a := range apps {
|
for _, a := range apps {
|
||||||
|
|
||||||
for _, t := range a.TagsKey {
|
for _, t := range a.TagsKey {
|
||||||
tagId, ok := tagMap[t]
|
tagId, ok := tagMap[t]
|
||||||
if ok {
|
if ok {
|
||||||
@ -579,24 +632,28 @@ func (a AppService) SyncAppList() error {
|
|||||||
|
|
||||||
for _, d := range a.Details {
|
for _, d := range a.Details {
|
||||||
d.AppId = a.ID
|
d.AppId = a.ID
|
||||||
appDetails = append(appDetails, d)
|
if d.ID == 0 {
|
||||||
|
addDetails = append(addDetails, d)
|
||||||
|
} else {
|
||||||
|
updateDetails = append(updateDetails, d)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
appIds = append(appIds, a.ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := appDetailRepo.DeleteByAppIds(ctx, appIds); err != nil {
|
if len(addDetails) > 0 {
|
||||||
tx.Rollback()
|
if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil {
|
||||||
return err
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for _, u := range updateDetails {
|
||||||
if len(appDetails) > 0 {
|
if err := appDetailRepo.Update(ctx, u); err != nil {
|
||||||
if err := appDetailRepo.BatchCreate(ctx, appDetails); err != nil {
|
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := appTagRepo.DeleteByAppIds(ctx, appIds); err != nil {
|
if err := appTagRepo.DeleteAll(ctx); err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,8 @@ const (
|
|||||||
const (
|
const (
|
||||||
ContainerPrefix = "1Panel-"
|
ContainerPrefix = "1Panel-"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AppNormal = "Normal"
|
||||||
|
AppTakeDown = "TakeDown"
|
||||||
|
)
|
||||||
|
@ -119,7 +119,7 @@ onMounted(() => {
|
|||||||
height: 100px;
|
height: 100px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 1px;
|
padding: 5px;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user