mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-01-23 10:50:24 +08:00
commit
8be411061f
@ -104,6 +104,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
## 感谢(排名不分先后)
|
## 感谢(排名不分先后)
|
||||||
> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf)
|
> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf)
|
||||||
>
|
>
|
||||||
@ -118,17 +119,11 @@
|
|||||||
> gopay [https://github.com/go-pay/gopay](https://github.com/go-pay/gopay)
|
> gopay [https://github.com/go-pay/gopay](https://github.com/go-pay/gopay)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 交流QQ群
|
## 交流QQ群
|
||||||
交流群①:190966648 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=mJafkvme3VNyiQlCFIFNRtY8Xlr7pj9U&jump_from=webapi&authKey=jL10vIESr+vO8wpxwyd6DlChzkrbHpzN9uhAsIHgAinL/Vvd+nvuRyilf2UqUlCy"><img border="0" src="https://bufanyun.cn-bj.ufileos.com/hotgo/group.png" alt="HotGo框架交流1群" title="HotGo框架交流1群"></a>
|
交流群①:190966648 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=mJafkvme3VNyiQlCFIFNRtY8Xlr7pj9U&jump_from=webapi&authKey=jL10vIESr+vO8wpxwyd6DlChzkrbHpzN9uhAsIHgAinL/Vvd+nvuRyilf2UqUlCy"><img border="0" src="https://bufanyun.cn-bj.ufileos.com/hotgo/group.png" alt="HotGo框架交流1群" title="HotGo框架交流1群"></a>
|
||||||
> <img src="https://bufanyun.cn-bj.ufileos.com/hotgo/hotgo1qun.png" width="400px"/>
|
> <img src="https://bufanyun.cn-bj.ufileos.com/hotgo/hotgo1qun.png" width="400px"/>
|
||||||
|
|
||||||
|
|
||||||
> 感谢你使用HotGo,公司团队精力时间有限,因此我们不再提供免费的技术服务!
|
|
||||||
>
|
|
||||||
> 同时您也可以联系我们,雇佣我们团队为您干活,谢谢合作!
|
|
||||||
|
|
||||||
|
|
||||||
## 商用说明
|
## 商用说明
|
||||||
|
|
||||||
> HotGo 是开源免费的,遵循 MIT 开源协议,意味着您无需支付任何费用,也无需授权,即可将它应用到您的产品中。
|
> HotGo 是开源免费的,遵循 MIT 开源协议,意味着您无需支付任何费用,也无需授权,即可将它应用到您的产品中。
|
||||||
|
@ -67,8 +67,8 @@
|
|||||||
| --- xxx插件 | 插件模块名称 |
|
| --- xxx插件 | 插件模块名称 |
|
||||||
| --- --- api | 对外接口。提供服务的输入/输出数据结构定义 |
|
| --- --- api | 对外接口。提供服务的输入/输出数据结构定义 |
|
||||||
| --- --- --- admin | 后台接口 |
|
| --- --- --- admin | 后台接口 |
|
||||||
| --- --- --- api | 前台通用接口,包含PC页面、uinapp接口等 |
|
| --- --- --- api | 前台通用接口,包含PC端、移动端接口等 |
|
||||||
| --- --- --- home | 前台PC端页面 |
|
| --- --- --- home | 前台PC端、H5端页面 |
|
||||||
| --- --- --- websocket | 可同时为多应用提供websocket接口 |
|
| --- --- --- websocket | 可同时为多应用提供websocket接口 |
|
||||||
| --- --- controller | 接收/解析用户输入参数的入口/接口层,也可以理解为控制器 |
|
| --- --- controller | 接收/解析用户输入参数的入口/接口层,也可以理解为控制器 |
|
||||||
| --- --- crons | 项目中由系统统一接管的定时任务处理 |
|
| --- --- crons | 项目中由系统统一接管的定时任务处理 |
|
||||||
@ -83,8 +83,8 @@
|
|||||||
| --- main.go | 插件始化文件和模块插拔接口 |
|
| --- main.go | 插件始化文件和模块插拔接口 |
|
||||||
| **api** | 对外接口。提供服务的输入/输出数据结构定义 |
|
| **api** | 对外接口。提供服务的输入/输出数据结构定义 |
|
||||||
| --- admin | 后台接口 |
|
| --- admin | 后台接口 |
|
||||||
| --- api | 前台通用接口,包含PC页面、uinapp接口等 |
|
| --- api | 前台通用接口,包含PC端、移动端接口等 |
|
||||||
| --- home | 前台PC端页面 |
|
| --- home | 前台PC端、H5端页面 |
|
||||||
| --- websocket | 可同时为多应用提供websocket接口 |
|
| --- websocket | 可同时为多应用提供websocket接口 |
|
||||||
| **hack** | 存放项目开发工具、脚本等内容例如,CLI工具的配置,各种shell/bat脚本等文件 |
|
| **hack** | 存放项目开发工具、脚本等内容例如,CLI工具的配置,各种shell/bat脚本等文件 |
|
||||||
| **internal** | 业务逻辑存放目录通过Golang internal特性对外部隐藏可见性 |
|
| **internal** | 业务逻辑存放目录通过Golang internal特性对外部隐藏可见性 |
|
||||||
|
@ -105,18 +105,7 @@ func (s *sSysTable) List(ctx context.Context, in sysin.TableListInp) (list []*sy
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
////关联表select
|
if err = mod.Fields(sysin.TableListModel{}).Page(in.Page, in.PerPage).OrderAsc(dao.AddonHgexampleTable.Columns().Sort).OrderDesc(dao.AddonHgexampleTable.Columns().Id).Scan(&list); err != nil {
|
||||||
//fields, err := hgorm.GenJoinSelect(ctx, sysin.TableListModel{}, dao.AddonHgexampleTable, []*hgorm.Join{
|
|
||||||
// {Dao: dao.AddonHgexampleTableCategory, Alias: "testCategory"},
|
|
||||||
// //{Dao: dao.AddonHgexampleTableCategory, Alias: "testCategory"},
|
|
||||||
//})
|
|
||||||
|
|
||||||
fields, err := hgorm.GenSelect(ctx, sysin.TableListModel{}, dao.AddonHgexampleTable)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = mod.Fields(fields).Page(in.Page, in.PerPage).OrderAsc(dao.AddonHgexampleTable.Columns().Sort).OrderDesc(dao.AddonHgexampleTable.Columns().Id).Scan(&list); err != nil {
|
|
||||||
err = gerror.Wrap(err, consts.ErrorORM)
|
err = gerror.Wrap(err, consts.ErrorORM)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -154,7 +143,7 @@ func (s *sSysTable) Export(ctx context.Context, in sysin.TableListInp) (err erro
|
|||||||
|
|
||||||
// Edit 修改/新增
|
// Edit 修改/新增
|
||||||
func (s *sSysTable) Edit(ctx context.Context, in sysin.TableEditInp) (err error) {
|
func (s *sSysTable) Edit(ctx context.Context, in sysin.TableEditInp) (err error) {
|
||||||
if err = hgorm.IsUnique(ctx, dao.AddonHgexampleTable, g.Map{dao.AddonHgexampleTable.Columns().Qq: in.Qq}, "QQ号码已存在,请换一个", in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.AddonHgexampleTable, g.Map{dao.AddonHgexampleTable.Columns().Qq: in.Qq}, "QQ号码已存在,请换一个", in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,10 @@ type NotifyAliPayReq struct {
|
|||||||
g.Meta `path:"/pay/notify/alipay" method:"post" tags:"支付异步通知" summary:"支付宝回调"`
|
g.Meta `path:"/pay/notify/alipay" method:"post" tags:"支付异步通知" summary:"支付宝回调"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotifyAliPayRes payin.PayNotifyModel
|
type NotifyAliPayRes struct {
|
||||||
|
g.Meta `mime:"text/html" type:"string" example:"<html/>"`
|
||||||
|
payin.PayNotifyModel
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyWxPayReq 微信支付回调
|
// NotifyWxPayReq 微信支付回调
|
||||||
type NotifyWxPayReq struct {
|
type NotifyWxPayReq struct {
|
||||||
@ -24,4 +27,7 @@ type NotifyQQPayReq struct {
|
|||||||
g.Meta `path:"/pay/notify/qqpay" method:"post" tags:"支付异步通知" summary:"QQ支付回调"`
|
g.Meta `path:"/pay/notify/qqpay" method:"post" tags:"支付异步通知" summary:"QQ支付回调"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotifyQQPayRes payin.PayNotifyModel
|
type NotifyQQPayRes struct {
|
||||||
|
g.Meta `mime:"text/xml" type:"string" example:"<html/>"`
|
||||||
|
payin.PayNotifyModel
|
||||||
|
}
|
||||||
|
@ -11,8 +11,9 @@ import (
|
|||||||
|
|
||||||
type HelloReq struct {
|
type HelloReq struct {
|
||||||
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
|
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
|
||||||
|
Name string `json:"name" d:"hotgo" dc:"名字"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HelloRes struct {
|
type HelloRes struct {
|
||||||
g.Meta `mime:"text/html" example:"string"`
|
Tips string `json:"tips"`
|
||||||
}
|
}
|
||||||
|
8
server/internal/consts/http.go
Normal file
8
server/internal/consts/http.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package consts
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTPContentTypeXml = "text/xml"
|
||||||
|
HTTPContentTypeHtml = "text/html"
|
||||||
|
HTTPContentTypeStream = "text/event-stream"
|
||||||
|
HTTPContentTypeJson = "application/json"
|
||||||
|
)
|
@ -7,8 +7,10 @@ package pay
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"hotgo/api/api/pay"
|
"hotgo/api/api/pay"
|
||||||
"hotgo/internal/consts"
|
"hotgo/internal/consts"
|
||||||
|
"hotgo/internal/library/response"
|
||||||
"hotgo/internal/model/input/payin"
|
"hotgo/internal/model/input/payin"
|
||||||
"hotgo/internal/service"
|
"hotgo/internal/service"
|
||||||
)
|
)
|
||||||
@ -21,32 +23,35 @@ type cNotify struct{}
|
|||||||
|
|
||||||
// AliPay 支付宝回调
|
// AliPay 支付宝回调
|
||||||
func (c *cNotify) AliPay(ctx context.Context, _ *pay.NotifyAliPayReq) (res *pay.NotifyAliPayRes, err error) {
|
func (c *cNotify) AliPay(ctx context.Context, _ *pay.NotifyAliPayReq) (res *pay.NotifyAliPayRes, err error) {
|
||||||
_, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeAliPay})
|
if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeAliPay}); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res = &pay.NotifyAliPayRes{PayType: consts.PayTypeAliPay, Message: "success"}
|
|
||||||
|
response.RText(g.RequestFromCtx(ctx), "success")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WxPay 微信支付回调
|
// WxPay 微信支付回调
|
||||||
func (c *cNotify) WxPay(ctx context.Context, _ *pay.NotifyWxPayReq) (res *pay.NotifyWxPayRes, err error) {
|
func (c *cNotify) WxPay(ctx context.Context, _ *pay.NotifyWxPayReq) (res *pay.NotifyWxPayRes, err error) {
|
||||||
_, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeWxPay})
|
if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeWxPay}); err != nil {
|
||||||
if err != nil {
|
return
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = &pay.NotifyWxPayRes{PayType: consts.PayTypeWxPay, Code: "SUCCESS", Message: "收单成功"}
|
response.CustomJson(g.RequestFromCtx(ctx), `{"code": "SUCCESS","message": "收单成功"}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// QQPay QQ支付回调
|
// QQPay QQ支付回调
|
||||||
func (c *cNotify) QQPay(ctx context.Context, _ *pay.NotifyQQPayReq) (res *pay.NotifyQQPayRes, err error) {
|
func (c *cNotify) QQPay(ctx context.Context, _ *pay.NotifyQQPayReq) (res *pay.NotifyQQPayRes, err error) {
|
||||||
_, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeQQPay})
|
if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeQQPay}); err != nil {
|
||||||
if err != nil {
|
return
|
||||||
return nil, err
|
}
|
||||||
}
|
|
||||||
|
r := g.RequestFromCtx(ctx)
|
||||||
res = &pay.NotifyQQPayRes{PayType: consts.PayTypeQQPay, Message: "SUCCESS"}
|
r.Response.ClearBuffer()
|
||||||
|
r.Response.Write(`<?xml version="1.0" encoding="UTF-8"?>`)
|
||||||
|
r.Response.WriteXml(g.Map{
|
||||||
|
"return_code": "SUCCESS",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"fmt"
|
||||||
"hotgo/api/api/user"
|
"hotgo/api/api/user"
|
||||||
|
"hotgo/utility/simple"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -17,7 +18,9 @@ var (
|
|||||||
|
|
||||||
type cHello struct{}
|
type cHello struct{}
|
||||||
|
|
||||||
func (c *cHello) Hello(ctx context.Context, _ *user.HelloReq) (res *user.HelloRes, err error) {
|
func (c *cHello) Hello(ctx context.Context, req *user.HelloReq) (res *user.HelloRes, err error) {
|
||||||
g.RequestFromCtx(ctx).Response.Writeln("Hello World api member!")
|
res = &user.HelloRes{
|
||||||
|
Tips: fmt.Sprintf("hello %v, this is the api for %v applications.", req.Name, simple.AppName(ctx)),
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
28
server/internal/library/cache/file/file.go
vendored
28
server/internal/library/cache/file/file.go
vendored
@ -71,15 +71,37 @@ func (c *AdapterFile) Get(ctx context.Context, key interface{}) (*gvar.Var, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *AdapterFile) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) {
|
func (c *AdapterFile) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) {
|
||||||
return nil, gerror.New("implement me")
|
result, err = c.Get(ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if result.IsNil() {
|
||||||
|
return gvar.New(value), c.Set(ctx, key, value, duration)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AdapterFile) GetOrSetFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
|
func (c *AdapterFile) GetOrSetFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
|
||||||
return nil, gerror.New("implement me")
|
v, err := c.Get(ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if v.IsNil() {
|
||||||
|
value, err := f(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if value == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return gvar.New(value), c.Set(ctx, key, value, duration)
|
||||||
|
} else {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AdapterFile) GetOrSetFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
|
func (c *AdapterFile) GetOrSetFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
|
||||||
return nil, gerror.New("implement me")
|
return c.GetOrSetFunc(ctx, key, f, duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AdapterFile) Contains(ctx context.Context, key interface{}) (bool, error) {
|
func (c *AdapterFile) Contains(ctx context.Context, key interface{}) (bool, error) {
|
||||||
|
@ -19,11 +19,11 @@ const (
|
|||||||
LogicWhereComments = "\n\t// 查询%s\n"
|
LogicWhereComments = "\n\t// 查询%s\n"
|
||||||
LogicWhereNoSupport = "\t// TODO 暂不支持生成[ %s ]查询方式,请自行补充此处代码!"
|
LogicWhereNoSupport = "\t// TODO 暂不支持生成[ %s ]查询方式,请自行补充此处代码!"
|
||||||
LogicListSimpleSelect = "\tfields, err := hgorm.GenSelect(ctx, sysin.%sListModel{}, dao.%s)\n\tif err != nil {\n\t\treturn\n\t}"
|
LogicListSimpleSelect = "\tfields, err := hgorm.GenSelect(ctx, sysin.%sListModel{}, dao.%s)\n\tif err != nil {\n\t\treturn\n\t}"
|
||||||
LogicListJoinSelect = "\t//关联表select\n\tfields, err := hgorm.GenJoinSelect(ctx, %sin.%sListModel{}, dao.%s, []*hgorm.Join{\n%v\t})\n\n\tif err != nil {\n\t\terr = gerror.Wrap(err, \"获取%s关联字段失败,请稍后重试!\")\n\t\treturn\n\t}"
|
LogicListJoinSelect = "\t//关联表select\n\tfields, err := hgorm.GenJoinSelect(ctx, %sin.%sListModel{}, &dao.%s, []*hgorm.Join{\n%v\t})\n\n\tif err != nil {\n\t\terr = gerror.Wrap(err, \"获取%s关联字段失败,请稍后重试!\")\n\t\treturn\n\t}"
|
||||||
LogicListJoinOnRelation = "\t// 关联表%s\n\tmod = mod.%s(hgorm.GenJoinOnRelation(\n\t\tdao.%s.Table(), dao.%s.Columns().%s, // 主表表名,关联字段\n\t\tdao.%s.Table(), \"%s\", dao.%s.Columns().%s, // 关联表表名,别名,关联字段\n\t)...)\n\n"
|
LogicListJoinOnRelation = "\t// 关联表%s\n\tmod = mod.%s(hgorm.GenJoinOnRelation(\n\t\tdao.%s.Table(), dao.%s.Columns().%s, // 主表表名,关联字段\n\t\tdao.%s.Table(), \"%s\", dao.%s.Columns().%s, // 关联表表名,别名,关联字段\n\t)...)\n\n"
|
||||||
LogicEditUpdate = "\tif _, err = s.Model(ctx%s).\n\t\t\tFields(%sin.%sUpdateFields{}).\n\t\t\tWherePri(in.%s).Data(in).Update(); err != nil {\n\t\t\terr = gerror.Wrap(err, \"修改%s失败,请稍后重试!\")\n\t\t}\n\t\treturn"
|
LogicEditUpdate = "\tif _, err = s.Model(ctx%s).\n\t\t\tFields(%sin.%sUpdateFields{}).\n\t\t\tWherePri(in.%s).Data(in).Update(); err != nil {\n\t\t\terr = gerror.Wrap(err, \"修改%s失败,请稍后重试!\")\n\t\t}\n\t\treturn"
|
||||||
LogicEditInsert = "\tif _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).\n\t\tFields(%sin.%sInsertFields{}).\n\t\tData(in).Insert(); err != nil {\n\t\terr = gerror.Wrap(err, \"新增%s失败,请稍后重试!\")\n\t}"
|
LogicEditInsert = "\tif _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).\n\t\tFields(%sin.%sInsertFields{}).\n\t\tData(in).Insert(); err != nil {\n\t\terr = gerror.Wrap(err, \"新增%s失败,请稍后重试!\")\n\t}"
|
||||||
LogicEditUnique = "\t// 验证'%s'唯一\n\tif err = hgorm.IsUnique(ctx, dao.%s, g.Map{dao.%s.Columns().%s: in.%s}, \"%s已存在\", in.Id); err != nil {\n\t\treturn\n\t}\n"
|
LogicEditUnique = "\t// 验证'%s'唯一\n\tif err = hgorm.IsUnique(ctx, &dao.%s, g.Map{dao.%s.Columns().%s: in.%s}, \"%s已存在\", in.Id); err != nil {\n\t\treturn\n\t}\n"
|
||||||
LogicSwitchUpdate = "g.Map{\n\t\tin.Key: in.Value,\n%s}"
|
LogicSwitchUpdate = "g.Map{\n\t\tin.Key: in.Value,\n%s}"
|
||||||
LogicStatusUpdate = "g.Map{\n\t\tdao.%s.Columns().Status: in.Status,\n%s}"
|
LogicStatusUpdate = "g.Map{\n\t\tdao.%s.Columns().Status: in.Status,\n%s}"
|
||||||
)
|
)
|
||||||
@ -133,7 +133,7 @@ func (l *gCurd) generateLogicListJoin(ctx context.Context, in *CurdPreviewInput)
|
|||||||
|
|
||||||
for _, join := range in.options.Join {
|
for _, join := range in.options.Join {
|
||||||
if isEffectiveJoin(join) {
|
if isEffectiveJoin(join) {
|
||||||
joinSelectRows = joinSelectRows + fmt.Sprintf("\t\t{Dao: dao.%s, Alias: \"%s\"},\n", join.DaoName, join.Alias)
|
joinSelectRows = joinSelectRows + fmt.Sprintf("\t\t{Dao: &dao.%s, Alias: \"%s\"},\n", join.DaoName, join.Alias)
|
||||||
linkBuffer.WriteString(fmt.Sprintf(LogicListJoinOnRelation, join.Alias, consts.GenCodesJoinLinkMap[join.LinkMode], in.In.DaoName, in.In.DaoName, gstr.CaseCamel(join.MasterField), join.DaoName, join.Alias, join.DaoName, gstr.CaseCamel(join.Field)))
|
linkBuffer.WriteString(fmt.Sprintf(LogicListJoinOnRelation, join.Alias, consts.GenCodesJoinLinkMap[join.LinkMode], in.In.DaoName, in.In.DaoName, gstr.CaseCamel(join.MasterField), join.DaoName, join.Alias, join.DaoName, gstr.CaseCamel(join.Field)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,11 +143,9 @@ func (l *gCurd) generateLogicListJoin(ctx context.Context, in *CurdPreviewInput)
|
|||||||
data["select"] = selectBuffer.String()
|
data["select"] = selectBuffer.String()
|
||||||
data["fields"] = "fields"
|
data["fields"] = "fields"
|
||||||
data["link"] = linkBuffer.String()
|
data["link"] = linkBuffer.String()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
data["fields"] = fmt.Sprintf("%sin.%sListModel{}", in.options.TemplateGroup, in.In.VarName)
|
data["fields"] = fmt.Sprintf("%sin.%sListModel{}", in.options.TemplateGroup, in.In.VarName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +163,6 @@ func (l *gCurd) generateLogicListWhere(ctx context.Context, in *CurdPreviewInput
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ package hgorm
|
|||||||
// dao.
|
// dao.
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gogf/gf/v2/database/gdb"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
@ -25,56 +24,41 @@ type daoInstance interface {
|
|||||||
|
|
||||||
// Join 关联表属性
|
// Join 关联表属性
|
||||||
type Join struct {
|
type Join struct {
|
||||||
Dao interface{} // 关联表dao实例
|
Dao daoInstance // 关联表dao实例
|
||||||
Alias string // 别名
|
Alias string // 别名
|
||||||
fields map[string]*gdb.TableField // 表字段列表
|
fields map[string]*gdb.TableField // 表字段列表
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenJoinOnRelation 生成关联表关联条件
|
// GenJoinOnRelation 生成关联表关联条件
|
||||||
func GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField string) []string {
|
func GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField string) []string {
|
||||||
return []string{
|
relation := fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", alias, onField, masterTable, masterField)
|
||||||
joinTable,
|
return []string{joinTable, alias, relation}
|
||||||
alias,
|
|
||||||
fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", alias, onField, masterTable, masterField),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenJoinSelect 生成关联表select
|
// GenJoinSelect 生成关联表select
|
||||||
// 这里会将实体中的字段驼峰转为下划线于数据库进行匹配,意味着数据库字段必须全部是小写字母+下划线的格式
|
// 这里会将实体中的字段驼峰转为下划线于数据库进行匹配,意味着数据库字段必须全部是小写字母+下划线的格式
|
||||||
func GenJoinSelect(ctx context.Context, entity interface{}, masterDao interface{}, joins []*Join) (allFields string, err error) {
|
func GenJoinSelect(ctx context.Context, entity interface{}, dao daoInstance, joins []*Join) (allFields string, err error) {
|
||||||
var tmpFields []string
|
var tmpFields []string
|
||||||
|
|
||||||
md, ok := masterDao.(daoInstance)
|
|
||||||
if !ok {
|
|
||||||
err = errors.New("masterDao unimplemented interface format.daoInstance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(joins) == 0 {
|
if len(joins) == 0 {
|
||||||
err = errors.New("JoinFields joins len = 0")
|
err = gerror.New("JoinFields joins len = 0")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range joins {
|
for _, v := range joins {
|
||||||
jd, ok := v.Dao.(daoInstance)
|
v.fields, err = v.Dao.Ctx(ctx).TableFields(v.Dao.Table())
|
||||||
if !ok {
|
|
||||||
err = errors.New("joins index unimplemented interface format.daoInstance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
v.fields, err = jd.Ctx(ctx).TableFields(jd.Table())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
masterFields, err := md.Ctx(ctx).TableFields(md.Table())
|
masterFields, err := dao.Ctx(ctx).TableFields(dao.Table())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
entityFields, err := convert.GetEntityFieldTags(entity)
|
entityFields, err := convert.GetEntityFieldTags(entity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(entityFields) == 0 {
|
if len(entityFields) == 0 {
|
||||||
@ -104,42 +88,7 @@ func GenJoinSelect(ctx context.Context, entity interface{}, masterDao interface{
|
|||||||
// 主表
|
// 主表
|
||||||
originalField := gstr.CaseSnakeFirstUpper(field)
|
originalField := gstr.CaseSnakeFirstUpper(field)
|
||||||
if _, ok := masterFields[originalField]; ok {
|
if _, ok := masterFields[originalField]; ok {
|
||||||
tmpFields = append(tmpFields, fmt.Sprintf("`%s`.`%s`", md.Table(), originalField))
|
tmpFields = append(tmpFields, fmt.Sprintf("`%s`.`%s`", dao.Table(), originalField))
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gstr.Implode(",", convert.UniqueSlice(tmpFields)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenSelect 生成select
|
|
||||||
// 这里会将实体中的字段驼峰转为下划线于数据库进行匹配,意味着数据库字段必须全部是小写字母+下划线的格式
|
|
||||||
func GenSelect(ctx context.Context, entity interface{}, dao interface{}) (allFields string, err error) {
|
|
||||||
var tmpFields []string
|
|
||||||
|
|
||||||
md, ok := dao.(daoInstance)
|
|
||||||
if !ok {
|
|
||||||
err = errors.New("dao unimplemented interface format.daoInstance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fields, err := md.Ctx(ctx).TableFields(md.Table())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
entityFields, err := convert.GetEntityFieldTags(entity)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(entityFields) == 0 {
|
|
||||||
return "*", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, field := range entityFields {
|
|
||||||
originalField := gstr.CaseSnakeFirstUpper(field)
|
|
||||||
if _, ok := fields[originalField]; ok {
|
|
||||||
tmpFields = append(tmpFields, fmt.Sprintf("`%s`", originalField))
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +102,7 @@ func GetPkField(ctx context.Context, dao daoInstance) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
return "", errors.New("field not found")
|
return "", gerror.New("field not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
@ -161,23 +110,18 @@ func GetPkField(ctx context.Context, dao daoInstance) (string, error) {
|
|||||||
return field.Name, nil
|
return field.Name, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", errors.New("no primary key")
|
return "", gerror.New("no primary key")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUnique 是否唯一
|
// IsUnique 是否唯一
|
||||||
func IsUnique(ctx context.Context, dao interface{}, where g.Map, message string, pkId ...interface{}) error {
|
func IsUnique(ctx context.Context, dao daoInstance, where g.Map, message string, pkId ...interface{}) error {
|
||||||
d, ok := dao.(daoInstance)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("IsUnique dao unimplemented interface format.daoInstance")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(where) == 0 {
|
if len(where) == 0 {
|
||||||
return errors.New("where condition cannot be empty")
|
return gerror.New("where condition cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
m := d.Ctx(ctx).Where(where)
|
m := dao.Ctx(ctx).Where(where)
|
||||||
if len(pkId) > 0 {
|
if len(pkId) > 0 {
|
||||||
field, err := GetPkField(ctx, d)
|
field, err := GetPkField(ctx, dao)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -192,32 +136,28 @@ func IsUnique(ctx context.Context, dao interface{}, where g.Map, message string,
|
|||||||
if count > 0 {
|
if count > 0 {
|
||||||
if message == "" {
|
if message == "" {
|
||||||
for k := range where {
|
for k := range where {
|
||||||
message = fmt.Sprintf("in the table:%s, %v not uniqued", d.Table(), where[k])
|
message = fmt.Sprintf("in the table:%s, %v not uniqued", dao.Table(), where[k])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.New(message)
|
return gerror.New(message)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenSubTree 生成下级关系树
|
// GenSubTree 生成下级关系树
|
||||||
func GenSubTree(ctx context.Context, dao interface{}, oldPid int64) (newPid int64, newLevel int, subTree string, err error) {
|
func GenSubTree(ctx context.Context, dao daoInstance, oldPid int64) (newPid int64, newLevel int, subTree string, err error) {
|
||||||
// 顶级树
|
// 顶级树
|
||||||
if oldPid <= 0 {
|
if oldPid <= 0 {
|
||||||
return 0, 1, "", nil
|
return 0, 1, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
d, ok := dao.(daoInstance)
|
field, err := GetPkField(ctx, dao)
|
||||||
if !ok {
|
|
||||||
return 0, 0, "", errors.New("GenTree dao unimplemented interface format.daoInstance")
|
|
||||||
}
|
|
||||||
field, err := GetPkField(ctx, d)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, "", err
|
return 0, 0, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
models, err := d.Ctx(ctx).Where(field, oldPid).One()
|
models, err := dao.Ctx(ctx).Where(field, oldPid).One()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, "", err
|
return 0, 0, "", err
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/gogf/gf/v2/errors/gcode"
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
"hotgo/internal/library/contexts"
|
"hotgo/internal/library/contexts"
|
||||||
"hotgo/internal/model"
|
"hotgo/internal/model"
|
||||||
"time"
|
"time"
|
||||||
@ -50,22 +51,23 @@ func RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
|
|||||||
contexts.SetResponse(r.Context(), res)
|
contexts.SetResponse(r.Context(), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SusJson 返回成功JSON
|
// CustomJson 自定义JSON
|
||||||
func SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
func CustomJson(r *ghttp.Request, content interface{}) {
|
||||||
if isExit {
|
// 清空响应
|
||||||
JsonExit(r, gcode.CodeOK.Code(), message, data...)
|
r.Response.ClearBuffer()
|
||||||
return
|
|
||||||
}
|
|
||||||
RJson(r, gcode.CodeOK.Code(), message, data...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FailJson 返回失败JSON
|
// 写入响应
|
||||||
func FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
r.Response.WriteJson(content)
|
||||||
if isExit {
|
|
||||||
JsonExit(r, gcode.CodeNil.Code(), message, data...)
|
// 加入到上下文
|
||||||
return
|
contexts.SetResponse(r.Context(), &model.Response{
|
||||||
}
|
Code: 0,
|
||||||
RJson(r, gcode.CodeNil.Code(), message, data...)
|
Message: "",
|
||||||
|
Data: content,
|
||||||
|
Error: nil,
|
||||||
|
Timestamp: gtime.Timestamp(),
|
||||||
|
TraceID: gctx.CtxId(r.Context()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect 重定向
|
// Redirect 重定向
|
||||||
@ -73,11 +75,6 @@ func Redirect(r *ghttp.Request, location string, code ...int) {
|
|||||||
r.Response.RedirectTo(location, code...)
|
r.Response.RedirectTo(location, code...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download 下载文件
|
|
||||||
func Download(r *ghttp.Request, location string, code ...int) {
|
|
||||||
r.Response.ServeFileDownload("test.txt")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RText 返回成功文本
|
// RText 返回成功文本
|
||||||
func RText(r *ghttp.Request, message string) {
|
func RText(r *ghttp.Request, message string) {
|
||||||
// 清空响应
|
// 清空响应
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
"hotgo/internal/consts"
|
"hotgo/internal/consts"
|
||||||
"hotgo/internal/dao"
|
"hotgo/internal/dao"
|
||||||
"hotgo/internal/library/hgorm"
|
|
||||||
"hotgo/internal/library/hgorm/handler"
|
"hotgo/internal/library/hgorm/handler"
|
||||||
"hotgo/internal/model/entity"
|
"hotgo/internal/model/entity"
|
||||||
"hotgo/internal/model/input/adminin"
|
"hotgo/internal/model/input/adminin"
|
||||||
@ -218,12 +217,7 @@ func (s *sAdminCreditsLog) List(ctx context.Context, in adminin.CreditsLogListIn
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fields, err := hgorm.GenSelect(ctx, adminin.CreditsLogListModel{}, dao.AdminCreditsLog)
|
err = mod.Fields(adminin.CreditsLogListModel{}).Page(in.Page, in.PerPage).OrderDesc(dao.AdminCreditsLog.Columns().Id).Scan(&list)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mod.Fields(fields).Page(in.Page, in.PerPage).OrderDesc(dao.AdminCreditsLog.Columns().Id).Scan(&list)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,11 @@ func (s *sAdminDept) Delete(ctx context.Context, in adminin.DeptDeleteInp) (err
|
|||||||
|
|
||||||
// Edit 修改/新增
|
// Edit 修改/新增
|
||||||
func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err error) {
|
func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err error) {
|
||||||
if err = hgorm.IsUnique(ctx, dao.AdminDept, g.Map{dao.AdminDept.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.AdminDept, g.Map{dao.AdminDept.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, dao.AdminDept, in.Pid); err != nil {
|
if in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, &dao.AdminDept, in.Pid); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ func (s *sAdminMember) VerifyUnique(ctx context.Context, in adminin.VerifyUnique
|
|||||||
err = gerror.Newf("字段 [ %v ] 未配置唯一属性验证", k)
|
err = gerror.Newf("字段 [ %v ] 未配置唯一属性验证", k)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = hgorm.IsUnique(ctx, dao.AdminMember, g.Map{k: v}, message, in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.AdminMember, g.Map{k: v}, message, in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,7 +599,6 @@ func (s *sAdminMember) List(ctx context.Context, in adminin.MemberListInp) (list
|
|||||||
list[i].PostIds = append(list[i].PostIds, v.Int64())
|
list[i].PostIds = append(list[i].PostIds, v.Int64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +294,8 @@ func (s *sAdminOrder) List(ctx context.Context, in adminin.OrderListInp) (list [
|
|||||||
}
|
}
|
||||||
|
|
||||||
//关联表select
|
//关联表select
|
||||||
fields, err := hgorm.GenJoinSelect(ctx, adminin.OrderListModel{}, dao.AdminOrder, []*hgorm.Join{
|
fields, err := hgorm.GenJoinSelect(ctx, adminin.OrderListModel{}, &dao.AdminOrder, []*hgorm.Join{
|
||||||
{Dao: dao.PayLog, Alias: "payLog"},
|
{Dao: &dao.PayLog, Alias: "payLog"},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -171,15 +171,15 @@ func (s *sAdminRole) UpdatePermissions(ctx context.Context, in adminin.UpdatePer
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *sAdminRole) Edit(ctx context.Context, in adminin.RoleEditInp) (err error) {
|
func (s *sAdminRole) Edit(ctx context.Context, in adminin.RoleEditInp) (err error) {
|
||||||
if err = hgorm.IsUnique(ctx, dao.AdminRole, g.Map{dao.AdminRole.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.AdminRole, g.Map{dao.AdminRole.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = hgorm.IsUnique(ctx, dao.AdminRole, g.Map{dao.AdminRole.Columns().Key: in.Key}, "编码已存在", in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.AdminRole, g.Map{dao.AdminRole.Columns().Key: in.Key}, "编码已存在", in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, dao.AdminRole, in.Pid); err != nil {
|
if in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, &dao.AdminRole, in.Pid); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ import (
|
|||||||
|
|
||||||
// HomeAuth 前台页面鉴权中间件
|
// HomeAuth 前台页面鉴权中间件
|
||||||
func (s *sMiddleware) HomeAuth(r *ghttp.Request) {
|
func (s *sMiddleware) HomeAuth(r *ghttp.Request) {
|
||||||
r.Response.Header().Set("Content-Type", "text/html")
|
|
||||||
|
|
||||||
// 鉴权
|
// 鉴权
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ import (
|
|||||||
type sMiddleware struct {
|
type sMiddleware struct {
|
||||||
LoginUrl string // 登录路由地址
|
LoginUrl string // 登录路由地址
|
||||||
DemoWhiteList g.Map // 演示模式放行的路由白名单
|
DemoWhiteList g.Map // 演示模式放行的路由白名单
|
||||||
PayNotifyRoutes g.Map // 支付异步通知路由
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -47,11 +46,6 @@ func NewMiddleware() *sMiddleware {
|
|||||||
"/admin/site/mobileLogin": struct{}{}, // 手机号登录
|
"/admin/site/mobileLogin": struct{}{}, // 手机号登录
|
||||||
"/admin/genCodes/preview": struct{}{}, // 预览代码
|
"/admin/genCodes/preview": struct{}{}, // 预览代码
|
||||||
},
|
},
|
||||||
PayNotifyRoutes: g.Map{
|
|
||||||
"/api/pay/notify/alipay": struct{}{}, // 支付宝
|
|
||||||
"/api/pay/notify/wxpay": struct{}{}, // 微信支付
|
|
||||||
"/api/pay/notify/qqpay": struct{}{}, // QQ支付
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,17 +19,17 @@ func (s *sMiddleware) Develop(r *ghttp.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !gstr.InArray(ips, "*") {
|
if !gstr.InArray(ips, "*") {
|
||||||
cuIp := location.GetClientIp(r)
|
clientIp := location.GetClientIp(r)
|
||||||
ok := false
|
ok := false
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if ip == cuIp {
|
if ip == clientIp {
|
||||||
ok = true
|
ok = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
response.JsonExit(r, gcode.CodeNotSupported.Code(), fmt.Sprintf("当前IP[%s]没有配置生成白名单!", cuIp))
|
response.JsonExit(r, gcode.CodeNotSupported.Code(), fmt.Sprintf("当前IP[%s]没有配置生成白名单!", clientIp))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,45 +6,41 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/gogf/gf/v2/errors/gcode"
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gmeta"
|
||||||
"hotgo/internal/consts"
|
"hotgo/internal/consts"
|
||||||
"hotgo/internal/library/contexts"
|
"hotgo/internal/library/contexts"
|
||||||
"hotgo/internal/library/response"
|
"hotgo/internal/library/response"
|
||||||
"hotgo/internal/model/input/payin"
|
|
||||||
"hotgo/utility/charset"
|
"hotgo/utility/charset"
|
||||||
"hotgo/utility/simple"
|
"hotgo/utility/simple"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResponseHandler HTTP响应预处理
|
// ResponseHandler HTTP响应预处理
|
||||||
func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
|
func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
|
||||||
r.Middleware.Next()
|
r.Middleware.Next()
|
||||||
|
|
||||||
|
contentType := getContentType(r)
|
||||||
// 已存在响应
|
// 已存在响应
|
||||||
if r.Response.BufferLength() > 0 && contexts.Get(r.Context()).Response != nil {
|
if contentType != consts.HTTPContentTypeStream && r.Response.BufferLength() > 0 && contexts.Get(r.Context()).Response != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// html模板响应
|
switch contentType {
|
||||||
if r.Response.Header().Get("Content-Type") == "text/html" {
|
case consts.HTTPContentTypeHtml:
|
||||||
s.responseHtml(r)
|
s.responseHtml(r)
|
||||||
return
|
return
|
||||||
}
|
case consts.HTTPContentTypeXml:
|
||||||
|
s.responseXml(r)
|
||||||
// 支付通知响应
|
|
||||||
if _, ok := s.PayNotifyRoutes[r.Router.Uri]; ok {
|
|
||||||
s.responsePayNotify(r)
|
|
||||||
return
|
return
|
||||||
}
|
case consts.HTTPContentTypeStream:
|
||||||
|
// ...
|
||||||
// 默认json响应
|
default:
|
||||||
responseJson(r)
|
responseJson(r)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// responseHtml html模板响应
|
// responseHtml html模板响应
|
||||||
func (s *sMiddleware) responseHtml(r *ghttp.Request) {
|
func (s *sMiddleware) responseHtml(r *ghttp.Request) {
|
||||||
@ -54,56 +50,23 @@ func (s *sMiddleware) responseHtml(r *ghttp.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.Response.ClearBuffer()
|
r.Response.ClearBuffer()
|
||||||
_ = r.Response.WriteTplContent(simple.DefaultErrorTplContent(r.Context()), g.Map{
|
_ = r.Response.WriteTplContent(simple.DefaultErrorTplContent(r.Context()), g.Map{"code": code, "message": message, "stack": resp})
|
||||||
"code": code,
|
|
||||||
"message": message,
|
|
||||||
"stack": resp,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// responsePayNotify 支付通知响应
|
// responseXml xml响应
|
||||||
func (s *sMiddleware) responsePayNotify(r *ghttp.Request) {
|
func (s *sMiddleware) responseXml(r *ghttp.Request) {
|
||||||
var (
|
|
||||||
ctx = r.Context()
|
|
||||||
err error
|
|
||||||
data *payin.PayNotifyModel
|
|
||||||
)
|
|
||||||
|
|
||||||
code, message, resp := parseResponse(r)
|
code, message, resp := parseResponse(r)
|
||||||
if code != gcode.CodeOK.Code() {
|
|
||||||
response.RJson(r, code, message, data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = gconv.Scan(resp, &data); err != nil || data == nil {
|
|
||||||
g.Log("exception").Errorf(ctx, "middleware.responsePayNotify Scan err:%+v, data:%+v", err, data)
|
|
||||||
r.Response.ClearBuffer()
|
|
||||||
r.Response.WriteStatus(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch data.PayType {
|
|
||||||
case consts.PayTypeAliPay:
|
|
||||||
response.RText(r, data.Message)
|
|
||||||
|
|
||||||
case consts.PayTypeWxPay:
|
|
||||||
r.Response.ClearBuffer()
|
|
||||||
r.Response.WriteJson(fmt.Sprintf(`{"code": "%v","message": "%v"}`, data.Code, data.Message))
|
|
||||||
|
|
||||||
case consts.PayTypeQQPay:
|
|
||||||
r.Response.ClearBuffer()
|
r.Response.ClearBuffer()
|
||||||
r.Response.Write(`<?xml version="1.0" encoding="UTF-8"?>`)
|
r.Response.Write(`<?xml version="1.0" encoding="UTF-8"?>`)
|
||||||
r.Response.WriteXml(g.Map{
|
|
||||||
"return_code": data.Message,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
switch code {
|
||||||
|
case gcode.CodeOK.Code():
|
||||||
|
r.Response.WriteXml(g.Map{"code": code, "message": message, "data": resp})
|
||||||
default:
|
default:
|
||||||
err = gerror.Newf("无效的支付方式,这可能是没有配置通知回调响应方式导致的:%+v", data)
|
r.Response.WriteXml(g.Map{"code": code, "message": message, "error": resp})
|
||||||
g.Log("exception").Error(ctx, err)
|
|
||||||
r.Response.ClearBuffer()
|
|
||||||
r.Response.WriteStatus(http.StatusInternalServerError, err.Error())
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// responseJson json响应
|
// responseJson json响应
|
||||||
@ -114,11 +77,8 @@ func responseJson(r *ghttp.Request) {
|
|||||||
|
|
||||||
// parseResponse 解析响应数据
|
// parseResponse 解析响应数据
|
||||||
func parseResponse(r *ghttp.Request) (code int, message string, resp interface{}) {
|
func parseResponse(r *ghttp.Request) (code int, message string, resp interface{}) {
|
||||||
var (
|
ctx := r.Context()
|
||||||
ctx = r.Context()
|
err := r.GetError()
|
||||||
err = r.GetError()
|
|
||||||
)
|
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return gcode.CodeOK.Code(), "操作成功", r.GetHandlerResponse()
|
return gcode.CodeOK.Code(), "操作成功", r.GetHandlerResponse()
|
||||||
}
|
}
|
||||||
@ -126,12 +86,15 @@ func parseResponse(r *ghttp.Request) (code int, message string, resp interface{}
|
|||||||
// 是否输出错误堆栈到页面
|
// 是否输出错误堆栈到页面
|
||||||
if g.Cfg().MustGet(ctx, "hotgo.debug", true).Bool() {
|
if g.Cfg().MustGet(ctx, "hotgo.debug", true).Bool() {
|
||||||
message = gerror.Current(err).Error()
|
message = gerror.Current(err).Error()
|
||||||
|
if getContentType(r) == consts.HTTPContentTypeHtml {
|
||||||
|
resp = charset.SerializeStack(err)
|
||||||
|
} else {
|
||||||
resp = charset.ParseErrStack(err)
|
resp = charset.ParseErrStack(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message = consts.ErrorMessage(gerror.Current(err))
|
message = consts.ErrorMessage(gerror.Current(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析错误状态码
|
|
||||||
code = gerror.Code(err).Code()
|
code = gerror.Code(err).Code()
|
||||||
|
|
||||||
// 记录异常日志
|
// 记录异常日志
|
||||||
@ -142,3 +105,18 @@ func parseResponse(r *ghttp.Request) (code int, message string, resp interface{}
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getContentType(r *ghttp.Request) (contentType string) {
|
||||||
|
contentType = r.Response.Header().Get("Content-Type")
|
||||||
|
if contentType != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mime := gmeta.Get(r.GetHandlerResponse(), "mime").String()
|
||||||
|
if mime == "" {
|
||||||
|
contentType = consts.HTTPContentTypeJson
|
||||||
|
} else {
|
||||||
|
contentType = mime
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
"hotgo/internal/consts"
|
"hotgo/internal/consts"
|
||||||
"hotgo/internal/dao"
|
"hotgo/internal/dao"
|
||||||
"hotgo/internal/library/hgorm"
|
|
||||||
"hotgo/internal/library/hgorm/handler"
|
"hotgo/internal/library/hgorm/handler"
|
||||||
"hotgo/internal/library/location"
|
"hotgo/internal/library/location"
|
||||||
"hotgo/internal/library/payment"
|
"hotgo/internal/library/payment"
|
||||||
@ -188,12 +187,7 @@ func (s *sPayRefund) List(ctx context.Context, in payin.PayRefundListInp) (list
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fields, err := hgorm.GenSelect(ctx, payin.PayRefundListModel{}, dao.PayRefund)
|
err = mod.Fields(payin.PayRefundListModel{}).Page(in.Page, in.PerPage).OrderDesc(dao.PayRefund.Columns().Id).Scan(&list)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mod.Fields(fields).Page(in.Page, in.PerPage).OrderDesc(dao.PayRefund.Columns().Id).Scan(&list)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ func (s *sSysCurdDemo) List(ctx context.Context, in sysin.CurdDemoListInp) (list
|
|||||||
}
|
}
|
||||||
|
|
||||||
//关联表select
|
//关联表select
|
||||||
fields, err := hgorm.GenJoinSelect(ctx, sysin.CurdDemoListModel{}, dao.SysGenCurdDemo, []*hgorm.Join{
|
fields, err := hgorm.GenJoinSelect(ctx, sysin.CurdDemoListModel{}, &dao.SysGenCurdDemo, []*hgorm.Join{
|
||||||
{Dao: dao.TestCategory, Alias: "testCategory"},
|
{Dao: &dao.TestCategory, Alias: "testCategory"},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -82,7 +82,7 @@ func (s *sSysDictType) Delete(ctx context.Context, in sysin.DictTypeDeleteInp) (
|
|||||||
|
|
||||||
// Edit 修改/新增
|
// Edit 修改/新增
|
||||||
func (s *sSysDictType) Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error) {
|
func (s *sSysDictType) Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error) {
|
||||||
if err = hgorm.IsUnique(ctx, dao.SysDictType, g.Map{dao.SysDictType.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.SysDictType, g.Map{dao.SysDictType.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +84,8 @@ func (s *sSysLoginLog) List(ctx context.Context, in sysin.LoginLogListInp) (list
|
|||||||
}
|
}
|
||||||
|
|
||||||
//关联表select
|
//关联表select
|
||||||
fields, err := hgorm.GenJoinSelect(ctx, sysin.LoginLogListModel{}, dao.SysLoginLog, []*hgorm.Join{
|
fields, err := hgorm.GenJoinSelect(ctx, sysin.LoginLogListModel{}, &dao.SysLoginLog, []*hgorm.Join{
|
||||||
{Dao: dao.SysLog, Alias: "sysLog"},
|
{Dao: &dao.SysLog, Alias: "sysLog"},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -79,7 +79,7 @@ func (s *sSysProvinces) Delete(ctx context.Context, in sysin.ProvincesDeleteInp)
|
|||||||
// Edit 修改/新增省市区数据
|
// Edit 修改/新增省市区数据
|
||||||
func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error) {
|
func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error) {
|
||||||
// 关系树
|
// 关系树
|
||||||
in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, dao.SysProvinces, in.Pid)
|
in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, &dao.SysProvinces, in.Pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ func (s *sSysProvinces) UniqueId(ctx context.Context, in sysin.ProvincesUniqueId
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = hgorm.IsUnique(ctx, dao.SysProvinces, g.Map{dao.SysProvinces.Columns().Id: in.NewId}, "", in.OldId); err != nil {
|
if err = hgorm.IsUnique(ctx, &dao.SysProvinces, g.Map{dao.SysProvinces.Columns().Id: in.NewId}, "", in.OldId); err != nil {
|
||||||
res.IsUnique = false
|
res.IsUnique = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ func (s *sSysServeLog) List(ctx context.Context, in sysin.ServeLogListInp) (list
|
|||||||
}
|
}
|
||||||
|
|
||||||
//关联表select
|
//关联表select
|
||||||
fields, err := hgorm.GenJoinSelect(ctx, sysin.ServeLogListModel{}, dao.SysServeLog, []*hgorm.Join{
|
fields, err := hgorm.GenJoinSelect(ctx, sysin.ServeLogListModel{}, &dao.SysServeLog, []*hgorm.Join{
|
||||||
{Dao: dao.SysLog, Alias: "sysLog"},
|
{Dao: &dao.SysLog, Alias: "sysLog"},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,10 +16,9 @@ import (
|
|||||||
|
|
||||||
// Home 前台页面路由
|
// Home 前台页面路由
|
||||||
func Home(ctx context.Context, group *ghttp.RouterGroup) {
|
func Home(ctx context.Context, group *ghttp.RouterGroup) {
|
||||||
// 允许通过根地址访问的路由可以同时加到这里
|
|
||||||
// 访问地址:http://127.0.0.1:8000
|
|
||||||
group.Group("/", func(group *ghttp.RouterGroup) {
|
group.Group("/", func(group *ghttp.RouterGroup) {
|
||||||
group.Middleware(service.Middleware().HomeAuth)
|
group.Middleware(service.Middleware().HomeAuth)
|
||||||
|
// 允许通过根地址访问的路由可以加到这里,访问地址:http://127.0.0.1:8000
|
||||||
group.Bind(
|
group.Bind(
|
||||||
base.Site, // 基础
|
base.Site, // 基础
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user