From cdd3d507b881bfaa82fad7e26aeb4a54395245df Mon Sep 17 00:00:00 2001 From: John Date: Wed, 31 Oct 2018 22:39:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=B3=A8=E5=86=8C=E6=97=B6?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=B9=E6=B3=95=E5=AE=9A=E4=B9=89=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=9B=E6=A8=A1=E6=9D=BF=E5=BC=95=E6=93=8E=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0strlimit/hidestr/highlight/toupper/tolower/nl2br?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=A8=A1=E6=9D=BF=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/net/ghttp/ghttp_server.go | 2 +- .../ghttp/ghttp_server_service_controller.go | 22 ++++++- g/net/ghttp/ghttp_server_service_object.go | 30 +++++++-- g/os/gview/gview.go | 49 +++++++++++---- g/util/gstr/gstr.go | 61 ++++++++++++++++++- geg/net/ghttp/server/controller/user.go | 9 ++- geg/net/ghttp/server/object/user.go | 31 ++++++++++ geg/os/gview/build_in_funcs/build_in_funcs.go | 7 +++ geg/util/gstr/gstr_hidestr.go | 11 ++++ 9 files changed, 199 insertions(+), 23 deletions(-) create mode 100644 geg/net/ghttp/server/object/user.go create mode 100644 geg/util/gstr/gstr_hidestr.go diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index 2a4979588..954864822 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -276,7 +276,7 @@ func (s *Server) Start() error { // 打印展示路由表 func (s *Server) DumpRoutesMap() { - if s.config.DumpRouteMap { + if s.config.DumpRouteMap && len(s.routesMap) > 0 { // (等待一定时间后)当所有框架初始化信息打印完毕之后才打印路由表信息 gtime.SetTimeout(50*time.Millisecond, func() { glog.Header(false).Println(fmt.Sprintf("\n%s\n", s.GetRouteMap())) diff --git a/g/net/ghttp/ghttp_server_service_controller.go b/g/net/ghttp/ghttp_server_service_controller.go index 4455f4697..2580c7428 100644 --- a/g/net/ghttp/ghttp_server_service_controller.go +++ b/g/net/ghttp/ghttp_server_service_controller.go @@ -9,6 +9,7 @@ package ghttp import ( "errors" + "gitee.com/johng/gf/g/os/glog" "strings" "reflect" "fmt" @@ -42,6 +43,14 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e if mname == "Init" || mname == "Shut" || mname == "Exit" { continue } + if _, ok := v.Method(i).Interface().(func()); !ok { + if methodMap != nil { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String()) + glog.Warning(s) + return errors.New(s) + } + continue + } ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "") if ctlName[0] == '*' { ctlName = fmt.Sprintf(`(%s)`, ctlName) @@ -82,9 +91,15 @@ func (s *Server)BindControllerMethod(pattern string, c Controller, method string t := v.Type() sname := t.Elem().Name() mname := strings.TrimSpace(method) - if !v.MethodByName(mname).IsValid() { + fval := v.MethodByName(mname) + if !fval.IsValid() { return errors.New("invalid method name:" + mname) } + if _, ok := fval.Interface().(func()); !ok { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, fval.Type().String()) + glog.Warning(s) + return errors.New(s) + } pkgPath := t.Elem().PkgPath() pkgName := gfile.Basename(pkgPath) ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "") @@ -119,6 +134,11 @@ func (s *Server)BindControllerRest(pattern string, c Controller) error { if _, ok := s.methodsMap[method]; !ok { continue } + if _, ok := v.Method(i).Interface().(func()); !ok { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String()) + glog.Warning(s) + return errors.New(s) + } pkgName := gfile.Basename(pkgPath) ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "") if ctlName[0] == '*' { diff --git a/g/net/ghttp/ghttp_server_service_object.go b/g/net/ghttp/ghttp_server_service_object.go index 8603ab6f1..58e3cf246 100644 --- a/g/net/ghttp/ghttp_server_service_object.go +++ b/g/net/ghttp/ghttp_server_service_object.go @@ -9,6 +9,7 @@ package ghttp import ( "errors" + "gitee.com/johng/gf/g/os/glog" "strings" "reflect" "fmt" @@ -48,6 +49,15 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er if mname == "Init" || mname == "Shut" { continue } + faddr, ok := v.Method(i).Interface().(func(*Request)) + if !ok { + if methodMap != nil { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func(*Request))" is required`, v.Method(i).Type().String()) + glog.Warning(s) + return errors.New(s) + } + continue + } objName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "") if objName[0] == '*' { objName = fmt.Sprintf(`(%s)`, objName) @@ -58,7 +68,7 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er rtype : gROUTE_REGISTER_OBJECT, ctype : nil, fname : "", - faddr : v.Method(i).Interface().(func(*Request)), + faddr : faddr, finit : finit, fshut : fshut, } @@ -76,7 +86,7 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er rtype : gROUTE_REGISTER_OBJECT, ctype : nil, fname : "", - faddr : v.Method(i).Interface().(func(*Request)), + faddr : faddr, finit : finit, fshut : fshut, } @@ -97,6 +107,12 @@ func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string) if !fval.IsValid() { return errors.New("invalid method name:" + mname) } + faddr, ok := fval.Interface().(func(*Request)) + if !ok { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func(*Request)" is required`, fval.Type().String()) + glog.Warning(s) + return errors.New(s) + } finit := (func(*Request))(nil) fshut := (func(*Request))(nil) if v.MethodByName("Init").IsValid() { @@ -117,7 +133,7 @@ func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string) rtype : gROUTE_REGISTER_OBJECT, ctype : nil, fname : "", - faddr : fval.Interface().(func(*Request)), + faddr : faddr, finit : finit, fshut : fshut, } @@ -146,6 +162,12 @@ func (s *Server)BindObjectRest(pattern string, obj interface{}) error { if _, ok := s.methodsMap[method]; !ok { continue } + faddr, ok := v.Method(i).Interface().(func(*Request)) + if !ok { + s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String()) + glog.Warning(s) + return errors.New(s) + } pkgName := gfile.Basename(pkgPath) objName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "") if objName[0] == '*' { @@ -157,7 +179,7 @@ func (s *Server)BindObjectRest(pattern string, obj interface{}) error { rtype : gROUTE_REGISTER_OBJECT, ctype : nil, fname : "", - faddr : v.Method(i).Interface().(func(*Request)), + faddr : faddr, finit : finit, fshut : fshut, } diff --git a/g/os/gview/gview.go b/g/os/gview/gview.go index 011024b2d..76852c9cf 100644 --- a/g/os/gview/gview.go +++ b/g/os/gview/gview.go @@ -8,6 +8,7 @@ package gview import ( + "fmt" "gitee.com/johng/gf/g/encoding/gurl" "gitee.com/johng/gf/g/os/glog" "gitee.com/johng/gf/g/os/gtime" @@ -84,14 +85,18 @@ func New(path string) *View { view.BindFunc("html", view.funcHtmlEncode) view.BindFunc("htmlencode", view.funcHtmlEncode) view.BindFunc("htmldecode", view.funcHtmlDecode) - //view.BindFunc("htmlchars", view.funcHtmlChars) - //view.BindFunc("htmldechars", view.funcHtmlCharsDecode) view.BindFunc("url", view.funcUrlEncode) view.BindFunc("urlencode", view.funcUrlEncode) view.BindFunc("urldecode", view.funcUrlDecode) view.BindFunc("date", view.funcDate) view.BindFunc("substr", view.funcSubStr) + view.BindFunc("strlimit", view.funcStrLimit) view.BindFunc("compare", view.funcCompare) + view.BindFunc("hidestr", view.funcHideStr) + view.BindFunc("highlight", view.funcHighlight) + view.BindFunc("toupper", view.funcToUpper) + view.BindFunc("tolower", view.funcToLower) + view.BindFunc("nl2br", view.funcNl2Br) view.BindFunc("include", view.funcInclude) return view } @@ -256,16 +261,6 @@ func (view *View) funcHtmlDecode(html interface{}) string { return ghtml.EntitiesDecode(gconv.String(html)) } -// 模板内置方法:htmlchars -func (view *View) funcHtmlChars(html interface{}) string { - return ghtml.SpecialChars(gconv.String(html)) -} - -// 模板内置方法:htmlcharsdecode -func (view *View) funcHtmlCharsDecode(html interface{}) string { - return ghtml.SpecialCharsDecode(gconv.String(html)) -} - // 模板内置方法:url func (view *View) funcUrlEncode(url interface{}) string { return gurl.Encode(gconv.String(url)) @@ -295,4 +290,34 @@ func (view *View) funcSubStr(start, end int, str interface{}) string { return gstr.SubStr(gconv.String(str), start, end) } +// 模板内置方法:strlimit +func (view *View) funcStrLimit(length int, suffix string, str interface{}) string { + return gstr.StrLimit(gconv.String(str), length, suffix) +} + +// 模板内置方法:highlight +func (view *View) funcHighlight(key string, color string, str interface{}) string { + return gstr.Replace(gconv.String(str), key, fmt.Sprintf(`%s`, color, key)) +} + +// 模板内置方法:hidestr +func (view *View) funcHideStr(percent int, hide string, str interface{}) string { + return gstr.HideStr(gconv.String(str), percent, hide) +} + +// 模板内置方法:toupper +func (view *View) funcToUpper(str interface{}) string { + return gstr.ToUpper(gconv.String(str)) +} + +// 模板内置方法:toupper +func (view *View) funcToLower(str interface{}) string { + return gstr.ToLower(gconv.String(str)) +} + +// 模板内置方法:nl2br +func (view *View) funcNl2Br(str interface{}) string { + return gstr.Nl2Br(gconv.String(str)) +} + diff --git a/g/util/gstr/gstr.go b/g/util/gstr/gstr.go index dd788afe1..8decd74ba 100644 --- a/g/util/gstr/gstr.go +++ b/g/util/gstr/gstr.go @@ -7,11 +7,19 @@ // 字符串操作. package gstr -import "strings" +import ( + "bytes" + "math" + "strings" +) // 字符串替换 -func Replace(origin, search, replace string) string { - return strings.Replace(origin, search, replace, -1) +func Replace(origin, search, replace string, count...int) string { + n := -1 + if len(count) > 0 { + n = count[0] + } + return strings.Replace(origin, search, replace, n) } // 使用map进行字符串替换 @@ -120,4 +128,51 @@ func SubStr(str string, start int, length...int) (substr string) { } // 返回子串 return string(rs[start : end]) +} + +// 字符串长度截取限制,超过长度限制被截取并在字符串末尾追加指定的内容,支持中文 +func StrLimit(str string, length int, suffix...string) (string) { + rs := []rune(str) + if len(str) < length { + return str + } + addstr := "..." + if len(suffix) > 0 { + addstr = suffix[0] + } + return string(rs[0 : length]) + addstr +} + +// 按照百分比从字符串中间向两边隐藏字符(主要用于姓名、手机号、邮箱地址、身份证号等的隐藏),支持utf-8中文,支持email格式。 +func HideStr(str string, percent int, hide string) string { + array := strings.Split(str, "@") + if len(array) > 1 { + str = array[0] + } + rs := []rune(str) + length := len(rs) + mid := math.Floor(float64(length/2)) + hideLen := int(math.Floor(float64(length) * (float64(percent)/100))) + start := int(mid - math.Floor(float64(hideLen) / 2)) + hideStr := []rune("") + hideRune := []rune(hide) + for i := 0; i < int(hideLen); i++ { + hideStr = append(hideStr, hideRune...) + } + buffer := bytes.NewBuffer(nil) + buffer.WriteString(string(rs[0 : start])) + buffer.WriteString(string(hideStr)) + buffer.WriteString(string(rs[start + hideLen : ])) + if len(array) > 1 { + buffer.WriteString(array[1]) + } + return buffer.String() +} + +// 将\n\r替换为html中的
标签。 +func Nl2Br(str string) string { + str = Replace(str, "\r\n", "\n") + str = Replace(str, "\n\r", "\n") + str = Replace(str, "\n", "
") + return str } \ No newline at end of file diff --git a/geg/net/ghttp/server/controller/user.go b/geg/net/ghttp/server/controller/user.go index f0283ec90..50db001c9 100644 --- a/geg/net/ghttp/server/controller/user.go +++ b/geg/net/ghttp/server/controller/user.go @@ -1,8 +1,8 @@ package main import ( - "gitee.com/johng/gf/g/frame/gmvc" "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/frame/gmvc" ) type User struct { @@ -13,8 +13,13 @@ func (c *User) Index() { c.View.Display("index.html") } +// 不符合规范,不会被自动注册 +func (c *User) Test(value interface{}) { + c.View.Display("index.html") +} + func main() { - g.View().SetPath("C:/www/static") + //g.View().SetPath("C:/www/static") s := g.Server() s.BindController("/user", new(User)) s.SetPort(8199) diff --git a/geg/net/ghttp/server/object/user.go b/geg/net/ghttp/server/object/user.go new file mode 100644 index 000000000..cd39824c8 --- /dev/null +++ b/geg/net/ghttp/server/object/user.go @@ -0,0 +1,31 @@ +package main + +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/net/ghttp" +) + +type User struct { + +} + +func (c *User) Index(r *ghttp.Request) { + r.Response.Write("Index") +} + +// 不符合规范,不会被注册 +func (c *User) Test(r *ghttp.Request, value interface{}) { + r.Response.Write("Test") +} + +func main() { + s := g.Server() + s.BindObjectMethod("/user", new(User), "Test") + s.SetPort(8199) + s.Run() +} + + + + + diff --git a/geg/os/gview/build_in_funcs/build_in_funcs.go b/geg/os/gview/build_in_funcs/build_in_funcs.go index 462b8d763..d39c683dd 100644 --- a/geg/os/gview/build_in_funcs/build_in_funcs.go +++ b/geg/os/gview/build_in_funcs/build_in_funcs.go @@ -20,6 +20,13 @@ func main() { {{compare 1 1}} {{"我是中国人" | substr 2 -1}} {{"我是中国人" | substr 2 2}} +{{"我是中国人" | strlimit 2 "..."}} +{{"热爱GF热爱生活" | hidestr 20 "*"}} +{{"热爱GF热爱生活" | hidestr 50 "*"}} +{{"热爱GF热爱生活" | highlight "GF" "red"}} +{{"gf" | toupper}} +{{"GF" | tolower}} +{{"Go\nFrame" | nl2br}} ` content, err := g.View().ParseContent(tplContent, nil) fmt.Println(err) diff --git a/geg/util/gstr/gstr_hidestr.go b/geg/util/gstr/gstr_hidestr.go new file mode 100644 index 000000000..3cc38d4f2 --- /dev/null +++ b/geg/util/gstr/gstr_hidestr.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + "gitee.com/johng/gf/g/util/gstr" +) + +func main() { + fmt.Println(gstr.HideStr("热爱GF热爱生活", 20, "*")) + fmt.Println(gstr.HideStr("热爱GF热爱生活", 50, "*")) +}