Files
req/resource.go
T
what cc3f6d90e7 重构: ResAuthDB 重命名为 ResScope,统一权限过滤范围命名
原名字跟"身份认证"(Auth)容易混淆,实际控制的是资源查询/写入时按角色过滤的范围(关闭/仅自身/含关联资源),改用 Scope 更准确。ResAuthOff/On/All 同步改名为 ResScopeOff/On/All,数值保持不变,兼容数据库里已有的 is_auth_db 存量数据。
2026-07-21 18:00:39 +08:00

150 lines
5.0 KiB
Go
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package req
import (
"reflect"
"git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/exp"
"git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/reflux"
)
type ResDataType string
type ResScope int
const (
// 关闭权限过滤
ResScopeOff ResScope = iota
// 开启权限过滤, 不包括关联资源
ResScopeOn
// 开启权限过滤, 包括关联资源
ResScopeAll
)
const (
ResString ResDataType = "string"
ResText ResDataType = "text"
ResInteger ResDataType = "integer"
ResSmallInteger ResDataType = "smallInteger"
ResDecimal ResDataType = "decimal"
ResBoolean ResDataType = "boolean"
ResJson ResDataType = "json"
ResEnum ResDataType = "enum"
ResTimestamp ResDataType = "timestamp"
ResDate ResDataType = "date"
ResDatetime ResDataType = "dateTime"
ResVector ResDataType = "vector"
)
const (
IsExpr byte = 1 << iota
IsOmitempty
Ignored
)
type Resource interface {
GetUuid() string
GetName() string
GetCode() string
GetDescription() string
GetPrimarykey() string
GetConn() string
GetFields() []ResField
GetField(string) (ResField, bool)
HasField(string) bool
// GetTable 原始表名
GetTable() string
// GetTableExpr 可用于 FROM/JOIN 的表引用表达式
GetTableExpr() exp.LiteralExpression
DB() *db.Database
BeginTransaction() (*db.TxDatabase, error)
GetDBTable(User, ...ResOption) *db.SelectDataset
GetStruct(extends ...reflect.StructField) any
GetSliceStruct(extends ...reflect.StructField) any
// GetHistoryRoles 配置了变更留痕的角色列表,为空表示不留痕
GetHistoryRoles() []string
// 是否虚拟资源
IsVirtual() bool
// 是否系统资源
IsSystem() bool
}
// ResVirtualTable 虚拟表接口,由业务层实现,框架通过 SQLite vtab 机制调用。
// Select 提供列表查询,Fetch 提供单条完整查询(含 Detail 补充字段),
// Insert/Update/Delete 支持写操作并自动同步缓存。
type ResVirtualTable interface {
GetResource() Resource
// Fetch 按主键获取单条完整数据,内部负责调用远端接口并补充 Detail 专属字段。
// 框架在 item cache miss 时调用,结果写入 item cache 供后续查询复用。
Fetch(pk any) (map[string]any, error)
// Detail 对已有的 item 数据进行补充,填充列表接口不返回的详情字段。
// changed=true 时框架会将修改后的数据回写 item cache。
Detail(item reflux.R) (changed bool, err error)
// Select 查询列表数据,filter 为过滤条件,pagesize/page 控制分页。
// 返回的 items 每项为 map[string]anytotal 为总记录数。
Select(filter reflux.R, pagesize, page int) (items []any, total int64, err error)
// Insert 新增一条记录,返回新记录的 rowid。
Insert(item reflux.R) (rowid int64, err error)
// Update 按 rowid 更新记录。
Update(rowid any, item reflux.R) error
// Delete 按 rowid 删除记录。
Delete(rowid any) error
}
// ResVirtualTableSetup 由 framework 在 sqlite_vtable build tag 下注册到容器,负责向 SQLite
// 注册虚拟表模块({res.GetTable()}_mod)。当前由上层在资源缓存构建时提前对所有 vtable 连接的资源
type ResVirtualTableSetup func(res Resource) error
// GetResource 按 code 或 uuid 查找已注册的资源,找不到返回 ok=false。放在 req 而不是 contracts
// 是为了让 req 自己的子包(比如 resource 包)也能通过 DI 拿到查找能力,不用反过来 import
// contractscontracts 依赖 reqimport 反过来会成环)。contracts.GetResource 是它的类型别名,
// 兼容原有引用。
type GetResource func(code string) (Resource, bool)
// MustResource 按 code 或 uuid 查找已注册的资源,找不到时由具体实现负责报错(通常是 panic)。
type MustResource func(code string) Resource
type ResField interface {
GetName() string
GetCode() string
GetCodeResource() string
GetDataType() ResDataType
GetQueryDataType() RouteParamType
GetRawDefault() db.Expression
ToStructField(tags ...string) reflect.StructField
ToValue(any) any
ToBlueprint(table *schema.Blueprint) *schema.ColumnDefinition
ToQueryField(t RouteParamType, alias string, options byte) QueryField
IsVirtual() bool
// GetRoles 配置了"能读写该字段真实值"的角色列表,为空表示不限制(所有角色都能读写真实值);
// 非空时,用户所属角色只要有一个在列表里就有权限,否则:查询时这个字段会被替换成脱敏哨兵值
// (见 resource 包的 MaskFunc),写入时这个字段会被静默丢弃。注意这跟 GetHistoryRoles 等
// "空=没人有权限"的既有约定相反:这是后加的限制能力,必须保证未配置时不影响任何现有字段的
// 读写行为。
GetRoles() []string
}
type QueryField interface {
ResField
Type() RouteParamType
Alias() string
GetCodeOrAlias() string
IsExpr() bool
IsOmitempty() bool
Ignored() bool
SetOptions(byte) QueryField
ToSql() db.Expression
ToStructField(tags ...string) reflect.StructField
}