mirror of
https://github.com/ZSCNetSupportDept/scheduler.git
synced 2025-10-28 20:45:05 +08:00
config...
This commit is contained in:
6
Makefile
6
Makefile
@@ -14,7 +14,7 @@ EMBED_FRONTEND = 1
|
|||||||
# **运行配置项**
|
# **运行配置项**
|
||||||
|
|
||||||
# 如果运行,使用的配置文件在哪里?
|
# 如果运行,使用的配置文件在哪里?
|
||||||
CONFIG_FILE_PATH = $(PWD)/ignore/secret.yaml
|
CONFIG_FILE_PATH = $(PWD)/config.yaml
|
||||||
# 如果运行,使用的成员信息文件在哪里?
|
# 如果运行,使用的成员信息文件在哪里?
|
||||||
CSV_PATH = $(PWD)/ignore/aa.csv
|
CSV_PATH = $(PWD)/ignore/aa.csv
|
||||||
|
|
||||||
@@ -24,5 +24,9 @@ LISTEN_PORT = 25005
|
|||||||
TEMPLATE_DIR = $(PWD)/src/templates
|
TEMPLATE_DIR = $(PWD)/src/templates
|
||||||
# 前端文件的目录
|
# 前端文件的目录
|
||||||
FRONTEND_PATH = $(PWD)/src/FrontEnd
|
FRONTEND_PATH = $(PWD)/src/FrontEnd
|
||||||
|
# 数据库路径
|
||||||
|
DATABASE = $(PWD)/scheduler.db
|
||||||
|
# 额外的参数
|
||||||
|
ARGS = ;
|
||||||
|
|
||||||
include build/Makefile
|
include build/Makefile
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: clean help run build
|
.PHONY: clean help run build start
|
||||||
|
|
||||||
help:
|
help:
|
||||||
./build/Help
|
./build/Help
|
||||||
@@ -15,5 +15,6 @@ build: BackEnd
|
|||||||
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
TEMPLATE=$(TEMPLATE_DIR) FRONTEND=$(FRONTEND_PATH) CSV_PATH=$(CSV_PATH) $(TARGET_PATH)/scheduler --config $(CONFIG_FILE_PATH)
|
SCHEDULER_DB_PATH="$(DATABASE)" $(TARGET_PATH)/scheduler --config $(CONFIG_FILE_PATH) --app.templatedir $(TEMPLATE_DIR) --app.memberfile $(CSV_PATH) --app.frontenddir $(FRONTEND_PATH) $(ARGS)
|
||||||
|
|
||||||
|
start: build run
|
||||||
|
|||||||
27
config.yaml
27
config.yaml
@@ -1,18 +1,17 @@
|
|||||||
# 其中有的配置可以通过环境变量覆盖,前端,模板的路径通过环境变量设置
|
# 示例配置文件
|
||||||
# 这是一个示例配置文件。
|
|
||||||
app:
|
app:
|
||||||
Name: "scheduler for ZSC Network Support staff"
|
Name: "scheduler for ZSC Network Support staff"
|
||||||
ListenPort: 25005
|
ListenPath: ":25005"
|
||||||
File: "member.csv" #成员信息文件的路径,看文档
|
MemberFile: "member.csv"
|
||||||
DB:
|
FrontEndDir: ""
|
||||||
|
TemplateDir: ""
|
||||||
|
option:
|
||||||
|
DatabaseAutoMigrate: false
|
||||||
|
Debug: true
|
||||||
|
DB: # 数据库的其他信息要通过环境变量传递。
|
||||||
Type: "SQLite"
|
Type: "SQLite"
|
||||||
Path: "./scheduler.db"
|
|
||||||
Port: ""
|
|
||||||
User: ""
|
|
||||||
Password: ""
|
|
||||||
Name: ""
|
|
||||||
business:
|
business:
|
||||||
Session: "2024-2025" #学年
|
Year: "2024-2025"
|
||||||
Semester: 1 #学期,1 或 2
|
Semester: 1
|
||||||
StartTime: "2025-3-10" #开始值班的日期,日期必须是星期一
|
StartTime: "2025-3-10"
|
||||||
Week: 15 #准备值班多少周
|
Week: 15
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"strings"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/golang-module/carbon/v2"
|
"github.com/golang-module/carbon/v2"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@@ -12,10 +12,12 @@ import (
|
|||||||
|
|
||||||
func Load() {
|
func Load() {
|
||||||
|
|
||||||
parseArgs()
|
i, err := Init()
|
||||||
readconfig()
|
if err != nil {
|
||||||
overrides()
|
panic(err)
|
||||||
fmt.Printf("%+v\n", Default)
|
}
|
||||||
|
Default = *i
|
||||||
|
fmt.Println(Default.String())
|
||||||
|
|
||||||
carbon.SetDefault(carbon.Default{
|
carbon.SetDefault(carbon.Default{
|
||||||
Layout: carbon.DateTimeLayout,
|
Layout: carbon.DateTimeLayout,
|
||||||
@@ -26,34 +28,61 @@ func Load() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readconfig() {
|
func Init() (*Config, error) {
|
||||||
viper.SetConfigFile(pathToConfigure)
|
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
|
||||||
fmt.Printf("Error reading config file: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := viper.Unmarshal(&Default); err != nil {
|
|
||||||
panic(fmt.Errorf("映射配置到结构体失败: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
FrontEnd = os.Getenv("FRONTEND")
|
v := viper.New()
|
||||||
}
|
|
||||||
|
//解析命令行传过来的参数
|
||||||
|
pflag.StringP("config", "c", "", "Path to the configuration file (required).")
|
||||||
|
pflag.String("app.name", "ZSCNetworkSupport Scheduler", "Name of the application")
|
||||||
|
pflag.String("app.listenpath", ":25005", "HTTP listen path")
|
||||||
|
pflag.String("app.memberfile", "members.csv", "Path to the member file")
|
||||||
|
pflag.String("app.frontenddir", "./FrontEnd", "Path to the frontend directory")
|
||||||
|
pflag.String("app.templatedir", "./template", "Path to the template directory")
|
||||||
|
|
||||||
|
pflag.Bool("option.databaseautomigrate", false, "Enable automatic database migration")
|
||||||
|
pflag.Bool("option.debug", false, "Enable debug mode")
|
||||||
|
|
||||||
|
pflag.String("db.type", "SQLite", "Database type (e.g., mysql, sqlite)")
|
||||||
|
|
||||||
|
pflag.String("business.year", "", "Business year")
|
||||||
|
pflag.Int("business.semester", 0, "Current semester")
|
||||||
|
pflag.String("business.starttime", "", "Start time of the semester")
|
||||||
|
pflag.Int("business.week", 0, "Total weeks in the semester")
|
||||||
|
|
||||||
func parseArgs() {
|
|
||||||
pflag.String("config", "./config.yaml", "the path to config file.")
|
|
||||||
pflag.Bool("init-db", false, "whether to initialize the database on starting,useful when migrating to a new one.")
|
|
||||||
viper.BindPFlags(pflag.CommandLine)
|
|
||||||
pflag.Parse()
|
pflag.Parse()
|
||||||
pathToConfigure = viper.GetString("config")
|
if err := v.BindPFlags(pflag.CommandLine); err != nil {
|
||||||
InitDB = viper.GetBool("init-db")
|
return nil, fmt.Errorf("failed to bind command-line flags: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
func overrides() {
|
|
||||||
if CSVPath := os.Getenv("CSV_PATH"); CSVPath != "" {
|
|
||||||
Default.App.File = CSVPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ListenPort, err := strconv.Atoi(os.Getenv("LISTEN_PORT")); ListenPort != 0 && err != nil {
|
//加载环境变量
|
||||||
Default.App.ListenPort = ListenPort
|
v.BindEnv("db.Path")
|
||||||
|
v.BindEnv("db.User")
|
||||||
|
v.BindEnv("db.Port")
|
||||||
|
v.BindEnv("db.Name")
|
||||||
|
v.BindEnv("db.Passwd")
|
||||||
|
v.SetEnvPrefix("SCHEDULER")
|
||||||
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
v.AutomaticEnv()
|
||||||
|
|
||||||
|
//加载配置文件
|
||||||
|
configFile := v.GetString("config")
|
||||||
|
if configFile == "" {
|
||||||
|
pflag.Usage()
|
||||||
|
return nil, errors.New("the --config flag is required")
|
||||||
}
|
}
|
||||||
|
v.SetConfigFile(configFile)
|
||||||
|
v.SetConfigType("yaml")
|
||||||
|
|
||||||
|
if err := v.ReadInConfig(); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read config file '%s': %w", configFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出配置
|
||||||
|
var cfg Config
|
||||||
|
if err := v.Unmarshal(&cfg); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal configuration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &cfg, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
// 系统配置
|
// 系统配置
|
||||||
package config
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
App struct {
|
App struct {
|
||||||
Name string `mapstructure:"Name"`
|
Name string `mapstructure:"Name"`
|
||||||
ListenPort int `mapstructure:"ListenPort"`
|
ListenPath string `mapstructure:"ListenPath"`
|
||||||
File string `mapstructure:"File"`
|
MemberFile string `mapstructure:"MemberFile"`
|
||||||
|
FrontEndDir string `mapstructure:"FrontEndDir"`
|
||||||
|
TemplateDir string `mapstructure:"TemplateDir"`
|
||||||
} `mapstructure:"app"`
|
} `mapstructure:"app"`
|
||||||
|
Option struct {
|
||||||
|
DatabaseAutoMigrate bool `mapstructure:"DatabaseAutoMigrate"`
|
||||||
|
Debug bool `mapstructure:"Debug"`
|
||||||
|
} `mapstructure:"option"`
|
||||||
DB struct {
|
DB struct {
|
||||||
Type string `mapstructure:"Type"`
|
Type string `mapstructure:"Type"`
|
||||||
Path string `mapstructure:"Path"`
|
Path string `mapstructure:"Path"`
|
||||||
Port int `mapstructure:"Port"`
|
Port int `mapstructure:"Port"`
|
||||||
User string `mapstructure:"User"`
|
|
||||||
Password string `mapstructure:"Password"`
|
|
||||||
Name string `mapstructure:"Name"`
|
Name string `mapstructure:"Name"`
|
||||||
|
User string `mapstructure:"User"`
|
||||||
|
Passwd string `mapstructure:"Passwd"`
|
||||||
} `mapstructure:"DB"`
|
} `mapstructure:"DB"`
|
||||||
Business struct {
|
Business struct {
|
||||||
Session string `mapstructure:"Session"`
|
Year string `mapstructure:"Year"`
|
||||||
Semester int `mapstructure:"Semester"`
|
Semester int `mapstructure:"Semester"`
|
||||||
StartTime string `mapstructure:"StartTime"`
|
StartTime string `mapstructure:"StartTime"`
|
||||||
Week int `mapstructure:"Week"`
|
Week int `mapstructure:"Week"`
|
||||||
@@ -25,5 +36,47 @@ type Config struct {
|
|||||||
|
|
||||||
var pathToConfigure string //配置文件的路径
|
var pathToConfigure string //配置文件的路径
|
||||||
var Default Config //系统的默认配置
|
var Default Config //系统的默认配置
|
||||||
var InitDB bool
|
|
||||||
var FrontEnd string
|
func (c *Config) String() string {
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
builder.WriteString("\n\n\n\n\n")
|
||||||
|
|
||||||
|
builder.WriteString("Configuration:\n")
|
||||||
|
builder.WriteString("--------------\n")
|
||||||
|
|
||||||
|
// App Section
|
||||||
|
builder.WriteString("[App]\n")
|
||||||
|
builder.WriteString(fmt.Sprintf(" Name: %s\n", c.App.Name))
|
||||||
|
builder.WriteString(fmt.Sprintf(" ListenPath: %s\n", c.App.ListenPath))
|
||||||
|
builder.WriteString(fmt.Sprintf(" MemberFile: %s\n", c.App.MemberFile))
|
||||||
|
builder.WriteString(fmt.Sprintf(" FrontEndDir: %s\n", c.App.FrontEndDir))
|
||||||
|
builder.WriteString(fmt.Sprintf(" TemplateDir: %s\n", c.App.TemplateDir))
|
||||||
|
builder.WriteString("\n")
|
||||||
|
|
||||||
|
// Option Section
|
||||||
|
builder.WriteString("[Option]\n")
|
||||||
|
builder.WriteString(fmt.Sprintf(" Auto Migrate: %t\n", c.Option.DatabaseAutoMigrate))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Debug Mode: %t\n", c.Option.Debug))
|
||||||
|
builder.WriteString("\n")
|
||||||
|
|
||||||
|
// DB Section
|
||||||
|
builder.WriteString("[Database]\n")
|
||||||
|
builder.WriteString(fmt.Sprintf(" Type: %s\n", c.DB.Type))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Path: %s\n", c.DB.Path))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Port: %d\n", c.DB.Port))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Name: %s\n", c.DB.Name))
|
||||||
|
builder.WriteString(fmt.Sprintf(" User: %s\n", c.DB.User))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Password: %s\n", c.DB.Passwd))
|
||||||
|
builder.WriteString("\n")
|
||||||
|
|
||||||
|
// Business Section
|
||||||
|
builder.WriteString("[Business]\n")
|
||||||
|
builder.WriteString(fmt.Sprintf(" Year: %s\n", c.Business.Year))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Semester: %d\n", c.Business.Semester))
|
||||||
|
builder.WriteString(fmt.Sprintf(" StartTime: %s\n", c.Business.StartTime))
|
||||||
|
builder.WriteString(fmt.Sprintf(" Week: %d\n", c.Business.Week))
|
||||||
|
builder.WriteString("--------------\n\n\n\n\n")
|
||||||
|
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|||||||
12
src/main.go
12
src/main.go
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@@ -20,6 +19,9 @@ func main() {
|
|||||||
|
|
||||||
config.Load()
|
config.Load()
|
||||||
db.Connect()
|
db.Connect()
|
||||||
|
if config.Default.Option.DatabaseAutoMigrate == true {
|
||||||
|
db.Main.AutoMigrate(&model.Member{}, &model.Tweak{})
|
||||||
|
}
|
||||||
|
|
||||||
app := echo.New()
|
app := echo.New()
|
||||||
csv() //初始化Model.MemberList
|
csv() //初始化Model.MemberList
|
||||||
@@ -28,18 +30,16 @@ func main() {
|
|||||||
route.Middleware(app) //注册中间件
|
route.Middleware(app) //注册中间件
|
||||||
|
|
||||||
renderer := tl.Tlw{
|
renderer := tl.Tlw{
|
||||||
Tl: template.Must(template.ParseGlob(os.Getenv("TEMPLATE") + "/*.html")),
|
Tl: template.Must(template.ParseGlob(config.Default.App.TemplateDir + "/*.html")),
|
||||||
}
|
}
|
||||||
app.Renderer = renderer //注册模板
|
app.Renderer = renderer //注册模板
|
||||||
|
|
||||||
listenAddress := fmt.Sprintf(":%d", config.Default.App.ListenPort)
|
app.Logger.Fatal(app.Start(config.Default.App.ListenPath)) //启动服务器
|
||||||
|
|
||||||
app.Logger.Fatal(app.Start(listenAddress)) //启动服务器
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取csv文件
|
// 读取csv文件
|
||||||
func csv() {
|
func csv() {
|
||||||
data, err := os.OpenFile(config.Default.App.File, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
data, err := os.OpenFile(config.Default.App.MemberFile, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"zsxyww.com/scheduler/config"
|
|
||||||
db "zsxyww.com/scheduler/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if config.InitDB == true {
|
|
||||||
db.Main.AutoMigrate(&Member{}, &Tweak{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,3 +22,8 @@ const FRESH = 5 //实习成员
|
|||||||
const PRE = 6 //前成员
|
const PRE = 6 //前成员
|
||||||
|
|
||||||
var MemberList []*Member
|
var MemberList []*Member
|
||||||
|
|
||||||
|
// 在数据库中创建一个成员
|
||||||
|
func (m *Member) Create() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
func Route(app *echo.Echo) {
|
func Route(app *echo.Echo) {
|
||||||
// here is the route for our site
|
// here is the route for our site
|
||||||
staticFiles := app.Group("/*")
|
staticFiles := app.Group("/*")
|
||||||
staticFiles.Use(middleware.Static(config.FrontEnd))
|
staticFiles.Use(middleware.Static(config.Default.App.FrontEndDir))
|
||||||
|
|
||||||
api := app.Group("/api/")
|
api := app.Group("/api/")
|
||||||
api.GET("getAssignment", handler.GetAssignment)
|
api.GET("getAssignment", handler.GetAssignment)
|
||||||
|
|||||||
Reference in New Issue
Block a user