feat(1.0):调试模版消息
This commit is contained in:
parent
d469c4a8ab
commit
de9acfa863
@ -34,6 +34,6 @@ eg :
|
||||
|
||||
```shell
|
||||
# 根目录下执行
|
||||
go run cmd/gormgen/main.go -dsn "root:api2api..@tcp(sh-cynosdbmysql-grp-88th45wy.sql.tencentcdb.com:28555)/mini_chat?charset=utf8mb4&parseTime=True&loc=Local" -tables "log_operation,log_request,admin,app_keyword,app_keyword_reply,app_user,app_message_log,mini_program"
|
||||
go run cmd/gormgen/main.go -dsn "root:api2api..@tcp(sh-cynosdbmysql-grp-88th45wy.sql.tencentcdb.com:28555)/mini_chat?charset=utf8mb4&parseTime=True&loc=Local" -tables "log_operation,log_request,admin,app_keyword,app_keyword_reply,app_user,app_message_log,mini_program,mini_program_access_token"
|
||||
|
||||
```
|
||||
|
||||
39
internal/pkg/miniprogram/access_token.go
Normal file
39
internal/pkg/miniprogram/access_token.go
Normal file
@ -0,0 +1,39 @@
|
||||
package miniprogram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
type AccessTokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
}
|
||||
|
||||
// GetAccessToken 获取微信 access_token
|
||||
// DOC: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
|
||||
func GetAccessToken(appID, appSecret string, resultStruct interface{}) error {
|
||||
requestData := map[string]string{}
|
||||
requestData["grant_type"] = "client_credential"
|
||||
requestData["appid"] = appID
|
||||
requestData["secret"] = appSecret
|
||||
|
||||
response, err := resty.New().R().
|
||||
ForceContentType("application/json").
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetQueryParams(requestData).
|
||||
SetResult(resultStruct).
|
||||
Get("https://api.weixin.qq.com/cgi-bin/token")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查响应状态码
|
||||
if response.IsError() {
|
||||
return fmt.Errorf("服务异常(%d)", response.StatusCode())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
16
internal/pkg/miniprogram/access_token_test.go
Normal file
16
internal/pkg/miniprogram/access_token_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package miniprogram
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetAccessToken(t *testing.T) {
|
||||
res := new(AccessTokenResponse)
|
||||
err := GetAccessToken("wx26ad074017e1e63f", "026c19ce4f3bb090c56573024c59a8be", res)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
t.Logf("access_token: %s", res.AccessToken)
|
||||
t.Logf("expires_in: %d", res.ExpiresIn)
|
||||
}
|
||||
58
internal/pkg/miniprogram/subscribe.go
Normal file
58
internal/pkg/miniprogram/subscribe.go
Normal file
@ -0,0 +1,58 @@
|
||||
package miniprogram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
type SendSubscribeMessageResponse struct {
|
||||
Errcode int `json:"errcode"`
|
||||
Errmsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
type SendSubscribeMessageRequest struct {
|
||||
Touser string `json:"touser"`
|
||||
TemplateID string `json:"template_id"`
|
||||
Page string `json:"page"`
|
||||
MiniprogramState string `json:"miniprogram_state"`
|
||||
Lang string `json:"lang"`
|
||||
Data struct {
|
||||
Thing1 struct {
|
||||
Value string `json:"value"`
|
||||
} `json:"thing1"`
|
||||
Time2 struct {
|
||||
Value string `json:"value"`
|
||||
} `json:"time2"`
|
||||
Thing4 struct {
|
||||
Value string `json:"value"`
|
||||
} `json:"thing4"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// SendSubscribeMessage 发送订阅消息
|
||||
// DOC: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html
|
||||
func SendSubscribeMessage(accessToken string, requestData *SendSubscribeMessageRequest, resultStruct interface{}) error {
|
||||
response, err := resty.New().R().
|
||||
ForceContentType("application/json").
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(requestData).
|
||||
SetResult(resultStruct).
|
||||
Post(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s", accessToken))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查响应状态码
|
||||
if response.IsError() {
|
||||
return fmt.Errorf("服务异常(%d)", response.StatusCode())
|
||||
}
|
||||
|
||||
// 检查响应结果
|
||||
if response.Result().(*SendSubscribeMessageResponse).Errcode != 0 {
|
||||
return fmt.Errorf("服务异常(%d): %s", response.Result().(*SendSubscribeMessageResponse).Errcode, response.Result().(*SendSubscribeMessageResponse).Errmsg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
32
internal/pkg/miniprogram/subscribe_test.go
Normal file
32
internal/pkg/miniprogram/subscribe_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package miniprogram
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSendSubscribeMessage(t *testing.T) {
|
||||
res := new(AccessTokenResponse)
|
||||
err := GetAccessToken("wx26ad074017e1e63f", "026c19ce4f3bb090c56573024c59a8be", res)
|
||||
if err != nil {
|
||||
t.Errorf("获取 access_token 错误: %s", err.Error())
|
||||
}
|
||||
|
||||
sendSubscribeMessageRequest := new(SendSubscribeMessageRequest)
|
||||
sendSubscribeMessageRequest.Touser = "onjlN4wrsGe09SdRrpl4D_FWBh0I"
|
||||
sendSubscribeMessageRequest.TemplateID = "9dCV3z7vRPBGm8iMtSXsD7ZVyUjld46w7HTH9zLnzWw"
|
||||
sendSubscribeMessageRequest.Page = "pages/contact/index"
|
||||
sendSubscribeMessageRequest.MiniprogramState = "trial"
|
||||
sendSubscribeMessageRequest.Lang = "zh_CN"
|
||||
sendSubscribeMessageRequest.Data.Thing1.Value = "测试(CC)"
|
||||
sendSubscribeMessageRequest.Data.Time2.Value = "2025-10-27"
|
||||
sendSubscribeMessageRequest.Data.Thing4.Value = "测试(CC)"
|
||||
|
||||
sendSubscribeMessageResponse := new(SendSubscribeMessageResponse)
|
||||
err = SendSubscribeMessage(res.AccessToken, sendSubscribeMessageRequest, sendSubscribeMessageResponse)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
t.Logf("Errcode: %d", sendSubscribeMessageResponse.Errcode)
|
||||
t.Logf("Errmsg: %s", sendSubscribeMessageResponse.Errmsg)
|
||||
}
|
||||
@ -35,8 +35,8 @@ func newAppMessageLog(db *gorm.DB, opts ...gen.DOOption) appMessageLog {
|
||||
_appMessageLog.ReceiverID = field.NewString(tableName, "receiver_id")
|
||||
_appMessageLog.MsgType = field.NewInt32(tableName, "msg_type")
|
||||
_appMessageLog.Content = field.NewString(tableName, "content")
|
||||
_appMessageLog.IsRead = field.NewInt32(tableName, "is_read")
|
||||
_appMessageLog.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_appMessageLog.IsRead = field.NewInt32(tableName, "is_read")
|
||||
|
||||
_appMessageLog.fillFieldMap()
|
||||
|
||||
@ -56,8 +56,8 @@ type appMessageLog struct {
|
||||
ReceiverID field.String // 接收人ID
|
||||
MsgType field.Int32 // 消息类型(1:文本 2:图片)
|
||||
Content field.String // 消息内容
|
||||
IsRead field.Int32 // 是否已读(0:未读 1:已读)
|
||||
CreatedAt field.Time // 创建时间
|
||||
IsRead field.Int32 // 是否已读(0:未读 1:已读)
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@ -83,6 +83,7 @@ func (a *appMessageLog) updateTableName(table string) *appMessageLog {
|
||||
a.MsgType = field.NewInt32(table, "msg_type")
|
||||
a.Content = field.NewString(table, "content")
|
||||
a.CreatedAt = field.NewTime(table, "created_at")
|
||||
a.IsRead = field.NewInt32(table, "is_read")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
@ -108,8 +109,8 @@ func (a *appMessageLog) fillFieldMap() {
|
||||
a.fieldMap["receiver_id"] = a.ReceiverID
|
||||
a.fieldMap["msg_type"] = a.MsgType
|
||||
a.fieldMap["content"] = a.Content
|
||||
a.fieldMap["is_read"] = a.IsRead
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["is_read"] = a.IsRead
|
||||
}
|
||||
|
||||
func (a appMessageLog) clone(db *gorm.DB) appMessageLog {
|
||||
|
||||
@ -25,6 +25,7 @@ var (
|
||||
LogOperation *logOperation
|
||||
LogRequest *logRequest
|
||||
MiniProgram *miniProgram
|
||||
MiniProgramAccessToken *miniProgramAccessToken
|
||||
)
|
||||
|
||||
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
@ -37,48 +38,52 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
LogOperation = &Q.LogOperation
|
||||
LogRequest = &Q.LogRequest
|
||||
MiniProgram = &Q.MiniProgram
|
||||
MiniProgramAccessToken = &Q.MiniProgramAccessToken
|
||||
}
|
||||
|
||||
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Admin: newAdmin(db, opts...),
|
||||
AppKeyword: newAppKeyword(db, opts...),
|
||||
AppKeywordReply: newAppKeywordReply(db, opts...),
|
||||
AppMessageLog: newAppMessageLog(db, opts...),
|
||||
AppUser: newAppUser(db, opts...),
|
||||
LogOperation: newLogOperation(db, opts...),
|
||||
LogRequest: newLogRequest(db, opts...),
|
||||
MiniProgram: newMiniProgram(db, opts...),
|
||||
db: db,
|
||||
Admin: newAdmin(db, opts...),
|
||||
AppKeyword: newAppKeyword(db, opts...),
|
||||
AppKeywordReply: newAppKeywordReply(db, opts...),
|
||||
AppMessageLog: newAppMessageLog(db, opts...),
|
||||
AppUser: newAppUser(db, opts...),
|
||||
LogOperation: newLogOperation(db, opts...),
|
||||
LogRequest: newLogRequest(db, opts...),
|
||||
MiniProgram: newMiniProgram(db, opts...),
|
||||
MiniProgramAccessToken: newMiniProgramAccessToken(db, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
db *gorm.DB
|
||||
|
||||
Admin admin
|
||||
AppKeyword appKeyword
|
||||
AppKeywordReply appKeywordReply
|
||||
AppMessageLog appMessageLog
|
||||
AppUser appUser
|
||||
LogOperation logOperation
|
||||
LogRequest logRequest
|
||||
MiniProgram miniProgram
|
||||
Admin admin
|
||||
AppKeyword appKeyword
|
||||
AppKeywordReply appKeywordReply
|
||||
AppMessageLog appMessageLog
|
||||
AppUser appUser
|
||||
LogOperation logOperation
|
||||
LogRequest logRequest
|
||||
MiniProgram miniProgram
|
||||
MiniProgramAccessToken miniProgramAccessToken
|
||||
}
|
||||
|
||||
func (q *Query) Available() bool { return q.db != nil }
|
||||
|
||||
func (q *Query) clone(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Admin: q.Admin.clone(db),
|
||||
AppKeyword: q.AppKeyword.clone(db),
|
||||
AppKeywordReply: q.AppKeywordReply.clone(db),
|
||||
AppMessageLog: q.AppMessageLog.clone(db),
|
||||
AppUser: q.AppUser.clone(db),
|
||||
LogOperation: q.LogOperation.clone(db),
|
||||
LogRequest: q.LogRequest.clone(db),
|
||||
MiniProgram: q.MiniProgram.clone(db),
|
||||
db: db,
|
||||
Admin: q.Admin.clone(db),
|
||||
AppKeyword: q.AppKeyword.clone(db),
|
||||
AppKeywordReply: q.AppKeywordReply.clone(db),
|
||||
AppMessageLog: q.AppMessageLog.clone(db),
|
||||
AppUser: q.AppUser.clone(db),
|
||||
LogOperation: q.LogOperation.clone(db),
|
||||
LogRequest: q.LogRequest.clone(db),
|
||||
MiniProgram: q.MiniProgram.clone(db),
|
||||
MiniProgramAccessToken: q.MiniProgramAccessToken.clone(db),
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,49 +97,52 @@ func (q *Query) WriteDB() *Query {
|
||||
|
||||
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Admin: q.Admin.replaceDB(db),
|
||||
AppKeyword: q.AppKeyword.replaceDB(db),
|
||||
AppKeywordReply: q.AppKeywordReply.replaceDB(db),
|
||||
AppMessageLog: q.AppMessageLog.replaceDB(db),
|
||||
AppUser: q.AppUser.replaceDB(db),
|
||||
LogOperation: q.LogOperation.replaceDB(db),
|
||||
LogRequest: q.LogRequest.replaceDB(db),
|
||||
MiniProgram: q.MiniProgram.replaceDB(db),
|
||||
db: db,
|
||||
Admin: q.Admin.replaceDB(db),
|
||||
AppKeyword: q.AppKeyword.replaceDB(db),
|
||||
AppKeywordReply: q.AppKeywordReply.replaceDB(db),
|
||||
AppMessageLog: q.AppMessageLog.replaceDB(db),
|
||||
AppUser: q.AppUser.replaceDB(db),
|
||||
LogOperation: q.LogOperation.replaceDB(db),
|
||||
LogRequest: q.LogRequest.replaceDB(db),
|
||||
MiniProgram: q.MiniProgram.replaceDB(db),
|
||||
MiniProgramAccessToken: q.MiniProgramAccessToken.replaceDB(db),
|
||||
}
|
||||
}
|
||||
|
||||
type queryCtx struct {
|
||||
Admin *adminDo
|
||||
AppKeyword *appKeywordDo
|
||||
AppKeywordReply *appKeywordReplyDo
|
||||
AppMessageLog *appMessageLogDo
|
||||
AppUser *appUserDo
|
||||
LogOperation *logOperationDo
|
||||
LogRequest *logRequestDo
|
||||
MiniProgram *miniProgramDo
|
||||
Admin *adminDo
|
||||
AppKeyword *appKeywordDo
|
||||
AppKeywordReply *appKeywordReplyDo
|
||||
AppMessageLog *appMessageLogDo
|
||||
AppUser *appUserDo
|
||||
LogOperation *logOperationDo
|
||||
LogRequest *logRequestDo
|
||||
MiniProgram *miniProgramDo
|
||||
MiniProgramAccessToken *miniProgramAccessTokenDo
|
||||
}
|
||||
|
||||
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
return &queryCtx{
|
||||
Admin: q.Admin.WithContext(ctx),
|
||||
AppKeyword: q.AppKeyword.WithContext(ctx),
|
||||
AppKeywordReply: q.AppKeywordReply.WithContext(ctx),
|
||||
AppMessageLog: q.AppMessageLog.WithContext(ctx),
|
||||
AppUser: q.AppUser.WithContext(ctx),
|
||||
LogOperation: q.LogOperation.WithContext(ctx),
|
||||
LogRequest: q.LogRequest.WithContext(ctx),
|
||||
MiniProgram: q.MiniProgram.WithContext(ctx),
|
||||
Admin: q.Admin.WithContext(ctx),
|
||||
AppKeyword: q.AppKeyword.WithContext(ctx),
|
||||
AppKeywordReply: q.AppKeywordReply.WithContext(ctx),
|
||||
AppMessageLog: q.AppMessageLog.WithContext(ctx),
|
||||
AppUser: q.AppUser.WithContext(ctx),
|
||||
LogOperation: q.LogOperation.WithContext(ctx),
|
||||
LogRequest: q.LogRequest.WithContext(ctx),
|
||||
MiniProgram: q.MiniProgram.WithContext(ctx),
|
||||
MiniProgramAccessToken: q.MiniProgramAccessToken.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
|
||||
return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.ReplaceDB(tx)) }, opts...)
|
||||
return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
|
||||
}
|
||||
|
||||
func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
|
||||
tx := q.db.Begin(opts...)
|
||||
return &QueryTx{Query: q.ReplaceDB(tx), Error: tx.Error}
|
||||
return &QueryTx{Query: q.clone(tx), Error: tx.Error}
|
||||
}
|
||||
|
||||
type QueryTx struct {
|
||||
|
||||
336
internal/repository/mysql/dao/mini_program_access_token.gen.go
Normal file
336
internal/repository/mysql/dao/mini_program_access_token.gen.go
Normal file
@ -0,0 +1,336 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"mini-chat/internal/repository/mysql/model"
|
||||
)
|
||||
|
||||
func newMiniProgramAccessToken(db *gorm.DB, opts ...gen.DOOption) miniProgramAccessToken {
|
||||
_miniProgramAccessToken := miniProgramAccessToken{}
|
||||
|
||||
_miniProgramAccessToken.miniProgramAccessTokenDo.UseDB(db, opts...)
|
||||
_miniProgramAccessToken.miniProgramAccessTokenDo.UseModel(&model.MiniProgramAccessToken{})
|
||||
|
||||
tableName := _miniProgramAccessToken.miniProgramAccessTokenDo.TableName()
|
||||
_miniProgramAccessToken.ALL = field.NewAsterisk(tableName)
|
||||
_miniProgramAccessToken.ID = field.NewInt32(tableName, "id")
|
||||
_miniProgramAccessToken.AppID = field.NewString(tableName, "app_id")
|
||||
_miniProgramAccessToken.AccessToken = field.NewString(tableName, "access_token")
|
||||
_miniProgramAccessToken.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_miniProgramAccessToken.ExpiredAt = field.NewTime(tableName, "expired_at")
|
||||
|
||||
_miniProgramAccessToken.fillFieldMap()
|
||||
|
||||
return _miniProgramAccessToken
|
||||
}
|
||||
|
||||
// miniProgramAccessToken 小程序 access_token 表
|
||||
type miniProgramAccessToken struct {
|
||||
miniProgramAccessTokenDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int32 // 主键
|
||||
AppID field.String // app_id
|
||||
AccessToken field.String // access_token
|
||||
CreatedAt field.Time // 创建时间
|
||||
ExpiredAt field.Time // 过期时间
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (m miniProgramAccessToken) Table(newTableName string) *miniProgramAccessToken {
|
||||
m.miniProgramAccessTokenDo.UseTable(newTableName)
|
||||
return m.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessToken) As(alias string) *miniProgramAccessToken {
|
||||
m.miniProgramAccessTokenDo.DO = *(m.miniProgramAccessTokenDo.As(alias).(*gen.DO))
|
||||
return m.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (m *miniProgramAccessToken) updateTableName(table string) *miniProgramAccessToken {
|
||||
m.ALL = field.NewAsterisk(table)
|
||||
m.ID = field.NewInt32(table, "id")
|
||||
m.AppID = field.NewString(table, "app_id")
|
||||
m.AccessToken = field.NewString(table, "access_token")
|
||||
m.CreatedAt = field.NewTime(table, "created_at")
|
||||
m.ExpiredAt = field.NewTime(table, "expired_at")
|
||||
|
||||
m.fillFieldMap()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *miniProgramAccessToken) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := m.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (m *miniProgramAccessToken) fillFieldMap() {
|
||||
m.fieldMap = make(map[string]field.Expr, 5)
|
||||
m.fieldMap["id"] = m.ID
|
||||
m.fieldMap["app_id"] = m.AppID
|
||||
m.fieldMap["access_token"] = m.AccessToken
|
||||
m.fieldMap["created_at"] = m.CreatedAt
|
||||
m.fieldMap["expired_at"] = m.ExpiredAt
|
||||
}
|
||||
|
||||
func (m miniProgramAccessToken) clone(db *gorm.DB) miniProgramAccessToken {
|
||||
m.miniProgramAccessTokenDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m miniProgramAccessToken) replaceDB(db *gorm.DB) miniProgramAccessToken {
|
||||
m.miniProgramAccessTokenDo.ReplaceDB(db)
|
||||
return m
|
||||
}
|
||||
|
||||
type miniProgramAccessTokenDo struct{ gen.DO }
|
||||
|
||||
func (m miniProgramAccessTokenDo) Debug() *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Debug())
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) WithContext(ctx context.Context) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) ReadDB() *miniProgramAccessTokenDo {
|
||||
return m.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) WriteDB() *miniProgramAccessTokenDo {
|
||||
return m.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Session(config *gorm.Session) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Session(config))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Clauses(conds ...clause.Expression) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Returning(value interface{}, columns ...string) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Not(conds ...gen.Condition) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Or(conds ...gen.Condition) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Select(conds ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Where(conds ...gen.Condition) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Order(conds ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Distinct(cols ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Omit(cols ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Join(table schema.Tabler, on ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) LeftJoin(table schema.Tabler, on ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) RightJoin(table schema.Tabler, on ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Group(cols ...field.Expr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Having(conds ...gen.Condition) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Limit(limit int) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Offset(offset int) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Unscoped() *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Create(values ...*model.MiniProgramAccessToken) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return m.DO.Create(values)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) CreateInBatches(values []*model.MiniProgramAccessToken, batchSize int) error {
|
||||
return m.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (m miniProgramAccessTokenDo) Save(values ...*model.MiniProgramAccessToken) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return m.DO.Save(values)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) First() (*model.MiniProgramAccessToken, error) {
|
||||
if result, err := m.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.MiniProgramAccessToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Take() (*model.MiniProgramAccessToken, error) {
|
||||
if result, err := m.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.MiniProgramAccessToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Last() (*model.MiniProgramAccessToken, error) {
|
||||
if result, err := m.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.MiniProgramAccessToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Find() ([]*model.MiniProgramAccessToken, error) {
|
||||
result, err := m.DO.Find()
|
||||
return result.([]*model.MiniProgramAccessToken), err
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.MiniProgramAccessToken, err error) {
|
||||
buf := make([]*model.MiniProgramAccessToken, 0, batchSize)
|
||||
err = m.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) FindInBatches(result *[]*model.MiniProgramAccessToken, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return m.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Attrs(attrs ...field.AssignExpr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Assign(attrs ...field.AssignExpr) *miniProgramAccessTokenDo {
|
||||
return m.withDO(m.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Joins(fields ...field.RelationField) *miniProgramAccessTokenDo {
|
||||
for _, _f := range fields {
|
||||
m = *m.withDO(m.DO.Joins(_f))
|
||||
}
|
||||
return &m
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Preload(fields ...field.RelationField) *miniProgramAccessTokenDo {
|
||||
for _, _f := range fields {
|
||||
m = *m.withDO(m.DO.Preload(_f))
|
||||
}
|
||||
return &m
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) FirstOrInit() (*model.MiniProgramAccessToken, error) {
|
||||
if result, err := m.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.MiniProgramAccessToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) FirstOrCreate() (*model.MiniProgramAccessToken, error) {
|
||||
if result, err := m.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.MiniProgramAccessToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) FindByPage(offset int, limit int) (result []*model.MiniProgramAccessToken, count int64, err error) {
|
||||
result, err = m.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = m.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = m.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = m.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Scan(result interface{}) (err error) {
|
||||
return m.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (m miniProgramAccessTokenDo) Delete(models ...*model.MiniProgramAccessToken) (result gen.ResultInfo, err error) {
|
||||
return m.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (m *miniProgramAccessTokenDo) withDO(do gen.Dao) *miniProgramAccessTokenDo {
|
||||
m.DO = *do.(*gen.DO)
|
||||
return m
|
||||
}
|
||||
@ -20,8 +20,8 @@ type AppMessageLog struct {
|
||||
ReceiverID string `gorm:"column:receiver_id;not null;comment:接收人ID" json:"receiver_id"` // 接收人ID
|
||||
MsgType int32 `gorm:"column:msg_type;not null;comment:消息类型(1:文本 2:图片)" json:"msg_type"` // 消息类型(1:文本 2:图片)
|
||||
Content string `gorm:"column:content;not null;comment:消息内容" json:"content"` // 消息内容
|
||||
IsRead int32 `gorm:"column:is_read;not null;default:0;comment:是否已读(0:未读 1:已读)" json:"is_read"` // 是否已读(0:未读 1:已读)
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
||||
IsRead int32 `gorm:"column:is_read;comment:是否已读(0:未读 1:已读)" json:"is_read"` // 是否已读(0:未读 1:已读)
|
||||
}
|
||||
|
||||
// TableName AppMessageLog's table name
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TableNameMiniProgramAccessToken = "mini_program_access_token"
|
||||
|
||||
// MiniProgramAccessToken 小程序 access_token 表
|
||||
type MiniProgramAccessToken struct {
|
||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键" json:"id"` // 主键
|
||||
AppID string `gorm:"column:app_id;not null;comment:app_id" json:"app_id"` // app_id
|
||||
AccessToken string `gorm:"column:access_token;not null;comment:access_token" json:"access_token"` // access_token
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
||||
ExpiredAt time.Time `gorm:"column:expired_at;not null;default:CURRENT_TIMESTAMP;comment:过期时间" json:"expired_at"` // 过期时间
|
||||
}
|
||||
|
||||
// TableName MiniProgramAccessToken's table name
|
||||
func (*MiniProgramAccessToken) TableName() string {
|
||||
return TableNameMiniProgramAccessToken
|
||||
}
|
||||
32
internal/services/services_miniprogram/miniprogram.go
Normal file
32
internal/services/services_miniprogram/miniprogram.go
Normal file
@ -0,0 +1,32 @@
|
||||
package services_miniprogram
|
||||
|
||||
import (
|
||||
"mini-chat/internal/pkg/core"
|
||||
"mini-chat/internal/pkg/logger"
|
||||
"mini-chat/internal/repository/mysql"
|
||||
"mini-chat/internal/repository/mysql/dao"
|
||||
)
|
||||
|
||||
var _ Service = (*service)(nil)
|
||||
|
||||
type Service interface {
|
||||
i()
|
||||
|
||||
GetAccessToken(appID, appSecret string, ctx core.Context) (string, error)
|
||||
}
|
||||
|
||||
type service struct {
|
||||
logger logger.CustomLogger
|
||||
writeDB *dao.Query
|
||||
readDB *dao.Query
|
||||
}
|
||||
|
||||
func New(logger logger.CustomLogger, db mysql.Repo) Service {
|
||||
return &service{
|
||||
logger: logger,
|
||||
writeDB: dao.Use(db.GetDbW()),
|
||||
readDB: dao.Use(db.GetDbR()),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) i() {}
|
||||
@ -0,0 +1,53 @@
|
||||
package services_miniprogram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"mini-chat/internal/pkg/core"
|
||||
"mini-chat/internal/pkg/miniprogram"
|
||||
"mini-chat/internal/repository/mysql/model"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (s *service) GetAccessToken(appID, appSecret string, ctx core.Context) (string, error) {
|
||||
info, err := s.readDB.MiniProgramAccessToken.WithContext(ctx.RequestContext()).
|
||||
Where(s.readDB.MiniProgramAccessToken.AppID.Eq(appID)).
|
||||
Where(s.readDB.MiniProgramAccessToken.ExpiredAt.Gte(time.Now())).First()
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return "", err
|
||||
}
|
||||
|
||||
accessToken := ""
|
||||
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// 生成 access_token
|
||||
accessTokenResponse := new(miniprogram.AccessTokenResponse)
|
||||
if err := miniprogram.GetAccessToken(appID, appSecret, accessTokenResponse); err != nil {
|
||||
s.logger.Error("GetAccessToken failed", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if accessTokenResponse.AccessToken == "" {
|
||||
return "", fmt.Errorf("access_token is empty")
|
||||
}
|
||||
|
||||
// 保存 access_token
|
||||
accessTokenData := new(model.MiniProgramAccessToken)
|
||||
accessTokenData.AppID = appID
|
||||
accessTokenData.AccessToken = accessTokenResponse.AccessToken
|
||||
accessTokenData.CreatedAt = time.Now()
|
||||
accessTokenData.ExpiredAt = time.Now().Add(time.Duration(accessTokenResponse.ExpiresIn) * time.Second)
|
||||
if err := s.writeDB.MiniProgramAccessToken.WithContext(ctx.RequestContext()).Create(accessTokenData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
accessToken = accessTokenResponse.AccessToken
|
||||
} else {
|
||||
accessToken = info.AccessToken
|
||||
}
|
||||
|
||||
return accessToken, nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user