This commit is contained in:
2026-08-16 09:02:39 +08:00
parent c554152f4f
commit f7f6db8695
105 changed files with 2535 additions and 948 deletions
+1 -5
View File
@@ -24,11 +24,7 @@ func NewAnnouncementService(uc *biz.AnnouncementUsecase) *AnnouncementService {
}
func announcementDTO(item *biz.Announcement) *dto.AnnouncementResponse {
attachments := any([]any{})
if len(item.Attachments) > 0 {
_ = json.Unmarshal(item.Attachments, &attachments)
}
return &dto.AnnouncementResponse{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, DeletedAt: nil, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: attachments}
return &dto.AnnouncementResponse{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, DeletedAt: nil, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: json.RawMessage(item.Attachments)}
}
func announcementDO(in AnnouncementInput) *biz.Announcement {
+10 -10
View File
@@ -63,7 +63,10 @@ func (s *APIService) AllAPI(ctx context.Context, strict bool) ([]*dto.APIRespons
}
func (s *APIService) Groups(ctx context.Context) ([]string, map[string]string, error) {
items, err := s.AllAPI(ctx, false)
// The compatible group endpoint uses an unqualified Find, whose natural order is
// the primary-key ascending order. GetAllApis intentionally uses id DESC,
// so do not reuse it here or the group/dropdown order changes.
items, _, err := s.uc.ListAPIs(ctx, 0, 0, &biz.API{OrderKey: "id"})
if err != nil {
return nil, nil, err
}
@@ -133,15 +136,9 @@ func (s *APIService) SyncAPIResponses(ctx context.Context, routes []dto.APIReque
items := make([]*biz.API, 0, len(routes))
for i := range routes {
routes[i].Path = s.NormalizeRoutePath(routes[i].Path)
if routes[i].APIGroup == "" || routes[i].Description == "" {
group, description := routeMetadata(routes[i].Method, routes[i].Path)
if routes[i].APIGroup == "" {
routes[i].APIGroup = group
}
if routes[i].Description == "" {
routes[i].Description = description
}
}
// The compatible sync endpoint compares Gin's route table directly, so newly
// discovered routes carry only path and method. Group/description are
// intentionally left empty for the operator to fill in the sync dialog.
items = append(items, apiDomain(&routes[i]))
}
return s.SyncAPIs(ctx, items)
@@ -150,6 +147,9 @@ func (s *APIService) SyncAPIResponses(ctx context.Context, routes []dto.APIReque
func (s *APIService) DeleteAPIs(ctx context.Context, ids []uint) error {
return s.uc.DeleteAPIs(ctx, ids)
}
func (s *APIService) DeleteAPI(ctx context.Context, id uint) error {
return s.uc.DeleteAPI(ctx, id)
}
func (s *APIService) APIRoleIDs(ctx context.Context, path, method string) ([]uint, error) {
return s.uc.APIRoleIDs(ctx, path, method)
}
+4 -4
View File
@@ -29,7 +29,7 @@ func opDTO(v *biz.OperationRecord) *dto.OperationRecordResponse {
if v.User != nil {
user = convertUser(v.User)
}
return &dto.OperationRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, IP: v.IP, Method: v.Method, Path: v.Path, Status: v.Status, LatencyMS: v.LatencyMS, Agent: v.Agent, ErrorMessage: v.ErrorMessage, Body: v.Body, Response: v.Response, UserID: v.UserID, RequestID: v.RequestID, TraceID: v.TraceID, DeviceID: v.DeviceID, User: user}
return &dto.OperationRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, IP: v.IP, Method: v.Method, Path: v.Path, Status: v.Status, LatencyMS: v.LatencyMS, Agent: v.Agent, ErrorMessage: v.ErrorMessage, Body: v.Body, Response: v.Response, UserID: v.UserID, RequestID: v.RequestID, TraceID: v.TraceID, DeviceID: v.DeviceID, User: user}
}
func (s *AuditService) Operations(ctx context.Context, page, size int, q *biz.OperationRecord) ([]*dto.OperationRecordResponse, int64, error) {
items, total, err := s.uc.ListOperations(ctx, page, size, q)
@@ -67,7 +67,7 @@ func loginDTO(v *biz.LoginLog) *dto.LoginLogResponse {
if v.User != nil {
user = convertUser(v.User)
}
return &dto.LoginLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, Username: v.Username, IP: v.IP, Status: v.Status, ErrorMessage: v.ErrorMessage, Agent: v.Agent, UserID: v.UserID, User: user}
return &dto.LoginLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Username: v.Username, IP: v.IP, Status: v.Status, ErrorMessage: v.ErrorMessage, Agent: v.Agent, UserID: v.UserID, User: user}
}
func (s *AuditService) Logins(ctx context.Context, page, size int, q *biz.LoginLog) ([]*dto.LoginLogResponse, int64, error) {
items, total, err := s.uc.ListLogins(ctx, page, size, q)
@@ -98,10 +98,10 @@ func (s *AuditRecorder) RecordDataAccessRequest(ctx context.Context, value *dto.
return s.RecordDataAccess(ctx, &biz.DataAccessLog{EventType: value.EventType, Operation: value.Operation, UserID: value.UserID, AuthorityID: value.AuthorityID, RequestID: value.RequestID, Method: value.Method, Path: value.Path, Detail: value.Detail})
}
func (s *AuditService) DataAccessRequest(ctx context.Context, req *dto.DataAccessListRequest) ([]*dto.DataAccessLogResponse, int64, error) {
return s.DataAccess(ctx, req.Page, req.PageSize, &biz.DataAccessLog{EventType: req.EventType, TargetTable: req.TargetTable, UserID: req.UserID})
return s.DataAccess(ctx, req.Page, req.PageSize, &biz.DataAccessLog{EventType: req.EventType, TargetTable: req.TargetTable})
}
func dataAccessDTO(v *biz.DataAccessLog) *dto.DataAccessLogResponse {
return &dto.DataAccessLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
return &dto.DataAccessLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
}
func (s *AuditService) DataAccess(ctx context.Context, page, size int, q *biz.DataAccessLog) ([]*dto.DataAccessLogResponse, int64, error) {
items, total, err := s.uc.ListDataAccess(ctx, page, size, q)
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
func errorDTO(v *biz.ErrorRecord) *dto.ErrorRecordResponse {
return &dto.ErrorRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, Form: v.Form, Info: v.Info, Level: v.Level, RequestID: v.RequestID, TraceID: v.TraceID, Solution: v.Solution, Status: v.Status}
return &dto.ErrorRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Form: v.Form, Info: v.Info, Level: v.Level, RequestID: v.RequestID, TraceID: v.TraceID, Solution: v.Solution, Status: v.Status}
}
func (s *AuditRecorder) CreateError(ctx context.Context, v *biz.ErrorRecord) error {
return s.uc.CreateError(ctx, v)
+2 -2
View File
@@ -34,8 +34,8 @@ func (s *AuthService) Login(ctx context.Context, req *dto.LoginRequest, ip, agen
return loginResult(value), nil
}
func (s *AuthService) SwitchAuthority(ctx context.Context, id, authorityID uint) (*LoginResult, error) {
value, err := s.uc.SwitchAuthority(ctx, id, authorityID)
func (s *AuthService) SwitchAuthority(ctx context.Context, claims *biz.AuthClaims, authorityID uint) (*LoginResult, error) {
value, err := s.uc.SwitchAuthority(ctx, claims, authorityID)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -28,7 +28,7 @@ func authorityDomain(req *dto.AuthorityRequest) *biz.Authority {
}
func authorityResponse(value *biz.Authority) *dto.AuthorityResponse {
return &dto.AuthorityResponse{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
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}
}
func (s *AuthorityService) Authorities(ctx context.Context) ([]*dto.AuthorityResponse, error) {
+22 -20
View File
@@ -14,11 +14,7 @@ func NewDictionaryService(uc *biz.DictionaryUsecase) *DictionaryService {
}
func dictionaryDomain(value *dto.DictionaryRequest) *biz.Dictionary {
status := true
if value.Status != nil {
status = *value.Status
}
return &biz.Dictionary{ID: value.ID, Name: value.Name, Type: value.Type, Status: status, Desc: value.Description, ParentID: value.ParentID}
return &biz.Dictionary{ID: value.ID, Name: value.Name, Type: value.Type, Status: value.Status, Desc: value.Description, ParentID: value.ParentID}
}
func (s *DictionaryService) CreateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) (*dto.DictionaryResponse, error) {
value := dictionaryDomain(req)
@@ -31,13 +27,19 @@ func (s *DictionaryService) UpdateDictionaryRequest(ctx context.Context, req *dt
return s.UpdateDictionary(ctx, dictionaryDomain(req))
}
func dictionaryDTO(v *biz.Dictionary) *dto.DictionaryResponse {
children := make([]*dto.DictionaryResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, dictionaryDTO(x))
var children []*dto.DictionaryResponse
if v.Children != nil {
children = make([]*dto.DictionaryResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, dictionaryDTO(x))
}
}
details := make([]*dto.DictionaryDetailResponse, 0, len(v.Details))
for _, x := range v.Details {
details = append(details, detailDTO(x))
var details []*dto.DictionaryDetailResponse
if v.Details != nil {
details = make([]*dto.DictionaryDetailResponse, 0, len(v.Details))
for _, x := range v.Details {
details = append(details, detailDTO(x))
}
}
return &dto.DictionaryResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, Type: v.Type, Status: v.Status, Desc: v.Desc, ParentID: v.ParentID, Children: children, SysDictionaryDetails: details}
}
@@ -87,11 +89,7 @@ func (s *DictionaryService) DeleteDictionary(ctx context.Context, id uint) error
}
func detailDomain(value *dto.DictionaryDetailRequest) *biz.DictionaryDetail {
status := true
if value.Status != nil {
status = *value.Status
}
return &biz.DictionaryDetail{ID: value.ID, Label: value.Label, Value: value.Value, Extend: value.Extend, Status: status, Sort: value.Sort, DictionaryID: value.DictionaryID, ParentID: value.ParentID, Level: value.Level, Path: value.Path}
return &biz.DictionaryDetail{ID: value.ID, Label: value.Label, Value: value.Value, Extend: value.Extend, Status: value.Status, Sort: value.Sort, DictionaryID: value.DictionaryID, ParentID: value.ParentID, Level: value.Level, Path: value.Path}
}
func (s *DictionaryService) CreateDictionaryDetailRequest(ctx context.Context, req *dto.DictionaryDetailRequest) error {
return s.CreateDictionaryDetail(ctx, detailDomain(req))
@@ -100,11 +98,15 @@ func (s *DictionaryService) UpdateDictionaryDetailRequest(ctx context.Context, r
return s.UpdateDictionaryDetail(ctx, detailDomain(req))
}
func detailDTO(v *biz.DictionaryDetail) *dto.DictionaryDetailResponse {
children := make([]*dto.DictionaryDetailResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, detailDTO(x))
var children []*dto.DictionaryDetailResponse
if v.Children != nil {
children = make([]*dto.DictionaryDetailResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, detailDTO(x))
}
}
return &dto.DictionaryDetailResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Label: v.Label, Value: v.Value, Extend: v.Extend, Status: v.Status, Sort: v.Sort, DictionaryID: v.DictionaryID, ParentID: v.ParentID, Level: v.Level, Path: v.Path, Disabled: !v.Status, Children: children}
disabled := v.Status != nil && !*v.Status
return &dto.DictionaryDetailResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Label: v.Label, Value: v.Value, Extend: v.Extend, Status: v.Status, Sort: v.Sort, DictionaryID: v.DictionaryID, ParentID: v.ParentID, Level: v.Level, Path: v.Path, Disabled: disabled, Children: children}
}
func (s *DictionaryService) DictionaryDetails(ctx context.Context, page, size int, filter biz.DictionaryDetailFilter) ([]*dto.DictionaryDetailResponse, int64, error) {
items, total, err := s.uc.ListDictionaryDetails(ctx, page, size, filter)
+17 -8
View File
@@ -13,15 +13,24 @@ type AnnouncementRequest struct {
Attachments json.RawMessage `json:"attachments"`
}
type AnnouncementSearchRequest struct {
Page int `form:"page"`
PageSize int `form:"pageSize"`
StartCreatedAt *time.Time `form:"startCreatedAt"`
EndCreatedAt *time.Time `form:"endCreatedAt"`
}
type AnnouncementResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
Title string `json:"title"`
Content string `json:"content"`
UserID *uint `json:"userID"`
Attachments any `json:"attachments"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
// Keep the soft-delete slot in the transport shape while omitting it from
// JSON responses.
DeletedAt any `json:"-"`
Title string `json:"title"`
Content string `json:"content"`
UserID *uint `json:"userID"`
Attachments any `json:"attachments"`
}
type SelectOptionResponse struct {
+1 -1
View File
@@ -25,7 +25,7 @@ type APIResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Path string `json:"path"`
Description string `json:"description"`
APIGroup string `json:"apiGroup"`
+29 -6
View File
@@ -34,11 +34,30 @@ type DataAccessListRequest struct {
PageSize int `json:"pageSize"`
EventType string `json:"eventType"`
TargetTable string `json:"targetTable"`
UserID uint `json:"userId"`
}
type OperationRecordSearchRequest struct {
Page int `form:"page"`
PageSize int `form:"pageSize"`
Path string `form:"path"`
Method string `form:"method"`
Status int `form:"status"`
}
type LoginLogSearchRequest struct {
Page int `form:"page"`
PageSize int `form:"pageSize"`
Username string `form:"username"`
Status bool `form:"status"`
}
type AuditIDQuery struct {
ID uint `form:"ID"`
}
type ErrorRecordRequest struct {
ID uint `json:"ID"`
Form string `json:"form"`
Form string `json:"form" binding:"required"`
Info string `json:"info"`
Level string `json:"level"`
RequestID string `json:"request_id"`
@@ -50,7 +69,8 @@ type ErrorRecordRequest struct {
type OperationRecordResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
DeletedAt any `json:"DeletedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
IP string `json:"ip"`
Method string `json:"method"`
Path string `json:"path"`
@@ -70,7 +90,8 @@ type OperationRecordResponse struct {
type LoginLogResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
DeletedAt any `json:"DeletedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
Username string `json:"username"`
IP string `json:"ip"`
Status bool `json:"status"`
@@ -83,7 +104,8 @@ type LoginLogResponse struct {
type DataAccessLogResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
DeletedAt any `json:"DeletedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
EventType string `json:"eventType"`
TargetTable string `json:"targetTable"`
Operation string `json:"operation"`
@@ -99,7 +121,8 @@ type DataAccessLogResponse struct {
type ErrorRecordResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
DeletedAt any `json:"DeletedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
Form string `json:"form"`
Info string `json:"info"`
Level string `json:"level"`
+7 -2
View File
@@ -1,5 +1,7 @@
package dto
import "time"
type AuthorityRequest struct {
AuthorityID uint `json:"authorityId"`
AuthorityName string `json:"authorityName"`
@@ -17,16 +19,19 @@ type DeleteAuthorityRequest struct {
AuthorityID uint `json:"authorityId"`
}
type SetRoleUsersRequest struct {
AuthorityID uint `json:"authorityId"`
AuthorityID uint `json:"authorityId" form:"authorityId"`
UserIDs []uint `json:"userIds"`
}
type SetDataScopeRequest struct {
AuthorityID uint `json:"authorityId"`
AuthorityID uint `json:"authorityId" form:"authorityId"`
DataScope int `json:"dataScope"`
DepartmentIDs []uint `json:"deptIds"`
}
type AuthorityResponse struct {
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt *time.Time `json:"DeletedAt"`
AuthorityID uint `json:"authorityId"`
AuthorityName string `json:"authorityName"`
ParentID *uint `json:"parentId"`
+33 -16
View File
@@ -3,14 +3,22 @@ package dto
import "time"
type ExportConditionRequest struct {
From string `json:"from"`
Column string `json:"column"`
Operator string `json:"operator"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
TemplateID string `json:"templateID"`
From string `json:"from"`
Column string `json:"column"`
Operator string `json:"operator"`
}
type ExportJoinRequest struct {
Join string `json:"joins"`
Table string `json:"table"`
On string `json:"on"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
TemplateID string `json:"templateID"`
Join string `json:"joins"`
Table string `json:"table"`
On string `json:"on"`
}
type ExportTemplateRequest struct {
ID uint `json:"ID"`
@@ -28,22 +36,31 @@ type ExportTemplateRequest struct {
}
type ExportConditionResponse struct {
From string `json:"from"`
Column string `json:"column"`
Operator string `json:"operator"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
TemplateID string `json:"templateID"`
From string `json:"from"`
Column string `json:"column"`
Operator string `json:"operator"`
}
type ExportJoinResponse struct {
Join string `json:"joins"`
Table string `json:"table"`
On string `json:"on"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
TemplateID string `json:"templateID"`
Join string `json:"joins"`
Table string `json:"table"`
On string `json:"on"`
}
type ExportTemplateResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
// The compatible embedded gorm.DeletedAt field is json:"-".
DeletedAt any `json:"-"`
DBName string `json:"dbName"`
Name string `json:"name"`
TableName string `json:"tableName"`
+20 -19
View File
@@ -6,23 +6,24 @@ type MediaResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
Name string `json:"name"`
ClassID int `json:"classId"`
URL string `json:"url"`
Tag string `json:"tag"`
Key string `json:"key"`
Size int64 `json:"size"`
Mime string `json:"mime"`
MD5 string `json:"md5"`
UserID uint `json:"userId"`
// The compatible model embeds gorm.DeletedAt with json:"-", so this field is omitted.
DeletedAt any `json:"-"`
Name string `json:"name"`
ClassID int `json:"classId"`
URL string `json:"url"`
Tag string `json:"tag"`
Key string `json:"key"`
Size int64 `json:"size"`
Mime string `json:"mime"`
MD5 string `json:"md5"`
UserID uint `json:"userId"`
}
type MediaCategoryResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
PID uint `json:"pid"`
Children []*MediaCategoryResponse `json:"children"`
@@ -37,9 +38,9 @@ type StorageObjectResponse struct {
type InitUploadResponse struct {
Instant bool `json:"instant"`
UploadID uint `json:"uploadId,omitempty"`
UploadID uint `json:"uploadId"`
UploadedChunks []int `json:"uploadedChunks"`
Media *MediaResponse `json:"media"`
Media *MediaResponse `json:"media,omitempty"`
}
type MediaListRequest struct {
@@ -86,13 +87,13 @@ type CategoryRequest struct {
PID uint `json:"pid"`
}
type InitUploadRequest struct {
FileName string `json:"fileName"`
FileHash string `json:"fileHash"`
FileSize int64 `json:"fileSize"`
ChunkSize int64 `json:"chunkSize"`
ChunkTotal int `json:"chunkTotal"`
FileName string `json:"fileName" binding:"required"`
FileHash string `json:"fileHash" binding:"required"`
FileSize int64 `json:"fileSize" binding:"required"`
ChunkSize int64 `json:"chunkSize" binding:"required"`
ChunkTotal int `json:"chunkTotal" binding:"required"`
Mime string `json:"mime"`
}
type CompleteUploadRequest struct {
UploadID uint `json:"uploadId"`
UploadID uint `json:"uploadId" binding:"required"`
}
+25 -14
View File
@@ -1,5 +1,7 @@
package dto
import "time"
type MenuMetaRequest struct {
ActiveName string `json:"activeName"`
KeepAlive bool `json:"keepAlive"`
@@ -58,7 +60,7 @@ type GetAuthorityMenusRequest struct {
}
type SetMenuRolesRequest struct {
MenuID uint `json:"menuId"`
MenuID uint `json:"menuId" form:"menuId"`
AuthorityIDs []uint `json:"authorityIds"`
}
@@ -73,22 +75,29 @@ type MenuMetaResponse struct {
}
type MenuButtonResponse struct {
ID uint `json:"ID"`
Name string `json:"name"`
Description string `json:"desc"`
SysBaseMenuID uint `json:"sysBaseMenuID"`
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 MenuParameterResponse struct {
ID uint `json:"ID"`
SysBaseMenuID uint `json:"SysBaseMenuID"`
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 MenuResponse struct {
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
ID uint `json:"ID"`
MenuID uint `json:"menuId,omitempty"`
ParentID uint `json:"parentId"`
Path string `json:"path"`
Name string `json:"name"`
@@ -103,8 +112,10 @@ type MenuResponse struct {
}
type AuthorityMenuResponse struct {
MenuID uint `json:"menuId"`
AuthorityID uint `json:"authorityId"`
SysBaseMenu *MenuResponse `json:"sysBaseMenu"`
ParentID uint `json:"parentId"`
// 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"`
AuthorityID uint `json:"-"`
}
+2 -2
View File
@@ -31,7 +31,7 @@ type DepartmentResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
ParentID uint `json:"parentId"`
Ancestors string `json:"ancestors"`
@@ -75,7 +75,7 @@ type PositionResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
Code string `json:"code"`
Sort int `json:"sort"`
+43 -31
View File
@@ -32,11 +32,20 @@ type DictionaryDetailsByParentRequest struct {
}
type SystemParameterRequest struct {
ID uint `json:"ID" form:"ID"`
Name string `json:"name" form:"name"`
Key string `json:"key" form:"key"`
Value string `json:"value" form:"value"`
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 {
Page int `json:"page" form:"page"`
PageSize int `json:"pageSize" form:"pageSize"`
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
Name string `json:"name" form:"name"`
Key string `json:"key" form:"key"`
}
type CreateAPITokenRequest struct {
UserID uint `json:"userId"`
AuthorityID uint `json:"authorityId"`
@@ -54,7 +63,7 @@ type APITokenResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
UserID uint `json:"userId"`
AuthorityID uint `json:"authorityId"`
Token string `json:"token"`
@@ -65,33 +74,36 @@ type APITokenResponse struct {
}
type SecurityConfigResponse struct {
ID uint `json:"ID"`
CaptchaOpen int `json:"captchaOpen"`
CaptchaTimeout int `json:"captchaTimeout"`
KeyLong int `json:"keyLong"`
ImgWidth int `json:"imgWidth"`
ImgHeight int `json:"imgHeight"`
PwdMinLength int `json:"pwdMinLength"`
PwdRequireUpper bool `json:"pwdRequireUpper"`
PwdRequireLower bool `json:"pwdRequireLower"`
PwdRequireDigit bool `json:"pwdRequireDigit"`
PwdRequireSpecial bool `json:"pwdRequireSpecial"`
LimitEnable bool `json:"limitEnable"`
LimitWindow int `json:"limitWindow"`
LimitCount int `json:"limitCount"`
LockEnable bool `json:"lockEnable"`
LockThreshold int `json:"lockThreshold"`
LockDuration int `json:"lockDuration"`
PwdExpireEnable bool `json:"pwdExpireEnable"`
PwdExpireDays int `json:"pwdExpireDays"`
ForceNewUserChangePassword bool `json:"forceNewUserChangePassword"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
CaptchaOpen int `json:"captchaOpen"`
CaptchaTimeout int `json:"captchaTimeout"`
KeyLong int `json:"keyLong"`
ImgWidth int `json:"imgWidth"`
ImgHeight int `json:"imgHeight"`
PwdMinLength int `json:"pwdMinLength"`
PwdRequireUpper bool `json:"pwdRequireUpper"`
PwdRequireLower bool `json:"pwdRequireLower"`
PwdRequireDigit bool `json:"pwdRequireDigit"`
PwdRequireSpecial bool `json:"pwdRequireSpecial"`
LimitEnable bool `json:"limitEnable"`
LimitWindow int `json:"limitWindow"`
LimitCount int `json:"limitCount"`
LockEnable bool `json:"lockEnable"`
LockThreshold int `json:"lockThreshold"`
LockDuration int `json:"lockDuration"`
PwdExpireEnable bool `json:"pwdExpireEnable"`
PwdExpireDays int `json:"pwdExpireDays"`
ForceNewUserChangePassword bool `json:"forceNewUserChangePassword"`
}
type SystemParameterResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
Key string `json:"key"`
Value string `json:"value"`
@@ -102,10 +114,10 @@ type DictionaryResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
Type string `json:"type"`
Status bool `json:"status"`
Status *bool `json:"status"`
Desc string `json:"desc"`
ParentID *uint `json:"parentID"`
Children []*DictionaryResponse `json:"children"`
@@ -116,11 +128,11 @@ type DictionaryDetailResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Label string `json:"label"`
Value string `json:"value"`
Extend string `json:"extend"`
Status bool `json:"status"`
Status *bool `json:"status"`
Sort int `json:"sort"`
DictionaryID uint `json:"sysDictionaryID"`
ParentID *uint `json:"parentID"`
@@ -133,7 +145,7 @@ type DictionaryDetailResponse struct {
type DictionaryExportResponse struct {
Name string `json:"name"`
Type string `json:"type"`
Status bool `json:"status"`
Status *bool `json:"status"`
Desc string `json:"desc"`
SysDictionaryDetails []*DictionaryDetailExportResponse `json:"sysDictionaryDetails"`
}
@@ -142,7 +154,7 @@ type DictionaryDetailExportResponse struct {
Label string `json:"label"`
Value string `json:"value"`
Extend string `json:"extend"`
Status bool `json:"status"`
Status *bool `json:"status"`
Sort int `json:"sort"`
Level int `json:"level"`
Path string `json:"path"`
+1 -1
View File
@@ -78,7 +78,7 @@ type UserResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
UUID string `json:"uuid"`
Username string `json:"userName"`
NickName string `json:"nickName"`
+20 -4
View File
@@ -23,18 +23,33 @@ type TaskRequest struct {
}
type DeleteTaskRequest struct {
ID uint `json:"ID"`
ID uint `json:"ID" binding:"required"`
}
type ToggleTaskRequest struct {
ID uint `json:"ID"`
ID uint `json:"ID" binding:"required"`
Enabled bool `json:"enabled"`
}
type TaskListRequest struct {
Page int `form:"page"`
PageSize int `form:"pageSize"`
Name string `form:"name"`
ExecutorType string `form:"executorType"`
Enabled *bool `form:"enabled"`
}
type TaskLogListRequest struct {
Page int `form:"page"`
PageSize int `form:"pageSize"`
TaskID uint `form:"taskId"`
Status string `form:"status"`
}
type TaskResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
Name string `json:"name"`
Description string `json:"description"`
Spec string `json:"spec"`
@@ -54,7 +69,8 @@ type TaskResponse struct {
type TaskLogResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
DeletedAt any `json:"DeletedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"-"`
TaskID uint `json:"taskId"`
TaskName string `json:"taskName"`
TriggerType string `json:"triggerType"`
+15 -7
View File
@@ -6,13 +6,21 @@ type VersionResponse struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
DeletedAt any `json:"DeletedAt"`
DeletedAt any `json:"-"`
VersionName string `json:"versionName"`
VersionCode string `json:"versionCode"`
Description string `json:"description"`
VersionData string `json:"versionData"`
}
type VersionSearchRequest struct {
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
VersionName *string `json:"versionName" form:"versionName"`
VersionCode *string `json:"versionCode" form:"versionCode"`
Page int `json:"page" form:"page"`
PageSize int `json:"pageSize" form:"pageSize"`
}
type VersionMenuMetaRequest struct {
ActiveName string `json:"activeName"`
KeepAlive bool `json:"keepAlive"`
@@ -61,24 +69,24 @@ type VersionDictionaryDetailRequest struct {
type VersionDictionaryRequest struct {
Name string `json:"name"`
Type string `json:"type"`
Status bool `json:"status"`
Status *bool `json:"status"`
Description string `json:"desc"`
Details []VersionDictionaryDetailRequest `json:"sysDictionaryDetails"`
}
type ImportVersionRequest struct {
Version struct {
Name string `json:"name"`
Code string `json:"code"`
Name string `json:"name" binding:"required"`
Code string `json:"code" binding:"required"`
Description string `json:"description"`
ExportTime string `json:"exportTime"`
} `json:"version"`
} `json:"version" binding:"required"`
Menus []VersionMenuRequest `json:"menus"`
APIs []VersionAPIRequest `json:"apis"`
Dictionaries []VersionDictionaryRequest `json:"dictionaries"`
}
type ExportVersionRequest struct {
VersionName string `json:"versionName"`
VersionCode string `json:"versionCode"`
VersionName string `json:"versionName" binding:"required"`
VersionCode string `json:"versionCode" binding:"required"`
Description string `json:"description"`
MenuIDs []uint `json:"menuIds"`
APIIDs []uint `json:"apiIds"`
+4 -4
View File
@@ -70,10 +70,10 @@ func (s *ExportService) ConsumeToken(ctx context.Context, token string, expectBl
func exportTemplateDomain(value *dto.ExportTemplateRequest) *biz.ExportTemplate {
out := &biz.ExportTemplate{ID: value.ID, DBName: value.DBName, Name: value.Name, TableName: value.TableName, TemplateID: value.TemplateID, TemplateInfo: value.TemplateInfo, SQL: value.SQL, ImportSQL: value.ImportSQL, Limit: value.Limit, Order: value.Order}
for _, item := range value.Conditions {
out.Conditions = append(out.Conditions, biz.ExportCondition{From: item.From, Column: item.Column, Operator: item.Operator})
out.Conditions = append(out.Conditions, biz.ExportCondition{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, TemplateID: item.TemplateID, From: item.From, Column: item.Column, Operator: item.Operator})
}
for _, item := range value.Joins {
out.Joins = append(out.Joins, biz.ExportJoin{Join: item.Join, Table: item.Table, On: item.On})
out.Joins = append(out.Joins, biz.ExportJoin{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, TemplateID: item.TemplateID, Join: item.Join, Table: item.Table, On: item.On})
}
return out
}
@@ -91,14 +91,14 @@ func exportDTO(v *biz.ExportTemplate) *dto.ExportTemplateResponse {
if v.Conditions != nil {
conditions = make([]dto.ExportConditionResponse, 0, len(v.Conditions))
for _, x := range v.Conditions {
conditions = append(conditions, dto.ExportConditionResponse{From: x.From, Column: x.Column, Operator: x.Operator})
conditions = append(conditions, dto.ExportConditionResponse{ID: x.ID, CreatedAt: x.CreatedAt, UpdatedAt: x.UpdatedAt, TemplateID: x.TemplateID, From: x.From, Column: x.Column, Operator: x.Operator})
}
}
var joins []dto.ExportJoinResponse
if v.Joins != nil {
joins = make([]dto.ExportJoinResponse, 0, len(v.Joins))
for _, x := range v.Joins {
joins = append(joins, dto.ExportJoinResponse{Join: x.Join, Table: x.Table, On: x.On})
joins = append(joins, dto.ExportJoinResponse{ID: x.ID, CreatedAt: x.CreatedAt, UpdatedAt: x.UpdatedAt, TemplateID: x.TemplateID, Join: x.Join, Table: x.Table, On: x.On})
}
}
return &dto.ExportTemplateResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, DBName: v.DBName, Name: v.Name, TableName: v.TableName, TemplateID: v.TemplateID, TemplateInfo: v.TemplateInfo, SQL: v.SQL, ImportSQL: v.ImportSQL, Limit: v.Limit, Order: v.Order, Conditions: conditions, Joins: joins}
+6 -3
View File
@@ -23,9 +23,12 @@ func mediaDTO(v *biz.MediaFile) *dto.MediaResponse {
return &dto.MediaResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, ClassID: v.CategoryID, URL: v.URL, Tag: v.Tag, Key: v.Key, Size: v.Size, Mime: v.Mime, MD5: v.MD5, UserID: v.UserID}
}
func categoryDTO(v *biz.AttachmentCategory) *dto.MediaCategoryResponse {
children := make([]*dto.MediaCategoryResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, categoryDTO(x))
var children []*dto.MediaCategoryResponse
if v.Children != nil {
children = make([]*dto.MediaCategoryResponse, 0, len(v.Children))
for _, x := range v.Children {
children = append(children, categoryDTO(x))
}
}
return &dto.MediaCategoryResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, PID: v.ParentID, Children: children}
}
+3 -1
View File
@@ -13,7 +13,9 @@ func (s *MediaService) InitUpload(ctx context.Context, userID uint, name, hash s
return nil, err
}
if media != nil {
return &dto.InitUploadResponse{Instant: true, Media: mediaDTO(media), UploadedChunks: []int{}}, nil
// The compatible response leaves UploadedChunks nil on an instant-upload hit, producing
// JSON null while still returning uploadId: 0.
return &dto.InitUploadResponse{Instant: true, Media: mediaDTO(media)}, nil
}
return &dto.InitUploadResponse{Instant: false, UploadID: session.ID, UploadedChunks: chunks, Media: nil}, nil
}
+4 -4
View File
@@ -58,7 +58,7 @@ func (s *MenuService) AuthorityMenus(ctx context.Context, authorityID uint) ([]*
}
out := make([]*dto.AuthorityMenuResponse, 0, len(items))
for _, item := range items {
out = append(out, &dto.AuthorityMenuResponse{MenuID: item.ID, AuthorityID: authorityID, SysBaseMenu: menuResponse(item), ParentID: item.ParentID})
out = append(out, &dto.AuthorityMenuResponse{MenuResponse: menuResponse(item), MenuID: item.ID, AuthorityID: authorityID})
}
return out, nil
}
@@ -94,16 +94,16 @@ func menuResponse(menu *biz.Menu) *dto.MenuResponse {
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{ID: button.ID, Name: button.Name, Description: button.Description, SysBaseMenuID: button.MenuID})
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
}
}
parameters := make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
for _, parameter := range menu.Parameters {
parameters = append(parameters, dto.MenuParameterResponse{ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
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{ID: menu.ID, 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}
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}
}
func menuResponses(items []*biz.Menu) []*dto.MenuResponse {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
)
func securityDTO(v *biz.SecurityConfig) *dto.SecurityConfigResponse {
return &dto.SecurityConfigResponse{ID: v.ID, CaptchaOpen: v.CaptchaOpen, CaptchaTimeout: v.CaptchaTimeout, KeyLong: v.KeyLong, ImgWidth: v.ImgWidth, ImgHeight: v.ImgHeight, PwdMinLength: v.PwdMinLength, PwdRequireUpper: v.PwdRequireUpper, PwdRequireLower: v.PwdRequireLower, PwdRequireDigit: v.PwdRequireDigit, PwdRequireSpecial: v.PwdRequireSpecial, LimitEnable: v.LimitEnable, LimitWindow: v.LimitWindow, LimitCount: v.LimitCount, LockEnable: v.LockEnable, LockThreshold: v.LockThreshold, LockDuration: v.LockDuration, PwdExpireEnable: v.PwdExpireEnable, PwdExpireDays: v.PwdExpireDays, ForceNewUserChangePassword: v.ForceNewUserChangePassword}
return &dto.SecurityConfigResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, CaptchaOpen: v.CaptchaOpen, CaptchaTimeout: v.CaptchaTimeout, KeyLong: v.KeyLong, ImgWidth: v.ImgWidth, ImgHeight: v.ImgHeight, PwdMinLength: v.PwdMinLength, PwdRequireUpper: v.PwdRequireUpper, PwdRequireLower: v.PwdRequireLower, PwdRequireDigit: v.PwdRequireDigit, PwdRequireSpecial: v.PwdRequireSpecial, LimitEnable: v.LimitEnable, LimitWindow: v.LimitWindow, LimitCount: v.LimitCount, LockEnable: v.LockEnable, LockThreshold: v.LockThreshold, LockDuration: v.LockDuration, PwdExpireEnable: v.PwdExpireEnable, PwdExpireDays: v.PwdExpireDays, ForceNewUserChangePassword: v.ForceNewUserChangePassword}
}
func (s *SecurityService) CurrentSecurity(ctx context.Context) (*biz.SecurityConfig, error) {
return s.uc.Current(ctx)
+11 -5
View File
@@ -21,14 +21,20 @@ type DatabaseInit struct {
}
func (s *SystemConfigService) Initialize(ctx context.Context, input *DatabaseInit, apis []*biz.API) error {
config := ""
switch input.DBType {
driver, config := input.DBType, ""
switch driver {
case "mysql":
config = "timeout=5s&parseTime=True&loc=Local&charset=utf8mb4"
config = "charset=utf8mb4&parseTime=True&loc=Local"
case "pgsql":
config = "sslmode=disable TimeZone=Local"
config = "sslmode=disable TimeZone=Asia/Shanghai"
case "sqlite", "mssql":
default:
// The compatible initialization flow treats an omitted or unknown dbType as MySQL during
// initialization rather than rejecting it as an unsupported driver.
driver = "mysql"
config = "charset=utf8mb4&parseTime=True&loc=Local"
}
return s.uc.Initialize(ctx, &biz.DatabaseConfig{Driver: input.DBType, Host: input.Host, Port: input.Port, User: input.UserName, Password: input.Password, Name: input.DBName, Path: input.DBPath, Config: config, Template: input.Template, AdminPassword: input.AdminPassword, APIs: apis})
return s.uc.Initialize(ctx, &biz.DatabaseConfig{Driver: driver, Host: input.Host, Port: input.Port, User: input.UserName, Password: input.Password, Name: input.DBName, Path: input.DBPath, Config: config, Template: input.Template, AdminPassword: input.AdminPassword, APIs: apis})
}
func (s *SystemConfigService) InitializeRoutes(ctx context.Context, input *DatabaseInit, routes []dto.Route) error {
+1 -1
View File
@@ -71,7 +71,7 @@ func (s *TaskService) Logs(ctx context.Context, page, size int, taskID uint, sta
}
out := make([]*dto.TaskLogResponse, 0, len(items))
for _, v := range items {
out = append(out, &dto.TaskLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, TaskID: v.TaskID, TaskName: v.TaskName, TriggerType: v.TriggerType, StartedAt: v.StartedAt, FinishedAt: v.FinishedAt, DurationMS: v.DurationMS, Status: v.Status, ErrorMsg: v.ErrorMsg, Output: v.Output})
out = append(out, &dto.TaskLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, TaskID: v.TaskID, TaskName: v.TaskName, TriggerType: v.TriggerType, StartedAt: v.StartedAt, FinishedAt: v.FinishedAt, DurationMS: v.DurationMS, Status: v.Status, ErrorMsg: v.ErrorMsg, Output: v.Output})
}
return out, total, nil
}
+3 -1
View File
@@ -90,7 +90,9 @@ func (s *UserService) CreateUser(ctx context.Context, input UserInput) (*dto.Use
return convertUser(user), nil
}
func (s *UserService) UpdateUser(ctx context.Context, input UserInput) error {
return s.uc.UpdateUser(ctx, &biz.User{ID: input.ID, NickName: input.NickName, HeaderImg: input.HeaderImg, AuthorityID: input.AuthorityID, Phone: input.Phone, Email: input.Email, Enable: input.Enable}, input.AuthorityIDs)
// The compatible ChangeUserInfo payload uses authorityIds for role assignment; the
// standalone authorityId field is not applied by setUserInfo.
return s.uc.UpdateUser(ctx, &biz.User{ID: input.ID, NickName: input.NickName, HeaderImg: input.HeaderImg, Phone: input.Phone, Email: input.Email, Enable: input.Enable}, input.AuthorityIDs)
}
func (s *UserService) UpdateSelfUser(ctx context.Context, input UserInput) error {
return s.uc.UpdateSelfUser(ctx, &biz.User{ID: input.ID, NickName: input.NickName, HeaderImg: input.HeaderImg, Phone: input.Phone, Email: input.Email, Enable: input.Enable})
+1 -1
View File
@@ -6,7 +6,7 @@ import (
)
func convertAuthority(value biz.Authority) *dto.AuthorityResponse {
return &dto.AuthorityResponse{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: []*dto.AuthorityResponse{}, Menus: []any{}, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
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}
}
func convertUser(user *biz.User) *dto.UserResponse {
authorities := make([]*dto.AuthorityResponse, 0, len(user.Authorities))
+153 -18
View File
@@ -12,6 +12,123 @@ import (
type VersionService struct{ uc *biz.VersionUsecase }
func NewVersionService(uc *biz.VersionUsecase) *VersionService { return &VersionService{uc: uc} }
type versionExportInfo struct {
Name string `json:"name"`
Code string `json:"code"`
Description string `json:"description"`
ExportTime string `json:"exportTime"`
}
type versionExportMenuParameter struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
SysBaseMenuID uint `json:"SysBaseMenuID"`
Type string `json:"type"`
Key string `json:"key"`
Value string `json:"value"`
}
type versionExportMenuButton struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
Name string `json:"name"`
Description string `json:"desc"`
SysBaseMenuID uint `json:"sysBaseMenuID"`
}
type versionExportMenu struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
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 dto.VersionMenuMetaRequest `json:"meta"`
Authorities []any `json:"authoritys"`
Children []*versionExportMenu `json:"children"`
Parameters []versionExportMenuParameter `json:"parameters"`
MenuButtons []versionExportMenuButton `json:"menuBtn"`
}
type versionExportAPI struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
Path string `json:"path"`
Description string `json:"description"`
APIGroup string `json:"apiGroup"`
Method string `json:"method"`
}
type versionExportDictionaryDetail struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
Label string `json:"label"`
Value string `json:"value"`
Extend string `json:"extend"`
Status *bool `json:"status"`
Sort int `json:"sort"`
DictionaryID int `json:"sysDictionaryID"`
ParentID *uint `json:"parentID"`
Children []versionExportDictionaryDetail `json:"children"`
Level int `json:"level"`
Path string `json:"path"`
Disabled bool `json:"disabled"`
}
type versionExportDictionary struct {
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
Name string `json:"name"`
Type string `json:"type"`
Status *bool `json:"status"`
Desc string `json:"desc"`
ParentID *uint `json:"parentID"`
Children []versionExportDictionary `json:"children"`
Details []versionExportDictionaryDetail `json:"sysDictionaryDetails"`
}
type versionExportDocument struct {
Version versionExportInfo `json:"version"`
Menus []*versionExportMenu `json:"menus"`
APIs []versionExportAPI `json:"apis"`
Dictionaries []versionExportDictionary `json:"dictionaries"`
}
func exportMenu(value *biz.Menu) *versionExportMenu {
menu := &versionExportMenu{
Path: value.Path, Name: value.Name, Hidden: value.Hidden, Component: value.Component, Sort: value.Sort,
Meta: dto.VersionMenuMetaRequest{ActiveName: value.ActiveName, KeepAlive: value.KeepAlive, DefaultMenu: value.DefaultMenu, Title: value.Title, Icon: value.Icon, CloseTab: value.CloseTab, TransitionType: value.TransitionType},
}
if len(value.Parameters) > 0 {
menu.Parameters = make([]versionExportMenuParameter, 0, len(value.Parameters))
for _, parameter := range value.Parameters {
menu.Parameters = append(menu.Parameters, versionExportMenuParameter{Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
}
}
if len(value.Buttons) > 0 {
menu.MenuButtons = make([]versionExportMenuButton, 0, len(value.Buttons))
for _, button := range value.Buttons {
menu.MenuButtons = append(menu.MenuButtons, versionExportMenuButton{Name: button.Name, Description: button.Description})
}
}
if len(value.Children) > 0 {
menu.Children = make([]*versionExportMenu, 0, len(value.Children))
for _, child := range value.Children {
menu.Children = append(menu.Children, exportMenu(child))
}
}
return menu
}
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}
}
@@ -38,7 +155,19 @@ func (s *VersionService) VersionData(ctx context.Context, id uint) (string, stri
if err != nil {
return "", "", err
}
return v.Data, v.Code, nil
if v.Data != "" {
return v.Data, 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")},
Menus: []*versionExportMenu{},
APIs: []versionExportAPI{},
}
raw, marshalErr := json.MarshalIndent(payload, "", " ")
if marshalErr != nil {
return "", "", marshalErr
}
return string(raw), v.Code, nil
}
func (s *VersionService) DeleteVersions(ctx context.Context, ids []uint) error {
return s.uc.DeleteVersions(ctx, ids)
@@ -53,24 +182,34 @@ func (s *VersionService) Export(ctx context.Context, name, code, description str
bundle.Code = code
bundle.Description = description
bundle.ExportTime = time.Now().Format("2006-01-02 15:04:05")
menus := make([]*dto.MenuResponse, 0, len(bundle.Menus))
for _, v := range bundle.Menus {
menus = append(menus, menuResponse(v))
var menus []*versionExportMenu
if bundle.Menus != nil {
menus = make([]*versionExportMenu, 0, len(bundle.Menus))
for _, value := range bundle.Menus {
menus = append(menus, exportMenu(value))
}
}
apis := make([]*dto.APIResponse, 0, len(bundle.APIs))
for _, v := range bundle.APIs {
apis = append(apis, apiResponse(v))
apis := make([]versionExportAPI, 0, len(bundle.APIs))
for _, value := range bundle.APIs {
apis = append(apis, versionExportAPI{Path: value.Path, Description: value.Description, APIGroup: value.APIGroup, Method: value.Method})
}
dicts := make([]*dto.DictionaryResponse, 0, len(bundle.Dictionaries))
for _, v := range bundle.Dictionaries {
dicts = append(dicts, dictionaryDTO(v))
dictionaries := make([]versionExportDictionary, 0, len(bundle.Dictionaries))
for _, value := range bundle.Dictionaries {
details := make([]versionExportDictionaryDetail, 0, len(value.Details))
for _, detail := range value.Details {
details = append(details, versionExportDictionaryDetail{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: detail.Status, Sort: detail.Sort})
}
dictionaries = append(dictionaries, versionExportDictionary{Name: value.Name, Type: value.Type, Status: value.Status, Desc: value.Desc, Details: details})
}
payload := map[string]any{"version": map[string]any{"name": name, "code": code, "description": description, "exportTime": bundle.ExportTime}, "menus": menus, "apis": apis, "dictionaries": dicts}
payload := versionExportDocument{Version: versionExportInfo{Name: name, Code: code, Description: description, ExportTime: bundle.ExportTime}, Menus: menus, APIs: apis, Dictionaries: dictionaries}
raw, err := json.MarshalIndent(payload, "", " ")
if err != nil {
return err
return &biz.VersionStageError{Stage: biz.VersionStageJSON, Err: err}
}
return s.uc.CreateVersion(ctx, &biz.Version{Name: name, Code: code, Description: description, Data: string(raw)})
if err = s.uc.CreateVersion(ctx, &biz.Version{Name: name, Code: code, Description: description, Data: string(raw)}); err != nil {
return &biz.VersionStageError{Stage: biz.VersionStageSave, Err: err}
}
return nil
}
func (s *VersionService) Import(ctx context.Context, bundle *biz.VersionBundle) error {
return s.uc.ImportVersionBundle(ctx, bundle)
@@ -102,11 +241,7 @@ func (s *VersionService) ImportRequest(ctx context.Context, req *dto.ImportVersi
for _, dictionary := range req.Dictionaries {
item := &biz.Dictionary{Name: dictionary.Name, Type: dictionary.Type, Status: dictionary.Status, Desc: dictionary.Description}
for _, detail := range dictionary.Details {
status := true
if detail.Status != nil {
status = *detail.Status
}
item.Details = append(item.Details, &biz.DictionaryDetail{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: status, Sort: detail.Sort, ParentID: detail.ParentID, Level: detail.Level, Path: detail.Path})
item.Details = append(item.Details, &biz.DictionaryDetail{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: detail.Status, Sort: detail.Sort, ParentID: detail.ParentID, Level: detail.Level, Path: detail.Path})
}
bundle.Dictionaries = append(bundle.Dictionaries, item)
}