1、google验证器
2、导出告警去重 3、去掉提示音
This commit is contained in:
		| @ -215,3 +215,21 @@ func (e MmAlarmLog) ClearAll(c *gin.Context) { | |||||||
|  |  | ||||||
| 	e.OK(nil, "清空成功") | 	e.OK(nil, "清空成功") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Export 导出钱包告警记录 | ||||||
|  | func (e MmAlarmLog) Export(c *gin.Context) { | ||||||
|  | 	req := dto.MmAlarmLogGetPageReq{} | ||||||
|  | 	s := service.MmAlarmLog{} | ||||||
|  | 	err := e.MakeContext(c). | ||||||
|  | 		MakeOrm(). | ||||||
|  | 		Bind(&req). | ||||||
|  | 		MakeService(&s.Service). | ||||||
|  | 		Errors | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	s.Export(&req, c) | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package apis | package apis | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"go-admin/app/admin/models" | 	"go-admin/app/admin/models" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| @ -456,6 +457,7 @@ func (e SysUser) GetInfo(c *gin.Context) { | |||||||
| 	mp["deptId"] = sysUser.DeptId | 	mp["deptId"] = sysUser.DeptId | ||||||
| 	mp["name"] = sysUser.NickName | 	mp["name"] = sysUser.NickName | ||||||
| 	mp["code"] = 200 | 	mp["code"] = 200 | ||||||
|  |  | ||||||
| 	e.OK(mp, "") | 	e.OK(mp, "") | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -481,3 +483,103 @@ func (e SysUser) GetList(c *gin.Context) { | |||||||
| 	} | 	} | ||||||
| 	e.OK(datas, "查询成功") | 	e.OK(datas, "查询成功") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // 是否需要检查google验证器 | ||||||
|  | func (e SysUser) NeedCheckGoogleAuth(c *gin.Context) { | ||||||
|  | 	s := service.SysUser{} | ||||||
|  | 	err := e.MakeContext(c). | ||||||
|  | 		MakeOrm(). | ||||||
|  | 		MakeService(&s.Service). | ||||||
|  | 		Errors | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	needGoogleAuth, err := s.NeedCheckGoogleAuth(user.GetUserId(c)) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	e.OK(needGoogleAuth, "查询成功") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 检查谷歌验证码 | ||||||
|  | func (e SysUser) CheckGoogleAuth(c *gin.Context) { | ||||||
|  | 	s := service.SysUser{} | ||||||
|  | 	req := dto.CheckGoogleAuthReq{} | ||||||
|  | 	err := e.MakeContext(c). | ||||||
|  | 		MakeOrm(). | ||||||
|  | 		Bind(&req). | ||||||
|  | 		MakeService(&s.Service). | ||||||
|  | 		Errors | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if req.Code == "" { | ||||||
|  | 		e.Error(500, errors.New("验证码不能为空"), "验证码不能为空") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result, err := s.CheckGoogleAuth(&req, user.GetUserId(c)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	e.OK(result, "验证成功") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 获取是否需要绑定google验证器 | ||||||
|  | func (e SysUser) NeedGooglAuth(c *gin.Context) { | ||||||
|  | 	s := service.SysUser{} | ||||||
|  | 	err := e.MakeContext(c). | ||||||
|  | 		MakeOrm(). | ||||||
|  | 		MakeService(&s.Service). | ||||||
|  | 		Errors | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	userId := user.GetUserId(c) | ||||||
|  |  | ||||||
|  | 	need, err := s.NeedGooglAuth(userId) | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	e.OK(need, "查询成功") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e SysUser) SetGoogleSecret(c *gin.Context) { | ||||||
|  | 	s := service.SysUser{} | ||||||
|  | 	req := dto.SetGoogleSecretReq{} | ||||||
|  | 	err := e.MakeContext(c). | ||||||
|  | 		MakeOrm(). | ||||||
|  | 		Bind(&req). | ||||||
|  | 		MakeService(&s.Service). | ||||||
|  | 		Errors | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = s.SetGoogleSecret(&req, user.GetUserId(c)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Logger.Error(err) | ||||||
|  | 		e.Error(500, err, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	e.OK(nil, "设置成功") | ||||||
|  | } | ||||||
|  | |||||||
| @ -2,29 +2,31 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"go-admin/common/models" | 	"go-admin/common/models" | ||||||
|  |  | ||||||
| 	"golang.org/x/crypto/bcrypt" | 	"golang.org/x/crypto/bcrypt" | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type SysUser struct { | type SysUser struct { | ||||||
| 	UserId   int      `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"` | 	UserId       int      `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"` | ||||||
| 	Username string   `json:"username" gorm:"size:64;comment:用户名"` | 	Username     string   `json:"username" gorm:"size:64;comment:用户名"` | ||||||
| 	Password string   `json:"-" gorm:"size:128;comment:密码"` | 	Password     string   `json:"-" gorm:"size:128;comment:密码"` | ||||||
| 	NickName string   `json:"nickName" gorm:"size:128;comment:昵称"` | 	NickName     string   `json:"nickName" gorm:"size:128;comment:昵称"` | ||||||
| 	Phone    string   `json:"phone" gorm:"size:11;comment:手机号"` | 	Phone        string   `json:"phone" gorm:"size:11;comment:手机号"` | ||||||
| 	RoleId   int      `json:"roleId" gorm:"size:20;comment:角色ID"` | 	RoleId       int      `json:"roleId" gorm:"size:20;comment:角色ID"` | ||||||
| 	Salt     string   `json:"-" gorm:"size:255;comment:加盐"` | 	Salt         string   `json:"-" gorm:"size:255;comment:加盐"` | ||||||
| 	Avatar   string   `json:"avatar" gorm:"size:255;comment:头像"` | 	Avatar       string   `json:"avatar" gorm:"size:255;comment:头像"` | ||||||
| 	Sex      string   `json:"sex" gorm:"size:255;comment:性别"` | 	Sex          string   `json:"sex" gorm:"size:255;comment:性别"` | ||||||
| 	Email    string   `json:"email" gorm:"size:128;comment:邮箱"` | 	Email        string   `json:"email" gorm:"size:128;comment:邮箱"` | ||||||
| 	DeptId   int      `json:"deptId" gorm:"size:20;comment:部门"` | 	DeptId       int      `json:"deptId" gorm:"size:20;comment:部门"` | ||||||
| 	PostId   int      `json:"postId" gorm:"size:20;comment:岗位"` | 	PostId       int      `json:"postId" gorm:"size:20;comment:岗位"` | ||||||
| 	Remark   string   `json:"remark" gorm:"size:255;comment:备注"` | 	Remark       string   `json:"remark" gorm:"size:255;comment:备注"` | ||||||
| 	Status   string   `json:"status" gorm:"size:4;comment:状态"` | 	Status       string   `json:"status" gorm:"size:4;comment:状态"` | ||||||
| 	DeptIds  []int    `json:"deptIds" gorm:"-"` | 	DeptIds      []int    `json:"deptIds" gorm:"-"` | ||||||
| 	PostIds  []int    `json:"postIds" gorm:"-"` | 	PostIds      []int    `json:"postIds" gorm:"-"` | ||||||
| 	RoleIds  []int    `json:"roleIds" gorm:"-"` | 	RoleIds      []int    `json:"roleIds" gorm:"-"` | ||||||
| 	Dept     *SysDept `json:"dept"` | 	GoogleSecret string   `json:"googleSecret" gorm:"size:100;comment:谷歌秘钥"` | ||||||
|  | 	Dept         *SysDept `json:"dept"` | ||||||
| 	models.ControlBy | 	models.ControlBy | ||||||
| 	models.ModelTime | 	models.ModelTime | ||||||
| } | } | ||||||
|  | |||||||
| @ -25,5 +25,6 @@ func registerMmAlarmLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid | |||||||
| 		r.DELETE("", api.Delete) | 		r.DELETE("", api.Delete) | ||||||
|  |  | ||||||
| 		r.DELETE("clear-all", actions.PermissionAction(), api.ClearAll) //清理所有数据 | 		r.DELETE("clear-all", actions.PermissionAction(), api.ClearAll) //清理所有数据 | ||||||
|  | 		r.GET("export", actions.PermissionAction(), api.Export)         //导出数据 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -37,5 +37,10 @@ func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle | |||||||
| 	{ | 	{ | ||||||
| 		v1auth.GET("/getinfo", api.GetInfo) | 		v1auth.GET("/getinfo", api.GetInfo) | ||||||
| 		v1auth.GET("/sys-user/options", api.GetList) | 		v1auth.GET("/sys-user/options", api.GetList) | ||||||
|  |  | ||||||
|  | 		v1auth.GET("need-check-google-auth", api.NeedCheckGoogleAuth) //是否需要检查google验证 | ||||||
|  | 		v1auth.GET("need-auth", api.NeedGooglAuth)                    //是否需要配置谷歌验证 | ||||||
|  | 		v1auth.PUT("set-google-auth", api.SetGoogleSecret)            //设置谷歌验证 | ||||||
|  | 		v1auth.GET("google-code", api.CheckGoogleAuth)                //验证谷歌验证码 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,30 +1,28 @@ | |||||||
| package dto | package dto | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  |  | ||||||
| 	"go-admin/app/admin/models" | 	"go-admin/app/admin/models" | ||||||
| 	"go-admin/common/dto" | 	"go-admin/common/dto" | ||||||
| 	common "go-admin/common/models" | 	common "go-admin/common/models" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type MmAlarmLogGetPageReq struct { | type MmAlarmLogGetPageReq struct { | ||||||
| 	dto.Pagination     `search:"-"` | 	dto.Pagination `search:"-"` | ||||||
|     MachineId string `form:"machineId"  search:"type:exact;column:machine_id;table:mm_alarm_log" comment:"设备id"` | 	MachineId      string `form:"machineId"  search:"type:exact;column:machine_id;table:mm_alarm_log" comment:"设备id"` | ||||||
|     BiosId string `form:"biosId"  search:"type:exact;column:bios_id;table:mm_alarm_log" comment:"设备码"` | 	BiosId         string `form:"biosId"  search:"type:exact;column:bios_id;table:mm_alarm_log" comment:"设备码"` | ||||||
|     MmAlarmLogOrder | 	MmAlarmLogOrder | ||||||
| } | } | ||||||
|  |  | ||||||
| type MmAlarmLogOrder struct { | type MmAlarmLogOrder struct { | ||||||
|     Id string `form:"idOrder"  search:"type:order;column:id;table:mm_alarm_log"` | 	Id        string `form:"idOrder"  search:"type:order;column:id;table:mm_alarm_log"` | ||||||
|     MachineId string `form:"machineIdOrder"  search:"type:order;column:machine_id;table:mm_alarm_log"` | 	MachineId string `form:"machineIdOrder"  search:"type:order;column:machine_id;table:mm_alarm_log"` | ||||||
|     BiosId string `form:"biosIdOrder"  search:"type:order;column:bios_id;table:mm_alarm_log"` | 	BiosId    string `form:"biosIdOrder"  search:"type:order;column:bios_id;table:mm_alarm_log"` | ||||||
|     Content string `form:"contentOrder"  search:"type:order;column:content;table:mm_alarm_log"` | 	Content   string `form:"contentOrder"  search:"type:order;column:content;table:mm_alarm_log"` | ||||||
|     CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:mm_alarm_log"` | 	CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:mm_alarm_log"` | ||||||
|     UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:mm_alarm_log"` | 	UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:mm_alarm_log"` | ||||||
|     DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:mm_alarm_log"` | 	DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:mm_alarm_log"` | ||||||
|     CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:mm_alarm_log"` | 	CreateBy  string `form:"createByOrder"  search:"type:order;column:create_by;table:mm_alarm_log"` | ||||||
|     UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:mm_alarm_log"` | 	UpdateBy  string `form:"updateByOrder"  search:"type:order;column:update_by;table:mm_alarm_log"` | ||||||
|      |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MmAlarmLogGetPageReq) GetNeedSearch() interface{} { | func (m *MmAlarmLogGetPageReq) GetNeedSearch() interface{} { | ||||||
| @ -32,21 +30,21 @@ func (m *MmAlarmLogGetPageReq) GetNeedSearch() interface{} { | |||||||
| } | } | ||||||
|  |  | ||||||
| type MmAlarmLogInsertReq struct { | type MmAlarmLogInsertReq struct { | ||||||
|     Id int `json:"-" comment:"主键id"` // 主键id | 	Id        int    `json:"-" comment:"主键id"` // 主键id | ||||||
|     MachineId string `json:"machineId" comment:"设备id"` | 	MachineId string `json:"machineId" comment:"设备id"` | ||||||
|     BiosId string `json:"biosId" comment:"设备码"` | 	BiosId    string `json:"biosId" comment:"设备码"` | ||||||
|     Content string `json:"content" comment:"内容"` | 	Content   string `json:"content" comment:"内容"` | ||||||
|     common.ControlBy | 	common.ControlBy | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *MmAlarmLogInsertReq) Generate(model *models.MmAlarmLog)  { | func (s *MmAlarmLogInsertReq) Generate(model *models.MmAlarmLog) { | ||||||
|     if s.Id == 0 { | 	if s.Id == 0 { | ||||||
|         model.Model = common.Model{ Id: s.Id } | 		model.Model = common.Model{Id: s.Id} | ||||||
|     } | 	} | ||||||
|     model.MachineId = s.MachineId | 	model.MachineId = s.MachineId | ||||||
|     model.BiosId = s.BiosId | 	model.BiosId = s.BiosId | ||||||
|     model.Content = s.Content | 	model.Content = s.Content | ||||||
|     model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | 	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *MmAlarmLogInsertReq) GetId() interface{} { | func (s *MmAlarmLogInsertReq) GetId() interface{} { | ||||||
| @ -54,21 +52,21 @@ func (s *MmAlarmLogInsertReq) GetId() interface{} { | |||||||
| } | } | ||||||
|  |  | ||||||
| type MmAlarmLogUpdateReq struct { | type MmAlarmLogUpdateReq struct { | ||||||
|     Id int `uri:"id" comment:"主键id"` // 主键id | 	Id        int    `uri:"id" comment:"主键id"` // 主键id | ||||||
|     MachineId string `json:"machineId" comment:"设备id"` | 	MachineId string `json:"machineId" comment:"设备id"` | ||||||
|     BiosId string `json:"biosId" comment:"设备码"` | 	BiosId    string `json:"biosId" comment:"设备码"` | ||||||
|     Content string `json:"content" comment:"内容"` | 	Content   string `json:"content" comment:"内容"` | ||||||
|     common.ControlBy | 	common.ControlBy | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *MmAlarmLogUpdateReq) Generate(model *models.MmAlarmLog)  { | func (s *MmAlarmLogUpdateReq) Generate(model *models.MmAlarmLog) { | ||||||
|     if s.Id == 0 { | 	if s.Id == 0 { | ||||||
|         model.Model = common.Model{ Id: s.Id } | 		model.Model = common.Model{Id: s.Id} | ||||||
|     } | 	} | ||||||
|     model.MachineId = s.MachineId | 	model.MachineId = s.MachineId | ||||||
|     model.BiosId = s.BiosId | 	model.BiosId = s.BiosId | ||||||
|     model.Content = s.Content | 	model.Content = s.Content | ||||||
|     model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | 	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *MmAlarmLogUpdateReq) GetId() interface{} { | func (s *MmAlarmLogUpdateReq) GetId() interface{} { | ||||||
| @ -77,8 +75,9 @@ func (s *MmAlarmLogUpdateReq) GetId() interface{} { | |||||||
|  |  | ||||||
| // MmAlarmLogGetReq 功能获取请求参数 | // MmAlarmLogGetReq 功能获取请求参数 | ||||||
| type MmAlarmLogGetReq struct { | type MmAlarmLogGetReq struct { | ||||||
|      Id int `uri:"id"` | 	Id int `uri:"id"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *MmAlarmLogGetReq) GetId() interface{} { | func (s *MmAlarmLogGetReq) GetId() interface{} { | ||||||
| 	return s.Id | 	return s.Id | ||||||
| } | } | ||||||
| @ -91,3 +90,9 @@ type MmAlarmLogDeleteReq struct { | |||||||
| func (s *MmAlarmLogDeleteReq) GetId() interface{} { | func (s *MmAlarmLogDeleteReq) GetId() interface{} { | ||||||
| 	return s.Ids | 	return s.Ids | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type MmAlarmLogExportResp struct { | ||||||
|  | 	MachineId string `json:"machineId" comment:"设备id" excel:"设备id"` | ||||||
|  | 	BiosId    string `json:"biosId" comment:"设备码" excel:"设备码"` | ||||||
|  | 	Content   string `json:"content" comment:"内容" excel:"内容"` | ||||||
|  | } | ||||||
|  | |||||||
| @ -192,3 +192,18 @@ type SysUserOptions struct { | |||||||
| 	UserId   int    `json:"userId"` | 	UserId   int    `json:"userId"` | ||||||
| 	NickName string `json:"nickName"` | 	NickName string `json:"nickName"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type SetGoogleSecretReq struct { | ||||||
|  | 	Secret string `json:"secret" vd:"len($)>0"` | ||||||
|  | 	Code   string `json:"code" vd:"len($)>0"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GoogleSecretResp struct { | ||||||
|  | 	Secret        string `json:"secret"` | ||||||
|  | 	OtpAuthUrl    string `json:"otpAuthUrl"` | ||||||
|  | 	NeedGooglAuth bool   `json:"needGooglAuth"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type CheckGoogleAuthReq struct { | ||||||
|  | 	Code string `json:"code" form:"code" vd:"len($)>0"` | ||||||
|  | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ package service | |||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  |  | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
| 	"github.com/go-admin-team/go-admin-core/sdk/service" | 	"github.com/go-admin-team/go-admin-core/sdk/service" | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
|  |  | ||||||
| @ -10,12 +11,45 @@ import ( | |||||||
| 	"go-admin/app/admin/service/dto" | 	"go-admin/app/admin/service/dto" | ||||||
| 	"go-admin/common/actions" | 	"go-admin/common/actions" | ||||||
| 	cDto "go-admin/common/dto" | 	cDto "go-admin/common/dto" | ||||||
|  | 	"go-admin/common/helper" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type MmAlarmLog struct { | type MmAlarmLog struct { | ||||||
| 	service.Service | 	service.Service | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // 导出列表 | ||||||
|  | func (e MmAlarmLog) Export(req *dto.MmAlarmLogGetPageReq, c *gin.Context) error { | ||||||
|  | 	var datas []models.MmAlarmLog | ||||||
|  | 	list := make([]dto.MmAlarmLogExportResp, 0) | ||||||
|  | 	query := e.Orm.Model(&models.MmAlarmLog{}) | ||||||
|  |  | ||||||
|  | 	if req.MachineId != "" { | ||||||
|  | 		query = query.Where("machine_id = ?", req.MachineId) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err := query. | ||||||
|  | 		Select("machine_id, bios_id, content"). | ||||||
|  | 		Distinct(). | ||||||
|  | 		Find(&datas). | ||||||
|  | 		Error | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Log.Errorf("MmAlarmLogService Export error:%s \r\n", err) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, data := range datas { | ||||||
|  | 		list = append(list, dto.MmAlarmLogExportResp{ | ||||||
|  | 			MachineId: data.MachineId, | ||||||
|  | 			BiosId:    data.BiosId, | ||||||
|  | 			Content:   data.Content, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return helper.ExportExcel(c, "钱包告警记录", list, []string{}) | ||||||
|  | } | ||||||
|  |  | ||||||
| // 清除所有记录 | // 清除所有记录 | ||||||
| func (e MmAlarmLog) ClearAll(p *actions.DataPermission) error { | func (e MmAlarmLog) ClearAll(p *actions.DataPermission) error { | ||||||
| 	if err := e.Orm.Exec("TRUNCATE TABLE mm_alarm_log;").Error; err != nil { | 	if err := e.Orm.Exec("TRUNCATE TABLE mm_alarm_log;").Error; err != nil { | ||||||
|  | |||||||
| @ -148,6 +148,8 @@ func (e *MmRiskLog) Remove(d *dto.MmRiskLogDeleteReq, p *actions.DataPermission) | |||||||
| // Save 保存MmRiskLog对象 | // Save 保存MmRiskLog对象 | ||||||
| func (e *MmRiskLog) Save(req *dto.MmRiskLogBatchReq) error { | func (e *MmRiskLog) Save(req *dto.MmRiskLogBatchReq) error { | ||||||
| 	datas := make([]models.MmRiskLog, 0) | 	datas := make([]models.MmRiskLog, 0) | ||||||
|  | 	configService := SysConfig{Service: e.Service} | ||||||
|  | 	config, _ := configService.GetByKey("wallet_alarm") | ||||||
|  |  | ||||||
| 	for _, item := range req.Contents { | 	for _, item := range req.Contents { | ||||||
| 		data := models.MmRiskLog{} | 		data := models.MmRiskLog{} | ||||||
| @ -163,11 +165,13 @@ func (e *MmRiskLog) Save(req *dto.MmRiskLogBatchReq) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	helper.SafeGo(func() { | 	if config.ConfigValue == "1" { | ||||||
| 		if err := e.SendMsg(datas); err != nil { | 		helper.SafeGo(func() { | ||||||
| 			e.Log.Errorf("发送消息失败:%s", err) | 			if err := e.SendMsg(datas); err != nil { | ||||||
| 		} | 				e.Log.Errorf("发送消息失败:%s", err) | ||||||
| 	}) | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @ -183,7 +187,7 @@ func (e *MmRiskLog) SendMsg(datas []models.MmRiskLog) error { | |||||||
|  |  | ||||||
| 	alarmLogs := []models.MmAlarmLog{} | 	alarmLogs := []models.MmAlarmLog{} | ||||||
| 	for _, item := range datas { | 	for _, item := range datas { | ||||||
| 		if helper.ArrayAny(addresss, item.Content) { | 		if helper.ArrayAny(addresss, item.Content) || item.Type != 1 { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"go-admin/app/admin/models" | 	"go-admin/app/admin/models" | ||||||
| 	"go-admin/app/admin/service/dto" | 	"go-admin/app/admin/service/dto" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
| 	log "github.com/go-admin-team/go-admin-core/logger" | 	log "github.com/go-admin-team/go-admin-core/logger" | ||||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg" | 	"github.com/go-admin-team/go-admin-core/sdk/pkg" | ||||||
| @ -12,12 +13,118 @@ import ( | |||||||
|  |  | ||||||
| 	"go-admin/common/actions" | 	"go-admin/common/actions" | ||||||
| 	cDto "go-admin/common/dto" | 	cDto "go-admin/common/dto" | ||||||
|  | 	"go-admin/common/helper" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type SysUser struct { | type SysUser struct { | ||||||
| 	service.Service | 	service.Service | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CheckGoogleAuth 检查谷歌验证器 | ||||||
|  | func (e SysUser) CheckGoogleAuth(req *dto.CheckGoogleAuthReq, i int) (bool, error) { | ||||||
|  | 	var sysUser models.SysUser | ||||||
|  |  | ||||||
|  | 	if err := e.Orm.Model(sysUser).Where("user_id =?", i).First(&sysUser).Error; err != nil { | ||||||
|  | 		return false, errors.New("获取用户信息失败") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	googleAuth := helper.NewGoogleAuth() | ||||||
|  |  | ||||||
|  | 	if resp, _ := googleAuth.VerifyCodeWithTolerance(sysUser.GoogleSecret, req.Code); !resp { | ||||||
|  | 		return false, errors.New("验证码错误") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 是否需要检查google验证器 | ||||||
|  | func (e SysUser) NeedCheckGoogleAuth(i int) (bool, error) { | ||||||
|  | 	var sysUser models.SysUser | ||||||
|  |  | ||||||
|  | 	if err := e.Orm.Model(sysUser).Where("user_id =?", i).First(&sysUser).Error; err != nil { | ||||||
|  | 		e.Log.Errorf("获取用户信息失败 %v", err) | ||||||
|  | 		return false, errors.New("获取用户信息失败") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	configService := SysConfig{} | ||||||
|  | 	configService.Orm = e.Orm | ||||||
|  | 	configService.Log = e.Log | ||||||
|  |  | ||||||
|  | 	configData, _ := configService.GetByKey("google_auth") | ||||||
|  | 	needGooleAuth := false | ||||||
|  |  | ||||||
|  | 	if configData.ConfigValue == "1" && sysUser.GoogleSecret != "" { | ||||||
|  | 		needGooleAuth = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return needGooleAuth, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e SysUser) SetGoogleSecret(req *dto.SetGoogleSecretReq, i int) error { | ||||||
|  | 	var user models.SysUser | ||||||
|  |  | ||||||
|  | 	if err := e.Orm.Model(user).Where("user_id =?", i).First(&user).Error; err != nil { | ||||||
|  | 		e.Log.Errorf("db error: %v", err) | ||||||
|  | 		return errors.New("获取用户信息失败") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if user.GoogleSecret != "" { | ||||||
|  | 		return errors.New("该用户已绑定谷歌验证器") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	googleAuth := helper.NewGoogleAuth() | ||||||
|  |  | ||||||
|  | 	if !googleAuth.VerifyCode(req.Secret, req.Code) { | ||||||
|  | 		return errors.New("验证码错误") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	db := e.Orm.Model(&models.SysUser{}).Where("user_id =?", i).Update("google_secret", req.Secret) | ||||||
|  |  | ||||||
|  | 	if db.Error != nil { | ||||||
|  | 		e.Log.Errorf("db error: %s", db.Error) | ||||||
|  | 		return db.Error | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if db.RowsAffected == 0 { | ||||||
|  | 		return errors.New("绑定goole验证器失败") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e SysUser) NeedGooglAuth(userId int) (dto.GoogleSecretResp, error) { | ||||||
|  | 	var sysUser models.SysUser | ||||||
|  | 	configService := SysConfig{} | ||||||
|  | 	configService.Orm = e.Orm | ||||||
|  | 	configService.Log = e.Log | ||||||
|  | 	googleAuthConfig, _ := configService.GetByKey("google_auth") | ||||||
|  | 	result := dto.GoogleSecretResp{ | ||||||
|  | 		NeedGooglAuth: false, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err := e.Orm.Model(&models.SysUser{}).Where("user_id =?", userId).Select("user_id, google_secret,username").First(&sysUser).Error | ||||||
|  | 	if err != nil { | ||||||
|  | 		e.Log.Errorf("db error: %s", err) | ||||||
|  | 		return result, errors.New("获取用户信息失败") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if strings.Trim(googleAuthConfig.ConfigValue, " ") == "1" && sysUser.GoogleSecret == "" { | ||||||
|  | 		result.NeedGooglAuth = true | ||||||
|  | 		googleAuth := helper.NewGoogleAuth() | ||||||
|  | 		secret, otpAuthUrl, err := googleAuth.GenerateSecret(sysUser.Username) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			e.Log.Errorf("生成谷歌验证器失败: %s", err) | ||||||
|  | 			return result, errors.New("生成谷歌验证器失败") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		result.Secret = secret | ||||||
|  | 		result.OtpAuthUrl = otpAuthUrl | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return result, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // 根据权限获取user id | // 根据权限获取user id | ||||||
| func (e SysUser) GetByPermission(permission string) ([]int, error) { | func (e SysUser) GetByPermission(permission string) ([]int, error) { | ||||||
| 	result := make([]int, 0) | 	result := make([]int, 0) | ||||||
|  | |||||||
							
								
								
									
										66
									
								
								common/helper/google_auth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								common/helper/google_auth.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | package helper | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/pquerna/otp" | ||||||
|  | 	"github.com/pquerna/otp/totp" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // GoogleAuth 用于管理 TOTP 的生成和验证 | ||||||
|  | type GoogleAuth struct { | ||||||
|  | 	Issuer string // 项目名称或公司名 WindowsLock | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewGoogleAuth 创建一个 GoogleAuth 实例 | ||||||
|  | func NewGoogleAuth() *GoogleAuth { | ||||||
|  | 	return &GoogleAuth{ | ||||||
|  | 		Issuer: "WindowsLock", | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GenerateSecret 生成一个用户绑定谷歌验证器所需的密钥和二维码 URL | ||||||
|  | func (g *GoogleAuth) GenerateSecret(account string) (secret string, otpAuthUrl string, err error) { | ||||||
|  | 	key, err := totp.Generate(totp.GenerateOpts{ | ||||||
|  | 		Issuer:      g.Issuer, | ||||||
|  | 		AccountName: account, | ||||||
|  | 		Period:      30, | ||||||
|  | 		SecretSize:  20, | ||||||
|  | 		Digits:      otp.DigitsSix, | ||||||
|  | 		Algorithm:   otp.AlgorithmSHA1, | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return key.Secret(), key.URL(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // VerifyCode 验证用户输入的 TOTP 验证码是否正确 | ||||||
|  | func (g *GoogleAuth) VerifyCode(secret, code string) bool { | ||||||
|  | 	valid := totp.Validate(code, secret) | ||||||
|  | 	return valid | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // VerifyCodeWithTolerance 带时间偏移容错的验证码校验(容忍1个时间步长) | ||||||
|  | func (g *GoogleAuth) VerifyCodeWithTolerance(secret, inputCode string) (bool, error) { | ||||||
|  | 	code := strings.TrimSpace(inputCode) | ||||||
|  |  | ||||||
|  | 	return totp.ValidateCustom(code, secret, time.Now(), totp.ValidateOpts{ | ||||||
|  | 		Period:    30, | ||||||
|  | 		Skew:      1, // 允许前后 1 个周期(±30 秒)内的验证码 | ||||||
|  | 		Digits:    otp.DigitsSix, | ||||||
|  | 		Algorithm: otp.AlgorithmSHA1, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GenerateQRCodeURL 生成 otpauth:// URL,适合用在二维码中 | ||||||
|  | func (g *GoogleAuth) GenerateQRCodeURL(account, secret string) string { | ||||||
|  | 	return fmt.Sprintf("otpauth://totp/%s:%s?secret=%s&issuer=%s", g.Issuer, account, secret, g.Issuer) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g *GoogleAuth) GenerateCode(secret string) (string, error) { | ||||||
|  | 	return totp.GenerateCode(secret, time.Now()) | ||||||
|  | } | ||||||
| @ -5,6 +5,8 @@ import ( | |||||||
| 	"go-admin/common" | 	"go-admin/common" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"go-admin/common/global" | ||||||
|  |  | ||||||
| 	"github.com/gin-gonic/gin" | 	"github.com/gin-gonic/gin" | ||||||
| 	"github.com/go-admin-team/go-admin-core/sdk" | 	"github.com/go-admin-team/go-admin-core/sdk" | ||||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||||
| @ -15,14 +17,14 @@ import ( | |||||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/response" | 	"github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||||
| 	"github.com/mssola/user_agent" | 	"github.com/mssola/user_agent" | ||||||
| 	"go-admin/common/global" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func PayloadFunc(data interface{}) jwt.MapClaims { | func PayloadFunc(data interface{}) jwt.MapClaims { | ||||||
| 	if v, ok := data.(map[string]interface{}); ok { | 	if v, ok := data.(map[string]interface{}); ok { | ||||||
| 		u, _ := v["user"].(SysUser) | 		u, _ := v["user"].(SysUser) | ||||||
| 		r, _ := v["role"].(SysRole) | 		r, _ := v["role"].(SysRole) | ||||||
| 		return jwt.MapClaims{ |  | ||||||
|  | 		result := jwt.MapClaims{ | ||||||
| 			jwt.IdentityKey:  u.UserId, | 			jwt.IdentityKey:  u.UserId, | ||||||
| 			jwt.RoleIdKey:    r.RoleId, | 			jwt.RoleIdKey:    r.RoleId, | ||||||
| 			jwt.RoleKey:      r.RoleKey, | 			jwt.RoleKey:      r.RoleKey, | ||||||
| @ -30,6 +32,8 @@ func PayloadFunc(data interface{}) jwt.MapClaims { | |||||||
| 			jwt.DataScopeKey: r.DataScope, | 			jwt.DataScopeKey: r.DataScope, | ||||||
| 			jwt.RoleNameKey:  r.RoleName, | 			jwt.RoleNameKey:  r.RoleName, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		return result | ||||||
| 	} | 	} | ||||||
| 	return jwt.MapClaims{} | 	return jwt.MapClaims{} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								common/middleware/handler/google_auth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								common/middleware/handler/google_auth.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | package handler | ||||||
| @ -2,27 +2,29 @@ package handler | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"go-admin/common/models" | 	"go-admin/common/models" | ||||||
|  |  | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type SysUser struct { | type SysUser struct { | ||||||
| 	UserId   int    `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"` | 	UserId       int    `gorm:"primaryKey;autoIncrement;comment:编码"  json:"userId"` | ||||||
| 	Username string `json:"username" gorm:"size:64;comment:用户名"` | 	Username     string `json:"username" gorm:"size:64;comment:用户名"` | ||||||
| 	Password string `json:"-" gorm:"size:128;comment:密码"` | 	Password     string `json:"-" gorm:"size:128;comment:密码"` | ||||||
| 	NickName string `json:"nickName" gorm:"size:128;comment:昵称"` | 	NickName     string `json:"nickName" gorm:"size:128;comment:昵称"` | ||||||
| 	Phone    string `json:"phone" gorm:"size:11;comment:手机号"` | 	Phone        string `json:"phone" gorm:"size:11;comment:手机号"` | ||||||
| 	RoleId   int    `json:"roleId" gorm:"size:20;comment:角色ID"` | 	RoleId       int    `json:"roleId" gorm:"size:20;comment:角色ID"` | ||||||
| 	Salt     string `json:"-" gorm:"size:255;comment:加盐"` | 	Salt         string `json:"-" gorm:"size:255;comment:加盐"` | ||||||
| 	Avatar   string `json:"avatar" gorm:"size:255;comment:头像"` | 	Avatar       string `json:"avatar" gorm:"size:255;comment:头像"` | ||||||
| 	Sex      string `json:"sex" gorm:"size:255;comment:性别"` | 	Sex          string `json:"sex" gorm:"size:255;comment:性别"` | ||||||
| 	Email    string `json:"email" gorm:"size:128;comment:邮箱"` | 	Email        string `json:"email" gorm:"size:128;comment:邮箱"` | ||||||
| 	DeptId   int    `json:"deptId" gorm:"size:20;comment:部门"` | 	DeptId       int    `json:"deptId" gorm:"size:20;comment:部门"` | ||||||
| 	PostId   int    `json:"postId" gorm:"size:20;comment:岗位"` | 	PostId       int    `json:"postId" gorm:"size:20;comment:岗位"` | ||||||
| 	Remark   string `json:"remark" gorm:"size:255;comment:备注"` | 	Remark       string `json:"remark" gorm:"size:255;comment:备注"` | ||||||
| 	Status   string `json:"status" gorm:"size:4;comment:状态"` | 	Status       string `json:"status" gorm:"size:4;comment:状态"` | ||||||
| 	DeptIds  []int  `json:"deptIds" gorm:"-"` | 	DeptIds      []int  `json:"deptIds" gorm:"-"` | ||||||
| 	PostIds  []int  `json:"postIds" gorm:"-"` | 	PostIds      []int  `json:"postIds" gorm:"-"` | ||||||
| 	RoleIds  []int  `json:"roleIds" gorm:"-"` | 	RoleIds      []int  `json:"roleIds" gorm:"-"` | ||||||
|  | 	GoogleSecret string `json:"googleSecret" gorm:"size:100;comment:谷歌验证器秘钥"` | ||||||
| 	//Dept     *SysDept `json:"dept"` | 	//Dept     *SysDept `json:"dept"` | ||||||
| 	models.ControlBy | 	models.ControlBy | ||||||
| 	models.ModelTime | 	models.ModelTime | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @ -48,6 +48,7 @@ require ( | |||||||
| 	github.com/andeya/goutil v1.0.1 // indirect | 	github.com/andeya/goutil v1.0.1 // indirect | ||||||
| 	github.com/beorn7/perks v1.0.1 // indirect | 	github.com/beorn7/perks v1.0.1 // indirect | ||||||
| 	github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect | 	github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect | ||||||
|  | 	github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect | ||||||
| 	github.com/bytedance/sonic v1.13.2 // indirect | 	github.com/bytedance/sonic v1.13.2 // indirect | ||||||
| 	github.com/bytedance/sonic/loader v0.2.4 // indirect | 	github.com/bytedance/sonic/loader v0.2.4 // indirect | ||||||
| 	github.com/casbin/gorm-adapter/v3 v3.32.0 // indirect | 	github.com/casbin/gorm-adapter/v3 v3.32.0 // indirect | ||||||
| @ -110,6 +111,7 @@ require ( | |||||||
| 	github.com/nyaruka/phonenumbers v1.0.55 // indirect | 	github.com/nyaruka/phonenumbers v1.0.55 // indirect | ||||||
| 	github.com/pelletier/go-toml/v2 v2.2.4 // indirect | 	github.com/pelletier/go-toml/v2 v2.2.4 // indirect | ||||||
| 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | ||||||
|  | 	github.com/pquerna/otp v1.5.0 // indirect | ||||||
| 	github.com/prometheus/client_model v0.6.1 // indirect | 	github.com/prometheus/client_model v0.6.1 // indirect | ||||||
| 	github.com/prometheus/common v0.62.0 // indirect | 	github.com/prometheus/common v0.62.0 // indirect | ||||||
| 	github.com/prometheus/procfs v0.15.1 // indirect | 	github.com/prometheus/procfs v0.15.1 // indirect | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user