Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2025-06-10 16:03:17 +08:00
commit be1cfa63da
18 changed files with 222 additions and 41 deletions

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "معاينة البطاقة",
"contentImage": "صورة المحتوى",
"cardSize": "حجم البطاقة",
"large": "كبير",
"medium": "متوسط",
"small": "صغير",
"fitImage": "تعديل حجم الصورة تلقائيًا",
"showIcon": "إظهار الأيقونة",
"wrapAllFields": "التفاف الحقول تلقائيًا",
"gallery": "معرض",
"newTag": "علامة جديدة",
"pleaseWait": "يرجى الانتظار...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Kartenansicht",
"contentImage": "Inhaltsbild",
"cardSize": "Kartengröße",
"large": "Groß",
"medium": "Mittel",
"small": "Klein",
"fitImage": "Bildgröße automatisch anpassen",
"showIcon": "Symbol anzeigen",
"wrapAllFields": "Felder automatisch umbrechen",
"gallery": "Galerie",
"newTag": "Neuer Tag",
"pleaseWait": "Bitte warten...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Card preview",
"contentImage": "Content image",
"cardSize": "Card size",
"large": "Large",
"medium": "Medium",
"small": "Small",
"fitImage": "Auto-fit image size",
"showIcon": "Show icon",
"wrapAllFields": "Auto-wrap fields",
"gallery": "Gallery",
"newTag": "New tag",
"pleaseWait": "Please wait...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Vista previa de la tarjeta",
"contentImage": "Imagen del contenido",
"cardSize": "Tamaño de la tarjeta",
"large": "Grande",
"medium": "Mediano",
"small": "Pequeño",
"fitImage": "Ajustar automáticamente el tamaño de la imagen",
"showIcon": "Mostrar ícono",
"wrapAllFields": "Ajuste automático de campos",
"gallery": "Galería",
"newTag": "Nueva etiqueta",
"pleaseWait": "Por favor, espere...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Aperçu de la carte",
"contentImage": "Image du contenu",
"cardSize": "Taille de la carte",
"large": "Grand",
"medium": "Moyen",
"small": "Petit",
"fitImage": "Ajuster automatiquement la taille de l'image",
"showIcon": "Afficher l'icône",
"wrapAllFields": "Retour automatique des champs",
"gallery": "Galerie",
"newTag": "Nouvelle étiquette",
"pleaseWait": "Veuillez patienter...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "תצוגה מקדימה של כרטיס",
"contentImage": "תמונת תוכן",
"cardSize": "גודל כרטיס",
"large": "גדול",
"medium": "בינוני",
"small": "קטן",
"fitImage": "התאמה אוטומטית לגודל התמונה",
"showIcon": "הצג אייקון",
"wrapAllFields": "עטיפת שדות אוטומטית",
"gallery": "גלריה",
"newTag": "תג חדש",
"pleaseWait": "אנא המתן...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Anteprima della carta",
"contentImage": "Immagine del contenuto",
"cardSize": "Dimensione della carta",
"large": "Grande",
"medium": "Medio",
"small": "Piccolo",
"fitImage": "Adatta automaticamente la dimensione dell'immagine",
"showIcon": "Mostra icona",
"wrapAllFields": "Avvolgi automaticamente i campi",
"gallery": "Galleria",
"newTag": "Nuova etichetta",
"pleaseWait": "Attendere prego...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "カードプレビュー",
"contentImage": "コンテンツ画像",
"cardSize": "カードサイズ",
"large": "大",
"medium": "中",
"small": "小",
"fitImage": "画像サイズを自動調整",
"showIcon": "アイコンを表示",
"wrapAllFields": "フィールドを自動折り返し",
"gallery": "ギャラリー",
"newTag": "新しいタグ",
"pleaseWait": "しばらくお待ちください...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Podgląd karty",
"contentImage": "Obraz treści",
"cardSize": "Rozmiar karty",
"large": "Duży",
"medium": "Średni",
"small": "Mały",
"fitImage": "Automatyczne dopasowanie rozmiaru obrazu",
"showIcon": "Pokaż ikonę",
"wrapAllFields": "Automatyczne zawijanie pól",
"gallery": "Galeria",
"newTag": "Nowy tag",
"pleaseWait": "Proszę czekać...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "Предпросмотр карты",
"contentImage": "Изображение содержимого",
"cardSize": "Размер карты",
"large": "Большой",
"medium": "Средний",
"small": "Маленький",
"fitImage": "Автоматическая подгонка размера изображения",
"showIcon": "Показать значок",
"wrapAllFields": "Автоматический перенос полей",
"gallery": "Галерея",
"newTag": "Новый тег",
"pleaseWait": "Пожалуйста, подождите...",

