first commit
This commit is contained in:
42
base/data_list.go
Normal file
42
base/data_list.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataList struct {
|
||||
Uuid string `db:"uuid"`
|
||||
ResourceUuid string `db:"resource_uuid"` // 所属资源UUID
|
||||
Code string `db:"code"` // 列表标识
|
||||
Name string `db:"name"` // 列表名称
|
||||
Title string `db:"title"` // 布局标题
|
||||
PrimaryKey string `db:"primaryKey"` // 主键标识
|
||||
Layout string `db:"layout"` // 主键标识
|
||||
IsOperationColumn bool `db:"isOperationColumn"` // 是否显示操作栏,1是,0否
|
||||
OperationColumnWidth int `db:"operationColumnWidth"` // 操作列宽度
|
||||
IsPaginate bool `db:"isPaginate"` // 是否分页
|
||||
IsTreeData bool `db:"isTreeData"` // 是否使用树形列表
|
||||
TreeDataConfig res_type.ResFieldByMap `db:"treeDataConfig"` // 树形列表配置
|
||||
IsExpandedRow string `db:"isExpandedRow"` // 列表明细控件
|
||||
ExpandedRowConfig res_type.ResFieldByMap `db:"expandedRowConfig"` // 列表明细控件配置
|
||||
IsTreeSider bool `db:"isTreeSider"` // 是否打开侧边栏侧边栏
|
||||
TreeSiderConfig res_type.ResFieldByMap `db:"treeSiderConfig"` // 侧边栏设置
|
||||
IsDynamicRefresh bool `db:"isDynamicRefresh"` // 是否启用动态刷新
|
||||
PageSize int `db:"pagesize"` // 分页大小
|
||||
IsAuxiliaryPanel bool `db:"isAuxiliaryPanel"` // 是否使用附属面板
|
||||
AuxiliaryPanelConfig res_type.ResFieldByMap `db:"auxiliaryPanelConfig"` // 附属面板配置
|
||||
SortConfig res_type.ResFieldByAnys `db:"sortConfig"` // 排序设置
|
||||
FieldsSort res_type.ResFieldByAnys `db:"fieldsSort"` // 字段排序
|
||||
GroupConfig res_type.ResFieldByAnys `db:"groupConfig"` // 分组设置
|
||||
XlsxFieldsSort res_type.ResFieldByAnys `db:"xlsxFieldsSort"` // 字段排序
|
||||
XlsxImportFieldsSort res_type.ResFieldByAnys `db:"xlsxImportFieldsSort"` // 字段排序
|
||||
XlsxImportConfig res_type.ResFieldByMap `db:"xlsxImportConfig"` // 导入设置
|
||||
TabsSort res_type.ResFieldByAnys `db:"tabsSort"` // 标签排序
|
||||
OperationsSort res_type.ResFieldByAnys `db:"operationsSort"` // 按钮排序
|
||||
FsmConfig res_type.ResFieldByAnys `db:"fsmConfig"` // FSM设置
|
||||
ApprovalConfig res_type.ResFieldByAnys `db:"approvalConfig"` // 审批设置
|
||||
UniqueImportFields res_type.ResFieldByAnys `db:"uniqueImportFields"` // 导入字段唯一效验
|
||||
Roles res_type.ResFieldByAnys `db:"roles"` // 列表权限
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
34
base/data_list_field.go
Normal file
34
base/data_list_field.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataListField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
DataListUuid string `db:"data_list_uuid"` // 所属列表 UUID
|
||||
Title res_type.ResFieldByString `db:"title"` // 列表标题
|
||||
Code string `db:"code"` // 字段名称
|
||||
CodeResource string `db:"codeResource"` // 字段所属资源
|
||||
Alias string `db:"alias"` // 字段别名
|
||||
IsExpr bool `db:"isExpr"` // 字段名是否为SQL表达式
|
||||
FieldDataType string `db:"fieldDataType"` // 字段数据类型
|
||||
Width int `db:"width"` // 列宽
|
||||
IsWidthFixed bool `db:"isWidthFixed"` // 列宽固定
|
||||
Fixed bool `db:"fixed"` // 字段冻结
|
||||
Align string `db:"align"` // 对齐方式
|
||||
IsShow int `db:"isShow"` // 是否显示
|
||||
WidgetByJs string `db:"widgetByJs"` // 前端数据渲染控件
|
||||
WidgetByJsSetting res_type.ResFieldByMap `db:"widgetByJsSetting"` // 前端数据渲染控件设置参数
|
||||
IsSearch bool `db:"isSearch"` // 允许关键字搜索
|
||||
IsVirtual bool `db:"isVirtual"` // 是否虚拟字段
|
||||
IsSort bool `db:"isSort"` // 允许字段排序
|
||||
EditableByJs string `db:"editableByJs"` // 字段更新组件
|
||||
EditableByJsSetting res_type.ResFieldByMap `db:"editableByJsSetting"` // 字段更新组件设置
|
||||
FilterByJs string `db:"filterByJs"` // 字段筛选组件
|
||||
FilterByJsSetting res_type.ResFieldByMap `db:"filterByJsSetting"` // 字段筛选组件设置参数
|
||||
FilterOperator string `db:"filterOperator"` // 字段筛选符号
|
||||
EditableRoles res_type.ResFieldByAnys `db:"editableRoles"` // 字段编辑权限
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
24
base/data_list_import_field.go
Normal file
24
base/data_list_import_field.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataListImportField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
DataListUuid string `db:"data_list_uuid"` // 所属列表 UUID
|
||||
Title res_type.ResFieldByString `db:"title"` // 列表标题
|
||||
Code string `db:"code"` // 字段名称
|
||||
CodeResource string `db:"codeResource"` // 字段所属资源
|
||||
FieldDataType string `db:"fieldDataType"` // 字段数据类型
|
||||
Width int `db:"width"` // 列宽
|
||||
Align string `db:"align"` // 对齐方式
|
||||
IsWidthFixed bool `db:"isWidthFixed"` // 列宽固定
|
||||
ConvertByJs string `db:"convertByJs"` // 前端数据转换控件
|
||||
ConvertByJsSetting res_type.ResFieldByMap `db:"convertByJsSetting"` // 前端数据转换控件设置参数
|
||||
IsVirtual bool `db:"isVirtual"` // 是否虚拟字段
|
||||
IsValidator int `db:"isValidator"` // 导入字段验证
|
||||
Validators res_type.ResFieldByMap `db:"validators"` // 导入字段验证规则
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
36
base/data_list_operation.go
Normal file
36
base/data_list_operation.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataListOperation struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Puuid string `db:"pUuid"`
|
||||
DataListUuid string `db:"data_list_uuid"` // 所属列表 UUID
|
||||
Name string `db:"name"` // 按钮名称
|
||||
Code string `db:"code"` // 按钮标识
|
||||
Category string `db:"category"` // 按钮类型
|
||||
Icon string `db:"icon"` // 按钮图标
|
||||
Size string `db:"size"` // 按钮大小
|
||||
Block bool `db:"block"` // 固定宽度
|
||||
Ghost bool `db:"ghost"` // 背景透明
|
||||
Shape string `db:"shape"` // 按钮形状
|
||||
Type string `db:"type"` // 按钮样式
|
||||
IsPopConfirm bool `db:"isPopConfirm"` // 按钮提示
|
||||
PopTitle string `db:"popTitle"` // 按钮提示
|
||||
PopOkText string `db:"popOkText"` // 按钮提示
|
||||
PopCancelText string `db:"popCancelText"` // 按钮提示
|
||||
PopOkType string `db:"popOkType"` // 按钮提示
|
||||
PopPlacement string `db:"popPlacement"` // 按钮提示
|
||||
Widget string `db:"widget"` // 按钮组件
|
||||
WidgetType string `db:"widgetType"` // 组件类型
|
||||
WidgetProps res_type.ResFieldByMap `db:"widgetProps"` // 组件PROPS
|
||||
WidgetSetting res_type.ResFieldByMap `db:"widgetSetting"` // 组件设置
|
||||
WidgetContainerSetting res_type.ResFieldByMap `db:"widgetContainerSetting"` // 组件容器设置
|
||||
IsRefresh int `db:"isRefresh"` // 0不刷新, 1刷新所有数据, 2刷新一条数据
|
||||
NoAuthType string `db:"noAuthType"` // 无按钮权限处理方式
|
||||
Roles res_type.ResFieldByAnys `db:"roles"` // 按钮权限
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
17
base/data_list_tab.go
Normal file
17
base/data_list_tab.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataListTab struct {
|
||||
Uuid string `db:"uuid"`
|
||||
DataListUuid string `db:"data_list_uuid"` // 所属列表 UUID
|
||||
Label string `db:"label"` // 标签名
|
||||
Code string `db:"code"` // 标签标识
|
||||
Order res_type.ResFieldByAnys `db:"order"` // 排序
|
||||
UseOrderMode int `db:"useOrderMode"` // 排序模式
|
||||
IsDefault bool `db:"isDefault"` // 是否默认
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
19
base/data_list_xlsx_field.go
Normal file
19
base/data_list_xlsx_field.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type DataListXlsxField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
DataListUuid string `db:"data_list_uuid"` // 所属列表 UUID
|
||||
Title res_type.ResFieldByString `db:"title"` // 列表标题
|
||||
Code string `db:"code"` // 字段名称
|
||||
CodeResource string `db:"codeResource"` // 字段所属资源
|
||||
Alias string `db:"alias"` // 字段别名
|
||||
FieldDataType string `db:"fieldDataType"` // 字段数据类型
|
||||
IsExpr bool `db:"isExpr"` // 字段名是否为SQL表达式
|
||||
IsShow bool `db:"isShow"` // 字段名是否为SQL表达式
|
||||
ConvertByJs string `db:"convertByJs"` // 字段数据转换组件
|
||||
ConvertByJsSetting res_type.ResFieldByMap `db:"convertByJsSetting"` // 字段数据转换组件参数
|
||||
}
|
||||
31
base/fsm_transition.go
Normal file
31
base/fsm_transition.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type FsmTransition struct {
|
||||
Uuid string `db:"uuid"`
|
||||
FsmUuid string `db:"fsm_uuid"`
|
||||
Name string `db:"name"`
|
||||
Code string `db:"code"`
|
||||
From string `db:"from"`
|
||||
To string `db:"to"`
|
||||
ResourceUuid string `db:"resource_uuid"`
|
||||
FsmName string `db:"fsm_name"`
|
||||
PrimaryKey string `db:"primaryKey"`
|
||||
StatusField string `db:"statusField"`
|
||||
StatusOptions res_type.ResFieldByAnys `db:"statusOptions"`
|
||||
IsPopConfirm bool `db:"isPopConfirm"`
|
||||
PopTitle string `db:"popTitle"`
|
||||
PopOkText string `db:"popOkText"`
|
||||
PopCancelText string `db:"popCancelText"`
|
||||
PopOkType string `db:"popOkType"`
|
||||
PopPlacement string `db:"popPlacement"`
|
||||
WidgetContainerSetting res_type.ResFieldByMap `db:"widgetContainerSetting"`
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
OperationRoles res_type.ResFieldByAnys `db:"operationRoles"`
|
||||
IsWithLayoutForm bool `db:"isWithLayoutForm"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
25
base/layout.go
Normal file
25
base/layout.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type Layout struct {
|
||||
Uuid string `db:"uuid"`
|
||||
ResourceUuid string `db:"resource_uuid"` // 所属资源UUID
|
||||
Code string `db:"code"` // 布局标识
|
||||
Name string `db:"name"` // 布局名称
|
||||
Type int `db:"type"` // 布局类型
|
||||
Align string `db:"align"` // 方向
|
||||
PrimaryKey string `db:"primaryKey"` // 主键
|
||||
AutoComplete string `db:"autoComplete"` // 自动填充表单, off | on
|
||||
RowHeight int `db:"rowHeight"` // 栅格行高
|
||||
MarginX int `db:"marginX"` // 栅格 x 间距
|
||||
MarginY int `db:"marginY"` // 栅格 y 间距
|
||||
FormProps res_type.ResFieldByAnys `db:"formProps"` // 表单PROPS
|
||||
ListenChangeFields res_type.ResFieldByAnys `db:"listenChangeFields"` // 监听字段
|
||||
ListenChangeFieldsFunc res_type.ResFieldByString `db:"listenChangeFieldsFunc"` // 监听字段回调方法
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
35
base/layout_field.go
Normal file
35
base/layout_field.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type LayoutField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
LayoutUuid string `db:"layout_uuid"` // 所属布局 UUID
|
||||
Type string `db:"type"`
|
||||
X int `db:"x"`
|
||||
Y int `db:"y"`
|
||||
W int `db:"w"`
|
||||
H int `db:"h"`
|
||||
MinH int `db:"minH"`
|
||||
MinW int `db:"minW"`
|
||||
MaxH int `db:"maxH"`
|
||||
MaxW int `db:"maxW"`
|
||||
Code string `db:"code"`
|
||||
Label string `db:"label"`
|
||||
Widget string `db:"widget"`
|
||||
WidgetPerfix string `db:"widgetPerfix"`
|
||||
WidgetDecorator res_type.ResFieldByString `db:"widgetDecorator"`
|
||||
SubWidgets res_type.ResFieldByAnys `db:"subWidgets"`
|
||||
Placeholder string `db:"placeholder"`
|
||||
Help string `db:"help"`
|
||||
Disabled int `db:"disabled"`
|
||||
InitialValue string `db:"initialValue"`
|
||||
Extras res_type.ResFieldByMap `db:"extras"`
|
||||
Validators res_type.ResFieldByMap `db:"validators"`
|
||||
Hidden bool `db:"hidden"`
|
||||
IsVirtual bool `db:"isVirtual"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
23
base/menu.go
Normal file
23
base/menu.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type Menu struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Id int `db:"id"`
|
||||
Pid int `db:"pid"`
|
||||
Type string `db:"type"`
|
||||
Name string `db:"name"`
|
||||
Icon string `db:"icon"`
|
||||
Widget string `db:"widget"`
|
||||
WidgetType string `db:"widgetType"`
|
||||
WidgetProps res_type.ResFieldByMap `db:"widgetProps"`
|
||||
WidgetSetting res_type.ResFieldByMap `db:"widgetSetting"`
|
||||
WidgetContainerSetting res_type.ResFieldByMap `db:"widgetContainerSetting"`
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
Platform string `db:"platform"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
17
base/print_template.go
Normal file
17
base/print_template.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type PrintTemplate struct {
|
||||
Uuid string `db:"uuid"`
|
||||
ResourceUuid string `db:"resource_uuid"` // 所属资源UUID
|
||||
Code string `db:"code"` // 打印模板标识
|
||||
Name string `db:"name"` // 打印模板名称
|
||||
PrimaryKey string `db:"primaryKey"` // 主键标识
|
||||
Roles res_type.ResFieldByAnys `db:"roles"` // 打印权限
|
||||
Template res_type.ResFieldByMap `db:"template"` // 打印权限
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
21
base/print_template_field.go
Normal file
21
base/print_template_field.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type PrintTemplateField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
PrintTemplateUuid string `db:"print_template_uuid"` // 所属打印模板UUID
|
||||
Label res_type.ResFieldByString `db:"label"` // 字段标签
|
||||
Code string `db:"code"` // 字段名称
|
||||
CodeResource string `db:"codeResource"` // 字段所属资源
|
||||
Category string `db:"category"` // 字段控件类型
|
||||
Alias string `db:"alias"` // 字段别名
|
||||
IsExpr bool `db:"isExpr"` // 字段名是否为SQL表达式
|
||||
FieldDataType string `db:"fieldDataType"` // 字段数据类型
|
||||
WidgetByJs string `db:"widgetByJs"` // 前端数据渲染控件
|
||||
WidgetByJsSetting res_type.ResFieldByMap `db:"widgetByJsSetting"` // 前端数据渲染控件设置参数
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
19
base/res_api.go
Normal file
19
base/res_api.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type ResApi struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Code string `db:"code"`
|
||||
Name string `db:"name"`
|
||||
PrimaryKey string `db:"primaryKey"`
|
||||
ResourceUuid string `db:"resource_uuid"`
|
||||
Method string `db:"method"`
|
||||
Category string `db:"action"`
|
||||
Params res_type.ResFieldByAnys `db:"params"`
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
18
base/res_api_approval.go
Normal file
18
base/res_api_approval.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type ResApiApproval struct {
|
||||
Uuid string `db:"uuid"`
|
||||
ApiUuid string `db:"api_uuid"`
|
||||
Code string `db:"code"`
|
||||
Name string `db:"name"`
|
||||
MarkField string `db:"markField"`
|
||||
RolesUuid res_type.ResFieldByAnys `db:"rolesUuid"`
|
||||
Flows res_type.ResFieldByAnys `db:"flows"`
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
13
base/res_api_field.go
Normal file
13
base/res_api_field.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package base
|
||||
|
||||
type ResApiField struct {
|
||||
Uuid string `db:"id"`
|
||||
ApiUuid string `db:"api_uuid"`
|
||||
Code string `db:"code"` // 字段名称
|
||||
CodeResource string `db:"resource"` // 字段所属资源
|
||||
Alias string `db:"alias"` // 字段别名
|
||||
IsExpr bool `db:"isExpr"` // 字段名是否为SQL表达式
|
||||
FieldDataType string `db:"fieldDataType"` // 字段数据类型
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
19
base/res_condition.go
Normal file
19
base/res_condition.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package base
|
||||
|
||||
type ResCondition struct {
|
||||
Uuid string `db:"id"`
|
||||
Id int `db:"id"`
|
||||
Pid int `db:"pid"`
|
||||
Type string `db:"type"`
|
||||
CategoryUuid string `db:"category_uuid"`
|
||||
Column string `db:"column"`
|
||||
ColumnResource string `db:"columnResource"`
|
||||
Operator string `db:"operator"`
|
||||
ColumnSqlFunc string `db:"columnSqlFunc"`
|
||||
ColumnSqlFuncParam string `db:"columnSqlFuncParam"`
|
||||
IgnoreEmptyParma bool `db:"ignoreEmptyParma"`
|
||||
ValueType string `db:"valueType"`
|
||||
Value string `db:"value"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
14
base/res_configure.go
Normal file
14
base/res_configure.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package base
|
||||
|
||||
type ResConfigure struct {
|
||||
Uuid string `db:"uuid"`
|
||||
ResourceUuid string `db:"resource_uuid"`
|
||||
Key string `db:"key"`
|
||||
Value string `db:"value"`
|
||||
Label string `db:"label"`
|
||||
Type string `db:"type"`
|
||||
IsPrivate bool `db:"isPrivate"`
|
||||
Desc string `db:"desc"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
288
base/res_field.go
Normal file
288
base/res_field.go
Normal file
@@ -0,0 +1,288 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"git.fsdpf.net/go/contracts"
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
"git.fsdpf.net/go/db"
|
||||
"git.fsdpf.net/go/db/schema"
|
||||
)
|
||||
|
||||
// 资源字段
|
||||
type ResField struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Name string `db:"name"`
|
||||
Code string `db:"code"`
|
||||
CodeResource string `db:"codeResource"`
|
||||
DataType res_type.ResDataType `db:"table_type"`
|
||||
Length string `db:"length"`
|
||||
Comment string `db:"comment"`
|
||||
Default string `db:"default"`
|
||||
}
|
||||
|
||||
type ResFields []ResField
|
||||
|
||||
func (c *ResFields) Scan(value any) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(value.([]byte), c); err != nil {
|
||||
return fmt.Errorf("ResFields json.Unmarshal Error, %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c ResFields) Value() (driver.Value, error) {
|
||||
b, err := json.Marshal(c)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
func (this ResField) ToStructField(tags ...string) reflect.StructField {
|
||||
var typ reflect.Type
|
||||
|
||||
fCode := this.Code
|
||||
fTag := `db:"` + fCode + `" json:"` + fCode + `"`
|
||||
|
||||
if len(tags) > 0 {
|
||||
fTag = strings.Join(tags, " ") + " " + fTag
|
||||
}
|
||||
|
||||
switch this.DataType {
|
||||
case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum,
|
||||
contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime:
|
||||
typ = reflect.TypeOf(res_type.ResFieldByString(""))
|
||||
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger:
|
||||
typ = reflect.TypeOf(res_type.ResFieldByInteger(0))
|
||||
case contracts.ResDataType_Decimal:
|
||||
typ = reflect.TypeOf(float64(0))
|
||||
case contracts.ResDataType_Boolean:
|
||||
typ = reflect.TypeOf(true)
|
||||
case contracts.ResDataType_Json:
|
||||
if this.Default != "" && this.Default[0:1] == "[" {
|
||||
typ = reflect.TypeOf(res_type.ResFieldByAnys{})
|
||||
} else {
|
||||
typ = reflect.TypeOf(res_type.ResFieldByMap{})
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.StructField{
|
||||
Name: strings.ToUpper(fCode[:1]) + fCode[1:],
|
||||
Tag: reflect.StructTag(fTag),
|
||||
Type: typ,
|
||||
}
|
||||
}
|
||||
|
||||
func (this ResField) GetCode() string {
|
||||
return this.Code
|
||||
}
|
||||
|
||||
func (this ResField) GetCodeResource() string {
|
||||
return this.CodeResource
|
||||
}
|
||||
|
||||
func (this ResField) GetName() string {
|
||||
return this.Name
|
||||
}
|
||||
|
||||
func (this ResField) GetDataType() contracts.ResDataType {
|
||||
return this.DataType
|
||||
}
|
||||
|
||||
func (this ResField) GetQueryDataType() contracts.QueryDataType {
|
||||
switch this.GetDataType() {
|
||||
case contracts.ResDataType_Enum,
|
||||
contracts.ResDataType_Timestamp, contracts.ResDataType_Date,
|
||||
contracts.ResDataType_Datetime, contracts.ResDataType_String,
|
||||
contracts.ResDataType_Text:
|
||||
return contracts.QueryDataType_String
|
||||
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger:
|
||||
return contracts.QueryDataType_Integer
|
||||
case contracts.ResDataType_Decimal:
|
||||
return contracts.QueryDataType_Float
|
||||
case contracts.ResDataType_Boolean:
|
||||
return contracts.QueryDataType_Bool
|
||||
case contracts.ResDataType_Json:
|
||||
if this.Default != "" && this.Default[0:1] == "[" {
|
||||
return contracts.QueryDataType_Array
|
||||
}
|
||||
return contracts.QueryDataType_Json
|
||||
}
|
||||
return contracts.QueryDataType_String
|
||||
}
|
||||
|
||||
func (this ResField) ToValue(v any) any {
|
||||
// 类型转换, 填补 cast 未知的类型
|
||||
switch data := v.(type) {
|
||||
case res_type.ResFieldByInteger:
|
||||
v = int64(data)
|
||||
case res_type.ResFieldByFloat:
|
||||
v = float64(data)
|
||||
case res_type.ResFieldByNumber:
|
||||
v = float64(data)
|
||||
case res_type.ResFieldByString:
|
||||
v = strings.Trim(string(data), " ")
|
||||
case res_type.ResFieldByAnys:
|
||||
if v != nil {
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
v = []any(data)
|
||||
case res_type.ResFieldByMap:
|
||||
if v != nil {
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
v = map[string]any(data)
|
||||
case []any, []string, []int, []float64, []float32, []int64:
|
||||
if v != nil {
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
v = data
|
||||
case map[string]any, map[string]string, map[string]int:
|
||||
if v != nil {
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
v = data
|
||||
}
|
||||
|
||||
switch this.DataType {
|
||||
case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum,
|
||||
contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime:
|
||||
return strings.Trim(cast.ToString(v), " ")
|
||||
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger:
|
||||
return cast.ToInt(v)
|
||||
case contracts.ResDataType_Decimal:
|
||||
return strings.Trim(cast.ToString(v), " ")
|
||||
case contracts.ResDataType_Boolean:
|
||||
v, _ := strconv.ParseBool(fmt.Sprintf("%v", v))
|
||||
return v
|
||||
case contracts.ResDataType_Json:
|
||||
if v == nil {
|
||||
if this.Default != "" && this.Default[0:1] == "[" {
|
||||
return "[]"
|
||||
} else if this.Default != "" && this.Default[0:1] == "{" {
|
||||
return "{}"
|
||||
} else if this.Default == "" {
|
||||
return "{}"
|
||||
}
|
||||
|
||||
return this.Default
|
||||
}
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
return strings.Trim(cast.ToString(v), " ")
|
||||
}
|
||||
|
||||
func (this ResField) GetRawDefault(driver string) db.Expression {
|
||||
if this.DataType == "json" && this.Default == "" {
|
||||
return db.Raw("'{}'")
|
||||
}
|
||||
|
||||
if len(this.Default) > 4 && strings.ToLower(this.Default[0:4]) == "sql:" {
|
||||
sql := strings.ToLower(this.Default[4:])
|
||||
if sql == "uuid()" {
|
||||
return Uuid(driver)
|
||||
}
|
||||
return db.Raw(sql)
|
||||
}
|
||||
|
||||
if this.Default == "" {
|
||||
if this.GetDataType() == contracts.ResDataType_Date || this.GetDataType() == contracts.ResDataType_Datetime {
|
||||
return db.Raw("NULL")
|
||||
}
|
||||
return db.Raw("''")
|
||||
}
|
||||
|
||||
if strings.ToUpper(this.Default) == "CURRENT_TIMESTAMP" {
|
||||
return db.Raw(this.Default)
|
||||
}
|
||||
|
||||
return db.Raw("'" + this.Default + "'")
|
||||
}
|
||||
|
||||
func (this ResField) ToBlueprint(table *schema.Blueprint) (temp *schema.ColumnDefinition) {
|
||||
isNull := false
|
||||
comment := this.Name
|
||||
def := any(this.Default)
|
||||
|
||||
if this.Comment != "" {
|
||||
comment += " [ " + strings.Trim(this.Comment, `' "`) + " ]"
|
||||
}
|
||||
|
||||
switch this.DataType {
|
||||
case "string":
|
||||
len := 255
|
||||
if v, err := strconv.Atoi(strings.Trim(this.Length, `' "`)); err == nil {
|
||||
len = v
|
||||
}
|
||||
temp = table.String(this.Code, len)
|
||||
case "smallInteger":
|
||||
// integer 默认长度 4
|
||||
temp = table.SmallInteger(this.Code)
|
||||
case "boolean":
|
||||
// integer 默认长度 1
|
||||
temp = table.Boolean(this.Code)
|
||||
case "integer":
|
||||
// integer 默认长度 11
|
||||
temp = table.Integer(this.Code)
|
||||
case "date", "dateTime":
|
||||
if this.DataType == "date" {
|
||||
temp = table.Date(this.Code)
|
||||
} else {
|
||||
temp = table.DateTime(this.Code)
|
||||
}
|
||||
|
||||
if strings.ToUpper(this.Default) == "CURRENT_TIMESTAMP" {
|
||||
def = db.Raw(this.Default)
|
||||
} else if def == "" {
|
||||
isNull = true
|
||||
}
|
||||
case "decimal":
|
||||
allowed := strings.SplitN(this.Length, ",", 2)
|
||||
total := 8
|
||||
places := 2
|
||||
if v, err := strconv.Atoi(strings.Trim(allowed[0], `' "`)); err == nil {
|
||||
total = v
|
||||
}
|
||||
if v, err := strconv.Atoi(strings.Trim(allowed[1], `' "`)); err == nil {
|
||||
places = v
|
||||
}
|
||||
temp = table.Decimal(this.Code, total, places)
|
||||
case "enum":
|
||||
allowed := []string{}
|
||||
for _, v := range strings.Split(this.Length, ",") {
|
||||
allowed = append(allowed, strings.Trim(v, `' "`))
|
||||
}
|
||||
temp = table.Enum(this.Code, allowed)
|
||||
case "json":
|
||||
temp = table.Json(this.Code)
|
||||
isNull = true
|
||||
case "text":
|
||||
temp = table.Text(this.Code)
|
||||
isNull = true
|
||||
}
|
||||
|
||||
if isNull {
|
||||
temp.Nullable()
|
||||
} else {
|
||||
temp.Default(def)
|
||||
}
|
||||
|
||||
temp.Comment(comment)
|
||||
|
||||
return temp
|
||||
}
|
||||
14
base/res_field_sql_defined.go
Normal file
14
base/res_field_sql_defined.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"git.fsdpf.net/go/db"
|
||||
)
|
||||
|
||||
func Uuid(driver string) db.Expression {
|
||||
if driver == "sqlite" {
|
||||
return db.Raw("'" + uuid.NewString() + "'")
|
||||
}
|
||||
return db.Raw("uuid()")
|
||||
}
|
||||
15
base/res_listener.go
Normal file
15
base/res_listener.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type ResListener struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Code string `db:"code"`
|
||||
Name string `db:"name"`
|
||||
ResourceUuid string `db:"resource_uuid"`
|
||||
Event res_type.ResFieldByAnys `db:"event"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
15
base/res_relation.go
Normal file
15
base/res_relation.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package base
|
||||
|
||||
type ResRelation struct {
|
||||
Uuid string `db:"uuid"`
|
||||
CategoryUuid string `db:"category_uuid"` // 所属 UUID
|
||||
Name string `db:"name"` // 关联名称
|
||||
Code string `db:"code"` // 关联标识
|
||||
Type string `db:"type"` // 关联类型
|
||||
ResourceCode string `db:"actuallyResource"` // 实际资源资源
|
||||
RelationForeignKey string `db:"actuallyField"` // 实际资源资源字段
|
||||
RelationResource string `db:"relationResource"` // 被关联的资源
|
||||
RelationField string `db:"relationField"` // 被关联的字段
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
9
base/res_role.go
Normal file
9
base/res_role.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package base
|
||||
|
||||
type ResRole struct {
|
||||
Uuid string `db:"id"`
|
||||
ResUuid string `db:"resource_uuid"`
|
||||
RoleUuid string `db:"role_uuid"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
17
base/res_widget_operations.go
Normal file
17
base/res_widget_operations.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type ResWidgetOperation struct {
|
||||
Uuid string `db:"uuid"`
|
||||
WidgetUuid string `db:"widget_uuid"`
|
||||
Name string `db:"name"`
|
||||
NoAuthType string `db:"noAuthType"`
|
||||
PropsAuthRule res_type.ResFieldByAnys `db:"propsAuthRule"`
|
||||
ExtraAuthRule res_type.ResFieldByAnys `db:"extraAuthRule"`
|
||||
Roles res_type.ResFieldByAnys `db:"roles"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
340
base/resource.go
Normal file
340
base/resource.go
Normal file
@@ -0,0 +1,340 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"reflect"
|
||||
"unicode"
|
||||
|
||||
"github.com/samber/do"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"git.fsdpf.net/go/contracts"
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
"git.fsdpf.net/go/db"
|
||||
"git.fsdpf.net/go/queue"
|
||||
)
|
||||
|
||||
// 资源
|
||||
type Resource struct {
|
||||
container *do.Injector
|
||||
|
||||
Uuid string `db:"uuid"`
|
||||
PUuid string `db:"pUuid"`
|
||||
Code string `db:"code"`
|
||||
Name string `db:"name"`
|
||||
IsResVirtual bool `db:"isVirtual"`
|
||||
Table string `db:"table"`
|
||||
Namespace string `db:"namespace"`
|
||||
Workspace string `db:"workspace"`
|
||||
Primarykey string `db:"primaryKey"`
|
||||
IsHistoryRecord bool `db:"isHistoryRecord"`
|
||||
HistoryCacheMax int `db:"historyCacheMax"`
|
||||
Fields ResFields `db:"fields"`
|
||||
Roles res_type.ResFieldByMap `db:"roles"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
|
||||
// 资源UUID
|
||||
func (this Resource) GetUuid() string {
|
||||
return this.Uuid
|
||||
}
|
||||
|
||||
// 资源CODE
|
||||
func (this Resource) GetCode() string {
|
||||
return this.Code
|
||||
}
|
||||
|
||||
// 资源名
|
||||
func (this Resource) GetName() string {
|
||||
return this.Name
|
||||
}
|
||||
|
||||
// 主键
|
||||
func (this Resource) GetPrimarykey() string {
|
||||
return this.Primarykey
|
||||
}
|
||||
|
||||
// 是否虚拟资源
|
||||
func (this Resource) IsVirtual() bool {
|
||||
return this.IsResVirtual
|
||||
}
|
||||
|
||||
// 是否系统资源
|
||||
func (this Resource) IsSystem() bool {
|
||||
return this.Namespace == "Framework\\Service"
|
||||
}
|
||||
|
||||
// 资源字段
|
||||
func (this Resource) GetFields() (result []contracts.ResField) {
|
||||
for _, item := range this.Fields {
|
||||
result = append(result, item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 资源字段
|
||||
func (this Resource) GetField(code string) (contracts.ResField, bool) {
|
||||
return lo.Find(this.GetFields(), func(v contracts.ResField) bool {
|
||||
return v.GetCode() == code
|
||||
})
|
||||
}
|
||||
|
||||
// 判断资源字段
|
||||
func (this Resource) HasField(code string) bool {
|
||||
return lo.SomeBy(this.GetFields(), func(v contracts.ResField) bool {
|
||||
return v.GetCode() == code
|
||||
})
|
||||
}
|
||||
|
||||
// 开启事物
|
||||
func (this Resource) BeginTransaction() (*db.Transaction, error) {
|
||||
return this.GetDB().Connection.BeginTransaction()
|
||||
}
|
||||
|
||||
// 获取资源对应的数据库连接
|
||||
func (this Resource) GetDB() *db.Builder {
|
||||
db := do.MustInvoke[db.DB](this.container)
|
||||
|
||||
if this.IsSystem() {
|
||||
return db.Connection("service-support").Query()
|
||||
}
|
||||
|
||||
return db.Connection("default").Query()
|
||||
}
|
||||
|
||||
// 获取资源对应的数据表
|
||||
func (this Resource) GetTable() db.Expression {
|
||||
if this.IsVirtual() {
|
||||
return db.Raw("(" + this.Table + ")")
|
||||
}
|
||||
|
||||
return db.Raw(this.Table)
|
||||
}
|
||||
|
||||
func (this Resource) GetDBDriver() string {
|
||||
return this.GetDB().Connection.GetConfig().Driver
|
||||
}
|
||||
|
||||
func (this Resource) GetAuthDBTable(u contracts.User, params ...any) *db.Builder {
|
||||
this.GetRolesCondition(u)
|
||||
|
||||
return this.GetDBTable(append(params, u)...)
|
||||
}
|
||||
|
||||
// GetDBTable("Test", contracts.User)
|
||||
func (this Resource) GetDBTable(params ...any) *db.Builder {
|
||||
builder := this.GetDB()
|
||||
|
||||
var user contracts.User
|
||||
alias := this.Code
|
||||
|
||||
for _, param := range params {
|
||||
switch v := param.(type) {
|
||||
case *db.Transaction:
|
||||
builder.Tx = v
|
||||
case string:
|
||||
alias = v
|
||||
case contracts.User:
|
||||
user = v
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化数据库存储数据
|
||||
builder.Before(func(b *db.Builder, t string, data ...map[string]any) {
|
||||
if t == db.TYPE_UPDATE {
|
||||
// 格式化保存数据
|
||||
this.formatSaveValue(data[0])
|
||||
}
|
||||
if t == db.TYPE_INSERT {
|
||||
// 移除 table alias
|
||||
b.Table(string(this.GetTable()))
|
||||
for i := 0; i < len(data); i++ {
|
||||
// 格式化保存数据
|
||||
this.formatSaveValue(data[i])
|
||||
// 填充保存数据
|
||||
this.fillSaveValue(data[i], user, db.TYPE_INSERT)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 资源事件
|
||||
this.onResEvent(builder)
|
||||
|
||||
// 用户事件
|
||||
if this.IsHistoryRecord {
|
||||
this.onUserEvent(builder, user)
|
||||
}
|
||||
|
||||
// 虚拟资源暂时不考虑鉴权
|
||||
if !this.IsVirtual() {
|
||||
// 返回鉴权后的 DB Builder
|
||||
// return
|
||||
}
|
||||
|
||||
return builder.Table(string(this.GetTable()), alias)
|
||||
}
|
||||
|
||||
func (this Resource) WithRolesCondition(b *db.Builder, roles ...string) {
|
||||
|
||||
}
|
||||
|
||||
// 获取鉴权条件
|
||||
func (this Resource) GetRolesCondition(u contracts.User) {
|
||||
// isFullRight := false
|
||||
// isFullNot := false
|
||||
|
||||
// roles := do.MustInvoke[GetResRoles](this.container)(this.GetUuid())
|
||||
// GetResRelations := do.MustInvoke[GetResRelations](this.container)
|
||||
|
||||
// subTables := lo.Reduce(roles, func(carry *db.Builder, item ResRole, _ int) *db.Builder {
|
||||
// db := this.GetDB().Table(string(this.GetTable()), this.GetCode()).Select("`" + this.GetCode() + "`.*")
|
||||
|
||||
// joins := lo.Filter(GetResRelations(item.Uuid), func(item ResRelation, _ int) bool {
|
||||
// return item.Type == "inner" || item.Type == "left" || item.Type == "right"
|
||||
// })
|
||||
|
||||
// join := orm.NewJoin(contracts.RelationType(item.Type), item.Code, oResource, item.RelationResource, item.RelationField, item.RelationForeignKey)
|
||||
|
||||
// // 关联扩展条件
|
||||
// join.SetCondition(orm.NewConditionByRes(GetResConditions(item.Uuid)))
|
||||
|
||||
// return carry
|
||||
// }, nil)
|
||||
|
||||
// fmt.Println(subTables.ToSql())
|
||||
|
||||
}
|
||||
|
||||
// 格式化保存数据
|
||||
func (this Resource) formatSaveValue(data map[string]any) {
|
||||
//
|
||||
for k, v := range data {
|
||||
if k == "id" || k == "created_user" || k == "created_at" || k == "deleted_at" || k == "updated_at" {
|
||||
delete(data, k)
|
||||
} else if val, ok := v.(db.Expression); ok {
|
||||
data[k] = val
|
||||
} else if field, ok := this.GetField(k); ok {
|
||||
data[k] = field.ToValue(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 填充保存数据
|
||||
func (this Resource) fillSaveValue(data map[string]any, u contracts.User, t string) {
|
||||
for _, field := range this.GetFields() {
|
||||
fCode := field.GetCode()
|
||||
|
||||
if fCode == "id" || fCode == "created_user" || fCode == "created_at" || fCode == "deleted_at" || fCode == "updated_at" || fCode == "owned_user" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 只有新增默认字段
|
||||
if _, ok := data[fCode]; !ok {
|
||||
data[fCode] = field.GetRawDefault(this.GetDBDriver())
|
||||
}
|
||||
}
|
||||
|
||||
// 拥有者
|
||||
if _, ok := data["owned_user"]; !ok {
|
||||
data["owned_user"] = u.Uuid()
|
||||
}
|
||||
// 创建者
|
||||
data["created_user"] = u.Uuid()
|
||||
if this.GetDBDriver() == "sqlite" {
|
||||
// 更新时间
|
||||
// sqlite 不能自动更新时间, "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
|
||||
data["updated_at"] = db.Raw("CURRENT_TIMESTAMP")
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (this Resource) GetStruct(extends ...reflect.StructField) any {
|
||||
fields := []reflect.StructField{}
|
||||
|
||||
for _, field := range this.Fields {
|
||||
if unicode.IsLetter(rune(field.Code[0])) {
|
||||
fields = append(fields, field.ToStructField())
|
||||
} else {
|
||||
log.Printf("资源字段错误, 必须以字母开头 <- %s", field.Code)
|
||||
}
|
||||
}
|
||||
|
||||
fields = lo.UniqBy(append(fields, extends...), func(v reflect.StructField) string {
|
||||
return v.Name
|
||||
})
|
||||
|
||||
t := reflect.StructOf(fields)
|
||||
|
||||
return reflect.New(t).Interface()
|
||||
}
|
||||
|
||||
func (this Resource) GetSliceStruct(extends ...reflect.StructField) any {
|
||||
t := reflect.TypeOf(this.GetStruct(extends...))
|
||||
|
||||
st := reflect.SliceOf(t.Elem())
|
||||
|
||||
return reflect.New(st).Interface()
|
||||
}
|
||||
|
||||
// 资源事件
|
||||
func (this Resource) onResEvent(builder *db.Builder) {
|
||||
builder.After(func(b *db.Builder, t string, result sql.Result, err error, data ...map[string]any) {
|
||||
if err != nil || t == db.TYPE_SELECT {
|
||||
return
|
||||
} else if num, err := result.RowsAffected(); num == 0 || err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 全局触发器
|
||||
// 1. 清除系统缓存
|
||||
if err := do.MustInvoke[contracts.Queue](this.container).Publish(contracts.ResQueueTopic, contracts.ResQueuePayload{
|
||||
Type: t,
|
||||
Res: this,
|
||||
Result: result,
|
||||
}); err != nil {
|
||||
log.Println("Queue Publish Err:", contracts.ResQueueTopic, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 用户事件
|
||||
func (this Resource) onUserEvent(builder *db.Builder, user contracts.User) {
|
||||
old := []map[string]any{}
|
||||
|
||||
builder.Before(func(b *db.Builder, t string, data ...map[string]any) {
|
||||
if t != db.TYPE_UPDATE && t != db.TYPE_DELETE {
|
||||
return
|
||||
}
|
||||
// 查询保存之前的数据
|
||||
if _, err := b.Get(&old); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
|
||||
builder.After(func(b *db.Builder, t string, result sql.Result, err error, data ...map[string]any) {
|
||||
if err != nil || t == db.TYPE_SELECT {
|
||||
return
|
||||
} else if num, err := result.RowsAffected(); num == 0 || err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
user = GetAnonymous()
|
||||
}
|
||||
|
||||
// 触发消息队列
|
||||
if err := do.MustInvoke[contracts.Queue](this.container).Publish(contracts.UserQueuetTopic, contracts.UserQueuePayload{
|
||||
Type: t,
|
||||
User: user,
|
||||
Res: this,
|
||||
Old: old,
|
||||
New: data,
|
||||
Result: result,
|
||||
}); err != nil {
|
||||
log.Println("Queue Publish Err:", contracts.UserQueuetTopic, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
23
base/route.go
Normal file
23
base/route.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"git.fsdpf.net/go/contracts/res_type"
|
||||
)
|
||||
|
||||
type Route struct {
|
||||
Uuid string `db:"uuid"`
|
||||
Name string `db:"name"`
|
||||
Uri string `db:"uri"`
|
||||
Layout string `db:"layout"`
|
||||
IsLogin bool `db:"isLogin"`
|
||||
IsPhone bool `db:"isPhone"`
|
||||
Type string `db:"type"`
|
||||
Component string `db:"component"`
|
||||
WidgetProps res_type.ResFieldByMap `db:"widgetProps"`
|
||||
WidgetSetting res_type.ResFieldByMap `db:"widgetSetting"`
|
||||
WidgetContainerSetting res_type.ResFieldByMap `db:"widgetContainerSetting"`
|
||||
Exact bool `db:"exact"`
|
||||
Platform string `db:"platform"`
|
||||
UpdatedAt string `db:"updated_at"`
|
||||
CreatedAt string `db:"created_at"`
|
||||
}
|
||||
81
base/user.go
Normal file
81
base/user.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"git.fsdpf.net/go/contracts"
|
||||
)
|
||||
|
||||
type user struct {
|
||||
id int
|
||||
uuid string
|
||||
username string
|
||||
nickname string
|
||||
platform string
|
||||
roles []string
|
||||
}
|
||||
|
||||
func (this user) ID() int {
|
||||
return this.id
|
||||
}
|
||||
|
||||
func (this user) Uuid() string {
|
||||
return this.uuid
|
||||
}
|
||||
|
||||
func (this user) Username() string {
|
||||
return this.username
|
||||
}
|
||||
|
||||
func (this user) Nickname() string {
|
||||
return this.nickname
|
||||
}
|
||||
|
||||
func (this user) GetUserInfo() any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this user) Roles() (roles []string) {
|
||||
return this.roles
|
||||
}
|
||||
|
||||
func (this user) HasUserRoles(roles ...string) bool {
|
||||
return lo.Contains(this.Roles(), "ffffffff-ffff-ffff-ffff-ffffffffffff") || len(lo.Intersect(this.Roles(), roles)) > 0
|
||||
}
|
||||
|
||||
func (this user) IsAnonymous() bool {
|
||||
return reflect.DeepEqual(this.Roles(), []string{"00000000-0000-0000-0000-000000000000"})
|
||||
}
|
||||
|
||||
func (this user) Platform() string {
|
||||
if this.platform == "" {
|
||||
return "unknown"
|
||||
}
|
||||
return this.platform
|
||||
}
|
||||
|
||||
// 获取匿名用户
|
||||
func GetAnonymous() contracts.User {
|
||||
return user{
|
||||
id: 0,
|
||||
uuid: "00000000-0000-0000-0000-000000000000",
|
||||
username: "anonymous",
|
||||
nickname: "匿名者",
|
||||
roles: []string{"00000000-0000-0000-0000-000000000000"},
|
||||
platform: "unknown",
|
||||
}
|
||||
}
|
||||
|
||||
// 系统用户
|
||||
func GetSystemUser() contracts.User {
|
||||
return user{
|
||||
id: -1,
|
||||
uuid: "ffffffff-ffff-ffff-ffff-ffffffffffff",
|
||||
username: "system",
|
||||
nickname: "系统",
|
||||
roles: []string{"ffffffff-ffff-ffff-ffff-ffffffffffff"},
|
||||
platform: "unknown",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user