commits
This commit is contained in:
+298
-298
@@ -1,298 +1,298 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
"server/pkg/jwtutil"
|
||||
"server/services"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// PlatformEmailController 系统邮箱配置(yz_system_email)
|
||||
type PlatformEmailController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (c *PlatformEmailController) platformClaims() (*jwtutil.Claims, error) {
|
||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return nil, fmt.Errorf("未登录")
|
||||
}
|
||||
parts := strings.SplitN(auth, " ", 2)
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
return nil, fmt.Errorf("认证信息格式错误")
|
||||
}
|
||||
claims, err := jwtutil.ParseToken(parts[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无效的token")
|
||||
}
|
||||
if claims.UserType != "platform" {
|
||||
return nil, fmt.Errorf("无权访问")
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func (c *PlatformEmailController) jsonErr(httpStatus, bizCode int, msg string) {
|
||||
c.Ctx.Output.SetStatus(httpStatus)
|
||||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
func emailRowToMap(m models.SystemEmail) map[string]interface{} {
|
||||
out := map[string]interface{}{
|
||||
"id": m.ID,
|
||||
"from_address": m.FromAddress,
|
||||
"host": m.Host,
|
||||
"port": m.Port,
|
||||
"password": m.Password,
|
||||
"encryption": m.Encryption,
|
||||
"timeout": m.Timeout,
|
||||
"status": m.Status,
|
||||
"create_time": m.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
"update_time": m.UpdateTime.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if m.FromName != nil {
|
||||
out["from_name"] = *m.FromName
|
||||
} else {
|
||||
out["from_name"] = ""
|
||||
}
|
||||
if m.Remark != nil {
|
||||
out["remark"] = *m.Remark
|
||||
} else {
|
||||
out["remark"] = ""
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GetInfo GET /platform/email/info
|
||||
func (c *PlatformEmailController) GetInfo() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
rows, err := services.ListSystemEmails()
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "获取邮箱配置失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
list := make([]map[string]interface{}, 0, len(rows))
|
||||
for i := range rows {
|
||||
list = append(list, emailRowToMap(rows[i]))
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": list}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
type emailFormPayload struct {
|
||||
FromAddress string `json:"fromAddress"`
|
||||
FromName string `json:"fromName"`
|
||||
Host string `json:"host"`
|
||||
Port interface{} `json:"port"`
|
||||
Password string `json:"password"`
|
||||
Encryption string `json:"encryption"`
|
||||
Timeout interface{} `json:"timeout"`
|
||||
Status interface{} `json:"status"`
|
||||
}
|
||||
type testEmailPayload struct {
|
||||
emailFormPayload
|
||||
TestEmail string `json:"testEmail"`
|
||||
}
|
||||
|
||||
func parseInt8Flexible(v interface{}) int8 {
|
||||
if v == nil {
|
||||
return 1
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case bool:
|
||||
if x {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
case float64:
|
||||
return int8(x)
|
||||
case int:
|
||||
return int8(x)
|
||||
case int8:
|
||||
return x
|
||||
case string:
|
||||
s := strings.TrimSpace(x)
|
||||
if s == "" {
|
||||
return 1
|
||||
}
|
||||
n, err := strconv.ParseInt(s, 10, 8)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
return int8(n)
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func parseUintFlexible(v interface{}) uint {
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case float64:
|
||||
if x < 0 {
|
||||
return 0
|
||||
}
|
||||
return uint(x)
|
||||
case string:
|
||||
n, err := parseUintString(x)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return n
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func parseUintString(s string) (uint, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return 0, fmt.Errorf("empty")
|
||||
}
|
||||
n, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(n), nil
|
||||
}
|
||||
|
||||
func normalizeEncryption(s string) string {
|
||||
s = strings.ToLower(strings.TrimSpace(s))
|
||||
switch s {
|
||||
case "ssl", "tls", "none":
|
||||
return s
|
||||
default:
|
||||
return "ssl"
|
||||
}
|
||||
}
|
||||
|
||||
// EditInfo POST /platform/email/editinfo
|
||||
func (c *PlatformEmailController) EditInfo() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||
if err != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
var p emailFormPayload
|
||||
if uerr := json.Unmarshal(raw, &p); uerr != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
from := strings.TrimSpace(p.FromAddress)
|
||||
host := strings.TrimSpace(p.Host)
|
||||
if from == "" || host == "" {
|
||||
c.jsonErr(400, 400, "发件人邮箱与 SMTP 主机不能为空")
|
||||
return
|
||||
}
|
||||
port := parseUintFlexible(p.Port)
|
||||
if port == 0 {
|
||||
port = 465
|
||||
}
|
||||
timeout := parseUintFlexible(p.Timeout)
|
||||
if timeout == 0 {
|
||||
timeout = 30
|
||||
}
|
||||
enc := normalizeEncryption(p.Encryption)
|
||||
cnt, cerr := models.Orm.QueryTable(new(models.SystemEmail)).Count()
|
||||
if cerr != nil {
|
||||
c.jsonErr(500, 500, "读取邮箱配置失败: "+cerr.Error())
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(p.Password) == "" && cnt == 0 {
|
||||
c.jsonErr(400, 400, "授权码/密码不能为空")
|
||||
return
|
||||
}
|
||||
var fn *string
|
||||
if strings.TrimSpace(p.FromName) != "" {
|
||||
s := strings.TrimSpace(p.FromName)
|
||||
fn = &s
|
||||
}
|
||||
status := parseInt8Flexible(p.Status)
|
||||
err = services.UpsertFirstSystemEmail(from, fn, host, port, strings.TrimSpace(p.Password), enc, timeout, status, nil)
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "保存邮箱配置失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
// SendTestEmail POST /platform/email/sendtestemail
|
||||
func (c *PlatformEmailController) SendTestEmail() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||
if err != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
var p testEmailPayload
|
||||
if uerr := json.Unmarshal(raw, &p); uerr != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
to := strings.TrimSpace(p.TestEmail)
|
||||
if to == "" {
|
||||
c.jsonErr(400, 400, "测试收件邮箱不能为空")
|
||||
return
|
||||
}
|
||||
from := strings.TrimSpace(p.FromAddress)
|
||||
host := strings.TrimSpace(p.Host)
|
||||
if from == "" || host == "" {
|
||||
c.jsonErr(400, 400, "发件人邮箱与 SMTP 主机不能为空")
|
||||
return
|
||||
}
|
||||
port := parseUintFlexible(p.Port)
|
||||
if port == 0 {
|
||||
port = 465
|
||||
}
|
||||
timeout := parseUintFlexible(p.Timeout)
|
||||
if timeout == 0 {
|
||||
timeout = 30
|
||||
}
|
||||
enc := normalizeEncryption(p.Encryption)
|
||||
pass := strings.TrimSpace(p.Password)
|
||||
if pass == "" {
|
||||
rows, lerr := services.ListSystemEmails()
|
||||
if lerr == nil && len(rows) > 0 {
|
||||
pass = rows[0].Password
|
||||
}
|
||||
}
|
||||
if pass == "" {
|
||||
c.jsonErr(400, 400, "授权码/密码不能为空(请填写或先保存配置)")
|
||||
return
|
||||
}
|
||||
cfg := services.SMTPConfig{
|
||||
FromAddress: from,
|
||||
FromName: strings.TrimSpace(p.FromName),
|
||||
Host: host,
|
||||
Port: port,
|
||||
Password: pass,
|
||||
Encryption: enc,
|
||||
Timeout: timeout,
|
||||
}
|
||||
if err := services.SendTestEmailSMTP(cfg, to); err != nil {
|
||||
c.jsonErr(500, 500, "发送失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "发送成功"}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
"server/pkg/jwtutil"
|
||||
"server/services"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// PlatformEmailController 系统邮箱配置(yz_system_email)
|
||||
type PlatformEmailController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (c *PlatformEmailController) platformClaims() (*jwtutil.Claims, error) {
|
||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return nil, fmt.Errorf("未登录")
|
||||
}
|
||||
parts := strings.SplitN(auth, " ", 2)
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
return nil, fmt.Errorf("认证信息格式错误")
|
||||
}
|
||||
claims, err := jwtutil.ParseToken(parts[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无效的token")
|
||||
}
|
||||
if claims.UserType != "platform" {
|
||||
return nil, fmt.Errorf("无权访问")
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func (c *PlatformEmailController) jsonErr(httpStatus, bizCode int, msg string) {
|
||||
c.Ctx.Output.SetStatus(httpStatus)
|
||||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
func emailRowToMap(m models.SystemEmail) map[string]interface{} {
|
||||
out := map[string]interface{}{
|
||||
"id": m.ID,
|
||||
"from_address": m.FromAddress,
|
||||
"host": m.Host,
|
||||
"port": m.Port,
|
||||
"password": m.Password,
|
||||
"encryption": m.Encryption,
|
||||
"timeout": m.Timeout,
|
||||
"status": m.Status,
|
||||
"create_time": m.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
"update_time": m.UpdateTime.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if m.FromName != nil {
|
||||
out["from_name"] = *m.FromName
|
||||
} else {
|
||||
out["from_name"] = ""
|
||||
}
|
||||
if m.Remark != nil {
|
||||
out["remark"] = *m.Remark
|
||||
} else {
|
||||
out["remark"] = ""
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GetInfo GET /platform/email/info
|
||||
func (c *PlatformEmailController) GetInfo() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
rows, err := services.ListSystemEmails()
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "获取邮箱配置失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
list := make([]map[string]interface{}, 0, len(rows))
|
||||
for i := range rows {
|
||||
list = append(list, emailRowToMap(rows[i]))
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": list}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
type emailFormPayload struct {
|
||||
FromAddress string `json:"fromAddress"`
|
||||
FromName string `json:"fromName"`
|
||||
Host string `json:"host"`
|
||||
Port interface{} `json:"port"`
|
||||
Password string `json:"password"`
|
||||
Encryption string `json:"encryption"`
|
||||
Timeout interface{} `json:"timeout"`
|
||||
Status interface{} `json:"status"`
|
||||
}
|
||||
type testEmailPayload struct {
|
||||
emailFormPayload
|
||||
TestEmail string `json:"testEmail"`
|
||||
}
|
||||
|
||||
func parseInt8Flexible(v interface{}) int8 {
|
||||
if v == nil {
|
||||
return 1
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case bool:
|
||||
if x {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
case float64:
|
||||
return int8(x)
|
||||
case int:
|
||||
return int8(x)
|
||||
case int8:
|
||||
return x
|
||||
case string:
|
||||
s := strings.TrimSpace(x)
|
||||
if s == "" {
|
||||
return 1
|
||||
}
|
||||
n, err := strconv.ParseInt(s, 10, 8)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
return int8(n)
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func parseUintFlexible(v interface{}) uint {
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case float64:
|
||||
if x < 0 {
|
||||
return 0
|
||||
}
|
||||
return uint(x)
|
||||
case string:
|
||||
n, err := parseUintString(x)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return n
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func parseUintString(s string) (uint, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return 0, fmt.Errorf("empty")
|
||||
}
|
||||
n, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(n), nil
|
||||
}
|
||||
|
||||
func normalizeEncryption(s string) string {
|
||||
s = strings.ToLower(strings.TrimSpace(s))
|
||||
switch s {
|
||||
case "ssl", "tls", "none":
|
||||
return s
|
||||
default:
|
||||
return "ssl"
|
||||
}
|
||||
}
|
||||
|
||||
// EditInfo POST /platform/email/editinfo
|
||||
func (c *PlatformEmailController) EditInfo() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||
if err != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
var p emailFormPayload
|
||||
if uerr := json.Unmarshal(raw, &p); uerr != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
from := strings.TrimSpace(p.FromAddress)
|
||||
host := strings.TrimSpace(p.Host)
|
||||
if from == "" || host == "" {
|
||||
c.jsonErr(400, 400, "发件人邮箱与 SMTP 主机不能为空")
|
||||
return
|
||||
}
|
||||
port := parseUintFlexible(p.Port)
|
||||
if port == 0 {
|
||||
port = 465
|
||||
}
|
||||
timeout := parseUintFlexible(p.Timeout)
|
||||
if timeout == 0 {
|
||||
timeout = 30
|
||||
}
|
||||
enc := normalizeEncryption(p.Encryption)
|
||||
cnt, cerr := models.Orm.QueryTable(new(models.SystemEmail)).Count()
|
||||
if cerr != nil {
|
||||
c.jsonErr(500, 500, "读取邮箱配置失败: "+cerr.Error())
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(p.Password) == "" && cnt == 0 {
|
||||
c.jsonErr(400, 400, "授权码/密码不能为空")
|
||||
return
|
||||
}
|
||||
var fn *string
|
||||
if strings.TrimSpace(p.FromName) != "" {
|
||||
s := strings.TrimSpace(p.FromName)
|
||||
fn = &s
|
||||
}
|
||||
status := parseInt8Flexible(p.Status)
|
||||
err = services.UpsertFirstSystemEmail(from, fn, host, port, strings.TrimSpace(p.Password), enc, timeout, status, nil)
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "保存邮箱配置失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
// SendTestEmail POST /platform/email/sendtestemail
|
||||
func (c *PlatformEmailController) SendTestEmail() {
|
||||
if _, err := c.platformClaims(); err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||
if err != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
var p testEmailPayload
|
||||
if uerr := json.Unmarshal(raw, &p); uerr != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
to := strings.TrimSpace(p.TestEmail)
|
||||
if to == "" {
|
||||
c.jsonErr(400, 400, "测试收件邮箱不能为空")
|
||||
return
|
||||
}
|
||||
from := strings.TrimSpace(p.FromAddress)
|
||||
host := strings.TrimSpace(p.Host)
|
||||
if from == "" || host == "" {
|
||||
c.jsonErr(400, 400, "发件人邮箱与 SMTP 主机不能为空")
|
||||
return
|
||||
}
|
||||
port := parseUintFlexible(p.Port)
|
||||
if port == 0 {
|
||||
port = 465
|
||||
}
|
||||
timeout := parseUintFlexible(p.Timeout)
|
||||
if timeout == 0 {
|
||||
timeout = 30
|
||||
}
|
||||
enc := normalizeEncryption(p.Encryption)
|
||||
pass := strings.TrimSpace(p.Password)
|
||||
if pass == "" {
|
||||
rows, lerr := services.ListSystemEmails()
|
||||
if lerr == nil && len(rows) > 0 {
|
||||
pass = rows[0].Password
|
||||
}
|
||||
}
|
||||
if pass == "" {
|
||||
c.jsonErr(400, 400, "授权码/密码不能为空(请填写或先保存配置)")
|
||||
return
|
||||
}
|
||||
cfg := services.SMTPConfig{
|
||||
FromAddress: from,
|
||||
FromName: strings.TrimSpace(p.FromName),
|
||||
Host: host,
|
||||
Port: port,
|
||||
Password: pass,
|
||||
Encryption: enc,
|
||||
Timeout: timeout,
|
||||
}
|
||||
if err := services.SendTestEmailSMTP(cfg, to); err != nil {
|
||||
c.jsonErr(500, 500, "发送失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "发送成功"}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user