feat: 合并Gin_Vue

This commit is contained in:
TsMask
2023-10-16 17:10:38 +08:00
parent 5289818fd4
commit 40a32cb67f
203 changed files with 19719 additions and 178 deletions

View 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)
}

View 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,
}))
}

View 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)
}

View 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)
}

View 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)
}

View 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)
}

View 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,
}))
}

View 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))
}

View 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)
}

View 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))
}

View 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)
}

View 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))
}