feat: 合并Gin_Vue
This commit is contained in:
85
src/modules/common/common.go
Normal file
85
src/modules/common/common.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/middleware"
|
||||
"ems.agt/src/modules/common/controller"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 模块路由注册
|
||||
func Setup(router *gin.Engine) {
|
||||
logger.Infof("开始加载 ====> common 模块路由")
|
||||
|
||||
// 路由主页
|
||||
indexGroup := router.Group("/")
|
||||
indexGroup.GET("",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 10,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewIndex.Handler,
|
||||
)
|
||||
|
||||
// 验证码操作处理
|
||||
indexGroup.GET("/captchaImage",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 60,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewCaptcha.Image,
|
||||
)
|
||||
|
||||
// 账号身份操作处理
|
||||
{
|
||||
indexGroup.POST("/login",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 10,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewAccount.Login,
|
||||
)
|
||||
indexGroup.GET("/getInfo", middleware.PreAuthorize(nil), controller.NewAccount.Info)
|
||||
indexGroup.GET("/getRouters", middleware.PreAuthorize(nil), controller.NewAccount.Router)
|
||||
indexGroup.POST("/logout",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 5,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewAccount.Logout,
|
||||
)
|
||||
}
|
||||
|
||||
// 账号注册操作处理
|
||||
{
|
||||
indexGroup.POST("/register",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 10,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewRegister.UserName,
|
||||
)
|
||||
}
|
||||
|
||||
// 通用请求
|
||||
commonGroup := router.Group("/common")
|
||||
{
|
||||
commonGroup.GET("/hash", middleware.PreAuthorize(nil), controller.NewCommont.Hash)
|
||||
}
|
||||
|
||||
// 文件操作处理
|
||||
fileGroup := router.Group("/file")
|
||||
{
|
||||
fileGroup.GET("/download/:filePath", middleware.PreAuthorize(nil), controller.NewFile.Download)
|
||||
fileGroup.POST("/upload", middleware.PreAuthorize(nil), controller.NewFile.Upload)
|
||||
fileGroup.POST("/chunkCheck", middleware.PreAuthorize(nil), controller.NewFile.ChunkCheck)
|
||||
fileGroup.POST("/chunkUpload", middleware.PreAuthorize(nil), controller.NewFile.ChunkUpload)
|
||||
fileGroup.POST("/chunkMerge", middleware.PreAuthorize(nil), controller.NewFile.ChunkMerge)
|
||||
}
|
||||
}
|
||||
144
src/modules/common/controller/account.go
Normal file
144
src/modules/common/controller/account.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/config"
|
||||
commonConstants "ems.agt/src/framework/constants/common"
|
||||
tokenConstants "ems.agt/src/framework/constants/token"
|
||||
ctxUtils "ems.agt/src/framework/utils/ctx"
|
||||
tokenUtils "ems.agt/src/framework/utils/token"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
libAccount "ems.agt/src/lib_features/account"
|
||||
commonModel "ems.agt/src/modules/common/model"
|
||||
commonService "ems.agt/src/modules/common/service"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 AccountController 结构体
|
||||
var NewAccount = &AccountController{
|
||||
accountService: commonService.NewAccountImpl,
|
||||
sysLogLoginService: systemService.NewSysLogLoginImpl,
|
||||
}
|
||||
|
||||
// 账号身份操作处理
|
||||
//
|
||||
// PATH /
|
||||
type AccountController struct {
|
||||
// 账号身份操作服务
|
||||
accountService commonService.IAccount
|
||||
// 系统登录访问
|
||||
sysLogLoginService systemService.ISysLogLogin
|
||||
}
|
||||
|
||||
// 系统登录
|
||||
//
|
||||
// POST /login
|
||||
func (s *AccountController) Login(c *gin.Context) {
|
||||
var loginBody commonModel.LoginBody
|
||||
if err := c.ShouldBindJSON(&loginBody); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := ctxUtils.IPAddrLocation(c)
|
||||
os, browser := ctxUtils.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码
|
||||
err := s.accountService.ValidateCaptcha(
|
||||
loginBody.Code,
|
||||
loginBody.UUID,
|
||||
)
|
||||
// 根据错误信息,创建系统访问记录
|
||||
if err != nil {
|
||||
msg := err.Error() + " " + loginBody.Code
|
||||
s.sysLogLoginService.NewSysLogLogin(
|
||||
loginBody.Username, commonConstants.STATUS_NO, msg,
|
||||
ipaddr, location, os, browser,
|
||||
)
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser, err := s.accountService.LoginByUsername(loginBody.Username, loginBody.Password)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 生成令牌,创建系统访问记录
|
||||
tokenStr := tokenUtils.Create(&loginUser, ipaddr, location, os, browser)
|
||||
if tokenStr == "" {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
} else {
|
||||
s.sysLogLoginService.NewSysLogLogin(
|
||||
loginBody.Username, commonConstants.STATUS_YES, "登录成功",
|
||||
ipaddr, location, os, browser,
|
||||
)
|
||||
}
|
||||
|
||||
// 设置登录会话-兼容旧登录方式
|
||||
libAccount.SessionToken(loginBody.Username, ipaddr)
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
tokenConstants.RESPONSE_FIELD: tokenStr,
|
||||
}))
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
//
|
||||
// GET /getInfo
|
||||
func (s *AccountController) Info(c *gin.Context) {
|
||||
loginUser, err := ctxUtils.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, result.CodeMsg(401, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 角色权限集合,管理员拥有所有权限
|
||||
isAdmin := config.IsAdmin(loginUser.UserID)
|
||||
roles, perms := s.accountService.RoleAndMenuPerms(loginUser.UserID, isAdmin)
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"user": loginUser.User,
|
||||
"roles": roles,
|
||||
"permissions": perms,
|
||||
}))
|
||||
}
|
||||
|
||||
// 登录用户路由信息
|
||||
//
|
||||
// GET /getRouters
|
||||
func (s *AccountController) Router(c *gin.Context) {
|
||||
userID := ctxUtils.LoginUserToUserID(c)
|
||||
|
||||
// 前端路由,管理员拥有所有
|
||||
isAdmin := config.IsAdmin(userID)
|
||||
buildMenus := s.accountService.RouteMenus(userID, isAdmin)
|
||||
c.JSON(200, result.OkData(buildMenus))
|
||||
}
|
||||
|
||||
// 系统登出
|
||||
//
|
||||
// POST /logout
|
||||
func (s *AccountController) Logout(c *gin.Context) {
|
||||
tokenStr := ctxUtils.Authorization(c)
|
||||
if tokenStr != "" {
|
||||
// 存在token时记录退出信息
|
||||
userName := tokenUtils.Remove(tokenStr)
|
||||
if userName != "" {
|
||||
// 当前请求信息
|
||||
ipaddr, location := ctxUtils.IPAddrLocation(c)
|
||||
os, browser := ctxUtils.UaOsBrowser(c)
|
||||
// 创建系统访问记录
|
||||
s.sysLogLoginService.NewSysLogLogin(
|
||||
userName, commonConstants.STATUS_NO, "退出成功",
|
||||
ipaddr, location, os, browser,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkMsg("退出成功"))
|
||||
}
|
||||
129
src/modules/common/controller/captcha.go
Normal file
129
src/modules/common/controller/captcha.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/constants/captcha"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
)
|
||||
|
||||
// 实例化控制层 CaptchaController 结构体
|
||||
var NewCaptcha = &CaptchaController{
|
||||
sysConfigService: systemService.NewSysConfigImpl,
|
||||
}
|
||||
|
||||
// 验证码操作处理
|
||||
//
|
||||
// PATH /
|
||||
type CaptchaController struct {
|
||||
// 参数配置服务
|
||||
sysConfigService systemService.ISysConfig
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
//
|
||||
// GET /captchaImage
|
||||
func (s *CaptchaController) Image(c *gin.Context) {
|
||||
// 从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
|
||||
captchaEnabled := parse.Boolean(captchaEnabledStr)
|
||||
if !captchaEnabled {
|
||||
c.JSON(200, result.Ok(map[string]any{
|
||||
"captchaEnabled": captchaEnabled,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
// 生成唯一标识
|
||||
verifyKey := ""
|
||||
data := map[string]any{
|
||||
"captchaEnabled": captchaEnabled,
|
||||
"uuid": "",
|
||||
"img": "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
|
||||
}
|
||||
|
||||
// 从数据库配置获取验证码类型 math 数值计算 char 字符验证
|
||||
captchaType := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaType")
|
||||
if captchaType == captcha.TYPE_MATH {
|
||||
math := config.Get("mathCaptcha").(map[string]any)
|
||||
driverCaptcha := &base64Captcha.DriverMath{
|
||||
//Height png height in pixel.
|
||||
Height: math["height"].(int),
|
||||
// Width Captcha png width in pixel.
|
||||
Width: math["width"].(int),
|
||||
//NoiseCount text noise count.
|
||||
NoiseCount: math["noise"].(int),
|
||||
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
|
||||
ShowLineOptions: base64Captcha.OptionShowHollowLine,
|
||||
}
|
||||
if math["color"].(bool) {
|
||||
//BgColor captcha image background color (optional)
|
||||
driverCaptcha.BgColor = parse.Color(math["background"].(string))
|
||||
}
|
||||
// 验证码生成
|
||||
id, question, answer := driverCaptcha.GenerateIdQuestionAnswer()
|
||||
// 验证码表达式解析输出
|
||||
item, err := driverCaptcha.DrawCaptcha(question)
|
||||
if err != nil {
|
||||
logger.Infof("Generate Id Question Answer %s %s : %v", captchaType, question, err)
|
||||
} else {
|
||||
data["uuid"] = id
|
||||
data["img"] = item.EncodeB64string()
|
||||
expiration := captcha.EXPIRATION * time.Second
|
||||
verifyKey = cachekey.CAPTCHA_CODE_KEY + id
|
||||
redis.SetByExpire("", verifyKey, answer, expiration)
|
||||
}
|
||||
}
|
||||
if captchaType == captcha.TYPE_CHAR {
|
||||
char := config.Get("charCaptcha").(map[string]any)
|
||||
driverCaptcha := &base64Captcha.DriverString{
|
||||
//Height png height in pixel.
|
||||
Height: char["height"].(int),
|
||||
// Width Captcha png width in pixel.
|
||||
Width: char["width"].(int),
|
||||
//NoiseCount text noise count.
|
||||
NoiseCount: char["noise"].(int),
|
||||
//Length random string length.
|
||||
Length: char["size"].(int),
|
||||
//Source is a unicode which is the rand string from.
|
||||
Source: char["chars"].(string),
|
||||
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
|
||||
ShowLineOptions: base64Captcha.OptionShowHollowLine,
|
||||
}
|
||||
if char["color"].(bool) {
|
||||
//BgColor captcha image background color (optional)
|
||||
driverCaptcha.BgColor = parse.Color(char["background"].(string))
|
||||
}
|
||||
// 验证码生成
|
||||
id, question, answer := driverCaptcha.GenerateIdQuestionAnswer()
|
||||
// 验证码表达式解析输出
|
||||
item, err := driverCaptcha.DrawCaptcha(question)
|
||||
if err != nil {
|
||||
logger.Infof("Generate Id Question Answer %s %s : %v", captchaType, question, err)
|
||||
} else {
|
||||
data["uuid"] = id
|
||||
data["img"] = item.EncodeB64string()
|
||||
expiration := captcha.EXPIRATION * time.Second
|
||||
verifyKey = cachekey.CAPTCHA_CODE_KEY + id
|
||||
redis.SetByExpire("", verifyKey, answer, expiration)
|
||||
}
|
||||
}
|
||||
|
||||
// 本地开发下返回验证码结果,方便接口调试
|
||||
if config.Env() == "local" {
|
||||
text, _ := redis.Get("", verifyKey)
|
||||
data["text"] = text
|
||||
c.JSON(200, result.Ok(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
20
src/modules/common/controller/common.go
Normal file
20
src/modules/common/controller/common.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 CommontController 结构体
|
||||
var NewCommont = &CommontController{}
|
||||
|
||||
// 通用请求
|
||||
//
|
||||
// PATH /
|
||||
type CommontController struct{}
|
||||
|
||||
// 哈希加密
|
||||
//
|
||||
// GET /hash
|
||||
func (s *CommontController) Hash(c *gin.Context) {
|
||||
c.String(200, "commont Hash")
|
||||
}
|
||||
185
src/modules/common/controller/file.go
Normal file
185
src/modules/common/controller/file.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/constants/uploadsubpath"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 FileController 结构体
|
||||
var NewFile = &FileController{}
|
||||
|
||||
// 文件操作处理
|
||||
//
|
||||
// PATH /
|
||||
type FileController struct{}
|
||||
|
||||
// 下载文件
|
||||
//
|
||||
// GET /download/:filePath
|
||||
func (s *FileController) Download(c *gin.Context) {
|
||||
filePath := c.Param("filePath")
|
||||
if len(filePath) < 8 {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// base64解析出地址
|
||||
decodedBytes, err := base64.StdEncoding.DecodeString(filePath)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, err.Error()))
|
||||
return
|
||||
}
|
||||
routerPath := string(decodedBytes)
|
||||
// 地址文件名截取
|
||||
fileName := routerPath[strings.LastIndex(routerPath, "/")+1:]
|
||||
|
||||
// 响应头
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+url.QueryEscape(fileName)+`"`)
|
||||
c.Writer.Header().Set("Accept-Ranges", "bytes")
|
||||
c.Writer.Header().Set("Content-Type", "application/octet-stream")
|
||||
|
||||
// 断点续传
|
||||
headerRange := c.GetHeader("Range")
|
||||
resultMap, err := file.ReadUploadFileStream(routerPath, headerRange)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
if headerRange != "" {
|
||||
c.Writer.Header().Set("Content-Range", fmt.Sprint(resultMap["range"]))
|
||||
c.Writer.Header().Set("Content-Length", fmt.Sprint(resultMap["chunkSize"]))
|
||||
c.Status(206)
|
||||
} else {
|
||||
c.Writer.Header().Set("Content-Length", fmt.Sprint(resultMap["fileSize"]))
|
||||
c.Status(200)
|
||||
|
||||
}
|
||||
c.Writer.Write(resultMap["data"].([]byte))
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
//
|
||||
// POST /upload
|
||||
func (s *FileController) Upload(c *gin.Context) {
|
||||
// 上传的文件
|
||||
formFile, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 子路径
|
||||
subPath := c.PostForm("subPath")
|
||||
if _, ok := uploadsubpath.UploadSubpath[subPath]; !ok {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上传文件转存
|
||||
upFilePath, err := file.TransferUploadFile(formFile, subPath, nil)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
newFileName := upFilePath[strings.LastIndex(upFilePath, "/")+1:]
|
||||
c.JSON(200, result.OkData(map[string]string{
|
||||
"url": "http://" + c.Request.Host + upFilePath,
|
||||
"fileName": upFilePath,
|
||||
"newFileName": newFileName,
|
||||
"originalFileName": formFile.Filename,
|
||||
}))
|
||||
}
|
||||
|
||||
// 切片文件检查
|
||||
//
|
||||
// POST /chunkCheck
|
||||
func (s *FileController) ChunkCheck(c *gin.Context) {
|
||||
var body struct {
|
||||
// 唯一标识
|
||||
Identifier string `json:"identifier" binding:"required"`
|
||||
// 文件名
|
||||
FileName string `json:"fileName" binding:"required"`
|
||||
}
|
||||
err := c.ShouldBindJSON(&body)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 读取标识目录
|
||||
chunks, err := file.ChunkCheckFile(body.Identifier, body.FileName)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.OkData(chunks))
|
||||
}
|
||||
|
||||
// 切片文件合并
|
||||
//
|
||||
// POST /chunkMerge
|
||||
func (s *FileController) ChunkMerge(c *gin.Context) {
|
||||
var body struct {
|
||||
// 唯一标识
|
||||
Identifier string `json:"identifier" binding:"required"`
|
||||
// 文件名
|
||||
FileName string `json:"fileName" binding:"required"`
|
||||
// 子路径类型
|
||||
SubPath string `json:"subPath" binding:"required"`
|
||||
}
|
||||
err := c.ShouldBindJSON(&body)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
if _, ok := uploadsubpath.UploadSubpath[body.SubPath]; !ok {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 切片文件合并
|
||||
mergeFilePath, err := file.ChunkMergeFile(body.Identifier, body.FileName, body.SubPath)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
newFileName := mergeFilePath[strings.LastIndex(mergeFilePath, "/")+1:]
|
||||
c.JSON(200, result.OkData(map[string]string{
|
||||
"url": "http://" + c.Request.Host + mergeFilePath,
|
||||
"fileName": mergeFilePath,
|
||||
"newFileName": newFileName,
|
||||
"originalFileName": body.FileName,
|
||||
}))
|
||||
}
|
||||
|
||||
// 切片文件上传
|
||||
//
|
||||
// POST /chunkUpload
|
||||
func (s *FileController) ChunkUpload(c *gin.Context) {
|
||||
// 切片编号
|
||||
index := c.PostForm("index")
|
||||
// 切片唯一标识
|
||||
identifier := c.PostForm("identifier")
|
||||
// 上传的文件
|
||||
formFile, err := c.FormFile("file")
|
||||
if index == "" || identifier == "" || err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上传文件转存
|
||||
chunkFilePath, err := file.TransferChunkUploadFile(formFile, index, identifier)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(206, result.OkData(chunkFilePath))
|
||||
}
|
||||
28
src/modules/common/controller/index.go
Normal file
28
src/modules/common/controller/index.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 IndexController 结构体
|
||||
var NewIndex = &IndexController{}
|
||||
|
||||
// 路由主页
|
||||
//
|
||||
// PATH /
|
||||
type IndexController struct{}
|
||||
|
||||
// 根路由
|
||||
//
|
||||
// GET /
|
||||
func (s *IndexController) Handler(c *gin.Context) {
|
||||
name := config.Get("framework.name").(string)
|
||||
version := config.Get("framework.version").(string)
|
||||
str := "欢迎使用%s后台管理框架,当前版本:%s,请通过前端管理地址访问。"
|
||||
c.JSON(200, result.OkMsg(fmt.Sprintf(str, name, version)))
|
||||
}
|
||||
88
src/modules/common/controller/register.go
Normal file
88
src/modules/common/controller/register.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
commonConstants "ems.agt/src/framework/constants/common"
|
||||
ctxUtils "ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/regular"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
commonModel "ems.agt/src/modules/common/model"
|
||||
commonService "ems.agt/src/modules/common/service"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 RegisterController 结构体
|
||||
var NewRegister = &RegisterController{
|
||||
registerService: commonService.NewRegisterImpl,
|
||||
sysLogLoginService: systemService.NewSysLogLoginImpl,
|
||||
}
|
||||
|
||||
// 账号注册操作处理
|
||||
//
|
||||
// PATH /
|
||||
type RegisterController struct {
|
||||
// 账号注册操作服务
|
||||
registerService commonService.IRegister
|
||||
// 系统登录访问
|
||||
sysLogLoginService systemService.ISysLogLogin
|
||||
}
|
||||
|
||||
// 账号注册
|
||||
//
|
||||
// GET /captchaImage
|
||||
func (s *RegisterController) UserName(c *gin.Context) {
|
||||
var registerBody commonModel.RegisterBody
|
||||
if err := c.ShouldBindJSON(®isterBody); err != nil {
|
||||
c.JSON(400, result.ErrMsg("参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断必传参数
|
||||
if !regular.ValidUsername(registerBody.Username) {
|
||||
c.JSON(200, result.ErrMsg("账号不能以数字开头,可包含大写小写字母,数字,且不少于5位"))
|
||||
return
|
||||
}
|
||||
if !regular.ValidPassword(registerBody.Password) {
|
||||
c.JSON(200, result.ErrMsg("登录密码至少包含大小写字母、数字、特殊符号,且不少于6位"))
|
||||
return
|
||||
}
|
||||
if registerBody.Password != registerBody.ConfirmPassword {
|
||||
c.JSON(200, result.ErrMsg("用户确认输入密码不一致"))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := ctxUtils.IPAddrLocation(c)
|
||||
os, browser := ctxUtils.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码
|
||||
err := s.registerService.ValidateCaptcha(
|
||||
registerBody.Code,
|
||||
registerBody.UUID,
|
||||
)
|
||||
// 根据错误信息,创建系统访问记录
|
||||
if err != nil {
|
||||
msg := err.Error() + " " + registerBody.Code
|
||||
s.sysLogLoginService.NewSysLogLogin(
|
||||
registerBody.Username, commonConstants.STATUS_NO, msg,
|
||||
ipaddr, location, os, browser,
|
||||
)
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
infoStr := s.registerService.ByUserName(registerBody.Username, registerBody.Password, registerBody.UserType)
|
||||
if !strings.HasPrefix(infoStr, "注册") {
|
||||
msg := registerBody.Username + " 注册成功 " + infoStr
|
||||
s.sysLogLoginService.NewSysLogLogin(
|
||||
registerBody.Username, commonConstants.STATUS_NO, msg,
|
||||
ipaddr, location, os, browser,
|
||||
)
|
||||
c.JSON(200, result.OkMsg("注册成功"))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.ErrMsg(infoStr))
|
||||
}
|
||||
16
src/modules/common/model/login_body.go
Normal file
16
src/modules/common/model/login_body.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
// LoginBody 用户登录对象
|
||||
type LoginBody struct {
|
||||
// Username 用户名
|
||||
Username string `json:"username" binding:"required"`
|
||||
|
||||
// Password 用户密码
|
||||
Password string `json:"password" binding:"required"`
|
||||
|
||||
// Code 验证码
|
||||
Code string `json:"code"`
|
||||
|
||||
// UUID 验证码唯一标识
|
||||
UUID string `json:"uuid"`
|
||||
}
|
||||
22
src/modules/common/model/register_body.go
Normal file
22
src/modules/common/model/register_body.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package model
|
||||
|
||||
// RegisterBody 用户注册对象
|
||||
type RegisterBody struct {
|
||||
// Username 用户名
|
||||
Username string `json:"username" binding:"required"`
|
||||
|
||||
// Password 用户密码
|
||||
Password string `json:"password" binding:"required"`
|
||||
|
||||
// ConfirmPassword 用户确认密码
|
||||
ConfirmPassword string `json:"confirmPassword" binding:"required"`
|
||||
|
||||
// Code 验证码
|
||||
Code string `json:"code"`
|
||||
|
||||
// UUID 验证码唯一标识
|
||||
UUID string `json:"uuid"`
|
||||
|
||||
// UserType 标记用户类型
|
||||
UserType string `json:"userType"`
|
||||
}
|
||||
21
src/modules/common/service/account.go
Normal file
21
src/modules/common/service/account.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package service
|
||||
|
||||
import "ems.agt/src/framework/vo"
|
||||
|
||||
// 账号身份操作服务 服务层接口
|
||||
type IAccount interface {
|
||||
// ValidateCaptcha 校验验证码
|
||||
ValidateCaptcha(code, uuid string) error
|
||||
|
||||
// LoginByUsername 登录生成token
|
||||
LoginByUsername(username, password string) (vo.LoginUser, error)
|
||||
|
||||
// ClearLoginRecordCache 清除错误记录次数
|
||||
ClearLoginRecordCache(username string) bool
|
||||
|
||||
// RoleAndMenuPerms 角色和菜单数据权限
|
||||
RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string)
|
||||
|
||||
// RouteMenus 前端路由所需要的菜单
|
||||
RouteMenus(userId string, isAdmin bool) []vo.Router
|
||||
}
|
||||
166
src/modules/common/service/account.impl.go
Normal file
166
src/modules/common/service/account.impl.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
adminConstants "ems.agt/src/framework/constants/admin"
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/framework/utils/crypto"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化服务层 AccountImpl 结构体
|
||||
var NewAccountImpl = &AccountImpl{
|
||||
sysUserService: systemService.NewSysUserImpl,
|
||||
sysConfigService: systemService.NewSysConfigImpl,
|
||||
sysRoleService: systemService.NewSysRoleImpl,
|
||||
sysMenuService: systemService.NewSysMenuImpl,
|
||||
}
|
||||
|
||||
// 账号身份操作服务 服务层处理
|
||||
type AccountImpl struct {
|
||||
// 用户信息服务
|
||||
sysUserService systemService.ISysUser
|
||||
// 参数配置服务
|
||||
sysConfigService systemService.ISysConfig
|
||||
// 角色服务
|
||||
sysRoleService systemService.ISysRole
|
||||
// 菜单服务
|
||||
sysMenuService systemService.ISysMenu
|
||||
}
|
||||
|
||||
// ValidateCaptcha 校验验证码
|
||||
func (s *AccountImpl) ValidateCaptcha(code, uuid string) error {
|
||||
// 验证码检查,从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
|
||||
if !parse.Boolean(captchaEnabledStr) {
|
||||
return nil
|
||||
}
|
||||
if code == "" || uuid == "" {
|
||||
return errors.New("验证码信息错误")
|
||||
}
|
||||
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
|
||||
captcha, _ := redis.Get("", verifyKey)
|
||||
if captcha == "" {
|
||||
return errors.New("验证码已失效")
|
||||
}
|
||||
redis.Del("", verifyKey)
|
||||
if captcha != code {
|
||||
return errors.New("验证码错误")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoginByUsername 登录创建用户信息
|
||||
func (s *AccountImpl) LoginByUsername(username, password string) (vo.LoginUser, error) {
|
||||
loginUser := vo.LoginUser{}
|
||||
|
||||
// 检查密码重试次数
|
||||
retrykey, retryCount, lockTime, err := s.passwordRetryCount(username)
|
||||
if err != nil {
|
||||
return loginUser, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.SelectUserByUserName(username)
|
||||
if sysUser.UserName != username {
|
||||
return loginUser, errors.New("用户不存在或密码错误")
|
||||
}
|
||||
if sysUser.DelFlag == common.STATUS_YES {
|
||||
return loginUser, errors.New("对不起,您的账号已被删除")
|
||||
}
|
||||
if sysUser.Status == common.STATUS_NO {
|
||||
return loginUser, errors.New("对不起,您的账号已禁用")
|
||||
}
|
||||
|
||||
// 检验用户密码
|
||||
compareBool := crypto.BcryptCompare(password, sysUser.Password)
|
||||
if !compareBool {
|
||||
redis.SetByExpire("", retrykey, retryCount+1, lockTime)
|
||||
return loginUser, errors.New("用户不存在或密码错误")
|
||||
} else {
|
||||
// 清除错误记录次数
|
||||
s.ClearLoginRecordCache(username)
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser.UserID = sysUser.UserID
|
||||
loginUser.DeptID = sysUser.DeptID
|
||||
loginUser.User = sysUser
|
||||
// 用户权限组标识
|
||||
isAdmin := config.IsAdmin(sysUser.UserID)
|
||||
if isAdmin {
|
||||
loginUser.Permissions = []string{adminConstants.PERMISSION}
|
||||
} else {
|
||||
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
|
||||
loginUser.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return loginUser, nil
|
||||
}
|
||||
|
||||
// ClearLoginRecordCache 清除错误记录次数
|
||||
func (s *AccountImpl) ClearLoginRecordCache(username string) bool {
|
||||
cacheKey := cachekey.PWD_ERR_CNT_KEY + username
|
||||
hasKey, _ := redis.Has("", cacheKey)
|
||||
if hasKey {
|
||||
delOk, _ := redis.Del("", cacheKey)
|
||||
return delOk
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// passwordRetryCount 密码重试次数
|
||||
func (s *AccountImpl) passwordRetryCount(username string) (string, int64, time.Duration, error) {
|
||||
// 验证登录次数和错误锁定时间
|
||||
maxRetryCount := config.Get("user.password.maxRetryCount").(int)
|
||||
lockTime := config.Get("user.password.lockTime").(int)
|
||||
// 验证缓存记录次数
|
||||
retrykey := cachekey.PWD_ERR_CNT_KEY + username
|
||||
retryCount, err := redis.Get("", retrykey)
|
||||
if retryCount == "" || err != nil {
|
||||
retryCount = "0"
|
||||
}
|
||||
// 是否超过错误值
|
||||
if parse.Number(retryCount) >= int64(maxRetryCount) {
|
||||
msg := fmt.Sprintf("密码输入错误 %d 次,帐户锁定 %d 分钟", maxRetryCount, lockTime)
|
||||
return retrykey, int64(maxRetryCount), time.Duration(lockTime) * time.Minute, errors.New(msg)
|
||||
}
|
||||
return retrykey, int64(maxRetryCount), time.Duration(lockTime) * time.Minute, nil
|
||||
}
|
||||
|
||||
// RoleAndMenuPerms 角色和菜单数据权限
|
||||
func (s *AccountImpl) RoleAndMenuPerms(userId string, isAdmin bool) ([]string, []string) {
|
||||
if isAdmin {
|
||||
return []string{adminConstants.ROLE_KEY}, []string{adminConstants.PERMISSION}
|
||||
} else {
|
||||
// 角色key
|
||||
roleGroup := []string{}
|
||||
roles := s.sysRoleService.SelectRoleListByUserId(userId)
|
||||
for _, role := range roles {
|
||||
roleGroup = append(roleGroup, role.RoleKey)
|
||||
}
|
||||
// 菜单权限key
|
||||
perms := s.sysMenuService.SelectMenuPermsByUserId(userId)
|
||||
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
|
||||
}
|
||||
}
|
||||
|
||||
// RouteMenus 前端路由所需要的菜单
|
||||
func (s *AccountImpl) RouteMenus(userId string, isAdmin bool) []vo.Router {
|
||||
var buildMenus []vo.Router
|
||||
if isAdmin {
|
||||
menus := s.sysMenuService.SelectMenuTreeByUserId("*")
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
} else {
|
||||
menus := s.sysMenuService.SelectMenuTreeByUserId(userId)
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
}
|
||||
return buildMenus
|
||||
}
|
||||
10
src/modules/common/service/register.go
Normal file
10
src/modules/common/service/register.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package service
|
||||
|
||||
// 账号注册操作处理 服务层接口
|
||||
type IRegister interface {
|
||||
// ValidateCaptcha 校验验证码
|
||||
ValidateCaptcha(code, uuid string) error
|
||||
|
||||
// ByUserName 账号注册
|
||||
ByUserName(username, password, userType string) string
|
||||
}
|
||||
100
src/modules/common/service/register.impl.go
Normal file
100
src/modules/common/service/register.impl.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
systemModel "ems.agt/src/modules/system/model"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化服务层 RegisterImpl 结构体
|
||||
var NewRegisterImpl = &RegisterImpl{
|
||||
sysUserService: systemService.NewSysUserImpl,
|
||||
sysConfigService: systemService.NewSysConfigImpl,
|
||||
sysRoleService: systemService.NewSysRoleImpl,
|
||||
}
|
||||
|
||||
// 账号注册操作处理 服务层处理
|
||||
type RegisterImpl struct {
|
||||
// 用户信息服务
|
||||
sysUserService systemService.ISysUser
|
||||
// 参数配置服务
|
||||
sysConfigService systemService.ISysConfig
|
||||
// 角色服务
|
||||
sysRoleService systemService.ISysRole
|
||||
}
|
||||
|
||||
// ValidateCaptcha 校验验证码
|
||||
func (s *RegisterImpl) ValidateCaptcha(code, uuid string) error {
|
||||
// 验证码检查,从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.SelectConfigValueByKey("sys.account.captchaEnabled")
|
||||
if !parse.Boolean(captchaEnabledStr) {
|
||||
return nil
|
||||
}
|
||||
if code == "" || uuid == "" {
|
||||
return errors.New("验证码信息错误")
|
||||
}
|
||||
verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid
|
||||
captcha, err := redis.Get("", verifyKey)
|
||||
if captcha == "" || err != nil {
|
||||
return errors.New("验证码已失效")
|
||||
}
|
||||
redis.Del("", verifyKey)
|
||||
if captcha != code {
|
||||
return errors.New("验证码错误")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByUserName 账号注册
|
||||
func (s *RegisterImpl) ByUserName(username, password, userType string) string {
|
||||
// 检查用户登录账号是否唯一
|
||||
uniqueUserName := s.sysUserService.CheckUniqueUserName(username, "")
|
||||
if !uniqueUserName {
|
||||
return fmt.Sprintf("注册用户【%s】失败,注册账号已存在", username)
|
||||
}
|
||||
|
||||
sysUser := systemModel.SysUser{
|
||||
UserName: username,
|
||||
NickName: username, // 昵称使用名称账号
|
||||
Password: password, // 原始密码
|
||||
Status: common.STATUS_YES, // 账号状态激活
|
||||
DeptID: "100", // 归属部门为根节点
|
||||
CreateBy: "注册", // 创建来源
|
||||
}
|
||||
// 标记用户类型
|
||||
if userType == "" {
|
||||
sysUser.UserType = "sys"
|
||||
}
|
||||
// 新增用户的角色管理
|
||||
sysUser.RoleIDs = s.registerRoleInit(userType)
|
||||
// 新增用户的岗位管理
|
||||
sysUser.PostIDs = s.registerPostInit(userType)
|
||||
|
||||
insertId := s.sysUserService.InsertUser(sysUser)
|
||||
if insertId != "" {
|
||||
return insertId
|
||||
}
|
||||
return "注册失败,请联系系统管理人员"
|
||||
}
|
||||
|
||||
// registerRoleInit 注册初始角色
|
||||
func (s *RegisterImpl) registerRoleInit(userType string) []string {
|
||||
if userType == "sys" {
|
||||
return []string{}
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// registerPostInit 注册初始岗位
|
||||
func (s *RegisterImpl) registerPostInit(userType string) []string {
|
||||
if userType == "sys" {
|
||||
return []string{}
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
149
src/modules/monitor/controller/sys_cache.go
Normal file
149
src/modules/monitor/controller/sys_cache.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysCacheController 结构体
|
||||
var NewSysCache = &SysCacheController{}
|
||||
|
||||
// 缓存监控信息
|
||||
//
|
||||
// PATH /monitor/cache
|
||||
type SysCacheController struct{}
|
||||
|
||||
// Redis信息
|
||||
//
|
||||
// GET /
|
||||
func (s *SysCacheController) Info(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"info": redis.Info(""),
|
||||
"dbSize": redis.KeySize(""),
|
||||
"commandStats": redis.CommandStats(""),
|
||||
}))
|
||||
}
|
||||
|
||||
// 缓存名称列表
|
||||
//
|
||||
// GET /getNames
|
||||
func (s *SysCacheController) Names(c *gin.Context) {
|
||||
caches := []model.SysCache{
|
||||
model.NewSysCacheNames("用户信息", cachekey.LOGIN_TOKEN_KEY),
|
||||
model.NewSysCacheNames("配置信息", cachekey.SYS_CONFIG_KEY),
|
||||
model.NewSysCacheNames("数据字典", cachekey.SYS_DICT_KEY),
|
||||
model.NewSysCacheNames("验证码", cachekey.CAPTCHA_CODE_KEY),
|
||||
model.NewSysCacheNames("防重提交", cachekey.REPEAT_SUBMIT_KEY),
|
||||
model.NewSysCacheNames("限流处理", cachekey.RATE_LIMIT_KEY),
|
||||
model.NewSysCacheNames("密码错误次数", cachekey.PWD_ERR_CNT_KEY),
|
||||
}
|
||||
c.JSON(200, result.OkData(caches))
|
||||
}
|
||||
|
||||
// 缓存名称下键名列表
|
||||
//
|
||||
// GET /getKeys/:cacheName
|
||||
func (s *SysCacheController) Keys(c *gin.Context) {
|
||||
cacheName := c.Param("cacheName")
|
||||
if cacheName == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
caches := []model.SysCache{}
|
||||
|
||||
// 遍历组装
|
||||
cacheKeys, _ := redis.GetKeys("", cacheName+":*")
|
||||
for _, key := range cacheKeys {
|
||||
caches = append(caches, model.NewSysCacheKeys(cacheName, key))
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(caches))
|
||||
}
|
||||
|
||||
// 缓存内容
|
||||
//
|
||||
// GET /getValue/:cacheName/:cacheKey
|
||||
func (s *SysCacheController) Value(c *gin.Context) {
|
||||
cacheName := c.Param("cacheName")
|
||||
cacheKey := c.Param("cacheKey")
|
||||
if cacheName == "" || cacheKey == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
cacheValue, err := redis.Get("", cacheName+":"+cacheKey)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
sysCache := model.NewSysCacheValue(cacheName, cacheKey, cacheValue)
|
||||
c.JSON(200, result.OkData(sysCache))
|
||||
}
|
||||
|
||||
// 删除缓存名称下键名列表
|
||||
//
|
||||
// DELETE /clearCacheName/:cacheName
|
||||
func (s *SysCacheController) ClearCacheName(c *gin.Context) {
|
||||
cacheName := c.Param("cacheName")
|
||||
if cacheName == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
cacheKeys, err := redis.GetKeys("", cacheName+":*")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
ok, _ := redis.DelKeys("", cacheKeys)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 删除缓存键名
|
||||
//
|
||||
// DELETE /clearCacheKey/:cacheName/:cacheKey
|
||||
func (s *SysCacheController) ClearCacheKey(c *gin.Context) {
|
||||
cacheName := c.Param("cacheName")
|
||||
cacheKey := c.Param("cacheKey")
|
||||
if cacheName == "" || cacheKey == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
ok, _ := redis.Del("", cacheName+":"+cacheKey)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 安全清理缓存名称
|
||||
//
|
||||
// DELETE /clearCacheSafe
|
||||
func (s *SysCacheController) ClearCacheSafe(c *gin.Context) {
|
||||
caches := []model.SysCache{
|
||||
model.NewSysCacheNames("配置信息", cachekey.SYS_CONFIG_KEY),
|
||||
model.NewSysCacheNames("数据字典", cachekey.SYS_DICT_KEY),
|
||||
model.NewSysCacheNames("验证码", cachekey.CAPTCHA_CODE_KEY),
|
||||
model.NewSysCacheNames("防重提交", cachekey.REPEAT_SUBMIT_KEY),
|
||||
model.NewSysCacheNames("限流处理", cachekey.RATE_LIMIT_KEY),
|
||||
model.NewSysCacheNames("密码错误次数", cachekey.PWD_ERR_CNT_KEY),
|
||||
}
|
||||
for _, v := range caches {
|
||||
cacheKeys, err := redis.GetKeys("", v.CacheName+":*")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
redis.DelKeys("", cacheKeys)
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
338
src/modules/monitor/controller/sys_job.go
Normal file
338
src/modules/monitor/controller/sys_job.go
Normal file
@@ -0,0 +1,338 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
"ems.agt/src/modules/monitor/service"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysJobLogController 结构体
|
||||
var NewSysJob = &SysJobController{
|
||||
sysJobService: service.NewSysJobImpl,
|
||||
sysDictDataService: systemService.NewSysDictDataImpl,
|
||||
}
|
||||
|
||||
// 调度任务信息
|
||||
//
|
||||
// PATH /monitor/job
|
||||
type SysJobController struct {
|
||||
// 调度任务服务
|
||||
sysJobService service.ISysJob
|
||||
// 字典数据服务
|
||||
sysDictDataService systemService.ISysDictData
|
||||
}
|
||||
|
||||
// 调度任务列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysJobController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysJobService.SelectJobPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 调度任务信息
|
||||
//
|
||||
// GET /:jobId
|
||||
func (s *SysJobController) Info(c *gin.Context) {
|
||||
jobId := c.Param("jobId")
|
||||
if jobId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.sysJobService.SelectJobById(jobId)
|
||||
if data.JobID == jobId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysJobController) Add(c *gin.Context) {
|
||||
var body model.SysJob
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.JobID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查cron表达式格式
|
||||
if parse.CronExpression(body.CronExpression) == 0 {
|
||||
msg := fmt.Sprintf("调度任务新增【%s】失败,Cron表达式不正确", body.JobName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查任务调用传入参数是否json格式
|
||||
if body.TargetParams != "" {
|
||||
msg := fmt.Sprintf("调度任务新增【%s】失败,任务传入参数json字符串不正确", body.JobName)
|
||||
if len(body.TargetParams) < 7 {
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
if !json.Valid([]byte(body.TargetParams)) {
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueJob := s.sysJobService.CheckUniqueJobName(body.JobName, body.JobGroup, "")
|
||||
if !uniqueJob {
|
||||
msg := fmt.Sprintf("调度任务新增【%s】失败,同任务组内有相同任务名称", body.JobName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysJobService.InsertJob(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysJobController) Edit(c *gin.Context) {
|
||||
var body model.SysJob
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.JobID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查cron表达式格式
|
||||
if parse.CronExpression(body.CronExpression) == 0 {
|
||||
msg := fmt.Sprintf("调度任务修改【%s】失败,Cron表达式不正确", body.JobName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查任务调用传入参数是否json格式
|
||||
if body.TargetParams != "" {
|
||||
msg := fmt.Sprintf("调度任务修改【%s】失败,任务传入参数json字符串不正确", body.JobName)
|
||||
if len(body.TargetParams) < 7 {
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
if !json.Valid([]byte(body.TargetParams)) {
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueJob := s.sysJobService.CheckUniqueJobName(body.JobName, body.JobGroup, body.JobID)
|
||||
if !uniqueJob {
|
||||
msg := fmt.Sprintf("调度任务修改【%s】失败,同任务组内有相同任务名称", body.JobName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysJobService.UpdateJob(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务删除
|
||||
//
|
||||
// DELETE /:jobIds
|
||||
func (s *SysJobController) Remove(c *gin.Context) {
|
||||
jobIds := c.Param("jobIds")
|
||||
if jobIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(jobIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysJobService.DeleteJobByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 调度任务修改状态
|
||||
//
|
||||
// PUT /changeStatus
|
||||
func (s *SysJobController) Status(c *gin.Context) {
|
||||
var body struct {
|
||||
// 任务ID
|
||||
JobId string `json:"jobId" binding:"required"`
|
||||
// 状态
|
||||
Status string `json:"status" binding:"required"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
job := s.sysJobService.SelectJobById(body.JobId)
|
||||
if job.JobID != body.JobId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问调度任务数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 与旧值相等不变更
|
||||
if job.Status == body.Status {
|
||||
c.JSON(200, result.ErrMsg("变更状态与旧值相等!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
job.Status = body.Status
|
||||
job.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
ok := s.sysJobService.ChangeStatus(job)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务立即执行一次
|
||||
//
|
||||
// PUT /run/:jobId
|
||||
func (s *SysJobController) Run(c *gin.Context) {
|
||||
jobId := c.Param("jobId")
|
||||
if jobId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
job := s.sysJobService.SelectJobById(jobId)
|
||||
if job.JobID != jobId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问调度任务数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
ok := s.sysJobService.RunQueueJob(job)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务重置刷新队列
|
||||
//
|
||||
// PUT /resetQueueJob
|
||||
func (s *SysJobController) ResetQueueJob(c *gin.Context) {
|
||||
s.sysJobService.ResetQueueJob()
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 导出调度任务信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysJobController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysJobService.SelectJobPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysJob)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("job_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "任务编号",
|
||||
"B1": "任务名称",
|
||||
"C1": "任务组名",
|
||||
"D1": "调用目标",
|
||||
"E1": "传入参数",
|
||||
"F1": "执行表达式",
|
||||
"G1": "出错策略",
|
||||
"H1": "并发执行",
|
||||
"I1": "任务状态",
|
||||
"J1": "备注说明",
|
||||
}
|
||||
// 读取任务组名字典数据
|
||||
dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 任务组名
|
||||
sysJobGroup := ""
|
||||
for _, v := range dictSysJobGroup {
|
||||
if row.JobGroup == v.DictValue {
|
||||
sysJobGroup = v.DictLabel
|
||||
break
|
||||
}
|
||||
}
|
||||
misfirePolicy := "放弃执行"
|
||||
if row.MisfirePolicy == "1" {
|
||||
misfirePolicy = "立即执行"
|
||||
} else if row.MisfirePolicy == "2" {
|
||||
misfirePolicy = "执行一次"
|
||||
}
|
||||
concurrent := "禁止"
|
||||
if row.Concurrent == "1" {
|
||||
concurrent = "允许"
|
||||
}
|
||||
// 状态
|
||||
statusValue := "失败"
|
||||
if row.Status == "1" {
|
||||
statusValue = "成功"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.JobID,
|
||||
"B" + idx: row.JobName,
|
||||
"C" + idx: sysJobGroup,
|
||||
"D" + idx: row.InvokeTarget,
|
||||
"E" + idx: row.TargetParams,
|
||||
"F" + idx: row.CronExpression,
|
||||
"G" + idx: misfirePolicy,
|
||||
"H" + idx: concurrent,
|
||||
"I" + idx: statusValue,
|
||||
"J" + idx: row.Remark,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
167
src/modules/monitor/controller/sys_job_log.go
Normal file
167
src/modules/monitor/controller/sys_job_log.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
"ems.agt/src/modules/monitor/service"
|
||||
systemService "ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysJobLogController 结构体
|
||||
var NewSysJobLog = &SysJobLogController{
|
||||
sysJobLogService: service.NewSysJobLogImpl,
|
||||
sysDictDataService: systemService.NewSysDictDataImpl,
|
||||
}
|
||||
|
||||
// 调度任务日志信息
|
||||
//
|
||||
// PATH /monitor/jobLog
|
||||
type SysJobLogController struct {
|
||||
// 调度任务日志服务
|
||||
sysJobLogService service.ISysJobLog
|
||||
// 字典数据服务
|
||||
sysDictDataService systemService.ISysDictData
|
||||
}
|
||||
|
||||
// 调度任务日志列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysJobLogController) List(c *gin.Context) {
|
||||
// 查询参数转换map
|
||||
querys := ctx.QueryMap(c)
|
||||
list := s.sysJobLogService.SelectJobLogPage(querys)
|
||||
c.JSON(200, result.Ok(list))
|
||||
}
|
||||
|
||||
// 调度任务日志信息
|
||||
//
|
||||
// GET /:jobLogId
|
||||
func (s *SysJobLogController) Info(c *gin.Context) {
|
||||
jobLogId := c.Param("jobLogId")
|
||||
if jobLogId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysJobLogService.SelectJobLogById(jobLogId)
|
||||
if data.JobLogID == jobLogId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务日志删除
|
||||
//
|
||||
// DELETE /:jobLogIds
|
||||
func (s *SysJobLogController) Remove(c *gin.Context) {
|
||||
jobLogIds := c.Param("jobLogIds")
|
||||
if jobLogIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(jobLogIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows := s.sysJobLogService.DeleteJobLogByIds(uniqueIDs)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 调度任务日志清空
|
||||
//
|
||||
// DELETE /clean
|
||||
func (s *SysJobLogController) Clean(c *gin.Context) {
|
||||
err := s.sysJobLogService.CleanJobLog()
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 导出调度任务日志信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysJobLogController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysJobLogService.SelectJobLogPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysJobLog)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("jobLog_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "日志序号",
|
||||
"B1": "任务名称",
|
||||
"C1": "任务组名",
|
||||
"D1": "调用目标",
|
||||
"E1": "传入参数",
|
||||
"F1": "日志信息",
|
||||
"G1": "执行状态",
|
||||
"H1": "记录时间",
|
||||
}
|
||||
// 读取任务组名字典数据
|
||||
dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 任务组名
|
||||
sysJobGroup := ""
|
||||
for _, v := range dictSysJobGroup {
|
||||
if row.JobGroup == v.DictValue {
|
||||
sysJobGroup = v.DictLabel
|
||||
break
|
||||
}
|
||||
}
|
||||
// 状态
|
||||
statusValue := "失败"
|
||||
if row.Status == "1" {
|
||||
statusValue = "成功"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.JobLogID,
|
||||
"B" + idx: row.JobName,
|
||||
"C" + idx: sysJobGroup,
|
||||
"D" + idx: row.InvokeTarget,
|
||||
"E" + idx: row.TargetParams,
|
||||
"F" + idx: row.JobMsg,
|
||||
"G" + idx: statusValue,
|
||||
"H" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DD_HH_MM_SS),
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
126
src/modules/monitor/controller/sys_user_online.go
Normal file
126
src/modules/monitor/controller/sys_user_online.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/framework/vo"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
"ems.agt/src/modules/monitor/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysUserOnlineController 结构体
|
||||
var NewSysUserOnline = &SysUserOnlineController{
|
||||
sysUserOnlineService: service.NewSysUserOnlineImpl,
|
||||
}
|
||||
|
||||
// 在线用户监控
|
||||
//
|
||||
// PATH /monitor/online
|
||||
type SysUserOnlineController struct {
|
||||
// 在线用户服务
|
||||
sysUserOnlineService service.ISysUserOnline
|
||||
}
|
||||
|
||||
// 在线用户列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysUserOnlineController) List(c *gin.Context) {
|
||||
ipaddr := c.Query("ipaddr")
|
||||
userName := c.Query("userName")
|
||||
|
||||
// 获取所有在线用户key
|
||||
keys, _ := redis.GetKeys("", cachekey.LOGIN_TOKEN_KEY+"*")
|
||||
|
||||
// 分批获取
|
||||
arr := make([]string, 0)
|
||||
for i := 0; i < len(keys); i += 20 {
|
||||
end := i + 20
|
||||
if end > len(keys) {
|
||||
end = len(keys)
|
||||
}
|
||||
chunk := keys[i:end]
|
||||
values, _ := redis.GetBatch("", chunk)
|
||||
for _, v := range values {
|
||||
arr = append(arr, v.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历字符串信息解析组合可用对象
|
||||
userOnlines := make([]model.SysUserOnline, 0)
|
||||
for _, str := range arr {
|
||||
if str == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
var loginUser vo.LoginUser
|
||||
err := json.Unmarshal([]byte(str), &loginUser)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
onlineUser := s.sysUserOnlineService.LoginUserToUserOnline(loginUser)
|
||||
if onlineUser.TokenID != "" {
|
||||
userOnlines = append(userOnlines, onlineUser)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据查询条件过滤
|
||||
filteredUserOnlines := make([]model.SysUserOnline, 0)
|
||||
if ipaddr != "" && userName != "" {
|
||||
for _, o := range userOnlines {
|
||||
if strings.Contains(o.IPAddr, ipaddr) && strings.Contains(o.UserName, userName) {
|
||||
filteredUserOnlines = append(filteredUserOnlines, o)
|
||||
}
|
||||
}
|
||||
} else if ipaddr != "" {
|
||||
for _, o := range userOnlines {
|
||||
if strings.Contains(o.IPAddr, ipaddr) {
|
||||
filteredUserOnlines = append(filteredUserOnlines, o)
|
||||
}
|
||||
}
|
||||
} else if userName != "" {
|
||||
for _, o := range userOnlines {
|
||||
if strings.Contains(o.UserName, userName) {
|
||||
filteredUserOnlines = append(filteredUserOnlines, o)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filteredUserOnlines = userOnlines
|
||||
}
|
||||
|
||||
// 按登录时间排序
|
||||
sort.Slice(filteredUserOnlines, func(i, j int) bool {
|
||||
return filteredUserOnlines[j].LoginTime > filteredUserOnlines[i].LoginTime
|
||||
})
|
||||
|
||||
c.JSON(200, result.Ok(map[string]any{
|
||||
"total": len(filteredUserOnlines),
|
||||
"rows": filteredUserOnlines,
|
||||
}))
|
||||
}
|
||||
|
||||
// 在线用户强制退出
|
||||
//
|
||||
// DELETE /:tokenId
|
||||
func (s *SysUserOnlineController) ForceLogout(c *gin.Context) {
|
||||
tokenId := c.Param("tokenId")
|
||||
if tokenId == "" || tokenId == "*" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 删除token
|
||||
ok, _ := redis.Del("", cachekey.LOGIN_TOKEN_KEY+tokenId)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
36
src/modules/monitor/controller/system_info.go
Normal file
36
src/modules/monitor/controller/system_info.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/monitor/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SystemInfoController 结构体
|
||||
var NewSystemInfo = &SystemInfoController{
|
||||
systemInfogService: service.NewSystemInfoImpl,
|
||||
}
|
||||
|
||||
// 服务器监控信息
|
||||
//
|
||||
// PATH /monitor/system-info
|
||||
type SystemInfoController struct {
|
||||
// 服务器系统相关信息服务
|
||||
systemInfogService service.ISystemInfo
|
||||
}
|
||||
|
||||
// 服务器信息
|
||||
//
|
||||
// GET /
|
||||
func (s *SystemInfoController) Info(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"project": s.systemInfogService.ProjectInfo(),
|
||||
"cpu": s.systemInfogService.CPUInfo(),
|
||||
"memory": s.systemInfogService.MemoryInfo(),
|
||||
"network": s.systemInfogService.NetworkInfo(),
|
||||
"time": s.systemInfogService.TimeInfo(),
|
||||
"system": s.systemInfogService.SystemInfo(),
|
||||
"disk": s.systemInfogService.DiskInfo(),
|
||||
}))
|
||||
}
|
||||
41
src/modules/monitor/model/sys_cache.go
Normal file
41
src/modules/monitor/model/sys_cache.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package model
|
||||
|
||||
import "strings"
|
||||
|
||||
// SysCache 缓存信息对象
|
||||
type SysCache struct {
|
||||
CacheName string `json:"cacheName"` // 缓存名称
|
||||
CacheKey string `json:"cacheKey"` // 缓存键名
|
||||
CacheValue string `json:"cacheValue"` // 缓存内容
|
||||
Remark string `json:"remark"` // 备注
|
||||
}
|
||||
|
||||
// NewSysCacheNames 创建新的缓存名称列表项实例
|
||||
func NewSysCacheNames(cacheName string, cacheKey string) SysCache {
|
||||
return SysCache{
|
||||
CacheName: cacheKey[:len(cacheKey)-1],
|
||||
CacheKey: "",
|
||||
CacheValue: "",
|
||||
Remark: cacheName,
|
||||
}
|
||||
}
|
||||
|
||||
// NewSysCacheKeys 创建新的缓存键名列表项实例
|
||||
func NewSysCacheKeys(cacheName string, cacheKey string) SysCache {
|
||||
return SysCache{
|
||||
CacheName: cacheName,
|
||||
CacheKey: strings.Replace(cacheKey, cacheName+":", "", 1),
|
||||
CacheValue: "",
|
||||
Remark: "",
|
||||
}
|
||||
}
|
||||
|
||||
// NewSysCacheValue 创建新的缓存键名内容项实例
|
||||
func NewSysCacheValue(cacheName string, cacheKey string, cacheValue string) SysCache {
|
||||
return SysCache{
|
||||
CacheName: cacheName,
|
||||
CacheKey: cacheKey,
|
||||
CacheValue: cacheValue,
|
||||
Remark: "",
|
||||
}
|
||||
}
|
||||
33
src/modules/monitor/model/sys_job.go
Normal file
33
src/modules/monitor/model/sys_job.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package model
|
||||
|
||||
// SysJob 调度任务信息表 sys_job
|
||||
type SysJob struct {
|
||||
// 任务ID
|
||||
JobID string `json:"jobId"`
|
||||
// 任务名称
|
||||
JobName string `json:"jobName" binding:"required"`
|
||||
// 任务组名
|
||||
JobGroup string `json:"jobGroup" binding:"required"`
|
||||
// 调用目标字符串
|
||||
InvokeTarget string `json:"invokeTarget" binding:"required"`
|
||||
// 调用目标传入参数
|
||||
TargetParams string `json:"targetParams"`
|
||||
// cron执行表达式
|
||||
CronExpression string `json:"cronExpression" binding:"required"`
|
||||
// 计划执行错误策略(1立即执行 2执行一次 3放弃执行)
|
||||
MisfirePolicy string `json:"misfirePolicy"`
|
||||
// 是否并发执行(0禁止 1允许)
|
||||
Concurrent string `json:"concurrent"`
|
||||
// 任务状态(0暂停 1正常)
|
||||
Status string `json:"status"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
23
src/modules/monitor/model/sys_job_log.go
Normal file
23
src/modules/monitor/model/sys_job_log.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// SysJobLog 定时任务调度日志表 sys_job_log
|
||||
type SysJobLog struct {
|
||||
// 日志序号
|
||||
JobLogID string `json:"jobLogId"`
|
||||
// 任务名称
|
||||
JobName string `json:"jobName"`
|
||||
// 任务组名
|
||||
JobGroup string `json:"jobGroup"`
|
||||
// 调用目标字符串
|
||||
InvokeTarget string `json:"invokeTarget"`
|
||||
// 调用目标传入参数
|
||||
TargetParams string `json:"targetParams"`
|
||||
// 日志信息
|
||||
JobMsg string `json:"jobMsg"`
|
||||
// 执行状态(0失败 1正常)
|
||||
Status string `json:"status"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 消耗时间(毫秒)
|
||||
CostTime int64 `json:"costTime"`
|
||||
}
|
||||
21
src/modules/monitor/model/sys_user_online.go
Normal file
21
src/modules/monitor/model/sys_user_online.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
// SysUserOnline 当前在线会话对象
|
||||
type SysUserOnline struct {
|
||||
// 会话编号
|
||||
TokenID string `json:"tokenId"`
|
||||
// 部门名称
|
||||
DeptName string `json:"deptName"`
|
||||
// 用户名称
|
||||
UserName string `json:"userName"`
|
||||
// 登录IP地址
|
||||
IPAddr string `json:"ipaddr"`
|
||||
// 登录地址
|
||||
LoginLocation string `json:"loginLocation"`
|
||||
// 浏览器类型
|
||||
Browser string `json:"browser"`
|
||||
// 操作系统
|
||||
OS string `json:"os"`
|
||||
// 登录时间
|
||||
LoginTime int64 `json:"loginTime"`
|
||||
}
|
||||
160
src/modules/monitor/monitor.go
Normal file
160
src/modules/monitor/monitor.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/middleware"
|
||||
"ems.agt/src/framework/middleware/collectlogs"
|
||||
"ems.agt/src/framework/middleware/repeat"
|
||||
"ems.agt/src/modules/monitor/controller"
|
||||
"ems.agt/src/modules/monitor/processor"
|
||||
"ems.agt/src/modules/monitor/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Setup 模块路由注册
|
||||
func Setup(router *gin.Engine) {
|
||||
logger.Infof("开始加载 ====> monitor 模块路由")
|
||||
|
||||
// 启动时需要的初始参数
|
||||
InitLoad()
|
||||
|
||||
// 服务器服务信息
|
||||
router.GET("/monitor/system-info",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:system:info"}}),
|
||||
controller.NewSystemInfo.Info,
|
||||
)
|
||||
|
||||
// 缓存服务信息
|
||||
sysCacheGroup := router.Group("/monitor/cache")
|
||||
{
|
||||
sysCacheGroup.GET("",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:info"}}),
|
||||
controller.NewSysCache.Info,
|
||||
)
|
||||
sysCacheGroup.GET("/getNames",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:list"}}),
|
||||
controller.NewSysCache.Names,
|
||||
)
|
||||
sysCacheGroup.GET("/getKeys/:cacheName",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:list"}}),
|
||||
controller.NewSysCache.Keys,
|
||||
)
|
||||
sysCacheGroup.GET("/getValue/:cacheName/:cacheKey",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:query"}}),
|
||||
controller.NewSysCache.Value,
|
||||
)
|
||||
sysCacheGroup.DELETE("/clearCacheName/:cacheName",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:remove"}}),
|
||||
controller.NewSysCache.ClearCacheName,
|
||||
)
|
||||
sysCacheGroup.DELETE("/clearCacheKey/:cacheName/:cacheKey",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:remove"}}),
|
||||
controller.NewSysCache.ClearCacheKey,
|
||||
)
|
||||
sysCacheGroup.DELETE("/clearCacheSafe",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:cache:remove"}}),
|
||||
controller.NewSysCache.ClearCacheSafe,
|
||||
)
|
||||
}
|
||||
|
||||
// 调度任务日志信息
|
||||
sysJobLogGroup := router.Group("/monitor/jobLog")
|
||||
{
|
||||
sysJobLogGroup.GET("/list",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:list"}}),
|
||||
controller.NewSysJobLog.List,
|
||||
)
|
||||
sysJobLogGroup.GET("/:jobLogId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:query"}}),
|
||||
controller.NewSysJobLog.Info,
|
||||
)
|
||||
sysJobLogGroup.DELETE("/:jobLogIds",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务日志信息", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSysJobLog.Remove,
|
||||
)
|
||||
sysJobLogGroup.DELETE("/clean",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务日志信息", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewSysJobLog.Clean,
|
||||
)
|
||||
sysJobLogGroup.POST("/export",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:export"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务日志信息", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSysJobLog.Export,
|
||||
)
|
||||
}
|
||||
|
||||
// 调度任务信息
|
||||
sysJobGroup := router.Group("/monitor/job")
|
||||
{
|
||||
sysJobGroup.GET("/list",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:list"}}),
|
||||
controller.NewSysJob.List,
|
||||
)
|
||||
sysJobGroup.GET("/:jobId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:query"}}),
|
||||
controller.NewSysJob.Info,
|
||||
)
|
||||
sysJobGroup.POST("",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:add"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewSysJob.Add,
|
||||
)
|
||||
sysJobGroup.PUT("",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:edit"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewSysJob.Edit,
|
||||
)
|
||||
sysJobGroup.DELETE("/:jobIds",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSysJob.Remove,
|
||||
)
|
||||
sysJobGroup.PUT("/changeStatus",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewSysJob.Status,
|
||||
)
|
||||
sysJobGroup.PUT("/run/:jobId",
|
||||
repeat.RepeatSubmit(10),
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewSysJob.Run,
|
||||
)
|
||||
sysJobGroup.PUT("/resetQueueJob",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewSysJob.ResetQueueJob,
|
||||
)
|
||||
sysJobGroup.POST("/export",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:export"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("调度任务信息", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSysJob.Export,
|
||||
)
|
||||
}
|
||||
|
||||
// 在线用户监控
|
||||
sysUserOnlineGroup := router.Group("/monitor/online")
|
||||
{
|
||||
sysUserOnlineGroup.GET("/list",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:online:list"}}),
|
||||
controller.NewSysUserOnline.List,
|
||||
)
|
||||
sysUserOnlineGroup.DELETE("/:tokenId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:online:forceLogout"}}),
|
||||
controller.NewSysUserOnline.ForceLogout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InitLoad 初始参数
|
||||
func InitLoad() {
|
||||
// 初始化定时任务处理
|
||||
processor.InitCronQueue()
|
||||
// 启动时,初始化调度任务
|
||||
service.NewSysJobImpl.ResetQueueJob()
|
||||
}
|
||||
60
src/modules/monitor/processor/bar/bar.go
Normal file
60
src/modules/monitor/processor/bar/bar.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package bar
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/cron"
|
||||
"ems.agt/src/framework/logger"
|
||||
)
|
||||
|
||||
var NewProcessor = &BarProcessor{
|
||||
progress: 0,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// bar 队列任务处理
|
||||
type BarProcessor struct {
|
||||
// 任务进度
|
||||
progress int
|
||||
// 执行次数
|
||||
count int
|
||||
}
|
||||
|
||||
func (s *BarProcessor) Execute(data any) any {
|
||||
logger.Infof("执行 %d 次,上次进度: %d ", s.count, s.progress)
|
||||
s.count++
|
||||
|
||||
options := data.(cron.JobData)
|
||||
sysJob := options.SysJob
|
||||
logger.Infof("重复 %v 任务ID %s", options.Repeat, sysJob.JobID)
|
||||
|
||||
// 实现任务处理逻辑
|
||||
i := 0
|
||||
s.progress = i
|
||||
for i < 5 {
|
||||
// 获取任务进度
|
||||
progress := s.progress
|
||||
logger.Infof("jonId: %s => 任务进度:%d", sysJob.JobID, progress)
|
||||
// 延迟响应
|
||||
time.Sleep(time.Second * 2)
|
||||
// 程序中途执行错误
|
||||
if i == 3 {
|
||||
// arr := [1]int{1}
|
||||
// arr[i] = 3
|
||||
// fmt.Println(arr)
|
||||
// return "i = 3"
|
||||
panic("程序中途执行错误")
|
||||
}
|
||||
i++
|
||||
// 改变任务进度
|
||||
s.progress = i
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return map[string]any{
|
||||
"repeat": options.Repeat,
|
||||
"jobName": sysJob.JobName,
|
||||
"invokeTarget": sysJob.InvokeTarget,
|
||||
"targetParams": sysJob.TargetParams,
|
||||
}
|
||||
}
|
||||
52
src/modules/monitor/processor/foo/foo.go
Normal file
52
src/modules/monitor/processor/foo/foo.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package foo
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/cron"
|
||||
"ems.agt/src/framework/logger"
|
||||
)
|
||||
|
||||
var NewProcessor = &FooProcessor{
|
||||
progress: 0,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// foo 队列任务处理
|
||||
type FooProcessor struct {
|
||||
// 任务进度
|
||||
progress int
|
||||
// 执行次数
|
||||
count int
|
||||
}
|
||||
|
||||
func (s *FooProcessor) Execute(data any) any {
|
||||
logger.Infof("执行 %d 次,上次进度: %d ", s.count, s.progress)
|
||||
s.count++
|
||||
|
||||
options := data.(cron.JobData)
|
||||
sysJob := options.SysJob
|
||||
logger.Infof("重复 %v 任务ID %s", options.Repeat, sysJob.JobID)
|
||||
|
||||
// 实现任务处理逻辑
|
||||
i := 0
|
||||
s.progress = i
|
||||
for i < 20 {
|
||||
// 获取任务进度
|
||||
progress := s.progress
|
||||
logger.Infof("jonId: %s => 任务进度:%d", sysJob.JobID, progress)
|
||||
// 延迟响应
|
||||
time.Sleep(time.Second * 2)
|
||||
i++
|
||||
// 改变任务进度
|
||||
s.progress = i
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return map[string]any{
|
||||
"repeat": options.Repeat,
|
||||
"jobName": sysJob.JobName,
|
||||
"invokeTarget": sysJob.InvokeTarget,
|
||||
"targetParams": sysJob.TargetParams,
|
||||
}
|
||||
}
|
||||
15
src/modules/monitor/processor/processor.go
Normal file
15
src/modules/monitor/processor/processor.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/cron"
|
||||
"ems.agt/src/modules/monitor/processor/bar"
|
||||
"ems.agt/src/modules/monitor/processor/foo"
|
||||
"ems.agt/src/modules/monitor/processor/simple"
|
||||
)
|
||||
|
||||
// InitCronQueue 初始定时任务队列
|
||||
func InitCronQueue() {
|
||||
cron.CreateQueue("simple", simple.NewProcessor)
|
||||
cron.CreateQueue("foo", foo.NewProcessor)
|
||||
cron.CreateQueue("bar", bar.NewProcessor)
|
||||
}
|
||||
26
src/modules/monitor/processor/simple/simple.go
Normal file
26
src/modules/monitor/processor/simple/simple.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package simple
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/cron"
|
||||
"ems.agt/src/framework/logger"
|
||||
)
|
||||
|
||||
var NewProcessor = &simpleProcessor{}
|
||||
|
||||
// simple 队列任务处理
|
||||
type simpleProcessor struct{}
|
||||
|
||||
func (s *simpleProcessor) Execute(data any) any {
|
||||
options := data.(cron.JobData)
|
||||
|
||||
sysJob := options.SysJob
|
||||
logger.Infof("重复 %v 任务ID %s", options.Repeat, sysJob.JobID)
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return map[string]any{
|
||||
"repeat": options.Repeat,
|
||||
"jobName": sysJob.JobName,
|
||||
"invokeTarget": sysJob.InvokeTarget,
|
||||
"targetParams": sysJob.TargetParams,
|
||||
}
|
||||
}
|
||||
29
src/modules/monitor/repository/sys_job.go
Normal file
29
src/modules/monitor/repository/sys_job.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// ISysJob 调度任务表 数据层接口
|
||||
type ISysJob interface {
|
||||
// SelectJobPage 分页查询调度任务集合
|
||||
SelectJobPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectJobList 查询调度任务集合
|
||||
SelectJobList(sysJob model.SysJob) []model.SysJob
|
||||
|
||||
// SelectJobByIds 通过调度ID查询调度任务信息
|
||||
SelectJobByIds(jobIds []string) []model.SysJob
|
||||
|
||||
// CheckUniqueJob 校验调度任务是否唯一
|
||||
CheckUniqueJob(sysJob model.SysJob) string
|
||||
|
||||
// InsertJob 新增调度任务信息
|
||||
InsertJob(sysJob model.SysJob) string
|
||||
|
||||
// UpdateJob 修改调度任务信息
|
||||
UpdateJob(sysJob model.SysJob) int64
|
||||
|
||||
// DeleteJobByIds 批量删除调度任务信息
|
||||
DeleteJobByIds(jobIds []string) int64
|
||||
}
|
||||
344
src/modules/monitor/repository/sys_job.impl.go
Normal file
344
src/modules/monitor/repository/sys_job.impl.go
Normal file
@@ -0,0 +1,344 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysJobImpl 结构体
|
||||
var NewSysJobImpl = &SysJobImpl{
|
||||
selectSql: `select job_id, job_name, job_group, invoke_target, target_params, cron_expression,
|
||||
misfire_policy, concurrent, status, create_by, create_time, remark from sys_job`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"job_id": "JobID",
|
||||
"job_name": "JobName",
|
||||
"job_group": "JobGroup",
|
||||
"invoke_target": "InvokeTarget",
|
||||
"target_params": "TargetParams",
|
||||
"cron_expression": "CronExpression",
|
||||
"misfire_policy": "MisfirePolicy",
|
||||
"concurrent": "Concurrent",
|
||||
"status": "Status",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// SysJobImpl 调度任务表 数据层处理
|
||||
type SysJobImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysJobImpl) convertResultRows(rows []map[string]any) []model.SysJob {
|
||||
arr := make([]model.SysJob, 0)
|
||||
for _, row := range rows {
|
||||
sysJob := model.SysJob{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysJob, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysJob)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectJobPage 分页查询调度任务集合
|
||||
func (r *SysJobImpl) SelectJobPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["jobName"]; ok && v != "" {
|
||||
conditions = append(conditions, "job_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["jobGroup"]; ok && v != "" {
|
||||
conditions = append(conditions, "job_group = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["invokeTarget"]; ok && v != "" {
|
||||
conditions = append(conditions, "invoke_target like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysJob{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_job"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectJobList 查询调度任务集合
|
||||
func (r *SysJobImpl) SelectJobList(sysJob model.SysJob) []model.SysJob {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysJob.JobName != "" {
|
||||
conditions = append(conditions, "job_name like concat(?, '%')")
|
||||
params = append(params, sysJob.JobName)
|
||||
}
|
||||
if sysJob.JobGroup != "" {
|
||||
conditions = append(conditions, "job_group = ?")
|
||||
params = append(params, sysJob.JobGroup)
|
||||
}
|
||||
if sysJob.InvokeTarget != "" {
|
||||
conditions = append(conditions, "invoke_target like concat(?, '%')")
|
||||
params = append(params, sysJob.InvokeTarget)
|
||||
}
|
||||
if sysJob.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysJob.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysJob{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectJobByIds 通过调度ID查询调度任务信息
|
||||
func (r *SysJobImpl) SelectJobByIds(jobIds []string) []model.SysJob {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(jobIds))
|
||||
querySql := r.selectSql + " where job_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(jobIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysJob{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// CheckUniqueJob 校验调度任务是否唯一
|
||||
func (r *SysJobImpl) CheckUniqueJob(sysJob model.SysJob) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysJob.JobName != "" {
|
||||
conditions = append(conditions, "job_name = ?")
|
||||
params = append(params, sysJob.JobName)
|
||||
}
|
||||
if sysJob.JobGroup != "" {
|
||||
conditions = append(conditions, "job_group = ?")
|
||||
params = append(params, sysJob.JobGroup)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select job_id as 'str' from sys_job " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InsertJob 新增调度任务信息
|
||||
func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysJob.JobID != "" {
|
||||
params["job_id"] = sysJob.JobID
|
||||
}
|
||||
if sysJob.JobName != "" {
|
||||
params["job_name"] = sysJob.JobName
|
||||
}
|
||||
if sysJob.JobGroup != "" {
|
||||
params["job_group"] = sysJob.JobGroup
|
||||
}
|
||||
if sysJob.InvokeTarget != "" {
|
||||
params["invoke_target"] = sysJob.InvokeTarget
|
||||
}
|
||||
if sysJob.TargetParams != "" {
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
}
|
||||
if sysJob.CronExpression != "" {
|
||||
params["cron_expression"] = sysJob.CronExpression
|
||||
}
|
||||
if sysJob.MisfirePolicy != "" {
|
||||
params["misfire_policy"] = sysJob.MisfirePolicy
|
||||
}
|
||||
if sysJob.Concurrent != "" {
|
||||
params["concurrent"] = sysJob.Concurrent
|
||||
}
|
||||
if sysJob.Status != "" {
|
||||
params["status"] = sysJob.Status
|
||||
}
|
||||
if sysJob.Remark != "" {
|
||||
params["remark"] = sysJob.Remark
|
||||
}
|
||||
if sysJob.CreateBy != "" {
|
||||
params["create_by"] = sysJob.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_job (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateJob 修改调度任务信息
|
||||
func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysJob.JobName != "" {
|
||||
params["job_name"] = sysJob.JobName
|
||||
}
|
||||
if sysJob.JobGroup != "" {
|
||||
params["job_group"] = sysJob.JobGroup
|
||||
}
|
||||
if sysJob.InvokeTarget != "" {
|
||||
params["invoke_target"] = sysJob.InvokeTarget
|
||||
}
|
||||
if sysJob.TargetParams != "" {
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
}
|
||||
if sysJob.CronExpression != "" {
|
||||
params["cron_expression"] = sysJob.CronExpression
|
||||
}
|
||||
if sysJob.MisfirePolicy != "" {
|
||||
params["misfire_policy"] = sysJob.MisfirePolicy
|
||||
}
|
||||
if sysJob.Concurrent != "" {
|
||||
params["concurrent"] = sysJob.Concurrent
|
||||
}
|
||||
if sysJob.Status != "" {
|
||||
params["status"] = sysJob.Status
|
||||
}
|
||||
if sysJob.Remark != "" {
|
||||
params["remark"] = sysJob.Remark
|
||||
}
|
||||
if sysJob.UpdateBy != "" {
|
||||
params["update_by"] = sysJob.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_job set " + strings.Join(keys, ",") + " where job_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysJob.JobID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteJobByIds 批量删除调度任务信息
|
||||
func (r *SysJobImpl) DeleteJobByIds(jobIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(jobIds))
|
||||
sql := "delete from sys_job where job_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(jobIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
26
src/modules/monitor/repository/sys_job_log.go
Normal file
26
src/modules/monitor/repository/sys_job_log.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// 调度任务日志表 数据层接口
|
||||
type ISysJobLog interface {
|
||||
// 分页查询调度任务日志集合
|
||||
SelectJobLogPage(query map[string]any) map[string]any
|
||||
|
||||
// 查询调度任务日志集合
|
||||
SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog
|
||||
|
||||
// 通过调度ID查询调度任务日志信息
|
||||
SelectJobLogById(jobLogId string) model.SysJobLog
|
||||
|
||||
// 新增调度任务日志信息
|
||||
InsertJobLog(sysJobLog model.SysJobLog) string
|
||||
|
||||
// 批量删除调度任务日志信息
|
||||
DeleteJobLogByIds(jobLogId []string) int64
|
||||
|
||||
// 清空调度任务日志
|
||||
CleanJobLog() error
|
||||
}
|
||||
272
src/modules/monitor/repository/sys_job_log.impl.go
Normal file
272
src/modules/monitor/repository/sys_job_log.impl.go
Normal file
@@ -0,0 +1,272 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysJobLogImpl 结构体
|
||||
var NewSysJobLogImpl = &SysJobLogImpl{
|
||||
selectSql: `select job_log_id, job_name, job_group, invoke_target,
|
||||
target_params, job_msg, status, create_time, cost_time from sys_job_log`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"job_log_id": "JobLogID",
|
||||
"job_name": "JobName",
|
||||
"job_group": "JobGroup",
|
||||
"invoke_target": "InvokeTarget",
|
||||
"target_params": "TargetParams",
|
||||
"job_msg": "JobMsg",
|
||||
"status": "Status",
|
||||
"create_time": "CreateTime",
|
||||
"cost_time": "CostTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysJobLogImpl 调度任务日志表 数据层处理
|
||||
type SysJobLogImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysJobLogImpl) convertResultRows(rows []map[string]any) []model.SysJobLog {
|
||||
arr := make([]model.SysJobLog, 0)
|
||||
for _, row := range rows {
|
||||
sysJobLog := model.SysJobLog{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysJobLog, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysJobLog)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// 分页查询调度任务日志集合
|
||||
func (r *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["jobName"]; ok && v != "" {
|
||||
conditions = append(conditions, "job_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["jobGroup"]; ok && v != "" {
|
||||
conditions = append(conditions, "job_group = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["invokeTarget"]; ok && v != "" {
|
||||
conditions = append(conditions, "invoke_target like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "create_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "create_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysJobLog{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_job_log"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by job_log_id desc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// 查询调度任务日志集合
|
||||
func (r *SysJobLogImpl) SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysJobLog.JobName != "" {
|
||||
conditions = append(conditions, "job_name like concat(?, '%')")
|
||||
params = append(params, sysJobLog.JobName)
|
||||
}
|
||||
if sysJobLog.JobGroup != "" {
|
||||
conditions = append(conditions, "job_group = ?")
|
||||
params = append(params, sysJobLog.JobGroup)
|
||||
}
|
||||
if sysJobLog.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysJobLog.Status)
|
||||
}
|
||||
if sysJobLog.InvokeTarget != "" {
|
||||
conditions = append(conditions, "invoke_target like concat(?, '%')")
|
||||
params = append(params, sysJobLog.InvokeTarget)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysJobLog{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// 通过调度ID查询调度任务日志信息
|
||||
func (r *SysJobLogImpl) SelectJobLogById(jobLogId string) model.SysJobLog {
|
||||
querySql := r.selectSql + " where job_log_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{jobLogId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysJobLog{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysJobLog{}
|
||||
}
|
||||
|
||||
// 新增调度任务日志信息
|
||||
func (r *SysJobLogImpl) InsertJobLog(sysJobLog model.SysJobLog) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
if sysJobLog.JobLogID != "" {
|
||||
params["job_log_id"] = sysJobLog.JobLogID
|
||||
}
|
||||
if sysJobLog.JobName != "" {
|
||||
params["job_name"] = sysJobLog.JobName
|
||||
}
|
||||
if sysJobLog.JobGroup != "" {
|
||||
params["job_group"] = sysJobLog.JobGroup
|
||||
}
|
||||
if sysJobLog.InvokeTarget != "" {
|
||||
params["invoke_target"] = sysJobLog.InvokeTarget
|
||||
}
|
||||
if sysJobLog.TargetParams != "" {
|
||||
params["target_params"] = sysJobLog.TargetParams
|
||||
}
|
||||
if sysJobLog.JobMsg != "" {
|
||||
params["job_msg"] = sysJobLog.JobMsg
|
||||
}
|
||||
if sysJobLog.Status != "" {
|
||||
params["status"] = sysJobLog.Status
|
||||
}
|
||||
if sysJobLog.CostTime > 0 {
|
||||
params["cost_time"] = sysJobLog.CostTime
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_job_log (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// 批量删除调度任务日志信息
|
||||
func (r *SysJobLogImpl) DeleteJobLogByIds(jobLogIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(jobLogIds))
|
||||
sql := "delete from sys_job_log where job_log_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(jobLogIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// 清空调度任务日志
|
||||
func (r *SysJobLogImpl) CleanJobLog() error {
|
||||
sql := "truncate table sys_job_log"
|
||||
_, err := datasource.ExecDB("", sql, []any{})
|
||||
return err
|
||||
}
|
||||
38
src/modules/monitor/service/sys_job.go
Normal file
38
src/modules/monitor/service/sys_job.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// ISysJob 调度任务信息 服务层接口
|
||||
type ISysJob interface {
|
||||
// SelectJobPage 分页查询调度任务集合
|
||||
SelectJobPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectJobList 查询调度任务集合
|
||||
SelectJobList(sysJob model.SysJob) []model.SysJob
|
||||
|
||||
// SelectJobById 通过调度ID查询调度任务信息
|
||||
SelectJobById(jobId string) model.SysJob
|
||||
|
||||
// CheckUniqueJobName 校验调度任务名称和组是否唯一
|
||||
CheckUniqueJobName(jobName, jobGroup, jobId string) bool
|
||||
|
||||
// InsertJob 新增调度任务信息
|
||||
InsertJob(sysJob model.SysJob) string
|
||||
|
||||
// UpdateJob 修改调度任务信息
|
||||
UpdateJob(sysJob model.SysJob) int64
|
||||
|
||||
// DeleteJobByIds 批量删除调度任务信息
|
||||
DeleteJobByIds(jobIds []string) (int64, error)
|
||||
|
||||
// ChangeStatus 任务调度状态修改
|
||||
ChangeStatus(sysJob model.SysJob) bool
|
||||
|
||||
// RunQueueJob 立即运行一次调度任务
|
||||
RunQueueJob(sysJob model.SysJob) bool
|
||||
|
||||
// ResetQueueJob 重置初始调度任务
|
||||
ResetQueueJob()
|
||||
}
|
||||
190
src/modules/monitor/service/sys_job.impl.go
Normal file
190
src/modules/monitor/service/sys_job.impl.go
Normal file
@@ -0,0 +1,190 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/cron"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
"ems.agt/src/modules/monitor/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysJobImpl 结构体
|
||||
var NewSysJobImpl = &SysJobImpl{
|
||||
sysJobRepository: repository.NewSysJobImpl,
|
||||
}
|
||||
|
||||
// SysJobImpl 调度任务 服务层处理
|
||||
type SysJobImpl struct {
|
||||
// 调度任务数据信息
|
||||
sysJobRepository repository.ISysJob
|
||||
}
|
||||
|
||||
// SelectJobPage 分页查询调度任务集合
|
||||
func (r *SysJobImpl) SelectJobPage(query map[string]any) map[string]any {
|
||||
return r.sysJobRepository.SelectJobPage(query)
|
||||
}
|
||||
|
||||
// SelectJobList 查询调度任务集合
|
||||
func (r *SysJobImpl) SelectJobList(sysJob model.SysJob) []model.SysJob {
|
||||
return r.sysJobRepository.SelectJobList(sysJob)
|
||||
}
|
||||
|
||||
// SelectJobById 通过调度ID查询调度任务信息
|
||||
func (r *SysJobImpl) SelectJobById(jobId string) model.SysJob {
|
||||
if jobId == "" {
|
||||
return model.SysJob{}
|
||||
}
|
||||
jobs := r.sysJobRepository.SelectJobByIds([]string{jobId})
|
||||
if len(jobs) > 0 {
|
||||
return jobs[0]
|
||||
}
|
||||
return model.SysJob{}
|
||||
}
|
||||
|
||||
// CheckUniqueJobName 校验调度任务名称和组是否唯一
|
||||
func (r *SysJobImpl) CheckUniqueJobName(jobName, jobGroup, jobId string) bool {
|
||||
uniqueId := r.sysJobRepository.CheckUniqueJob(model.SysJob{
|
||||
JobName: jobName,
|
||||
JobGroup: jobGroup,
|
||||
})
|
||||
if uniqueId == jobId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// InsertJob 新增调度任务信息
|
||||
func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
|
||||
insertId := r.sysJobRepository.InsertJob(sysJob)
|
||||
if insertId == "" && sysJob.Status == common.STATUS_YES {
|
||||
sysJob.JobID = insertId
|
||||
r.insertQueueJob(sysJob, true)
|
||||
}
|
||||
return insertId
|
||||
}
|
||||
|
||||
// UpdateJob 修改调度任务信息
|
||||
func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
|
||||
rows := r.sysJobRepository.UpdateJob(sysJob)
|
||||
if rows > 0 {
|
||||
//状态正常添加队列任务
|
||||
if sysJob.Status == common.STATUS_YES {
|
||||
r.insertQueueJob(sysJob, true)
|
||||
}
|
||||
// 状态禁用删除队列任务
|
||||
if sysJob.Status == common.STATUS_NO {
|
||||
r.deleteQueueJob(sysJob)
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteJobByIds 批量删除调度任务信息
|
||||
func (r *SysJobImpl) DeleteJobByIds(jobIds []string) (int64, error) {
|
||||
// 检查是否存在
|
||||
jobs := r.sysJobRepository.SelectJobByIds(jobIds)
|
||||
if len(jobs) <= 0 {
|
||||
return 0, errors.New("没有权限访问调度任务数据!")
|
||||
}
|
||||
if len(jobs) == len(jobIds) {
|
||||
// 清除任务
|
||||
for _, job := range jobs {
|
||||
r.deleteQueueJob(job)
|
||||
}
|
||||
rows := r.sysJobRepository.DeleteJobByIds(jobIds)
|
||||
return rows, nil
|
||||
}
|
||||
return 0, errors.New("删除调度任务信息失败!")
|
||||
}
|
||||
|
||||
// ChangeStatus 任务调度状态修改
|
||||
func (r *SysJobImpl) ChangeStatus(sysJob model.SysJob) bool {
|
||||
// 更新状态
|
||||
newSysJob := model.SysJob{
|
||||
JobID: sysJob.JobID,
|
||||
Status: sysJob.Status,
|
||||
UpdateBy: sysJob.UpdateBy,
|
||||
}
|
||||
rows := r.sysJobRepository.UpdateJob(newSysJob)
|
||||
if rows > 0 {
|
||||
//状态正常添加队列任务
|
||||
if sysJob.Status == common.STATUS_YES {
|
||||
r.insertQueueJob(sysJob, true)
|
||||
}
|
||||
// 状态禁用删除队列任务
|
||||
if sysJob.Status == common.STATUS_NO {
|
||||
r.deleteQueueJob(sysJob)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ResetQueueJob 重置初始调度任务
|
||||
func (r *SysJobImpl) ResetQueueJob() {
|
||||
// 获取注册的队列名称
|
||||
queueNames := cron.QueueNames()
|
||||
if len(queueNames) == 0 {
|
||||
return
|
||||
}
|
||||
// 查询系统中定义状态为正常启用的任务
|
||||
sysJobs := r.sysJobRepository.SelectJobList(model.SysJob{
|
||||
Status: common.STATUS_YES,
|
||||
})
|
||||
for _, sysJob := range sysJobs {
|
||||
for _, name := range queueNames {
|
||||
if name == sysJob.InvokeTarget {
|
||||
r.insertQueueJob(sysJob, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RunQueueJob 立即运行一次调度任务
|
||||
func (r *SysJobImpl) RunQueueJob(sysJob model.SysJob) bool {
|
||||
return r.insertQueueJob(sysJob, false)
|
||||
}
|
||||
|
||||
// insertQueueJob 添加调度任务
|
||||
func (r *SysJobImpl) insertQueueJob(sysJob model.SysJob, repeat bool) bool {
|
||||
// 获取队列 Processor
|
||||
queue := cron.GetQueue(sysJob.InvokeTarget)
|
||||
if queue.Name != sysJob.InvokeTarget {
|
||||
return false
|
||||
}
|
||||
|
||||
// 给执行任务数据参数
|
||||
options := cron.JobData{
|
||||
Repeat: repeat,
|
||||
SysJob: sysJob,
|
||||
}
|
||||
|
||||
// 不是重复任务的情况,立即执行一次
|
||||
if !repeat {
|
||||
// 执行单次任务
|
||||
status := queue.RunJob(options, cron.JobOptions{
|
||||
JobId: sysJob.JobID,
|
||||
})
|
||||
// 执行中或等待中的都返回正常
|
||||
return status == cron.Active || status == cron.Waiting
|
||||
}
|
||||
|
||||
// 执行重复任务
|
||||
queue.RunJob(options, cron.JobOptions{
|
||||
JobId: sysJob.JobID,
|
||||
Cron: sysJob.CronExpression,
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// deleteQueueJob 删除调度任务
|
||||
func (r *SysJobImpl) deleteQueueJob(sysJob model.SysJob) bool {
|
||||
// 获取队列 Processor
|
||||
queue := cron.GetQueue(sysJob.InvokeTarget)
|
||||
if queue.Name != sysJob.InvokeTarget {
|
||||
return false
|
||||
}
|
||||
return queue.RemoveJob(sysJob.JobID)
|
||||
}
|
||||
23
src/modules/monitor/service/sys_job_log.go
Normal file
23
src/modules/monitor/service/sys_job_log.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// ISysJobLog 调度任务日志 服务层接口
|
||||
type ISysJobLog interface {
|
||||
// SelectJobLogPage 分页查询调度任务日志集合
|
||||
SelectJobLogPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectJobLogList 查询调度任务日志集合
|
||||
SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog
|
||||
|
||||
// SelectJobLogById 通过调度ID查询调度任务日志信息
|
||||
SelectJobLogById(jobLogId string) model.SysJobLog
|
||||
|
||||
// DeleteJobLogByIds 批量删除调度任务日志信息
|
||||
DeleteJobLogByIds(jobLogIds []string) int64
|
||||
|
||||
// CleanJobLog 清空调度任务日志
|
||||
CleanJobLog() error
|
||||
}
|
||||
42
src/modules/monitor/service/sys_job_log.impl.go
Normal file
42
src/modules/monitor/service/sys_job_log.impl.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
"ems.agt/src/modules/monitor/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysJobLogImpl 结构体
|
||||
var NewSysJobLogImpl = &SysJobLogImpl{
|
||||
sysJobLogRepository: repository.NewSysJobLogImpl,
|
||||
}
|
||||
|
||||
// SysJobLogImpl 调度任务日志 服务层处理
|
||||
type SysJobLogImpl struct {
|
||||
// 调度任务日志数据信息
|
||||
sysJobLogRepository repository.ISysJobLog
|
||||
}
|
||||
|
||||
// SelectJobLogPage 分页查询调度任务日志集合
|
||||
func (s *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any {
|
||||
return s.sysJobLogRepository.SelectJobLogPage(query)
|
||||
}
|
||||
|
||||
// SelectJobLogList 查询调度任务日志集合
|
||||
func (s *SysJobLogImpl) SelectJobLogList(sysJobLog model.SysJobLog) []model.SysJobLog {
|
||||
return s.sysJobLogRepository.SelectJobLogList(sysJobLog)
|
||||
}
|
||||
|
||||
// SelectJobLogById 通过调度ID查询调度任务日志信息
|
||||
func (s *SysJobLogImpl) SelectJobLogById(jobLogId string) model.SysJobLog {
|
||||
return s.sysJobLogRepository.SelectJobLogById(jobLogId)
|
||||
}
|
||||
|
||||
// DeleteJobLogByIds 批量删除调度任务日志信息
|
||||
func (s *SysJobLogImpl) DeleteJobLogByIds(jobLogIds []string) int64 {
|
||||
return s.sysJobLogRepository.DeleteJobLogByIds(jobLogIds)
|
||||
}
|
||||
|
||||
// CleanJobLog 清空调度任务日志
|
||||
func (s *SysJobLogImpl) CleanJobLog() error {
|
||||
return s.sysJobLogRepository.CleanJobLog()
|
||||
}
|
||||
12
src/modules/monitor/service/sys_user_online.go
Normal file
12
src/modules/monitor/service/sys_user_online.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/vo"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// ISysUserOnline 在线用户 服务层接口
|
||||
type ISysUserOnline interface {
|
||||
// LoginUserToUserOnline 设置在线用户信息
|
||||
LoginUserToUserOnline(loginUser vo.LoginUser) model.SysUserOnline
|
||||
}
|
||||
33
src/modules/monitor/service/sys_user_online.impl.go
Normal file
33
src/modules/monitor/service/sys_user_online.impl.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/vo"
|
||||
"ems.agt/src/modules/monitor/model"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysUserOnlineImpl 结构体
|
||||
var NewSysUserOnlineImpl = &SysUserOnlineImpl{}
|
||||
|
||||
// SysUserOnlineImpl 在线用户 服务层处理
|
||||
type SysUserOnlineImpl struct{}
|
||||
|
||||
// LoginUserToUserOnline 设置在线用户信息
|
||||
func (r *SysUserOnlineImpl) LoginUserToUserOnline(loginUser vo.LoginUser) model.SysUserOnline {
|
||||
if loginUser.UserID == "" {
|
||||
return model.SysUserOnline{}
|
||||
}
|
||||
|
||||
sysUserOnline := model.SysUserOnline{
|
||||
TokenID: loginUser.UUID,
|
||||
UserName: loginUser.User.UserName,
|
||||
IPAddr: loginUser.IPAddr,
|
||||
LoginLocation: loginUser.LoginLocation,
|
||||
Browser: loginUser.Browser,
|
||||
OS: loginUser.OS,
|
||||
LoginTime: loginUser.LoginTime,
|
||||
}
|
||||
if loginUser.User.DeptID != "" {
|
||||
sysUserOnline.DeptName = loginUser.User.Dept.DeptName
|
||||
}
|
||||
return sysUserOnline
|
||||
}
|
||||
25
src/modules/monitor/service/system_info.go
Normal file
25
src/modules/monitor/service/system_info.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package service
|
||||
|
||||
// ISystemInfo 服务器系统相关信息 服务层接口
|
||||
type ISystemInfo interface {
|
||||
// ProjectInfo 程序项目信息
|
||||
ProjectInfo() map[string]any
|
||||
|
||||
// SystemInfo 系统信息
|
||||
SystemInfo() map[string]any
|
||||
|
||||
// TimeInfo 系统时间信息
|
||||
TimeInfo() map[string]string
|
||||
|
||||
// MemoryInfo 内存信息
|
||||
MemoryInfo() map[string]any
|
||||
|
||||
// CPUInfo CPU信息
|
||||
CPUInfo() map[string]any
|
||||
|
||||
// NetworkInfo 网络信息
|
||||
NetworkInfo() map[string]string
|
||||
|
||||
// DiskInfo 磁盘信息
|
||||
DiskInfo() []map[string]string
|
||||
}
|
||||
236
src/modules/monitor/service/system_info.impl.go
Normal file
236
src/modules/monitor/service/system_info.impl.go
Normal file
@@ -0,0 +1,236 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/host"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
"github.com/shirou/gopsutil/v3/net"
|
||||
)
|
||||
|
||||
// 实例化服务层 SystemInfoImpl 结构体
|
||||
var NewSystemInfoImpl = &SystemInfoImpl{}
|
||||
|
||||
// SystemInfoImpl 服务器系统相关信息 服务层处理
|
||||
type SystemInfoImpl struct{}
|
||||
|
||||
// ProjectInfo 程序项目信息
|
||||
func (s *SystemInfoImpl) ProjectInfo() map[string]any {
|
||||
// 获取工作目录
|
||||
appDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
appDir = ""
|
||||
}
|
||||
// 项目依赖
|
||||
dependencies := s.dependencies()
|
||||
return map[string]any{
|
||||
"appDir": appDir,
|
||||
"env": config.Env(),
|
||||
"name": config.Get("framework.name"),
|
||||
"version": config.Get("framework.version"),
|
||||
"dependencies": dependencies,
|
||||
}
|
||||
}
|
||||
|
||||
// dependencies 读取mod内项目包依赖
|
||||
func (s *SystemInfoImpl) dependencies() map[string]string {
|
||||
var pkgs = make(map[string]string)
|
||||
|
||||
// 打开 go.mod 文件
|
||||
file, err := os.Open("go.mod")
|
||||
if err != nil {
|
||||
return pkgs
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 使用 bufio.Scanner 逐行读取文件内容
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
// 行不为空,不以module\require开头,不带有 // indirect 注释,则解析包名和版本
|
||||
prefixLine := strings.HasPrefix(line, "module") || strings.HasPrefix(line, "require") || strings.HasPrefix(line, "go ")
|
||||
suffixLine := strings.HasSuffix(line, ")") || strings.HasSuffix(line, "// indirect")
|
||||
if line == "" || prefixLine || suffixLine {
|
||||
continue
|
||||
}
|
||||
|
||||
modInfo := strings.Split(line, " ")
|
||||
if len(modInfo) >= 2 {
|
||||
moduleName := strings.TrimSpace(modInfo[0])
|
||||
version := strings.TrimSpace(modInfo[1])
|
||||
pkgs[moduleName] = version
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
pkgs["scanner-err"] = err.Error()
|
||||
}
|
||||
return pkgs
|
||||
}
|
||||
|
||||
// SystemInfo 系统信息
|
||||
func (s *SystemInfoImpl) SystemInfo() map[string]any {
|
||||
info, err := host.Info()
|
||||
if err != nil {
|
||||
info.Platform = err.Error()
|
||||
}
|
||||
// 用户目录
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
homeDir = ""
|
||||
}
|
||||
cmd, err := os.Executable()
|
||||
if err != nil {
|
||||
cmd = ""
|
||||
}
|
||||
return map[string]any{
|
||||
"platform": info.Platform,
|
||||
"go": runtime.Version(),
|
||||
"processId": os.Getpid(),
|
||||
"arch": info.KernelArch,
|
||||
"uname": runtime.GOARCH,
|
||||
"release": info.OS,
|
||||
"hostname": info.Hostname,
|
||||
"homeDir": homeDir,
|
||||
"cmd": cmd,
|
||||
"execCommand": strings.Join(os.Args, " "),
|
||||
}
|
||||
}
|
||||
|
||||
// TimeInfo 系统时间信息
|
||||
func (s *SystemInfoImpl) TimeInfo() map[string]string {
|
||||
// 获取当前时间
|
||||
current := time.Now().Format("2006-01-02 15:04:05")
|
||||
// 获取程序运行时间
|
||||
uptime := time.Since(config.RunTime()).String()
|
||||
// 获取时区
|
||||
timezone := time.Now().Format("-0700 MST")
|
||||
// 获取时区名称
|
||||
timezoneName := time.Now().Format("MST")
|
||||
|
||||
return map[string]string{
|
||||
"current": current,
|
||||
"uptime": uptime,
|
||||
"timezone": timezone,
|
||||
"timezoneName": timezoneName,
|
||||
}
|
||||
}
|
||||
|
||||
// MemoryInfo 内存信息
|
||||
func (s *SystemInfoImpl) MemoryInfo() map[string]any {
|
||||
memInfo, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
memInfo.UsedPercent = 0
|
||||
memInfo.Available = 0
|
||||
memInfo.Total = 0
|
||||
}
|
||||
|
||||
var memStats runtime.MemStats
|
||||
runtime.ReadMemStats(&memStats)
|
||||
|
||||
return map[string]any{
|
||||
"usage": fmt.Sprintf("%.2f", memInfo.UsedPercent), // 内存利用率
|
||||
"freemem": parse.Bit(float64(memInfo.Available)), // 可用内存大小(GB)
|
||||
"totalmem": parse.Bit(float64(memInfo.Total)), // 总内存大小(GB)
|
||||
"rss": parse.Bit(float64(memStats.Sys)), // 常驻内存大小(RSS)
|
||||
"heapTotal": parse.Bit(float64(memStats.HeapSys)), // 堆总大小
|
||||
"heapUsed": parse.Bit(float64(memStats.HeapAlloc)), // 堆已使用大小
|
||||
"external": parse.Bit(float64(memStats.Sys - memStats.HeapSys)), // 外部内存大小(非堆)
|
||||
}
|
||||
}
|
||||
|
||||
// CPUInfo CPU信息
|
||||
func (s *SystemInfoImpl) CPUInfo() map[string]any {
|
||||
var core int32 = 0
|
||||
var speed string = "未知"
|
||||
var model string = "未知"
|
||||
cpuInfo, err := cpu.Info()
|
||||
if err == nil {
|
||||
core = cpuInfo[0].Cores
|
||||
speed = fmt.Sprintf("%.0fMHz", cpuInfo[0].Mhz)
|
||||
model = strings.TrimSpace(cpuInfo[0].ModelName)
|
||||
}
|
||||
|
||||
useds := []string{}
|
||||
cpuPercent, err := cpu.Percent(0, true)
|
||||
if err == nil {
|
||||
for _, v := range cpuPercent {
|
||||
useds = append(useds, fmt.Sprintf("%.2f", v))
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"model": model,
|
||||
"speed": speed,
|
||||
"core": core,
|
||||
"coreUsed": useds,
|
||||
}
|
||||
}
|
||||
|
||||
// NetworkInfo 网络信息
|
||||
func (s *SystemInfoImpl) NetworkInfo() map[string]string {
|
||||
ipAddrs := make(map[string]string)
|
||||
interfaces, err := net.Interfaces()
|
||||
if err == nil {
|
||||
for _, iface := range interfaces {
|
||||
name := iface.Name
|
||||
if name[len(name)-1] == '0' {
|
||||
name = name[0 : len(name)-1]
|
||||
name = strings.Trim(name, "")
|
||||
}
|
||||
// ignore localhost
|
||||
if name == "lo" {
|
||||
continue
|
||||
}
|
||||
var addrs []string
|
||||
for _, v := range iface.Addrs {
|
||||
prefix := strings.Split(v.Addr, "/")[0]
|
||||
if strings.Contains(prefix, "::") {
|
||||
addrs = append(addrs, fmt.Sprintf("IPv6 %s", prefix))
|
||||
}
|
||||
if strings.Contains(prefix, ".") {
|
||||
addrs = append(addrs, fmt.Sprintf("IPv4 %s", prefix))
|
||||
}
|
||||
}
|
||||
ipAddrs[name] = strings.Join(addrs, " / ")
|
||||
}
|
||||
}
|
||||
return ipAddrs
|
||||
}
|
||||
|
||||
// DiskInfo 磁盘信息
|
||||
func (s *SystemInfoImpl) DiskInfo() []map[string]string {
|
||||
disks := make([]map[string]string, 0)
|
||||
|
||||
partitions, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
return disks
|
||||
}
|
||||
|
||||
for _, partition := range partitions {
|
||||
usage, err := disk.Usage(partition.Mountpoint)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
disks = append(disks, map[string]string{
|
||||
"size": parse.Bit(float64(usage.Total)),
|
||||
"used": parse.Bit(float64(usage.Used)),
|
||||
"avail": parse.Bit(float64(usage.Free)),
|
||||
"pcent": fmt.Sprintf("%.1f%%", usage.UsedPercent),
|
||||
"target": partition.Device,
|
||||
})
|
||||
}
|
||||
return disks
|
||||
}
|
||||
220
src/modules/system/controller/sys_config.go
Normal file
220
src/modules/system/controller/sys_config.go
Normal file
@@ -0,0 +1,220 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysConfigController 结构体
|
||||
var NewSysConfig = &SysConfigController{
|
||||
sysConfigService: service.NewSysConfigImpl,
|
||||
}
|
||||
|
||||
// 参数配置信息
|
||||
//
|
||||
// PATH /system/config
|
||||
type SysConfigController struct {
|
||||
// 参数配置服务
|
||||
sysConfigService service.ISysConfig
|
||||
}
|
||||
|
||||
// 参数配置列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysConfigController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysConfigService.SelectConfigPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 参数配置信息
|
||||
//
|
||||
// GET /:configId
|
||||
func (s *SysConfigController) Info(c *gin.Context) {
|
||||
configId := c.Param("configId")
|
||||
if configId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysConfigService.SelectConfigById(configId)
|
||||
if data.ConfigID == configId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 参数配置新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysConfigController) Add(c *gin.Context) {
|
||||
var body model.SysConfig
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ConfigID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueConfigKey := s.sysConfigService.CheckUniqueConfigKey(body.ConfigKey, "")
|
||||
if !uniqueConfigKey {
|
||||
msg := fmt.Sprintf("参数配置新增【%s】失败,参数键名已存在", body.ConfigKey)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysConfigService.InsertConfig(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 参数配置修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysConfigController) Edit(c *gin.Context) {
|
||||
var body model.SysConfig
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ConfigID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueConfigKey := s.sysConfigService.CheckUniqueConfigKey(body.ConfigKey, body.ConfigID)
|
||||
if !uniqueConfigKey {
|
||||
msg := fmt.Sprintf("参数配置修改【%s】失败,参数键名已存在", body.ConfigKey)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
config := s.sysConfigService.SelectConfigById(body.ConfigID)
|
||||
if config.ConfigID != body.ConfigID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问参数配置数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysConfigService.UpdateConfig(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 参数配置删除
|
||||
//
|
||||
// DELETE /:configIds
|
||||
func (s *SysConfigController) Remove(c *gin.Context) {
|
||||
configIds := c.Param("configIds")
|
||||
if configIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(configIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysConfigService.DeleteConfigByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 参数配置刷新缓存
|
||||
//
|
||||
// PUT /refreshCache
|
||||
func (s *SysConfigController) RefreshCache(c *gin.Context) {
|
||||
s.sysConfigService.ResetConfigCache()
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 参数配置根据参数键名
|
||||
//
|
||||
// GET /configKey/:configKey
|
||||
func (s *SysConfigController) ConfigKey(c *gin.Context) {
|
||||
configKey := c.Param("configKey")
|
||||
if configKey == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
key := s.sysConfigService.SelectConfigValueByKey(configKey)
|
||||
if key != "" {
|
||||
c.JSON(200, result.OkData(key))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 导出参数配置信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysConfigController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysConfigService.SelectConfigPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysConfig)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("config_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "参数编号",
|
||||
"B1": "参数名称",
|
||||
"C1": "参数键名",
|
||||
"D1": "参数键值",
|
||||
"E1": "系统内置",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
typeValue := "否"
|
||||
if row.ConfigType == "Y" {
|
||||
typeValue = "是"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ConfigID,
|
||||
"B" + idx: row.ConfigName,
|
||||
"C" + idx: row.ConfigKey,
|
||||
"D" + idx: row.ConfigValue,
|
||||
"E" + idx: typeValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
309
src/modules/system/controller/sys_dept.go
Normal file
309
src/modules/system/controller/sys_dept.go
Normal file
@@ -0,0 +1,309 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysDeptController 结构体
|
||||
var NewSysDept = &SysDeptController{
|
||||
sysDeptService: service.NewSysDeptImpl,
|
||||
}
|
||||
|
||||
// 部门信息
|
||||
//
|
||||
// PATH /system/dept
|
||||
type SysDeptController struct {
|
||||
// 部门服务
|
||||
sysDeptService service.ISysDept
|
||||
}
|
||||
|
||||
// 部门列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysDeptController) List(c *gin.Context) {
|
||||
var querys struct {
|
||||
// 部门ID
|
||||
DeptID string `json:"deptId"`
|
||||
// 父部门ID
|
||||
ParentID string `json:"parentId" `
|
||||
// 部门名称
|
||||
DeptName string `json:"deptName" `
|
||||
// 部门状态(0正常 1停用)
|
||||
Status string `json:"status"`
|
||||
}
|
||||
err := c.ShouldBindQuery(&querys)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
SysDeptController := model.SysDept{
|
||||
DeptID: querys.DeptID,
|
||||
ParentID: querys.ParentID,
|
||||
DeptName: querys.DeptName,
|
||||
Status: querys.Status,
|
||||
}
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysDeptService.SelectDeptList(SysDeptController, dataScopeSQL)
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 部门信息
|
||||
//
|
||||
// GET /:deptId
|
||||
func (s *SysDeptController) Info(c *gin.Context) {
|
||||
deptId := c.Param("deptId")
|
||||
if deptId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysDeptService.SelectDeptById(deptId)
|
||||
if data.DeptID == deptId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 部门新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysDeptController) Add(c *gin.Context) {
|
||||
var body model.SysDept
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DeptID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
deptParent := s.sysDeptService.SelectDeptById(body.ParentID)
|
||||
if deptParent.DeptID != body.ParentID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问部门数据!"))
|
||||
return
|
||||
}
|
||||
if deptParent.Status == common.STATUS_NO {
|
||||
msg := fmt.Sprintf("上级部门【%s】停用,不允许新增", deptParent.DeptName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
if deptParent.DelFlag == common.STATUS_YES {
|
||||
msg := fmt.Sprintf("上级部门【%s】已删除,不允许新增", deptParent.DeptName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
body.Ancestors = deptParent.Ancestors + "," + body.ParentID
|
||||
} else {
|
||||
body.Ancestors = "0"
|
||||
}
|
||||
|
||||
// 检查同级下名称唯一
|
||||
uniqueDeptName := s.sysDeptService.CheckUniqueDeptName(body.DeptName, body.ParentID, "")
|
||||
if !uniqueDeptName {
|
||||
msg := fmt.Sprintf("部门新增【%s】失败,部门名称已存在", body.DeptName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysDeptService.InsertDept(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 部门修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysDeptController) Edit(c *gin.Context) {
|
||||
var body model.SysDept
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DeptID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级部门不能选自己
|
||||
if body.DeptID == body.ParentID {
|
||||
msg := fmt.Sprintf("部门修改【%s】失败,上级部门不能是自己", body.DeptName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
deptInfo := s.sysDeptService.SelectDeptById(body.DeptID)
|
||||
if deptInfo.DeptID != body.DeptID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问部门数据!"))
|
||||
return
|
||||
}
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
deptParent := s.sysDeptService.SelectDeptById(body.ParentID)
|
||||
if deptParent.DeptID != body.ParentID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问部门数据!"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查同级下名称唯一
|
||||
uniqueDeptName := s.sysDeptService.CheckUniqueDeptName(body.DeptName, body.ParentID, body.DeptID)
|
||||
if !uniqueDeptName {
|
||||
msg := fmt.Sprintf("部门修改【%s】失败,部门名称已存在", body.DeptName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级停用需要检查下级是否有在使用
|
||||
if body.Status == common.STATUS_NO {
|
||||
hasChild := s.sysDeptService.HasChildByDeptId(body.DeptID)
|
||||
if hasChild > 0 {
|
||||
msg := fmt.Sprintf("该部门包含未停用的子部门数量:%d", hasChild)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysDeptService.UpdateDept(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 部门删除
|
||||
//
|
||||
// DELETE /:deptId
|
||||
func (s *SysDeptController) Remove(c *gin.Context) {
|
||||
deptId := c.Param("deptId")
|
||||
if deptId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
dept := s.sysDeptService.SelectDeptById(deptId)
|
||||
if dept.DeptID != deptId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问部门数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在子部门
|
||||
hasChild := s.sysDeptService.HasChildByDeptId(deptId)
|
||||
if hasChild > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,存在子部门数:%d", hasChild)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否分配给用户
|
||||
existUser := s.sysDeptService.CheckDeptExistUser(deptId)
|
||||
if existUser > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,部门已分配给用户数:%d", existUser)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
rows := s.sysDeptService.DeleteDeptById(deptId)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 部门列表(排除节点)
|
||||
//
|
||||
// GET /list/exclude/:deptId
|
||||
func (s *SysDeptController) ExcludeChild(c *gin.Context) {
|
||||
deptId := c.Param("deptId")
|
||||
if deptId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysDeptService.SelectDeptList(model.SysDept{}, dataScopeSQL)
|
||||
|
||||
// 过滤排除节点
|
||||
filtered := make([]model.SysDept, 0)
|
||||
for _, dept := range data {
|
||||
hasAncestor := false
|
||||
ancestorList := strings.Split(dept.Ancestors, ",")
|
||||
for _, ancestor := range ancestorList {
|
||||
if ancestor == deptId {
|
||||
hasAncestor = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !(dept.DeptID == deptId || hasAncestor) {
|
||||
filtered = append(filtered, dept)
|
||||
}
|
||||
}
|
||||
c.JSON(200, result.OkData(filtered))
|
||||
}
|
||||
|
||||
// 部门树结构列表
|
||||
//
|
||||
// GET /treeSelect
|
||||
func (s *SysDeptController) TreeSelect(c *gin.Context) {
|
||||
var querys struct {
|
||||
// 部门ID
|
||||
DeptID string `json:"deptId"`
|
||||
// 父部门ID
|
||||
ParentID string `json:"parentId" `
|
||||
// 部门名称
|
||||
DeptName string `json:"deptName" `
|
||||
// 部门状态(0正常 1停用)
|
||||
Status string `json:"status"`
|
||||
}
|
||||
err := c.ShouldBindQuery(&querys)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
SysDeptController := model.SysDept{
|
||||
DeptID: querys.DeptID,
|
||||
ParentID: querys.ParentID,
|
||||
DeptName: querys.DeptName,
|
||||
Status: querys.Status,
|
||||
}
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysDeptService.SelectDeptTreeSelect(SysDeptController, dataScopeSQL)
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 部门树结构列表(指定角色)
|
||||
//
|
||||
// GET /roleDeptTreeSelect/:roleId
|
||||
func (s *SysDeptController) RoleDeptTreeSelect(c *gin.Context) {
|
||||
roleId := c.Param("roleId")
|
||||
if roleId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
deptTreeSelect := s.sysDeptService.SelectDeptTreeSelect(model.SysDept{}, dataScopeSQL)
|
||||
checkedKeys := s.sysDeptService.SelectDeptListByRoleId(roleId)
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"depts": deptTreeSelect,
|
||||
"checkedKeys": checkedKeys,
|
||||
}))
|
||||
}
|
||||
244
src/modules/system/controller/sys_dict_data.go
Normal file
244
src/modules/system/controller/sys_dict_data.go
Normal file
@@ -0,0 +1,244 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysDictDataController 结构体
|
||||
var NewSysDictData = &SysDictDataController{
|
||||
sysDictDataService: service.NewSysDictDataImpl,
|
||||
sysDictTypeService: service.NewSysDictTypeImpl,
|
||||
}
|
||||
|
||||
// 字典类型对应的字典数据信息
|
||||
//
|
||||
// PATH /system/dict/data
|
||||
type SysDictDataController struct {
|
||||
// 字典数据服务
|
||||
sysDictDataService service.ISysDictData
|
||||
// 字典类型服务
|
||||
sysDictTypeService service.ISysDictType
|
||||
}
|
||||
|
||||
// 字典数据列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysDictDataController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysDictDataService.SelectDictDataPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 字典数据详情
|
||||
//
|
||||
// GET /:dictCode
|
||||
func (s *SysDictDataController) Info(c *gin.Context) {
|
||||
dictCode := c.Param("dictCode")
|
||||
if dictCode == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysDictDataService.SelectDictDataByCode(dictCode)
|
||||
if data.DictCode == dictCode {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典数据新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysDictDataController) Add(c *gin.Context) {
|
||||
var body model.SysDictData
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DictCode != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典类型是否存在
|
||||
sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType)
|
||||
if sysDictType.DictType != body.DictType {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问字典类型数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典标签唯一
|
||||
uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, "")
|
||||
if !uniqueDictLabel {
|
||||
msg := fmt.Sprintf("数据新增【%s】失败,该字典类型下标签名已存在", body.DictLabel)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典键值唯一
|
||||
uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, "")
|
||||
if !uniqueDictValue {
|
||||
msg := fmt.Sprintf("数据新增【%s】失败,该字典类型下标签值已存在", body.DictValue)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysDictDataService.InsertDictData(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典类型修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysDictDataController) Edit(c *gin.Context) {
|
||||
var body model.SysDictData
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DictCode == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典类型是否存在
|
||||
sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType)
|
||||
if sysDictType.DictType != body.DictType {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问字典类型数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典编码是否存在
|
||||
SysDictDataController := s.sysDictDataService.SelectDictDataByCode(body.DictCode)
|
||||
if SysDictDataController.DictCode != body.DictCode {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问字典编码数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典标签唯一
|
||||
uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, body.DictCode)
|
||||
if !uniqueDictLabel {
|
||||
msg := fmt.Sprintf("数据修改【%s】失败,该字典类型下标签名已存在", body.DictLabel)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典键值唯一
|
||||
uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, body.DictCode)
|
||||
if !uniqueDictValue {
|
||||
msg := fmt.Sprintf("数据修改【%s】失败,该字典类型下标签值已存在", body.DictValue)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysDictDataService.UpdateDictData(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典数据删除
|
||||
//
|
||||
// DELETE /:dictCodes
|
||||
func (s *SysDictDataController) Remove(c *gin.Context) {
|
||||
dictCodes := c.Param("dictCodes")
|
||||
if dictCodes == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(dictCodes, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysDictDataService.DeleteDictDataByCodes(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 字典数据列表(指定字典类型)
|
||||
//
|
||||
// GET /type/:dictType
|
||||
func (s *SysDictDataController) DictType(c *gin.Context) {
|
||||
dictType := c.Param("dictType")
|
||||
if dictType == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.sysDictDataService.SelectDictDataByType(dictType)
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 字典数据列表导出
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysDictDataController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysDictDataService.SelectDictDataPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysDictData)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("dict_data_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "字典编码",
|
||||
"B1": "字典排序",
|
||||
"C1": "字典标签",
|
||||
"D1": "字典键值",
|
||||
"E1": "字典类型",
|
||||
"F1": "状态",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
statusValue := "停用"
|
||||
if row.Status == "1" {
|
||||
statusValue = "正常"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.DictCode,
|
||||
"B" + idx: row.DictSort,
|
||||
"C" + idx: row.DictLabel,
|
||||
"D" + idx: row.DictValue,
|
||||
"E" + idx: row.DictType,
|
||||
"F" + idx: statusValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
242
src/modules/system/controller/sys_dict_type.go
Normal file
242
src/modules/system/controller/sys_dict_type.go
Normal file
@@ -0,0 +1,242 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysDictTypeController 结构体
|
||||
var NewSysDictType = &SysDictTypeController{
|
||||
sysDictTypeService: service.NewSysDictTypeImpl,
|
||||
}
|
||||
|
||||
// 字典类型信息
|
||||
//
|
||||
// PATH /system/dict/type
|
||||
type SysDictTypeController struct {
|
||||
// 字典类型服务
|
||||
sysDictTypeService service.ISysDictType
|
||||
}
|
||||
|
||||
// 字典类型列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysDictTypeController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysDictTypeService.SelectDictTypePage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 字典类型信息
|
||||
//
|
||||
// GET /:dictId
|
||||
func (s *SysDictTypeController) Info(c *gin.Context) {
|
||||
dictId := c.Param("dictId")
|
||||
if dictId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysDictTypeService.SelectDictTypeByID(dictId)
|
||||
if data.DictID == dictId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典类型新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysDictTypeController) Add(c *gin.Context) {
|
||||
var body model.SysDictType
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DictID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典名称唯一
|
||||
uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, "")
|
||||
if !uniqueDictName {
|
||||
msg := fmt.Sprintf("字典新增【%s】失败,字典名称已存在", body.DictName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典类型唯一
|
||||
uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, "")
|
||||
if !uniqueDictType {
|
||||
msg := fmt.Sprintf("字典新增【%s】失败,字典类型已存在", body.DictType)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysDictTypeService.InsertDictType(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典类型修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysDictTypeController) Edit(c *gin.Context) {
|
||||
var body model.SysDictType
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.DictID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
dictInfo := s.sysDictTypeService.SelectDictTypeByID(body.DictID)
|
||||
if dictInfo.DictID != body.DictID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问字典类型数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典名称唯一
|
||||
uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, body.DictID)
|
||||
if !uniqueDictName {
|
||||
msg := fmt.Sprintf("字典修改【%s】失败,字典名称已存在", body.DictName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查字典类型唯一
|
||||
uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, body.DictID)
|
||||
if !uniqueDictType {
|
||||
msg := fmt.Sprintf("字典修改【%s】失败,字典类型已存在", body.DictType)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysDictTypeService.UpdateDictType(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 字典类型删除
|
||||
//
|
||||
// DELETE /:dictIds
|
||||
func (s *SysDictTypeController) Remove(c *gin.Context) {
|
||||
dictIds := c.Param("dictIds")
|
||||
if dictIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(dictIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysDictTypeService.DeleteDictTypeByIDs(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 字典类型刷新缓存
|
||||
//
|
||||
// PUT /refreshCache
|
||||
func (s *SysDictTypeController) RefreshCache(c *gin.Context) {
|
||||
s.sysDictTypeService.ResetDictCache()
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 字典类型选择框列表
|
||||
//
|
||||
// GET /getDictOptionselect
|
||||
func (s *SysDictTypeController) DictOptionselect(c *gin.Context) {
|
||||
data := s.sysDictTypeService.SelectDictTypeList(model.SysDictType{
|
||||
Status: common.STATUS_YES,
|
||||
})
|
||||
|
||||
type labelValue struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// 数据组
|
||||
arr := []labelValue{}
|
||||
for _, v := range data {
|
||||
arr = append(arr, labelValue{
|
||||
Label: v.DictName,
|
||||
Value: v.DictType,
|
||||
})
|
||||
}
|
||||
c.JSON(200, result.OkData(arr))
|
||||
}
|
||||
|
||||
// 字典类型列表导出
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysDictTypeController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysDictTypeService.SelectDictTypePage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysDictType)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("dict_type_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "字典主键",
|
||||
"B1": "字典名称",
|
||||
"C1": "字典类型",
|
||||
"D1": "状态",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
statusValue := "停用"
|
||||
if row.Status == "1" {
|
||||
statusValue = "正常"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.DictID,
|
||||
"B" + idx: row.DictName,
|
||||
"C" + idx: row.DictType,
|
||||
"D" + idx: statusValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
158
src/modules/system/controller/sys_log_login.go
Normal file
158
src/modules/system/controller/sys_log_login.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
commonService "ems.agt/src/modules/common/service"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysLogLoginController 结构体
|
||||
var NewSysLogLogin = &SysLogLoginController{
|
||||
sysLogLoginService: service.NewSysLogLoginImpl,
|
||||
accountService: commonService.NewAccountImpl,
|
||||
}
|
||||
|
||||
// 系统登录日志信息
|
||||
//
|
||||
// PATH /system/log/login
|
||||
type SysLogLoginController struct {
|
||||
// 系统登录日志服务
|
||||
sysLogLoginService service.ISysLogLogin
|
||||
// 账号身份操作服务
|
||||
accountService commonService.IAccount
|
||||
}
|
||||
|
||||
// 系统登录日志列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysLogLoginController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysLogLoginService.SelectSysLogLoginPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 系统登录日志删除
|
||||
//
|
||||
// DELETE /:infoIds
|
||||
func (s *SysLogLoginController) Remove(c *gin.Context) {
|
||||
infoIds := c.Param("infoIds")
|
||||
if infoIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(infoIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows := s.sysLogLoginService.DeleteSysLogLoginByIds(uniqueIDs)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 系统登录日志清空
|
||||
//
|
||||
// DELETE /clean
|
||||
func (s *SysLogLoginController) Clean(c *gin.Context) {
|
||||
err := s.sysLogLoginService.CleanSysLogLogin()
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 系统登录日志账户解锁
|
||||
//
|
||||
// PUT /unlock/:userName
|
||||
func (s *SysLogLoginController) Unlock(c *gin.Context) {
|
||||
userName := c.Param("userName")
|
||||
if userName == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
ok := s.accountService.ClearLoginRecordCache(userName)
|
||||
if ok {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 导出系统登录日志信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysLogLoginController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysLogLoginService.SelectSysLogLoginPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysLogLogin)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("sys_log_login_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "序号",
|
||||
"B1": "用户账号",
|
||||
"C1": "登录状态",
|
||||
"D1": "登录地址",
|
||||
"E1": "登录地点",
|
||||
"F1": "浏览器",
|
||||
"G1": "操作系统",
|
||||
"H1": "提示消息",
|
||||
"I1": "访问时间",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 状态
|
||||
statusValue := "失败"
|
||||
if row.Status == "1" {
|
||||
statusValue = "成功"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.LoginID,
|
||||
"B" + idx: row.UserName,
|
||||
"C" + idx: statusValue,
|
||||
"D" + idx: row.IPAddr,
|
||||
"E" + idx: row.LoginLocation,
|
||||
"F" + idx: row.Browser,
|
||||
"G" + idx: row.OS,
|
||||
"H" + idx: row.Msg,
|
||||
"I" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DD_HH_MM_SS),
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
155
src/modules/system/controller/sys_log_operate.go
Normal file
155
src/modules/system/controller/sys_log_operate.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysLogOperateController 结构体
|
||||
var NewSysLogOperate = &SysLogOperateController{
|
||||
SysLogOperateService: service.NewSysLogOperateImpl,
|
||||
}
|
||||
|
||||
// 操作日志记录信息
|
||||
//
|
||||
// PATH /system/log/operate
|
||||
type SysLogOperateController struct {
|
||||
// 操作日志服务
|
||||
SysLogOperateService service.ISysLogOperate
|
||||
}
|
||||
|
||||
// 操作日志列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysLogOperateController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 操作日志删除
|
||||
//
|
||||
// DELETE /:operIds
|
||||
func (s *SysLogOperateController) Remove(c *gin.Context) {
|
||||
operIds := c.Param("operIds")
|
||||
if operIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(operIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows := s.SysLogOperateService.DeleteSysLogOperateByIds(uniqueIDs)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 操作日志清空
|
||||
//
|
||||
// DELETE /clean
|
||||
func (s *SysLogOperateController) Clean(c *gin.Context) {
|
||||
err := s.SysLogOperateService.CleanSysLogOperate()
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 导出操作日志
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysLogOperateController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.SysLogOperateService.SelectSysLogOperatePage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysLogOperate)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("sys_log_operate_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "操作序号",
|
||||
"B1": "操作模块",
|
||||
"C1": "业务类型",
|
||||
"D1": "请求方法",
|
||||
"E1": "请求方式",
|
||||
"F1": "操作类别",
|
||||
"G1": "操作人员",
|
||||
"H1": "部门名称",
|
||||
"I1": "请求地址",
|
||||
"J1": "操作地址",
|
||||
"K1": "操作地点",
|
||||
"L1": "请求参数",
|
||||
"M1": "操作消息",
|
||||
"N1": "状态",
|
||||
"O1": "消耗时间(毫秒)",
|
||||
"P1": "操作时间",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 业务类型
|
||||
businessType := ""
|
||||
// 操作类别
|
||||
OperatorType := ""
|
||||
// 状态
|
||||
statusValue := "失败"
|
||||
if row.Status == "1" {
|
||||
statusValue = "成功"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.OperID,
|
||||
"B" + idx: row.Title,
|
||||
"C" + idx: businessType,
|
||||
"D" + idx: row.Method,
|
||||
"E" + idx: row.RequestMethod,
|
||||
"F" + idx: OperatorType,
|
||||
"G" + idx: row.OperName,
|
||||
"H" + idx: row.DeptName,
|
||||
"I" + idx: row.OperURL,
|
||||
"J" + idx: row.OperIP,
|
||||
"K" + idx: row.OperLocation,
|
||||
"L" + idx: row.OperParam,
|
||||
"M" + idx: row.OperMsg,
|
||||
"N" + idx: statusValue,
|
||||
"O" + idx: row.CostTime,
|
||||
"P" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DD_HH_MM_SS),
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
287
src/modules/system/controller/sys_menu.go
Normal file
287
src/modules/system/controller/sys_menu.go
Normal file
@@ -0,0 +1,287 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/constants/menu"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/regular"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysMenuController 结构体
|
||||
var NewSysMenu = &SysMenuController{
|
||||
sysMenuService: service.NewSysMenuImpl,
|
||||
}
|
||||
|
||||
// 菜单信息
|
||||
//
|
||||
// PATH /system/menu
|
||||
type SysMenuController struct {
|
||||
// 菜单服务
|
||||
sysMenuService service.ISysMenu
|
||||
}
|
||||
|
||||
// 菜单列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysMenuController) List(c *gin.Context) {
|
||||
query := model.SysMenu{}
|
||||
if v, ok := c.GetQuery("menuName"); ok {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v, ok := c.GetQuery("status"); ok {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(c)
|
||||
if config.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuList(query, userId)
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 菜单信息
|
||||
//
|
||||
// GET /:menuId
|
||||
func (s *SysMenuController) Info(c *gin.Context) {
|
||||
menuId := c.Param("menuId")
|
||||
if menuId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuById(menuId)
|
||||
if data.MenuID == menuId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysMenuController) Add(c *gin.Context) {
|
||||
var body model.SysMenu
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.MenuID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 目录和菜单检查地址唯一
|
||||
if menu.TYPE_DIR == body.MenuType || menu.TYPE_MENU == body.MenuType {
|
||||
uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, "")
|
||||
if !uniqueNenuPath {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,菜单路由地址已存在", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, "")
|
||||
if !uniqueNenuName {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,菜单名称已存在", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 外链菜单需要符合网站http(s)开头
|
||||
if body.IsFrame == common.STATUS_NO && !regular.ValidHttp(body.Path) {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,非内部地址必须以http(s)://开头", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysMenuService.InsertMenu(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysMenuController) Edit(c *gin.Context) {
|
||||
var body model.SysMenu
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.MenuID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级菜单不能选自己
|
||||
if body.MenuID == body.ParentID {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,上级菜单不能选择自己", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
menuInfo := s.sysMenuService.SelectMenuById(body.MenuID)
|
||||
if menuInfo.MenuID != body.MenuID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问菜单数据"))
|
||||
return
|
||||
}
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
menuParent := s.sysMenuService.SelectMenuById(body.ParentID)
|
||||
if menuParent.MenuID != body.ParentID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问菜单数据"))
|
||||
return
|
||||
}
|
||||
// 禁用菜单时检查父菜单是否使用
|
||||
if body.Status == common.STATUS_YES && menuParent.Status == common.STATUS_NO {
|
||||
c.JSON(200, result.ErrMsg("上级菜单未启用!"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 目录和菜单检查地址唯一
|
||||
if menu.TYPE_DIR == body.MenuType || menu.TYPE_MENU == body.MenuType {
|
||||
uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, body.MenuID)
|
||||
if !uniqueNenuPath {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,菜单路由地址已存在", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, body.MenuID)
|
||||
if !uniqueNenuName {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,菜单名称已存在", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 外链菜单需要符合网站http(s)开头
|
||||
if body.IsFrame == common.STATUS_NO && !regular.ValidHttp(body.Path) {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,非内部地址必须以http(s)://开头", body.MenuName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 禁用菜单时检查子菜单是否使用
|
||||
if body.Status == common.STATUS_NO {
|
||||
hasStatus := s.sysMenuService.HasChildByMenuIdAndStatus(body.MenuID, common.STATUS_YES)
|
||||
if hasStatus > 0 {
|
||||
msg := fmt.Sprintf("不允许禁用,存在使用子菜单数:%d", hasStatus)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysMenuService.UpdateMenu(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单删除
|
||||
//
|
||||
// DELETE /:menuId
|
||||
func (s *SysMenuController) Remove(c *gin.Context) {
|
||||
menuId := c.Param("menuId")
|
||||
if menuId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
menu := s.sysMenuService.SelectMenuById(menuId)
|
||||
if menu.MenuID != menuId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问菜单数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在子菜单
|
||||
hasChild := s.sysMenuService.HasChildByMenuIdAndStatus(menuId, "")
|
||||
if hasChild > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,存在子菜单数:%d", hasChild)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否分配给角色
|
||||
existRole := s.sysMenuService.CheckMenuExistRole(menuId)
|
||||
if existRole > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,菜单已分配给角色数:%d", existRole)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
rows := s.sysMenuService.DeleteMenuById(menuId)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单树结构列表
|
||||
//
|
||||
// GET /treeSelect
|
||||
func (s *SysMenuController) TreeSelect(c *gin.Context) {
|
||||
query := model.SysMenu{}
|
||||
if v, ok := c.GetQuery("menuName"); ok {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v, ok := c.GetQuery("status"); ok {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(c)
|
||||
if config.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId)
|
||||
c.JSON(200, result.OkData(data))
|
||||
|
||||
}
|
||||
|
||||
// 菜单树结构列表(指定角色)
|
||||
//
|
||||
// GET /roleMenuTreeSelect/:roleId
|
||||
func (s *SysMenuController) RoleMenuTreeSelect(c *gin.Context) {
|
||||
roleId := c.Param("roleId")
|
||||
if roleId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
query := model.SysMenu{}
|
||||
if v, ok := c.GetQuery("menuName"); ok {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v, ok := c.GetQuery("status"); ok {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(c)
|
||||
if config.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
menuTreeSelect := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId)
|
||||
checkedKeys := s.sysMenuService.SelectMenuListByRoleId(roleId)
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"menus": menuTreeSelect,
|
||||
"checkedKeys": checkedKeys,
|
||||
}))
|
||||
}
|
||||
126
src/modules/system/controller/sys_notice.go
Normal file
126
src/modules/system/controller/sys_notice.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysNoticeController 结构体
|
||||
var NewSysNotice = &SysNoticeController{
|
||||
sysNoticeService: service.NewSysNoticeImpl,
|
||||
}
|
||||
|
||||
// 通知公告信息
|
||||
//
|
||||
// PATH /system/notice
|
||||
type SysNoticeController struct {
|
||||
// 公告服务
|
||||
sysNoticeService service.ISysNotice
|
||||
}
|
||||
|
||||
// 通知公告列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysNoticeController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysNoticeService.SelectNoticePage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 通知公告信息
|
||||
//
|
||||
// GET /:noticeId
|
||||
func (s *SysNoticeController) Info(c *gin.Context) {
|
||||
noticeId := c.Param("noticeId")
|
||||
if noticeId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysNoticeService.SelectNoticeById(noticeId)
|
||||
if data.NoticeID == noticeId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 通知公告新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysNoticeController) Add(c *gin.Context) {
|
||||
var body model.SysNotice
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.NoticeID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysNoticeService.InsertNotice(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 通知公告修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysNoticeController) Edit(c *gin.Context) {
|
||||
var body model.SysNotice
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.NoticeID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
notice := s.sysNoticeService.SelectNoticeById(body.NoticeID)
|
||||
if notice.NoticeID != body.NoticeID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问公告信息数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysNoticeService.UpdateNotice(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 通知公告删除
|
||||
//
|
||||
// DELETE /:noticeIds
|
||||
func (s *SysNoticeController) Remove(c *gin.Context) {
|
||||
noticeIds := c.Param("noticeIds")
|
||||
if noticeIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(noticeIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysNoticeService.DeleteNoticeByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
211
src/modules/system/controller/sys_post.go
Normal file
211
src/modules/system/controller/sys_post.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysPostController 结构体
|
||||
var NewSysPost = &SysPostController{
|
||||
sysPostService: service.NewSysPostImpl,
|
||||
}
|
||||
|
||||
// 岗位信息
|
||||
//
|
||||
// PATH /system/post
|
||||
type SysPostController struct {
|
||||
// 岗位服务
|
||||
sysPostService service.ISysPost
|
||||
}
|
||||
|
||||
// 岗位列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysPostController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysPostService.SelectPostPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 岗位信息
|
||||
//
|
||||
// GET /:postId
|
||||
func (s *SysPostController) Info(c *gin.Context) {
|
||||
postId := c.Param("postId")
|
||||
if postId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysPostService.SelectPostById(postId)
|
||||
if data.PostID == postId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 岗位新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysPostController) Add(c *gin.Context) {
|
||||
var body model.SysPost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.PostID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueuPostName := s.sysPostService.CheckUniquePostName(body.PostName, "")
|
||||
if !uniqueuPostName {
|
||||
msg := fmt.Sprintf("岗位新增【%s】失败,岗位名称已存在", body.PostName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查编码属性值唯一
|
||||
uniquePostCode := s.sysPostService.CheckUniquePostCode(body.PostCode, "")
|
||||
if !uniquePostCode {
|
||||
msg := fmt.Sprintf("岗位新增【%s】失败,岗位编码已存在", body.PostCode)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysPostService.InsertPost(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 岗位修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysPostController) Edit(c *gin.Context) {
|
||||
var body model.SysPost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.PostID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
post := s.sysPostService.SelectPostById(body.PostID)
|
||||
if post.PostID != body.PostID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问岗位数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueuPostName := s.sysPostService.CheckUniquePostName(body.PostName, body.PostID)
|
||||
if !uniqueuPostName {
|
||||
msg := fmt.Sprintf("岗位修改【%s】失败,岗位名称已存在", body.PostName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查编码属性值唯一
|
||||
uniquePostCode := s.sysPostService.CheckUniquePostCode(body.PostCode, body.PostID)
|
||||
if !uniquePostCode {
|
||||
msg := fmt.Sprintf("岗位修改【%s】失败,岗位编码已存在", body.PostCode)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysPostService.UpdatePost(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 岗位删除
|
||||
//
|
||||
// DELETE /:postIds
|
||||
func (s *SysPostController) Remove(c *gin.Context) {
|
||||
postIds := c.Param("postIds")
|
||||
if postIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(postIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysPostService.DeletePostByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 导出岗位信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysPostController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
data := s.sysPostService.SelectPostPage(querys)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysPost)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("post_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "岗位编号",
|
||||
"B1": "岗位编码",
|
||||
"C1": "岗位名称",
|
||||
"D1": "岗位排序",
|
||||
"E1": "状态",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
statusValue := "停用"
|
||||
if row.Status == "1" {
|
||||
statusValue = "正常"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.PostID,
|
||||
"B" + idx: row.PostCode,
|
||||
"C" + idx: row.PostName,
|
||||
"D" + idx: row.PostSort,
|
||||
"E" + idx: statusValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
282
src/modules/system/controller/sys_profile.go
Normal file
282
src/modules/system/controller/sys_profile.go
Normal file
@@ -0,0 +1,282 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/constants/admin"
|
||||
"ems.agt/src/framework/constants/uploadsubpath"
|
||||
"ems.agt/src/framework/utils/crypto"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/regular"
|
||||
"ems.agt/src/framework/utils/token"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysProfileController 结构体
|
||||
var NewSysProfile = &SysProfileController{
|
||||
sysUserService: service.NewSysUserImpl,
|
||||
sysRoleService: service.NewSysRoleImpl,
|
||||
sysPostService: service.NewSysPostImpl,
|
||||
sysMenuService: service.NewSysMenuImpl,
|
||||
}
|
||||
|
||||
// 个人信息
|
||||
//
|
||||
// PATH /system/user/profile
|
||||
type SysProfileController struct {
|
||||
// 用户服务
|
||||
sysUserService service.ISysUser
|
||||
// 角色服务
|
||||
sysRoleService service.ISysRole
|
||||
// 岗位服务
|
||||
sysPostService service.ISysPost
|
||||
// 菜单服务
|
||||
sysMenuService service.ISysMenu
|
||||
}
|
||||
|
||||
// 个人信息
|
||||
//
|
||||
// GET /
|
||||
func (s *SysProfileController) Info(c *gin.Context) {
|
||||
loginUser, err := ctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, result.CodeMsg(401, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户所属角色组
|
||||
roleGroup := []string{}
|
||||
roles := s.sysRoleService.SelectRoleListByUserId(loginUser.UserID)
|
||||
for _, role := range roles {
|
||||
roleGroup = append(roleGroup, role.RoleName)
|
||||
}
|
||||
isAdmin := config.IsAdmin(loginUser.UserID)
|
||||
if isAdmin {
|
||||
roleGroup = append(roleGroup, "管理员")
|
||||
}
|
||||
|
||||
// 查询用户所属岗位组
|
||||
postGroup := []string{}
|
||||
posts := s.sysPostService.SelectPostListByUserId(loginUser.UserID)
|
||||
for _, post := range posts {
|
||||
postGroup = append(postGroup, post.PostName)
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"user": loginUser.User,
|
||||
"roleGroup": parse.RemoveDuplicates(roleGroup),
|
||||
"postGroup": parse.RemoveDuplicates(postGroup),
|
||||
}))
|
||||
}
|
||||
|
||||
// 个人信息修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysProfileController) UpdateProfile(c *gin.Context) {
|
||||
var body struct {
|
||||
// 昵称
|
||||
NickName string `json:"nickName" binding:"required"`
|
||||
// 性别
|
||||
Sex string `json:"sex" binding:"required"`
|
||||
// 手机号
|
||||
PhoneNumber string `json:"phonenumber"`
|
||||
// 邮箱
|
||||
Email string `json:"email"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.Sex == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser, err := ctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, result.CodeMsg(401, err.Error()))
|
||||
return
|
||||
}
|
||||
userId := loginUser.UserID
|
||||
userName := loginUser.User.UserName
|
||||
|
||||
// 检查手机号码格式并判断是否唯一
|
||||
if body.PhoneNumber != "" {
|
||||
if regular.ValidMobile(body.PhoneNumber) {
|
||||
uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, userId)
|
||||
if !uniquePhone {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,手机号码已存在", userName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,手机号码格式错误", userName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
body.PhoneNumber = "nil"
|
||||
}
|
||||
|
||||
// 检查邮箱格式并判断是否唯一
|
||||
if body.Email != "" {
|
||||
if regular.ValidEmail(body.Email) {
|
||||
uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, userId)
|
||||
if !uniqueEmail {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,邮箱已存在", userName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,邮箱格式错误", userName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
body.Email = "nil"
|
||||
}
|
||||
|
||||
// 用户基本资料
|
||||
sysUser := model.SysUser{
|
||||
UserID: userId,
|
||||
UpdateBy: userName,
|
||||
NickName: body.NickName,
|
||||
PhoneNumber: body.PhoneNumber,
|
||||
Email: body.Email,
|
||||
Sex: body.Sex,
|
||||
}
|
||||
rows := s.sysUserService.UpdateUser(sysUser)
|
||||
if rows > 0 {
|
||||
// 更新缓存用户信息
|
||||
loginUser.User = s.sysUserService.SelectUserByUserName(userName)
|
||||
// 用户权限组标识
|
||||
isAdmin := config.IsAdmin(sysUser.UserID)
|
||||
if isAdmin {
|
||||
loginUser.Permissions = []string{admin.PERMISSION}
|
||||
} else {
|
||||
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
|
||||
loginUser.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
// 刷新令牌信息
|
||||
token.Cache(&loginUser)
|
||||
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.ErrMsg("上传图片异常"))
|
||||
}
|
||||
|
||||
// 个人重置密码
|
||||
//
|
||||
// PUT /updatePwd
|
||||
func (s *SysProfileController) UpdatePwd(c *gin.Context) {
|
||||
var body struct {
|
||||
// 旧密码
|
||||
OldPassword string `json:"oldPassword" binding:"required"`
|
||||
// 新密码
|
||||
NewPassword string `json:"newPassword" binding:"required"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser, err := ctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, result.CodeMsg(401, err.Error()))
|
||||
return
|
||||
}
|
||||
userId := loginUser.UserID
|
||||
userName := loginUser.User.UserName
|
||||
|
||||
// 查询当前登录用户信息得到密码值
|
||||
user := s.sysUserService.SelectUserById(userId)
|
||||
if user.UserID != userId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问用户数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查匹配用户密码
|
||||
oldCompare := crypto.BcryptCompare(body.OldPassword, user.Password)
|
||||
if !oldCompare {
|
||||
c.JSON(200, result.ErrMsg("修改密码失败,旧密码错误"))
|
||||
return
|
||||
}
|
||||
newCompare := crypto.BcryptCompare(body.NewPassword, user.Password)
|
||||
if newCompare {
|
||||
c.JSON(200, result.ErrMsg("新密码不能与旧密码相同"))
|
||||
return
|
||||
}
|
||||
|
||||
// 修改新密码
|
||||
sysUser := model.SysUser{
|
||||
UserID: userId,
|
||||
UpdateBy: userName,
|
||||
Password: body.NewPassword,
|
||||
}
|
||||
rows := s.sysUserService.UpdateUser(sysUser)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 个人头像上传
|
||||
//
|
||||
// POST /avatar
|
||||
func (s *SysProfileController) Avatar(c *gin.Context) {
|
||||
formFile, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上传文件转存
|
||||
filePath, err := file.TransferUploadFile(formFile, uploadsubpath.AVATART, []string{".jpg", ".jpeg", ".png"})
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser, err := ctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, result.CodeMsg(401, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 更新头像地址
|
||||
sysUser := model.SysUser{
|
||||
UserID: loginUser.UserID,
|
||||
UpdateBy: loginUser.User.UserName,
|
||||
Avatar: filePath,
|
||||
}
|
||||
rows := s.sysUserService.UpdateUser(sysUser)
|
||||
if rows > 0 {
|
||||
// 更新缓存用户信息
|
||||
loginUser.User = s.sysUserService.SelectUserByUserName(loginUser.User.UserName)
|
||||
// 用户权限组标识
|
||||
isAdmin := config.IsAdmin(sysUser.UserID)
|
||||
if isAdmin {
|
||||
loginUser.Permissions = []string{admin.PERMISSION}
|
||||
} else {
|
||||
perms := s.sysMenuService.SelectMenuPermsByUserId(sysUser.UserID)
|
||||
loginUser.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
// 刷新令牌信息
|
||||
token.Cache(&loginUser)
|
||||
|
||||
c.JSON(200, result.OkData(filePath))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
408
src/modules/system/controller/sys_role.go
Normal file
408
src/modules/system/controller/sys_role.go
Normal file
@@ -0,0 +1,408 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/constants/admin"
|
||||
"ems.agt/src/framework/constants/roledatascope"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysRoleController 结构体
|
||||
var NewSysRole = &SysRoleController{
|
||||
sysRoleService: service.NewSysRoleImpl,
|
||||
sysUserService: service.NewSysUserImpl,
|
||||
}
|
||||
|
||||
// 角色信息
|
||||
//
|
||||
// PATH /system/role
|
||||
type SysRoleController struct {
|
||||
// 角色服务
|
||||
sysRoleService service.ISysRole
|
||||
// 用户服务
|
||||
sysUserService service.ISysUser
|
||||
}
|
||||
|
||||
// 角色列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysRoleController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 角色信息详情
|
||||
//
|
||||
// GET /:roleId
|
||||
func (s *SysRoleController) Info(c *gin.Context) {
|
||||
roleId := c.Param("roleId")
|
||||
if roleId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysRoleService.SelectRoleById(roleId)
|
||||
if data.RoleID == roleId {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 角色信息新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysRoleController) Add(c *gin.Context) {
|
||||
var body model.SysRole
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.RoleID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断角色名称是否唯一
|
||||
uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, "")
|
||||
if !uniqueRoleName {
|
||||
msg := fmt.Sprintf("角色新增【%s】失败,角色名称已存在", body.RoleName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断角色键值是否唯一
|
||||
uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, "")
|
||||
if !uniqueRoleKey {
|
||||
msg := fmt.Sprintf("角色新增【%s】失败,角色键值已存在", body.RoleName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysRoleService.InsertRole(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 角色信息修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysRoleController) Edit(c *gin.Context) {
|
||||
var body model.SysRole
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.RoleID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否管理员角色
|
||||
if body.RoleID == admin.ROLE_ID {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员角色"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
role := s.sysRoleService.SelectRoleById(body.RoleID)
|
||||
if role.RoleID != body.RoleID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问角色数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断角色名称是否唯一
|
||||
uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, body.RoleID)
|
||||
if !uniqueRoleName {
|
||||
msg := fmt.Sprintf("角色修改【%s】失败,角色名称已存在", body.RoleName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断角色键值是否唯一
|
||||
uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, body.RoleID)
|
||||
if !uniqueRoleKey {
|
||||
msg := fmt.Sprintf("角色修改【%s】失败,角色键值已存在", body.RoleName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysRoleService.UpdateRole(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 角色信息删除
|
||||
//
|
||||
// DELETE /:roleIds
|
||||
func (s *SysRoleController) Remove(c *gin.Context) {
|
||||
roleIds := c.Param("roleIds")
|
||||
if roleIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(roleIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
// 检查是否管理员角色
|
||||
for _, id := range uniqueIDs {
|
||||
if id == admin.ROLE_ID {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员角色"))
|
||||
return
|
||||
}
|
||||
}
|
||||
rows, err := s.sysRoleService.DeleteRoleByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 角色状态变更
|
||||
//
|
||||
// PUT /changeStatus
|
||||
func (s *SysRoleController) Status(c *gin.Context) {
|
||||
var body struct {
|
||||
// 角色ID
|
||||
RoleID string `json:"roleId" binding:"required"`
|
||||
// 状态
|
||||
Status string `json:"status" binding:"required"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否管理员角色
|
||||
if body.RoleID == admin.ROLE_ID {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员角色"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
role := s.sysRoleService.SelectRoleById(body.RoleID)
|
||||
if role.RoleID != body.RoleID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问角色数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 与旧值相等不变更
|
||||
if role.Status == body.Status {
|
||||
c.JSON(200, result.ErrMsg("变更状态与旧值相等!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 更新状态不刷新缓存
|
||||
userName := ctx.LoginUserToUserName(c)
|
||||
SysRoleController := model.SysRole{
|
||||
RoleID: body.RoleID,
|
||||
Status: body.Status,
|
||||
UpdateBy: userName,
|
||||
}
|
||||
rows := s.sysRoleService.UpdateRole(SysRoleController)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 角色数据权限修改
|
||||
//
|
||||
// PUT /dataScope
|
||||
func (s *SysRoleController) DataScope(c *gin.Context) {
|
||||
var body struct {
|
||||
// 角色ID
|
||||
RoleID string `json:"roleId"`
|
||||
// 部门组(数据权限)
|
||||
DeptIds []string `json:"deptIds"`
|
||||
// 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限)
|
||||
DataScope string `json:"dataScope"`
|
||||
// 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示)
|
||||
DeptCheckStrictly string `json:"deptCheckStrictly"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否管理员角色
|
||||
if body.RoleID == admin.ROLE_ID {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员角色"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
role := s.sysRoleService.SelectRoleById(body.RoleID)
|
||||
if role.RoleID != body.RoleID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问角色数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 更新数据权限
|
||||
userName := ctx.LoginUserToUserName(c)
|
||||
SysRoleController := model.SysRole{
|
||||
RoleID: body.RoleID,
|
||||
DeptIds: body.DeptIds,
|
||||
DataScope: body.DataScope,
|
||||
DeptCheckStrictly: body.DeptCheckStrictly,
|
||||
UpdateBy: userName,
|
||||
}
|
||||
rows := s.sysRoleService.AuthDataScope(SysRoleController)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 角色分配用户列表
|
||||
//
|
||||
// GET /authUser/allocatedList
|
||||
func (s *SysRoleController) AuthUserAllocatedList(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
roleId, ok := querys["roleId"]
|
||||
if !ok || roleId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
role := s.sysRoleService.SelectRoleById(roleId.(string))
|
||||
if role.RoleID != roleId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问角色数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u")
|
||||
data := s.sysUserService.SelectAllocatedPage(querys, dataScopeSQL)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 角色分配选择授权
|
||||
//
|
||||
// PUT /authUser/checked
|
||||
func (s *SysRoleController) AuthUserChecked(c *gin.Context) {
|
||||
var body struct {
|
||||
// 角色ID
|
||||
RoleID string `json:"roleId" binding:"required"`
|
||||
// 用户ID组
|
||||
UserIDs string `json:"userIds" binding:"required"`
|
||||
// 选择操作 添加true 取消false
|
||||
Checked bool `json:"checked"`
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(body.UserIDs, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
role := s.sysRoleService.SelectRoleById(body.RoleID)
|
||||
if role.RoleID != body.RoleID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问角色数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
var rows int64
|
||||
if body.Checked {
|
||||
rows = s.sysRoleService.InsertAuthUsers(body.RoleID, uniqueIDs)
|
||||
} else {
|
||||
rows = s.sysRoleService.DeleteAuthUsers(body.RoleID, uniqueIDs)
|
||||
}
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 导出角色信息
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysRoleController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysRole)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("role_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "角色序号",
|
||||
"B1": "角色名称",
|
||||
"C1": "角色权限",
|
||||
"D1": "角色排序",
|
||||
"E1": "数据范围",
|
||||
"F1": "角色状态",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 数据范围
|
||||
dataScope := "空"
|
||||
if v, ok := roledatascope.RoleDataScope[row.DataScope]; ok {
|
||||
dataScope = v
|
||||
}
|
||||
// 角色状态
|
||||
statusValue := "停用"
|
||||
if row.Status == "1" {
|
||||
statusValue = "正常"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.RoleID,
|
||||
"B" + idx: row.RoleName,
|
||||
"C" + idx: row.RoleKey,
|
||||
"D" + idx: row.RoleSort,
|
||||
"E" + idx: dataScope,
|
||||
"F" + idx: statusValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
481
src/modules/system/controller/sys_user.go
Normal file
481
src/modules/system/controller/sys_user.go
Normal file
@@ -0,0 +1,481 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/config"
|
||||
"ems.agt/src/framework/constants/admin"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/regular"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysUserController 结构体
|
||||
var NewSysUser = &SysUserController{
|
||||
sysUserService: service.NewSysUserImpl,
|
||||
sysRoleService: service.NewSysRoleImpl,
|
||||
sysPostService: service.NewSysPostImpl,
|
||||
sysDictDataService: service.NewSysDictDataImpl,
|
||||
}
|
||||
|
||||
// 用户信息
|
||||
//
|
||||
// PATH /system/user
|
||||
type SysUserController struct {
|
||||
// 用户服务
|
||||
sysUserService service.ISysUser
|
||||
// 角色服务
|
||||
sysRoleService service.ISysRole
|
||||
// 岗位服务
|
||||
sysPostService service.ISysPost
|
||||
// 字典数据服务
|
||||
sysDictDataService service.ISysDictData
|
||||
}
|
||||
|
||||
// 用户信息列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysUserController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u")
|
||||
data := s.sysUserService.SelectUserPage(querys, dataScopeSQL)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 用户信息详情
|
||||
//
|
||||
// GET /:userId
|
||||
func (s *SysUserController) Info(c *gin.Context) {
|
||||
userId := c.Param("userId")
|
||||
if userId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 查询系统角色列表
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
roles := s.sysRoleService.SelectRoleList(model.SysRole{}, dataScopeSQL)
|
||||
|
||||
// 不是系统指定管理员需要排除其角色
|
||||
if !config.IsAdmin(userId) {
|
||||
rolesFilter := make([]model.SysRole, 0)
|
||||
for _, r := range roles {
|
||||
if r.RoleID != admin.ROLE_ID {
|
||||
rolesFilter = append(rolesFilter, r)
|
||||
}
|
||||
}
|
||||
roles = rolesFilter
|
||||
}
|
||||
|
||||
// 查询系统岗位列表
|
||||
posts := s.sysPostService.SelectPostList(model.SysPost{})
|
||||
|
||||
// 新增用户时,用户ID为0
|
||||
if userId == "0" {
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"user": map[string]any{},
|
||||
"roleIds": []string{},
|
||||
"postIds": []string{},
|
||||
"roles": roles,
|
||||
"posts": posts,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
user := s.sysUserService.SelectUserById(userId)
|
||||
if user.UserID != userId {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问用户数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 角色ID组
|
||||
roleIds := make([]string, 0)
|
||||
for _, r := range user.Roles {
|
||||
roleIds = append(roleIds, r.RoleID)
|
||||
}
|
||||
|
||||
// 岗位ID组
|
||||
postIds := make([]string, 0)
|
||||
userPosts := s.sysPostService.SelectPostListByUserId(userId)
|
||||
for _, p := range userPosts {
|
||||
postIds = append(postIds, p.PostID)
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"user": user,
|
||||
"roleIds": roleIds,
|
||||
"postIds": postIds,
|
||||
"roles": roles,
|
||||
"posts": posts,
|
||||
}))
|
||||
}
|
||||
|
||||
// 用户信息新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysUserController) Add(c *gin.Context) {
|
||||
var body model.SysUser
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.UserID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户登录账号是否唯一
|
||||
uniqueUserName := s.sysUserService.CheckUniqueUserName(body.UserName, "")
|
||||
if !uniqueUserName {
|
||||
msg := fmt.Sprintf("新增用户【%s】失败,登录账号已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查手机号码格式并判断是否唯一
|
||||
if body.PhoneNumber != "" {
|
||||
if regular.ValidMobile(body.PhoneNumber) {
|
||||
uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, "")
|
||||
if !uniquePhone {
|
||||
msg := fmt.Sprintf("新增用户【%s】失败,手机号码已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("新增用户【%s】失败,手机号码格式错误", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查邮箱格式并判断是否唯一
|
||||
if body.Email != "" {
|
||||
if regular.ValidEmail(body.Email) {
|
||||
uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, "")
|
||||
if !uniqueEmail {
|
||||
msg := fmt.Sprintf("新增用户【%s】失败,邮箱已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("新增用户【%s】失败,邮箱格式错误", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysUserService.InsertUser(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 用户信息修改
|
||||
//
|
||||
// POST /
|
||||
func (s *SysUserController) Edit(c *gin.Context) {
|
||||
var body model.SysUser
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.UserID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否管理员用户
|
||||
if config.IsAdmin(body.UserID) {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员用户"))
|
||||
return
|
||||
}
|
||||
|
||||
user := s.sysUserService.SelectUserById(body.UserID)
|
||||
if user.UserID != body.UserID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问用户数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户登录账号是否唯一
|
||||
uniqueUserName := s.sysUserService.CheckUniqueUserName(body.UserName, body.UserID)
|
||||
if !uniqueUserName {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,登录账号已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查手机号码格式并判断是否唯一
|
||||
if body.PhoneNumber != "" {
|
||||
if regular.ValidMobile(body.PhoneNumber) {
|
||||
uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, body.UserID)
|
||||
if !uniquePhone {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,手机号码已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,手机号码格式错误", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查邮箱格式并判断是否唯一
|
||||
if body.Email != "" {
|
||||
if regular.ValidEmail(body.Email) {
|
||||
uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, body.UserID)
|
||||
if !uniqueEmail {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,邮箱已存在", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("修改用户【%s】失败,邮箱格式错误", body.UserName)
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
body.UserName = "" // 忽略修改登录用户名称
|
||||
body.Password = "" // 忽略修改密码
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysUserService.UpdateUserAndRolePost(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 用户信息删除
|
||||
//
|
||||
// DELETE /:userIds
|
||||
func (s *SysUserController) Remove(c *gin.Context) {
|
||||
userIds := c.Param("userIds")
|
||||
if userIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(userIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.sysUserService.DeleteUserByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 用户重置密码
|
||||
//
|
||||
// PUT /resetPwd
|
||||
func (s *SysUserController) ResetPwd(c *gin.Context) {
|
||||
var body struct {
|
||||
UserID string `json:"userId" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否管理员用户
|
||||
if config.IsAdmin(body.UserID) {
|
||||
c.JSON(200, result.ErrMsg("不允许操作管理员用户"))
|
||||
return
|
||||
}
|
||||
|
||||
user := s.sysUserService.SelectUserById(body.UserID)
|
||||
if user.UserID != body.UserID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问用户数据!"))
|
||||
return
|
||||
}
|
||||
if !regular.ValidPassword(body.Password) {
|
||||
c.JSON(200, result.ErrMsg("登录密码至少包含大小写字母、数字、特殊符号,且不少于6位"))
|
||||
return
|
||||
}
|
||||
|
||||
userName := ctx.LoginUserToUserName(c)
|
||||
SysUserController := model.SysUser{
|
||||
UserID: body.UserID,
|
||||
Password: body.Password,
|
||||
UpdateBy: userName,
|
||||
}
|
||||
rows := s.sysUserService.UpdateUser(SysUserController)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 用户状态修改
|
||||
//
|
||||
// PUT /changeStatus
|
||||
func (s *SysUserController) Status(c *gin.Context) {
|
||||
var body struct {
|
||||
UserID string `json:"userId" binding:"required"`
|
||||
Status string `json:"status" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
user := s.sysUserService.SelectUserById(body.UserID)
|
||||
if user.UserID != body.UserID {
|
||||
c.JSON(200, result.ErrMsg("没有权限访问用户数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 与旧值相等不变更
|
||||
if user.Status == body.Status {
|
||||
c.JSON(200, result.ErrMsg("变更状态与旧值相等!"))
|
||||
return
|
||||
}
|
||||
|
||||
userName := ctx.LoginUserToUserName(c)
|
||||
SysUserController := model.SysUser{
|
||||
UserID: body.UserID,
|
||||
Status: body.Status,
|
||||
UpdateBy: userName,
|
||||
}
|
||||
rows := s.sysUserService.UpdateUser(SysUserController)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 用户信息列表导出
|
||||
//
|
||||
// POST /export
|
||||
func (s *SysUserController) Export(c *gin.Context) {
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
querys := ctx.BodyJSONMap(c)
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u")
|
||||
data := s.sysUserService.SelectUserPage(querys, dataScopeSQL)
|
||||
if data["total"].(int64) == 0 {
|
||||
c.JSON(200, result.ErrMsg("导出数据记录为空"))
|
||||
return
|
||||
}
|
||||
rows := data["rows"].([]model.SysUser)
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("user_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "用户序号",
|
||||
"B1": "登录名称",
|
||||
"C1": "用户名称",
|
||||
"D1": "用户邮箱",
|
||||
"E1": "手机号码",
|
||||
"F1": "用户性别",
|
||||
"G1": "帐号状态",
|
||||
"H1": "最后登录IP",
|
||||
"I1": "最后登录时间",
|
||||
"J1": "部门名称",
|
||||
"K1": "部门负责人",
|
||||
}
|
||||
// 读取用户性别字典数据
|
||||
dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 用户性别
|
||||
sysUserSex := "未知"
|
||||
for _, v := range dictSysUserSex {
|
||||
if row.Sex == v.DictValue {
|
||||
sysUserSex = v.DictLabel
|
||||
break
|
||||
}
|
||||
}
|
||||
// 帐号状态
|
||||
statusValue := "停用"
|
||||
if row.Status == "1" {
|
||||
statusValue = "正常"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.UserID,
|
||||
"B" + idx: row.UserName,
|
||||
"C" + idx: row.NickName,
|
||||
"D" + idx: row.Email,
|
||||
"E" + idx: row.PhoneNumber,
|
||||
"F" + idx: sysUserSex,
|
||||
"G" + idx: statusValue,
|
||||
"H" + idx: row.LoginIP,
|
||||
"I" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS),
|
||||
"J" + idx: row.Dept.DeptName,
|
||||
"K" + idx: row.Dept.Leader,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 用户信息列表导入模板下载
|
||||
//
|
||||
// GET /importTemplate
|
||||
func (s *SysUserController) Template(c *gin.Context) {
|
||||
fileName := fmt.Sprintf("user_import_template_%d.xlsx", time.Now().UnixMilli())
|
||||
asserPath := "assets/template/excel/user_import_template.xlsx"
|
||||
c.FileAttachment(asserPath, fileName)
|
||||
}
|
||||
|
||||
// 用户信息列表导入
|
||||
//
|
||||
// POST /importData
|
||||
func (s *SysUserController) ImportData(c *gin.Context) {
|
||||
// 允许进行更新
|
||||
updateSupport := c.PostForm("updateSupport")
|
||||
// 上传的文件
|
||||
formFile, err := c.FormFile("file")
|
||||
if err != nil || updateSupport == "" {
|
||||
c.JSON(400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 保存表格文件
|
||||
filePath, err := file.TransferExeclUploadFile(formFile)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 读取表格数据
|
||||
rows, err := file.ReadSheet(filePath, "")
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 获取操作人名称
|
||||
operName := ctx.LoginUserToUserName(c)
|
||||
isUpdateSupport := parse.Boolean(updateSupport)
|
||||
message := s.sysUserService.ImportUser(rows, isUpdateSupport, operName)
|
||||
c.JSON(200, result.OkMsg(message))
|
||||
}
|
||||
25
src/modules/system/model/sys_config.go
Normal file
25
src/modules/system/model/sys_config.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
// 参数配置对象 sys_config
|
||||
type SysConfig struct {
|
||||
// 参数主键
|
||||
ConfigID string `json:"configId"`
|
||||
// 参数名称
|
||||
ConfigName string `json:"configName" binding:"required"`
|
||||
// 参数键名
|
||||
ConfigKey string `json:"configKey" binding:"required"`
|
||||
// 参数键值
|
||||
ConfigValue string `json:"configValue" binding:"required"`
|
||||
// 系统内置(Y是 N否)
|
||||
ConfigType string `json:"configType"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
41
src/modules/system/model/sys_dept.go
Normal file
41
src/modules/system/model/sys_dept.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package model
|
||||
|
||||
// SysDept 部门对象 sys_dept
|
||||
type SysDept struct {
|
||||
// 部门ID
|
||||
DeptID string `json:"deptId"`
|
||||
// 父部门ID
|
||||
ParentID string `json:"parentId" binding:"required"`
|
||||
// 祖级列表
|
||||
Ancestors string `json:"ancestors"`
|
||||
// 部门名称
|
||||
DeptName string `json:"deptName" binding:"required"`
|
||||
// 显示顺序
|
||||
OrderNum int `json:"orderNum"`
|
||||
// 负责人
|
||||
Leader string `json:"leader"`
|
||||
// 联系电话
|
||||
Phone string `json:"phone"`
|
||||
// 邮箱
|
||||
Email string `json:"email"`
|
||||
// 部门状态(0正常 1停用)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
DelFlag string `json:"delFlag"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 子部门列表
|
||||
Children []SysDept `json:"children,omitempty"`
|
||||
|
||||
// 父部门名称
|
||||
ParentName string `json:"parentName,omitempty"`
|
||||
}
|
||||
31
src/modules/system/model/sys_dict_data.go
Normal file
31
src/modules/system/model/sys_dict_data.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package model
|
||||
|
||||
// SysDictData 字典数据对象 sys_dict_data
|
||||
type SysDictData struct {
|
||||
// 字典编码
|
||||
DictCode string `json:"dictCode"`
|
||||
// 字典排序
|
||||
DictSort int `json:"dictSort"`
|
||||
// 字典标签
|
||||
DictLabel string `json:"dictLabel" binding:"required"`
|
||||
// 字典键值
|
||||
DictValue string `json:"dictValue" binding:"required"`
|
||||
// 字典类型
|
||||
DictType string `json:"dictType" binding:"required"`
|
||||
// 样式属性(样式扩展)
|
||||
TagClass string `json:"tagClass"`
|
||||
// 标签类型(预设颜色)
|
||||
TagType string `json:"tagType"`
|
||||
// 状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
23
src/modules/system/model/sys_dict_type.go
Normal file
23
src/modules/system/model/sys_dict_type.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// SysDictType 字典类型对象 sys_dict_type
|
||||
type SysDictType struct {
|
||||
// 字典主键
|
||||
DictID string `json:"dictId"`
|
||||
// 字典名称
|
||||
DictName string `json:"dictName" binding:"required"`
|
||||
// 字典类型
|
||||
DictType string `json:"dictType" binding:"required"`
|
||||
// 状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
23
src/modules/system/model/sys_log_login.go
Normal file
23
src/modules/system/model/sys_log_login.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// SysLogLogin 系统登录日志表 sys_log_login
|
||||
type SysLogLogin struct {
|
||||
// 登录ID
|
||||
LoginID string `json:"loginId"`
|
||||
// 用户账号
|
||||
UserName string `json:"userName"`
|
||||
// 登录IP地址
|
||||
IPAddr string `json:"ipaddr"`
|
||||
// 登录地点
|
||||
LoginLocation string `json:"loginLocation"`
|
||||
// 浏览器类型
|
||||
Browser string `json:"browser"`
|
||||
// 操作系统
|
||||
OS string `json:"os"`
|
||||
// 登录状态(0失败 1成功)
|
||||
Status string `json:"status"`
|
||||
// 提示消息
|
||||
Msg string `json:"msg"`
|
||||
// 访问时间
|
||||
LoginTime int64 `json:"loginTime"`
|
||||
}
|
||||
37
src/modules/system/model/sys_log_operate.go
Normal file
37
src/modules/system/model/sys_log_operate.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package model
|
||||
|
||||
// SysLogOperate 系统操作日志表 sys_log_operate
|
||||
type SysLogOperate struct {
|
||||
// 日志主键
|
||||
OperID string `json:"operId"`
|
||||
// 模块标题
|
||||
Title string `json:"title"`
|
||||
// 业务类型(0其它 1新增 2修改 3删除 4授权 5导出 6导入 7强退 8清空数据)
|
||||
BusinessType string `json:"businessType"`
|
||||
// 方法名称
|
||||
Method string `json:"method"`
|
||||
// 请求方式
|
||||
RequestMethod string `json:"requestMethod"`
|
||||
// 操作人员类别(0其它 1后台用户 2手机端用户)
|
||||
OperatorType string `json:"operatorType"`
|
||||
// 操作人员
|
||||
OperName string `json:"operName"`
|
||||
// 部门名称
|
||||
DeptName string `json:"deptName"`
|
||||
// 请求URL
|
||||
OperURL string `json:"operUrl"`
|
||||
// 主机地址
|
||||
OperIP string `json:"operIp"`
|
||||
// 操作地点
|
||||
OperLocation string `json:"operLocation"`
|
||||
// 请求参数
|
||||
OperParam string `json:"operParam"`
|
||||
// 操作消息
|
||||
OperMsg string `json:"operMsg"`
|
||||
// 操作状态(0异常 1正常)
|
||||
Status string `json:"status"`
|
||||
// 操作时间
|
||||
OperTime int64 `json:"operTime"`
|
||||
// 消耗时间(毫秒)
|
||||
CostTime int64 `json:"costTime"`
|
||||
}
|
||||
46
src/modules/system/model/sys_menu.go
Normal file
46
src/modules/system/model/sys_menu.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package model
|
||||
|
||||
// SysMenu 菜单权限对象 sys_menu
|
||||
type SysMenu struct {
|
||||
// 菜单ID
|
||||
MenuID string `json:"menuId"`
|
||||
// 菜单名称
|
||||
MenuName string `json:"menuName" binding:"required"`
|
||||
// 父菜单ID 默认0
|
||||
ParentID string `json:"parentId" binding:"required"`
|
||||
// 显示顺序
|
||||
MenuSort int `json:"menuSort"`
|
||||
// 路由地址
|
||||
Path string `json:"path"`
|
||||
// 组件路径
|
||||
Component string `json:"component"`
|
||||
// 是否内部跳转(0否 1是)
|
||||
IsFrame string `json:"isFrame"`
|
||||
// 是否缓存(0不缓存 1缓存)
|
||||
IsCache string `json:"isCache"`
|
||||
// 菜单类型(D目录 M菜单 B按钮)
|
||||
MenuType string `json:"menuType" binding:"required"`
|
||||
// 是否显示(0隐藏 1显示)
|
||||
Visible string `json:"visible"`
|
||||
// 菜单状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 权限标识
|
||||
Perms string `json:"perms"`
|
||||
// 菜单图标(#无图标)
|
||||
Icon string `json:"icon"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 子菜单
|
||||
Children []SysMenu `json:"children,omitempty"`
|
||||
}
|
||||
27
src/modules/system/model/sys_notice.go
Normal file
27
src/modules/system/model/sys_notice.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
// SysNotice 通知公告对象 sys_notice
|
||||
type SysNotice struct {
|
||||
// 公告ID
|
||||
NoticeID string `json:"noticeId"`
|
||||
// 公告标题
|
||||
NoticeTitle string `json:"noticeTitle" binding:"required"`
|
||||
// 公告类型(1通知 2公告)
|
||||
NoticeType string `json:"noticeType" binding:"required"`
|
||||
// 公告内容
|
||||
NoticeContent string `json:"noticeContent" binding:"required"`
|
||||
// 公告状态(0关闭 1正常)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
DelFlag string `json:"delFlag"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
25
src/modules/system/model/sys_post.go
Normal file
25
src/modules/system/model/sys_post.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
// SysPost 岗位对象 sys_post
|
||||
type SysPost struct {
|
||||
// 岗位ID
|
||||
PostID string `json:"postId"`
|
||||
// 岗位编码
|
||||
PostCode string `json:"postCode" binding:"required"`
|
||||
// 岗位名称
|
||||
PostName string `json:"postName" binding:"required"`
|
||||
// 显示顺序
|
||||
PostSort int `json:"postSort"`
|
||||
// 状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
40
src/modules/system/model/sys_role.go
Normal file
40
src/modules/system/model/sys_role.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
// SysRole 角色对象 sys_role
|
||||
type SysRole struct {
|
||||
// 角色ID
|
||||
RoleID string `json:"roleId"`
|
||||
// 角色名称
|
||||
RoleName string `json:"roleName" binding:"required"`
|
||||
// 角色键值
|
||||
RoleKey string `json:"roleKey" binding:"required"`
|
||||
// 显示顺序
|
||||
RoleSort int `json:"roleSort"`
|
||||
// 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限)
|
||||
DataScope string `json:"dataScope"`
|
||||
// 菜单树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示)
|
||||
MenuCheckStrictly string `json:"menuCheckStrictly"`
|
||||
// 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示)
|
||||
DeptCheckStrictly string `json:"deptCheckStrictly"`
|
||||
// 角色状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
DelFlag string `json:"delFlag"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 菜单组
|
||||
MenuIds []string `json:"menuIds,omitempty"`
|
||||
// 部门组(数据权限)
|
||||
DeptIds []string `json:"deptIds,omitempty"`
|
||||
}
|
||||
15
src/modules/system/model/sys_role_dept.go
Normal file
15
src/modules/system/model/sys_role_dept.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
// SysRoleDept 角色和部门关联对象 sys_role_dept
|
||||
type SysRoleDept struct {
|
||||
RoleID string `json:"roleId"` // 角色ID
|
||||
DeptID string `json:"deptId"` // 部门ID
|
||||
}
|
||||
|
||||
// NewSysRoleDept 创建角色和部门关联对象的构造函数
|
||||
func NewSysRoleDept(roleID string, deptID string) SysRoleDept {
|
||||
return SysRoleDept{
|
||||
RoleID: roleID,
|
||||
DeptID: deptID,
|
||||
}
|
||||
}
|
||||
15
src/modules/system/model/sys_role_menu.go
Normal file
15
src/modules/system/model/sys_role_menu.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
// SysRoleMenu 角色和菜单关联对象 sys_role_menu
|
||||
type SysRoleMenu struct {
|
||||
RoleID string `json:"roleId"` // 角色ID
|
||||
MenuID string `json:"menuId"` // 菜单ID
|
||||
}
|
||||
|
||||
// NewSysRoleMenu 创建角色和菜单关联对象的构造函数
|
||||
func NewSysRoleMenu(roleID string, menuID string) SysRoleMenu {
|
||||
return SysRoleMenu{
|
||||
RoleID: roleID,
|
||||
MenuID: menuID,
|
||||
}
|
||||
}
|
||||
56
src/modules/system/model/sys_user.go
Normal file
56
src/modules/system/model/sys_user.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package model
|
||||
|
||||
// SysUser 用户对象 sys_user
|
||||
type SysUser struct {
|
||||
// 用户ID
|
||||
UserID string `json:"userId"`
|
||||
// 部门ID
|
||||
DeptID string `json:"deptId"`
|
||||
// 用户账号
|
||||
UserName string `json:"userName" binding:"required"`
|
||||
// 用户昵称
|
||||
NickName string `json:"nickName" binding:"required"`
|
||||
// 用户类型(sys系统用户)
|
||||
UserType string `json:"userType"`
|
||||
// 用户邮箱
|
||||
Email string `json:"email"`
|
||||
// 手机号码
|
||||
PhoneNumber string `json:"phonenumber"`
|
||||
// 用户性别(0未知 1男 2女)
|
||||
Sex string `json:"sex"`
|
||||
// 头像地址
|
||||
Avatar string `json:"avatar"`
|
||||
// 密码
|
||||
Password string `json:"-"`
|
||||
// 帐号状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
DelFlag string `json:"delFlag"`
|
||||
// 最后登录IP
|
||||
LoginIP string `json:"loginIp"`
|
||||
// 最后登录时间
|
||||
LoginDate int64 `json:"loginDate"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 部门对象
|
||||
Dept SysDept `json:"dept,omitempty" binding:"structonly"`
|
||||
// 角色对象组
|
||||
Roles []SysRole `json:"roles"`
|
||||
// 角色ID
|
||||
RoleID string `json:"roleId,omitempty"`
|
||||
// 角色组
|
||||
RoleIDs []string `json:"roleIds,omitempty"`
|
||||
// 岗位组
|
||||
PostIDs []string `json:"postIds,omitempty"`
|
||||
}
|
||||
15
src/modules/system/model/sys_user_post.go
Normal file
15
src/modules/system/model/sys_user_post.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
// SysUserPost 用户和岗位关联对象 sys_user_post
|
||||
type SysUserPost struct {
|
||||
UserID string `json:"userId"` // 用户ID
|
||||
PostID string `json:"postId"` // 岗位ID
|
||||
}
|
||||
|
||||
// NewSysUserPost 创建用户和岗位关联对象的构造函数
|
||||
func NewSysUserPost(userID string, postID string) SysUserPost {
|
||||
return SysUserPost{
|
||||
UserID: userID,
|
||||
PostID: postID,
|
||||
}
|
||||
}
|
||||
15
src/modules/system/model/sys_user_role.go
Normal file
15
src/modules/system/model/sys_user_role.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
// SysUserRole 用户和角色关联对象 sys_user_role
|
||||
type SysUserRole struct {
|
||||
UserID string `json:"userId"` // 用户ID
|
||||
RoleID string `json:"roleId"` // 角色ID
|
||||
}
|
||||
|
||||
// NewSysUserRole 创建用户和角色关联对象的构造函数
|
||||
func NewSysUserRole(userID string, roleID string) SysUserRole {
|
||||
return SysUserRole{
|
||||
UserID: userID,
|
||||
RoleID: roleID,
|
||||
}
|
||||
}
|
||||
30
src/modules/system/repository/sys_config.go
Normal file
30
src/modules/system/repository/sys_config.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysConfig 参数配置表 数据层接口
|
||||
type ISysConfig interface {
|
||||
// SelectDictDataPage 分页查询参数配置列表数据
|
||||
SelectConfigPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectConfigList 查询参数配置列表
|
||||
SelectConfigList(sysConfig model.SysConfig) []model.SysConfig
|
||||
|
||||
// SelectConfigValueByKey 通过参数键名查询参数键值
|
||||
SelectConfigValueByKey(configKey string) string
|
||||
|
||||
// SelectConfigByIds 通过配置ID查询参数配置信息
|
||||
SelectConfigByIds(configIds []string) []model.SysConfig
|
||||
|
||||
// CheckUniqueConfig 校验配置参数是否唯一
|
||||
CheckUniqueConfig(sysConfig model.SysConfig) string
|
||||
|
||||
// InsertConfig 新增参数配置
|
||||
InsertConfig(sysConfig model.SysConfig) string
|
||||
|
||||
// UpdateConfig 修改参数配置
|
||||
UpdateConfig(sysConfig model.SysConfig) int64
|
||||
|
||||
// DeleteConfigByIds 批量删除参数配置信息
|
||||
DeleteConfigByIds(configIds []string) int64
|
||||
}
|
||||
339
src/modules/system/repository/sys_config.impl.go
Normal file
339
src/modules/system/repository/sys_config.impl.go
Normal file
@@ -0,0 +1,339 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysConfigImpl 结构体
|
||||
var NewSysConfigImpl = &SysConfigImpl{
|
||||
selectSql: `select
|
||||
config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark
|
||||
from sys_config`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"config_id": "ConfigID",
|
||||
"config_name": "ConfigName",
|
||||
"config_key": "ConfigKey",
|
||||
"config_value": "ConfigValue",
|
||||
"config_type": "ConfigType",
|
||||
"remark": "Remark",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysConfigImpl 参数配置表 数据层处理
|
||||
type SysConfigImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysConfigImpl) convertResultRows(rows []map[string]any) []model.SysConfig {
|
||||
arr := make([]model.SysConfig, 0)
|
||||
for _, row := range rows {
|
||||
sysConfig := model.SysConfig{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysConfig, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysConfig)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectDictDataPage 分页查询参数配置列表数据
|
||||
func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["configName"]; ok && v != "" {
|
||||
conditions = append(conditions, "config_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["configType"]; ok && v != "" {
|
||||
conditions = append(conditions, "config_type = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["configKey"]; ok && v != "" {
|
||||
conditions = append(conditions, "config_key like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "create_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "create_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysConfig{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_config"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectConfigList 查询参数配置列表
|
||||
func (r *SysConfigImpl) SelectConfigList(sysConfig model.SysConfig) []model.SysConfig {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysConfig.ConfigName != "" {
|
||||
conditions = append(conditions, "config_name like concat(?, '%')")
|
||||
params = append(params, sysConfig.ConfigName)
|
||||
}
|
||||
if sysConfig.ConfigType != "" {
|
||||
conditions = append(conditions, "config_type = ?")
|
||||
params = append(params, sysConfig.ConfigType)
|
||||
}
|
||||
if sysConfig.ConfigKey != "" {
|
||||
conditions = append(conditions, "config_key like concat(?, '%')")
|
||||
params = append(params, sysConfig.ConfigKey)
|
||||
}
|
||||
if sysConfig.CreateTime > 0 {
|
||||
conditions = append(conditions, "create_time >= ?")
|
||||
params = append(params, sysConfig.CreateTime)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysConfig{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectConfigValueByKey 通过参数键名查询参数键值
|
||||
func (r *SysConfigImpl) SelectConfigValueByKey(configKey string) string {
|
||||
querySql := "select config_value as 'str' from sys_config where config_key = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{configKey})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectConfigByIds 通过配置ID查询参数配置信息
|
||||
func (r *SysConfigImpl) SelectConfigByIds(configIds []string) []model.SysConfig {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(configIds))
|
||||
querySql := r.selectSql + " where config_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(configIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysConfig{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// CheckUniqueConfig 校验配置参数是否唯一
|
||||
func (r *SysConfigImpl) CheckUniqueConfig(sysConfig model.SysConfig) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysConfig.ConfigKey != "" {
|
||||
conditions = append(conditions, "config_key = ?")
|
||||
params = append(params, sysConfig.ConfigKey)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select config_id as 'str' from sys_config " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InsertConfig 新增参数配置
|
||||
func (r *SysConfigImpl) InsertConfig(sysConfig model.SysConfig) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysConfig.ConfigName != "" {
|
||||
params["config_name"] = sysConfig.ConfigName
|
||||
}
|
||||
if sysConfig.ConfigKey != "" {
|
||||
params["config_key"] = sysConfig.ConfigKey
|
||||
}
|
||||
if sysConfig.ConfigValue != "" {
|
||||
params["config_value"] = sysConfig.ConfigValue
|
||||
}
|
||||
if sysConfig.ConfigType != "" {
|
||||
params["config_type"] = sysConfig.ConfigType
|
||||
}
|
||||
if sysConfig.Remark != "" {
|
||||
params["remark"] = sysConfig.Remark
|
||||
}
|
||||
if sysConfig.CreateBy != "" {
|
||||
params["create_by"] = sysConfig.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_config (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateConfig 修改参数配置
|
||||
func (r *SysConfigImpl) UpdateConfig(sysConfig model.SysConfig) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysConfig.ConfigName != "" {
|
||||
params["config_name"] = sysConfig.ConfigName
|
||||
}
|
||||
if sysConfig.ConfigKey != "" {
|
||||
params["config_key"] = sysConfig.ConfigKey
|
||||
}
|
||||
if sysConfig.ConfigValue != "" {
|
||||
params["config_value"] = sysConfig.ConfigValue
|
||||
}
|
||||
if sysConfig.ConfigType != "" {
|
||||
params["config_type"] = sysConfig.ConfigType
|
||||
}
|
||||
if sysConfig.Remark != "" {
|
||||
params["remark"] = sysConfig.Remark
|
||||
}
|
||||
if sysConfig.UpdateBy != "" {
|
||||
params["update_by"] = sysConfig.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_config set " + strings.Join(keys, ",") + " where config_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysConfig.ConfigID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteConfigByIds 批量删除参数配置信息
|
||||
func (r *SysConfigImpl) DeleteConfigByIds(configIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(configIds))
|
||||
sql := "delete from sys_config where config_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(configIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
42
src/modules/system/repository/sys_dept.go
Normal file
42
src/modules/system/repository/sys_dept.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysDept 部门表 数据层接口
|
||||
type ISysDept interface {
|
||||
// SelectDeptList 查询部门管理数据
|
||||
SelectDeptList(sysDept model.SysDept, dataScopeSQL string) []model.SysDept
|
||||
|
||||
// SelectDeptListByRoleId 根据角色ID查询部门树信息
|
||||
SelectDeptListByRoleId(roleId string, deptCheckStrictly bool) []string
|
||||
|
||||
// SelectDeptById 根据部门ID查询信息
|
||||
SelectDeptById(deptId string) model.SysDept
|
||||
|
||||
// SelectChildrenDeptById 根据ID查询所有子部门
|
||||
SelectChildrenDeptById(deptId string) []model.SysDept
|
||||
|
||||
// HasChildByDeptId 是否存在子节点
|
||||
HasChildByDeptId(deptId string) int64
|
||||
|
||||
// CheckDeptExistUser 查询部门是否存在用户
|
||||
CheckDeptExistUser(deptId string) int64
|
||||
|
||||
// CheckUniqueDept 校验部门是否唯一
|
||||
CheckUniqueDept(sysDept model.SysDept) string
|
||||
|
||||
// InsertDept 新增部门信息
|
||||
InsertDept(sysDept model.SysDept) string
|
||||
|
||||
// UpdateDept 修改部门信息
|
||||
UpdateDept(sysDept model.SysDept) int64
|
||||
|
||||
// UpdateDeptStatusNormal 修改所在部门正常状态
|
||||
UpdateDeptStatusNormal(deptIds []string) int64
|
||||
|
||||
// UpdateDeptChildren 修改子元素关系
|
||||
UpdateDeptChildren(sysDepts []model.SysDept) int64
|
||||
|
||||
// DeleteDeptById 删除部门管理信息
|
||||
DeleteDeptById(deptId string) int64
|
||||
}
|
||||
393
src/modules/system/repository/sys_dept.impl.go
Normal file
393
src/modules/system/repository/sys_dept.impl.go
Normal file
@@ -0,0 +1,393 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysDeptImpl 结构体
|
||||
var NewSysDeptImpl = &SysDeptImpl{
|
||||
selectSql: `select
|
||||
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
|
||||
from sys_dept d`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"dept_id": "DeptID",
|
||||
"parent_id": "ParentID",
|
||||
"ancestors": "Ancestors",
|
||||
"dept_name": "DeptName",
|
||||
"order_num": "OrderNum",
|
||||
"leader": "Leader",
|
||||
"phone": "Phone",
|
||||
"email": "Email",
|
||||
"status": "Status",
|
||||
"del_flag": "DelFlag",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"parent_name": "ParentName",
|
||||
},
|
||||
}
|
||||
|
||||
// SysDeptImpl 部门表 数据层处理
|
||||
type SysDeptImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysDeptImpl) convertResultRows(rows []map[string]any) []model.SysDept {
|
||||
arr := make([]model.SysDept, 0)
|
||||
for _, row := range rows {
|
||||
sysDept := model.SysDept{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysDept, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysDept)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectDeptList 查询部门管理数据
|
||||
func (r *SysDeptImpl) SelectDeptList(sysDept model.SysDept, dataScopeSQL string) []model.SysDept {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDept.DeptID != "" {
|
||||
conditions = append(conditions, "dept_id = ?")
|
||||
params = append(params, sysDept.DeptID)
|
||||
}
|
||||
if sysDept.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysDept.ParentID)
|
||||
}
|
||||
if sysDept.DeptName != "" {
|
||||
conditions = append(conditions, "dept_name like concat(?, '%')")
|
||||
params = append(params, sysDept.DeptName)
|
||||
}
|
||||
if sysDept.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysDept.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where d.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by d.parent_id, d.order_num asc "
|
||||
querySql := r.selectSql + whereSql + dataScopeSQL + orderSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDept{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectDeptListByRoleId 根据角色ID查询部门树信息
|
||||
func (r *SysDeptImpl) SelectDeptListByRoleId(roleId string, deptCheckStrictly bool) []string {
|
||||
querySql := `select d.dept_id as 'str' from sys_dept d
|
||||
left join sys_role_dept rd on d.dept_id = rd.dept_id
|
||||
where rd.role_id = ? `
|
||||
var params []any
|
||||
params = append(params, roleId)
|
||||
// 展开
|
||||
if deptCheckStrictly {
|
||||
querySql += ` and d.dept_id not in
|
||||
(select d.parent_id from sys_dept d
|
||||
inner join sys_role_dept rd on d.dept_id = rd.dept_id
|
||||
and rd.role_id = ?) `
|
||||
params = append(params, roleId)
|
||||
}
|
||||
querySql += "order by d.parent_id, d.order_num"
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, 0)
|
||||
for _, v := range results {
|
||||
ids = append(ids, fmt.Sprintf("%v", v["str"]))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectDeptById 根据部门ID查询信息
|
||||
func (r *SysDeptImpl) SelectDeptById(deptId string) model.SysDept {
|
||||
querySql := `select d.dept_id, d.parent_id, d.ancestors,
|
||||
d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status,
|
||||
(select dept_name from sys_dept where dept_id = d.parent_id) parent_name
|
||||
from sys_dept d where d.dept_id = ?`
|
||||
results, err := datasource.RawDB("", querySql, []any{deptId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysDept{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysDept{}
|
||||
}
|
||||
|
||||
// SelectChildrenDeptById 根据ID查询所有子部门
|
||||
func (r *SysDeptImpl) SelectChildrenDeptById(deptId string) []model.SysDept {
|
||||
querySql := r.selectSql + " where find_in_set(?, d.ancestors)"
|
||||
results, err := datasource.RawDB("", querySql, []any{deptId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDept{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// HasChildByDeptId 是否存在子节点
|
||||
func (r *SysDeptImpl) HasChildByDeptId(deptId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_dept where status = '1' and parent_id = ? limit 1"
|
||||
results, err := datasource.RawDB("", querySql, []any{deptId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckDeptExistUser 查询部门是否存在用户
|
||||
func (r *SysDeptImpl) CheckDeptExistUser(deptId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_user where dept_id = ? and del_flag = '0'"
|
||||
results, err := datasource.RawDB("", querySql, []any{deptId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckUniqueDept 校验部门是否唯一
|
||||
func (r *SysDeptImpl) CheckUniqueDept(sysDept model.SysDept) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDept.DeptName != "" {
|
||||
conditions = append(conditions, "dept_name = ?")
|
||||
params = append(params, sysDept.DeptName)
|
||||
}
|
||||
if sysDept.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysDept.ParentID)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
if whereSql == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select dept_id as 'str' from sys_dept " + whereSql + " and del_flag = '0' limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InsertDept 新增部门信息
|
||||
func (r *SysDeptImpl) InsertDept(sysDept model.SysDept) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDept.DeptID != "" {
|
||||
params["dept_id"] = sysDept.DeptID
|
||||
}
|
||||
if sysDept.ParentID != "" {
|
||||
params["parent_id"] = sysDept.ParentID
|
||||
}
|
||||
if sysDept.DeptName != "" {
|
||||
params["dept_name"] = sysDept.DeptName
|
||||
}
|
||||
if sysDept.Ancestors != "" {
|
||||
params["ancestors"] = sysDept.Ancestors
|
||||
}
|
||||
if sysDept.OrderNum > 0 {
|
||||
params["order_num"] = sysDept.OrderNum
|
||||
}
|
||||
if sysDept.Leader != "" {
|
||||
params["leader"] = sysDept.Leader
|
||||
}
|
||||
if sysDept.Phone != "" {
|
||||
params["phone"] = sysDept.Phone
|
||||
}
|
||||
if sysDept.Email != "" {
|
||||
params["email"] = sysDept.Email
|
||||
}
|
||||
if sysDept.Status != "" {
|
||||
params["status"] = sysDept.Status
|
||||
}
|
||||
if sysDept.CreateBy != "" {
|
||||
params["create_by"] = sysDept.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_dept (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateDept 修改部门信息
|
||||
func (r *SysDeptImpl) UpdateDept(sysDept model.SysDept) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDept.ParentID != "" {
|
||||
params["parent_id"] = sysDept.ParentID
|
||||
}
|
||||
if sysDept.DeptName != "" {
|
||||
params["dept_name"] = sysDept.DeptName
|
||||
}
|
||||
if sysDept.Ancestors != "" {
|
||||
params["ancestors"] = sysDept.Ancestors
|
||||
}
|
||||
if sysDept.OrderNum > 0 {
|
||||
params["order_num"] = sysDept.OrderNum
|
||||
}
|
||||
if sysDept.Leader != "" {
|
||||
params["leader"] = sysDept.Leader
|
||||
}
|
||||
if sysDept.Phone != "" {
|
||||
params["phone"] = sysDept.Phone
|
||||
}
|
||||
if sysDept.Email != "" {
|
||||
params["email"] = sysDept.Email
|
||||
}
|
||||
if sysDept.Status != "" {
|
||||
params["status"] = sysDept.Status
|
||||
}
|
||||
if sysDept.UpdateBy != "" {
|
||||
params["update_by"] = sysDept.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_dept set " + strings.Join(keys, ",") + " where dept_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysDept.DeptID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// UpdateDeptStatusNormal 修改所在部门正常状态
|
||||
func (r *SysDeptImpl) UpdateDeptStatusNormal(deptIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(deptIds))
|
||||
sql := "update sys_dept set status = '1' where dept_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(deptIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("update err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// UpdateDeptChildren 修改子元素关系
|
||||
func (r *SysDeptImpl) UpdateDeptChildren(sysDepts []model.SysDept) int64 {
|
||||
// 无参数
|
||||
if len(sysDepts) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// 更新条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
for _, dept := range sysDepts {
|
||||
caseSql := fmt.Sprintf("WHEN dept_id = '%s' THEN '%s'", dept.DeptID, dept.Ancestors)
|
||||
conditions = append(conditions, caseSql)
|
||||
params = append(params, dept.DeptID)
|
||||
}
|
||||
|
||||
cases := strings.Join(conditions, " ")
|
||||
placeholders := repo.KeyPlaceholderByQuery(len(params))
|
||||
sql := "update sys_dept set ancestors = CASE " + cases + " END where dept_id in (" + placeholders + ")"
|
||||
results, err := datasource.ExecDB("", sql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteDeptById 删除部门管理信息
|
||||
func (r *SysDeptImpl) DeleteDeptById(deptId string) int64 {
|
||||
sql := "update sys_dept set status = '0', del_flag = '1' where dept_id = ?"
|
||||
results, err := datasource.ExecDB("", sql, []any{deptId})
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
33
src/modules/system/repository/sys_dict_data.go
Normal file
33
src/modules/system/repository/sys_dict_data.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysDictData 字典类型数据表 数据层接口
|
||||
type ISysDictData interface {
|
||||
// SelectDictDataPage 根据条件分页查询字典数据
|
||||
SelectDictDataPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectDictDataList 根据条件查询字典数据
|
||||
SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData
|
||||
|
||||
// SelectDictDataByCodes 根据字典数据编码查询信息
|
||||
SelectDictDataByCodes(dictCodes []string) []model.SysDictData
|
||||
|
||||
// CountDictDataByType 查询字典数据
|
||||
CountDictDataByType(dictType string) int64
|
||||
|
||||
// CheckUniqueDictData 校验字典数据是否唯一
|
||||
CheckUniqueDictData(sysDictData model.SysDictData) string
|
||||
|
||||
// DeleteDictDataByCodes 批量删除字典数据信息
|
||||
DeleteDictDataByCodes(dictCodes []string) int64
|
||||
|
||||
// InsertDictData 新增字典数据信息
|
||||
InsertDictData(sysDictData model.SysDictData) string
|
||||
|
||||
// UpdateDictData 修改字典数据信息
|
||||
UpdateDictData(sysDictData model.SysDictData) int64
|
||||
|
||||
// UpdateDictDataType 同步修改字典类型
|
||||
UpdateDictDataType(oldDictType string, newDictType string) int64
|
||||
}
|
||||
368
src/modules/system/repository/sys_dict_data.impl.go
Normal file
368
src/modules/system/repository/sys_dict_data.impl.go
Normal file
@@ -0,0 +1,368 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysDictDataImpl 结构体
|
||||
var NewSysDictDataImpl = &SysDictDataImpl{
|
||||
selectSql: `select
|
||||
dict_code, dict_sort, dict_label, dict_value, dict_type, tag_class, tag_type, status, create_by, create_time, remark
|
||||
from sys_dict_data`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"dict_code": "DictCode",
|
||||
"dict_sort": "DictSort",
|
||||
"dict_label": "DictLabel",
|
||||
"dict_value": "DictValue",
|
||||
"dict_type": "DictType",
|
||||
"tag_class": "TagClass",
|
||||
"tag_type": "TagType",
|
||||
"status": "Status",
|
||||
"remark": "Remark",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysDictDataImpl 字典类型数据表 数据层处理
|
||||
type SysDictDataImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysDictDataImpl) convertResultRows(rows []map[string]any) []model.SysDictData {
|
||||
arr := make([]model.SysDictData, 0)
|
||||
for _, row := range rows {
|
||||
sysDictData := model.SysDictData{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysDictData, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysDictData)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectDictDataPage 根据条件分页查询字典数据
|
||||
func (r *SysDictDataImpl) SelectDictDataPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["dictType"]; ok && v != "" {
|
||||
conditions = append(conditions, "dict_type = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["dictLabel"]; ok && v != "" {
|
||||
conditions = append(conditions, "dict_label like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysDictData{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_dict_data"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by dict_sort asc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectDictDataList 根据条件查询字典数据
|
||||
func (r *SysDictDataImpl) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDictData.DictLabel != "" {
|
||||
conditions = append(conditions, "dict_label like concat(?, '%')")
|
||||
params = append(params, sysDictData.DictLabel)
|
||||
}
|
||||
if sysDictData.DictType != "" {
|
||||
conditions = append(conditions, "dict_type = ?")
|
||||
params = append(params, sysDictData.DictType)
|
||||
}
|
||||
if sysDictData.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysDictData.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by dict_sort asc "
|
||||
querySql := r.selectSql + whereSql + orderSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDictData{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectDictDataByCodes 根据字典数据编码查询信息
|
||||
func (r *SysDictDataImpl) SelectDictDataByCodes(dictCodes []string) []model.SysDictData {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(dictCodes))
|
||||
querySql := r.selectSql + " where dict_code in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(dictCodes)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDictData{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// CountDictDataByType 查询字典数据
|
||||
func (r *SysDictDataImpl) CountDictDataByType(dictType string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_dict_data where dict_type = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{dictType})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckUniqueDictData 校验字典数据是否唯一
|
||||
func (r *SysDictDataImpl) CheckUniqueDictData(sysDictData model.SysDictData) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDictData.DictType != "" {
|
||||
conditions = append(conditions, "dict_type = ?")
|
||||
params = append(params, sysDictData.DictType)
|
||||
}
|
||||
if sysDictData.DictLabel != "" {
|
||||
conditions = append(conditions, "dict_label = ?")
|
||||
params = append(params, sysDictData.DictLabel)
|
||||
}
|
||||
if sysDictData.DictValue != "" {
|
||||
conditions = append(conditions, "dict_value = ?")
|
||||
params = append(params, sysDictData.DictValue)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select dict_code as 'str' from sys_dict_data " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeleteDictDataByCodes 批量删除字典数据信息
|
||||
func (r *SysDictDataImpl) DeleteDictDataByCodes(dictCodes []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(dictCodes))
|
||||
sql := "delete from sys_dict_data where dict_code in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(dictCodes)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// InsertDictData 新增字典数据信息
|
||||
func (r *SysDictDataImpl) InsertDictData(sysDictData model.SysDictData) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDictData.DictSort > 0 {
|
||||
params["dict_sort"] = sysDictData.DictSort
|
||||
}
|
||||
if sysDictData.DictLabel != "" {
|
||||
params["dict_label"] = sysDictData.DictLabel
|
||||
}
|
||||
if sysDictData.DictValue != "" {
|
||||
params["dict_value"] = sysDictData.DictValue
|
||||
}
|
||||
if sysDictData.DictType != "" {
|
||||
params["dict_type"] = sysDictData.DictType
|
||||
}
|
||||
if sysDictData.TagClass != "" {
|
||||
params["tag_class"] = sysDictData.TagClass
|
||||
}
|
||||
if sysDictData.TagType != "" {
|
||||
params["tag_type"] = sysDictData.TagType
|
||||
}
|
||||
if sysDictData.Status != "" {
|
||||
params["status"] = sysDictData.Status
|
||||
}
|
||||
if sysDictData.Remark != "" {
|
||||
params["remark"] = sysDictData.Remark
|
||||
}
|
||||
if sysDictData.CreateBy != "" {
|
||||
params["create_by"] = sysDictData.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_dict_data (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateDictData 修改字典数据信息
|
||||
func (r *SysDictDataImpl) UpdateDictData(sysDictData model.SysDictData) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDictData.DictSort > 0 {
|
||||
params["dict_sort"] = sysDictData.DictSort
|
||||
}
|
||||
if sysDictData.DictLabel != "" {
|
||||
params["dict_label"] = sysDictData.DictLabel
|
||||
}
|
||||
if sysDictData.DictValue != "" {
|
||||
params["dict_value"] = sysDictData.DictValue
|
||||
}
|
||||
if sysDictData.DictType != "" {
|
||||
params["dict_type"] = sysDictData.DictType
|
||||
}
|
||||
if sysDictData.TagClass != "" {
|
||||
params["tag_class"] = sysDictData.TagClass
|
||||
}
|
||||
if sysDictData.TagType != "" {
|
||||
params["tag_type"] = sysDictData.TagType
|
||||
}
|
||||
if sysDictData.Status != "" {
|
||||
params["status"] = sysDictData.Status
|
||||
}
|
||||
if sysDictData.Remark != "" {
|
||||
params["remark"] = sysDictData.Remark
|
||||
}
|
||||
if sysDictData.UpdateBy != "" {
|
||||
params["update_by"] = sysDictData.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_dict_data set " + strings.Join(keys, ",") + " where dict_code = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysDictData.DictCode)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// UpdateDictDataType 同步修改字典类型
|
||||
func (r *SysDictDataImpl) UpdateDictDataType(oldDictType string, newDictType string) int64 {
|
||||
// 参数拼接
|
||||
params := make([]any, 0)
|
||||
if oldDictType == "" || newDictType == "" {
|
||||
return 0
|
||||
}
|
||||
params = append(params, newDictType)
|
||||
params = append(params, oldDictType)
|
||||
|
||||
// 构建执行语句
|
||||
sql := "update sys_dict_data set dict_type = ? where dict_type = ?"
|
||||
|
||||
// 执行更新
|
||||
rows, err := datasource.ExecDB("", sql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
30
src/modules/system/repository/sys_dict_type.go
Normal file
30
src/modules/system/repository/sys_dict_type.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysDictType 字典类型表 数据层接口
|
||||
type ISysDictType interface {
|
||||
// SelectDictTypePage 根据条件分页查询字典类型
|
||||
SelectDictTypePage(query map[string]any) map[string]any
|
||||
|
||||
// SelectDictTypeList 根据条件查询字典类型
|
||||
SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType
|
||||
|
||||
// SelectDictTypeByIDs 根据字典类型ID查询信息
|
||||
SelectDictTypeByIDs(dictIDs []string) []model.SysDictType
|
||||
|
||||
// SelectDictTypeByType 根据字典类型查询信息
|
||||
SelectDictTypeByType(dictType string) model.SysDictType
|
||||
|
||||
// CheckUniqueDictType 校验字典类型是否唯一
|
||||
CheckUniqueDictType(sysDictType model.SysDictType) string
|
||||
|
||||
// InsertDictType 新增字典类型信息
|
||||
InsertDictType(sysDictType model.SysDictType) string
|
||||
|
||||
// UpdateDictType 修改字典类型信息
|
||||
UpdateDictType(sysDictType model.SysDictType) int64
|
||||
|
||||
// DeleteDictTypeByIDs 批量删除字典类型信息
|
||||
DeleteDictTypeByIDs(dictIDs []string) int64
|
||||
}
|
||||
334
src/modules/system/repository/sys_dict_type.impl.go
Normal file
334
src/modules/system/repository/sys_dict_type.impl.go
Normal file
@@ -0,0 +1,334 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysDictTypeImpl 结构体
|
||||
var NewSysDictTypeImpl = &SysDictTypeImpl{
|
||||
selectSql: `select
|
||||
dict_id, dict_name, dict_type, status, create_by, create_time, remark
|
||||
from sys_dict_type`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"dict_id": "DictID",
|
||||
"dict_name": "DictName",
|
||||
"dict_type": "DictType",
|
||||
"remark": "Remark",
|
||||
"status": "Status",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysDictTypeImpl 字典类型表 数据层处理
|
||||
type SysDictTypeImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysDictTypeImpl) convertResultRows(rows []map[string]any) []model.SysDictType {
|
||||
arr := make([]model.SysDictType, 0)
|
||||
for _, row := range rows {
|
||||
sysDictType := model.SysDictType{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysDictType, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysDictType)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectDictTypePage 根据条件分页查询字典类型
|
||||
func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["dictName"]; ok && v != "" {
|
||||
conditions = append(conditions, "dict_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["dictType"]; ok && v != "" {
|
||||
conditions = append(conditions, "dict_type like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "create_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "create_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysDictType{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_dict_type"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectDictTypeList 根据条件查询字典类型
|
||||
func (r *SysDictTypeImpl) SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDictType.DictName != "" {
|
||||
conditions = append(conditions, "dict_name like concat(?, '%')")
|
||||
params = append(params, sysDictType.DictName)
|
||||
}
|
||||
if sysDictType.DictType != "" {
|
||||
conditions = append(conditions, "dict_type like concat(?, '%')")
|
||||
params = append(params, sysDictType.DictType)
|
||||
}
|
||||
if sysDictType.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysDictType.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDictType{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectDictTypeByIDs 根据字典类型ID查询信息
|
||||
func (r *SysDictTypeImpl) SelectDictTypeByIDs(dictIDs []string) []model.SysDictType {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(dictIDs))
|
||||
querySql := r.selectSql + " where dict_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(dictIDs)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysDictType{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectDictTypeByType 根据字典类型查询信息
|
||||
func (r *SysDictTypeImpl) SelectDictTypeByType(dictType string) model.SysDictType {
|
||||
querySql := r.selectSql + " where dict_type = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{dictType})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysDictType{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysDictType{}
|
||||
}
|
||||
|
||||
// CheckUniqueDictType 校验字典是否唯一
|
||||
func (r *SysDictTypeImpl) CheckUniqueDictType(sysDictType model.SysDictType) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysDictType.DictName != "" {
|
||||
conditions = append(conditions, "dict_name = ?")
|
||||
params = append(params, sysDictType.DictName)
|
||||
}
|
||||
if sysDictType.DictType != "" {
|
||||
conditions = append(conditions, "dict_type = ?")
|
||||
params = append(params, sysDictType.DictType)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select dict_id as 'str' from sys_dict_type " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InsertDictType 新增字典类型信息
|
||||
func (r *SysDictTypeImpl) InsertDictType(sysDictType model.SysDictType) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDictType.DictName != "" {
|
||||
params["dict_name"] = sysDictType.DictName
|
||||
}
|
||||
if sysDictType.DictType != "" {
|
||||
params["dict_type"] = sysDictType.DictType
|
||||
}
|
||||
if sysDictType.Status != "" {
|
||||
params["status"] = sysDictType.Status
|
||||
}
|
||||
if sysDictType.Remark != "" {
|
||||
params["remark"] = sysDictType.Remark
|
||||
}
|
||||
if sysDictType.CreateBy != "" {
|
||||
params["create_by"] = sysDictType.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_dict_type (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateDictType 修改字典类型信息
|
||||
func (r *SysDictTypeImpl) UpdateDictType(sysDictType model.SysDictType) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysDictType.DictName != "" {
|
||||
params["dict_name"] = sysDictType.DictName
|
||||
}
|
||||
if sysDictType.DictType != "" {
|
||||
params["dict_type"] = sysDictType.DictType
|
||||
}
|
||||
if sysDictType.Status != "" {
|
||||
params["status"] = sysDictType.Status
|
||||
}
|
||||
if sysDictType.Remark != "" {
|
||||
params["remark"] = sysDictType.Remark
|
||||
}
|
||||
if sysDictType.UpdateBy != "" {
|
||||
params["update_by"] = sysDictType.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_dict_type set " + strings.Join(keys, ",") + " where dict_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysDictType.DictID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteDictTypeByIDs 批量删除字典类型信息
|
||||
func (r *SysDictTypeImpl) DeleteDictTypeByIDs(dictIDs []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(dictIDs))
|
||||
sql := "delete from sys_dict_type where dict_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(dictIDs)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
21
src/modules/system/repository/sys_log_login.go
Normal file
21
src/modules/system/repository/sys_log_login.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysLogLogin 系统登录日志表 数据层接口
|
||||
type ISysLogLogin interface {
|
||||
// SelectSysLogLoginPage 分页查询系统登录日志集合
|
||||
SelectSysLogLoginPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectSysLogLoginList 查询系统登录日志集合
|
||||
SelectSysLogLoginList(sysLogLogin model.SysLogLogin) []model.SysLogLogin
|
||||
|
||||
// InsertSysLogLogin 新增系统登录日志
|
||||
InsertSysLogLogin(sysLogLogin model.SysLogLogin) string
|
||||
|
||||
// DeleteSysLogLoginByIds 批量删除系统登录日志
|
||||
DeleteSysLogLoginByIds(loginIds []string) int64
|
||||
|
||||
// CleanSysLogLogin 清空系统登录日志
|
||||
CleanSysLogLogin() error
|
||||
}
|
||||
245
src/modules/system/repository/sys_log_login.impl.go
Normal file
245
src/modules/system/repository/sys_log_login.impl.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysLogLoginImpl 结构体
|
||||
var NewSysLogLoginImpl = &SysLogLoginImpl{
|
||||
selectSql: `select login_id, user_name, ipaddr, login_location,
|
||||
browser, os, status, msg, login_time from sys_log_login`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"login_id": "LoginID",
|
||||
"user_name": "UserName",
|
||||
"status": "Status",
|
||||
"ipaddr": "IPAddr",
|
||||
"login_location": "LoginLocation",
|
||||
"browser": "Browser",
|
||||
"os": "OS",
|
||||
"msg": "Msg",
|
||||
"login_time": "LoginTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysLogLoginImpl 系统登录访问表 数据层处理
|
||||
type SysLogLoginImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysLogLoginImpl) convertResultRows(rows []map[string]any) []model.SysLogLogin {
|
||||
arr := make([]model.SysLogLogin, 0)
|
||||
for _, row := range rows {
|
||||
SysLogLogin := model.SysLogLogin{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&SysLogLogin, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, SysLogLogin)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectSysLogLoginPage 分页查询系统登录日志集合
|
||||
func (r *SysLogLoginImpl) SelectSysLogLoginPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["ipaddr"]; ok && v != "" {
|
||||
conditions = append(conditions, "ipaddr like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["userName"]; ok && v != "" {
|
||||
conditions = append(conditions, "user_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "login_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "login_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysLogLogin{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_log_login"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by login_id desc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectSysLogLoginList 查询系统登录日志集合
|
||||
func (r *SysLogLoginImpl) SelectSysLogLoginList(SysLogLogin model.SysLogLogin) []model.SysLogLogin {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if SysLogLogin.IPAddr != "" {
|
||||
conditions = append(conditions, "title like concat(?, '%')")
|
||||
params = append(params, SysLogLogin.IPAddr)
|
||||
}
|
||||
if SysLogLogin.UserName != "" {
|
||||
conditions = append(conditions, "user_name like concat(?, '%')")
|
||||
params = append(params, SysLogLogin.UserName)
|
||||
}
|
||||
if SysLogLogin.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, SysLogLogin.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysLogLogin{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// InsertSysLogLogin 新增系统登录日志
|
||||
func (r *SysLogLoginImpl) InsertSysLogLogin(SysLogLogin model.SysLogLogin) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
params["login_time"] = time.Now().UnixMilli()
|
||||
if SysLogLogin.UserName != "" {
|
||||
params["user_name"] = SysLogLogin.UserName
|
||||
}
|
||||
if SysLogLogin.Status != "" {
|
||||
params["status"] = SysLogLogin.Status
|
||||
}
|
||||
if SysLogLogin.IPAddr != "" {
|
||||
params["ipaddr"] = SysLogLogin.IPAddr
|
||||
}
|
||||
if SysLogLogin.LoginLocation != "" {
|
||||
params["login_location"] = SysLogLogin.LoginLocation
|
||||
}
|
||||
if SysLogLogin.Browser != "" {
|
||||
params["browser"] = SysLogLogin.Browser
|
||||
}
|
||||
if SysLogLogin.OS != "" {
|
||||
params["os"] = SysLogLogin.OS
|
||||
}
|
||||
if SysLogLogin.Msg != "" {
|
||||
params["msg"] = SysLogLogin.Msg
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_log_login (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// DeleteSysLogLoginByIds 批量删除系统登录日志
|
||||
func (r *SysLogLoginImpl) DeleteSysLogLoginByIds(loginIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(loginIds))
|
||||
sql := "delete from sys_log_login where login_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(loginIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CleanSysLogLogin 清空系统登录日志
|
||||
func (r *SysLogLoginImpl) CleanSysLogLogin() error {
|
||||
sql := "truncate table sys_log_login"
|
||||
_, err := datasource.ExecDB("", sql, []any{})
|
||||
return err
|
||||
}
|
||||
24
src/modules/system/repository/sys_log_operate.go
Normal file
24
src/modules/system/repository/sys_log_operate.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysLogOperate 操作日志表 数据层接口
|
||||
type ISysLogOperate interface {
|
||||
// SelectSysLogOperatePage 分页查询系统操作日志集合
|
||||
SelectSysLogOperatePage(query map[string]any) map[string]any
|
||||
|
||||
// SelectSysLogOperateList 查询系统操作日志集合
|
||||
SelectSysLogOperateList(sysLogOperate model.SysLogOperate) []model.SysLogOperate
|
||||
|
||||
// SelectSysLogOperateById 查询操作日志详细
|
||||
SelectSysLogOperateById(operId string) model.SysLogOperate
|
||||
|
||||
// InsertSysLogOperate 新增操作日志
|
||||
InsertSysLogOperate(sysLogOperate model.SysLogOperate) string
|
||||
|
||||
// DeleteSysLogOperateByIds 批量删除系统操作日志
|
||||
DeleteSysLogOperateByIds(operIds []string) int64
|
||||
|
||||
// CleanSysLogOperate 清空操作日志
|
||||
CleanSysLogOperate() error
|
||||
}
|
||||
299
src/modules/system/repository/sys_log_operate.impl.go
Normal file
299
src/modules/system/repository/sys_log_operate.impl.go
Normal file
@@ -0,0 +1,299 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysLogOperateImpl 结构体
|
||||
var NewSysLogOperateImpl = &SysLogOperateImpl{
|
||||
selectSql: `select
|
||||
oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name,
|
||||
oper_url, oper_ip, oper_location, oper_param, oper_msg, status, oper_time, cost_time
|
||||
from sys_log_operate`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"oper_id": "OperID",
|
||||
"title": "Title",
|
||||
"business_type": "BusinessType",
|
||||
"method": "Method",
|
||||
"request_method": "RequestMethod",
|
||||
"operator_type": "OperatorType",
|
||||
"oper_name": "OperName",
|
||||
"dept_name": "DeptName",
|
||||
"oper_url": "OperURL",
|
||||
"oper_ip": "OperIP",
|
||||
"oper_location": "OperLocation",
|
||||
"oper_param": "OperParam",
|
||||
"oper_msg": "OperMsg",
|
||||
"status": "Status",
|
||||
"oper_time": "OperTime",
|
||||
"cost_time": "CostTime",
|
||||
},
|
||||
}
|
||||
|
||||
// SysLogOperateImpl 操作日志表 数据层处理
|
||||
type SysLogOperateImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysLogOperateImpl) convertResultRows(rows []map[string]any) []model.SysLogOperate {
|
||||
arr := make([]model.SysLogOperate, 0)
|
||||
for _, row := range rows {
|
||||
SysLogOperate := model.SysLogOperate{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&SysLogOperate, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, SysLogOperate)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectSysLogOperatePage 分页查询系统操作日志集合
|
||||
func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["title"]; ok && v != "" {
|
||||
conditions = append(conditions, "title like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["businessType"]; ok && v != "" {
|
||||
conditions = append(conditions, "business_type = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["operName"]; ok && v != "" {
|
||||
conditions = append(conditions, "oper_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "oper_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "oper_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysLogOperate{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_log_operate"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by oper_id desc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectSysLogOperateList 查询系统操作日志集合
|
||||
func (r *SysLogOperateImpl) SelectSysLogOperateList(SysLogOperate model.SysLogOperate) []model.SysLogOperate {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if SysLogOperate.Title != "" {
|
||||
conditions = append(conditions, "title like concat(?, '%')")
|
||||
params = append(params, SysLogOperate.Title)
|
||||
}
|
||||
if SysLogOperate.BusinessType != "" {
|
||||
conditions = append(conditions, "business_type = ?")
|
||||
params = append(params, SysLogOperate.BusinessType)
|
||||
}
|
||||
if SysLogOperate.OperName != "" {
|
||||
conditions = append(conditions, "oper_name like concat(?, '%')")
|
||||
params = append(params, SysLogOperate.OperName)
|
||||
}
|
||||
if SysLogOperate.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, SysLogOperate.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysLogOperate{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectSysLogOperateById 查询操作日志详细
|
||||
func (r *SysLogOperateImpl) SelectSysLogOperateById(operId string) model.SysLogOperate {
|
||||
querySql := r.selectSql + " where oper_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{operId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysLogOperate{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysLogOperate{}
|
||||
}
|
||||
|
||||
// InsertSysLogOperate 新增操作日志
|
||||
func (r *SysLogOperateImpl) InsertSysLogOperate(SysLogOperate model.SysLogOperate) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
params["oper_time"] = time.Now().UnixMilli()
|
||||
if SysLogOperate.Title != "" {
|
||||
params["title"] = SysLogOperate.Title
|
||||
}
|
||||
if SysLogOperate.BusinessType != "" {
|
||||
params["business_type"] = SysLogOperate.BusinessType
|
||||
}
|
||||
if SysLogOperate.Method != "" {
|
||||
params["method"] = SysLogOperate.Method
|
||||
}
|
||||
if SysLogOperate.RequestMethod != "" {
|
||||
params["request_method"] = SysLogOperate.RequestMethod
|
||||
}
|
||||
if SysLogOperate.OperatorType != "" {
|
||||
params["operator_type"] = SysLogOperate.OperatorType
|
||||
}
|
||||
if SysLogOperate.DeptName != "" {
|
||||
params["dept_name"] = SysLogOperate.DeptName
|
||||
}
|
||||
if SysLogOperate.OperName != "" {
|
||||
params["oper_name"] = SysLogOperate.OperName
|
||||
}
|
||||
if SysLogOperate.OperURL != "" {
|
||||
params["oper_url"] = SysLogOperate.OperURL
|
||||
}
|
||||
if SysLogOperate.OperIP != "" {
|
||||
params["oper_ip"] = SysLogOperate.OperIP
|
||||
}
|
||||
if SysLogOperate.OperLocation != "" {
|
||||
params["oper_location"] = SysLogOperate.OperLocation
|
||||
}
|
||||
if SysLogOperate.OperParam != "" {
|
||||
params["oper_param"] = SysLogOperate.OperParam
|
||||
}
|
||||
if SysLogOperate.OperMsg != "" {
|
||||
params["oper_msg"] = SysLogOperate.OperMsg
|
||||
}
|
||||
if SysLogOperate.Status != "" {
|
||||
params["status"] = SysLogOperate.Status
|
||||
}
|
||||
if SysLogOperate.CostTime > 0 {
|
||||
params["cost_time"] = SysLogOperate.CostTime
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_log_operate (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// DeleteSysLogOperateByIds 批量删除系统操作日志
|
||||
func (r *SysLogOperateImpl) DeleteSysLogOperateByIds(operIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(operIds))
|
||||
sql := "delete from sys_log_operate where oper_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(operIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CleanSysLogOperate 清空操作日志
|
||||
func (r *SysLogOperateImpl) CleanSysLogOperate() error {
|
||||
sql := "truncate table sys_log_operate"
|
||||
_, err := datasource.ExecDB("", sql, []any{})
|
||||
return err
|
||||
}
|
||||
36
src/modules/system/repository/sys_menu.go
Normal file
36
src/modules/system/repository/sys_menu.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysMenu 菜单表 数据层接口
|
||||
type ISysMenu interface {
|
||||
// SelectMenuList 查询系统菜单列表
|
||||
SelectMenuList(sysMenu model.SysMenu, userId string) []model.SysMenu
|
||||
|
||||
// SelectMenuPermsByUserId 根据用户ID查询权限
|
||||
SelectMenuPermsByUserId(userId string) []string
|
||||
|
||||
// SelectMenuTreeByUserId 根据用户ID查询菜单
|
||||
SelectMenuTreeByUserId(userId string) []model.SysMenu
|
||||
|
||||
// SelectMenuListByRoleId 根据角色ID查询菜单树信息
|
||||
SelectMenuListByRoleId(roleId string, menuCheckStrictly bool) []string
|
||||
|
||||
// SelectMenuByIds 根据菜单ID查询信息
|
||||
SelectMenuByIds(menuIds []string) []model.SysMenu
|
||||
|
||||
// HasChildByMenuIdAndStatus 存在菜单子节点数量与状态
|
||||
HasChildByMenuIdAndStatus(menuId, status string) int64
|
||||
|
||||
// InsertMenu 新增菜单信息
|
||||
InsertMenu(sysMenu model.SysMenu) string
|
||||
|
||||
// UpdateMenu 修改菜单信息
|
||||
UpdateMenu(sysMenu model.SysMenu) int64
|
||||
|
||||
// DeleteMenuById 删除菜单管理信息
|
||||
DeleteMenuById(menuId string) int64
|
||||
|
||||
// CheckUniqueMenu 校验菜单是否唯一
|
||||
CheckUniqueMenu(sysMenu model.SysMenu) string
|
||||
}
|
||||
476
src/modules/system/repository/sys_menu.impl.go
Normal file
476
src/modules/system/repository/sys_menu.impl.go
Normal file
@@ -0,0 +1,476 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/constants/menu"
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysMenuImpl 结构体
|
||||
var NewSysMenuImpl = &SysMenuImpl{
|
||||
selectSql: `select
|
||||
m.menu_id, m.menu_name, m.parent_id, m.menu_sort, m.path, m.component, m.is_frame, m.is_cache, m.menu_type, m.visible, m.status, ifnull(m.perms,'') as perms, m.icon, m.create_time, m.remark
|
||||
from sys_menu m`,
|
||||
|
||||
selectSqlByUser: `select distinct
|
||||
m.menu_id, m.menu_name, m.parent_id, m.menu_sort, m.path, m.component, m.is_frame, m.is_cache, m.menu_type, m.visible, m.status, ifnull(m.perms,'') as perms, m.icon, m.create_time, m.remark
|
||||
from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||
left join sys_role ro on ur.role_id = ro.role_id`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"menu_id": "MenuID",
|
||||
"menu_name": "MenuName",
|
||||
"parent_name": "ParentName",
|
||||
"parent_id": "ParentID",
|
||||
"path": "Path",
|
||||
"menu_sort": "MenuSort",
|
||||
"component": "Component",
|
||||
"is_frame": "IsFrame",
|
||||
"is_cache": "IsCache",
|
||||
"menu_type": "MenuType",
|
||||
"visible": "Visible",
|
||||
"status": "Status",
|
||||
"perms": "Perms",
|
||||
"icon": "Icon",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// SysMenuImpl 菜单表 数据层处理
|
||||
type SysMenuImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 查询视图用户对象SQL
|
||||
selectSqlByUser string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysMenuImpl) convertResultRows(rows []map[string]any) []model.SysMenu {
|
||||
arr := make([]model.SysMenu, 0)
|
||||
for _, row := range rows {
|
||||
sysMenu := model.SysMenu{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysMenu, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysMenu)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectMenuList 查询系统菜单列表
|
||||
func (r *SysMenuImpl) SelectMenuList(sysMenu model.SysMenu, userId string) []model.SysMenu {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysMenu.MenuName != "" {
|
||||
conditions = append(conditions, "m.menu_name like concat(?, '%')")
|
||||
params = append(params, sysMenu.MenuName)
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
conditions = append(conditions, "m.visible = ?")
|
||||
params = append(params, sysMenu.Visible)
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
conditions = append(conditions, "m.status = ?")
|
||||
params = append(params, sysMenu.Status)
|
||||
}
|
||||
|
||||
fromSql := r.selectSql
|
||||
|
||||
// 个人菜单
|
||||
if userId != "*" {
|
||||
fromSql = r.selectSqlByUser
|
||||
conditions = append(conditions, "ur.user_id = ?")
|
||||
params = append(params, userId)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by m.parent_id, m.menu_sort"
|
||||
querySql := fromSql + whereSql + orderSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectMenuPermsByUserId 根据用户ID查询权限
|
||||
func (r *SysMenuImpl) SelectMenuPermsByUserId(userId string) []string {
|
||||
querySql := `select distinct m.perms as 'str' from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||
left join sys_role r on r.role_id = ur.role_id
|
||||
where m.status = '1' and m.perms != '' and r.status = '1' and ur.user_id = ? `
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, []any{userId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// 读取结果
|
||||
rows := make([]string, 0)
|
||||
for _, m := range results {
|
||||
rows = append(rows, fmt.Sprintf("%v", m["str"]))
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// SelectMenuTreeByUserId 根据用户ID查询菜单
|
||||
func (r *SysMenuImpl) SelectMenuTreeByUserId(userId string) []model.SysMenu {
|
||||
var params []any
|
||||
var querySql string
|
||||
|
||||
if userId == "*" {
|
||||
// 管理员全部菜单
|
||||
querySql = r.selectSql + ` where
|
||||
m.menu_type in (?,?) and m.status = '1'
|
||||
order by m.parent_id, m.menu_sort`
|
||||
params = append(params, menu.TYPE_DIR)
|
||||
params = append(params, menu.TYPE_MENU)
|
||||
} else {
|
||||
// 用户ID权限
|
||||
querySql = r.selectSqlByUser + ` where
|
||||
m.menu_type in (?, ?) and m.status = '1'
|
||||
and ur.user_id = ? and ro.status = '1'
|
||||
order by m.parent_id, m.menu_sort`
|
||||
params = append(params, menu.TYPE_DIR)
|
||||
params = append(params, menu.TYPE_MENU)
|
||||
params = append(params, userId)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectMenuListByRoleId 根据角色ID查询菜单树信息
|
||||
func (r *SysMenuImpl) SelectMenuListByRoleId(roleId string, menuCheckStrictly bool) []string {
|
||||
querySql := `select m.menu_id as 'str' from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
where rm.role_id = ? `
|
||||
var params []any
|
||||
params = append(params, roleId)
|
||||
// 展开
|
||||
if menuCheckStrictly {
|
||||
querySql += ` and m.menu_id not in
|
||||
(select m.parent_id from sys_menu m
|
||||
inner join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
and rm.role_id = ?) `
|
||||
params = append(params, roleId)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, 0)
|
||||
for _, v := range results {
|
||||
ids = append(ids, fmt.Sprintf("%v", v["str"]))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectMenuByIds 根据菜单ID查询信息
|
||||
func (r *SysMenuImpl) SelectMenuByIds(menuIds []string) []model.SysMenu {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(menuIds))
|
||||
querySql := r.selectSql + " where m.menu_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(menuIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// HasChildByMenuIdAndStatus 存在菜单子节点数量与状态
|
||||
func (r *SysMenuImpl) HasChildByMenuIdAndStatus(menuId, status string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_menu where parent_id = ?"
|
||||
params := []any{menuId}
|
||||
|
||||
// 菜单状态
|
||||
if status != "" {
|
||||
querySql += " and status = ? and menu_type in (?, ?) "
|
||||
params = append(params, status)
|
||||
params = append(params, menu.TYPE_DIR)
|
||||
params = append(params, menu.TYPE_MENU)
|
||||
}
|
||||
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertMenu 新增菜单信息
|
||||
func (r *SysMenuImpl) InsertMenu(sysMenu model.SysMenu) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysMenu.MenuID != "" {
|
||||
params["menu_id"] = sysMenu.MenuID
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
params["parent_id"] = sysMenu.ParentID
|
||||
}
|
||||
if sysMenu.MenuName != "" {
|
||||
params["menu_name"] = sysMenu.MenuName
|
||||
}
|
||||
if sysMenu.MenuSort > 0 {
|
||||
params["menu_sort"] = sysMenu.MenuSort
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
params["path"] = sysMenu.Path
|
||||
}
|
||||
if sysMenu.Component != "" {
|
||||
params["component"] = sysMenu.Component
|
||||
}
|
||||
if sysMenu.IsFrame != "" {
|
||||
params["is_frame"] = sysMenu.IsFrame
|
||||
}
|
||||
if sysMenu.IsCache != "" {
|
||||
params["is_cache"] = sysMenu.IsCache
|
||||
}
|
||||
if sysMenu.MenuType != "" {
|
||||
params["menu_type"] = sysMenu.MenuType
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
params["visible"] = sysMenu.Visible
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
params["status"] = sysMenu.Status
|
||||
}
|
||||
if sysMenu.Perms != "" {
|
||||
params["perms"] = sysMenu.Perms
|
||||
}
|
||||
if sysMenu.Icon != "" {
|
||||
params["icon"] = sysMenu.Icon
|
||||
} else {
|
||||
params["icon"] = "#"
|
||||
}
|
||||
if sysMenu.Remark != "" {
|
||||
params["remark"] = sysMenu.Remark
|
||||
}
|
||||
if sysMenu.CreateBy != "" {
|
||||
params["create_by"] = sysMenu.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据菜单类型重置参数
|
||||
if sysMenu.MenuType == menu.TYPE_BUTTON {
|
||||
params["component"] = ""
|
||||
params["path"] = ""
|
||||
params["icon"] = "#"
|
||||
params["is_cache"] = "1"
|
||||
params["is_frame"] = "1"
|
||||
params["visible"] = "1"
|
||||
params["status"] = "1"
|
||||
}
|
||||
if sysMenu.MenuType == menu.TYPE_DIR {
|
||||
params["component"] = ""
|
||||
params["perms"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_menu (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateMenu 修改菜单信息
|
||||
func (r *SysMenuImpl) UpdateMenu(sysMenu model.SysMenu) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysMenu.MenuID != "" {
|
||||
params["menu_id"] = sysMenu.MenuID
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
params["parent_id"] = sysMenu.ParentID
|
||||
}
|
||||
if sysMenu.MenuName != "" {
|
||||
params["menu_name"] = sysMenu.MenuName
|
||||
}
|
||||
if sysMenu.MenuSort > 0 {
|
||||
params["menu_sort"] = sysMenu.MenuSort
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
params["path"] = sysMenu.Path
|
||||
}
|
||||
if sysMenu.Component != "" {
|
||||
params["component"] = sysMenu.Component
|
||||
}
|
||||
if sysMenu.IsFrame != "" {
|
||||
params["is_frame"] = sysMenu.IsFrame
|
||||
}
|
||||
if sysMenu.IsCache != "" {
|
||||
params["is_cache"] = sysMenu.IsCache
|
||||
}
|
||||
if sysMenu.MenuType != "" {
|
||||
params["menu_type"] = sysMenu.MenuType
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
params["visible"] = sysMenu.Visible
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
params["status"] = sysMenu.Status
|
||||
}
|
||||
if sysMenu.Perms != "" {
|
||||
params["perms"] = sysMenu.Perms
|
||||
}
|
||||
if sysMenu.Icon != "" {
|
||||
params["icon"] = sysMenu.Icon
|
||||
} else {
|
||||
params["icon"] = "#"
|
||||
}
|
||||
if sysMenu.Remark != "" {
|
||||
params["remark"] = sysMenu.Remark
|
||||
}
|
||||
if sysMenu.UpdateBy != "" {
|
||||
params["update_by"] = sysMenu.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据菜单类型重置参数
|
||||
if sysMenu.MenuType == menu.TYPE_BUTTON {
|
||||
params["component"] = ""
|
||||
params["path"] = ""
|
||||
params["icon"] = "#"
|
||||
params["is_cache"] = "1"
|
||||
params["is_frame"] = "1"
|
||||
params["visible"] = "1"
|
||||
params["status"] = "1"
|
||||
}
|
||||
if sysMenu.MenuType == menu.TYPE_DIR {
|
||||
params["component"] = ""
|
||||
params["perms"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_menu set " + strings.Join(keys, ",") + " where menu_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysMenu.MenuID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteMenuById 删除菜单管理信息
|
||||
func (r *SysMenuImpl) DeleteMenuById(menuId string) int64 {
|
||||
sql := "delete from sys_menu where menu_id = ?"
|
||||
results, err := datasource.ExecDB("", sql, []any{menuId})
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CheckUniqueMenu 校验菜单是否唯一
|
||||
func (r *SysMenuImpl) CheckUniqueMenu(sysMenu model.SysMenu) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysMenu.MenuName != "" {
|
||||
conditions = append(conditions, "menu_name = ?")
|
||||
params = append(params, sysMenu.MenuName)
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysMenu.ParentID)
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
conditions = append(conditions, "path = ?")
|
||||
params = append(params, sysMenu.Path)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
if whereSql == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select menu_id as 'str' from sys_menu " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
24
src/modules/system/repository/sys_notice.go
Normal file
24
src/modules/system/repository/sys_notice.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysNotice 通知公告表 数据层接口
|
||||
type ISysNotice interface {
|
||||
// SelectNoticePage 分页查询公告列表
|
||||
SelectNoticePage(query map[string]any) map[string]any
|
||||
|
||||
// SelectNoticeList 查询公告列表
|
||||
SelectNoticeList(sysNotice model.SysNotice) []model.SysNotice
|
||||
|
||||
// SelectNoticeById 查询公告信息
|
||||
SelectNoticeByIds(noticeIds []string) []model.SysNotice
|
||||
|
||||
// InsertNotice 新增公告
|
||||
InsertNotice(sysNotice model.SysNotice) string
|
||||
|
||||
// UpdateNotice 修改公告
|
||||
UpdateNotice(sysNotice model.SysNotice) int64
|
||||
|
||||
// DeleteNoticeByIds 批量删除公告信息
|
||||
DeleteNoticeByIds(noticeIds []string) int64
|
||||
}
|
||||
297
src/modules/system/repository/sys_notice.impl.go
Normal file
297
src/modules/system/repository/sys_notice.impl.go
Normal file
@@ -0,0 +1,297 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysNoticeImpl 结构体
|
||||
var NewSysNoticeImpl = &SysNoticeImpl{
|
||||
selectSql: `select
|
||||
notice_id, notice_title, notice_type, notice_content, status, del_flag,
|
||||
create_by, create_time, update_by, update_time, remark from sys_notice`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"notice_id": "NoticeID",
|
||||
"notice_title": "NoticeTitle",
|
||||
"notice_type": "NoticeType",
|
||||
"notice_content": "NoticeContent",
|
||||
"status": "Status",
|
||||
"del_flag": "DelFlag",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// SysNoticeImpl 通知公告表 数据层处理
|
||||
type SysNoticeImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysNoticeImpl) convertResultRows(rows []map[string]any) []model.SysNotice {
|
||||
arr := make([]model.SysNotice, 0)
|
||||
for _, row := range rows {
|
||||
sysNotice := model.SysNotice{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysNotice, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysNotice)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectNoticePage 分页查询公告列表
|
||||
func (r *SysNoticeImpl) SelectNoticePage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["noticeTitle"]; ok && v != "" {
|
||||
conditions = append(conditions, "notice_title like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["noticeType"]; ok && v != "" {
|
||||
conditions = append(conditions, "notice_type = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["createBy"]; ok && v != "" {
|
||||
conditions = append(conditions, "create_by like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "create_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "create_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysNotice{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_notice"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectNoticeList 查询公告列表
|
||||
func (r *SysNoticeImpl) SelectNoticeList(sysNotice model.SysNotice) []model.SysNotice {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysNotice.NoticeTitle != "" {
|
||||
conditions = append(conditions, "notice_title like concat(?, '%')")
|
||||
params = append(params, sysNotice.NoticeTitle)
|
||||
}
|
||||
if sysNotice.NoticeType != "" {
|
||||
conditions = append(conditions, "notice_type = ?")
|
||||
params = append(params, sysNotice.NoticeType)
|
||||
}
|
||||
if sysNotice.CreateBy != "" {
|
||||
conditions = append(conditions, "create_by like concat(?, '%')")
|
||||
params = append(params, sysNotice.CreateBy)
|
||||
}
|
||||
if sysNotice.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysNotice.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysNotice{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectNoticeByIds 查询公告信息
|
||||
func (r *SysNoticeImpl) SelectNoticeByIds(noticeIds []string) []model.SysNotice {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(noticeIds))
|
||||
querySql := r.selectSql + " where notice_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(noticeIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysNotice{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// InsertNotice 新增公告
|
||||
func (r *SysNoticeImpl) InsertNotice(sysNotice model.SysNotice) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysNotice.NoticeTitle != "" {
|
||||
params["notice_title"] = sysNotice.NoticeTitle
|
||||
}
|
||||
if sysNotice.NoticeType != "" {
|
||||
params["notice_type"] = sysNotice.NoticeType
|
||||
}
|
||||
if sysNotice.NoticeContent != "" {
|
||||
params["notice_content"] = sysNotice.NoticeContent
|
||||
}
|
||||
if sysNotice.Status != "" {
|
||||
params["status"] = sysNotice.Status
|
||||
}
|
||||
if sysNotice.Remark != "" {
|
||||
params["remark"] = sysNotice.Remark
|
||||
}
|
||||
if sysNotice.CreateBy != "" {
|
||||
params["create_by"] = sysNotice.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_notice (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateNotice 修改公告
|
||||
func (r *SysNoticeImpl) UpdateNotice(sysNotice model.SysNotice) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysNotice.NoticeTitle != "" {
|
||||
params["notice_title"] = sysNotice.NoticeTitle
|
||||
}
|
||||
if sysNotice.NoticeType != "" {
|
||||
params["notice_type"] = sysNotice.NoticeType
|
||||
}
|
||||
if sysNotice.NoticeContent != "" {
|
||||
params["notice_content"] = sysNotice.NoticeContent
|
||||
}
|
||||
if sysNotice.Status != "" {
|
||||
params["status"] = sysNotice.Status
|
||||
}
|
||||
if sysNotice.Remark != "" {
|
||||
params["remark"] = sysNotice.Remark
|
||||
}
|
||||
if sysNotice.UpdateBy != "" {
|
||||
params["update_by"] = sysNotice.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_notice set " + strings.Join(keys, ",") + " where notice_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysNotice.NoticeID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteNoticeByIds 批量删除公告信息
|
||||
func (r *SysNoticeImpl) DeleteNoticeByIds(noticeIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(noticeIds))
|
||||
sql := "update sys_notice set del_flag = '1' where notice_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(noticeIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("update err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
30
src/modules/system/repository/sys_post.go
Normal file
30
src/modules/system/repository/sys_post.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysPost 岗位表 数据层接口
|
||||
type ISysPost interface {
|
||||
// SelectPostPage 查询岗位分页数据集合
|
||||
SelectPostPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectPostList 查询岗位数据集合
|
||||
SelectPostList(sysPost model.SysPost) []model.SysPost
|
||||
|
||||
// SelectPostByIds 通过岗位ID查询岗位信息
|
||||
SelectPostByIds(postIds []string) []model.SysPost
|
||||
|
||||
// SelectPostListByUserId 根据用户ID获取岗位选择框列表
|
||||
SelectPostListByUserId(userId string) []model.SysPost
|
||||
|
||||
// DeletePostByIds 批量删除岗位信息
|
||||
DeletePostByIds(postIds []string) int64
|
||||
|
||||
// UpdatePost 修改岗位信息
|
||||
UpdatePost(sysPost model.SysPost) int64
|
||||
|
||||
// InsertPost 新增岗位信息
|
||||
InsertPost(sysPost model.SysPost) string
|
||||
|
||||
// CheckUniquePost 校验岗位唯一
|
||||
CheckUniquePost(sysPost model.SysPost) string
|
||||
}
|
||||
323
src/modules/system/repository/sys_post.impl.go
Normal file
323
src/modules/system/repository/sys_post.impl.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysPostImpl 结构体
|
||||
var NewSysPostImpl = &SysPostImpl{
|
||||
selectSql: `select
|
||||
post_id, post_code, post_name, post_sort, status, create_by, create_time, remark
|
||||
from sys_post`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"post_id": "PostID",
|
||||
"post_code": "PostCode",
|
||||
"post_name": "PostName",
|
||||
"post_sort": "PostSort",
|
||||
"status": "Status",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// SysPostImpl 岗位表 数据层处理
|
||||
type SysPostImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysPostImpl) convertResultRows(rows []map[string]any) []model.SysPost {
|
||||
arr := make([]model.SysPost, 0)
|
||||
for _, row := range rows {
|
||||
sysPost := model.SysPost{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysPost, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysPost)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectPostPage 查询岗位分页数据集合
|
||||
func (r *SysPostImpl) SelectPostPage(query map[string]any) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["postCode"]; ok && v != "" {
|
||||
conditions = append(conditions, "post_code like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["postName"]; ok && v != "" {
|
||||
conditions = append(conditions, "post_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysPost{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from sys_post"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by post_sort limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectPostList 查询岗位数据集合
|
||||
func (r *SysPostImpl) SelectPostList(sysPost model.SysPost) []model.SysPost {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysPost.PostCode != "" {
|
||||
conditions = append(conditions, "post_code like concat(?, '%')")
|
||||
params = append(params, sysPost.PostCode)
|
||||
}
|
||||
if sysPost.PostName != "" {
|
||||
conditions = append(conditions, "post_name like concat(?, '%')")
|
||||
params = append(params, sysPost.PostName)
|
||||
}
|
||||
if sysPost.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysPost.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by post_sort"
|
||||
querySql := r.selectSql + whereSql + orderSql
|
||||
rows, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysPost{}
|
||||
}
|
||||
return r.convertResultRows(rows)
|
||||
}
|
||||
|
||||
// SelectPostByIds 通过岗位ID查询岗位信息
|
||||
func (r *SysPostImpl) SelectPostByIds(postIds []string) []model.SysPost {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(postIds))
|
||||
querySql := r.selectSql + " where post_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(postIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysPost{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectPostListByUserId 根据用户ID获取岗位选择框列表
|
||||
func (r *SysPostImpl) SelectPostListByUserId(userId string) []model.SysPost {
|
||||
// 查询数据
|
||||
querySql := `select distinct
|
||||
p.post_id, p.post_name, p.post_code
|
||||
from sys_post p
|
||||
left join sys_user_post up on up.post_id = p.post_id
|
||||
left join sys_user u on u.user_id = up.user_id
|
||||
where u.user_id = ? order by p.post_id`
|
||||
rows, err := datasource.RawDB("", querySql, []any{userId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysPost{}
|
||||
}
|
||||
return r.convertResultRows(rows)
|
||||
}
|
||||
|
||||
// DeletePostByIds 批量删除岗位信息
|
||||
func (r *SysPostImpl) DeletePostByIds(postIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(postIds))
|
||||
sql := "delete from sys_post where post_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(postIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// UpdatePost 修改岗位信息
|
||||
func (r *SysPostImpl) UpdatePost(sysPost model.SysPost) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysPost.PostCode != "" {
|
||||
params["post_code"] = sysPost.PostCode
|
||||
}
|
||||
if sysPost.PostName != "" {
|
||||
params["post_name"] = sysPost.PostName
|
||||
}
|
||||
if sysPost.PostSort > 0 {
|
||||
params["post_sort"] = sysPost.PostSort
|
||||
}
|
||||
if sysPost.Status != "" {
|
||||
params["status"] = sysPost.Status
|
||||
}
|
||||
if sysPost.Remark != "" {
|
||||
params["remark"] = sysPost.Remark
|
||||
}
|
||||
if sysPost.UpdateBy != "" {
|
||||
params["update_by"] = sysPost.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_post set " + strings.Join(keys, ",") + " where post_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysPost.PostID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// InsertPost 新增岗位信息
|
||||
func (r *SysPostImpl) InsertPost(sysPost model.SysPost) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysPost.PostID != "" {
|
||||
params["post_id"] = sysPost.PostID
|
||||
}
|
||||
if sysPost.PostCode != "" {
|
||||
params["post_code"] = sysPost.PostCode
|
||||
}
|
||||
if sysPost.PostName != "" {
|
||||
params["post_name"] = sysPost.PostName
|
||||
}
|
||||
if sysPost.PostSort > 0 {
|
||||
params["post_sort"] = sysPost.PostSort
|
||||
}
|
||||
if sysPost.Status != "" {
|
||||
params["status"] = sysPost.Status
|
||||
}
|
||||
if sysPost.Remark != "" {
|
||||
params["remark"] = sysPost.Remark
|
||||
}
|
||||
if sysPost.CreateBy != "" {
|
||||
params["create_by"] = sysPost.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_post (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// CheckUniquePost 校验岗位唯一
|
||||
func (r *SysPostImpl) CheckUniquePost(sysPost model.SysPost) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysPost.PostName != "" {
|
||||
conditions = append(conditions, "post_name= ?")
|
||||
params = append(params, sysPost.PostName)
|
||||
}
|
||||
if sysPost.PostCode != "" {
|
||||
conditions = append(conditions, "post_code = ?")
|
||||
params = append(params, sysPost.PostCode)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select post_id as 'str' from sys_post " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
30
src/modules/system/repository/sys_role.go
Normal file
30
src/modules/system/repository/sys_role.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysRole 角色表 数据层接口
|
||||
type ISysRole interface {
|
||||
// SelectRolePage 根据条件分页查询角色数据
|
||||
SelectRolePage(query map[string]any, dataScopeSQL string) map[string]any
|
||||
|
||||
// SelectRoleList 根据条件查询角色数据
|
||||
SelectRoleList(sysRole model.SysRole, dataScopeSQL string) []model.SysRole
|
||||
|
||||
// SelectRoleListByUserId 根据用户ID获取角色选择框列表
|
||||
SelectRoleListByUserId(userId string) []model.SysRole
|
||||
|
||||
// SelectRoleByIds 通过角色ID查询角色
|
||||
SelectRoleByIds(roleIds []string) []model.SysRole
|
||||
|
||||
// UpdateRole 修改角色信息
|
||||
UpdateRole(sysRole model.SysRole) int64
|
||||
|
||||
// InsertRole 新增角色信息
|
||||
InsertRole(sysRole model.SysRole) string
|
||||
|
||||
// DeleteRoleByIds 批量删除角色信息
|
||||
DeleteRoleByIds(roleIds []string) int64
|
||||
|
||||
// CheckUniqueRole 校验角色是否唯一
|
||||
CheckUniqueRole(sysRole model.SysRole) string
|
||||
}
|
||||
382
src/modules/system/repository/sys_role.impl.go
Normal file
382
src/modules/system/repository/sys_role.impl.go
Normal file
@@ -0,0 +1,382 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysRoleImpl 结构体
|
||||
var NewSysRoleImpl = &SysRoleImpl{
|
||||
selectSql: `select distinct
|
||||
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly,
|
||||
r.dept_check_strictly, r.status, r.del_flag, r.create_time, r.remark
|
||||
from sys_role r
|
||||
left join sys_user_role ur on ur.role_id = r.role_id
|
||||
left join sys_user u on u.user_id = ur.user_id
|
||||
left join sys_dept d on u.dept_id = d.dept_id`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"role_id": "RoleID",
|
||||
"role_name": "RoleName",
|
||||
"role_key": "RoleKey",
|
||||
"role_sort": "RoleSort",
|
||||
"data_scope": "DataScope",
|
||||
"menu_check_strictly": "MenuCheckStrictly",
|
||||
"dept_check_strictly": "DeptCheckStrictly",
|
||||
"status": "Status",
|
||||
"del_flag": "DelFlag",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// SysRoleImpl 角色表 数据层处理
|
||||
type SysRoleImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysRoleImpl) convertResultRows(rows []map[string]any) []model.SysRole {
|
||||
arr := make([]model.SysRole, 0)
|
||||
for _, row := range rows {
|
||||
sysRole := model.SysRole{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysRole, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysRole)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectRolePage 根据条件分页查询角色数据
|
||||
func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["roleId"]; ok && v != "" {
|
||||
conditions = append(conditions, "r.role_id = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["roleName"]; ok && v != "" {
|
||||
conditions = append(conditions, "r.role_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["roleKey"]; ok && v != "" {
|
||||
conditions = append(conditions, "r.role_key like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "r.status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "r.create_time >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "r.create_time <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
if v, ok := query["deptId"]; ok && v != "" {
|
||||
conditions = append(conditions, `(u.dept_id = ? or u.dept_id in (
|
||||
select t.dept_id from sys_dept t where find_in_set(?, ancestors)
|
||||
))`)
|
||||
params = append(params, v)
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where r.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysRole{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := `select count(distinct r.role_id) as 'total' from sys_role r
|
||||
left join sys_user_role ur on ur.role_id = r.role_id
|
||||
left join sys_user u on u.user_id = ur.user_id
|
||||
left join sys_dept d on u.dept_id = d.dept_id`
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql+dataScopeSQL, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " order by r.role_sort asc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + dataScopeSQL + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectRoleList 根据条件查询角色数据
|
||||
func (r *SysRoleImpl) SelectRoleList(sysRole model.SysRole, dataScopeSQL string) []model.SysRole {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysRole.RoleID != "" {
|
||||
conditions = append(conditions, "r.role_id = ?")
|
||||
params = append(params, sysRole.RoleID)
|
||||
}
|
||||
if sysRole.RoleKey != "" {
|
||||
conditions = append(conditions, "r.role_key like concat(?, '%')")
|
||||
params = append(params, sysRole.RoleKey)
|
||||
}
|
||||
if sysRole.RoleName != "" {
|
||||
conditions = append(conditions, "r.role_name like concat(?, '%')")
|
||||
params = append(params, sysRole.RoleName)
|
||||
}
|
||||
if sysRole.Status != "" {
|
||||
conditions = append(conditions, "r.status = ?")
|
||||
params = append(params, sysRole.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where r.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by r.role_sort"
|
||||
querySql := r.selectSql + whereSql + dataScopeSQL + orderSql
|
||||
rows, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysRole{}
|
||||
}
|
||||
return r.convertResultRows(rows)
|
||||
}
|
||||
|
||||
// SelectRoleListByUserId 根据用户ID获取角色选择框列表
|
||||
func (r *SysRoleImpl) SelectRoleListByUserId(userId string) []model.SysRole {
|
||||
querySql := r.selectSql + " where r.del_flag = '0' and ur.user_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{userId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysRole{}
|
||||
}
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectRoleByIds 通过角色ID查询角色
|
||||
func (r *SysRoleImpl) SelectRoleByIds(roleIds []string) []model.SysRole {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(roleIds))
|
||||
querySql := r.selectSql + " where r.role_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(roleIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysRole{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// UpdateRole 修改角色信息
|
||||
func (r *SysRoleImpl) UpdateRole(sysRole model.SysRole) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysRole.RoleName != "" {
|
||||
params["role_name"] = sysRole.RoleName
|
||||
}
|
||||
if sysRole.RoleKey != "" {
|
||||
params["role_key"] = sysRole.RoleKey
|
||||
}
|
||||
if sysRole.RoleSort > 0 {
|
||||
params["role_sort"] = sysRole.RoleSort
|
||||
}
|
||||
if sysRole.DataScope != "" {
|
||||
params["data_scope"] = sysRole.DataScope
|
||||
}
|
||||
if sysRole.MenuCheckStrictly != "" {
|
||||
params["menu_check_strictly"] = sysRole.MenuCheckStrictly
|
||||
}
|
||||
if sysRole.DeptCheckStrictly != "" {
|
||||
params["dept_check_strictly"] = sysRole.DeptCheckStrictly
|
||||
}
|
||||
if sysRole.Status != "" {
|
||||
params["status"] = sysRole.Status
|
||||
}
|
||||
if sysRole.Remark != "" {
|
||||
params["remark"] = sysRole.Remark
|
||||
}
|
||||
if sysRole.UpdateBy != "" {
|
||||
params["update_by"] = sysRole.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_role set " + strings.Join(keys, ",") + " where role_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysRole.RoleID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// InsertRole 新增角色信息
|
||||
func (r *SysRoleImpl) InsertRole(sysRole model.SysRole) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysRole.RoleID != "" {
|
||||
params["role_id"] = sysRole.RoleID
|
||||
}
|
||||
if sysRole.RoleName != "" {
|
||||
params["role_name"] = sysRole.RoleName
|
||||
}
|
||||
if sysRole.RoleKey != "" {
|
||||
params["role_key"] = sysRole.RoleKey
|
||||
}
|
||||
if sysRole.RoleSort > 0 {
|
||||
params["role_sort"] = sysRole.RoleSort
|
||||
}
|
||||
if sysRole.DataScope != "" {
|
||||
params["data_scope"] = sysRole.DataScope
|
||||
}
|
||||
if sysRole.MenuCheckStrictly != "" {
|
||||
params["menu_check_strictly"] = sysRole.MenuCheckStrictly
|
||||
}
|
||||
if sysRole.DeptCheckStrictly != "" {
|
||||
params["dept_check_strictly"] = sysRole.DeptCheckStrictly
|
||||
}
|
||||
if sysRole.Status != "" {
|
||||
params["status"] = sysRole.Status
|
||||
}
|
||||
if sysRole.Remark != "" {
|
||||
params["remark"] = sysRole.Remark
|
||||
}
|
||||
if sysRole.CreateBy != "" {
|
||||
params["create_by"] = sysRole.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_role (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// DeleteRoleByIds 批量删除角色信息
|
||||
func (r *SysRoleImpl) DeleteRoleByIds(roleIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(roleIds))
|
||||
sql := "update sys_role set del_flag = '1' where role_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(roleIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CheckUniqueRole 校验角色是否唯一
|
||||
func (r *SysRoleImpl) CheckUniqueRole(sysRole model.SysRole) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysRole.RoleName != "" {
|
||||
conditions = append(conditions, "r.role_name = ?")
|
||||
params = append(params, sysRole.RoleName)
|
||||
}
|
||||
if sysRole.RoleKey != "" {
|
||||
conditions = append(conditions, "r.role_key = ?")
|
||||
params = append(params, sysRole.RoleKey)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select role_id as 'str' from sys_role r " + whereSql + " and r.del_flag = '0' limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
15
src/modules/system/repository/sys_role_dept.go
Normal file
15
src/modules/system/repository/sys_role_dept.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysRoleDept 角色与部门关联表 数据层接口
|
||||
type ISysRoleDept interface {
|
||||
// DeleteRoleDept 批量删除角色部门关联信息
|
||||
DeleteRoleDept(roleIds []string) int64
|
||||
|
||||
// DeleteDeptRole 批量删除部门角色关联信息
|
||||
DeleteDeptRole(deptIds []string) int64
|
||||
|
||||
// BatchRoleDept 批量新增角色部门信息
|
||||
BatchRoleDept(sysRoleDepts []model.SysRoleDept) int64
|
||||
}
|
||||
58
src/modules/system/repository/sys_role_dept.impl.go
Normal file
58
src/modules/system/repository/sys_role_dept.impl.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysRoleDeptImpl 结构体
|
||||
var NewSysRoleDeptImpl = &SysRoleDeptImpl{}
|
||||
|
||||
// SysRoleDeptImpl 角色与部门关联表 数据层处理
|
||||
type SysRoleDeptImpl struct{}
|
||||
|
||||
// DeleteRoleDept 批量删除角色部门关联信息
|
||||
func (r *SysRoleDeptImpl) DeleteRoleDept(roleIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(roleIds))
|
||||
sql := "delete from sys_role_dept where role_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(roleIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteDeptRole 批量删除部门角色关联信息
|
||||
func (r *SysRoleDeptImpl) DeleteDeptRole(deptIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(deptIds))
|
||||
sql := "delete from sys_role_dept where dept_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(deptIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// BatchRoleDept 批量新增角色部门信息
|
||||
func (r *SysRoleDeptImpl) BatchRoleDept(sysRoleDepts []model.SysRoleDept) int64 {
|
||||
keyValues := make([]string, 0)
|
||||
for _, item := range sysRoleDepts {
|
||||
keyValues = append(keyValues, fmt.Sprintf("(%s,%s)", item.RoleID, item.DeptID))
|
||||
}
|
||||
sql := "insert into sys_role_dept(role_id, dept_id) values " + strings.Join(keyValues, ",")
|
||||
results, err := datasource.ExecDB("", sql, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
18
src/modules/system/repository/sys_role_menu.go
Normal file
18
src/modules/system/repository/sys_role_menu.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysRoleMenu 角色与菜单关联表 数据层接口
|
||||
type ISysRoleMenu interface {
|
||||
// CheckMenuExistRole 查询菜单分配给角色使用数量
|
||||
CheckMenuExistRole(menuId string) int64
|
||||
|
||||
// DeleteRoleMenu 批量删除角色和菜单关联
|
||||
DeleteRoleMenu(roleIds []string) int64
|
||||
|
||||
// DeleteMenuRole 批量删除菜单和角色关联
|
||||
DeleteMenuRole(menuIds []string) int64
|
||||
|
||||
// BatchRoleMenu 批量新增角色菜单信息
|
||||
BatchRoleMenu(sysRoleMenus []model.SysRoleMenu) int64
|
||||
}
|
||||
73
src/modules/system/repository/sys_role_menu.impl.go
Normal file
73
src/modules/system/repository/sys_role_menu.impl.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysRoleMenuImpl 结构体
|
||||
var NewSysRoleMenuImpl = &SysRoleMenuImpl{}
|
||||
|
||||
// SysRoleMenuImpl 角色与菜单关联表 数据层处理
|
||||
type SysRoleMenuImpl struct{}
|
||||
|
||||
// CheckMenuExistRole 查询菜单分配给角色使用数量
|
||||
func (r *SysRoleMenuImpl) CheckMenuExistRole(menuId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_role_menu where menu_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{menuId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// DeleteRoleMenu 批量删除角色和菜单关联
|
||||
func (r *SysRoleMenuImpl) DeleteRoleMenu(roleIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(roleIds))
|
||||
sql := "delete from sys_role_menu where role_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(roleIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteMenuRole 批量删除菜单和角色关联
|
||||
func (r *SysRoleMenuImpl) DeleteMenuRole(menuIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(menuIds))
|
||||
sql := "delete from sys_role_menu where menu_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(menuIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// BatchRoleMenu 批量新增角色菜单信息
|
||||
func (r *SysRoleMenuImpl) BatchRoleMenu(sysRoleMenus []model.SysRoleMenu) int64 {
|
||||
keyValues := make([]string, 0)
|
||||
for _, item := range sysRoleMenus {
|
||||
keyValues = append(keyValues, fmt.Sprintf("(%s,%s)", item.RoleID, item.MenuID))
|
||||
}
|
||||
sql := "insert into sys_role_menu(role_id, menu_id) values " + strings.Join(keyValues, ",")
|
||||
results, err := datasource.ExecDB("", sql, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
33
src/modules/system/repository/sys_user.go
Normal file
33
src/modules/system/repository/sys_user.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysUser 用户表 数据层接口
|
||||
type ISysUser interface {
|
||||
// SelectUserPage 根据条件分页查询用户列表
|
||||
SelectUserPage(query map[string]any, dataScopeSQL string) map[string]any
|
||||
|
||||
// SelectAllocatedPage 根据条件分页查询分配用户角色列表
|
||||
SelectAllocatedPage(query map[string]any, dataScopeSQL string) map[string]any
|
||||
|
||||
// SelectUserList 根据条件查询用户列表
|
||||
SelectUserList(sysUser model.SysUser, dataScopeSQL string) []model.SysUser
|
||||
|
||||
// SelectUserByIds 通过用户ID查询用户
|
||||
SelectUserByIds(userIds []string) []model.SysUser
|
||||
|
||||
// SelectUserByUserName 通过用户登录账号查询用户
|
||||
SelectUserByUserName(userName string) model.SysUser
|
||||
|
||||
// InsertUser 新增用户信息
|
||||
InsertUser(sysUser model.SysUser) string
|
||||
|
||||
// UpdateUser 修改用户信息
|
||||
UpdateUser(sysUser model.SysUser) int64
|
||||
|
||||
// DeleteUserByIds 批量删除用户信息
|
||||
DeleteUserByIds(userIds []string) int64
|
||||
|
||||
// CheckUniqueUser 校验用户信息是否唯一
|
||||
CheckUniqueUser(sysUser model.SysUser) string
|
||||
}
|
||||
580
src/modules/system/repository/sys_user.impl.go
Normal file
580
src/modules/system/repository/sys_user.impl.go
Normal file
@@ -0,0 +1,580 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/crypto"
|
||||
"ems.agt/src/framework/utils/date"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysUserImpl 结构体
|
||||
var NewSysUserImpl = &SysUserImpl{
|
||||
selectSql: `select
|
||||
u.user_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
|
||||
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
|
||||
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
left join sys_user_role ur on u.user_id = ur.user_id
|
||||
left join sys_role r on r.role_id = ur.role_id`,
|
||||
|
||||
sysUserMap: map[string]string{
|
||||
"user_id": "UserID",
|
||||
"dept_id": "DeptID",
|
||||
"user_name": "UserName",
|
||||
"nick_name": "NickName",
|
||||
"user_type": "UserType",
|
||||
"email": "Email",
|
||||
"phonenumber": "PhoneNumber",
|
||||
"sex": "Sex",
|
||||
"avatar": "Avatar",
|
||||
"password": "Password",
|
||||
"status": "Status",
|
||||
"del_flag": "DelFlag",
|
||||
"login_ip": "LoginIP",
|
||||
"login_date": "LoginDate",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
|
||||
sysDeptMap: map[string]string{
|
||||
"dept_id": "DeptID",
|
||||
"parent_id": "ParentID",
|
||||
"dept_name": "DeptName",
|
||||
"ancestors": "Ancestors",
|
||||
"order_num": "OrderNum",
|
||||
"leader": "Leader",
|
||||
"dept_status": "Status",
|
||||
},
|
||||
|
||||
sysRoleMap: map[string]string{
|
||||
"role_id": "RoleID",
|
||||
"role_name": "RoleName",
|
||||
"role_key": "RoleKey",
|
||||
"role_sort": "RoleSort",
|
||||
"data_scope": "DataScope",
|
||||
"role_status": "Status",
|
||||
},
|
||||
}
|
||||
|
||||
// SysUserImpl 用户表 数据层处理
|
||||
type SysUserImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 用户信息实体映射
|
||||
sysUserMap map[string]string
|
||||
// 用户部门实体映射 一对一
|
||||
sysDeptMap map[string]string
|
||||
// 用户角色实体映射 一对多
|
||||
sysRoleMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysUserImpl) convertResultRows(rows []map[string]any) []model.SysUser {
|
||||
arr := make([]model.SysUser, 0)
|
||||
|
||||
for _, row := range rows {
|
||||
sysUser := model.SysUser{}
|
||||
sysDept := model.SysDept{}
|
||||
sysRole := model.SysRole{}
|
||||
sysUser.Roles = []model.SysRole{}
|
||||
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.sysUserMap[key]; ok {
|
||||
repo.SetFieldValue(&sysUser, keyMapper, value)
|
||||
}
|
||||
if keyMapper, ok := r.sysDeptMap[key]; ok {
|
||||
repo.SetFieldValue(&sysDept, keyMapper, value)
|
||||
}
|
||||
if keyMapper, ok := r.sysRoleMap[key]; ok {
|
||||
repo.SetFieldValue(&sysRole, keyMapper, value)
|
||||
}
|
||||
}
|
||||
|
||||
sysUser.Dept = sysDept
|
||||
if sysRole.RoleKey != "" {
|
||||
sysUser.Roles = append(sysUser.Roles, sysRole)
|
||||
}
|
||||
|
||||
one := true
|
||||
for i, a := range arr {
|
||||
if a.UserID == sysUser.UserID {
|
||||
arrUser := &arr[i]
|
||||
arrUser.Roles = append(arrUser.Roles, sysUser.Roles...)
|
||||
one = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if one {
|
||||
arr = append(arr, sysUser)
|
||||
}
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectUserPage 根据条件分页查询用户列表
|
||||
func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) map[string]any {
|
||||
selectUserSql := `select
|
||||
u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id`
|
||||
selectUserTotalSql := `select count(distinct u.user_id) as 'total'
|
||||
from sys_user u left join sys_dept d on u.dept_id = d.dept_id`
|
||||
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["userId"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.user_id = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["userName"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.user_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["phonenumber"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.phonenumber like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
beginTime, ok := query["beginTime"]
|
||||
if !ok {
|
||||
beginTime, ok = query["params[beginTime]"]
|
||||
}
|
||||
if ok && beginTime != "" {
|
||||
conditions = append(conditions, "u.login_date >= ?")
|
||||
beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, beginDate.UnixMilli())
|
||||
}
|
||||
endTime, ok := query["endTime"]
|
||||
if !ok {
|
||||
endTime, ok = query["params[endTime]"]
|
||||
}
|
||||
if ok && endTime != "" {
|
||||
conditions = append(conditions, "u.login_date <= ?")
|
||||
endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD)
|
||||
params = append(params, endDate.UnixMilli())
|
||||
}
|
||||
if v, ok := query["deptId"]; ok && v != "" {
|
||||
conditions = append(conditions, "(u.dept_id = ? or u.dept_id in ( select t.dept_id from sys_dept t where find_in_set(?, ancestors) ))")
|
||||
params = append(params, v)
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where u.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysUser{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := selectUserTotalSql + whereSql + dataScopeSQL
|
||||
totalRows, err := datasource.RawDB("", totalSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := selectUserSql + whereSql + dataScopeSQL + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectAllocatedPage 根据条件分页查询分配用户角色列表
|
||||
func (r *SysUserImpl) SelectAllocatedPage(query map[string]any, dataScopeSQL string) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["userName"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.user_name like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["phonenumber"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.phonenumber like concat(?, '%')")
|
||||
params = append(params, v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
conditions = append(conditions, "u.status = ?")
|
||||
params = append(params, v)
|
||||
}
|
||||
// 分配角色用户
|
||||
if allocated, ok := query["allocated"]; ok && allocated != "" {
|
||||
if roleId, ok := query["roleId"]; ok && roleId != "" {
|
||||
if parse.Boolean(allocated) {
|
||||
conditions = append(conditions, "r.role_id = ?")
|
||||
params = append(params, roleId)
|
||||
} else {
|
||||
conditions = append(conditions, `(r.role_id != ? or r.role_id IS NULL)
|
||||
and u.user_id not in (
|
||||
select u.user_id from sys_user u
|
||||
inner join sys_user_role ur on u.user_id = ur.user_id
|
||||
and ur.role_id = ?
|
||||
)`)
|
||||
params = append(params, roleId)
|
||||
params = append(params, roleId)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where u.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.SysUser{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := `select count(distinct u.user_id) as 'total' from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
left join sys_user_role ur on u.user_id = ur.user_id
|
||||
left join sys_role r on r.role_id = ur.role_id`
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql+dataScopeSQL, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 查询数据
|
||||
querySql := `select distinct
|
||||
u.user_id, u.dept_id, u.user_name, u.nick_name, u.email,
|
||||
u.phonenumber, u.status, u.create_time, d.dept_name
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
left join sys_user_role ur on u.user_id = ur.user_id
|
||||
left join sys_role r on r.role_id = ur.role_id`
|
||||
querySql = querySql + whereSql + dataScopeSQL + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectUserList 根据条件查询用户列表
|
||||
func (r *SysUserImpl) SelectUserList(sysUser model.SysUser, dataScopeSQL string) []model.SysUser {
|
||||
selectUserSql := `select
|
||||
u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id`
|
||||
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysUser.UserID != "" {
|
||||
conditions = append(conditions, "u.user_id = ?")
|
||||
params = append(params, sysUser.UserID)
|
||||
}
|
||||
if sysUser.UserName != "" {
|
||||
conditions = append(conditions, "u.user_name like concat(?, '%')")
|
||||
params = append(params, sysUser.UserName)
|
||||
}
|
||||
if sysUser.Status != "" {
|
||||
conditions = append(conditions, "u.status = ?")
|
||||
params = append(params, sysUser.Status)
|
||||
}
|
||||
if sysUser.PhoneNumber != "" {
|
||||
conditions = append(conditions, "u.phonenumber like concat(?, '%')")
|
||||
params = append(params, sysUser.PhoneNumber)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where u.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := selectUserSql + whereSql + dataScopeSQL
|
||||
rows, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysUser{}
|
||||
}
|
||||
return r.convertResultRows(rows)
|
||||
}
|
||||
|
||||
// SelectUserByIds 通过用户ID查询用户
|
||||
func (r *SysUserImpl) SelectUserByIds(userIds []string) []model.SysUser {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
|
||||
querySql := r.selectSql + " where u.del_flag = '0' and u.user_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(userIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysUser{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectUserByUserName 通过用户登录账号查询用户
|
||||
func (r *SysUserImpl) SelectUserByUserName(userName string) model.SysUser {
|
||||
querySql := r.selectSql + " where u.del_flag = '0' and u.user_name = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{userName})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysUser{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysUser{}
|
||||
}
|
||||
|
||||
// InsertUser 新增用户信息
|
||||
func (r *SysUserImpl) InsertUser(sysUser model.SysUser) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysUser.UserID != "" {
|
||||
params["user_id"] = sysUser.UserID
|
||||
}
|
||||
if sysUser.DeptID != "" {
|
||||
params["dept_id"] = sysUser.DeptID
|
||||
}
|
||||
if sysUser.UserName != "" {
|
||||
params["user_name"] = sysUser.UserName
|
||||
}
|
||||
if sysUser.NickName != "" {
|
||||
params["nick_name"] = sysUser.NickName
|
||||
}
|
||||
if sysUser.UserType != "" {
|
||||
params["user_type"] = sysUser.UserType
|
||||
}
|
||||
if sysUser.Avatar != "" {
|
||||
params["avatar"] = sysUser.Avatar
|
||||
}
|
||||
if sysUser.Email != "" {
|
||||
params["email"] = sysUser.Email
|
||||
}
|
||||
if sysUser.PhoneNumber != "" {
|
||||
params["phonenumber"] = sysUser.PhoneNumber
|
||||
}
|
||||
if sysUser.Sex != "" {
|
||||
params["sex"] = sysUser.Sex
|
||||
}
|
||||
if sysUser.Password != "" {
|
||||
password := crypto.BcryptHash(sysUser.Password)
|
||||
params["password"] = password
|
||||
}
|
||||
if sysUser.Status != "" {
|
||||
params["status"] = sysUser.Status
|
||||
}
|
||||
if sysUser.Remark != "" {
|
||||
params["remark"] = sysUser.Remark
|
||||
}
|
||||
if sysUser.CreateBy != "" {
|
||||
params["create_by"] = sysUser.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_user (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateUser 修改用户信息
|
||||
func (r *SysUserImpl) UpdateUser(sysUser model.SysUser) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysUser.DeptID != "" {
|
||||
params["dept_id"] = sysUser.DeptID
|
||||
}
|
||||
if sysUser.UserName != "" {
|
||||
params["user_name"] = sysUser.UserName
|
||||
}
|
||||
if sysUser.NickName != "" {
|
||||
params["nick_name"] = sysUser.NickName
|
||||
}
|
||||
if sysUser.UserType != "" {
|
||||
params["user_type"] = sysUser.UserType
|
||||
}
|
||||
if sysUser.Avatar != "" {
|
||||
params["avatar"] = sysUser.Avatar
|
||||
}
|
||||
if sysUser.Email != "" {
|
||||
if sysUser.Email == "nil" {
|
||||
params["email"] = ""
|
||||
} else {
|
||||
params["email"] = sysUser.Email
|
||||
}
|
||||
}
|
||||
if sysUser.PhoneNumber != "" {
|
||||
if sysUser.PhoneNumber == "nil" {
|
||||
params["phonenumber"] = ""
|
||||
} else {
|
||||
params["phonenumber"] = sysUser.PhoneNumber
|
||||
}
|
||||
}
|
||||
if sysUser.Sex != "" {
|
||||
params["sex"] = sysUser.Sex
|
||||
}
|
||||
if sysUser.Password != "" {
|
||||
password := crypto.BcryptHash(sysUser.Password)
|
||||
params["password"] = password
|
||||
}
|
||||
if sysUser.Status != "" {
|
||||
params["status"] = sysUser.Status
|
||||
}
|
||||
if sysUser.Remark != "" {
|
||||
params["remark"] = sysUser.Remark
|
||||
}
|
||||
if sysUser.UpdateBy != "" {
|
||||
params["update_by"] = sysUser.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
if sysUser.LoginIP != "" {
|
||||
params["login_ip"] = sysUser.LoginIP
|
||||
}
|
||||
if sysUser.LoginDate > 0 {
|
||||
params["login_date"] = sysUser.LoginDate
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_user set " + strings.Join(keys, ",") + " where user_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysUser.UserID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteUserByIds 批量删除用户信息
|
||||
func (r *SysUserImpl) DeleteUserByIds(userIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
|
||||
sql := "update sys_user set del_flag = '1' where user_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(userIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("update err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CheckUniqueUser 校验用户信息是否唯一
|
||||
func (r *SysUserImpl) CheckUniqueUser(sysUser model.SysUser) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysUser.UserName != "" {
|
||||
conditions = append(conditions, "user_name = ?")
|
||||
params = append(params, sysUser.UserName)
|
||||
}
|
||||
if sysUser.PhoneNumber != "" {
|
||||
conditions = append(conditions, "phonenumber = ?")
|
||||
params = append(params, sysUser.PhoneNumber)
|
||||
}
|
||||
if sysUser.Email != "" {
|
||||
conditions = append(conditions, "email = ?")
|
||||
params = append(params, sysUser.Email)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select user_id as 'str' from sys_user " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
15
src/modules/system/repository/sys_user_post.go
Normal file
15
src/modules/system/repository/sys_user_post.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysUserPost 用户与岗位关联表 数据层接口
|
||||
type ISysUserPost interface {
|
||||
// CountUserPostByPostId 通过岗位ID查询岗位使用数量
|
||||
CountUserPostByPostId(postId string) int64
|
||||
|
||||
// BatchUserPost 批量新增用户岗位信息
|
||||
BatchUserPost(sysUserPosts []model.SysUserPost) int64
|
||||
|
||||
// DeleteUserPost 批量删除用户和岗位关联
|
||||
DeleteUserPost(userIds []string) int64
|
||||
}
|
||||
60
src/modules/system/repository/sys_user_post.impl.go
Normal file
60
src/modules/system/repository/sys_user_post.impl.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysUserPostImpl 结构体
|
||||
var NewSysUserPostImpl = &SysUserPostImpl{}
|
||||
|
||||
// SysUserPostImpl 用户与岗位关联表 数据层处理
|
||||
type SysUserPostImpl struct{}
|
||||
|
||||
// CountUserPostByPostId 通过岗位ID查询岗位使用数量
|
||||
func (r *SysUserPostImpl) CountUserPostByPostId(postId string) int64 {
|
||||
querySql := "select count(1) as total from sys_user_role where role_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{postId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// DeleteUserPost 批量删除用户和岗位关联
|
||||
func (r *SysUserPostImpl) DeleteUserPost(userIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
|
||||
sql := "delete from sys_user_post where user_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(userIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// BatchUserPost 批量新增用户岗位信息
|
||||
func (r *SysUserPostImpl) BatchUserPost(sysUserPosts []model.SysUserPost) int64 {
|
||||
keyValues := make([]string, 0)
|
||||
for _, item := range sysUserPosts {
|
||||
keyValues = append(keyValues, fmt.Sprintf("(%s,%s)", item.UserID, item.PostID))
|
||||
}
|
||||
sql := "insert into sys_user_post(user_id, post_id) values " + strings.Join(keyValues, ",")
|
||||
results, err := datasource.ExecDB("", sql, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
18
src/modules/system/repository/sys_user_role.go
Normal file
18
src/modules/system/repository/sys_user_role.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package repository
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysUserRole 用户与角色关联表 数据层接口
|
||||
type ISysUserRole interface {
|
||||
// CountUserRoleByRoleId 通过角色ID查询角色使用数量
|
||||
CountUserRoleByRoleId(roleId string) int64
|
||||
|
||||
// BatchUserRole 批量新增用户角色信息
|
||||
BatchUserRole(sysUserRoles []model.SysUserRole) int64
|
||||
|
||||
// DeleteUserRole 批量删除用户和角色关联
|
||||
DeleteUserRole(userIds []string) int64
|
||||
|
||||
// DeleteUserRoleByRoleId 批量取消授权用户角色
|
||||
DeleteUserRoleByRoleId(roleId string, userIds []string) int64
|
||||
}
|
||||
74
src/modules/system/repository/sys_user_role.impl.go
Normal file
74
src/modules/system/repository/sys_user_role.impl.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/datasource"
|
||||
"ems.agt/src/framework/logger"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/repo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysUserRoleImpl 结构体
|
||||
var NewSysUserRoleImpl = &SysUserRoleImpl{}
|
||||
|
||||
// SysUserRoleImpl 用户与角色关联表 数据层处理
|
||||
type SysUserRoleImpl struct{}
|
||||
|
||||
// CountUserRoleByRoleId 通过角色ID查询角色使用数量
|
||||
func (r *SysUserRoleImpl) CountUserRoleByRoleId(roleId string) int64 {
|
||||
querySql := "select count(1) as total from sys_user_role where role_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{roleId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// BatchUserRole 批量新增用户角色信息
|
||||
func (r *SysUserRoleImpl) BatchUserRole(sysUserRoles []model.SysUserRole) int64 {
|
||||
keyValues := make([]string, 0)
|
||||
for _, item := range sysUserRoles {
|
||||
keyValues = append(keyValues, fmt.Sprintf("(%s,%s)", item.UserID, item.RoleID))
|
||||
}
|
||||
sql := "insert into sys_user_role(user_id, role_id) values " + strings.Join(keyValues, ",")
|
||||
results, err := datasource.ExecDB("", sql, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteUserRole 批量删除用户和角色关联
|
||||
func (r *SysUserRoleImpl) DeleteUserRole(userIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
|
||||
sql := "delete from sys_user_role where user_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(userIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteUserRoleByRoleId 批量取消授权用户角色
|
||||
func (r *SysUserRoleImpl) DeleteUserRoleByRoleId(roleId string, userIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(userIds))
|
||||
sql := "delete from sys_user_role where role_id= ? and user_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(userIds)
|
||||
parameters = append([]any{roleId}, parameters...)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
30
src/modules/system/service/sys_config.go
Normal file
30
src/modules/system/service/sys_config.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package service
|
||||
|
||||
import "ems.agt/src/modules/system/model"
|
||||
|
||||
// ISysConfig 参数配置 服务层接口
|
||||
type ISysConfig interface {
|
||||
// SelectDictDataPage 分页查询参数配置列表数据
|
||||
SelectConfigPage(query map[string]any) map[string]any
|
||||
|
||||
// SelectConfigValueByKey 通过参数键名查询参数键值
|
||||
SelectConfigValueByKey(configKey string) string
|
||||
|
||||
// SelectConfigById 通过配置ID查询参数配置信息
|
||||
SelectConfigById(configId string) model.SysConfig
|
||||
|
||||
// CheckUniqueConfigKey 校验参数键名是否唯一
|
||||
CheckUniqueConfigKey(configKey, configId string) bool
|
||||
|
||||
// InsertConfig 新增参数配置
|
||||
InsertConfig(sysConfig model.SysConfig) string
|
||||
|
||||
// UpdateConfig 修改参数配置
|
||||
UpdateConfig(sysConfig model.SysConfig) int64
|
||||
|
||||
// DeleteConfigByIds 批量删除参数配置信息
|
||||
DeleteConfigByIds(configIds []string) (int64, error)
|
||||
|
||||
// ResetConfigCache 重置参数缓存数据
|
||||
ResetConfigCache()
|
||||
}
|
||||
157
src/modules/system/service/sys_config.impl.go
Normal file
157
src/modules/system/service/sys_config.impl.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"ems.agt/src/framework/constants/cachekey"
|
||||
"ems.agt/src/framework/redis"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysConfigImpl 结构体
|
||||
var NewSysConfigImpl = &SysConfigImpl{
|
||||
sysConfigRepository: repository.NewSysConfigImpl,
|
||||
}
|
||||
|
||||
// SysConfigImpl 参数配置 服务层处理
|
||||
type SysConfigImpl struct {
|
||||
// 参数配置表
|
||||
sysConfigRepository repository.ISysConfig
|
||||
}
|
||||
|
||||
// SelectDictDataPage 分页查询参数配置列表数据
|
||||
func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any {
|
||||
return r.sysConfigRepository.SelectConfigPage(query)
|
||||
}
|
||||
|
||||
// SelectConfigList 查询参数配置列表
|
||||
func (r *SysConfigImpl) SelectConfigList(sysConfig model.SysConfig) []model.SysConfig {
|
||||
return r.sysConfigRepository.SelectConfigList(sysConfig)
|
||||
}
|
||||
|
||||
// SelectConfigValueByKey 通过参数键名查询参数键值
|
||||
func (r *SysConfigImpl) SelectConfigValueByKey(configKey string) string {
|
||||
cacheKey := r.getCacheKey(configKey)
|
||||
// 从缓存中读取
|
||||
cacheValue, err := redis.Get("", cacheKey)
|
||||
if cacheValue != "" || err != nil {
|
||||
return cacheValue
|
||||
}
|
||||
// 无缓存时读取数据放入缓存中
|
||||
configValue := r.sysConfigRepository.SelectConfigValueByKey(configKey)
|
||||
if configValue != "" {
|
||||
redis.Set("", cacheKey, configValue)
|
||||
return configValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectConfigById 通过配置ID查询参数配置信息
|
||||
func (r *SysConfigImpl) SelectConfigById(configId string) model.SysConfig {
|
||||
if configId == "" {
|
||||
return model.SysConfig{}
|
||||
}
|
||||
configs := r.sysConfigRepository.SelectConfigByIds([]string{configId})
|
||||
if len(configs) > 0 {
|
||||
return configs[0]
|
||||
}
|
||||
return model.SysConfig{}
|
||||
}
|
||||
|
||||
// CheckUniqueConfigKey 校验参数键名是否唯一
|
||||
func (r *SysConfigImpl) CheckUniqueConfigKey(configKey, configId string) bool {
|
||||
uniqueId := r.sysConfigRepository.CheckUniqueConfig(model.SysConfig{
|
||||
ConfigKey: configKey,
|
||||
})
|
||||
if uniqueId == configId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// InsertConfig 新增参数配置
|
||||
func (r *SysConfigImpl) InsertConfig(sysConfig model.SysConfig) string {
|
||||
configId := r.sysConfigRepository.InsertConfig(sysConfig)
|
||||
if configId != "" {
|
||||
r.loadingConfigCache(sysConfig.ConfigKey)
|
||||
}
|
||||
return configId
|
||||
}
|
||||
|
||||
// UpdateConfig 修改参数配置
|
||||
func (r *SysConfigImpl) UpdateConfig(sysConfig model.SysConfig) int64 {
|
||||
rows := r.sysConfigRepository.UpdateConfig(sysConfig)
|
||||
if rows > 0 {
|
||||
r.loadingConfigCache(sysConfig.ConfigKey)
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteConfigByIds 批量删除参数配置信息
|
||||
func (r *SysConfigImpl) DeleteConfigByIds(configIds []string) (int64, error) {
|
||||
// 检查是否存在
|
||||
configs := r.sysConfigRepository.SelectConfigByIds(configIds)
|
||||
if len(configs) <= 0 {
|
||||
return 0, errors.New("没有权限访问参数配置数据!")
|
||||
}
|
||||
for _, config := range configs {
|
||||
// 检查是否为内置参数
|
||||
if config.ConfigType == "Y" {
|
||||
return 0, errors.New(config.ConfigID + " 配置参数属于内置参数,禁止删除!")
|
||||
}
|
||||
// 清除缓存
|
||||
r.clearConfigCache(config.ConfigKey)
|
||||
}
|
||||
if len(configs) == len(configIds) {
|
||||
rows := r.sysConfigRepository.DeleteConfigByIds(configIds)
|
||||
return rows, nil
|
||||
}
|
||||
return 0, errors.New("删除参数配置信息失败!")
|
||||
}
|
||||
|
||||
// ResetConfigCache 重置参数缓存数据
|
||||
func (r *SysConfigImpl) ResetConfigCache() {
|
||||
r.clearConfigCache("*")
|
||||
r.loadingConfigCache("*")
|
||||
}
|
||||
|
||||
// getCacheKey 组装缓存key
|
||||
func (r *SysConfigImpl) getCacheKey(configKey string) string {
|
||||
return cachekey.SYS_CONFIG_KEY + configKey
|
||||
}
|
||||
|
||||
// loadingConfigCache 加载参数缓存数据
|
||||
func (r *SysConfigImpl) loadingConfigCache(configKey string) {
|
||||
// 查询全部参数
|
||||
if configKey == "*" {
|
||||
sysConfigs := r.SelectConfigList(model.SysConfig{})
|
||||
for _, v := range sysConfigs {
|
||||
key := r.getCacheKey(v.ConfigKey)
|
||||
redis.Del("", key)
|
||||
redis.Set("", key, v.ConfigValue)
|
||||
}
|
||||
return
|
||||
}
|
||||
// 指定参数
|
||||
if configKey != "" {
|
||||
cacheValue := r.sysConfigRepository.SelectConfigValueByKey(configKey)
|
||||
if cacheValue != "" {
|
||||
key := r.getCacheKey(configKey)
|
||||
redis.Del("", key)
|
||||
redis.Set("", key, cacheValue)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// clearConfigCache 清空参数缓存数据
|
||||
func (r *SysConfigImpl) clearConfigCache(configKey string) bool {
|
||||
key := r.getCacheKey(configKey)
|
||||
keys, err := redis.GetKeys("", key)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
delOk, _ := redis.DelKeys("", keys)
|
||||
return delOk
|
||||
}
|
||||
39
src/modules/system/service/sys_dept.go
Normal file
39
src/modules/system/service/sys_dept.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"ems.agt/src/framework/vo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
)
|
||||
|
||||
// ISysDept 部门管理 服务层接口
|
||||
type ISysDept interface {
|
||||
// SelectDeptList 查询部门管理数据
|
||||
SelectDeptList(sysDept model.SysDept, dataScopeSQL string) []model.SysDept
|
||||
|
||||
// SelectDeptListByRoleId 根据角色ID查询部门树信息
|
||||
SelectDeptListByRoleId(roleId string) []string
|
||||
|
||||
// SelectDeptById 根据部门ID查询信息
|
||||
SelectDeptById(deptId string) model.SysDept
|
||||
|
||||
// HasChildByDeptId 是否存在子节点
|
||||
HasChildByDeptId(deptId string) int64
|
||||
|
||||
// CheckDeptExistUser 查询部门是否存在用户
|
||||
CheckDeptExistUser(deptId string) int64
|
||||
|
||||
// CheckUniqueDeptName 校验同级部门名称是否唯一
|
||||
CheckUniqueDeptName(deptName, parentId, deptId string) bool
|
||||
|
||||
// InsertDept 新增部门信息
|
||||
InsertDept(sysDept model.SysDept) string
|
||||
|
||||
// UpdateDept 修改部门信息
|
||||
UpdateDept(sysDept model.SysDept) int64
|
||||
|
||||
// DeleteDeptById 删除部门管理信息
|
||||
DeleteDeptById(deptId string) int64
|
||||
|
||||
// SelectDeptTreeSelect 查询部门树结构信息
|
||||
SelectDeptTreeSelect(sysDept model.SysDept, dataScopeSQL string) []vo.TreeSelect
|
||||
}
|
||||
202
src/modules/system/service/sys_dept.impl.go
Normal file
202
src/modules/system/service/sys_dept.impl.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"ems.agt/src/framework/constants/common"
|
||||
"ems.agt/src/framework/vo"
|
||||
"ems.agt/src/modules/system/model"
|
||||
"ems.agt/src/modules/system/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysDeptImpl 结构体
|
||||
var NewSysDeptImpl = &SysDeptImpl{
|
||||
sysDeptRepository: repository.NewSysDeptImpl,
|
||||
sysRoleRepository: repository.NewSysRoleImpl,
|
||||
sysRoleDeptRepository: repository.NewSysRoleDeptImpl,
|
||||
}
|
||||
|
||||
// SysDeptImpl 部门表 服务层处理
|
||||
type SysDeptImpl struct {
|
||||
// 部门服务
|
||||
sysDeptRepository repository.ISysDept
|
||||
// 角色服务
|
||||
sysRoleRepository repository.ISysRole
|
||||
// 角色与部门关联服务
|
||||
sysRoleDeptRepository repository.ISysRoleDept
|
||||
}
|
||||
|
||||
// SelectDeptList 查询部门管理数据
|
||||
func (r *SysDeptImpl) SelectDeptList(sysDept model.SysDept, dataScopeSQL string) []model.SysDept {
|
||||
return r.sysDeptRepository.SelectDeptList(sysDept, dataScopeSQL)
|
||||
}
|
||||
|
||||
// SelectDeptListByRoleId 根据角色ID查询部门树信息 TODO
|
||||
func (r *SysDeptImpl) SelectDeptListByRoleId(roleId string) []string {
|
||||
roles := r.sysRoleRepository.SelectRoleByIds([]string{roleId})
|
||||
if len(roles) > 0 {
|
||||
role := roles[0]
|
||||
if role.RoleID == roleId {
|
||||
return r.sysDeptRepository.SelectDeptListByRoleId(
|
||||
role.RoleID,
|
||||
role.DeptCheckStrictly == "1",
|
||||
)
|
||||
}
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectDeptById 根据部门ID查询信息
|
||||
func (r *SysDeptImpl) SelectDeptById(deptId string) model.SysDept {
|
||||
return r.sysDeptRepository.SelectDeptById(deptId)
|
||||
}
|
||||
|
||||
// HasChildByDeptId 是否存在子节点
|
||||
func (r *SysDeptImpl) HasChildByDeptId(deptId string) int64 {
|
||||
return r.sysDeptRepository.HasChildByDeptId(deptId)
|
||||
}
|
||||
|
||||
// CheckDeptExistUser 查询部门是否存在用户
|
||||
func (r *SysDeptImpl) CheckDeptExistUser(deptId string) int64 {
|
||||
return r.sysDeptRepository.CheckDeptExistUser(deptId)
|
||||
}
|
||||
|
||||
// CheckUniqueDeptName 校验同级部门名称是否唯一
|
||||
func (r *SysDeptImpl) CheckUniqueDeptName(deptName, parentId, deptId string) bool {
|
||||
uniqueId := r.sysDeptRepository.CheckUniqueDept(model.SysDept{
|
||||
DeptName: deptName,
|
||||
ParentID: parentId,
|
||||
})
|
||||
if uniqueId == deptId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// InsertDept 新增部门信息
|
||||
func (r *SysDeptImpl) InsertDept(sysDept model.SysDept) string {
|
||||
return r.sysDeptRepository.InsertDept(sysDept)
|
||||
}
|
||||
|
||||
// UpdateDept 修改部门信息
|
||||
func (r *SysDeptImpl) UpdateDept(sysDept model.SysDept) int64 {
|
||||
parentDept := r.sysDeptRepository.SelectDeptById(sysDept.ParentID)
|
||||
dept := r.sysDeptRepository.SelectDeptById(sysDept.DeptID)
|
||||
// 上级与当前部门祖级列表更新
|
||||
if parentDept.DeptID == sysDept.ParentID && dept.DeptID == sysDept.DeptID {
|
||||
newAncestors := parentDept.Ancestors + "," + parentDept.DeptID
|
||||
oldAncestors := dept.Ancestors
|
||||
// 祖级列表不一致时更新
|
||||
if newAncestors != oldAncestors {
|
||||
sysDept.Ancestors = newAncestors
|
||||
r.updateDeptChildren(sysDept.DeptID, newAncestors, oldAncestors)
|
||||
}
|
||||
}
|
||||
// 如果该部门是启用状态,则启用该部门的所有上级部门
|
||||
if sysDept.Status == common.STATUS_YES && parentDept.Status == common.STATUS_NO {
|
||||
r.updateDeptStatusNormal(sysDept.Ancestors)
|
||||
}
|
||||
return r.sysDeptRepository.UpdateDept(sysDept)
|
||||
}
|
||||
|
||||
// updateDeptStatusNormal 修改所在部门正常状态
|
||||
func (r *SysDeptImpl) updateDeptStatusNormal(ancestors string) int64 {
|
||||
if ancestors == "" || ancestors == "0" {
|
||||
return 0
|
||||
}
|
||||
deptIds := strings.Split(ancestors, ",")
|
||||
return r.sysDeptRepository.UpdateDeptStatusNormal(deptIds)
|
||||
}
|
||||
|
||||
// updateDeptChildren 修改子元素关系
|
||||
func (r *SysDeptImpl) updateDeptChildren(deptId, newAncestors, oldAncestors string) int64 {
|
||||
childrens := r.sysDeptRepository.SelectChildrenDeptById(deptId)
|
||||
if len(childrens) == 0 {
|
||||
return 0
|
||||
}
|
||||
// 替换父ID
|
||||
for i := range childrens {
|
||||
child := &childrens[i]
|
||||
ancestors := strings.Replace(child.Ancestors, oldAncestors, newAncestors, -1)
|
||||
child.Ancestors = ancestors
|
||||
}
|
||||
return r.sysDeptRepository.UpdateDeptChildren(childrens)
|
||||
}
|
||||
|
||||
// DeleteDeptById 删除部门管理信息
|
||||
func (r *SysDeptImpl) DeleteDeptById(deptId string) int64 {
|
||||
// 删除角色与部门关联
|
||||
r.sysRoleDeptRepository.DeleteDeptRole([]string{deptId})
|
||||
return r.sysDeptRepository.DeleteDeptById(deptId)
|
||||
}
|
||||
|
||||
// SelectDeptTreeSelect 查询部门树结构信息
|
||||
func (r *SysDeptImpl) SelectDeptTreeSelect(sysDept model.SysDept, dataScopeSQL string) []vo.TreeSelect {
|
||||
sysDepts := r.sysDeptRepository.SelectDeptList(sysDept, dataScopeSQL)
|
||||
depts := r.parseDataToTree(sysDepts)
|
||||
tree := make([]vo.TreeSelect, 0)
|
||||
for _, dept := range depts {
|
||||
tree = append(tree, vo.SysDeptTreeSelect(dept))
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// parseDataToTree 将数据解析为树结构,构建前端所需要下拉树结构
|
||||
func (r *SysDeptImpl) parseDataToTree(sysDepts []model.SysDept) []model.SysDept {
|
||||
// 节点分组
|
||||
nodesMap := make(map[string][]model.SysDept)
|
||||
// 节点id
|
||||
treeIds := []string{}
|
||||
// 树节点
|
||||
tree := []model.SysDept{}
|
||||
|
||||
for _, item := range sysDepts {
|
||||
parentID := item.ParentID
|
||||
// 分组
|
||||
mapItem, ok := nodesMap[parentID]
|
||||
if !ok {
|
||||
mapItem = []model.SysDept{}
|
||||
}
|
||||
mapItem = append(mapItem, item)
|
||||
nodesMap[parentID] = mapItem
|
||||
// 记录节点ID
|
||||
treeIds = append(treeIds, item.DeptID)
|
||||
}
|
||||
|
||||
for key, value := range nodesMap {
|
||||
// 选择不是节点ID的作为树节点
|
||||
found := false
|
||||
for _, id := range treeIds {
|
||||
if id == key {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
tree = append(tree, value...)
|
||||
}
|
||||
}
|
||||
|
||||
for i, node := range tree {
|
||||
iN := r.parseDataToTreeComponet(node, &nodesMap)
|
||||
tree[i] = iN
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
// parseDataToTreeComponet 递归函数处理子节点
|
||||
func (r *SysDeptImpl) parseDataToTreeComponet(node model.SysDept, nodesMap *map[string][]model.SysDept) model.SysDept {
|
||||
id := node.DeptID
|
||||
children, ok := (*nodesMap)[id]
|
||||
if ok {
|
||||
node.Children = children
|
||||
}
|
||||
if len(node.Children) > 0 {
|
||||
for i, child := range node.Children {
|
||||
icN := r.parseDataToTreeComponet(child, nodesMap)
|
||||
node.Children[i] = icN
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user