diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 4846e37e..647ab9a0 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -232,6 +232,115 @@ func _list_import(m *ice.Message, prefix, chain, file string) { m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, chain), kit.MDB_COUNT, count) m.Echo("%d", count) } +func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { + list := map[string]int{} + m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) { + if val[kit.MDB_META] != nil { + val = val[kit.MDB_META].(map[string]interface{}) + } + list[kit.Format(val[field])]++ + }) + for k, i := range list { + m.Push(field, k) + m.Push(kit.MDB_COUNT, i) + } + m.Sort(kit.MDB_COUNT, "int_r") +} + +func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { + fields := kit.Split(kit.Select("zone,id,time,type,name,text", m.Option(FIELDS))) + m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { + if val[kit.MDB_META] != nil { + val = val[kit.MDB_META].(map[string]interface{}) + } + m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) { + if value[kit.MDB_META] != nil { + value = value[kit.MDB_META].(map[string]interface{}) + } + + m.Push(zone, value, fields, val) + }) + }) + +} +func _zone_export(m *ice.Message, prefix, chain, file string) { + f, p, e := kit.Create(kit.Keys(file, CSV)) + m.Assert(e) + defer f.Close() + + w := csv.NewWriter(f) + defer w.Flush() + + fields := kit.Split(kit.Select("zone,id,time,type,name,text", m.Option(FIELDS))) + m.Assert(w.Write(fields)) + + count := 0 + m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) { + if val[kit.MDB_META] != nil { + val = val[kit.MDB_META].(map[string]interface{}) + } + + m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + if value[kit.MDB_META] != nil { + value = value[kit.MDB_META].(map[string]interface{}) + } + + list := []string{} + for _, k := range fields { + list = append(list, kit.Select(kit.Format(val[k]), kit.Format(value[k]))) + } + m.Assert(w.Write(list)) + count++ + }) + }) + + m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count) + m.Echo(p) +} +func _zone_import(m *ice.Message, prefix, chain, file string) { + f, e := os.Open(kit.Keys(file, CSV)) + m.Assert(e) + defer f.Close() + + r := csv.NewReader(f) + head, _ := r.Read() + count := 0 + + list := map[string]string{} + + zkey := m.Option(FIELDS) + + for { + line, e := r.Read() + if e != nil { + break + } + + zone := "" + data := kit.Dict() + for i, k := range head { + switch k { + case zkey: + zone = line[i] + case kit.MDB_ID: + continue + case kit.MDB_EXTRA: + kit.Value(data, k, kit.UnMarshal(line[i])) + default: + kit.Value(data, k, line[i]) + } + } + if list[zone] == "" { + list[zone] = m.Rich(prefix, chain, kit.Dict(zkey, zone)) + } + + m.Grow(prefix, kit.Keys(chain, kit.MDB_HASH, list[zone]), data) + count++ + } + + m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, chain), kit.MDB_COUNT, count) + m.Echo("%d", count) +} const ( CSV = "csv" @@ -242,6 +351,7 @@ const ( META = "meta" HASH = "hash" LIST = "list" + ZONE = "zone" ) const ( FIELDS = "fields" @@ -252,8 +362,8 @@ const ( CREATE = "create" INSERT = "insert" - SELECT = "select" MODIFY = "modify" + SELECT = "select" DELETE = "delete" REMOVE = "remove" @@ -282,14 +392,6 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", _list_delete(m, arg[0], arg[1], arg[3], arg[4]) } }}, - SELECT: {Name: "select conf key type field value", Help: "数据查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - switch arg[2] { - case HASH: - _hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(kit.MDB_FOREACH, arg, 4)) - case LIST: - _list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) - } - }}, MODIFY: {Name: "modify conf key type field value arg...", Help: "编辑", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[2] { case HASH: @@ -298,12 +400,25 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", _list_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) } }}, + SELECT: {Name: "select conf key type field value", Help: "数据查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + switch arg[2] { + case HASH: + _hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(kit.MDB_FOREACH, arg, 4)) + case LIST: + _list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) + case ZONE: + _zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) + } + }}, EXPORT: {Name: "export conf key type file", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option("cache.limit", -2) switch file := _file_name(m, arg...); arg[2] { case HASH: _hash_export(m, arg[0], arg[1], file) case LIST: _list_export(m, arg[0], arg[1], file) + case ZONE: + _zone_export(m, arg[0], arg[1], file) } }}, IMPORT: {Name: "import conf key type file", Help: "导入数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -312,6 +427,8 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", _hash_import(m, arg[0], arg[1], file) case LIST: _list_import(m, arg[0], arg[1], file) + case ZONE: + _zone_import(m, arg[0], arg[1], file) } }}, PRUNES: {Name: "prunes conf key type [field value]...", Help: "清理数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/core/team/task.go b/core/team/task.go index 3a82ce44..56ace9f4 100644 --- a/core/team/task.go +++ b/core/team/task.go @@ -6,158 +6,62 @@ import ( "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - "encoding/csv" - "os" "path" "strings" "time" ) -func _task_list(m *ice.Message, zone string, id string, field ...interface{}) { - fields := strings.Split(kit.Select("begin_time,zone,id,status,level,type,name,text", m.Option("fields")), ",") - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { - if zone = kit.Format(kit.Value(val, "meta.zone")); id == "" { - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - m.Push(zone, value, fields) - }) - return - } - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) { - m.Push("detail", value) - }) - }) +func _sub_key(m *ice.Message, zone string) string { + return kit.Keys(m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, kit.Hashs(zone)) +} + +func _task_list(m *ice.Message, zone string, id string) { + m.Option(mdb.FIELDS, "begin_time,zone,id,status,level,type,name,text") + m.Cmdy(mdb.SELECT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE, zone, id) } func _task_create(m *ice.Message, zone string) { - if m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), zone, nil) == nil { - m.Conf(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_META, kit.MDB_SHORT), kit.MDB_ZONE) - m.Rich(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.Data(kit.MDB_ZONE, zone)) - m.Log_CREATE(kit.MDB_ZONE, zone) - } + m.Conf(m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN), kit.MDB_META, kit.MDB_SHORT), kit.MDB_ZONE) + m.Cmdy(mdb.INSERT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, kit.MDB_ZONE, zone) } func _task_insert(m *ice.Message, zone string, arg ...string) { - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), zone, func(key string, value map[string]interface{}) { - id := m.Grow(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), kit.Dict( - BEGIN_TIME, m.Time(), CLOSE_TIME, m.Time("30m"), kit.MDB_EXTRA, kit.Dict(), - STATUS, StatusPrepare, LEVEL, 3, SCORE, 3, arg, - )) - m.Log_INSERT(kit.MDB_ZONE, zone, kit.MDB_ID, id, arg[0], arg[1]) - m.Echo("%d", id) - }) + if msg := m.Cmd(mdb.SELECT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, kit.MDB_ZONE, zone); len(msg.Appendv(kit.MDB_HASH)) == 0 { + m.Debug("what %v", msg.Formats("meta")) + _task_create(m, zone) + } + + m.Cmdy(mdb.INSERT, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, + BEGIN_TIME, m.Time(), CLOSE_TIME, m.Time("30m"), STATUS, StatusPrepare, LEVEL, 3, SCORE, 3, arg, + ) } -func _task_modify(m *ice.Message, zone, id, pro, set string) { - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) { - switch pro { - case kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TIME: - m.Info("not allow %v", key) - case STATUS: - if value[STATUS] == set { - break - } - switch value[STATUS] { - case StatusCancel, StatusFinish: - m.Info("not allow %v", key) - return - } - switch set { - case StatusProcess: - kit.Value(value, BEGIN_TIME, m.Time()) - case StatusCancel, StatusFinish: - kit.Value(value, CLOSE_TIME, m.Time()) - } - fallthrough - default: - m.Log_MODIFY(kit.MDB_ZONE, zone, kit.MDB_ID, id, kit.MDB_KEY, pro, kit.MDB_VALUE, set) - kit.Value(value, pro, set) - } - }) - }) +func _task_modify(m *ice.Message, zone, id, field, value string, arg ...string) { + if field == STATUS { + switch value { + case StatusProcess: + arg = append(arg, BEGIN_TIME, m.Time()) + case StatusCancel, StatusFinish: + arg = append(arg, CLOSE_TIME, m.Time()) + } + } + m.Cmdy(mdb.MODIFY, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, kit.MDB_ID, id, field, value, arg) } func _task_delete(m *ice.Message, zone, id string) { - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) { - m.Log_DELETE(kit.MDB_ZONE, zone, kit.MDB_ID, id) - kit.Value(value, STATUS, StatusCancel) - }) - }) + m.Cmdy(mdb.MODIFY, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, kit.MDB_ID, id, STATUS, StatusCancel) } func _task_export(m *ice.Message, file string) { - f, p, e := kit.Create(file) - m.Assert(e) - defer f.Close() - - w := csv.NewWriter(f) - defer w.Flush() - - m.Assert(w.Write([]string{ - kit.MDB_ZONE, kit.MDB_ID, kit.MDB_TIME, - kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT, - LEVEL, STATUS, SCORE, - BEGIN_TIME, CLOSE_TIME, - kit.MDB_EXTRA, - })) - count := 0 - m.Option("cache.limit", -2) - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.MDB_FOREACH, func(key string, val map[string]interface{}) { - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - m.Assert(w.Write(kit.Simple( - kit.Format(kit.Value(val, "meta.zone")), - kit.Format(value[kit.MDB_ID]), - kit.Format(value[kit.MDB_TIME]), - kit.Format(value[kit.MDB_TYPE]), - kit.Format(value[kit.MDB_NAME]), - kit.Format(value[kit.MDB_TEXT]), - kit.Format(value[LEVEL]), - kit.Format(value[STATUS]), - kit.Format(value[SCORE]), - kit.Format(value[BEGIN_TIME]), - kit.Format(value[CLOSE_TIME]), - kit.Format(value[kit.MDB_EXTRA]), - ))) - count++ - }) - }) - m.Log_EXPORT("file", p, "count", count) - m.Echo(p) + m.Option(mdb.FIELDS, "zone,id,time,type,name,text,level,status,score,begin_time,close_time,extra") + m.Cmdy(mdb.EXPORT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE) } func _task_import(m *ice.Message, file string) { - f, e := os.Open(file) - m.Assert(e) - defer f.Close() - - r := csv.NewReader(f) - heads, _ := r.Read() - count := 0 - for { - lines, e := r.Read() - if e != nil { - break - } - - zone := "" - data := kit.Dict() - for i, k := range heads { - switch k { - case kit.MDB_ZONE: - zone = lines[i] - case kit.MDB_ID: - continue - case kit.MDB_EXTRA: - kit.Value(data, k, kit.UnMarshal(lines[i])) - default: - kit.Value(data, k, lines[i]) - } - } - - _task_create(m, zone) - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), zone, func(key string, value map[string]interface{}) { - id := m.Grow(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), data) - m.Log_INSERT(kit.MDB_ZONE, zone, kit.MDB_ID, id) - count++ - }) + m.Option(mdb.FIELDS, kit.MDB_ZONE) + m.Cmdy(mdb.IMPORT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE, file) +} +func _task_input(m *ice.Message, field, value string) { + switch field { + case kit.MDB_ZONE: + m.Cmdy(mdb.INPUTS, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, field, value) + case kit.MDB_NAME, kit.MDB_TEXT: + m.Cmdy(mdb.INPUTS, m.Prefix(TASK), _sub_key(m, m.Option(kit.MDB_ZONE)), mdb.LIST, field, value) } - m.Log_IMPORT("file", file, "count", count) - m.Echo(file) } func _task_search(m *ice.Message, kind, name, text string, arg ...string) { @@ -195,28 +99,6 @@ func _task_action(m *ice.Message, status interface{}, action ...string) []string } return action } -func _task_input(m *ice.Message, field, value string) { - switch field { - case "zone": - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.MDB_FOREACH, func(key string, val map[string]interface{}) { - m.Push("zone", kit.Value(val, "meta.zone")) - m.Push("count", kit.Select("0", kit.Format(kit.Value(val, "meta.count")))) - }) - m.Sort("count", "int_r") - case "name", "text": - list := map[string]int{} - m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.MDB_FOREACH, func(key string, val map[string]interface{}) { - m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - list[kit.Format(value[field])]++ - }) - }) - for k, i := range list { - m.Push("key", k) - m.Push("count", i) - } - m.Sort("count", "int_r") - } -} func _task_scope(m *ice.Message, arg ...string) (time.Time, time.Time) { begin_time := time.Now() if len(arg) > 1 { @@ -278,9 +160,8 @@ func init() { TASK: {Name: "task", Help: "task", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE)}, }, Commands: map[string]*ice.Command{ - TASK: {Name: "task zone=auto id=auto auto 添加:button 导出:button 导入:button", Help: "任务", Action: map[string]*ice.Action{ - mdb.INSERT: {Name: "insert zone type=once,step,week name text begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - _task_create(m, arg[1]) + TASK: {Name: "task zone id auto 添加 导出 导入", Help: "任务", Action: map[string]*ice.Action{ + mdb.INSERT: {Name: "insert zone@key type=once,step,week name@key text@key begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) { _task_insert(m, arg[1], arg[2:]...) }}, mdb.MODIFY: {Name: "modify key value", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { @@ -289,12 +170,15 @@ func init() { mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { _task_delete(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID)) }}, - mdb.EXPORT: {Name: "export file", Help: "导出", Hand: func(m *ice.Message, arg ...string) { + mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { _task_export(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv"), arg, 0)) }}, - mdb.IMPORT: {Name: "import file", Help: "导入", Hand: func(m *ice.Message, arg ...string) { + mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { _task_import(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv"), arg, 0)) }}, + mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { + _task_input(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) + }}, mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { _task_search(m, arg[0], arg[1], arg[2], arg[3:]...) @@ -309,20 +193,11 @@ func init() { gdb.END: {Name: "end", Help: "完成", Hand: func(m *ice.Message, arg ...string) { _task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), STATUS, StatusFinish) }}, - - "input": {Name: "input key value", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - _task_input(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if _task_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1)); len(arg) < 2 { + m.Cmdy(mdb.SELECT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.ZONE, arg) + if len(arg) > 0 { m.Table(func(index int, value map[string]string, head []string) { - m.PushAction(_task_action(m, value[STATUS])) - }) - } else { - m.Table(func(index int, value map[string]string, head []string) { - if value["key"] == "status" { - m.Push("key", "action") - } + m.PushRender("action", "button", "", _task_action(m, value[STATUS])...) }) } }}, diff --git a/core/team/team.go b/core/team/team.go index caa56ecd..7f0d9983 100644 --- a/core/team/team.go +++ b/core/team/team.go @@ -8,7 +8,6 @@ import ( const TEAM = "team" var Index = &ice.Context{Name: TEAM, Help: "团队中心", - Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, diff --git a/data.go b/data.go index bfb1819b..182d5c2a 100644 --- a/data.go +++ b/data.go @@ -37,7 +37,9 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin begin := kit.Int(m.Option("cache.begin")) limit := kit.Int(m.Option("cache.limit")) count := kit.Int(m.Option("cache.count", kit.Int(kit.Value(cache, "meta.count")))) - if begin >= 0 || m.Option("cache.limit") == "" { + if limit == -2 { + } else if limit == -1 { + } else if begin >= 0 || m.Option("cache.limit") == "" { if begin > 0 { begin -= 1 }