Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
so-operation-api
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
smart-operation
so-operation-api
Commits
e59949b8
Commit
e59949b8
authored
Jul 03, 2023
by
黄智
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
角色模块
parent
0c9d92ab
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
788 additions
and
41 deletions
+788
-41
src/bean/entity/system_role.go
src/bean/entity/system_role.go
+1
-1
src/bean/entity/system_role_menu.go
src/bean/entity/system_role_menu.go
+10
-0
src/bean/entity/system_user_role.go
src/bean/entity/system_user_role.go
+10
-0
src/bean/vo/request/system_role.go
src/bean/vo/request/system_role.go
+20
-18
src/bean/vo/response/system_role.go
src/bean/vo/response/system_role.go
+22
-22
src/controller/system_role.go
src/controller/system_role.go
+176
-0
src/router/router.go
src/router/router.go
+2
-0
src/router/systemrolerouter.go
src/router/systemrolerouter.go
+26
-0
src/service/system_role.go
src/service/system_role.go
+521
-0
No files found.
src/bean/entity/system_role.go
View file @
e59949b8
...
...
@@ -13,7 +13,7 @@ type SystemRole struct {
CreatedBy
int
`json:"created_by"`
// 角色创建人
CreatedTime
time
.
Time
`json:"created_time"`
// 角色创建时间
UpdatedTime
time
.
Time
`json:"updated_time"`
// 角色更新时间
UpdatedBy
string
`json:"updated_by"`
// 角色更新人
UpdatedBy
int
`json:"updated_by"`
// 角色更新人
RoleType
int
`json:"role_type"`
// 角色类型(0 普通角色 1 内置角色类型 不能删除和编辑 )
RoleId
string
`json:"role_id"`
// 角色id(uuid)
IsDeleted
int
`json:"is_deleted" xorm:"is_deleted"`
// 是否删除
...
...
src/bean/entity/system_role_menu.go
0 → 100644
View file @
e59949b8
package
entity
import
"time"
type
SystemRoleMenu
struct
{
Id
int64
`json:"id" xorm:"pk autoincr" `
// 主键自增id
RoleId
string
`json:"role_id" xorm:"role_id"`
// 角色id(uuid)
MenuId
string
`json:"menu_id" xorm:"menu_id" `
// 菜单id(uuid)
CreatedTime
time
.
Time
`json:"created_time" xorm:"created" `
// 创建时间
}
src/bean/entity/system_user_role.go
0 → 100644
View file @
e59949b8
package
entity
import
"time"
type
SystemUserRole
struct
{
Id
int64
`json:"id" xorm:"pk autoincr" `
// 主键自增id
UserId
int
`json:"user_id" xorm:"user_id" `
// 用户id 唯一标识
RoleId
string
`json:"role_id" xorm:"role_id"`
// 角色id(uuid)
CreatedTime
time
.
Time
`json:"created_time" xorm:"created" `
// 创建时间
}
src/bean/vo/request/system_role.go
View file @
e59949b8
package
request
type
CreateSystemRoleReq
struct
{
RoleName
string
`json:"role_name" vd:"len($)>0;msg:'请输入角色名称'"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
RoleId
string
`json:"role_id"`
// 角色id(uuid)
DataPurview
int
`json:"data_purview" vd:"$>0;msg:'请输入数据权限'"`
// 数据权限:1-仅自己,2-本组织所有,3-全平台所有
MenuIds
[]
int
`json:"menu_ids" `
// 菜单ids
CreatedBy
string
`json:"created_by"`
// 用户创建人
RoleName
string
`json:"role_name" vd:"len($)>0;msg:'请输入角色名称'"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
RoleId
string
`json:"role_id"`
// 角色id(uuid)
//
DataPurview int `json:"data_purview" vd:"$>0;msg:'请输入数据权限'"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
MenuIds
[]
int
`json:"menu_ids" `
// 菜单ids
CreatedBy
int
`json:"created_by"`
// 用户创建人
}
type
UpdateSystemRoleReq
struct
{
Id
int
`json:"id"`
// id
RoleName
string
`json:"role_name" vd:"len($)>0;msg:'请输入角色名称'"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
DataPurview
int
`json:"data_purview" vd:"$>0;msg:'请输入数据权限'"`
// 数据权限:1-仅自己,2-本组织所有,3-全平台所有
MenuIds
[]
int
`json:"menu_ids" `
// 菜单ids
UpdatedBy
string
`json:"updated_by"`
// 角色更新人
Id
int
`json:"id"`
// id
RoleName
string
`json:"role_name" vd:"len($)>0;msg:'请输入角色名称'"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
//
DataPurview int `json:"data_purview" vd:"$>0;msg:'请输入数据权限'"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
MenuIds
[]
int
`json:"menu_ids" `
// 菜单ids
UpdatedBy
int
`json:"updated_by"`
// 角色更新人
}
type
SystemRoleListReq
struct
{
IsAdmin
int
`json:"is_admin"`
IsAdmin
int
`json:"is_admin"`
Search
string
`json:"search" form:"search"`
Pagination
}
type
SystemAllotUserListReq
struct
{
Pagination
RoleId
int
`json:"role_id" form:"role_id" vd:"$>0;msg:'请输入role_id'"`
// 角色id
IsAdmin
int
`json:"is_admin" form:"is_admin"`
// 账户类型
OrganizationId
int64
`json:"organization_id" form:"organization_id"`
// 所属组织
Search
string
`json:"search" form:"search"`
RoleId
int
`json:"role_id" form:"role_id" vd:"$>0;msg:'请输入role_id'"`
// 角色id
IsAdmin
int
`json:"is_admin" form:"is_admin"`
// 账户类型
OrganizationId
int64
`json:"organization_id" form:"organization_id"`
// 所属组织
}
type
SystemRoleDetailReq
struct
{
Id
string
`json:"id" form:"id" vd:"len($)>0;msg:'请输入id'"`
// id
...
...
src/bean/vo/response/system_role.go
View file @
e59949b8
...
...
@@ -13,27 +13,27 @@ type SystemUserRole struct {
}
type
SystemRoleList
struct
{
Id
int64
`json:"id"`
// id
RoleName
string
`json:"role_name"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
CreatedBy
string
`json:"created_by"`
// 角色创建人
CreatedTime
time
.
Time
`json:"created_time"`
// 角色创建时间
RoleType
int
`json:"role_type"`
// 角色类型(0 普通角色 1 内置角色类型 不能删除和编辑 )
RoleId
string
`json:"role_id"`
// 角色id(uuid)
DataPurview
int
`json:"data_purview"`
// 数据权限:1-仅自己,2-本组织所有,3-全平台所有
UserCount
int
`json:"user_count"`
// 用户数
CantAllot
int
`json:"cant_allot"`
// 是否可分配用户
SystemAccount
string
`json:"system_account" xorm:"system_account"`
// 系统账号
Id
int64
`json:"id"`
// id
RoleName
string
`json:"role_name"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
CreatedBy
string
`json:"created_by"`
// 角色创建人
CreatedTime
time
.
Time
`json:"created_time"`
// 角色创建时间
RoleType
int
`json:"role_type"`
// 角色类型(0 普通角色 1 内置角色类型 不能删除和编辑 )
RoleId
string
`json:"role_id"`
// 角色id(uuid)
//
DataPurview int `json:"data_purview"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
UserCount
int
`json:"user_count"`
// 用户数
CantAllot
int
`json:"cant_allot"`
// 是否可分配用户
SystemAccount
string
`json:"system_account" xorm:"system_account"`
// 系统账号
}
// SystemRoleDetailRes 系统角色详情
type
SystemRoleDetailRes
struct
{
Id
int64
`json:"id"`
// id
RoleName
string
`json:"role_name"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
DataPurview
int
`json:"data_purview"`
// 数据权限:1-仅自己,2-本组织所有,3-全平台所有
Id
int64
`json:"id"`
// id
RoleName
string
`json:"role_name"`
// 角色名称
RoleDesc
string
`json:"role_desc"`
// 角色描述
State
int
`json:"state"`
// 状态0禁用1启用
//
DataPurview int `json:"data_purview"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
RoleId
string
`json:"role_id"`
// 角色id(uuid)
CreatedTime
jsontime
.
Time
`json:"created_time"`
// 角色创建时间
UpdatedTime
jsontime
.
Time
`json:"updated_time"`
// 角色更新时间
...
...
@@ -49,16 +49,16 @@ type SystemRoleListRes struct {
CreatedTime
jsontime
.
Time
`json:"created_time"`
// 角色创建时间
RoleType
int
`json:"role_type"`
// 角色类型(0 普通角色 1 内置角色类型 不能删除和编辑 )
RoleId
string
`json:"role_id"`
// 角色id(uuid)
DataPurview
int
`json:"data_purview"`
// 数据权限:1-仅自己,2-本组织所有,3-全平台所有
UserCount
int
`json:"user_count"`
// 用户数
CantAllot
int
`json:"cant_allot"`
// 是否可分配用户
//
DataPurview int `json:"data_purview"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
UserCount
int
`json:"user_count"`
// 用户数
CantAllot
int
`json:"cant_allot"`
// 是否可分配用户
}
type
SystemAllotUserList
struct
{
Id
int32
`json:"id" `
// id
SystemAccount
string
`json:"system_account"`
// 系统账号
IsAdmin
int
`json:"is_admin"`
// 用户类型
ContactPhone
string
`json:"contact_phone"`
// 联系人电话
Phone
string
`json:"phone"`
// 联系人电话
OrganizationId
string
`json:"organization_id"`
// 所属组织
OrganizationName
string
`json:"organization_name" xorm:"name"`
// 所属组织
State
int
`json:"state"`
// 状态0禁用1启用
...
...
@@ -72,7 +72,7 @@ type SystemAllotUserListRes struct {
Id
int32
`json:"id" `
// id
SystemAccount
string
`json:"system_account"`
// 系统账号
IsAdmin
int
`json:"is_admin"`
// 用户类型
ContactPhone
string
`json:"contact_phone"`
// 联系人电话
Phone
string
`json:"phone"`
// 联系人电话
OrganizationId
string
`json:"organization_id"`
// 所属组织
OrganizationName
string
`json:"organization_name"`
// 所属组织
State
int
`json:"state"`
// 状态0禁用1启用
...
...
src/controller/system_role.go
0 → 100644
View file @
e59949b8
package
controller
import
(
"errors"
vd
"github.com/bytedance/go-tagexpr/validator"
"github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
)
// CreateSystemRole 创建角色
func
CreateSystemRole
(
c
*
gin
.
Context
)
{
params
:=
request
.
CreateSystemRoleReq
{}
if
err
:=
c
.
ShouldBindJSON
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
""
)
return
}
user
:=
header
.
GetUser
(
c
)
if
user
.
Id
==
0
{
SendJsonResponse
(
c
,
resp
.
LoginFail
.
ErrorDetail
(
errors
.
New
(
"登录失败"
)),
nil
)
return
}
params
.
CreatedBy
=
user
.
Id
_
,
err
:=
service
.
CreateSystemRole
(
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
nil
)
}
// UpdateSystemRole 编辑角色
func
UpdateSystemRole
(
c
*
gin
.
Context
)
{
params
:=
request
.
UpdateSystemRoleReq
{}
if
err
:=
c
.
ShouldBindJSON
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
""
)
return
}
user
:=
header
.
GetUser
(
c
)
if
user
.
Id
==
0
{
SendJsonResponse
(
c
,
resp
.
LoginFail
.
ErrorDetail
(
errors
.
New
(
"登录失败"
)),
nil
)
return
}
params
.
UpdatedBy
=
user
.
Id
// params.UpdatedBy = "1746af3c-059d-4870-b076-6e78c617a142"
_
,
err
:=
service
.
UpdateSystemRole
(
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
nil
)
}
// SystemRoleState 修改角色状态
func
SystemRoleState
(
c
*
gin
.
Context
)
{
params
:=
request
.
SystemRoleStateReq
{}
params
.
Id
=
c
.
Param
(
"id"
)
params
.
State
=
c
.
Param
(
"state"
)
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
""
)
return
}
_
,
err
:=
service
.
SystemRoleState
(
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
nil
)
}
// SystemRoleList 系统角色列表
func
SystemRoleList
(
c
*
gin
.
Context
)
{
params
:=
request
.
SystemRoleListReq
{}
// 绑定分页数据
if
err
:=
c
.
ShouldBindQuery
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
user
:=
header
.
GetUser
(
c
)
if
user
.
Id
==
0
{
SendJsonResponse
(
c
,
resp
.
LoginFail
.
ErrorDetail
(
errors
.
New
(
"登录失败"
)),
nil
)
return
}
//params.IsAdmin = user.IsAdmin
// 分页数据初始化 limit page Offset
//params.PageInfo = params.PageInfo.InitPage()
list
,
count
,
err
:=
service
.
SystemRoleList
(
&
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonPageResponse
(
c
,
err
,
list
,
count
)
}
// SystemAllotUserList 角色可分配账户列表
func
SystemAllotUserList
(
c
*
gin
.
Context
)
{
params
:=
request
.
SystemAllotUserListReq
{}
// 绑定分页数据
if
err
:=
c
.
ShouldBindQuery
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
// 分页数据初始化 limit page Offset
//params.PageInfo = params.PageInfo.InitPage()
list
,
count
,
err
:=
service
.
SystemAllotUserList
(
&
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonPageResponse
(
c
,
err
,
list
,
count
)
}
// SystemRoleDetail 系统角色详情
func
SystemRoleDetail
(
c
*
gin
.
Context
)
{
params
:=
request
.
SystemRoleDetailReq
{}
params
.
Id
=
c
.
Param
(
"id"
)
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
""
)
return
}
result
,
err
:=
service
.
SystemRoleDetail
(
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
result
)
}
// SystemRoleAllotmentUser 给角色分配账户
func
SystemRoleAllotmentUser
(
c
*
gin
.
Context
)
{
params
:=
request
.
SystemRoleAllotmentUserReq
{}
if
err
:=
c
.
ShouldBindJSON
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
""
)
return
}
err
:=
service
.
SystemRoleAllotmentUser
(
&
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
nil
)
}
// DeleteSystemRole 删除角色
func
DeleteSystemRole
(
c
*
gin
.
Context
)
{
params
:=
request
.
DeleteSystemRoleReq
{}
if
err
:=
c
.
ShouldBindJSON
(
&
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
nil
)
return
}
if
err
:=
vd
.
Validate
(
params
);
err
!=
nil
{
SendJsonResponse
(
c
,
resp
.
InvalidParam
.
ErrorDetail
(
err
),
""
)
return
}
err
:=
service
.
DeleteSystemRole
(
params
)
if
err
!=
nil
{
SendJsonResponse
(
c
,
err
,
nil
)
return
}
SendJsonResponse
(
c
,
resp
.
OK
,
nil
)
}
src/router/router.go
View file @
e59949b8
...
...
@@ -38,6 +38,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) {
InitOrganizationRouter
(
r
)
// 初始化用户相关路由
InitSystemUserRouter
(
r
)
// 初始化角色相关路由
InitSystemRoleRouter
(
r
)
// 初始化菜单相关路由(r)
InitSystemMenuRouter
(
r
)
// 初始化指标配置路由
...
...
src/router/systemrolerouter.go
0 → 100644
View file @
e59949b8
package
router
import
(
"fmt"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"github.com/gin-gonic/gin"
)
// InitSystemRoleRouter 初始化角色相关路由
func
InitSystemRoleRouter
(
e
*
gin
.
Engine
)
{
base
:=
e
.
Group
(
fmt
.
Sprintf
(
"%s/role"
,
conf
.
Options
.
Prefix
),
header
.
SetContext
)
{
base
.
PUT
(
"create"
,
controller
.
CreateSystemRole
)
// 添加系统角色
base
.
POST
(
"update"
,
controller
.
UpdateSystemRole
)
// 编辑系统角色
base
.
POST
(
"state/:id/:state"
,
controller
.
SystemRoleState
)
// 系统角色状态
base
.
GET
(
"list"
,
controller
.
SystemRoleList
)
// 系统角色列表
base
.
GET
(
"detail/:id"
,
controller
.
SystemRoleDetail
)
// 系统角色详情
base
.
POST
(
"allotment/user"
,
controller
.
SystemRoleAllotmentUser
)
// 角色分配账户
base
.
GET
(
"allotment/list"
,
controller
.
SystemAllotUserList
)
// 角色可分配账户列表
base
.
DELETE
(
"delete"
,
controller
.
DeleteSystemRole
)
// 删除系统角色
}
}
src/service/system_role.go
0 → 100644
View file @
e59949b8
package
service
import
(
"errors"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"xorm.io/xorm"
"strconv"
"time"
"go.uber.org/zap"
)
const
(
roleTypeNormal
=
0
roleTypeSystem
=
1
roleTypeSupertube
=
2
)
// CreateSystemRole 创建系统角色
func
CreateSystemRole
(
params
request
.
CreateSystemRoleReq
)
(
resultData
int64
,
err
error
)
{
roleId
:=
util
.
GetUUID
()
systemRole
:=
entity
.
SystemRole
{
RoleName
:
params
.
RoleName
,
RoleDesc
:
params
.
RoleDesc
,
State
:
params
.
State
,
CreatedBy
:
params
.
CreatedBy
,
CreatedTime
:
time
.
Now
(),
UpdatedTime
:
time
.
Now
(),
UpdatedBy
:
params
.
CreatedBy
,
RoleType
:
roleTypeNormal
,
RoleId
:
roleId
,
//DataPurview: params.DataPurview,
}
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
// 开始事务
_
,
err
=
db
.
Transaction
(
func
(
session
*
xorm
.
Session
)
(
data
interface
{},
err
error
)
{
// 插入角色
_
,
err
=
session
.
Insert
(
&
systemRole
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"创建系统角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbInsertError
.
ErrorDetail
(
errors
.
New
(
"创建系统角色失败"
))
return
}
// 查询菜单权限
var
systemMenuArr
[]
entity
.
SystemMenu
err
=
session
.
In
(
"id"
,
params
.
MenuIds
)
.
Find
(
&
systemMenuArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询菜单列表失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询菜单列表失败"
))
return
}
var
systemRoleMenuArr
[]
entity
.
SystemRoleMenu
currentTime
:=
time
.
Now
()
for
_
,
v
:=
range
systemMenuArr
{
tempSystemRoleMenu
:=
entity
.
SystemRoleMenu
{
RoleId
:
roleId
,
MenuId
:
v
.
MenuId
,
CreatedTime
:
currentTime
,
}
systemRoleMenuArr
=
append
(
systemRoleMenuArr
,
tempSystemRoleMenu
)
}
// 权限菜单不为空则添加角色菜单
if
len
(
systemRoleMenuArr
)
>
0
{
_
,
err
=
session
.
Insert
(
&
systemRoleMenuArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"创建系统角色菜单失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbInsertError
.
ErrorDetail
(
errors
.
New
(
"创建系统角色菜单失败"
))
return
}
}
return
})
if
err
!=
nil
{
return
}
return
}
// UpdateSystemRole 修改系统角色
func
UpdateSystemRole
(
params
request
.
UpdateSystemRoleReq
)
(
resultData
int64
,
err
error
)
{
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
systemRole
:=
entity
.
SystemRole
{}
has
,
err
:=
db
.
ID
(
params
.
Id
)
.
Get
(
&
systemRole
)
if
err
!=
nil
||
!
has
{
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"角色异常"
))
return
}
roleId
:=
systemRole
.
RoleId
systemRole
=
entity
.
SystemRole
{
RoleName
:
params
.
RoleName
,
RoleDesc
:
params
.
RoleDesc
,
State
:
params
.
State
,
UpdatedTime
:
time
.
Now
(),
UpdatedBy
:
params
.
UpdatedBy
,
//DataPurview: params.DataPurview,
}
// 查询菜单权限
menuIds
:=
[]
string
{}
err
=
db
.
Table
(
"system_menu"
)
.
Cols
(
"menu_id"
)
.
In
(
"id"
,
params
.
MenuIds
)
.
Find
(
&
menuIds
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询菜单失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询菜单失败"
))
return
}
// 开启事务
_
,
err
=
db
.
Transaction
(
func
(
session
*
xorm
.
Session
)
(
data
interface
{},
err
error
)
{
// 内置角色和超管不可编辑其他信息 只能修改菜单
if
systemRole
.
RoleType
!=
roleTypeSupertube
&&
systemRole
.
RoleType
!=
roleTypeSystem
{
// 更新角色信息
_
,
err
=
session
.
Cols
(
"role_name"
,
"role_desc"
,
"state"
,
"updated_time"
,
"updated_by"
,
"data_purview"
)
.
ID
(
params
.
Id
)
.
Update
(
&
systemRole
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"修改系统角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbUpdateError
.
ErrorDetail
(
errors
.
New
(
"修改系统角色失败"
))
return
}
}
// 删除原有菜单权限
delData
:=
entity
.
SystemRoleMenu
{}
_
,
err
=
session
.
Where
(
"role_id=?"
,
roleId
)
.
Delete
(
delData
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"删除原有菜单权限失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbDeleteError
.
ErrorDetail
(
errors
.
New
(
"删除原有菜单权限失败"
))
}
systemRoleMenuArr
:=
[]
entity
.
SystemRoleMenu
{}
currentTime
:=
time
.
Now
()
for
_
,
v
:=
range
menuIds
{
tempSystemRoleMenu
:=
entity
.
SystemRoleMenu
{
RoleId
:
roleId
,
MenuId
:
v
,
CreatedTime
:
currentTime
,
}
systemRoleMenuArr
=
append
(
systemRoleMenuArr
,
tempSystemRoleMenu
)
}
// 权限菜单不为空则添加角色菜单
if
len
(
systemRoleMenuArr
)
>
0
{
_
,
err
=
session
.
Insert
(
&
systemRoleMenuArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"创建系统角色菜单失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbInsertError
.
ErrorDetail
(
errors
.
New
(
"创建系统角色菜单失败"
))
return
}
}
return
})
if
err
!=
nil
{
return
}
return
}
// SystemRoleState 修改系统角色状态
func
SystemRoleState
(
params
request
.
SystemRoleStateReq
)
(
resultData
int64
,
err
error
)
{
systemRole
:=
entity
.
SystemRole
{}
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
id
,
_
:=
strconv
.
Atoi
(
params
.
Id
)
get
,
err
:=
db
.
ID
(
id
)
.
Get
(
&
systemRole
)
if
err
!=
nil
||
!
get
{
conf
.
Logger
.
Error
(
"查询角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbUpdateError
.
ErrorDetail
(
errors
.
New
(
"查询角色失败"
))
return
}
if
systemRole
.
RoleType
==
roleTypeSystem
||
systemRole
.
RoleType
==
roleTypeSupertube
{
conf
.
Logger
.
Error
(
"当前角色不可更换状态"
,
zap
.
Error
(
err
))
err
=
resp
.
DbUpdateError
.
ErrorDetail
(
errors
.
New
(
"当前角色不可更换状态"
))
return
}
systemRole
.
State
=
0
if
params
.
State
==
"1"
{
systemRole
.
State
=
1
}
obj
:=
db
.
ID
(
id
)
update
,
err
:=
obj
.
Cols
(
"state"
)
.
Where
(
"is_deleted = 0"
)
.
Update
(
&
systemRole
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"修改系统角色状态失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbUpdateError
.
ErrorDetail
(
errors
.
New
(
"修改系统角色状态失败"
))
return
}
return
update
,
nil
}
// SystemRoleList 获取系统角色列表
func
SystemRoleList
(
params
*
request
.
SystemRoleListReq
)
(
resultData
[]
response
.
SystemRoleListRes
,
count
int64
,
err
error
)
{
systemRoleArr
:=
[]
response
.
SystemRoleList
{}
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
modelObj
:=
db
.
Table
(
"system_role as sr"
)
modelObj
.
Select
(
"sr.id,sr.role_name,sr.created_time,sr.created_by,sr.role_desc,sr.state,sr.role_type,sr.role_id,su.system_account"
)
modelObj
.
Join
(
"left"
,
"system_user as su"
,
"sr.created_by = su.id"
)
if
params
.
Search
!=
""
{
modelObj
.
Where
(
"sr.role_name like ?"
,
"%"
+
params
.
Search
+
"%"
)
}
modelObj
.
Where
(
"sr.is_deleted = 0"
)
if
params
.
IsAdmin
!=
1
{
modelObj
.
Where
(
"sr.role_type !=?"
,
roleTypeSupertube
)
}
// 查询系统角色列表
count
,
err
=
modelObj
.
OrderBy
(
"sr.id desc"
)
.
Limit
(
params
.
GetPageSize
(),
(
params
.
GetPage
()
-
1
)
*
params
.
GetPageSize
())
.
FindAndCount
(
&
systemRoleArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询系统角色列表失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询系统角色列表失败"
))
return
}
// 拼装返回结果
SystemRoleListArr
:=
[]
response
.
SystemRoleListRes
{}
roleIds
:=
[]
string
{}
for
_
,
v
:=
range
systemRoleArr
{
SystemRoleListRes
:=
response
.
SystemRoleListRes
{
Id
:
v
.
Id
,
RoleName
:
v
.
RoleName
,
RoleDesc
:
v
.
RoleDesc
,
State
:
v
.
State
,
CreatedBy
:
v
.
SystemAccount
,
CreatedTime
:
jsontime
.
Time
(
v
.
CreatedTime
),
RoleType
:
v
.
RoleType
,
RoleId
:
v
.
RoleId
,
//DataPurview: v.DataPurview,
}
// 业务系统角色不可分配用户
if
v
.
RoleType
!=
0
{
SystemRoleListRes
.
CantAllot
=
1
}
SystemRoleListArr
=
append
(
SystemRoleListArr
,
SystemRoleListRes
)
roleIds
=
append
(
roleIds
,
v
.
RoleId
)
}
// 查询角色关联用户数量
userCountMap
:=
make
([]
struct
{
RoleId
string
`json:"role_id"`
UserCount
int
`json:"user_count"`
},
0
)
err
=
db
.
Select
(
"role_id::varchar,count(*) as user_count"
)
.
Table
(
"system_user_role"
)
.
In
(
"role_id"
,
roleIds
)
.
GroupBy
(
"role_id"
)
.
Find
(
&
userCountMap
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询角色关联用户数量失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询角色关联用户数量失败"
))
return
}
// 用户数关联到角色id
userCountMapKey
:=
make
(
map
[
string
]
int
)
for
_
,
v
:=
range
userCountMap
{
userCountMapKey
[
v
.
RoleId
]
=
v
.
UserCount
}
// 用户数拼接到返回结果
for
k
,
v
:=
range
SystemRoleListArr
{
SystemRoleListArr
[
k
]
.
UserCount
=
userCountMapKey
[
v
.
RoleId
]
}
resultData
=
SystemRoleListArr
return
resultData
,
count
,
nil
}
// SystemAllotUserList 角色可分配账户列表
func
SystemAllotUserList
(
params
*
request
.
SystemAllotUserListReq
)
(
resultData
[]
response
.
SystemAllotUserListRes
,
count
int64
,
err
error
)
{
// 账户类型筛选条件不可为业务系统账户,强制清空账户类型筛选项
//if params.IsAdmin == isAdminSystem {
// params.IsAdmin = 0
//}
var
SystemUserArr
[]
response
.
SystemAllotUserList
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
systemRole
:=
entity
.
SystemRole
{}
get
,
roleErr
:=
db
.
Table
(
"system_role"
)
.
ID
(
params
.
RoleId
)
.
Get
(
&
systemRole
)
if
roleErr
!=
nil
||
!
get
{
conf
.
Logger
.
Error
(
"查询角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询角色失败"
))
return
}
modelObj
:=
db
.
Table
(
"system_user as su"
)
modelObj
.
Select
(
"su.id,su.system_account,su.phone,su.organization_id,so.name,su.created_time,su.state,ur.role_id,ur.user_id as ur_user_id"
)
modelObj
.
Join
(
"left"
,
"system_organization as so"
,
"su.organization_id = so.organization_id"
)
modelObj
.
Join
(
"left"
,
"system_user_role as ur"
,
"su.id = ur.user_id and ur.role_id=?"
,
systemRole
.
RoleId
)
if
params
.
Search
!=
""
{
params
.
Search
=
"%"
+
params
.
Search
+
"%"
modelObj
.
Where
(
"su.system_account like ? or su.phone ? "
,
params
.
Search
,
params
.
Search
)
}
if
systemRole
.
RoleType
==
2
{
modelObj
.
Where
(
"so.data_type = 2"
)
}
if
params
.
OrganizationId
!=
0
{
systemOrganization
:=
entity
.
SystemOrganization
{}
has
,
organizationErr
:=
db
.
Table
(
"system_organization"
)
.
ID
(
params
.
OrganizationId
)
.
Get
(
&
systemOrganization
)
if
organizationErr
!=
nil
||
!
has
{
conf
.
Logger
.
Error
(
"查询组织架构失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询组织架构失败"
))
return
}
modelObj
.
Where
(
"su.organization_id = ?"
,
systemOrganization
.
OrganizationId
)
if
systemRole
.
RoleType
==
2
&&
systemOrganization
.
DataType
!=
2
{
return
nil
,
0
,
nil
}
}
// 根据用户当前角色排除可分配角色类型
//switch util.RoleId(systemRole.RoleId) {
//case util.YEWUXITONGJUESE: // 业务系统账户不可分配任何角色的账户
// return
//case util.ZUZHIGUANLIYUAN: // 组织管理员不可分配任何角色的账户
// return
//case util.CHAOJIGUANLIYUAN:
// modelObj.Where("su.is_admin = ?", isAdminOrdinary)
//case util.PINGTAIYUNYINGZHE:
// modelObj.Where("su.is_admin = ?", isAdminOrdinary)
//default:
// modelObj.In("su.is_admin", []int{isAdminOrganize, isAdminOrdinary})
//}
//
//// 排除业务系统用户
//modelObj.Where("su.is_admin != ?", isAdminSystem)
//if params.IsAdmin != 0 {
// modelObj.Where("su.is_admin = ?", params.IsAdmin)
//}
modelObj
.
Where
(
"su.is_deleted = 0"
)
count
,
err
=
modelObj
.
OrderBy
(
"su.id desc"
)
.
Limit
(
params
.
GetPageSize
(),
(
params
.
GetPage
()
-
1
)
*
params
.
GetPageSize
())
.
FindAndCount
(
&
SystemUserArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询系统账户列表失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询系统账户列表失败"
))
return
}
var
SystemUserListResArr
[]
response
.
SystemAllotUserListRes
for
_
,
v
:=
range
SystemUserArr
{
SystemUserListRes
:=
response
.
SystemAllotUserListRes
{
Id
:
v
.
Id
,
SystemAccount
:
v
.
SystemAccount
,
IsAdmin
:
v
.
IsAdmin
,
Phone
:
v
.
Phone
,
OrganizationId
:
v
.
OrganizationId
,
OrganizationName
:
v
.
OrganizationName
,
State
:
v
.
State
,
CreatedTime
:
jsontime
.
Time
(
v
.
CreatedTime
),
SystemId
:
v
.
SystemId
,
IsBind
:
0
,
}
if
v
.
UrSystemId
!=
""
{
SystemUserListRes
.
IsBind
=
1
}
SystemUserListResArr
=
append
(
SystemUserListResArr
,
SystemUserListRes
)
}
resultData
=
SystemUserListResArr
return
resultData
,
count
,
nil
}
// SystemRoleDetail 系统角色详情
func
SystemRoleDetail
(
params
request
.
SystemRoleDetailReq
)
(
resultData
response
.
SystemRoleDetailRes
,
err
error
)
{
systemRole
:=
entity
.
SystemRole
{}
systemRoleDetailRes
:=
response
.
SystemRoleDetailRes
{}
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
// 查询系统角色详情
id
,
_
:=
strconv
.
Atoi
(
params
.
Id
)
has
,
err
:=
db
.
ID
(
id
)
.
Where
(
"is_deleted = 0"
)
.
Get
(
&
systemRole
)
if
err
!=
nil
||
!
has
{
conf
.
Logger
.
Error
(
"查询系统角色详情失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询系统角色详情失败"
))
return
}
// 拼装返回结果
systemRoleDetailRes
.
Id
=
systemRole
.
Id
systemRoleDetailRes
.
RoleId
=
systemRole
.
RoleId
systemRoleDetailRes
.
RoleName
=
systemRole
.
RoleName
systemRoleDetailRes
.
RoleDesc
=
systemRole
.
RoleDesc
systemRoleDetailRes
.
State
=
systemRole
.
State
//systemRoleDetailRes.DataPurview = systemRole.DataPurview
systemRoleDetailRes
.
RoleId
=
systemRole
.
RoleId
systemRoleDetailRes
.
CreatedTime
=
jsontime
.
Time
(
systemRole
.
CreatedTime
)
systemRoleDetailRes
.
UpdatedTime
=
jsontime
.
Time
(
systemRole
.
UpdatedTime
)
systemRoleDetailRes
.
RoleType
=
systemRole
.
RoleType
// 查询角色关联菜单
systemMenusArr
:=
[]
response
.
SystemMenus
{}
err
=
db
.
Select
(
"sm.id,sm.menu_id"
)
.
Table
(
"system_role_menu as rm"
)
.
Join
(
"left"
,
"system_menu sm"
,
"rm.menu_id = sm.menu_id"
)
.
Where
(
"rm.role_id=?"
,
systemRole
.
RoleId
)
.
Find
(
&
systemMenusArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询角色菜单失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询角色菜单失败"
))
return
}
systemRoleDetailRes
.
Menus
=
systemMenusArr
resultData
=
systemRoleDetailRes
return
resultData
,
nil
}
// SystemRoleAllotmentUser 分配用户
func
SystemRoleAllotmentUser
(
params
*
request
.
SystemRoleAllotmentUserReq
)
(
err
error
)
{
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
// 查询角色
systemRole
:=
entity
.
SystemRole
{}
_
,
err
=
db
.
Table
(
"system_role"
)
.
ID
(
params
.
Id
)
.
Where
(
"is_deleted =0"
)
.
Get
(
&
systemRole
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询角色失败"
))
return
err
}
//if systemRole.RoleId == string(util.YEWUXITONGJUESE) || systemRole.RoleId == string(util.ZUZHIGUANLIYUAN) {
// err = res.DbSelectError.ErrorDetail(errors.New("当前角色不可分配用户"))
// return err
//}
// 开启事务
_
,
err
=
db
.
Transaction
(
func
(
session
*
xorm
.
Session
)
(
data
interface
{},
err
error
)
{
// 删除原有角色关联记录
delData
:=
entity
.
SystemUserRole
{}
_
,
err
=
session
.
Where
(
"role_id=?"
,
systemRole
.
RoleId
)
.
Delete
(
delData
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"删除原有角色关联失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbDeleteError
.
ErrorDetail
(
errors
.
New
(
"删除原有角色关联失败"
))
}
// 查询用户信息
systemUserArr
:=
[]
entity
.
SystemUser
{}
//userCount, err := session.In("id", params.UserIds).Where("is_admin !=?", isAdminSystem).FindAndCount(&systemUserArr)
userCount
,
err
:=
session
.
In
(
"id"
,
params
.
UserIds
)
.
FindAndCount
(
&
systemUserArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询用户失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询用户失败"
))
return
}
// 查询结果用户数和入参用户数不匹配则认定为有异常用户
if
len
(
params
.
UserIds
)
!=
int
(
userCount
)
{
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"无法分配,存在异常用户!"
))
return
}
systemUserRoleArr
:=
[]
entity
.
SystemUserRole
{}
for
_
,
v
:=
range
systemUserArr
{
temp
:=
entity
.
SystemUserRole
{
UserId
:
v
.
Id
,
RoleId
:
systemRole
.
RoleId
,
CreatedTime
:
time
.
Now
(),
}
systemUserRoleArr
=
append
(
systemUserRoleArr
,
temp
)
}
if
len
(
systemUserRoleArr
)
>
0
{
// 添加角色和用户关联记录
_
,
err
=
session
.
Insert
(
systemUserRoleArr
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"分配用户失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbUpdateError
.
ErrorDetail
(
errors
.
New
(
"分配用户失败"
))
return
}
}
return
})
return
}
// DeleteSystemRole 删除系统角色
func
DeleteSystemRole
(
params
request
.
DeleteSystemRoleReq
)
(
err
error
)
{
db
,
err
:=
client
.
GetDbClient
()
if
err
!=
nil
{
err
=
resp
.
DbConnectError
.
ErrorDetail
(
err
)
return
}
roleIds
:=
[]
string
{}
SystemUserCount
,
err
:=
db
.
Table
(
"system_role"
)
.
Cols
(
"role_id"
)
.
In
(
"id"
,
params
.
Ids
)
.
Where
(
"state!=1 and role_type !=1 and role_type !=2"
)
.
FindAndCount
(
&
roleIds
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"查询需要删除的角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"查询需要删除的角色失败"
))
return
err
}
if
len
(
params
.
Ids
)
!=
int
(
SystemUserCount
)
{
err
=
resp
.
DbSelectError
.
ErrorDetail
(
errors
.
New
(
"删除内容中有未禁用或内置角色,不可删除!"
))
return
}
// 开启事务
_
,
err
=
db
.
Transaction
(
func
(
session
*
xorm
.
Session
)
(
data
interface
{},
err
error
)
{
// 删除系统角色
updateData
:=
entity
.
SystemRole
{}
updateData
.
IsDeleted
=
1
_
,
err
=
session
.
Cols
(
"is_deleted"
)
.
In
(
"role_id"
,
roleIds
)
.
Update
(
&
updateData
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"删除系统角色失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbDeleteError
.
ErrorDetail
(
errors
.
New
(
"删除系统角色失败"
))
return
}
// 删除角色对应菜单
delData
:=
entity
.
SystemRoleMenu
{}
_
,
err
=
session
.
In
(
"role_id"
,
roleIds
)
.
Delete
(
delData
)
if
err
!=
nil
{
conf
.
Logger
.
Error
(
"删除角色菜单权限失败"
,
zap
.
Error
(
err
))
err
=
resp
.
DbDeleteError
.
ErrorDetail
(
errors
.
New
(
"删除角色菜单权限失败"
))
}
return
})
return
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment