mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-11-14 05:03:49 +08:00
tt
This commit is contained in:
233
hotgo-server/app/service/sysService/config_service.go
Normal file
233
hotgo-server/app/service/sysService/config_service.go
Normal file
@@ -0,0 +1,233 @@
|
||||
package sysService
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/form/input"
|
||||
"github.com/bufanyun/hotgo/app/service/internal/dao"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
var Config = new(config)
|
||||
|
||||
type config struct{}
|
||||
|
||||
//
|
||||
// @Title 最大排序
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictDataMaxSortRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) GetValue(ctx context.Context, in input.SysConfigGetValueInp) (*input.SysConfigGetValueModel, error) {
|
||||
var res input.SysConfigGetValueModel
|
||||
|
||||
if err := dao.SysConfig.Ctx(ctx).
|
||||
Fields("value").
|
||||
Where("key", in.Key).
|
||||
Order("id desc").
|
||||
Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 菜单名称是否唯一
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeUniqueRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) NameUnique(ctx context.Context, in input.SysConfigNameUniqueInp) (*input.SysConfigNameUniqueModel, error) {
|
||||
|
||||
var res input.SysConfigNameUniqueModel
|
||||
isUnique, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.IsUnique = isUnique
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 删除
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) Delete(ctx context.Context, in input.SysConfigDeleteInp) error {
|
||||
|
||||
exist, err := dao.SysConfig.Ctx(ctx).Where("Member_id", in.Id).One()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !exist.IsEmpty() {
|
||||
return gerror.New("请先解除该部门下所有已关联用户关联关系!")
|
||||
}
|
||||
_, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 修改/新增
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) Edit(ctx context.Context, in input.SysConfigEditInp) (err error) {
|
||||
|
||||
if in.Name == "" {
|
||||
err = gerror.New("名称不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
uniqueName, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !uniqueName {
|
||||
err = gerror.New("名称已存在")
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.SysConfig.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 最大排序
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictDataMaxSortRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) MaxSort(ctx context.Context, in input.SysConfigMaxSortInp) (*input.SysConfigMaxSortModel, error) {
|
||||
var res input.SysConfigMaxSortModel
|
||||
|
||||
if in.Id > 0 {
|
||||
if err := dao.SysConfig.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
res.Sort = res.Sort + 10
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定字典类型信息
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeViewRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *config) View(ctx context.Context, in input.SysConfigViewInp) (res *input.SysConfigViewModel, err error) {
|
||||
|
||||
if err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取列表
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return res
|
||||
// @Return err
|
||||
//
|
||||
func (service *config) List(ctx context.Context, in input.SysConfigListInp) (list []*input.SysConfigListModel, totalCount int, err error) {
|
||||
|
||||
mod := dao.SysConfig.Ctx(ctx)
|
||||
|
||||
if in.Realname != "" {
|
||||
mod = mod.WhereLike("realname", "%"+in.Realname+"%")
|
||||
}
|
||||
if in.Username != "" {
|
||||
mod = mod.WhereLike("username", "%"+in.Username+"%")
|
||||
}
|
||||
if in.Mobile > 0 {
|
||||
mod = mod.Where("mobile", in.Mobile)
|
||||
}
|
||||
if in.Status > 0 {
|
||||
mod = mod.Where("status", in.Status)
|
||||
}
|
||||
if in.DeptId > 0 {
|
||||
mod = mod.Where("dept_id", in.DeptId)
|
||||
}
|
||||
|
||||
// 日期范围
|
||||
if in.StartTime != "" {
|
||||
mod = mod.WhereGTE("created_at", in.StartTime)
|
||||
}
|
||||
if in.EndTime != "" {
|
||||
mod = mod.WhereLTE("created_at", in.EndTime)
|
||||
}
|
||||
|
||||
totalCount, err = mod.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
//// TODO 重写树入参
|
||||
//for i := 0; i < len(list); i++ {
|
||||
//}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
505
hotgo-server/app/service/sysService/dict_service.go
Normal file
505
hotgo-server/app/service/sysService/dict_service.go
Normal file
@@ -0,0 +1,505 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sysService
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/com"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/form/adminForm"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/bufanyun/hotgo/app/service/internal/dao"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Dict = new(dict)
|
||||
|
||||
type dict struct{}
|
||||
|
||||
//
|
||||
// @Title 数据键值是否唯一
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeUniqueRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) DataUnique(ctx context.Context, req *adminForm.DictDataUniqueReq) (*adminForm.DictDataUniqueRes, error) {
|
||||
var (
|
||||
res adminForm.DictDataUniqueRes
|
||||
err error
|
||||
)
|
||||
|
||||
res.IsUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 查询字典数据最大排序
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictDataMaxSortRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) DataMaxSort(ctx context.Context, req *adminForm.DictDataMaxSortReq) (*adminForm.DictDataMaxSortRes, error) {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort desc")
|
||||
res adminForm.DictDataMaxSortRes
|
||||
err error
|
||||
)
|
||||
|
||||
if err = m.Scan(&res); err != nil && err.Error() != "sql: no rows in result set" {
|
||||
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.Sort = res.Sort + 10
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 删除字典类型
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) DataDelete(ctx context.Context, req *adminForm.DictDataDeleteReq) error {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx).Where("id", req.Id)
|
||||
err error
|
||||
)
|
||||
|
||||
_, err = m.Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 修改/新增字典类型
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) DataEdit(ctx context.Context, req *adminForm.DictDataEditReq) error {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx)
|
||||
isUnique bool
|
||||
err error
|
||||
)
|
||||
|
||||
if req.Label == "" {
|
||||
err = gerror.New("字典标签不能为空")
|
||||
return err
|
||||
}
|
||||
if req.Type == "" {
|
||||
err = gerror.New("字典类型不能为空")
|
||||
return err
|
||||
}
|
||||
if req.Value == "" {
|
||||
err = gerror.New("字典键值不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
isUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
if !isUnique {
|
||||
err = gerror.New("字典键值已存在")
|
||||
return err
|
||||
}
|
||||
|
||||
req.UpdatedAt = gtime.Now()
|
||||
|
||||
// 修改
|
||||
if req.Id > 0 {
|
||||
_, err = m.Where("id", req.Id).Data(req).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
req.CreatedAt = gtime.Now()
|
||||
|
||||
// 新增
|
||||
_, err = m.Data(req).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定字典数据信息
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeViewRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) DataView(ctx context.Context, req *adminForm.DictDataViewReq) (*adminForm.DictDataViewRes, error) {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx).Where("id", req.Id)
|
||||
res adminForm.DictDataViewRes
|
||||
err error
|
||||
)
|
||||
|
||||
if err = m.Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定字典类型的属性数据
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictAttributeRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (*adminForm.DictAttributeRes, error) {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort asc,id desc")
|
||||
res adminForm.DictAttributeRes
|
||||
err error
|
||||
)
|
||||
|
||||
if err = m.Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取字典数据列表
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return res
|
||||
// @Return err
|
||||
//
|
||||
func (service *dict) DataList(ctx context.Context, req *adminForm.DictDataListReq) (*adminForm.DictDataListRes, error) {
|
||||
var (
|
||||
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type)
|
||||
list []*entity.SysDictData
|
||||
res adminForm.DictDataListRes
|
||||
totalCount int
|
||||
err error
|
||||
)
|
||||
|
||||
totalCount, err = m.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.List = list
|
||||
res.Page = req.Page
|
||||
res.Limit = req.Limit
|
||||
res.TotalCount = totalCount
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 导出字典类型
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictDataListRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) TypeExport(ctx context.Context, req *adminForm.DictTypeExportReq) error {
|
||||
|
||||
// 导出格式
|
||||
type exportImage struct {
|
||||
Id int64 `json:"id" `
|
||||
Name string `json:"name" `
|
||||
Type string `json:"type" `
|
||||
Remark string `json:"remark" `
|
||||
Status string `json:"status" `
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
var (
|
||||
list []exportImage
|
||||
titleList = []string{"ID", "字典名称", "字典类型", "备注", "状态", "创建时间", "更新时间"}
|
||||
fileName = "字典类型导出-" + com.Context.Get(ctx).ReqId + ".xlsx"
|
||||
sheetName = "HotGo"
|
||||
err error
|
||||
)
|
||||
|
||||
if err = dao.SysDictType.Ctx(ctx).Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO 格式化格式
|
||||
for i := 0; i < len(list); i++ {
|
||||
if list[i].Status == consts.StatusEnabled {
|
||||
list[i].Status = "启用"
|
||||
} else if list[i].Status == consts.StatusDisable {
|
||||
list[i].Status = "禁用"
|
||||
} else if list[i].Status == consts.StatusDelete {
|
||||
list[i].Status = "已删除"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 强转类型
|
||||
writer := com.Context.Get(ctx).Request.Response.Writer
|
||||
w, _ := interface{}(writer).(*ghttp.ResponseWriter)
|
||||
|
||||
g.Log().Print(ctx, "gconv.Interfaces(list):", gconv.Interfaces(list))
|
||||
if err = utils.Excel.ExportByStruct(w, titleList, gconv.Interfaces(list), fileName, sheetName); err != nil {
|
||||
err = gerror.Wrap(err, "ExportByStruct:")
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO 加入到上下文
|
||||
com.Context.SetResponse(ctx, &model.Response{
|
||||
Code: consts.CodeOK,
|
||||
Message: "导出成功",
|
||||
Timestamp: time.Now().Unix(),
|
||||
ReqId: com.Context.Get(ctx).ReqId,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 删除字典类型
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) TypeDelete(ctx context.Context, req *adminForm.DictTypeDeleteReq) error {
|
||||
var (
|
||||
m = dao.SysDictType.Ctx(ctx).Where("id", req.Id)
|
||||
err error
|
||||
)
|
||||
|
||||
_, err = m.Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 修改/新增字典类型
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) TypeEdit(ctx context.Context, req *adminForm.DictTypeEditReq) error {
|
||||
var (
|
||||
m = dao.SysDictType.Ctx(ctx)
|
||||
isUnique bool
|
||||
err error
|
||||
)
|
||||
|
||||
if req.Name == "" {
|
||||
err = gerror.New("字典名称不能为空")
|
||||
return err
|
||||
}
|
||||
if req.Type == "" {
|
||||
err = gerror.New("字典类型不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
isUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
if !isUnique {
|
||||
err = gerror.New("字典类型已存在")
|
||||
return err
|
||||
}
|
||||
|
||||
req.UpdatedAt = gtime.Now()
|
||||
|
||||
// 修改
|
||||
if req.Id > 0 {
|
||||
_, err = m.Where("id", req.Id).Data(req).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
req.CreatedAt = gtime.Now()
|
||||
|
||||
// 新增
|
||||
_, err = m.Where("id", req.Id).Data(req).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 类型是否唯一
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeUniqueRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) TypeUnique(ctx context.Context, req *adminForm.DictTypeUniqueReq) (*adminForm.DictTypeUniqueRes, error) {
|
||||
var (
|
||||
res adminForm.DictTypeUniqueRes
|
||||
err error
|
||||
)
|
||||
|
||||
res.IsUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定字典类型信息
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return *adminForm.DictTypeViewRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *dict) TypeView(ctx context.Context, req *adminForm.DictTypeViewReq) (*adminForm.DictTypeViewRes, error) {
|
||||
var (
|
||||
m = dao.SysDictType.Ctx(ctx).Where("id", req.Id)
|
||||
res adminForm.DictTypeViewRes
|
||||
err error
|
||||
)
|
||||
|
||||
if err = m.Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取字典类型列表
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return res
|
||||
// @Return err
|
||||
//
|
||||
func (service *dict) TypeList(ctx context.Context, req *adminForm.DictTypeListReq) (*adminForm.DictTypeListRes, error) {
|
||||
var (
|
||||
m = dao.SysDictType.Ctx(ctx)
|
||||
list []*entity.SysDictType
|
||||
res adminForm.DictTypeListRes
|
||||
totalCount int
|
||||
err error
|
||||
)
|
||||
|
||||
if req.Name != "" {
|
||||
m = m.WhereLike("name", "%"+req.Name+"%")
|
||||
}
|
||||
|
||||
if req.Type != "" {
|
||||
m = m.Where("type", req.Type)
|
||||
}
|
||||
|
||||
// 日期范围
|
||||
if req.StartTime != "" {
|
||||
m = m.WhereGTE("created_at", req.StartTime)
|
||||
}
|
||||
if req.EndTime != "" {
|
||||
m = m.WhereLTE("created_at", req.EndTime)
|
||||
}
|
||||
|
||||
// 状态
|
||||
if req.Status > 0 {
|
||||
m = m.Where("status", req.Status)
|
||||
}
|
||||
|
||||
totalCount, err = m.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.List = list
|
||||
res.Page = req.Page
|
||||
res.Limit = req.Limit
|
||||
res.TotalCount = totalCount
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
400
hotgo-server/app/service/sysService/log_service.go
Normal file
400
hotgo-server/app/service/sysService/log_service.go
Normal file
@@ -0,0 +1,400 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sysService
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/bufanyun/hotgo/app/com"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/factory/queue"
|
||||
"github.com/bufanyun/hotgo/app/form/input"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/bufanyun/hotgo/app/service/internal/dao"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Log = new(log)
|
||||
|
||||
type log struct{}
|
||||
|
||||
//
|
||||
// @Title 导出
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param in
|
||||
// @Return err
|
||||
//
|
||||
func (service *log) Export(ctx context.Context, in input.LogListInp) (err error) {
|
||||
|
||||
// 导出格式
|
||||
type exportImage struct {
|
||||
Id int64 `json:"id" description:""`
|
||||
AppId string `json:"app_id" description:"应用id"`
|
||||
Method string `json:"method" description:"提交类型"`
|
||||
Module string `json:"module" description:"模块"`
|
||||
Url string `json:"url" description:"提交url"`
|
||||
Ip string `json:"ip" description:"ip地址"`
|
||||
ErrorCode int `json:"error_code" description:"报错code"`
|
||||
ErrorMsg string `json:"error_msg" description:"报错信息"`
|
||||
ReqId string `json:"req_id" description:"对外id"`
|
||||
TakeUpTime int64 `json:"take_up_time" description:"请求耗时"`
|
||||
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
|
||||
MemberName string `json:"member_name"`
|
||||
Region string `json:"region"`
|
||||
}
|
||||
|
||||
var (
|
||||
titleList = []string{"ID", "应用", "提交类型", "模块", "提交url", "ip地址", "报错code", "报错信息", "对外id", "请求耗时", "创建时间", "用户", "访问地"}
|
||||
fileName = "全局日志导出-" + com.Context.Get(ctx).ReqId + ".xlsx"
|
||||
sheetName = "HotGo"
|
||||
exportList []exportImage
|
||||
row exportImage
|
||||
)
|
||||
|
||||
list, _, err := service.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO 格式化格式
|
||||
for i := 0; i < len(list); i++ {
|
||||
row.Id = list[i].Id
|
||||
row.AppId = list[i].AppId
|
||||
row.Module = list[i].Module
|
||||
row.Method = list[i].Method
|
||||
row.Url = list[i].Url
|
||||
row.Ip = list[i].Ip
|
||||
row.ReqId = list[i].ReqId
|
||||
row.ErrorCode = list[i].ErrorCode
|
||||
row.ErrorMsg = list[i].ErrorMsg
|
||||
row.TakeUpTime = list[i].TakeUpTime
|
||||
row.CreatedAt = list[i].CreatedAt
|
||||
row.MemberName = list[i].MemberName
|
||||
row.Region = list[i].Region
|
||||
exportList = append(exportList, row)
|
||||
}
|
||||
|
||||
// TODO 强转类型
|
||||
writer := com.Context.Get(ctx).Request.Response.Writer
|
||||
w, _ := interface{}(writer).(*ghttp.ResponseWriter)
|
||||
|
||||
if err = utils.Excel.ExportByStruct(w, titleList, gconv.Interfaces(exportList), fileName, sheetName); err != nil {
|
||||
err = gerror.Wrap(err, "ExportByStruct:")
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO 加入到上下文
|
||||
com.Context.SetResponse(ctx, &model.Response{
|
||||
Code: consts.CodeOK,
|
||||
Message: "导出成功",
|
||||
Timestamp: time.Now().Unix(),
|
||||
ReqId: com.Context.Get(ctx).ReqId,
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取菜单列表
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return res
|
||||
// @Return err
|
||||
//
|
||||
func (service *log) List(ctx context.Context, in input.LogListInp) (list []*input.LogListModel, totalCount int, err error) {
|
||||
|
||||
mod := dao.SysLog.Ctx(ctx)
|
||||
|
||||
// 访问路径
|
||||
if in.Url != "" {
|
||||
mod = mod.WhereLike("url", "%"+in.Url+"%")
|
||||
}
|
||||
|
||||
// 模块
|
||||
if in.Module != "" {
|
||||
mod = mod.Where("module", in.Module)
|
||||
}
|
||||
|
||||
// 请求方式
|
||||
if in.Method != "" {
|
||||
mod = mod.Where("method", in.Method)
|
||||
}
|
||||
|
||||
// 用户
|
||||
if in.MemberId > 0 {
|
||||
mod = mod.Where("member_id", in.MemberId)
|
||||
}
|
||||
|
||||
// 访问IP
|
||||
if in.Ip != "" {
|
||||
mod = mod.Where("ip", in.Ip)
|
||||
}
|
||||
|
||||
// 日期范围
|
||||
if in.StartTime != "" {
|
||||
mod = mod.WhereGTE("created_at", in.StartTime)
|
||||
}
|
||||
if in.EndTime != "" {
|
||||
mod = mod.WhereLTE("created_at", in.EndTime)
|
||||
}
|
||||
|
||||
// 状态码
|
||||
if in.ErrorCode != "" {
|
||||
mod = mod.Where("error_code", in.ErrorCode)
|
||||
}
|
||||
|
||||
// 请求耗时
|
||||
if in.TakeUpTime > 0 {
|
||||
mod = mod.WhereGTE("take_up_time", in.TakeUpTime)
|
||||
}
|
||||
|
||||
totalCount, err = mod.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(list); i++ {
|
||||
// TODO 管理员
|
||||
if list[i].AppId == consts.AppAdmin {
|
||||
memberName, err := dao.AdminMember.Ctx(ctx).Fields("realname").Where("id", list[i].MemberId).Value()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
list[i].MemberName = memberName.String()
|
||||
}
|
||||
// TODO 接口
|
||||
if list[i].AppId == consts.AppApi {
|
||||
//memberName, err = dao.Member.Ctx(ctx).Fields("realname").Where("id", res.List[i].MemberId).Value()
|
||||
//if err != nil {
|
||||
// err = gerror.Wrap(err, consts.ErrorORM)
|
||||
// return nil, err
|
||||
//}
|
||||
}
|
||||
|
||||
if list[i].MemberName == "" {
|
||||
list[i].MemberName = "游客"
|
||||
}
|
||||
|
||||
// TODO 获取省市编码对应的地区名称
|
||||
region, err := dao.SysProvinces.GetRegion(ctx, list[i].ProvinceId, list[i].CityId)
|
||||
if err != nil {
|
||||
return list, totalCount, err
|
||||
}
|
||||
list[i].Region = region
|
||||
|
||||
// TODO 截取请求url路径
|
||||
if gstr.Contains(list[i].Url, "?") {
|
||||
list[i].Url = gstr.StrTillEx(list[i].Url, "?")
|
||||
}
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 真实写入
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param commonLog
|
||||
// @Return err
|
||||
//
|
||||
func (service *log) RealWrite(ctx context.Context, commonLog entity.SysLog) error {
|
||||
|
||||
result, err := dao.SysLog.Ctx(ctx).Data(commonLog).Insert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := result.LastInsertId(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 根据配置自动记录请求日志
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return err
|
||||
//
|
||||
func (service *log) AutoLog(ctx context.Context) (err error) {
|
||||
// TODO 日志开关
|
||||
logSwitch, _ := g.Cfg().Get(ctx, "hotgo.log.switch", true)
|
||||
if !logSwitch.Bool() {
|
||||
return nil
|
||||
}
|
||||
|
||||
data := service.AnalysisLog(ctx)
|
||||
|
||||
// TODO 判断模块是否需要记录
|
||||
module, _ := g.Cfg().Get(ctx, "hotgo.log.module", nil)
|
||||
if module == nil {
|
||||
return nil
|
||||
}
|
||||
if exist := utils.Charset.IsExists(module.Strings(), data.Module); !exist {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO 判断状态码是否需要记录
|
||||
code, _ := g.Cfg().Get(ctx, "hotgo.log.skipCode", nil)
|
||||
if code != nil {
|
||||
if exist := utils.Charset.IsExists(code.Strings(), gconv.String(data.ErrorCode)); exist {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 是否开启队列
|
||||
queueSwitch, _ := g.Cfg().Get(ctx, "hotgo.log.queue", true)
|
||||
if queueSwitch.Bool() {
|
||||
// TODO 获取生产者实例
|
||||
queueInstance, err := queue.InstanceProducer()
|
||||
if err != nil {
|
||||
queue.FatalLog(ctx, "InstanceProducer异常", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO 生产消息
|
||||
mqMsg, err := queueInstance.SendMsg(consts.QueueLogTopic, gconv.String(data))
|
||||
|
||||
// TODO 记录生产日志
|
||||
queue.ProducerLog(ctx, consts.QueueLogTopic, mqMsg.MsgId, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return service.RealWrite(ctx, data)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 队列消费
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param mqMsg
|
||||
// @Return err
|
||||
//
|
||||
func (service *log) QueueJob(ctx context.Context, mqMsg queue.MqMsg) (err error) {
|
||||
|
||||
var data entity.SysLog
|
||||
if err = json.Unmarshal(mqMsg.Body, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return service.RealWrite(ctx, data)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 解析日志数据
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return entity.SysLog
|
||||
//
|
||||
func (service *log) AnalysisLog(ctx context.Context) entity.SysLog {
|
||||
|
||||
var (
|
||||
modelContext = com.Context.Get(ctx)
|
||||
response = modelContext.ComResponse
|
||||
user = modelContext.User
|
||||
request = modelContext.Request
|
||||
module = modelContext.Module
|
||||
ip = request.GetClientIp()
|
||||
locationData = com.Ip.GetLocation(ctx, ip)
|
||||
postData = "null"
|
||||
getData = "null"
|
||||
headerData = "null"
|
||||
data = entity.SysLog{}
|
||||
memberId = 0
|
||||
errorCode = 0
|
||||
errorMsg = ""
|
||||
errorData = "null"
|
||||
reqId = ""
|
||||
timestamp = 0
|
||||
appId = ""
|
||||
)
|
||||
|
||||
// TODO 响应数据
|
||||
if response != nil {
|
||||
errorCode = response.Code
|
||||
errorMsg = response.Message
|
||||
reqId = response.ReqId
|
||||
timestamp = gconv.Int(response.Timestamp)
|
||||
|
||||
if len(gconv.String(response.Error)) > 0 {
|
||||
errorData = gconv.String(response.Error)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 请求头
|
||||
if reqHeadersBytes, _ := json.Marshal(request.Header); len(gconv.String(reqHeadersBytes)) > 0 {
|
||||
headerData = gconv.String(reqHeadersBytes)
|
||||
}
|
||||
|
||||
// TODO post参数
|
||||
if gconv.String(request.PostForm) != "" {
|
||||
postData = gconv.String(request.PostForm)
|
||||
}
|
||||
|
||||
// TODO get参数
|
||||
if len(request.URL.Query()) > 0 {
|
||||
getData = gconv.String(request.URL.Query())
|
||||
}
|
||||
|
||||
// TODO 当前登录用户
|
||||
if user != nil {
|
||||
memberId = int(user.Id)
|
||||
appId = user.App
|
||||
}
|
||||
|
||||
data = entity.SysLog{
|
||||
AppId: appId,
|
||||
MerchantId: 0,
|
||||
MemberId: memberId,
|
||||
Method: request.Method,
|
||||
Module: module,
|
||||
Url: request.RequestURI,
|
||||
GetData: getData,
|
||||
PostData: postData,
|
||||
HeaderData: headerData,
|
||||
Ip: ip,
|
||||
ProvinceId: locationData.ProvinceCode,
|
||||
CityId: locationData.CityCode,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMsg: errorMsg,
|
||||
ErrorData: errorData,
|
||||
ReqId: reqId,
|
||||
Timestamp: timestamp,
|
||||
UserAgent: request.Header.Get("User-Agent"),
|
||||
Status: consts.StatusEnabled,
|
||||
TakeUpTime: modelContext.TakeUpTime,
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
29
hotgo-server/app/service/sysService/provinces_service.go
Normal file
29
hotgo-server/app/service/sysService/provinces_service.go
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sysService
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/com"
|
||||
)
|
||||
|
||||
var Provinces = new(provinces)
|
||||
|
||||
type provinces struct{}
|
||||
|
||||
//
|
||||
// @Title 获取地区中的省市编码
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param location
|
||||
//
|
||||
func (service *provinces) GetLocationCode(ctx context.Context, location com.IpLocationData) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user