zhangjq il y a 6 ans
Parent
commit
97c1dcece3
5 fichiers modifiés avec 719 ajouts et 13 suppressions
  1. 52 0
      config/config.go
  2. 616 0
      config/iniconfig.go
  3. 13 12
      controllers/SystemController.go_new
  4. 7 1
      engine/apiengine.go
  5. 31 0
      utils/paths.go

+ 52 - 0
config/config.go

@@ -0,0 +1,52 @@
+package config
+
+import "fmt"
+
+type ApiConfig struct {
+	RunMode string
+	HttpPort int64
+	LogMode string
+	AppName string
+	DataSource string
+}
+
+var AppConfig ApiConfig
+var _config *Config =nil
+
+func init()  {
+	ParseConfig()
+}
+
+func ParseConfig()  {
+	_config, err := LoadConfiguration("conf/app.conf")
+	if err != nil{
+		fmt.Println(err.Error())
+		AppConfig.AppName = ""
+		AppConfig.HttpPort = 8080
+		AppConfig.LogMode = "debug"
+		AppConfig.RunMode = "debug"
+		AppConfig.DataSource = ""
+	}else{
+		AppConfig.AppName = _config.String("appname","")
+		AppConfig.HttpPort = _config.Integer("httpport", 8080)
+		AppConfig.LogMode = _config.String("logmode", "debug")
+		AppConfig.RunMode = _config.String("runmode", "debug")
+		AppConfig.DataSource = _config.String("datasource", "")
+	}
+
+
+}
+
+func (c *ApiConfig)GetKey(key string) string{
+	if _config == nil{
+		ParseConfig()
+	}
+	return _config.String(key,"")
+}
+
+func (c *ApiConfig)GetInt(key string) int64 {
+	if _config == nil{
+		ParseConfig()
+	}
+	return  _config.Integer(key, 0)
+}

+ 616 - 0
config/iniconfig.go