View file

@ -1,4 +1,13 @@
{
"cardPreview1": "卡片預覽",
"contentImage": "內容圖片",
"cardSize": "卡片大小",
"large": "大",
"medium": "中",
"small": "小",
"fitImage": "自動調整圖片大小",
"showIcon": "顯示圖示",
"wrapAllFields": "欄位自動換行",
"gallery": "圖庫",
"newTag": "新建標籤",
"pleaseWait": "請稍等片刻...",

View file

@ -1,14 +1,13 @@
{
"articleCover": "页面封面",
"articleContent": "页面内容",
"cardView": "卡片预览",
"cardPreview1": "卡片预览",
"contentImage": "内容图",
"cardSize": "卡片大小",
"big": "大",
"middle": "中",
"large": "大",
"medium": "中",
"small": "小",
"adjustImg": "自适应图片大小",
"showIcon": "显示页面图标",
"wrapAllFields": "对所有属性换行",
"fitImage": "自适应图片大小",
"showIcon": "显示图标",
"wrapAllFields": "字段自动换行",
"gallery": "画廊",
"newTag": "新建标签",
"pleaseWait": "请稍等片刻...",

View file

@ -207,15 +207,7 @@ func NewTableView() (ret *View) {
ID: ast.NewNodeID(),
Name: getI18nName("table"),
LayoutType: LayoutTypeTable,
Table: &LayoutTable{
BaseLayout: &BaseLayout{
Spec: 0,
ID: ast.NewNodeID(),
Filters: []*ViewFilter{},
Sorts: []*ViewSort{},
PageSize: TableViewDefaultPageSize,
},
},
Table: NewLayoutTable(),
}
return
}
@ -226,15 +218,7 @@ func NewTableViewWithBlockKey(blockKeyID string) (view *View, blockKey, selectKe
ID: ast.NewNodeID(),
Name: name,
LayoutType: LayoutTypeTable,
Table: &LayoutTable{
BaseLayout: &BaseLayout{
Spec: 0,
ID: ast.NewNodeID(),
Filters: []*ViewFilter{},
Sorts: []*ViewSort{},
PageSize: TableViewDefaultPageSize,
},
},
Table: NewLayoutTable(),
}
blockKey = NewKey(blockKeyID, getI18nName("key"), "", KeyTypeBlock)
view.Table.Columns = []*ViewTableColumn{{ID: blockKeyID}}
@ -249,18 +233,7 @@ func NewGalleryView() (ret *View) {
ID: ast.NewNodeID(),
Name: getI18nName("gallery"),
LayoutType: LayoutTypeGallery,
Gallery: &LayoutGallery{
BaseLayout: &BaseLayout{
Spec: 0,
ID: ast.NewNodeID(),
Filters: []*ViewFilter{},
Sorts: []*ViewSort{},
PageSize: GalleryViewDefaultPageSize,
},
CoverFrom: CoverFromContentImage,
CardSize: CardSizeMedium,
ShowIcon: true,
},
Gallery: NewLayoutGallery(),
}
return
}

View file

