feat: ticket enhancemnet

This commit is contained in:
zhangsz
2025-07-02 17:22:35 +08:00
parent 24ed4e874a
commit 758276ecfc
11 changed files with 577 additions and 108 deletions

View File

@@ -126,6 +126,11 @@ type YamlConfig struct {
Enabled bool `yaml:"enabled"`
File string `yaml:"file"`
} `yaml:"testConfig"`
PsapConfig struct {
Enabled bool `yaml:"enabled"`
File string `yaml:"file"`
} `yaml:"psapConfig"`
}
type RestParam struct {
@@ -253,6 +258,16 @@ func NewYamlConfig() YamlConfig {
}
}
// InitPsapConfig 初始化PSAP配置
func InitPsapConfig() error {
if !yamlConfig.PsapConfig.Enabled {
return nil
}
_, err := ReadPsapConfig(yamlConfig.PsapConfig.File)
return err
}
func ReadConfig(configFile string) {
YamlConfigInfo.FilePath = configFile
@@ -270,6 +285,11 @@ func ReadConfig(configFile string) {
}
yamlConfig = YamlConfigInfo.ConfigLines
// 初始化PSAP配置
if err := InitPsapConfig(); err != nil {
fmt.Printf("Failed to load PSAP config: %v\n", err)
}
ReadOriginalConfig(configFile)
}

184
lib/config/psap.go Normal file
View File

@@ -0,0 +1,184 @@
package config
import (
"fmt"
"os"
"be.ems/lib/email"
"gopkg.in/yaml.v3"
)
// PsapConfig PSAP配置结构体
type PsapConfig struct {
Ticket struct {
Notification struct {
SMTP email.EmailConfig `yaml:"smtp"`
} `yaml:"notifcation"` // 注意:配置文件中是 "notifcation",保持一致
Timeout struct {
// 时间单位为分钟
New int `yaml:"new"` // NEW状态超时时间分钟
InProgress int `yaml:"inProgress"` // IN_PROGRESS状态超时时间分钟
NoAnswer1 int `yaml:"noAnswer1"` // NO_ANSWER_1状态超时时间分钟
NoAnswer2 int `yaml:"noAnswer2"` // NO_ANSWER_2状态超时时间分钟
NearlyTimeout int `yaml:"nearlyTimeout"` // 提前提醒时间(分钟)
} `yaml:"timeout"`
} `yaml:"ticket"`
}
var psapConfig *PsapConfig
// ReadPsapConfig 读取PSAP配置文件
func ReadPsapConfig(configFile string) (*PsapConfig, error) {
yamlFile, err := os.ReadFile(configFile)
if err != nil {
return nil, fmt.Errorf("read psap config file error: %w", err)
}
var config PsapConfig
err = yaml.Unmarshal(yamlFile, &config)
if err != nil {
return nil, fmt.Errorf("unmarshal psap config error: %w", err)
}
psapConfig = &config
return &config, nil
}
// GetPsapConfig 获取PSAP配置
func GetPsapConfig() *PsapConfig {
if psapConfig == nil {
// 如果配置未加载,尝试从默认位置加载
config, err := ReadPsapConfig("./etc/psap.yaml")
if err != nil {
fmt.Printf("Failed to load PSAP config: %v\n", err)
return nil
}
psapConfig = config
}
return psapConfig
}
// GetSMTPConfig 获取SMTP配置
func GetSMTPConfig() *email.EmailConfig {
config := GetPsapConfig()
if config == nil {
return nil
}
return &config.Ticket.Notification.SMTP
}
// GetTimeoutConfig 获取超时配置
func GetTimeoutConfig() *struct {
New int `yaml:"new"`
InProgress int `yaml:"inProgress"`
NoAnswer1 int `yaml:"noAnswer1"`
NoAnswer2 int `yaml:"noAnswer2"`
NearlyTimeout int `yaml:"nearlyTimeout"`
} {
config := GetPsapConfig()
if config == nil {
return nil
}
return &config.Ticket.Timeout
}
// 以下是具体的配置获取方法
// GetNewTicketTimeoutMicros 获取NEW状态超时时间微秒
func GetNewTicketTimeoutMicros() int64 {
config := GetTimeoutConfig()
if config == nil {
return 60 * 60 * 1000000 // 默认60分钟
}
return int64(config.New) * 60 * 1000000 // 分钟转微秒
}
// GetInProgressTicketTimeoutMicros 获取IN_PROGRESS状态超时时间微秒
func GetInProgressTicketTimeoutMicros() int64 {
config := GetTimeoutConfig()
if config == nil {
return 60 * 60 * 1000000 // 默认60分钟
}
return int64(config.InProgress) * 60 * 1000000
}
// GetNoAnswer1TicketTimeoutMicros 获取NO_ANSWER_1状态超时时间微秒
func GetNoAnswer1TicketTimeoutMicros() int64 {
config := GetTimeoutConfig()
if config == nil {
return 4 * 60 * 60 * 1000000 // 默认4小时
}
return int64(config.NoAnswer1) * 60 * 1000000
}
// GetNoAnswer2TicketTimeoutMicros 获取NO_ANSWER_2状态超时时间微秒
func GetNoAnswer2TicketTimeoutMicros() int64 {
config := GetTimeoutConfig()
if config == nil {
return 8 * 60 * 60 * 1000000 // 默认8小时
}
return int64(config.NoAnswer2) * 60 * 1000000
}
// GetNearlyTimeoutMicros 获取提前提醒时间(微秒)
func GetNearlyTimeoutMicros() int64 {
config := GetTimeoutConfig()
if config == nil {
return 20 * 60 * 1000000 // 默认20分钟
}
return int64(config.NearlyTimeout) * 60 * 1000000
}
// IsSMTPEnabled 检查SMTP是否启用
func IsSMTPEnabled() bool {
config := GetSMTPConfig()
if config == nil {
return false
}
return config.Enabled
}
// GetSMTPHost 获取SMTP主机
func GetSMTPHost() string {
config := GetSMTPConfig()
if config == nil {
return ""
}
return config.Host
}
// GetSMTPPort 获取SMTP端口
func GetSMTPPort() int {
config := GetSMTPConfig()
if config == nil {
return 25
}
return config.Port
}
// GetSMTPUser 获取SMTP用户名
func GetSMTPUsername() string {
config := GetSMTPConfig()
if config == nil {
return ""
}
return config.Username
}
// GetSMTPPassword 获取SMTP密码
func GetSMTPPassword() string {
config := GetSMTPConfig()
if config == nil {
return ""
}
return config.Password
}
// GetSMTPFrom 获取SMTP发件人
func GetSMTPFrom() string {
config := GetSMTPConfig()
if config == nil {
return ""
}
return config.From
}

