excel-export/biz/config/config.go

239 lines
4.9 KiB
Go

package config
import (
"errors"
"fmt"
"github.com/flytam/filenamify"
"github.com/spf13/viper"
"io/fs"
"log"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
)
var DefaultConfig = &Config{}
type (
Config struct {
Systems []System `json:"System" mapstructure:"System"`
Servers map[string]Server `json:"Servers" mapstructure:"Servers"`
}
System struct {
Name string
Db string
Jobs []Job
}
Server struct {
Db string
Sql string
}
Job struct {
Name string
Base string
Excel string
Tasks []Task
File string
Size int //文件最大行数
}
Task struct {
PK string `mapstructure:"pk"`
Sql string
Timestamp bool
Elt string
Order string
Excel []map[string]string
}
ResPage struct {
Page int `json:"current_page"`
PageSize int `json:"per_page"`
Total int `json:"total"`
LastPage int `json:"last_page"`
Data []map[string]interface{} `json:"data"`
}
FileInfoWithModTime struct {
fs.FileInfo
ModTime time.Time
}
FileInfoStatus struct {
fs.FileInfo
Status int8
Time time.Time
}
)
func (c Config) GetSystem(name string) (System, error) {
for _, s := range c.Systems {
//fmt.Println(s.Name)
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 := params["sql"].(string)
split := "where"
sql = strings.ToLower(sql)
if strings.Index(sql, split) != -1 {
split = " and "
}
hasOrder := strings.Index(sql, " order by ")
if hasOrder != -1 {
sql = sql[:hasOrder]
}
m := regexp.MustCompile("({[a-zA-Z0-9]+})")
if strings.Trim(t.Elt, " ") != "" {
sql = sql + split + 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
}
func GetServer(conf *Config, serverName string) (Server, error) {
if _, ok := conf.Servers[serverName]; !ok {
return Server{}, errors.New("没有找到相关配置:" + serverName)
}
return conf.Servers[serverName], nil
}
func GetBaseSql(job *Job, condition [][3]interface{}) string {
base := job.Base
conditionStr := ""
for _, value := range condition {
conditionStr += " AND "
conditionStr += fmt.Sprintf("%s %s ", value[0], value[1])
last := value[2]
if lasts, ok := last.([]interface{}); ok {
conditionStr += "("
for _, lastValue := range lasts {
conditionStr += fmt.Sprintf("'%s',", lastValue.(string))
}
conditionStr = conditionStr[:len(conditionStr)-1]
conditionStr += ")"
} else {
conditionStr += fmt.Sprintf(" %s", last.(string))
}
}
return base + conditionStr
}