1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"net/smtp"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
// 定义User模型
type User struct {
ID uint `gorm:"primaryKey"`
Username string `gorm:"unique"`
Email string `gorm:"unique"`
Password string
SubscriptionID uint
Subscription Subscription
IsActive bool
CreatedAt time.Time
}
// 定义Subscription模型
type Subscription struct {
ID uint `gorm:"primaryKey"`
Name string
CreatedAt time.Time
}
// 定义Resource模型
type Resource struct {
ID uint `gorm:"primaryKey"`
Name string
ResourceType string
CreatedAt time.Time
}
// 定义UserResource模型
type UserResource struct {
ID uint `gorm:"primaryKey"`
UserID uint
ResourceID uint
CreatedAt time.Time
}
// 定义Activation模型
type Activation struct {
ID uint `gorm:"primaryKey"`
UserID uint
ActivationCode string `gorm:"size:9"`
CreatedAt time.Time
}
// 生成9位激活码
func generateActivationCode() (string, error) {
b := make([]byte, 6) // 6 bytes * 4/3 = 8 characters
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b)[:9], nil
}
// 发送激活邮件
func sendActivationEmail(user *User, code string) error {
from := "your-email@example.com"
pass := "your-email-password"
to := user.Email
activationLink := fmt.Sprintf("http://your-domain.com/activate?code=%s", code)
msg := fmt.Sprintf("To: %s\r\n"+
"Subject: Please activate your account\r\n"+
"\r\n"+
"Click the following link to activate your account:\r\n"+
"%s\r\n", to, activationLink)
return smtp.SendMail("smtp.example.com:587",
smtp.PlainAuth("", from, pass, "smtp.example.com"),
from, []string{to}, []byte(msg))
}
func main() {
dsn := "host=localhost user=gorm dbname=gorm password=gorm sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移表结构
db.AutoMigrate(&User{}, &Subscription{}, &Resource{}, &UserResource{}, &Activation{})
// 用户注册示例
activationCode, err := generateActivationCode()
if err != nil {
panic("failed to generate activation code")
}
user := User{
Username: "test_user",
Email: "test_user@example.com",
Password: "password", // 在实际应用中应加密存储密码
SubscriptionID: 1, // 假设已经有一个 Subscription
}
db.Create(&user)
activation := Activation{
UserID: user.ID,
ActivationCode: activationCode,
}
db.Create(&activation)
// 发送激活邮件
if err := sendActivationEmail(&user, activationCode); err != nil {
panic("failed to send activation email")
}
fmt.Println("User registered, awaiting activation...")
}
// 激活用户
func activateUser(w http.ResponseWriter, r *http.Request) {
activationCode := r.URL.Query().Get("code")
if activationCode == "" {
http.Error(w, "Missing activation code", http.StatusBadRequest)
return
}
dsn := "host=localhost user=gorm dbname=gorm password=gorm sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
http.Error(w, "Database connection error", http.StatusInternalServerError)
return
}
var activation Activation
if err := db.Where("activation_code = ?", activationCode).First(&activation).Error; err != nil {
http.Error(w, "Invalid activation code", http.StatusBadRequest)
return
}
var user User
db.First(&user, activation.UserID)
// 更新用户激活状态
user.IsActive = true
db.Save(&user)
// 删除激活记录
db.Delete(&activation)
w.Write([]byte("Account activated successfully!"))
}
func main() {
http.HandleFunc("/activate", activateUser)
http.ListenAndServe(":8080", nil)
}
|