fix
This commit is contained in:
parent
f63acae353
commit
6698e59c3a
|
|
@ -49,6 +49,20 @@ func newApp(logger *slog.Logger, hs *kratoshttp.Server, scheduler *worker.TaskSc
|
|||
)
|
||||
}
|
||||
|
||||
func zapSettings(admin *conf.AdminBackend) (string, logging.Options) {
|
||||
options := logging.Options{Level: "info", Format: "json", EncodeLevel: "LowercaseLevelEncoder", LogInConsole: true, ShowLine: true, RetentionDay: 7}
|
||||
root := "logs"
|
||||
if admin == nil || admin.Zap == nil {
|
||||
return root, options
|
||||
}
|
||||
zapConfig := admin.Zap
|
||||
options = logging.Options{Level: zapConfig.Level, Format: zapConfig.Format, EncodeLevel: zapConfig.EncodeLevel, Prefix: zapConfig.Prefix, StacktraceKey: zapConfig.StacktraceKey, LogInConsole: zapConfig.LogInConsole, ShowLine: zapConfig.ShowLine, RetentionDay: int(zapConfig.RetentionDay), FileOnlyModules: zapConfig.FileOnlyModules}
|
||||
if zapConfig.Director != "" {
|
||||
root = zapConfig.Director
|
||||
}
|
||||
return root, options
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
c := config.New(
|
||||
|
|
@ -66,21 +80,13 @@ func main() {
|
|||
if err := c.Scan(&bc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logOptions := logging.Options{Level: "info", Format: "json", EncodeLevel: "LowercaseLevelEncoder", LogInConsole: true, ShowLine: true, RetentionDay: 7}
|
||||
logRoot := "logs"
|
||||
if bc.Admin != nil && bc.Admin.Zap != nil {
|
||||
zapConfig := bc.Admin.Zap
|
||||
logOptions = logging.Options{Level: zapConfig.Level, Format: zapConfig.Format, EncodeLevel: zapConfig.EncodeLevel, Prefix: zapConfig.Prefix, StacktraceKey: zapConfig.StacktraceKey, LogInConsole: zapConfig.LogInConsole, ShowLine: zapConfig.ShowLine, RetentionDay: int(zapConfig.RetentionDay), FileOnlyModules: zapConfig.FileOnlyModules}
|
||||
if zapConfig.Director != "" {
|
||||
logRoot = zapConfig.Director
|
||||
}
|
||||
}
|
||||
logRoot, logOptions := zapSettings(bc.Admin)
|
||||
loggerAttrs := []any{slog.String("service.id", id), slog.String("service.name", Name), slog.String("service.version", Version)}
|
||||
if bc.Admin != nil && bc.Admin.App != nil {
|
||||
loggerAttrs = append(loggerAttrs, slog.String("node", bc.Admin.App.Node), slog.String("app_id", bc.Admin.App.AppId), slog.String("env", bc.Admin.App.Env))
|
||||
}
|
||||
logger, closeLogger := logging.NewZapLogger(logRoot, "application.log", logOptions, loggerAttrs...)
|
||||
defer closeLogger()
|
||||
logger, loggerControl := logging.NewReloadableZapLogger(logRoot, "application.log", logOptions, loggerAttrs...)
|
||||
defer loggerControl.Close()
|
||||
log.SetDefault(logger)
|
||||
if bc.Admin != nil {
|
||||
bc.Admin.ConfigPath = flagconf
|
||||
|
|
@ -89,7 +95,14 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
app, cleanup, err := wireApp(bc.Server, bc.Data, bc.Admin, logger)
|
||||
runtime := conf.NewRuntime(bc.Data, bc.Admin)
|
||||
unsubscribeLogger := runtime.Subscribe(func(_ *conf.Data, admin *conf.AdminBackend) {
|
||||
root, options := zapSettings(admin)
|
||||
loggerControl.Reload(root, options)
|
||||
})
|
||||
defer unsubscribeLogger()
|
||||
|
||||
app, cleanup, err := wireApp(bc.Server, runtime, logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ import (
|
|||
)
|
||||
|
||||
// wireApp init kratos application.
|
||||
func wireApp(*conf.Server, *conf.Data, *conf.AdminBackend, *slog.Logger) (*kratos.App, func(), error) {
|
||||
panic(wire.Build(conf.NewRuntime, server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
|
||||
func wireApp(*conf.Server, *conf.Runtime, *slog.Logger) (*kratos.App, func(), error) {
|
||||
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ import (
|
|||
// Injectors from wire.go:
|
||||
|
||||
// wireApp init kratos application.
|
||||
func wireApp(confServer *conf.Server, confData *conf.Data, adminBackend *conf.AdminBackend, logger *slog.Logger) (*kratos.App, func(), error) {
|
||||
runtime := conf.NewRuntime(confData, adminBackend)
|
||||
func wireApp(confServer *conf.Server, runtime *conf.Runtime, logger *slog.Logger) (*kratos.App, func(), error) {
|
||||
dataData, cleanup, err := data.NewData(runtime)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
@ -72,7 +71,7 @@ func wireApp(confServer *conf.Server, confData *conf.Data, adminBackend *conf.Ad
|
|||
taskService := service.NewTaskService(taskUsecase, mediaUsecase, runtime)
|
||||
taskScheduler := worker.NewTaskScheduler(taskService, logger)
|
||||
task := handler.NewTask(taskService, taskScheduler)
|
||||
mediaService := service.NewMediaService(mediaUsecase)
|
||||
mediaService := service.NewMediaService(mediaUsecase, runtime)
|
||||
media := handler.NewMedia(mediaService)
|
||||
auditRepo := data.NewAuditRepo(dataData)
|
||||
auditUsecase := biz.NewAuditUsecase(auditRepo)
|
||||
|
|
@ -94,7 +93,8 @@ func wireApp(confServer *conf.Server, confData *conf.Data, adminBackend *conf.Ad
|
|||
user := handler.NewUser(systemService)
|
||||
navigation := handler.NewNavigation(systemService)
|
||||
session := handler.NewSession(settingsService)
|
||||
httpServer := server.NewGinServer(confServer, runtime, systemService, accessService, authority, menu, api, permission, organization, announcement, email, task, media, audit, export, version, dictionary, parameter, apiToken, systemConfig, public, user, navigation, session, settingsService, auditService, logger)
|
||||
engine := server.NewGinEngine(runtime, systemService, accessService, authority, menu, api, permission, organization, announcement, email, task, media, audit, export, version, dictionary, parameter, apiToken, systemConfig, public, user, navigation, session, settingsService, auditService, logger)
|
||||
httpServer := server.NewGinServer(confServer, engine)
|
||||
app := newApp(logger, httpServer, taskScheduler)
|
||||
return app, func() {
|
||||
cleanup()
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ admin:
|
|||
path_prefix: uploads/file
|
||||
media:
|
||||
session_ttl: 24
|
||||
max_file_size: 0
|
||||
system:
|
||||
use_redis: false
|
||||
use_multipoint: false
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package biz
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -43,51 +42,23 @@ func NewAnnouncementUsecase(repo AnnouncementRepo) *AnnouncementUsecase {
|
|||
return &AnnouncementUsecase{repo: repo}
|
||||
}
|
||||
|
||||
func validateAnnouncement(item *Announcement) error {
|
||||
if item == nil || item.Title == "" {
|
||||
return errors.New("公告标题不能为空")
|
||||
}
|
||||
if len(item.Attachments) == 0 || !json.Valid(item.Attachments) {
|
||||
item.Attachments = json.RawMessage("[]")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uc *AnnouncementUsecase) Create(ctx context.Context, item *Announcement) error {
|
||||
if err := validateAnnouncement(item); err != nil {
|
||||
return err
|
||||
}
|
||||
return uc.repo.Create(ctx, item)
|
||||
}
|
||||
|
||||
func (uc *AnnouncementUsecase) Update(ctx context.Context, item *Announcement) error {
|
||||
if item == nil || item.ID == 0 {
|
||||
return errors.New("公告ID不能为空")
|
||||
}
|
||||
if err := validateAnnouncement(item); err != nil {
|
||||
return err
|
||||
}
|
||||
return uc.repo.Update(ctx, item)
|
||||
}
|
||||
|
||||
func (uc *AnnouncementUsecase) Delete(ctx context.Context, id uint) error {
|
||||
if id == 0 {
|
||||
return errors.New("公告ID不能为空")
|
||||
}
|
||||
return uc.repo.Delete(ctx, id)
|
||||
}
|
||||
|
||||
func (uc *AnnouncementUsecase) DeleteByIDs(ctx context.Context, ids []uint) error {
|
||||
if len(ids) == 0 {
|
||||
return errors.New("公告ID不能为空")
|
||||
}
|
||||
return uc.repo.DeleteByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (uc *AnnouncementUsecase) Find(ctx context.Context, id uint) (*Announcement, error) {
|
||||
if id == 0 {
|
||||
return nil, errors.New("公告ID不能为空")
|
||||
}
|
||||
return uc.repo.Find(ctx, id)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,19 @@ package biz
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidLogMonth = errors.New("日志月份格式不正确")
|
||||
ErrInvalidLogDate = errors.New("日志日期格式不正确")
|
||||
ErrInvalidLogPath = errors.New("日志文件路径不合法")
|
||||
ErrLogFileNotFound = errors.New("日志文件不存在")
|
||||
ErrLogFileUnreadable = errors.New("日志文件不可读取")
|
||||
ErrLogRootUnavailable = errors.New("日志目录不可读取")
|
||||
)
|
||||
|
||||
type OperationRecord struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -71,16 +71,39 @@ func (uc *SettingsUsecase) ImportDictionary(ctx context.Context, dictionary *Dic
|
|||
return uc.SettingsRepo.ImportDictionary(ctx, dictionary, details)
|
||||
}
|
||||
|
||||
func (uc *SettingsUsecase) DictionaryDetailsByParent(ctx context.Context, dictionaryID, parentID uint) ([]*DictionaryDetail, error) {
|
||||
func (uc *SettingsUsecase) DictionaryDetailsByParent(ctx context.Context, dictionaryID uint, parentID *uint, includeChildren bool) ([]*DictionaryDetail, error) {
|
||||
items, _, err := uc.ListDictionaryDetails(ctx, 0, 0, DictionaryDetailFilter{DictionaryID: dictionaryID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]*DictionaryDetail, 0)
|
||||
direct := make([]*DictionaryDetail, 0)
|
||||
for _, item := range items {
|
||||
if (parentID == 0 && item.ParentID == nil) || (item.ParentID != nil && *item.ParentID == parentID) {
|
||||
out = append(out, item)
|
||||
if (parentID == nil && item.ParentID == nil) || (parentID != nil && item.ParentID != nil && *item.ParentID == *parentID) {
|
||||
direct = append(direct, item)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
if !includeChildren {
|
||||
return direct, nil
|
||||
}
|
||||
children := make(map[uint][]*DictionaryDetail)
|
||||
for _, item := range items {
|
||||
item.Children = []*DictionaryDetail{}
|
||||
if item.ParentID != nil {
|
||||
children[*item.ParentID] = append(children[*item.ParentID], item)
|
||||
}
|
||||
}
|
||||
var attach func(*DictionaryDetail)
|
||||
attach = func(item *DictionaryDetail) {
|
||||
item.Children = children[item.ID]
|
||||
if item.Children == nil {
|
||||
item.Children = []*DictionaryDetail{}
|
||||
}
|
||||
for _, child := range item.Children {
|
||||
attach(child)
|
||||
}
|
||||
}
|
||||
for _, item := range direct {
|
||||
attach(item)
|
||||
}
|
||||
return direct, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash
|
|||
if size <= 0 || chunkSize <= 0 || total <= 0 {
|
||||
return nil, nil, nil, errors.New("上传参数不合法")
|
||||
}
|
||||
if media, err := uc.FindMediaByHash(ctx, userID, hash); err == nil {
|
||||
copy := *media
|
||||
copy.ID = 0
|
||||
copy.Name = name
|
||||
if err = uc.CreateMedia(ctx, ©); err == nil {
|
||||
return nil, ©, nil, nil
|
||||
if completed, err := uc.FindCompletedSession(ctx, userID, hash); err == nil && completed.MediaID != 0 {
|
||||
if media, findErr := uc.FindMedia(ctx, completed.MediaID); findErr == nil {
|
||||
copy := &MediaFile{Name: name, URL: media.URL, Tag: media.Tag, Key: media.Key}
|
||||
if createErr := uc.CreateMedia(ctx, copy); createErr == nil {
|
||||
return nil, copy, nil, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
session, err := uc.FindUploadingSession(ctx, userID, hash)
|
||||
|
|
@ -53,8 +53,8 @@ func (uc *MediaUsecase) SaveChunk(ctx context.Context, userID, uploadID uint, in
|
|||
if err != nil || session.UserID != userID {
|
||||
return errors.New("上传会话不存在或无权操作")
|
||||
}
|
||||
if session.Status != "uploading" || index < 0 || index >= session.ChunkTotal {
|
||||
return errors.New("上传会话状态或分片序号不合法")
|
||||
if session.Status != "uploading" {
|
||||
return errors.New("上传会话状态不允许收片")
|
||||
}
|
||||
hash := md5.New()
|
||||
key := fmt.Sprintf(".chunks/%d/%08d", uploadID, index)
|
||||
|
|
@ -63,9 +63,9 @@ func (uc *MediaUsecase) SaveChunk(ctx context.Context, userID, uploadID uint, in
|
|||
return err
|
||||
}
|
||||
actual := hex.EncodeToString(hash.Sum(nil))
|
||||
if !strings.EqualFold(actual, expected) {
|
||||
if actual != expected {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return errors.New("分片校验失败")
|
||||
return fmt.Errorf("分片 %d 校验失败", index)
|
||||
}
|
||||
return uc.UpsertChunk(ctx, uploadID, &UploadChunk{Index: index, Hash: actual, Size: stored.Size})
|
||||
}
|
||||
|
|
@ -74,15 +74,26 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
|||
if err != nil || session.UserID != userID {
|
||||
return nil, errors.New("上传会话不存在或无权操作")
|
||||
}
|
||||
claimed, err := uc.ClaimUploadSession(ctx, uploadID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !claimed {
|
||||
return nil, errors.New("上传不在可合并状态(可能已在合并或已完成)")
|
||||
}
|
||||
fail := func(value error) (*MediaFile, error) {
|
||||
_ = uc.FailUploadSession(ctx, uploadID)
|
||||
return nil, value
|
||||
}
|
||||
chunks, err := uc.ListChunks(ctx, uploadID)
|
||||
if err != nil || len(chunks) != session.ChunkTotal {
|
||||
return nil, errors.New("分片不完整")
|
||||
return fail(fmt.Errorf("分片不全: %d/%d", len(chunks), session.ChunkTotal))
|
||||
}
|
||||
sort.Slice(chunks, func(i, j int) bool { return chunks[i].Index < chunks[j].Index })
|
||||
names := make([]string, 0, len(chunks))
|
||||
for index, chunk := range chunks {
|
||||
if chunk.Index != index {
|
||||
return nil, errors.New("分片序号不连续")
|
||||
return fail(errors.New("分片序号不连续"))
|
||||
}
|
||||
names = append(names, fmt.Sprintf(".chunks/%d/%08d", uploadID, index))
|
||||
}
|
||||
|
|
@ -90,16 +101,16 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
|||
key := time.Now().Format("20060102") + "/" + uuid.NewString() + ext
|
||||
stored, hash, err := uc.files.Compose(ctx, names, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return fail(err)
|
||||
}
|
||||
if !strings.EqualFold(hash, session.FileHash) {
|
||||
if hash != session.FileHash {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return nil, errors.New("整文件校验失败")
|
||||
return fail(errors.New("整文件校验失败"))
|
||||
}
|
||||
media := &MediaFile{Name: session.FileName, URL: stored.URL, Tag: strings.TrimPrefix(ext, "."), Key: key, Size: stored.Size, Mime: mime, MD5: hash, UserID: userID}
|
||||
if err = uc.CreateMedia(ctx, media); err != nil {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return nil, err
|
||||
return fail(err)
|
||||
}
|
||||
_ = uc.CompleteUploadSession(ctx, uploadID, key, media.ID)
|
||||
_ = uc.DeleteChunks(ctx, uploadID)
|
||||
|
|
|
|||
|
|
@ -22,9 +22,12 @@ type UploadChunk struct {
|
|||
}
|
||||
|
||||
type UploadRepo interface {
|
||||
FindCompletedSession(context.Context, uint, string) (*UploadSession, error)
|
||||
FindUploadingSession(context.Context, uint, string) (*UploadSession, error)
|
||||
CreateUploadSession(context.Context, *UploadSession) error
|
||||
FindUploadSession(context.Context, uint) (*UploadSession, error)
|
||||
ClaimUploadSession(context.Context, uint) (bool, error)
|
||||
FailUploadSession(context.Context, uint) error
|
||||
CompleteUploadSession(context.Context, uint, string, uint) error
|
||||
DeleteUploadSession(context.Context, uint) error
|
||||
UpsertChunk(context.Context, uint, *UploadChunk) error
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc (unknown)
|
||||
// protoc-gen-go v1.36.12
|
||||
// protoc v7.35.1
|
||||
// source: conf/conf.proto
|
||||
|
||||
package conf
|
||||
|
|
@ -1167,6 +1167,7 @@ func (x *AdminBackend_Email) GetIsLoginAuth() bool {
|
|||
type AdminBackend_Media struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
SessionTtl int32 `protobuf:"varint,1,opt,name=session_ttl,json=sessionTtl,proto3" json:"session_ttl,omitempty"`
|
||||
MaxFileSize int64 `protobuf:"varint,2,opt,name=max_file_size,json=maxFileSize,proto3" json:"max_file_size,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
|
@ -1208,6 +1209,13 @@ func (x *AdminBackend_Media) GetSessionTtl() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (x *AdminBackend_Media) GetMaxFileSize() int64 {
|
||||
if x != nil {
|
||||
return x.MaxFileSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AdminBackend_Disk struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MountPoint string `protobuf:"bytes,1,opt,name=mount_point,json=mountPoint,proto3" json:"mount_point,omitempty"`
|
||||
|
|
@ -2046,7 +2054,7 @@ const file_conf_conf_proto_rawDesc = "" +
|
|||
"\x12connect_timeout_ms\x18\n" +
|
||||
" \x01(\x03R\x10connectTimeoutMs\x12\x15\n" +
|
||||
"\x06is_zap\x18\v \x01(\bR\x05isZap\x120\n" +
|
||||
"\x05hosts\x18\f \x03(\v2\x1a.kratos.api.Data.MongoHostR\x05hosts\"\x90\x1b\n" +
|
||||
"\x05hosts\x18\f \x03(\v2\x1a.kratos.api.Data.MongoHostR\x05hosts\"\xb4\x1b\n" +
|
||||
"\fAdminBackend\x12#\n" +
|
||||
"\rrouter_prefix\x18\x01 \x01(\tR\frouterPrefix\x12.\n" +
|
||||
"\x03jwt\x18\x02 \x01(\v2\x1c.kratos.api.AdminBackend.JWTR\x03jwt\x12:\n" +
|
||||
|
|
@ -2089,10 +2097,11 @@ const file_conf_conf_proto_rawDesc = "" +
|
|||
"\bnickname\x18\x05 \x01(\tR\bnickname\x12\x12\n" +
|
||||
"\x04port\x18\x06 \x01(\x05R\x04port\x12\x15\n" +
|
||||
"\x06is_ssl\x18\a \x01(\bR\x05isSsl\x12\"\n" +
|
||||
"\ris_login_auth\x18\b \x01(\bR\visLoginAuth\x1a(\n" +
|
||||
"\ris_login_auth\x18\b \x01(\bR\visLoginAuth\x1aL\n" +
|
||||
"\x05Media\x12\x1f\n" +
|
||||
"\vsession_ttl\x18\x01 \x01(\x05R\n" +
|
||||
"sessionTtl\x1a'\n" +
|
||||
"sessionTtl\x12\"\n" +
|
||||
"\rmax_file_size\x18\x02 \x01(\x03R\vmaxFileSize\x1a'\n" +
|
||||
"\x04Disk\x12\x1f\n" +
|
||||
"\vmount_point\x18\x01 \x01(\tR\n" +
|
||||
"mountPoint\x1a\xc3\x01\n" +
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ message AdminBackend {
|
|||
|
||||
message Media {
|
||||
int32 session_ttl = 1;
|
||||
int64 max_file_size = 2;
|
||||
}
|
||||
|
||||
message Disk {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package conf
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
|
@ -9,7 +10,10 @@ import (
|
|||
// Runtime owns the active immutable configuration snapshot. Callers always
|
||||
// receive clones so a config file reload cannot race with request handling.
|
||||
type Runtime struct {
|
||||
snapshot atomic.Pointer[runtimeSnapshot]
|
||||
snapshot atomic.Pointer[runtimeSnapshot]
|
||||
mu sync.RWMutex
|
||||
nextID uint64
|
||||
listeners map[uint64]func(*Data, *AdminBackend)
|
||||
}
|
||||
|
||||
type runtimeSnapshot struct {
|
||||
|
|
@ -18,7 +22,7 @@ type runtimeSnapshot struct {
|
|||
}
|
||||
|
||||
func NewRuntime(data *Data, admin *AdminBackend) *Runtime {
|
||||
runtime := &Runtime{}
|
||||
runtime := &Runtime{listeners: make(map[uint64]func(*Data, *AdminBackend))}
|
||||
runtime.Replace(data, admin)
|
||||
return runtime
|
||||
}
|
||||
|
|
@ -38,7 +42,37 @@ func cloneAdmin(value *AdminBackend) *AdminBackend {
|
|||
}
|
||||
|
||||
func (r *Runtime) Replace(data *Data, admin *AdminBackend) {
|
||||
r.snapshot.Store(&runtimeSnapshot{data: cloneData(data), admin: cloneAdmin(admin)})
|
||||
data = cloneData(data)
|
||||
admin = cloneAdmin(admin)
|
||||
r.snapshot.Store(&runtimeSnapshot{data: data, admin: admin})
|
||||
r.mu.RLock()
|
||||
listeners := make([]func(*Data, *AdminBackend), 0, len(r.listeners))
|
||||
for _, listener := range r.listeners {
|
||||
listeners = append(listeners, listener)
|
||||
}
|
||||
r.mu.RUnlock()
|
||||
for _, listener := range listeners {
|
||||
listener(cloneData(data), cloneAdmin(admin))
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe registers a callback invoked after every successful runtime
|
||||
// configuration replacement. It is used by long-lived clients such as the
|
||||
// logger and other long-lived clients that must follow runtime config changes.
|
||||
func (r *Runtime) Subscribe(listener func(*Data, *AdminBackend)) func() {
|
||||
if listener == nil {
|
||||
return func() {}
|
||||
}
|
||||
r.mu.Lock()
|
||||
r.nextID++
|
||||
id := r.nextID
|
||||
r.listeners[id] = listener
|
||||
r.mu.Unlock()
|
||||
return func() {
|
||||
r.mu.Lock()
|
||||
delete(r.listeners, id)
|
||||
r.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runtime) Data() *Data {
|
||||
|
|
|
|||
|
|
@ -29,19 +29,11 @@ type announcementRepo struct{ data *Data }
|
|||
func NewAnnouncementRepo(data *Data) biz.AnnouncementRepo { return &announcementRepo{data: data} }
|
||||
|
||||
func newAnnouncement(item *biz.Announcement) announcementPO {
|
||||
attachments := []byte(item.Attachments)
|
||||
if len(attachments) == 0 || !json.Valid(attachments) {
|
||||
attachments = []byte("[]")
|
||||
}
|
||||
return announcementPO{ID: item.ID, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: jsonPO(attachments)}
|
||||
return announcementPO{ID: item.ID, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: jsonPO(item.Attachments)}
|
||||
}
|
||||
|
||||
func announcementToBiz(item announcementPO) *biz.Announcement {
|
||||
attachments := json.RawMessage(item.Attachments)
|
||||
if len(attachments) == 0 || !json.Valid(attachments) {
|
||||
attachments = json.RawMessage("[]")
|
||||
}
|
||||
return &biz.Announcement{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: attachments}
|
||||
return &biz.Announcement{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: json.RawMessage(item.Attachments)}
|
||||
}
|
||||
|
||||
func (r *announcementRepo) Create(ctx context.Context, item *biz.Announcement) error {
|
||||
|
|
@ -63,16 +55,7 @@ func (r *announcementRepo) DeleteByIDs(ctx context.Context, ids []uint) error {
|
|||
|
||||
func (r *announcementRepo) Update(ctx context.Context, item *biz.Announcement) error {
|
||||
po := newAnnouncement(item)
|
||||
result := r.data.gormDB.WithContext(ctx).Model(&announcementPO{}).Where("id = ?", item.ID).Updates(map[string]any{
|
||||
"title": po.Title, "content": po.Content, "user_id": po.UserID, "attachments": po.Attachments,
|
||||
})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
return r.data.gormDB.WithContext(ctx).Model(&announcementPO{}).Where("id = ?", item.ID).Updates(&po).Error
|
||||
}
|
||||
|
||||
func (r *announcementRepo) Find(ctx context.Context, id uint) (*biz.Announcement, error) {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ func apiFromPO(po apiPO) *biz.API {
|
|||
}
|
||||
func (r *accessRepo) CreateAPI(ctx context.Context, v *biz.API) error {
|
||||
po := apiPO{Path: v.Path, Description: v.Description, APIGroup: v.APIGroup, Method: strings.ToUpper(v.Method)}
|
||||
var count int64
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&apiPO{}).Where("path = ? AND method = ?", po.Path, po.Method).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在相同api")
|
||||
}
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -53,7 +60,22 @@ func (r *accessRepo) CreateAPI(ctx context.Context, v *biz.API) error {
|
|||
return nil
|
||||
}
|
||||
func (r *accessRepo) UpdateAPI(ctx context.Context, v *biz.API) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(&apiPO{}).Where("id = ?", v.ID).Updates(map[string]any{"path": v.Path, "description": v.Description, "api_group": v.APIGroup, "method": strings.ToUpper(v.Method)}).Error
|
||||
db := r.data.gormDB.WithContext(ctx)
|
||||
var old apiPO
|
||||
if err := db.First(&old, v.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
method := strings.ToUpper(v.Method)
|
||||
if old.Path != v.Path || old.Method != method {
|
||||
var count int64
|
||||
if err := db.Model(&apiPO{}).Where("id <> ? AND path = ? AND method = ?", v.ID, v.Path, method).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在相同api路径")
|
||||
}
|
||||
}
|
||||
return db.Model(&old).Updates(map[string]any{"path": v.Path, "description": v.Description, "api_group": v.APIGroup, "method": method}).Error
|
||||
}
|
||||
func (r *accessRepo) DeleteAPIs(ctx context.Context, ids []uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
|
|
|
|||
|
|
@ -14,28 +14,32 @@ import (
|
|||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
func logRoot() (string, error) {
|
||||
root, err := filepath.Abs("logs")
|
||||
func (r *auditRepo) logRoot() (string, error) {
|
||||
admin := r.data.runtime.Admin()
|
||||
if admin == nil || admin.Zap == nil || strings.TrimSpace(admin.Zap.Director) == "" {
|
||||
return "", biz.ErrLogRootUnavailable
|
||||
}
|
||||
root, err := filepath.Abs(admin.Zap.Director)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.Join(biz.ErrLogRootUnavailable, err)
|
||||
}
|
||||
info, err := os.Stat(root)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return root, nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.Join(biz.ErrLogRootUnavailable, err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", errors.New("日志路径不是目录")
|
||||
return "", biz.ErrLogRootUnavailable
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
func (r *auditRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate, error) {
|
||||
if parsed, err := time.Parse("2006-01", month); err != nil || parsed.Format("2006-01") != month {
|
||||
return nil, errors.New("日志月份格式不正确")
|
||||
return nil, biz.ErrInvalidLogMonth
|
||||
}
|
||||
root, err := logRoot()
|
||||
root, err := r.logRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -73,9 +77,9 @@ func (r *auditRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate,
|
|||
}
|
||||
func (r *auditRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile, error) {
|
||||
if parsed, err := time.Parse("2006-01-02", date); err != nil || parsed.Format("2006-01-02") != date {
|
||||
return nil, errors.New("日志日期格式不正确")
|
||||
return nil, biz.ErrInvalidLogDate
|
||||
}
|
||||
root, err := logRoot()
|
||||
root, err := r.logRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -112,24 +116,27 @@ func (r *auditRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile, e
|
|||
return out, err
|
||||
}
|
||||
func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *int64) (*biz.LogContent, error) {
|
||||
if _, err := time.Parse("2006-01-02", date); err != nil {
|
||||
return nil, errors.New("日志日期格式不正确")
|
||||
if parsed, err := time.Parse("2006-01-02", date); err != nil || parsed.Format("2006-01-02") != date {
|
||||
return nil, biz.ErrInvalidLogDate
|
||||
}
|
||||
root, err := logRoot()
|
||||
root, err := r.logRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dateRoot := filepath.Join(root, date)
|
||||
target := filepath.Clean(filepath.Join(dateRoot, filepath.FromSlash(path)))
|
||||
if target == dateRoot || !strings.HasPrefix(target, dateRoot+string(os.PathSeparator)) || !strings.EqualFold(filepath.Ext(target), ".log") {
|
||||
return nil, errors.New("日志文件路径不合法")
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
}
|
||||
info, err := os.Lstat(target)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, biz.ErrLogFileNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() {
|
||||
return nil, errors.New("日志文件路径不合法")
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
}
|
||||
end := info.Size()
|
||||
if cursor != nil && *cursor >= 0 && *cursor < end {
|
||||
|
|
@ -142,13 +149,13 @@ func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *i
|
|||
}
|
||||
file, err := os.Open(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
|
||||
}
|
||||
defer file.Close()
|
||||
data := make([]byte, end-start)
|
||||
n, err := file.ReadAt(data, start)
|
||||
if err != nil && n == 0 {
|
||||
return nil, err
|
||||
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
|
||||
}
|
||||
data = data[:n]
|
||||
lines := bytes.Split(data, []byte("\n"))
|
||||
|
|
@ -162,5 +169,9 @@ func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *i
|
|||
data = data[offset:]
|
||||
limited = true
|
||||
}
|
||||
return &biz.LogContent{Date: date, Path: path, Content: string(data), LineCount: bytes.Count(data, []byte("\n")), NextCursor: start, HasMore: start > 0, LimitedByBytes: limited, Size: info.Size(), ModifiedAt: info.ModTime()}, nil
|
||||
lineCount := bytes.Count(data, []byte("\n"))
|
||||
if len(data) > 0 && data[len(data)-1] != '\n' {
|
||||
lineCount++
|
||||
}
|
||||
return &biz.LogContent{Date: date, Path: path, Content: string(data), LineCount: lineCount, NextCursor: start, HasMore: start > 0, LimitedByBytes: limited, Size: info.Size(), ModifiedAt: info.ModTime()}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ func (uploadChunkPO) TableName() string { return "media_upload_chunks" }
|
|||
func uploadFromPO(v uploadSessionPO) *biz.UploadSession {
|
||||
return &biz.UploadSession{ID: v.ID, UserID: v.UserID, FileName: v.FileName, FileHash: v.FileHash, FileSize: v.FileSize, ChunkSize: v.ChunkSize, ChunkTotal: v.ChunkTotal, Status: v.Status, StorageKey: v.StorageKey, MediaID: v.MediaID}
|
||||
}
|
||||
func (r *mediaRepo) FindCompletedSession(ctx context.Context, userID uint, hash string) (*biz.UploadSession, error) {
|
||||
var po uploadSessionPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("user_id = ? AND file_hash = ? AND status = ?", userID, hash, "completed").First(&po).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uploadFromPO(po), nil
|
||||
}
|
||||
func (r *mediaRepo) FindUploadingSession(ctx context.Context, userID uint, hash string) (*biz.UploadSession, error) {
|
||||
var po uploadSessionPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("user_id = ? AND file_hash = ? AND status = ?", userID, hash, "uploading").First(&po).Error; err != nil {
|
||||
|
|
@ -66,6 +73,13 @@ func (r *mediaRepo) FindUploadSession(ctx context.Context, id uint) (*biz.Upload
|
|||
}
|
||||
return uploadFromPO(po), nil
|
||||
}
|
||||
func (r *mediaRepo) ClaimUploadSession(ctx context.Context, id uint) (bool, error) {
|
||||
result := r.data.gormDB.WithContext(ctx).Model(&uploadSessionPO{}).Where("id = ? AND status = ?", id, "uploading").Update("status", "merging")
|
||||
return result.RowsAffected == 1, result.Error
|
||||
}
|
||||
func (r *mediaRepo) FailUploadSession(ctx context.Context, id uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(&uploadSessionPO{}).Where("id = ?", id).Update("status", "failed").Error
|
||||
}
|
||||
func (r *mediaRepo) CompleteUploadSession(ctx context.Context, id uint, key string, mediaID uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(&uploadSessionPO{}).Where("id = ?", id).Updates(map[string]any{"status": "completed", "storage_key": key, "media_id": mediaID}).Error
|
||||
}
|
||||
|
|
@ -74,7 +88,7 @@ func (r *mediaRepo) DeleteUploadSession(ctx context.Context, id uint) error {
|
|||
}
|
||||
func (r *mediaRepo) UpsertChunk(ctx context.Context, uploadID uint, v *biz.UploadChunk) error {
|
||||
po := uploadChunkPO{UploadID: uploadID, ChunkIndex: v.Index, ChunkHash: v.Hash, Size: v.Size}
|
||||
return r.data.gormDB.WithContext(ctx).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "upload_id"}, {Name: "chunk_index"}}, DoUpdates: clause.AssignmentColumns([]string{"chunk_hash", "size", "updated_at"})}).Create(&po).Error
|
||||
return r.data.gormDB.WithContext(ctx).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "upload_id"}, {Name: "chunk_index"}}, DoNothing: true}).Create(&po).Error
|
||||
}
|
||||
func (r *mediaRepo) ListChunks(ctx context.Context, uploadID uint) ([]*biz.UploadChunk, error) {
|
||||
var pos []uploadChunkPO
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import (
|
|||
kratoshttp "github.com/go-kratos/kratos/v3/transport/http"
|
||||
)
|
||||
|
||||
func NewGinServer(c *conf.Server, runtime *conf.Runtime, system *service.SystemService, access *service.AccessService, authority *handler.Authority, menu *handler.Menu, api *handler.API, permission *handler.Permission, organization *handler.Organization, announcement *handler.Announcement, email *handler.Email, task *handler.Task, media *handler.Media, auditHandler *handler.Audit, export *handler.Export, version *handler.Version, dictionary *handler.Dictionary, parameter *handler.Parameter, apiToken *handler.APIToken, systemConfig *handler.SystemConfig, publicHandler *handler.Public, user *handler.User, navigation *handler.Navigation, session *handler.Session, settings *service.SettingsService, audit *service.AuditService, logger *slog.Logger) *kratoshttp.Server {
|
||||
func NewGinEngine(runtime *conf.Runtime, system *service.SystemService, access *service.AccessService, authority *handler.Authority, menu *handler.Menu, api *handler.API, permission *handler.Permission, organization *handler.Organization, announcement *handler.Announcement, email *handler.Email, task *handler.Task, media *handler.Media, auditHandler *handler.Audit, export *handler.Export, version *handler.Version, dictionary *handler.Dictionary, parameter *handler.Parameter, apiToken *handler.APIToken, systemConfig *handler.SystemConfig, publicHandler *handler.Public, user *handler.User, navigation *handler.Navigation, session *handler.Session, settings *service.SettingsService, audit *service.AuditService, logger *slog.Logger) *gin.Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
engine := gin.New()
|
||||
engine.Use(servermiddleware.RequestMeta(), servermiddleware.Recovery(audit, logger), servermiddleware.AccessLog(runtime, logger), servermiddleware.ErrorAudit(audit), servermiddleware.SecurityRateLimit(system, settings), servermiddleware.OperationAudit(runtime, audit))
|
||||
|
|
@ -62,7 +62,10 @@ func NewGinServer(c *conf.Server, runtime *conf.Runtime, system *service.SystemS
|
|||
}
|
||||
httpx.Fail(c, "请求的接口不存在")
|
||||
})
|
||||
return engine
|
||||
}
|
||||
|
||||
func NewGinServer(c *conf.Server, engine *gin.Engine) *kratoshttp.Server {
|
||||
network, address := "tcp", ":8000"
|
||||
if c != nil && c.Http != nil {
|
||||
if c.Http.Network != "" {
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ func announcementInput(req dto.AnnouncementRequest) service.AnnouncementInput {
|
|||
|
||||
func (h *Announcement) Create(c *gin.Context) {
|
||||
var req dto.AnnouncementRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.Create(c.Request.Context(), announcementInput(req)); err != nil {
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
httpx.Fail(c, "创建失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
|
|
@ -37,7 +37,7 @@ func (h *Announcement) Create(c *gin.Context) {
|
|||
func (h *Announcement) Delete(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
if err := h.service.Delete(c.Request.Context(), uint(id)); err != nil {
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
|
|
@ -58,7 +58,7 @@ func (h *Announcement) DeleteByIDs(c *gin.Context) {
|
|||
ids = append(ids, uint(id))
|
||||
}
|
||||
if err := h.service.DeleteByIDs(c.Request.Context(), ids); err != nil {
|
||||
httpx.Fail(c, "批量删除失败:"+err.Error())
|
||||
httpx.Fail(c, "批量删除失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
|
|
@ -66,12 +66,12 @@ func (h *Announcement) DeleteByIDs(c *gin.Context) {
|
|||
|
||||
func (h *Announcement) Update(c *gin.Context) {
|
||||
var req dto.AnnouncementRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.Update(c.Request.Context(), announcementInput(req)); err != nil {
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
|
|
@ -81,7 +81,7 @@ func (h *Announcement) Find(c *gin.Context) {
|
|||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Find(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败:"+err.Error())
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.OKWithData(c, item)
|
||||
|
|
@ -98,7 +98,7 @@ func (h *Announcement) List(c *gin.Context) {
|
|||
}
|
||||
items, total, err := h.service.List(c.Request.Context(), page, pageSize, start, end)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: page, PageSize: pageSize}, "获取成功")
|
||||
|
|
@ -107,7 +107,7 @@ func (h *Announcement) List(c *gin.Context) {
|
|||
func (h *Announcement) DataSource(c *gin.Context) {
|
||||
users, err := h.service.UserOptions(c.Request.Context())
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败:"+err.Error())
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.OKWithData(c, gin.H{"userID": users})
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ func NewAPI(service *service.AccessService) *API { return &API{service: service}
|
|||
|
||||
func (h *API) List(c *gin.Context) {
|
||||
var req dto.APIListRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
items, total, err := h.service.ListAPI(c.Request.Context(), &req)
|
||||
|
|
@ -37,8 +37,8 @@ func (h *API) All(c *gin.Context) {
|
|||
}
|
||||
func (h *API) Create(c *gin.Context) {
|
||||
var req dto.APIRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
created, err := h.service.CreateAPIRequest(c.Request.Context(), &req)
|
||||
|
|
@ -50,44 +50,44 @@ func (h *API) Create(c *gin.Context) {
|
|||
}
|
||||
func (h *API) Update(c *gin.Context) {
|
||||
var req dto.APIRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateAPIRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "修改失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "修改成功")
|
||||
}
|
||||
func (h *API) Delete(c *gin.Context) {
|
||||
var req dto.DeleteAPIRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteAPIs(c.Request.Context(), []uint{req.ID}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *API) DeleteByIDs(c *gin.Context) {
|
||||
var req dto.DeleteAPIsRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteAPIs(c.Request.Context(), req.IDs); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *API) Find(c *gin.Context) {
|
||||
var req dto.GetAPIRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
item, err := h.service.FindAPIResponse(c.Request.Context(), req.ID)
|
||||
|
|
@ -116,7 +116,7 @@ func (h *API) Groups(c *gin.Context) {
|
|||
groupAPIMap[parts[1]] = item.APIGroup
|
||||
}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"groups": groups, "apiGroupMap": groupAPIMap}, "获取成功")
|
||||
httpx.OKWithData(c, gin.H{"groups": groups, "apiGroupMap": groupAPIMap})
|
||||
}
|
||||
func (h *API) Roles(c *gin.Context) {
|
||||
path, method := c.Query("path"), c.Query("method")
|
||||
|
|
@ -126,7 +126,7 @@ func (h *API) Roles(c *gin.Context) {
|
|||
}
|
||||
ids, err := h.service.APIRoleIDs(c.Request.Context(), path, method)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败"+err.Error())
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
|
|
@ -136,8 +136,8 @@ func (h *API) Roles(c *gin.Context) {
|
|||
}
|
||||
func (h *API) SetRoles(c *gin.Context) {
|
||||
var req dto.SetAPIRolesRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Path == "" || req.Method == "" {
|
||||
|
|
@ -145,10 +145,10 @@ func (h *API) SetRoles(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.SetAPIRoles(c.Request.Context(), req.Path, req.Method, req.AuthorityIDs); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "设置失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
func (h *API) Sync(engine *gin.Engine) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
|
@ -159,28 +159,32 @@ func (h *API) Sync(engine *gin.Engine) gin.HandlerFunc {
|
|||
}
|
||||
result, err := h.service.SyncAPIResponses(c.Request.Context(), values)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "同步检查失败")
|
||||
httpx.Fail(c, "同步失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, result, "获取成功")
|
||||
httpx.OKWithData(c, result)
|
||||
}
|
||||
}
|
||||
func (h *API) Ignore(c *gin.Context) {
|
||||
var req dto.IgnoreAPIRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Path == "" || req.Method == "" {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Path == "" || req.Method == "" {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.SetAPIIgnored(c.Request.Context(), req.Path, req.Method, req.Flag); err != nil {
|
||||
httpx.Fail(c, "忽略设置失败")
|
||||
httpx.Fail(c, "忽略失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
}
|
||||
func (h *API) ApplySync(c *gin.Context) {
|
||||
var req dto.ApplyAPISyncRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.ApplyAPISyncRequest(c.Request.Context(), &req); err != nil {
|
||||
|
|
@ -189,24 +193,26 @@ func (h *API) ApplySync(c *gin.Context) {
|
|||
}
|
||||
httpx.OK(c)
|
||||
}
|
||||
func (h *API) FreshCasbin(c *gin.Context) { httpx.OK(c) }
|
||||
func (h *API) FreshCasbin(c *gin.Context) {
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "刷新成功")
|
||||
}
|
||||
|
||||
func (h *API) SetPolicyPaths(c *gin.Context) {
|
||||
var req dto.SetPolicyPathsRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.SetPolicyPathsRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
func (h *API) PolicyPaths(c *gin.Context) {
|
||||
var req dto.GetPolicyPathsRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
paths, err := h.service.PolicyPathResponses(c.Request.Context(), req.AuthorityID)
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ func NewAPIToken(service *service.SettingsService) *APIToken {
|
|||
|
||||
func (h *APIToken) Create(c *gin.Context) {
|
||||
var req dto.CreateAPITokenRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
token, err := h.service.CreateAPIToken(c.Request.Context(), req.UserID, req.AuthorityID, req.Days, req.Remark)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "签发失败:"+err.Error())
|
||||
httpx.Fail(c, "签发失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"token": token}, "签发成功")
|
||||
|
|
@ -32,8 +32,8 @@ func (h *APIToken) Create(c *gin.Context) {
|
|||
|
||||
func (h *APIToken) List(c *gin.Context) {
|
||||
var req dto.APITokenListRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
items, total, err := h.service.APITokens(c.Request.Context(), req.Page, req.PageSize, req.UserID, req.Status)
|
||||
|
|
@ -46,13 +46,13 @@ func (h *APIToken) List(c *gin.Context) {
|
|||
|
||||
func (h *APIToken) Delete(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DisableAPIToken(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "作废失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "作废成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
"kra/internal/service/dto"
|
||||
|
|
@ -56,27 +58,27 @@ func (h *Audit) Operation(c *gin.Context) {
|
|||
}
|
||||
func (h *Audit) DeleteOperation(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteOperations(c.Request.Context(), []uint{req.ID}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Audit) DeleteOperations(c *gin.Context) {
|
||||
var req dto.IDsRequest
|
||||
if c.ShouldBindJSON(&req) != nil || len(req.IDs) == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteOperations(c.Request.Context(), req.IDs); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "批量删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
|
||||
func (h *Audit) Logins(c *gin.Context) {
|
||||
|
|
@ -100,27 +102,27 @@ func (h *Audit) Login(c *gin.Context) {
|
|||
}
|
||||
func (h *Audit) DeleteLogin(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteLogins(c.Request.Context(), []uint{req.ID}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Audit) DeleteLogins(c *gin.Context) {
|
||||
var req dto.IDsRequest
|
||||
if c.ShouldBindJSON(&req) != nil || len(req.IDs) == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteLogins(c.Request.Context(), req.IDs); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "批量删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
|
||||
func (h *Audit) DataAccess(c *gin.Context) {
|
||||
|
|
@ -131,7 +133,7 @@ func (h *Audit) DataAccess(c *gin.Context) {
|
|||
}
|
||||
items, total, err := h.service.DataAccessRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: req.Page, PageSize: req.PageSize}, "获取成功")
|
||||
|
|
@ -143,16 +145,16 @@ func (h *Audit) DeleteDataAccess(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.DeleteDataAccess(c.Request.Context(), req.IDs); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *Audit) LogDates(c *gin.Context) {
|
||||
data, err := h.service.LogDates(c.Request.Context(), c.Query("month"))
|
||||
if err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
failLogViewer(c, err)
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, data, "获取成功")
|
||||
|
|
@ -160,7 +162,7 @@ func (h *Audit) LogDates(c *gin.Context) {
|
|||
func (h *Audit) LogFiles(c *gin.Context) {
|
||||
data, err := h.service.LogFiles(c.Request.Context(), c.Query("date"))
|
||||
if err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
failLogViewer(c, err)
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, data, "获取成功")
|
||||
|
|
@ -177,26 +179,45 @@ func (h *Audit) LogContent(c *gin.Context) {
|
|||
}
|
||||
data, err := h.service.LogContent(c.Request.Context(), c.Query("date"), c.Query("path"), cursor)
|
||||
if err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
failLogViewer(c, err)
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, data, "获取成功")
|
||||
}
|
||||
|
||||
func failLogViewer(c *gin.Context, err error) {
|
||||
message := "读取日志失败"
|
||||
switch {
|
||||
case errors.Is(err, biz.ErrInvalidLogMonth):
|
||||
message = "日志月份格式不正确"
|
||||
case errors.Is(err, biz.ErrInvalidLogDate):
|
||||
message = "日志日期格式不正确"
|
||||
case errors.Is(err, biz.ErrInvalidLogPath):
|
||||
message = "日志文件路径不合法"
|
||||
case errors.Is(err, biz.ErrLogFileNotFound):
|
||||
message = "日志文件不存在"
|
||||
case errors.Is(err, biz.ErrLogFileUnreadable):
|
||||
message = "日志文件不可读取"
|
||||
case errors.Is(err, biz.ErrLogRootUnavailable):
|
||||
message = "日志目录不可读取"
|
||||
}
|
||||
httpx.Fail(c, message)
|
||||
}
|
||||
|
||||
func (h *Audit) DeleteError(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
if err := h.service.DeleteErrors(c.Request.Context(), []uint{uint(id)}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Audit) DeleteErrors(c *gin.Context) {
|
||||
if err := h.service.DeleteErrors(c.Request.Context(), IDsFromQuery(c)); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "批量删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
func (h *Audit) UpdateError(c *gin.Context) {
|
||||
var req dto.ErrorRecordRequest
|
||||
|
|
@ -205,19 +226,19 @@ func (h *Audit) UpdateError(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.UpdateErrorRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
func (h *Audit) Error(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Error(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
httpx.Fail(c, "查询失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
httpx.OKWithData(c, item)
|
||||
}
|
||||
func (h *Audit) Errors(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
|
|
@ -232,20 +253,20 @@ func (h *Audit) Errors(c *gin.Context) {
|
|||
}
|
||||
items, total, err := h.service.ErrorsFilter(c.Request.Context(), p, size, c.Query("form"), c.Query("info"), createdAtRange)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
|
||||
}
|
||||
func (h *Audit) CreateError(c *gin.Context) {
|
||||
var req dto.ErrorRecordRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Form == "" {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateErrorRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func (h *Authority) Create(c *gin.Context) {
|
|||
}
|
||||
value, err := h.service.CreateAuthorityRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
httpx.Fail(c, "创建失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"authority": value}, "创建成功")
|
||||
|
|
@ -43,7 +43,7 @@ func (h *Authority) Copy(c *gin.Context) {
|
|||
}
|
||||
value, err := h.service.CopyAuthorityRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "拷贝失败:"+err.Error())
|
||||
httpx.Fail(c, "拷贝失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"authority": value}, "拷贝成功")
|
||||
|
|
@ -56,7 +56,7 @@ func (h *Authority) Update(c *gin.Context) {
|
|||
}
|
||||
value, err := h.service.UpdateAuthorityRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "更新失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"authority": value}, "更新成功")
|
||||
|
|
@ -68,10 +68,10 @@ func (h *Authority) Delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.DeleteAuthority(c.Request.Context(), req.AuthorityID); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "删除失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Authority) SetUsers(c *gin.Context) {
|
||||
var req dto.SetRoleUsersRequest
|
||||
|
|
@ -80,16 +80,16 @@ func (h *Authority) SetUsers(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.SetAuthorityUsers(c.Request.Context(), req.AuthorityID, req.UserIDs); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "设置失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
func (h *Authority) Users(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("authorityId"), 10, 64)
|
||||
ids, err := h.service.AuthorityUserIDs(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败"+err.Error())
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
|
|
@ -104,16 +104,16 @@ func (h *Authority) SetDataScope(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.SetDataScope(c.Request.Context(), req.AuthorityID, req.DataScope, req.DepartmentIDs); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "设置失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
func (h *Authority) DataScopeDepartments(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("authorityId"), 10, 64)
|
||||
ids, err := h.service.DataScopeDepartmentIDs(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败"+err.Error())
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
|
|
|
|||
|
|
@ -19,54 +19,50 @@ func NewDictionary(service *service.SettingsService) *Dictionary {
|
|||
|
||||
func (h *Dictionary) Create(c *gin.Context) {
|
||||
var req dto.DictionaryRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Name == "" || req.Type == "" {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateDictionaryRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
created, err := h.service.CreateDictionaryRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, created, "创建成功")
|
||||
}
|
||||
func (h *Dictionary) Update(c *gin.Context) {
|
||||
var req dto.DictionaryRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateDictionaryRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
func (h *Dictionary) Delete(c *gin.Context) {
|
||||
var req dto.DictionaryRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteDictionary(c.Request.Context(), req.ID); err != nil {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
if err := h.service.DeleteDictionary(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Dictionary) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
var status *bool
|
||||
if raw, exists := c.GetQuery("status"); exists {
|
||||
value, parseErr := strconv.ParseBool(raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
status = &value
|
||||
var req dto.DictionaryRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
item, err := h.service.Dictionary(c.Request.Context(), uint(id), c.Query("type"), status, true)
|
||||
item, err := h.service.Dictionary(c.Request.Context(), req.ID, req.Type, req.Status, true)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
httpx.Fail(c, "字典未创建或未开启")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysDictionary": item}, "查询成功")
|
||||
|
|
@ -82,8 +78,16 @@ func (h *Dictionary) List(details bool) gin.HandlerFunc {
|
|||
}
|
||||
}
|
||||
func (h *Dictionary) Export(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.ExportDictionary(c.Request.Context(), uint(id))
|
||||
var req dto.DictionaryRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.ID == 0 {
|
||||
httpx.Fail(c, "字典ID不能为空")
|
||||
return
|
||||
}
|
||||
item, err := h.service.ExportDictionary(c.Request.Context(), req.ID)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "导出失败")
|
||||
return
|
||||
|
|
@ -103,56 +107,60 @@ func (h *Dictionary) Export(c *gin.Context) {
|
|||
}
|
||||
func (h *Dictionary) Import(c *gin.Context) {
|
||||
var req dto.ImportDictionaryRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.ImportDictionaryJSON(c.Request.Context(), req.JSON); err != nil {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
if err := h.service.ImportDictionaryJSON(c.Request.Context(), req.JSON); err != nil {
|
||||
httpx.Fail(c, "导入失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "导入成功")
|
||||
}
|
||||
|
||||
func (h *Dictionary) CreateDetail(c *gin.Context) {
|
||||
var req dto.DictionaryDetailRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.DictionaryID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateDictionaryDetailRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
}
|
||||
func (h *Dictionary) UpdateDetail(c *gin.Context) {
|
||||
var req dto.DictionaryDetailRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateDictionaryDetailRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
func (h *Dictionary) DeleteDetail(c *gin.Context) {
|
||||
var req dto.DictionaryDetailRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteDictionaryDetail(c.Request.Context(), req.ID); err != nil {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
if err := h.service.DeleteDictionaryDetail(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Dictionary) FindDetail(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.DictionaryDetail(c.Request.Context(), uint(id))
|
||||
var req dto.DictionaryDetailRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
item, err := h.service.DictionaryDetail(c.Request.Context(), req.ID)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
|
|
@ -197,31 +205,54 @@ func (h *Dictionary) Details(c *gin.Context) {
|
|||
}
|
||||
func (h *Dictionary) Tree(byType bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("sysDictionaryID"), 10, 64)
|
||||
rawID := c.Query("sysDictionaryID")
|
||||
id, parseErr := strconv.ParseUint(rawID, 10, 64)
|
||||
typ := ""
|
||||
if byType {
|
||||
typ = c.Query("type")
|
||||
if typ == "" {
|
||||
httpx.Fail(c, "字典类型不能为空")
|
||||
return
|
||||
}
|
||||
} else if rawID == "" {
|
||||
httpx.Fail(c, "字典ID不能为空")
|
||||
return
|
||||
} else if parseErr != nil {
|
||||
httpx.Fail(c, "字典ID格式错误")
|
||||
return
|
||||
}
|
||||
items, err := h.service.DictionaryTree(c.Request.Context(), uint(id), typ)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, items, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"list": items}, "获取成功")
|
||||
}
|
||||
}
|
||||
func (h *Dictionary) DetailsByParent(c *gin.Context) {
|
||||
parentID, _ := strconv.ParseUint(c.Query("parentID"), 10, 64)
|
||||
dictionaryID, _ := strconv.ParseUint(c.Query("sysDictionaryID"), 10, 64)
|
||||
items, err := h.service.DictionaryDetailsByParent(c.Request.Context(), uint(dictionaryID), uint(parentID))
|
||||
var req dto.DictionaryDetailsByParentRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
items, err := h.service.DictionaryDetailsByParent(c.Request.Context(), req.DictionaryID, req.ParentID, req.IncludeChildren)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, items, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"list": items}, "获取成功")
|
||||
}
|
||||
func (h *Dictionary) Path(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
rawID := c.Query("id")
|
||||
if rawID == "" {
|
||||
httpx.Fail(c, "字典详情ID不能为空")
|
||||
return
|
||||
}
|
||||
id, parseErr := strconv.ParseUint(rawID, 10, 64)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, "字典详情ID格式错误")
|
||||
return
|
||||
}
|
||||
item, err := h.service.DictionaryDetail(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -49,60 +48,72 @@ func exportParams(values url.Values) map[string]string {
|
|||
|
||||
func (h *Export) Create(c *gin.Context) {
|
||||
var req dto.ExportTemplateRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Name == "" || req.TemplateID == "" {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name == "" {
|
||||
httpx.Fail(c, "Name值不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
httpx.Fail(c, "创建失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
}
|
||||
func (h *Export) Update(c *gin.Context) {
|
||||
var req dto.ExportTemplateRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name == "" {
|
||||
httpx.Fail(c, "Name值不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
func (h *Export) Delete(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.Delete(c.Request.Context(), []uint{req.ID}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Export) DeleteMany(c *gin.Context) {
|
||||
var req dto.IDsRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.Delete(c.Request.Context(), req.IDs); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "批量删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
func (h *Export) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Template(c.Request.Context(), uint(id), "")
|
||||
var req dto.ExportTemplateRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
item, err := h.service.Template(c.Request.Context(), req.ID, "")
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysExportTemplate": item}, "查询成功")
|
||||
httpx.OKWithData(c, gin.H{"resysExportTemplate": item})
|
||||
}
|
||||
func (h *Export) List(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
|
|
@ -120,12 +131,17 @@ func (h *Export) List(c *gin.Context) {
|
|||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
|
||||
}
|
||||
func (h *Export) Preview(c *gin.Context) {
|
||||
sql, err := h.service.Preview(c.Request.Context(), c.Query("templateID"), exportParams(c.Request.URL.Query()))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "预览失败:"+err.Error())
|
||||
templateID := c.Query("templateID")
|
||||
if templateID == "" {
|
||||
httpx.Fail(c, "模板ID不能为空")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"sql": sql}, "获取成功")
|
||||
sql, err := h.service.Preview(c.Request.Context(), templateID, exportParams(c.Request.URL.Query()))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.OKWithData(c, gin.H{"sql": sql})
|
||||
}
|
||||
|
||||
func (h *Export) Issue(blank bool) gin.HandlerFunc {
|
||||
|
|
@ -137,18 +153,27 @@ func (h *Export) Issue(blank bool) gin.HandlerFunc {
|
|||
}
|
||||
token := strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
raw, _ := json.Marshal(exportToken{TemplateID: templateID, Params: exportParams(c.Request.URL.Query()), Blank: blank})
|
||||
if err := h.system.CacheSet(c.Request.Context(), "export:"+token, string(raw), 5*time.Minute); err != nil {
|
||||
if err := h.system.CacheSet(c.Request.Context(), "export:"+token, string(raw), 30*time.Minute); err != nil {
|
||||
httpx.Fail(c, "导出令牌创建失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"token": token}, "获取成功")
|
||||
path := "/sysExportTemplate/exportExcelByToken?token=" + token
|
||||
if blank {
|
||||
path = "/sysExportTemplate/exportTemplateByToken?token=" + token
|
||||
}
|
||||
httpx.OKWithData(c, path)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Export) Import(c *gin.Context) {
|
||||
templateID := c.Query("templateID")
|
||||
if templateID == "" {
|
||||
httpx.Fail(c, "模板ID不能为空")
|
||||
return
|
||||
}
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
httpx.Fail(c, "请选择导入文件")
|
||||
httpx.Fail(c, "文件获取失败")
|
||||
return
|
||||
}
|
||||
opened, err := file.Open()
|
||||
|
|
@ -157,31 +182,35 @@ func (h *Export) Import(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
defer opened.Close()
|
||||
templateID := c.PostForm("templateID")
|
||||
if templateID == "" {
|
||||
templateID = c.Query("templateID")
|
||||
}
|
||||
if err = h.service.Import(c.Request.Context(), templateID, opened); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "导入成功")
|
||||
}
|
||||
|
||||
func (h *Export) Download(expectBlank bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
token := c.Query("token")
|
||||
if token == "" {
|
||||
httpx.Fail(c, "导出token不能为空")
|
||||
return
|
||||
}
|
||||
raw, ok, err := h.system.CacheGet(c.Request.Context(), "export:"+token)
|
||||
if err != nil || !ok {
|
||||
httpx.Fail(c, "导出令牌无效或已过期")
|
||||
httpx.Fail(c, "导出token无效或已过期")
|
||||
return
|
||||
}
|
||||
var value exportToken
|
||||
if json.Unmarshal([]byte(raw), &value) != nil {
|
||||
httpx.Fail(c, "解析导出参数失败")
|
||||
return
|
||||
}
|
||||
if value.Blank != expectBlank {
|
||||
httpx.Fail(c, "token类型错误")
|
||||
return
|
||||
}
|
||||
_ = h.system.CacheDelete(c.Request.Context(), "export:"+token)
|
||||
var value exportToken
|
||||
if json.Unmarshal([]byte(raw), &value) != nil || value.Blank != expectBlank {
|
||||
httpx.Fail(c, "导出令牌无效")
|
||||
return
|
||||
}
|
||||
var data []byte
|
||||
var name string
|
||||
if expectBlank {
|
||||
|
|
@ -190,10 +219,16 @@ func (h *Export) Download(expectBlank bool) gin.HandlerFunc {
|
|||
data, name, err = h.service.Export(c.Request.Context(), value.TemplateID, value.Params)
|
||||
}
|
||||
if err != nil {
|
||||
httpx.Fail(c, "导出失败:"+err.Error())
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
c.Header("Content-Disposition", "attachment; filename*=UTF-8''"+url.QueryEscape(name))
|
||||
if expectBlank {
|
||||
name = strings.TrimSuffix(name, "_template.xlsx") + "模板.xlsx"
|
||||
} else {
|
||||
name = strings.TrimSuffix(name, ".xlsx") + strings.ReplaceAll(uuid.NewString(), "-", "")[:6] + ".xlsx"
|
||||
}
|
||||
c.Header("Content-Disposition", "attachment; filename="+name)
|
||||
c.Header("success", "true")
|
||||
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ func (h *Media) Storage(c *gin.Context) {
|
|||
}
|
||||
items, next, more, err := h.service.Storage(c.Request.Context(), req.Prefix, req.Cursor, req.Limit)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "列举失败")
|
||||
httpx.Fail(c, "列举存储桶文件失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"list": items, "nextCursor": next, "hasMore": more}, "获取成功")
|
||||
|
|
@ -136,14 +136,14 @@ func (h *Media) Storage(c *gin.Context) {
|
|||
func (h *Media) Categories(c *gin.Context) {
|
||||
items, err := h.service.Categories(c.Request.Context())
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取分类列表失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, items, "获取成功")
|
||||
httpx.OKWithData(c, items)
|
||||
}
|
||||
func (h *Media) SaveCategory(c *gin.Context) {
|
||||
var req dto.CategoryRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Name == "" {
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
|
|
@ -155,7 +155,7 @@ func (h *Media) SaveCategory(c *gin.Context) {
|
|||
}
|
||||
func (h *Media) DeleteCategory(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
|
|
@ -173,12 +173,16 @@ func (h *Media) InitUpload(c *gin.Context) {
|
|||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if config := h.service.MediaConfig(); config != nil && config.MaxFileSize > 0 && req.FileSize > config.MaxFileSize {
|
||||
httpx.Fail(c, "文件超过大小上限")
|
||||
return
|
||||
}
|
||||
result, err := h.service.InitUpload(c.Request.Context(), claims.ID, req.FileName, req.FileHash, req.FileSize, req.ChunkSize, req.ChunkTotal)
|
||||
if err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, result, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, result, "成功")
|
||||
}
|
||||
func (h *Media) SaveChunk(c *gin.Context) {
|
||||
claims := servermiddleware.Claims(c)
|
||||
|
|
@ -199,7 +203,7 @@ func (h *Media) SaveChunk(c *gin.Context) {
|
|||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "ok")
|
||||
}
|
||||
func (h *Media) CompleteUpload(c *gin.Context) {
|
||||
claims := servermiddleware.Claims(c)
|
||||
|
|
@ -213,7 +217,7 @@ func (h *Media) CompleteUpload(c *gin.Context) {
|
|||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"media": item}, "上传成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"media": item}, "成功")
|
||||
}
|
||||
func (h *Media) CancelUpload(c *gin.Context) {
|
||||
claims := servermiddleware.Claims(c)
|
||||
|
|
@ -226,5 +230,5 @@ func (h *Media) CancelUpload(c *gin.Context) {
|
|||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "已取消")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ func (h *Menu) Create(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.Create(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "新增失败")
|
||||
httpx.Fail(c, "添加失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "添加成功")
|
||||
}
|
||||
|
||||
func (h *Menu) Update(c *gin.Context) {
|
||||
|
|
@ -55,7 +55,7 @@ func (h *Menu) Update(c *gin.Context) {
|
|||
httpx.Fail(c, "更新失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
|
||||
func (h *Menu) Delete(c *gin.Context) {
|
||||
|
|
@ -65,10 +65,10 @@ func (h *Menu) Delete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.Delete(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *Menu) Find(c *gin.Context) {
|
||||
|
|
@ -95,7 +95,7 @@ func (h *Menu) SetAuthorityMenus(c *gin.Context) {
|
|||
httpx.Fail(c, "添加失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "添加成功")
|
||||
}
|
||||
|
||||
func (h *Menu) AuthorityMenus(c *gin.Context) {
|
||||
|
|
@ -143,5 +143,5 @@ func (h *Menu) SetRoles(c *gin.Context) {
|
|||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func (h *Organization) FindDepartment(c *gin.Context) {
|
|||
id, _ := strconv.ParseUint(c.Query("id"), 10, 64)
|
||||
item, err := h.service.Department(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "获取成功")
|
||||
|
|
@ -83,7 +83,7 @@ func (h *Organization) DepartmentUsers(c *gin.Context) {
|
|||
id, _ := strconv.ParseUint(c.Query("deptId"), 10, 64)
|
||||
ids, err := h.service.DepartmentUserIDs(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
|
|
@ -98,10 +98,10 @@ func (h *Organization) SetDepartmentUsers(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.SetDepartmentUsers(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "设置失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
func (h *Organization) SetUserDepartments(c *gin.Context) {
|
||||
var req dto.SetUserDepartmentsRequest
|
||||
|
|
@ -113,7 +113,7 @@ func (h *Organization) SetUserDepartments(c *gin.Context) {
|
|||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
||||
func (h *Organization) ListPositions(c *gin.Context) {
|
||||
|
|
@ -177,7 +177,7 @@ func (h *Organization) FindPosition(c *gin.Context) {
|
|||
id, _ := strconv.ParseUint(c.Query("id"), 10, 64)
|
||||
item, err := h.service.Position(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "获取成功")
|
||||
|
|
@ -186,7 +186,7 @@ func (h *Organization) PositionUsers(c *gin.Context) {
|
|||
id, _ := strconv.ParseUint(c.Query("positionId"), 10, 64)
|
||||
ids, err := h.service.PositionUserIDs(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
|
|
@ -201,10 +201,10 @@ func (h *Organization) SetPositionUsers(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.SetPositionUsers(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "设置失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
func (h *Organization) SetUserPositions(c *gin.Context) {
|
||||
var req dto.SetUserPositionsRequest
|
||||
|
|
@ -216,5 +216,5 @@ func (h *Organization) SetUserPositions(c *gin.Context) {
|
|||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,73 +20,65 @@ func NewParameter(service *service.SettingsService) *Parameter {
|
|||
|
||||
func (h *Parameter) Create(c *gin.Context) {
|
||||
var req dto.SystemParameterRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.Key == "" {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateParameterRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) Update(c *gin.Context) {
|
||||
var req dto.SystemParameterRequest
|
||||
if c.ShouldBindJSON(&req) != nil || req.ID == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateParameterRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) Delete(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
if err := h.service.DeleteParameters(c.Request.Context(), []uint{uint(id)}); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) DeleteMany(c *gin.Context) {
|
||||
ids := IDsFromQuery(c)
|
||||
if len(ids) == 0 {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteParameters(c.Request.Context(), ids); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "批量删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Parameter(c.Request.Context(), uint(id), "")
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
httpx.Fail(c, "查询失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
httpx.OKWithData(c, item)
|
||||
}
|
||||
|
||||
func (h *Parameter) Get(c *gin.Context) {
|
||||
item, err := h.service.Parameter(c.Request.Context(), 0, c.Query("key"))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "获取成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) List(c *gin.Context) {
|
||||
|
|
@ -99,7 +91,7 @@ func (h *Parameter) List(c *gin.Context) {
|
|||
}
|
||||
items, total, err := h.service.ParametersFilter(c.Request.Context(), p, size, c.Query("name"), c.Query("key"), start, end)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
httpx.Fail(c, "获取失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func (h *Permission) SetButtons(c *gin.Context) {
|
|||
httpx.Fail(c, "分配失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "分配成功")
|
||||
}
|
||||
|
||||
func (h *Permission) CanRemoveButton(c *gin.Context) {
|
||||
|
|
@ -52,5 +52,5 @@ func (h *Permission) CanRemoveButton(c *gin.Context) {
|
|||
httpx.Fail(c, "此按钮正在被使用无法删除")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ func (h *Session) Logout(c *gin.Context) {
|
|||
token, _ = c.Cookie("x-token")
|
||||
}
|
||||
if err := h.settings.BlacklistToken(c.Request.Context(), token); err != nil {
|
||||
httpx.Fail(c, "退出失败")
|
||||
httpx.Fail(c, "jwt作废失败")
|
||||
return
|
||||
}
|
||||
httpx.SetTokenCookie(c, "", -1)
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "jwt作废成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ func (h *SystemConfig) GetSecurity(c *gin.Context) {
|
|||
|
||||
func (h *SystemConfig) SetSecurity(c *gin.Context) {
|
||||
var req dto.SecurityConfigRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
result, err := h.settings.SaveSecurityRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "设置安全配置失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, result, "设置成功")
|
||||
|
|
@ -54,12 +54,12 @@ func (h *SystemConfig) Get(c *gin.Context) {
|
|||
|
||||
func (h *SystemConfig) Set(c *gin.Context) {
|
||||
var req dto.SetSystemConfigRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.system.SaveSystemConfig(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "配置保存失败: "+err.Error())
|
||||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func (h *Task) Create(c *gin.Context) {
|
|||
httpx.Fail(c, "调度失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建成功")
|
||||
}
|
||||
|
||||
func (h *Task) Update(c *gin.Context) {
|
||||
|
|
@ -55,7 +55,7 @@ func (h *Task) Update(c *gin.Context) {
|
|||
httpx.Fail(c, "调度失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "更新成功")
|
||||
}
|
||||
|
||||
func (h *Task) Delete(c *gin.Context) {
|
||||
|
|
@ -69,7 +69,7 @@ func (h *Task) Delete(c *gin.Context) {
|
|||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *Task) Toggle(c *gin.Context) {
|
||||
|
|
@ -79,14 +79,14 @@ func (h *Task) Toggle(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.Toggle(c.Request.Context(), req.ID, req.Enabled); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
httpx.Fail(c, "操作失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.scheduler.ScheduleID(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "调度失败")
|
||||
httpx.Fail(c, "操作失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "操作成功")
|
||||
}
|
||||
|
||||
func (h *Task) Trigger(c *gin.Context) {
|
||||
|
|
@ -96,10 +96,10 @@ func (h *Task) Trigger(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.scheduler.TriggerID(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "任务不存在")
|
||||
httpx.Fail(c, "触发失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "已触发, 执行结果见执行日志")
|
||||
}
|
||||
|
||||
func (h *Task) List(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ func (h *User) Update(c *gin.Context) {
|
|||
httpx.Fail(c, "修改失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
||||
func (h *User) UpdateSelf(c *gin.Context) {
|
||||
|
|
@ -73,7 +73,7 @@ func (h *User) UpdateSelf(c *gin.Context) {
|
|||
httpx.Fail(c, "修改失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
||||
func (h *User) Delete(c *gin.Context) {
|
||||
|
|
@ -91,7 +91,7 @@ func (h *User) Delete(c *gin.Context) {
|
|||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *User) ResetPassword(c *gin.Context) {
|
||||
|
|
@ -101,10 +101,10 @@ func (h *User) ResetPassword(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if err := h.service.ResetPassword(c.Request.Context(), req.ID, req.Password); err != nil {
|
||||
httpx.Fail(c, "重置失败")
|
||||
httpx.Fail(c, "重置失败"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "重置成功")
|
||||
}
|
||||
|
||||
func (h *User) ChangePassword(c *gin.Context) {
|
||||
|
|
@ -118,7 +118,7 @@ func (h *User) ChangePassword(c *gin.Context) {
|
|||
httpx.Fail(c, "修改失败,原密码与当前账户不符")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "修改成功")
|
||||
}
|
||||
|
||||
func (h *User) SetSelfSetting(c *gin.Context) {
|
||||
|
|
@ -132,7 +132,7 @@ func (h *User) SetSelfSetting(c *gin.Context) {
|
|||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "设置成功")
|
||||
}
|
||||
|
||||
func (h *User) SetAuthorities(c *gin.Context) {
|
||||
|
|
@ -145,7 +145,7 @@ func (h *User) SetAuthorities(c *gin.Context) {
|
|||
httpx.Fail(c, "修改失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "修改成功")
|
||||
}
|
||||
|
||||
func (h *User) SwitchAuthority(c *gin.Context) {
|
||||
|
|
@ -164,7 +164,7 @@ func (h *User) SwitchAuthority(c *gin.Context) {
|
|||
c.Header("new-expires-at", strconv.FormatInt(login.ExpiresAt/1000, 10))
|
||||
maxAge := int(time.Until(time.UnixMilli(login.ExpiresAt)).Seconds())
|
||||
httpx.SetTokenCookie(c, login.Token, maxAge)
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "修改成功")
|
||||
}
|
||||
|
||||
func (h *User) Get(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (h *Version) Find(c *gin.Context) {
|
|||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
httpx.OKWithData(c, item)
|
||||
}
|
||||
func (h *Version) List(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ import (
|
|||
)
|
||||
|
||||
// ProviderSet is server providers.
|
||||
var ProviderSet = wire.NewSet(NewGinServer, handler.NewAuthority, handler.NewMenu, handler.NewAPI, handler.NewPermission, handler.NewOrganization, handler.NewAnnouncement, handler.NewEmail, handler.NewTask, handler.NewMedia, handler.NewAudit, handler.NewExport, handler.NewVersion, handler.NewDictionary, handler.NewParameter, handler.NewAPIToken, handler.NewSystemConfig, handler.NewPublic, handler.NewUser, handler.NewNavigation, handler.NewSession, worker.NewTaskScheduler)
|
||||
var ProviderSet = wire.NewSet(NewGinEngine, NewGinServer, handler.NewAuthority, handler.NewMenu, handler.NewAPI, handler.NewPermission, handler.NewOrganization, handler.NewAnnouncement, handler.NewEmail, handler.NewTask, handler.NewMedia, handler.NewAudit, handler.NewExport, handler.NewVersion, handler.NewDictionary, handler.NewParameter, handler.NewAPIToken, handler.NewSystemConfig, handler.NewPublic, handler.NewUser, handler.NewNavigation, handler.NewSession, worker.NewTaskScheduler)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ type apiMetadataValue struct{ group, description string }
|
|||
|
||||
var apiMetadata = map[string]apiMetadataValue{
|
||||
"DELETE /api/deleteApisByIds": {group: "api", description: "批量删除api"},
|
||||
"DELETE /customer/customer": {group: "客户", description: "删除客户"},
|
||||
"DELETE /dataAccessLog/deleteDataAccessLogByIds": {group: "数据权限审计", description: "批量删除数据权限审计日志"},
|
||||
"DELETE /department/deleteDepartment": {group: "部门", description: "删除部门"},
|
||||
"DELETE /info/deleteInfo": {group: "公告", description: "删除公告"},
|
||||
|
|
@ -35,8 +34,6 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"GET /attachmentCategory/getCategoryList": {group: "媒体库分类", description: "分类列表"},
|
||||
"GET /authority/getDataScopeDepts": {group: "角色", description: "获取角色自定义部门集"},
|
||||
"GET /authority/getUsersByAuthority": {group: "角色", description: "获取角色关联用户ID列表"},
|
||||
"GET /customer/customer": {group: "客户", description: "获取单一客户"},
|
||||
"GET /customer/customerList": {group: "客户", description: "获取客户列表"},
|
||||
"GET /department/findDepartment": {group: "部门", description: "根据ID获取部门"},
|
||||
"GET /department/getDepartmentUsers": {group: "部门", description: "获取部门成员ID列表"},
|
||||
"GET /info/findInfo": {group: "公告", description: "根据ID获取公告"},
|
||||
|
|
@ -48,8 +45,6 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"GET /position/findPosition": {group: "岗位", description: "根据ID获取岗位"},
|
||||
"GET /position/getPositionUsers": {group: "岗位", description: "获取岗位成员ID列表"},
|
||||
"GET /securityConfig/getSecurityConfig": {group: "安全配置", description: "获取安全配置"},
|
||||
"GET /simpleUploader/checkFileMd5": {group: "断点续传(插件版)", description: "文件完整度验证"},
|
||||
"GET /simpleUploader/mergeFileMd5": {group: "断点续传(插件版)", description: "上传完成合并文件"},
|
||||
"GET /sysDictionary/exportSysDictionary": {group: "系统字典", description: "导出字典JSON"},
|
||||
"GET /sysDictionary/findSysDictionary": {group: "系统字典", description: "根据ID获取字典(建议选择)"},
|
||||
"GET /sysDictionary/getSysDictionaryList": {group: "系统字典", description: "获取字典列表"},
|
||||
|
|
@ -62,7 +57,6 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"GET /sysDictionaryDetail/getSysDictionaryDetailList": {group: "系统字典详情", description: "获取字典内容列表"},
|
||||
"GET /sysError/findSysError": {group: "错误日志", description: "根据ID获取错误日志"},
|
||||
"GET /sysError/getSysErrorList": {group: "错误日志", description: "获取错误日志列表"},
|
||||
"GET /sysError/getSysErrorSolution": {group: "错误日志", description: "触发错误处理(异步)"},
|
||||
"GET /sysExportTemplate/exportExcel": {group: "导出模板", description: "导出Excel"},
|
||||
"GET /sysExportTemplate/exportTemplate": {group: "导出模板", description: "下载模板"},
|
||||
"GET /sysExportTemplate/findSysExportTemplate": {group: "导出模板", description: "根据ID获取导出模板"},
|
||||
|
|
@ -103,12 +97,8 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"POST /authorityBtn/canRemoveAuthorityBtn": {group: "按钮权限", description: "删除按钮"},
|
||||
"POST /authorityBtn/getAuthorityBtn": {group: "按钮权限", description: "获取已有按钮权限"},
|
||||
"POST /authorityBtn/setAuthorityBtn": {group: "按钮权限", description: "设置按钮权限"},
|
||||
"POST /autoCode/initAPI": {group: "代码生成器", description: "生成插件 API 初始化文件"},
|
||||
"POST /autoCode/initDictionary": {group: "代码生成器", description: "生成插件字典初始化文件"},
|
||||
"POST /autoCode/initMenu": {group: "代码生成器", description: "生成插件菜单初始化文件"},
|
||||
"POST /casbin/getPolicyPathByAuthorityId": {group: "casbin", description: "获取权限列表"},
|
||||
"POST /casbin/updateCasbin": {group: "casbin", description: "更改角色api权限"},
|
||||
"POST /customer/customer": {group: "客户", description: "创建客户"},
|
||||
"POST /dataAccessLog/getDataAccessLogList": {group: "数据权限审计", description: "获取数据权限审计日志"},
|
||||
"POST /department/createDepartment": {group: "部门", description: "创建部门"},
|
||||
"POST /department/getDepartmentList": {group: "部门", description: "获取部门树"},
|
||||
|
|
@ -139,7 +129,6 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"POST /position/getPositionList": {group: "岗位", description: "获取岗位列表"},
|
||||
"POST /position/setPositionUsers": {group: "岗位", description: "设置岗位成员(反向分配)"},
|
||||
"POST /securityConfig/setSecurityConfig": {group: "安全配置", description: "设置安全配置"},
|
||||
"POST /simpleUploader/upload": {group: "断点续传(插件版)", description: "插件版分片上传"},
|
||||
"POST /sysApiToken/createApiToken": {group: "API Token", description: "签发API Token"},
|
||||
"POST /sysApiToken/deleteApiToken": {group: "API Token", description: "作废API Token"},
|
||||
"POST /sysApiToken/getApiTokenList": {group: "API Token", description: "获取API Token列表"},
|
||||
|
|
@ -168,7 +157,6 @@ var apiMetadata = map[string]apiMetadataValue{
|
|||
"POST /user/setUserDepartments": {group: "系统用户", description: "设置用户归属部门"},
|
||||
"POST /user/setUserPositions": {group: "系统用户", description: "设置用户岗位"},
|
||||
"PUT /authority/updateAuthority": {group: "角色", description: "更新角色信息"},
|
||||
"PUT /customer/customer": {group: "客户", description: "更新客户"},
|
||||
"PUT /department/updateDepartment": {group: "部门", description: "更新部门"},
|
||||
"PUT /info/updateInfo": {group: "公告", description: "更新公告"},
|
||||
"PUT /position/updatePosition": {group: "岗位", description: "更新岗位"},
|
||||
|
|
|
|||
|
|
@ -14,8 +14,12 @@ func dictionaryDomain(value *dto.DictionaryRequest) *biz.Dictionary {
|
|||
}
|
||||
return &biz.Dictionary{ID: value.ID, Name: value.Name, Type: value.Type, Status: status, Desc: value.Description, ParentID: value.ParentID}
|
||||
}
|
||||
func (s *SettingsService) CreateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) error {
|
||||
return s.CreateDictionary(ctx, dictionaryDomain(req))
|
||||
func (s *SettingsService) CreateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) (map[string]any, error) {
|
||||
value := dictionaryDomain(req)
|
||||
if err := s.CreateDictionary(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dictionaryDTO(value), nil
|
||||
}
|
||||
func (s *SettingsService) UpdateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) error {
|
||||
return s.UpdateDictionary(ctx, dictionaryDomain(req))
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ func (s *SettingsService) ImportDictionaryJSON(ctx context.Context, raw string)
|
|||
}
|
||||
return s.uc.ImportDictionary(ctx, dictionary, details)
|
||||
}
|
||||
func (s *SettingsService) DictionaryDetailsByParent(ctx context.Context, dictionaryID, parentID uint) ([]map[string]any, error) {
|
||||
items, err := s.uc.DictionaryDetailsByParent(ctx, dictionaryID, parentID)
|
||||
func (s *SettingsService) DictionaryDetailsByParent(ctx context.Context, dictionaryID uint, parentID *uint, includeChildren bool) ([]map[string]any, error) {
|
||||
items, err := s.uc.DictionaryDetailsByParent(ctx, dictionaryID, parentID, includeChildren)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ type InitUploadRequest struct {
|
|||
FileSize int64 `json:"fileSize"`
|
||||
ChunkSize int64 `json:"chunkSize"`
|
||||
ChunkTotal int `json:"chunkTotal"`
|
||||
Mime string `json:"mime"`
|
||||
}
|
||||
type CompleteUploadRequest struct {
|
||||
UploadID uint `json:"uploadId"`
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ type DictionaryDetailRequest struct {
|
|||
type ImportDictionaryRequest struct {
|
||||
JSON string `json:"json"`
|
||||
}
|
||||
type DictionaryDetailsByParentRequest struct {
|
||||
DictionaryID uint `json:"sysDictionaryID" form:"sysDictionaryID" binding:"required"`
|
||||
ParentID *uint `json:"parentID" form:"parentID"`
|
||||
IncludeChildren bool `json:"includeChildren" form:"includeChildren"`
|
||||
}
|
||||
type SystemParameterRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Name string `json:"name" form:"name"`
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ type SetSystemConfigRequest struct {
|
|||
PathPrefix string `json:"pathPrefix"`
|
||||
} `json:"local"`
|
||||
Media struct {
|
||||
SessionTTL int32 `json:"sessionTtl"`
|
||||
SessionTTL int32 `json:"sessionTtl"`
|
||||
MaxFileSize int64 `json:"maxFileSize"`
|
||||
} `json:"media"`
|
||||
Storage *conf.AdminBackend_Storage `json:"storage"`
|
||||
Zap *conf.AdminBackend_Zap `json:"zap"`
|
||||
|
|
|
|||
|
|
@ -5,12 +5,24 @@ import (
|
|||
"io"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/conf"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type MediaService struct{ uc *biz.MediaUsecase }
|
||||
type MediaService struct {
|
||||
uc *biz.MediaUsecase
|
||||
runtime *conf.Runtime
|
||||
}
|
||||
|
||||
func NewMediaService(uc *biz.MediaUsecase) *MediaService { return &MediaService{uc: uc} }
|
||||
func NewMediaService(uc *biz.MediaUsecase, runtime *conf.Runtime) *MediaService {
|
||||
return &MediaService{uc: uc, runtime: runtime}
|
||||
}
|
||||
func (s *MediaService) MediaConfig() *conf.AdminBackend_Media {
|
||||
if config := s.runtime.Admin(); config != nil {
|
||||
return config.Media
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func mediaDTO(v *biz.MediaFile) map[string]any {
|
||||
return map[string]any{"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}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func (s *SystemService) SystemConfig() map[string]any {
|
|||
admin["local"] = map[string]any{"storePath": config.Local.StorePath, "pathPrefix": config.Local.PathPrefix}
|
||||
}
|
||||
if config.Media != nil {
|
||||
admin["media"] = map[string]any{"sessionTtl": config.Media.SessionTtl}
|
||||
admin["media"] = map[string]any{"sessionTtl": config.Media.SessionTtl, "maxFileSize": config.Media.MaxFileSize}
|
||||
}
|
||||
if config.Email != nil {
|
||||
email = map[string]any{"to": config.Email.To, "from": config.Email.From, "host": config.Email.Host, "secret": "******", "nickname": config.Email.Nickname, "port": config.Email.Port, "is-ssl": config.Email.IsSsl, "is-loginauth": config.Email.IsLoginAuth}
|
||||
|
|
@ -169,8 +169,11 @@ func (s *SystemService) SaveSystemConfig(ctx context.Context, req *dto.SetSystem
|
|||
next.Local.PathPrefix = req.Config.Admin.Local.PathPrefix
|
||||
}
|
||||
}
|
||||
if next.Media != nil && req.Config.Admin.Media.SessionTTL > 0 {
|
||||
next.Media.SessionTtl = req.Config.Admin.Media.SessionTTL
|
||||
if next.Media != nil {
|
||||
if req.Config.Admin.Media.SessionTTL > 0 {
|
||||
next.Media.SessionTtl = req.Config.Admin.Media.SessionTTL
|
||||
}
|
||||
next.Media.MaxFileSize = req.Config.Admin.Media.MaxFileSize
|
||||
}
|
||||
if req.Config.Admin.Storage != nil {
|
||||
preserveStorageSecrets(req.Config.Admin.Storage, next.Storage)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package logging
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-kratos/kratos/contrib/otel/v3/tracing"
|
||||
|
|
@ -20,6 +22,85 @@ type Options struct {
|
|||
FileOnlyModules []string
|
||||
}
|
||||
|
||||
type handlerOperation struct {
|
||||
attrs []slog.Attr
|
||||
group string
|
||||
}
|
||||
|
||||
type reloadableHandlerState struct {
|
||||
mu sync.RWMutex
|
||||
handler slog.Handler
|
||||
cleanup func()
|
||||
}
|
||||
|
||||
type reloadableHandler struct {
|
||||
state *reloadableHandlerState
|
||||
ops []handlerOperation
|
||||
}
|
||||
|
||||
func (h *reloadableHandler) resolved() slog.Handler {
|
||||
current := h.state.handler
|
||||
for _, operation := range h.ops {
|
||||
if operation.group != "" {
|
||||
current = current.WithGroup(operation.group)
|
||||
} else {
|
||||
current = current.WithAttrs(operation.attrs)
|
||||
}
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
func (h *reloadableHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
h.state.mu.RLock()
|
||||
defer h.state.mu.RUnlock()
|
||||
return h.resolved().Enabled(ctx, level)
|
||||
}
|
||||
|
||||
func (h *reloadableHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
h.state.mu.RLock()
|
||||
defer h.state.mu.RUnlock()
|
||||
return h.resolved().Handle(ctx, record)
|
||||
}
|
||||
|
||||
func (h *reloadableHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
next := append([]handlerOperation(nil), h.ops...)
|
||||
next = append(next, handlerOperation{attrs: append([]slog.Attr(nil), attrs...)})
|
||||
return &reloadableHandler{state: h.state, ops: next}
|
||||
}
|
||||
|
||||
func (h *reloadableHandler) WithGroup(name string) slog.Handler {
|
||||
next := append([]handlerOperation(nil), h.ops...)
|
||||
next = append(next, handlerOperation{group: name})
|
||||
return &reloadableHandler{state: h.state, ops: next}
|
||||
}
|
||||
|
||||
type ReloadableLogger struct {
|
||||
state *reloadableHandlerState
|
||||
filename string
|
||||
}
|
||||
|
||||
func (l *ReloadableLogger) Reload(root string, options Options) {
|
||||
handler, cleanup := newZapHandler(root, l.filename, options)
|
||||
l.state.mu.Lock()
|
||||
previous := l.state.cleanup
|
||||
l.state.handler = handler
|
||||
l.state.cleanup = cleanup
|
||||
l.state.mu.Unlock()
|
||||
if previous != nil {
|
||||
previous()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ReloadableLogger) Close() {
|
||||
l.state.mu.Lock()
|
||||
cleanup := l.state.cleanup
|
||||
l.state.cleanup = nil
|
||||
l.state.mu.Unlock()
|
||||
if cleanup != nil {
|
||||
cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
type moduleFilterCore struct {
|
||||
zapcore.Core
|
||||
fileOnly map[string]struct{}
|
||||
|
|
@ -63,7 +144,7 @@ func moduleField(fields []zapcore.Field) string {
|
|||
|
||||
// NewZapLogger adapts a Zap core to the slog logger used by Kratos v3.
|
||||
// The file layout remains compatible with the administration log viewer.
|
||||
func NewZapLogger(root, filename string, options Options, attrs ...any) (*slog.Logger, func()) {
|
||||
func newZapHandler(root, filename string, options Options) (slog.Handler, func()) {
|
||||
file := NewDailyWriter(root, filename, options.RetentionDay)
|
||||
encoder := zap.NewProductionEncoderConfig()
|
||||
encoder.EncodeTime = zapcore.RFC3339NanoTimeEncoder
|
||||
|
|
@ -114,10 +195,24 @@ func NewZapLogger(root, filename string, options Options, attrs ...any) (*slog.L
|
|||
handlerOptions = append(handlerOptions, zapslog.WithCaller(true))
|
||||
}
|
||||
handler := zapslog.NewHandler(zapLogger.Core(), handlerOptions...)
|
||||
logger := kratoslog.NewLogger(handler, kratoslog.WithExtractor(tracing.TraceAttrs)).With(attrs...)
|
||||
cleanup := func() {
|
||||
_ = zapLogger.Sync()
|
||||
_ = file.Close()
|
||||
}
|
||||
return logger, cleanup
|
||||
return handler, cleanup
|
||||
}
|
||||
|
||||
// NewReloadableZapLogger keeps the slog/Kratos adapter stable while replacing
|
||||
// the underlying Zap core when the runtime configuration changes.
|
||||
func NewReloadableZapLogger(root, filename string, options Options, attrs ...any) (*slog.Logger, *ReloadableLogger) {
|
||||
handler, cleanup := newZapHandler(root, filename, options)
|
||||
state := &reloadableHandlerState{handler: handler, cleanup: cleanup}
|
||||
control := &ReloadableLogger{state: state, filename: filename}
|
||||
logger := kratoslog.NewLogger(&reloadableHandler{state: state}, kratoslog.WithExtractor(tracing.TraceAttrs)).With(attrs...)
|
||||
return logger, control
|
||||
}
|
||||
|
||||
func NewZapLogger(root, filename string, options Options, attrs ...any) (*slog.Logger, func()) {
|
||||
logger, control := NewReloadableZapLogger(root, filename, options, attrs...)
|
||||
return logger, control.Close
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@
|
|||
<el-form-item label="大文件上传会话有效期(小时)">
|
||||
<el-input-number v-model="config.admin.media.sessionTtl" :min="1" :max="720" class="!w-full" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单文件最大字节数(0 为不限)">
|
||||
<el-input-number v-model="config.admin.media.maxFileSize" :min="0" class="!w-full" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运行开关" class="md:col-span-2">
|
||||
<div class="flex flex-wrap gap-5">
|
||||
<el-switch v-model="config.admin.system.useRedis" active-text="启用 Redis" />
|
||||
|
|
@ -226,7 +229,7 @@
|
|||
routerPrefix: '',
|
||||
jwt: { signingKey: '******', expiresTime: '168h', bufferTime: '24h', issuer: 'kra' },
|
||||
captcha: { keyLong: 6, imgWidth: 240, imgHeight: 80, storeExpiration: '3m' },
|
||||
local: { storePath: 'uploads/file', pathPrefix: 'uploads/file' }, media: { sessionTtl: 24 },
|
||||
local: { storePath: 'uploads/file', pathPrefix: 'uploads/file' }, media: { sessionTtl: 24, maxFileSize: 0 },
|
||||
zap: { level: 'info', prefix: '[kra] ', format: 'json', director: 'logs', encode_level: 'LowercaseLevelEncoder', stacktrace_key: 'stacktrace', show_line: true, log_in_console: true, retention_day: 7, access_req_body: true, access_resp_data: true, access_req_headers: false, access_log_max_bytes: 32768, file_only_modules: [] },
|
||||
cors: { mode: 'whitelist', whitelist: [] }, app: { node: '', app_id: 'kra', env: 'development' },
|
||||
system: { useRedis: false, useMultipoint: false, useStrictAuth: false, disableAutoMigrate: false, useMongo: false },
|
||||
|
|
|
|||
Loading…
Reference in New Issue