hotime/code/makecode.go
2021-06-07 11:32:47 +08:00

394 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package code
import (
. "../common"
"../db"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
)
type MakeCode struct {
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.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"] = "备注"
}
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"] = "备注"
}
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
}
//数据生成完后开始关联id
for fk, fv := range that.TableColumns {
for k, v := range fv {
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
}