v0.9.33 修复表格会话数据BUG & 安全更新
This commit is contained in:
parent
d68accee47
commit
6d2cdaaf1b
13 changed files with 373 additions and 50 deletions
|
|
@ -20,5 +20,5 @@ func check(t *testing.T) {
|
||||||
for key := range gou.Flows {
|
for key := range gou.Flows {
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
assert.Equal(t, 18, len(keys))
|
assert.Equal(t, 19, len(keys))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,15 +118,20 @@ func (api API) MergeDefaultQueryParam(param gou.QueryParam, i int, sid string) g
|
||||||
|
|
||||||
// GetQueryParam 解析参数
|
// GetQueryParam 解析参数
|
||||||
func GetQueryParam(v interface{}, sid string) gou.QueryParam {
|
func GetQueryParam(v interface{}, sid string) gou.QueryParam {
|
||||||
|
fmt.Println("\n==== GetQueryParam ===== SID:", sid)
|
||||||
data := map[string]interface{}{}
|
data := map[string]interface{}{}
|
||||||
if sid != "" {
|
if sid != "" {
|
||||||
var err error
|
var err error
|
||||||
ss := session.Global().ID(sid)
|
ss := session.Global().ID(sid)
|
||||||
data, err = ss.Dump()
|
data, err = ss.Dump()
|
||||||
|
utils.Dump(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
xlog.Printf("读取会话信息出错 %s", err.Error())
|
xlog.Printf("读取会话信息出错 %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fmt.Println("==== GetQueryParam========================")
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
v = share.Bind(v, maps.Of(data).Dot())
|
v = share.Bind(v, maps.Of(data).Dot())
|
||||||
param, ok := gou.AnyToQueryParam(v)
|
param, ok := gou.AnyToQueryParam(v)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package share
|
package share
|
||||||
|
|
||||||
// VERSION 版本号
|
// VERSION 版本号
|
||||||
const VERSION = "0.9.32"
|
const VERSION = "0.9.33"
|
||||||
|
|
||||||
// DOMAIN 许可域(废弃)
|
// DOMAIN 许可域(废弃)
|
||||||
const DOMAIN = "*.iqka.com"
|
const DOMAIN = "*.iqka.com"
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func apiDefaultWhere(model *gou.Model, withs map[string]gou.With, name string, p
|
||||||
}
|
}
|
||||||
|
|
||||||
// apiDefaultSetting 数据表格配置默认值
|
// apiDefaultSetting 数据表格配置默认值
|
||||||
func apiDefaultSetting(table *Table) share.API {
|
func apiDefaultSetting() share.API {
|
||||||
return share.API{
|
return share.API{
|
||||||
Name: "setting",
|
Name: "setting",
|
||||||
Guard: "bearer-jwt",
|
Guard: "bearer-jwt",
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package table
|
package table
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
"github.com/yaoapp/kun/any"
|
"github.com/yaoapp/kun/any"
|
||||||
"github.com/yaoapp/kun/maps"
|
"github.com/yaoapp/kun/maps"
|
||||||
|
"github.com/yaoapp/kun/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -39,11 +41,17 @@ func ProcessSearch(process *gou.Process) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before Hook
|
// Before Hook
|
||||||
process.Args = table.Before(table.Hooks.BeforeSearch, process.Args)
|
process.Args = table.Before(table.Hooks.BeforeSearch, process.Args, process.Sid)
|
||||||
|
|
||||||
// 参数表
|
// 参数表
|
||||||
process.ValidateArgNums(4)
|
process.ValidateArgNums(4)
|
||||||
param := api.MergeDefaultQueryParam(process.ArgsQueryParams(1), 0, process.Sid)
|
param := api.MergeDefaultQueryParam(process.ArgsQueryParams(1), 0, process.Sid)
|
||||||
|
|
||||||
|
fmt.Println("\n==== ProcessSearch ============= SID:", process.Sid)
|
||||||
|
utils.Dump(param)
|
||||||
|
fmt.Println("==== END ProcessSearch ===============================================")
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
page := process.ArgsInt(2, api.DefaultInt(1))
|
page := process.ArgsInt(2, api.DefaultInt(1))
|
||||||
pagesize := process.ArgsInt(3, api.DefaultInt(2))
|
pagesize := process.ArgsInt(3, api.DefaultInt(2))
|
||||||
|
|
||||||
|
|
@ -51,7 +59,7 @@ func ProcessSearch(process *gou.Process) interface{} {
|
||||||
response := gou.NewProcess(api.Process, param, page, pagesize).Run()
|
response := gou.NewProcess(api.Process, param, page, pagesize).Run()
|
||||||
|
|
||||||
// After Hook
|
// After Hook
|
||||||
return table.After(table.Hooks.AfterSearch, response)
|
return table.After(table.Hooks.AfterSearch, response, process.Sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessFind xiang.table.Find
|
// ProcessFind xiang.table.Find
|
||||||
|
|
@ -67,7 +75,7 @@ func ProcessFind(process *gou.Process) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before Hook
|
// Before Hook
|
||||||
process.Args = table.Before(table.Hooks.BeforeFind, process.Args)
|
process.Args = table.Before(table.Hooks.BeforeFind, process.Args, process.Sid)
|
||||||
|
|
||||||
// 参数表
|
// 参数表
|
||||||
process.ValidateArgNums(2)
|
process.ValidateArgNums(2)
|
||||||
|
|
@ -78,7 +86,7 @@ func ProcessFind(process *gou.Process) interface{} {
|
||||||
response := gou.NewProcess(api.Process, id, param).Run()
|
response := gou.NewProcess(api.Process, id, param).Run()
|
||||||
|
|
||||||
// After Hook
|
// After Hook
|
||||||
return table.After(table.Hooks.AfterFind, response)
|
return table.After(table.Hooks.AfterFind, response, process.Sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessSave xiang.table.Save
|
// ProcessSave xiang.table.Save
|
||||||
|
|
@ -95,7 +103,7 @@ func ProcessSave(process *gou.Process) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before Hook
|
// Before Hook
|
||||||
process.Args = table.Before(table.Hooks.BeforeSave, process.Args)
|
process.Args = table.Before(table.Hooks.BeforeSave, process.Args, process.Sid)
|
||||||
|
|
||||||
// 参数处理
|
// 参数处理
|
||||||
process.ValidateArgNums(2)
|
process.ValidateArgNums(2)
|
||||||
|
|
@ -104,7 +112,7 @@ func ProcessSave(process *gou.Process) interface{} {
|
||||||
response := gou.NewProcess(api.Process, process.Args[1]).Run()
|
response := gou.NewProcess(api.Process, process.Args[1]).Run()
|
||||||
|
|
||||||
// After Hook
|
// After Hook
|
||||||
return table.After(table.Hooks.AfterSave, response)
|
return table.After(table.Hooks.AfterSave, response, process.Sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessDelete xiang.table.Delete
|
// ProcessDelete xiang.table.Delete
|
||||||
|
|
@ -315,10 +323,10 @@ func ProcessSelect(process *gou.Process) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before Hook
|
// Before Hook
|
||||||
process.Args = table.Before(table.Hooks.BeforeSelect, process.Args)
|
process.Args = table.Before(table.Hooks.BeforeSelect, process.Args, process.Sid)
|
||||||
|
|
||||||
response := gou.NewProcess(api.Process, process.Args[1:]...).Run()
|
response := gou.NewProcess(api.Process, process.Args[1:]...).Run()
|
||||||
|
|
||||||
// After Hook
|
// After Hook
|
||||||
return table.After(table.Hooks.AfterSelect, response)
|
return table.After(table.Hooks.AfterSelect, response, process.Sid)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ func (table *Table) loadAPIs() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defaults := getDefaultAPIs(table.Bind)
|
defaults := getDefaultAPIs(table.Bind)
|
||||||
defaults["setting"] = apiDefaultSetting(table)
|
defaults["setting"] = apiDefaultSetting()
|
||||||
|
|
||||||
for name := range table.APIs {
|
for name := range table.APIs {
|
||||||
if _, has := defaults[name]; !has {
|
if _, has := defaults[name]; !has {
|
||||||
|
|
@ -150,7 +150,7 @@ func getDefaultAPIs(bind Bind) map[string]share.API {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before 运行 Before hook
|
// Before 运行 Before hook
|
||||||
func (table *Table) Before(process string, processArgs []interface{}) []interface{} {
|
func (table *Table) Before(process string, processArgs []interface{}, sid string) []interface{} {
|
||||||
if process == "" {
|
if process == "" {
|
||||||
return processArgs
|
return processArgs
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +161,7 @@ func (table *Table) Before(process string, processArgs []interface{}) []interfac
|
||||||
res = append(res, processArgs[0])
|
res = append(res, processArgs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := gou.NewProcess(process, args...).Exec()
|
response, err := gou.NewProcess(process, args...).WithSID(sid).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
xlog.Println("Hook执行失败: ", err.Error(), maps.StrAny{"process": process, "args": args})
|
xlog.Println("Hook执行失败: ", err.Error(), maps.StrAny{"process": process, "args": args})
|
||||||
return processArgs
|
return processArgs
|
||||||
|
|
@ -177,11 +177,11 @@ func (table *Table) Before(process string, processArgs []interface{}) []interfac
|
||||||
}
|
}
|
||||||
|
|
||||||
// After 运行 After hook
|
// After 运行 After hook
|
||||||
func (table *Table) After(process string, data interface{}) interface{} {
|
func (table *Table) After(process string, data interface{}, sid string) interface{} {
|
||||||
if process == "" {
|
if process == "" {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
response, err := gou.NewProcess(process, data).Exec()
|
response, err := gou.NewProcess(process, data).WithSID(sid).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
xlog.Println("Hook执行失败: ", err.Error(), maps.StrAny{"process": process, "data": data})
|
xlog.Println("Hook执行失败: ", err.Error(), maps.StrAny{"process": process, "data": data})
|
||||||
return data
|
return data
|
||||||
|
|
|
||||||
|
|
@ -48,5 +48,5 @@ func check(t *testing.T) {
|
||||||
for key := range Tables {
|
for key := range Tables {
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
assert.Equal(t, 8, len(keys))
|
assert.Equal(t, 9, len(keys))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
"name": "象传应用",
|
"name": "象传应用",
|
||||||
"short": "象传",
|
"short": "象传",
|
||||||
"description": "象传应用后台",
|
"description": "象传应用后台",
|
||||||
|
"option": {
|
||||||
|
"index": "/table/service"
|
||||||
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"default": "oss",
|
"default": "oss",
|
||||||
"oss": {
|
"oss": {
|
||||||
|
|
@ -14,6 +17,5 @@
|
||||||
},
|
},
|
||||||
"cos": {},
|
"cos": {},
|
||||||
"s3": {}
|
"s3": {}
|
||||||
},
|
}
|
||||||
"option": {}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
tests/flows/hooks/session.flow.json
Normal file
17
tests/flows/hooks/session.flow.json
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"label": "会话测试",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Before:Select",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "会话数据",
|
||||||
|
"process": "session.Dump"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "打印数据",
|
||||||
|
"process": "xiang.helper.Print",
|
||||||
|
"args": ["会话数据:", "{{$res.会话数据}}"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "{{$in}}"
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
"select": { "guard": "-" },
|
"select": { "guard": "-" },
|
||||||
"search": {
|
"search": {
|
||||||
"process": "models.service.Paginate",
|
"process": "models.service.Paginate",
|
||||||
"guard": "-",
|
|
||||||
"default": [null, null, 15]
|
"default": [null, null, 15]
|
||||||
},
|
},
|
||||||
"find": {
|
"find": {
|
||||||
|
|
|
||||||
305
tests/tables/session.json
Normal file
305
tests/tables/session.json
Normal file
|
|
@ -0,0 +1,305 @@
|
||||||
|
{
|
||||||
|
"name": "会话调试",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"decription": "会话调试",
|
||||||
|
"bind": {
|
||||||
|
"model": "service",
|
||||||
|
"withs": {
|
||||||
|
"manu": {
|
||||||
|
"query": {
|
||||||
|
"select": ["id", "name", "short_name", "status"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": {
|
||||||
|
"query": {
|
||||||
|
"select": ["id", "name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hooks": {
|
||||||
|
"before:search": "flows.hooks.session",
|
||||||
|
"after:search": "flows.hooks.session"
|
||||||
|
},
|
||||||
|
"apis": {
|
||||||
|
"search": {
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"wheres": [{ "column": "status", "value": "{{user_id}}" }],
|
||||||
|
"withs": { "manu": {}, "kind": {} }
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"服务名称": {
|
||||||
|
"label": "服务名称",
|
||||||
|
"view": {
|
||||||
|
"type": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "input",
|
||||||
|
"props": {
|
||||||
|
"value": ":name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"所属厂商": {
|
||||||
|
"label": "所属厂商",
|
||||||
|
"view": {
|
||||||
|
"name": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":manu.short_name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":manu.id",
|
||||||
|
"searchable": true,
|
||||||
|
"remote": {
|
||||||
|
"api": "/api/manu/get",
|
||||||
|
"query": {
|
||||||
|
"select": ["id", "name"],
|
||||||
|
"keyword": "where_name_like"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"服务类型": {
|
||||||
|
"label": "服务类型",
|
||||||
|
"view": {
|
||||||
|
"name": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":kind.name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":kind.id",
|
||||||
|
"tree": true,
|
||||||
|
"searchable": true,
|
||||||
|
"remote": {
|
||||||
|
"api": "/api/kind/tree",
|
||||||
|
"query": {
|
||||||
|
"select": ["id", "name"],
|
||||||
|
"keyword": "where_name_like"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"服务领域": {
|
||||||
|
"label": "服务领域",
|
||||||
|
"view": {
|
||||||
|
"name": "tags",
|
||||||
|
"props": {
|
||||||
|
"value": ":fields"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":fields",
|
||||||
|
"searchable": true,
|
||||||
|
"inputable": true,
|
||||||
|
"multiple": true,
|
||||||
|
"options": [
|
||||||
|
{ "label": "视频会议", "value": "视频会议" },
|
||||||
|
{ "label": "即时通信", "value": "即时通信" },
|
||||||
|
{ "label": "客服管理", "value": "客服管理" },
|
||||||
|
{ "label": "财务管理", "value": "财务管理" },
|
||||||
|
{ "label": "客户关系管理", "value": "客户关系管理" },
|
||||||
|
{ "label": "营销管理", "value": "营销管理" },
|
||||||
|
{ "label": "办公自动化", "value": "办公自动化" },
|
||||||
|
{ "label": "ERP", "value": "ERP" },
|
||||||
|
{ "label": "人力", "value": "人力" },
|
||||||
|
{ "label": "采购", "value": "采购" },
|
||||||
|
{ "label": "供应链", "value": "供应链" },
|
||||||
|
{ "label": "企业网盘", "value": "企业网盘" },
|
||||||
|
{ "label": "邮件服务", "value": "邮件服务" },
|
||||||
|
{ "label": "电子合同", "value": "电子合同" },
|
||||||
|
{ "label": "安全工具", "value": "安全工具" },
|
||||||
|
{ "label": "舆情分析", "value": "舆情分析" },
|
||||||
|
{ "label": "行业应用", "value": "行业应用" },
|
||||||
|
{ "label": "其他", "value": "其他" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"计费方式C": {
|
||||||
|
"label": "计费方式",
|
||||||
|
"view": {
|
||||||
|
"name": "xxxxx",
|
||||||
|
"components": { "label": {}, "image": {} }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"计费方式": {
|
||||||
|
"label": "计费方式",
|
||||||
|
"view": {
|
||||||
|
"name": "tags",
|
||||||
|
"props": {
|
||||||
|
"value": ":fields",
|
||||||
|
"format": [".jpg", "..."]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":price_options",
|
||||||
|
"multiple": true,
|
||||||
|
"options": [
|
||||||
|
{ "label": "按年订阅", "value": "按年订阅" },
|
||||||
|
{ "label": "按月订阅", "value": "按月订阅" },
|
||||||
|
{ "label": "按量计费", "value": "按量计费" },
|
||||||
|
{ "label": "私有化部署", "value": "私有化部署" },
|
||||||
|
{ "label": "其他", "value": "其他" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"行业覆盖": {
|
||||||
|
"label": "行业覆盖",
|
||||||
|
"view": {
|
||||||
|
"name": "tags",
|
||||||
|
"props": {
|
||||||
|
"value": ":industries"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":industries",
|
||||||
|
"inputable": true,
|
||||||
|
"multiple": true,
|
||||||
|
"options": [
|
||||||
|
{ "label": "房地产", "value": "房地产" },
|
||||||
|
{ "label": "旅游", "value": "旅游" },
|
||||||
|
{ "label": "教育", "value": "教育" },
|
||||||
|
{ "label": "互联网", "value": "互联网" },
|
||||||
|
{ "label": "其他", "value": "其他" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"状态": {
|
||||||
|
"label": "状态",
|
||||||
|
"view": {
|
||||||
|
"name": "tags",
|
||||||
|
"props": {
|
||||||
|
"value": ":status",
|
||||||
|
"options": [
|
||||||
|
{ "label": "开启", "value": "enabled", "color": "primary" },
|
||||||
|
{ "label": "关闭", "value": "disabled", "color": "danger" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "select",
|
||||||
|
"props": {
|
||||||
|
"value": ":status",
|
||||||
|
"options": [
|
||||||
|
{ "label": "开启", "value": "enabled" },
|
||||||
|
{ "label": "关闭", "value": "disabled" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"创建时间": {
|
||||||
|
"label": "创建时间",
|
||||||
|
"view": {
|
||||||
|
"name": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":created_at",
|
||||||
|
"datetime-format": "YYYY年MM月DD日 @hh:mm:ss"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"更新时间": {
|
||||||
|
"label": "更新时间",
|
||||||
|
"view": {
|
||||||
|
"name": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":update_at",
|
||||||
|
"datetime-format": "YYYY年MM月DD日 @hh:mm:ss"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"查询排序": {
|
||||||
|
"label": "查询排序",
|
||||||
|
"view": {
|
||||||
|
"type": "label",
|
||||||
|
"props": {
|
||||||
|
"value": ":rank"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"type": "input",
|
||||||
|
"props": {
|
||||||
|
"value": ":rank",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filters": {},
|
||||||
|
"list": {
|
||||||
|
"primary": "id",
|
||||||
|
"layout": {
|
||||||
|
"columns": [
|
||||||
|
{ "name": "服务名称", "width": 6 },
|
||||||
|
{ "name": "所属厂商", "width": 6 },
|
||||||
|
{ "name": "服务类型", "width": 4 },
|
||||||
|
{ "name": "状态", "width": 4 },
|
||||||
|
{ "name": "服务领域", "width": 4 },
|
||||||
|
{ "name": "计费方式", "width": 4 },
|
||||||
|
{ "name": "创建时间", "width": 6 },
|
||||||
|
{ "name": "更新时间", "width": 6 }
|
||||||
|
],
|
||||||
|
"filters": []
|
||||||
|
},
|
||||||
|
"actions": {}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"primary": "id",
|
||||||
|
"layout": {
|
||||||
|
"fieldset": [
|
||||||
|
{
|
||||||
|
"title": "基础信息",
|
||||||
|
"description": "",
|
||||||
|
"columns": [
|
||||||
|
{ "name": "服务名称", "width": 6 },
|
||||||
|
{ "name": "所属厂商", "width": 6 },
|
||||||
|
{ "name": "服务类型", "width": 6 },
|
||||||
|
{ "name": "状态", "width": 6 },
|
||||||
|
{ "name": "rank", "width": 6 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "数据标签",
|
||||||
|
"description": "",
|
||||||
|
"columns": ["服务领域", "计费方式", "行业覆盖"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"cancel": {},
|
||||||
|
"save": {
|
||||||
|
"type": "button",
|
||||||
|
"props": {
|
||||||
|
"label": "保存"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"insert": {},
|
||||||
|
"view": {}
|
||||||
|
}
|
||||||
45
user/user.go
45
user/user.go
|
|
@ -1,14 +1,15 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
|
"github.com/yaoapp/gou/session"
|
||||||
|
"github.com/yaoapp/kun/any"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/kun/maps"
|
"github.com/yaoapp/kun/maps"
|
||||||
"github.com/yaoapp/xiang/config"
|
"github.com/yaoapp/xiang/helper"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -52,6 +53,7 @@ func Auth(field string, value string, password string) maps.Map {
|
||||||
|
|
||||||
row := rows[0]
|
row := rows[0]
|
||||||
passwordHash := row.Get("password").(string)
|
passwordHash := row.Get("password").(string)
|
||||||
|
row.Del("password")
|
||||||
|
|
||||||
err = bcrypt.CompareHashAndPassword([]byte(passwordHash), []byte(password))
|
err = bcrypt.CompareHashAndPassword([]byte(passwordHash), []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -59,38 +61,23 @@ func Auth(field string, value string, password string) maps.Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
expiresAt := time.Now().Unix() + 3600
|
expiresAt := time.Now().Unix() + 3600
|
||||||
token := MakeToken(row, expiresAt)
|
|
||||||
row.Del("password")
|
// token := MakeToken(row, expiresAt)
|
||||||
|
sid := session.ID()
|
||||||
|
id := any.Of(row.Get("id")).CInt()
|
||||||
|
token := helper.JwtMake(id, map[string]interface{}{}, map[string]interface{}{
|
||||||
|
"expires_at": expiresAt,
|
||||||
|
"sid": sid,
|
||||||
|
})
|
||||||
|
session.Global().Expire(time.Duration(token.ExpiresAt)*time.Second).ID(sid).Set("user_id", id)
|
||||||
|
session.Global().ID(sid).Set("user", row)
|
||||||
|
|
||||||
// 读取菜单
|
// 读取菜单
|
||||||
menus := gou.NewProcess("flows.xiang.menu").Run()
|
menus := gou.NewProcess("flows.xiang.menu").Run()
|
||||||
return maps.Map{
|
return maps.Map{
|
||||||
"expires_at": expiresAt,
|
"expires_at": token.ExpiresAt,
|
||||||
"token": token,
|
"token": token.Token,
|
||||||
"user": row,
|
"user": row,
|
||||||
"menus": menus,
|
"menus": menus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeToken 生成 JWT Token
|
|
||||||
func MakeToken(row maps.Map, ExpiresAt int64) string {
|
|
||||||
claims := &JwtClaims{
|
|
||||||
ID: int(row.Get("id").(int64)),
|
|
||||||
Type: row.Get("type").(string),
|
|
||||||
Name: row.Get("name").(string),
|
|
||||||
StandardClaims: jwt.StandardClaims{
|
|
||||||
Id: fmt.Sprintf("%s_%d", row.Get("type"), row.Get("id")),
|
|
||||||
Subject: fmt.Sprintf("%d", row.Get("id")),
|
|
||||||
ExpiresAt: ExpiresAt,
|
|
||||||
Issuer: fmt.Sprintf("%d", row.Get("id")),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
||||||
tokenString, err := token.SignedString([]byte(config.Conf.JWT.Secret))
|
|
||||||
if err != nil {
|
|
||||||
exception.New("生成登录口令失败 %s", 500, err).Throw()
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokenString
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "数据表格接口API",
|
"description": "数据表格接口API",
|
||||||
"group": "xiang/table",
|
"group": "xiang/table",
|
||||||
"guard": "in-process",
|
"guard": "bearer-jwt",
|
||||||
"paths": [
|
"paths": [
|
||||||
{
|
{
|
||||||
"path": "/:name/search",
|
"path": "/:name/search",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue