migrate from github

This commit is contained in:
2026-07-15 22:42:31 +08:00
commit 3ad559f05e
262 changed files with 21637 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
package invitation_repo
import (
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type InvitationGetByIDOperation struct {
repo *InvitationRepository
id int64
tx *gorm.DB
}
func (r *InvitationRepository) GetByID(id int64) *InvitationGetByIDOperation {
return &InvitationGetByIDOperation{
repo: r,
id: id,
}
}
func (op *InvitationGetByIDOperation) WithTx(tx *gorm.DB) *InvitationGetByIDOperation {
op.tx = tx
return op
}
func (op *InvitationGetByIDOperation) Exec() (*model.Invitation, error) {
var invitation model.Invitation
var err error
if op.tx != nil {
err = op.tx.First(&invitation, op.id).Error
} else {
err = op.repo.db.First(&invitation, op.id).Error
}
return &invitation, err
}
type InvitationCreateOperation struct {
repo *InvitationRepository
invitation *model.Invitation
tx *gorm.DB
}
func (r *InvitationRepository) Create(invitation *model.Invitation) *InvitationCreateOperation {
return &InvitationCreateOperation{
repo: r,
invitation: invitation,
}
}
func (op *InvitationCreateOperation) WithTx(tx *gorm.DB) *InvitationCreateOperation {
op.tx = tx
return op
}
func (op *InvitationCreateOperation) Exec() error {
if op.tx != nil {
return op.tx.Create(op.invitation).Error
}
return op.repo.db.Create(op.invitation).Error
}
type InvitationUpdateOperation struct {
repo *InvitationRepository
invitation *model.Invitation
tx *gorm.DB
}
func (r *InvitationRepository) Update(invitation *model.Invitation) *InvitationUpdateOperation {
return &InvitationUpdateOperation{
repo: r,
invitation: invitation,
}
}
func (op *InvitationUpdateOperation) WithTx(tx *gorm.DB) *InvitationUpdateOperation {
op.tx = tx
return op
}
func (op *InvitationUpdateOperation) Exec() error {
if op.tx != nil {
return op.tx.Save(op.invitation).Error
}
return op.repo.db.Save(op.invitation).Error
}
type InvitationDeleteOperation struct {
repo *InvitationRepository
id int64
tx *gorm.DB
}
func (r *InvitationRepository) Delete(id int64) *InvitationDeleteOperation {
return &InvitationDeleteOperation{
repo: r,
id: id,
}
}
func (op *InvitationDeleteOperation) WithTx(tx *gorm.DB) *InvitationDeleteOperation {
op.tx = tx
return op
}
func (op *InvitationDeleteOperation) Exec() error {
if op.tx == nil {
op.tx = op.repo.db
}
return op.tx.Delete(&model.Invitation{}, op.id).Error
}
@@ -0,0 +1,37 @@
package invitation_repo
import (
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type InvitationGetByCodeOperation struct {
repo *InvitationRepository
code string
tx *gorm.DB
}
func (r *InvitationRepository) GetByCode(code string) *InvitationGetByCodeOperation {
return &InvitationGetByCodeOperation{
repo: r,
code: code,
}
}
func (op *InvitationGetByCodeOperation) WithTx(tx *gorm.DB) *InvitationGetByCodeOperation {
op.tx = tx
return op
}
func (op *InvitationGetByCodeOperation) Exec() (*model.Invitation, error) {
var invitation model.Invitation
var err error
if op.tx != nil {
err = op.tx.Where("code = ?", op.code).First(&invitation).Error
} else {
err = op.repo.db.Where("code = ?", op.code).First(&invitation).Error
}
return &invitation, err
}
@@ -0,0 +1,11 @@
package invitation_repo
import "gorm.io/gorm"
type InvitationRepository struct {
db *gorm.DB
}
func NewInvitationRepository(db *gorm.DB) *InvitationRepository {
return &InvitationRepository{db: db}
}
+234
View File
@@ -0,0 +1,234 @@
package invitation_repo
import (
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type InvitationListOperation struct {
repo *InvitationRepository
m *model.Invitation
creatorID *int64
keyword *string
maxUsedCnt *int64
expiresAtStart *string
expiresAtEnd *string
createdAtStart *string
createdAtEnd *string
disabled *bool
sortField string
sortDesc bool
page int
pageSize int
tx *gorm.DB
}
func (r *InvitationRepository) List(m *model.Invitation) *InvitationListOperation {
return &InvitationListOperation{
repo: r,
m: m,
}
}
func (op *InvitationListOperation) WithTx(tx *gorm.DB) *InvitationListOperation {
op.tx = tx
return op
}
func (op *InvitationListOperation) WithCreatorID(creatorID *int64) *InvitationListOperation {
op.creatorID = creatorID
return op
}
func (op *InvitationListOperation) WithKeyword(keyword *string) *InvitationListOperation {
op.keyword = keyword
return op
}
func (op *InvitationListOperation) WithMaxUsedCnt(maxUsedCnt *int64) *InvitationListOperation {
op.maxUsedCnt = maxUsedCnt
return op
}
func (op *InvitationListOperation) WithExpiresAtRange(start, end *string) *InvitationListOperation {
op.expiresAtStart = start
op.expiresAtEnd = end
return op
}
func (op *InvitationListOperation) WithCreatedAtRange(start, end *string) *InvitationListOperation {
op.createdAtStart = start
op.createdAtEnd = end
return op
}
func (op *InvitationListOperation) WithDisabled(disabled *bool) *InvitationListOperation {
op.disabled = disabled
return op
}
func (op *InvitationListOperation) WithSort(field string, desc bool) *InvitationListOperation {
op.sortField = field
op.sortDesc = desc
return op
}
func (op *InvitationListOperation) WithPagination(page, pageSize int) *InvitationListOperation {
op.page = page
op.pageSize = pageSize
return op
}
func (op *InvitationListOperation) Exec() ([]model.Invitation, error) {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
dbQuery := db.Model(&model.Invitation{})
if op.m != nil {
dbQuery = dbQuery.Where(op.m)
}
if op.creatorID != nil {
dbQuery = dbQuery.Where("created_by = ?", *op.creatorID)
}
if op.keyword != nil && *op.keyword != "" {
dbQuery = dbQuery.Where("code ILIKE ?", "%"+*op.keyword+"%")
}
if op.maxUsedCnt != nil {
dbQuery = dbQuery.Where("max_used_cnt = ?", *op.maxUsedCnt)
}
if op.expiresAtStart != nil && *op.expiresAtStart != "" {
dbQuery = dbQuery.Where("expires_at >= ?", *op.expiresAtStart)
}
if op.expiresAtEnd != nil && *op.expiresAtEnd != "" {
dbQuery = dbQuery.Where("expires_at <= ?", *op.expiresAtEnd)
}
if op.createdAtStart != nil && *op.createdAtStart != "" {
dbQuery = dbQuery.Where("created_at >= ?", *op.createdAtStart)
}
if op.createdAtEnd != nil && *op.createdAtEnd != "" {
dbQuery = dbQuery.Where("created_at <= ?", *op.createdAtEnd)
}
if op.disabled != nil {
dbQuery = dbQuery.Where("disabled = ?", *op.disabled)
}
sortField := op.sortField
if sortField == "" {
sortField = "created_at"
}
orderDirection := "ASC"
if op.sortDesc {
orderDirection = "DESC"
}
dbQuery = dbQuery.Order(sortField + " " + orderDirection)
page := op.page
pageSize := op.pageSize
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
if pageSize > 100 {
pageSize = 100
}
offset := (page - 1) * pageSize
dbQuery = dbQuery.Offset(offset).Limit(pageSize)
var invitations []model.Invitation
err := dbQuery.Find(&invitations).Error
if err != nil {
return nil, err
}
return invitations, nil
}
func (op *InvitationListOperation) ExecWithTotal() ([]model.Invitation, int64, error) {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
dbQuery := db.Model(&model.Invitation{})
if op.m != nil {
dbQuery = dbQuery.Where(op.m)
}
if op.creatorID != nil {
dbQuery = dbQuery.Where("created_by = ?", *op.creatorID)
}
if op.keyword != nil && *op.keyword != "" {
dbQuery = dbQuery.Where("code ILIKE ?", "%"+*op.keyword+"%")
}
if op.maxUsedCnt != nil {
dbQuery = dbQuery.Where("max_used_cnt = ?", *op.maxUsedCnt)
}
if op.expiresAtStart != nil && *op.expiresAtStart != "" {
dbQuery = dbQuery.Where("expires_at >= ?", *op.expiresAtStart)
}
if op.expiresAtEnd != nil && *op.expiresAtEnd != "" {
dbQuery = dbQuery.Where("expires_at <= ?", *op.expiresAtEnd)
}
if op.createdAtStart != nil && *op.createdAtStart != "" {
dbQuery = dbQuery.Where("created_at >= ?", *op.createdAtStart)
}
if op.createdAtEnd != nil && *op.createdAtEnd != "" {
dbQuery = dbQuery.Where("created_at <= ?", *op.createdAtEnd)
}
if op.disabled != nil {
dbQuery = dbQuery.Where("disabled = ?", *op.disabled)
}
var total int64
err := dbQuery.Count(&total).Error
if err != nil {
return nil, 0, err
}
sortField := op.sortField
if sortField == "" {
sortField = "created_at"
}
orderDirection := "ASC"
if op.sortDesc {
orderDirection = "DESC"
}
dbQuery = dbQuery.Order(sortField + " " + orderDirection)
page := op.page
pageSize := op.pageSize
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
if pageSize > 100 {
pageSize = 100
}
offset := (page - 1) * pageSize
dbQuery = dbQuery.Offset(offset).Limit(pageSize)
var invitations []model.Invitation
err = dbQuery.Find(&invitations).Error
if err != nil {
return nil, 0, err
}
return invitations, total, nil
}
@@ -0,0 +1,142 @@
package invitation_repo
import (
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type InvitationRecordCreateOperation struct {
repo *InvitationRepository
record *model.InvitationRecord
tx *gorm.DB
}
func (r *InvitationRepository) CreateRecord(record *model.InvitationRecord) *InvitationRecordCreateOperation {
return &InvitationRecordCreateOperation{
repo: r,
record: record,
}
}
func (op *InvitationRecordCreateOperation) WithTx(tx *gorm.DB) *InvitationRecordCreateOperation {
op.tx = tx
return op
}
func (op *InvitationRecordCreateOperation) Exec() error {
if op.tx != nil {
return op.tx.Create(op.record).Error
}
return op.repo.db.Create(op.record).Error
}
type InvitationRecordListOperation struct {
repo *InvitationRepository
code *string
status *string
usedAtStart *string
usedAtEnd *string
creatorID *int64
keyword *string
page int
pageSize int
tx *gorm.DB
}
func (r *InvitationRepository) ListRecords() *InvitationRecordListOperation {
return &InvitationRecordListOperation{
repo: r,
}
}
func (op *InvitationRecordListOperation) WithTx(tx *gorm.DB) *InvitationRecordListOperation {
op.tx = tx
return op
}
func (op *InvitationRecordListOperation) WithCode(code *string) *InvitationRecordListOperation {
op.code = code
return op
}
func (op *InvitationRecordListOperation) WithStatus(status *string) *InvitationRecordListOperation {
op.status = status
return op
}
func (op *InvitationRecordListOperation) WithUsedAtRange(start, end *string) *InvitationRecordListOperation {
op.usedAtStart = start
op.usedAtEnd = end
return op
}
func (op *InvitationRecordListOperation) WithCreatorID(creatorID *int64) *InvitationRecordListOperation {
op.creatorID = creatorID
return op
}
func (op *InvitationRecordListOperation) WithKeyword(keyword *string) *InvitationRecordListOperation {
op.keyword = keyword
return op
}
func (op *InvitationRecordListOperation) WithPagination(page, pageSize int) *InvitationRecordListOperation {
op.page = page
op.pageSize = pageSize
return op
}
func (op *InvitationRecordListOperation) ExecWithTotal() ([]model.InvitationRecord, int64, error) {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
query := db.Model(&model.InvitationRecord{})
if op.creatorID != nil {
query = query.Joins("JOIN invitations ON invitations.code = invitation_records.code").
Where("invitations.created_by = ?", *op.creatorID)
}
if op.code != nil && *op.code != "" {
query = query.Where("code = ?", *op.code)
}
if op.keyword != nil && *op.keyword != "" {
keyword := "%" + *op.keyword + "%"
query = query.Where("invitation_records.code ILIKE ? OR invitation_records.used_by ILIKE ?", keyword, keyword)
}
if op.status != nil && *op.status != "" {
query = query.Where("status = ?", *op.status)
}
if op.usedAtStart != nil && *op.usedAtStart != "" {
query = query.Where("used_at >= ?", *op.usedAtStart)
}
if op.usedAtEnd != nil && *op.usedAtEnd != "" {
query = query.Where("used_at <= ?", *op.usedAtEnd)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
page := op.page
pageSize := op.pageSize
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
if pageSize > 200 {
pageSize = 200
}
offset := (page - 1) * pageSize
query = query.Order("used_at DESC").Offset(offset).Limit(pageSize)
var records []model.InvitationRecord
if err := query.Find(&records).Error; err != nil {
return nil, 0, err
}
return records, total, nil
}
@@ -0,0 +1,48 @@
package invitation_repo
import (
"time"
"github.com/XingfenD/yoresee_doc/internal/model"
"gorm.io/gorm"
)
type InvitationValidateAndUseOperation struct {
repo *InvitationRepository
code string
tx *gorm.DB
}
func (r *InvitationRepository) ValidateAndUse(code string) *InvitationValidateAndUseOperation {
return &InvitationValidateAndUseOperation{
repo: r,
code: code,
}
}
func (op *InvitationValidateAndUseOperation) WithTx(tx *gorm.DB) *InvitationValidateAndUseOperation {
op.tx = tx
return op
}
func (op *InvitationValidateAndUseOperation) Exec() (bool, error) {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
now := time.Now()
result := db.Model(&model.Invitation{}).
Where("code = ? AND deleted_at IS NULL AND disabled = ?", op.code, false).
Where("(expires_at IS NULL OR expires_at > ?)", now).
Where("(max_used_cnt IS NULL OR used_cnt < max_used_cnt)").
UpdateColumn("used_cnt", gorm.Expr("used_cnt + ?", 1))
if result.Error != nil {
return false, result.Error
}
if result.RowsAffected == 0 {
return false, nil
}
return true, nil
}