chore: initial import 萌邮 MengPost (React+Vite + Go+Gin)

Made-with: Cursor
This commit is contained in:
2026-04-17 22:27:57 +08:00
commit 0c31a4b376
40 changed files with 4263 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
package models
import (
"time"
"mengpost-backend/database"
)
// Account 代表一个邮箱账户的完整连接信息.
type Account struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Password string `json:"password,omitempty"`
SMTPHost string `json:"smtp_host"`
SMTPPort int `json:"smtp_port"`
IMAPHost string `json:"imap_host"`
IMAPPort int `json:"imap_port"`
UseTLS bool `json:"use_tls"`
CreatedAt time.Time `json:"created_at"`
}
func ListAccounts() ([]Account, error) {
rows, err := database.DB.Query(`SELECT id,name,email,smtp_host,smtp_port,imap_host,imap_port,use_tls,created_at FROM accounts ORDER BY id DESC`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []Account
for rows.Next() {
var a Account
var tls int
if err := rows.Scan(&a.ID, &a.Name, &a.Email, &a.SMTPHost, &a.SMTPPort, &a.IMAPHost, &a.IMAPPort, &tls, &a.CreatedAt); err != nil {
return nil, err
}
a.UseTLS = tls == 1
out = append(out, a)
}
return out, nil
}
func GetAccount(id int64) (*Account, error) {
row := database.DB.QueryRow(`SELECT id,name,email,password,smtp_host,smtp_port,imap_host,imap_port,use_tls,created_at FROM accounts WHERE id=?`, id)
var a Account
var tls int
if err := row.Scan(&a.ID, &a.Name, &a.Email, &a.Password, &a.SMTPHost, &a.SMTPPort, &a.IMAPHost, &a.IMAPPort, &tls, &a.CreatedAt); err != nil {
return nil, err
}
a.UseTLS = tls == 1
return &a, nil
}
func CreateAccount(a *Account) error {
tls := 0
if a.UseTLS {
tls = 1
}
res, err := database.DB.Exec(
`INSERT INTO accounts(name,email,password,smtp_host,smtp_port,imap_host,imap_port,use_tls) VALUES(?,?,?,?,?,?,?,?)`,
a.Name, a.Email, a.Password, a.SMTPHost, a.SMTPPort, a.IMAPHost, a.IMAPPort, tls,
)
if err != nil {
return err
}
id, _ := res.LastInsertId()
a.ID = id
return nil
}
func UpdateAccount(a *Account) error {
tls := 0
if a.UseTLS {
tls = 1
}
_, err := database.DB.Exec(
`UPDATE accounts SET name=?,email=?,password=COALESCE(NULLIF(?, ''), password),smtp_host=?,smtp_port=?,imap_host=?,imap_port=?,use_tls=? WHERE id=?`,
a.Name, a.Email, a.Password, a.SMTPHost, a.SMTPPort, a.IMAPHost, a.IMAPPort, tls, a.ID,
)
return err
}
func DeleteAccount(id int64) error {
_, err := database.DB.Exec(`DELETE FROM accounts WHERE id=?`, id)
return err
}

View File

@@ -0,0 +1,50 @@
package models
import (
"time"
"mengpost-backend/database"
)
// SentLog 记录一次外发邮件的结果.
type SentLog struct {
ID int64 `json:"id"`
AccountID int64 `json:"account_id"`
To string `json:"to"`
Subject string `json:"subject"`
Body string `json:"body"`
Status string `json:"status"`
Error string `json:"error"`
CreatedAt time.Time `json:"created_at"`
}
func AddSentLog(l *SentLog) error {
_, err := database.DB.Exec(
`INSERT INTO sent_logs(account_id,to_addr,subject,body,status,error) VALUES(?,?,?,?,?,?)`,
l.AccountID, l.To, l.Subject, l.Body, l.Status, l.Error,
)
return err
}
func ListSentLogs(accountID int64, limit int) ([]SentLog, error) {
if limit <= 0 {
limit = 50
}
rows, err := database.DB.Query(
`SELECT id,account_id,to_addr,subject,body,status,error,created_at FROM sent_logs WHERE account_id=? ORDER BY id DESC LIMIT ?`,
accountID, limit,
)
if err != nil {
return nil, err
}
defer rows.Close()
var out []SentLog
for rows.Next() {
var l SentLog
if err := rows.Scan(&l.ID, &l.AccountID, &l.To, &l.Subject, &l.Body, &l.Status, &l.Error, &l.CreatedAt); err != nil {
return nil, err
}
out = append(out, l)
}
return out, nil
}