85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
package dao
|
||
|
||
import (
|
||
"database/sql"
|
||
"fmt"
|
||
|
||
"dd_fiber_api/pkg/database"
|
||
|
||
"github.com/didi/gendry/builder"
|
||
)
|
||
|
||
// AccessSource 访问来源
|
||
type AccessSource string
|
||
|
||
const (
|
||
AccessSourcePurchase AccessSource = "PURCHASE" // 购买获得
|
||
AccessSourceGrant AccessSource = "GRANT" // 系统或人工授权
|
||
)
|
||
|
||
// UserSectionAccessDAO 用户小节访问记录 DAO
|
||
type UserSectionAccessDAO struct {
|
||
client *database.MySQLClient
|
||
}
|
||
|
||
// NewUserSectionAccessDAO 创建用户小节访问记录 DAO
|
||
func NewUserSectionAccessDAO(client *database.MySQLClient) *UserSectionAccessDAO {
|
||
return &UserSectionAccessDAO{client: client}
|
||
}
|
||
|
||
// GetByUserAndSection 查询用户是否已拥有某个小节的访问权限
|
||
func (d *UserSectionAccessDAO) GetByUserAndSection(userID, sectionID string) (bool, error) {
|
||
table := "camp_user_section_access"
|
||
where := map[string]any{
|
||
"user_id": userID,
|
||
"section_id": sectionID,
|
||
}
|
||
cond, vals, err := builder.BuildSelect(table, where, []string{"id"})
|
||
if err != nil {
|
||
return false, fmt.Errorf("构建查询失败: %v", err)
|
||
}
|
||
var id string
|
||
err = d.client.DB.QueryRow(cond, vals...).Scan(&id)
|
||
if err == sql.ErrNoRows {
|
||
return false, nil
|
||
}
|
||
if err != nil {
|
||
return false, fmt.Errorf("查询访问记录失败: %v", err)
|
||
}
|
||
return true, nil
|
||
}
|
||
|
||
// Create 创建访问记录(简化版本,只保留访问权限相关字段)
|
||
// 订单相关信息可以从 orders 表查询,不需要冗余存储
|
||
func (d *UserSectionAccessDAO) Create(
|
||
id, userID, campID, sectionID string,
|
||
paidPriceFen int32,
|
||
accessSource AccessSource,
|
||
) error {
|
||
table := "camp_user_section_access"
|
||
|
||
data := []map[string]any{{
|
||
"id": id,
|
||
"user_id": userID,
|
||
"camp_id": campID,
|
||
"section_id": sectionID,
|
||
"paid_price_fen": paidPriceFen,
|
||
"access_source": string(accessSource),
|
||
}}
|
||
|
||
cond, vals, err := builder.BuildInsert(table, data)
|
||
if err != nil {
|
||
return fmt.Errorf("构建插入失败: %v", err)
|
||
}
|
||
|
||
// 使用 ON DUPLICATE KEY UPDATE 实现幂等性
|
||
// 如果已存在,只更新 paid_price_fen 和 access_source(避免重复插入)
|
||
cond += " ON DUPLICATE KEY UPDATE paid_price_fen=VALUES(paid_price_fen), access_source=VALUES(access_source)"
|
||
|
||
if _, err := d.client.DB.Exec(cond, vals...); err != nil {
|
||
return fmt.Errorf("创建访问记录失败: %v", err)
|
||
}
|
||
return nil
|
||
}
|
||
|