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 }