hotime/code/makecode.go

616 lines
17 KiB
Go
Raw Normal View History

package code
import (
. "../common"
"../db"
"errors"
2021-06-04 02:04:37 +00:00
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
2021-06-04 02:04:37 +00:00
"strings"
)
type MakeCode struct {
2021-06-12 05:33:35 +00:00
IndexMenus Map
TableConfig Map
TableColumns map[string]map[string]Map
SearchColumns map[string]map[string]Map
Config Map
Error
}
func (that *MakeCode) Db2JSON(name string, path string, db db.HoTimeDB) {
2021-06-04 18:18:56 +00:00
isMake := false
idSlice := Slice{}
if that.TableColumns == nil {
that.TableColumns = make(map[string]map[string]Map)
}
2021-06-12 05:33:35 +00:00
if that.SearchColumns == nil {
that.SearchColumns = make(map[string]map[string]Map)
}
//加载配置文件
btes, err := ioutil.ReadFile(path)
2021-06-07 03:32:47 +00:00
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("配置文件不存在,或者配置出错,使用缺省默认配置"))
}
2021-06-11 00:06:44 +00:00
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
}
}
}
}
}
}
2021-06-05 23:50:58 +00:00
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")
2021-06-12 05:33:35 +00:00
search := that.TableConfig.GetMap(tableName).GetSlice("search")
//初始化
if that.TableColumns[tableName] == nil {
that.TableColumns[tableName] = map[string]Map{}
}
2021-06-12 05:33:35 +00:00
//初始化搜索项
if that.SearchColumns[tableName] == nil {
that.SearchColumns[tableName] = map[string]Map{}
}
//注入源数据
2021-06-05 23:50:58 +00:00
for index, _ := range columns {
columnsName := columns.GetMap(index).GetString("name")
that.TableColumns[tableName][columnsName] = columns.GetMap(index)
}
2021-06-12 05:33:35 +00:00
//注入search源数据
for index, _ := range search {
searchName := search.GetMap(index).GetString("name")
that.SearchColumns[tableName][searchName] = search.GetMap(index)
}
}
2021-06-04 02:04:37 +00:00
myInit := strings.Replace(InitTpt, "{{name}}", name, -1)
ctrList := ""
2021-06-04 18:18:56 +00:00
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" {
2021-06-04 18:18:56 +00:00
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") == "" {
2021-06-11 00:06:44 +00:00
v["label"] = v.GetString("name")
2021-06-04 18:18:56 +00:00
}
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"},
2021-06-12 19:08:43 +00:00
{"type": "search", "name": "keyword", "label": "请输入关键词", "value": nil},
{"type": "search", "name": "daterange", "label": "时间段", "value": nil},
{"type": "search", "name": "sort", "label": "排序", "value": nil},
2021-06-12 05:33:35 +00:00
//{"type": "select", "name": "state", "label": "状态", "value": nil,
// "options": []Map{
// {"name": "正常", "value": 0},
// {"name": "异常", "value": 1},
// {"name": "全部", "value": nil},
// },
//},
2021-06-04 18:18:56 +00:00
},
}
2021-06-04 18:18:56 +00:00
}
2021-06-07 03:32:47 +00:00
//else {
// if !(that.TableConfig.GetMap(v.GetString("name")).GetString("label") != "备注" &&
// v.GetString("label") == "备注") {
// that.TableConfig.GetMap(v.GetString("name"))["label"] = v.GetString("label")
// }
//
//}
2021-06-04 18:18:56 +00:00
//初始化
if that.TableColumns[v.GetString("name")] == nil {
that.TableColumns[v.GetString("name")] = make(map[string]Map)
}
2021-06-11 00:06:44 +00:00
2021-06-12 05:33:35 +00:00
//初始化
if that.SearchColumns[v.GetString("name")] == nil {
that.SearchColumns[v.GetString("name")] = make(map[string]Map)
}
2021-06-04 18:18:56 +00:00
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") + "]);")
}
2021-06-04 18:18:56 +00:00
idSlice = append(idSlice, tableInfo)
for _, info := range tableInfo {
if info.GetString("label") == "" {
2021-06-11 00:06:44 +00:00
info["label"] = info.GetString("name")
}
2021-06-05 23:50:58 +00:00
coloum := that.TableColumns[v.GetString("name")][info.GetString("name")]
2021-06-04 18:18:56 +00:00
2021-06-05 23:50:58 +00:00
if coloum == nil {
2021-06-07 03:32:47 +00:00
//根据类型判断真实类型
for k, v := range ColumnDataType {
if strings.Contains(info.GetString("type"), k) {
info["type"] = v
break
}
}
2021-06-05 23:50:58 +00:00
coloum = Map{
2021-06-04 18:18:56 +00:00
"name": info.GetString("name"),
"type": info.GetString("type"),
"label": info.GetString("label"),
//"add": false, "info": false, "edit": false, "list": true,
2021-06-07 03:32:47 +00:00
//"must": false,
2021-06-04 18:18:56 +00:00
}
2021-06-12 05:33:35 +00:00
//备注以空格隔开,空格后的是其他备注
indexNum := strings.Index(info.GetString("label"), " ")
if indexNum > 0 {
coloum["label"] = info.GetString("label")[:indexNum]
}
2021-06-07 03:32:47 +00:00
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
}
}
2021-06-12 05:33:35 +00:00
2021-06-12 19:08:43 +00:00
//如果是select类型需要设置options
if coloum.GetString("type") == "number" {
coloum["sortable"] = true
}
2021-06-12 05:33:35 +00:00
//如果是select类型需要设置options
if coloum.GetString("type") == "select" {
options := Slice{}
comments := strings.Split(info.GetString("label"), " ")
if len(comments) >= 2 {
optionComment := strings.Split(comments[1], ",")
for _, v := range optionComment {
optionSlice := strings.Split(v, "-")
if len(optionSlice) >= 2 {
options = append(options, Map{"name": optionSlice[1], "value": optionSlice[0]})
}
}
}
coloum["options"] = options
}
2021-06-07 03:32:47 +00:00
if !coloum.GetBool("notUse") {
that.TableConfig.GetMap(v.GetString("name"))["columns"] = append(that.TableConfig.GetMap(v.GetString("name")).GetSlice("columns"), coloum)
2021-06-04 02:04:37 +00:00
}
2021-06-07 03:32:47 +00:00
}
//else {
//
// //if !(coloum.GetString("label") != "备注" && info.GetString("label") == "备注") {
// // coloum["label"] = info.GetString("label")
// //}
// //coloum["type"] = info.GetString("type")
//}
//暂时不关闭参数,保证表数据完全读取到
2021-06-05 23:50:58 +00:00
that.TableColumns[v.GetString("name")][info.GetString("name")] = coloum
2021-06-04 02:04:37 +00:00
}
2021-06-04 02:04:37 +00:00
2021-06-04 18:18:56 +00:00
//创建模块文件
//判断文件是否存在
//_, 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)
}
2021-06-04 18:18:56 +00:00
isMake = true
}
2021-06-04 02:04:37 +00:00
2021-06-04 18:18:56 +00:00
ctrList = ctrList + `"` + v.GetString("name") + `":` + v.GetString("name") + "Ctr,\r\n "
}
2021-06-05 23:50:58 +00:00
that.Config["tables"] = that.TableConfig
2021-06-04 18:18:56 +00:00
2021-06-07 03:32:47 +00:00
//生成id判断数据库是否有改变以保证数据库和配置文件匹配唯一
2021-06-04 18:18:56 +00:00
id := Md5(ObjToStr(idSlice))
2021-06-04 02:04:37 +00:00
if id == that.Config.GetString("id") {
2021-06-04 18:18:56 +00:00
if isMake { //有生成包文件
fmt.Println("有新的业务代码生成,请重新运行")
os.Exit(-1)
}
2021-06-04 02:04:37 +00:00
return
}
2021-06-11 00:06:44 +00:00
//数据生成完后进一步解析
2021-06-07 03:32:47 +00:00
for fk, fv := range that.TableColumns {
2021-06-11 00:06:44 +00:00
//判断是否将表写入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
}
}
2021-06-07 03:32:47 +00:00
for k, v := range fv {
2021-06-12 05:33:35 +00:00
//搜索服务
if that.SearchColumns[fk][v.GetString("name")] == nil &&
v.GetString("type") == "select" {
search := that.TableConfig.GetMap(fk).GetSlice("search")
sv := DeepCopyMap(v).(Map)
sv["value"] = nil
sv["options"] = append(sv.GetSlice("options"), Map{"name": "全部", "value": nil})
that.TableConfig.GetMap(fk)["search"] = append(search, sv)
}
2021-06-11 01:41:23 +00:00
//虚招后缀是_id结尾的表字段 假设org_id
2021-06-07 03:32:47 +00:00
if len(k) <= 3 || strings.LastIndex(k, "_id") != len(k)-3 {
continue
}
2021-06-11 01:41:23 +00:00
//普通表匹配 org_id匹配为org
2021-06-07 03:32:47 +00:00
oldTableName := k[:len(k)-3]
//上级ID匹配
if oldTableName == "parent" {
oldTableName = fk
}
2021-06-11 01:41:23 +00:00
//如果依然找不到则查询system_org是否存在
if that.TableConfig[DefaultMenuParentName+"_"+oldTableName] != nil {
oldTableName = DefaultMenuParentName + "_" + oldTableName
}
2021-06-07 03:32:47 +00:00
//字段有动词前缀,自动进行解析
prefixColumn := strings.Index(oldTableName, "_")
2021-06-11 01:41:23 +00:00
//sys_org_id oldTableName即为sys此处判断为org表存在
2021-06-07 03:32:47 +00:00
if prefixColumn > -1 && that.TableConfig[oldTableName[prefixColumn+1:]] != nil {
oldTableName = oldTableName[prefixColumn+1:]
}
2021-06-11 01:41:23 +00:00
//如果依然找不到则查询system_org是否存在
if prefixColumn > -1 && that.TableConfig[DefaultMenuParentName+"_"+oldTableName[prefixColumn+1:]] != nil {
oldTableName = DefaultMenuParentName + "_" + oldTableName[prefixColumn+1:]
}
//普通方式查询不到,则转换为大型项目模块划分,暂时只支持一级模块划分,
//比如表sys_user 字段org_id查询不到sys_org表则查询org表org表查询不到则查询默认前缀system_org表
2021-06-07 03:32:47 +00:00
//都查询不到则找不到,
prefix := strings.Index(fk, "_")
tableName := oldTableName
if prefix > 0 {
2021-06-11 01:41:23 +00:00
//表模块前缀sys_user sys即为前缀 sys_org
2021-06-07 03:32:47 +00:00
tableName = fk[:prefix+1] + oldTableName
if that.TableConfig[tableName] == nil {
2021-06-11 01:41:23 +00:00
//不存在则改为org
2021-06-07 03:32:47 +00:00
tableName = oldTableName
}
//表前缀+去除字段前缀
prefixColumn := strings.Index(oldTableName, "_")
if prefixColumn > -1 {
tableName = fk[:prefix+1] + oldTableName[prefixColumn+1:]
if that.TableConfig[tableName] == nil {
tableName = oldTableName
}
}
}
2021-06-11 00:06:44 +00:00
//如果数据匹配则写入到配置中
2021-06-07 03:32:47 +00:00
if that.TableConfig[tableName] != nil {
v["link"] = tableName
2021-06-11 01:41:23 +00:00
//一般查询name字段或者label字段如果没有name字段则默认第二个地段
2021-06-07 03:32:47 +00:00
if that.TableColumns[tableName]["name"] != nil {
2021-06-12 05:33:35 +00:00
v["value"] = "name"
continue
2021-06-07 03:32:47 +00:00
}
2021-06-11 01:41:23 +00:00
if that.TableColumns[tableName]["label"] != nil {
2021-06-12 05:33:35 +00:00
v["value"] = "label"
continue
2021-06-11 01:41:23 +00:00
}
2021-06-07 03:32:47 +00:00
if len(that.TableConfig.GetMap(tableName).GetSlice("columns")) > 2 {
2021-06-12 05:33:35 +00:00
v["value"] = that.TableConfig.GetMap(tableName).GetSlice("columns").GetMap(1).GetString("name")
continue
2021-06-07 03:32:47 +00:00
}
}
}
}
2021-06-04 18:18:56 +00:00
fmt.Println(id, "---", that.Config.GetString("id"))
2021-06-04 02:04:37 +00:00
that.Config["id"] = id
//init文件初始化
myInit = strings.Replace(myInit, "{{id}}", id, -1)
myInit = strings.Replace(myInit, "{{tablesCtr}}", ctrList, -1)
_ = os.MkdirAll(name, os.ModeDir)
2021-06-04 18:18:56 +00:00
err = ioutil.WriteFile(name+"/init.go", []byte(myInit), os.ModePerm)
2021-06-04 02:04:37 +00:00
if err != nil {
that.Error.SetError(err)
}
//写入配置文件
2021-06-04 18:18:56 +00:00
//var configByte bytes.Buffer
2021-06-04 18:18:56 +00:00
//err = json.Indent(&configByte, []byte(that.Config.ToJsonString()), "", "\t")
_ = os.MkdirAll(filepath.Dir(path), os.ModeDir)
2021-06-04 18:18:56 +00:00
err = ioutil.WriteFile(path, []byte(that.Config.ToJsonString()), os.ModePerm)
if err != nil {
that.Error.SetError(err)
}
2021-06-04 02:04:37 +00:00
fmt.Println("有新的代码生成,请重新运行")
os.Exit(-1)
}
2021-06-07 03:32:47 +00:00
func (that *MakeCode) Info(table string) string {
reStr := ""
for _, v := range that.TableColumns[table] {
2021-06-07 03:32:47 +00:00
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] {
2021-06-07 03:32:47 +00:00
//不可使用,未在前端展示,但在内存中保持有
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] {
2021-06-07 03:32:47 +00:00
//不可使用,未在前端展示,但在内存中保持有
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] {
2021-06-07 03:32:47 +00:00
//不可使用,未在前端展示,但在内存中保持有
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{}
2021-06-12 19:08:43 +00:00
keyword := Map{}
daterange := Map{}
sort := Map{}
search := that.TableConfig.GetMap(table).GetSlice("search")
for k, _ := range search {
reqValue := req.FormValue(search.GetMap(k).GetString("name"))
if reqValue == "" {
continue
}
2021-06-12 19:08:43 +00:00
searchItem := search.GetMap(k)
searchItemName := searchItem.GetString("name")
columns := that.TableConfig.GetMap(table).GetSlice("columns")
if searchItem.GetString("type") == "search" {
for columnKey, _ := range columns {
if searchItemName == "keyword" &&
columns.GetMap(columnKey).GetString("type") == "text" {
keyword[columns.GetMap(columnKey).GetString("name")+"[~]"] = reqValue
}
//日期类型
if searchItemName == "daterange" && columns.GetMap(columnKey).GetString("type") == "time" {
fmt.Println(req.Form["daterange"])
daterange[columns.GetMap(columnKey).GetString("name")+"[<>]"] = ObjToSlice(req.Form["daterange"])
}
}
if searchItem.GetString("name") == "sort" {
sort["ORDER"] = reqValue
}
continue
}
data[searchItemName] = reqValue
}
where := Map{}
if len(keyword) == 1 {
for k, v := range keyword {
data[k] = v
}
}
if len(keyword) > 1 {
data["OR"] = keyword
}
if len(daterange) == 1 {
for k, v := range daterange {
data[k] = v
}
}
if len(daterange) > 1 {
data["AND"] = Map{"OR": daterange}
}
2021-06-12 19:08:43 +00:00
if len(data) > 1 {
where["AND"] = data
}
2021-06-12 19:08:43 +00:00
if len(data) == 1 {
where = data
}
if len(sort) != 0 {
for k, v := range sort {
where[k] = v
}
}
2021-06-12 19:08:43 +00:00
return reStr, where
}