package config import ( "errors" "fmt" "github.com/flytam/filenamify" "github.com/spf13/viper" "log" "path/filepath" "regexp" "strconv" "strings" "time" ) var DefaultConfig = &Config{} type ( Config struct { Systems []System `json:"System" mapstructure:"System"` } System struct { Name string Db string Jobs []Job } Job struct { Name string Tasks []Task File string Size int //文件最大行数 } Task struct { PK string `mapstructure:"pk"` Sql string Timestamp bool Elt string Order string } ) func (c Config) GetSystem(name string) (System, error) { for _, s := range c.Systems { if s.Name == name { return s, nil } } return System{}, errors.New("没有找到相关配置:" + name) } func (s System) GetJob(name string) (Job, error) { for _, j := range s.Jobs { if j.Name == name { return j, nil } } return Job{}, errors.New("没有找到相关配置:" + name) } func (j Job) GetFileName(params map[string]interface{}) string { m := regexp.MustCompile("({[a-zA-Z0-9]+})") //替换文件名参数 fileName := m.ReplaceAllFunc([]byte(j.File), func(b []byte) []byte { field := string(b[1 : len(b)-1]) if val, ok := params[field]; ok { return []byte(toString(val, "20060102")) } return b }) //安全命名 path, name := filepath.Split(string(fileName)) name, err := filenamify.Filenamify(name, filenamify.Options{Replacement: "-"}) if err != nil { log.Printf("不安全的文件名:%s", err.Error()) } return path + name } func (t Task) GetSql(params map[string]interface{}) string { sql := t.Sql m := regexp.MustCompile("({[a-zA-Z0-9]+})") if strings.Trim(t.Elt, " ") != "" { sql = sql + " where " + t.Elt build := m.ReplaceAllFunc([]byte(sql), func(b []byte) []byte { field := string(b[1 : len(b)-1]) if val, ok := params[field]; ok { return []byte(toString(val, t.Timestamp)) } return b }) sql = string(build) } if strings.Trim(t.Order, " ") != "" { sql = sql + " order by " + t.Order } return sql } func toString(parm interface{}, timestamp interface{}) string { switch p := parm.(type) { case time.Time: switch t := timestamp.(type) { case bool: if t { return strconv.FormatInt(p.Unix(), 10) } else { return p.Format("2006-01-02 15:04:05") } case string: return p.Format(t) default: return "" } case string: return p case int: return strconv.Itoa(p) case int32: return strconv.FormatInt(int64(p), 10) default: return fmt.Sprint(p) } } func LoadConfig(path string) *Config { var c Config viper.AddConfigPath(path) //设置读取的文件路径 viper.SetConfigName("Config") //设置读取的文件名 viper.SetConfigType("yaml") //设置文件的类型 //尝试进行配置读取 if err := viper.ReadInConfig(); err != nil { fmt.Println("请将config.yml.example拷贝为config.yaml") panic(err) } //v := viper.GetViper() //fmt.Println(v) if err := viper.Unmarshal(&c); err != nil { panic(err) } DefaultConfig = &c return &c } func GetJob(conf *Config, sys, job string) (Job, string, error) { s, err := conf.GetSystem(sys) if err != nil { return Job{}, "", err } j, err := s.GetJob(job) if err != nil { return Job{}, "", err } return j, s.Db, nil }