Skip to content

Commit

Permalink
feat: Add Multi-Language Support for Application Labels (#7714)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengkunwang223 authored Jan 14, 2025
1 parent 999e5a7 commit 04a1ec9
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 38 deletions.
4 changes: 2 additions & 2 deletions backend/app/api/v1/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
17 changes: 14 additions & 3 deletions backend/app/dto/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 16 additions & 14 deletions backend/app/dto/response/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 4 additions & 3 deletions backend/app/model/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
53 changes: 42 additions & 11 deletions backend/app/service/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -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)
Expand All @@ -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 != "" {
Expand Down Expand Up @@ -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,
Expand All @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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))
Expand Down
2 changes: 2 additions & 0 deletions backend/init/migration/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ func Init() {
migrations.AddAutoRestart,
migrations.AddApiInterfaceConfig,
migrations.AddApiKeyValidityTime,

migrations.UpdateAppTag,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
Expand Down
10 changes: 10 additions & 0 deletions backend/init/migration/migrations/v_1_10.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
}
8 changes: 4 additions & 4 deletions frontend/src/views/app-store/apps/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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;
}
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/app-store/installed/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down

0 comments on commit 04a1ec9

Please sign in to comment.