diff --git a/application.go b/application.go index 3da2941..07e1b0a 100644 --- a/application.go +++ b/application.go @@ -68,18 +68,20 @@ func (that *Application) Run(router Router) { if that.Router == nil { that.Router = Router{} } - for k, v := range router { + for k, _ := range router { + v := router[k] if that.Router[k] == nil { that.Router[k] = v } //直达接口层复用 - for k1, v1 := range v { + for k1, _ := range v { + v1 := v[k1] if that.Router[k][k1] == nil { that.Router[k][k1] = v1 } - for k2, v2 := range v1 { - + for k2, _ := range v1 { + v2 := v1[k2] that.Router[k][k1][k2] = v2 } } @@ -585,15 +587,27 @@ func Init(config string) *Application { //appIns.Router[codeMake.GetString("name")] = TptProject appIns.Router[codeMake.GetString("name")] = Proj{} + for k2, _ := range TptProject { - appIns.Router[codeMake.GetString("name")][k2] = Ctr{} - for k3, v3 := range TptProject[k2] { + if appIns.Router[codeMake.GetString("name")][k2] == nil { + appIns.Router[codeMake.GetString("name")][k2] = Ctr{} + } + for k3, _ := range TptProject[k2] { + v3 := TptProject[k2][k3] appIns.Router[codeMake.GetString("name")][k2][k3] = v3 } } for k1, _ := range appIns.MakeCodeRouter[codeMake.GetString("name")].TableColumns { - appIns.Router[codeMake.GetString("name")][k1] = appIns.Router[codeMake.GetString("name")]["hotimeCommon"] + if appIns.Router[codeMake.GetString("name")][k1] == nil { + appIns.Router[codeMake.GetString("name")][k1] = Ctr{} + } + + for k2, _ := range appIns.Router[codeMake.GetString("name")]["hotimeCommon"] { + //golang毛病 + v2 := appIns.Router[codeMake.GetString("name")]["hotimeCommon"][k2] + appIns.Router[codeMake.GetString("name")][k1][k2] = v2 + } } setMakeCodeListener(codeMake.GetString("name"), &appIns) @@ -731,6 +745,16 @@ func setMakeCodeListener(name string, appIns *Application) { context.Req.Method == "POST" { return isFinished } + //分析 + if len(context.RouterString) == 3 && context.RouterString[2] == "analyse" && + context.Req.Method == "GET" { + + if context.Router[context.RouterString[0]][context.RouterString[1]]["analyse"] == nil { + return isFinished + } + + context.Router[context.RouterString[0]][context.RouterString[1]]["analyse"](context) + } //查询单条 if len(context.RouterString) == 3 && context.Req.Method == "GET" { diff --git a/code.go b/code.go index 7e30a37..47166dd 100644 --- a/code.go +++ b/code.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "net/http" "os" + "sort" "strings" "time" ) @@ -686,6 +687,173 @@ var TptProject = Proj{ that.Display(0, Map{"count": count, "data": reData}) }, + "analyse": func(that *Context) { + hotimeName := that.RouterString[0] + //hotimeName := "super" + fileConfig := that.MakeCodeRouter[hotimeName].FileConfig + tableName := that.RouterString[1] + data := that.Db.Get(fileConfig.GetString("table"), "*", Map{"id": that.Session(fileConfig.GetString("table") + "_id").ToCeilInt()}) + where := Map{} + + //树状结构不允许修改自身的属性,修改别人的可以 + btes, err := ioutil.ReadFile(fileConfig.GetString("config")) + if err != nil { + that.Display(4, "找不到权限配置文件") + return + } + + conf := ObjToMap(string(btes)) + //相同则 + //if tableName!=fileConfig.GetString("table"){ + + flow := conf.GetMap("flow").GetMap(tableName) + if flow != nil && flow.GetMap("sql") != nil { + sql := ObjToMap(DeepCopyMap(flow.GetMap("sql"))) + for k, _ := range sql { + //for uk,_:=range data{ + // if sql[uk]==nil{ + // continue + // } + // uv:=data.GetString(uk) + // + // tv:=strings.Replace(sql.GetString(uk),uk,uv,-1) + // if tv!=uv{ + // where[k]=tv + // break + // } + //} + if k == "parent_ids[~]" && tableName == fileConfig.GetString("table") { + where[k] = strings.Replace(sql.GetString(k), "id", data.GetString("id"), -1) + continue + } + if k == "parent_ids[~]" && data[tableName+"_id"] != nil { + where[k] = strings.Replace(sql.GetString(k), tableName+"_id", data.GetString(tableName+"_id"), -1) + continue + } + if data[sql.GetString(k)] != nil { + where[k] = data[sql.GetString(k)] + } + } + } + //} + + _, where = that.MakeCodeRouter[hotimeName].Search(tableName, data, where, that.Req, that.Db) + delete(where, "ORDER") + //page := ObjToInt(that.Req.FormValue("page")) + //pageSize := ObjToInt(that.Req.FormValue("pageSize")) + + //download := ObjToInt(that.Req.FormValue("download")) + // + //if page < 1 { + // page = 1 + //} + // + //if pageSize <= 0 { + // pageSize = 20 + //} + redData := Map{} + + data["count"] = that.Db.Count(tableName, where) + testQu := []string{} + testQuData := that.MakeCodeRouter[hotimeName].TableColumns[tableName] + for key, _ := range testQuData { + //fmt.Println(key, ":", value) + testQu = append(testQu, key) + } + sort.Strings(testQu) + for _, k := range testQu { + v := testQuData[k] + //不可使用,未在前端展示,但在内存中保持有 + if v.GetBool("notUse") { + + continue + } + + if strings.Contains(k, "state") { + continue + } + if strings.Contains(k, "scope") { + continue + } + if strings.Contains(k, "_code") { + continue + } + //检索查询 + if v.GetString("type") == "select" { + + ops := v.GetSlice("options") + for k1, _ := range ops { + v1 := ops.GetMap(k1) + where1 := DeepCopyMap(where).(Map) + if where1["AND"] != nil { + and := where1.GetMap("AND") + and[k] = v1.GetString("value") + } else { + where1[k] = v1.GetString("value") + where1 = Map{"AND": where1} + } + v1["count"] = that.Db.Count(tableName, where1) + ops[k1] = v1 + } + redData[k] = ops + } + + //检索查询 + if v.GetString("type") == "number" { + + if strings.Contains(k, "area_id") { + areas := that.Db.Select("area", "id,name", Map{"parent_id": 533301}) + for ak, av := range areas { + where1 := DeepCopyMap(where).(Map) + if where1["AND"] != nil { + and := where1.GetMap("AND") + and["area_id"] = av.GetCeilInt64("id") + } else { + where1["area_id"] = av.GetCeilInt64("id") + where1 = Map{"AND": where1} + } + av["count"] = that.Db.Count(tableName, where1) + areas[ak] = av + } + + redData["area"] = areas + continue + } + + if strings.Contains(k, "_id") { + continue + } + if k == "id" { + continue + } + if strings.Contains(k, "percent") { + continue + } + if strings.Contains(k, "exp_") { + continue + } + if strings.Contains(k, "side") { + continue + } + if strings.Contains(k, "lat") { + continue + } + if strings.Contains(k, "lng") { + continue + } + if strings.Contains(k, "distance") { + continue + } + where1 := DeepCopyMap(where).(Map) + redData[k] = that.Db.Sum(tableName, k, where1) + + } + + } + + that.Display(0, redData) + + }, }, "hotime": Ctr{ "file": func(that *Context) { diff --git a/code/makecode.go b/code/makecode.go index 6f3e949..fd3d2af 100644 --- a/code/makecode.go +++ b/code/makecode.go @@ -540,7 +540,7 @@ func (that *MakeCode) Db2JSON(db *db.HoTimeDB, config Map) { } sql := flow.GetMap(fk).GetMap("sql") if k == "parent_id" { - sql["parent_ids[~]"] = "%," + av.GetString("name") + ",%" + sql["parent_ids[~]"] = "," + av.GetString("name") + "," } else { sql[k] = k } @@ -581,7 +581,7 @@ func (that *MakeCode) Db2JSON(db *db.HoTimeDB, config Map) { flow[fk] = Map{"table": fk, "stop": false, "sql": Map{}} } sql := flow.GetMap(fk).GetMap("sql") - sql["parent_ids[~]"] = "%,id,%" + sql["parent_ids[~]"] = ",id," flow.GetMap(fk)["sql"] = sql } @@ -1049,15 +1049,18 @@ func (that *MakeCode) Search(table string, userData Map, data Map, req *http.Req if len(reqValue) == 0 || reqValue[0] == "" { if parent_idsStr != "" && userData[searchItem.GetString("name")] != nil { + + if data[searchItemName] == nil { + continue + } where := Map{parent_idsStr: "," + ObjToStr(userData.GetCeilInt64(searchItem.GetString("name"))) + ","} r := db.Select(searchItem.GetString("link"), "id", where) reqValue = []string{} for _, v := range r { reqValue = append(reqValue, v.GetString("id")) } - if data[searchItemName] != nil { - data[searchItemName] = reqValue - } + + data[searchItemName] = reqValue } @@ -1113,7 +1116,9 @@ func (that *MakeCode) Search(table string, userData Map, data Map, req *http.Req if keywordTableStr == v.GetString("value") { childs := db.Select(v.GetString("link"), "id", Map{v.GetString("value") + "[~]": keywordStr}) childIds := Slice{} + for _, cv := range childs { + childIds = append(childIds, cv.GetCeilInt64("id")) } if len(childIds) != 0 { diff --git a/db/hotimedb.go b/db/hotimedb.go index c22e4c6..7a78b6f 100644 --- a/db/hotimedb.go +++ b/db/hotimedb.go @@ -702,7 +702,7 @@ func (that *HoTimeDB) Select(table string, qu ...interface{}) []Map { } } - if reflect.ValueOf(qu[0]).Type().String() == "common.Slice" { + if reflect.ValueOf(qu[0]).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(qu[0]).Type().String(), "[]") { qu0 := ObjToSlice(qu[0]) for key, _ := range qu0 { v := qu0.GetMap(key) @@ -849,6 +849,31 @@ func (that *HoTimeDB) Count(table string, qu ...interface{}) int { var condition = []string{"AND", "OR"} var vcond = []string{"GROUP", "ORDER", "LIMIT"} +// Count 计数 +func (that *HoTimeDB) Sum(table string, column string, qu ...interface{}) float64 { + var req = []interface{}{} + if len(qu) == 2 { + req = append(req, qu[0]) + req = append(req, "SUM("+column+")") + req = append(req, qu[1]) + } else { + req = append(req, "SUM("+column+")") + req = append(req, qu...) + } + + //req=append(req,qu...) + data := that.Select(table, req...) + //fmt.Println(data) + if len(data) == 0 { + return 0 + } + //res,_:=StrToInt(data[0]["COUNT(*)"].(string)) + res := ObjToStr(data[0]["SUM("+column+")"]) + count := ObjToFloat64(res) + return count + +} + //where语句解析 func (that *HoTimeDB) where(data Map) (string, []interface{}) { @@ -942,11 +967,12 @@ func (that *HoTimeDB) where(data Map) (string, []interface{}) { where += k } - if reflect.ValueOf(v).Type().String() == "common.Slice" { - for i := 0; i < len(v.(Slice)); i++ { - where += " " + ObjToStr(v.(Slice)[i]) + " " + if reflect.ValueOf(v).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(v).Type().String(), "[]") { + vs := ObjToSlice(v) + for i := 0; i < len(vs); i++ { + where += " " + vs.GetString(i) + " " - if len(v.(Slice)) != i+1 { + if len(vs) != i+1 { where += ", " } @@ -1078,16 +1104,18 @@ func (that *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { k = "`" + k + "` " } where += k + " NOT BETWEEN ? AND ? " - res = append(res, v.(Slice)[0]) - res = append(res, v.(Slice)[1]) + vs := ObjToSlice(v) + res = append(res, vs[0]) + res = append(res, vs[1]) case "[<>]": k = strings.Replace(k, "[<>]", "", -1) if !strings.Contains(k, ".") { k = "`" + k + "` " } where += k + " BETWEEN ? AND ? " - res = append(res, v.(Slice)[0]) - res = append(res, v.(Slice)[1]) + vs := ObjToSlice(v) + res = append(res, vs[0]) + res = append(res, vs[1]) default: if !strings.Contains(k, ".") { k = "`" + k + "` " @@ -1098,6 +1126,98 @@ func (that *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { return where, res } + if len(vs) == 1 { + where += k + "=? " + res = append(res, vs[0]) + return where, res + } + + min := int64(0) + isMin := true + IsRange := true + num := int64(0) + isNum := true + + where1 := "" + res1 := Slice{} + where2 := k + " IN (" + res2 := Slice{} + for kvs := 0; kvs <= len(vs); kvs++ { + vsv := int64(0) + if kvs < len(vs) { + vsv = vs.GetCeilInt64(kvs) + //确保是全部是int类型 + if ObjToStr(vsv) != vs.GetString(kvs) { + IsRange = false + break + } + } + + if isNum { + isNum = false + num = vsv + } else { + num++ + } + if isMin { + isMin = false + min = vsv + } + //不等于则到了分路口 + if num != vsv { + //between + if num-min > 1 { + if where1 != "" { + where1 += " OR " + k + " BETWEEN ? AND ? " + } else { + where1 += k + " BETWEEN ? AND ? " + } + res1 = append(res1, min) + res1 = append(res1, num-1) + } else { + //如果就前进一步就用OR + where2 += "?," + res2 = append(res2, min) + } + min = vsv + num = vsv + } + + } + + if IsRange { + + where3 := "" + + if where1 != "" { + where3 += where1 + res = append(res, res1...) + } + + if len(res2) == 1 { + if where3 == "" { + where3 += k + " = ? " + } else { + where3 += " OR " + k + " = ? " + } + res = append(res, res2...) + } else if len(res2) > 1 { + where2 = where2[:len(where2)-1] + if where3 == "" { + where3 += where2 + ")" + } else { + where3 += " OR " + where2 + ")" + } + res = append(res, res2...) + } + + if where3 != "" { + where += "(" + where3 + ")" + } + + return where, res + } + where += k + " IN (" res = append(res, vs...) @@ -1131,6 +1251,100 @@ func (that *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { if len(vs) == 0 { return where, res } + + if len(vs) == 1 { + where += k + "=? " + res = append(res, vs[0]) + return where, res + } + + //In转betwin和IN,提升部分性能 + min := int64(0) + isMin := true + IsRange := true + num := int64(0) + isNum := true + + where1 := "" + res1 := Slice{} + where2 := k + " IN (" + res2 := Slice{} + for kvs := 0; kvs <= len(vs); kvs++ { + vsv := int64(0) + if kvs < len(vs) { + vsv = vs.GetCeilInt64(kvs) + //确保是全部是int类型 + if ObjToStr(vsv) != vs.GetString(kvs) { + IsRange = false + break + } + } + + if isNum { + isNum = false + num = vsv + } else { + num++ + } + if isMin { + isMin = false + min = vsv + } + //不等于则到了分路口 + if num != vsv { + //between + if num-min > 1 { + if where1 != "" { + where1 += " OR " + k + " BETWEEN ? AND ? " + } else { + where1 += k + " BETWEEN ? AND ? " + } + res1 = append(res1, min) + res1 = append(res1, num-1) + } else { + //如果就前进一步就用OR + where2 += "?," + res2 = append(res2, min) + } + min = vsv + num = vsv + } + + } + + if IsRange { + + where3 := "" + + if where1 != "" { + where3 += where1 + res = append(res, res1...) + } + + if len(res2) == 1 { + if where3 == "" { + where3 += k + " = ? " + } else { + where3 += " OR " + k + " = ? " + } + res = append(res, res2...) + } else if len(res2) > 1 { + where2 = where2[:len(where2)-1] + if where3 == "" { + where3 += where2 + ")" + } else { + where3 += " OR " + where2 + ")" + } + res = append(res, res2...) + } + + if where3 != "" { + where += "(" + where3 + ")" + } + + return where, res + } + where += k + " IN (" res = append(res, vs...)