first commit
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
// Package miniapp 提供被纳管小程序的数据访问。
|
||||
package miniapp
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"portal-mini-go/internal/model"
|
||||
"portal-mini-go/internal/pkg/errors"
|
||||
)
|
||||
|
||||
// Repository 小程序数据访问。
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func New(db *gorm.DB) *Repository { return &Repository{db: db} }
|
||||
|
||||
// Create 新建小程序。AppID 已存在时返回可读业务错误。
|
||||
// 注意:软删除记录仍占用 app_id 唯一索引,故此处一并查软删除态。
|
||||
func (r *Repository) Create(ctx context.Context, m *model.MiniProgram) error {
|
||||
if _, err := r.GetByAppID(ctx, m.AppID); err == nil {
|
||||
return errors.New(40900, "app_id 已存在")
|
||||
} else if !errors.Is(err, errors.ErrNotFound) {
|
||||
return err
|
||||
}
|
||||
if err := r.db.WithContext(ctx).Create(m).Error; err != nil {
|
||||
return errors.Wrap(50000, "create mini program", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update 按 ID 更新小程序非零值字段(cols 为待更新列)。
|
||||
func (r *Repository) Update(ctx context.Context, id uint64, cols map[string]interface{}) error {
|
||||
res := r.db.WithContext(ctx).
|
||||
Model(&model.MiniProgram{}).
|
||||
Where("id = ?", id).
|
||||
Updates(cols)
|
||||
if res.Error != nil {
|
||||
return errors.Wrap(50000, "update mini program", res.Error)
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return errors.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByID 按 ID 查询小程序,软删除记录不可见。
|
||||
func (r *Repository) GetByID(ctx context.Context, id uint64) (*model.MiniProgram, error) {
|
||||
var m model.MiniProgram
|
||||
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&m).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.ErrNotFound
|
||||
}
|
||||
return nil, errors.Wrap(50000, "query mini program", err)
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// GetByAppID 按 AppID 查询(含软删除态),不存在返回 ErrNotFound。
|
||||
// 用于唯一性预校验与按 AppID 取配置。
|
||||
func (r *Repository) GetByAppID(ctx context.Context, appID string) (*model.MiniProgram, error) {
|
||||
var m model.MiniProgram
|
||||
if err := r.db.WithContext(ctx).Unscoped().Where("app_id = ?", appID).First(&m).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.ErrNotFound
|
||||
}
|
||||
return nil, errors.Wrap(50000, "query mini program by app_id", err)
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// GetActiveByAppID 按 AppID 查询“已启用且未删除”的小程序,
|
||||
// 用于登录鉴权与 code2session 取凭证;不存在/已停用/已删除均返回 ErrNotFound。
|
||||
func (r *Repository) GetActiveByAppID(ctx context.Context, appID string) (*model.MiniProgram, error) {
|
||||
var m model.MiniProgram
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("app_id = ? AND status = ?", appID, model.MiniProgramStatusEnabled).
|
||||
First(&m).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.ErrNotFound
|
||||
}
|
||||
return nil, errors.Wrap(50000, "query active mini program", err)
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// List 分页查询,status < 0 表示不过滤。
|
||||
func (r *Repository) List(ctx context.Context, status int8, page, size int) ([]model.MiniProgram, int64, error) {
|
||||
q := r.db.WithContext(ctx).Model(&model.MiniProgram{})
|
||||
if status >= 0 {
|
||||
q = q.Where("status = ?", status)
|
||||
}
|
||||
var total int64
|
||||
if err := q.Count(&total).Error; err != nil {
|
||||
return nil, 0, errors.Wrap(50000, "count mini program", err)
|
||||
}
|
||||
var list []model.MiniProgram
|
||||
if err := q.Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil {
|
||||
return nil, 0, errors.Wrap(50000, "list mini program", err)
|
||||
}
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
// Delete 软删除小程序。
|
||||
func (r *Repository) Delete(ctx context.Context, id uint64) error {
|
||||
res := r.db.WithContext(ctx).Where("id = ?", id).Delete(&model.MiniProgram{})
|
||||
if res.Error != nil {
|
||||
return errors.Wrap(50000, "delete mini program", res.Error)
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return errors.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Package user 提供用户数据访问。所有查询强制按 mini_id 过滤,
|
||||
// 从数据层保证各小程序用户体系相互独立。
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"portal-mini-go/internal/model"
|
||||
"portal-mini-go/internal/pkg/errors"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func New(db *gorm.DB) *Repository { return &Repository{db: db} }
|
||||
|
||||
// UpsertByOpenID 按 mini_id + openid 创建或返回已有用户。
|
||||
func (r *Repository) UpsertByOpenID(ctx context.Context, miniID uint64, openID, unionID, nickname, avatar string) (*model.User, error) {
|
||||
var u model.User
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("mini_id = ? AND openid = ?", miniID, openID).
|
||||
Attrs(model.User{MiniID: miniID, OpenID: openID, UnionID: unionID, Nickname: nickname, Avatar: avatar}).
|
||||
FirstOrCreate(&u).Error
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(50000, "upsert user", err)
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
// GetByID 按 mini_id + id 查询用户,跨小程序查询直接返回未找到。
|
||||
func (r *Repository) GetByID(ctx context.Context, miniID uint64, id uint64) (*model.User, error) {
|
||||
var u model.User
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("mini_id = ? AND id = ?", miniID, id).
|
||||
First(&u).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.ErrNotFound
|
||||
}
|
||||
return nil, errors.Wrap(50000, "query user", err)
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
// UpdateProfile 更新用户资料,限定在 mini_id 范围内。
|
||||
func (r *Repository) UpdateProfile(ctx context.Context, miniID uint64, id uint64, nickname, avatar string) error {
|
||||
res := r.db.WithContext(ctx).
|
||||
Model(&model.User{}).
|
||||
Where("mini_id = ? AND id = ?", miniID, id).
|
||||
Updates(map[string]interface{}{"nickname": nickname, "avatar": avatar})
|
||||
if res.Error != nil {
|
||||
return errors.Wrap(50000, "update user", res.Error)
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return errors.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user