diff --git a/app/appearance/langs/ar_SA.json b/app/appearance/langs/ar_SA.json index 0b5e83b8d..c72505191 100644 --- a/app/appearance/langs/ar_SA.json +++ b/app/appearance/langs/ar_SA.json @@ -1,4 +1,13 @@ { + "cardPreview1": "معاينة البطاقة", + "contentImage": "صورة المحتوى", + "cardSize": "حجم البطاقة", + "large": "كبير", + "medium": "متوسط", + "small": "صغير", + "fitImage": "تعديل حجم الصورة تلقائيًا", + "showIcon": "إظهار الأيقونة", + "wrapAllFields": "التفاف الحقول تلقائيًا", "gallery": "معرض", "newTag": "علامة جديدة", "pleaseWait": "يرجى الانتظار...", diff --git a/app/appearance/langs/de_DE.json b/app/appearance/langs/de_DE.json index 5277c475e..6f0e9f0cb 100644 --- a/app/appearance/langs/de_DE.json +++ b/app/appearance/langs/de_DE.json @@ -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...", diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 9ba297934..7ef3eaf1c 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -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...", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index a3bf4bc3b..546da525a 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -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...", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index e40d4c7c3..6edecdc13 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -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...", diff --git a/app/appearance/langs/he_IL.json b/app/appearance/langs/he_IL.json index d7215cea7..9694f54cb 100644 --- a/app/appearance/langs/he_IL.json +++ b/app/appearance/langs/he_IL.json @@ -1,4 +1,13 @@ { + "cardPreview1": "תצוגה מקדימה של כרטיס", + "contentImage": "תמונת תוכן", + "cardSize": "גודל כרטיס", + "large": "גדול", + "medium": "בינוני", + "small": "קטן", + "fitImage": "התאמה אוטומטית לגודל התמונה", + "showIcon": "הצג אייקון", + "wrapAllFields": "עטיפת שדות אוטומטית", "gallery": "גלריה", "newTag": "תג חדש", "pleaseWait": "אנא המתן...", diff --git a/app/appearance/langs/it_IT.json b/app/appearance/langs/it_IT.json index bb0e41ea3..19bc79d57 100644 --- a/app/appearance/langs/it_IT.json +++ b/app/appearance/langs/it_IT.json @@ -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...", diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index b424d5401..088f5732a 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1,4 +1,13 @@ { + "cardPreview1": "カードプレビュー", + "contentImage": "コンテンツ画像", + "cardSize": "カードサイズ", + "large": "大", + "medium": "中", + "small": "小", + "fitImage": "画像サイズを自動調整", + "showIcon": "アイコンを表示", + "wrapAllFields": "フィールドを自動折り返し", "gallery": "ギャラリー", "newTag": "新しいタグ", "pleaseWait": "しばらくお待ちください...", diff --git a/app/appearance/langs/pl_PL.json b/app/appearance/langs/pl_PL.json index 16d1298ae..1ff83075f 100644 --- a/app/appearance/langs/pl_PL.json +++ b/app/appearance/langs/pl_PL.json @@ -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ć...", diff --git a/app/appearance/langs/ru_RU.json b/app/appearance/langs/ru_RU.json index 86d8ebdac..92c5e90b4 100644 --- a/app/appearance/langs/ru_RU.json +++ b/app/appearance/langs/ru_RU.json @@ -1,4 +1,13 @@ { + "cardPreview1": "Предпросмотр карты", + "contentImage": "Изображение содержимого", + "cardSize": "Размер карты", + "large": "Большой", + "medium": "Средний", + "small": "Маленький", + "fitImage": "Автоматическая подгонка размера изображения", + "showIcon": "Показать значок", + "wrapAllFields": "Автоматический перенос полей", "gallery": "Галерея", "newTag": "Новый тег", "pleaseWait": "Пожалуйста, подождите...", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 549d0a6bf..3c2a2abaa 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1,4 +1,13 @@ { + "cardPreview1": "卡片預覽", + "contentImage": "內容圖片", + "cardSize": "卡片大小", + "large": "大", + "medium": "中", + "small": "小", + "fitImage": "自動調整圖片大小", + "showIcon": "顯示圖示", + "wrapAllFields": "欄位自動換行", "gallery": "圖庫", "newTag": "新建標籤", "pleaseWait": "請稍等片刻...", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 277b20b21..daab69175 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,14 +1,13 @@ { - "articleCover": "页面封面", - "articleContent": "页面内容", - "cardView": "卡片预览", + "cardPreview1": "卡片预览", + "contentImage": "内容图", "cardSize": "卡片大小", - "big": "大", - "middle": "中", + "large": "大", + "medium": "中", "small": "小", - "adjustImg": "自适应图片大小", - "showIcon": "显示页面图标", - "wrapAllFields": "对所有属性换行", + "fitImage": "自适应图片大小", + "showIcon": "显示图标", + "wrapAllFields": "字段自动换行", "gallery": "画廊", "newTag": "新建标签", "pleaseWait": "请稍等片刻...", diff --git a/kernel/av/av.go b/kernel/av/av.go index d4f5db735..762b92f23 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -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 } diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index 959b58ddf..86761c549 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -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"` // 资源字段 ID,CoverFrom 为 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"` // 画廊总卡片数 diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index 9c9bc811e..220e4f10a 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -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 diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 642992e0e..bd2a209a2 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -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 { diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 4ee57bc01..1f1faaf1c 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -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 { diff --git a/kernel/sql/av_gallery.go b/kernel/sql/av_gallery.go index e9df96815..d15e3e27f 100644 --- a/kernel/sql/av_gallery.go +++ b/kernel/sql/av_gallery.go @@ -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{}, } // 组装字段