修复网页端编码问题
This commit is contained in:
@@ -4,6 +4,8 @@ package mailutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -40,13 +42,31 @@ func DecodeCharset(buf []byte, charset string) string {
|
|||||||
return string(decoded)
|
return string(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeRFC2047 解码邮件头中的 RFC 2047 encoded-word。
|
||||||
|
func DecodeRFC2047(value string) string {
|
||||||
|
decoder := mime.WordDecoder{
|
||||||
|
CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
|
||||||
|
data, err := io.ReadAll(input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return strings.NewReader(DecodeCharset(data, charset)), nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
decoded, err := decoder.DecodeHeader(value)
|
||||||
|
if err != nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return decoded
|
||||||
|
}
|
||||||
|
|
||||||
// FormatAddressList 解析 RFC 2047 编码的地址列表头并格式化为可读字符串。
|
// FormatAddressList 解析 RFC 2047 编码的地址列表头并格式化为可读字符串。
|
||||||
// 例如: "=?gb2312?B?zuIgzsS35Q==?= <a@b.com>" → "吴文锋 <a@b.com>"
|
// 例如: "=?gb2312?B?zuIgzsS35Q==?= <a@b.com>" → "吴文锋 <a@b.com>"
|
||||||
func FormatAddressList(header *asgomail.Header, key string) string {
|
func FormatAddressList(header *asgomail.Header, key string) string {
|
||||||
addrs, err := header.AddressList(key)
|
addrs, err := header.AddressList(key)
|
||||||
if err != nil || len(addrs) == 0 {
|
if err != nil || len(addrs) == 0 {
|
||||||
// 降级:返回原始值
|
// 降级:返回解码后的原始值
|
||||||
return header.Get(key)
|
return DecodeRFC2047(header.Get(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
var parts []string
|
var parts []string
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"mail_go/config"
|
"mail_go/config"
|
||||||
|
"mail_go/internal/mailutil"
|
||||||
"mail_go/internal/storage"
|
"mail_go/internal/storage"
|
||||||
"mail_go/internal/store"
|
"mail_go/internal/store"
|
||||||
"mail_go/internal/web/handlers"
|
"mail_go/internal/web/handlers"
|
||||||
@@ -73,6 +74,9 @@ func templateFuncs() template.FuncMap {
|
|||||||
"formatBytes": func(b int64) string {
|
"formatBytes": func(b int64) string {
|
||||||
return formatBytes(b)
|
return formatBytes(b)
|
||||||
},
|
},
|
||||||
|
"decodeHeader": func(s string) string {
|
||||||
|
return mailutil.DecodeRFC2047(s)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h2>{{if .message.Subject}}{{.message.Subject}}{{else}}(无主题){{end}}</h2>
|
<h2>{{if .message.Subject}}{{.message.Subject}}{{else}}(无主题){{end}}</h2>
|
||||||
<div class="mail-meta" style="margin-top:12px;">
|
<div class="mail-meta" style="margin-top:12px;">
|
||||||
<p><strong>发件人:</strong> {{.message.FromAddr}}</p>
|
<p><strong>发件人:</strong> {{decodeHeader .message.FromAddr}}</p>
|
||||||
<p><strong>收件人:</strong> {{.message.ToAddr}}</p>
|
<p><strong>收件人:</strong> {{.message.ToAddr}}</p>
|
||||||
{{if .message.CcAddr}}<p><strong>抄送:</strong> {{.message.CcAddr}}</p>{{end}}
|
{{if .message.CcAddr}}<p><strong>抄送:</strong> {{.message.CcAddr}}</p>{{end}}
|
||||||
<p><strong>所属用户:</strong> {{if .message.User.ID}}{{.message.User.Username}}{{else}}—{{end}}</p>
|
<p><strong>所属用户:</strong> {{if .message.User.ID}}{{.message.User.Username}}{{else}}—{{end}}</p>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .messages}}
|
{{range .messages}}
|
||||||
<tr style="cursor:pointer;" onclick="location.href='/admin/mails/{{.ID}}'">
|
<tr style="cursor:pointer;" onclick="location.href='/admin/mails/{{.ID}}'">
|
||||||
<td>{{.FromAddr}}</td>
|
<td>{{decodeHeader .FromAddr}}</td>
|
||||||
<td>{{.ToAddr}}</td>
|
<td>{{.ToAddr}}</td>
|
||||||
<td>{{.Subject}}</td>
|
<td>{{.Subject}}</td>
|
||||||
<td>{{if .User.ID}}{{.User.Username}}{{else}}—{{end}}</td>
|
<td>{{if .User.ID}}{{.User.Username}}{{else}}—{{end}}</td>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .messages}}
|
{{range .messages}}
|
||||||
<tr class="{{if not .IsRead}}unread{{end}}">
|
<tr class="{{if not .IsRead}}unread{{end}}">
|
||||||
<td>{{.FromAddr}}</td>
|
<td>{{decodeHeader .FromAddr}}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="/inbox/{{.ID}}" class="message-subject">
|
<a href="/inbox/{{.ID}}" class="message-subject">
|
||||||
{{if .Subject}}{{.Subject}}{{else}}(无主题){{end}}
|
{{if .Subject}}{{.Subject}}{{else}}(无主题){{end}}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h2>{{if .message.Subject}}{{.message.Subject}}{{else}}(无主题){{end}}</h2>
|
<h2>{{if .message.Subject}}{{.message.Subject}}{{else}}(无主题){{end}}</h2>
|
||||||
<div class="mail-meta" style="margin-top:12px;">
|
<div class="mail-meta" style="margin-top:12px;">
|
||||||
<p><strong>发件人:</strong> {{.message.FromAddr}}</p>
|
<p><strong>发件人:</strong> {{decodeHeader .message.FromAddr}}</p>
|
||||||
<p><strong>收件人:</strong> {{.message.ToAddr}}</p>
|
<p><strong>收件人:</strong> {{.message.ToAddr}}</p>
|
||||||
{{if .message.CcAddr}}<p><strong>抄送:</strong> {{.message.CcAddr}}</p>{{end}}
|
{{if .message.CcAddr}}<p><strong>抄送:</strong> {{.message.CcAddr}}</p>{{end}}
|
||||||
<p><strong>时间:</strong> {{.message.Date.Format "2006-01-02 15:04:05"}}</p>
|
<p><strong>时间:</strong> {{.message.Date.Format "2006-01-02 15:04:05"}}</p>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
onsubmit="return confirm('确定要删除这封邮件吗?');">
|
onsubmit="return confirm('确定要删除这封邮件吗?');">
|
||||||
<button type="submit" class="btn btn-danger">删除邮件</button>
|
<button type="submit" class="btn btn-danger">删除邮件</button>
|
||||||
</form>
|
</form>
|
||||||
<a href="/compose?to={{.message.FromAddr}}&subject={{if .message.Subject}}Re: {{.message.Subject}}{{end}}" class="btn btn-primary" style="margin-left:8px;">回复</a>
|
<a href="/compose?to={{decodeHeader .message.FromAddr}}&subject={{if .message.Subject}}Re: {{.message.Subject}}{{end}}" class="btn btn-primary" style="margin-left:8px;">回复</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user