优化
This commit is contained in:
@@ -39,15 +39,15 @@ func (s *AnnouncementService) Update(ctx context.Context, in AnnouncementInput)
|
||||
return s.uc.Update(ctx, announcementDO(in))
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Delete(ctx context.Context, id uint) error {
|
||||
func (s *AnnouncementService) Delete(ctx context.Context, id string) error {
|
||||
return s.uc.Delete(ctx, id)
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) DeleteByIDs(ctx context.Context, ids []uint) error {
|
||||
func (s *AnnouncementService) DeleteByIDs(ctx context.Context, ids []string) error {
|
||||
return s.uc.DeleteByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Find(ctx context.Context, id uint) (*dto.AnnouncementResponse, error) {
|
||||
func (s *AnnouncementService) Find(ctx context.Context, id string) (*dto.AnnouncementResponse, error) {
|
||||
item, err := s.uc.Find(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -71,7 +71,7 @@ func (s *APIService) Groups(ctx context.Context) ([]string, map[string]string, e
|
||||
return nil, nil, err
|
||||
}
|
||||
seen := make(map[string]bool)
|
||||
groups := make([]string, 0)
|
||||
var groups []string
|
||||
groupAPIMap := make(map[string]string)
|
||||
for _, item := range items {
|
||||
if !seen[item.APIGroup] {
|
||||
@@ -126,7 +126,10 @@ func (s *APIService) PolicyPathResponses(ctx context.Context, authorityID uint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]dto.PolicyPathRequest, 0, len(items))
|
||||
var out []dto.PolicyPathRequest
|
||||
if len(items) > 0 {
|
||||
out = make([]dto.PolicyPathRequest, 0, len(items))
|
||||
}
|
||||
for _, item := range items {
|
||||
out = append(out, dto.PolicyPathRequest{Path: item.Path, Method: item.Method})
|
||||
}
|
||||
|
||||
@@ -28,7 +28,11 @@ func authorityDomain(req *dto.AuthorityRequest) *biz.Authority {
|
||||
}
|
||||
|
||||
func authorityResponse(value *biz.Authority) *dto.AuthorityResponse {
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: []*dto.AuthorityResponse{}, Menus: []any{}, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
var menus []*dto.MenuResponse
|
||||
if value.Menus != nil {
|
||||
menus = menuResponses(value.Menus)
|
||||
}
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: nil, Menus: menus, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
|
||||
func (s *AuthorityService) Authorities(ctx context.Context) ([]*dto.AuthorityResponse, error) {
|
||||
@@ -56,7 +60,9 @@ func (s *AuthorityService) CopyAuthorityRequest(ctx context.Context, req *dto.Co
|
||||
if err := s.uc.CopyAuthority(ctx, req.OldAuthorityID, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
result := authorityResponse(value)
|
||||
result.Children = []*dto.AuthorityResponse{}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *AuthorityService) UpdateAuthorityRequest(ctx context.Context, req *dto.AuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
|
||||
@@ -14,9 +14,12 @@ func NewDepartmentService(uc *biz.DepartmentUsecase) *DepartmentService {
|
||||
}
|
||||
|
||||
func departmentResponse(value *biz.Department) *dto.DepartmentResponse {
|
||||
children := make([]*dto.DepartmentResponse, 0, len(value.Children))
|
||||
for _, child := range value.Children {
|
||||
children = append(children, departmentResponse(child))
|
||||
var children []*dto.DepartmentResponse
|
||||
if value.Children != nil {
|
||||
children = make([]*dto.DepartmentResponse, 0, len(value.Children))
|
||||
for _, child := range value.Children {
|
||||
children = append(children, departmentResponse(child))
|
||||
}
|
||||
}
|
||||
var leader any
|
||||
if value.Leader != nil {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
func TestDepartmentResponsePreservesNilAndEmptyChildren(t *testing.T) {
|
||||
if got := departmentResponse(&biz.Department{}).Children; got != nil {
|
||||
t.Fatalf("single/search department children = %#v, want nil", got)
|
||||
}
|
||||
if got := departmentResponse(&biz.Department{Children: []*biz.Department{}}).Children; got == nil || len(got) != 0 {
|
||||
t.Fatalf("tree leaf children = %#v, want empty slice", got)
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func (s *DictionaryService) ExportDictionary(ctx context.Context, id uint) (*dto
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
details := make([]*dto.DictionaryDetailExportResponse, 0, len(v.Details))
|
||||
var details []*dto.DictionaryDetailExportResponse
|
||||
for _, detail := range v.Details {
|
||||
details = append(details, &dto.DictionaryDetailExportResponse{
|
||||
Label: detail.Label, Value: detail.Value, Extend: detail.Extend,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type dictionaryExportRepo struct {
|
||||
biz.DictionaryRepo
|
||||
value *biz.Dictionary
|
||||
}
|
||||
|
||||
func (r dictionaryExportRepo) ExportDictionary(context.Context, uint) (*biz.Dictionary, error) {
|
||||
return r.value, nil
|
||||
}
|
||||
|
||||
func TestExportDictionaryPreservesNilDetails(t *testing.T) {
|
||||
service := NewDictionaryService(biz.NewDictionaryUsecase(dictionaryExportRepo{value: &biz.Dictionary{Name: "empty", Type: "empty"}}))
|
||||
result, err := service.ExportDictionary(context.Background(), 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if result.SysDictionaryDetails != nil {
|
||||
t.Fatalf("export details = %#v, want nil", result.SysDictionaryDetails)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func bindErrorMutation(t *testing.T, body string) (ErrorRecordMutationRequest, error) {
|
||||
t.Helper()
|
||||
context, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
context.Request = httptest.NewRequest("PUT", "/sysError/updateSysError", strings.NewReader(body))
|
||||
context.Request.Header.Set("Content-Type", "application/json")
|
||||
var request ErrorRecordMutationRequest
|
||||
return request, context.ShouldBindJSON(&request)
|
||||
}
|
||||
|
||||
func TestErrorRecordMutationAcceptsExplicitEmptyPointerFields(t *testing.T) {
|
||||
request, err := bindErrorMutation(t, `{"ID":1,"form":"","info":"","solution":""}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if request.Form == nil || *request.Form != "" || request.Info == nil || *request.Info != "" || request.Solution == nil || *request.Solution != "" {
|
||||
t.Fatalf("explicit empty values lost: form=%#v info=%#v solution=%#v", request.Form, request.Info, request.Solution)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorRecordMutationRequiresFormButKeepsOtherFieldsOmittable(t *testing.T) {
|
||||
request, err := bindErrorMutation(t, `{"ID":1}`)
|
||||
if err == nil {
|
||||
t.Fatal("missing form unexpectedly accepted")
|
||||
}
|
||||
if request.Info != nil || request.Solution != nil {
|
||||
t.Fatalf("omitted fields = (%#v, %#v), want nil", request.Info, request.Solution)
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,12 @@ type DeleteAuthorityRequest struct {
|
||||
}
|
||||
type SetRoleUsersRequest struct {
|
||||
AuthorityID uint `json:"authorityId" form:"authorityId"`
|
||||
UserIDs []uint `json:"userIds"`
|
||||
UserIDs []uint `json:"userIds" form:"userIds"`
|
||||
}
|
||||
type SetDataScopeRequest struct {
|
||||
AuthorityID uint `json:"authorityId" form:"authorityId"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DepartmentIDs []uint `json:"deptIds"`
|
||||
DataScope int `json:"dataScope" form:"dataScope"`
|
||||
DepartmentIDs []uint `json:"deptIds" form:"deptIds"`
|
||||
}
|
||||
|
||||
type AuthorityResponse struct {
|
||||
@@ -36,7 +36,7 @@ type AuthorityResponse struct {
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentID *uint `json:"parentId"`
|
||||
Children []*AuthorityResponse `json:"children"`
|
||||
Menus []any `json:"menus"`
|
||||
Menus []*MenuResponse `json:"menus"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ type IDRequest struct {
|
||||
type IDsRequest struct {
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
type MediaBatchDeleteRequest struct {
|
||||
IDs []uint `json:"ids" binding:"required"`
|
||||
}
|
||||
type RenameMediaRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -13,19 +13,27 @@ type MenuMetaRequest struct {
|
||||
}
|
||||
|
||||
type MenuButtonRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
SysBaseMenuID uint `json:"sysBaseMenuID"`
|
||||
}
|
||||
|
||||
type MenuParameterRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
SysBaseMenuID uint `json:"SysBaseMenuID"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type MenuRequest struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
@@ -39,20 +47,16 @@ type MenuRequest struct {
|
||||
}
|
||||
|
||||
type DeleteMenuRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
type GetMenuRequest struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
type AuthorityMenuItemRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
type SetAuthorityMenusRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Menus []AuthorityMenuItemRequest `json:"menus"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Menus []MenuRequest `json:"menus"`
|
||||
}
|
||||
|
||||
type GetAuthorityMenusRequest struct {
|
||||
@@ -108,14 +112,32 @@ type MenuResponse struct {
|
||||
Children []*MenuResponse `json:"children"`
|
||||
Parameters []MenuParameterResponse `json:"parameters"`
|
||||
MenuButtons []MenuButtonResponse `json:"menuBtn"`
|
||||
Authorities []*AuthorityResponse `json:"authoritys"`
|
||||
}
|
||||
|
||||
type DynamicMenuResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
MenuID uint `json:"menuId"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta MenuMetaResponse `json:"meta"`
|
||||
Children []*DynamicMenuResponse `json:"children"`
|
||||
Parameters []MenuParameterResponse `json:"parameters"`
|
||||
MenuButtons []MenuButtonResponse `json:"menuBtn"`
|
||||
Buttons map[string]uint `json:"btns"`
|
||||
Authorities []*AuthorityResponse `json:"authoritys"`
|
||||
}
|
||||
|
||||
type AuthorityMenuResponse struct {
|
||||
// The administration response embeds the base-menu fields, so menu fields are
|
||||
// flat in the response (there is no sysBaseMenu envelope). Keep the
|
||||
// authority ID internal, matching the compatible json:"-" field.
|
||||
*MenuResponse
|
||||
MenuID uint `json:"menuId"`
|
||||
*DynamicMenuResponse
|
||||
AuthorityID uint `json:"-"`
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package dto
|
||||
|
||||
type GetAuthorityButtonsRequest struct {
|
||||
MenuID uint `json:"menuID"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
MenuID uint `json:"menuID"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Selected []uint `json:"selected"`
|
||||
}
|
||||
|
||||
type SetAuthorityButtonsRequest struct {
|
||||
|
||||
@@ -31,11 +31,13 @@ type DictionaryDetailsByParentRequest struct {
|
||||
IncludeChildren bool `json:"includeChildren" form:"includeChildren"`
|
||||
}
|
||||
type SystemParameterRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
Key string `json:"key" form:"key" binding:"required"`
|
||||
Value string `json:"value" form:"value" binding:"required"`
|
||||
Description string `json:"desc" form:"desc"`
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt" form:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt" form:"UpdatedAt"`
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
Key string `json:"key" form:"key" binding:"required"`
|
||||
Value string `json:"value" form:"value" binding:"required"`
|
||||
Description string `json:"desc" form:"desc"`
|
||||
}
|
||||
|
||||
type SystemParameterSearchRequest struct {
|
||||
|
||||
@@ -75,25 +75,26 @@ type LoginLogRequest struct {
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"userName"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Authority *AuthorityResponse `json:"authority"`
|
||||
Authorities []*AuthorityResponse `json:"authorities"`
|
||||
DeptID uint `json:"deptId"`
|
||||
Department any `json:"dept"`
|
||||
Departments []*DepartmentResponse `json:"departments"`
|
||||
Positions []*PositionResponse `json:"positions"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
OriginSetting map[string]any `json:"originSetting"`
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"userName"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Authority *AuthorityResponse `json:"authority"`
|
||||
Authorities []*AuthorityResponse `json:"authorities"`
|
||||
DeptID uint `json:"deptId"`
|
||||
Department any `json:"dept"`
|
||||
Departments []*DepartmentResponse `json:"departments"`
|
||||
Positions []*PositionResponse `json:"positions"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
OriginSetting map[string]any `json:"originSetting"`
|
||||
PasswordUpdatedAt *time.Time `json:"passwordUpdatedAt"`
|
||||
}
|
||||
|
||||
type ServerInfoResponse struct {
|
||||
|
||||
@@ -7,10 +7,10 @@ type VersionResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
VersionName string `json:"versionName"`
|
||||
VersionCode string `json:"versionCode"`
|
||||
Description string `json:"description"`
|
||||
VersionData string `json:"versionData"`
|
||||
VersionName *string `json:"versionName"`
|
||||
VersionCode *string `json:"versionCode"`
|
||||
Description *string `json:"description"`
|
||||
VersionData *string `json:"versionData"`
|
||||
}
|
||||
|
||||
type VersionSearchRequest struct {
|
||||
|
||||
+64
-19
@@ -56,9 +56,10 @@ func (s *MenuService) AuthorityMenus(ctx context.Context, authorityID uint) ([]*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]*dto.AuthorityMenuResponse, 0, len(items))
|
||||
var out []*dto.AuthorityMenuResponse
|
||||
for _, item := range items {
|
||||
out = append(out, &dto.AuthorityMenuResponse{MenuResponse: menuResponse(item), MenuID: item.ID, AuthorityID: authorityID})
|
||||
item.MenuID = item.ID
|
||||
out = append(out, &dto.AuthorityMenuResponse{DynamicMenuResponse: dynamicMenuResponse(item), AuthorityID: authorityID})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -74,42 +75,86 @@ func (s *MenuService) SetRoles(ctx context.Context, req *dto.SetMenuRolesRequest
|
||||
}
|
||||
|
||||
func menuDomain(v *dto.MenuRequest) *biz.Menu {
|
||||
menu := &biz.Menu{ID: v.ID, ParentID: v.ParentID, Path: v.Path, Name: v.Name, Hidden: v.Hidden, Component: v.Component, Sort: v.Sort, ActiveName: v.Meta.ActiveName, KeepAlive: v.Meta.KeepAlive, DefaultMenu: v.Meta.DefaultMenu, Title: v.Meta.Title, Icon: v.Meta.Icon, CloseTab: v.Meta.CloseTab, TransitionType: v.Meta.TransitionType}
|
||||
menu := &biz.Menu{CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, ID: v.ID, ParentID: v.ParentID, Path: v.Path, Name: v.Name, Hidden: v.Hidden, Component: v.Component, Sort: v.Sort, ActiveName: v.Meta.ActiveName, KeepAlive: v.Meta.KeepAlive, DefaultMenu: v.Meta.DefaultMenu, Title: v.Meta.Title, Icon: v.Meta.Icon, CloseTab: v.Meta.CloseTab, TransitionType: v.Meta.TransitionType}
|
||||
menu.Buttons = make([]*biz.MenuButton, 0, len(v.MenuButtons))
|
||||
for _, button := range v.MenuButtons {
|
||||
menu.Buttons = append(menu.Buttons, &biz.MenuButton{ID: button.ID, Name: button.Name, Description: button.Description, MenuID: v.ID})
|
||||
menu.Buttons = append(menu.Buttons, &biz.MenuButton{CreatedAt: button.CreatedAt, UpdatedAt: button.UpdatedAt, ID: button.ID, Name: button.Name, Description: button.Description, MenuID: v.ID})
|
||||
}
|
||||
menu.Parameters = make([]*biz.MenuParameter, 0, len(v.Parameters))
|
||||
for _, parameter := range v.Parameters {
|
||||
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{ID: parameter.ID, MenuID: v.ID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, MenuID: v.ID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
return menu
|
||||
}
|
||||
|
||||
func menuResponse(menu *biz.Menu) *dto.MenuResponse {
|
||||
children := make([]*dto.MenuResponse, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, menuResponse(child))
|
||||
}
|
||||
buttons := make([]dto.MenuButtonResponse, 0, len(menu.Buttons))
|
||||
buttonAuthorities := make(map[string]uint, len(menu.Buttons))
|
||||
for _, button := range menu.Buttons {
|
||||
buttons = append(buttons, dto.MenuButtonResponse{CreatedAt: button.CreatedAt, UpdatedAt: button.UpdatedAt, ID: button.ID, Name: button.Name, Description: button.Description, SysBaseMenuID: button.MenuID})
|
||||
if button.AuthorityID != 0 {
|
||||
buttonAuthorities[button.Name] = button.AuthorityID
|
||||
var children []*dto.MenuResponse
|
||||
if menu.Children != nil {
|
||||
children = make([]*dto.MenuResponse, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, menuResponse(child))
|
||||
}
|
||||
}
|
||||
parameters := make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, dto.MenuParameterResponse{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
var buttons []dto.MenuButtonResponse
|
||||
if menu.Buttons != nil {
|
||||
buttons = make([]dto.MenuButtonResponse, 0, len(menu.Buttons))
|
||||
for _, button := range menu.Buttons {
|
||||
buttons = append(buttons, dto.MenuButtonResponse{CreatedAt: button.CreatedAt, UpdatedAt: button.UpdatedAt, ID: button.ID, Name: button.Name, Description: button.Description, SysBaseMenuID: button.MenuID})
|
||||
}
|
||||
}
|
||||
return &dto.MenuResponse{CreatedAt: menu.CreatedAt, UpdatedAt: menu.UpdatedAt, ID: menu.ID, MenuID: menu.MenuID, ParentID: menu.ParentID, Path: menu.Path, Name: menu.Name, Hidden: menu.Hidden, Component: menu.Component, Sort: menu.Sort, Meta: dto.MenuMetaResponse{ActiveName: menu.ActiveName, KeepAlive: menu.KeepAlive, DefaultMenu: menu.DefaultMenu, Title: menu.Title, Icon: menu.Icon, CloseTab: menu.CloseTab, TransitionType: menu.TransitionType}, Children: children, Parameters: parameters, MenuButtons: buttons, Buttons: buttonAuthorities}
|
||||
var parameters []dto.MenuParameterResponse
|
||||
if menu.Parameters != nil {
|
||||
parameters = make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, dto.MenuParameterResponse{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
}
|
||||
return &dto.MenuResponse{CreatedAt: menu.CreatedAt, UpdatedAt: menu.UpdatedAt, ID: menu.ID, MenuID: menu.MenuID, ParentID: menu.ParentID, Path: menu.Path, Name: menu.Name, Hidden: menu.Hidden, Component: menu.Component, Sort: menu.Sort, Meta: dto.MenuMetaResponse{ActiveName: menu.ActiveName, KeepAlive: menu.KeepAlive, DefaultMenu: menu.DefaultMenu, Title: menu.Title, Icon: menu.Icon, CloseTab: menu.CloseTab, TransitionType: menu.TransitionType}, Children: children, Parameters: parameters, MenuButtons: buttons}
|
||||
}
|
||||
|
||||
func dynamicMenuResponse(menu *biz.Menu) *dto.DynamicMenuResponse {
|
||||
var children []*dto.DynamicMenuResponse
|
||||
if menu.Children != nil {
|
||||
children = make([]*dto.DynamicMenuResponse, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, dynamicMenuResponse(child))
|
||||
}
|
||||
}
|
||||
var parameters []dto.MenuParameterResponse
|
||||
if menu.Parameters != nil {
|
||||
parameters = make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, dto.MenuParameterResponse{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
}
|
||||
var buttonAuthorities map[string]uint
|
||||
for _, button := range menu.Buttons {
|
||||
if button.AuthorityID == 0 {
|
||||
continue
|
||||
}
|
||||
if buttonAuthorities == nil {
|
||||
buttonAuthorities = make(map[string]uint)
|
||||
}
|
||||
buttonAuthorities[button.Name] = button.AuthorityID
|
||||
}
|
||||
return &dto.DynamicMenuResponse{CreatedAt: menu.CreatedAt, UpdatedAt: menu.UpdatedAt, ID: menu.ID, MenuID: menu.MenuID, ParentID: menu.ParentID, Path: menu.Path, Name: menu.Name, Hidden: menu.Hidden, Component: menu.Component, Sort: menu.Sort, Meta: dto.MenuMetaResponse{ActiveName: menu.ActiveName, KeepAlive: menu.KeepAlive, DefaultMenu: menu.DefaultMenu, Title: menu.Title, Icon: menu.Icon, CloseTab: menu.CloseTab, TransitionType: menu.TransitionType}, Children: children, Parameters: parameters, MenuButtons: nil, Buttons: buttonAuthorities}
|
||||
}
|
||||
|
||||
func menuResponses(items []*biz.Menu) []*dto.MenuResponse {
|
||||
if items == nil {
|
||||
return nil
|
||||
}
|
||||
out := make([]*dto.MenuResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, menuResponse(item))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func dynamicMenuResponses(items []*biz.Menu) []*dto.DynamicMenuResponse {
|
||||
out := make([]*dto.DynamicMenuResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, dynamicMenuResponse(item))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func TestMenuDomainPreservesRelationIdentity(t *testing.T) {
|
||||
createdAt := time.Date(2025, time.March, 4, 5, 6, 7, 0, time.UTC)
|
||||
updatedAt := time.Date(2025, time.April, 5, 6, 7, 8, 0, time.UTC)
|
||||
menu := menuDomain(&dto.MenuRequest{
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
ID: 10,
|
||||
MenuButtons: []dto.MenuButtonRequest{{
|
||||
CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 31, Name: "edit", Description: "编辑",
|
||||
}},
|
||||
Parameters: []dto.MenuParameterRequest{{
|
||||
CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 21, Type: "query", Key: "id", Value: "1",
|
||||
}},
|
||||
})
|
||||
if !menu.CreatedAt.Equal(createdAt) || !menu.UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("menu timestamps = (%v, %v), want (%v, %v)", menu.CreatedAt, menu.UpdatedAt, createdAt, updatedAt)
|
||||
}
|
||||
if len(menu.Buttons) != 1 || menu.Buttons[0].ID != 31 || menu.Buttons[0].MenuID != 10 || !menu.Buttons[0].CreatedAt.Equal(createdAt) || !menu.Buttons[0].UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("button conversion = %+v", menu.Buttons)
|
||||
}
|
||||
if len(menu.Parameters) != 1 || menu.Parameters[0].ID != 21 || menu.Parameters[0].MenuID != 10 || !menu.Parameters[0].CreatedAt.Equal(createdAt) || !menu.Parameters[0].UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("parameter conversion = %+v", menu.Parameters)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMenuResponseEmptyCollectionContracts(t *testing.T) {
|
||||
if got := menuResponses(nil); got != nil {
|
||||
t.Fatalf("base menu top-level nil = %#v, want nil", got)
|
||||
}
|
||||
if got := dynamicMenuResponses(nil); got == nil || len(got) != 0 {
|
||||
t.Fatalf("dynamic menu top-level empty = %#v, want non-nil empty slice", got)
|
||||
}
|
||||
|
||||
base := menuResponse(&biz.Menu{Children: nil, Buttons: []*biz.MenuButton{}, Parameters: []*biz.MenuParameter{}})
|
||||
if base.Children != nil {
|
||||
t.Fatalf("leaf children = %#v, want nil", base.Children)
|
||||
}
|
||||
if base.MenuButtons == nil || base.Parameters == nil {
|
||||
t.Fatalf("preloaded empty relations = (%#v, %#v), want empty slices", base.MenuButtons, base.Parameters)
|
||||
}
|
||||
encoded, err := json.Marshal(base)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(encoded, &payload); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if value, ok := payload["authoritys"]; !ok || value != nil {
|
||||
t.Fatalf("authoritys JSON = %#v (present=%v), want explicit null", value, ok)
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ func NewParameterService(uc *biz.ParameterUsecase) *ParameterService {
|
||||
}
|
||||
|
||||
func parameterDomain(value *dto.SystemParameterRequest) *biz.SystemParameter {
|
||||
return &biz.SystemParameter{ID: value.ID, Name: value.Name, Key: value.Key, Value: value.Value, Desc: value.Description}
|
||||
return &biz.SystemParameter{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, Name: value.Name, Key: value.Key, Value: value.Value, Desc: value.Description}
|
||||
}
|
||||
func (s *ParameterService) CreateParameterRequest(ctx context.Context, req *dto.SystemParameterRequest) error {
|
||||
return s.CreateParameter(ctx, parameterDomain(req))
|
||||
@@ -40,8 +40,15 @@ func (s *ParameterService) Parameters(ctx context.Context, page, size int, q *bi
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *ParameterService) Parameter(ctx context.Context, id uint, key string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameter(ctx, id, key)
|
||||
func (s *ParameterService) ParameterByID(ctx context.Context, id string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameterByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parameterDTO(v), nil
|
||||
}
|
||||
func (s *ParameterService) ParameterByKey(ctx context.Context, key string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameterByKey(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -53,6 +60,6 @@ func (s *ParameterService) CreateParameter(ctx context.Context, v *biz.SystemPar
|
||||
func (s *ParameterService) UpdateParameter(ctx context.Context, v *biz.SystemParameter) error {
|
||||
return s.uc.UpdateParameter(ctx, v)
|
||||
}
|
||||
func (s *ParameterService) DeleteParameters(ctx context.Context, ids []uint) error {
|
||||
func (s *ParameterService) DeleteParameters(ctx context.Context, ids []string) error {
|
||||
return s.uc.DeleteParameters(ctx, ids)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@ func (s *PermissionService) SetSelectedButtons(ctx context.Context, authorityID,
|
||||
return s.uc.SetSelectedButtons(ctx, authorityID, menuID, ids)
|
||||
}
|
||||
|
||||
func (s *PermissionService) CanRemoveButton(ctx context.Context, id uint) (bool, error) {
|
||||
func (s *PermissionService) CanRemoveButton(ctx context.Context, id string) (bool, error) {
|
||||
return s.uc.CanRemoveButton(ctx, id)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func (s *SecurityService) CurrentSecurity(ctx context.Context) (*biz.SecurityCon
|
||||
return s.uc.Current(ctx)
|
||||
}
|
||||
func (s *SecurityService) Security(ctx context.Context) (*dto.SecurityConfigResponse, error) {
|
||||
value, err := s.CurrentSecurity(ctx)
|
||||
value, err := s.uc.Security(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -45,12 +45,20 @@ func (s *UserService) User(ctx context.Context, id uint) (*dto.UserResponse, err
|
||||
return convertUser(value), nil
|
||||
}
|
||||
|
||||
func (s *UserService) Menus(ctx context.Context, authorityID uint) ([]*dto.MenuResponse, error) {
|
||||
func (s *UserService) UserByUUID(ctx context.Context, uuid string) (*dto.UserResponse, error) {
|
||||
value, err := s.uc.UserByUUID(ctx, uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertUser(value), nil
|
||||
}
|
||||
|
||||
func (s *UserService) Menus(ctx context.Context, authorityID uint) ([]*dto.DynamicMenuResponse, error) {
|
||||
menus, err := s.uc.Menus(ctx, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menuResponses(menus), nil
|
||||
return dynamicMenuResponses(menus), nil
|
||||
}
|
||||
|
||||
func (s *UserService) ListUsers(ctx context.Context, page, pageSize int, filter *biz.UserListFilter) ([]*dto.UserResponse, int64, error) {
|
||||
|
||||
@@ -6,24 +6,39 @@ import (
|
||||
)
|
||||
|
||||
func convertAuthority(value biz.Authority) *dto.AuthorityResponse {
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: []*dto.AuthorityResponse{}, Menus: []any{}, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
var menus []*dto.MenuResponse
|
||||
if value.Menus != nil {
|
||||
menus = menuResponses(value.Menus)
|
||||
}
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: nil, Menus: menus, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
func convertUser(user *biz.User) *dto.UserResponse {
|
||||
authorities := make([]*dto.AuthorityResponse, 0, len(user.Authorities))
|
||||
for _, value := range user.Authorities {
|
||||
authorities = append(authorities, convertAuthority(value))
|
||||
var authorities []*dto.AuthorityResponse
|
||||
if user.Authorities != nil {
|
||||
authorities = make([]*dto.AuthorityResponse, 0, len(user.Authorities))
|
||||
for _, value := range user.Authorities {
|
||||
authorities = append(authorities, convertAuthority(value))
|
||||
}
|
||||
}
|
||||
departments := make([]*dto.DepartmentResponse, 0, len(user.Departments))
|
||||
for i := range user.Departments {
|
||||
departments = append(departments, departmentResponse(&user.Departments[i]))
|
||||
var departments []*dto.DepartmentResponse
|
||||
if user.Departments != nil {
|
||||
departments = make([]*dto.DepartmentResponse, 0, len(user.Departments))
|
||||
for i := range user.Departments {
|
||||
departments = append(departments, departmentResponse(&user.Departments[i]))
|
||||
}
|
||||
}
|
||||
positions := make([]*dto.PositionResponse, 0, len(user.Positions))
|
||||
for i := range user.Positions {
|
||||
positions = append(positions, positionResponse(&user.Positions[i]))
|
||||
var positions []*dto.PositionResponse
|
||||
if user.Positions != nil {
|
||||
positions = make([]*dto.PositionResponse, 0, len(user.Positions))
|
||||
for i := range user.Positions {
|
||||
positions = append(positions, positionResponse(&user.Positions[i]))
|
||||
}
|
||||
}
|
||||
var department any = map[string]any{}
|
||||
// The primary department is represented by a zero-value object when it is
|
||||
// absent, preserving the response shape expected by the administration UI.
|
||||
var department any = dto.DepartmentResponse{}
|
||||
if user.Department != nil {
|
||||
department = departmentResponse(user.Department)
|
||||
}
|
||||
return &dto.UserResponse{ID: user.ID, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, DeletedAt: nil, UUID: user.UUID, Username: user.Username, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Authority: convertAuthority(user.Authority), Authorities: authorities, DeptID: user.DeptID, Department: department, Departments: departments, Positions: positions, Phone: user.Phone, Email: user.Email, Enable: user.Enable, OriginSetting: user.OriginSetting}
|
||||
return &dto.UserResponse{ID: user.ID, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, DeletedAt: nil, UUID: user.UUID, Username: user.Username, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Authority: convertAuthority(user.Authority), Authorities: authorities, DeptID: user.DeptID, Department: department, Departments: departments, Positions: positions, Phone: user.Phone, Email: user.Email, Enable: user.Enable, OriginSetting: user.OriginSetting, PasswordUpdatedAt: user.PasswordUpdatedAt}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,15 @@ func exportMenu(value *biz.Menu) *versionExportMenu {
|
||||
func versionDTO(v *biz.Version) *dto.VersionResponse {
|
||||
return &dto.VersionResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, VersionName: v.Name, VersionCode: v.Code, Description: v.Description, VersionData: v.Data}
|
||||
}
|
||||
|
||||
func versionValue(value *string) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
return *value
|
||||
}
|
||||
|
||||
func versionPointer(value string) *string { return &value }
|
||||
func (s *VersionService) Versions(ctx context.Context, page, size int, name, code string, createdAtRange []*time.Time) ([]*dto.VersionResponse, int64, error) {
|
||||
items, total, err := s.uc.ListVersions(ctx, page, size, name, code, createdAtRange)
|
||||
if err != nil {
|
||||
@@ -155,11 +164,11 @@ func (s *VersionService) VersionData(ctx context.Context, id uint) (string, stri
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if v.Data != "" {
|
||||
return v.Data, v.Code, nil
|
||||
if v.Data != nil && *v.Data != "" {
|
||||
return *v.Data, versionValue(v.Code), nil
|
||||
}
|
||||
payload := versionExportDocument{
|
||||
Version: versionExportInfo{Name: v.Name, Code: v.Code, Description: v.Description, ExportTime: v.CreatedAt.Format("2006-01-02 15:04:05")},
|
||||
Version: versionExportInfo{Name: versionValue(v.Name), Code: versionValue(v.Code), Description: versionValue(v.Description), ExportTime: v.CreatedAt.Format("2006-01-02 15:04:05")},
|
||||
Menus: []*versionExportMenu{},
|
||||
APIs: []versionExportAPI{},
|
||||
}
|
||||
@@ -167,7 +176,7 @@ func (s *VersionService) VersionData(ctx context.Context, id uint) (string, stri
|
||||
if marshalErr != nil {
|
||||
return "", "", marshalErr
|
||||
}
|
||||
return string(raw), v.Code, nil
|
||||
return string(raw), versionValue(v.Code), nil
|
||||
}
|
||||
func (s *VersionService) DeleteVersions(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteVersions(ctx, ids)
|
||||
@@ -206,7 +215,7 @@ func (s *VersionService) Export(ctx context.Context, name, code, description str
|
||||
if err != nil {
|
||||
return &biz.VersionStageError{Stage: biz.VersionStageJSON, Err: err}
|
||||
}
|
||||
if err = s.uc.CreateVersion(ctx, &biz.Version{Name: name, Code: code, Description: description, Data: string(raw)}); err != nil {
|
||||
if err = s.uc.CreateVersion(ctx, &biz.Version{Name: versionPointer(name), Code: versionPointer(code), Description: versionPointer(description), Data: versionPointer(string(raw))}); err != nil {
|
||||
return &biz.VersionStageError{Stage: biz.VersionStageSave, Err: err}
|
||||
}
|
||||
return nil
|
||||
@@ -250,10 +259,10 @@ func (s *VersionService) ImportRequest(ctx context.Context, req *dto.ImportVersi
|
||||
}
|
||||
raw, _ := json.Marshal(req)
|
||||
_ = s.uc.CreateVersion(ctx, &biz.Version{
|
||||
Name: req.Version.Name,
|
||||
Code: req.Version.Code + "_imported_" + time.Now().Format("20060102150405"),
|
||||
Description: "导入版本: " + req.Version.Description,
|
||||
Data: string(raw),
|
||||
Name: versionPointer(req.Version.Name),
|
||||
Code: versionPointer(req.Version.Code + "_imported_" + time.Now().Format("20060102150405")),
|
||||
Description: versionPointer("导入版本: " + req.Version.Description),
|
||||
Data: versionPointer(string(raw)),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user