Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
f5a8533926
16 changed files with 149 additions and 101 deletions
|
@ -1200,7 +1200,7 @@
|
|||
"38": "Too many keywords mentioned [%d], adjust if necessary [Settings - Search - Backlink Mentions - Keyword Limit]",
|
||||
"39": "Deleting index %s",
|
||||
"40": "Inserting index %s",
|
||||
"41": "Upload completed",
|
||||
"41": "Upload completed [%d]",
|
||||
"42": "The setting is complete, the application will be closed automatically, please restart later...",
|
||||
"43": "The maximum storage capacity of cloud space [%s] has been exceeded, and data upload cannot continue",
|
||||
"44": "Parse template failed: %s",
|
||||
|
|
|
@ -1200,7 +1200,7 @@
|
|||
"38": "Demasiadas palabras clave mencionadas [%d], ajústelas si es necesario [Configuración - Búsqueda - Menciones de backlinks - Límite de palabras clave]",
|
||||
"39": "Eliminando índice %s",
|
||||
"40": "Insertando índice %s",
|
||||
"41": "Carga completada",
|
||||
"41": "Carga completada [%d]",
|
||||
"42": "La configuración se ha completado, la aplicación se cerrará automáticamente, por favor reinicie más tarde...",
|
||||
"43": "Se ha superado la capacidad máxima de almacenamiento del espacio en la nube [%s] y la carga de datos no puede continuar",
|
||||
"44": "El proceso de análisis de la plantilla ha fallado: %s",
|
||||
|
|
|
@ -1200,7 +1200,7 @@
|
|||
"38": "Trop de mots-clés mentionnés [%d], ajustez si nécessaire [Paramètres - Recherche - Mentions de backlink - Limite de mots-clés]",
|
||||
"39": "Suppression de l'index %s",
|
||||
"40": "Insertion de l'index %s",
|
||||
"41": "Transfert complété",
|
||||
"41": "Transfert complété [%d]",
|
||||
"42": "Le paramétrage est terminé, l'application se fermera automatiquement, merci de redémarrer plus tard...",
|
||||
"43": "La capacité de stockage maximale de l'espace cloud [%s] a été dépassée et le téléchargement des données ne peut pas continuer",
|
||||
"44": "L'analyse du template a échoué : %s",
|
||||
|
|
|
@ -1200,7 +1200,7 @@
|
|||
"38": "提及關鍵字數量 [%d] 過多,如有需要可以調整 [設置 - 搜索 - 反連提及 - 關鍵字數量限制]",
|
||||
"39": "正在刪除索引 %s",
|
||||
"40": "正在插入索引 %s",
|
||||
"41": "上傳完畢",
|
||||
"41": "上傳完畢 [%d]",
|
||||
"42": "設置完成,即將自動關閉應用,請稍後重新啟動...",
|
||||
"43": "已超過雲端空間最大存儲容量 [%s],無法繼續上傳資料",
|
||||
"44": "範本解析失敗:%s",
|
||||
|
|
|
@ -1200,7 +1200,7 @@
|
|||
"38": "提及关键字数量 [%d] 过多,如有需要可以调整 [设置 - 搜索 - 反链提及 - 关键字数量限制]",
|
||||
"39": "正在删除索引 %s",
|
||||
"40": "正在插入索引 %s",
|
||||
"41": "上传完毕",
|
||||
"41": "上传完毕 [%d]",
|
||||
"42": "设置完成,即将自动关闭应用,请稍后重新启动...",
|
||||
"43": "已超过云端空间最大存储容量 [%s],无法继续上传数据",
|
||||
"44": "模板解析失败:%s",
|
||||
|
|
|
@ -35,6 +35,8 @@ Below are the detailed changes in this version.
|
|||
* [Search and replace fails in some cases](https://github.com/siyuan-note/siyuan/issues/10016)
|
||||
* [Reference jump is not located in read-only mode](https://github.com/siyuan-note/siyuan/issues/10028)
|
||||
* [Converting PDF annotation ref to text fails after setting the appearance](https://github.com/siyuan-note/siyuan/issues/10029)
|
||||
* [Pressing the scoring shortcut key immediately after `Alt+F` is invalid](https://github.com/siyuan-note/siyuan/issues/10020)
|
||||
* [The images in the embed blocks are not uploaded to the community hosting](https://github.com/siyuan-note/siyuan/issues/10042)
|
||||
|
||||
### Development
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
* [某些情況下搜尋替換失效](https://github.com/siyuan-note/siyuan/issues/10016)
|
||||
* [唯讀模式下引用跳轉後未定位瀏覽位置](https://github.com/siyuan-note/siyuan/issues/10028)
|
||||
* [無法轉換外觀樣式的 PDF 註解引用為文字](https://github.com/siyuan-note/siyuan/issues/10029)
|
||||
* [`Alt+F` 後快速按下評分快捷鍵失效](https://github.com/siyuan-note/siyuan/issues/10020)
|
||||
* [在嵌入區塊中的圖片未能上傳社群](https://github.com/siyuan-note/siyuan/issues/10042)
|
||||
|
||||
### 開發者
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
* [某些情况下搜索替换失效](https://github.com/siyuan-note/siyuan/issues/10016)
|
||||
* [只读模式下引用跳转后未定位浏览位置](https://github.com/siyuan-note/siyuan/issues/10028)
|
||||
* [无法转换带外观样式的 PDF 注释引用为文本](https://github.com/siyuan-note/siyuan/issues/10029)
|
||||
* [`Alt+F` 后快速按下评分快捷键失效](https://github.com/siyuan-note/siyuan/issues/10020)
|
||||
* [在嵌入块中的图片未能上传社区](https://github.com/siyuan-note/siyuan/issues/10042)
|
||||
|
||||
### 开发者
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
@ -257,14 +258,15 @@ func uploadCloud(c *gin.Context) {
|
|||
}
|
||||
|
||||
rootID := arg["id"].(string)
|
||||
err := model.UploadAssets2Cloud(rootID)
|
||||
count, err := model.UploadAssets2Cloud(rootID)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
ret.Data = map[string]interface{}{"closeTimeout": 3000}
|
||||
} else {
|
||||
util.PushMsg(model.Conf.Language(41), 3000)
|
||||
return
|
||||
}
|
||||
|
||||
util.PushMsg(fmt.Sprintf(model.Conf.Language(41), count), 3000)
|
||||
}
|
||||
|
||||
func insertLocalAssets(c *gin.Context) {
|
||||
|
|
|
@ -475,7 +475,7 @@ type ValueRollup struct {
|
|||
Contents []*Value `json:"contents"`
|
||||
}
|
||||
|
||||
func (r *ValueRollup) RenderContents(calc *RollupCalc) {
|
||||
func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
||||
if nil == calc {
|
||||
return
|
||||
}
|
||||
|
@ -531,103 +531,105 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc) {
|
|||
case CalcOperatorSum:
|
||||
sum := 0.0
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
sum += n
|
||||
if nil != v.Number {
|
||||
sum += v.Number.Content
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(sum)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(sum, destKey.NumberFormat)}}
|
||||
case CalcOperatorAverage:
|
||||
sum := 0.0
|
||||
count := 0
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
sum += n
|
||||
if nil != v.Number {
|
||||
sum += v.Number.Content
|
||||
count++
|
||||
}
|
||||
}
|
||||
if 0 < count {
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(sum / float64(count))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(sum/float64(count), destKey.NumberFormat)}}
|
||||
}
|
||||
case CalcOperatorMedian:
|
||||
var numbers []float64
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
numbers = append(numbers, n)
|
||||
if nil != v.Number {
|
||||
numbers = append(numbers, v.Number.Content)
|
||||
}
|
||||
}
|
||||
sort.Float64s(numbers)
|
||||
if 0 < len(numbers) {
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(numbers[len(numbers)/2])}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(numbers[len(numbers)/2], destKey.NumberFormat)}}
|
||||
}
|
||||
case CalcOperatorMin:
|
||||
min := math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
if n < min {
|
||||
min = n
|
||||
if nil != v.Number {
|
||||
if v.Number.Content < min {
|
||||
min = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(min)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(min, destKey.NumberFormat)}}
|
||||
case CalcOperatorMax:
|
||||
max := -math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
if n > max {
|
||||
max = n
|
||||
if nil != v.Number {
|
||||
if v.Number.Content > max {
|
||||
max = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(max)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(max, destKey.NumberFormat)}}
|
||||
case CalcOperatorRange:
|
||||
min := math.MaxFloat64
|
||||
max := -math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if "" != v.String() {
|
||||
n, _ := strconv.ParseFloat(v.String(), 64)
|
||||
if n < min {
|
||||
min = n
|
||||
if nil != v.Number {
|
||||
if v.Number.Content < min {
|
||||
min = v.Number.Content
|
||||
}
|
||||
if n > max {
|
||||
max = n
|
||||
if v.Number.Content > max {
|
||||
max = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(max - min)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(max-min, destKey.NumberFormat)}}
|
||||
case CalcOperatorChecked:
|
||||
countChecked := 0
|
||||
for _, v := range r.Contents {
|
||||
if "√" == v.String() {
|
||||
countChecked++
|
||||
if nil != v.Checkbox {
|
||||
if v.Checkbox.Checked {
|
||||
countChecked++
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countChecked))}}
|
||||
case CalcOperatorUnchecked:
|
||||
countUnchecked := 0
|
||||
for _, v := range r.Contents {
|
||||
if "√" != v.String() {
|
||||
countUnchecked++
|
||||
if nil != v.Checkbox {
|
||||
if !v.Checkbox.Checked {
|
||||
countUnchecked++
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countUnchecked))}}
|
||||
case CalcOperatorPercentChecked:
|
||||
countChecked := 0
|
||||
for _, v := range r.Contents {
|
||||
if "√" == v.String() {
|
||||
countChecked++
|
||||
if nil != v.Checkbox {
|
||||
if v.Checkbox.Checked {
|
||||
countChecked++
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countChecked * 100 / len(r.Contents)))}}
|
||||
case CalcOperatorPercentUnchecked:
|
||||
countUnchecked := 0
|
||||
for _, v := range r.Contents {
|
||||
if "√" != v.String() {
|
||||
countUnchecked++
|
||||
if nil != v.Checkbox {
|
||||
if !v.Checkbox.Checked {
|
||||
countUnchecked++
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countUnchecked * 100 / len(r.Contents)))}}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/88250/lute/editor"
|
||||
"io"
|
||||
"io/fs"
|
||||
"mime"
|
||||
|
@ -509,13 +510,25 @@ func GetAssetAbsPath(relativePath string) (ret string, err error) {
|
|||
return "", errors.New(fmt.Sprintf(Conf.Language(12), relativePath))
|
||||
}
|
||||
|
||||
func UploadAssets2Cloud(rootID string) (err error) {
|
||||
func UploadAssets2Cloud(rootID string) (count int, err error) {
|
||||
if !IsSubscriber() {
|
||||
return
|
||||
}
|
||||
|
||||
sqlAssets := sql.QueryRootBlockAssets(rootID)
|
||||
err = uploadAssets2Cloud(sqlAssets, bizTypeUploadAssets)
|
||||
tree, err := loadTreeByBlockID(rootID)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
assets := assetsLinkDestsInTree(tree)
|
||||
embedAssets := assetsLinkDestsInQueryEmbedNodes(tree)
|
||||
assets = append(assets, embedAssets...)
|
||||
assets = gulu.Str.RemoveDuplicatedElem(assets)
|
||||
err = uploadAssets2Cloud(assets, bizTypeUploadAssets)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
count = len(assets)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -525,17 +538,17 @@ const (
|
|||
)
|
||||
|
||||
// uploadAssets2Cloud 将资源文件上传到云端图床。
|
||||
func uploadAssets2Cloud(sqlAssets []*sql.Asset, bizType string) (err error) {
|
||||
func uploadAssets2Cloud(assetPaths []string, bizType string) (err error) {
|
||||
var uploadAbsAssets []string
|
||||
for _, asset := range sqlAssets {
|
||||
for _, assetPath := range assetPaths {
|
||||
var absPath string
|
||||
absPath, err = GetAssetAbsPath(asset.Path)
|
||||
absPath, err = GetAssetAbsPath(assetPath)
|
||||
if nil != err {
|
||||
logging.LogWarnf("get asset [%s] abs path failed: %s", asset, err)
|
||||
logging.LogWarnf("get asset [%s] abs path failed: %s", assetPath, err)
|
||||
return
|
||||
}
|
||||
if "" == absPath {
|
||||
logging.LogErrorf("not found asset [%s]", asset)
|
||||
logging.LogErrorf("not found asset [%s]", assetPath)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -1044,9 +1057,45 @@ func emojisInTree(tree *parse.Tree) (ret []string) {
|
|||
return
|
||||
}
|
||||
|
||||
func assetsLinkDestsInTree(tree *parse.Tree) (ret []string) {
|
||||
func assetsLinkDestsInQueryEmbedNodes(tree *parse.Tree) (ret []string) {
|
||||
// The images in the embed blocks are not uploaded to the community hosting https://github.com/siyuan-note/siyuan/issues/10042
|
||||
|
||||
ret = []string{}
|
||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering || ast.NodeBlockQueryEmbedScript != n.Type {
|
||||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
stmt := n.TokensStr()
|
||||
stmt = html.UnescapeString(stmt)
|
||||
stmt = strings.ReplaceAll(stmt, editor.IALValEscNewLine, "\n")
|
||||
sqlBlocks := sql.SelectBlocksRawStmt(stmt, 1, Conf.Search.Limit)
|
||||
for _, sqlBlock := range sqlBlocks {
|
||||
subtree, _ := loadTreeByBlockID(sqlBlock.ID)
|
||||
if nil == subtree {
|
||||
continue
|
||||
}
|
||||
embedNode := treenode.GetNodeInTree(subtree, sqlBlock.ID)
|
||||
if nil == embedNode {
|
||||
continue
|
||||
}
|
||||
|
||||
ret = append(ret, assetsLinkDestsInNode(embedNode)...)
|
||||
}
|
||||
return ast.WalkContinue
|
||||
})
|
||||
ret = gulu.Str.RemoveDuplicatedElem(ret)
|
||||
return
|
||||
}
|
||||
|
||||
func assetsLinkDestsInTree(tree *parse.Tree) (ret []string) {
|
||||
ret = assetsLinkDestsInNode(tree.Root)
|
||||
return
|
||||
}
|
||||
|
||||
func assetsLinkDestsInNode(node *ast.Node) (ret []string) {
|
||||
ret = []string{}
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
// 修改以下代码时需要同时修改 database 构造行级元素实现,增加必要的类型
|
||||
if !entering || (ast.NodeLinkDest != n.Type && ast.NodeHTMLBlock != n.Type && ast.NodeInlineHTML != n.Type &&
|
||||
ast.NodeIFrame != n.Type && ast.NodeWidget != n.Type && ast.NodeAudio != n.Type && ast.NodeVideo != n.Type &&
|
||||
|
@ -1103,7 +1152,7 @@ func assetsLinkDestsInTree(tree *parse.Tree) (ret []string) {
|
|||
dest := strings.TrimSpace(string(src))
|
||||
ret = append(ret, dest)
|
||||
} else {
|
||||
logging.LogWarnf("src is missing the closing double quote in tree [%s] ", tree.Box+tree.Path)
|
||||
logging.LogWarnf("src is missing the closing double quote in tree [%s] ", node.Box+node.Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,26 +243,22 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|||
relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID)
|
||||
if nil != relVal && nil != relVal.Relation {
|
||||
destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
|
||||
if nil != destAv {
|
||||
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
|
||||
if nil != destAv && nil != destKey {
|
||||
for _, bID := range relVal.Relation.BlockIDs {
|
||||
destVal := destAv.GetValue(kv.Key.Rollup.KeyID, bID)
|
||||
if nil == destVal {
|
||||
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
|
||||
destVal = treenode.GetAttributeViewDefaultValue(ast.NewNodeID(), kv.Key.Rollup.KeyID, blockID, destKey.Type)
|
||||
}
|
||||
|
||||
if av.KeyTypeNumber == destVal.Type {
|
||||
destVal.Number.Format = kv.Key.NumberFormat
|
||||
if av.KeyTypeNumber == destKey.Type {
|
||||
destVal.Number.Format = destKey.NumberFormat
|
||||
destVal.Number.FormatNumber()
|
||||
}
|
||||
|
||||
kv.Values[0].Rollup.Contents = append(kv.Values[0].Rollup.Contents, destVal.Clone())
|
||||
kv.Values[0].Rollup.RenderContents(kv.Key.Rollup.Calc)
|
||||
}
|
||||
kv.Values[0].Rollup.RenderContents(kv.Key.Rollup.Calc, destKey)
|
||||
}
|
||||
}
|
||||
case av.KeyTypeRelation:
|
||||
|
@ -817,25 +813,25 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
|
|||
break
|
||||
}
|
||||
|
||||
destKey, _ := destAv.GetKey(rollupKey.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, blockID := range relVal.Relation.BlockIDs {
|
||||
destVal := destAv.GetValue(rollupKey.Rollup.KeyID, blockID)
|
||||
if nil == destVal {
|
||||
destKey, _ := destAv.GetKey(rollupKey.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
|
||||
destVal = treenode.GetAttributeViewDefaultValue(ast.NewNodeID(), rollupKey.Rollup.KeyID, blockID, destKey.Type)
|
||||
}
|
||||
if av.KeyTypeNumber == destVal.Type {
|
||||
destVal.Number.Format = rollupKey.NumberFormat
|
||||
if av.KeyTypeNumber == destKey.Type {
|
||||
destVal.Number.Format = destKey.NumberFormat
|
||||
destVal.Number.FormatNumber()
|
||||
}
|
||||
|
||||
cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destVal.Clone())
|
||||
}
|
||||
|
||||
cell.Value.Rollup.RenderContents(rollupKey.Rollup.Calc)
|
||||
cell.Value.Rollup.RenderContents(rollupKey.Rollup.Calc, destKey)
|
||||
case av.KeyTypeRelation: // 渲染关联列
|
||||
relKey, _ := attrView.GetKey(cell.Value.KeyID)
|
||||
if nil != relKey && nil != relKey.Relation {
|
||||
|
|
|
@ -780,12 +780,17 @@ func IsSubscriber() bool {
|
|||
}
|
||||
|
||||
func IsPaidUser() bool {
|
||||
// S3/WebDAV data sync and backup are available for a fee https://github.com/siyuan-note/siyuan/issues/8780
|
||||
|
||||
if IsSubscriber() {
|
||||
return true
|
||||
}
|
||||
return nil != Conf.GetUser() // Sign in to use S3/WebDAV data sync https://github.com/siyuan-note/siyuan/issues/8779
|
||||
// TODO S3/WebDAV data sync and backup are available for a fee https://github.com/siyuan-note/siyuan/issues/8780
|
||||
// return nil != Conf.User && 1 == Conf.User.UserSiYuanOneTimePayStatus
|
||||
|
||||
u := Conf.GetUser()
|
||||
if nil == u {
|
||||
return false
|
||||
}
|
||||
return 1 == u.UserSiYuanOneTimePayStatus
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
@ -67,8 +67,11 @@ func Export2Liandi(id string) (err error) {
|
|||
return errors.New(Conf.Language(204))
|
||||
}
|
||||
|
||||
sqlAssets := sql.QueryRootBlockAssets(id)
|
||||
err = uploadAssets2Cloud(sqlAssets, bizTypeExport2Liandi)
|
||||
assets := assetsLinkDestsInTree(tree)
|
||||
embedAssets := assetsLinkDestsInQueryEmbedNodes(tree)
|
||||
assets = append(assets, embedAssets...)
|
||||
assets = gulu.Str.RemoveDuplicatedElem(assets)
|
||||
err = uploadAssets2Cloud(assets, bizTypeExport2Liandi)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -115,21 +115,6 @@ func QueryAssetByHash(hash string) (ret *Asset) {
|
|||
return
|
||||
}
|
||||
|
||||
func QueryRootBlockAssets(rootID string) (ret []*Asset) {
|
||||
sqlStmt := "SELECT * FROM assets WHERE root_id = ?"
|
||||
rows, err := query(sqlStmt, rootID)
|
||||
if nil != err {
|
||||
logging.LogErrorf("sql query [%s] failed: %s", sqlStmt, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
asset := scanAssetRows(rows)
|
||||
ret = append(ret, asset)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func scanAssetRows(rows *sql.Rows) (ret *Asset) {
|
||||
var asset Asset
|
||||
if err := rows.Scan(&asset.ID, &asset.BlockID, &asset.RootID, &asset.Box, &asset.DocPath, &asset.Path, &asset.Name, &asset.Title, &asset.Hash); nil != err {
|
||||
|
|
|
@ -774,25 +774,25 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
|
|||
break
|
||||
}
|
||||
|
||||
destKey, _ := destAv.GetKey(rollupKey.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, blockID := range relVal.Relation.BlockIDs {
|
||||
destVal := destAv.GetValue(rollupKey.Rollup.KeyID, blockID)
|
||||
if nil == destVal {
|
||||
destKey, _ := destAv.GetKey(rollupKey.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
|
||||
destVal = GetAttributeViewDefaultValue(ast.NewNodeID(), rollupKey.Rollup.KeyID, blockID, destKey.Type)
|
||||
}
|
||||
if av.KeyTypeNumber == destVal.Type {
|
||||
destVal.Number.Format = rollupKey.NumberFormat
|
||||
if av.KeyTypeNumber == destKey.Type {
|
||||
destVal.Number.Format = destKey.NumberFormat
|
||||
destVal.Number.FormatNumber()
|
||||
}
|
||||
|
||||
cell.Value.Rollup.Contents = append(cell.Value.Rollup.Contents, destVal.Clone())
|
||||
}
|
||||
|
||||
cell.Value.Rollup.RenderContents(rollupKey.Rollup.Calc)
|
||||
cell.Value.Rollup.RenderContents(rollupKey.Rollup.Calc, destKey)
|
||||
case av.KeyTypeRelation: // 渲染关联列
|
||||
relKey, _ := attrView.GetKey(cell.Value.KeyID)
|
||||
if nil != relKey && nil != relKey.Relation {
|
||||
|
|
Loading…
Add table
Reference in a new issue