config...

This commit is contained in:
2025-07-18 19:52:42 +08:00
parent 18a07dd5b3
commit f984167c77
9 changed files with 157 additions and 78 deletions

View File

@@ -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
@@ -24,5 +24,9 @@ LISTEN_PORT = 25005
TEMPLATE_DIR = $(PWD)/src/templates
# 前端文件的目录
FRONTEND_PATH = $(PWD)/src/FrontEnd
# 数据库路径
DATABASE = $(PWD)/scheduler.db
# 额外的参数
ARGS = ;
include build/Makefile

View File

@@ -1,4 +1,4 @@
.PHONY: clean help run build
.PHONY: clean help run build start
help:
./build/Help
@@ -15,5 +15,6 @@ build: BackEnd
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

View File

@@ -1,18 +1,17 @@
# 其中有的配置可以通过环境变量覆盖,前端,模板的路径通过环境变量设置
# 这是一个示例配置文件。
# 示例配置文件
app:
Name: "scheduler for ZSC Network Support staff"
ListenPort: 25005
File: "member.csv" #成员信息文件的路径,看文档
DB:
ListenPath: ":25005"
MemberFile: "member.csv"
FrontEndDir: ""
TemplateDir: ""
option:
DatabaseAutoMigrate: false
Debug: true
DB: # 数据库的其他信息要通过环境变量传递。
Type: "SQLite"
Path: "./scheduler.db"
Port: ""
User: ""
Password: ""
Name: ""
business:
Session: "2024-2025" #学年
Semester: 1 #学期1 或 2
StartTime: "2025-3-10" #开始值班的日期,日期必须是星期一
Week: 15 #准备值班多少周
Year: "2024-2025"
Semester: 1
StartTime: "2025-3-10"
Week: 15

View File

@@ -1,9 +1,9 @@
package config
import (
"errors"
"fmt"
"os"
"strconv"
"strings"
"github.com/golang-module/carbon/v2"
"github.com/spf13/pflag"
@@ -12,10 +12,12 @@ import (
func Load() {
parseArgs()
readconfig()
overrides()
fmt.Printf("%+v\n", Default)
i, err := Init()
if err != nil {
panic(err)
}
Default = *i
fmt.Println(Default.String())
carbon.SetDefault(carbon.Default{
Layout: carbon.DateTimeLayout,
@@ -26,34 +28,61 @@ func Load() {
}
func readconfig() {
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))
}
func Init() (*Config, error) {
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()
pathToConfigure = viper.GetString("config")
InitDB = viper.GetBool("init-db")
}
func overrides() {
if CSVPath := os.Getenv("CSV_PATH"); CSVPath != "" {
Default.App.File = CSVPath
if err := v.BindPFlags(pflag.CommandLine); err != nil {
return nil, fmt.Errorf("failed to bind command-line flags: %w", err)
}
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
}

View File

@@ -1,22 +1,33 @@
// 系统配置
package config
import (
"fmt"
"strings"
)
type Config struct {
App struct {
Name string `mapstructure:"Name"`
ListenPort int `mapstructure:"ListenPort"`
File string `mapstructure:"File"`
Name string `mapstructure:"Name"`
ListenPath string `mapstructure:"ListenPath"`
MemberFile string `mapstructure:"MemberFile"`
FrontEndDir string `mapstructure:"FrontEndDir"`
TemplateDir string `mapstructure:"TemplateDir"`
} `mapstructure:"app"`
Option struct {
DatabaseAutoMigrate bool `mapstructure:"DatabaseAutoMigrate"`
Debug bool `mapstructure:"Debug"`
} `mapstructure:"option"`
DB struct {
Type string `mapstructure:"Type"`
Path string `mapstructure:"Path"`
Port int `mapstructure:"Port"`
User string `mapstructure:"User"`
Password string `mapstructure:"Password"`
Name string `mapstructure:"Name"`
Type string `mapstructure:"Type"`
Path string `mapstructure:"Path"`
Port int `mapstructure:"Port"`
Name string `mapstructure:"Name"`
User string `mapstructure:"User"`
Passwd string `mapstructure:"Passwd"`
} `mapstructure:"DB"`
Business struct {
Session string `mapstructure:"Session"`
Year string `mapstructure:"Year"`
Semester int `mapstructure:"Semester"`
StartTime string `mapstructure:"StartTime"`
Week int `mapstructure:"Week"`
@@ -25,5 +36,47 @@ type Config struct {
var pathToConfigure string //配置文件的路径
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()
}

View File

@@ -1,7 +1,6 @@
package main
import (
"fmt"
"html/template"
"os"
@@ -20,6 +19,9 @@ func main() {
config.Load()
db.Connect()
if config.Default.Option.DatabaseAutoMigrate == true {
db.Main.AutoMigrate(&model.Member{}, &model.Tweak{})
}
app := echo.New()
csv() //初始化Model.MemberList
@@ -28,18 +30,16 @@ func main() {
route.Middleware(app) //注册中间件
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 //注册模板
listenAddress := fmt.Sprintf(":%d", config.Default.App.ListenPort)
app.Logger.Fatal(app.Start(listenAddress)) //启动服务器
app.Logger.Fatal(app.Start(config.Default.App.ListenPath)) //启动服务器
}
// 读取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 {
panic(err)
}

View File

@@ -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{})
}
}

View File

@@ -22,3 +22,8 @@ const FRESH = 5 //实习成员
const PRE = 6 //前成员
var MemberList []*Member
// 在数据库中创建一个成员
func (m *Member) Create() error {
return nil
}

View File

@@ -10,7 +10,7 @@ import (
func Route(app *echo.Echo) {
// here is the route for our site
staticFiles := app.Group("/*")
staticFiles.Use(middleware.Static(config.FrontEnd))
staticFiles.Use(middleware.Static(config.Default.App.FrontEndDir))
api := app.Group("/api/")
api.GET("getAssignment", handler.GetAssignment)