feat: 开发中...
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -39,3 +39,5 @@ out/
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
*.d.ts
|
*.d.ts
|
||||||
|
|
||||||
|
uploads/
|
@@ -13,6 +13,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
|
|||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
|
||||||
@@ -53,6 +54,18 @@ public class BlogExceptionHandler {
|
|||||||
return ResponseVO.failed(e.getMessage());
|
return ResponseVO.failed(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(IOException.class)
|
||||||
|
public ResponseVO<String> onIOException(IOException e) {
|
||||||
|
if ("dev".equals(environment.getProperty("spring.profiles.active"))) {
|
||||||
|
log.error("", e);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(writer));
|
||||||
|
// StringWriter 不需要 close()
|
||||||
|
return new ResponseVO<>(403, e.getMessage(), writer.toString());
|
||||||
|
}
|
||||||
|
return ResponseVO.failed(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public ResponseVO<String> onException(Exception e) {
|
public ResponseVO<String> onException(Exception e) {
|
||||||
if ("dev".equals(environment.getProperty("spring.profiles.active"))) {
|
if ("dev".equals(environment.getProperty("spring.profiles.active"))) {
|
||||||
@@ -64,4 +77,16 @@ public class BlogExceptionHandler {
|
|||||||
}
|
}
|
||||||
return ResponseVO.failed(e.getMessage());
|
return ResponseVO.failed(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(Throwable.class)
|
||||||
|
public ResponseVO<String> onThrowable(Throwable e) {
|
||||||
|
if ("dev".equals(environment.getProperty("spring.profiles.active"))) {
|
||||||
|
log.error("", e);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(writer));
|
||||||
|
// StringWriter 不需要 close()
|
||||||
|
return new ResponseVO<>(403, e.getMessage(), writer.toString());
|
||||||
|
}
|
||||||
|
return ResponseVO.failed(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,37 +1,66 @@
|
|||||||
package cn.hamster3.application.blog.controller;
|
package cn.hamster3.application.blog.controller;
|
||||||
|
|
||||||
|
import cn.hamster3.application.blog.service.IAttachService;
|
||||||
|
import cn.hamster3.application.blog.vo.PageableVO;
|
||||||
import cn.hamster3.application.blog.vo.ResponseVO;
|
import cn.hamster3.application.blog.vo.ResponseVO;
|
||||||
|
import cn.hamster3.application.blog.vo.attach.AttachInfoResponseVO;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
@Tag(name = "AttachController", description = "附件相关接口")
|
@Tag(name = "AttachController", description = "附件相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/api/v1/attach", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/api/v1/attach", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class AttachController {
|
public class AttachController {
|
||||||
|
@Resource
|
||||||
|
private IAttachService attachService;
|
||||||
|
|
||||||
@PostMapping("/")
|
@PostMapping("/")
|
||||||
public ResponseVO<Void> createAttach(@RequestBody MultipartFile file) {
|
@Operation(summary = "新建附件")
|
||||||
return ResponseVO.success();
|
public ResponseVO<Long> createAttach(@RequestParam MultipartFile file) throws IOException {
|
||||||
|
return attachService.createAttach(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{attachID}/")
|
@GetMapping("/{attachID}/")
|
||||||
public ResponseVO<Void> getAttach(@PathVariable String attachID) {
|
@Operation(summary = "获取附件信息")
|
||||||
return ResponseVO.success();
|
public ResponseVO<AttachInfoResponseVO> getAttachInfo(@PathVariable Long attachID) {
|
||||||
|
return attachService.getAttachInfo(attachID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{attachID}/content")
|
||||||
|
@Operation(summary = "获取附件内容")
|
||||||
|
public ResponseEntity<InputStreamResource> getAttachContent(@PathVariable Long attachID) throws IOException {
|
||||||
|
return attachService.getAttachContent(attachID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public ResponseVO<Void> getAttachList() {
|
@Operation(summary = "获取附件列表")
|
||||||
return ResponseVO.success();
|
public ResponseVO<PageableVO<AttachInfoResponseVO>> getAttachList(
|
||||||
|
@Parameter(description = "页码", example = "0") int page,
|
||||||
|
@Parameter(description = "大小", example = "10") int size
|
||||||
|
) {
|
||||||
|
return attachService.getAttachList(PageRequest.of(page, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{attachID}/")
|
@PutMapping("/{attachID}/")
|
||||||
public ResponseVO<Void> modifyAttach(@PathVariable String attachID, @RequestBody MultipartFile file) {
|
@Operation(summary = "更新附件")
|
||||||
return ResponseVO.success();
|
public ResponseVO<Void> updateAttach(@PathVariable Long attachID, @RequestParam MultipartFile file) throws IOException {
|
||||||
|
return attachService.updateAttach(attachID, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{attachID}/")
|
@DeleteMapping("/{attachID}/")
|
||||||
public ResponseVO<Void> deleteAttach(@PathVariable String attachID) {
|
@Operation(summary = "删除附件")
|
||||||
return ResponseVO.success();
|
public ResponseVO<Void> deleteAttach(@PathVariable Long attachID) {
|
||||||
|
return attachService.deleteAttach(attachID);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -21,6 +21,14 @@ public class AttachEntity {
|
|||||||
@Column(name = "id", nullable = false, updatable = false)
|
@Column(name = "id", nullable = false, updatable = false)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Column(name = "name", nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Column(name = "content_type", nullable = false)
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Lob
|
@Lob
|
||||||
@Basic(fetch = FetchType.LAZY)
|
@Basic(fetch = FetchType.LAZY)
|
||||||
|
@@ -4,8 +4,6 @@ import jakarta.persistence.*;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.hibernate.annotations.JdbcTypeCode;
|
|
||||||
import org.hibernate.type.SqlTypes;
|
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
import org.springframework.data.annotation.CreatedBy;
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
import org.springframework.data.annotation.CreatedDate;
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
import org.springframework.data.annotation.LastModifiedBy;
|
||||||
@@ -32,10 +30,6 @@ public class BlogEntity {
|
|||||||
@Column(name = "abstracts", nullable = false, length = 512)
|
@Column(name = "abstracts", nullable = false, length = 512)
|
||||||
private String abstracts;
|
private String abstracts;
|
||||||
|
|
||||||
@Column(name = "password", length = 60)
|
|
||||||
@JdbcTypeCode(SqlTypes.VARCHAR)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
@Lob
|
@Lob
|
||||||
@Basic(fetch = FetchType.LAZY)
|
@Basic(fetch = FetchType.LAZY)
|
||||||
|
@@ -3,20 +3,24 @@ package cn.hamster3.application.blog.entity.mapper;
|
|||||||
import cn.hamster3.application.blog.entity.AttachEntity;
|
import cn.hamster3.application.blog.entity.AttachEntity;
|
||||||
import cn.hamster3.application.blog.entity.UserEntity;
|
import cn.hamster3.application.blog.entity.UserEntity;
|
||||||
import cn.hamster3.application.blog.vo.attach.AttachInfoResponseVO;
|
import cn.hamster3.application.blog.vo.attach.AttachInfoResponseVO;
|
||||||
|
import cn.hamster3.application.blog.vo.user.UserInfoResponseVO;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.MappingConstants;
|
import org.mapstruct.MappingConstants;
|
||||||
import org.mapstruct.ReportingPolicy;
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
|
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
|
||||||
public interface AttachMapper {
|
public interface AttachMapper {
|
||||||
AttachInfoResponseVO entityToInfoVO(AttachEntity entity);
|
AttachInfoResponseVO entityToInfoVO(AttachEntity entity);
|
||||||
|
|
||||||
@NotNull
|
default UserInfoResponseVO mapToInfoVO(@NotNull UserEntity value) {
|
||||||
@SuppressWarnings("unused")
|
return new UserInfoResponseVO(
|
||||||
default UUID map(@NotNull UserEntity value) {
|
value.getId(),
|
||||||
return value.getId();
|
value.getEmail(),
|
||||||
|
value.getNickname(),
|
||||||
|
value.getRole(),
|
||||||
|
value.getCreateTime(),
|
||||||
|
value.getUpdateTime()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,20 +10,12 @@ import org.mapstruct.Mapper;
|
|||||||
import org.mapstruct.MappingConstants;
|
import org.mapstruct.MappingConstants;
|
||||||
import org.mapstruct.ReportingPolicy;
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
|
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
|
||||||
public interface BlogMapper {
|
public interface BlogMapper {
|
||||||
BlogEntity voToEntity(BlogUpdateRequireVO vo);
|
BlogEntity voToEntity(BlogUpdateRequireVO vo);
|
||||||
|
|
||||||
BlogInfoResponseVO entityToInfoVO(BlogEntity entity);
|
BlogInfoResponseVO entityToInfoVO(BlogEntity entity);
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
default UUID mapToUUID(@NotNull UserEntity value) {
|
|
||||||
return value.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
default UserInfoResponseVO mapToInfoVO(@NotNull UserEntity value) {
|
default UserInfoResponseVO mapToInfoVO(@NotNull UserEntity value) {
|
||||||
return new UserInfoResponseVO(
|
return new UserInfoResponseVO(
|
||||||
value.getId(),
|
value.getId(),
|
||||||
|
@@ -5,11 +5,22 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface AttachRepository extends JpaRepository<AttachEntity, Long>, JpaSpecificationExecutor<AttachEntity> {
|
public interface AttachRepository extends JpaRepository<AttachEntity, Long>, JpaSpecificationExecutor<AttachEntity> {
|
||||||
|
boolean existsByIdAndCreator_Id(Long id, UUID id1);
|
||||||
|
@Query("select a from AttachEntity a where a.id = ?1")
|
||||||
|
AttachEntity findByIdWithContent(Long id);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Modifying
|
||||||
|
@Query("update AttachEntity a set a.data = ?1, a.contentType = ?2 where a.id = ?3")
|
||||||
|
void updateDataAndContentTypeById(byte[] data, String contentType, Long id);
|
||||||
|
|
||||||
@Query("select a from AttachEntity a where a.creator.id = ?1 order by a.createTime DESC")
|
@Query("select a from AttachEntity a where a.creator.id = ?1 order by a.createTime DESC")
|
||||||
Page<AttachEntity> findByCreator_IdOrderByCreateTimeDesc(UUID id, Pageable pageable);
|
Page<AttachEntity> findByCreator_IdOrderByCreateTimeDesc(UUID id, Pageable pageable);
|
||||||
}
|
}
|
@@ -3,22 +3,26 @@ package cn.hamster3.application.blog.entity.repo;
|
|||||||
import cn.hamster3.application.blog.entity.BlogEntity;
|
import cn.hamster3.application.blog.entity.BlogEntity;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.*;
|
import org.springframework.data.jpa.repository.EntityGraph;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface BlogRepository extends JpaRepository<BlogEntity, Long>, JpaSpecificationExecutor<BlogEntity> {
|
public interface BlogRepository extends JpaRepository<BlogEntity, Long>, JpaSpecificationExecutor<BlogEntity> {
|
||||||
@Query("select b from BlogEntity b where b.creator.id = ?1 order by b.createTime DESC")
|
boolean existsByIdAndCreator_Id(Long id, UUID id1);
|
||||||
Page<BlogEntity> findByCreator_IdOrderByCreateTimeDesc(UUID id, Pageable pageable);
|
|
||||||
|
@EntityGraph(attributePaths = {"creator"})
|
||||||
|
@Query("select b from BlogEntity b where b.id = ?1")
|
||||||
|
BlogEntity findByIdWithCreator(Long id);
|
||||||
|
|
||||||
@EntityGraph(attributePaths = {"content"})
|
@EntityGraph(attributePaths = {"content"})
|
||||||
@Query("select b from BlogEntity b where b.id = ?1")
|
@Query("select b from BlogEntity b where b.id = ?1")
|
||||||
Optional<BlogEntity> findByIDWithContent(Long id);
|
Optional<BlogEntity> findByIdWithContent(Long id);
|
||||||
|
|
||||||
|
@Query("select b from BlogEntity b where b.creator.id = ?1 order by b.createTime DESC")
|
||||||
|
Page<BlogEntity> findByCreator_IdOrderByCreateTimeDesc(UUID id, Pageable pageable);
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Modifying
|
|
||||||
@Query("update BlogEntity b set b.title = ?1, b.abstracts = ?2, b.password = ?3, b.content = ?4 where b.id = ?5")
|
|
||||||
void updateTitleAndAbstractsAndPasswordAndContentById(String title, String abstracts, String password, String content, Long id);
|
|
||||||
}
|
}
|
@@ -1,4 +1,26 @@
|
|||||||
package cn.hamster3.application.blog.service;
|
package cn.hamster3.application.blog.service;
|
||||||
|
|
||||||
|
import cn.hamster3.application.blog.vo.PageableVO;
|
||||||
|
import cn.hamster3.application.blog.vo.ResponseVO;
|
||||||
|
import cn.hamster3.application.blog.vo.attach.AttachInfoResponseVO;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface IAttachService {
|
public interface IAttachService {
|
||||||
|
@NotNull ResponseVO<Long> createAttach(@NotNull MultipartFile file) throws IOException;
|
||||||
|
|
||||||
|
@NotNull ResponseVO<AttachInfoResponseVO> getAttachInfo(@NotNull Long attachID);
|
||||||
|
|
||||||
|
@NotNull ResponseEntity<InputStreamResource> getAttachContent(@NotNull Long attachID) throws IOException;
|
||||||
|
|
||||||
|
@NotNull ResponseVO<PageableVO<AttachInfoResponseVO>> getAttachList(@NotNull Pageable pageable);
|
||||||
|
|
||||||
|
@NotNull ResponseVO<Void> updateAttach(@NotNull Long attachID, @NotNull MultipartFile file) throws IOException;
|
||||||
|
|
||||||
|
@NotNull ResponseVO<Void> deleteAttach(@NotNull Long attachID);
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,155 @@
|
|||||||
package cn.hamster3.application.blog.service.impl;
|
package cn.hamster3.application.blog.service.impl;
|
||||||
|
|
||||||
|
import cn.hamster3.application.blog.config.security.BlogUser;
|
||||||
|
import cn.hamster3.application.blog.entity.AttachEntity;
|
||||||
|
import cn.hamster3.application.blog.entity.mapper.AttachMapper;
|
||||||
|
import cn.hamster3.application.blog.entity.repo.AttachRepository;
|
||||||
import cn.hamster3.application.blog.service.IAttachService;
|
import cn.hamster3.application.blog.service.IAttachService;
|
||||||
|
import cn.hamster3.application.blog.util.BlogUtils;
|
||||||
|
import cn.hamster3.application.blog.vo.PageableVO;
|
||||||
|
import cn.hamster3.application.blog.vo.ResponseVO;
|
||||||
|
import cn.hamster3.application.blog.vo.attach.AttachInfoResponseVO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class AttachService implements IAttachService {
|
public class AttachService implements IAttachService {
|
||||||
|
private static final File ATTACH_FOLDER = new File("uploads");
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (ATTACH_FOLDER.mkdirs()) {
|
||||||
|
log.info("attach folder created!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AttachMapper attachMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachRepository attachRepo;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseVO<Long> createAttach(@NotNull MultipartFile file) throws IOException {
|
||||||
|
ResponseVO<Long> checked = BlogUtils.checkAuthorPermission();
|
||||||
|
if (checked != null) {
|
||||||
|
return checked;
|
||||||
|
}
|
||||||
|
log.info("prepare to save file: {}({} bytes)", file.getOriginalFilename(), file.getSize());
|
||||||
|
AttachEntity attachEntity = new AttachEntity();
|
||||||
|
attachEntity.setName(file.getOriginalFilename());
|
||||||
|
attachEntity.setContentType(file.getContentType());
|
||||||
|
attachEntity.setData(file.getBytes());
|
||||||
|
attachEntity = attachRepo.save(attachEntity);
|
||||||
|
|
||||||
|
File localCacheFile = new File(ATTACH_FOLDER, String.valueOf(attachEntity.getId()));
|
||||||
|
Files.copy(file.getInputStream(), localCacheFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
return ResponseVO.success(attachEntity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseVO<AttachInfoResponseVO> getAttachInfo(@NotNull Long attachID) {
|
||||||
|
AttachEntity entity = attachRepo.findById(attachID).orElse(null);
|
||||||
|
if (entity == null) {
|
||||||
|
return ResponseVO.notFound();
|
||||||
|
}
|
||||||
|
return ResponseVO.success(attachMapper.entityToInfoVO(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseEntity<InputStreamResource> getAttachContent(@NotNull Long attachID) throws IOException {
|
||||||
|
File localCacheFile = new File(ATTACH_FOLDER, String.valueOf(attachID));
|
||||||
|
AttachEntity entity;
|
||||||
|
if (localCacheFile.exists()) {
|
||||||
|
entity = attachRepo.findById(attachID).orElse(null);
|
||||||
|
} else {
|
||||||
|
entity = attachRepo.findByIdWithContent(attachID);
|
||||||
|
}
|
||||||
|
if (entity == null) {
|
||||||
|
return ResponseEntity.notFound().build();
|
||||||
|
}
|
||||||
|
if (!localCacheFile.exists()) {
|
||||||
|
try (ByteArrayInputStream stream = new ByteArrayInputStream(entity.getData())) {
|
||||||
|
Files.copy(stream, localCacheFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InputStream stream = Files.newInputStream(localCacheFile.toPath());
|
||||||
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.header("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
.header("Content-Disposition", String.format("attachment; filename=\"%s\"", entity.getName()))
|
||||||
|
.header("Pragma", "no-cache")
|
||||||
|
.header("Expires", "0")
|
||||||
|
.contentLength(localCacheFile.length())
|
||||||
|
.contentType(MediaType.parseMediaType(entity.getContentType()))
|
||||||
|
.body(new InputStreamResource(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseVO<PageableVO<AttachInfoResponseVO>> getAttachList(@NotNull Pageable pageable) {
|
||||||
|
return PageableVO.success(attachRepo.findAll(pageable).map(o -> attachMapper.entityToInfoVO(o)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseVO<Void> updateAttach(@NotNull Long attachID, @NotNull MultipartFile file) throws IOException {
|
||||||
|
ResponseVO<Void> checked = BlogUtils.checkAuthorPermission();
|
||||||
|
if (checked != null) {
|
||||||
|
return checked;
|
||||||
|
}
|
||||||
|
if (!attachRepo.existsById(attachID)) {
|
||||||
|
return ResponseVO.notFound();
|
||||||
|
}
|
||||||
|
attachRepo.updateDataAndContentTypeById(file.getBytes(), file.getContentType(), attachID);
|
||||||
|
|
||||||
|
File localCacheFile = new File(ATTACH_FOLDER, String.valueOf(attachID));
|
||||||
|
Files.copy(file.getInputStream(), localCacheFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
log.info("written attach data to local cache file: {}", localCacheFile.getName());
|
||||||
|
|
||||||
|
return ResponseVO.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResponseVO<Void> deleteAttach(@NotNull Long attachID) {
|
||||||
|
BlogUser user = BlogUtils.getCurrentUser().orElse(null);
|
||||||
|
if (user == null) {
|
||||||
|
return ResponseVO.unauthorized();
|
||||||
|
}
|
||||||
|
switch (user.getRole()) {
|
||||||
|
case AUTHOR -> {
|
||||||
|
if (!attachRepo.existsByIdAndCreator_Id(attachID, user.getId())) {
|
||||||
|
return ResponseVO.failed("该附件不存在或不属于你!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ADMIN -> {
|
||||||
|
if (!attachRepo.existsById(attachID)) {
|
||||||
|
return ResponseVO.failed("该附件不存在!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return ResponseVO.failed("你没有这个权限!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attachRepo.deleteById(attachID);
|
||||||
|
|
||||||
|
File localCacheFile = new File(ATTACH_FOLDER, String.valueOf(attachID));
|
||||||
|
if (localCacheFile.delete()) {
|
||||||
|
log.info("deleted local attach cache file: {}", localCacheFile.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseVO.success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
package cn.hamster3.application.blog.service.impl;
|
package cn.hamster3.application.blog.service.impl;
|
||||||
|
|
||||||
import cn.hamster3.application.blog.config.security.BlogUser;
|
import cn.hamster3.application.blog.config.security.BlogUser;
|
||||||
import cn.hamster3.application.blog.config.security.UserAuditorAware;
|
import cn.hamster3.application.blog.constant.UserRole;
|
||||||
import cn.hamster3.application.blog.entity.BlogEntity;
|
import cn.hamster3.application.blog.entity.BlogEntity;
|
||||||
import cn.hamster3.application.blog.entity.UserEntity;
|
|
||||||
import cn.hamster3.application.blog.entity.mapper.BlogMapper;
|
import cn.hamster3.application.blog.entity.mapper.BlogMapper;
|
||||||
import cn.hamster3.application.blog.entity.repo.BlogRepository;
|
import cn.hamster3.application.blog.entity.repo.BlogRepository;
|
||||||
import cn.hamster3.application.blog.service.IBlogService;
|
import cn.hamster3.application.blog.service.IBlogService;
|
||||||
@@ -26,16 +25,13 @@ public class BlogService implements IBlogService {
|
|||||||
@Resource
|
@Resource
|
||||||
private BlogRepository blogRepo;
|
private BlogRepository blogRepo;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private UserAuditorAware userAuditorAware;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<Long> createBlog(@NotNull BlogUpdateRequireVO requireVO) {
|
public @NotNull ResponseVO<Long> createBlog(@NotNull BlogUpdateRequireVO requireVO) {
|
||||||
log.info("create blog vo: {}", requireVO);
|
ResponseVO<Long> checked = BlogUtils.checkAuthorPermission();
|
||||||
UserEntity user = userAuditorAware.getCurrentAuditor().orElse(null);
|
if (checked != null) {
|
||||||
if (user == null) {
|
return checked;
|
||||||
return ResponseVO.unauthorized();
|
|
||||||
}
|
}
|
||||||
|
log.info("create blog vo: {}", requireVO);
|
||||||
BlogEntity entity = blogMapper.voToEntity(requireVO);
|
BlogEntity entity = blogMapper.voToEntity(requireVO);
|
||||||
entity = blogRepo.save(entity);
|
entity = blogRepo.save(entity);
|
||||||
return ResponseVO.success(entity.getId());
|
return ResponseVO.success(entity.getId());
|
||||||
@@ -43,7 +39,7 @@ public class BlogService implements IBlogService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<BlogInfoResponseVO> getBlogInfo(@NotNull Long blogID) {
|
public @NotNull ResponseVO<BlogInfoResponseVO> getBlogInfo(@NotNull Long blogID) {
|
||||||
return blogRepo.findByIDWithContent(blogID)
|
return blogRepo.findByIdWithContent(blogID)
|
||||||
.map(o -> ResponseVO.success(blogMapper.entityToInfoVO(o)))
|
.map(o -> ResponseVO.success(blogMapper.entityToInfoVO(o)))
|
||||||
.orElseThrow(() -> new IllegalArgumentException("未找到该文章!"));
|
.orElseThrow(() -> new IllegalArgumentException("未找到该文章!"));
|
||||||
}
|
}
|
||||||
@@ -55,30 +51,55 @@ public class BlogService implements IBlogService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<Void> updateBlog(@NotNull Long blogID, @NotNull BlogUpdateRequireVO requireVO) {
|
public @NotNull ResponseVO<Void> updateBlog(@NotNull Long blogID, @NotNull BlogUpdateRequireVO requireVO) {
|
||||||
if (!blogRepo.existsById(blogID)) {
|
|
||||||
return ResponseVO.failed("该博文不存在!");
|
|
||||||
}
|
|
||||||
BlogUser user = BlogUtils.getCurrentUser().orElse(null);
|
BlogUser user = BlogUtils.getCurrentUser().orElse(null);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ResponseVO.unauthorized();
|
return ResponseVO.unauthorized();
|
||||||
}
|
}
|
||||||
//todo 权限检查
|
log.info("update blog vo: {}", requireVO);
|
||||||
blogRepo.updateTitleAndAbstractsAndPasswordAndContentById(
|
BlogEntity blogEntity = blogRepo.findByIdWithCreator(blogID);
|
||||||
requireVO.getTitle(),
|
if (blogEntity == null) {
|
||||||
requireVO.getAbstracts(),
|
return ResponseVO.failed("该博文不存在!");
|
||||||
requireVO.getPassword(),
|
}
|
||||||
requireVO.getContent(),
|
if (user.getRole() == UserRole.GUEST) {
|
||||||
blogID
|
return ResponseVO.failed("你没有这个权限!");
|
||||||
);
|
}
|
||||||
|
if (user.getRole() != UserRole.ADMIN) {
|
||||||
|
if (!blogEntity.getCreator().getId().equals(user.getId())) {
|
||||||
|
return ResponseVO.failed("你没有这个权限!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blogEntity.setTitle(requireVO.getTitle());
|
||||||
|
blogEntity.setAbstracts(requireVO.getAbstracts());
|
||||||
|
blogEntity.setContent(requireVO.getContent());
|
||||||
|
blogEntity.setTop(requireVO.getTop());
|
||||||
|
blogEntity.setPublish(requireVO.getPublish());
|
||||||
|
blogEntity.setTags(requireVO.getTags());
|
||||||
|
blogRepo.save(blogEntity);
|
||||||
return ResponseVO.success();
|
return ResponseVO.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<Void> removeBlog(@NotNull Long blogID) {
|
public @NotNull ResponseVO<Void> removeBlog(@NotNull Long blogID) {
|
||||||
|
BlogUser user = BlogUtils.getCurrentUser().orElse(null);
|
||||||
|
if (user == null) {
|
||||||
|
return ResponseVO.unauthorized();
|
||||||
|
}
|
||||||
|
switch (user.getRole()) {
|
||||||
|
case AUTHOR -> {
|
||||||
|
if (!blogRepo.existsByIdAndCreator_Id(blogID, user.getId())) {
|
||||||
|
return ResponseVO.failed("该博文不存在或不属于你!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ADMIN -> {
|
||||||
if (!blogRepo.existsById(blogID)) {
|
if (!blogRepo.existsById(blogID)) {
|
||||||
return ResponseVO.failed("该博文不存在!");
|
return ResponseVO.failed("该博文不存在!");
|
||||||
}
|
}
|
||||||
//todo 权限检查
|
}
|
||||||
|
default -> {
|
||||||
|
return ResponseVO.failed("你没有这个权限!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
blogRepo.deleteById(blogID);
|
blogRepo.deleteById(blogID);
|
||||||
return ResponseVO.success();
|
return ResponseVO.success();
|
||||||
}
|
}
|
||||||
|
@@ -23,14 +23,9 @@ public class BlogUtils {
|
|||||||
public static Optional<BlogUser> getCurrentUser() {
|
public static Optional<BlogUser> getCurrentUser() {
|
||||||
Authentication authentication = getCurrentAuthentication();
|
Authentication authentication = getCurrentAuthentication();
|
||||||
if (authentication == null) {
|
if (authentication == null) {
|
||||||
log.info("current user authentication: null");
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
log.info("current user authentication: {}", authentication);
|
log.info("current user authentication: {}", authentication);
|
||||||
log.info("current user authentication getPrincipal: {}", authentication.getPrincipal());
|
|
||||||
log.info("current user authentication getCredentials: {}", authentication.getCredentials());
|
|
||||||
log.info("current user authentication getDetails: {}", authentication.getDetails());
|
|
||||||
log.info("current user authentication getAuthorities: {}", authentication.getAuthorities());
|
|
||||||
if (!authentication.isAuthenticated()) {
|
if (!authentication.isAuthenticated()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -45,14 +40,21 @@ public class BlogUtils {
|
|||||||
return getCurrentUser().map(BlogUser::getId);
|
return getCurrentUser().map(BlogUser::getId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
public static UserRole getCurrentUserRole() {
|
public static <T> ResponseVO<T> checkAuthorPermission() {
|
||||||
return getCurrentUser().map(BlogUser::getRole).orElse(UserRole.GUEST);
|
BlogUser user = getCurrentUser().orElse(null);
|
||||||
|
if (user == null) {
|
||||||
|
return ResponseVO.unauthorized();
|
||||||
|
}
|
||||||
|
return switch (user.getRole()) {
|
||||||
|
case AUTHOR, ADMIN -> null;
|
||||||
|
default -> ResponseVO.failed("你没有这个权限!");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T> ResponseVO<T> checkAdminPermission() {
|
public static <T> ResponseVO<T> checkAdminPermission() {
|
||||||
BlogUser user = BlogUtils.getCurrentUser().orElse(null);
|
BlogUser user = getCurrentUser().orElse(null);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ResponseVO.unauthorized();
|
return ResponseVO.unauthorized();
|
||||||
}
|
}
|
||||||
|
@@ -1,19 +1,23 @@
|
|||||||
package cn.hamster3.application.blog.vo.attach;
|
package cn.hamster3.application.blog.vo.attach;
|
||||||
|
|
||||||
|
import cn.hamster3.application.blog.vo.user.UserInfoResponseVO;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class AttachInfoResponseVO {
|
public class AttachInfoResponseVO {
|
||||||
@NotNull
|
@NotNull
|
||||||
private Long id;
|
private Long id;
|
||||||
@NotNull
|
@NotNull
|
||||||
private UUID creator;
|
private UserInfoResponseVO creator;
|
||||||
|
@NotNull
|
||||||
|
private UserInfoResponseVO updater;
|
||||||
@NotNull
|
@NotNull
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -4,11 +4,13 @@ import cn.hamster3.application.blog.vo.user.UserInfoResponseVO;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BlogInfoResponseVO {
|
public class BlogInfoResponseVO {
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
package cn.hamster3.application.blog.vo.blog;
|
package cn.hamster3.application.blog.vo.blog;
|
||||||
|
|
||||||
import jakarta.annotation.Nullable;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BlogUpdateRequireVO {
|
public class BlogUpdateRequireVO {
|
||||||
@Length(max = 32, message = "标题长度不能超过 32 个字符!")
|
@Length(max = 32, message = "标题长度不能超过 32 个字符!")
|
||||||
@@ -19,10 +20,6 @@ public class BlogUpdateRequireVO {
|
|||||||
@Length(max = 512, message = "摘要长度不能超过 512 个字符!")
|
@Length(max = 512, message = "摘要长度不能超过 512 个字符!")
|
||||||
private String abstracts;
|
private String abstracts;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Length(max = 16, message = "密码最大长度不能超过 16 个字符!")
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@NotBlank(message = "博客文章内容不能为空!")
|
@NotBlank(message = "博客文章内容不能为空!")
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
@@ -3,10 +3,12 @@ package cn.hamster3.application.blog.vo.setting;
|
|||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SettingInfoResponseVO {
|
public class SettingInfoResponseVO {
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -4,9 +4,11 @@ import jakarta.validation.constraints.Email;
|
|||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserCreateRequireVO {
|
public class UserCreateRequireVO {
|
||||||
@Email(message = "邮箱配置不合法!")
|
@Email(message = "邮箱配置不合法!")
|
||||||
|
@@ -4,11 +4,13 @@ import cn.hamster3.application.blog.constant.UserRole;
|
|||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserInfoResponseVO {
|
public class UserInfoResponseVO {
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -4,9 +4,12 @@ import jakarta.validation.constraints.Email;
|
|||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserLoginRequireVO {
|
public class UserLoginRequireVO {
|
||||||
@Email(message = "邮箱配置不合法!")
|
@Email(message = "邮箱配置不合法!")
|
||||||
|
@@ -3,9 +3,11 @@ package cn.hamster3.application.blog.vo.user;
|
|||||||
import cn.hamster3.application.blog.constant.UserRole;
|
import cn.hamster3.application.blog.constant.UserRole;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserUpdateRequireVO {
|
public class UserUpdateRequireVO {
|
||||||
private String email;
|
private String email;
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
server:
|
server:
|
||||||
port: 8080
|
port: 8080
|
||||||
|
|
||||||
|
spring:
|
||||||
servlet:
|
servlet:
|
||||||
context-path: /
|
context-path: /
|
||||||
multipart:
|
multipart:
|
||||||
enable: true
|
max-file-size: 16MB
|
||||||
max-file-size: 16M
|
max-request-size: 32MB
|
||||||
max-require-size: 32M
|
|
||||||
spring:
|
|
||||||
# 要使用的环境预设
|
# 要使用的环境预设
|
||||||
# prod: 生产环境
|
# prod: 生产环境
|
||||||
# dev: 开发环境
|
# dev: 开发环境
|
||||||
|
@@ -106,7 +106,7 @@ function handleCreated(editor: IDomEditor) {
|
|||||||
/>
|
/>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
<el-main>
|
<el-main class="edit-form-side">
|
||||||
<el-form :model="editBlog">
|
<el-form :model="editBlog">
|
||||||
<el-form-item label="博文标题">
|
<el-form-item label="博文标题">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -152,17 +152,15 @@ function handleCreated(editor: IDomEditor) {
|
|||||||
|
|
||||||
.edit-content-side {
|
.edit-content-side {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 80%;
|
width: 61.8%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 0 1px;
|
||||||
|
border-color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-content-toolbar {
|
.edit-content-toolbar {
|
||||||
height: 80px;
|
border-bottom: 1px solid #ccc;
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-top-width: 0;
|
|
||||||
}
|
|
||||||
.edit-content-scrollbar {
|
|
||||||
height: calc(100% - 80px);
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -28,16 +28,22 @@ function deleteBlog() {
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="blog-container">
|
<el-container class="blog-container">
|
||||||
<el-header class="blog-header">
|
<el-header class="blog-header">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20" style="height: 100%; padding: 0; margin: 0">
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
|
<div style="display: flex; width: 100% height: 100%">
|
||||||
<p>{{ blogInfo?.creator.nickname }}</p>
|
<p>{{ blogInfo?.creator.nickname }}</p>
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<h1 class="blog-title">{{ blogInfo?.title }}</h1>
|
<h1 class="blog-title">{{ blogInfo?.title }}</h1>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" v-if="globalStore.currentUserInfo?.role === 'ADMIN'">
|
<el-col :span="4" v-if="globalStore.currentUserInfo?.role === 'ADMIN'">
|
||||||
|
<div style="display: flex; width: 100% height: 100%">
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
<el-button type="primary" @click="editBlog">编辑</el-button>
|
<el-button type="primary" @click="editBlog">编辑</el-button>
|
||||||
<el-button type="danger" @click="deleteBlog">删除</el-button>
|
<el-button type="danger" @click="deleteBlog">删除</el-button>
|
||||||
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-header>
|
</el-header>
|
||||||
@@ -62,6 +68,7 @@ function deleteBlog() {
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-author {
|
.blog-author {
|
||||||
|
Reference in New Issue
Block a user