mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 15:59:16 +08:00
feat: Add Multi-Language Support for Application Labels (#7714)
This commit is contained in:
parent
999e5a779a
commit
04a1ec9a9a
@ -22,7 +22,7 @@ func (b *BaseApi) SearchApp(c *gin.Context) {
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
list, err := appService.PageApp(req)
|
||||
list, err := appService.PageApp(c, req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@ -173,7 +173,7 @@ func (b *BaseApi) InstallApp(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetAppTags(c *gin.Context) {
|
||||
tags, err := appService.GetAppTags()
|
||||
tags, err := appService.GetAppTags(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -104,9 +104,20 @@ type AppConfigVersion struct {
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Sort int `json:"sort"`
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Sort int `json:"sort"`
|
||||
Locales Locale `json:"locales"`
|
||||
}
|
||||
|
||||
type Locale struct {
|
||||
En string `json:"en"`
|
||||
Ja string `json:"ja"`
|
||||
Ms string `json:"ms"`
|
||||
PtBr string `json:"pt-br"`
|
||||
Ru string `json:"ru"`
|
||||
ZhHant string `json:"zh-hant"`
|
||||
Zh string `json:"zh"`
|
||||
}
|
||||
|
||||
type AppForm struct {
|
||||
|
@ -29,23 +29,25 @@ type AppDTO struct {
|
||||
}
|
||||
|
||||
type AppItem struct {
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
ID uint `json:"id"`
|
||||
ShortDescZh string `json:"shortDescZh"`
|
||||
ShortDescEn string `json:"shortDescEn"`
|
||||
Icon string `json:"icon"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Resource string `json:"resource"`
|
||||
Installed bool `json:"installed"`
|
||||
Versions []string `json:"versions"`
|
||||
Limit int `json:"limit"`
|
||||
Tags []model.Tag `json:"tags"`
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
ID uint `json:"id"`
|
||||
ShortDescZh string `json:"shortDescZh"`
|
||||
ShortDescEn string `json:"shortDescEn"`
|
||||
Icon string `json:"icon"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Resource string `json:"resource"`
|
||||
Installed bool `json:"installed"`
|
||||
Versions []string `json:"versions"`
|
||||
Limit int `json:"limit"`
|
||||
Tags []TagDTO `json:"tags"`
|
||||
}
|
||||
|
||||
type TagDTO struct {
|
||||
model.Tag
|
||||
ID uint `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type AppInstalledCheck struct {
|
||||
|
@ -2,7 +2,8 @@ package model
|
||||
|
||||
type Tag struct {
|
||||
BaseModel
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Sort int `json:"sort" gorm:"type:int;not null;default:1"`
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Translations string `json:"translations"`
|
||||
Sort int `json:"sort" gorm:"type:int;not null;default:1"`
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -34,8 +35,8 @@ type AppService struct {
|
||||
}
|
||||
|
||||
type IAppService interface {
|
||||
PageApp(req request.AppSearch) (interface{}, error)
|
||||
GetAppTags() ([]response.TagDTO, error)
|
||||
PageApp(ctx *gin.Context, req request.AppSearch) (interface{}, error)
|
||||
GetAppTags(ctx *gin.Context) ([]response.TagDTO, error)
|
||||
GetApp(key string) (*response.AppDTO, error)
|
||||
GetAppDetail(appId uint, version, appType string) (response.AppDetailDTO, error)
|
||||
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
|
||||
@ -50,7 +51,7 @@ func NewIAppService() IAppService {
|
||||
return &AppService{}
|
||||
}
|
||||
|
||||
func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
func (a AppService) PageApp(ctx *gin.Context, req request.AppSearch) (interface{}, error) {
|
||||
var opts []repo.DBOption
|
||||
opts = append(opts, appRepo.OrderByRecommend())
|
||||
if req.Name != "" {
|
||||
@ -90,6 +91,7 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
var appDTOs []*response.AppItem
|
||||
lang := strings.ToLower(common.GetLang(ctx))
|
||||
for _, ap := range apps {
|
||||
appDTO := &response.AppItem{
|
||||
ID: ap.ID,
|
||||
@ -115,7 +117,27 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
appDTO.Tags = tags
|
||||
for _, t := range tags {
|
||||
if t.Name != "" {
|
||||
tagDTO := response.TagDTO{
|
||||
ID: t.ID,
|
||||
Key: t.Key,
|
||||
Name: t.Name,
|
||||
}
|
||||
appDTO.Tags = append(appDTO.Tags, tagDTO)
|
||||
} else {
|
||||
var translations = make(map[string]string)
|
||||
_ = json.Unmarshal([]byte(t.Translations), &translations)
|
||||
if name, ok := translations[lang]; ok {
|
||||
tagDTO := response.TagDTO{
|
||||
ID: t.ID,
|
||||
Key: t.Key,
|
||||
Name: name,
|
||||
}
|
||||
appDTO.Tags = append(appDTO.Tags, tagDTO)
|
||||
}
|
||||
}
|
||||
}
|
||||
installs, _ := appInstallRepo.ListBy(appInstallRepo.WithAppId(ap.ID))
|
||||
appDTO.Installed = len(installs) > 0
|
||||
}
|
||||
@ -125,13 +147,21 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetAppTags() ([]response.TagDTO, error) {
|
||||
func (a AppService) GetAppTags(ctx *gin.Context) ([]response.TagDTO, error) {
|
||||
tags, _ := tagRepo.All()
|
||||
res := make([]response.TagDTO, 0)
|
||||
lang := strings.ToLower(common.GetLang(ctx))
|
||||
for _, tag := range tags {
|
||||
res = append(res, response.TagDTO{
|
||||
Tag: tag,
|
||||
})
|
||||
tagDTO := response.TagDTO{
|
||||
ID: tag.ID,
|
||||
Key: tag.Key,
|
||||
}
|
||||
var translations = make(map[string]string)
|
||||
_ = json.Unmarshal([]byte(tag.Translations), &translations)
|
||||
if name, ok := translations[lang]; ok {
|
||||
tagDTO.Name = name
|
||||
}
|
||||
res = append(res, tagDTO)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@ -827,10 +857,11 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
oldAppIds []uint
|
||||
)
|
||||
for _, t := range list.Extra.Tags {
|
||||
translations, _ := json.Marshal(t.Locales)
|
||||
tags = append(tags, &model.Tag{
|
||||
Key: t.Key,
|
||||
Name: t.Name,
|
||||
Sort: t.Sort,
|
||||
Key: t.Key,
|
||||
Translations: string(translations),
|
||||
Sort: t.Sort,
|
||||
})
|
||||
}
|
||||
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))
|
||||
|
@ -99,6 +99,8 @@ func Init() {
|
||||
migrations.AddAutoRestart,
|
||||
migrations.AddApiInterfaceConfig,
|
||||
migrations.AddApiKeyValidityTime,
|
||||
|
||||
migrations.UpdateAppTag,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
@ -360,3 +360,13 @@ var AddApiKeyValidityTime = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateAppTag = &gormigrate.Migration{
|
||||
ID: "20241226-update-app-tag",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.Tag{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
:type="activeTag === item.key ? 'primary' : ''"
|
||||
:plain="activeTag !== item.key"
|
||||
>
|
||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
{{ item.name }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="inline">
|
||||
@ -42,7 +42,7 @@
|
||||
@click="changeTag(item.key)"
|
||||
:key="item.key"
|
||||
>
|
||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
{{ item.name }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
@ -139,7 +139,7 @@
|
||||
<div class="app-tag">
|
||||
<el-tag v-for="(tag, ind) in app.tags" :key="ind" class="p-mr-5">
|
||||
<span>
|
||||
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
|
||||
{{ tag.name }}
|
||||
</span>
|
||||
</el-tag>
|
||||
<el-tag v-if="app.status === 'TakeDown'" class="p-mr-5">
|
||||
@ -270,7 +270,7 @@ const changeTag = (key: string) => {
|
||||
const getTagValue = (key: string) => {
|
||||
const tag = tags.value.find((tag) => tag.key === key);
|
||||
if (tag) {
|
||||
return language == 'zh' || language == 'tw' ? tag.name : tag.key;
|
||||
return tag.name;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
:type="activeTag === item.key ? 'primary' : ''"
|
||||
:plain="activeTag !== item.key"
|
||||
>
|
||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||
{{ item.name }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="inline">
|
||||
|
Loading…
x
Reference in New Issue
Block a user