diff --git a/luoo_music/src/main/java/com/luoo/music/controller/ArticleController.java b/luoo_music/src/main/java/com/luoo/music/controller/ArticleController.java new file mode 100644 index 0000000..6adee0d --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/controller/ArticleController.java @@ -0,0 +1,46 @@ +package com.luoo.music.controller; + +import api.PageResult; +import api.Result; +import com.luoo.music.dto.response.cms.ArticleRespDTO; +import com.luoo.music.service.CMSArticleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @author Revers. + * @date 2024/02/23 20:40 + **/ + +@RestController +@CrossOrigin +@Api(tags = "雀跃APP文章 APIs") +@RequestMapping("/article") +public class ArticleController { + + @Autowired + private CMSArticleService articleService; + + @ApiOperation(value = "查询文章详情", notes = "查询文章详情") + @GetMapping("/{id}") + public Result findOne(@ApiParam(value = "文章ID", required = true) @PathVariable String id){ + return articleService.findOne(id); + } + + + @ApiOperation(value = "查询文章列表", notes = "查询文章列表") + @PostMapping("/search/{page}/{size}") + public Result> search(@ApiParam(value = "页码", required = true) @PathVariable int page, + @ApiParam(value = "每页条数", required = true) @PathVariable int size){ + return articleService.search(page, size); + } + + @ApiOperation(value = "文章阅览次数加一", notes = "文章阅览次数加一") + @PostMapping("/{id}") + public Result> visitAdd(@ApiParam(value = "文章ID", required = true) @PathVariable String id){ + return articleService.visitAdd(id); + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/controller/CMSAdvertisementController.java b/luoo_music/src/main/java/com/luoo/music/controller/CMSAdvertisementController.java new file mode 100644 index 0000000..6e2ae41 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/controller/CMSAdvertisementController.java @@ -0,0 +1,72 @@ +package com.luoo.music.controller; + +import api.PageResult; +import api.Result; +import com.luoo.music.dto.request.cms.AdvertisementReqModel; +import com.luoo.music.dto.response.cms.AdvertisementRespDTO; +import com.luoo.music.service.CMSAdvertisementService; +import com.luoo.music.service.S3Service; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; + +/** + * @author Revers. + * @date 2024/02/23 20:44 + **/ + +@RestController +@CrossOrigin +@Api(tags = "雀跃广告后台CMS APIs") +@RequestMapping("/cms/ad") +public class CMSAdvertisementController { + + @Autowired + private CMSAdvertisementService adService; + @Autowired + private S3Service s3Service; + + @ApiOperation(value = "上传封面", notes = "上传封面") + @PostMapping("/upload/image") + public Result batchUpload(@ApiParam(value = "封面图片文件", required = true) @RequestParam("file") MultipartFile file) { + return s3Service.upload(file, Boolean.FALSE); + } + + @ApiOperation(value = "添加广告", notes = "添加广告") + @PostMapping("/add") + public Result add(@ApiParam(value = "广告信息", required = true) @Valid @RequestBody AdvertisementReqModel adReqModel){ + return adService.add(adReqModel); + } + + @ApiOperation(value = "删除单条广告", notes = "逻辑删除") + @DeleteMapping("/{id}") + public Result delete(@ApiParam(value = "广告ID", required = true) @PathVariable String id){ + return adService.deleteById(id); + } + + @ApiOperation(value = "更新广告", notes = "更新广告") + @PutMapping( "/{id}") + public Result update(@ApiParam(value = "广告ID", required = true) @PathVariable String id, + @ApiParam(value = "广告信息", required = true) @RequestBody AdvertisementReqModel updateModel){ + return adService.update(id, updateModel); + } + + @ApiOperation(value = "查询广告详情", notes = "查询广告详情") + @GetMapping("/{id}") + public Result findOne(@ApiParam(value = "文章ID", required = true) @PathVariable String id){ + return adService.findOne(id); + } + + + @ApiOperation(value = "查询广告列表", notes = "查询广告列表") + @PostMapping("/search/{page}/{size}") + public Result> search(@ApiParam(value = "页码", required = true) @PathVariable int page, + @ApiParam(value = "每页条数", required = true) @PathVariable int size){ + return adService.search(page, size); + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/controller/CMSArticleController.java b/luoo_music/src/main/java/com/luoo/music/controller/CMSArticleController.java new file mode 100644 index 0000000..e79249f --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/controller/CMSArticleController.java @@ -0,0 +1,72 @@ +package com.luoo.music.controller; + +import api.PageResult; +import api.Result; +import com.luoo.music.dto.request.cms.*; +import com.luoo.music.dto.response.cms.ArticleRespDTO; +import com.luoo.music.service.CMSArticleService; +import com.luoo.music.service.S3Service; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; + +/** + * @author Revers. + * @date 2024/02/22 15:14 + **/ + +@RestController +@CrossOrigin +@Api(tags = "雀跃文章后台CMS APIs") +@RequestMapping("/cms/article") +public class CMSArticleController { + + @Autowired + private CMSArticleService articleService; + @Autowired + private S3Service s3Service; + + @ApiOperation(value = "上传封面", notes = "上传封面") + @PostMapping("/upload/image") + public Result batchUpload(@ApiParam(value = "封面图片文件", required = true) @RequestParam("file") MultipartFile file) { + return s3Service.upload(file, Boolean.FALSE); + } + + @ApiOperation(value = "添加文章", notes = "添加文章") + @PostMapping("/add") + public Result add(@ApiParam(value = "文章信息", required = true) @Valid @RequestBody ArticleAddModel articleAddModel){ + return articleService.add(articleAddModel); + } + + @ApiOperation(value = "删除单条文章", notes = "逻辑删除") + @DeleteMapping("/{id}") + public Result delete(@ApiParam(value = "文章ID", required = true) @PathVariable String id){ + return articleService.deleteById(id); + } + + @ApiOperation(value = "更新文章", notes = "更新文章") + @PutMapping( "/{id}") + public Result update(@ApiParam(value = "文章ID", required = true) @PathVariable String id, + @ApiParam(value = "文章信息", required = true) @RequestBody ArticleAddModel updateModel){ + return articleService.update(id, updateModel); + } + + @ApiOperation(value = "查询文章详情", notes = "查询文章详情") + @GetMapping("/{id}") + public Result findOne(@ApiParam(value = "文章ID", required = true) @PathVariable String id){ + return articleService.findOne(id); + } + + + @ApiOperation(value = "查询文章列表", notes = "查询文章列表") + @PostMapping("/search/{page}/{size}") + public Result> search( @ApiParam(value = "页码", required = true) @PathVariable int page, + @ApiParam(value = "每页条数", required = true) @PathVariable int size){ + return articleService.search(page, size); + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/dao/AdvertisementDao.java b/luoo_music/src/main/java/com/luoo/music/dao/AdvertisementDao.java new file mode 100644 index 0000000..c0e4597 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dao/AdvertisementDao.java @@ -0,0 +1,8 @@ +package com.luoo.music.dao; + +import com.luoo.music.pojo.Advertisement; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface AdvertisementDao extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/luoo_music/src/main/java/com/luoo/music/dao/ArticleDao.java b/luoo_music/src/main/java/com/luoo/music/dao/ArticleDao.java new file mode 100644 index 0000000..cd16248 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dao/ArticleDao.java @@ -0,0 +1,8 @@ +package com.luoo.music.dao; + +import com.luoo.music.pojo.Article; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface ArticleDao extends JpaRepository, JpaSpecificationExecutor
{ +} diff --git a/luoo_music/src/main/java/com/luoo/music/dto/request/cms/AdvertisementReqModel.java b/luoo_music/src/main/java/com/luoo/music/dto/request/cms/AdvertisementReqModel.java new file mode 100644 index 0000000..eb1eb75 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dto/request/cms/AdvertisementReqModel.java @@ -0,0 +1,56 @@ +package com.luoo.music.dto.request.cms; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author Revers. + * @date 2024/02/23 21:03 + **/ + +@Data +@ApiModel(value = "增加或修改广告对象") +public class AdvertisementReqModel { + + @NotBlank(message = "广告名称必填") + @ApiModelProperty(value = "广告名称") + private String name; + + @NotBlank(message = "广告位置必填") + @ApiModelProperty(value = "广告位置") + private String location; + + @NotBlank(message = "广告图片必填") + @ApiModelProperty(value = "广告图片路径") + private String image; + + @NotBlank(message = "开始时间必填") + @ApiModelProperty(value = "开始时间,yyyy-MM-dd HH:mm:ss") + private String startTime; + + @NotBlank(message = "到期时间必填") + @ApiModelProperty(value = "到期时间时间,yyyy-MM-dd HH:mm:ss") + private String endTime; + + @NotBlank(message = "跳转类型必填") + @ApiModelProperty(value = "跳转类型") + private String type; + + @NotBlank(message = "跳转地址必填") + @ApiModelProperty(value = "跳转地址") + private String url; + + @NotBlank(message = "广告显示必填") + @ApiModelProperty(value = "是否显示广告,0:否,1:是") + private String isDisplay; + + @ApiModelProperty(value = "备注") + private String content; + + @ApiModelProperty(value = "发布人ID") + private String userId; + +} diff --git a/luoo_music/src/main/java/com/luoo/music/dto/request/cms/ArticleAddModel.java b/luoo_music/src/main/java/com/luoo/music/dto/request/cms/ArticleAddModel.java new file mode 100644 index 0000000..7ae4e9e --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dto/request/cms/ArticleAddModel.java @@ -0,0 +1,52 @@ +package com.luoo.music.dto.request.cms; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author Revers. + * @date 2024/02/22 18:29 + **/ + +@Data +@ApiModel(value = "增加或修改文章对象") +public class ArticleAddModel { + + @NotBlank(message = "文章标题必填") + @ApiModelProperty(value = "文章标题") + private String title; + + @NotBlank(message = "文章类型必填") + @ApiModelProperty(value = "文章类型") + private String type; + + @NotBlank(message = "文章封面必填") + @ApiModelProperty(value = "文章封面路径") + private String image; + + @NotBlank(message = "发布方式必填") + @ApiModelProperty(value = "是否定时发布,0:否,1:是") + private String isScheduled; + + @ApiModelProperty(value = "定时发布时间,yyyy-MM-dd HH:mm:ss") + private String pubTime; + + @ApiModelProperty(value = "发布人ID") + private String userId; + + @NotBlank(message = "文章详情必填") + @ApiModelProperty(value = "文章详情") + private String content; + + @NotBlank(message = "评论设置必填") + @ApiModelProperty(value = "是否允许评论,0:否,1:是") + private String allowCommit; + + @NotBlank(message = "自动推送必填") + @ApiModelProperty(value = "是否自动推送,0:否,1:是") + private String autoPush; + +} diff --git a/luoo_music/src/main/java/com/luoo/music/dto/response/cms/AdvertisementRespDTO.java b/luoo_music/src/main/java/com/luoo/music/dto/response/cms/AdvertisementRespDTO.java new file mode 100644 index 0000000..84a22fd --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dto/response/cms/AdvertisementRespDTO.java @@ -0,0 +1,59 @@ +package com.luoo.music.dto.response.cms; + +import com.luoo.music.pojo.Advertisement; +import com.luoo.music.pojo.Article; +import com.luoo.music.util.Constants; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang.StringUtils; + +/** + * @author Revers. + * @date 2024/02/23 21:33 + **/ + +@Data +public class AdvertisementRespDTO { + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "ID") + private String id; + @ApiModelProperty(value = "广告名称") + private String name; + @ApiModelProperty(value = "广告位置") + private String location; + @ApiModelProperty(value = "广告图片路径") + private String image; + @ApiModelProperty(value = "跳转类型") + private String type; + @ApiModelProperty(value = "跳转地址") + private String url; + @ApiModelProperty(value = "备注") + private String content; + + @ApiModelProperty(value = "发布作者id") + private String userId; + @ApiModelProperty(value = "发布作者昵称") + private String userName; + @ApiModelProperty(value = "编辑日期,格式为: yyyy.MM.dd") + private String date; + + public static AdvertisementRespDTO convertPojo(Advertisement ad) { + AdvertisementRespDTO response = new AdvertisementRespDTO(); + + response.setId(ad.getId()); + response.setName(ad.getName()); + response.setLocation(ad.getLocation()); + response.setType(ad.getType()); + if (StringUtils.isNotBlank(ad.getImage())) { + response.setImage(Constants.Advertisement_RESOURCE_PREFIX + ad.getImage()); + } else { + response.setImage(""); + } + response.setUrl(ad.getUrl()); + response.setContent(ad.getContent()); + response.setUserId(ad.getUserId()); + response.setUserName(ad.getUserName()); + response.setDate(ad.getCreateTime().toString()); + return response; + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/dto/response/cms/ArticleRespDTO.java b/luoo_music/src/main/java/com/luoo/music/dto/response/cms/ArticleRespDTO.java new file mode 100644 index 0000000..e37b784 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/dto/response/cms/ArticleRespDTO.java @@ -0,0 +1,63 @@ +package com.luoo.music.dto.response.cms; + +import com.luoo.music.pojo.Article; +import com.luoo.music.util.Constants; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang.StringUtils; + +import java.io.Serializable; + +/** + * @author Revers. + * @date 2024/02/23 19:35 + **/ +@Data +public class ArticleRespDTO implements Serializable { + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "ID") + private String id; + @ApiModelProperty(value = "文章标题") + private String title; + @ApiModelProperty(value = "文章类型") + private String type; + @ApiModelProperty(value = "文章封面路径") + private String image; + @ApiModelProperty(value = "文章详情") + private String content; + @ApiModelProperty(value = "概要") + private String summary; + + @ApiModelProperty(value = "发布作者id") + private String userId; + @ApiModelProperty(value = "发布作者昵称") + private String userName; + @ApiModelProperty(value = "编辑日期,格式为: yyyy.MM.dd") + private String date; + + @ApiModelProperty(value = "总评论数,大于99,显示99+") + private Long commitsNum; + @ApiModelProperty(value = "总阅览数,大于99,显示99+") + private Long vistisNum; + + + public static ArticleRespDTO convertPojo(Article article) { + ArticleRespDTO response = new ArticleRespDTO(); + response.setId(article.getId()); + response.setTitle(article.getTitle()); + response.setType(article.getType()); + if (StringUtils.isNotBlank(article.getImage())) { + response.setImage(Constants.ARTICLE_RESOURCE_PREFIX + article.getImage()); + } else { + response.setImage(""); + } + response.setSummary(article.getSummary()); + response.setContent(article.getContent()); + response.setUserId(article.getUserId()); + response.setUserName(article.getUserName()); + response.setDate(article.getPubTime().toString()); + response.setCommitsNum(article.getComment()); + response.setVistisNum(article.getVisits()); + return response; + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/Advertisement.java b/luoo_music/src/main/java/com/luoo/music/pojo/Advertisement.java new file mode 100644 index 0000000..e88f3a5 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/pojo/Advertisement.java @@ -0,0 +1,105 @@ +package com.luoo.music.pojo; + +import lombok.Data; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @author Revers. + * @date 2024/02/23 20:47 + **/ + +@Data +@Entity +@DynamicInsert +@DynamicUpdate +@Table(name="tb_advertisement") +@EntityListeners(AuditingEntityListener.class) +public class Advertisement implements Serializable { + @Id() + private String id; + + /** + * 广告名称 + */ + private String name; + + /** + * 广告放置位置 + */ + private String location; + + /** + * 广告图片 + */ + private String image; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 到期时间 + */ + private LocalDateTime endTime; + /** + * 跳转地址类型 + */ + private String type; + /** + * 跳转地址 + */ + private String url; + + /** + * 是否显示广告 + */ + private String display; + + /** + * 广告备注 + */ + private String content; + + /** + * 浏览量 + */ + private Long visits; + + /** + * 创建时间 + */ + @CreatedDate + private LocalDateTime createTime; + /** + * 更新时间 + */ + @LastModifiedDate + private LocalDateTime updateTime; + /** + * 用户ID + */ + private String userId; + /** + * 用户昵称 + */ + private String userName; + /** + * 用户类型 + */ + private String userType; + /** + * 是否被删除 否:0 是:1 + */ + private String isDeleted; + +} diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/Article.java b/luoo_music/src/main/java/com/luoo/music/pojo/Article.java new file mode 100644 index 0000000..ff3eaef --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/pojo/Article.java @@ -0,0 +1,111 @@ +package com.luoo.music.pojo; + +import lombok.Data; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 文章表 + * @author Revers. + * @date 2024/02/21 16:01 + **/ + +@Data +@Entity +@DynamicInsert +@DynamicUpdate +@Table(name="tb_article_2") +@EntityListeners(AuditingEntityListener.class) +public class Article implements Serializable { + + @Id() + private String id; + + /** + * 文章标题 + */ + private String title; + /** + * 文章类型 + */ + private String type; + /** + * 封面路径 + */ + private String image; + /** + * 概要 + */ + private String summary; + /** + * 文章详情 + */ + private String content; + + /** + * 发布状态 未发布:0,已发布:1 + */ + private String isPublish; + /** + * 是否定时发布 否:0 是:1 + */ + private String isScheduled; + /** + * 是否被删除 否:0 是:1 + */ + private String isDeleted; + /** + * 浏览量 + */ + private Long visits; + /** + * 评论量 + */ + private Long comment; + /** + * 发布时间 + */ + private LocalDateTime pubTime; + /** + * 创建时间 + */ + @CreatedDate + private LocalDateTime createTime; + /** + * 更新时间 + */ + @LastModifiedDate + private LocalDateTime updateTime; + /** + * 用户ID + */ + private String userId; + /** + * 用户昵称 + */ + private String userName; + /** + * 用户类型 + */ + private String userType; + + /** + * 是否允许评论, + * 0:否,1:是* + * */ + private String allowCommit; + + /** + * 是否自动推送, + * 0:否,1:是 + * **/ + private String autoPush; + +} diff --git a/luoo_music/src/main/java/com/luoo/music/service/ArticleService.java b/luoo_music/src/main/java/com/luoo/music/service/ArticleService.java new file mode 100644 index 0000000..98eaf26 --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/service/ArticleService.java @@ -0,0 +1,17 @@ +package com.luoo.music.service; + +import com.luoo.music.dao.ArticleDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Revers. + * @date 2024/02/21 16:32 + **/ + +@Service +public class ArticleService { + + @Autowired + private ArticleDao articleDao; +} diff --git a/luoo_music/src/main/java/com/luoo/music/service/CMSAdvertisementService.java b/luoo_music/src/main/java/com/luoo/music/service/CMSAdvertisementService.java new file mode 100644 index 0000000..f0efcaf --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/service/CMSAdvertisementService.java @@ -0,0 +1,203 @@ +package com.luoo.music.service; + +import api.PageResult; +import api.Result; +import com.luoo.music.client.UserClient; +import com.luoo.music.dao.AdvertisementDao; +import com.luoo.music.dto.request.cms.AdvertisementReqModel; +import com.luoo.music.dto.response.cms.AdvertisementRespDTO; +import com.luoo.music.pojo.Advertisement; +import com.luoo.music.pojo.UserInfo; +import com.luoo.music.util.Constants; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import util.IdWorker; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * @author Revers. + * @date 2024/02/23 20:46 + **/ + +@Service +public class CMSAdvertisementService { + @Autowired + private S3Service s3Service; + @Autowired + private IdWorker idWorker; + @Autowired + private AdvertisementDao adDao; + @Autowired + private UserClient userClient; + + public Result add(AdvertisementReqModel paramAdd) { + String image = null; + if (StringUtils.isNotBlank(paramAdd.getImage())) { + // 新增时有图片一定是 temp/ + String srcKey = paramAdd.getImage().substring(paramAdd.getImage().indexOf(Constants.TEMP_KEY_PREFIX)); + image = moveAdImage(srcKey, paramAdd.getImage()); + if (StringUtils.isBlank(image)) { + return Result.failed("保存失败"); + } + } + + Advertisement ad = new Advertisement(); + ad.setId(String.valueOf(idWorker.nextId())); + ad.setName(paramAdd.getName()); + ad.setLocation(paramAdd.getLocation()); + ad.setImage(image); + ad.setStartTime(LocalDateTime.parse(paramAdd.getStartTime(), Constants.formatter)); + ad.setEndTime(LocalDateTime.parse(paramAdd.getEndTime(), Constants.formatter)); + ad.setType(paramAdd.getType()); + ad.setUrl(paramAdd.getUrl()); + ad.setDisplay(paramAdd.getIsDisplay()); + ad.setContent(paramAdd.getContent()); + ad.setVisits(0l); + ad.setIsDeleted("0"); + + UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId()); + if (!Objects.isNull(userInfo)) { + ad.setUserId(userInfo.getId()); + ad.setUserName(userInfo.getName()); + ad.setUserType(userInfo.getType()); + } + adDao.save(ad); + + return Result.success(); + } + + private String moveAdImage(String srcKey, String image) { + if (StringUtils.isNotBlank(image) && StringUtils.isNotBlank(srcKey)) { + String suffix = image.substring(image.lastIndexOf(Constants.DOT)); + String destKeySuffix = String.format("%d%s", idWorker.nextId(), suffix); + String destKey = Constants.Advertisement_KEY_PREFIX + destKeySuffix; + int copy = s3Service.copy(Constants.BUCKET, srcKey, destKey); + if (copy > 0) { + return destKeySuffix; + } + } + return null; + } + + public Result deleteById(String id){ + Advertisement ad = adDao.findById(id).get(); + if (!Objects.isNull(ad)) { + ad.setIsDeleted("1"); + adDao.save(ad); + return Result.success(); + } + return Result.failed("广告不存在"); + } + + public Result update(String id,AdvertisementReqModel param){ + Optional optional = adDao.findById(id); + if (!optional.isPresent()) { + return Result.failed("找不到广告: " + id); + } + + Advertisement ad = optional.get(); + + //如果图片路径存在 temp/ 则为新图片 + if (StringUtils.isNotBlank(param.getImage()) && param.getImage().contains(Constants.TEMP_KEY_PREFIX)) { + + String srcKey = param.getImage().substring(param.getImage().indexOf(Constants.TEMP_KEY_PREFIX)); + + if (StringUtils.isNotBlank(srcKey)) { + String image = moveAdImage(srcKey, param.getImage()); + if (StringUtils.isBlank(image)) { + return Result.failed("更新失败"); + } + ad.setImage(image); + } + } + + if (StringUtils.isNotBlank(param.getName())) + ad.setName(param.getName()); + + if (StringUtils.isNotBlank(param.getLocation())) + ad.setLocation(param.getLocation()); + + if (StringUtils.isNotBlank(param.getStartTime())) + ad.setStartTime(LocalDateTime.parse(param.getStartTime(), Constants.formatter)); + + if (StringUtils.isNotBlank(param.getEndTime())) + ad.setEndTime(LocalDateTime.parse(param.getEndTime(), Constants.formatter)); + + + if(StringUtils.isNotBlank(param.getType())) + ad.setType(param.getType()); + + if(StringUtils.isNotBlank(param.getUrl())) + ad.setUrl(param.getUrl()); + + if(StringUtils.isNotBlank(param.getIsDisplay())) + ad.setDisplay(param.getIsDisplay()); + + if(StringUtils.isNotBlank(param.getContent())) + ad.setContent(param.getContent()); + + return Result.success(); + } + + public Result findOne(String id) { + Optional optional=adDao.findById(id); + if(!optional.isPresent()) { + return Result.failed("无法找到广告: " + id); + } + Advertisement ad = optional.get(); + + if("1".equals(ad.getIsDeleted())){ + return Result.success(null); + }else { + AdvertisementRespDTO response = AdvertisementRespDTO.convertPojo(ad); + return Result.success(response); + } + } + + public Result> search(int page, int size) { + List result = new ArrayList<>(); + PageRequest pageRequest = PageRequest.of(page - 1, size); + Specification AdSpecification = buildSearchSpecification(); + Page AdPage = adDao.findAll(AdSpecification,pageRequest); + + long totalElements = AdPage.getTotalElements(); + List content = AdPage.getContent(); + if (!CollectionUtils.isEmpty(content)) { + for (Advertisement item : content) { + AdvertisementRespDTO response = AdvertisementRespDTO.convertPojo(item); + result.add(response); + } + } + return Result.success(new PageResult<>(totalElements, result)); + } + private Specification buildSearchSpecification() { + return (Root root, CriteriaQuery query, CriteriaBuilder builder) -> { + List predicateList = new ArrayList(); + Predicate isDeleted = builder.equal(root.get("isDeleted"), "0"); + Predicate isDisplay = builder.equal(root.get("display"), "1"); + predicateList.add(builder.and(isDeleted, isDisplay)); + + + LocalDateTime now = LocalDateTime.now(); + predicateList.add(builder.lessThan(root.get("startTime"),now)); + predicateList.add(builder.greaterThan(root.get("endTime"), now)); + + return builder.and(predicateList.toArray(new Predicate[predicateList.size()])); + }; + } + +} diff --git a/luoo_music/src/main/java/com/luoo/music/service/CMSArticleService.java b/luoo_music/src/main/java/com/luoo/music/service/CMSArticleService.java new file mode 100644 index 0000000..dd42fcb --- /dev/null +++ b/luoo_music/src/main/java/com/luoo/music/service/CMSArticleService.java @@ -0,0 +1,231 @@ +package com.luoo.music.service; + +import api.PageResult; +import api.Result; +import com.luoo.music.client.UserClient; +import com.luoo.music.dao.*; +import com.luoo.music.dto.request.cms.ArticleAddModel; +import com.luoo.music.dto.response.cms.ArticleRespDTO; +import com.luoo.music.pojo.Article; +import com.luoo.music.pojo.UserInfo; +import com.luoo.music.util.Constants; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import util.IdWorker; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import java.time.LocalDateTime; +import java.util.*; + +/** + * @author Revers. + * @date 2024/02/22 15:15 + **/ + +@Service +public class CMSArticleService { + @Autowired + private S3Service s3Service; + @Autowired + private IdWorker idWorker; + @Autowired + private ArticleDao articleDao; + @Autowired + private UserClient userClient; + + public Result add(ArticleAddModel paramAdd) { + String image = null; + if (StringUtils.isNotBlank(paramAdd.getImage())) { + // 新增时有图片一定是 temp/ + String srcKey = paramAdd.getImage().substring(paramAdd.getImage().indexOf(Constants.TEMP_KEY_PREFIX)); + image = moveArticleImage(srcKey, paramAdd.getImage()); + if (StringUtils.isBlank(image)) { + return Result.failed("保存失败"); + } + } + + Article article = new Article(); + article.setId(String.valueOf(idWorker.nextId())); + article.setTitle(paramAdd.getTitle()); + article.setType(paramAdd.getType()); + article.setImage(image); + //article.setSummary(); + article.setContent(paramAdd.getContent()); + article.setVisits(0l); + article.setComment(0l); + article.setIsDeleted("0"); + + UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId()); + + if (!Objects.isNull(userInfo)) { + article.setUserId(userInfo.getId()); + article.setUserName(userInfo.getName()); + article.setUserType(userInfo.getType()); + } + article.setAllowCommit(paramAdd.getAllowCommit()); + article.setAutoPush(paramAdd.getAutoPush()); + article.setIsPublish("1"); + article.setPubTime(LocalDateTime.now()); + article.setIsScheduled(paramAdd.getIsScheduled()); + +/* String pubTimeStr = paramAdd.getPubTime(); + LocalDateTime pubTime = LocalDateTime.now(); + if ("1".equals(paramAdd.getIsScheduled())) { // 定时发布 + if (StringUtils.isNotBlank(pubTimeStr)) {// 定时发布确定发布时间 + pubTime = LocalDateTime.parse(pubTimeStr, Constants.formatter); + if(pubTime.isBefore(LocalDateTime.now())){ //发布时间比现在早 + article.setState("1"); + article.setIsPublish("1"); + article.setPubTime(LocalDateTime.now()); + }else {//发布时间比现在晚 + article.setState("0"); + article.setIsPublish("0"); + article.setPubTime(pubTime); + } + }else { // 定时发布未确定发布时间 + article.setState("1"); + article.setIsPublish("1"); + article.setPubTime(LocalDateTime.now()); + } + } else { //非定时发布 + article.setState("1"); + article.setIsPublish("1"); + article.setPubTime(LocalDateTime.now()); + }*/ + + articleDao.save(article); + return Result.success(); + } + + private String moveArticleImage(String srcKey, String image) { + if (StringUtils.isNotBlank(image) && StringUtils.isNotBlank(srcKey)) { + String suffix = image.substring(image.lastIndexOf(Constants.DOT)); + String destKeySuffix = String.format("%d%s", idWorker.nextId(), suffix); + String destKey = Constants.ARTICLE_KEY_PREFIX + destKeySuffix; + int copy = s3Service.copy(Constants.BUCKET, srcKey, destKey); + if (copy > 0) { + return destKeySuffix; + } + } + return null; + } + + public Result deleteById(String id){ + Article article = articleDao.findById(id).get(); + if (!Objects.isNull(article)) { + article.setIsDeleted("1"); + articleDao.save(article); + return Result.success(); + } + return Result.failed("文章不存在"); + } + + public Result visitAdd(String id){ + Article article = articleDao.findById(id).get(); + if (!Objects.isNull(article)) { + article.setVisits(article.getVisits()+1); + articleDao.save(article); + return Result.success(); + } + return Result.failed("文章不存在"); + } + + public Result update(String id,ArticleAddModel param){ + Optional
optional = articleDao.findById(id); + if (!optional.isPresent()) { + return Result.failed("找不到期刊: " + id); + } + + Article article = optional.get(); + + //如果图片路径存在 temp/ 则为新图片 + if (StringUtils.isNotBlank(param.getImage()) && param.getImage().contains(Constants.TEMP_KEY_PREFIX)) { + + String srcKey = param.getImage().substring(param.getImage().indexOf(Constants.TEMP_KEY_PREFIX)); + + if (StringUtils.isNotBlank(srcKey)) { + String image = moveArticleImage(srcKey, param.getImage()); + if (StringUtils.isBlank(image)) { + return Result.failed("更新失败"); + } + article.setImage(image); + } + } + + if (StringUtils.isNotBlank(param.getTitle())) + article.setTitle(param.getTitle()); + + if (StringUtils.isNotBlank(param.getType())) + article.setType(param.getType()); + + if (StringUtils.isNotBlank(param.getContent())) { + //article.setSummary(); + article.setContent(param.getContent()); + } + + if (StringUtils.isNotBlank(param.getAllowCommit())) + article.setAllowCommit(param.getAllowCommit()); + + if (StringUtils.isNotBlank(param.getAutoPush())) + article.setAutoPush(param.getAutoPush()); + + if(StringUtils.isNotBlank(param.getIsScheduled())) + article.setIsScheduled(param.getIsScheduled()); + + if(StringUtils.isNotBlank(param.getPubTime())) + article.setPubTime(LocalDateTime.parse(param.getPubTime(), Constants.formatter)); + + //TODO: 发布方式 + + return Result.success(); + } + + public Result findOne(String id) { + Optional
optional=articleDao.findById(id); + if(!optional.isPresent()) { + return Result.failed("无法找到文章: " + id); + } + Article article = optional.get(); + + if("1".equals(article.getIsDeleted())){ + return Result.success(null); + }else { + ArticleRespDTO response = ArticleRespDTO.convertPojo(article); + return Result.success(response); + } + } + + public Result> search(int page, int size) { + List result = new ArrayList<>(); + PageRequest pageRequest = PageRequest.of(page - 1, size); + Specification
articleSpecification = buildSearchSpecification(); + Page
ArticlePage = articleDao.findAll(articleSpecification,pageRequest); + + long totalElements = ArticlePage.getTotalElements(); + List
content = ArticlePage.getContent(); + if (!CollectionUtils.isEmpty(content)) { + for (Article item : content) { + ArticleRespDTO response = ArticleRespDTO.convertPojo(item); + result.add(response); + } + } + return Result.success(new PageResult<>(totalElements, result)); + } + private Specification
buildSearchSpecification() { + return (Root
root, CriteriaQuery query, CriteriaBuilder builder) -> { + List predicateList = new ArrayList(); + Predicate isDeleted = builder.equal(root.get("isDeleted"), "0"); + Predicate isPublish = builder.equal(root.get("isPublish"), "1"); + predicateList.add(builder.and(isDeleted, isPublish)); + return builder.and(predicateList.toArray(new Predicate[predicateList.size()])); + }; + } +} diff --git a/luoo_music/src/main/java/com/luoo/music/util/Constants.java b/luoo_music/src/main/java/com/luoo/music/util/Constants.java index c2064eb..191db5a 100644 --- a/luoo_music/src/main/java/com/luoo/music/util/Constants.java +++ b/luoo_music/src/main/java/com/luoo/music/util/Constants.java @@ -16,12 +16,20 @@ public class Constants { public static final String MUSIC_RESOURCE_PREFIX="http://cdn.indie.cn/music/"; // 歌曲文件、封面、歌词前缀 public static final String SONG_RESOURCE_PREFIX="http://cdn.indie.cn/song/"; + public static final String ARTICLE_RESOURCE_PREFIX="http://cdn.indie.cn/article/"; + + public static final String Advertisement_RESOURCE_PREFIX="http://cdn.indie.cn/ad/"; + public static final String BUCKET = "indie"; public static final String RESOURCE_PREFIX="http://cdn.indie.cn/"; public static final String MUSIC_KEY_PREFIX = "music/"; public static final String SONG_KEY_PREFIX = "song/"; public static final String TEMP_KEY_PREFIX = "temp/"; + public static final String Advertisement_KEY_PREFIX = "ad/"; + + public static final String ARTICLE_KEY_PREFIX = "article/"; + public static final String DOT = "."; public static final String COMMA = ",";