package code import ( . "../common" "../db" "errors" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" ) type MakeCode struct { IndexMenus Map TableConfig Map TableColumns map[string]map[string]Map Config Map Error } func (that *MakeCode) Db2JSON(name string, path string, db db.HoTimeDB) { isMake := false idSlice := Slice{} if that.TableColumns == nil { that.TableColumns = make(map[string]map[string]Map) } //加载配置文件 btes, err := ioutil.ReadFile(path) Config["name"] = name that.Config = DeepCopyMap(Config).(Map) if err == nil { cmap := Map{} //文件是否损坏 cmap.JsonToMap(string(btes), &that.Error) for k, v := range cmap { that.Config[k] = v //程序配置 Config[k] = v //系统配置 } } else { that.Error.SetError(errors.New("配置文件不存在,或者配置出错,使用缺省默认配置")) } that.IndexMenus = Map{} menusConfig := that.Config.GetSlice("menus") //将配置写入到内存中仅作为判断用 if menusConfig != nil { for kmenu, _ := range menusConfig { menu := menusConfig.GetMap(kmenu) if menu != nil { mname := menu.GetString("table") if mname == "" { //如果为空则不是表格 mname = menu.GetString("name") } that.IndexMenus[mname] = menu childMenus := menu.GetSlice("menus") if childMenus != nil { for ckmenu, _ := range childMenus { cmenu := childMenus.GetMap(ckmenu) if cmenu != nil { cname := cmenu.GetString("table") if cmenu.GetString("table") == "" { continue } that.IndexMenus[mname+"/"+cname] = cmenu } } } } } } that.TableConfig = that.Config.GetMap("tables") if that.TableConfig == nil { that.TableConfig = Map{} } for tableName, _ := range that.TableConfig { columns := that.TableConfig.GetMap(tableName).GetSlice("columns") //初始化 if that.TableColumns[tableName] == nil { that.TableColumns[tableName] = map[string]Map{} } //注入源数据 for index, _ := range columns { columnsName := columns.GetMap(index).GetString("name") that.TableColumns[tableName][columnsName] = columns.GetMap(index) } } myInit := strings.Replace(InitTpt, "{{name}}", name, -1) ctrList := "" nowTables := make([]Map, 0) if db.Type == "mysql" { nowTables = db.Select("INFORMATION_SCHEMA.TABLES", "TABLE_NAME as name,TABLE_COMMENT as label", Map{"TABLE_SCHEMA": db.DBName}) } if db.Type == "sqlite" { nowTables = db.Select("sqlite_sequence", "name") } //idSlice=append(idSlice,nowTables) for _, v := range nowTables { if that.TableConfig.GetMap(v.GetString("name")) == nil { if v.GetString("label") == "" { v["label"] = v.GetString("name") } that.TableConfig[v.GetString("name")] = Map{ "label": v.GetString("label"), "table": v.GetString("name"), "auth": []string{"add", "delete", "edit", "info"}, "columns": []Map{}, "search": []Map{ //{"type": "tree", "name": "oid", "label": "组织", "table": "organization", "showName": "label", "children": "children"}, {"type": "text", "name": "keyword", "label": "请输入关键词", "value": nil}, {"type": "date", "name": "date", "label": "时间段", "value": nil}, {"type": "select", "name": "state", "label": "状态", "value": nil, "option": []Map{ {"name": "正常", "value": 0}, {"name": "异常", "value": 1}, {"name": "全部", "value": nil}, }, }, }, } } //else { // if !(that.TableConfig.GetMap(v.GetString("name")).GetString("label") != "备注" && // v.GetString("label") == "备注") { // that.TableConfig.GetMap(v.GetString("name"))["label"] = v.GetString("label") // } // //} //初始化 if that.TableColumns[v.GetString("name")] == nil { that.TableColumns[v.GetString("name")] = make(map[string]Map) } tableInfo := make([]Map, 0) if db.Type == "mysql" { tableInfo = db.Select("INFORMATION_SCHEMA.COLUMNS", "COLUMN_NAME AS name,COLUMN_TYPE AS type,COLUMN_COMMENT AS label", Map{"AND": Map{"TABLE_SCHEMA": db.DBName, "TABLE_NAME": v.GetString("name")}}) } if db.Type == "sqlite" { tableInfo = db.Query("pragma table_info([" + v.GetString("name") + "]);") } idSlice = append(idSlice, tableInfo) for _, info := range tableInfo { if info.GetString("label") == "" { info["label"] = info.GetString("name") } coloum := that.TableColumns[v.GetString("name")][info.GetString("name")] if coloum == nil { //备注以空格隔开,空格后的是其他备注 indexNum := strings.Index(info.GetString("label"), " ") if indexNum >= 0 { info["label"] = info.GetString("label")[:] } //根据类型判断真实类型 for k, v := range ColumnDataType { if strings.Contains(info.GetString("type"), k) { info["type"] = v break } } coloum = Map{ "name": info.GetString("name"), "type": info.GetString("type"), "label": info.GetString("label"), //"add": false, "info": false, "edit": false, "list": true, //"must": false, } for _, v := range ColumnNameType { if (v.Strict && coloum.GetString("name") == v.Name) || strings.Contains(coloum.GetString("name"), v.Name) { //全部都不需要则不加入 if v.Edit == false && v.List == false && v.Info == false { coloum["notUse"] = true break } if v.Info == false { coloum["info"] = v.Info } if v.Edit == false { coloum["edit"] = v.Edit coloum["add"] = v.Edit } if v.List == false { coloum["list"] = v.List } if v.Must == true { coloum["must"] = v.Must } if v.Type != "" { coloum["type"] = v.Type } break } } if !coloum.GetBool("notUse") { that.TableConfig.GetMap(v.GetString("name"))["columns"] = append(that.TableConfig.GetMap(v.GetString("name")).GetSlice("columns"), coloum) } } //else { // // //if !(coloum.GetString("label") != "备注" && info.GetString("label") == "备注") { // // coloum["label"] = info.GetString("label") // //} // //coloum["type"] = info.GetString("type") //} //暂时不关闭参数,保证表数据完全读取到 that.TableColumns[v.GetString("name")][info.GetString("name")] = coloum } //创建模块文件 //判断文件是否存在 //_, err := os.OpenFile(name+"/"+v.GetString("name"), os.O_RDONLY, os.ModePerm) _, err := os.Stat(name + "/" + v.GetString("name") + ".go") if err != nil { //文件不存在,则根据模板创建 myCtr := strings.Replace(CtrTpt, "{{name}}", name, -1) myCtr = strings.Replace(myCtr, "{{table}}", v.GetString("name"), -1) _ = os.MkdirAll(name, os.ModeDir) err = ioutil.WriteFile(name+"/"+v.GetString("name")+".go", []byte(myCtr), os.ModePerm) if err != nil { that.Error.SetError(err) } isMake = true } ctrList = ctrList + `"` + v.GetString("name") + `":` + v.GetString("name") + "Ctr,\r\n " } that.Config["tables"] = that.TableConfig //生成id,判断数据库是否有改变,以保证数据库和配置文件匹配唯一 id := Md5(ObjToStr(idSlice)) if id == that.Config.GetString("id") { if isMake { //有生成包文件 fmt.Println("有新的业务代码生成,请重新运行") os.Exit(-1) } return } //数据生成完后进一步解析 for fk, fv := range that.TableColumns { //判断是否将表写入menu中 isMenusGet := false //判断是否被目录收录 for indexKey, _ := range that.IndexMenus { indexCode := strings.Index(indexKey, fk) //如果相等或者表名在目录中已经设置(主要前一位是/并且他是最后一个字符串) if indexKey == fk || (indexCode != -1 && indexKey[indexCode-1] == '/' && indexKey[indexCode:] == fk) { isMenusGet = true break } } //目录没有收录 if !isMenusGet { tablePrefixCode := strings.Index(fk, "_") isNewPrefix := false //假定表名没有前缀 prefixName := "" //并且代表有前缀,根据数据表分库设定使用 if tablePrefixCode != -1 { prefixName = fk[:tablePrefixCode] } if tablePrefixCode != -1 { for ck, _ := range that.TableColumns { //判断不止一个前缀相同 if strings.Index(ck, prefixName) == 0 && ck != prefixName && ck != fk { isNewPrefix = true break } } } menuIns := Map{"label": that.TableConfig.GetMap(fk).GetString("label"), "table": fk} //多耗费一点内存 mMenu := Map{"menus": Slice{menuIns}, "label": that.TableConfig.GetMap(fk).GetString("label"), "name": prefixName, "icon": "el-icon-setting"} //表名有前缀 if !isNewPrefix { //是否已有对应前缀,已经有对应的menu只需要push进去即可 prefixName = DefaultMenuParentName mMenu = Map{"menus": Slice{menuIns}, "label": "系统管理", "name": prefixName, "icon": "el-icon-setting"} } //没有新前缀 if that.IndexMenus[prefixName] != nil { that.IndexMenus.GetMap(prefixName)["menus"] = append(that.IndexMenus.GetMap(prefixName).GetSlice("menus"), menuIns) that.IndexMenus[prefixName+"/"+fk] = menuIns } else { that.Config["menus"] = append(that.Config.GetSlice("menus"), mMenu) //注入配置 //写入Index that.IndexMenus[prefixName] = mMenu that.IndexMenus[prefixName+"/"+fk] = menuIns } } for k, v := range fv { //虚招后缀是_id结尾的表字段 if len(k) <= 3 || strings.LastIndex(k, "_id") != len(k)-3 { continue } //普通表匹配 oldTableName := k[:len(k)-3] //上级ID匹配 if oldTableName == "parent" { oldTableName = fk } //字段有动词前缀,自动进行解析 prefixColumn := strings.Index(oldTableName, "_") if prefixColumn > -1 && that.TableConfig[oldTableName[prefixColumn+1:]] != nil { oldTableName = oldTableName[prefixColumn+1:] } //普通方式查询不到,则转换为大型项目模块划分,暂时只支持一级模块划分,比如表sys_user 字段org_id,查询不到sys_org表则查询org表, //都查询不到则找不到, prefix := strings.Index(fk, "_") tableName := oldTableName if prefix > 0 { //表模块前缀 tableName = fk[:prefix+1] + oldTableName if that.TableConfig[tableName] == nil { tableName = oldTableName } //表前缀+去除字段前缀 prefixColumn := strings.Index(oldTableName, "_") if prefixColumn > -1 { tableName = fk[:prefix+1] + oldTableName[prefixColumn+1:] if that.TableConfig[tableName] == nil { tableName = oldTableName } } } //如果数据匹配则写入到配置中 if that.TableConfig[tableName] != nil { v["link"] = tableName //一般查询name字段,如果没有name字段则默认第二个地段 if that.TableColumns[tableName]["name"] != nil { v["value"] = tableName + "." + "name" break } if len(that.TableConfig.GetMap(tableName).GetSlice("columns")) > 2 { v["value"] = tableName + "." + that.TableConfig.GetMap(tableName).GetSlice("columns").GetMap(1).GetString("name") break } } } } fmt.Println(id, "---", that.Config.GetString("id")) that.Config["id"] = id //init文件初始化 myInit = strings.Replace(myInit, "{{id}}", id, -1) myInit = strings.Replace(myInit, "{{tablesCtr}}", ctrList, -1) _ = os.MkdirAll(name, os.ModeDir) err = ioutil.WriteFile(name+"/init.go", []byte(myInit), os.ModePerm) if err != nil { that.Error.SetError(err) } //写入配置文件 //var configByte bytes.Buffer //err = json.Indent(&configByte, []byte(that.Config.ToJsonString()), "", "\t") _ = os.MkdirAll(filepath.Dir(path), os.ModeDir) err = ioutil.WriteFile(path, []byte(that.Config.ToJsonString()), os.ModePerm) if err != nil { that.Error.SetError(err) } fmt.Println("有新的代码生成,请重新运行") os.Exit(-1) } func (that *MakeCode) Info(table string) string { reStr := "" for _, v := range that.TableColumns[table] { if v == nil { continue } if v.Get("info") == nil || v.GetBool("info") { reStr += v.GetString("name") + "," } } if len(reStr) != 0 { reStr = reStr[:len(reStr)-1] } return reStr } func (that *MakeCode) Add(table string, req *http.Request) Map { data := Map{} for _, v := range that.TableColumns[table] { //不可使用,未在前端展示,但在内存中保持有 if v.GetBool("notUse") { continue } if v.Get("add") == nil || v.GetBool("add") { reqValue := req.FormValue(v.GetString("name")) if reqValue == "" { return nil } data[v.GetString("name")] = reqValue } } if len(data) == 0 { return nil } return data } func (that *MakeCode) Edit(table string, req *http.Request) Map { data := Map{} for _, v := range that.TableColumns[table] { //不可使用,未在前端展示,但在内存中保持有 if v.GetBool("notUse") { continue } if v.Get("edit") == nil || v.GetBool("edit") { reqValue := req.FormValue(v.GetString("name")) if reqValue == "" { continue } data[v.GetString("name")] = reqValue } } if len(data) == 0 { return nil } return data } func (that *MakeCode) Search(table string, req *http.Request) (string, Map) { reStr := "" for _, v := range that.TableColumns[table] { //不可使用,未在前端展示,但在内存中保持有 if v.GetBool("notUse") { continue } if v.Get("list") == nil || v.GetBool("list") { reStr += v.GetString("name") + "," } } if len(reStr) != 0 { reStr = reStr[:len(reStr)-1] } data := Map{} search := that.TableConfig.GetSlice("search") for k, _ := range search { reqValue := req.FormValue(search.GetMap(k).GetString("name")) if reqValue == "" { continue } data[search.GetMap(k).GetString("name")] = reqValue } return reStr, data }