diff --git a/kernel/av/av.go b/kernel/av/av.go index a575ab446..5f9ea004b 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -220,6 +220,21 @@ func (view *View) GetGroup(groupID string) *View { return nil } +// GetGroupKey 获取分组视图的分组字段。 +func (view *View) GetGroupKey(attrView *AttributeView) (ret *Key) { + if nil == view.Group || "" == view.Group.Field { + return + } + + for _, kv := range attrView.KeyValues { + if kv.Key.ID == view.Group.Field { + ret = kv.Key + return + } + } + return +} + // GroupCalc 描述了分组计算规则和结果的结构。 type GroupCalc struct { Field string `json:"field"` // 字段 ID diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 6fd98f5c8..94281e755 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -63,18 +63,19 @@ func sortAttributeViewGroup(avID, blockID, previousGroupID, groupID string) (err return err } - var group *av.View + var groupView *av.View var index, previousIndex int for i, g := range view.Groups { if g.ID == groupID { - group = g + groupView = g index = i break } } - if nil == group { + if nil == groupView { return } + view.Group.Order = av.GroupOrderMan view.Groups = append(view.Groups[:index], view.Groups[index+1:]...) for i, g := range view.Groups { @@ -83,7 +84,7 @@ func sortAttributeViewGroup(avID, blockID, previousGroupID, groupID string) (err break } } - view.Groups = util.InsertElem(view.Groups, previousIndex, group) + view.Groups = util.InsertElem(view.Groups, previousIndex, groupView) err = av.SaveAttributeView(attrView) return @@ -295,6 +296,7 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error } err = av.SaveAttributeView(attrView) + ReloadAttrView(avID) return } @@ -1573,6 +1575,19 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { return } + // 临时记录每个分组视图的状态,以便后面重新生成分组后可以恢复这些状态 + type GroupState struct { + Folded bool + Hidden int + } + groupStates := map[string]*GroupState{} + for _, groupView := range view.Groups { + groupStates[groupView.Name] = &GroupState{ + Folded: groupView.GroupFolded, + Hidden: groupView.GroupHidden, + } + } + group := view.Group view.Groups = nil viewable := sql.RenderView(attrView, view, "") @@ -1586,30 +1601,12 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { return } - // 如果是按日期分组,则需要记录每个分组视图的一些状态字段,以便后面重新计算分组后可以恢复这些状态 - type GroupState struct { - Folded bool - Hidden int - } - groupStates := map[string]*GroupState{} - if isGroupByDate(view) { - for _, groupView := range view.Groups { - groupStates[groupView.Name] = &GroupState{ - Folded: groupView.GroupFolded, - Hidden: groupView.GroupHidden, - } - } - } - var rangeStart, rangeEnd float64 switch group.Method { case av.GroupMethodValue: if av.GroupOrderMan != group.Order { sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).String(false) < items[j].GetValue(group.Field).String(false) - } - return items[i].GetValue(group.Field).String(false) > items[j].GetValue(group.Field).String(false) + return items[i].GetValue(group.Field).String(false) < items[j].GetValue(group.Field).String(false) }) } case av.GroupMethodRangeNum: @@ -1619,17 +1616,11 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { rangeStart, rangeEnd = group.Range.NumStart, group.Range.NumStart+group.Range.NumStep sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).Number.Content < items[j].GetValue(group.Field).Number.Content - } - return items[i].GetValue(group.Field).Number.Content > items[j].GetValue(group.Field).Number.Content + return items[i].GetValue(group.Field).Number.Content < items[j].GetValue(group.Field).Number.Content }) case av.GroupMethodDateDay, av.GroupMethodDateWeek, av.GroupMethodDateMonth, av.GroupMethodDateYear, av.GroupMethodDateRelative: sort.SliceStable(items, func(i, j int) bool { - if av.GroupOrderAsc == group.Order { - return items[i].GetValue(group.Field).Date.Content < items[j].GetValue(group.Field).Date.Content - } - return items[i].GetValue(group.Field).Date.Content > items[j].GetValue(group.Field).Date.Content + return items[i].GetValue(group.Field).Date.Content < items[j].GetValue(group.Field).Date.Content }) } @@ -1747,24 +1738,23 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) { view.Groups = append(view.Groups, v) } - if isGroupByDate(view) { - view.GroupUpdated = time.Now().UnixMilli() + view.GroupUpdated = time.Now().UnixMilli() - // 则恢复分组视图状态 - for _, groupView := range view.Groups { - if state, ok := groupStates[groupView.Name]; ok { - groupView.GroupFolded = state.Folded - groupView.GroupHidden = state.Hidden - } + // 则恢复分组视图状态 + for _, groupView := range view.Groups { + if state, ok := groupStates[groupView.Name]; ok { + groupView.GroupFolded = state.Folded + groupView.GroupHidden = state.Hidden } } if av.GroupOrderMan != view.Group.Order { sort.SliceStable(view.Groups, func(i, j int) bool { + iName, jName := view.Groups[i].Name, view.Groups[j].Name if av.GroupOrderAsc == view.Group.Order { - return view.Groups[i].Name < view.Groups[j].Name + return util.NaturalCompare(iName, jName) } - return view.Groups[i].Name > view.Groups[j].Name + return util.NaturalCompare(jName, iName) }) } @@ -3063,7 +3053,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a } // 如果存在分组条件,则将分组条件应用到新添加的块上 - groupKey := getViewGroupKey(view, attrView) + groupKey := view.GetGroupKey(attrView) if nil != view && nil != groupKey { if !filterKeyIDs[groupKey.ID] /* 过滤条件应用过的话就不重复处理了 */ && "" != groupID { if groupView := view.GetGroup(groupID); nil != groupView { @@ -3091,7 +3081,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a if av.KeyTypeSelect == groupKey.Type || av.KeyTypeMSelect == groupKey.Type { // 因为单选或多选只能按选项分组,并且可能存在空白分组(前面可能找不到临近项) ,所以单选或多选类型的分组字段使用分组值内容对应的选项 - if opt := groupKey.GetOption(groupView.GroupValue); nil != opt { + if opt := groupKey.GetOption(groupView.GroupValue); nil != opt && av.GroupValueDefault != groupView.GroupValue { newValue.MSelect[0].Content = opt.Name newValue.MSelect[0].Color = opt.Color } @@ -3175,6 +3165,9 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er } err = av.SaveAttributeView(attrView) + if nil != err { + return + } historyDir, err := GetHistoryDir(HistoryOpUpdate) if err != nil { @@ -3865,6 +3858,7 @@ func updateAttributeViewColTemplate(operation *Operation) (err error) { } } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } @@ -4521,7 +4515,7 @@ func updateAttributeViewValue(tx *Transaction, attrView *av.AttributeView, keyID func regenAttrViewViewGroups(attrView *av.AttributeView, keyID string) { for _, view := range attrView.Views { - groupKey := getViewGroupKey(view, attrView) + groupKey := view.GetGroupKey(attrView) if nil == groupKey { continue } @@ -4546,17 +4540,6 @@ func regenAttrViewViewGroups(attrView *av.AttributeView, keyID string) { } } -func getViewGroupKey(view *av.View, attrView *av.AttributeView) *av.Key { - if nil == view.Group { - return nil - } - if "" == view.Group.Field { - return nil - } - ret, _ := attrView.GetKey(view.Group.Field) - return ret -} - func unbindBlockAv(tx *Transaction, avID, blockID string) { node, tree, err := getNodeByBlockID(tx, blockID) if err != nil { @@ -4750,6 +4733,7 @@ func removeAttributeViewColumnOption(operation *Operation) (err error) { break } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } @@ -4868,6 +4852,7 @@ func updateAttributeViewColumnOption(operation *Operation) (err error) { } } + regenAttrViewViewGroups(attrView, operation.ID) err = av.SaveAttributeView(attrView) return } diff --git a/kernel/model/auth.go b/kernel/model/auth.go index 79022d226..e1551ff70 100644 --- a/kernel/model/auth.go +++ b/kernel/model/auth.go @@ -46,8 +46,7 @@ const ( var ( accountsMap = AccountsMap{} - - key = make([]byte, 32) + jwtKey = make([]byte, 32) ) func GetBasicAuthAccount(username string) *Account { @@ -69,7 +68,7 @@ func InitAccounts() { } func InitJWT() { - if _, err := rand.Read(key); err != nil { + if _, err := rand.Read(jwtKey); err != nil { logging.LogErrorf("generate JWT signing key failed: %s", err) return } @@ -87,7 +86,7 @@ func InitJWT() { ClaimsKeyRole: RoleReader, }, ) - if token, err := t.SignedString(key); err != nil { + if token, err := t.SignedString(jwtKey); err != nil { logging.LogErrorf("JWT signature failed: %s", err) return } else { @@ -101,7 +100,7 @@ func ParseJWT(tokenString string) (*jwt.Token, error) { return jwt.Parse( tokenString, func(token *jwt.Token) (interface{}, error) { - return key, nil + return jwtKey, nil }, jwt.WithIssuer(iss), jwt.WithSubject(sub), diff --git a/kernel/model/box.go b/kernel/model/box.go index a1b658692..b38b1a6b7 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -690,7 +690,7 @@ func fullReindex() { sql.IndexIgnoreCached = false openedBoxes := Conf.GetOpenedBoxes() for _, openedBox := range openedBoxes { - index(openedBox.ID) + indexBox(openedBox.ID) } LoadFlashcards() debug.FreeOSMemory() diff --git a/kernel/model/conf.go b/kernel/model/conf.go index d224fc01d..c1dd5403a 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -870,7 +870,7 @@ func InitBoxes() { box.UpdateHistoryGenerated() // 初始化历史生成时间为当前时间 if !initialized { - index(box.ID) + indexBox(box.ID) } } diff --git a/kernel/model/index.go b/kernel/model/index.go index 23d4ab5cb..c9721623b 100644 --- a/kernel/model/index.go +++ b/kernel/model/index.go @@ -120,7 +120,7 @@ func unindex(boxID string) { func (box *Box) Index() { task.AppendTask(task.DatabaseIndexRef, removeBoxRefs, box.ID) - task.AppendTask(task.DatabaseIndex, index, box.ID) + task.AppendTask(task.DatabaseIndex, indexBox, box.ID) task.AppendTask(task.DatabaseIndexRef, IndexRefs) go func() { sql.FlushQueue() @@ -132,7 +132,7 @@ func removeBoxRefs(boxID string) { sql.DeleteBoxRefsQueue(boxID) } -func index(boxID string) { +func indexBox(boxID string) { box := Conf.Box(boxID) if nil == box { return