@ -16,7 +16,11 @@
package av
import "sort"
import (
"sort"
"github.com/88250/lute/ast"
)
// LayoutGallery 描述了画廊布局的结构。
type LayoutGallery struct {
@ -33,6 +37,21 @@ type LayoutGallery struct {
CardIDs []string `json:"cardIds"` // 卡片 ID用于自定义排序
}
func NewLayoutGallery() *LayoutGallery {
return &LayoutGallery{
BaseLayout: &BaseLayout{
Spec: 0,
ID: ast.NewNodeID(),
Filters: []*ViewFilter{},
Sorts: []*ViewSort{},
PageSize: GalleryViewDefaultPageSize,
},
CoverFrom: CoverFromContentImage,
CardSize: CardSizeMedium,
ShowIcon: true,
}
}
type CardSize int
const (
@ -62,6 +81,13 @@ type ViewGalleryCardField struct {
type Gallery struct {
*BaseInstance
CoverFrom CoverFrom `json:"coverFrom"` // 封面来源
CoverFromAssetKeyID string `json:"coverFromAssetKeyId,omitempty"` // 资源字段 IDCoverFrom 为 CoverFromAssetField 时有效
CardSize CardSize `json:"cardSize"` // 卡片大小
FitImage bool `json:"fitImage"` // 是否适应封面图片大小
ShowIcon bool `json:"showIcon"` // 是否显示字段图标
WrapField bool `json:"wrapField"` // 是否换行字段内容
Fields []*GalleryField `json:"fields"` // 画廊字段
Cards []*GalleryCard `json:"cards"` // 画廊卡片
CardCount int `json:"cardCount"` // 画廊总卡片数

View file

@ -18,6 +18,8 @@ package av
import (
"sort"
"github.com/88250/lute/ast"
)
// LayoutTable 描述了表格布局的结构。
@ -28,6 +30,18 @@ type LayoutTable struct {
RowIDs []string `json:"rowIds"` // 行 ID用于自定义排序
}
func NewLayoutTable() *LayoutTable {
return &LayoutTable{
BaseLayout: &BaseLayout{
Spec: 0,
ID: ast.NewNodeID(),
Filters: []*ViewFilter{},
Sorts: []*ViewSort{},
PageSize: TableViewDefaultPageSize,
},
}
}
// ViewTableColumn 描述了表格列的结构。
type ViewTableColumn struct {
ID string `json:"id"` // 列 ID

View file

@ -44,6 +44,68 @@ import (
"github.com/xrash/smetrics"
)
func (tx *Transaction) doChangeAttrViewLayout(operation *Operation) (ret *TxErr) {
err := changeAttrViewLayout(operation)
if err != nil {
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func changeAttrViewLayout(operation *Operation) (err error) {
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return
}
view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
if err != nil {
return
}
newLayout := operation.Layout
if newLayout == view.LayoutType {
return
}
view.LayoutType = newLayout
switch newLayout {
case av.LayoutTypeTable:
if nil != view.Table {
break
}
view.Table = av.NewLayoutTable()
switch view.LayoutType {
case av.LayoutTypeGallery:
for _, field := range view.Gallery.CardFields {
view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{ID: field.ID})
}
for _, cardID := range view.Gallery.CardIDs {
view.Table.RowIDs = append(view.Table.RowIDs, cardID)
}
}
case av.LayoutTypeGallery:
if nil != view.Gallery {
break
}
view.Gallery = av.NewLayoutGallery()
switch view.LayoutType {
case av.LayoutTypeTable:
for _, col := range view.Table.Columns {
view.Gallery.CardFields = append(view.Gallery.CardFields, &av.ViewGalleryCardField{ID: col.ID})
}
for _, rowID := range view.Table.RowIDs {
view.Gallery.CardIDs = append(view.Gallery.CardIDs, rowID)
}
}
}
err = av.SaveAttributeView(attrView)
return
}
func (tx *Transaction) doSetAttrViewWrapField(operation *Operation) (ret *TxErr) {
err := setAttrViewWrapField(operation)
if err != nil {

View file

@ -290,6 +290,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
ret = tx.doSetAttrViewShowIcon(op)
case "setAttrViewWrapField":
ret = tx.doSetAttrViewWrapField(op)
case "changeAttrViewLayout":
ret = tx.doChangeAttrViewLayout(op)
}
if nil != ret {

View file

@ -26,8 +26,14 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
Filters: view.Gallery.Filters,
Sorts: view.Gallery.Sorts,
},
Fields: []*av.GalleryField{},
Cards: []*av.GalleryCard{},
CoverFrom: view.Gallery.CoverFrom,
CoverFromAssetKeyID: view.Gallery.CoverFromAssetKeyID,
CardSize: view.Gallery.CardSize,
FitImage: view.Gallery.FitImage,
ShowIcon: view.Gallery.ShowIcon,
WrapField: view.Gallery.WrapField,
Fields: []*av.GalleryField{},
Cards: []*av.GalleryCard{},
}
// 组装字段