mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-03 03:11:34 +08:00
1017 lines
38 KiB
Go
1017 lines
38 KiB
Go
// SiYuan - Refactor your thinking
|
||
// Copyright (c) 2020-present, b3log.org
|
||
//
|
||
// This program is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU Affero General Public License as published by
|
||
// the Free Software Foundation, either version 3 of the License, or
|
||
// (at your option) any later version.
|
||
//
|
||
// This program is distributed in the hope that it will be useful,
|
||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
// GNU Affero General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Affero General Public License
|
||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
package av
|
||
|
||
import (
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/88250/lute/ast"
|
||
"github.com/siyuan-note/siyuan/kernel/util"
|
||
)
|
||
|
||
type Filterable interface {
|
||
FilterRows(attrView *AttributeView)
|
||
}
|
||
|
||
type ViewFilter struct {
|
||
Column string `json:"column"`
|
||
Operator FilterOperator `json:"operator"`
|
||
Value *Value `json:"value"`
|
||
RelativeDate *RelativeDate `json:"relativeDate"`
|
||
RelativeDate2 *RelativeDate `json:"relativeDate2"`
|
||
}
|
||
|
||
type RelativeDateUnit int
|
||
|
||
const (
|
||
RelativeDateUnitDay = iota
|
||
RelativeDateUnitWeek
|
||
RelativeDateUnitMonth
|
||
RelativeDateUnitYear
|
||
)
|
||
|
||
type RelativeDateDirection int
|
||
|
||
const (
|
||
RelativeDateDirectionBefore = -1
|
||
RelativeDateDirectionThis = 0
|
||
RelativeDateDirectionAfter = 1
|
||
)
|
||
|
||
type RelativeDate struct {
|
||
Count int `json:"count"` // 数量
|
||
Unit RelativeDateUnit `json:"unit"` // 单位:0 天、1 周、2 月、3 年
|
||
Direction RelativeDateDirection `json:"direction"` // 方向:-1 前、0 当前、1 后
|
||
}
|
||
|
||
type FilterOperator string
|
||
|
||
const (
|
||
FilterOperatorIsEqual FilterOperator = "="
|
||
FilterOperatorIsNotEqual FilterOperator = "!="
|
||
FilterOperatorIsGreater FilterOperator = ">"
|
||
FilterOperatorIsGreaterOrEqual FilterOperator = ">="
|
||
FilterOperatorIsLess FilterOperator = "<"
|
||
FilterOperatorIsLessOrEqual FilterOperator = "<="
|
||
FilterOperatorContains FilterOperator = "Contains"
|
||
FilterOperatorDoesNotContain FilterOperator = "Does not contains"
|
||
FilterOperatorIsEmpty FilterOperator = "Is empty"
|
||
FilterOperatorIsNotEmpty FilterOperator = "Is not empty"
|
||
FilterOperatorStartsWith FilterOperator = "Starts with"
|
||
FilterOperatorEndsWith FilterOperator = "Ends with"
|
||
FilterOperatorIsBetween FilterOperator = "Is between"
|
||
FilterOperatorIsTrue FilterOperator = "Is true"
|
||
FilterOperatorIsFalse FilterOperator = "Is false"
|
||
)
|
||
|
||
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID string, attrViewCache *map[string]*AttributeView) bool {
|
||
if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) {
|
||
return true
|
||
}
|
||
|
||
if nil != filter.Value && value.Type != filter.Value.Type {
|
||
// 由于字段类型被用户编辑过导致和过滤器值类型不匹配,该情况下不过滤
|
||
return true
|
||
}
|
||
|
||
if nil != value.Rollup && KeyTypeRollup == value.Type && nil != filter.Value && KeyTypeRollup == filter.Value.Type &&
|
||
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
|
||
// 单独处理汇总类型的比较
|
||
|
||
// 处理为空和不为空
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEmpty:
|
||
return 0 == len(value.Rollup.Contents)
|
||
case FilterOperatorIsNotEmpty:
|
||
return 0 != len(value.Rollup.Contents)
|
||
}
|
||
|
||
// 处理值比较
|
||
key, _ := attrView.GetKey(value.KeyID)
|
||
if nil == key {
|
||
return false
|
||
}
|
||
|
||
relKey, _ := attrView.GetKey(key.Rollup.RelationKeyID)
|
||
if nil == relKey {
|
||
return false
|
||
}
|
||
|
||
relVal := attrView.GetValue(relKey.ID, rowID)
|
||
if nil == relVal || nil == relVal.Relation {
|
||
return false
|
||
}
|
||
|
||
destAv := (*attrViewCache)[relKey.Relation.AvID]
|
||
if nil == destAv {
|
||
destAv, _ = ParseAttributeView(relKey.Relation.AvID)
|
||
if nil != destAv {
|
||
(*attrViewCache)[relKey.Relation.AvID] = destAv
|
||
}
|
||
}
|
||
if nil == destAv {
|
||
return false
|
||
}
|
||
|
||
destKey, _ := destAv.GetKey(key.Rollup.KeyID)
|
||
if nil == destKey {
|
||
return false
|
||
}
|
||
|
||
for _, blockID := range relVal.Relation.BlockIDs {
|
||
destVal := destAv.GetValue(key.Rollup.KeyID, blockID)
|
||
if nil == destVal {
|
||
if destAv.ExistBlock(blockID) { // 数据库中存在行但是列值不存在是数据未初始化,这里补一个默认值
|
||
destVal = GetAttributeViewDefaultValue(ast.NewNodeID(), key.Rollup.KeyID, blockID, destKey.Type)
|
||
}
|
||
if nil == destVal {
|
||
continue
|
||
}
|
||
}
|
||
|
||
switch filter.Operator {
|
||
case FilterOperatorContains:
|
||
if destVal.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||
return true
|
||
}
|
||
case FilterOperatorDoesNotContain:
|
||
ret := destVal.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator)
|
||
if !ret {
|
||
return false
|
||
}
|
||
default:
|
||
if destVal.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
switch filter.Operator {
|
||
case FilterOperatorContains:
|
||
return false
|
||
case FilterOperatorDoesNotContain:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
if nil != value.Relation && KeyTypeRelation == value.Type && nil != filter.Value && KeyTypeRelation == filter.Value.Type &&
|
||
nil != filter.Value.Relation && 0 < len(filter.Value.Relation.BlockIDs) {
|
||
// 单独处理关联类型的比较
|
||
|
||
// 处理为空和不为空
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEmpty:
|
||
return 0 == len(value.Relation.Contents)
|
||
case FilterOperatorIsNotEmpty:
|
||
return 0 != len(value.Relation.Contents)
|
||
}
|
||
|
||
for _, relationValue := range value.Relation.Contents {
|
||
filterValue := &Value{Type: KeyTypeBlock, Block: &ValueBlock{Content: filter.Value.Relation.BlockIDs[0]}}
|
||
|
||
switch filter.Operator {
|
||
case FilterOperatorContains:
|
||
if relationValue.filter(filterValue, filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||
return true
|
||
}
|
||
case FilterOperatorDoesNotContain:
|
||
ret := relationValue.filter(filterValue, filter.RelativeDate, filter.RelativeDate2, filter.Operator)
|
||
if !ret {
|
||
return false
|
||
}
|
||
default:
|
||
if relationValue.filter(filterValue, filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
switch filter.Operator {
|
||
case FilterOperatorContains:
|
||
return false
|
||
case FilterOperatorDoesNotContain:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
return value.filter(filter.Value, filter.RelativeDate, filter.RelativeDate2, filter.Operator)
|
||
}
|
||
|
||
func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDate, operator FilterOperator) bool {
|
||
switch value.Type {
|
||
case KeyTypeBlock:
|
||
if nil != value.Block && nil != other && nil != other.Block {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return value.Block.Content == other.Block.Content
|
||
case FilterOperatorIsNotEqual:
|
||
return value.Block.Content != other.Block.Content
|
||
case FilterOperatorContains:
|
||
return strings.Contains(value.Block.Content, other.Block.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
return !strings.Contains(value.Block.Content, other.Block.Content)
|
||
case FilterOperatorStartsWith:
|
||
return strings.HasPrefix(value.Block.Content, other.Block.Content)
|
||
case FilterOperatorEndsWith:
|
||
return strings.HasSuffix(value.Block.Content, other.Block.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.Block.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.Block.Content)
|
||
}
|
||
}
|
||
case KeyTypeText:
|
||
if nil != value.Text && nil != other && nil != other.Text {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return value.Text.Content == other.Text.Content
|
||
case FilterOperatorIsNotEqual:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return value.Text.Content != other.Text.Content
|
||
case FilterOperatorContains:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return strings.Contains(value.Text.Content, other.Text.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return !strings.Contains(value.Text.Content, other.Text.Content)
|
||
case FilterOperatorStartsWith:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return strings.HasPrefix(value.Text.Content, other.Text.Content)
|
||
case FilterOperatorEndsWith:
|
||
if "" == strings.TrimSpace(other.Text.Content) {
|
||
return true
|
||
}
|
||
return strings.HasSuffix(value.Text.Content, other.Text.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.Text.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.Text.Content)
|
||
}
|
||
}
|
||
case KeyTypeNumber:
|
||
if nil != value.Number && nil != other && nil != other.Number {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
if !other.Number.IsNotEmpty {
|
||
return true
|
||
}
|
||
return value.Number.Content == other.Number.Content
|
||
case FilterOperatorIsNotEqual:
|
||
if !other.Number.IsNotEmpty {
|
||
return true
|
||
}
|
||
return value.Number.Content != other.Number.Content
|
||
case FilterOperatorIsGreater:
|
||
return value.Number.Content > other.Number.Content
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
return value.Number.Content >= other.Number.Content
|
||
case FilterOperatorIsLess:
|
||
return value.Number.Content < other.Number.Content
|
||
case FilterOperatorIsLessOrEqual:
|
||
return value.Number.Content <= other.Number.Content
|
||
case FilterOperatorIsEmpty:
|
||
return !value.Number.IsNotEmpty
|
||
case FilterOperatorIsNotEmpty:
|
||
return value.Number.IsNotEmpty
|
||
}
|
||
}
|
||
case KeyTypeDate:
|
||
if nil != value.Date {
|
||
switch operator {
|
||
case FilterOperatorIsEmpty:
|
||
return !value.Date.IsNotEmpty
|
||
case FilterOperatorIsNotEmpty:
|
||
return value.Date.IsNotEmpty
|
||
}
|
||
|
||
if !value.Date.IsNotEmpty {
|
||
// 空值不进行比较,直接排除
|
||
// Database date filter excludes empty values https://github.com/siyuan-note/siyuan/issues/11061
|
||
return false
|
||
}
|
||
|
||
if nil != relativeDate { // 使用相对时间比较
|
||
relativeTimeStart, relativeTimeEnd := calcRelativeTimeRegion(relativeDate.Count, relativeDate.Unit, relativeDate.Direction)
|
||
relativeTimeStart2, relativeTimeEnd2 := calcRelativeTimeRegion(relativeDate2.Count, relativeDate2.Unit, relativeDate2.Direction)
|
||
return filterRelativeTime(value.Date.Content, value.Date.IsNotEmpty, operator, relativeTimeStart, relativeTimeEnd, relativeDate.Direction, relativeTimeStart2, relativeTimeEnd2, relativeDate2.Direction)
|
||
} else { // 使用具体时间比较
|
||
if nil == other.Date {
|
||
return true
|
||
}
|
||
return filterTime(value.Date.Content, value.Date.IsNotEmpty, other.Date.Content, other.Date.Content2, operator)
|
||
}
|
||
}
|
||
case KeyTypeCreated:
|
||
if nil != value.Created {
|
||
if nil != relativeDate { // 使用相对时间比较
|
||
relativeTimeStart, relativeTimeEnd := calcRelativeTimeRegion(relativeDate.Count, relativeDate.Unit, relativeDate.Direction)
|
||
relativeTimeStart2, relativeTimeEnd2 := calcRelativeTimeRegion(relativeDate2.Count, relativeDate2.Unit, relativeDate2.Direction)
|
||
return filterRelativeTime(value.Created.Content, true, operator, relativeTimeStart, relativeTimeEnd, relativeDate.Direction, relativeTimeStart2, relativeTimeEnd2, relativeDate2.Direction)
|
||
} else { // 使用具体时间比较
|
||
if nil == other.Created {
|
||
return true
|
||
}
|
||
return filterTime(value.Created.Content, value.Created.IsNotEmpty, other.Created.Content, other.Created.Content2, operator)
|
||
}
|
||
}
|
||
case KeyTypeUpdated:
|
||
if nil != value.Updated {
|
||
if nil != relativeDate { // 使用相对时间比较
|
||
relativeTimeStart, relativeTimeEnd := calcRelativeTimeRegion(relativeDate.Count, relativeDate.Unit, relativeDate.Direction)
|
||
relativeTimeStart2, relativeTimeEnd2 := calcRelativeTimeRegion(relativeDate2.Count, relativeDate2.Unit, relativeDate2.Direction)
|
||
return filterRelativeTime(value.Updated.Content, true, operator, relativeTimeStart, relativeTimeEnd, relativeDate.Direction, relativeTimeStart2, relativeTimeEnd2, relativeDate2.Direction)
|
||
} else { // 使用具体时间比较
|
||
if nil == other.Updated {
|
||
return true
|
||
}
|
||
|
||
return filterTime(value.Updated.Content, value.Updated.IsNotEmpty, other.Updated.Content, other.Updated.Content2, operator)
|
||
}
|
||
}
|
||
case KeyTypeSelect, KeyTypeMSelect:
|
||
if nil != value.MSelect {
|
||
if nil != other && nil != other.MSelect {
|
||
switch operator {
|
||
case FilterOperatorIsEqual, FilterOperatorContains:
|
||
contains := false
|
||
for _, v := range value.MSelect {
|
||
for _, v2 := range other.MSelect {
|
||
if v.Content == v2.Content {
|
||
contains = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return contains
|
||
case FilterOperatorIsNotEqual, FilterOperatorDoesNotContain:
|
||
contains := false
|
||
for _, v := range value.MSelect {
|
||
for _, v2 := range other.MSelect {
|
||
if v.Content == v2.Content {
|
||
contains = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return !contains
|
||
case FilterOperatorIsEmpty:
|
||
return 0 == len(value.MSelect) || 1 == len(value.MSelect) && "" == value.MSelect[0].Content
|
||
case FilterOperatorIsNotEmpty:
|
||
return 0 != len(value.MSelect) && !(1 == len(value.MSelect) && "" == value.MSelect[0].Content)
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 没有设置比较值
|
||
|
||
switch operator {
|
||
case FilterOperatorIsEqual, FilterOperatorIsNotEqual, FilterOperatorContains, FilterOperatorDoesNotContain:
|
||
return true
|
||
case FilterOperatorIsEmpty:
|
||
return 0 == len(value.MSelect) || 1 == len(value.MSelect) && "" == value.MSelect[0].Content
|
||
case FilterOperatorIsNotEmpty:
|
||
return 0 != len(value.MSelect) && !(1 == len(value.MSelect) && "" == value.MSelect[0].Content)
|
||
}
|
||
}
|
||
case KeyTypeURL:
|
||
if nil != value.URL && nil != other && nil != other.URL {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return value.URL.Content == other.URL.Content
|
||
case FilterOperatorIsNotEqual:
|
||
return value.URL.Content != other.URL.Content
|
||
case FilterOperatorContains:
|
||
return strings.Contains(value.URL.Content, other.URL.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
return !strings.Contains(value.URL.Content, other.URL.Content)
|
||
case FilterOperatorStartsWith:
|
||
return strings.HasPrefix(value.URL.Content, other.URL.Content)
|
||
case FilterOperatorEndsWith:
|
||
return strings.HasSuffix(value.URL.Content, other.URL.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.URL.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.URL.Content)
|
||
}
|
||
}
|
||
case KeyTypeEmail:
|
||
if nil != value.Email && nil != other && nil != other.Email {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return value.Email.Content == other.Email.Content
|
||
case FilterOperatorIsNotEqual:
|
||
return value.Email.Content != other.Email.Content
|
||
case FilterOperatorContains:
|
||
return strings.Contains(value.Email.Content, other.Email.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
return !strings.Contains(value.Email.Content, other.Email.Content)
|
||
case FilterOperatorStartsWith:
|
||
return strings.HasPrefix(value.Email.Content, other.Email.Content)
|
||
case FilterOperatorEndsWith:
|
||
return strings.HasSuffix(value.Email.Content, other.Email.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.Email.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.Email.Content)
|
||
}
|
||
}
|
||
case KeyTypePhone:
|
||
if nil != value.Phone && nil != other && nil != other.Phone {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return value.Phone.Content == other.Phone.Content
|
||
case FilterOperatorIsNotEqual:
|
||
return value.Phone.Content != other.Phone.Content
|
||
case FilterOperatorContains:
|
||
return strings.Contains(value.Phone.Content, other.Phone.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
return !strings.Contains(value.Phone.Content, other.Phone.Content)
|
||
case FilterOperatorStartsWith:
|
||
return strings.HasPrefix(value.Phone.Content, other.Phone.Content)
|
||
case FilterOperatorEndsWith:
|
||
return strings.HasSuffix(value.Phone.Content, other.Phone.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.Phone.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.Phone.Content)
|
||
}
|
||
}
|
||
case KeyTypeMAsset:
|
||
if nil != value.MAsset && nil != other && nil != other.MAsset && 0 < len(value.MAsset) && 0 < len(other.MAsset) {
|
||
switch operator {
|
||
case FilterOperatorIsEqual, FilterOperatorContains:
|
||
contains := false
|
||
for _, v := range value.MAsset {
|
||
for _, v2 := range other.MAsset {
|
||
if v.Content == v2.Content {
|
||
contains = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return contains
|
||
case FilterOperatorIsNotEqual, FilterOperatorDoesNotContain:
|
||
contains := false
|
||
for _, v := range value.MAsset {
|
||
for _, v2 := range other.MAsset {
|
||
if v.Content == v2.Content {
|
||
contains = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return !contains
|
||
case FilterOperatorIsEmpty:
|
||
return 0 == len(value.MAsset) || 1 == len(value.MAsset) && "" == value.MAsset[0].Content
|
||
case FilterOperatorIsNotEmpty:
|
||
return 0 != len(value.MAsset) && !(1 == len(value.MAsset) && "" == value.MAsset[0].Content)
|
||
}
|
||
}
|
||
case KeyTypeTemplate:
|
||
if nil != value.Template && nil != other && nil != other.Template {
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content == other.Template.Content
|
||
case FilterOperatorIsNotEqual:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content != other.Template.Content
|
||
case FilterOperatorIsGreater:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content > other.Template.Content
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content >= other.Template.Content
|
||
case FilterOperatorIsLess:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content < other.Template.Content
|
||
case FilterOperatorIsLessOrEqual:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return value.Template.Content <= other.Template.Content
|
||
case FilterOperatorContains:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return strings.Contains(value.Template.Content, other.Template.Content)
|
||
case FilterOperatorDoesNotContain:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return !strings.Contains(value.Template.Content, other.Template.Content)
|
||
case FilterOperatorStartsWith:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return strings.HasPrefix(value.Template.Content, other.Template.Content)
|
||
case FilterOperatorEndsWith:
|
||
if "" == strings.TrimSpace(other.Template.Content) {
|
||
return true
|
||
}
|
||
return strings.HasSuffix(value.Template.Content, other.Template.Content)
|
||
case FilterOperatorIsEmpty:
|
||
return "" == strings.TrimSpace(value.Template.Content)
|
||
case FilterOperatorIsNotEmpty:
|
||
return "" != strings.TrimSpace(value.Template.Content)
|
||
}
|
||
}
|
||
case KeyTypeCheckbox:
|
||
if nil != value.Checkbox {
|
||
switch operator {
|
||
case FilterOperatorIsTrue:
|
||
return value.Checkbox.Checked
|
||
case FilterOperatorIsFalse:
|
||
return !value.Checkbox.Checked
|
||
}
|
||
}
|
||
}
|
||
|
||
switch operator {
|
||
case FilterOperatorIsEmpty:
|
||
return value.IsEmpty()
|
||
case FilterOperatorIsNotEmpty:
|
||
return !value.IsEmpty()
|
||
}
|
||
return false
|
||
}
|
||
|
||
func filterRelativeTime(valueMills int64, valueIsNotEmpty bool, operator FilterOperator, otherValueStart, otherValueEnd time.Time, direction RelativeDateDirection, otherValueStart2, otherValueEnd2 time.Time, direction2 RelativeDateDirection) bool {
|
||
valueTime := time.UnixMilli(valueMills)
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && valueTime.Before(otherValueEnd)
|
||
case FilterOperatorIsNotEqual:
|
||
return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd)
|
||
case FilterOperatorIsGreater:
|
||
return valueTime.After(otherValueEnd) || valueTime.Equal(otherValueEnd)
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)
|
||
case FilterOperatorIsLess:
|
||
return valueTime.Before(otherValueStart)
|
||
case FilterOperatorIsLessOrEqual:
|
||
return valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd)
|
||
case FilterOperatorIsBetween:
|
||
if RelativeDateDirectionBefore == direction {
|
||
if RelativeDateDirectionBefore == direction2 {
|
||
var leftStart, rightEnd time.Time
|
||
if otherValueStart.Before(otherValueStart2) {
|
||
leftStart = otherValueStart
|
||
} else {
|
||
leftStart = otherValueStart2
|
||
}
|
||
if otherValueEnd.Before(otherValueStart2) {
|
||
rightEnd = otherValueEnd
|
||
} else {
|
||
rightEnd = otherValueStart2
|
||
}
|
||
return (valueTime.After(leftStart) || valueTime.Equal(leftStart)) && (valueTime.Before(rightEnd) || valueTime.Equal(rightEnd))
|
||
} else if RelativeDateDirectionThis == direction2 {
|
||
return ((valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))) ||
|
||
((valueTime.After(otherValueStart2) || valueTime.Equal(otherValueStart2)) && (valueTime.Before(otherValueEnd2) || valueTime.Equal(otherValueEnd2)))
|
||
} else if RelativeDateDirectionAfter == direction2 {
|
||
var leftStart, rightEnd time.Time
|
||
if otherValueStart.Before(otherValueStart2) {
|
||
leftStart = otherValueStart
|
||
} else {
|
||
leftStart = otherValueStart2
|
||
}
|
||
if otherValueEnd.Before(otherValueEnd2) {
|
||
rightEnd = otherValueEnd2
|
||
} else {
|
||
rightEnd = otherValueEnd
|
||
}
|
||
return (valueTime.After(leftStart) || valueTime.Equal(leftStart)) && (valueTime.Before(rightEnd) || valueTime.Equal(rightEnd))
|
||
}
|
||
} else if RelativeDateDirectionThis == direction {
|
||
return ((valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))) ||
|
||
((valueTime.After(otherValueStart2) || valueTime.Equal(otherValueStart2)) && (valueTime.Before(otherValueEnd2) || valueTime.Equal(otherValueEnd2)))
|
||
} else if RelativeDateDirectionAfter == direction {
|
||
if RelativeDateDirectionBefore == direction2 {
|
||
var leftStart, rightEnd time.Time
|
||
if otherValueStart.Before(otherValueStart2) {
|
||
leftStart = otherValueStart
|
||
} else {
|
||
leftStart = otherValueStart2
|
||
}
|
||
if otherValueEnd.Before(otherValueEnd2) {
|
||
rightEnd = otherValueEnd2
|
||
} else {
|
||
rightEnd = otherValueEnd
|
||
}
|
||
return (valueTime.After(leftStart) || valueTime.Equal(leftStart)) && (valueTime.Before(rightEnd) || valueTime.Equal(rightEnd))
|
||
} else if RelativeDateDirectionThis == direction2 {
|
||
return ((valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))) ||
|
||
((valueTime.After(otherValueStart2) || valueTime.Equal(otherValueStart2)) && (valueTime.Before(otherValueEnd2) || valueTime.Equal(otherValueEnd2)))
|
||
} else if RelativeDateDirectionAfter == direction2 {
|
||
var leftStart, rightEnd time.Time
|
||
if otherValueStart.Before(otherValueStart2) {
|
||
leftStart = otherValueStart
|
||
} else {
|
||
leftStart = otherValueStart2
|
||
}
|
||
if otherValueEnd.After(otherValueEnd2) {
|
||
rightEnd = otherValueEnd
|
||
} else {
|
||
rightEnd = otherValueEnd2
|
||
}
|
||
return (valueTime.After(leftStart) || valueTime.Equal(leftStart)) && (valueTime.Before(rightEnd) || valueTime.Equal(rightEnd))
|
||
}
|
||
}
|
||
return false
|
||
case FilterOperatorIsEmpty:
|
||
return !valueIsNotEmpty
|
||
case FilterOperatorIsNotEmpty:
|
||
return valueIsNotEmpty
|
||
}
|
||
return false
|
||
}
|
||
|
||
func filterTime(valueMills int64, valueIsNotEmpty bool, otherValueMills, otherValueMills2 int64, operator FilterOperator) bool {
|
||
valueTime := time.UnixMilli(valueMills)
|
||
otherValueTime := time.UnixMilli(otherValueMills)
|
||
otherValueStart := time.Date(otherValueTime.Year(), otherValueTime.Month(), otherValueTime.Day(), 0, 0, 0, 0, otherValueTime.Location())
|
||
otherValueEnd := time.Date(otherValueTime.Year(), otherValueTime.Month(), otherValueTime.Day(), 23, 59, 59, 999999999, otherValueTime.Location())
|
||
switch operator {
|
||
case FilterOperatorIsEqual:
|
||
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && valueTime.Before(otherValueEnd)
|
||
case FilterOperatorIsNotEqual:
|
||
return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd)
|
||
case FilterOperatorIsGreater:
|
||
return valueTime.After(otherValueEnd) || valueTime.Equal(otherValueEnd)
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)
|
||
case FilterOperatorIsLess:
|
||
return valueTime.Before(otherValueStart)
|
||
case FilterOperatorIsLessOrEqual:
|
||
return valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd)
|
||
case FilterOperatorIsBetween:
|
||
otherValueTime2 := time.UnixMilli(otherValueMills2)
|
||
otherValueEnd2 := time.Date(otherValueTime2.Year(), otherValueTime2.Month(), otherValueTime2.Day(), 23, 59, 59, 999999999, otherValueTime2.Location())
|
||
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd2) || valueTime.Equal(otherValueEnd2))
|
||
case FilterOperatorIsEmpty:
|
||
return !valueIsNotEmpty
|
||
case FilterOperatorIsNotEmpty:
|
||
return valueIsNotEmpty
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 根据 Count、Unit 和 Direction 计算相对当前时间的开始时间和结束时间
|
||
func calcRelativeTimeRegion(count int, unit RelativeDateUnit, direction RelativeDateDirection) (start, end time.Time) {
|
||
now := time.Now()
|
||
switch unit {
|
||
case RelativeDateUnitDay:
|
||
switch direction {
|
||
case RelativeDateDirectionBefore:
|
||
// 结束时间:今天的 0 点
|
||
end = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||
// 开始时间:结束时间减去 count 天
|
||
start = end.AddDate(0, 0, -count)
|
||
case RelativeDateDirectionThis:
|
||
// 开始时间:今天的 0 点
|
||
start = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||
// 结束时间:今天的 23:59:59.999999999
|
||
end = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 999999999, now.Location())
|
||
case RelativeDateDirectionAfter:
|
||
// 开始时间:今天的 23:59:59.999999999
|
||
start = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 999999999, now.Location())
|
||
// 结束时间:开始时间加上 count 天
|
||
end = start.AddDate(0, 0, count)
|
||
}
|
||
case RelativeDateUnitWeek:
|
||
weekday := int(now.Weekday())
|
||
if 0 == weekday {
|
||
weekday = 7
|
||
}
|
||
switch direction {
|
||
case RelativeDateDirectionBefore:
|
||
// 结束时间:本周的周一
|
||
end = time.Date(now.Year(), now.Month(), now.Day()-weekday+1, 0, 0, 0, 0, now.Location())
|
||
// 开始时间:结束时间减去 count*7 天
|
||
start = end.AddDate(0, 0, -count*7)
|
||
case RelativeDateDirectionThis:
|
||
// 开始时间:本周的周一
|
||
start = time.Date(now.Year(), now.Month(), now.Day()-weekday+1, 0, 0, 0, 0, now.Location())
|
||
// 结束时间:本周的周日
|
||
end = time.Date(now.Year(), now.Month(), now.Day()-weekday+7, 23, 59, 59, 999999999, now.Location())
|
||
case RelativeDateDirectionAfter:
|
||
// 开始时间:本周的周日
|
||
start = time.Date(now.Year(), now.Month(), now.Day()-weekday+7, 23, 59, 59, 999999999, now.Location())
|
||
// 结束时间:开始时间加上 count*7 天
|
||
end = start.AddDate(0, 0, count*7)
|
||
}
|
||
case RelativeDateUnitMonth:
|
||
switch direction {
|
||
case RelativeDateDirectionBefore:
|
||
// 结束时间:本月的 1 号
|
||
end = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
||
// 开始时间:结束时间减去 count 个月
|
||
start = end.AddDate(0, -count, 0)
|
||
case RelativeDateDirectionThis:
|
||
// 开始时间:本月的 1 号
|
||
start = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
||
// 结束时间:下个月的 1 号减去 1 纳秒
|
||
end = time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, now.Location()).Add(-time.Nanosecond)
|
||
case RelativeDateDirectionAfter:
|
||
// 开始时间:下个月的 1 号减去 1 纳秒
|
||
start = time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, now.Location()).Add(-time.Nanosecond)
|
||
// 结束时间:开始时间加上 count 个月
|
||
end = start.AddDate(0, count, 0)
|
||
}
|
||
case RelativeDateUnitYear:
|
||
switch direction {
|
||
case RelativeDateDirectionBefore:
|
||
// 结束时间:今年的 1 月 1 号
|
||
end = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
|
||
// 开始时间:结束时间减去 count 年
|
||
start = end.AddDate(-count, 0, 0)
|
||
case RelativeDateDirectionThis:
|
||
// 开始时间:今年的 1 月 1 号
|
||
start = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
|
||
// 结束时间:明年的 1 月 1 号减去 1 纳秒
|
||
end = time.Date(now.Year()+1, 1, 1, 0, 0, 0, 0, now.Location()).Add(-time.Nanosecond)
|
||
case RelativeDateDirectionAfter:
|
||
// 开始时间:今年的 12 月 31 号
|
||
start = time.Date(now.Year(), 12, 31, 23, 59, 59, 999999999, now.Location())
|
||
// 结束时间:开始时间加上 count 年
|
||
end = start.AddDate(count, 0, 0)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
func (filter *ViewFilter) GetAffectValue(key *Key, defaultVal *Value) (ret *Value) {
|
||
if nil != filter.Value {
|
||
if KeyTypeRelation == filter.Value.Type || KeyTypeTemplate == filter.Value.Type || KeyTypeRollup == filter.Value.Type || KeyTypeUpdated == filter.Value.Type || KeyTypeCreated == filter.Value.Type {
|
||
// 所有生成的数据都不设置默认值
|
||
return nil
|
||
}
|
||
}
|
||
|
||
if nil == filter.Value {
|
||
if nil != filter.RelativeDate {
|
||
// 相对日期今天的动态日期不设置默认值
|
||
return nil
|
||
}
|
||
// 两个值都空的情况下也不设置默认值
|
||
return nil
|
||
}
|
||
|
||
if FilterOperatorIsEmpty != filter.Operator && FilterOperatorIsNotEmpty != filter.Operator {
|
||
if filter.Value.IsEmpty() {
|
||
// 在不是过滤空值和非空值的情况下,空值不设置默认值 https://github.com/siyuan-note/siyuan/issues/11297
|
||
return nil
|
||
}
|
||
}
|
||
|
||
ret = filter.Value.Clone()
|
||
ret.CreatedAt = util.CurrentTimeMillis()
|
||
ret.UpdatedAt = ret.CreatedAt + 1000
|
||
|
||
if nil != defaultVal {
|
||
// 如果有默认值则优先使用默认值
|
||
clonedDefaultVal := defaultVal.Clone()
|
||
defaultRawVal := clonedDefaultVal.GetValByType(filter.Value.Type)
|
||
if nil != defaultRawVal {
|
||
ret.SetValByType(filter.Value.Type, defaultRawVal)
|
||
return
|
||
}
|
||
}
|
||
// 没有默认值则使用过滤条件的值
|
||
|
||
switch filter.Value.Type {
|
||
case KeyTypeBlock:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
|
||
case FilterOperatorContains:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
|
||
case FilterOperatorDoesNotContain:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
|
||
case FilterOperatorStartsWith:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
|
||
case FilterOperatorEndsWith:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
|
||
}
|
||
case KeyTypeText:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Text = &ValueText{Content: filter.Value.Text.Content}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.Text = &ValueText{Content: ""}
|
||
case FilterOperatorContains:
|
||
ret.Text = &ValueText{Content: filter.Value.Text.Content}
|
||
case FilterOperatorDoesNotContain:
|
||
ret.Text = &ValueText{Content: ""}
|
||
case FilterOperatorStartsWith:
|
||
ret.Text = &ValueText{Content: filter.Value.Text.Content}
|
||
case FilterOperatorEndsWith:
|
||
ret.Text = &ValueText{Content: filter.Value.Text.Content}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Text = &ValueText{Content: ""}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Text = &ValueText{Content: ""}
|
||
}
|
||
case KeyTypeNumber:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Number = &ValueNumber{Content: filter.Value.Number.Content, IsNotEmpty: false}
|
||
case FilterOperatorIsNotEqual:
|
||
if 0 == filter.Value.Number.Content {
|
||
ret.Number = &ValueNumber{Content: 1, IsNotEmpty: true}
|
||
} else {
|
||
ret.Number = &ValueNumber{Content: 0, IsNotEmpty: true}
|
||
}
|
||
case FilterOperatorIsGreater:
|
||
ret.Number = &ValueNumber{Content: filter.Value.Number.Content + 1, IsNotEmpty: true}
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
ret.Number = &ValueNumber{Content: filter.Value.Number.Content, IsNotEmpty: true}
|
||
case FilterOperatorIsLess:
|
||
ret.Number = &ValueNumber{Content: filter.Value.Number.Content - 1, IsNotEmpty: true}
|
||
case FilterOperatorIsLessOrEqual:
|
||
ret.Number = &ValueNumber{Content: filter.Value.Number.Content, IsNotEmpty: true}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Number = &ValueNumber{Content: 0, IsNotEmpty: false}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Number = &ValueNumber{Content: 0, IsNotEmpty: true}
|
||
}
|
||
case KeyTypeDate:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content, IsNotEmpty: true}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.Date = &ValueDate{Content: util.CurrentTimeMillis(), IsNotEmpty: true}
|
||
case FilterOperatorIsGreater:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content + 1000*60, IsNotEmpty: true}
|
||
case FilterOperatorIsGreaterOrEqual:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content, IsNotEmpty: true}
|
||
case FilterOperatorIsLess:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content - 1000*60, IsNotEmpty: true}
|
||
case FilterOperatorIsLessOrEqual:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content, IsNotEmpty: true}
|
||
case FilterOperatorIsBetween:
|
||
ret.Date = &ValueDate{Content: filter.Value.Date.Content - 1000*60, IsNotEmpty: true}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Date = &ValueDate{Content: 0, IsNotEmpty: false}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Date = &ValueDate{Content: util.CurrentTimeMillis(), IsNotEmpty: true}
|
||
}
|
||
case KeyTypeSelect, KeyTypeMSelect:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
valueSelect := &ValueSelect{Content: "", Color: "1"}
|
||
if 0 < len(key.Options) {
|
||
valueSelect.Color = key.Options[0].Color
|
||
}
|
||
if 0 < len(filter.Value.MSelect) {
|
||
valueSelect.Content = filter.Value.MSelect[0].Content
|
||
valueSelect.Color = filter.Value.MSelect[0].Color
|
||
}
|
||
ret.MSelect = []*ValueSelect{valueSelect}
|
||
case FilterOperatorIsNotEqual:
|
||
if 0 < len(filter.Value.MSelect) {
|
||
ret.MSelect = []*ValueSelect{}
|
||
}
|
||
case FilterOperatorIsEmpty:
|
||
ret.MSelect = []*ValueSelect{}
|
||
case FilterOperatorIsNotEmpty:
|
||
if 0 < len(key.Options) {
|
||
ret.MSelect = []*ValueSelect{{Content: key.Options[0].Name, Color: key.Options[0].Color}}
|
||
}
|
||
}
|
||
case KeyTypeURL:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.URL = &ValueURL{Content: filter.Value.URL.Content}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.URL = &ValueURL{Content: filter.Value.URL.Content}
|
||
case FilterOperatorContains:
|
||
ret.URL = &ValueURL{Content: filter.Value.URL.Content}
|
||
case FilterOperatorDoesNotContain:
|
||
ret.URL = &ValueURL{Content: ""}
|
||
case FilterOperatorStartsWith:
|
||
ret.URL = &ValueURL{Content: filter.Value.URL.Content}
|
||
case FilterOperatorEndsWith:
|
||
ret.URL = &ValueURL{Content: filter.Value.URL.Content}
|
||
case FilterOperatorIsEmpty:
|
||
ret.URL = &ValueURL{}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.URL = &ValueURL{}
|
||
}
|
||
case KeyTypeEmail:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
|
||
case FilterOperatorContains:
|
||
ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
|
||
case FilterOperatorDoesNotContain:
|
||
ret.Email = &ValueEmail{Content: ""}
|
||
case FilterOperatorStartsWith:
|
||
ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
|
||
case FilterOperatorEndsWith:
|
||
ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Email = &ValueEmail{Content: ""}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Email = &ValueEmail{Content: ""}
|
||
}
|
||
case KeyTypePhone:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual:
|
||
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
|
||
case FilterOperatorIsNotEqual:
|
||
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content + ""}
|
||
case FilterOperatorContains:
|
||
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
|
||
case FilterOperatorDoesNotContain:
|
||
ret.Phone = &ValuePhone{Content: ""}
|
||
case FilterOperatorStartsWith:
|
||
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
|
||
case FilterOperatorEndsWith:
|
||
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
|
||
case FilterOperatorIsEmpty:
|
||
ret.Phone = &ValuePhone{Content: ""}
|
||
case FilterOperatorIsNotEmpty:
|
||
ret.Phone = &ValuePhone{Content: ""}
|
||
}
|
||
case KeyTypeMAsset:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsEqual, FilterOperatorContains:
|
||
if 0 < len(filter.Value.MAsset) {
|
||
ret.MAsset = []*ValueAsset{{Type: filter.Value.MAsset[0].Type, Name: filter.Value.MAsset[0].Name, Content: filter.Value.MAsset[0].Content}}
|
||
}
|
||
case FilterOperatorIsNotEqual, FilterOperatorDoesNotContain:
|
||
case FilterOperatorIsEmpty:
|
||
ret.MAsset = []*ValueAsset{}
|
||
case FilterOperatorIsNotEmpty:
|
||
}
|
||
case KeyTypeCheckbox:
|
||
switch filter.Operator {
|
||
case FilterOperatorIsTrue:
|
||
ret.Checkbox = &ValueCheckbox{Checked: true}
|
||
case FilterOperatorIsFalse:
|
||
ret.Checkbox = &ValueCheckbox{Checked: false}
|
||
}
|
||
case KeyTypeRelation:
|
||
switch filter.Operator {
|
||
case FilterOperatorContains:
|
||
if 0 < len(filter.Value.Relation.Contents) {
|
||
ret.Relation = &ValueRelation{Contents: filter.Value.Relation.Contents}
|
||
}
|
||
case FilterOperatorDoesNotContain:
|
||
case FilterOperatorIsEmpty:
|
||
ret.Relation = &ValueRelation{Contents: []*Value{}}
|
||
case FilterOperatorIsNotEmpty:
|
||
}
|
||
}
|
||
return
|
||
}
|