feat: Initial commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"baihu/internal/constant"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// EnvironmentVariable represents an environment variable
|
||||
type EnvironmentVariable struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:255;not null"`
|
||||
Value string `json:"value" gorm:"type:text"`
|
||||
Remark string `json:"remark" gorm:"size:500"`
|
||||
UserID uint `json:"user_id" gorm:"index"`
|
||||
CreatedAt LocalTime `json:"created_at"`
|
||||
UpdatedAt LocalTime `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||
}
|
||||
|
||||
func (EnvironmentVariable) TableName() string {
|
||||
return constant.TablePrefix + "envs"
|
||||
}
|
||||
|
||||
// Script represents a script file
|
||||
type Script struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:255;not null"`
|
||||
Content string `json:"content" gorm:"type:text"`
|
||||
UserID uint `json:"user_id" gorm:"index"`
|
||||
CreatedAt LocalTime `json:"created_at"`
|
||||
UpdatedAt LocalTime `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||
}
|
||||
|
||||
func (Script) TableName() string {
|
||||
return constant.TablePrefix + "scripts"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"baihu/internal/constant"
|
||||
)
|
||||
|
||||
// Setting 系统设置
|
||||
type Setting struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Section string `json:"section" gorm:"size:50;not null;index:idx_section_key"`
|
||||
Key string `json:"key" gorm:"size:100;not null;index:idx_section_key"`
|
||||
Value string `json:"value" gorm:"type:text"`
|
||||
}
|
||||
|
||||
func (Setting) TableName() string {
|
||||
return constant.TablePrefix + "settings"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"baihu/internal/constant"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Task represents a scheduled task
|
||||
type Task struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"size:255;not null"`
|
||||
Command string `json:"command" gorm:"type:text;not null"`
|
||||
Schedule string `json:"schedule" gorm:"size:100"` // cron expression
|
||||
Timeout int `json:"timeout" gorm:"default:30"` // 超时时间(分钟),默认30分钟
|
||||
Enabled bool `json:"enabled" gorm:"default:true"`
|
||||
LastRun *LocalTime `json:"last_run"`
|
||||
NextRun *LocalTime `json:"next_run"`
|
||||
CreatedAt LocalTime `json:"created_at"`
|
||||
UpdatedAt LocalTime `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||
}
|
||||
|
||||
func (Task) TableName() string {
|
||||
return constant.TablePrefix + "tasks"
|
||||
}
|
||||
|
||||
// TaskLog represents a log entry for task execution
|
||||
type TaskLog struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
TaskID uint `json:"task_id" gorm:"index"`
|
||||
Command string `json:"command" gorm:"type:text"`
|
||||
Output string `json:"-" gorm:"type:longtext"` // gzip+base64 compressed
|
||||
Status string `json:"status" gorm:"size:20"` // success, failed
|
||||
Duration int64 `json:"duration"` // milliseconds
|
||||
ExitCode int `json:"exit_code"`
|
||||
CreatedAt LocalTime `json:"created_at"`
|
||||
}
|
||||
|
||||
func (TaskLog) TableName() string {
|
||||
return constant.TablePrefix + "task_logs"
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const TimeFormat = "2006-01-02 15:04:05"
|
||||
|
||||
// LocalTime 自定义时间类型,JSON 序列化为 "年-月-日 时:分:秒" 格式
|
||||
type LocalTime time.Time
|
||||
|
||||
func (t LocalTime) MarshalJSON() ([]byte, error) {
|
||||
tt := time.Time(t)
|
||||
if tt.IsZero() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(fmt.Sprintf(`"%s"`, tt.Format(TimeFormat))), nil
|
||||
}
|
||||
|
||||
func (t *LocalTime) UnmarshalJSON(data []byte) error {
|
||||
if string(data) == "null" || string(data) == `""` {
|
||||
return nil
|
||||
}
|
||||
// 去掉引号
|
||||
s := string(data)
|
||||
if len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"' {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
tt, err := time.ParseInLocation(TimeFormat, s, time.Local)
|
||||
if err != nil {
|
||||
// 尝试解析 ISO 格式
|
||||
tt, err = time.Parse(time.RFC3339, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*t = LocalTime(tt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t LocalTime) Value() (driver.Value, error) {
|
||||
return time.Time(t), nil
|
||||
}
|
||||
|
||||
func (t *LocalTime) Scan(v interface{}) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
switch val := v.(type) {
|
||||
case time.Time:
|
||||
*t = LocalTime(val)
|
||||
case string:
|
||||
tt, err := time.ParseInLocation(TimeFormat, val, time.Local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = LocalTime(tt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t LocalTime) Time() time.Time {
|
||||
return time.Time(t)
|
||||
}
|
||||
|
||||
func Now() LocalTime {
|
||||
return LocalTime(time.Now())
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"baihu/internal/constant"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// User represents a system user
|
||||
type User struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Username string `json:"username" gorm:"size:100;uniqueIndex;not null"`
|
||||
Password string `json:"-" gorm:"size:255;not null"`
|
||||
Email string `json:"email" gorm:"size:255"`
|
||||
Role string `json:"role" gorm:"size:20;default:user"` // admin, user
|
||||
CreatedAt LocalTime `json:"created_at"`
|
||||
UpdatedAt LocalTime `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||
}
|
||||
|
||||
func (User) TableName() string {
|
||||
return constant.TablePrefix + "users"
|
||||
}
|
||||
Reference in New Issue
Block a user