@@ -0,0 +1,616 @@
+package config
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+type configSection struct {
+	name   string
+	values map[string]interface{}
+}
+
+/*
+Config holds the contents of an ini file organized into sections.
+*/
+type Config struct {
+	configSection
+	sections map[string]*configSection
+}
+
+/*
+LoadConfiguration takes a path, treats it as a file and scans it for an ini configuration.
+*/
+func LoadConfiguration(path string) (*Config, error) {
+
+	config := new(Config)
+	err := config.InitializeFromPath(path)
+
+	if err != nil {
+		return nil, err
+	}
+	return config, nil
+}
+
+/*
+LoadConfigurationFromReader takes a reader and scans it for an ini configuration.
+The caller should close the reader.
+*/
+func LoadConfigurationFromReader(input io.Reader) (*Config, error) {
+
+	config := new(Config)
+	err := config.InitializeFromReader(input)
+
+	if err != nil {
+		return nil, err
+	}
+	return config, nil
+}
+
+/*
+InitializeFromPath takes a path, treats it as a file and scans it for an ini configuration.
+*/
+func (config *Config) InitializeFromPath(path string) error {
+
+	f, err := os.Open(path)
+
+	if err != nil {
+		return err
+	}
+
+	defer f.Close()
+
+	return config.InitializeFromReader(bufio.NewReader(f))
+}
+
+/*
+InitializeFromReader takes a reader and scans it for an ini configuration.
+The caller should close the reader.
+*/
+func (config *Config) InitializeFromReader(input io.Reader) error {
+
+	var currentSection *configSection
+
+	scanner := bufio.NewScanner(input)
+	config.values = make(map[string]interface{})
+	config.sections = make(map[string]*configSection)
+
+	for scanner.Scan() {
+		curLine := scanner.Text()
+
+		curLine = strings.TrimSpace(curLine)
+
+		if len(curLine) == 0 {
+			continue // ignore empty lines
+		}
+
+		if strings.HasPrefix(curLine, ";") || strings.HasPrefix(curLine, "#") {
+			continue // comment
+		}
+
+		if strings.HasPrefix(curLine, "[") {
+
+			if !strings.HasSuffix(curLine, "]") {
+				return errors.New("mini: section names must be surrounded by [ and ], as in [section]")
+			}
+
+			sectionName := curLine[1 : len(curLine)-1]
+
+			if sect, ok := config.sections[sectionName]; !ok { //reuse sections
+				currentSection = new(configSection)
+				currentSection.name = sectionName
+				currentSection.values = make(map[string]interface{})
+				config.sections[currentSection.name] = currentSection
+			} else {
+				currentSection = sect
+			}
+
+			continue
+		}
+
+		index := strings.Index(curLine, "=")
+
+		if index <= 0 {
+			return errors.New("mini: configuration format requires an equals between the key and value")
+		}
+
+		key := strings.ToLower(strings.TrimSpace(curLine[0:index]))
+		isArray := strings.HasSuffix(key, "[]")
+
+		if isArray {
+			key = key[0 : len(key)-2]
+		}
+
+		value := strings.TrimSpace(curLine[index+1:])
+		value = strings.Trim(value, "\"'") //clear quotes
+
+		valueMap := config.values
+
+		if currentSection != nil {
+			valueMap = currentSection.values
+		}
+
+		if isArray {
+			arr := valueMap[key]
+
+			if arr == nil {
+				arr = make([]interface{}, 0)
+				valueMap[key] = arr
+			}
+
+			valueMap[key] = append(arr.([]interface{}), value)
+		} else {
+			valueMap[key] = value
+		}
+	}
+
+	return scanner.Err()
+}
+
+/*
+SetName sets the config's name, which allows it to be returned in SectionNames, or in get functions that take a name.
+*/
+func (config *Config) SetName(name string) {
+	config.name = name
+}
+
+//Return non-array values
+func get(values map[string]interface{}, key string) interface{} {
+	if len(key) == 0 || values == nil {
+		return nil
+	}
+
+	key = strings.ToLower(key)
+	val, ok := values[key]
+
+	if ok {
+		switch val.(type) {
+		case []interface{}:
+			return nil
+		default:
+			return val
+		}
+	}
+
+	return nil
+}
+
+//Return array values
+func getArray(values map[string]interface{}, key string) []interface{} {
+	if len(key) == 0 || values == nil {
+		return nil
+	}
+
+	key = strings.ToLower(key)
+	val, ok := values[key]
+
+	if ok {
+		switch v := val.(type) {
+		case []interface{}:
+			return v
+		default:
+			retVal := make([]interface{}, 1)
+			retVal[0] = val
+			return retVal
+		}
+	}
+
+	return nil
+}
+
+func getString(values map[string]interface{}, key string, def string) string {
+
+	val := get(values, key)
+
+	if val != nil {
+		str, err := strconv.Unquote(fmt.Sprintf("\"%v\"", val))
+
+		if err == nil {
+			return str
+		}
+
+		return def
+	}
+
+	return def
+}
+
+func getBoolean(values map[string]interface{}, key string, def bool) bool {
+
+	val := get(values, key)
+
+	if val != nil {
+		retVal, err := strconv.ParseBool(fmt.Sprint(val))
+
+		if err != nil {
+			return def
+		}
+		return retVal
+	}
+
+	return def
+}
+
+func getInteger(values map[string]interface{}, key string, def int64) int64 {
+
+	val := get(values, key)
+
+	if val != nil {
+		retVal, err := strconv.ParseInt(fmt.Sprint(val), 0, 64)
+
+		if err != nil {
+			return def
+		}
+		return retVal
+	}
+
+	return def
+}
+
+func getFloat(values map[string]interface{}, key string, def float64) float64 {
+
+	val := get(values, key)
+
+	if val != nil {
+		retVal, err := strconv.ParseFloat(fmt.Sprint(val), 64)
+
+		if err != nil {
+			return def
+		}
+		return retVal
+	}
+
+	return def
+}
+
+func getStrings(values map[string]interface{}, key string) []string {
+
+	val := getArray(values, key)
+
+	if val != nil {
+		retVal := make([]string, len(val))
+
+		var err error
+		for i, v := range val {
+			retVal[i], err = strconv.Unquote(fmt.Sprintf("\"%v\"", v))
+			if err != nil {
+				return nil
+			}
+		}
+		return retVal
+	}
+
+	return nil
+}
+
+func getIntegers(values map[string]interface{}, key string) []int64 {
+
+	val := getArray(values, key)
+
+	if val != nil {
+		retVal := make([]int64, len(val))
+
+		var err error
+		for i, v := range val {
+			retVal[i], err = strconv.ParseInt(fmt.Sprint(v), 0, 64)
+			if err != nil {
+				return nil
+			}
+		}
+		return retVal
+	}
+
+	return nil
+}
+
+func getFloats(values map[string]interface{}, key string) []float64 {
+
+	val := getArray(values, key)
+
+	if val != nil {
+		retVal := make([]float64, len(val))
+
+		var err error
+		for i, v := range val {
+			retVal[i], err = strconv.ParseFloat(fmt.Sprint(v), 64)
+			if err != nil {
+				return nil
+			}
+		}
+		return retVal
+	}
+
+	return nil
+}
+
+/*
+String looks for the specified key and returns it as a string. If not found the default value def is returned.
+*/
+func (config *Config) String(key string, def string) string {
+	return getString(config.values, key, def)
+}
+
+/*
+Boolean looks for the specified key and returns it as a bool. If not found the default value def is returned.
+*/
+func (config *Config) Boolean(key string, def bool) bool {
+	return getBoolean(config.values, key, def)
+}
+
+/*
+Integer looks for the specified key and returns it as an int. If not found the default value def is returned.
+*/
+func (config *Config) Integer(key string, def int64) int64 {
+	return getInteger(config.values, key, def)
+}
+
+/*
+Float looks for the specified key and returns it as a float. If not found the default value def is returned.
+*/
+func (config *Config) Float(key string, def float64) float64 {
+	return getFloat(config.values, key, def)
+}
+
+/*
+Strings looks for an array of strings under the provided key.
+If no matches are found nil is returned. If only one matches an array of 1 is returned.
+*/
+func (config *Config) Strings(key string) []string {
+	return getStrings(config.values, key)
+}
+
+/*
+Integers looks for an array of ints under the provided key.
+If no matches are found nil is returned.
+*/
+func (config *Config) Integers(key string) []int64 {
+	return getIntegers(config.values, key)
+}
+
+/*
+Floats looks for an array of floats under the provided key.
+If no matches are found nil is returned.
+*/
+func (config *Config) Floats(key string) []float64 {
+	return getFloats(config.values, key)
+}
+
+func (config *Config) sectionForName(sectionName string) *configSection {
+	if len(sectionName) == 0 || sectionName == config.name {
+		return &(config.configSection)
+	}
+
+	return config.sections[sectionName]
+}
+
+/*
+StringFromSection looks for the specified key and returns it as a string. If not found the default value def is returned.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) StringFromSection(sectionName string, key string, def string) string {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getString(section.values, key, def)
+	}
+
+	return def
+}
+
+/*
+BooleanFromSection looks for the specified key and returns it as a boolean. If not found the default value def is returned.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) BooleanFromSection(sectionName string, key string, def bool) bool {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getBoolean(section.values, key, def)
+	}
+
+	return def
+}
+
+/*
+IntegerFromSection looks for the specified key and returns it as an int64. If not found the default value def is returned.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) IntegerFromSection(sectionName string, key string, def int64) int64 {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getInteger(section.values, key, def)
+	}
+
+	return def
+}
+
+/*
+FloatFromSection looks for the specified key and returns it as a float. If not found the default value def is returned.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) FloatFromSection(sectionName string, key string, def float64) float64 {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getFloat(section.values, key, def)
+	}
+
+	return def
+}
+
+/*
+StringsFromSection returns the value of an array key, if the value of the key is a non-array, then
+that value is returned in an array of length 1.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) StringsFromSection(sectionName string, key string) []string {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getStrings(section.values, key)
+	}
+
+	return nil
+}
+
+/*
+IntegersFromSection looks for an array of integers in the provided section and under the provided key.
+If no matches are found nil is returned.
+*/
+func (config *Config) IntegersFromSection(sectionName string, key string) []int64 {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getIntegers(section.values, key)
+	}
+
+	return nil
+}
+
+/*
+FloatsFromSection looks for an array of floats in the provided section and under the provided key.
+If no matches are found nil is returned.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) FloatsFromSection(sectionName string, key string) []float64 {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		return getFloats(section.values, key)
+	}
+
+	return nil
+}
+
+/*
+DataFromSection reads the values of a section into a struct. The values should be of the types:
+  bool
+  string
+  []string
+  int64
+  []int64
+  float64
+  []float64
+Values that are missing in the section are not set, and values that are missing in the
+struct but present in the section are ignored.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) DataFromSection(sectionName string, data interface{}) bool {
+	section := config.sectionForName(sectionName)
+
+	if section == nil {
+		return false
+	}
+
+	values := section.values
+
+	fields := reflect.ValueOf(data).Elem()
+	dataType := fields.Type()
+
+	for i := 0; i < fields.NumField(); i++ {
+		field := fields.Field(i)
+
+		if !field.CanSet() {
+			continue
+		}
+
+		fieldType := dataType.Field(i)
+		fieldName := fieldType.Name
+
+		switch field.Type().Kind() {
+		case reflect.Bool:
+			field.SetBool(getBoolean(values, fieldName, field.Interface().(bool)))
+		case reflect.Int64:
+			field.SetInt(getInteger(values, fieldName, field.Interface().(int64)))
+		case reflect.Float64:
+			field.SetFloat(getFloat(values, fieldName, field.Interface().(float64)))
+		case reflect.String:
+			field.SetString(getString(values, fieldName, field.Interface().(string)))
+		case reflect.Array, reflect.Slice:
+			switch fieldType.Type.Elem().Kind() {
+			case reflect.Int64:
+				ints := getIntegers(values, fieldName)
+				if ints != nil {
+					field.Set(reflect.ValueOf(ints))
+				}
+			case reflect.Float64:
+				floats := getFloats(values, fieldName)
+				if floats != nil {
+					field.Set(reflect.ValueOf(floats))
+				}
+			case reflect.String:
+				strings := getStrings(values, fieldName)
+				if strings != nil {
+					field.Set(reflect.ValueOf(strings))
+				}
+			}
+		}
+	}
+	return true
+}
+
+/*
+Keys returns all of the global keys in the config.
+*/
+func (config *Config) Keys() []string {
+	keys := make([]string, 0, len(config.values))
+	for key := range config.values {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+/*
+KeysForSection returns all of the keys found in the section named sectionName.
+
+If the section name matches the config.name or "" the global data is searched.
+*/
+func (config *Config) KeysForSection(sectionName string) []string {
+	section := config.sectionForName(sectionName)
+
+	if section != nil {
+		keys := make([]string, 0, len(section.values))
+		for key := range section.values {
+			keys = append(keys, key)
+		}
+		sort.Strings(keys)
+		return keys
+	}
+
+	return nil
+}
+
+/*
+SectionNames returns the names for each of the sections in a config structure. If the config was assigned
+a name, that name is included in the list. If the name is not set, then only explicitely named sections are returned.
+*/
+func (config *Config) SectionNames() []string {
+	sectionNames := make([]string, 0, len(config.sections))
+	for name := range config.sections {
+		sectionNames = append(sectionNames, name)
+	}
+
+	if len(config.name) > 0 {
+		sectionNames = append(sectionNames, config.name)
+	}
+
+	sort.Strings(sectionNames)
+
+	return sectionNames
+}

+ 13 - 12
controllers/SystemController.go_new

@@ -3,6 +3,7 @@ package controllers
 
 import (
 	"git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
+	sysmodel "git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
 )
 
 
@@ -17,9 +18,9 @@ func System_Login(c *SystemController) {
 	c.Ctx.BindJSON(&logininfo)
 	ret := __none_func__(logininfo)
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 
@@ -32,9 +33,9 @@ func System_Logout(c *SystemController) {
 	
 	ret := __none_func__()
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 
@@ -48,9 +49,9 @@ func System_GetMenuTree(c *SystemController) {
 	user := c.Ctx.Param(":user")
 	ret := __none_func__(user)
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 
@@ -65,9 +66,9 @@ func System_FindUserPage(c *SystemController) {
 	c.Ctx.BindJSON(&getpageinfo)
 	ret := __none_func__(getpageinfo)
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 
@@ -81,9 +82,9 @@ func System_FindPermissions(c *SystemController) {
 	user := c.Ctx.Param(":user")
 	ret := __none_func__(user)
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 
@@ -97,9 +98,9 @@ func System_AddPermission(c *SystemController) {
 	user := c.Ctx.Param(":user")
 	ret := __none_func__(user)
 	if ret {
-		c.Ctx.JSON(200, models.SysReturn{200, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
 	}else{
-		c.Ctx.JSON(200, models.SysReturn{500, "", nil})
+		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
 	}
 }
 

+ 7 - 1
engine/apiengine.go

@@ -6,6 +6,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/xormplus/xorm"
 	"github.com/gin-contrib/cors"
+	"git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
 )
 
 type ApiEngine struct {
@@ -14,8 +15,13 @@ type ApiEngine struct {
 	listen_addr string
 }
 
-func NewApiEngine(driverName, dataSourceName string, addr string) *ApiEngine {
+func Default()  *ApiEngine{
+	apiengine := NewApiEngine("mysql", config.AppConfig.DataSource, fmt.Sprintf(":%d",config.AppConfig.HttpPort))
+	return apiengine
+}
 
+func NewApiEngine(driverName, dataSourceName string, addr string) *ApiEngine {
+	gin.SetMode(config.AppConfig.RunMode)
 	engine := &ApiEngine{}
 	var err error
 	engine.OrmEngine, err = xorm.NewEngine(driverName, dataSourceName)

+ 31 - 0
utils/paths.go

@@ -0,0 +1,31 @@
+package utils
+
+import (
+	"os/exec"
+	"os"
+	"path/filepath"
+	"strings"
+	"errors"
+	"runtime"
+)
+func GetCurrentPath() (string, error) {
+	file, err := exec.LookPath(os.Args[0])
+	if err != nil {
+		return "", err
+	}
+	path, err := filepath.Abs(file)
+	if err != nil {
+		return "", err
+	}
+	//fmt.Println("path111:", path)
+	if runtime.GOOS == "windows" {
+		path = strings.Replace(path, "\\", "/", -1)
+	}
+	//fmt.Println("path222:", path)
+	i := strings.LastIndex(path, "/")
+	if i < 0 {
+		return "", errors.New(`Can't find "/" or "\".`)
+	}
+	//fmt.Println("path333:", path)
+	return string(path[0 : i+1]), nil
+}