Fearure:
- 增加收件箱功能(有BUG) - 增加已发送|草稿箱|发送历史 本地记录
This commit is contained in:
221
history.go
Normal file
221
history.go
Normal file
@@ -0,0 +1,221 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
const historyDBName = "history.db"
|
||||
|
||||
type EmailStatus string
|
||||
|
||||
const (
|
||||
StatusSent EmailStatus = "sent"
|
||||
StatusDraft EmailStatus = "draft"
|
||||
)
|
||||
|
||||
type EmailHistory struct {
|
||||
ID int64
|
||||
From string
|
||||
To string
|
||||
Cc string
|
||||
Bcc string
|
||||
Subject string
|
||||
BodyText string
|
||||
BodyHTML string
|
||||
Attachments string
|
||||
Status EmailStatus
|
||||
DeliveryMethod string
|
||||
CreatedAt time.Time
|
||||
SentAt *time.Time
|
||||
}
|
||||
|
||||
func getHistoryDBPath() (string, error) {
|
||||
configDir, err := getConfigDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(configDir, historyDBName), nil
|
||||
}
|
||||
|
||||
func initHistoryDB() (*sql.DB, error) {
|
||||
dbPath, err := getHistoryDBPath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS emails (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
from_addr TEXT NOT NULL,
|
||||
to_addrs TEXT NOT NULL,
|
||||
cc_addrs TEXT,
|
||||
bcc_addrs TEXT,
|
||||
subject TEXT NOT NULL,
|
||||
body_text TEXT,
|
||||
body_html TEXT,
|
||||
attachments TEXT,
|
||||
status TEXT NOT NULL,
|
||||
delivery_method TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
sent_at DATETIME
|
||||
)
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func SaveEmail(from, to, cc, bcc, subject, bodyText, bodyHTML, attachments, deliveryMethod string, status EmailStatus) (int64, error) {
|
||||
db, err := initHistoryDB()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
stmt, err := db.Prepare(`
|
||||
INSERT INTO emails (from_addr, to_addrs, cc_addrs, bcc_addrs, subject, body_text, body_html, attachments, status, delivery_method, created_at, sent_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
now := time.Now()
|
||||
var sentAt *time.Time
|
||||
if status == StatusSent {
|
||||
sentAt = &now
|
||||
}
|
||||
result, err := stmt.Exec(from, to, cc, bcc, subject, bodyText, bodyHTML, attachments, status, deliveryMethod, now, sentAt)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result.LastInsertId()
|
||||
}
|
||||
|
||||
func UpdateEmailStatus(id int64, status EmailStatus) error {
|
||||
db, err := initHistoryDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("UPDATE emails SET status = ?, sent_at = ? WHERE id = ?", status, time.Now(), id)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetEmailHistory(status EmailStatus) ([]EmailHistory, error) {
|
||||
db, err := initHistoryDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var query string
|
||||
var args []interface{}
|
||||
|
||||
if status == "" {
|
||||
query = "SELECT id, from_addr, to_addrs, cc_addrs, bcc_addrs, subject, body_text, body_html, attachments, status, delivery_method, created_at, sent_at FROM emails ORDER BY created_at DESC"
|
||||
} else {
|
||||
query = "SELECT id, from_addr, to_addrs, cc_addrs, bcc_addrs, subject, body_text, body_html, attachments, status, delivery_method, created_at, sent_at FROM emails WHERE status = ? ORDER BY created_at DESC"
|
||||
args = []interface{}{status}
|
||||
}
|
||||
|
||||
rows, err := db.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var histories []EmailHistory
|
||||
for rows.Next() {
|
||||
var h EmailHistory
|
||||
var sentAt sql.NullTime
|
||||
err := rows.Scan(&h.ID, &h.From, &h.To, &h.Cc, &h.Bcc, &h.Subject, &h.BodyText, &h.BodyHTML, &h.Attachments, &h.Status, &h.DeliveryMethod, &h.CreatedAt, &sentAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sentAt.Valid {
|
||||
h.SentAt = &sentAt.Time
|
||||
}
|
||||
histories = append(histories, h)
|
||||
}
|
||||
|
||||
return histories, nil
|
||||
}
|
||||
|
||||
func GetEmailByID(id int64) (*EmailHistory, error) {
|
||||
db, err := initHistoryDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
var h EmailHistory
|
||||
var sentAt sql.NullTime
|
||||
err = db.QueryRow("SELECT id, from_addr, to_addrs, cc_addrs, bcc_addrs, subject, body_text, body_html, attachments, status, delivery_method, created_at, sent_at FROM emails WHERE id = ?", id).Scan(
|
||||
&h.ID, &h.From, &h.To, &h.Cc, &h.Bcc, &h.Subject, &h.BodyText, &h.BodyHTML, &h.Attachments, &h.Status, &h.DeliveryMethod, &h.CreatedAt, &sentAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sentAt.Valid {
|
||||
h.SentAt = &sentAt.Time
|
||||
}
|
||||
return &h, nil
|
||||
}
|
||||
|
||||
func DeleteEmailHistory(id int64) error {
|
||||
db, err := initHistoryDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("DELETE FROM emails WHERE id = ?", id)
|
||||
return err
|
||||
}
|
||||
|
||||
func getAttachmentsJSON(paths []string) string {
|
||||
if len(paths) == 0 {
|
||||
return "[]"
|
||||
}
|
||||
data, _ := json.Marshal(paths)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func parseAttachmentsJSON(jsonStr string) []string {
|
||||
if jsonStr == "" || jsonStr == "[]" {
|
||||
return nil
|
||||
}
|
||||
var paths []string
|
||||
json.Unmarshal([]byte(jsonStr), &paths)
|
||||
return paths
|
||||
}
|
||||
|
||||
func init() {
|
||||
dbPath, err := getHistoryDBPath()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
||||
if _, err := initHistoryDB(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to initialize history DB: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user