mirror of https://github.com/go-sonic/sonic.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
8.4 KiB
Go
240 lines
8.4 KiB
Go
package impl
|
|
|
|
import (
|
|
"context"
|
|
"mime/multipart"
|
|
"os"
|
|
"strings"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/go-sonic/sonic/consts"
|
|
"github.com/go-sonic/sonic/dal"
|
|
"github.com/go-sonic/sonic/log"
|
|
"github.com/go-sonic/sonic/model/dto"
|
|
"github.com/go-sonic/sonic/model/entity"
|
|
"github.com/go-sonic/sonic/model/param"
|
|
"github.com/go-sonic/sonic/service"
|
|
"github.com/go-sonic/sonic/service/file_storage"
|
|
"github.com/go-sonic/sonic/util/xerr"
|
|
)
|
|
|
|
type attachmentServiceImpl struct {
|
|
OptionService service.OptionService
|
|
FileStorageComposite file_storage.FileStorageComposite
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) ConvertToDTOs(ctx context.Context, attachments []*entity.Attachment) ([]*dto.AttachmentDTO, error) {
|
|
dtos := make([]*dto.AttachmentDTO, 0, len(attachments))
|
|
for _, attachment := range attachments {
|
|
dto := &dto.AttachmentDTO{
|
|
ID: attachment.ID,
|
|
Name: attachment.Name,
|
|
Path: attachment.Path,
|
|
FileKey: attachment.FileKey,
|
|
ThumbPath: attachment.ThumbPath,
|
|
MediaType: attachment.MediaType,
|
|
Suffix: attachment.Suffix,
|
|
Width: attachment.Width,
|
|
Height: attachment.Height,
|
|
Size: attachment.Size,
|
|
AttachmentType: consts.AttachmentType(attachment.Type),
|
|
}
|
|
dtos = append(dtos, dto)
|
|
path, err := a.FileStorageComposite.GetFileStorage(consts.AttachmentType(attachment.Type)).GetFilePath(ctx, attachment.Path)
|
|
if err != nil {
|
|
log.CtxError(ctx, "GetFilePath err", zap.Error(err))
|
|
}
|
|
thumbPath, err := a.FileStorageComposite.GetFileStorage(consts.AttachmentType(attachment.Type)).GetFilePath(ctx, attachment.ThumbPath)
|
|
if err != nil {
|
|
log.CtxError(ctx, "GetFilePath err", zap.Error(err))
|
|
}
|
|
dto.Path = path
|
|
dto.ThumbPath = thumbPath
|
|
}
|
|
return dtos, nil
|
|
}
|
|
|
|
func NewAttachmentService(optionService service.OptionService, fileStorageComposite file_storage.FileStorageComposite) service.AttachmentService {
|
|
return &attachmentServiceImpl{
|
|
FileStorageComposite: fileStorageComposite,
|
|
OptionService: optionService,
|
|
}
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) ConvertToDTO(ctx context.Context, attachment *entity.Attachment) (*dto.AttachmentDTO, error) {
|
|
dto := &dto.AttachmentDTO{
|
|
ID: attachment.ID,
|
|
Name: attachment.Name,
|
|
Path: attachment.Path,
|
|
FileKey: attachment.FileKey,
|
|
ThumbPath: attachment.ThumbPath,
|
|
MediaType: attachment.MediaType,
|
|
Suffix: attachment.Suffix,
|
|
Width: attachment.Width,
|
|
Height: attachment.Height,
|
|
Size: attachment.Size,
|
|
AttachmentType: consts.AttachmentType(attachment.Type),
|
|
}
|
|
path, err := a.FileStorageComposite.GetFileStorage(consts.AttachmentType(attachment.Type)).GetFilePath(ctx, attachment.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
thumbPath, err := a.FileStorageComposite.GetFileStorage(consts.AttachmentType(attachment.Type)).GetFilePath(ctx, attachment.ThumbPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dto.Path = path
|
|
dto.ThumbPath = thumbPath
|
|
return dto, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) Page(ctx context.Context, queryParam *param.AttachmentQuery) ([]*entity.Attachment, int64, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
attachmentDo := attachmentDAL.WithContext(ctx)
|
|
if queryParam.Keyword != "" {
|
|
attachmentDo = attachmentDo.Where(attachmentDAL.Name.Like(queryParam.Keyword))
|
|
}
|
|
if queryParam.PageNum >= 0 && queryParam.PageSize >= 0 {
|
|
if queryParam.PageSize > 50 {
|
|
queryParam.PageSize = 50
|
|
}
|
|
} else {
|
|
queryParam.PageSize = 10
|
|
queryParam.PageNum = 0
|
|
}
|
|
if queryParam.Keyword != "" {
|
|
attachmentDo = attachmentDo.Where(attachmentDAL.Name.Like(queryParam.Keyword))
|
|
}
|
|
if queryParam.AttachmentType != nil {
|
|
attachmentDo = attachmentDo.Where(attachmentDAL.Type.Eq(*queryParam.AttachmentType))
|
|
}
|
|
if queryParam.MediaType != "" {
|
|
attachmentDo = attachmentDo.Where(attachmentDAL.MediaType.Eq(queryParam.MediaType))
|
|
}
|
|
attachments, totalCount, err := attachmentDo.FindByPage(queryParam.PageNum*queryParam.PageSize, queryParam.PageSize)
|
|
if err != nil {
|
|
return nil, 0, WrapDBErr(err)
|
|
}
|
|
return attachments, totalCount, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) GetAttachment(ctx context.Context, attachmentID int32) (*entity.Attachment, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
attachment, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.ID.Eq(attachmentID)).Take()
|
|
if err != nil {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
return attachment, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) Upload(ctx context.Context, fileHeader *multipart.FileHeader) (attachmentDTO *dto.AttachmentDTO, err error) {
|
|
|
|
attachmentType := a.OptionService.GetAttachmentType(ctx)
|
|
|
|
fileStorage := a.FileStorageComposite.GetFileStorage(attachmentType)
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
|
|
attachmentDTO, err = fileStorage.Upload(ctx, fileHeader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
record, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.Path.Eq(attachmentDTO.Path)).Take()
|
|
if record != nil && err == nil {
|
|
return nil, xerr.BadParam.New("附件路径为 " + attachmentDTO.Path + " 已经存在").
|
|
WithStatus(xerr.StatusBadRequest).
|
|
WithMsg("附件路径为 " + attachmentDTO.Path + " 已经存在")
|
|
}
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
attachmentEntity := &entity.Attachment{
|
|
FileKey: attachmentDTO.FileKey,
|
|
Height: attachmentDTO.Height,
|
|
MediaType: attachmentDTO.MediaType,
|
|
Name: attachmentDTO.Name,
|
|
Path: strings.ReplaceAll(attachmentDTO.Path, string(os.PathSeparator), "/"),
|
|
Size: attachmentDTO.Size,
|
|
Suffix: attachmentDTO.Suffix,
|
|
ThumbPath: attachmentDTO.ThumbPath,
|
|
Type: attachmentDTO.AttachmentType,
|
|
Width: attachmentDTO.Width,
|
|
}
|
|
|
|
// change file path separator to url separator
|
|
if err = attachmentDAL.WithContext(ctx).Create(attachmentEntity); err != nil {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
attachmentDTO.ID = attachmentEntity.ID
|
|
|
|
return attachmentDTO, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) Delete(ctx context.Context, attachmentID int32) (*entity.Attachment, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
attachment, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.ID.Eq(attachmentID)).Take()
|
|
if err != nil {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
result, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.ID.Eq(attachmentID)).Delete()
|
|
if err != nil || result.RowsAffected != 1 {
|
|
return nil, xerr.WithMsg(err, "delete file failed")
|
|
}
|
|
fileStorage := a.FileStorageComposite.GetFileStorage(consts.AttachmentType(attachment.Type))
|
|
err = fileStorage.Delete(ctx, attachment.FileKey)
|
|
if err != nil {
|
|
return nil, xerr.WithMsg(err, "delete file failed")
|
|
}
|
|
return attachment, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) DeleteBatch(ctx context.Context, IDs []int32) (attachments []*entity.Attachment, err error) {
|
|
attachments = make([]*entity.Attachment, 0)
|
|
var globalErr error
|
|
for _, id := range IDs {
|
|
attachment, err := a.Delete(ctx, id)
|
|
if err != nil {
|
|
globalErr = err
|
|
} else {
|
|
attachments = append(attachments, attachment)
|
|
}
|
|
}
|
|
if globalErr != nil {
|
|
return attachments, xerr.NoType.Wrap(err).WithMsg("Failed to delete some files")
|
|
}
|
|
return attachments, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) Update(ctx context.Context, id int32, updateParam *param.AttachmentUpdate) (*entity.Attachment, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
attachment, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.ID.Eq(id)).Take()
|
|
if err != nil {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
result, err := attachmentDAL.WithContext(ctx).Where(attachmentDAL.ID.Eq(id)).Updates(entity.Attachment{Name: updateParam.Name})
|
|
if err != nil {
|
|
return nil, WrapDBErr(err)
|
|
}
|
|
if result.RowsAffected != 1 {
|
|
return nil, xerr.NoType.New("update failed")
|
|
}
|
|
attachment.Name = updateParam.Name
|
|
return attachment, nil
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) GetAllMediaTypes(ctx context.Context) ([]string, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
var allMediaTypes []string
|
|
err := attachmentDAL.WithContext(ctx).Distinct(attachmentDAL.MediaType).Select(attachmentDAL.MediaType).Scan(&allMediaTypes)
|
|
return allMediaTypes, WrapDBErr(err)
|
|
}
|
|
|
|
func (a *attachmentServiceImpl) GetAllTypes(ctx context.Context) ([]consts.AttachmentType, error) {
|
|
attachmentDAL := dal.GetQueryByCtx(ctx).Attachment
|
|
var allTypes []consts.AttachmentType
|
|
err := attachmentDAL.WithContext(ctx).Distinct(attachmentDAL.Type).Select(attachmentDAL.Type).Scan(&allTypes)
|
|
return allTypes, err
|
|
}
|