作者 tangxvhui

Merge branch 'dev' into test

正在显示 52 个修改的文件 包含 638 行增加41 行删除
... ... @@ -3,13 +3,14 @@ package main
import (
"context"
"flag"
"net/http"
"strings"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"net/http"
"strings"
"github.com/golang-jwt/jwt/v4/request"
"github.com/zeromicro/go-zero/core/conf"
... ... @@ -65,7 +66,8 @@ func systemSetup(c config.Config) {
// 默认的token头 Authorization 修改为 x-mmm-accesstoken
request.AuthorizationHeaderExtractor = &request.PostExtractionFilter{
request.HeaderExtractor{"x-mmm-accesstoken"}, func(tok string) (string, error) {
Extractor: request.HeaderExtractor{"x-mmm-accesstoken"},
Filter: func(tok string) (string, error) {
// Should be a bearer token
if len(tok) > 6 && strings.ToUpper(tok[0:7]) == "BEARER " {
return tok[7:], nil
... ...
... ... @@ -130,7 +130,7 @@ type (
type (
MiniSetUserLikeRequset {
ArticleId int64 `json:"articleId"` //文章id
CommentId int64 `json:"commentId"` //评论id
CommentId int64 `json:"commentId,optional"` //评论id
UserId int64 `json:",optional"` //操作人
Flag int `json:"flag"` //点赞标志 1、点赞 2 、取消点赞
}
... ...
... ... @@ -68,7 +68,7 @@ type (
}
RoleItem {
Id int64 `json:"id,optional"` // 角色ID
CompanyId int64 `json:"companyId,optional,omitempty"` // 公司ID
CompanyId int64 `json:"companyId,optional,string,omitempty"` // 公司ID
Name string `json:"name"` // 角色名称
AuthIds []int64 `json:"authIds,optional,omitempty"` // 角色权限列表
AuthsDesc string `json:"authsDesc,optional,omitempty"` // 权限列表描述
... ...
... ... @@ -141,6 +141,8 @@ type(
Summary string `json:"summary"` // 快讯概要
Time int64 `json:"time"` // 时间
ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读
Images []string `json:"images"` // 图片列表
Author UserItem `json:"author"` // 作者
}
MiniUserFollowedSearchRequest{
Page int `json:"page,optional"`
... ... @@ -166,7 +168,7 @@ type(
//Roles []int64 `json:"roleId,omitempty"` // 角色
Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
Name string `json:"name,omitempty"` // 名称
Avatar string `json:"avatar,omitempty"` // 头像
Avatar *string `json:"avatar,omitempty"` // 头像
Phone string `json:"phone,omitempty"` // 手机号 唯一
Position string `json:"position,omitempty"` // 职位
Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
... ... @@ -389,6 +391,9 @@ type(
}
SystemUserAccountUpdateRequest struct{
Id int64 `path:"id"`
Name string `json:"name"` // 姓名
Roles []int64 `json:"roles"` // 权限角色
Status int `json:"enable"` // 状态 1:启用 2:禁用
}
SystemUserAccountUpdateResponse struct{}
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取所有的标签
func MiniAllArticleTagHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniAllArticleTagRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取文章的编辑记录
func MiniArticleBackupSearchHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleBackupSearchRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
// 获取我的文章浏览记录
func MiniArticleMarkListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleMarkListRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取我发布的文章
func MiniArticleSearchMeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleSearchMeRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 设置文章的定性标签
func MiniArticleSetTagHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleSetTagRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 保存文章进草稿箱
func MiniCreateArticleDraftHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleDraftCreateRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 发布新的文章
func MiniCreateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleCreateRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 删除文章的草稿箱
func MiniDeleteArticleDraftMeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleDraftDeleteMeRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取我的文章草稿内容
func MiniGetArticleDraftMeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleDraftGetMeRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 小程序端展示文章内容
func MiniGetArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleGetRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 查询我的草稿箱内容列表
func MiniSearchArticleDraftMeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleDraftSearchMeRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 设置文章\评论的点赞操作
func MiniSetUserLikeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniSetUserLikeRequset
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 更新文章草稿箱的内容
func MiniUpdateArticleDraftHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleDraftUpdateRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取点赞文章的的人员列表
func MiniUserLikeArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniUserLikeArticleRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 填写评估时@谁 的可选择者列表
func MiniArticleCommentAtWhoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniArticleCommentAtWhoRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 填写评论
func MiniCreateArticleCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniCreateArticleCommentRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 小程序端人员删除评论
func MiniDeleteArticleCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniDeleteArticleCommentRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取单条评论详情
func MiniGetArticleCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniGetArticleCommentRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 小程序端获取 根据文章id 获取评论列表
func MiniListArticleCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniListArticleCommentRequest
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 获取前5的评论
func MiniTop5ArticleCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniTop5ArticleCommentRequest
... ...
... ... @@ -25,6 +25,7 @@ func NewMiniSearchArticleDraftMeLogic(ctx context.Context, svcCtx *svc.ServiceCo
}
}
// 查询我的草稿箱内容列表
func (l *MiniSearchArticleDraftMeLogic) MiniSearchArticleDraftMe(req *types.MiniArticleDraftSearchMeRequest) (resp *types.MiniArticleDraftSearchMeResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
... ...
... ... @@ -26,6 +26,7 @@ func NewMiniUpdateArticleDraftLogic(ctx context.Context, svcCtx *svc.ServiceCont
}
}
// 更新文章草稿箱的内容
func (l *MiniUpdateArticleDraftLogic) MiniUpdateArticleDraft(req *types.MiniArticleDraftUpdateRequest) (resp *types.MiniArticleDraftUpdateResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
... ...
... ... @@ -2,6 +2,7 @@ package article
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
... ... @@ -26,6 +27,7 @@ func NewSystemArticleGetHistoryLogic(ctx context.Context, svcCtx *svc.ServiceCon
}
}
// 获取文章的编辑历史记录详情
func (l *SystemArticleGetHistoryLogic) SystemArticleGetHistory(req *types.SystemArticleGetHistoryRequest) (resp *types.SystemArticleGetHistoryResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
backup, err := l.svcCtx.ArticleBackupRepository.FindOne(l.ctx, conn, req.Id)
... ...
... ... @@ -2,6 +2,7 @@ package comment
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
... ... @@ -26,6 +27,7 @@ func NewSystemArticleCommentSearchLogic(ctx context.Context, svcCtx *svc.Service
}
}
// 搜索文章的评论
func (l *SystemArticleCommentSearchLogic) SystemArticleCommentSearch(req *types.SystemArticleCommentSearchRequest) (resp *types.SystemArticleCommentSearchResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
queryOptions := domain.NewQueryOptions().
... ...
... ... @@ -24,6 +24,7 @@ func NewSystemGetAticleCommentLogic(ctx context.Context, svcCtx *svc.ServiceCont
}
}
// 后台获取文章的评论详情
func (l *SystemGetAticleCommentLogic) SystemGetAticleComment(req *types.SystemGetCommentRequest) (resp *types.SystemGetCommentResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
... ...
... ... @@ -31,14 +31,16 @@ func (l *SystemDeleteRoleLogic) SystemDeleteRole(req *types.RoleDeleteRequest) (
conn = l.svcCtx.DefaultDBConn()
role *domain.Role
userRemoveRoleList []*domain.User
userRoles []*domain.UserRole
)
if role, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("角色不存在", err)
}
for _, item := range role.Users {
_, userRoles, _ = l.svcCtx.UserRoleRepository.Find(l.ctx, conn, domain.IndexCompanyId(role.CompanyId)().WithKV("roleId", role.Id).WithFindOnly())
for _, item := range userRoles {
var user *domain.User
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, item.Id); err != nil {
return nil, xerr.NewErrMsgErr("用户存在", err)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, item.UserId); err != nil {
continue
}
userRemoveRoleList = append(userRemoveRoleList, user)
}
... ... @@ -52,6 +54,9 @@ func (l *SystemDeleteRoleLogic) SystemDeleteRole(req *types.RoleDeleteRequest) (
return err
}
}
if err = l.svcCtx.UserRoleRepository.DeleteRole(l.ctx, conn, role.Id); err != nil {
return err
}
return nil
}, true); err != nil {
return nil, xerr.NewErrMsgErr("删除角色失败", err)
... ...
... ... @@ -2,7 +2,9 @@ package role
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
... ... @@ -29,13 +31,24 @@ func (l *SystemGetRoleLogic) SystemGetRole(req *types.RoleGetRequest) (resp *typ
var (
conn = l.svcCtx.DefaultDBConn()
role *domain.Role
users []*domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
)
if role, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("角色不存在", err)
}
_, users, _ = l.svcCtx.UserRepository.FindByCompanyRoles(l.ctx, conn, userToken.CompanyId, []int64{role.Id}, domain.NewQueryOptions().WithFindOnly())
typesRole := NewTypesRole(role)
lo.ForEach(users, func(item *domain.User, index int) {
typesRole.Users = append(typesRole.Users, types.RoleUser{
Id: item.Id,
Name: item.Name,
})
})
resp = &types.RoleGetResponse{
Role: NewTypesRole(role),
Role: typesRole,
}
for _, auth := range domain.Auths {
resp.AuthList = append(resp.AuthList, types.Auth{
Id: auth.Id,
... ...
... ... @@ -56,6 +56,13 @@ func (l *SystemSaveRoleLogic) SystemSaveRole(req *types.RoleSaveRequest) (resp *
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: role.Id,
}); err != nil {
return err
}
}
return nil
}, true); err != nil {
... ... @@ -82,7 +89,7 @@ func NewDomainRole(ctx context.Context, item types.RoleItem) *domain.Role {
Name: item.Name,
Auths: item.AuthIds,
Remark: item.Remark,
Users: users,
//Users: users,
}
return role
}
... ... @@ -92,12 +99,6 @@ func NewTypesRole(item *domain.Role) types.RoleItem {
role types.RoleItem
users []types.RoleUser = make([]types.RoleUser, 0)
)
lo.ForEach(item.Users, func(item domain.User, index int) {
users = append(users, types.RoleUser{
Id: item.Id,
Name: item.Name,
})
})
role = types.RoleItem{
Id: item.Id,
CompanyId: item.CompanyId,
... ...
... ... @@ -35,6 +35,7 @@ func (l *SystemSearchRoleLogic) SystemSearchRole(req *types.RoleSearchRequest) (
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
roles []*domain.Role
total int64
users []*domain.User
)
queryOptions := domain.IndexCompanyId(userToken.CompanyId)()
if req.Page != 0 && req.Size != 0 {
... ... @@ -57,17 +58,27 @@ func (l *SystemSearchRoleLogic) SystemSearchRole(req *types.RoleSearchRequest) (
})
return
}
roleIds := domain.Values(roles, func(item *domain.Role) int64 {
return item.Id
})
_, users, _ = l.svcCtx.UserRepository.FindByCompanyRoles(l.ctx, conn, userToken.CompanyId, roleIds, domain.NewQueryOptions().WithFindOnly())
lo.ForEach(roles, func(item *domain.Role, index int) {
role := NewTypesRole(item)
role.UsersDesc = usersDesc(item)
usersAll := make([]domain.User, 0)
for _, u := range users {
if lo.Contains(u.Roles, item.Id) {
usersAll = append(usersAll, *u)
}
}
role.UsersDesc = usersDesc(usersAll)
role.AuthsDesc = authsDesc(item)
resp.List = append(resp.List, role)
})
return
}
func usersDesc(item *domain.Role) string {
users := lo.Slice(item.Users, 0, 3)
func usersDesc(usersAll []domain.User) string {
users := lo.Slice(usersAll, 0, 3)
var (
nameList = make([]string, 0)
desc string = " "
... ... @@ -79,7 +90,7 @@ func usersDesc(item *domain.Role) string {
return desc
}
desc = fmt.Sprintf("%s%s", strings.Join(nameList, "、"),
lo.Ternary(len(item.Users) > 3, fmt.Sprintf("...共%d人", len(item.Users)), ""),
lo.Ternary(len(usersAll) > 3, fmt.Sprintf("...共%d人", len(usersAll)), ""),
)
return desc
}
... ...
... ... @@ -37,6 +37,8 @@ func (l *SystemUpdateRoleLogic) SystemUpdateRole(req *types.RoleUpdateRequest) (
userRemoveRoleList []*domain.User
userAddRoleList []*domain.User
userRoles []*domain.UserRole
)
if role, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("角色不存在", err)
... ... @@ -46,11 +48,12 @@ func (l *SystemUpdateRoleLogic) SystemUpdateRole(req *types.RoleUpdateRequest) (
return nil, xerr.NewErrMsg(fmt.Sprintf("unknown auth %d ", authId))
}
}
lo.ForEach(role.Users, func(item domain.User, index int) {
beforeUserIds = append(beforeUserIds, item.Id)
_, userRoles, _ = l.svcCtx.UserRoleRepository.Find(l.ctx, conn, domain.IndexCompanyId(role.CompanyId)().WithKV("roleId", role.Id).WithFindOnly())
beforeUserIds = domain.Values(userRoles, func(item *domain.UserRole) int64 {
return item.UserId
})
tempRole := NewDomainRole(l.ctx, req.Role)
lo.ForEach(tempRole.Users, func(item domain.User, index int) {
lo.ForEach(req.Role.Users, func(item types.RoleUser, index int) {
afterUserIds = append(afterUserIds, item.Id)
})
removeList, addList := lo.Difference(beforeUserIds, afterUserIds)
... ... @@ -69,26 +72,36 @@ func (l *SystemUpdateRoleLogic) SystemUpdateRole(req *types.RoleUpdateRequest) (
userAddRoleList = append(userAddRoleList, user)
}
if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
// 更新角色
role.Name = tempRole.Name
role.Auths = tempRole.Auths
role.Remark = tempRole.Remark
role.Users = tempRole.Users
if role, err = l.svcCtx.RoleRepository.UpdateWithVersion(ctx, conn, role); err != nil {
return err
}
// 移除角色用户
for _, user := range userRemoveRoleList {
user.RemoveRole(role.Id)
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if err = l.svcCtx.UserRoleRepository.DeleteByUserAndRole(ctx, conn, user.Id, role.Id); err != nil {
return err
}
}
// 新增角色用户
for _, user := range userAddRoleList {
user.AddRole(role.Id)
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: role.Id,
}); err != nil {
return err
}
}
return nil
}, true); err != nil {
... ...
... ... @@ -58,7 +58,7 @@ func NewUserItemSimple(user *domain.User, company *domain.Company) *types.UserIt
Id: user.Id,
Name: user.Name,
CompanyName: lo.Ternary(company != nil, company.Name, ""),
Avatar: user.Avatar,
Avatar: lo.ToPtr(user.Avatar),
Phone: user.Phone,
Position: user.Position,
AuditStatus: &user.AuditStatus,
... ...
... ... @@ -48,7 +48,7 @@ func (l *MiniUserInfoLogic) MiniUserInfo(req *types.MiniUserInfoRequest) (resp *
User: &types.UserItem{
Id: user.Id,
Name: user.Name,
Avatar: user.Avatar,
Avatar: lo.ToPtr(user.Avatar),
Position: user.Position,
AuditStatus: lo.ToPtr(user.AuditStatus),
Enable: user.Enable,
... ...
... ... @@ -34,6 +34,7 @@ func (l *MiniUserNewsLogic) MiniUserNews(req *types.MiniUserNewsRequest) (resp *
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
articles []*domain.Article
readArticles = make([]*domain.UserReadArticle, 0)
userMap = make(map[int64]*domain.User)
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil {
return nil, xerr.NewErrMsgErr("用户不存在", err)
... ... @@ -67,8 +68,19 @@ func (l *MiniUserNewsLogic) MiniUserNews(req *types.MiniUserNewsRequest) (resp *
Title: item.Title,
Summary: item.Summary,
Time: item.CreatedAt,
Images: make([]string, 0),
ReadFlag: false,
}
if author, _ := domain.LazyLoad(userMap, l.ctx, conn, item.AuthorId, l.svcCtx.UserRepository.FindOne); author != nil {
newsItem.Author = types.UserItem{
Id: author.Id,
Name: author.Name,
Avatar: lo.ToPtr(author.Avatar),
}
}
for _, img := range item.Images {
newsItem.Images = append(newsItem.Images, img.Url)
}
if _, ok := readArticlesMap[item.Id]; ok {
newsItem.ReadFlag = true
}
... ...
... ... @@ -67,10 +67,20 @@ func (l *SystemUserAccountSaveLogic) SystemUserAccountSave(req *types.SystemUser
AuditStatus: domain.UserAuditStatusPassed,
}
user.WithName(name)
if user, err = l.svcCtx.UserRepository.Insert(ctx, conn, user); err != nil {
return err
}
for _, roleId := range req.Roles {
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: roleId,
}); err != nil {
return err
}
user.AddRole(roleId)
}
if user, err = l.svcCtx.UserRepository.Insert(ctx, conn, user); err != nil {
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
return nil
... ...
... ... @@ -2,6 +2,11 @@ package user
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -24,7 +29,49 @@ func NewSystemUserAccountUpdateLogic(ctx context.Context, svcCtx *svc.ServiceCon
}
func (l *SystemUserAccountUpdateLogic) SystemUserAccountUpdate(req *types.SystemUserAccountUpdateRequest) (resp *types.SystemUserAccountUpdateResponse, err error) {
// todo: add your logic here and delete this line
var (
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
user *domain.User
conn = l.svcCtx.DefaultDBConn()
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("用户不存在", err)
}
if user.CompanyId != userToken.CompanyId {
return nil, xerr.NewErrMsgErr("无权限更改", err)
}
if req.Name != user.Name {
user.WithName(req.Name)
}
removeList, addList := lo.Difference(user.Roles, req.Roles)
if len(removeList) > 0 || len(addList) > 0 {
user.Roles = req.Roles
}
user.Enable = req.Status
if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if len(removeList) > 0 || len(addList) > 0 {
if err = l.svcCtx.UserRoleRepository.DeleteByUser(ctx, conn, user.Id); err != nil {
return err
}
user.Roles = []int64{}
for _, roleId := range req.Roles {
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: roleId,
}); err != nil {
return err
}
user.AddRole(roleId)
}
}
return nil
}, true); err != nil {
return nil, xerr.NewErrMsgErr("更新用户信息失败", err)
}
resp = &types.SystemUserAccountUpdateResponse{}
return
}
... ...
... ... @@ -39,6 +39,7 @@ type ServiceContext struct {
UserLoveFlagRepository domain.UserLoveFlagRepository
UserReadArticleRepository domain.UserReadArticleRepository
UserRepository domain.UserRepository
UserRoleRepository domain.UserRoleRepository
ApiAuthService authlib.ApiAuthService
SmsService smslib.SMSService
... ... @@ -80,6 +81,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)),
UserReadArticleRepository: repository.NewUserReadArticleRepository(cache.NewCachedRepository(mlCache)),
ArticleTagRepository: repository.NewArticleTagRepository(cache.NewCachedRepository(mlCache)),
UserRoleRepository: repository.NewUserRoleRepository(cache.NewCachedRepository(mlCache)),
}
}
... ...
... ... @@ -478,6 +478,8 @@ type UserNewsItem struct {
Summary string `json:"summary"` // 快讯概要
Time int64 `json:"time"` // 时间
ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读
Images []string `json:"images"` // 图片列表
Author UserItem `json:"author"` // 作者
}
type MiniUserFollowedSearchRequest struct {
... ... @@ -503,7 +505,7 @@ type UserItem struct {
CompanyLogo *string `json:"companyLogo,omitempty"` // 公司LOGO
Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
Name string `json:"name,omitempty"` // 名称
Avatar string `json:"avatar,omitempty"` // 头像
Avatar *string `json:"avatar,omitempty"` // 头像
Phone string `json:"phone,omitempty"` // 手机号 唯一
Position string `json:"position,omitempty"` // 职位
Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
... ... @@ -690,6 +692,9 @@ type SystemUserAccountEnableResponse struct {
type SystemUserAccountUpdateRequest struct {
Id int64 `path:"id"`
Name string `json:"name"` // 姓名
Roles []int64 `json:"roles"` // 权限角色
Status int `json:"enable"` // 状态 1:启用 2:禁用
}
type SystemUserAccountUpdateResponse struct {
... ... @@ -865,7 +870,7 @@ type WhichUserLikeArticle struct {
type MiniSetUserLikeRequset struct {
ArticleId int64 `json:"articleId"` //文章id
CommentId int64 `json:"commentId"` //评论id
CommentId int64 `json:"commentId,optional"` //评论id
UserId int64 `json:",optional"` //操作人
Flag int `json:"flag"` //点赞标志 1、点赞 2 、取消点赞
}
... ... @@ -1220,7 +1225,7 @@ type MiniSearchArticleItem struct {
ArticleId int64 `json:"articleId"`
Title string `json:"title"`
Author string `json:"author"` // 发布人
Avatar string `json:"avatar"`
Avatar string `json:"avatar"` // 发布人的头像
Images []string `json:"images"`
CreatedAt int64 `json:"createdAt"`
MeReadFlag int `json:"meReadFlag"` //已读标识 [0:未读] [1:已读]
... ... @@ -1270,7 +1275,7 @@ type RoleSearchResponse struct {
type RoleItem struct {
Id int64 `json:"id,optional"` // 角色ID
CompanyId int64 `json:"companyId,optional,omitempty"` // 公司ID
CompanyId int64 `json:"companyId,optional,string,omitempty"` // 公司ID
Name string `json:"name"` // 角色名称
AuthIds []int64 `json:"authIds,optional,omitempty"` // 角色权限列表
AuthsDesc string `json:"authsDesc,optional,omitempty"` // 权限列表描述
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: user_role/v1
group: user_role
jwt: JwtAuth
)
service Core {
@handler getUserRole
post /user_role/:id (UserRoleGetRequest) returns (UserRoleGetResponse)
@handler saveUserRole
post /user_role (UserRoleSaveRequest) returns (UserRoleSaveResponse)
@handler deleteUserRole
delete /user_role/:id (UserRoleDeleteRequest) returns (UserRoleDeleteResponse)
@handler updateUserRole
put /user_role/:id (UserRoleUpdateRequest) returns (UserRoleUpdateResponse)
@handler searchUserRole
post /user_role/search (UserRoleSearchRequest) returns (UserRoleSearchResponse)
}
type (
UserRoleGetRequest {
Id int64 `path:"id"`
}
UserRoleGetResponse struct{
UserRole UserRoleItem `json:"user_role"`
}
UserRoleSaveRequest struct{
UserRole UserRoleItem `json:"user_role"`
}
UserRoleSaveResponse struct{}
UserRoleDeleteRequest struct{
Id int64 `path:"id"`
}
UserRoleDeleteResponse struct{}
UserRoleUpdateRequest struct{
Id int64 `path:"id"`
UserRole UserRoleItem `json:"user_role"`
}
UserRoleUpdateResponse struct{}
UserRoleSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
UserRoleSearchResponse{
List []UserRoleItem `json:"list"`
Total int64 `json:"total"`
}
UserRoleItem struct{
}
)
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message UserRoleGetReq {
int64 Id = 1;
}
message UserRoleGetResp{
UserRoleItem User = 1;
}
message UserRoleSaveReq {
}
message UserRoleSaveResp{
}
message UserRoleDeleteReq {
int64 Id = 1;
}
message UserRoleDeleteResp{
}
message UserRoleUpdateReq {
int64 Id = 1;
}
message UserRoleUpdateResp{
}
message UserRoleSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message UserRoleSearchResp{
repeated UserRoleItem List =1;
int64 Total =2;
}
message UserRoleItem {
}
service UserRoleService {
rpc UserRoleGet(UserRoleGetReq) returns(UserRoleGetResp);
rpc UserRoleSave(UserRoleSaveReq) returns(UserRoleSaveResp);
rpc UserRoleDelete(UserRoleDeleteReq) returns(UserRoleDeleteResp);
rpc UserRoleUpdate(UserRoleUpdateReq) returns(UserRoleUpdateResp);
rpc UserRoleSearch(UserRoleSearchReq) returns(UserRoleSearchResp);
}
... ...
... ... @@ -16,6 +16,7 @@ func Migrate(db *gorm.DB) {
&models.UserLoveFlag{},
&models.UserReadArticle{},
&models.User{},
&models.UserRole{},
&models.Role{},
&models.Company{},
&models.UserFollow{},
... ...
package models
import (
"gorm.io/gorm"
)
type UserRole struct {
Id int64 // 唯一标识
CompanyId int64 // 公司ID
UserId int64
RoleId int64
CreatedAt int64
UpdatedAt int64
DeletedAt int64
Version int
}
func (m *UserRole) TableName() string {
return "user_role"
}
func (m *UserRole) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserRole) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserRole) CacheKeyFunc() string {
return ""
}
func (m *UserRole) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*UserRole); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *UserRole) CachePrimaryKeyFunc() string {
return ""
}
... ...
... ... @@ -242,6 +242,39 @@ func (repository *UserRepository) FindDepartmentUsers(ctx context.Context, conn
return total, dms, nil
}
func (repository *UserRepository) FindByCompanyRoles(ctx context.Context, conn transaction.Conn, companyId int64, roles []int64, queryOptions map[string]interface{}) (int64, []*domain.User, error) {
var (
tx = conn.DB()
ms []*models.User
dms = make([]*domain.User, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id asc")
tx.Select("id", "name", "roles")
tx.Where("company_id = ?", companyId)
tx.Where("flag = ?", domain.UserAdmin)
tx.Where("id in (select user_id from user_role where role_id in(?)) ", roles)
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserRepository) FindCompanyPositions(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*domain.User, error) {
var (
tx = conn.DB()
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type UserRoleRepository struct {
*cache.CachedRepository
}
func (repository *UserRoleRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m = &models.UserRole{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m *models.UserRole
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m *models.UserRole
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
tx = conn.DB()
m = &models.UserRole{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) DeleteByUser(ctx context.Context, conn transaction.Conn, userId int64) error {
var (
tx = conn.DB()
m = &models.UserRole{}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("user_id = ?", userId).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return err
}
return nil
}
func (repository *UserRoleRepository) DeleteRole(ctx context.Context, conn transaction.Conn, roleId int64) error {
var (
tx = conn.DB()
m = &models.UserRole{}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("role_id = ?", roleId).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return err
}
return nil
}
func (repository *UserRoleRepository) DeleteByUserAndRole(ctx context.Context, conn transaction.Conn, userId int64, roleId int64) error {
var (
tx = conn.DB()
m = &models.UserRole{}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("user_id = ?", userId).Where("role_id = ?", roleId).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return err
}
return nil
}
func (repository *UserRoleRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserRole, error) {
var (
err error
tx = conn.DB()
m = new(models.UserRole)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserRole)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserRole, error) {
var (
tx = conn.DB()
ms []*models.UserRole
dms = make([]*domain.UserRole, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if v, ok := queryOptions["companyId"]; ok {
tx.Where("company_id = ?", v)
}
if v, ok := queryOptions["roleId"]; ok {
tx.Where("role_id = ?", v)
}
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserRoleRepository) ModelToDomainModel(from *models.UserRole) (*domain.UserRole, error) {
to := &domain.UserRole{}
err := copier.Copy(to, from)
return to, err
}
func (repository *UserRoleRepository) DomainModelToModel(from *domain.UserRole) (*models.UserRole, error) {
to := &models.UserRole{}
err := copier.Copy(to, from)
return to, err
}
func NewUserRoleRepository(cache *cache.CachedRepository) domain.UserRoleRepository {
return &UserRoleRepository{CachedRepository: cache}
}
... ...
... ... @@ -11,7 +11,7 @@ type Role struct {
Name string `json:"name"` // 角色名称
Auths []int64 `json:"auths"` // 角色权限列表
Remark string `json:"remark"` // 备注
Users []User `json:"users"` // 绑定的用户
//Users []User `json:"users"` // (废弃)绑定的用户
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
... ...
... ... @@ -39,6 +39,7 @@ type UserRepository interface {
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*User, error)
FindOneByCompanyIdAndPhone(ctx context.Context, conn transaction.Conn, companyId int64, phone string, status []int) (*User, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*User, error)
FindByCompanyRoles(ctx context.Context, conn transaction.Conn, companyId int64, roles []int64, queryOptions map[string]interface{}) (int64, []*User, error)
FindDepartmentUsers(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*User, error)
FindCompanyPositions(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*User, error)
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type UserRole struct {
Id int64 // 唯一标识
CompanyId int64 // 公司ID
UserId int64
RoleId int64
CreatedAt int64
UpdatedAt int64
DeletedAt int64
Version int
}
type UserRoleRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
Update(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
Delete(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
DeleteByUser(ctx context.Context, conn transaction.Conn, userId int64) error
DeleteRole(ctx context.Context, conn transaction.Conn, roleId int64) error
DeleteByUserAndRole(ctx context.Context, conn transaction.Conn, userId int64, roleId int64) error
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserRole, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserRole, error)
}
func (m *UserRole) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
CREATE TABLE `comment` (
CREATE TABLE `department` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `department` (
CREATE TABLE `role` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `role` (
CREATE TABLE `user` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user` (
CREATE TABLE `user_role` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
... ...