You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.7 KiB
92 lines
3.7 KiB
package user
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"yunyan/comm"
|
|
"yunyan/lego/core"
|
|
"yunyan/lego/core/cbase"
|
|
"yunyan/lego/sys/log"
|
|
"yunyan/lego/sys/mysql"
|
|
)
|
|
|
|
// dbUserFeedback App 用户反馈。本地 gorm 结构,不进 pb:
|
|
// 客户端只提交、不回读;后台列表由 console 直连业务库查询。
|
|
//
|
|
// version / phonemodel / channel 是提交当时从 user 行抄下来的快照。
|
|
// 用户之后升级或换机,这条记录仍停在提交时的环境上,排查「哪一版出的问题」靠它。
|
|
type dbUserFeedback struct {
|
|
Id uint64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
|
Uid string `gorm:"column:uid;size:50;index" json:"uid"`
|
|
Message string `gorm:"column:message;size:2000" json:"message"`
|
|
Version string `gorm:"column:version;size:32" json:"version"`
|
|
Phonemodel string `gorm:"column:phonemodel;size:64" json:"phonemodel"`
|
|
Channel int32 `gorm:"column:channel" json:"channel"`
|
|
Createtime int64 `gorm:"column:createtime;index" json:"createtime"`
|
|
}
|
|
|
|
type modelFeedbackComp struct {
|
|
cbase.ModuleCompBase
|
|
module *User
|
|
}
|
|
|
|
func (this *modelFeedbackComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
|
|
this.ModuleCompBase.Init(service, module, comp, opt)
|
|
this.module = module.(*User)
|
|
if err = mysql.CreateTable(comm.TableUserFeedback, &dbUserFeedback{}); err != nil {
|
|
this.module.Errorln(err)
|
|
}
|
|
// 后台列表按手机号/昵称筛时要 JOIN user。user 表多半是老库的 utf8mb4_general_ci,
|
|
// 新表按服务器默认建会是 utf8mb4_0900_ai_ci,联表直接 1267。对齐后再查。
|
|
this.alignCollation()
|
|
return
|
|
}
|
|
|
|
func (this *modelFeedbackComp) alignCollation() {
|
|
target := this.tableCollation(comm.TableUser)
|
|
charset, ok := collationCharset(target)
|
|
if !ok {
|
|
this.module.Warn("用户反馈表排序规则对齐:user 表排序规则读不到或不合法,跳过", log.Field{Key: "collation", Value: target})
|
|
return
|
|
}
|
|
cur := this.tableCollation(comm.TableUserFeedback)
|
|
if cur == "" || cur == target {
|
|
return
|
|
}
|
|
if res := mysql.Exec("ALTER TABLE `" + comm.TableUserFeedback + "` CONVERT TO CHARACTER SET " + charset + " COLLATE " + target); res.Error != nil {
|
|
this.module.Error("用户反馈表排序规则对齐失败", log.Field{Key: "from", Value: cur},
|
|
log.Field{Key: "to", Value: target}, log.Field{Key: "err", Value: res.Error.Error()})
|
|
return
|
|
}
|
|
this.module.Infof("用户反馈表排序规则对齐:%s → %s", cur, target)
|
|
}
|
|
|
|
func (this *modelFeedbackComp) tableCollation(table string) string {
|
|
var coll string
|
|
res := mysql.Raw("SELECT TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?", table).Scan(&coll)
|
|
if res.Error != nil {
|
|
this.module.Warn("读表排序规则失败", log.Field{Key: "table", Value: table}, log.Field{Key: "err", Value: res.Error.Error()})
|
|
return ""
|
|
}
|
|
return coll
|
|
}
|
|
|
|
// insert 写入一条反馈。用户资料读不到时快照留空,内容照样落库——
|
|
// 反馈本身比「附带的版本号」重要,不能因为查用户失败就把内容丢掉。
|
|
func (this *modelFeedbackComp) insert(uid, message string) error {
|
|
row := &dbUserFeedback{
|
|
Uid: uid,
|
|
Message: message,
|
|
Createtime: time.Now().Unix(),
|
|
}
|
|
if user, err := this.module.model.findforid(uid); err == nil && user != nil {
|
|
row.Version = user.Version
|
|
row.Phonemodel = user.Phonemodel
|
|
row.Channel = int32(user.Channel)
|
|
} else if err != nil && !errors.Is(err, mysql.ErrNoDocuments) {
|
|
this.module.Warn("用户反馈:读用户快照失败,仍写入内容",
|
|
log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
}
|
|
return mysql.Insert(comm.TableUserFeedback, row)
|
|
}
|
|
|