View File

@@ -1,19 +1,83 @@
package email
import "net/smtp"
import (
"crypto/tls"
"fmt"
"net/smtp"
"strconv"
"strings"
"gopkg.in/gomail.v2"
)
type EmailConfig struct {
Enabled bool `yaml:"enabled"` // 是否启用邮件发送
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
TLSSkipVerify bool `yaml:"tlsSkipVerify"`
From string `yaml:"from"`
To []string `yaml:"to"`
Subject string `yaml:"subject"`
Body string `yaml:"body"`
}
// 简单邮件发送函数
func SendEmail(to, subject, body string) error {
from := "your@email.com"
password := "your_password"
smtpHost := "smtp.yourserver.com"
smtpPort := "587"
// 该函数使用标准库的 smtp 包发送邮件
// 注意:此函数不支持 TLS 加密,建议使用 gomail 包发送邮件以支持 TLS 和其他高级功能
// gomail 包的使用示例见 SendEmailWithGomail 函数
func SendEmail(email EmailConfig) error {
username := email.Username
from := email.From
password := email.Password
to := strings.Join(email.To, ",") // 将多个收件人用逗号连接
subject := email.Subject
body := email.Body
smtpHost := email.Host
smtpPort := email.Port
msg := "From: " + from + "\n" +
"To: " + to + "\n" +
"Subject: " + subject + "\n\n" +
body
auth := smtp.PlainAuth("", from, password, smtpHost)
return smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, []byte(msg))
auth := smtp.PlainAuth(from, username, password, smtpHost)
return smtp.SendMail(smtpHost+":"+strconv.Itoa(smtpPort), auth, from, []string{to}, []byte(msg))
}
func SendEmailWithGomail(email EmailConfig) error {
m := gomail.NewMessage()
m.SetHeader("From", email.From)
m.SetHeader("To", email.To...)
m.SetHeader("Subject", email.Subject)
m.SetBody("text/plain", email.Body)
d := gomail.NewDialer(email.Host, email.Port, email.Username, email.Password)
// 配置 TLS
d.TLSConfig = &tls.Config{
InsecureSkipVerify: email.TLSSkipVerify,
}
// gomail 会自动处理 STARTTLS
if err := d.DialAndSend(m); err != nil {
fmt.Printf("Failed to DialAndSend:%v", err)
return err
}
return nil
}
// RemoveDuplicateEmails 去除重复的邮箱地址
func RemoveDuplicateEmails(emails []string) []string {
emailMap := make(map[string]struct{})
var uniqueEmails []string
for _, email := range emails {
if _, exists := emailMap[email]; !exists {
emailMap[email] = struct{}{}
uniqueEmails = append(uniqueEmails, email)
}
}
return uniqueEmails
}