feat: 实现 MVP-1 管理端 API 与凭据审计 (#23)

This commit is contained in:
ila
2026-08-21 23:08:08 +08:00
parent 4bb63f2b2a
commit 64f917b9c5
135 changed files with 13297 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/admin.exe
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 go-admin-team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+37
View File
@@ -0,0 +1,37 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/captcha"
)
type System struct {
api.Api
}
// GenerateCaptchaHandler 获取验证码
// @Summary 获取验证码
// @Description 获取验证码
// @Tags 登陆
// @Success 200 {object} response.Response{data=string,id=string,msg=string} "{"code": 200, "data": [...]}"
// @Router /api/v1/captcha [get]
func (e System) GenerateCaptchaHandler(c *gin.Context) {
if err := e.MakeContext(c).Errors; err != nil {
e.Error(500, err, "服务初始化失败!")
return
}
id, b64s, answer, err := captcha.DriverDigitFunc()
if err != nil {
e.Logger.Errorf("DriverDigitFunc error, %s", err.Error())
e.Error(500, err, "验证码获取失败")
return
}
e.Logger.Infof("DriverDigitFunc answer: %s", answer)
e.Custom(gin.H{
"code": 200,
"data": b64s,
"id": id,
"msg": "success",
})
}
+39
View File
@@ -0,0 +1,39 @@
package apis
import (
"github.com/gin-gonic/gin"
)
const INDEX = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GO-ADMIN欢迎您</title>
<style>
body{
margin:0;
padding:0;
overflow-y:hidden
}
</style>
<script src="https://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script type="text/javascript">
window.onerror=function(){return true;}
$(function(){
headerH = 0;
var h=$(window).height();
$("#iframe").height((h-headerH)+"px");
});
</script>
</head>
<body>
<iframe id="iframe" frameborder="0" src="https://www.go-admin.pro" style="width:100%;"></iframe>
</body>
</html>
`
func GoAdmin(c *gin.Context) {
c.Header("Content-Type", "text/html; charset=utf-8")
c.String(200, INDEX)
}
+148
View File
@@ -0,0 +1,148 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
"git.ilapage.cn/OPC/chorus/admin/common/actions"
)
type SysApi struct {
api.Api
}
// GetPage 获取接口管理列表
// @Summary 获取接口管理列表
// @Description 获取接口管理列表
// @Tags 接口管理
// @Param name query string false "名称"
// @Param title query string false "标题"
// @Param path query string false "地址"
// @Param action query string false "类型"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Success 200 {object} response.Response{data=response.Page{list=[]models.SysApi}} "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-api [get]
// @Security Bearer
func (e SysApi) GetPage(c *gin.Context) {
s := service.SysApi{}
req := dto.SysApiGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
//数据权限检查
p := actions.GetPermissionFromContext(c)
list := make([]models.SysApi, 0)
var count int64
err = s.GetPage(&req, p, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get 获取接口管理
// @Summary 获取接口管理
// @Description 获取接口管理
// @Tags 接口管理
// @Param id path string false "id"
// @Success 200 {object} response.Response{data=models.SysApi} "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-api/{id} [get]
// @Security Bearer
func (e SysApi) Get(c *gin.Context) {
req := dto.SysApiGetReq{}
s := service.SysApi{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
p := actions.GetPermissionFromContext(c)
var object models.SysApi
err = s.Get(&req, p, &object).Error
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Update 修改接口管理
// @Summary 修改接口管理
// @Description 修改接口管理
// @Tags 接口管理
// @Accept application/json
// @Product application/json
// @Param data body dto.SysApiUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}"
// @Router /api/v1/sys-api/{id} [put]
// @Security Bearer
func (e SysApi) Update(c *gin.Context) {
req := dto.SysApiUpdateReq{}
s := service.SysApi{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
return
}
req.SetUpdateBy(user.GetUserId(c))
p := actions.GetPermissionFromContext(c)
err = s.Update(&req, p)
if err != nil {
e.Error(500, err, "更新失败")
return
}
e.OK(req.GetId(), "更新成功")
}
// DeleteSysApi 删除接口管理
// @Summary 删除接口管理
// @Description 删除接口管理
// @Tags 接口管理
// @Param data body dto.SysApiDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}"
// @Router /api/v1/sys-api [delete]
// @Security Bearer
func (e SysApi) DeleteSysApi(c *gin.Context) {
req := dto.SysApiDeleteReq{}
s := service.SysApi{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
return
}
p := actions.GetPermissionFromContext(c)
err = s.Remove(&req, p)
if err != nil {
e.Error(500, err, "删除失败")
return
}
e.OK(req.GetId(), "删除成功")
}
+313
View File
@@ -0,0 +1,313 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysConfig struct {
api.Api
}
// GetPage 获取配置管理列表
// @Summary 获取配置管理列表
// @Description 获取配置管理列表
// @Tags 配置管理
// @Param configName query string false "名称"
// @Param configKey query string false "key"
// @Param configType query string false "类型"
// @Param isFrontend query int false "是否前端"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Success 200 {object} response.Response{data=response.Page{list=[]models.SysApi}} "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-config [get]
// @Security Bearer
func (e SysConfig) GetPage(c *gin.Context) {
s := service.SysConfig{}
req := dto.SysConfigGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
return
}
list := make([]models.SysConfig, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get 获取配置管理
// @Summary 获取配置管理
// @Description 获取配置管理
// @Tags 配置管理
// @Param id path string false "id"
// @Success 200 {object} response.Response{data=models.SysConfig} "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-config/{id} [get]
// @Security Bearer
func (e SysConfig) Get(c *gin.Context) {
req := dto.SysConfigGetReq{}
s := service.SysConfig{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysConfig
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(object, "查询成功")
}
// Insert 创建配置管理
// @Summary 创建配置管理
// @Description 创建配置管理
// @Tags 配置管理
// @Accept application/json
// @Product application/json
// @Param data body dto.SysConfigControl true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "创建成功"}"
// @Router /api/v1/sys-config [post]
// @Security Bearer
func (e SysConfig) Insert(c *gin.Context) {
s := service.SysConfig{}
req := dto.SysConfigControl{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Error(500, err, "创建失败")
return
}
e.OK(req.GetId(), "创建成功")
}
// Update 修改配置管理
// @Summary 修改配置管理
// @Description 修改配置管理
// @Tags 配置管理
// @Accept application/json
// @Product application/json
// @Param data body dto.SysConfigControl true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}"
// @Router /api/v1/sys-config/{id} [put]
// @Security Bearer
func (e SysConfig) Update(c *gin.Context) {
s := service.SysConfig{}
req := dto.SysConfigControl{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req)
if err != nil {
e.Error(500, err, "更新失败")
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete 删除配置管理
// @Summary 删除配置管理
// @Description 删除配置管理
// @Tags 配置管理
// @Param ids body []int false "ids"
// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}"
// @Router /api/v1/sys-config [delete]
// @Security Bearer
func (e SysConfig) Delete(c *gin.Context) {
s := service.SysConfig{}
req := dto.SysConfigDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Remove(&req)
if err != nil {
e.Error(500, err, "删除失败")
return
}
e.OK(req.GetId(), "删除成功")
}
// Get2SysApp 获取系统配置信息
// @Summary 获取系统前台配置信息,主要注意这里不在验证权限
// @Description 获取系统配置信息,主要注意这里不在验证权限
// @Tags 配置管理
// @Success 200 {object} response.Response{data=map[string]string} "{"code": 200, "data": [...]}"
// @Router /api/v1/app-config [get]
func (e SysConfig) Get2SysApp(c *gin.Context) {
req := dto.SysConfigGetToSysAppReq{}
s := service.SysConfig{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
return
}
// 控制只读前台的数据
req.IsFrontend = "1"
list := make([]models.SysConfig, 0)
err = s.GetWithKeyList(&req, &list)
if err != nil {
e.Error(500, err, "查询失败")
return
}
mp := make(map[string]string)
for i := 0; i < len(list); i++ {
key := list[i].ConfigKey
if key != "" {
mp[key] = list[i].ConfigValue
}
}
e.OK(mp, "查询成功")
}
// Get2Set 获取配置
// @Summary 获取配置
// @Description 界面操作设置配置值的获取
// @Tags 配置管理
// @Accept application/json
// @Product application/json
// @Success 200 {object} response.Response{data=map[string]interface{}} "{"code": 200, "message": "修改成功"}"
// @Router /api/v1/set-config [get]
// @Security Bearer
func (e SysConfig) Get2Set(c *gin.Context) {
s := service.SysConfig{}
req := make([]dto.GetSetSysConfigReq, 0)
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.GetForSet(&req)
if err != nil {
e.Error(500, err, "查询失败")
return
}
m := make(map[string]interface{}, 0)
for _, v := range req {
m[v.ConfigKey] = v.ConfigValue
}
e.OK(m, "查询成功")
}
// Update2Set 设置配置
// @Summary 设置配置
// @Description 界面操作设置配置值
// @Tags 配置管理
// @Accept application/json
// @Product application/json
// @Param data body []dto.GetSetSysConfigReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}"
// @Router /api/v1/set-config [put]
// @Security Bearer
func (e SysConfig) Update2Set(c *gin.Context) {
s := service.SysConfig{}
req := make([]dto.GetSetSysConfigReq, 0)
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.UpdateForSet(&req)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK("", "更新成功")
}
// GetSysConfigByKEYForService 根据Key获取SysConfig的Service
// @Summary 根据Key获取SysConfig的Service
// @Description 根据Key获取SysConfig的Service
// @Tags 配置管理
// @Param configKey path string false "configKey"
// @Success 200 {object} response.Response{data=dto.SysConfigByKeyReq} "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-config/{id} [get]
// @Security Bearer
func (e SysConfig) GetSysConfigByKEYForService(c *gin.Context) {
var s = new(service.SysConfig)
var req = new(dto.SysConfigByKeyReq)
var resp = new(dto.GetSysConfigByKEYForServiceResp)
err := e.MakeContext(c).
MakeOrm().
Bind(req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.GetWithKey(req, resp)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(resp, s.Msg)
}
+238
View File
@@ -0,0 +1,238 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysDept struct {
api.Api
}
// GetPage
// @Summary 分页部门列表数据
// @Description 分页列表
// @Tags 部门
// @Param deptName query string false "deptName"
// @Param deptId query string false "deptId"
// @Param position query string false "position"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dept [get]
// @Security Bearer
func (e SysDept) GetPage(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysDept, 0)
list, err = s.SetDeptPage(&req)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(list, "查询成功")
}
// Get
// @Summary 获取部门数据
// @Description 获取JSON
// @Tags 部门
// @Param deptId path string false "deptId"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dept/{deptId} [get]
// @Security Bearer
func (e SysDept) Get(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysDept
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Insert 添加部门
// @Summary 添加部门
// @Description 获取JSON
// @Tags 部门
// @Accept application/json
// @Product application/json
// @Param data body dto.SysDeptInsertReq true "data"
// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
// @Router /api/v1/dept [post]
// @Security Bearer
func (e SysDept) Insert(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Error(500, err, "创建失败")
return
}
e.OK(req.GetId(), "创建成功")
}
// Update
// @Summary 修改部门
// @Description 获取JSON
// @Tags 部门
// @Accept application/json
// @Product application/json
// @Param id path int true "id"
// @Param data body dto.SysDeptUpdateReq true "body"
// @Success 200 {string} string "{"code": 200, "message": "添加成功"}"
// @Success 200 {string} string "{"code": -1, "message": "添加失败"}"
// @Router /api/v1/dept/{deptId} [put]
// @Security Bearer
func (e SysDept) Update(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除部门
// @Description 删除数据
// @Tags 部门
// @Param data body dto.SysDeptDeleteReq true "body"
// @Success 200 {string} string "{"code": 200, "message": "删除成功"}"
// @Success 200 {string} string "{"code": -1, "message": "删除失败"}"
// @Router /api/v1/dept [delete]
// @Security Bearer
func (e SysDept) Delete(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.Remove(&req)
if err != nil {
e.Error(500, err, "删除失败")
return
}
e.OK(req.GetId(), "删除成功")
}
// Get2Tree 用户管理 左侧部门树
func (e SysDept) Get2Tree(c *gin.Context) {
s := service.SysDept{}
req := dto.SysDeptGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]dto.DeptLabel, 0)
list, err = s.SetDeptTree(&req)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(list, "")
}
// GetDeptTreeRoleSelect TODO: 此接口需要调整不应该将list和选中放在一起
func (e SysDept) GetDeptTreeRoleSelect(c *gin.Context) {
s := service.SysDept{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
id, err := pkg.StringToInt(c.Param("roleId"))
result, err := s.SetDeptLabel()
if err != nil {
e.Error(500, err, err.Error())
return
}
menuIds := make([]int, 0)
if id != 0 {
menuIds, err = s.GetWithRoleId(id)
if err != nil {
e.Error(500, err, err.Error())
return
}
}
e.OK(gin.H{
"depts": result,
"checkedKeys": menuIds,
}, "")
}
+220
View File
@@ -0,0 +1,220 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysDictData struct {
api.Api
}
// GetPage
// @Summary 字典数据列表
// @Description 获取JSON
// @Tags 字典数据
// @Param status query string false "status"
// @Param dictCode query string false "dictCode"
// @Param dictType query string false "dictType"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/data [get]
// @Security Bearer
func (e SysDictData) GetPage(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysDictData, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get
// @Summary 通过编码获取字典数据
// @Description 获取JSON
// @Tags 字典数据
// @Param dictCode path int true "字典编码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/data/{dictCode} [get]
// @Security Bearer
func (e SysDictData) Get(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysDictData
err = s.Get(&req, &object)
if err != nil {
e.Logger.Warnf("Get error: %s", err.Error())
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Insert
// @Summary 添加字典数据
// @Description 获取JSON
// @Tags 字典数据
// @Accept application/json
// @Product application/json
// @Param data body dto.SysDictDataInsertReq true "data"
// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}"
// @Router /api/v1/dict/data [post]
// @Security Bearer
func (e SysDictData) Insert(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Error(500, err, "创建失败")
return
}
e.OK(req.GetId(), "创建成功")
}
// Update
// @Summary 修改字典数据
// @Description 获取JSON
// @Tags 字典数据
// @Accept application/json
// @Product application/json
// @Param data body dto.SysDictDataUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}"
// @Router /api/v1/dict/data/{dictCode} [put]
// @Security Bearer
func (e SysDictData) Update(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req)
if err != nil {
e.Error(500, err, "更新失败")
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除字典数据
// @Description 删除数据
// @Tags 字典数据
// @Param dictCode body dto.SysDictDataDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}"
// @Router /api/v1/dict/data [delete]
// @Security Bearer
func (e SysDictData) Delete(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Remove(&req)
if err != nil {
e.Error(500, err, "删除失败")
return
}
e.OK(req.GetId(), "删除成功")
}
// GetAll 数据字典根据key获取 业务页面使用
// @Summary 数据字典根据key获取
// @Description 数据字典根据key获取
// @Tags 字典数据
// @Param dictType query int true "dictType"
// @Success 200 {object} response.Response{data=[]dto.SysDictDataGetAllResp} "{"code": 200, "data": [...]}"
// @Router /api/v1/dict-data/option-select [get]
// @Security Bearer
func (e SysDictData) GetAll(c *gin.Context) {
s := service.SysDictData{}
req := dto.SysDictDataGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysDictData, 0)
err = s.GetAll(&req, &list)
if err != nil {
e.Error(500, err, "查询失败")
return
}
l := make([]dto.SysDictDataGetAllResp, 0)
for _, i := range list {
d := dto.SysDictDataGetAllResp{}
e.Translate(i, &d)
l = append(l, d)
}
e.OK(l,"查询成功")
}
+210
View File
@@ -0,0 +1,210 @@
package apis
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysDictType struct {
api.Api
}
// GetPage 字典类型列表数据
// @Summary 字典类型列表数据
// @Description 获取JSON
// @Tags 字典类型
// @Param dictName query string false "dictName"
// @Param dictId query string false "dictId"
// @Param dictType query string false "dictType"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type [get]
// @Security Bearer
func (e SysDictType) GetPage(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysDictType, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get 字典类型通过字典id获取
// @Summary 字典类型通过字典id获取
// @Description 获取JSON
// @Tags 字典类型
// @Param dictId path int true "字典类型编码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type/{dictId} [get]
// @Security Bearer
func (e SysDictType) Get(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysDictType
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
//Insert 字典类型创建
// @Summary 添加字典类型
// @Description 获取JSON
// @Tags 字典类型
// @Accept application/json
// @Product application/json
// @Param data body dto.SysDictTypeInsertReq true "data"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type [post]
// @Security Bearer
func (e SysDictType) Insert(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Logger.Error(err)
e.Error(500, err,fmt.Sprintf(" 创建字典类型失败,详情:%s", err.Error()))
return
}
e.OK(req.GetId(), "创建成功")
}
// Update
// @Summary 修改字典类型
// @Description 获取JSON
// @Tags 字典类型
// @Accept application/json
// @Product application/json
// @Param data body dto.SysDictTypeUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type/{dictId} [put]
// @Security Bearer
func (e SysDictType) Update(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Error(500, err, err.Error())
e.Logger.Error(err)
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除字典类型
// @Description 删除数据
// @Tags 字典类型
// @Param dictCode body dto.SysDictTypeDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type [delete]
// @Security Bearer
func (e SysDictType) Delete(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Remove(&req)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(req.GetId(), "删除成功")
}
// GetAll
// @Summary 字典类型全部数据 代码生成使用接口
// @Description 获取JSON
// @Tags 字典类型
// @Param dictName query string false "dictName"
// @Param dictId query string false "dictId"
// @Param dictType query string false "dictType"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/dict/type-option-select [get]
// @Security Bearer
func (e SysDictType) GetAll(c *gin.Context) {
s := service.SysDictType{}
req :=dto.SysDictTypeGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysDictType, 0)
err = s.GetAll(&req, &list)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(list, "查询成功")
}
+110
View File
@@ -0,0 +1,110 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysLoginLog struct {
api.Api
}
// GetPage 登录日志列表
// @Summary 登录日志列表
// @Description 获取JSON
// @Tags 登录日志
// @Param username query string false "用户名"
// @Param ipaddr query string false "ip地址"
// @Param loginLocation query string false "归属地"
// @Param status query string false "状态"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-login-log [get]
// @Security Bearer
func (e SysLoginLog) GetPage(c *gin.Context) {
s := service.SysLoginLog{}
req :=dto.SysLoginLogGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysLoginLog, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get 登录日志通过id获取
// @Summary 登录日志通过id获取
// @Description 获取JSON
// @Tags 登录日志
// @Param id path string false "id"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-login-log/{id} [get]
// @Security Bearer
func (e SysLoginLog) Get(c *gin.Context) {
s := service.SysLoginLog{}
req :=dto.SysLoginLogGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysLoginLog
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Delete 登录日志删除
// @Summary 登录日志删除
// @Description 登录日志删除
// @Tags 登录日志
// @Param data body dto.SysLoginLogDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-login-log [delete]
// @Security Bearer
func (e SysLoginLog) Delete(c *gin.Context) {
s := service.SysLoginLog{}
req :=dto.SysLoginLogDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.Remove(&req)
if err != nil {
e.Error(500, err, "删除失败")
return
}
e.OK(req.GetId(), "删除成功")
}
+249
View File
@@ -0,0 +1,249 @@
package apis
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysMenu struct {
api.Api
}
// GetPage Menu列表数据
// @Summary Menu列表数据
// @Description 获取JSON
// @Tags 菜单
// @Param menuName query string false "menuName"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menu [get]
// @Security Bearer
func (e SysMenu) GetPage(c *gin.Context) {
s := service.SysMenu{}
req := dto.SysMenuGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var list = make([]models.SysMenu, 0)
err = s.GetPage(&req, &list).Error
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(list, "查询成功")
}
// Get 获取菜单详情
// @Summary Menu详情数据
// @Description 获取JSON
// @Tags 菜单
// @Param id path string false "id"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menu/{id} [get]
// @Security Bearer
func (e SysMenu) Get(c *gin.Context) {
req := dto.SysMenuGetReq{}
s := new(service.SysMenu)
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object = models.SysMenu{}
err = s.Get(&req, &object).Error
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Insert 创建菜单
// @Summary 创建菜单
// @Description 获取JSON
// @Tags 菜单
// @Accept application/json
// @Product application/json
// @Param data body dto.SysMenuInsertReq true "data"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menu [post]
// @Security Bearer
func (e SysMenu) Insert(c *gin.Context) {
req := dto.SysMenuInsertReq{}
s := new(service.SysMenu)
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req).Error
if err != nil {
e.Error(500, err, "创建失败")
return
}
e.OK(req.GetId(), "创建成功")
}
// Update 修改菜单
// @Summary 修改菜单
// @Description 获取JSON
// @Tags 菜单
// @Accept application/json
// @Product application/json
// @Param id path int true "id"
// @Param data body dto.SysMenuUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menu/{id} [put]
// @Security Bearer
func (e SysMenu) Update(c *gin.Context) {
req := dto.SysMenuUpdateReq{}
s := new(service.SysMenu)
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req).Error
if err != nil {
e.Error(500, err, "更新失败")
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete 删除菜单
// @Summary 删除菜单
// @Description 删除数据
// @Tags 菜单
// @Param data body dto.SysMenuDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menu [delete]
// @Security Bearer
func (e SysMenu) Delete(c *gin.Context) {
control := new(dto.SysMenuDeleteReq)
s := new(service.SysMenu)
err := e.MakeContext(c).
MakeOrm().
Bind(control, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.Remove(control).Error
if err != nil {
e.Logger.Errorf("RemoveSysMenu error, %s", err)
e.Error(500, err, "删除失败")
return
}
e.OK(control.GetId(), "删除成功")
}
// GetMenuRole 根据登录角色名称获取菜单列表数据(左菜单使用)
// @Summary 根据登录角色名称获取菜单列表数据(左菜单使用)
// @Description 获取JSON
// @Tags 菜单
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menurole [get]
// @Security Bearer
func (e SysMenu) GetMenuRole(c *gin.Context) {
s := new(service.SysMenu)
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
result, err := s.SetMenuRole(user.GetRoleName(c))
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(result, "")
}
// GetMenuTreeSelect 根据角色ID查询菜单下拉树结构
// @Summary 角色修改使用的菜单列表
// @Description 获取JSON
// @Tags 菜单
// @Accept application/json
// @Product application/json
// @Param roleId path int true "roleId"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/menuTreeselect/{roleId} [get]
// @Security Bearer
func (e SysMenu) GetMenuTreeSelect(c *gin.Context) {
m := service.SysMenu{}
r := service.SysRole{}
req := dto.SelectRole{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&m.Service).
MakeService(&r.Service).
Bind(&req, nil).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
result, err := m.SetLabel()
if err != nil {
e.Error(500, err, "查询失败")
return
}
menuIds := make([]int, 0)
if req.RoleId != 0 {
menuIds, err = r.GetRoleMenuId(req.RoleId)
if err != nil {
e.Error(500, err, "")
return
}
}
e.OK(gin.H{
"menus": result,
"checkedKeys": menuIds,
}, "获取成功")
}
+118
View File
@@ -0,0 +1,118 @@
package apis
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysOperaLog struct {
api.Api
}
// GetPage 操作日志列表
// @Summary 操作日志列表
// @Description 获取JSON
// @Tags 操作日志
// @Param title query string false "title"
// @Param method query string false "method"
// @Param requestMethod query string false "requestMethod"
// @Param operUrl query string false "operUrl"
// @Param operIp query string false "operIp"
// @Param status query string false "status"
// @Param beginTime query string false "beginTime"
// @Param endTime query string false "endTime"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-opera-log [get]
// @Security Bearer
func (e SysOperaLog) GetPage(c *gin.Context) {
s := service.SysOperaLog{}
req := new(dto.SysOperaLogGetPageReq)
err := e.MakeContext(c).
MakeOrm().
Bind(req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysOperaLog, 0)
var count int64
err = s.GetPage(req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get 操作日志通过id获取
// @Summary 操作日志通过id获取
// @Description 获取JSON
// @Tags 操作日志
// @Param id path string false "id"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-opera-log/{id} [get]
// @Security Bearer
func (e SysOperaLog) Get(c *gin.Context) {
s := new(service.SysOperaLog)
req :=dto.SysOperaLogGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysOperaLog
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Delete 操作日志删除
// DeleteSysMenu 操作日志删除
// @Summary 删除操作日志
// @Description 删除数据
// @Tags 操作日志
// @Param data body dto.SysOperaLogDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-opera-log [delete]
// @Security Bearer
func (e SysOperaLog) Delete(c *gin.Context) {
s := new(service.SysOperaLog)
req :=dto.SysOperaLogDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.Remove(&req)
if err != nil {
e.Logger.Error(err)
e.Error(500,err, fmt.Sprintf("删除失败!错误详情:%s", err.Error()))
return
}
e.OK(req.GetId(), "删除成功")
}
+184
View File
@@ -0,0 +1,184 @@
package apis
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysPost struct {
api.Api
}
// GetPage
// @Summary 岗位列表数据
// @Description 获取JSON
// @Tags 岗位
// @Param postName query string false "postName"
// @Param postCode query string false "postCode"
// @Param postId query string false "postId"
// @Param status query string false "status"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/post [get]
// @Security Bearer
func (e SysPost) GetPage(c *gin.Context) {
s := service.SysPost{}
req :=dto.SysPostPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysPost, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get
// @Summary 获取岗位信息
// @Description 获取JSON
// @Tags 岗位
// @Param id path int true "编码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/post/{postId} [get]
// @Security Bearer
func (e SysPost) Get(c *gin.Context) {
s := service.SysPost{}
req :=dto.SysPostGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysPost
err = s.Get(&req, &object)
if err != nil {
e.Error(500, err, fmt.Sprintf("岗位信息获取失败!错误详情:%s", err.Error()))
return
}
e.OK(object, "查询成功")
}
// Insert
// @Summary 添加岗位
// @Description 获取JSON
// @Tags 岗位
// @Accept application/json
// @Product application/json
// @Param data body dto.SysPostInsertReq true "data"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/post [post]
// @Security Bearer
func (e SysPost) Insert(c *gin.Context) {
s := service.SysPost{}
req :=dto.SysPostInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("新建岗位失败!错误详情:%s", err.Error()))
return
}
e.OK(req.GetId(), "创建成功")
}
// Update
// @Summary 修改岗位
// @Description 获取JSON
// @Tags 岗位
// @Accept application/json
// @Product application/json
// @Param data body dto.SysPostUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/post/{id} [put]
// @Security Bearer
func (e SysPost) Update(c *gin.Context) {
s := service.SysPost{}
req :=dto.SysPostUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("岗位更新失败!错误详情:%s", err.Error()))
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除岗位
// @Description 删除数据
// @Tags 岗位
// @Param id body dto.SysPostDeleteReq true "请求参数"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/post [delete]
// @Security Bearer
func (e SysPost) Delete(c *gin.Context) {
s := service.SysPost{}
req :=dto.SysPostDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.Remove(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("岗位删除失败!错误详情:%s", err.Error()))
return
}
e.OK(req.GetId(), "删除成功")
}
+284
View File
@@ -0,0 +1,284 @@
package apis
import (
"fmt"
"git.ilapage.cn/OPC/chorus/admin/common/global"
"net/http"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/sdk"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
)
type SysRole struct {
api.Api
}
// GetPage
// @Summary 角色列表数据
// @Description Get JSON
// @Tags 角色/Role
// @Param roleName query string false "roleName"
// @Param status query string false "status"
// @Param roleKey query string false "roleKey"
// @Param pageSize query int false "页条数"
// @Param pageIndex query int false "页码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role [get]
// @Security Bearer
func (e SysRole) GetPage(c *gin.Context) {
s := service.SysRole{}
req := dto.SysRoleGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.Form).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
list := make([]models.SysRole, 0)
var count int64
err = s.GetPage(&req, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get
// @Summary 获取Role数据
// @Description 获取JSON
// @Tags 角色/Role
// @Param roleId path string false "roleId"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role/{id} [get]
// @Security Bearer
func (e SysRole) Get(c *gin.Context) {
s := service.SysRole{}
req := dto.SysRoleGetReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, fmt.Sprintf(" %s ", err.Error()))
return
}
var object models.SysRole
err = s.Get(&req, &object)
if err != nil {
e.Error(http.StatusUnprocessableEntity, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Insert
// @Summary 创建角色
// @Description 获取JSON
// @Tags 角色/Role
// @Accept application/json
// @Product application/json
// @Param data body dto.SysRoleInsertReq true "data"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role [post]
// @Security Bearer
func (e SysRole) Insert(c *gin.Context) {
s := service.SysRole{}
req := dto.SysRoleInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.CreateBy = user.GetUserId(c)
if req.Status == "" {
req.Status = "2"
}
cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
err = s.Insert(&req, cb)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "创建失败,"+err.Error())
return
}
_, err = global.LoadPolicy(c)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "创建失败,"+err.Error())
return
}
e.OK(req.GetId(), "创建成功")
}
// Update 修改用户角色
// @Summary 修改用户角色
// @Description 获取JSON
// @Tags 角色/Role
// @Accept application/json
// @Product application/json
// @Param data body dto.SysRoleUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role/{id} [put]
// @Security Bearer
func (e SysRole) Update(c *gin.Context) {
s := service.SysRole{}
req := dto.SysRoleUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
req.SetUpdateBy(user.GetUserId(c))
err = s.Update(&req, cb)
if err != nil {
e.Logger.Error(err)
return
}
_, err = global.LoadPolicy(c)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "更新失败,"+err.Error())
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除用户角色
// @Description 删除数据
// @Tags 角色/Role
// @Param data body dto.SysRoleDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role [delete]
// @Security Bearer
func (e SysRole) Delete(c *gin.Context) {
s := new(service.SysRole)
req := dto.SysRoleDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, fmt.Sprintf("删除角色 %v 失败,\r\n失败信息 %s", req.Ids, err.Error()))
return
}
cb := sdk.Runtime.GetCasbinKey(c.Request.Host)
err = s.Remove(&req, cb)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, "")
return
}
e.OK(req.GetId(), fmt.Sprintf("删除角色角色 %v 状态成功!", req.GetId()))
}
// Update2Status 修改用户角色状态
// @Summary 修改用户角色
// @Description 获取JSON
// @Tags 角色/Role
// @Accept application/json
// @Product application/json
// @Param data body dto.UpdateStatusReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role-status/{id} [put]
// @Security Bearer
func (e SysRole) Update2Status(c *gin.Context) {
s := service.SysRole{}
req := dto.UpdateStatusReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, fmt.Sprintf("更新角色状态失败,失败原因:%s ", err.Error()))
return
}
req.SetUpdateBy(user.GetUserId(c))
err = s.UpdateStatus(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("更新角色状态失败,失败原因:%s ", err.Error()))
return
}
e.OK(req.GetId(), fmt.Sprintf("更新角色 %v 状态成功!", req.GetId()))
}
// Update2DataScope 更新角色数据权限
// @Summary 更新角色数据权限
// @Description 获取JSON
// @Tags 角色/Role
// @Accept application/json
// @Product application/json
// @Param data body dto.RoleDataScopeReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/role-status/{id} [put]
// @Security Bearer
func (e SysRole) Update2DataScope(c *gin.Context) {
s := service.SysRole{}
req := dto.RoleDataScopeReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
data := &models.SysRole{
RoleId: req.RoleId,
DataScope: req.DataScope,
DeptIds: req.DeptIds,
}
data.UpdateBy = user.GetUserId(c)
err = s.UpdateDataScope(&req).Error
if err != nil {
e.Error(500, err, fmt.Sprintf("更新角色数据权限失败!错误详情:%s", err.Error()))
return
}
e.OK(nil, "操作成功")
}
+459
View File
@@ -0,0 +1,459 @@
package apis
import (
"github.com/gin-gonic/gin/binding"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"golang.org/x/crypto/bcrypt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"github.com/google/uuid"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
"git.ilapage.cn/OPC/chorus/admin/common/actions"
)
type SysUser struct {
api.Api
}
// GetPage
// @Summary 列表用户信息数据
// @Description 获取JSON
// @Tags 用户
// @Param username query string false "username"
// @Success 200 {string} {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-user [get]
// @Security Bearer
func (e SysUser) GetPage(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserGetPageReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
//数据权限检查
p := actions.GetPermissionFromContext(c)
list := make([]models.SysUser, 0)
var count int64
err = s.GetPage(&req, p, &list, &count)
if err != nil {
e.Error(500, err, "查询失败")
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}
// Get
// @Summary 获取用户
// @Description 获取JSON
// @Tags 用户
// @Param userId path int true "用户编码"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-user/{userId} [get]
// @Security Bearer
func (e SysUser) Get(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserById{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
var object models.SysUser
//数据权限检查
p := actions.GetPermissionFromContext(c)
err = s.Get(&req, p, &object)
if err != nil {
e.Error(http.StatusUnprocessableEntity, err, "查询失败")
return
}
e.OK(object, "查询成功")
}
// Insert
// @Summary 创建用户
// @Description 获取JSON
// @Tags 用户
// @Accept application/json
// @Product application/json
// @Param data body dto.SysUserInsertReq true "用户数据"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-user [post]
// @Security Bearer
func (e SysUser) Insert(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserInsertReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
e.OK(req.GetId(), "创建成功")
}
// Update
// @Summary 修改用户数据
// @Description 获取JSON
// @Tags 用户
// @Accept application/json
// @Product application/json
// @Param data body dto.SysUserUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-user/{userId} [put]
// @Security Bearer
func (e SysUser) Update(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
//数据权限检查
p := actions.GetPermissionFromContext(c)
err = s.Update(&req, p)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(req.GetId(), "更新成功")
}
// Delete
// @Summary 删除用户数据
// @Description 删除数据
// @Tags 用户
// @Param userId path int true "userId"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/sys-user/{userId} [delete]
// @Security Bearer
func (e SysUser) Delete(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserById{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置编辑人
req.SetUpdateBy(user.GetUserId(c))
// 数据权限检查
p := actions.GetPermissionFromContext(c)
err = s.Remove(&req, p)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(req.GetId(), "删除成功")
}
// InsetAvatar
// @Summary 修改头像
// @Description 获取JSON
// @Tags 个人中心
// @Accept multipart/form-data
// @Param file formData file true "file"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/avatar [post]
// @Security Bearer
func (e SysUser) InsetAvatar(c *gin.Context) {
s := service.SysUser{}
req := dto.UpdateSysUserAvatarReq{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 数据权限检查
p := actions.GetPermissionFromContext(c)
form, _ := c.MultipartForm()
files := form.File["upload[]"]
guid := uuid.New().String()
filPath := "static/uploadfile/" + guid + ".jpg"
for _, file := range files {
e.Logger.Debugf("upload avatar file: %s", file.Filename)
// 上传文件至指定目录
err = c.SaveUploadedFile(file, filPath)
if err != nil {
e.Logger.Errorf("save file error, %s", err.Error())
e.Error(500, err, "")
return
}
}
req.UserId = p.UserId
req.Avatar = "/" + filPath
err = s.UpdateAvatar(&req, p)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(filPath, "修改成功")
}
// UpdateStatus 修改用户状态
// @Summary 修改用户状态
// @Description 获取JSON
// @Tags 用户
// @Accept application/json
// @Product application/json
// @Param data body dto.UpdateSysUserStatusReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/status [put]
// @Security Bearer
func (e SysUser) UpdateStatus(c *gin.Context) {
s := service.SysUser{}
req := dto.UpdateSysUserStatusReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON, nil).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
//数据权限检查
p := actions.GetPermissionFromContext(c)
err = s.UpdateStatus(&req, p)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(req.GetId(), "更新成功")
}
// ResetPwd 重置用户密码
// @Summary 重置用户密码
// @Description 获取JSON
// @Tags 用户
// @Accept application/json
// @Product application/json
// @Param data body dto.ResetSysUserPwdReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/pwd/reset [put]
// @Security Bearer
func (e SysUser) ResetPwd(c *gin.Context) {
s := service.SysUser{}
req := dto.ResetSysUserPwdReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
//数据权限检查
p := actions.GetPermissionFromContext(c)
err = s.ResetPwd(&req, p)
if err != nil {
e.Logger.Error(err)
return
}
e.OK(req.GetId(), "更新成功")
}
// UpdatePwd
// @Summary 修改密码
// @Description 获取JSON
// @Tags 用户
// @Accept application/json
// @Product application/json
// @Param data body dto.PassWord true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/pwd/set [put]
// @Security Bearer
func (e SysUser) UpdatePwd(c *gin.Context) {
s := service.SysUser{}
req := dto.PassWord{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 数据权限检查
p := actions.GetPermissionFromContext(c)
var hash []byte
if hash, err = bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost); err != nil {
req.NewPassword = string(hash)
}
err = s.UpdatePwd(user.GetUserId(c), req.OldPassword, req.NewPassword, p)
if err != nil {
e.Logger.Error(err)
e.Error(http.StatusForbidden, err, "密码修改失败")
return
}
e.OK(nil, "密码修改成功")
}
// GetProfile
// @Summary 获取个人中心用户
// @Description 获取JSON
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/profile [get]
// @Security Bearer
func (e SysUser) GetProfile(c *gin.Context) {
s := service.SysUser{}
req := dto.SysUserById{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.Id = user.GetUserId(c)
sysUser := models.SysUser{}
roles := make([]models.SysRole, 0)
posts := make([]models.SysPost, 0)
err = s.GetProfile(&req, &sysUser, &roles, &posts)
if err != nil {
e.Logger.Errorf("get user profile error, %s", err.Error())
e.Error(500, err, "获取用户信息失败")
return
}
e.OK(gin.H{
"user": sysUser,
"roles": roles,
"posts": posts,
}, "查询成功")
}
// GetInfo
// @Summary 获取个人信息
// @Description 获取JSON
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/getinfo [get]
// @Security Bearer
func (e SysUser) GetInfo(c *gin.Context) {
req := dto.SysUserById{}
s := service.SysUser{}
r := service.SysRole{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&r.Service).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
p := actions.GetPermissionFromContext(c)
var roles = make([]string, 1)
roles[0] = user.GetRoleName(c)
var permissions = make([]string, 1)
permissions[0] = "*:*:*"
var buttons = make([]string, 1)
buttons[0] = "*:*:*"
var mp = make(map[string]interface{})
mp["roles"] = roles
if user.GetRoleName(c) == "admin" || user.GetRoleName(c) == "系统管理员" {
mp["permissions"] = permissions
mp["buttons"] = buttons
} else {
list, _ := r.GetById(user.GetRoleId(c))
mp["permissions"] = list
mp["buttons"] = list
}
sysUser := models.SysUser{}
req.Id = user.GetUserId(c)
err = s.Get(&req, p, &sysUser)
if err != nil {
e.Error(http.StatusUnauthorized, err, "登录失败")
return
}
mp["introduction"] = " am a super administrator"
mp["avatar"] = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
if sysUser.Avatar != "" {
mp["avatar"] = sysUser.Avatar
}
mp["userName"] = sysUser.Username
mp["userId"] = sysUser.UserId
mp["deptId"] = sysUser.DeptId
mp["name"] = sysUser.NickName
mp["code"] = 200
e.OK(mp, "")
}
+16
View File
@@ -0,0 +1,16 @@
package models
type CasbinRule struct {
ID uint `gorm:"primaryKey;autoIncrement"`
Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
V0 string `gorm:"size:512;uniqueIndex:unique_index"`
V1 string `gorm:"size:512;uniqueIndex:unique_index"`
V2 string `gorm:"size:512;uniqueIndex:unique_index"`
V3 string `gorm:"size:512;uniqueIndex:unique_index"`
V4 string `gorm:"size:512;uniqueIndex:unique_index"`
V5 string `gorm:"size:512;uniqueIndex:unique_index"`
}
func (CasbinRule) TableName() string {
return "sys_casbin_rule"
}
+81
View File
@@ -0,0 +1,81 @@
package models
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"gorm.io/gorm"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/config"
)
type DataPermission struct {
DataScope string
UserId int
DeptId int
RoleId int
}
func (e *DataPermission) GetDataScope(tableName string, db *gorm.DB) (*gorm.DB, error) {
if !config.ApplicationConfig.EnableDP {
usageStr := `数据权限已经为您` + pkg.Green(`关闭`) + `,如需开启请参考配置文件字段说明`
log.Debug("%s\n", usageStr)
return db, nil
}
user := new(SysUser)
role := new(SysRole)
err := db.Find(user, e.UserId).Error
if err != nil {
return nil, errors.New("获取用户数据出错 msg:" + err.Error())
}
err = db.Find(role, user.RoleId).Error
if err != nil {
return nil, errors.New("获取用户数据出错 msg:" + err.Error())
}
if role.DataScope == "2" {
db = db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", user.RoleId)
}
if role.DataScope == "3" {
db = db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", user.DeptId)
}
if role.DataScope == "4" {
db = db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%"+pkg.IntToString(user.DeptId)+"%")
}
if role.DataScope == "5" || role.DataScope == "" {
db = db.Where(tableName+".create_by = ?", e.UserId)
}
return db, nil
}
//func DataScopes(tableName string, userId int) func(db *gorm.DB) *gorm.DB {
// return func(db *gorm.DB) *gorm.DB {
// user := new(SysUser)
// role := new(SysRole)
// user.UserId = userId
// err := db.Find(user, userId).Error
// if err != nil {
// db.Error = errors.New("获取用户数据出错 msg:" + err.Error())
// return db
// }
// err = db.Find(role, user.RoleId).Error
// if err != nil {
// db.Error = errors.New("获取用户数据出错 msg:" + err.Error())
// return db
// }
// if role.DataScope == "2" {
// return db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", user.RoleId)
// }
// if role.DataScope == "3" {
// return db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", user.DeptId)
// }
// if role.DataScope == "4" {
// return db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%"+pkg.IntToString(user.DeptId)+"%")
// }
// if role.DataScope == "5" || role.DataScope == "" {
// return db.Where(tableName+".create_by = ?", userId)
// }
// return db
// }
//}
+55
View File
@@ -0,0 +1,55 @@
package models
import (
"fmt"
"git.ilapage.cn/OPC/chorus/admin/common/global"
"gorm.io/gorm"
"io/ioutil"
"log"
"strings"
)
func InitDb(db *gorm.DB) (err error) {
filePath := "config/db.sql"
err = ExecSql(db, filePath)
if global.Driver == "postgres" {
filePath = "config/pg.sql"
err = ExecSql(db, filePath)
}
return err
}
func ExecSql(db *gorm.DB, filePath string) error {
sql, err := Ioutil(filePath)
if err != nil {
fmt.Println("数据库基础数据初始化脚本读取失败!原因:", err.Error())
return err
}
sqlList := strings.Split(sql, ";")
for i := 0; i < len(sqlList)-1; i++ {
if strings.Contains(sqlList[i], "--") {
fmt.Println(sqlList[i])
continue
}
sql := strings.Replace(sqlList[i]+";", "\n", "", -1)
sql = strings.TrimSpace(sql)
if err = db.Exec(sql).Error; err != nil {
log.Printf("error sql: %s", sql)
if !strings.Contains(err.Error(), "Query was empty") {
return err
}
}
}
return nil
}
func Ioutil(filePath string) (string, error) {
if contents, err := ioutil.ReadFile(filePath); err == nil {
//因为contents是[]byte类型,直接转换成string类型后会多一行空格,需要使用strings.Replace替换换行符
result := strings.Replace(string(contents), "\n", "", 1)
fmt.Println("Use ioutil.ReadFile to read a file:", result)
return result, nil
} else {
return "", err
}
}
+91
View File
@@ -0,0 +1,91 @@
package models
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"regexp"
"strings"
"github.com/bitly/go-simplejson"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/sdk/runtime"
"github.com/go-admin-team/go-admin-core/storage"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysApi struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
Handle string `json:"handle" gorm:"size:128;comment:handle"`
Title string `json:"title" gorm:"size:128;comment:标题"`
Path string `json:"path" gorm:"size:128;comment:地址"`
Action string `json:"action" gorm:"size:16;comment:请求类型"`
Type string `json:"type" gorm:"size:16;comment:接口类型"`
models.ModelTime
models.ControlBy
}
func (*SysApi) TableName() string {
return "sys_api"
}
func (e *SysApi) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysApi) GetId() interface{} {
return e.Id
}
func SaveSysApi(message storage.Messager) (err error) {
var rb []byte
rb, err = json.Marshal(message.GetValues())
if err != nil {
err = fmt.Errorf("json Marshal error, %v", err.Error())
return err
}
var l runtime.Routers
err = json.Unmarshal(rb, &l)
if err != nil {
err = fmt.Errorf("json Unmarshal error, %s", err.Error())
return err
}
dbList := sdk.Runtime.GetDb()
for _, d := range dbList {
for _, v := range l.List {
if v.HttpMethod != "HEAD" ||
strings.Contains(v.RelativePath, "/swagger/") ||
strings.Contains(v.RelativePath, "/static/") ||
strings.Contains(v.RelativePath, "/form-generator/") ||
strings.Contains(v.RelativePath, "/sys/tables") {
// 根据接口方法注释里的@Summary填充接口名称,适用于代码生成器
// 可在此处增加配置路径前缀的if判断,只对代码生成的自建应用进行定向的接口名称填充
jsonFile, _ := ioutil.ReadFile("docs/swagger.json")
jsonData, _ := simplejson.NewFromReader(bytes.NewReader(jsonFile))
urlPath := v.RelativePath
idPatten := "(.*)/:(\\w+)" // 正则替换,把:id换成{id}
reg, _ := regexp.Compile(idPatten)
if reg.MatchString(urlPath) {
urlPath = reg.ReplaceAllString(v.RelativePath, "${1}/{${2}}") // 把:id换成{id}
}
apiTitle, _ := jsonData.Get("paths").Get(urlPath).Get(strings.ToLower(v.HttpMethod)).Get("summary").String()
err := d.Debug().Where(SysApi{Path: v.RelativePath, Action: v.HttpMethod}).
Attrs(SysApi{Handle: v.Handler, Title: apiTitle}).
FirstOrCreate(&SysApi{}).
//Update("handle", v.Handler).
Error
if err != nil {
err := fmt.Errorf("Models SaveSysApi error: %s \r\n ", err.Error())
return err
}
}
}
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
package models
import (
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysConfig struct {
models.Model
ConfigName string `json:"configName" gorm:"size:128;comment:ConfigName"` //
ConfigKey string `json:"configKey" gorm:"size:128;comment:ConfigKey"` //
ConfigValue string `json:"configValue" gorm:"size:255;comment:ConfigValue"` //
ConfigType string `json:"configType" gorm:"size:64;comment:ConfigType"`
IsFrontend string `json:"isFrontend" gorm:"size:64;comment:是否前台"` //
Remark string `json:"remark" gorm:"size:128;comment:Remark"` //
models.ControlBy
models.ModelTime
}
func (*SysConfig) TableName() string {
return "sys_config"
}
func (e *SysConfig) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysConfig) GetId() interface{} {
return e.Id
}
+33
View File
@@ -0,0 +1,33 @@
package models
import "git.ilapage.cn/OPC/chorus/admin/common/models"
type SysDept struct {
DeptId int `json:"deptId" gorm:"primaryKey;autoIncrement;"` //部门编码
ParentId int `json:"parentId" gorm:""` //上级部门
DeptPath string `json:"deptPath" gorm:"size:255;"` //
DeptName string `json:"deptName" gorm:"size:128;"` //部门名称
Sort int `json:"sort" gorm:"size:4;"` //排序
Leader string `json:"leader" gorm:"size:128;"` //负责人
Phone string `json:"phone" gorm:"size:11;"` //手机
Email string `json:"email" gorm:"size:64;"` //邮箱
Status int `json:"status" gorm:"size:4;"` //状态
models.ControlBy
models.ModelTime
DataScope string `json:"dataScope" gorm:"-"`
Params string `json:"params" gorm:"-"`
Children []SysDept `json:"children" gorm:"-"`
}
func (*SysDept) TableName() string {
return "sys_dept"
}
func (e *SysDept) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysDept) GetId() interface{} {
return e.DeptId
}
+34
View File
@@ -0,0 +1,34 @@
package models
import (
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysDictData struct {
DictCode int `json:"dictCode" gorm:"primaryKey;column:dict_code;autoIncrement;comment:主键编码"`
DictSort int `json:"dictSort" gorm:"size:20;comment:DictSort"`
DictLabel string `json:"dictLabel" gorm:"size:128;comment:DictLabel"`
DictValue string `json:"dictValue" gorm:"size:255;comment:DictValue"`
DictType string `json:"dictType" gorm:"size:64;comment:DictType"`
CssClass string `json:"cssClass" gorm:"size:128;comment:CssClass"`
ListClass string `json:"listClass" gorm:"size:128;comment:ListClass"`
IsDefault string `json:"isDefault" gorm:"size:8;comment:IsDefault"`
Status int `json:"status" gorm:"size:4;comment:Status"`
Default string `json:"default" gorm:"size:8;comment:Default"`
Remark string `json:"remark" gorm:"size:255;comment:Remark"`
models.ControlBy
models.ModelTime
}
func (*SysDictData) TableName() string {
return "sys_dict_data"
}
func (e *SysDictData) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysDictData) GetId() interface{} {
return e.DictCode
}
+28
View File
@@ -0,0 +1,28 @@
package models
import (
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysDictType struct {
ID int `json:"id" gorm:"primaryKey;column:dict_id;autoIncrement;comment:主键编码"`
DictName string `json:"dictName" gorm:"size:128;comment:DictName"`
DictType string `json:"dictType" gorm:"size:128;comment:DictType"`
Status int `json:"status" gorm:"size:4;comment:Status"`
Remark string `json:"remark" gorm:"size:255;comment:Remark"`
models.ControlBy
models.ModelTime
}
func (*SysDictType) TableName() string {
return "sys_dict_type"
}
func (e *SysDictType) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysDictType) GetId() interface{} {
return e.ID
}
+72
View File
@@ -0,0 +1,72 @@
package models
import (
"encoding/json"
"errors"
"time"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/storage"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysLoginLog struct {
models.Model
Username string `json:"username" gorm:"size:128;comment:用户名"`
Status string `json:"status" gorm:"size:4;comment:状态"`
Ipaddr string `json:"ipaddr" gorm:"size:255;comment:ip地址"`
LoginLocation string `json:"loginLocation" gorm:"size:255;comment:归属地"`
Browser string `json:"browser" gorm:"size:255;comment:浏览器"`
Os string `json:"os" gorm:"size:255;comment:系统"`
Platform string `json:"platform" gorm:"size:255;comment:固件"`
LoginTime time.Time `json:"loginTime" gorm:"comment:登录时间"`
Remark string `json:"remark" gorm:"size:255;comment:备注"`
Msg string `json:"msg" gorm:"size:255;comment:信息"`
CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
UpdatedAt time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
models.ControlBy
}
func (*SysLoginLog) TableName() string {
return "sys_login_log"
}
func (e *SysLoginLog) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysLoginLog) GetId() interface{} {
return e.Id
}
// SaveLoginLog 从队列中获取登录日志
func SaveLoginLog(message storage.Messager) (err error) {
//准备db
db := sdk.Runtime.GetDbByKey(message.GetPrefix())
if db == nil {
err = errors.New("db not exist")
log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error())
return err
}
var rb []byte
rb, err = json.Marshal(message.GetValues())
if err != nil {
log.Errorf("json Marshal error, %s", err.Error())
return err
}
var l SysLoginLog
err = json.Unmarshal(rb, &l)
if err != nil {
log.Errorf("json Unmarshal error, %s", err.Error())
return err
}
err = db.Create(&l).Error
if err != nil {
log.Errorf("db create error, %s", err.Error())
return err
}
return nil
}
+50
View File
@@ -0,0 +1,50 @@
package models
import "git.ilapage.cn/OPC/chorus/admin/common/models"
type SysMenu struct {
MenuId int `json:"menuId" gorm:"primaryKey;autoIncrement"`
MenuName string `json:"menuName" gorm:"size:128;"`
Title string `json:"title" gorm:"size:128;"`
Icon string `json:"icon" gorm:"size:128;"`
Path string `json:"path" gorm:"size:128;"`
Paths string `json:"paths" gorm:"size:128;"`
MenuType string `json:"menuType" gorm:"size:1;"`
Action string `json:"action" gorm:"size:16;"`
Permission string `json:"permission" gorm:"size:255;"`
ParentId int `json:"parentId" gorm:"size:11;"`
NoCache bool `json:"noCache" gorm:"size:8;"`
Breadcrumb string `json:"breadcrumb" gorm:"size:255;"`
Component string `json:"component" gorm:"size:255;"`
Sort int `json:"sort" gorm:"size:4;"`
Visible string `json:"visible" gorm:"size:1;"`
IsFrame string `json:"isFrame" gorm:"size:1;DEFAULT:0;"`
SysApi []SysApi `json:"sysApi" gorm:"many2many:sys_menu_api_rule"`
Apis []int `json:"apis" gorm:"-"`
DataScope string `json:"dataScope" gorm:"-"`
Params string `json:"params" gorm:"-"`
RoleId int `gorm:"-"`
Children []SysMenu `json:"children,omitempty" gorm:"-"`
IsSelect bool `json:"is_select" gorm:"-"`
models.ControlBy
models.ModelTime
}
type SysMenuSlice []SysMenu
func (x SysMenuSlice) Len() int { return len(x) }
func (x SysMenuSlice) Less(i, j int) bool { return x[i].Sort < x[j].Sort }
func (x SysMenuSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (*SysMenu) TableName() string {
return "sys_menu"
}
func (e *SysMenu) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysMenu) GetId() interface{} {
return e.MenuId
}
+88
View File
@@ -0,0 +1,88 @@
package models
import (
"encoding/json"
"errors"
"time"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/storage"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysOperaLog struct {
models.Model
Title string `json:"title" gorm:"size:255;comment:操作模块"`
BusinessType string `json:"businessType" gorm:"size:128;comment:操作类型"`
BusinessTypes string `json:"businessTypes" gorm:"size:128;comment:BusinessTypes"`
Method string `json:"method" gorm:"size:128;comment:函数"`
RequestMethod string `json:"requestMethod" gorm:"size:128;comment:请求方式 GET POST PUT DELETE"`
OperatorType string `json:"operatorType" gorm:"size:128;comment:操作类型"`
OperName string `json:"operName" gorm:"size:128;comment:操作者"`
DeptName string `json:"deptName" gorm:"size:128;comment:部门名称"`
OperUrl string `json:"operUrl" gorm:"size:255;comment:访问地址"`
OperIp string `json:"operIp" gorm:"size:128;comment:客户端ip"`
OperLocation string `json:"operLocation" gorm:"size:128;comment:访问位置"`
OperParam string `json:"operParam" gorm:"text;comment:请求参数"`
Status string `json:"status" gorm:"size:4;comment:操作状态 1:正常 2:关闭"`
OperTime time.Time `json:"operTime" gorm:"comment:操作时间"`
JsonResult string `json:"jsonResult" gorm:"size:255;comment:返回数据"`
Remark string `json:"remark" gorm:"size:255;comment:备注"`
LatencyTime string `json:"latencyTime" gorm:"size:128;comment:耗时"`
UserAgent string `json:"userAgent" gorm:"size:255;comment:ua"`
CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
UpdatedAt time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
models.ControlBy
}
func (*SysOperaLog) TableName() string {
return "sys_opera_log"
}
func (e *SysOperaLog) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysOperaLog) GetId() interface{} {
return e.Id
}
// SaveOperaLog 从队列中获取操作日志
func SaveOperaLog(message storage.Messager) (err error) {
//准备db
db := sdk.Runtime.GetDbByKey(message.GetPrefix())
if db == nil {
err = errors.New("db not exist")
log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error())
// Log writing to the database ignores error
return nil
}
var rb []byte
rb, err = json.Marshal(message.GetValues())
if err != nil {
log.Errorf("json Marshal error, %s", err.Error())
// Log writing to the database ignores error
return nil
}
var l SysOperaLog
err = json.Unmarshal(rb, &l)
if err != nil {
log.Errorf("json Unmarshal error, %s", err.Error())
// Log writing to the database ignores error
return nil
}
// 超出100个字符返回值截断
if len(l.JsonResult) > 100 {
l.JsonResult = l.JsonResult[:100]
}
err = db.Create(&l).Error
if err != nil {
log.Errorf("db create error, %s", err.Error())
// Log writing to the database ignores error
return nil
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
package models
import "git.ilapage.cn/OPC/chorus/admin/common/models"
type SysPost struct {
PostId int `gorm:"primaryKey;autoIncrement" json:"postId"` //岗位编号
PostName string `gorm:"size:128;" json:"postName"` //岗位名称
PostCode string `gorm:"size:128;" json:"postCode"` //岗位代码
Sort int `gorm:"size:4;" json:"sort"` //岗位排序
Status int `gorm:"size:4;" json:"status"` //状态
Remark string `gorm:"size:255;" json:"remark"` //描述
models.ControlBy
models.ModelTime
DataScope string `gorm:"-" json:"dataScope"`
Params string `gorm:"-" json:"params"`
}
func (*SysPost) TableName() string {
return "sys_post"
}
func (e *SysPost) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysPost) GetId() interface{} {
return e.PostId
}
+35
View File
@@ -0,0 +1,35 @@
package models
import "git.ilapage.cn/OPC/chorus/admin/common/models"
type SysRole struct {
RoleId int `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
RoleName string `json:"roleName" gorm:"size:128;"` // 角色名称
Status string `json:"status" gorm:"size:4;"` // 状态 1禁用 2正常
RoleKey string `json:"roleKey" gorm:"size:128;"` //角色代码
RoleSort int `json:"roleSort" gorm:""` //角色排序
Flag string `json:"flag" gorm:"size:128;"` //
Remark string `json:"remark" gorm:"size:255;"` //备注
Admin bool `json:"admin" gorm:"size:4;"`
DataScope string `json:"dataScope" gorm:"size:128;"`
Params string `json:"params" gorm:"-"`
MenuIds []int `json:"menuIds" gorm:"-"`
DeptIds []int `json:"deptIds" gorm:"-"`
SysDept []SysDept `json:"sysDept" gorm:"many2many:sys_role_dept;foreignKey:RoleId;joinForeignKey:role_id;references:DeptId;joinReferences:dept_id;"`
SysMenu *[]SysMenu `json:"sysMenu" gorm:"many2many:sys_role_menu;foreignKey:RoleId;joinForeignKey:role_id;references:MenuId;joinReferences:menu_id;"`
models.ControlBy
models.ModelTime
}
func (*SysRole) TableName() string {
return "sys_role"
}
func (e *SysRole) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysRole) GetId() interface{} {
return e.RoleId
}
+77
View File
@@ -0,0 +1,77 @@
package models
import (
"git.ilapage.cn/OPC/chorus/admin/common/models"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
type SysUser struct {
UserId int `gorm:"primaryKey;autoIncrement;comment:编码" json:"userId"`
Username string `json:"username" gorm:"size:64;comment:用户名"`
Password string `json:"-" gorm:"size:128;comment:密码"`
NickName string `json:"nickName" gorm:"size:128;comment:昵称"`
Phone string `json:"phone" gorm:"size:11;comment:手机号"`
RoleId int `json:"roleId" gorm:"size:20;comment:角色ID"`
Salt string `json:"-" gorm:"size:255;comment:加盐"`
Avatar string `json:"avatar" gorm:"size:255;comment:头像"`
Sex string `json:"sex" gorm:"size:255;comment:性别"`
Email string `json:"email" gorm:"size:128;comment:邮箱"`
DeptId int `json:"deptId" gorm:"size:20;comment:部门"`
PostId int `json:"postId" gorm:"size:20;comment:岗位"`
Remark string `json:"remark" gorm:"size:255;comment:备注"`
Status string `json:"status" gorm:"size:4;comment:状态"`
DeptIds []int `json:"deptIds" gorm:"-"`
PostIds []int `json:"postIds" gorm:"-"`
RoleIds []int `json:"roleIds" gorm:"-"`
Dept *SysDept `json:"dept"`
models.ControlBy
models.ModelTime
}
func (*SysUser) TableName() string {
return "sys_user"
}
func (e *SysUser) Generate() models.ActiveRecord {
o := *e
return &o
}
func (e *SysUser) GetId() interface{} {
return e.UserId
}
// Encrypt 加密
func (e *SysUser) Encrypt() (err error) {
if e.Password == "" {
return
}
var hash []byte
if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
return
} else {
e.Password = string(hash)
return
}
}
func (e *SysUser) BeforeCreate(_ *gorm.DB) error {
return e.Encrypt()
}
func (e *SysUser) BeforeUpdate(_ *gorm.DB) error {
var err error
if e.Password != "" {
err = e.Encrypt()
}
return err
}
func (e *SysUser) AfterFind(_ *gorm.DB) error {
e.DeptIds = []int{e.DeptId}
e.PostIds = []int{e.PostId}
e.RoleIds = []int{e.RoleId}
return nil
}
+39
View File
@@ -0,0 +1,39 @@
package router
import (
"os"
"git.ilapage.cn/OPC/chorus/admin/app/chorus"
common "git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
)
// InitRouter 路由初始化,不要怀疑,这里用到了
func InitRouter() {
var r *gin.Engine
h := sdk.Runtime.GetEngine()
if h == nil {
log.Fatal("not found engine...")
os.Exit(-1)
}
switch h.(type) {
case *gin.Engine:
r = h.(*gin.Engine)
default:
log.Fatal("not support other engine")
os.Exit(-1)
}
// the jwt middleware
authMiddleware, err := common.AuthInit()
if err != nil {
log.Fatalf("JWT Init Error, %s", err.Error())
}
// 注册系统路由
InitSysRouter(r, authMiddleware)
chorus.Register(r.Group("/api/v1"), authMiddleware)
}
+41
View File
@@ -0,0 +1,41 @@
package router
import (
"github.com/gin-gonic/gin"
_ "github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
var (
routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
)
func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
// 无需认证的路由
examplesNoCheckRoleRouter(r)
// 需要认证的路由
examplesCheckRoleRouter(r, authMiddleware)
return r
}
// 无需认证的路由示例
func examplesNoCheckRoleRouter(r *gin.Engine) {
// 可根据业务需求来设置接口版本
v1 := r.Group("/api/v1")
for _, f := range routerNoCheckRole {
f(v1)
}
}
// 需要认证的路由示例
func examplesCheckRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddleware) {
// 可根据业务需求来设置接口版本
v1 := r.Group("/api/v1")
for _, f := range routerCheckRole {
f(v1, authMiddleware)
}
}
+24
View File
@@ -0,0 +1,24 @@
package router
import (
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysApiRouter)
}
// registerSysApiRouter
func registerSysApiRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysApi{}
r := v1.Group("/sys-api").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.PUT("/:id", api.Update)
}
}
+43
View File
@@ -0,0 +1,43 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysConfigRouter)
}
// 需认证的路由代码
func registerSysConfigRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysConfig{}
r := v1.Group("/config").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("/:id", api.Update)
r.DELETE("", api.Delete)
}
r1 := v1.Group("/configKey").Use(authMiddleware.MiddlewareFunc())
{
r1.GET("/:configKey", api.GetSysConfigByKEYForService)
}
r2 := v1.Group("/app-config")
{
r2.GET("", api.Get2SysApp)
}
r3 := v1.Group("/set-config").Use(authMiddleware.MiddlewareFunc())
{
r3.PUT("", api.Update2Set)
r3.GET("", api.Get2Set)
}
}
+32
View File
@@ -0,0 +1,32 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysDeptRouter)
}
// 需认证的路由代码
func registerSysDeptRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysDept{}
r := v1.Group("/dept").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("/:id", api.Update)
r.DELETE("", api.Delete)
}
r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
{
r1.GET("/deptTree", api.Get2Tree)
}
}
+37
View File
@@ -0,0 +1,37 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerDictRouter)
}
func registerDictRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
dictApi := apis.SysDictType{}
dataApi := apis.SysDictData{}
dicts := v1.Group("/dict").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
dicts.GET("/data", dataApi.GetPage)
dicts.GET("/data/:dictCode", dataApi.Get)
dicts.POST("/data", dataApi.Insert)
dicts.PUT("/data/:dictCode", dataApi.Update)
dicts.DELETE("/data", dataApi.Delete)
dicts.GET("/type-option-select", dictApi.GetAll)
dicts.GET("/type", dictApi.GetPage)
dicts.GET("/type/:id", dictApi.Get)
dicts.POST("/type", dictApi.Insert)
dicts.PUT("/type/:id", dictApi.Update)
dicts.DELETE("/type", dictApi.Delete)
}
opSelect := v1.Group("/dict-data").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
opSelect.GET("/option-select", dataApi.GetAll)
}
}
+24
View File
@@ -0,0 +1,24 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysLoginLogRouter)
}
// 需认证的路由代码
func registerSysLoginLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysLoginLog{}
r := v1.Group("/sys-login-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.DELETE("", api.Delete)
}
}
+33
View File
@@ -0,0 +1,33 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysMenuRouter)
}
// 需认证的路由代码
func registerSysMenuRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysMenu{}
r := v1.Group("/menu").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("/:id", api.Update)
r.DELETE("", api.Delete)
}
r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
{
r1.GET("/menurole", api.GetMenuRole)
//r1.GET("/menuids", api.GetMenuIDS)
}
}
+23
View File
@@ -0,0 +1,23 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysOperaLogRouter)
}
// 需认证的路由代码
func registerSysOperaLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysOperaLog{}
r := v1.Group("/sys-opera-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.DELETE("", api.Delete)
}
}
+25
View File
@@ -0,0 +1,25 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSyPostRouter)
}
// 需认证的路由代码
func registerSyPostRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysPost{}
r := v1.Group("/post").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("/:id", api.Update)
r.DELETE("", api.Delete)
}
}
+31
View File
@@ -0,0 +1,31 @@
package router
import (
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysRoleRouter)
}
// 需认证的路由代码
func registerSysRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysRole{}
r := v1.Group("/role").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("/:id", api.Update)
r.DELETE("", api.Delete)
}
r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
{
r1.PUT("/role-status", api.Update2Status)
r1.PUT("/roledatascope", api.Update2DataScope)
}
}
+44
View File
@@ -0,0 +1,44 @@
package router
import (
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"git.ilapage.cn/OPC/chorus/admin/common/middleware/handler"
)
func InitSysRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.RouterGroup {
g := r.Group("")
sysBaseRouter(g)
// 需要认证
sysCheckRoleRouterInit(g, authMiddleware)
return g
}
func sysBaseRouter(r *gin.RouterGroup) {
r.GET("/info", handler.Ping)
}
func sysCheckRoleRouterInit(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
v1 := r.Group("/api/v1")
{
v1.POST("/login", authMiddleware.LoginHandler)
// Refresh time can be longer than token timeout
v1.GET("/refresh_token", authMiddleware.RefreshHandler)
}
registerBaseRouter(v1, authMiddleware)
}
func registerBaseRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysMenu{}
api2 := apis.SysDept{}
v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{
v1auth.GET("/roleMenuTreeselect/:roleId", api.GetMenuTreeSelect)
//v1.GET("/menuTreeselect", api.GetMenuTreeSelect)
v1auth.GET("/roleDeptTreeselect/:roleId", api2.GetDeptTreeRoleSelect)
v1auth.POST("/logout", handler.LogOut)
}
}
+39
View File
@@ -0,0 +1,39 @@
package router
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/apis"
"git.ilapage.cn/OPC/chorus/admin/common/actions"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)
func init() {
routerCheckRole = append(routerCheckRole, registerSysUserRouter)
}
// 需认证的路由代码
func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.SysUser{}
r := v1.Group("/sys-user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
{
r.GET("", api.GetPage)
r.GET("/:id", api.Get)
r.POST("", api.Insert)
r.PUT("", api.Update)
r.DELETE("", api.Delete)
}
user := v1.Group("/user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
{
user.GET("/profile", api.GetProfile)
user.POST("/avatar", api.InsetAvatar)
user.PUT("/pwd/set", api.UpdatePwd)
user.PUT("/pwd/reset", api.ResetPwd)
user.PUT("/status", api.UpdateStatus)
}
v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc())
{
v1auth.GET("/getinfo", api.GetInfo)
}
}
+95
View File
@@ -0,0 +1,95 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
// SysApiGetPageReq 功能列表请求参数
type SysApiGetPageReq struct {
dto.Pagination `search:"-"`
Title string `form:"title" search:"type:contains;column:title;table:sys_api" comment:"标题"`
Path string `form:"path" search:"type:contains;column:path;table:sys_api" comment:"地址"`
Action string `form:"action" search:"type:exact;column:action;table:sys_api" comment:"请求方式"`
ParentId string `form:"parentId" search:"type:exact;column:parent_id;table:sys_api" comment:"按钮id"`
Type string `form:"type" search:"-" comment:"类型"`
SysApiOrder
}
type SysApiOrder struct {
TitleOrder string `search:"type:order;column:title;table:sys_api" form:"titleOrder"`
PathOrder string `search:"type:order;column:path;table:sys_api" form:"pathOrder"`
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_api" form:"createdAtOrder"`
}
func (m *SysApiGetPageReq) GetNeedSearch() interface{} {
return *m
}
// SysApiInsertReq 功能创建请求参数
type SysApiInsertReq struct {
Id int `json:"-" comment:"编码"` // 编码
Handle string `json:"handle" comment:"handle"`
Title string `json:"title" comment:"标题"`
Path string `json:"path" comment:"地址"`
Type string `json:"type" comment:""`
Action string `json:"action" comment:"类型"`
common.ControlBy
}
func (s *SysApiInsertReq) Generate(model *models.SysApi) {
model.Handle = s.Handle
model.Title = s.Title
model.Path = s.Path
model.Type = s.Type
model.Action = s.Action
}
func (s *SysApiInsertReq) GetId() interface{} {
return s.Id
}
// SysApiUpdateReq 功能更新请求参数
type SysApiUpdateReq struct {
Id int `uri:"id" comment:"编码"` // 编码
Handle string `json:"handle" comment:"handle"`
Title string `json:"title" comment:"标题"`
Path string `json:"path" comment:"地址"`
Type string `json:"type" comment:""`
Action string `json:"action" comment:"类型"`
common.ControlBy
}
func (s *SysApiUpdateReq) Generate(model *models.SysApi) {
if s.Id != 0 {
model.Id = s.Id
}
model.Handle = s.Handle
model.Title = s.Title
model.Path = s.Path
model.Type = s.Type
model.Action = s.Action
}
func (s *SysApiUpdateReq) GetId() interface{} {
return s.Id
}
// SysApiGetReq 功能获取请求参数
type SysApiGetReq struct {
Id int `uri:"id"`
}
func (s *SysApiGetReq) GetId() interface{} {
return s.Id
}
// SysApiDeleteReq 功能删除请求参数
type SysApiDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *SysApiDeleteReq) GetId() interface{} {
return s.Ids
}
+112
View File
@@ -0,0 +1,112 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
// SysConfigGetPageReq 列表或者搜索使用结构体
type SysConfigGetPageReq struct {
dto.Pagination `search:"-"`
ConfigName string `form:"configName" search:"type:contains;column:config_name;table:sys_config"`
ConfigKey string `form:"configKey" search:"type:contains;column:config_key;table:sys_config"`
ConfigType string `form:"configType" search:"type:exact;column:config_type;table:sys_config"`
IsFrontend string `form:"isFrontend" search:"type:exact;column:is_frontend;table:sys_config"`
SysConfigOrder
}
type SysConfigOrder struct {
IdOrder string `search:"type:order;column:id;table:sys_config" form:"idOrder"`
ConfigNameOrder string `search:"type:order;column:config_name;table:sys_config" form:"configNameOrder"`
ConfigKeyOrder string `search:"type:order;column:config_key;table:sys_config" form:"configKeyOrder"`
ConfigTypeOrder string `search:"type:order;column:config_type;table:sys_config" form:"configTypeOrder"`
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_config" form:"createdAtOrder"`
}
func (m *SysConfigGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysConfigGetToSysAppReq struct {
IsFrontend string `form:"isFrontend" search:"type:exact;column:is_frontend;table:sys_config"`
}
func (m *SysConfigGetToSysAppReq) GetNeedSearch() interface{} {
return *m
}
// SysConfigControl 增、改使用的结构体
type SysConfigControl struct {
Id int `uri:"Id" comment:"编码"` // 编码
ConfigName string `json:"configName" comment:""`
ConfigKey string `uri:"configKey" json:"configKey" comment:""`
ConfigValue string `json:"configValue" comment:""`
ConfigType string `json:"configType" comment:""`
IsFrontend string `json:"isFrontend"`
Remark string `json:"remark" comment:""`
common.ControlBy
}
// Generate 结构体数据转化 从 SysConfigControl 至 system.SysConfig 对应的模型
func (s *SysConfigControl) Generate(model *models.SysConfig) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
model.ConfigName = s.ConfigName
model.ConfigKey = s.ConfigKey
model.ConfigValue = s.ConfigValue
model.ConfigType = s.ConfigType
model.IsFrontend = s.IsFrontend
model.Remark = s.Remark
}
// GetId 获取数据对应的ID
func (s *SysConfigControl) GetId() interface{} {
return s.Id
}
// GetSetSysConfigReq 增、改使用的结构体
type GetSetSysConfigReq struct {
ConfigKey string `json:"configKey" comment:""`
ConfigValue string `json:"configValue" comment:""`
}
// Generate 结构体数据转化 从 SysConfigControl 至 system.SysConfig 对应的模型
func (s *GetSetSysConfigReq) Generate(model *models.SysConfig) {
model.ConfigValue = s.ConfigValue
}
type UpdateSetSysConfigReq map[string]string
// SysConfigByKeyReq 根据Key获取配置
type SysConfigByKeyReq struct {
ConfigKey string `uri:"configKey" search:"type:contains;column:config_key;table:sys_config"`
}
func (m *SysConfigByKeyReq) GetNeedSearch() interface{} {
return *m
}
type GetSysConfigByKEYForServiceResp struct {
ConfigKey string `json:"configKey" comment:""`
ConfigValue string `json:"configValue" comment:""`
}
type SysConfigGetReq struct {
Id int `uri:"id"`
}
func (s *SysConfigGetReq) GetId() interface{} {
return s.Id
}
type SysConfigDeleteReq struct {
Ids []int `json:"ids"`
common.ControlBy
}
func (s *SysConfigDeleteReq) GetId() interface{} {
return s.Ids
}
+110
View File
@@ -0,0 +1,110 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
// SysDeptGetPageReq 列表或者搜索使用结构体
type SysDeptGetPageReq struct {
DeptId int `form:"deptId" search:"type:exact;column:dept_id;table:sys_dept" comment:"id"` //id
ParentId int `form:"parentId" search:"type:exact;column:parent_id;table:sys_dept" comment:"上级部门"` //上级部门
DeptPath string `form:"deptPath" search:"type:exact;column:dept_path;table:sys_dept" comment:""` //路径
DeptName string `form:"deptName" search:"type:exact;column:dept_name;table:sys_dept" comment:"部门名称"` //部门名称
Sort int `form:"sort" search:"type:exact;column:sort;table:sys_dept" comment:"排序"` //排序
Leader string `form:"leader" search:"type:exact;column:leader;table:sys_dept" comment:"负责人"` //负责人
Phone string `form:"phone" search:"type:exact;column:phone;table:sys_dept" comment:"手机"` //手机
Email string `form:"email" search:"type:exact;column:email;table:sys_dept" comment:"邮箱"` //邮箱
Status string `form:"status" search:"type:exact;column:status;table:sys_dept" comment:"状态"` //状态
}
func (m *SysDeptGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysDeptInsertReq struct {
DeptId int `uri:"id" comment:"编码"` // 编码
ParentId int `json:"parentId" comment:"上级部门" vd:"?"` //上级部门
DeptPath string `json:"deptPath" comment:""` //路径
DeptName string `json:"deptName" comment:"部门名称" vd:"len($)>0"` //部门名称
Sort int `json:"sort" comment:"排序" vd:"?"` //排序
Leader string `json:"leader" comment:"负责人" vd:"@:len($)>0; msg:'leader不能为空'"` //负责人
Phone string `json:"phone" comment:"手机" vd:"?"` //手机
Email string `json:"email" comment:"邮箱" vd:"?"` //邮箱
Status int `json:"status" comment:"状态" vd:"$>0"` //状态
common.ControlBy
}
func (s *SysDeptInsertReq) Generate(model *models.SysDept) {
if s.DeptId != 0 {
model.DeptId = s.DeptId
}
model.DeptName = s.DeptName
model.ParentId = s.ParentId
model.DeptPath = s.DeptPath
model.Sort = s.Sort
model.Leader = s.Leader
model.Phone = s.Phone
model.Email = s.Email
model.Status = s.Status
}
// GetId 获取数据对应的ID
func (s *SysDeptInsertReq) GetId() interface{} {
return s.DeptId
}
type SysDeptUpdateReq struct {
DeptId int `uri:"id" comment:"编码"` // 编码
ParentId int `json:"parentId" comment:"上级部门" vd:"?"` //上级部门
DeptPath string `json:"deptPath" comment:""` //路径
DeptName string `json:"deptName" comment:"部门名称" vd:"len($)>0"` //部门名称
Sort int `json:"sort" comment:"排序" vd:"?"` //排序
Leader string `json:"leader" comment:"负责人" vd:"@:len($)>0; msg:'leader不能为空'"` //负责人
Phone string `json:"phone" comment:"手机" vd:"?"` //手机
Email string `json:"email" comment:"邮箱" vd:"?"` //邮箱
Status int `json:"status" comment:"状态" vd:"$>0"` //状态
common.ControlBy
}
// Generate 结构体数据转化 从 SysDeptControl 至 SysDept 对应的模型
func (s *SysDeptUpdateReq) Generate(model *models.SysDept) {
if s.DeptId != 0 {
model.DeptId = s.DeptId
}
model.DeptName = s.DeptName
model.ParentId = s.ParentId
model.DeptPath = s.DeptPath
model.Sort = s.Sort
model.Leader = s.Leader
model.Phone = s.Phone
model.Email = s.Email
model.Status = s.Status
}
// GetId 获取数据对应的ID
func (s *SysDeptUpdateReq) GetId() interface{} {
return s.DeptId
}
type SysDeptGetReq struct {
Id int `uri:"id"`
}
func (s *SysDeptGetReq) GetId() interface{} {
return s.Id
}
type SysDeptDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *SysDeptDeleteReq) GetId() interface{} {
return s.Ids
}
type DeptLabel struct {
Id int `gorm:"-" json:"id"`
Label string `gorm:"-" json:"label"`
Children []DeptLabel `gorm:"-" json:"children"`
}
@@ -0,0 +1,108 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysDictDataGetPageReq struct {
dto.Pagination `search:"-"`
Id int `form:"id" search:"type:exact;column:dict_code;table:sys_dict_data" comment:""`
DictLabel string `form:"dictLabel" search:"type:contains;column:dict_label;table:sys_dict_data" comment:""`
DictValue string `form:"dictValue" search:"type:contains;column:dict_value;table:sys_dict_data" comment:""`
DictType string `form:"dictType" search:"type:contains;column:dict_type;table:sys_dict_data" comment:""`
Status string `form:"status" search:"type:exact;column:status;table:sys_dict_data" comment:""`
}
func (m *SysDictDataGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysDictDataGetAllResp struct {
DictLabel string `json:"label"`
DictValue string `json:"value"`
}
type SysDictDataInsertReq struct {
Id int `json:"-" comment:""`
DictSort int `json:"dictSort" comment:""`
DictLabel string `json:"dictLabel" comment:""`
DictValue string `json:"dictValue" comment:""`
DictType string `json:"dictType" comment:""`
CssClass string `json:"cssClass" comment:""`
ListClass string `json:"listClass" comment:""`
IsDefault string `json:"isDefault" comment:""`
Status int `json:"status" comment:""`
Default string `json:"default" comment:""`
Remark string `json:"remark" comment:""`
common.ControlBy
}
func (s *SysDictDataInsertReq) Generate(model *models.SysDictData) {
model.DictCode = s.Id
model.DictSort = s.DictSort
model.DictLabel = s.DictLabel
model.DictValue = s.DictValue
model.DictType = s.DictType
model.CssClass = s.CssClass
model.ListClass = s.ListClass
model.IsDefault = s.IsDefault
model.Status = s.Status
model.Default = s.Default
model.Remark = s.Remark
}
func (s *SysDictDataInsertReq) GetId() interface{} {
return s.Id
}
type SysDictDataUpdateReq struct {
Id int `uri:"dictCode" comment:""`
DictSort int `json:"dictSort" comment:""`
DictLabel string `json:"dictLabel" comment:""`
DictValue string `json:"dictValue" comment:""`
DictType string `json:"dictType" comment:""`
CssClass string `json:"cssClass" comment:""`
ListClass string `json:"listClass" comment:""`
IsDefault string `json:"isDefault" comment:""`
Status int `json:"status" comment:""`
Default string `json:"default" comment:""`
Remark string `json:"remark" comment:""`
common.ControlBy
}
func (s *SysDictDataUpdateReq) Generate(model *models.SysDictData) {
model.DictCode = s.Id
model.DictSort = s.DictSort
model.DictLabel = s.DictLabel
model.DictValue = s.DictValue
model.DictType = s.DictType
model.CssClass = s.CssClass
model.ListClass = s.ListClass
model.IsDefault = s.IsDefault
model.Status = s.Status
model.Default = s.Default
model.Remark = s.Remark
}
func (s *SysDictDataUpdateReq) GetId() interface{} {
return s.Id
}
type SysDictDataGetReq struct {
Id int `uri:"dictCode"`
}
func (s *SysDictDataGetReq) GetId() interface{} {
return s.Id
}
type SysDictDataDeleteReq struct {
Ids []int `json:"ids"`
common.ControlBy `json:"-"`
}
func (s *SysDictDataDeleteReq) GetId() interface{} {
return s.Ids
}
@@ -0,0 +1,89 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysDictTypeGetPageReq struct {
dto.Pagination `search:"-"`
DictId []int `form:"dictId" search:"type:in;column:dict_id;table:sys_dict_type"`
DictName string `form:"dictName" search:"type:icontains;column:dict_name;table:sys_dict_type"`
DictType string `form:"dictType" search:"type:icontains;column:dict_type;table:sys_dict_type"`
Status int `form:"status" search:"type:exact;column:status;table:sys_dict_type"`
}
type SysDictTypeOrder struct {
DictIdOrder string `search:"type:order;column:dict_id;table:sys_dict_type" form:"dictIdOrder"`
}
func (m *SysDictTypeGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysDictTypeInsertReq struct {
Id int `uri:"id"`
DictName string `json:"dictName"`
DictType string `json:"dictType"`
Status int `json:"status"`
Remark string `json:"remark"`
common.ControlBy
}
func (s *SysDictTypeInsertReq) Generate(model *models.SysDictType) {
if s.Id != 0 {
model.ID = s.Id
}
model.DictName = s.DictName
model.DictType = s.DictType
model.Status = s.Status
model.Remark = s.Remark
}
func (s *SysDictTypeInsertReq) GetId() interface{} {
return s.Id
}
type SysDictTypeUpdateReq struct {
Id int `uri:"id"`
DictName string `json:"dictName"`
DictType string `json:"dictType"`
Status int `json:"status"`
Remark string `json:"remark"`
common.ControlBy
}
func (s *SysDictTypeUpdateReq) Generate(model *models.SysDictType) {
if s.Id != 0 {
model.ID = s.Id
}
model.DictName = s.DictName
model.DictType = s.DictType
model.Status = s.Status
model.Remark = s.Remark
}
func (s *SysDictTypeUpdateReq) GetId() interface{} {
return s.Id
}
type SysDictTypeGetReq struct {
Id int `uri:"id"`
}
func (s *SysDictTypeGetReq) GetId() interface{} {
return s.Id
}
type SysDictTypeDeleteReq struct {
Ids []int `json:"ids"`
common.ControlBy
}
func (s *SysDictTypeDeleteReq) GetId() interface{} {
return s.Ids
}
@@ -0,0 +1,57 @@
package dto
import (
"time"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysLoginLogGetPageReq struct {
dto.Pagination `search:"-"`
Username string `form:"username" search:"type:exact;column:username;table:sys_login_log" comment:"用户名"`
Status string `form:"status" search:"type:exact;column:status;table:sys_login_log" comment:"状态"`
Ipaddr string `form:"ipaddr" search:"type:exact;column:ipaddr;table:sys_login_log" comment:"ip地址"`
LoginLocation string `form:"loginLocation" search:"type:exact;column:login_location;table:sys_login_log" comment:"归属地"`
BeginTime string `form:"beginTime" search:"type:gte;column:ctime;table:sys_login_log" comment:"创建时间"`
EndTime string `form:"endTime" search:"type:lte;column:ctime;table:sys_login_log" comment:"创建时间"`
SysLoginLogOrder
}
type SysLoginLogOrder struct {
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_login_log" form:"createdAtOrder"`
}
func (m *SysLoginLogGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysLoginLogControl struct {
ID int `uri:"Id" comment:"主键"` // 主键
Username string `json:"username" comment:"用户名"`
Status string `json:"status" comment:"状态"`
Ipaddr string `json:"ipaddr" comment:"ip地址"`
LoginLocation string `json:"loginLocation" comment:"归属地"`
Browser string `json:"browser" comment:"浏览器"`
Os string `json:"os" comment:"系统"`
Platform string `json:"platform" comment:"固件"`
LoginTime time.Time `json:"loginTime" comment:"登录时间"`
Remark string `json:"remark" comment:"备注"`
Msg string `json:"msg" comment:"信息"`
}
type SysLoginLogGetReq struct {
Id int `uri:"id"`
}
func (s *SysLoginLogGetReq) GetId() interface{} {
return s.Id
}
// SysLoginLogDeleteReq 功能删除请求参数
type SysLoginLogDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *SysLoginLogDeleteReq) GetId() interface{} {
return s.Ids
}
+159
View File
@@ -0,0 +1,159 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
)
// SysMenuGetPageReq 列表或者搜索使用结构体
type SysMenuGetPageReq struct {
dto.Pagination `search:"-"`
Title string `form:"title" search:"type:contains;column:title;table:sys_menu" comment:"菜单名称"` // 菜单名称
Visible int `form:"visible" search:"type:exact;column:visible;table:sys_menu" comment:"显示状态"` // 显示状态
}
func (m *SysMenuGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysMenuInsertReq struct {
MenuId int `uri:"id" comment:"编码"` // 编码
MenuName string `form:"menuName" comment:"菜单name"` //菜单name
Title string `form:"title" comment:"显示名称"` //显示名称
Icon string `form:"icon" comment:"图标"` //图标
Path string `form:"path" comment:"路径"` //路径
Paths string `form:"paths" comment:"id路径"` //id路径
MenuType string `form:"menuType" comment:"菜单类型"` //菜单类型
SysApi []models.SysApi `form:"sysApi"`
Apis []int `form:"apis"`
Action string `form:"action" comment:"请求方式"` //请求方式
Permission string `form:"permission" comment:"权限编码"` //权限编码
ParentId int `form:"parentId" comment:"上级菜单"` //上级菜单
NoCache bool `form:"noCache" comment:"是否缓存"` //是否缓存
Breadcrumb string `form:"breadcrumb" comment:"是否面包屑"` //是否面包屑
Component string `form:"component" comment:"组件"` //组件
Sort int `form:"sort" comment:"排序"` //排序
Visible string `form:"visible" comment:"是否显示"` //是否显示
IsFrame string `form:"isFrame" comment:"是否frame"` //是否frame
common.ControlBy
}
func (s *SysMenuInsertReq) Generate(model *models.SysMenu) {
if s.MenuId != 0 {
model.MenuId = s.MenuId
}
model.MenuName = s.MenuName
model.Title = s.Title
model.Icon = s.Icon
model.Path = s.Path
model.Paths = s.Paths
model.MenuType = s.MenuType
model.Action = s.Action
model.SysApi = s.SysApi
model.Permission = s.Permission
model.ParentId = s.ParentId
model.NoCache = s.NoCache
model.Breadcrumb = s.Breadcrumb
model.Component = s.Component
model.Sort = s.Sort
model.Visible = s.Visible
model.IsFrame = s.IsFrame
if s.CreateBy != 0 {
model.CreateBy = s.CreateBy
}
if s.UpdateBy != 0 {
model.UpdateBy = s.UpdateBy
}
}
func (s *SysMenuInsertReq) GetId() interface{} {
return s.MenuId
}
type SysMenuUpdateReq struct {
MenuId int `uri:"id" comment:"编码"` // 编码
MenuName string `form:"menuName" comment:"菜单name"` //菜单name
Title string `form:"title" comment:"显示名称"` //显示名称
Icon string `form:"icon" comment:"图标"` //图标
Path string `form:"path" comment:"路径"` //路径
Paths string `form:"paths" comment:"id路径"` //id路径
MenuType string `form:"menuType" comment:"菜单类型"` //菜单类型
SysApi []models.SysApi `form:"sysApi"`
Apis []int `form:"apis"`
Action string `form:"action" comment:"请求方式"` //请求方式
Permission string `form:"permission" comment:"权限编码"` //权限编码
ParentId int `form:"parentId" comment:"上级菜单"` //上级菜单
NoCache bool `form:"noCache" comment:"是否缓存"` //是否缓存
Breadcrumb string `form:"breadcrumb" comment:"是否面包屑"` //是否面包屑
Component string `form:"component" comment:"组件"` //组件
Sort int `form:"sort" comment:"排序"` //排序
Visible string `form:"visible" comment:"是否显示"` //是否显示
IsFrame string `form:"isFrame" comment:"是否frame"` //是否frame
common.ControlBy
}
func (s *SysMenuUpdateReq) Generate(model *models.SysMenu) {
if s.MenuId != 0 {
model.MenuId = s.MenuId
}
model.MenuName = s.MenuName
model.Title = s.Title
model.Icon = s.Icon
model.Path = s.Path
model.Paths = s.Paths
model.MenuType = s.MenuType
model.Action = s.Action
model.SysApi = s.SysApi
model.Permission = s.Permission
model.ParentId = s.ParentId
model.NoCache = s.NoCache
model.Breadcrumb = s.Breadcrumb
model.Component = s.Component
model.Sort = s.Sort
model.Visible = s.Visible
model.IsFrame = s.IsFrame
if s.CreateBy != 0 {
model.CreateBy = s.CreateBy
}
if s.UpdateBy != 0 {
model.UpdateBy = s.UpdateBy
}
}
func (s *SysMenuUpdateReq) GetId() interface{} {
return s.MenuId
}
type SysMenuGetReq struct {
Id int `uri:"id"`
}
func (s *SysMenuGetReq) GetId() interface{} {
return s.Id
}
type SysMenuDeleteReq struct {
Ids []int `json:"ids"`
common.ControlBy
}
func (s *SysMenuDeleteReq) GetId() interface{} {
return s.Ids
}
type MenuLabel struct {
Id int `json:"id,omitempty" gorm:"-"`
Label string `json:"label,omitempty" gorm:"-"`
Children []MenuLabel `json:"children,omitempty" gorm:"-"`
}
type MenuRole struct {
models.SysMenu
IsSelect bool `json:"is_select" gorm:"-"`
}
type SelectRole struct {
RoleId int `uri:"roleId"`
}
@@ -0,0 +1,102 @@
package dto
import (
"time"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
const (
OperaStatusEnabel = "1" // 状态-正常
OperaStatusDisable = "2" // 状态-关闭
)
type SysOperaLogGetPageReq struct {
dto.Pagination `search:"-"`
Title string `form:"title" search:"type:contains;column:title;table:sys_opera_log" comment:"操作模块"`
Method string `form:"method" search:"type:contains;column:method;table:sys_opera_log" comment:"函数"`
RequestMethod string `form:"requestMethod" search:"type:contains;column:request_method;table:sys_opera_log" comment:"请求方式: GET POST PUT DELETE"`
OperUrl string `form:"operUrl" search:"type:contains;column:oper_url;table:sys_opera_log" comment:"访问地址"`
OperIp string `form:"operIp" search:"type:exact;column:oper_ip;table:sys_opera_log" comment:"客户端ip"`
Status int `form:"status" search:"type:exact;column:status;table:sys_opera_log" comment:"状态 1:正常 2:关闭"`
BeginTime string `form:"beginTime" search:"type:gte;column:created_at;table:sys_opera_log" comment:"创建时间"`
EndTime string `form:"endTime" search:"type:lte;column:created_at;table:sys_opera_log" comment:"更新时间"`
SysOperaLogOrder
}
type SysOperaLogOrder struct {
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_opera_log" form:"createdAtOrder"`
}
func (m *SysOperaLogGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysOperaLogControl struct {
ID int `uri:"Id" comment:"编码"` // 编码
Title string `json:"title" comment:"操作模块"`
BusinessType string `json:"businessType" comment:"操作类型"`
BusinessTypes string `json:"businessTypes" comment:""`
Method string `json:"method" comment:"函数"`
RequestMethod string `json:"requestMethod" comment:"请求方式"`
OperatorType string `json:"operatorType" comment:"操作类型"`
OperName string `json:"operName" comment:"操作者"`
DeptName string `json:"deptName" comment:"部门名称"`
OperUrl string `json:"operUrl" comment:"访问地址"`
OperIp string `json:"operIp" comment:"客户端ip"`
OperLocation string `json:"operLocation" comment:"访问位置"`
OperParam string `json:"operParam" comment:"请求参数"`
Status string `json:"status" comment:"操作状态"`
OperTime time.Time `json:"operTime" comment:"操作时间"`
JsonResult string `json:"jsonResult" comment:"返回数据"`
Remark string `json:"remark" comment:"备注"`
LatencyTime string `json:"latencyTime" comment:"耗时"`
UserAgent string `json:"userAgent" comment:"ua"`
}
func (s *SysOperaLogControl) Generate() (*models.SysOperaLog, error) {
return &models.SysOperaLog{
Model: common.Model{Id: s.ID},
Title: s.Title,
BusinessType: s.BusinessType,
BusinessTypes: s.BusinessTypes,
Method: s.Method,
RequestMethod: s.RequestMethod,
OperatorType: s.OperatorType,
OperName: s.OperName,
DeptName: s.DeptName,
OperUrl: s.OperUrl,
OperIp: s.OperIp,
OperLocation: s.OperLocation,
OperParam: s.OperParam,
Status: s.Status,
OperTime: s.OperTime,
JsonResult: s.JsonResult,
Remark: s.Remark,
LatencyTime: s.LatencyTime,
UserAgent: s.UserAgent,
}, nil
}
func (s *SysOperaLogControl) GetId() interface{} {
return s.ID
}
type SysOperaLogGetReq struct {
Id int `uri:"id"`
}
func (s *SysOperaLogGetReq) GetId() interface{} {
return s.Id
}
// SysOperaLogDeleteReq 功能删除请求参数
type SysOperaLogDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *SysOperaLogDeleteReq) GetId() interface{} {
return s.Ids
}
+111
View File
@@ -0,0 +1,111 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
)
// SysPostPageReq 列表或者搜索使用结构体
type SysPostPageReq struct {
dto.Pagination `search:"-"`
PostId int `form:"postId" search:"type:exact;column:post_id;table:sys_post" comment:"id"` // id
PostName string `form:"postName" search:"type:contains;column:post_name;table:sys_post" comment:"名称"` // 名称
PostCode string `form:"postCode" search:"type:contains;column:post_code;table:sys_post" comment:"编码"` // 编码
Sort int `form:"sort" search:"type:exact;column:sort;table:sys_post" comment:"排序"` // 排序
Status int `form:"status" search:"type:exact;column:status;table:sys_post" comment:"状态"` // 状态
Remark string `form:"remark" search:"type:exact;column:remark;table:sys_post" comment:"备注"` // 备注
}
func (m *SysPostPageReq) GetNeedSearch() interface{} {
return *m
}
// SysPostInsertReq 增使用的结构体
type SysPostInsertReq struct {
PostId int `uri:"id" comment:"id"`
PostName string `form:"postName" comment:"名称"`
PostCode string `form:"postCode" comment:"编码"`
Sort int `form:"sort" comment:"排序"`
Status int `form:"status" comment:"状态"`
Remark string `form:"remark" comment:"备注"`
common.ControlBy
}
func (s *SysPostInsertReq) Generate(model *models.SysPost) {
model.PostName = s.PostName
model.PostCode = s.PostCode
model.Sort = s.Sort
model.Status = s.Status
model.Remark = s.Remark
if s.ControlBy.UpdateBy != 0 {
model.UpdateBy = s.UpdateBy
}
if s.ControlBy.CreateBy != 0 {
model.CreateBy = s.CreateBy
}
}
// GetId 获取数据对应的ID
func (s *SysPostInsertReq) GetId() interface{} {
return s.PostId
}
// SysPostUpdateReq 改使用的结构体
type SysPostUpdateReq struct {
PostId int `uri:"id" comment:"id"`
PostName string `form:"postName" comment:"名称"`
PostCode string `form:"postCode" comment:"编码"`
Sort int `form:"sort" comment:"排序"`
Status int `form:"status" comment:"状态"`
Remark string `form:"remark" comment:"备注"`
common.ControlBy
}
func (s *SysPostUpdateReq) Generate(model *models.SysPost) {
model.PostId = s.PostId
model.PostName = s.PostName
model.PostCode = s.PostCode
model.Sort = s.Sort
model.Status = s.Status
model.Remark = s.Remark
if s.ControlBy.UpdateBy != 0 {
model.UpdateBy = s.UpdateBy
}
if s.ControlBy.CreateBy != 0 {
model.CreateBy = s.CreateBy
}
}
func (s *SysPostUpdateReq) GetId() interface{} {
return s.PostId
}
// SysPostGetReq 获取单个的结构体
type SysPostGetReq struct {
Id int `uri:"id"`
}
func (s *SysPostGetReq) GetId() interface{} {
return s.Id
}
// SysPostDeleteReq 删除的结构体
type SysPostDeleteReq struct {
Ids []int `json:"ids"`
common.ControlBy
}
func (s *SysPostDeleteReq) Generate(model *models.SysPost) {
if s.ControlBy.UpdateBy != 0 {
model.UpdateBy = s.UpdateBy
}
if s.ControlBy.CreateBy != 0 {
model.CreateBy = s.CreateBy
}
}
func (s *SysPostDeleteReq) GetId() interface{} {
return s.Ids
}
+164
View File
@@ -0,0 +1,164 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysRoleGetPageReq struct {
dto.Pagination `search:"-"`
RoleId int `form:"roleId" search:"type:exact;column:role_id;table:sys_role" comment:"角色编码"` // 角色编码
RoleName string `form:"roleName" search:"type:exact;column:role_name;table:sys_role" comment:"角色名称"` // 角色名称
Status string `form:"status" search:"type:exact;column:status;table:sys_role" comment:"状态"` // 状态
RoleKey string `form:"roleKey" search:"type:exact;column:role_key;table:sys_role" comment:"角色代码"` // 角色代码
RoleSort int `form:"roleSort" search:"type:exact;column:role_sort;table:sys_role" comment:"角色排序"` // 角色排序
Flag string `form:"flag" search:"type:exact;column:flag;table:sys_role" comment:"标记"` // 标记
Remark string `form:"remark" search:"type:exact;column:remark;table:sys_role" comment:"备注"` // 备注
Admin bool `form:"admin" search:"type:exact;column:admin;table:sys_role" comment:"是否管理员"`
DataScope string `form:"dataScope" search:"type:exact;column:data_scope;table:sys_role" comment:"是否管理员"`
}
type SysRoleOrder struct {
RoleIdOrder string `search:"type:order;column:role_id;table:sys_role" form:"roleIdOrder"`
RoleNameOrder string `search:"type:order;column:role_name;table:sys_role" form:"roleNameOrder"`
RoleSortOrder string `search:"type:order;column:role_sort;table:sys_role" form:"usernameOrder"`
StatusOrder string `search:"type:order;column:status;table:sys_role" form:"statusOrder"`
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_role" form:"createdAtOrder"`
}
func (m *SysRoleGetPageReq) GetNeedSearch() interface{} {
return *m
}
type SysRoleInsertReq struct {
RoleId int `uri:"id" comment:"角色编码"` // 角色编码
RoleName string `form:"roleName" comment:"角色名称"` // 角色名称
Status string `form:"status" comment:"状态"` // 状态 1禁用 2正常
RoleKey string `form:"roleKey" comment:"角色代码"` // 角色代码
RoleSort int `form:"roleSort" comment:"角色排序"` // 角色排序
Flag string `form:"flag" comment:"标记"` // 标记
Remark string `form:"remark" comment:"备注"` // 备注
Admin bool `form:"admin" comment:"是否管理员"`
DataScope string `form:"dataScope"`
SysMenu []models.SysMenu `form:"sysMenu"`
MenuIds []int `form:"menuIds"`
SysDept []models.SysDept `form:"sysDept"`
DeptIds []int `form:"deptIds"`
common.ControlBy
}
func (s *SysRoleInsertReq) Generate(model *models.SysRole) {
if s.RoleId != 0 {
model.RoleId = s.RoleId
}
model.RoleName = s.RoleName
model.Status = s.Status
model.RoleKey = s.RoleKey
model.RoleSort = s.RoleSort
model.Flag = s.Flag
model.Remark = s.Remark
model.Admin = s.Admin
model.DataScope = s.DataScope
model.SysMenu = &s.SysMenu
model.SysDept = s.SysDept
}
func (s *SysRoleInsertReq) GetId() interface{} {
return s.RoleId
}
type SysRoleUpdateReq struct {
RoleId int `uri:"id" comment:"角色编码"` // 角色编码
RoleName string `form:"roleName" comment:"角色名称"` // 角色名称
Status string `form:"status" comment:"状态"` // 状态
RoleKey string `form:"roleKey" comment:"角色代码"` // 角色代码
RoleSort int `form:"roleSort" comment:"角色排序"` // 角色排序
Flag string `form:"flag" comment:"标记"` // 标记
Remark string `form:"remark" comment:"备注"` // 备注
Admin bool `form:"admin" comment:"是否管理员"`
DataScope string `form:"dataScope"`
SysMenu []models.SysMenu `form:"sysMenu"`
MenuIds []int `form:"menuIds"`
SysDept []models.SysDept `form:"sysDept"`
DeptIds []int `form:"deptIds"`
common.ControlBy
}
func (s *SysRoleUpdateReq) Generate(model *models.SysRole) {
if s.RoleId != 0 {
model.RoleId = s.RoleId
}
model.RoleName = s.RoleName
model.Status = s.Status
model.RoleKey = s.RoleKey
model.RoleSort = s.RoleSort
model.Flag = s.Flag
model.Remark = s.Remark
model.Admin = s.Admin
model.DataScope = s.DataScope
model.SysMenu = &s.SysMenu
model.SysDept = s.SysDept
}
func (s *SysRoleUpdateReq) GetId() interface{} {
return s.RoleId
}
type UpdateStatusReq struct {
RoleId int `form:"roleId" comment:"角色编码"` // 角色编码
Status string `form:"status" comment:"状态"` // 状态
common.ControlBy
}
func (s *UpdateStatusReq) Generate(model *models.SysRole) {
if s.RoleId != 0 {
model.RoleId = s.RoleId
}
model.Status = s.Status
}
func (s *UpdateStatusReq) GetId() interface{} {
return s.RoleId
}
type SysRoleByName struct {
RoleName string `form:"role"` // 角色编码
}
type SysRoleGetReq struct {
Id int `uri:"id"`
}
func (s *SysRoleGetReq) GetId() interface{} {
return s.Id
}
type SysRoleDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *SysRoleDeleteReq) GetId() interface{} {
return s.Ids
}
// RoleDataScopeReq 角色数据权限修改
type RoleDataScopeReq struct {
RoleId int `json:"roleId" binding:"required"`
DataScope string `json:"dataScope" binding:"required"`
DeptIds []int `json:"deptIds"`
}
func (s *RoleDataScopeReq) Generate(model *models.SysRole) {
if s.RoleId != 0 {
model.RoleId = s.RoleId
}
model.DataScope = s.DataScope
model.DeptIds = s.DeptIds
}
type DeptIdList struct {
DeptId int `json:"DeptId"`
}
+189
View File
@@ -0,0 +1,189 @@
package dto
import (
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
common "git.ilapage.cn/OPC/chorus/admin/common/models"
)
type SysUserGetPageReq struct {
dto.Pagination `search:"-"`
UserId int `form:"userId" search:"type:exact;column:user_id;table:sys_user" comment:"用户ID"`
Username string `form:"username" search:"type:contains;column:username;table:sys_user" comment:"用户名"`
NickName string `form:"nickName" search:"type:contains;column:nick_name;table:sys_user" comment:"昵称"`
Phone string `form:"phone" search:"type:contains;column:phone;table:sys_user" comment:"手机号"`
RoleId string `form:"roleId" search:"type:exact;column:role_id;table:sys_user" comment:"角色ID"`
Sex string `form:"sex" search:"type:exact;column:sex;table:sys_user" comment:"性别"`
Email string `form:"email" search:"type:contains;column:email;table:sys_user" comment:"邮箱"`
PostId string `form:"postId" search:"type:exact;column:post_id;table:sys_user" comment:"岗位"`
Status string `form:"status" search:"type:exact;column:status;table:sys_user" comment:"状态"`
DeptJoin `search:"type:left;on:dept_id:dept_id;table:sys_user;join:sys_dept"`
SysUserOrder
}
type SysUserOrder struct {
UserIdOrder string `search:"type:order;column:user_id;table:sys_user" form:"userIdOrder"`
UsernameOrder string `search:"type:order;column:username;table:sys_user" form:"usernameOrder"`
StatusOrder string `search:"type:order;column:status;table:sys_user" form:"statusOrder"`
CreatedAtOrder string `search:"type:order;column:created_at;table:sys_user" form:"createdAtOrder"`
}
type DeptJoin struct {
DeptId string `search:"type:contains;column:dept_path;table:sys_dept" form:"deptId"`
}
func (m *SysUserGetPageReq) GetNeedSearch() interface{} {
return *m
}
type ResetSysUserPwdReq struct {
UserId int `json:"userId" comment:"用户ID" vd:"$>0"` // 用户ID
Password string `json:"password" comment:"密码" vd:"len($)>0"`
common.ControlBy
}
func (s *ResetSysUserPwdReq) GetId() interface{} {
return s.UserId
}
func (s *ResetSysUserPwdReq) Generate(model *models.SysUser) {
if s.UserId != 0 {
model.UserId = s.UserId
}
model.Password = s.Password
}
type UpdateSysUserAvatarReq struct {
UserId int `json:"userId" comment:"用户ID" vd:"len($)>0"` // 用户ID
Avatar string `json:"avatar" comment:"头像" vd:"len($)>0"`
common.ControlBy
}
func (s *UpdateSysUserAvatarReq) GetId() interface{} {
return s.UserId
}
func (s *UpdateSysUserAvatarReq) Generate(model *models.SysUser) {
if s.UserId != 0 {
model.UserId = s.UserId
}
model.Avatar = s.Avatar
}
type UpdateSysUserStatusReq struct {
UserId int `json:"userId" comment:"用户ID" vd:"$>0"` // 用户ID
Status string `json:"status" comment:"状态" vd:"len($)>0"`
common.ControlBy
}
func (s *UpdateSysUserStatusReq) GetId() interface{} {
return s.UserId
}
func (s *UpdateSysUserStatusReq) Generate(model *models.SysUser) {
if s.UserId != 0 {
model.UserId = s.UserId
}
model.Status = s.Status
}
type SysUserInsertReq struct {
UserId int `json:"userId" comment:"用户ID"` // 用户ID
Username string `json:"username" comment:"用户名" vd:"len($)>0"`
Password string `json:"password" comment:"密码"`
NickName string `json:"nickName" comment:"昵称" vd:"len($)>0"`
Phone string `json:"phone" comment:"手机号" vd:"len($)>0"`
RoleId int `json:"roleId" comment:"角色ID"`
Avatar string `json:"avatar" comment:"头像"`
Sex string `json:"sex" comment:"性别"`
Email string `json:"email" comment:"邮箱" vd:"len($)>0,email"`
DeptId int `json:"deptId" comment:"部门" vd:"$>0"`
PostId int `json:"postId" comment:"岗位"`
Remark string `json:"remark" comment:"备注"`
Status string `json:"status" comment:"状态" vd:"len($)>0" default:"1"`
common.ControlBy
}
func (s *SysUserInsertReq) Generate(model *models.SysUser) {
if s.UserId != 0 {
model.UserId = s.UserId
}
model.Username = s.Username
model.Password = s.Password
model.NickName = s.NickName
model.Phone = s.Phone
model.RoleId = s.RoleId
model.Avatar = s.Avatar
model.Sex = s.Sex
model.Email = s.Email
model.DeptId = s.DeptId
model.PostId = s.PostId
model.Remark = s.Remark
model.Status = s.Status
model.CreateBy = s.CreateBy
}
func (s *SysUserInsertReq) GetId() interface{} {
return s.UserId
}
type SysUserUpdateReq struct {
UserId int `json:"userId" comment:"用户ID"` // 用户ID
Username string `json:"username" comment:"用户名" vd:"len($)>0"`
NickName string `json:"nickName" comment:"昵称" vd:"len($)>0"`
Phone string `json:"phone" comment:"手机号" vd:"len($)>0"`
RoleId int `json:"roleId" comment:"角色ID"`
Avatar string `json:"avatar" comment:"头像"`
Sex string `json:"sex" comment:"性别"`
Email string `json:"email" comment:"邮箱" vd:"len($)>0,email"`
DeptId int `json:"deptId" comment:"部门" vd:"$>0"`
PostId int `json:"postId" comment:"岗位"`
Remark string `json:"remark" comment:"备注"`
Status string `json:"status" comment:"状态" default:"1"`
common.ControlBy
}
func (s *SysUserUpdateReq) Generate(model *models.SysUser) {
if s.UserId != 0 {
model.UserId = s.UserId
}
model.Username = s.Username
model.NickName = s.NickName
model.Phone = s.Phone
model.RoleId = s.RoleId
model.Avatar = s.Avatar
model.Sex = s.Sex
model.Email = s.Email
model.DeptId = s.DeptId
model.PostId = s.PostId
model.Remark = s.Remark
model.Status = s.Status
}
func (s *SysUserUpdateReq) GetId() interface{} {
return s.UserId
}
type SysUserById struct {
dto.ObjectById
common.ControlBy
}
func (s *SysUserById) GetId() interface{} {
if len(s.Ids) > 0 {
s.Ids = append(s.Ids, s.Id)
return s.Ids
}
return s.Id
}
func (s *SysUserById) GenerateM() (common.ActiveRecord, error) {
return &models.SysUser{}, nil
}
// PassWord 密码
type PassWord struct {
NewPassword string `json:"newPassword" vd:"len($)>0"`
OldPassword string `json:"oldPassword" vd:"len($)>0"`
}
+121
View File
@@ -0,0 +1,121 @@
package service
import (
"errors"
"fmt"
"github.com/go-admin-team/go-admin-core/sdk/runtime"
"github.com/go-admin-team/go-admin-core/sdk/service"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
"git.ilapage.cn/OPC/chorus/admin/common/actions"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/global"
)
type SysApi struct {
service.Service
}
// GetPage 获取SysApi列表
func (e *SysApi) GetPage(c *dto.SysApiGetPageReq, p *actions.DataPermission, list *[]models.SysApi, count *int64) error {
var err error
var data models.SysApi
orm := e.Orm.Debug().Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p),
)
if c.Type != "" {
qType := c.Type
if qType == "暂无" {
qType = ""
}
if global.Driver == "postgres" {
orm = orm.Where("type = ?", qType)
} else {
orm = orm.Where("`type` = ?", qType)
}
}
err = orm.Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("Service GetSysApiPage error:%s", err)
return err
}
return nil
}
// Get 获取SysApi对象with id
func (e *SysApi) Get(d *dto.SysApiGetReq, p *actions.DataPermission, model *models.SysApi) *SysApi {
var data models.SysApi
err := e.Orm.Model(&data).
Scopes(
actions.Permission(data.TableName(), p),
).
FirstOrInit(model, d.GetId()).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
if model.Id == 0 {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("Service GetSysApi error: %s", err)
_ = e.AddError(err)
return e
}
return e
}
// Update 修改SysApi对象
func (e *SysApi) Update(c *dto.SysApiUpdateReq, p *actions.DataPermission) error {
var model = models.SysApi{}
db := e.Orm.Debug().First(&model, c.GetId())
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
c.Generate(&model)
db = e.Orm.Save(&model)
if err := db.Error; err != nil {
e.Log.Errorf("Service UpdateSysApi error:%s", err)
return err
}
return nil
}
// Remove 删除SysApi
func (e *SysApi) Remove(d *dto.SysApiDeleteReq, p *actions.DataPermission) error {
var data models.SysApi
db := e.Orm.Model(&data).
Scopes(
actions.Permission(data.TableName(), p),
).Delete(&data, d.GetId())
if err := db.Error; err != nil {
e.Log.Errorf("Service RemoveSysApi error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权删除该数据")
}
return nil
}
// CheckStorageSysApi 创建SysApi对象
func (e *SysApi) CheckStorageSysApi(c *[]runtime.Router) error {
for _, v := range *c {
err := e.Orm.Debug().Where(models.SysApi{Path: v.RelativePath, Action: v.HttpMethod}).
Attrs(models.SysApi{Handle: v.Handler}).
FirstOrCreate(&models.SysApi{}).Error
if err != nil {
err := fmt.Errorf("Service CheckStorageSysApi error: %s \r\n ", err.Error())
return err
}
}
return nil
}
+183
View File
@@ -0,0 +1,183 @@
package service
import (
"errors"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
"github.com/go-admin-team/go-admin-core/sdk/service"
)
type SysConfig struct {
service.Service
}
// GetPage 获取SysConfig列表
func (e *SysConfig) GetPage(c *dto.SysConfigGetPageReq, list *[]models.SysConfig, count *int64) error {
err := e.Orm.
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("Service GetSysConfigPage error:%s", err)
return err
}
return nil
}
// Get 获取SysConfig对象
func (e *SysConfig) Get(d *dto.SysConfigGetReq, model *models.SysConfig) error {
err := e.Orm.
FirstOrInit(model, d.GetId()).
Error
if err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return err
}
if model.Id == 0 {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("Service GetSysApi error: %s", err)
_ = e.AddError(err)
return err
}
return nil
}
// Insert 创建SysConfig对象
func (e *SysConfig) Insert(c *dto.SysConfigControl) error {
var err error
var data models.SysConfig
c.Generate(&data)
err = e.Orm.Create(&data).Error
if err != nil {
e.Log.Errorf("Service InsertSysConfig error:%s", err)
return err
}
return nil
}
// Update 修改SysConfig对象
func (e *SysConfig) Update(c *dto.SysConfigControl) error {
var err error
var model = models.SysConfig{}
e.Orm.First(&model, c.GetId())
c.Generate(&model)
db := e.Orm.Save(&model)
err = db.Error
if err != nil {
e.Log.Errorf("Service UpdateSysConfig error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// SetSysConfig 修改SysConfig对象
func (e *SysConfig) SetSysConfig(c *[]dto.GetSetSysConfigReq) error {
var err error
for _, req := range *c {
var model = models.SysConfig{}
e.Orm.Where("config_key = ?", req.ConfigKey).First(&model)
if model.Id != 0 {
req.Generate(&model)
db := e.Orm.Save(&model)
err = db.Error
if err != nil {
e.Log.Errorf("Service SetSysConfig error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
}
}
return nil
}
func (e *SysConfig) GetForSet(c *[]dto.GetSetSysConfigReq) error {
var err error
var data models.SysConfig
err = e.Orm.Model(&data).
Find(c).Error
if err != nil {
e.Log.Errorf("Service GetSysConfigPage error:%s", err)
return err
}
return nil
}
func (e *SysConfig) UpdateForSet(c *[]dto.GetSetSysConfigReq) error {
m := *c
for _, req := range m {
var data models.SysConfig
if err := e.Orm.Where("config_key = ?", req.ConfigKey).
First(&data).Error; err != nil {
e.Log.Errorf("Service GetSysConfigPage error:%s", err)
return err
}
if data.ConfigValue != req.ConfigValue {
data.ConfigValue = req.ConfigValue
if err := e.Orm.Save(&data).Error; err != nil {
e.Log.Errorf("Service GetSysConfigPage error:%s", err)
return err
}
}
}
return nil
}
// Remove 删除SysConfig
func (e *SysConfig) Remove(d *dto.SysConfigDeleteReq) error {
var err error
var data models.SysConfig
db := e.Orm.Delete(&data, d.Ids)
if err = db.Error; err != nil {
e.Log.Errorf("Service RemoveSysConfig error:%s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
// GetWithKey 根据Key获取SysConfig
func (e *SysConfig) GetWithKey(c *dto.SysConfigByKeyReq, resp *dto.GetSysConfigByKEYForServiceResp) error {
var err error
var data models.SysConfig
err = e.Orm.Table(data.TableName()).Where("config_key = ?", c.ConfigKey).First(resp).Error
if err != nil {
e.Log.Errorf("At Service GetSysConfigByKEY Error:%s", err)
return err
}
return nil
}
func (e *SysConfig) GetWithKeyList(c *dto.SysConfigGetToSysAppReq, list *[]models.SysConfig) error {
err := e.Orm.
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
).
Find(list).Error
if err != nil {
e.Log.Errorf("Service GetSysConfigByKey error:%s", err)
return err
}
return nil
}
+294
View File
@@ -0,0 +1,294 @@
package service
import (
"errors"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
"github.com/go-admin-team/go-admin-core/sdk/service"
)
type SysDept struct {
service.Service
}
// GetPage 获取SysDept列表
//func (e *SysDept) GetPage(c *dto.SysDeptGetPageReq, list *[]models.SysDept) error {
// var err error
// var data models.SysDept
//
// err = e.Orm.Model(&data).
// Scopes(
// cDto.MakeCondition(c.GetNeedSearch()),
// ).
// Find(list).Error
// if err != nil {
// e.Log.Errorf("db error:%s", err)
// return err
// }
// return nil
//}
// Get 获取SysDept对象
func (e *SysDept) Get(d *dto.SysDeptGetReq, model *models.SysDept) error {
var err error
var data models.SysDept
err = e.Orm.Model(&data).
FirstOrInit(model, d.GetId()).
Error
if err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return err
}
if model.DeptId == 0 {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("Service GetSysApi error: %s", err)
_ = e.AddError(err)
return err
}
return nil
}
// Insert 创建SysDept对象
func (e *SysDept) Insert(c *dto.SysDeptInsertReq) error {
var err error
var data models.SysDept
c.Generate(&data)
tx := e.Orm.Debug().Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
err = tx.Create(&data).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
deptPath := pkg.IntToString(data.DeptId) + "/"
if data.ParentId != 0 {
var deptP models.SysDept
tx.First(&deptP, data.ParentId)
deptPath = deptP.DeptPath + deptPath
} else {
deptPath = "/0/" + deptPath
}
var mp = map[string]string{}
mp["dept_path"] = deptPath
if err = tx.Model(&data).Update("dept_path", deptPath).Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Update 修改SysDept对象
func (e *SysDept) Update(c *dto.SysDeptUpdateReq) error {
var err error
var model = models.SysDept{}
tx := e.Orm.Debug().Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
tx.First(&model, c.GetId())
c.Generate(&model)
deptPath := pkg.IntToString(model.DeptId) + "/"
if model.ParentId != 0 {
var deptP models.SysDept
tx.First(&deptP, model.ParentId)
deptPath = deptP.DeptPath + deptPath
} else {
deptPath = "/0/" + deptPath
}
model.DeptPath = deptPath
db := tx.Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("UpdateSysDept error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// Remove 删除SysDept
func (e *SysDept) Remove(d *dto.SysDeptDeleteReq) error {
var err error
var data models.SysDept
db := e.Orm.Model(&data).Delete(&data, d.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
// GetSysDeptList 获取组织数据
func (e *SysDept) getList(c *dto.SysDeptGetPageReq, list *[]models.SysDept) error {
var err error
var data models.SysDept
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
).
Find(list).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// SetDeptTree 设置组织数据
func (e *SysDept) SetDeptTree(c *dto.SysDeptGetPageReq) (m []dto.DeptLabel, err error) {
var list []models.SysDept
err = e.getList(c, &list)
m = make([]dto.DeptLabel, 0)
for i := 0; i < len(list); i++ {
if list[i].ParentId != 0 {
continue
}
e := dto.DeptLabel{}
e.Id = list[i].DeptId
e.Label = list[i].DeptName
deptsInfo := deptTreeCall(&list, e)
m = append(m, deptsInfo)
}
return
}
// Call 递归构造组织数据
func deptTreeCall(deptList *[]models.SysDept, dept dto.DeptLabel) dto.DeptLabel {
list := *deptList
childrenList := make([]dto.DeptLabel, 0)
for j := 0; j < len(list); j++ {
if dept.Id != list[j].ParentId {
continue
}
mi := dto.DeptLabel{Id: list[j].DeptId, Label: list[j].DeptName, Children: []dto.DeptLabel{}}
ms := deptTreeCall(deptList, mi)
childrenList = append(childrenList, ms)
}
dept.Children = childrenList
return dept
}
// SetDeptPage 设置dept页面数据
func (e *SysDept) SetDeptPage(c *dto.SysDeptGetPageReq) (m []models.SysDept, err error) {
var list []models.SysDept
err = e.getList(c, &list)
for i := 0; i < len(list); i++ {
if list[i].ParentId != 0 {
continue
}
info := e.deptPageCall(&list, list[i])
m = append(m, info)
}
return
}
func (e *SysDept) deptPageCall(deptlist *[]models.SysDept, menu models.SysDept) models.SysDept {
list := *deptlist
childrenList := make([]models.SysDept, 0)
for j := 0; j < len(list); j++ {
if menu.DeptId != list[j].ParentId {
continue
}
mi := models.SysDept{}
mi.DeptId = list[j].DeptId
mi.ParentId = list[j].ParentId
mi.DeptPath = list[j].DeptPath
mi.DeptName = list[j].DeptName
mi.Sort = list[j].Sort
mi.Leader = list[j].Leader
mi.Phone = list[j].Phone
mi.Email = list[j].Email
mi.Status = list[j].Status
mi.CreatedAt = list[j].CreatedAt
mi.Children = []models.SysDept{}
ms := e.deptPageCall(deptlist, mi)
childrenList = append(childrenList, ms)
}
menu.Children = childrenList
return menu
}
// GetWithRoleId 获取角色的部门ID集合
func (e *SysDept) GetWithRoleId(roleId int) ([]int, error) {
deptIds := make([]int, 0)
deptList := make([]dto.DeptIdList, 0)
if err := e.Orm.Table("sys_role_dept").
Select("sys_role_dept.dept_id").
Joins("LEFT JOIN sys_dept on sys_dept.dept_id=sys_role_dept.dept_id").
Where("role_id = ? ", roleId).
Where(" sys_role_dept.dept_id not in(select sys_dept.parent_id from sys_role_dept LEFT JOIN sys_dept on sys_dept.dept_id=sys_role_dept.dept_id where role_id =? )", roleId).
Find(&deptList).Error; err != nil {
return nil, err
}
for i := 0; i < len(deptList); i++ {
deptIds = append(deptIds, deptList[i].DeptId)
}
return deptIds, nil
}
func (e *SysDept) SetDeptLabel() (m []dto.DeptLabel, err error) {
list := make([]models.SysDept, 0)
err = e.Orm.Find(&list).Error
if err != nil {
log.Error("find dept list error, %s", err.Error())
return
}
m = make([]dto.DeptLabel, 0)
var item dto.DeptLabel
for i := range list {
if list[i].ParentId != 0 {
continue
}
item = dto.DeptLabel{}
item.Id = list[i].DeptId
item.Label = list[i].DeptName
deptInfo := deptLabelCall(&list, item)
m = append(m, deptInfo)
}
return
}
// deptLabelCall
func deptLabelCall(deptList *[]models.SysDept, dept dto.DeptLabel) dto.DeptLabel {
list := *deptList
var mi dto.DeptLabel
childrenList := make([]dto.DeptLabel, 0)
for j := 0; j < len(list); j++ {
if dept.Id != list[j].ParentId {
continue
}
mi = dto.DeptLabel{Id: list[j].DeptId, Label: list[j].DeptName, Children: []dto.DeptLabel{}}
ms := deptLabelCall(deptList, mi)
childrenList = append(childrenList, ms)
}
dept.Children = childrenList
return dept
}
+120
View File
@@ -0,0 +1,120 @@
package service
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysDictData struct {
service.Service
}
// GetPage 获取列表
func (e *SysDictData) GetPage(c *dto.SysDictDataGetPageReq, list *[]models.SysDictData, count *int64) error {
var err error
var data models.SysDictData
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Get 获取对象
func (e *SysDictData) Get(d *dto.SysDictDataGetReq, model *models.SysDictData) error {
var err error
var data models.SysDictData
db := e.Orm.Model(&data).
First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error: %s", err)
return err
}
if err = db.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Insert 创建对象
func (e *SysDictData) Insert(c *dto.SysDictDataInsertReq) error {
var err error
var data = new(models.SysDictData)
c.Generate(data)
err = e.Orm.Create(data).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Update 修改对象
func (e *SysDictData) Update(c *dto.SysDictDataUpdateReq) error {
var err error
var model = models.SysDictData{}
e.Orm.First(&model, c.GetId())
c.Generate(&model)
db := e.Orm.Save(model)
if err = db.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// Remove 删除
func (e *SysDictData) Remove(c *dto.SysDictDataDeleteReq) error {
var err error
var data models.SysDictData
db := e.Orm.Delete(&data, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
// GetAll 获取所有
func (e *SysDictData) GetAll(c *dto.SysDictDataGetPageReq, list *[]models.SysDictData) error {
var err error
var data models.SysDictData
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
).
Find(list).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
+124
View File
@@ -0,0 +1,124 @@
package service
import (
"errors"
"fmt"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysDictType struct {
service.Service
}
// GetPage 获取列表
func (e *SysDictType) GetPage(c *dto.SysDictTypeGetPageReq, list *[]models.SysDictType, count *int64) error {
var err error
var data models.SysDictType
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Get 获取对象
func (e *SysDictType) Get(d *dto.SysDictTypeGetReq, model *models.SysDictType) error {
var err error
db := e.Orm.First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error: %s", err)
return err
}
if err = db.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Insert 创建对象
func (e *SysDictType) Insert(c *dto.SysDictTypeInsertReq) error {
var err error
var data models.SysDictType
c.Generate(&data)
var count int64
e.Orm.Model(&data).Where("dict_type = ?", data.DictType).Count(&count)
if count > 0 {
return fmt.Errorf("当前字典类型[%s]已经存在!", data.DictType)
}
err = e.Orm.Create(&data).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Update 修改对象
func (e *SysDictType) Update(c *dto.SysDictTypeUpdateReq) error {
var err error
var model = models.SysDictType{}
e.Orm.First(&model, c.GetId())
c.Generate(&model)
db := e.Orm.Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// Remove 删除
func (e *SysDictType) Remove(d *dto.SysDictTypeDeleteReq) error {
var err error
var data models.SysDictType
db := e.Orm.Delete(&data, d.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
// GetAll 获取所有
func (e *SysDictType) GetAll(c *dto.SysDictTypeGetPageReq, list *[]models.SysDictType) error {
var err error
var data models.SysDictType
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
).
Find(list).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
+69
View File
@@ -0,0 +1,69 @@
package service
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysLoginLog struct {
service.Service
}
// GetPage 获取SysLoginLog列表
func (e *SysLoginLog) GetPage(c *dto.SysLoginLogGetPageReq, list *[]models.SysLoginLog, count *int64) error {
var err error
var data models.SysLoginLog
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Get 获取SysLoginLog对象
func (e *SysLoginLog) Get(d *dto.SysLoginLogGetReq, model *models.SysLoginLog) error {
var err error
db := e.Orm.First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error:%s", err)
return err
}
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Remove 删除SysLoginLog
func (e *SysLoginLog) Remove(c *dto.SysLoginLogDeleteReq) error {
var err error
var data models.SysLoginLog
db := e.Orm.Delete(&data, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
+422
View File
@@ -0,0 +1,422 @@
package service
import (
"fmt"
"sort"
"strings"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/pkg/errors"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
cModels "git.ilapage.cn/OPC/chorus/admin/common/models"
"github.com/go-admin-team/go-admin-core/sdk/service"
)
type SysMenu struct {
service.Service
}
// GetPage 获取SysMenu列表
func (e *SysMenu) GetPage(c *dto.SysMenuGetPageReq, menus *[]models.SysMenu) *SysMenu {
var menu = make([]models.SysMenu, 0)
err := e.getPage(c, &menu).Error
if err != nil {
_ = e.AddError(err)
return e
}
for i := 0; i < len(menu); i++ {
if menu[i].ParentId != 0 {
continue
}
menusInfo := menuCall(&menu, menu[i])
*menus = append(*menus, menusInfo)
}
return e
}
// getPage 菜单分页列表
func (e *SysMenu) getPage(c *dto.SysMenuGetPageReq, list *[]models.SysMenu) *SysMenu {
var err error
var data models.SysMenu
err = e.Orm.Model(&data).
Scopes(
cDto.OrderDest("sort", false),
cDto.MakeCondition(c.GetNeedSearch()),
).Preload("SysApi").
Find(list).Error
if err != nil {
e.Log.Errorf("getSysMenuPage error:%s", err)
_ = e.AddError(err)
return e
}
return e
}
// Get 获取SysMenu对象
func (e *SysMenu) Get(d *dto.SysMenuGetReq, model *models.SysMenu) *SysMenu {
var err error
var data models.SysMenu
db := e.Orm.Model(&data).Preload("SysApi").
First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("GetSysMenu error:%s", err)
_ = e.AddError(err)
return e
}
if err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
apis := make([]int, 0)
for _, v := range model.SysApi {
apis = append(apis, v.Id)
}
model.Apis = apis
return e
}
// Insert 创建SysMenu对象
func (e *SysMenu) Insert(c *dto.SysMenuInsertReq) *SysMenu {
var err error
var data models.SysMenu
c.Generate(&data)
tx := e.Orm.Debug().Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
err = tx.Where("id in ?", c.Apis).Find(&data.SysApi).Error
if err != nil {
tx.Rollback()
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
}
err = tx.Create(&data).Error
if err != nil {
tx.Rollback()
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
}
c.MenuId = data.MenuId
err = e.initPaths(tx, &data)
if err != nil {
tx.Rollback()
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
}
tx.Commit()
return e
}
func (e *SysMenu) initPaths(tx *gorm.DB, menu *models.SysMenu) error {
var err error
var data models.SysMenu
parentMenu := new(models.SysMenu)
if menu.ParentId != 0 {
err = tx.Model(&data).First(parentMenu, menu.ParentId).Error
if err != nil {
return err
}
if parentMenu.Paths == "" {
err = errors.New("父级paths异常,请尝试对当前节点父级菜单进行更新操作!")
return err
}
menu.Paths = parentMenu.Paths + "/" + pkg.IntToString(menu.MenuId)
} else {
menu.Paths = "/0/" + pkg.IntToString(menu.MenuId)
}
err = tx.Model(&data).Where("menu_id = ?", menu.MenuId).Update("paths", menu.Paths).Error
return err
}
// Update 修改SysMenu对象
func (e *SysMenu) Update(c *dto.SysMenuUpdateReq) *SysMenu {
var err error
tx := e.Orm.Debug().Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
var alist = make([]models.SysApi, 0)
var model = models.SysMenu{}
tx.Preload("SysApi").First(&model, c.GetId())
oldPath := model.Paths
tx.Where("id in ?", c.Apis).Find(&alist)
err = tx.Model(&model).Association("SysApi").Delete(model.SysApi)
if err != nil {
e.Log.Errorf("delete policy error:%s", err)
_ = e.AddError(err)
return e
}
c.Generate(&model)
model.SysApi = alist
db := tx.Model(&model).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
if db.RowsAffected == 0 {
_ = e.AddError(errors.New("无权更新该数据"))
return e
}
var menuList []models.SysMenu
tx.Where("paths like ?", oldPath+"%").Find(&menuList)
for _, v := range menuList {
v.Paths = strings.Replace(v.Paths, oldPath, model.Paths, 1)
tx.Model(&v).Update("paths", v.Paths)
}
return e
}
// Remove 删除SysMenu
func (e *SysMenu) Remove(d *dto.SysMenuDeleteReq) *SysMenu {
var err error
var data models.SysMenu
db := e.Orm.Model(&data).Delete(&data, d.Ids)
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
_ = e.AddError(err)
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
_ = e.AddError(err)
}
return e
}
// GetList 获取菜单数据
func (e *SysMenu) GetList(c *dto.SysMenuGetPageReq, list *[]models.SysMenu) error {
var err error
var data models.SysMenu
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
).
Find(list).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// SetLabel 修改角色中 设置菜单基础数据
func (e *SysMenu) SetLabel() (m []dto.MenuLabel, err error) {
var list []models.SysMenu
err = e.GetList(&dto.SysMenuGetPageReq{}, &list)
m = make([]dto.MenuLabel, 0)
for i := 0; i < len(list); i++ {
if list[i].ParentId != 0 {
continue
}
e := dto.MenuLabel{}
e.Id = list[i].MenuId
e.Label = list[i].Title
deptsInfo := menuLabelCall(&list, e)
m = append(m, deptsInfo)
}
return
}
// GetSysMenuByRoleName 左侧菜单
func (e *SysMenu) GetSysMenuByRoleName(roleName ...string) ([]models.SysMenu, error) {
var MenuList []models.SysMenu
var role models.SysRole
var err error
admin := false
for _, s := range roleName {
if s == "admin" {
admin = true
}
}
if len(roleName) > 0 && admin {
var data []models.SysMenu
err = e.Orm.Where(" menu_type in ('M','C')").
Order("sort").
Find(&data).
Error
MenuList = data
} else {
err = e.Orm.Model(&role).Preload("SysMenu", func(db *gorm.DB) *gorm.DB {
return db.Where(" menu_type in ('M','C')").Order("sort")
}).Where("role_name in ?", roleName).Find(&role).
Error
MenuList = *role.SysMenu
}
if err != nil {
e.Log.Errorf("db error:%s", err)
}
return MenuList, err
}
// menuLabelCall 递归构造组织数据
func menuLabelCall(eList *[]models.SysMenu, dept dto.MenuLabel) dto.MenuLabel {
list := *eList
min := make([]dto.MenuLabel, 0)
for j := 0; j < len(list); j++ {
if dept.Id != list[j].ParentId {
continue
}
mi := dto.MenuLabel{}
mi.Id = list[j].MenuId
mi.Label = list[j].Title
mi.Children = []dto.MenuLabel{}
if list[j].MenuType != "F" {
ms := menuLabelCall(eList, mi)
min = append(min, ms)
} else {
min = append(min, mi)
}
}
if len(min) > 0 {
dept.Children = min
} else {
dept.Children = nil
}
return dept
}
// menuCall 构建菜单树
func menuCall(menuList *[]models.SysMenu, menu models.SysMenu) models.SysMenu {
list := *menuList
min := make([]models.SysMenu, 0)
for j := 0; j < len(list); j++ {
if menu.MenuId != list[j].ParentId {
continue
}
mi := models.SysMenu{}
mi.MenuId = list[j].MenuId
mi.MenuName = list[j].MenuName
mi.Title = list[j].Title
mi.Icon = list[j].Icon
mi.Path = list[j].Path
mi.MenuType = list[j].MenuType
mi.Action = list[j].Action
mi.Permission = list[j].Permission
mi.ParentId = list[j].ParentId
mi.NoCache = list[j].NoCache
mi.Breadcrumb = list[j].Breadcrumb
mi.Component = list[j].Component
mi.Sort = list[j].Sort
mi.Visible = list[j].Visible
mi.CreatedAt = list[j].CreatedAt
mi.SysApi = list[j].SysApi
mi.Children = []models.SysMenu{}
if mi.MenuType != cModels.Button {
ms := menuCall(menuList, mi)
min = append(min, ms)
} else {
min = append(min, mi)
}
}
menu.Children = min
return menu
}
func menuDistinct(menuList []models.SysMenu) (result []models.SysMenu) {
distinctMap := make(map[int]struct{}, len(menuList))
for _, menu := range menuList {
if _, ok := distinctMap[menu.MenuId]; !ok {
distinctMap[menu.MenuId] = struct{}{}
result = append(result, menu)
}
}
return result
}
func recursiveSetMenu(orm *gorm.DB, mIds []int, menus *[]models.SysMenu) error {
if len(mIds) == 0 || menus == nil {
return nil
}
var subMenus []models.SysMenu
err := orm.Where(fmt.Sprintf(" menu_type in ('%s', '%s', '%s') and menu_id in ?",
cModels.Directory, cModels.Menu, cModels.Button), mIds).Order("sort").Find(&subMenus).Error
if err != nil {
return err
}
subIds := make([]int, 0)
for _, menu := range subMenus {
if menu.ParentId != 0 {
subIds = append(subIds, menu.ParentId)
}
if menu.MenuType != cModels.Button {
*menus = append(*menus, menu)
}
}
return recursiveSetMenu(orm, subIds, menus)
}
// SetMenuRole 获取左侧菜单树使用
func (e *SysMenu) SetMenuRole(roleName string) (m []models.SysMenu, err error) {
menus, err := e.getByRoleName(roleName)
m = make([]models.SysMenu, 0)
for i := 0; i < len(menus); i++ {
if menus[i].ParentId != 0 {
continue
}
menusInfo := menuCall(&menus, menus[i])
m = append(m, menusInfo)
}
return
}
func (e *SysMenu) getByRoleName(roleName string) ([]models.SysMenu, error) {
var role models.SysRole
var err error
data := make([]models.SysMenu, 0)
if roleName == "admin" {
err = e.Orm.Where(" menu_type in ('M','C') and deleted_at is null").
Order("sort").
Find(&data).
Error
err = errors.WithStack(err)
} else {
role.RoleKey = roleName
err = e.Orm.Model(&role).Where("role_key = ? ", roleName).Preload("SysMenu").First(&role).Error
if role.SysMenu != nil {
mIds := make([]int, 0)
for _, menu := range *role.SysMenu {
mIds = append(mIds, menu.MenuId)
}
if err := recursiveSetMenu(e.Orm, mIds, &data); err != nil {
return nil, err
}
data = menuDistinct(data)
}
}
sort.Sort(models.SysMenuSlice(data))
return data, err
}
+83
View File
@@ -0,0 +1,83 @@
package service
import (
"errors"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
)
type SysOperaLog struct {
service.Service
}
// GetPage 获取SysOperaLog列表
func (e *SysOperaLog) GetPage(c *dto.SysOperaLogGetPageReq, list *[]models.SysOperaLog, count *int64) error {
var err error
var data models.SysOperaLog
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("Service GetSysOperaLogPage error:%s", err.Error())
return err
}
return nil
}
// Get 获取SysOperaLog对象
func (e *SysOperaLog) Get(d *dto.SysOperaLogGetReq, model *models.SysOperaLog) error {
var data models.SysOperaLog
err := e.Orm.Model(&data).
First(model, d.GetId()).Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
return err
}
if err != nil {
e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
return err
}
return nil
}
// Insert 创建SysOperaLog对象
func (e *SysOperaLog) Insert(model *models.SysOperaLog) error {
var err error
var data models.SysOperaLog
err = e.Orm.Model(&data).
Create(model).Error
if err != nil {
e.Log.Errorf("Service InsertSysOperaLog error:%s", err.Error())
return err
}
return nil
}
// Remove 删除SysOperaLog
func (e *SysOperaLog) Remove(d *dto.SysOperaLogDeleteReq) error {
var err error
var data models.SysOperaLog
db := e.Orm.Model(&data).Delete(&data, d.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Service RemoveSysOperaLog error:%s", err.Error())
return err
}
if db.RowsAffected == 0 {
return errors.New("无权删除该数据")
}
return nil
}
+104
View File
@@ -0,0 +1,104 @@
package service
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysPost struct {
service.Service
}
// GetPage 获取SysPost列表
func (e *SysPost) GetPage(c *dto.SysPostPageReq, list *[]models.SysPost, count *int64) error {
var err error
var data models.SysPost
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error:%s \r", err)
return err
}
return nil
}
// Get 获取SysPost对象
func (e *SysPost) Get(d *dto.SysPostGetReq, model *models.SysPost) error {
var err error
var data models.SysPost
db := e.Orm.Model(&data).
First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error:%s", err)
return err
}
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Insert 创建SysPost对象
func (e *SysPost) Insert(c *dto.SysPostInsertReq) error {
var err error
var data models.SysPost
c.Generate(&data)
err = e.Orm.Create(&data).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Update 修改SysPost对象
func (e *SysPost) Update(c *dto.SysPostUpdateReq) error {
var err error
var model = models.SysPost{}
e.Orm.First(&model, c.GetId())
c.Generate(&model)
db := e.Orm.Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// Remove 删除SysPost
func (e *SysPost) Remove(d *dto.SysPostDeleteReq) error {
var err error
var data models.SysPost
db := e.Orm.Model(&data).Delete(&data, d.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Delete error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("无权删除该数据")
return err
}
return nil
}
+352
View File
@@ -0,0 +1,352 @@
package service
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/config"
"gorm.io/gorm/clause"
"github.com/casbin/casbin/v2"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysRole struct {
service.Service
}
// GetPage 获取SysRole列表
func (e *SysRole) GetPage(c *dto.SysRoleGetPageReq, list *[]models.SysRole, count *int64) error {
var err error
var data models.SysRole
err = e.Orm.Model(&data).Preload("SysMenu").
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Get 获取SysRole对象
func (e *SysRole) Get(d *dto.SysRoleGetReq, model *models.SysRole) error {
var err error
db := e.Orm.First(model, d.GetId())
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error:%s", err)
return err
}
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
model.MenuIds, err = e.GetRoleMenuId(model.RoleId)
if err != nil {
e.Log.Errorf("get menuIds error, %s", err.Error())
return err
}
return nil
}
// Insert 创建SysRole对象
func (e *SysRole) Insert(c *dto.SysRoleInsertReq, cb *casbin.SyncedEnforcer) error {
var err error
var data models.SysRole
var dataMenu []models.SysMenu
err = e.Orm.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&dataMenu).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
c.SysMenu = dataMenu
c.Generate(&data)
tx := e.Orm
if config.DatabaseConfig.Driver != "sqlite3" {
tx = e.Orm.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
}
var count int64
err = tx.Model(&data).Where("role_key = ?", c.RoleKey).Count(&count).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
if count > 0 {
err = errors.New("roleKey已存在,需更换在提交!")
e.Log.Errorf("db error:%s", err)
return err
}
err = tx.Create(&data).Error
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
mp := make(map[string]interface{}, 0)
polices := make([][]string, 0)
for _, menu := range dataMenu {
for _, api := range menu.SysApi {
if mp[data.RoleKey+"-"+api.Path+"-"+api.Action] != "" {
mp[data.RoleKey+"-"+api.Path+"-"+api.Action] = ""
polices = append(polices, []string{data.RoleKey, api.Path, api.Action})
}
}
}
if len(polices) <= 0 {
return nil
}
// 写入 sys_casbin_rule 权限表里 当前角色数据的记录
_, err = cb.AddNamedPolicies("p", polices)
if err != nil {
return err
}
return nil
}
// Update 修改SysRole对象
func (e *SysRole) Update(c *dto.SysRoleUpdateReq, cb *casbin.SyncedEnforcer) error {
var err error
tx := e.Orm
if config.DatabaseConfig.Driver != "sqlite3" {
tx = e.Orm.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
}
var model = models.SysRole{}
var mlist = make([]models.SysMenu, 0)
tx.Preload("SysMenu").First(&model, c.GetId())
tx.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&mlist)
err = tx.Model(&model).Association("SysMenu").Delete(model.SysMenu)
if err != nil {
e.Log.Errorf("delete policy error:%s", err)
return err
}
c.Generate(&model)
model.SysMenu = &mlist
// 更新关联的数据,使用 FullSaveAssociations 模式
db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
// 清除 sys_casbin_rule 权限表里 当前角色的所有记录
_, err = cb.RemoveFilteredPolicy(0, model.RoleKey)
if err != nil {
e.Log.Errorf("delete policy error:%s", err)
return err
}
mp := make(map[string]interface{}, 0)
polices := make([][]string, 0)
for _, menu := range mlist {
for _, api := range menu.SysApi {
if mp[model.RoleKey+"-"+api.Path+"-"+api.Action] != "" {
mp[model.RoleKey+"-"+api.Path+"-"+api.Action] = ""
//_, err = cb.AddNamedPolicy("p", model.RoleKey, api.Path, api.Action)
polices = append(polices, []string{model.RoleKey, api.Path, api.Action})
}
}
}
if len(polices) <= 0 {
return nil
}
// 写入 sys_casbin_rule 权限表里 当前角色数据的记录
_, err = cb.AddNamedPolicies("p", polices)
if err != nil {
return err
}
return nil
}
// Remove 删除SysRole
func (e *SysRole) Remove(c *dto.SysRoleDeleteReq, cb *casbin.SyncedEnforcer) error {
var err error
tx := e.Orm
if config.DatabaseConfig.Driver != "sqlite3" {
tx = e.Orm.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
}
var model = models.SysRole{}
tx.Preload("SysMenu").Preload("SysDept").First(&model, c.GetId())
//删除 SysRole 时,同时删除角色所有 关联其它表 记录 (SysMenu 和 SysMenu)
db := tx.Select(clause.Associations).Delete(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
// 清除 sys_casbin_rule 权限表里 当前角色的所有记录
_, _ = cb.RemoveFilteredPolicy(0, model.RoleKey)
return nil
}
// GetRoleMenuId 获取角色对应的菜单ids
func (e *SysRole) GetRoleMenuId(roleId int) ([]int, error) {
menuIds := make([]int, 0)
model := models.SysRole{}
model.RoleId = roleId
if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
return nil, err
}
l := *model.SysMenu
for i := 0; i < len(l); i++ {
menuIds = append(menuIds, l[i].MenuId)
}
return menuIds, nil
}
func (e *SysRole) UpdateDataScope(c *dto.RoleDataScopeReq) *SysRole {
var err error
tx := e.Orm
if config.DatabaseConfig.Driver != "sqlite3" {
tx = e.Orm.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
}
var dlist = make([]models.SysDept, 0)
var model = models.SysRole{}
tx.Preload("SysDept").First(&model, c.RoleId)
tx.Where("dept_id in ?", c.DeptIds).Find(&dlist)
// 删除SysRole 和 SysDept 的关联关系
err = tx.Model(&model).Association("SysDept").Delete(model.SysDept)
if err != nil {
e.Log.Errorf("delete SysDept error:%s", err)
_ = e.AddError(err)
return e
}
c.Generate(&model)
model.SysDept = dlist
// 更新关联的数据,使用 FullSaveAssociations 模式
db := tx.Model(&model).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
if db.RowsAffected == 0 {
_ = e.AddError(errors.New("无权更新该数据"))
return e
}
return e
}
// UpdateStatus 修改SysRole对象status
func (e *SysRole) UpdateStatus(c *dto.UpdateStatusReq) error {
var err error
tx := e.Orm
if config.DatabaseConfig.Driver != "sqlite3" {
tx = e.Orm.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
}
var model = models.SysRole{}
tx.First(&model, c.GetId())
c.Generate(&model)
// 更新关联的数据,使用 FullSaveAssociations 模式
db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model)
if err = db.Error; err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
return nil
}
// GetWithName 获取SysRole对象
func (e *SysRole) GetWithName(d *dto.SysRoleByName, model *models.SysRole) *SysRole {
var err error
db := e.Orm.Where("role_name = ?", d.RoleName).First(model)
err = db.Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
if err != nil {
e.Log.Errorf("db error:%s", err)
_ = e.AddError(err)
return e
}
model.MenuIds, err = e.GetRoleMenuId(model.RoleId)
if err != nil {
e.Log.Errorf("get menuIds error, %s", err.Error())
_ = e.AddError(err)
return e
}
return e
}
// GetById 获取SysRole对象
func (e *SysRole) GetById(roleId int) ([]string, error) {
permissions := make([]string, 0)
model := models.SysRole{}
model.RoleId = roleId
if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
return nil, err
}
l := *model.SysMenu
for i := 0; i < len(l); i++ {
if l[i].Permission != "" {
permissions = append(permissions, l[i].Permission)
}
}
return permissions, nil
}
+110
View File
@@ -0,0 +1,110 @@
package service
import (
"github.com/go-admin-team/go-admin-core/sdk/service"
)
// SysRoleMenu 即将弃用结构体
type SysRoleMenu struct {
service.Service
}
//func (e *SysRoleMenu) ReloadRule(tx *gorm.DB, roleId int, menuId []int) (err error) {
// var role models.SysRole
//
// msgID := e.MsgID
//
// menu := make([]models.Menu, 0)
// roleMenu := make([]models.RoleMenu, len(menuId))
// casbinRule := make([]models.CasbinRule, 0)
// //先删除所有的
// err = e.DeleteRoleMenu(tx, roleId)
// if err != nil {
// return
// }
//
// // 在事务中做一些数据库操作(从这一点使用'tx',而不是'db')
// err = tx.Where("role_id = ?", roleId).First(&role).Error
// if err != nil {
// log.Errorf("msgID[%s] get role error, %s", msgID, err.Error())
// return
// }
// err = tx.Where("menu_id in (?)", menuId).
// //Select("path, action, menu_id, menu_type").
// Find(&menu).Error
// if err != nil {
// log.Errorf("msgID[%s] get menu error, %s", msgID, err.Error())
// return
// }
// for i := range menu {
// roleMenu[i] = models.RoleMenu{
// RoleId: role.RoleId,
// MenuId: menu[i].MenuId,
// RoleName: role.RoleKey,
// }
// if menu[i].MenuType == "A" {
// casbinRule = append(casbinRule, models.CasbinRule{
// PType: "p",
// V0: role.RoleKey,
// V1: menu[i].Path,
// V2: menu[i].Action,
// })
// }
// }
// err = tx.Create(&roleMenu).Error
// if err != nil {
// log.Errorf("msgID[%s] batch create role's menu error, %s", msgID, err.Error())
// return
// }
// if len(casbinRule) > 0 {
// err = tx.Create(&casbinRule).Error
// if err != nil {
// log.Errorf("msgID[%s] batch create casbin rule error, %s", msgID, err.Error())
// return
// }
// }
//
// return
//}
//func (e *SysRoleMenu) DeleteRoleMenu(tx *gorm.DB, roleId int) (err error) {
// msgID := e.MsgID
// err = tx.Where("role_id = ?", roleId).
// Delete(&models.SysRoleDept{}).Error
// if err != nil {
// log.Errorf("msgID[%s] delete role's dept error, %s", msgID, err.Error())
// return
// }
// err = tx.Where("role_id = ?", roleId).
// Delete(&models.RoleMenu{}).Error
// if err != nil {
// log.Errorf("msgID[%s] delete role's menu error, %s", msgID, err.Error())
// return
// }
// var role models.SysRole
// err = tx.Where("role_id = ?", roleId).
// First(&role).Error
// if err != nil {
// log.Errorf("msgID[%s] get role error, %s", msgID, err.Error())
// return
// }
// err = tx.Where("v0 = ?", role.RoleKey).
// Delete(&models.CasbinRule{}).Error
// if err != nil {
// log.Errorf("msgID[%s] delete casbin rule error, %s", msgID, err.Error())
// return
// }
// return
//}
//
//func (e *SysRoleMenu) GetIDS(tx *gorm.DB, roleName string) ([]models.MenuPath, error) {
// var r []models.MenuPath
// table := tx.Select("sys_menu.path").Table("sys_role_menu")
// table = table.Joins("left join sys_role on sys_role.role_id=sys_role_menu.role_id")
// table = table.Joins("left join sys_menu on sys_menu.id=sys_role_menu.menu_id")
// table = table.Where("sys_role.role_name = ? and sys_menu.type=1", roleName)
// if err := table.Find(&r).Error; err != nil {
// return nil, err
// }
// return r, nil
//}
+266
View File
@@ -0,0 +1,266 @@
package service
import (
"errors"
"git.ilapage.cn/OPC/chorus/admin/app/admin/models"
"git.ilapage.cn/OPC/chorus/admin/app/admin/service/dto"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/common/actions"
cDto "git.ilapage.cn/OPC/chorus/admin/common/dto"
)
type SysUser struct {
service.Service
}
// GetPage 获取SysUser列表
func (e *SysUser) GetPage(c *dto.SysUserGetPageReq, p *actions.DataPermission, list *[]models.SysUser, count *int64) error {
var err error
var data models.SysUser
err = e.Orm.Debug().Preload("Dept").
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Get 获取SysUser对象
func (e *SysUser) Get(d *dto.SysUserById, p *actions.DataPermission, model *models.SysUser) error {
var data models.SysUser
err := e.Orm.Model(&data).Debug().
Scopes(
actions.Permission(data.TableName(), p),
).
First(model, d.GetId()).Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("db error: %s", err)
return err
}
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Insert 创建SysUser对象
func (e *SysUser) Insert(c *dto.SysUserInsertReq) error {
var err error
var data models.SysUser
var i int64
err = e.Orm.Model(&data).Where("username = ?", c.Username).Count(&i).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
if i > 0 {
err := errors.New("用户名已存在!")
e.Log.Errorf("db error: %s", err)
return err
}
c.Generate(&data)
err = e.Orm.Create(&data).Error
if err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
return nil
}
// Update 修改SysUser对象
func (e *SysUser) Update(c *dto.SysUserUpdateReq, p *actions.DataPermission) error {
var err error
var model models.SysUser
db := e.Orm.Scopes(
actions.Permission(model.TableName(), p),
).First(&model, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Service UpdateSysUser error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
c.Generate(&model)
update := e.Orm.Model(&model).Where("user_id = ?", &model.UserId).Omit("password", "salt").Updates(&model)
if err = update.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
if update.RowsAffected == 0 {
err = errors.New("update userinfo error")
log.Warnf("db update error")
return err
}
return nil
}
// UpdateAvatar 更新用户头像
func (e *SysUser) UpdateAvatar(c *dto.UpdateSysUserAvatarReq, p *actions.DataPermission) error {
var err error
var model models.SysUser
db := e.Orm.Scopes(
actions.Permission(model.TableName(), p),
).First(&model, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Service UpdateSysUser error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
err = e.Orm.Table(model.TableName()).Where("user_id =? ", c.UserId).Updates(c).Error
if err != nil {
e.Log.Errorf("Service UpdateSysUser error: %s", err)
return err
}
return nil
}
// UpdateStatus 更新用户状态
func (e *SysUser) UpdateStatus(c *dto.UpdateSysUserStatusReq, p *actions.DataPermission) error {
var err error
var model models.SysUser
db := e.Orm.Scopes(
actions.Permission(model.TableName(), p),
).First(&model, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Service UpdateSysUser error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
err = e.Orm.Table(model.TableName()).Where("user_id =? ", c.UserId).Updates(c).Error
if err != nil {
e.Log.Errorf("Service UpdateSysUser error: %s", err)
return err
}
return nil
}
// ResetPwd 重置用户密码
func (e *SysUser) ResetPwd(c *dto.ResetSysUserPwdReq, p *actions.DataPermission) error {
var err error
var model models.SysUser
db := e.Orm.Scopes(
actions.Permission(model.TableName(), p),
).First(&model, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("At Service ResetSysUserPwd error: %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
c.Generate(&model)
err = e.Orm.Omit("username", "nick_name", "phone", "role_id", "avatar", "sex").Save(&model).Error
if err != nil {
e.Log.Errorf("At Service ResetSysUserPwd error: %s", err)
return err
}
return nil
}
// Remove 删除SysUser
func (e *SysUser) Remove(c *dto.SysUserById, p *actions.DataPermission) error {
var err error
var data models.SysUser
db := e.Orm.Model(&data).
Scopes(
actions.Permission(data.TableName(), p),
).Delete(&data, c.GetId())
if err = db.Error; err != nil {
e.Log.Errorf("Error found in RemoveSysUser : %s", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权删除该数据")
}
return nil
}
// UpdatePwd 修改SysUser对象密码
func (e *SysUser) UpdatePwd(id int, oldPassword, newPassword string, p *actions.DataPermission) error {
var err error
if newPassword == "" {
return nil
}
c := &models.SysUser{}
err = e.Orm.Model(c).
Scopes(
actions.Permission(c.TableName(), p),
).Select("UserId", "Password", "Salt").
First(c, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("无权更新该数据")
}
e.Log.Errorf("db error: %s", err)
return err
}
var ok bool
ok, err = pkg.CompareHashAndPassword(c.Password, oldPassword)
if err != nil {
e.Log.Errorf("CompareHashAndPassword error, %s", err.Error())
return err
}
if !ok {
err = errors.New("incorrect Password")
e.Log.Warnf("user[%d] %s", id, err.Error())
return err
}
c.Password = newPassword
db := e.Orm.Model(c).Where("user_id = ?", id).
Select("Password", "Salt").
Updates(c)
if err = db.Error; err != nil {
e.Log.Errorf("db error: %s", err)
return err
}
if db.RowsAffected == 0 {
err = errors.New("set password error")
log.Warnf("db update error")
return err
}
return nil
}
func (e *SysUser) GetProfile(c *dto.SysUserById, user *models.SysUser, roles *[]models.SysRole, posts *[]models.SysPost) error {
err := e.Orm.Preload("Dept").First(user, c.GetId()).Error
if err != nil {
return err
}
err = e.Orm.Find(roles, user.RoleId).Error
if err != nil {
return err
}
err = e.Orm.Find(posts, user.PostIds).Error
if err != nil {
return err
}
return nil
}
+25
View File
@@ -0,0 +1,25 @@
package chorus
import (
"errors"
"fmt"
)
var (
ErrNotFound = errors.New("chorus resource not found")
ErrConflict = errors.New("chorus configuration version conflict")
ErrConnectivityDisabled = errors.New("connectivity checks require explicit authorization")
)
type FieldError struct {
Field string `json:"field"`
Message string `json:"message"`
}
func (e FieldError) Error() string {
return fmt.Sprintf("invalid %s: %s", e.Field, e.Message)
}
type CooldownError struct{ RetryAfterSeconds uint32 }
func (e CooldownError) Error() string { return "connectivity check is cooling down" }
+49
View File
@@ -0,0 +1,49 @@
package chorus
import (
"context"
"encoding/base64"
"errors"
"git.ilapage.cn/OPC/chorus/internal/core/model"
"git.ilapage.cn/OPC/chorus/internal/core/provider"
)
const connectivityPrompt = "Chorus connectivity probe. Reply with OK."
type LiveProbe struct{ http provider.HTTPClient }
func NewLiveProbe(httpClient provider.HTTPClient) (*LiveProbe, error) {
if httpClient == nil {
return nil, errors.New("safe provider HTTP client is required")
}
return &LiveProbe{http: httpClient}, nil
}
func (p *LiveProbe) Probe(ctx context.Context, cfg ProbeConfiguration) error {
client, err := provider.NewOpenAI(p.http, provider.OpenAIConfig{
BaseURL: cfg.BaseURL, AuthType: cfg.AuthType, APIKey: cfg.APIKey,
ExtraBody: cfg.ExtraBody, MaxResponseBytes: cfg.MaxResponseBytes,
})
if err != nil {
return errors.New("prepare connectivity probe")
}
probeCtx, cancel := context.WithTimeout(ctx, cfg.Timeout)
defer cancel()
request := provider.Request{Kind: cfg.Kind, APIType: cfg.APIType, ModelID: cfg.ModelID, RenderedPrompt: connectivityPrompt}
if cfg.APIType == model.APIImagesEdits {
content, err := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL4WQAAAABJRU5ErkJggg==")
if err != nil {
return errors.New("prepare connectivity image")
}
defer clear(content)
request.Inputs = []provider.Input{{Content: content, MIMEType: "image/png", Role: model.RolePrimary, Position: 0}}
}
outputs, err := client.Generate(probeCtx, request)
if err != nil || len(outputs) == 0 {
return errors.New("connectivity probe failed")
}
return nil
}
var _ ProbeRunner = (*LiveProbe)(nil)
+285
View File
@@ -0,0 +1,285 @@
package chorus
import (
"errors"
"net/http"
"strconv"
"strings"
"git.ilapage.cn/OPC/chorus/admin/common/middleware"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
"github.com/google/uuid"
"gorm.io/gorm"
)
type serviceFactory func(*gin.Context) (*Service, error)
var configuredFactory serviceFactory
// Configure installs the service factory used by the fixed go-admin router.
// The caller is responsible for supplying the repository-wide key ring and
// safe HTTP probe configuration during server setup.
func Configure(cipherConfig func(*gorm.DB) (*Service, error)) {
configuredFactory = func(c *gin.Context) (*Service, error) {
value, ok := c.Get("db")
if !ok {
return nil, errors.New("go-admin database context is unavailable")
}
db, ok := value.(*gorm.DB)
if !ok || db == nil {
return nil, errors.New("go-admin database context is invalid")
}
return cipherConfig(db)
}
}
// Register attaches the extension to the normal go-admin JWT and Casbin
// chain. It does not create a parallel authentication path.
func Register(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
if configuredFactory == nil {
panic("chorus admin service is not configured")
}
register(v1, authMiddleware.MiddlewareFunc(), middleware.AuthCheckRole(), configuredFactory)
}
// RegisterWithService is kept for handler tests and for explicit embedding.
// Production callers should use Register so that go-admin's JWT and Casbin
// middleware remain mandatory.
func RegisterWithService(v1 *gin.RouterGroup, authentication, authorization gin.HandlerFunc, service *Service) {
register(v1, authentication, authorization, func(*gin.Context) (*Service, error) { return service, nil })
}
func register(v1 *gin.RouterGroup, authentication, authorization gin.HandlerFunc, factory serviceFactory) {
r := v1.Group("/chorus").Use(authentication, authorization)
r.GET("/providers", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.Providers(c.Request.Context())
}))
r.POST("/providers", withBody[ProviderInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, input ProviderInput) (any, error) {
return service.CreateProvider(c.Request.Context(), actor, requestID, input)
}))
r.GET("/providers/:id", withID(factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64) (any, error) {
return service.Provider(c.Request.Context(), id)
}))
r.PUT("/providers/:id", withIDBody[ProviderInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64, input ProviderInput) (any, error) {
return service.UpdateProvider(c.Request.Context(), actor, requestID, id, input)
}))
r.PUT("/providers/:id/credential", withIDBody[struct {
APIKey string `json:"api_key"`
}](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64, input struct {
APIKey string `json:"api_key"`
}) (any, error) {
return service.RotateCredential(c.Request.Context(), actor, requestID, id, input.APIKey)
}))
r.POST("/providers/:id/credential/:version/activate", withTwoIDs(factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id, version uint64) (any, error) {
if version > uint64(^uint32(0)) {
return nil, FieldError{Field: "credential_version", Message: "is too large"}
}
return service.ActivateCredential(c.Request.Context(), actor, requestID, id, uint32(version))
}))
r.GET("/provider-models", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.ProviderModels(c.Request.Context())
}))
r.POST("/provider-models", withBody[ProviderModelInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, input ProviderModelInput) (any, error) {
return service.CreateProviderModel(c.Request.Context(), actor, requestID, input)
}))
r.PUT("/provider-models/:id", withIDBody[ProviderModelInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64, input ProviderModelInput) (any, error) {
return service.UpdateProviderModel(c.Request.Context(), actor, requestID, id, input)
}))
r.POST("/provider-models/:id/connectivity-checks", withID(factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64) (any, error) {
return service.StartConnectivityCheck(c.Request.Context(), actor, requestID, id)
}))
r.GET("/prompt-templates", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.PromptTemplates(c.Request.Context())
}))
r.POST("/prompt-templates", withBody[PromptTemplateInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, input PromptTemplateInput) (any, error) {
return service.CreatePromptTemplate(c.Request.Context(), actor, requestID, input)
}))
r.PUT("/prompt-templates/:id", withIDBody[PromptTemplateInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64, input PromptTemplateInput) (any, error) {
return service.UpdatePromptTemplate(c.Request.Context(), actor, requestID, id, input)
}))
r.GET("/route-pools", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.RoutePools(c.Request.Context())
}))
r.POST("/route-pools", withBody[RoutePoolInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, input RoutePoolInput) (any, error) {
return service.CreateRoutePool(c.Request.Context(), actor, requestID, input)
}))
r.PUT("/route-pools/:id", withIDBody[RoutePoolInput](factory, func(c *gin.Context, service *Service, actor uint64, requestID string, id uint64, input RoutePoolInput) (any, error) {
return service.UpdateRoutePool(c.Request.Context(), actor, requestID, id, input)
}))
r.GET("/users", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.Users(c.Request.Context())
}))
r.GET("/generations", withService(factory, func(c *gin.Context, service *Service, actor uint64, requestID string) (any, error) {
return service.Generations(c.Request.Context())
}))
}
type endpoint func(*gin.Context, *Service, uint64, string) (any, error)
type idEndpoint func(*gin.Context, *Service, uint64, string, uint64) (any, error)
func withService(factory serviceFactory, endpoint endpoint) gin.HandlerFunc {
return func(c *gin.Context) {
service, actor, requestID, ok := requestScope(c, factory)
if !ok {
return
}
data, err := endpoint(c, service, actor, requestID)
respond(c, data, err)
}
}
func withID(factory serviceFactory, endpoint idEndpoint) gin.HandlerFunc {
return func(c *gin.Context) {
service, actor, requestID, ok := requestScope(c, factory)
if !ok {
return
}
id, err := pathID(c, "id")
if err != nil {
respond(c, nil, err)
return
}
data, endpointErr := endpoint(c, service, actor, requestID, id)
respond(c, data, endpointErr)
}
}
func withTwoIDs(factory serviceFactory, endpoint func(*gin.Context, *Service, uint64, string, uint64, uint64) (any, error)) gin.HandlerFunc {
return func(c *gin.Context) {
service, actor, requestID, ok := requestScope(c, factory)
if !ok {
return
}
id, err := pathID(c, "id")
if err == nil {
var version uint64
version, err = pathID(c, "version")
if err == nil {
data, endpointErr := endpoint(c, service, actor, requestID, id, version)
respond(c, data, endpointErr)
return
}
}
respond(c, nil, err)
}
}
func withBody[T any](factory serviceFactory, endpoint func(*gin.Context, *Service, uint64, string, T) (any, error)) gin.HandlerFunc {
return func(c *gin.Context) {
service, actor, requestID, ok := requestScope(c, factory)
if !ok {
return
}
var input T
if err := c.ShouldBindJSON(&input); err != nil {
respond(c, nil, FieldError{Field: "body", Message: "must be valid JSON"})
return
}
data, endpointErr := endpoint(c, service, actor, requestID, input)
respond(c, data, endpointErr)
}
}
func withIDBody[T any](factory serviceFactory, endpoint func(*gin.Context, *Service, uint64, string, uint64, T) (any, error)) gin.HandlerFunc {
return func(c *gin.Context) {
service, actor, requestID, ok := requestScope(c, factory)
if !ok {
return
}
id, err := pathID(c, "id")
if err != nil {
respond(c, nil, err)
return
}
var input T
if err := c.ShouldBindJSON(&input); err != nil {
respond(c, nil, FieldError{Field: "body", Message: "must be valid JSON"})
return
}
data, endpointErr := endpoint(c, service, actor, requestID, id, input)
respond(c, data, endpointErr)
}
}
func requestScope(c *gin.Context, factory serviceFactory) (*Service, uint64, string, bool) {
service, err := factory(c)
if err != nil {
respond(c, nil, err)
return nil, 0, "", false
}
actor, err := actorID(c)
if err != nil {
respond(c, nil, err)
return nil, 0, "", false
}
requestID := strings.TrimSpace(c.GetHeader(pkg.TrafficKey))
if requestID == "" {
requestID = uuid.NewString()
}
return service, actor, requestID, true
}
func actorID(c *gin.Context) (uint64, error) {
claims := jwt.ExtractClaims(c)
value, ok := claims[jwt.IdentityKey]
if !ok {
return 0, errors.New("administrator identity is missing")
}
switch value := value.(type) {
case float64:
if value > 0 && value == float64(uint64(value)) {
return uint64(value), nil
}
case string:
parsed, err := strconv.ParseUint(value, 10, 64)
if err == nil && parsed > 0 {
return parsed, nil
}
case uint64:
if value > 0 {
return value, nil
}
}
return 0, errors.New("administrator identity is invalid")
}
func pathID(c *gin.Context, name string) (uint64, error) {
value, err := strconv.ParseUint(c.Param(name), 10, 64)
if err != nil || value == 0 {
return 0, FieldError{Field: name, Message: "must be a positive integer"}
}
return value, nil
}
func respond(c *gin.Context, data any, err error) {
if err == nil {
c.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "data": data, "msg": "ok"})
return
}
status, code, message := http.StatusInternalServerError, "internal_error", "request could not be completed"
response := gin.H{"code": status, "error": code, "msg": message}
var field FieldError
var cooldown CooldownError
switch {
case errors.As(err, &field):
status, code, message = http.StatusUnprocessableEntity, "validation_failed", "request fields are invalid"
response["field"] = field.Field
case errors.Is(err, ErrNotFound):
status, code, message = http.StatusNotFound, "not_found", "resource was not found"
case errors.Is(err, ErrConflict):
status, code, message = http.StatusConflict, "version_conflict", "configuration has changed; refresh and retry"
case errors.As(err, &cooldown):
status, code, message = http.StatusTooManyRequests, "connectivity_cooldown", "connectivity check is cooling down"
response["retry_after_seconds"] = cooldown.RetryAfterSeconds
case errors.Is(err, ErrConnectivityDisabled):
status, code, message = http.StatusForbidden, "connectivity_not_authorized", "connectivity checks require explicit authorization"
}
response["code"], response["error"], response["msg"] = status, code, message
c.JSON(status, response)
}
+53
View File
@@ -0,0 +1,53 @@
package chorus
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func TestChorusRoutesRequireAuthenticationAuthorizationAndHaveNoDeleteEndpoint(t *testing.T) {
gin.SetMode(gin.TestMode)
engine := gin.New()
authentication := func(c *gin.Context) {
if c.GetHeader("Authorization") != "Bearer test" {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Next()
}
authorization := func(c *gin.Context) {
if c.GetHeader("X-Chorus-Role") != "operator" {
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
}
RegisterWithService(engine.Group("/api/v1"), authentication, authorization, nil)
for _, test := range []struct {
name string
headers map[string]string
method string
path string
want int
}{
{name: "unauthenticated", method: http.MethodGet, path: "/api/v1/chorus/providers", want: http.StatusUnauthorized},
{name: "not authorized", method: http.MethodGet, path: "/api/v1/chorus/providers", headers: map[string]string{"Authorization": "Bearer test"}, want: http.StatusForbidden},
{name: "delete is not exposed", method: http.MethodDelete, path: "/api/v1/chorus/providers/1", headers: map[string]string{"Authorization": "Bearer test", "X-Chorus-Role": "operator"}, want: http.StatusNotFound},
} {
t.Run(test.name, func(t *testing.T) {
recorder := httptest.NewRecorder()
request := httptest.NewRequest(test.method, test.path, nil)
for key, value := range test.headers {
request.Header.Set(key, value)
}
engine.ServeHTTP(recorder, request)
if recorder.Code != test.want {
t.Fatalf("status = %d, want %d", recorder.Code, test.want)
}
})
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,329 @@
package chorus
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
"sync/atomic"
"testing"
"time"
"git.ilapage.cn/OPC/chorus/internal/core/model"
platformcrypto "git.ilapage.cn/OPC/chorus/internal/platform/crypto"
mysqldriver "github.com/go-sql-driver/mysql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/logger"
)
// These tests use only a locally designated disposable database. They are
// opt-in so routine package tests never touch a developer's MySQL instance.
func TestAdminServiceMySQL(t *testing.T) {
db := openAdminTestDB(t)
ctx := context.Background()
deleteAdminFixture(t, db, "admin-")
suffix := fmt.Sprintf("admin-%d", time.Now().UnixNano())
registerActiveRouteRestore(t, db, model.CapabilityImageGenerate)
t.Cleanup(func() { deleteAdminFixture(t, db, suffix) })
service := newAdminTestService(t, db, Config{})
secret := "synthetic-provider-secret-" + suffix
providerInput := ProviderInput{
Slug: "provider-" + suffix, Name: "Provider " + suffix,
BaseURL: "https://provider.invalid/v1", AuthType: "bearer", Enabled: true, APIKey: &secret,
}
providerView, err := service.CreateProvider(ctx, 7, "create-"+suffix, providerInput)
if err != nil {
t.Fatalf("create provider: %v", err)
}
if !providerView.Credential.HasCredential || providerView.Credential.Version != 1 {
t.Fatalf("unexpected credential metadata: %#v", providerView.Credential)
}
response, err := json.Marshal(providerView)
if err != nil {
t.Fatal(err)
}
if bytes.Contains(response, []byte(secret)) || bytes.Contains(response, []byte("ciphertext")) {
t.Fatalf("provider response contains protected credential data: %s", response)
}
var encrypted string
if err := db.Raw("SELECT CAST(api_key_enc AS CHAR) FROM provider_credentials WHERE provider_id = ? AND credential_version = 1", providerView.ID).Scan(&encrypted).Error; err != nil {
t.Fatalf("read stored credential: %v", err)
}
if encrypted == "" || strings.Contains(encrypted, secret) {
t.Fatal("provider credential was not encrypted at rest")
}
var summaries []string
if err := db.Raw("SELECT CAST(summary AS CHAR) FROM admin_audit_events WHERE target_type = 'provider' AND target_id = ?", fmt.Sprint(providerView.ID)).Scan(&summaries).Error; err != nil {
t.Fatalf("read credential audit events: %v", err)
}
for _, summary := range summaries {
if strings.Contains(summary, secret) || strings.Contains(summary, "ciphertext") || strings.Contains(summary, "nonce") {
t.Fatalf("credential audit event contains protected data: %s", summary)
}
}
rotatedSecret := "synthetic-rotated-secret-" + suffix
rotated, err := service.RotateCredential(ctx, 7, "rotate-"+suffix, providerView.ID, rotatedSecret)
if err != nil {
t.Fatalf("rotate credential: %v", err)
}
if rotated.Credential.Version != 2 || !rotated.Credential.HasCredential {
t.Fatalf("rotation did not expose only current metadata: %#v", rotated.Credential)
}
// A normal update omits api_key and must preserve the selected version.
retained, err := service.UpdateProvider(ctx, 7, "update-"+suffix, providerView.ID, ProviderInput{
Slug: providerInput.Slug, Name: providerInput.Name + " updated", BaseURL: providerInput.BaseURL,
AuthType: providerInput.AuthType, Enabled: true,
})
if err != nil {
t.Fatalf("update provider without key: %v", err)
}
if retained.Credential.Version != 2 {
t.Fatalf("empty regular update changed credential version to %d", retained.Credential.Version)
}
rolledBack, err := service.ActivateCredential(ctx, 7, "rollback-"+suffix, providerView.ID, 1)
if err != nil {
t.Fatalf("activate prior credential: %v", err)
}
if rolledBack.Credential.Version != 1 {
t.Fatalf("rollback selected version %d, want 1", rolledBack.Credential.Version)
}
modelView, err := service.CreateProviderModel(ctx, 7, "model-"+suffix, ProviderModelInput{
ProviderID: providerView.ID, Name: "Model " + suffix, ModelID: "image-" + suffix,
APIType: model.APIImages, Kind: model.KindImage, Capabilities: []model.Capability{model.CapabilityImageGenerate},
ExtraBody: json.RawMessage(`{"size":"1024x1024"}`), TimeoutMS: 1000, Weight: 100, Enabled: true,
})
if err != nil {
t.Fatalf("create provider model: %v", err)
}
templateView, err := service.CreatePromptTemplate(ctx, 7, "template-"+suffix, PromptTemplateInput{
TemplateKey: "template-" + suffix, Kind: model.KindImage, APIType: model.APIImages,
Capability: model.CapabilityImageGenerate, Name: "Template " + suffix,
TemplateText: "{{.UserPrompt}}", DefaultRoleRule: "", Enabled: true,
})
if err != nil {
t.Fatalf("create template: %v", err)
}
poolInput := RoutePoolInput{
Slug: "route-" + suffix, Name: "Route " + suffix, Capability: model.CapabilityImageGenerate,
PromptTemplateID: templateView.ID, MaxFailover: 1, Enabled: true,
Members: []RouteMemberInput{{ProviderModelID: modelView.ID, Weight: 100, FailureThreshold: 3, OpenSeconds: 60, HalfOpenMax: 1, Enabled: true, Position: 0}},
}
poolView, err := service.CreateRoutePool(ctx, 7, "route-create-"+suffix, poolInput)
if err != nil {
t.Fatalf("create route pool: %v", err)
}
poolInput.Version, poolInput.Publish = poolView.Version, true
published, err := service.UpdateRoutePool(ctx, 7, "route-publish-"+suffix, poolView.ID, poolInput)
if err != nil {
t.Fatalf("publish route pool: %v", err)
}
if !published.Active || published.Version != poolView.Version+1 {
t.Fatalf("route pool publication state = active:%t version:%d", published.Active, published.Version)
}
poolInput.Version = poolView.Version
if _, err := service.UpdateRoutePool(ctx, 7, "route-stale-"+suffix, poolView.ID, poolInput); !errors.Is(err, ErrConflict) {
t.Fatalf("stale route update error = %v, want version conflict", err)
}
}
func TestConnectivityChecksRequireAuthorizationAndReserveCooldownMySQL(t *testing.T) {
db := openAdminTestDB(t)
ctx := context.Background()
deleteAdminFixture(t, db, "probe-")
suffix := fmt.Sprintf("probe-%d", time.Now().UnixNano())
t.Cleanup(func() { deleteAdminFixture(t, db, suffix) })
disabled := newAdminTestService(t, db, Config{})
_, modelID := createEnabledProviderAndModel(t, disabled, suffix)
if _, err := disabled.StartConnectivityCheck(ctx, 9, "blocked-"+suffix, modelID); !errors.Is(err, ErrConnectivityDisabled) {
t.Fatalf("disabled connectivity error = %v, want explicit authorization error", err)
}
probe := &blockingProbe{started: make(chan struct{}, 1), release: make(chan struct{})}
service := newAdminTestService(t, db, Config{
AllowConnectivityChecks: true, ConnectivityCooldown: time.Minute, MaxResponseBytes: 4096, Probe: probe,
})
result := make(chan error, 1)
go func() {
_, err := service.StartConnectivityCheck(ctx, 9, "probe-"+suffix, modelID)
result <- err
}()
select {
case <-probe.started:
case <-time.After(5 * time.Second):
t.Fatal("mock connectivity probe did not start")
}
if _, err := service.StartConnectivityCheck(ctx, 9, "probe-duplicate-"+suffix, modelID); !isCooldown(err) {
t.Fatalf("second connectivity reservation error = %v, want cooldown", err)
}
if got := probe.calls.Load(); got != 1 {
t.Fatalf("probe calls while first is reserved = %d, want 1", got)
}
close(probe.release)
if err := <-result; err != nil {
t.Fatalf("complete mock connectivity probe: %v", err)
}
var events []string
if err := db.Raw("SELECT CAST(summary AS CHAR) FROM admin_audit_events WHERE target_type = 'provider_model' AND target_id = ?", fmt.Sprint(modelID)).Scan(&events).Error; err != nil {
t.Fatalf("read connectivity audits: %v", err)
}
for _, event := range events {
if strings.Contains(event, "synthetic-provider-secret") || strings.Contains(event, "ciphertext") {
t.Fatalf("connectivity audit contains protected data: %s", event)
}
}
}
type blockingProbe struct {
calls atomic.Int32
started chan struct{}
release chan struct{}
}
func (p *blockingProbe) Probe(context.Context, ProbeConfiguration) error {
p.calls.Add(1)
p.started <- struct{}{}
<-p.release
return nil
}
func isCooldown(err error) bool {
var cooldown CooldownError
return errors.As(err, &cooldown)
}
func openAdminTestDB(t *testing.T) *gorm.DB {
t.Helper()
if os.Getenv("CHORUS_RUN_ADMIN_TESTS") != "1" {
t.Skip("set CHORUS_RUN_ADMIN_TESTS=1 to run against the disposable MySQL test database")
}
dsn := strings.TrimSpace(os.Getenv("CHORUS_DSN"))
if dsn == "" {
t.Fatal("CHORUS_DSN is required for admin MySQL integration tests")
}
parsed, err := mysqldriver.ParseDSN(dsn)
if err != nil {
t.Fatalf("parse CHORUS_DSN: %v", err)
}
if parsed.DBName != "chorus_test" {
t.Fatalf("refusing to use non-disposable database %q", parsed.DBName)
}
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
if err != nil {
t.Fatalf("connect disposable MySQL database: %v", err)
}
return db
}
func newAdminTestService(t *testing.T, db *gorm.DB, cfg Config) *Service {
t.Helper()
ring, err := platformcrypto.NewKeyRing("test", map[string][]byte{"test": []byte("0123456789abcdef0123456789abcdef")})
if err != nil {
t.Fatal(err)
}
service, err := NewService(db, ring, cfg)
if err != nil {
t.Fatal(err)
}
return service
}
func createEnabledProviderAndModel(t *testing.T, service *Service, suffix string) (uint64, uint64) {
t.Helper()
secret := "synthetic-provider-secret-" + suffix
providerView, err := service.CreateProvider(context.Background(), 9, "fixture-provider-"+suffix, ProviderInput{
Slug: "probe-provider-" + suffix, Name: "Probe Provider " + suffix, BaseURL: "https://provider.invalid/v1",
AuthType: "bearer", Enabled: true, APIKey: &secret,
})
if err != nil {
t.Fatalf("create connectivity fixture provider: %v", err)
}
modelView, err := service.CreateProviderModel(context.Background(), 9, "fixture-model-"+suffix, ProviderModelInput{
ProviderID: providerView.ID, Name: "Probe Model " + suffix, ModelID: "probe-" + suffix,
APIType: model.APIChat, Kind: model.KindText, Capabilities: []model.Capability{model.CapabilityText},
TimeoutMS: 1000, Weight: 100, Enabled: true,
})
if err != nil {
t.Fatalf("create connectivity fixture model: %v", err)
}
return providerView.ID, modelView.ID
}
func deleteAdminFixture(t *testing.T, db *gorm.DB, suffix string) {
t.Helper()
var poolIDs []uint64
if err := db.Raw("SELECT id FROM route_pools WHERE slug LIKE ?", "%"+suffix+"%").Scan(&poolIDs).Error; err != nil {
t.Errorf("find route pools for cleanup: %v", err)
return
}
if len(poolIDs) > 0 {
if err := db.Where("route_pool_id IN ?", poolIDs).Delete(&activeRouteRow{}).Error; err != nil {
t.Errorf("delete active routes: %v", err)
}
if err := db.Where("id IN ?", poolIDs).Delete(&routePoolRow{}).Error; err != nil {
t.Errorf("delete route pools: %v", err)
}
}
if err := db.Where("template_key LIKE ?", "%"+suffix+"%").Delete(&promptTemplateRow{}).Error; err != nil {
t.Errorf("delete templates: %v", err)
}
var providerIDs []uint64
if err := db.Raw("SELECT id FROM providers WHERE slug LIKE ?", "%"+suffix+"%").Scan(&providerIDs).Error; err != nil {
t.Errorf("find providers for cleanup: %v", err)
return
}
if len(providerIDs) == 0 {
return
}
var modelIDs []uint64
if err := db.Raw("SELECT id FROM provider_models WHERE provider_id IN ?", providerIDs).Scan(&modelIDs).Error; err != nil {
t.Errorf("find provider models for cleanup: %v", err)
return
}
if len(modelIDs) > 0 {
if err := db.Where("provider_model_id IN ?", modelIDs).Delete(&connectivityRow{}).Error; err != nil {
t.Errorf("delete connectivity checks: %v", err)
}
if err := db.Where("id IN ?", modelIDs).Delete(&providerModelRow{}).Error; err != nil {
t.Errorf("delete provider models: %v", err)
}
}
if err := db.Model(&providerRow{}).Where("id IN ?", providerIDs).Updates(map[string]any{"auth_type": "none", "active_credential_id": nil}).Error; err != nil {
t.Errorf("clear active credentials: %v", err)
}
if err := db.Where("provider_id IN ?", providerIDs).Delete(&credentialRow{}).Error; err != nil {
t.Errorf("delete provider credentials: %v", err)
}
if err := db.Where("id IN ?", providerIDs).Delete(&providerRow{}).Error; err != nil {
t.Errorf("delete providers: %v", err)
}
if err := db.Where("target_type IN ('provider', 'provider_model', 'route_pool') AND request_id LIKE ?", "%"+suffix+"%").Delete(&auditRow{}).Error; err != nil {
t.Errorf("delete audit events: %v", err)
}
}
func registerActiveRouteRestore(t *testing.T, db *gorm.DB, capability model.Capability) {
t.Helper()
var previous activeRouteRow
err := db.Where("capability = ?", capability).First(&previous).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return
}
if err != nil {
t.Fatalf("read active route before test: %v", err)
}
t.Cleanup(func() {
if err := db.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "capability"}}, DoUpdates: clause.AssignmentColumns([]string{"route_pool_id", "operator_id", "created_at", "updated_at"})}).Create(&previous).Error; err != nil {
t.Errorf("restore active route: %v", err)
}
})
}
+166
View File
@@ -0,0 +1,166 @@
// Package chorus implements the MVP-1 business extension for the fixed
// go-admin backend. It deliberately keeps provider credentials out of all
// response DTOs and audit summaries.
package chorus
import (
"encoding/json"
"time"
"git.ilapage.cn/OPC/chorus/internal/core/model"
)
type ProviderInput struct {
Slug string `json:"slug"`
Name string `json:"name"`
BaseURL string `json:"base_url"`
AuthType string `json:"auth_type"`
Enabled bool `json:"enabled"`
APIKey *string `json:"api_key,omitempty"`
}
type CredentialInfo struct {
HasCredential bool `json:"has_credential"`
Version uint32 `json:"version,omitempty"`
KeyID string `json:"key_id,omitempty"`
}
type ProviderView struct {
ID uint64 `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
BaseURL string `json:"base_url"`
AuthType string `json:"auth_type"`
Enabled bool `json:"enabled"`
Credential CredentialInfo `json:"credential"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type ProviderModelInput struct {
ProviderID uint64 `json:"provider_id"`
Name string `json:"name"`
ModelID string `json:"model_id"`
APIType model.APIType `json:"api_type"`
Kind model.GenerationKind `json:"kind"`
Capabilities []model.Capability `json:"capabilities"`
ExtraBody json.RawMessage `json:"extra_body"`
TimeoutMS uint32 `json:"timeout_ms"`
Weight uint32 `json:"weight"`
Enabled bool `json:"enabled"`
}
type ProviderModelView struct {
ID uint64 `json:"id"`
ProviderID uint64 `json:"provider_id"`
ProviderName string `json:"provider_name"`
Name string `json:"name"`
ModelID string `json:"model_id"`
APIType model.APIType `json:"api_type"`
Kind model.GenerationKind `json:"kind"`
Capabilities []model.Capability `json:"capabilities"`
ExtraBody json.RawMessage `json:"extra_body"`
TimeoutMS uint32 `json:"timeout_ms"`
Weight uint32 `json:"weight"`
Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type PromptTemplateInput struct {
TemplateKey string `json:"template_key"`
Kind model.GenerationKind `json:"kind"`
APIType model.APIType `json:"api_type"`
Capability model.Capability `json:"capability"`
Name string `json:"name"`
TemplateText string `json:"template_text"`
DefaultRoleRule string `json:"default_role_rule"`
Enabled bool `json:"enabled"`
}
type PromptTemplateView struct {
ID uint64 `json:"id"`
TemplateKey string `json:"template_key"`
Kind model.GenerationKind `json:"kind"`
APIType model.APIType `json:"api_type"`
Capability model.Capability `json:"capability"`
Name string `json:"name"`
Version uint32 `json:"version"`
TemplateText string `json:"template_text"`
DefaultRoleRule string `json:"default_role_rule"`
Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type RouteMemberInput struct {
ProviderModelID uint64 `json:"provider_model_id"`
Weight uint32 `json:"weight"`
FailureThreshold uint32 `json:"failure_threshold"`
OpenSeconds uint32 `json:"open_seconds"`
HalfOpenMax uint32 `json:"half_open_max"`
Enabled bool `json:"enabled"`
Position uint32 `json:"position"`
}
type RoutePoolInput struct {
Slug string `json:"slug"`
Name string `json:"name"`
Capability model.Capability `json:"capability"`
PromptTemplateID uint64 `json:"prompt_template_id"`
MaxFailover uint32 `json:"max_failover"`
Enabled bool `json:"enabled"`
Publish bool `json:"publish"`
Version uint32 `json:"version,omitempty"`
Members []RouteMemberInput `json:"members"`
}
type RoutePoolView struct {
ID uint64 `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Capability model.Capability `json:"capability"`
PromptTemplateID uint64 `json:"prompt_template_id"`
MaxFailover uint32 `json:"max_failover"`
Version uint32 `json:"version"`
Enabled bool `json:"enabled"`
Active bool `json:"active"`
Members []RouteMemberInput `json:"members"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type ConnectivityCheckView struct {
ID uint64 `json:"id"`
ProviderModel uint64 `json:"provider_model_id"`
Status string `json:"status"`
ErrorCode string `json:"error_code,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
LatencyMS *uint32 `json:"latency_ms,omitempty"`
StartedAt time.Time `json:"started_at"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CooldownUntil time.Time `json:"cooldown_until"`
}
type UserView struct {
ID uint64 `json:"id"`
Email string `json:"email"`
DisplayName string `json:"display_name"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type GenerationView struct {
ID uint64 `json:"id"`
UserID uint64 `json:"user_id"`
Status model.GenerationStatus `json:"status"`
Kind model.GenerationKind `json:"kind"`
RenderedPrompt string `json:"rendered_prompt"`
Attempts json.RawMessage `json:"attempts"`
ErrorCode string `json:"error_code,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
ProviderAttemptCnt uint32 `json:"provider_attempt_count"`
CreatedAt time.Time `json:"created_at"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
}
+178
View File
@@ -0,0 +1,178 @@
package cmd
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
"git.ilapage.cn/OPC/chorus/admin/app/admin/router"
"git.ilapage.cn/OPC/chorus/admin/app/chorus"
"git.ilapage.cn/OPC/chorus/admin/common/database"
common "git.ilapage.cn/OPC/chorus/admin/common/middleware"
ext "git.ilapage.cn/OPC/chorus/admin/config"
corecrypto "git.ilapage.cn/OPC/chorus/internal/core/crypto"
platformcrypto "git.ilapage.cn/OPC/chorus/internal/platform/crypto"
safehttp "git.ilapage.cn/OPC/chorus/internal/platform/http"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/config/source/file"
"github.com/go-admin-team/go-admin-core/sdk"
coreapi "github.com/go-admin-team/go-admin-core/sdk/api"
coreconfig "github.com/go-admin-team/go-admin-core/sdk/config"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/spf13/cobra"
"gorm.io/gorm"
)
var configPath string
var rootCmd = &cobra.Command{
Use: "chorus-admin",
SilenceUsage: true,
}
var serverCmd = &cobra.Command{
Use: "server",
Short: "Start the Chorus go-admin backend",
PreRunE: func(cmd *cobra.Command, args []string) error {
return setup(configPath)
},
RunE: func(cmd *cobra.Command, args []string) error {
return serve()
},
}
func init() {
serverCmd.Flags().StringVarP(&configPath, "config", "c", "", "go-admin settings file")
rootCmd.AddCommand(serverCmd)
}
func Execute() error {
return rootCmd.Execute()
}
func setup(path string) error {
if strings.TrimSpace(path) == "" {
return errors.New("--config is required; use config/settings.example.yml as a starting point")
}
coreconfig.ExtendConfig = &ext.ExtConfig
coreconfig.Setup(file.NewSource(file.WithPath(path)), database.Setup)
serviceConfig, err := serviceConfigFromEnvironment(os.LookupEnv)
if err != nil {
return err
}
chorus.Configure(func(db *gorm.DB) (*chorus.Service, error) {
return chorus.NewService(db, serviceConfig.cipher, serviceConfig.config)
})
return nil
}
type configuredService struct {
cipher corecrypto.KeyCipher
config chorus.Config
}
func serviceConfigFromEnvironment(lookup func(string) (string, bool)) (configuredService, error) {
read := func(name string) string {
value, _ := lookup(name)
return strings.TrimSpace(value)
}
masterKey := []byte(read("CHORUS_MASTER_KEY"))
if len(masterKey) == 0 {
return configuredService{}, errors.New("CHORUS_MASTER_KEY is required for the admin backend")
}
ring, err := platformcrypto.NewKeyRing("primary", map[string][]byte{"primary": masterKey})
for index := range masterKey {
masterKey[index] = 0
}
if err != nil {
return configuredService{}, errors.New("CHORUS_MASTER_KEY has an unsupported length")
}
configured := configuredService{cipher: ring}
allowRaw := read("CHORUS_ADMIN_ALLOW_CONNECTIVITY_PROBES")
if allowRaw == "" || allowRaw == "0" {
return configured, nil
}
if allowRaw != "1" {
return configuredService{}, errors.New("CHORUS_ADMIN_ALLOW_CONNECTIVITY_PROBES must be 1 when set")
}
cooldown, err := positiveDuration(read("CHORUS_ADMIN_CONNECTIVITY_COOLDOWN_SECONDS"), time.Second)
if err != nil {
return configuredService{}, errors.New("CHORUS_ADMIN_CONNECTIVITY_COOLDOWN_SECONDS must be a positive integer")
}
timeout, err := positiveDuration(read("CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS"), time.Second)
if err != nil {
return configuredService{}, errors.New("CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS must be a positive integer")
}
maxResponse, err := positiveInt64(read("CHORUS_PROVIDER_MAX_RESPONSE_BYTES"))
if err != nil {
return configuredService{}, errors.New("CHORUS_PROVIDER_MAX_RESPONSE_BYTES must be a positive integer")
}
client, err := safehttp.New(safehttp.Config{Timeout: timeout, MaxRedirects: 3})
if err != nil {
return configuredService{}, errors.New("configure SSRF-safe connectivity client")
}
probe, err := chorus.NewLiveProbe(safehttp.NewProviderClient(client))
if err != nil {
return configuredService{}, errors.New("configure connectivity probe")
}
configured.config = chorus.Config{AllowConnectivityChecks: true, ConnectivityCooldown: cooldown, MaxResponseBytes: maxResponse, Probe: probe}
return configured, nil
}
func positiveDuration(raw string, unit time.Duration) (time.Duration, error) {
value, err := strconv.ParseInt(raw, 10, 64)
if err != nil || value <= 0 {
return 0, errors.New("invalid positive duration")
}
return time.Duration(value) * unit, nil
}
func positiveInt64(raw string) (int64, error) {
value, err := strconv.ParseInt(raw, 10, 64)
if err != nil || value <= 0 {
return 0, errors.New("invalid positive integer")
}
return value, nil
}
func serve() error {
if coreconfig.ApplicationConfig.Mode == pkg.ModeProd.String() {
gin.SetMode(gin.ReleaseMode)
}
engine := gin.New()
sdk.Runtime.SetEngine(engine)
engine.Use(common.Sentinel()).Use(common.RequestId(pkg.TrafficKey)).Use(coreapi.SetRequestLogger)
common.InitMiddleware(engine)
router.InitRouter()
server := &http.Server{
Addr: fmt.Sprintf("%s:%d", coreconfig.ApplicationConfig.Host, coreconfig.ApplicationConfig.Port),
Handler: engine,
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: time.Duration(coreconfig.ApplicationConfig.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(coreconfig.ApplicationConfig.WriterTimeout) * time.Second,
IdleTimeout: 60 * time.Second,
}
shutdown, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
result := make(chan error, 1)
go func() { result <- server.ListenAndServe() }()
select {
case <-shutdown.Done():
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
return server.Shutdown(ctx)
case err := <-result:
if errors.Is(err, http.ErrServerClosed) {
return nil
}
return err
}
}
+42
View File
@@ -0,0 +1,42 @@
package cmd
import (
"strings"
"testing"
)
func TestServiceConfigRequiresMasterKey(t *testing.T) {
_, err := serviceConfigFromEnvironment(func(string) (string, bool) { return "", false })
if err == nil || !strings.Contains(err.Error(), "CHORUS_MASTER_KEY") {
t.Fatalf("missing master key error = %v", err)
}
}
func TestServiceConfigKeepsConnectivityDisabledWithoutExplicitAuthorization(t *testing.T) {
configured, err := serviceConfigFromEnvironment(testEnvironment(map[string]string{
"CHORUS_MASTER_KEY": "0123456789abcdef0123456789abcdef",
}))
if err != nil {
t.Fatalf("configure disabled connectivity: %v", err)
}
if configured.config.AllowConnectivityChecks || configured.config.Probe != nil {
t.Fatal("connectivity probe must not be created without explicit authorization")
}
}
func TestServiceConfigRequiresAllExplicitConnectivityLimits(t *testing.T) {
_, err := serviceConfigFromEnvironment(testEnvironment(map[string]string{
"CHORUS_MASTER_KEY": "0123456789abcdef0123456789abcdef",
"CHORUS_ADMIN_ALLOW_CONNECTIVITY_PROBES": "1",
}))
if err == nil || !strings.Contains(err.Error(), "CHORUS_ADMIN_CONNECTIVITY_COOLDOWN_SECONDS") {
t.Fatalf("missing cooldown error = %v", err)
}
}
func testEnvironment(values map[string]string) func(string) (string, bool) {
return func(key string) (string, bool) {
value, ok := values[key]
return value, ok
}
}
+49
View File
@@ -0,0 +1,49 @@
package actions
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
// CreateAction 通用新增动作
func CreateAction(control dto.Control) gin.HandlerFunc {
return func(c *gin.Context) {
log := api.GetRequestLogger(c)
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
//新增操作
req := control.Generate()
err = req.Bind(c)
if err != nil {
response.Error(c, http.StatusUnprocessableEntity, err, err.Error())
return
}
var object models.ActiveRecord
object, err = req.GenerateM()
if err != nil {
response.Error(c, 500, err, "模型生成失败")
return
}
object.SetCreateBy(user.GetUserId(c))
err = db.WithContext(c).Create(object).Error
if err != nil {
log.Errorf("Create error: %s", err)
response.Error(c, 500, err, "创建失败")
return
}
response.OK(c, object.GetId(), "创建成功")
c.Next()
}
}
+61
View File
@@ -0,0 +1,61 @@
package actions
import (
"net/http"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
// DeleteAction 通用删除动作
func DeleteAction(control dto.Control) gin.HandlerFunc {
return func(c *gin.Context) {
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
msgID := pkg.GenerateMsgIDFromContext(c)
//删除操作
req := control.Generate()
err = req.Bind(c)
if err != nil {
log.Errorf("MsgID[%s] Bind error: %s", msgID, err)
response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
return
}
var object models.ActiveRecord
object, err = req.GenerateM()
if err != nil {
response.Error(c, 500, err, "模型生成失败")
return
}
object.SetUpdateBy(user.GetUserId(c))
//数据权限检查
p := GetPermissionFromContext(c)
db = db.WithContext(c).Scopes(
Permission(object.TableName(), p),
).Where(req.GetId()).Delete(object)
if err = db.Error; err != nil {
log.Errorf("MsgID[%s] Delete error: %s", msgID, err)
response.Error(c, 500, err, "删除失败")
return
}
if db.RowsAffected == 0 {
response.Error(c, http.StatusForbidden, nil, "无权删除该数据")
return
}
response.OK(c, object.GetId(), "删除成功")
c.Next()
}
}
+58
View File
@@ -0,0 +1,58 @@
package actions
import (
"errors"
"net/http"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
// IndexAction 通用查询动作
func IndexAction(m models.ActiveRecord, d dto.Index, f func() interface{}) gin.HandlerFunc {
return func(c *gin.Context) {
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
msgID := pkg.GenerateMsgIDFromContext(c)
list := f()
object := m.Generate()
req := d.Generate()
var count int64
//查询列表
err = req.Bind(c)
if err != nil {
response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
return
}
//数据权限检查
p := GetPermissionFromContext(c)
err = db.WithContext(c).Model(object).
Scopes(
dto.MakeCondition(req.GetNeedSearch()),
dto.Paginate(req.GetPageSize(), req.GetPageIndex()),
Permission(object.TableName(), p),
).
Find(list).Limit(-1).Offset(-1).
Count(&count).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
log.Errorf("MsgID[%s] Index error: %s", msgID, err)
response.Error(c, 500, err, "查询失败")
return
}
response.PageOK(c, list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
c.Next()
}
}
+96
View File
@@ -0,0 +1,96 @@
package actions
import (
"errors"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/config"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"gorm.io/gorm"
)
type DataPermission struct {
DataScope string
UserId int
DeptId int
RoleId int
}
func PermissionAction() gin.HandlerFunc {
return func(c *gin.Context) {
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
msgID := pkg.GenerateMsgIDFromContext(c)
var p = new(DataPermission)
if userId := user.GetUserIdStr(c); userId != "" {
p, err = newDataPermission(db, userId)
if err != nil {
log.Errorf("MsgID[%s] PermissionAction error: %s", msgID, err)
response.Error(c, 500, err, "权限范围鉴定错误")
c.Abort()
return
}
}
c.Set(PermissionKey, p)
c.Next()
}
}
func newDataPermission(tx *gorm.DB, userId interface{}) (*DataPermission, error) {
var err error
p := &DataPermission{}
err = tx.Table("sys_user").
Select("sys_user.user_id", "sys_role.role_id", "sys_user.dept_id", "sys_role.data_scope").
Joins("left join sys_role on sys_role.role_id = sys_user.role_id").
Where("sys_user.user_id = ?", userId).
Scan(p).Error
if err != nil {
err = errors.New("获取用户数据出错 msg:" + err.Error())
return nil, err
}
return p, nil
}
func Permission(tableName string, p *DataPermission) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if !config.ApplicationConfig.EnableDP {
return db
}
switch p.DataScope {
case "2":
return db.Where(tableName+".create_by in (select sys_user.user_id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", p.RoleId)
case "3":
return db.Where(tableName+".create_by in (SELECT user_id from sys_user where dept_id = ? )", p.DeptId)
case "4":
return db.Where(tableName+".create_by in (SELECT user_id from sys_user where sys_user.dept_id in(select dept_id from sys_dept where dept_path like ? ))", "%/"+pkg.IntToString(p.DeptId)+"/%")
case "5":
return db.Where(tableName+".create_by = ?", p.UserId)
default:
return db
}
}
}
func getPermissionFromContext(c *gin.Context) *DataPermission {
p := new(DataPermission)
if pm, ok := c.Get(PermissionKey); ok {
switch pm.(type) {
case *DataPermission:
p = pm.(*DataPermission)
}
}
return p
}
// GetPermissionFromContext 提供非action写法数据范围约束
func GetPermissionFromContext(c *gin.Context) *DataPermission {
return getPermissionFromContext(c)
}
+5
View File
@@ -0,0 +1,5 @@
package actions
const (
PermissionKey = "dataPermission"
)
+59
View File
@@ -0,0 +1,59 @@
package actions
import (
"net/http"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
// UpdateAction 通用更新动作
func UpdateAction(control dto.Control) gin.HandlerFunc {
return func(c *gin.Context) {
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
msgID := pkg.GenerateMsgIDFromContext(c)
req := control.Generate()
//更新操作
err = req.Bind(c)
if err != nil {
response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
return
}
var object models.ActiveRecord
object, err = req.GenerateM()
if err != nil {
response.Error(c, 500, err, "模型生成失败")
return
}
object.SetUpdateBy(user.GetUserId(c))
//数据权限检查
p := GetPermissionFromContext(c)
db = db.WithContext(c).Scopes(
Permission(object.TableName(), p),
).Where(req.GetId()).Updates(object)
if err = db.Error; err != nil {
log.Errorf("MsgID[%s] Update error: %s", msgID, err)
response.Error(c, 500, err, "更新失败")
return
}
if db.RowsAffected == 0 {
response.Error(c, http.StatusForbidden, nil, "无权更新该数据")
return
}
response.OK(c, object.GetId(), "更新成功")
c.Next()
}
}
+67
View File
@@ -0,0 +1,67 @@
package actions
import (
"errors"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"net/http"
"github.com/gin-gonic/gin"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/common/dto"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
// ViewAction 通用详情动作
func ViewAction(control dto.Control, f func() interface{}) gin.HandlerFunc {
return func(c *gin.Context) {
db, err := pkg.GetOrm(c)
if err != nil {
log.Error(err)
return
}
msgID := pkg.GenerateMsgIDFromContext(c)
//查看详情
req := control.Generate()
err = req.Bind(c)
if err != nil {
response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
return
}
var object models.ActiveRecord
object, err = req.GenerateM()
if err != nil {
response.Error(c, 500, err, "模型生成失败")
return
}
var rsp interface{}
if f != nil {
rsp = f()
} else {
rsp, _ = req.GenerateM()
}
//数据权限检查
p := GetPermissionFromContext(c)
err = db.Model(object).WithContext(c).Scopes(
Permission(object.TableName(), p),
).Where(req.GetId()).First(rsp).Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
response.Error(c, http.StatusNotFound, nil, "查看对象不存在或无权查看")
return
}
if err != nil {
log.Errorf("MsgID[%s] View error: %s", msgID, err)
response.Error(c, 500, err, "查看失败")
return
}
response.OK(c, rsp, "查询成功")
c.Next()
}
}
+135
View File
@@ -0,0 +1,135 @@
package apis
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/go-admin-team/go-admin-core/sdk/pkg/response"
"gorm.io/gorm"
"git.ilapage.cn/OPC/chorus/admin/common/service"
)
type Api struct {
Context *gin.Context
Logger *logger.Helper
Orm *gorm.DB
Errors error
}
func (e *Api) AddError(err error) {
if e.Errors == nil {
e.Errors = err
} else if err != nil {
e.Logger.Error(err)
e.Errors = fmt.Errorf("%v; %w", e.Errors, err)
}
}
// MakeContext 设置http上下文
func (e *Api) MakeContext(c *gin.Context) *Api {
e.Context = c
e.Logger = api.GetRequestLogger(c)
return e
}
// GetLogger 获取上下文提供的日志
func (e *Api) GetLogger() *logger.Helper {
return api.GetRequestLogger(e.Context)
}
func (e *Api) Bind(d interface{}, bindings ...binding.Binding) *Api {
var err error
if len(bindings) == 0 {
bindings = append(bindings, binding.JSON, nil)
}
for i := range bindings {
switch bindings[i] {
case binding.JSON:
err = e.Context.ShouldBindWith(d, binding.JSON)
case binding.XML:
err = e.Context.ShouldBindWith(d, binding.XML)
case binding.Form:
err = e.Context.ShouldBindWith(d, binding.Form)
case binding.Query:
err = e.Context.ShouldBindWith(d, binding.Query)
case binding.FormPost:
err = e.Context.ShouldBindWith(d, binding.FormPost)
case binding.FormMultipart:
err = e.Context.ShouldBindWith(d, binding.FormMultipart)
case binding.ProtoBuf:
err = e.Context.ShouldBindWith(d, binding.ProtoBuf)
case binding.MsgPack:
err = e.Context.ShouldBindWith(d, binding.MsgPack)
case binding.YAML:
err = e.Context.ShouldBindWith(d, binding.YAML)
case binding.Header:
err = e.Context.ShouldBindWith(d, binding.Header)
default:
err = e.Context.ShouldBindUri(d)
}
if err != nil {
e.AddError(err)
}
}
return e
}
// GetOrm 获取Orm DB
func (e *Api) GetOrm() (*gorm.DB, error) {
db, err := pkg.GetOrm(e.Context)
if err != nil {
e.Error(500, err, "数据库连接获取失败")
return nil, err
}
return db, nil
}
// MakeOrm 设置Orm DB
func (e *Api) MakeOrm() *Api {
var err error
if e.Logger == nil {
err = errors.New("at MakeOrm logger is nil")
//e.Logger.Error(500, err, "at MakeOrm logger is nil")
e.AddError(err)
return e
}
db, err := pkg.GetOrm(e.Context)
if err != nil {
e.Logger.Error(500, err, "数据库连接获取失败")
e.AddError(err)
}
e.Orm = db
return e
}
func (e *Api) MakeService(c *service.Service) *Api {
c.Log = e.Logger
c.Orm = e.Orm
return e
}
// Error 通常错误数据处理
func (e *Api) Error(code int, err error, msg string) {
response.Error(e.Context, code, err, msg)
}
// OK 通常成功数据处理
func (e *Api) OK(data interface{}, msg string) {
response.OK(e.Context, data, msg)
}
// PageOK 分页数据处理
func (e *Api) PageOK(result interface{}, count int, pageIndex int, pageSize int, msg string) {
response.PageOK(e.Context, result, count, pageIndex, pageSize, msg)
}
// Custom 兼容函数
func (e *Api) Custom(data gin.H) {
response.Custum(e.Context, data)
}
+66
View File
@@ -0,0 +1,66 @@
package database
import (
"time"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
toolsConfig "github.com/go-admin-team/go-admin-core/sdk/config"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
mycasbin "github.com/go-admin-team/go-admin-core/sdk/pkg/casbin"
toolsDB "github.com/go-admin-team/go-admin-core/tools/database"
. "github.com/go-admin-team/go-admin-core/tools/gorm/logger"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"git.ilapage.cn/OPC/chorus/admin/common/global"
)
// Setup 配置数据库
func Setup() {
for k := range toolsConfig.DatabasesConfig {
setupSimpleDatabase(k, toolsConfig.DatabasesConfig[k])
}
}
func setupSimpleDatabase(host string, c *toolsConfig.Database) {
if global.Driver == "" {
global.Driver = c.Driver
}
// Database sources can contain passwords; record only the configured logical name.
log.Infof("database connection configured: %s", host)
registers := make([]toolsDB.ResolverConfigure, len(c.Registers))
for i := range c.Registers {
registers[i] = toolsDB.NewResolverConfigure(
c.Registers[i].Sources,
c.Registers[i].Replicas,
c.Registers[i].Policy,
c.Registers[i].Tables)
}
resolverConfig := toolsDB.NewConfigure(c.Source, c.MaxIdleConns, c.MaxOpenConns, c.ConnMaxIdleTime, c.ConnMaxLifeTime, registers)
db, err := resolverConfig.Init(&gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
Logger: New(
logger.Config{
SlowThreshold: time.Second,
Colorful: true,
LogLevel: logger.LogLevel(
log.DefaultLogger.Options().Level.LevelForGorm()),
},
),
}, opens[c.Driver])
if err != nil {
log.Fatal(pkg.Red(c.Driver+" connect error :"), err)
} else {
log.Info(pkg.Green(c.Driver + " connect success !"))
}
e := mycasbin.Setup(db, "")
sdk.Runtime.SetDb(host, db)
sdk.Runtime.SetCasbin(host, e)
}
+16
View File
@@ -0,0 +1,16 @@
//go:build !sqlite3
package database
import (
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
)
var opens = map[string]func(string) gorm.Dialector{
"mysql": mysql.Open,
"postgres": postgres.Open,
"sqlserver": sqlserver.Open,
}
+19
View File
@@ -0,0 +1,19 @@
//go:build sqlite3
// +build sqlite3
package database
import (
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
)
var opens = map[string]func(string) gorm.Dialector{
"mysql": mysql.Open,
"postgres": postgres.Open,
"sqlite3": sqlite.Open,
"sqlserver": sqlserver.Open,
}
+74
View File
@@ -0,0 +1,74 @@
package dto
type AutoForm struct {
Fields []Field `json:"fields"`
FormRef string `json:"formRef"`
FormModel string `json:"formModel"`
Size string `json:"size"`
LabelPosition string `json:"labelPosition"`
LabelWidth int `json:"labelWidth"`
FormRules string `json:"formRules"`
Gutter int `json:"gutter"`
Disabled bool `json:"disabled"`
Span int `json:"span"`
FormBtns bool `json:"formBtns"`
}
type Config struct {
Label string `json:"label"`
LabelWidth interface{} `json:"labelWidth"`
ShowLabel bool `json:"showLabel"`
ChangeTag bool `json:"changeTag"`
Tag string `json:"tag"`
TagIcon string `json:"tagIcon"`
Required bool `json:"required"`
Layout string `json:"layout"`
Span int `json:"span"`
Document string `json:"document"`
RegList []interface{} `json:"regList"`
FormId int `json:"formId"`
RenderKey int64 `json:"renderKey"`
DefaultValue interface{} `json:"defaultValue"`
ShowTip bool `json:"showTip,omitempty"`
ButtonText string `json:"buttonText,omitempty"`
FileSize int `json:"fileSize,omitempty"`
SizeUnit string `json:"sizeUnit,omitempty"`
}
type Option struct {
Label string `json:"label"`
Value string `json:"value"`
}
type Slot struct {
Prepend string `json:"prepend,omitempty"`
Append string `json:"append,omitempty"`
ListType bool `json:"list-type,omitempty"`
Options []Option `json:"options,omitempty"`
}
type Field struct {
Config Config `json:"__config__"`
Slot Slot `json:"__slot__"`
Placeholder string `json:"placeholder,omitempty"`
Style Style `json:"style,omitempty"`
Clearable bool `json:"clearable,omitempty"`
PrefixIcon string `json:"prefix-icon,omitempty"`
SuffixIcon string `json:"suffix-icon,omitempty"`
Maxlength interface{} `json:"maxlength"`
ShowWordLimit bool `json:"show-word-limit,omitempty"`
Readonly bool `json:"readonly,omitempty"`
Disabled bool `json:"disabled"`
VModel string `json:"__vModel__"`
Action string `json:"action,omitempty"`
Accept string `json:"accept,omitempty"`
Name string `json:"name,omitempty"`
AutoUpload bool `json:"auto-upload,omitempty"`
ListType string `json:"list-type,omitempty"`
Multiple bool `json:"multiple,omitempty"`
Filterable bool `json:"filterable,omitempty"`
}
type Style struct {
Width string `json:"width"`
}
+106
View File
@@ -0,0 +1,106 @@
package dto
import (
vd "github.com/bytedance/go-tagexpr/v2/validator"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
)
type ObjectById struct {
Id int `uri:"id"`
Ids []int `json:"ids"`
}
func (s *ObjectById) Bind(ctx *gin.Context) error {
var err error
log := api.GetRequestLogger(ctx)
err = ctx.ShouldBindUri(s)
if err != nil {
log.Warnf("ShouldBindUri error: %s", err.Error())
return err
}
if ctx.Request.Method == http.MethodDelete {
err = ctx.ShouldBind(&s)
if err != nil {
log.Warnf("ShouldBind error: %s", err.Error())
return err
}
if len(s.Ids) > 0 {
return nil
}
if s.Ids == nil {
s.Ids = make([]int, 0)
}
if s.Id != 0 {
s.Ids = append(s.Ids, s.Id)
}
}
if err = vd.Validate(s); err != nil {
log.Errorf("Validate error: %s", err.Error())
return err
}
return err
}
func (s *ObjectById) GetId() interface{} {
if len(s.Ids) > 0 {
s.Ids = append(s.Ids, s.Id)
return s.Ids
}
return s.Id
}
type ObjectGetReq struct {
Id int `uri:"id"`
}
func (s *ObjectGetReq) Bind(ctx *gin.Context) error {
var err error
log := api.GetRequestLogger(ctx)
err = ctx.ShouldBindUri(s)
if err != nil {
log.Warnf("ShouldBindUri error: %s", err.Error())
return err
}
if err = vd.Validate(s); err != nil {
log.Errorf("Validate error: %s", err.Error())
return err
}
return err
}
func (s *ObjectGetReq) GetId() interface{} {
return s.Id
}
type ObjectDeleteReq struct {
Ids []int `json:"ids"`
}
func (s *ObjectDeleteReq) Bind(ctx *gin.Context) error {
var err error
log := api.GetRequestLogger(ctx)
err = ctx.ShouldBind(&s)
if err != nil {
log.Warnf("ShouldBind error: %s", err.Error())
return err
}
if len(s.Ids) > 0 {
return nil
}
if s.Ids == nil {
s.Ids = make([]int, 0)
}
if err = vd.Validate(s); err != nil {
log.Errorf("Validate error: %s", err.Error())
return err
}
return err
}
func (s *ObjectDeleteReq) GetId() interface{} {
return s.Ids
}
+12
View File
@@ -0,0 +1,12 @@
package dto
import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func OrderDest(sort string, bl bool) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Order(clause.OrderByColumn{Column: clause.Column{Name: sort}, Desc: bl})
}
}
+20
View File
@@ -0,0 +1,20 @@
package dto
type Pagination struct {
PageIndex int `form:"pageIndex"`
PageSize int `form:"pageSize"`
}
func (m *Pagination) GetPageIndex() int {
if m.PageIndex <= 0 {
m.PageIndex = 1
}
return m.PageIndex
}
func (m *Pagination) GetPageSize() int {
if m.PageSize <= 0 {
m.PageSize = 10
}
return m.PageSize
}
+84
View File
@@ -0,0 +1,84 @@
package dto
import (
"github.com/go-admin-team/go-admin-core/tools/search"
"git.ilapage.cn/OPC/chorus/admin/common/global"
"gorm.io/gorm"
)
type GeneralDelDto struct {
Id int `uri:"id" json:"id" validate:"required"`
Ids []int `json:"ids"`
}
func (g GeneralDelDto) GetIds() []int {
ids := make([]int, 0)
if g.Id != 0 {
ids = append(ids, g.Id)
}
if len(g.Ids) > 0 {
for _, id := range g.Ids {
if id > 0 {
ids = append(ids, id)
}
}
} else {
if g.Id > 0 {
ids = append(ids, g.Id)
}
}
if len(ids) <= 0 {
//方式全部删除
ids = append(ids, 0)
}
return ids
}
type GeneralGetDto struct {
Id int `uri:"id" json:"id" validate:"required"`
}
func MakeCondition(q interface{}) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
condition := &search.GormCondition{
GormPublic: search.GormPublic{},
Join: make([]*search.GormJoin, 0),
}
search.ResolveSearchQuery(global.Driver, q, condition)
for _, join := range condition.Join {
if join == nil {
continue
}
db = db.Joins(join.JoinOn)
for k, v := range join.Where {
db = db.Where(k, v...)
}
for k, v := range join.Or {
db = db.Or(k, v...)
}
for _, o := range join.Order {
db = db.Order(o)
}
}
for k, v := range condition.Where {
db = db.Where(k, v...)
}
for k, v := range condition.Or {
db = db.Or(k, v...)
}
for _, o := range condition.Order {
db = db.Order(o)
}
return db
}
}
func Paginate(pageSize, pageIndex int) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
offset := (pageIndex - 1) * pageSize
if offset < 0 {
offset = 0
}
return db.Offset(offset).Limit(pageSize)
}
}
+21
View File
@@ -0,0 +1,21 @@
package dto
import (
"github.com/gin-gonic/gin"
"git.ilapage.cn/OPC/chorus/admin/common/models"
)
type Index interface {
Generate() Index
Bind(ctx *gin.Context) error
GetPageIndex() int
GetPageSize() int
GetNeedSearch() interface{}
}
type Control interface {
Generate() Control
Bind(ctx *gin.Context) error
GenerateM() (models.ActiveRecord, error)
GetId() interface{}
}
+45
View File
@@ -0,0 +1,45 @@
package file_store
import "fmt"
type OXS struct {
// Endpoint 访问域名
Endpoint string
// AccessKeyID AK
AccessKeyID string
// AccessKeySecret AKS
AccessKeySecret string
// BucketName 桶名称
BucketName string
}
// Setup 配置文件存储driver
func (e *OXS) Setup(driver DriverType, options ...ClientOption) FileStoreType {
fileStoreType := driver
var fileStore FileStoreType
switch fileStoreType {
case AliYunOSS:
fileStore = new(ALiYunOSS)
err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
if err != nil {
fmt.Println(err)
}
return fileStore
case HuaweiOBS:
fileStore = new(HuaWeiOBS)
err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
if err != nil {
fmt.Println(err)
}
return fileStore
case QiNiuKodo:
fileStore = new(QiNiuKODO)
err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
if err != nil {
fmt.Println(err)
}
return fileStore
}
return nil
}
+27
View File
@@ -0,0 +1,27 @@
package file_store
// DriverType 驱动类型
type DriverType string
const (
// HuaweiOBS 华为云OBS
HuaweiOBS DriverType = "HuaweiOBS"
// AliYunOSS 阿里云OSS
AliYunOSS DriverType = "AliYunOSS"
// QiNiuKodo 七牛云kodo
QiNiuKodo DriverType = "QiNiuKodo"
)
type ClientOption map[string]interface{}
// TODO: FileStoreType名称待定
// FileStoreType OXS
type FileStoreType interface {
// Setup 装载 endpoint sss
Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error
// UpLoad 上传
UpLoad(yourObjectName string, localFile interface{}) error
// GetTempToken 获取临时Token
GetTempToken() (string, error)
}
+111
View File
@@ -0,0 +1,111 @@
package file_store
import (
"context"
"fmt"
"github.com/qiniu/go-sdk/v7/auth/qbox"
"github.com/qiniu/go-sdk/v7/storage"
)
type Zone string
const (
// HuaDong 华东
HuaDong Zone = "HuaDong"
// HuaBei 华北
HuaBei Zone = "HuaBei"
// HuaNan 华南
HuaNan Zone = "HuaNan"
// BeiMei 北美
BeiMei Zone = "BeiMei"
// XinJiaPo 新加坡
XinJiaPo Zone = "XinJiaPo"
)
type QiNiuKODO struct {
Client interface{}
BucketName string
cfg storage.Config
options []ClientOption
}
func (e *QiNiuKODO) getToken() string {
putPolicy := storage.PutPolicy{
Scope: e.BucketName,
}
if len(e.options) > 0 && e.options[0]["Expires"] != nil {
putPolicy.Expires = e.options[0]["Expires"].(uint64)
}
upToken := putPolicy.UploadToken(e.Client.(*qbox.Mac))
return upToken
}
//Setup 装载
//endpoint sss
func (e *QiNiuKODO) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
mac := qbox.NewMac(accessKeyID, accessKeySecret)
// 获取存储空间。
cfg := storage.Config{}
// 空间对应的机房
e.setZoneORDefault(cfg, options...)
// 是否使用https域名
cfg.UseHTTPS = true
// 上传是否使用CDN上传加速
cfg.UseCdnDomains = false
e.Client = mac
e.BucketName = BucketName
e.cfg = cfg
e.options = options
return nil
}
// setZoneORDefault 设置Zone或者默认华东
func (e *QiNiuKODO) setZoneORDefault(cfg storage.Config, options ...ClientOption) {
if len(options) > 0 && options[0]["Zone"] != nil {
if _, ok := options[0]["Zone"].(Zone); !ok {
cfg.Zone = &storage.ZoneHuadong
}
switch options[0]["Zone"].(Zone) {
case HuaDong:
cfg.Zone = &storage.ZoneHuadong
case HuaBei:
cfg.Zone = &storage.ZoneHuabei
case HuaNan:
cfg.Zone = &storage.ZoneHuanan
case BeiMei:
cfg.Zone = &storage.ZoneBeimei
case XinJiaPo:
cfg.Zone = &storage.ZoneXinjiapo
default:
cfg.Zone = &storage.ZoneHuadong
}
}
}
// UpLoad 文件上传
func (e *QiNiuKODO) UpLoad(yourObjectName string, localFile interface{}) error {
// 构建表单上传的对象
formUploader := storage.NewFormUploader(&e.cfg)
ret := storage.PutRet{}
// 可选配置
putExtra := storage.PutExtra{
Params: map[string]string{
"x:name": "github logo",
},
}
err := formUploader.PutFile(context.Background(), &ret, e.getToken(), yourObjectName, localFile.(string), &putExtra)
if err != nil {
fmt.Println(err)
return err
}
fmt.Println(ret.Key, ret.Hash)
return nil
}
func (e *QiNiuKODO) GetTempToken() (string, error) {
token := e.getToken()
return token, nil
}
+52
View File
@@ -0,0 +1,52 @@
package file_store
import (
"fmt"
"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
"log"
)
type HuaWeiOBS struct {
Client interface{}
BucketName string
}
func (e *HuaWeiOBS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
// 创建ObsClient结构体
client, err := obs.New(accessKeyID, accessKeySecret, endpoint)
if err != nil {
log.Println("Error:", err)
return err
}
e.Client = client
e.BucketName = BucketName
return nil
}
// UpLoad 文件上传
// yourObjectName 文件路径名称,与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
func (e *HuaWeiOBS) UpLoad(yourObjectName string, localFile interface{}) error {
// 获取存储空间。
input := &obs.PutFileInput{}
input.Bucket = e.BucketName
input.Key = yourObjectName
input.SourceFile = localFile.(string)
output, err := e.Client.(*obs.ObsClient).PutFile(input)
if err == nil {
fmt.Printf("RequestId:%s\n", output.RequestId)
fmt.Printf("ETag:%s, StorageClass:%s\n", output.ETag, output.StorageClass)
} else {
if obsError, ok := err.(obs.ObsError); ok {
fmt.Println(obsError.Code)
fmt.Println(obsError.Message)
} else {
fmt.Println(err)
}
}
return nil
}
func (e *HuaWeiOBS) GetTempToken() (string, error) {
return "", nil
}
+48
View File
@@ -0,0 +1,48 @@
package file_store
import (
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"log"
)
type ALiYunOSS struct {
Client interface{}
BucketName string
}
//Setup 装载
//endpoint sss
func (e *ALiYunOSS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
if err != nil {
log.Println("Error:", err)
return err
}
e.Client = client
e.BucketName = BucketName
return nil
}
// UpLoad 文件上传
func (e *ALiYunOSS) UpLoad(yourObjectName string, localFile interface{}) error {
// 获取存储空间。
bucket, err := e.Client.(*oss.Client).Bucket(e.BucketName)
if err != nil {
log.Println("Error:", err)
return err
}
// 设置分片大小为100 KB,指定分片上传并发数为3,并开启断点续传上传。
// 其中<yourObjectName>与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
// "LocalFile"为filePath,100*1024为partSize。
err = bucket.UploadFile(yourObjectName, localFile.(string), 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
if err != nil {
log.Println("Error:", err)
return err
}
return nil
}
func (e *ALiYunOSS) GetTempToken() (string, error) {
return "", nil
}
+11
View File
@@ -0,0 +1,11 @@
package global
const (
// Version go-admin version info
Version = "2.2.0"
)
var (
// Driver 数据库驱动
Driver string
)
+18
View File
@@ -0,0 +1,18 @@
package global
import (
"github.com/casbin/casbin/v2"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/sdk/api"
)
func LoadPolicy(c *gin.Context) (*casbin.SyncedEnforcer, error) {
log := api.GetRequestLogger(c)
if err := sdk.Runtime.GetCasbinKey(c.Request.Host).LoadPolicy(); err == nil {
return sdk.Runtime.GetCasbinKey(c.Request.Host), err
} else {
log.Errorf("casbin rbac_model or policy init error, %s ", err.Error())
return nil, err
}
}
+4
View File
@@ -0,0 +1,4 @@
package global
// LogoContent go-admin ascii显示,减少静态文件依赖
var LogoContent = []byte{10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 95, 95, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 32, 32, 32, 32, 32, 32, 32, 32, 44, 39, 32, 32, 44, 32, 96, 46, 32, 32, 44, 45, 45, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 46, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 46, 39, 124, 32, 32, 32, 32, 32, 44, 45, 43, 45, 44, 46, 39, 32, 95, 32, 124, 44, 45, 45, 46, 39, 124, 32, 32, 32, 32, 32, 32, 32, 32, 32, 44, 45, 45, 45, 44, 10, 32, 32, 44, 45, 45, 45, 45, 46, 95, 44, 46, 32, 32, 39, 32, 32, 32, 44, 39, 92, 32, 32, 32, 44, 39, 32, 32, 46, 39, 32, 124, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 32, 124, 32, 58, 32, 32, 44, 45, 43, 45, 46, 32, 59, 32, 32, 32, 44, 32, 124, 124, 124, 32, 32, 124, 44, 32, 32, 32, 32, 32, 32, 44, 45, 43, 45, 46, 32, 47, 32, 32, 124, 10, 32, 47, 32, 32, 32, 47, 32, 32, 39, 32, 47, 32, 47, 32, 32, 32, 47, 32, 32, 32, 124, 44, 45, 45, 45, 46, 39, 32, 32, 32, 44, 32, 44, 45, 45, 46, 45, 45, 46, 32, 32, 32, 32, 32, 32, 124, 32, 32, 32, 124, 32, 124, 32, 44, 45, 45, 46, 39, 124, 39, 32, 32, 32, 124, 32, 32, 124, 124, 96, 45, 45, 39, 95, 32, 32, 32, 32, 32, 44, 45, 45, 46, 39, 124, 39, 32, 32, 32, 124, 10, 124, 32, 32, 32, 58, 32, 32, 32, 32, 32, 124, 46, 32, 32, 32, 59, 32, 44, 46, 32, 58, 124, 32, 32, 32, 124, 32, 32, 32, 32, 124, 47, 32, 32, 32, 32, 32, 32, 32, 92, 32, 32, 32, 44, 45, 45, 46, 95, 95, 124, 32, 124, 124, 32, 32, 32, 124, 32, 32, 44, 39, 44, 32, 124, 32, 32, 124, 44, 44, 39, 32, 44, 39, 124, 32, 32, 32, 124, 32, 32, 32, 124, 32, 32, 44, 34, 39, 32, 124, 10, 124, 32, 32, 32, 124, 32, 46, 92, 32, 32, 46, 39, 32, 32, 32, 124, 32, 124, 58, 32, 58, 58, 32, 32, 32, 58, 32, 32, 46, 39, 46, 45, 45, 46, 32, 32, 46, 45, 46, 32, 124, 32, 47, 32, 32, 32, 44, 39, 32, 32, 32, 124, 124, 32, 32, 32, 124, 32, 47, 32, 32, 124, 32, 124, 45, 45, 39, 32, 39, 32, 32, 124, 32, 124, 32, 32, 32, 124, 32, 32, 32, 124, 32, 47, 32, 32, 124, 32, 124, 10, 46, 32, 32, 32, 59, 32, 39, 59, 32, 32, 124, 39, 32, 32, 32, 124, 32, 46, 59, 32, 58, 58, 32, 32, 32, 124, 46, 39, 32, 32, 32, 92, 95, 95, 92, 47, 58, 32, 46, 32, 46, 46, 32, 32, 32, 39, 32, 32, 47, 32, 32, 124, 124, 32, 32, 32, 58, 32, 124, 32, 32, 124, 32, 44, 32, 32, 32, 32, 124, 32, 32, 124, 32, 58, 32, 32, 32, 124, 32, 32, 32, 124, 32, 124, 32, 32, 124, 32, 124, 10, 39, 32, 32, 32, 46, 32, 32, 32, 46, 32, 124, 124, 32, 32, 32, 58, 32, 32, 32, 32, 124, 96, 45, 45, 45, 39, 32, 32, 32, 32, 32, 44, 34, 32, 46, 45, 45, 46, 59, 32, 124, 39, 32, 32, 32, 59, 32, 124, 58, 32, 32, 124, 124, 32, 32, 32, 58, 32, 124, 32, 32, 124, 47, 32, 32, 32, 32, 32, 39, 32, 32, 58, 32, 124, 95, 95, 32, 124, 32, 32, 32, 124, 32, 124, 32, 32, 124, 47, 10, 32, 96, 45, 45, 45, 96, 45, 39, 124, 32, 124, 32, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 32, 32, 47, 32, 32, 44, 46, 32, 32, 124, 124, 32, 32, 32, 124, 32, 39, 47, 32, 32, 39, 124, 32, 32, 32, 124, 32, 124, 96, 45, 39, 32, 32, 32, 32, 32, 32, 124, 32, 32, 124, 32, 39, 46, 39, 124, 124, 32, 32, 32, 124, 32, 124, 45, 45, 39, 10, 32, 46, 39, 95, 95, 47, 92, 95, 58, 32, 124, 32, 32, 96, 45, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 59, 32, 32, 58, 32, 32, 32, 46, 39, 32, 32, 32, 92, 32, 32, 32, 58, 32, 32, 32, 32, 58, 124, 124, 32, 32, 32, 59, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 59, 32, 32, 58, 32, 32, 32, 32, 59, 124, 32, 32, 32, 124, 47, 10, 32, 124, 32, 32, 32, 58, 32, 32, 32, 32, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 44, 32, 32, 32, 32, 32, 46, 45, 46, 47, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 39, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 124, 32, 32, 44, 32, 32, 32, 47, 32, 39, 45, 45, 45, 39, 10, 32, 32, 92, 32, 32, 32, 92, 32, 32, 47, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 45, 45, 96, 45, 45, 45, 39, 32, 32, 32, 32, 32, 96, 45, 45, 45, 45, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 96, 45, 39, 10, 32, 32, 32, 96, 45, 45, 96, 45, 39, 10}
+7
View File
@@ -0,0 +1,7 @@
package global
const (
LoginLog = "login_log_queue"
OperateLog = "operate_log_queue"
ApiCheck = "api_check_queue"
)

Some files were not shown because too many files have changed in this diff Show More