期刊和歌曲后台修改

main
JH 10 months ago
parent c293d155f6
commit c7901bc7d8

@ -52,13 +52,13 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- 解析音乐文件获取音乐时长 -->
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <artifactId>tika-core</artifactId>
<version>1.27</version> <version>1.27</version>
</dependency> </dependency>
<!-- s3 sdk -->
<!-- amazon s3 -->
<dependency> <dependency>
<groupId>software.amazon.awssdk</groupId> <groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId> <artifactId>s3</artifactId>

@ -27,7 +27,6 @@ public class AwsS3Config {
.region(region) .region(region)
.serviceConfiguration(s3Config) .serviceConfiguration(s3Config)
.build(); .build();
return s3; return s3;
} }
@ -38,7 +37,6 @@ public class AwsS3Config {
.endpointOverride(URI.create("https://s3.bitiful.net/")) .endpointOverride(URI.create("https://s3.bitiful.net/"))
.region(region) .region(region)
.build(); .build();
return presigner; return presigner;
} }
} }

@ -6,6 +6,7 @@ import com.luoo.music.request.cms.JournalAddModel;
import com.luoo.music.request.cms.JournalQueryModel; import com.luoo.music.request.cms.JournalQueryModel;
import com.luoo.music.response.cms.JournalVO; import com.luoo.music.response.cms.JournalVO;
import com.luoo.music.service.CMSJournalService; import com.luoo.music.service.CMSJournalService;
import com.luoo.music.service.S3Service;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
@ -24,20 +25,22 @@ public class CMSJournalController {
@Autowired @Autowired
private CMSJournalService journalService; private CMSJournalService journalService;
@Autowired
private S3Service s3Service;
@ApiOperation(value = "查询期刊列表", notes = "查询期刊列表") @ApiOperation(value = "查询期刊列表", notes = "查询期刊列表")
@RequestMapping(value="/search/{page}/{size}", method= RequestMethod.POST) @RequestMapping(value="/search/{page}/{size}", method= RequestMethod.POST)
public Result<PageResult<JournalVO>> search(@ApiParam(value = "查询条件对象", required = true) @RequestBody JournalQueryModel queryModel, public Result<PageResult<JournalVO>> search(@ApiParam(value = "查询条件对象", required = true) @RequestBody JournalQueryModel queryModel,
@ApiParam(value = "页码", required = true) @PathVariable int page, @ApiParam(value = "页码", required = true) @PathVariable int page,
@ApiParam(value = "每页条数", required = true) @PathVariable int size){ @ApiParam(value = "每页条数", required = true) @PathVariable int size){
return journalService.search(queryModel, page, size); return journalService.search(queryModel, page, size);
} }
@ApiOperation(value = "新增期刊", notes = "新增期刊") @ApiOperation(value = "新增期刊", notes = "新增期刊")
@RequestMapping(value = "/add", method = RequestMethod.POST) @RequestMapping(value = "/add", method = RequestMethod.POST)
public Result add(@ApiParam(value = "期刊信息", required = true) @RequestBody JournalAddModel addModel, public Result add(@ApiParam(value = "Header中的token信息", required = true) @RequestHeader("Admin-Token") String token,
@ApiParam(value = "封面文件", required = true) @RequestParam("imageFile") MultipartFile imageFile){ @ApiParam(value = "期刊信息", required = true) @RequestBody JournalAddModel addModel){
return journalService.add(addModel, imageFile); return journalService.add(token, addModel);
} }
@ApiOperation(value = "查询期刊详情", notes = "查询期刊详情") @ApiOperation(value = "查询期刊详情", notes = "查询期刊详情")
@ -49,17 +52,17 @@ public class CMSJournalController {
@ApiOperation(value = "更新期刊", notes = "更新期刊") @ApiOperation(value = "更新期刊", notes = "更新期刊")
@RequestMapping(value = "/{id}", method = RequestMethod.PUT) @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public Result update(@ApiParam(value = "期刊ID", required = true) @PathVariable String id, public Result update(@ApiParam(value = "期刊ID", required = true) @PathVariable String id,
@ApiParam(value = "期刊信息", required = true) @RequestBody JournalAddModel updateModel, @ApiParam(value = "Header中的token信息", required = true) @RequestHeader("Admin-Token") String token,
@ApiParam(value = "封面文件", required = true) @RequestParam("imageFile") MultipartFile imageFile){ @ApiParam(value = "期刊信息", required = true) @RequestBody JournalAddModel updateModel){
return journalService.update(id, updateModel, imageFile); return journalService.update(id, token, updateModel);
} }
@ApiOperation(value = "发布期刊", notes = "发布期刊") @ApiOperation(value = "发布期刊", notes = "发布期刊")
@RequestMapping(value="/publish/{id}",method= RequestMethod.PUT) @RequestMapping(value="/publish/{id}",method= RequestMethod.PUT)
public Result publish(@PathVariable String id, public Result publish(@PathVariable String id,
@ApiParam(value = "是否定时发布0:否1:是", required = true) @RequestParam("state") String scheduled, @ApiParam(value = "是否定时发布0:否1:是", required = true) @RequestParam("isScheduled") String isScheduled,
@ApiParam(value = "定时发布时间") @RequestParam("state") String pubTime){ @ApiParam(value = "定时发布时间") @RequestParam("state") String pubTime){
return journalService.publish(id, scheduled, pubTime); return journalService.publish(id, isScheduled, pubTime);
} }
@ApiOperation(value = "更新期刊启停状态", notes = "更新期刊启停状态") @ApiOperation(value = "更新期刊启停状态", notes = "更新期刊启停状态")
@ -74,4 +77,10 @@ public class CMSJournalController {
public Result delete(@ApiParam(value = "期刊ID", required = true) @PathVariable String id){ public Result delete(@ApiParam(value = "期刊ID", required = true) @PathVariable String id){
return journalService.deleteById(id); return journalService.deleteById(id);
} }
@ApiOperation(value = "上传期刊封面", notes = "上传期刊封面")
@RequestMapping(value = "/upload/image", method = RequestMethod.POST)
public Result batchUpload(@ApiParam(value = "封面图片文件", required = true) @RequestParam("file") MultipartFile file) {
return s3Service.upload(file, Boolean.FALSE);
}
} }

@ -6,6 +6,7 @@ import com.luoo.music.request.cms.SongAddModel;
import com.luoo.music.request.cms.SongQueryModel; import com.luoo.music.request.cms.SongQueryModel;
import com.luoo.music.response.cms.SongVO; import com.luoo.music.response.cms.SongVO;
import com.luoo.music.service.CMSSongService; import com.luoo.music.service.CMSSongService;
import com.luoo.music.service.S3Service;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,8 +25,10 @@ public class CMSSongController {
@Autowired @Autowired
private CMSSongService songService; private CMSSongService songService;
@Autowired
private S3Service s3Service;
@ApiOperation(value = "查询曲目列表", notes = "查询曲目列表") @ApiOperation(value = "查询曲列表", notes = "查询曲列表")
@RequestMapping(value="/search/{page}/{size}",method= RequestMethod.POST) @RequestMapping(value="/search/{page}/{size}",method= RequestMethod.POST)
public Result<PageResult<SongVO>> search(@ApiParam(value = "查询条件") @RequestBody SongQueryModel queryModel, public Result<PageResult<SongVO>> search(@ApiParam(value = "查询条件") @RequestBody SongQueryModel queryModel,
@ApiParam(value = "页码", required = true) @PathVariable int page, @ApiParam(value = "页码", required = true) @PathVariable int page,
@ -35,10 +38,9 @@ public class CMSSongController {
@ApiOperation(value = "新增歌曲", notes = "新增歌曲") @ApiOperation(value = "新增歌曲", notes = "新增歌曲")
@RequestMapping(value = "/add", method = RequestMethod.POST) @RequestMapping(value = "/add", method = RequestMethod.POST)
public Result add(@ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel addModel, public Result add(@ApiParam(value = "Header中的token信息", required = true) @RequestHeader("Admin-Token") String token,
@ApiParam(value = "封面图片", required = true) @RequestParam("imageFile") MultipartFile imageFile, @ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel addModel){
@ApiParam(value = "歌曲文件", required = true) @RequestParam("songFile") MultipartFile songFile){ return songService.add(token, addModel);
return songService.add(addModel, imageFile, songFile);
} }
@ApiOperation(value = "查询歌曲详情", notes = "查询歌曲详情") @ApiOperation(value = "查询歌曲详情", notes = "查询歌曲详情")
@ -49,11 +51,10 @@ public class CMSSongController {
@ApiOperation(value = "更新歌曲信息", notes = "更新歌曲信息") @ApiOperation(value = "更新歌曲信息", notes = "更新歌曲信息")
@RequestMapping(value = "/{id}", method = RequestMethod.PUT) @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public Result update(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id, public Result update(@ApiParam(value = "Header中的token信息", required = true) @RequestHeader("Admin-Token") String token,
@ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel updateModel, @ApiParam(value = "歌曲ID", required = true) @PathVariable String id,
@ApiParam(value = "封面图片", required = true) @RequestParam("imageFile") MultipartFile imageFile, @ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel updateModel){
@ApiParam(value = "歌曲文件", required = true) @RequestParam("songFile") MultipartFile songFile){ return songService.update(id, token, updateModel);
return songService.update(id, updateModel, imageFile, songFile);
} }
@ApiOperation(value = "更新歌曲启停状态", notes = "更新歌曲启停状态") @ApiOperation(value = "更新歌曲启停状态", notes = "更新歌曲启停状态")
@ -66,20 +67,26 @@ public class CMSSongController {
@ApiOperation(value = "更新歌曲歌词", notes = "更新歌曲歌词") @ApiOperation(value = "更新歌曲歌词", notes = "更新歌曲歌词")
@RequestMapping(value="/update/lyric/{id}",method= RequestMethod.PUT) @RequestMapping(value="/update/lyric/{id}",method= RequestMethod.PUT)
public Result updateSongLyric(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id, public Result updateSongLyric(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id,
@ApiParam(value = "歌曲歌词", required = true) @RequestParam("lyric") String lyric){ @ApiParam(value = "歌曲歌词信息", required = true) @RequestBody SongAddModel updateModel){
return songService.updateSongLyric(id, lyric); return songService.updateSongLyric(id, updateModel.getLyric());
} }
@ApiOperation(value = "批量上传歌曲", notes = "批量上传歌曲")
@RequestMapping(value = "/batch", method = RequestMethod.POST)
public Result batchUpload(@ApiParam(value = "多歌曲文件", required = true) @RequestParam("files") List<MultipartFile> files) {
return songService.batchUpload(files);
}
@ApiOperation(value = "删除单条歌曲", notes = "删除单条歌曲") @ApiOperation(value = "删除单条歌曲", notes = "删除单条歌曲")
@RequestMapping(value="/{id}", method= RequestMethod.DELETE) @RequestMapping(value="/{id}", method= RequestMethod.DELETE)
public Result delete(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id){ public Result delete(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id){
return songService.deleteById(id); return songService.deleteById(id);
} }
@ApiOperation(value = "上传歌曲", notes = "上传歌曲")
@RequestMapping(value = "/upload/song", method = RequestMethod.POST)
public Result batchUpload(@ApiParam(value = "歌曲文件", required = true) @RequestParam("file") MultipartFile file) {
return s3Service.upload(file, Boolean.TRUE);
}
@ApiOperation(value = "批量上传歌曲", notes = "批量上传歌曲")
@RequestMapping(value = "/batch", method = RequestMethod.POST)
public Result batchUpload(@ApiParam(value = "多歌曲文件", required = true) @RequestParam("files") List<MultipartFile> files) {
return songService.batchUpload(files);
}
} }

@ -1,75 +1,75 @@
package com.luoo.music.controller; //package com.luoo.music.controller;
//
//
import api.Result; //import api.Result;
import com.luoo.music.service.S3Service; //import com.luoo.music.service.S3Service;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin; //import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping; //import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; //import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController; //import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; //import org.springframework.web.multipart.MultipartFile;
//
import java.io.UnsupportedEncodingException; //import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat; //import java.text.SimpleDateFormat;
import java.util.Date; //import java.util.Date;
import java.util.List; //import java.util.List;
//
@RestController //@RestController
@CrossOrigin //@CrossOrigin
public class S3Controller { //public class S3Controller {
//
@Autowired // @Autowired
private S3Service s3Service; // private S3Service s3Service;
//
//
@GetMapping("/awstest") // @GetMapping("/awstest")
public Result test() throws UnsupportedEncodingException { // public Result test() throws UnsupportedEncodingException {
//
// s3Service.listObjects() //// s3Service.listObjects()
List list = s3Service.list(); // List list = s3Service.list();
return Result.success(); // return Result.success();
} // }
//
//
/** // /**
* // * 文件存储目录规划
* // *
* music // * music 存放期刊和期刊歌曲 二级目录为期刊期刊号 三级目录存放期刊歌曲和封面图片和歌曲图片
* // *
* song // * song 存放通用歌曲
* // *
* image // * image存放图片
* // *
* img // * img
* // *
* user/avatar/111.jpg // * user/avatar/111.jpg
* // *
* // *
* // *
* // *
*/ // */
@PostMapping("/awsUpload") // @PostMapping("/awsUpload")
public Result upload(MultipartFile file) { // public Result upload(MultipartFile file) {
//
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); // SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
// String fileName = UUID.randomUUID().toString().trim().replaceAll("-", ""); //// String fileName = UUID.randomUUID().toString().trim().replaceAll("-", "");
//
//
String filePath = sdf.format(new Date()) + "/" + file.getOriginalFilename(); // String filePath = sdf.format(new Date()) + "/" + file.getOriginalFilename();
try{ // try{
int code = s3Service.singleUpload("indie", filePath, file); // int code = s3Service.singleUpload("indie", filePath, file);
//
} catch (Exception ex){ // } catch (Exception ex){
} // }
//
//
return Result.success(); // return Result.success();
} // }
//
@PostMapping("/awsCopy") // @PostMapping("/awsCopy")
public Result copy() { // public Result copy() {
s3Service.copy(); // s3Service.copy();
return Result.success(); // return Result.success();
} // }
} //}

@ -16,6 +16,10 @@ import java.util.Set;
*/ */
public interface JournalDao extends JpaRepository<Journal,String>,JpaSpecificationExecutor<Journal>{ public interface JournalDao extends JpaRepository<Journal,String>,JpaSpecificationExecutor<Journal>{
List<Journal> findByJournalNo(String journalNo);
List<Journal> findByJournalNoIn(Set<String> journalNos);
List<Journal> findByIdIn(Set<String> ids); List<Journal> findByIdIn(Set<String> ids);
@Modifying @Modifying
@ -24,9 +28,8 @@ public interface JournalDao extends JpaRepository<Journal,String>,JpaSpecificati
@Param("pubTime") LocalDateTime pubTime); @Param("pubTime") LocalDateTime pubTime);
@Modifying @Modifying
@Query("UPDATE Journal j SET j.scheduled = :scheduled, j.pubTime = :pubTime WHERE j.id = :id") @Query("UPDATE Journal j SET j.isScheduled = '1', j.pubTime = :pubTime WHERE j.id = :id")
int updateScheduledPubById(@Param("id") String id, int updateScheduledPubById(@Param("id") String id,
@Param("scheduled") String scheduled,
@Param("pubTime") LocalDateTime pubTime); @Param("pubTime") LocalDateTime pubTime);
@Modifying @Modifying

@ -15,21 +15,21 @@ import java.util.List;
*/ */
public interface JournalSongDao extends JpaRepository<JournalSong,String>, JpaSpecificationExecutor<JournalSong> { public interface JournalSongDao extends JpaRepository<JournalSong,String>, JpaSpecificationExecutor<JournalSong> {
@Query("SELECT js.journalId, COUNT(js) AS songCount FROM JournalSong js WHERE js.journalId IN :journalIds GROUP BY js.journalId") @Query("SELECT js.journalNo, COUNT(js) AS songCount FROM JournalSong js WHERE js.journalNo IN :journalNos GROUP BY js.journalNo")
List<JournalSongCount> findSongCountByJournalIds(@Param("journalIds") List<String> journalIds); List<JournalSongCount> findSongCountByJournalNos(@Param("journalNos") List<String> journalNos);
@Query("SELECT js.journalId FROM JournalSong js WHERE js.songId = :songId") @Query("SELECT js FROM JournalSong js WHERE js.journalNo = :journalNo ORDER BY js.songNo")
List<String> findJournalBySongId(@Param("songId") String songId); List<JournalSong> findByJournalNo(@Param("journalNo") String journalNo);
@Query("SELECT js FROM JournalSong js WHERE js.songId IN :songIds ORDER BY js.id") @Modifying
List<JournalSong> findBySongId(@Param("songIds") List<String> songIds); @Query("DELETE FROM JournalSong js WHERE js.journalNo = :journalNo")
int deleteByJournalNo(@Param("journalNo") String journalNo);
@Query("SELECT js FROM JournalSong js WHERE js.journalId = :journalId ORDER BY js.id") @Query("SELECT js.journalNo FROM JournalSong js WHERE js.songId = :songId")
List<JournalSong> findByJournalId(@Param("journalId") String journalId); List<String> findJournalBySongId(@Param("songId") String songId);
@Modifying @Query("SELECT js FROM JournalSong js WHERE js.songId IN :songIds")
@Query("DELETE FROM JournalSong js WHERE js.journalId = :journalId") List<JournalSong> findBySongId(@Param("songIds") List<String> songIds);
int deleteByJournalId(@Param("journalId") String journalId);
@Modifying @Modifying
@Query("DELETE FROM JournalSong js WHERE js.songId = :songId") @Query("DELETE FROM JournalSong js WHERE js.songId = :songId")

@ -23,5 +23,5 @@ public interface SongInfoDao extends JpaRepository<SongInfo,String>, JpaSpecific
@Query("UPDATE SongInfo s SET s.lyric = :lyric WHERE s.id = :id") @Query("UPDATE SongInfo s SET s.lyric = :lyric WHERE s.id = :id")
int updateSongLyric(@Param("id") String id, @Param("lyric") String lyric); int updateSongLyric(@Param("id") String id, @Param("lyric") String lyric);
List<SongInfo> findByIdIn(Set<String> ids); List<SongInfo> findByIdIn(List<String> ids);
} }

@ -20,9 +20,9 @@ import java.time.LocalDateTime;
*/ */
@Data @Data
@Entity @Entity
@Table(name="tb_journal")
@DynamicInsert @DynamicInsert
@DynamicUpdate @DynamicUpdate
@Table(name="tb_journal")
@EntityListeners(AuditingEntityListener.class) @EntityListeners(AuditingEntityListener.class)
public class Journal implements Serializable{ public class Journal implements Serializable{
@ -32,19 +32,19 @@ public class Journal implements Serializable{
/** /**
* *
*/ */
private String number; private String journalNo;
/** /**
* *
*/ */
private String name; private String title;
/** /**
* *
*/ */
private String summary; private String image;
/** /**
* ID *
*/ */
private String userId; private String content;
/** /**
* 01 * 01
*/ */
@ -52,27 +52,43 @@ public class Journal implements Serializable{
/** /**
* 01 * 01
*/ */
private String status; private String isPublish;
/** /**
* 0 1 * 0 1
*/ */
private String scheduled; private String isScheduled;
/** /**
* *
*/
private Integer visits;
/**
*
*/ */
private String coverPhoto; private Integer comment;
/** /**
* *
*/ */
private LocalDateTime pubTime; private LocalDateTime pubTime;
/** /**
* *
*/ */
@CreatedDate @CreatedDate
private LocalDateTime createTime; private LocalDateTime createTime;
/** /**
* *
*/ */
@LastModifiedDate @LastModifiedDate
private LocalDateTime updateTime; private LocalDateTime updateTime;
/**
* ID
*/
private String userId;
/**
*
*/
private String userName;
/**
*
*/
private String userType;
} }

@ -7,7 +7,7 @@ import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
/** /**
* *
* @author locust * @author locust
*/ */
@Data @Data
@ -18,6 +18,36 @@ public class JournalSong {
@Id @Id
private String id; private String id;
private String journalId; /**
*
*/
private String name;
/**
* /
*/
private String artist;
/**
*
*/
private String album;
/**
*
*/
private String url;
/**
*
*/
private String image;
/**
*
*/
private String journalNo;
/**
*
*/
private Integer songNo;
/**
* ID
*/
private String songId; private String songId;
} }

@ -6,7 +6,7 @@ package com.luoo.music.pojo;
*/ */
public interface JournalSongCount { public interface JournalSongCount {
String getJournalId(); String getJournalNo();
Long getSongCount(); Long getSongCount();
} }

@ -43,13 +43,13 @@ public class SongInfo implements Serializable {
*/ */
private String album; private String album;
/** /**
* *
*/ */
private String picture; private String url;
/** /**
* 0:1: *
*/ */
private String state; private String image;
/** /**
* *
*/ */
@ -59,25 +59,33 @@ public class SongInfo implements Serializable {
*/ */
private Long duration; private Long duration;
/** /**
* * 0:1:
*/ */
private String url; private String state;
/** /**
* *
*/ */
private String lyric; @CreatedDate
private LocalDateTime createTime;
/** /**
* ID *
*/
@LastModifiedDate
private LocalDateTime updateTime;
/**
* ID
*/ */
private String userId; private String userId;
/** /**
* *
*/ */
@CreatedDate private String userName;
private LocalDateTime createTime;
/** /**
* *
*/ */
@LastModifiedDate private String userType;
private LocalDateTime updateTime; /**
*
*/
private String lyric;
} }

@ -14,20 +14,23 @@ import java.util.List;
public class JournalAddModel { public class JournalAddModel {
@ApiModelProperty(value = "期刊编号") @ApiModelProperty(value = "期刊编号")
private String number; private String journalNo;
@ApiModelProperty(value = "期刊标题") @ApiModelProperty(value = "期刊标题")
private String name; private String title;
@ApiModelProperty(value = "关联标签标签ID")
private List<String> tags;
@ApiModelProperty(value = "发布人ID") @ApiModelProperty(value = "发布人ID")
private String userId; private String userId;
@ApiModelProperty(value = "关联标签标签ID") @ApiModelProperty(value = "期刊封面路径")
private List<String> tags; private String image;
@ApiModelProperty(value = "关联歌曲音乐ID") @ApiModelProperty(value = "关联歌曲音乐ID")
private List<String> songs; private List<String> songs;
@ApiModelProperty(value = "期刊内容") @ApiModelProperty(value = "期刊内容")
private String summary; private String content;
} }

@ -30,4 +30,16 @@ public class SongAddModel {
@ApiModelProperty(value = "风格标签ID集合") @ApiModelProperty(value = "风格标签ID集合")
private List<String> tags; private List<String> tags;
@ApiModelProperty(value = "歌曲文件路径")
private String url;
@ApiModelProperty(value = "图片文件路径")
private String image;
@ApiModelProperty(value = "文件大小")
private Long size;
@ApiModelProperty(value = "歌曲时长")
private Long duration;
} }

@ -14,6 +14,9 @@ public class SongQueryModel {
@ApiModelProperty(value = "关键词") @ApiModelProperty(value = "关键词")
private String keyword; private String keyword;
@ApiModelProperty(value = "歌曲启用状态,曲库添加音乐检索歌曲时需传此参数 state=1")
private String state;
@ApiModelProperty(value = "发布者ID") @ApiModelProperty(value = "发布者ID")
private String userId; private String userId;

@ -18,13 +18,13 @@ public class JournalVO {
private String id; private String id;
@ApiModelProperty(value = "期刊编号") @ApiModelProperty(value = "期刊编号")
private String number; private String journalNo;
@ApiModelProperty(value = "期刊标题") @ApiModelProperty(value = "期刊标题")
private String name; private String title;
@ApiModelProperty(value = "期刊封面") @ApiModelProperty(value = "期刊封面")
private String coverPhoto; private String image;
@ApiModelProperty(value = "期刊标签") @ApiModelProperty(value = "期刊标签")
private List<String> tag; private List<String> tag;
@ -33,13 +33,16 @@ public class JournalVO {
private long songCount; private long songCount;
@ApiModelProperty(value = "评论数") @ApiModelProperty(value = "评论数")
private long commentCount; private long comment;
@ApiModelProperty(value = "播放数") @ApiModelProperty(value = "播放数")
private long playCount; private long visits;
@ApiModelProperty(value = "发布作者") @ApiModelProperty(value = "发布作者id")
private String userId;// private String userId;
@ApiModelProperty(value = "发布作者昵称")
private String userName;
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
private String createTime; private String createTime;
@ -51,11 +54,11 @@ public class JournalVO {
private String state; private String state;
@ApiModelProperty(value = "期刊发布状态0:待发布1:已发布") @ApiModelProperty(value = "期刊发布状态0:待发布1:已发布")
private String status; private String isPublish;
@ApiModelProperty(value = "期刊歌曲信息") @ApiModelProperty(value = "期刊歌曲信息")
private List<SongVO> songs; private List<SongVO> songs;
@ApiModelProperty(value = "期刊简介信息") @ApiModelProperty(value = "期刊简介信息")
private String summary; private String content;
} }

@ -29,7 +29,7 @@ public class SongVO {
private List<String> tags; private List<String> tags;
@ApiModelProperty(value = "封面路径") @ApiModelProperty(value = "封面路径")
private String picture; private String image;
@ApiModelProperty(value = "文件大小") @ApiModelProperty(value = "文件大小")
private String size; private String size;
@ -46,9 +46,12 @@ public class SongVO {
@ApiModelProperty(value = "歌曲启停状态0:停用1:启用") @ApiModelProperty(value = "歌曲启停状态0:停用1:启用")
private String state; private String state;
@ApiModelProperty(value = "上传人员") @ApiModelProperty(value = "上传人员ID")
private String userId; private String userId;
@ApiModelProperty(value = "上传人员昵称")
private String userName;
@ApiModelProperty(value = "文件路径") @ApiModelProperty(value = "文件路径")
private String url; private String url;

@ -0,0 +1,27 @@
package com.luoo.music.response.cms;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author locust
*/
@Data
@ApiModel(description = "文件上传后的路径")
public class UploadRespDto {
@ApiModelProperty(value = "部分路径")
private String partUrl;
@ApiModelProperty(value = "全路径")
private String fullUrl;
@ApiModelProperty(value = "文件大小")
private Long size;
@ApiModelProperty(value = "歌曲时长")
private Long duration;
}

@ -8,8 +8,9 @@ import com.luoo.music.request.cms.JournalAddModel;
import com.luoo.music.request.cms.JournalQueryModel; import com.luoo.music.request.cms.JournalQueryModel;
import com.luoo.music.response.cms.JournalVO; import com.luoo.music.response.cms.JournalVO;
import com.luoo.music.response.cms.SongVO; import com.luoo.music.response.cms.SongVO;
import com.luoo.music.util.CommonUtil; import com.luoo.music.util.Constants;
import com.luoo.music.util.UploadUtil; import com.luoo.music.util.UploadUtil;
import dto.UserLoginDto;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -18,13 +19,14 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import util.IdWorker; import util.IdWorker;
import util.JwtUtil;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import java.io.File;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
@ -36,6 +38,8 @@ import java.util.stream.Collectors;
@Service @Service
public class CMSJournalService { public class CMSJournalService {
@Autowired
private S3Service s3Service;
@Autowired @Autowired
private IdWorker idWorker; private IdWorker idWorker;
@Autowired @Autowired
@ -48,6 +52,8 @@ public class CMSJournalService {
private TagDao tagDao; private TagDao tagDao;
@Autowired @Autowired
private SongInfoDao songDao; private SongInfoDao songDao;
@Autowired
private JwtUtil jwtUtil;
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -78,32 +84,27 @@ public class CMSJournalService {
List<Journal> content = journalPage.getContent(); List<Journal> content = journalPage.getContent();
if (!CollectionUtils.isEmpty(content)) { if (!CollectionUtils.isEmpty(content)) {
List<String> ids = content.stream().map(Journal::getId).collect(Collectors.toList()); List<String> ids = content.stream().map(Journal::getId).collect(Collectors.toList());
Map<String, Long> songCountMap = songCountInfo(ids);
Map<String, List<String>> journalTagMap = tagInfo(ids); Map<String, List<String>> journalTagMap = tagInfo(ids);
List<String> journalNos = content.stream().map(Journal::getJournalNo).collect(Collectors.toList());
Map<String, Long> songCountMap = songCountInfo(journalNos);
for (Journal item : content) { for (Journal item : content) {
JournalVO response = new JournalVO(); JournalVO response = new JournalVO();
response.setId(item.getId()); response.setId(item.getId());
response.setNumber(item.getNumber()); response.setJournalNo(Constants.JOURNAL_NO_PREF + item.getJournalNo());
response.setName(item.getName()); response.setTitle(item.getTitle());
response.setCoverPhoto(item.getCoverPhoto()); response.setImage(item.getImage());
response.setCreateTime(item.getCreateTime().format(formatter)); response.setCreateTime(item.getCreateTime().format(formatter));
response.setState(item.getState()); response.setState(item.getState());
response.setStatus(item.getStatus()); response.setIsPublish(item.getIsPublish());
if (!Objects.isNull(item.getPubTime())) { if (!Objects.isNull(item.getPubTime())) {
response.setPubTime(item.getPubTime().format(formatter)); response.setPubTime(item.getPubTime().format(formatter));
} }
// TODO 编号文字转换
response.setUserId(item.getUserId()); response.setUserId(item.getUserId());
response.setUserName(item.getUserName());
response.setSongCount(songCountMap.get(item.getId())); response.setSongCount(songCountMap.get(item.getId()));
response.setTag(journalTagMap.get(item.getId())); response.setTag(journalTagMap.get(item.getId()));
if (!"1".equals(param.getTab())) { response.setVisits(item.getVisits());
response.setPlayCount(0); response.setComment(item.getComment());
response.setCommentCount(0);
} else {
// TODO 播放 评论 数
response.setPlayCount(0);
response.setCommentCount(0);
}
result.add(response); result.add(response);
} }
} }
@ -119,30 +120,30 @@ public class CMSJournalService {
return (Root<Journal> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> { return (Root<Journal> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
List<Predicate> predicateList = new ArrayList<Predicate>(); List<Predicate> predicateList = new ArrayList<Predicate>();
if("1".equals(param.getTab())) { if("1".equals(param.getTab())) {
Predicate state = builder.equal(root.get("state"), "1"); predicateList.add(builder.equal(root.get("isPublish"), "1"));
Predicate status = builder.equal(root.get("status"), "1");
predicateList.add(builder.and(state, status));
} else if ("2".equals(param.getTab())) { } else if ("2".equals(param.getTab())) {
predicateList.add(builder.equal(root.get("state"), "0")); predicateList.add(builder.equal(root.get("state"), "0"));
} else { } else {
Predicate state = builder.equal(root.get("state"), "1"); Predicate state = builder.equal(root.get("state"), "1");
Predicate status = builder.equal(root.get("status"), "0"); Predicate isPublish = builder.equal(root.get("isPublish"), "0");
predicateList.add(builder.and(state, status)); predicateList.add(builder.and(state, isPublish));
} }
if(StringUtils.isNotBlank(param.getUserId())) { if(StringUtils.isNotBlank(param.getUserId())) {
predicateList.add(builder.equal(root.get("userId"), param.getUserId())); predicateList.add(builder.equal(root.get("userId"), param.getUserId()));
} }
if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) { if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) {
predicateList.add(builder.between(root.get("createTime"), param.getStart(), param.getEnd())); LocalDateTime start = LocalDateTime.parse(param.getStart() + "T00:00:00");
LocalDateTime end = LocalDateTime.parse(param.getEnd() + "T00:00:00");
predicateList.add(builder.between(root.get("createTime"), start, end));
} }
if (!CollectionUtils.isEmpty(ids)) { if (!CollectionUtils.isEmpty(ids)) {
predicateList.add(root.get("id").in(ids)); predicateList.add(root.get("journalNo").in(ids));
} }
if(StringUtils.isNotBlank(param.getKeyword())) { if(StringUtils.isNotBlank(param.getKeyword())) {
String likeExpression = "%" + param.getKeyword() + "%"; String likeExpression = "%" + param.getKeyword() + "%";
Predicate name = builder.like(root.get("number"), likeExpression); Predicate journalNo = builder.like(root.get("journalNo"), likeExpression);
Predicate summary = builder.like(root.get("name"), likeExpression); Predicate title = builder.like(root.get("title"), likeExpression);
predicateList.add(builder.or(name, summary)); predicateList.add(builder.or(journalNo, title));
} }
return builder.and(predicateList.toArray(new Predicate[predicateList.size()])); return builder.and(predicateList.toArray(new Predicate[predicateList.size()]));
}; };
@ -150,14 +151,14 @@ public class CMSJournalService {
/** /**
* *
* @param ids * @param journalNos
* @return * @return
*/ */
private Map<String, Long> songCountInfo(List<String> ids) { private Map<String, Long> songCountInfo(List<String> journalNos) {
Map<String, Long> songCountMap = new HashMap<>(); Map<String, Long> songCountMap = new HashMap<>();
if (!CollectionUtils.isEmpty(ids)) { if (!CollectionUtils.isEmpty(journalNos)) {
List<JournalSongCount> journalSongCountList = journalSongDao.findSongCountByJournalIds(ids); List<JournalSongCount> journalSongCountList = journalSongDao.findSongCountByJournalNos(journalNos);
songCountMap = journalSongCountList.stream().collect(Collectors.toMap(JournalSongCount::getJournalId, JournalSongCount::getSongCount)); songCountMap = journalSongCountList.stream().collect(Collectors.toMap(JournalSongCount::getJournalNo, JournalSongCount::getSongCount));
} }
return songCountMap; return songCountMap;
} }
@ -193,56 +194,107 @@ public class CMSJournalService {
/** /**
* *
* @param param * @param param
* @param image
* @return * @return
*/ */
public Result add(JournalAddModel param, MultipartFile image) { public Result add(String token, JournalAddModel param) {
String imagePath = UploadUtil.upload(image, UploadUtil.IMAGE_DIR); List<Journal> byJournalNo = journalDao.findByJournalNo(param.getJournalNo());
Journal journal = buildJournal(null, param); if (byJournalNo.size() > 0) {
String id = String.valueOf(idWorker.nextId()); return Result.failed("保存失败,期刊编号已存在");
journal.setId(id); }
journal.setCoverPhoto(imagePath); String image = moveJournalImage(param);
journalDao.save(journal); if (StringUtils.isNotBlank(image)) {
batchSaveJournalRelatesInfo(id, param); Journal journal = buildJournal(null, param, token);
return Result.success(); String id = String.valueOf(idWorker.nextId());
journal.setId(id);
journal.setImage(image);
journalDao.save(journal);
batchSaveJournalRelatesInfo(id, param);
return Result.success();
} else {
return Result.failed("保存失败");
}
}
/**
*
* @param param
* @return
*/
private String moveJournalImage(JournalAddModel param) {
String image = param.getImage();
String srcKey = image.substring(image.indexOf(Constants.TEMP_KEY_PREFIX));
String suffix = image.substring(image.lastIndexOf(Constants.DOT));
String format = String.format("%05d", param.getJournalNo());
String destKeySuffix = format + "/00" + suffix;
String destKey = Constants.IMAGE_KEY_PREFIX + destKeySuffix;
int copy = s3Service.copy(Constants.BUCKET, srcKey, destKey);
if (copy > 0) {
return destKeySuffix;
}
return null;
} }
private Journal buildJournal(String id, JournalAddModel param) { /**
*
* @param id
* @param param
* @param token
* @return
*/
private Journal buildJournal(String id, JournalAddModel param, String token) {
Journal journal = new Journal(); Journal journal = new Journal();
if (!StringUtils.isBlank(id)) { if (!StringUtils.isBlank(id)) {
journal.setId(id); journal.setId(id);
} }
journal.setNumber(param.getNumber()); journal.setJournalNo(param.getJournalNo());
journal.setName(param.getName()); journal.setTitle(param.getTitle());
journal.setUserId(param.getUserId()); journal.setContent(param.getContent());
journal.setSummary(param.getSummary()); UserLoginDto user = jwtUtil.getUserLoginDto(token);
journal.setUserId(user.getUserId());
journal.setUserName(user.getNickName());
journal.setUserType(user.getRoles());
return journal; return journal;
} }
/** /**
* *
* @param id * @param journalId
* @param param * @param param
*/ */
private void batchSaveJournalRelatesInfo(String id, JournalAddModel param) { private void batchSaveJournalRelatesInfo(String journalId, JournalAddModel param) {
// 标签信息
if (!CollectionUtils.isEmpty(param.getTags())) { if (!CollectionUtils.isEmpty(param.getTags())) {
List<JournalTag> journalTagList = new ArrayList<>(); List<JournalTag> journalTagList = new ArrayList<>();
for (String item : param.getTags()) { for (String item : param.getTags()) {
JournalTag journalTag = new JournalTag(); JournalTag journalTag = new JournalTag();
journalTag.setId(String.valueOf(idWorker.nextId())); journalTag.setId(String.valueOf(idWorker.nextId()));
journalTag.setJournalId(id); journalTag.setJournalId(journalId);
journalTag.setTagId(item); journalTag.setTagId(item);
journalTagList.add(journalTag); journalTagList.add(journalTag);
} }
journalTagDao.saveAll(journalTagList); journalTagDao.saveAll(journalTagList);
} }
// 歌曲信息
if (!CollectionUtils.isEmpty(param.getSongs())) { if (!CollectionUtils.isEmpty(param.getSongs())) {
List<SongInfo> songList = songDao.findByIdIn(param.getSongs());
Map<String, SongInfo> idSongMap = songList.stream().collect(Collectors.toMap(SongInfo::getId, obj -> obj));
List<JournalSong> journalSongList = new ArrayList<>(); List<JournalSong> journalSongList = new ArrayList<>();
int num = 0;
for (String item : param.getSongs()) { for (String item : param.getSongs()) {
JournalSong journalSong = new JournalSong(); if (idSongMap.containsKey(item)) {
journalSong.setId(String.valueOf(idWorker.nextId())); SongInfo song = idSongMap.get(item);
journalSong.setJournalId(id); JournalSong journalSong = new JournalSong();
journalSong.setSongId(item); journalSong.setId(String.valueOf(idWorker.nextId()));
journalSong.setName(song.getName());
journalSong.setArtist(song.getArtist());
journalSong.setUrl(song.getUrl());
journalSong.setImage(song.getImage());
journalSong.setSongId(item);
journalSong.setJournalNo(param.getJournalNo());
journalSong.setSongNo(num + 1);
journalSong.setSongId(song.getId());
journalSongList.add(journalSong);
}
} }
journalSongDao.saveAll(journalSongList); journalSongDao.saveAll(journalSongList);
} }
@ -257,41 +309,33 @@ public class CMSJournalService {
Journal journal = journalDao.findById(id).get(); Journal journal = journalDao.findById(id).get();
JournalVO response = new JournalVO(); JournalVO response = new JournalVO();
response.setId(journal.getId()); response.setId(journal.getId());
response.setNumber(journal.getNumber()); response.setJournalNo(journal.getJournalNo());
response.setName(journal.getName()); response.setTitle(journal.getTitle());
response.setTag(journalTagDao.findTagsByJournalId(id)); response.setTag(journalTagDao.findTagsByJournalId(id));
response.setUserId(journal.getUserId()); response.setUserId(journal.getUserId());
response.setCoverPhoto(journal.getCoverPhoto()); response.setImage(Constants.IMAGE_RESOURCE_PREFIX + journal.getImage());
response.setSongs(songInfo(journal.getId())); response.setSongs(journalSongInfo(journal.getJournalNo()));
response.setSummary(journal.getSummary()); response.setContent(journal.getContent());
return Result.success(response); return Result.success(response);
} }
/** /**
* *
* @param id * @param journalNo
* @return * @return
*/ */
private List<SongVO> songInfo(String id) { private List<SongVO> journalSongInfo(String journalNo) {
List<SongVO> list = new ArrayList<>(); List<SongVO> list = new ArrayList<>();
List<JournalSong> journalSongList = journalSongDao.findByJournalId(id); List<JournalSong> journalSongList = journalSongDao.findByJournalNo(journalNo);
if (!CollectionUtils.isEmpty(journalSongList)) { if (!CollectionUtils.isEmpty(journalSongList)) {
Set<String> songIdSet = journalSongList.stream().map(JournalSong::getSongId).collect(Collectors.toSet());
List<SongInfo> songList = songDao.findByIdIn(songIdSet);
Map<String, SongInfo> idTagMap = songList.stream().collect(Collectors.toMap(SongInfo::getId, obj -> obj));
for (JournalSong item : journalSongList) { for (JournalSong item : journalSongList) {
if (idTagMap.containsKey(item.getSongId())) { SongVO songVO = new SongVO();
SongInfo song = idTagMap.get(item.getSongId()); songVO.setId(item.getSongId());
SongVO songVO = new SongVO(); songVO.setImage(Constants.RESOURCE_PREFIX + Constants.MUSIC_KEY_PREFIX + item.getImage());
songVO.setId(song.getId()); songVO.setName(item.getName());
songVO.setPicture(song.getPicture()); songVO.setArtist(item.getArtist());
songVO.setName(song.getName()); songVO.setAlbum(item.getAlbum());
songVO.setArtist(song.getArtist()); list.add(songVO);
songVO.setAlbum(song.getAlbum());
songVO.setDuration(CommonUtil.formatSongDuration(song.getDuration()));
songVO.setLyric(song.getLyric());
list.add(songVO);
}
} }
} }
return list; return list;
@ -300,32 +344,39 @@ public class CMSJournalService {
/** /**
* *
* @param id * @param id
* @param token
* @param param * @param param
* @param image
* @return * @return
*/ */
public Result update(String id, JournalAddModel param, MultipartFile image) { public Result update(String id, String token, JournalAddModel param) {
Journal journal = buildJournal(id, param); List<Journal> byJournalNo = journalDao.findByJournalNo(param.getJournalNo());
if (byJournalNo.size() > 0) {
return Result.failed("更新失败,期刊编号已存在");
}
Journal journal = buildJournal(id, param, token);
Journal oldJournal = journalDao.findById(id).get(); Journal oldJournal = journalDao.findById(id).get();
boolean bool = UploadUtil.fileHasChanged(oldJournal.getCoverPhoto(), image); String image = null;
if (bool) { if (param.getImage().contains(Constants.TEMP_KEY_PREFIX)) {
String imagePath = UploadUtil.upload(image, UploadUtil.IMAGE_DIR); image = moveJournalImage(param);
journal.setCoverPhoto(imagePath); if (StringUtils.isBlank(image)) {
Result.failed("更新失败");
}
} }
journal.setImage(image);
journalDao.save(journal); journalDao.save(journal);
batchDeleteJournalRelatesInfo(id); batchDeleteJournalRelatesInfo(id, oldJournal.getJournalNo());
batchSaveJournalRelatesInfo(id, param); batchSaveJournalRelatesInfo(id, param);
return Result.success(); return Result.success();
} }
/** /**
* *
* @param id * @param journalId
* @param journalNo
*/ */
private void batchDeleteJournalRelatesInfo(String id) { private void batchDeleteJournalRelatesInfo(String journalId, String journalNo) {
journalTagDao.deleteByJournalId(id); journalTagDao.deleteByJournalId(journalId);
journalSongDao.deleteByJournalId(id); journalSongDao.deleteByJournalNo(journalNo);
} }
/** /**
@ -340,7 +391,7 @@ public class CMSJournalService {
if ("1".equals(scheduled)) { if ("1".equals(scheduled)) {
if (StringUtils.isNotBlank(pubTimeStr)){ if (StringUtils.isNotBlank(pubTimeStr)){
pubTime = LocalDateTime.parse(pubTimeStr, formatter); pubTime = LocalDateTime.parse(pubTimeStr, formatter);
journalDao.updateScheduledPubById(id, scheduled, pubTime); journalDao.updateScheduledPubById(id, pubTime);
} }
} }
journalDao.updatePubById(id, pubTime); journalDao.updatePubById(id, pubTime);
@ -364,8 +415,11 @@ public class CMSJournalService {
* @return * @return
*/ */
public Result deleteById(String id) { public Result deleteById(String id) {
journalDao.deleteById(id); Journal journal = journalDao.findById(id).get();
batchDeleteJournalRelatesInfo(id); if (!Objects.isNull(journal)) {
journalDao.deleteById(id);
batchDeleteJournalRelatesInfo(id, journal.getJournalNo());
}
return Result.success(); return Result.success();
} }
} }

@ -8,7 +8,9 @@ import com.luoo.music.request.cms.SongAddModel;
import com.luoo.music.request.cms.SongQueryModel; import com.luoo.music.request.cms.SongQueryModel;
import com.luoo.music.response.cms.SongVO; import com.luoo.music.response.cms.SongVO;
import com.luoo.music.util.CommonUtil; import com.luoo.music.util.CommonUtil;
import com.luoo.music.util.Constants;
import com.luoo.music.util.UploadUtil; import com.luoo.music.util.UploadUtil;
import dto.UserLoginDto;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.tika.metadata.Metadata; import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser; import org.apache.tika.parser.AutoDetectParser;
@ -23,6 +25,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import util.IdWorker; import util.IdWorker;
import util.JwtUtil;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@ -33,6 +36,7 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -42,6 +46,8 @@ import java.util.stream.Collectors;
@Service @Service
public class CMSSongService { public class CMSSongService {
@Autowired
private S3Service s3Service;
@Autowired @Autowired
private SongInfoDao songDao; private SongInfoDao songDao;
@Autowired @Autowired
@ -54,6 +60,8 @@ public class CMSSongService {
private JournalDao journalDao; private JournalDao journalDao;
@Autowired @Autowired
private TagDao tagDao; private TagDao tagDao;
@Autowired
private JwtUtil jwtUtil;
private DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
@ -90,7 +98,7 @@ public class CMSSongService {
response.setArtist(item.getArtist()); response.setArtist(item.getArtist());
response.setAlbum(item.getAlbum()); response.setAlbum(item.getAlbum());
response.setTags(songTagMap.get(id)); response.setTags(songTagMap.get(id));
response.setPicture(item.getPicture()); response.setImage(item.getImage());
response.setSize(CommonUtil.formatSongSize(item.getSize())); response.setSize(CommonUtil.formatSongSize(item.getSize()));
response.setDuration(CommonUtil.formatSongDuration(item.getDuration())); response.setDuration(CommonUtil.formatSongDuration(item.getDuration()));
response.setJournal(songJournalMap.get(id)); response.setJournal(songJournalMap.get(id));
@ -113,10 +121,15 @@ public class CMSSongService {
return (Root<SongInfo> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> { return (Root<SongInfo> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
List<Predicate> predicateList = new ArrayList<Predicate>(); List<Predicate> predicateList = new ArrayList<Predicate>();
if(StringUtils.isNotBlank(param.getUserId())) { if(StringUtils.isNotBlank(param.getUserId())) {
predicateList.add(builder.equal(root.get("user_id"), param.getUserId())); predicateList.add(builder.equal(root.get("userId"), param.getUserId()));
} }
if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) { if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) {
predicateList.add(builder.between(root.get("create_time"), param.getStart(), param.getEnd())); LocalDateTime start = LocalDateTime.parse(param.getStart() + "T00:00:00");
LocalDateTime end = LocalDateTime.parse(param.getEnd() + "T00:00:00");
predicateList.add(builder.between(root.get("createTime"), start, end));
}
if(StringUtils.isNotBlank(param.getState())) {
predicateList.add(builder.equal(root.get("state"), param.getState()));
} }
if(StringUtils.isNotBlank(param.getKeyword())) { if(StringUtils.isNotBlank(param.getKeyword())) {
// 歌曲、歌手、专辑、歌词文本 // 歌曲、歌手、专辑、歌词文本
@ -135,21 +148,21 @@ public class CMSSongService {
Map<String, List<String>> result = new HashMap<>(); Map<String, List<String>> result = new HashMap<>();
List<JournalSong> bySongId = journalSongDao.findBySongId(ids); List<JournalSong> bySongId = journalSongDao.findBySongId(ids);
if (!CollectionUtils.isEmpty(bySongId)) { if (!CollectionUtils.isEmpty(bySongId)) {
Set<String> idSet = bySongId.stream().map(JournalSong::getJournalId).collect(Collectors.toSet()); Set<String> idSet = bySongId.stream().map(JournalSong::getJournalNo).collect(Collectors.toSet());
List<Journal> journalList = journalDao.findByIdIn(idSet); List<Journal> journalList = journalDao.findByJournalNoIn(idSet);
Map<String, Journal> idJournalMap = journalList.stream().collect(Collectors.toMap(Journal::getId, obj -> obj)); Map<String, Journal> idJournalMap = journalList.stream().collect(Collectors.toMap(Journal::getJournalNo, obj -> obj));
for (JournalSong item : bySongId) { for (JournalSong item : bySongId) {
String songId = item.getSongId(); String songId = item.getSongId();
String journalId = item.getJournalId(); String journalNo = item.getJournalNo();
List<String> list; List<String> list;
if (result.keySet().contains(songId)) { if (result.keySet().contains(songId)) {
list = result.get(songId); list = result.get(songId);
} else { } else {
list = new ArrayList<>(); list = new ArrayList<>();
} }
if (idJournalMap.keySet().contains(journalId)) { if (idJournalMap.keySet().contains(journalNo)) {
Journal journal = idJournalMap.get(journalId); Journal journal = idJournalMap.get(journalNo);
list.add(journal.getNumber() + " " + journal.getName()); list.add(Constants.JOURNAL_NO_PREF + journalNo + " " + journal.getTitle());
} }
result.put(songId, list); result.put(songId, list);
} }
@ -185,51 +198,76 @@ public class CMSSongService {
/** /**
* *
* @param token
* @param param * @param param
* @param imageFile
* @param songFile
* @return * @return
*/ */
public Result add(SongAddModel param, MultipartFile imageFile, MultipartFile songFile) { public Result add(String token, SongAddModel param) {
String imagePath= UploadUtil.upload(imageFile, UploadUtil.IMAGE_DIR);
String songPath = UploadUtil.upload(songFile, UploadUtil.SONG_DIR);
SongInfo song = new SongInfo();
String id = String.valueOf(idWorker.nextId()); String id = String.valueOf(idWorker.nextId());
String url = null;
if (StringUtils.isNotBlank(param.getUrl())) {
url = moveSongFile(id, param);
if (StringUtils.isBlank(url)) {
return Result.failed("保存失败");
}
}
String image = null;
if (StringUtils.isNotBlank(param.getImage())) {
image = moveSongImage(id, param);
if (StringUtils.isBlank(image)) {
return Result.failed("保存失败");
}
}
SongInfo song = buildSong(id, param, token);
song.setId(id); song.setId(id);
song.setName(param.getName()); song.setUrl(url);
song.setArtist(param.getArtist()); song.setImage(image);
song.setAlbum(param.getAlbum());
song.setPicture(imagePath);
song.setUrl(songPath);
song.setUserId(param.getUserId());
song.setSize(songFile.isEmpty() ? 0L : songFile.getSize());
song.setDuration(getSongDuration(songPath));
songDao.save(song); songDao.save(song);
batchSaveSongRelatesInfo(id, param); batchSaveSongRelatesInfo(id, param);
return Result.success("新增成功"); return Result.success("新增成功");
} }
/** private SongInfo buildSong(String id, SongAddModel param, String token) {
* SongInfo song = new SongInfo();
* @param songPath if (!StringUtils.isBlank(id)) {
* @return song.setId(id);
*/ }
private long getSongDuration(String songPath) { song.setName(param.getName());
try { song.setArtist(param.getArtist());
File audioFile = new File(songPath); song.setAlbum(param.getAlbum());
InputStream inputStream = new FileInputStream(audioFile); song.setSize(param.getSize());
Parser parser = new AutoDetectParser(); song.setDuration(param.getDuration());
Metadata metadata = new Metadata(); UserLoginDto user = jwtUtil.getUserLoginDto(token);
BodyContentHandler handler = new BodyContentHandler(); song.setUserId(user.getUserId());
parser.parse(inputStream, handler, metadata, new ParseContext()); song.setUserName(user.getNickName());
String durationString = metadata.get("xmpDM:duration"); song.setUserType(user.getRoles());
long duration = Long.parseLong(durationString); return song;
inputStream.close(); }
return duration;
} catch (Exception e) { private String moveSongFile(String id, SongAddModel param) {
e.printStackTrace(); String url = param.getUrl();
return 0; String srcKey = url.substring(url.indexOf(Constants.TEMP_KEY_PREFIX));
String suffix = url.substring(url.lastIndexOf(Constants.DOT));
String destKeySuffix = id + "/00" + suffix;
String destKey = Constants.SONG_KEY_PREFIX + destKeySuffix;
int copy = s3Service.copy(Constants.BUCKET, srcKey, destKey);
if (copy > 0) {
return destKeySuffix;
} }
return null;
}
private String moveSongImage(String id, SongAddModel param) {
String image = param.getImage();
String srcKey = image.substring(image.indexOf(Constants.TEMP_KEY_PREFIX));
String suffix = image.substring(image.lastIndexOf(Constants.DOT));
String destKeySuffix = id + "/00" + suffix;
String destKey = Constants.SONG_KEY_PREFIX + destKeySuffix;
int copy = s3Service.copy(Constants.BUCKET, srcKey, destKey);
if (copy > 0) {
return destKeySuffix;
}
return null;
} }
/** /**
@ -264,39 +302,37 @@ public class CMSSongService {
response.setArtist(song.getArtist()); response.setArtist(song.getArtist());
response.setAlbum(song.getAlbum()); response.setAlbum(song.getAlbum());
response.setTags(songTagDao.findTagsBySongId(id)); response.setTags(songTagDao.findTagsBySongId(id));
response.setPicture(song.getPicture()); response.setUrl(Constants.SONG_RESOURCE_PREFIX + song.getUrl());
response.setUrl(song.getUrl()); response.setImage(Constants.SONG_RESOURCE_PREFIX + song.getImage());
return Result.success(response); return Result.success(response);
} }
/** /**
* *
* @param id * @param id
* @param token
* @param param * @param param
* @param imageFile
* @param songFile
* @return * @return
*/ */
public Result update(String id, SongAddModel param, MultipartFile imageFile, MultipartFile songFile) { public Result update(String id, String token, SongAddModel param) {
SongInfo oldSong = songDao.findById(id).get(); SongInfo song = buildSong(id, param, token);
SongInfo song = new SongInfo(); String url = null;
song.setId(id); if (param.getUrl().contains(Constants.TEMP_KEY_PREFIX)) {
song.setName(param.getName()); url = moveSongFile(id, param);
song.setArtist(param.getAlbum()); if (StringUtils.isBlank(url)) {
song.setAlbum(param.getAlbum()); return Result.failed("更新失败");
song.setUserId(param.getUserId()); }
boolean imageBool = UploadUtil.fileHasChanged(oldSong.getPicture(), imageFile); song.setUrl(url);
if (imageBool) { song.setSize(param.getSize());
String imagePath = UploadUtil.upload(imageFile, UploadUtil.IMAGE_DIR); song.setDuration(param.getDuration());
song.setPicture(imagePath);
} }
String image = null;
boolean songBool = UploadUtil.fileHasChanged(oldSong.getUrl(), songFile); if (param.getImage().contains(Constants.TEMP_KEY_PREFIX)) {
if (songBool) { image = moveSongImage(id, param);
String songPath = UploadUtil.upload(imageFile, UploadUtil.SONG_DIR); if (StringUtils.isBlank(image)) {
song.setUrl(songPath); Result.failed("更新失败");
song.setSize(songFile.isEmpty() ? 0L : songFile.getSize()); }
song.setDuration(getSongDuration(songPath)); song.setImage(image);
} }
songDao.save(song); songDao.save(song);
songTagDao.deleteBySongId(id); songTagDao.deleteBySongId(id);
@ -329,25 +365,6 @@ public class CMSSongService {
return Result.success("更新成功"); return Result.success("更新成功");
} }
/**
*
* @param files
* @return
*/
public Result batchUpload(List<MultipartFile> files) {
for (MultipartFile file : files) {
SongInfo song = new SongInfo();
String id = String.valueOf(idWorker.nextId());
song.setId(id);
String songPath = UploadUtil.upload(file, UploadUtil.SONG_DIR);
song.setUrl(songPath);
song.setSize(file.isEmpty() ? 0L : file.getSize());
song.setDuration(getSongDuration(songPath));
songDao.save(song);
}
return Result.success("上传成功");
}
/** /**
* *
* @param id * @param id
@ -363,4 +380,31 @@ public class CMSSongService {
return Result.success("该歌曲已被删除"); return Result.success("该歌曲已被删除");
} }
} }
/**
*
* @param files
* @return
*/
public Result batchUpload(List<MultipartFile> files) {
for (MultipartFile file : files) {
if (!file.isEmpty()) {
String id = String.valueOf(idWorker.nextId());
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(Constants.DOT));
String keySuffix = id + "/00" + suffix;
String key = Constants.SONG_KEY_PREFIX + keySuffix;
int upload = s3Service.upload(Constants.BUCKET, key, file);
if (upload > 1) {
SongInfo song = new SongInfo();
song.setId(id);
song.setUrl(keySuffix);
song.setSize(file.isEmpty() ? 0L : file.getSize());
song.setDuration(CommonUtil.getSongDuration(Constants.SONG_RESOURCE_PREFIX + keySuffix));
songDao.save(song);
}
}
}
return Result.success("上传成功");
}
} }

@ -1,89 +1,99 @@
package com.luoo.music.service; package com.luoo.music.service;
import api.Result;
import com.luoo.music.response.cms.UploadRespDto;
import com.luoo.music.util.CommonUtil;
import com.luoo.music.util.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.SdkHttpResponse; import software.amazon.awssdk.http.SdkHttpResponse;
import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*; import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.model.CopyObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import util.IdWorker;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
@Service @Service
public class S3Service { public class S3Service {
@Resource
private S3Client s3Client;
@Resource @Resource
private S3Presigner s3Presigner; private S3Client s3Client;
@Autowired
// private IdWorker idWorker;
// public ListObjectsResponse listObjects(){
// ListObjectsResponse indie = s3Client.listObjects( ListObjectsV2Request.builder().bucket("indie"));
// return indie;
// }
public List<S3Object> list() throws UnsupportedEncodingException {
// if(StringUtil.isEmpty(bucket)) return ResultUtil.resultFail("参数错误");
ListObjectsV2Request.Builder builder = ListObjectsV2Request.builder();
// 设置bucket
builder.bucket("indie");
ListObjectsV2Request listObjReq = builder.build();
ListObjectsV2Response listObjRes = s3Client.listObjectsV2(listObjReq);
List<S3Object> s3ObjectList = listObjRes.contents();
return s3ObjectList; /**
* @param file
* @return
*/
public Result<UploadRespDto> upload(MultipartFile file, boolean isSong) {
if (!file.isEmpty()) {
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(Constants.DOT));
String keySuffix = String.valueOf(idWorker.nextId()) + suffix;
String key = Constants.TEMP_KEY_PREFIX + keySuffix;
int upload = upload(Constants.BUCKET, key, file);
if (upload < 1) {
return Result.failed("上传失败");
} else {
UploadRespDto resp = new UploadRespDto();
resp.setFullUrl(Constants.RESOURCE_PREFIX + key);
if (isSong) {
resp.setSize(file.isEmpty() ? 0L : file.getSize());
resp.setDuration(CommonUtil.getSongDuration(Constants.RESOURCE_PREFIX + key));
}
resp.setFullUrl(Constants.RESOURCE_PREFIX + key);
return Result.success(resp);
}
} else {
return Result.failed("文件为空,上传失败");
}
} }
/** /**
* * s3
* @param bucket bucket * @param bucket
* @param key * @param key
* @param file * @param file
* @return
* @throws IOException
*/ */
// @Async("awsThreadPoolExecutor") public int upload(String bucket, String key, MultipartFile file) {
public int singleUpload(String bucket, String key, MultipartFile file) throws IOException { try {
Long startTime = System.currentTimeMillis() / 1000; PutObjectRequest putObjectRequest = PutObjectRequest.builder()
PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket(bucket)
.bucket(bucket) .key(key)
.key(key) .build();
.build(); RequestBody requestBody = RequestBody.fromInputStream(file.getInputStream(), file.getSize());
RequestBody requestBody = RequestBody.fromInputStream(file.getInputStream(), file.getSize()); PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, requestBody);
PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, requestBody); SdkHttpResponse sdkHttpResponse = putObjectResponse.sdkHttpResponse();
SdkHttpResponse sdkHttpResponse = putObjectResponse.sdkHttpResponse(); if (!sdkHttpResponse.isSuccessful()) {
if(!sdkHttpResponse.isSuccessful()){ return -1;
return -1; }
} catch (Exception e) {
return -1;
} }
long endTime = System.currentTimeMillis() / 1000;
// log.info("上传文件(" + key + ")总计耗费时间为:" + (endTime - startTime) + " 秒");
return 1; return 1;
} }
/**
* s3
public int copy() { * @param bucket
* @param srcKey
String bucket = "indie"; //存储桶名 * @param destKey
String sourceKey = "20240121/1.mp3"; //copy的源文件路径 * @return
String destinationKey = "20240121/2.mp3"; // copy的目的地路径 */
CopyObjectResponse copyObjectResponse = s3Client.copyObject(CopyObjectRequest.builder().sourceBucket(bucket).sourceKey(sourceKey).destinationBucket(bucket).destinationKey(destinationKey).build()); public int copy(String bucket, String srcKey, String destKey) {
CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
.sourceBucket(bucket).sourceKey(srcKey).destinationBucket(bucket).destinationKey(destKey).build();
CopyObjectResponse copyObjectResponse = s3Client.copyObject(copyObjectRequest);
SdkHttpResponse sdkHttpResponse = copyObjectResponse.sdkHttpResponse(); SdkHttpResponse sdkHttpResponse = copyObjectResponse.sdkHttpResponse();
if(!sdkHttpResponse.isSuccessful()){ if(!sdkHttpResponse.isSuccessful()){
return -1; return -1;
@ -91,13 +101,12 @@ public class S3Service {
return 1; return 1;
} }
public void uploadAvatar(String bucket, String key, byte[] buffer) { public void uploadAvatar(String bucket, String key, byte[] buffer) {
PutObjectRequest putObjectRequest = PutObjectRequest.builder() PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucket) .bucket(bucket)
.key(key) .key(key)
.build(); .build();
RequestBody requestBody = RequestBody.fromInputStream(new ByteArrayInputStream(buffer), buffer.length); RequestBody requestBody = RequestBody.fromInputStream(new ByteArrayInputStream(buffer), buffer.length);
s3Client.putObject(putObjectRequest, requestBody); s3Client.putObject(putObjectRequest, requestBody);
} }
} }

@ -1,5 +1,14 @@
package com.luoo.music.util; package com.luoo.music.util;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.DecimalFormat; import java.text.DecimalFormat;
/** /**
@ -8,7 +17,30 @@ import java.text.DecimalFormat;
public class CommonUtil { public class CommonUtil {
/** /**
* *
* @param songPath
* @return
*/
public static long getSongDuration(String songPath) {
try {
File audioFile = new File(songPath);
InputStream inputStream = new FileInputStream(audioFile);
Parser parser = new AutoDetectParser();
Metadata metadata = new Metadata();
BodyContentHandler handler = new BodyContentHandler();
parser.parse(inputStream, handler, metadata, new ParseContext());
String durationString = metadata.get("xmpDM:duration");
long duration = Long.parseLong(durationString);
inputStream.close();
return duration;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
*
* @param size * @param size
* @return * @return
*/ */
@ -19,7 +51,7 @@ public class CommonUtil {
} }
/** /**
* *
* @param duration * @param duration
* @return * @return
*/ */

@ -0,0 +1,27 @@
package com.luoo.music.util;
/**
* @author locust
*/
public class Constants {
public static String JOURNAL_NO_PREF = "VOL•";
private String SONG_PREF = "song";
public static final String MUSIC_RESOURCE_PREFIX="http://cdn.indie.cn/music/";
public static final String IMAGE_RESOURCE_PREFIX="http://cdn.indie.cn/image/";
public static final String SONG_RESOURCE_PREFIX="http://cdn.indie.cn/song/";
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 IMAGE_KEY_PREFIX = "image/";
public static final String SONG_KEY_PREFIX = "song/";
public static final String TEMP_KEY_PREFIX = "temp/";
public static final String DOT = ".";
public static final String SLASH = "/";
}
Loading…
Cancel
Save