diff --git a/luoo_music/pom.xml b/luoo_music/pom.xml
index 57f041f..5b38728 100644
--- a/luoo_music/pom.xml
+++ b/luoo_music/pom.xml
@@ -48,6 +48,11 @@
org.springframework.boot
spring-boot-starter-actuator
+
+ org.apache.tika
+ tika-core
+ 1.27
+
app
diff --git a/luoo_music/src/main/java/com/luoo/music/MusicApplication.java b/luoo_music/src/main/java/com/luoo/music/MusicApplication.java
index 4f74b9f..c7079a6 100644
--- a/luoo_music/src/main/java/com/luoo/music/MusicApplication.java
+++ b/luoo_music/src/main/java/com/luoo/music/MusicApplication.java
@@ -14,12 +14,14 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import util.IdWorker;
import util.JwtUtil;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
+@EnableJpaAuditing
@EnableCaching
public class MusicApplication {
static Logger logger= LoggerFactory.getLogger(MusicApplication.class);
diff --git a/luoo_music/src/main/java/com/luoo/music/controller/CMSColumnController.java b/luoo_music/src/main/java/com/luoo/music/controller/CMSColumnController.java
new file mode 100644
index 0000000..48cd6ed
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/controller/CMSColumnController.java
@@ -0,0 +1,77 @@
+package com.luoo.music.controller;
+
+import api.PageResult;
+import api.Result;
+import com.luoo.music.request.cms.ColumnAddModel;
+import com.luoo.music.request.cms.ColumnQueryModel;
+import com.luoo.music.response.cms.ColumnVO;
+import com.luoo.music.service.CMSColumnService;
+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;
+
+/**
+ * @author locust
+ */
+@RestController
+@CrossOrigin
+@Api(tags = "雀跃期刊后台CMS APIs")
+@RequestMapping("/cms/column")
+public class CMSColumnController {
+
+ @Autowired
+ private CMSColumnService columnService;
+
+ @ApiOperation(value = "查询期刊列表", notes = "查询期刊列表")
+ @RequestMapping(value="/search/{page}/{size}", method= RequestMethod.POST)
+ public Result search(@ApiParam(value = "查询条件", required = true) @RequestBody ColumnQueryModel queryModel,
+ @ApiParam(value = "页码", required = true) @PathVariable int page,
+ @ApiParam(value = "每页条数", required = true) @PathVariable int size){
+ return columnService.search(queryModel, page, size);
+ }
+
+ @ApiOperation(value = "新增期刊", notes = "新增期刊")
+ @RequestMapping(value = "/add", method = RequestMethod.POST)
+ public Result add(@ApiParam(value = "期刊信息", required = true) @RequestBody ColumnAddModel addModel,
+ @ApiParam(value = "封面文件", required = true) @RequestParam("imageFile") MultipartFile imageFile){
+ return columnService.add(addModel, imageFile);
+ }
+
+ @ApiOperation(value = "查询期刊详情", notes = "查询期刊详情")
+ @RequestMapping(value="/{id}",method= RequestMethod.GET)
+ public Result findOne(@ApiParam(value = "期刊ID", required = true) @PathVariable String id){
+ return columnService.findOne(id);
+ }
+
+ @ApiOperation(value = "更新期刊", notes = "更新期刊")
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public Result update(@ApiParam(value = "期刊ID", required = true) @PathVariable String id,
+ @ApiParam(value = "期刊信息", required = true) @RequestBody ColumnAddModel updateModel,
+ @ApiParam(value = "封面文件", required = true) @RequestParam("imageFile") MultipartFile imageFile){
+ return columnService.update(id, updateModel, imageFile);
+ }
+
+ @ApiOperation(value = "发布期刊", notes = "发布期刊")
+ @RequestMapping(value="/publish/{id}",method= RequestMethod.PUT)
+ public Result publish(@PathVariable String id,
+ @ApiParam(value = "是否定时发布,0:否,1:是", required = true) @RequestParam("state") String scheduled,
+ @ApiParam(value = "定时发布时间") @RequestParam("state") String pubTime){
+ return columnService.publish(id, scheduled, pubTime);
+ }
+
+ @ApiOperation(value = "更新期刊启停状态", notes = "更新期刊启停状态")
+ @RequestMapping(value="/update/state/{id}",method= RequestMethod.PUT)
+ public Result updateColumnState(@ApiParam(value = "期刊ID", required = true) @PathVariable String id,
+ @ApiParam(value = "期刊启停状态,0:停用,1:启用", required = true) @RequestParam("state") String state){
+ return columnService.updateColumnState(id, state);
+ }
+
+ @ApiOperation(value = "删除单条期刊", notes = "删除单条期刊")
+ @RequestMapping(value="/{id}", method= RequestMethod.DELETE)
+ public Result delete(@ApiParam(value = "期刊ID", required = true) @PathVariable String id){
+ return columnService.deleteById(id);
+ }
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/controller/CMSSongController.java b/luoo_music/src/main/java/com/luoo/music/controller/CMSSongController.java
new file mode 100644
index 0000000..5ce42f9
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/controller/CMSSongController.java
@@ -0,0 +1,83 @@
+package com.luoo.music.controller;
+
+import api.Result;
+import com.luoo.music.request.cms.SongAddModel;
+import com.luoo.music.request.cms.SongQueryModel;
+import com.luoo.music.service.CMSSongService;
+import io.swagger.annotations.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+@RestController
+@CrossOrigin
+@Api(tags = "雀跃曲库后台CMS APIs")
+@RequestMapping("/cms/song")
+public class CMSSongController {
+
+ @Autowired
+ private CMSSongService songService;
+
+ @ApiOperation(value = "查询曲目列表", notes = "查询曲目列表")
+ @RequestMapping(value="/search/{page}/{size}",method= RequestMethod.POST)
+ public Result search(@ApiParam(value = "查询条件") @RequestBody SongQueryModel queryModel,
+ @ApiParam(value = "页码", required = true) @PathVariable int page,
+ @ApiParam(value = "每页条数", required = true)@PathVariable int size){
+ return songService.search(queryModel, page, size);
+ }
+
+ @ApiOperation(value = "新增歌曲", notes = "新增歌曲")
+ @RequestMapping(value = "/add", method = RequestMethod.POST)
+ public Result add(@ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel addModel,
+ @ApiParam(value = "封面图片", required = true) @RequestParam("imageFile") MultipartFile imageFile,
+ @ApiParam(value = "歌曲文件", required = true) @RequestParam("songFile") MultipartFile songFile){
+ return songService.add(addModel, imageFile, songFile);
+ }
+
+ @ApiOperation(value = "查询歌曲详情", notes = "查询歌曲详情")
+ @RequestMapping(value="/{id}",method= RequestMethod.GET)
+ public Result findOne(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id){
+ return songService.findOne(id);
+ }
+
+ @ApiOperation(value = "更新歌曲信息", notes = "更新歌曲信息")
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public Result update(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id,
+ @ApiParam(value = "歌曲信息", required = true) @RequestBody SongAddModel updateModel,
+ @ApiParam(value = "封面图片", required = true) @RequestParam("imageFile") MultipartFile imageFile,
+ @ApiParam(value = "歌曲文件", required = true) @RequestParam("songFile") MultipartFile songFile){
+ return songService.update(id, updateModel, imageFile, songFile);
+ }
+
+ @ApiOperation(value = "更新歌曲启停状态", notes = "更新歌曲启停状态")
+ @RequestMapping(value="/update/state/{id}",method= RequestMethod.PUT)
+ public Result updateSongState(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id,
+ @ApiParam(value = "歌曲状态,0:停用,1:启用", required = true) @RequestParam("state") String state){
+ return songService.updateSongState(id, state);
+ }
+
+ @ApiOperation(value = "更新歌曲歌词", notes = "更新歌曲歌词")
+ @RequestMapping(value="/update/lyric/{id}",method= RequestMethod.PUT)
+ public Result updateSongLyric(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id,
+ @ApiParam(value = "歌曲歌词", required = true) @RequestParam("lyric") String lyric){
+ return songService.updateSongLyric(id, lyric);
+ }
+
+
+ @ApiOperation(value = "批量上传歌曲", notes = "批量上传歌曲")
+ @RequestMapping(value = "/batch", method = RequestMethod.POST)
+ public Result batchUpload(@ApiParam(value = "多歌曲文件", required = true) @RequestParam("files") List files) {
+ return songService.batchUpload(files);
+ }
+
+ @ApiOperation(value = "删除单条歌曲", notes = "删除单条歌曲")
+ @RequestMapping(value="/{id}", method= RequestMethod.DELETE)
+ public Result delete(@ApiParam(value = "歌曲ID", required = true) @PathVariable String id){
+ return songService.deleteById(id);
+ }
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/CMSSongDao.java b/luoo_music/src/main/java/com/luoo/music/dao/CMSSongDao.java
new file mode 100644
index 0000000..7a810c3
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/dao/CMSSongDao.java
@@ -0,0 +1,35 @@
+package com.luoo.music.dao;
+
+import com.luoo.music.pojo.CMSSong;
+import com.luoo.music.pojo.Song;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author locust
+ */
+public interface CMSSongDao extends JpaRepository, JpaSpecificationExecutor {
+
+ // public List findSongsByVolid(String volid);
+
+ @Modifying
+ @Query("UPDATE CMSSong s SET s.state = :state WHERE s.id = :id")
+ int updateSongState(@Param("id") String id, @Param("state") String state);
+
+ @Modifying
+ @Query("UPDATE CMSSong s SET s.lyric = :lyric WHERE s.id = :id")
+ int updateSongLyric(@Param("id") String id, @Param("lyric") String lyric);
+
+ List findByIdIn(Set ids);
+
+
+ /*@Modifying
+ @Query("UPDATE Song s SET s.name = :#{#song.name}, s.artist = :#{#song.artist}, s.album = :#{#song.album}, s.picture = :#{#song.picture}, s.url = :#{#song.url}, s.size = :#{#song.size}, s.duration = :#{#song.duration}, s.updatetime = :#{#song.updatetime} WHERE s.id = :#{#song.id}")
+ int updateSong(@Param("song") Song song);*/
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/ColumnDao.java b/luoo_music/src/main/java/com/luoo/music/dao/ColumnDao.java
index 6779bd2..f00ea71 100644
--- a/luoo_music/src/main/java/com/luoo/music/dao/ColumnDao.java
+++ b/luoo_music/src/main/java/com/luoo/music/dao/ColumnDao.java
@@ -1,14 +1,54 @@
package com.luoo.music.dao;
+import com.luoo.music.pojo.Column;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Set;
-import com.luoo.music.pojo.Column;
/**
- * 数据访问接口
- * @author Administrator
- *
+ * @author locust
*/
public interface ColumnDao extends JpaRepository,JpaSpecificationExecutor{
-
+
+ List findByIdIn(Set ids);
+
+ @Modifying
+ @Query("UPDATE Column c SET c.state = '1', c.pubTime = :pubTime WHERE c.id = :id")
+ int updatePubById(@Param("id") String id,
+ @Param("pubTime") LocalDateTime pubTime);
+
+ @Modifying
+ @Query("UPDATE Column c SET c.scheduled = :scheduled, c.pubTime = :pubTime WHERE c.id = :id")
+ int updateScheduledPubById(@Param("id") String id,
+ @Param("scheduled") String scheduled,
+ @Param("pubTime") LocalDateTime pubTime);
+
+ @Modifying
+ @Query("UPDATE Column c SET c.state = :state WHERE c.id = :id")
+ int updateColumnState(@Param("id") String id, @Param("state") String state);
+
+ /*@Modifying
+ @Query("UPDATE Column c SET c.number = :#{#column.number}, c.name = :#{#column.name}, c.userid = :#{#column.userid}, c.summary = :#{#column.summary}, c.coverphoto = :#{#column.coverphoto} WHERE c.id = :#{#column.id}")
+ int updateColumn(@Param("column") Column column);
+
+ @Modifying
+ @Query("UPDATE Column c SET " +
+ "c.number = CASE WHEN :#{#column.number != null} THEN :#{#column.number} ELSE c.number END, " +
+ "c.name = CASE WHEN :#{#column.name != null} THEN :#{#column.name} ELSE c.name END, " +
+ "c.summary = CASE WHEN :#{#column.summary != null} THEN :#{#column.summary} ELSE c.summary END, " +
+ "c.state = CASE WHEN :#{#column.state != null} THEN :#{#column.state} ELSE c.state END, " +
+ "c.scheduled = CASE WHEN :#{#column.scheduled != null} THEN :#{#column.scheduled} ELSE c.scheduled END, " +
+ "c.userId = CASE WHEN :#{#column.userId != null} THEN :#{#column.userId} ELSE c.userId END, " +
+ "c.coverPhoto = CASE WHEN :#{#column.coverPhoto != null} THEN :#{#column.coverPhoto} ELSE c.coverPhoto END, " +
+ "c.pubTime = CASE WHEN :#{#column.pubTime != null} THEN :#{#column.pubTime} ELSE c.pubTime END " +
+ "WHERE c.id = :#{#column.id}")
+ int dynamicUpdateColumn(@Param("column") Column column);*/
+
}
+
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/ColumnSongDao.java b/luoo_music/src/main/java/com/luoo/music/dao/ColumnSongDao.java
new file mode 100644
index 0000000..9a3eae5
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/dao/ColumnSongDao.java
@@ -0,0 +1,31 @@
+package com.luoo.music.dao;
+
+import com.luoo.music.pojo.ColumnSong;
+import com.luoo.music.pojo.ColumnSongCount;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+public interface ColumnSongDao extends JpaRepository, JpaSpecificationExecutor {
+
+ @Query("SELECT cs.columnId, COUNT(cs) AS songCount FROM ColumnSong cs WHERE cs.columnId IN :columnIds GROUP BY cs.columnId")
+ List findSongCountByColumnIds(@Param("columnIds") List columnIds);
+
+ @Query("SELECT cs.columnId FROM ColumnSong cs WHERE cs.songId = :id")
+ List findColumnsBySongId(@Param("id") String id);
+
+ @Query("SELECT cs FROM ColumnSong cs WHERE cs.songId IN :ids ORDER BY cs.id ")
+ List findBySongId(@Param("ids") List ids);
+
+ @Query("SELECT cs FROM ColumnSong cs WHERE cs.columnId = :id ORDER BY cs.id ")
+ List findByColumnId(@Param("id") String id);
+
+ @Query("DELETE FROM ColumnSong cs WHERE cs.columnId = :id")
+ int deleteByColumnId(@Param("id") String id);
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/ColumnTagDao.java b/luoo_music/src/main/java/com/luoo/music/dao/ColumnTagDao.java
new file mode 100644
index 0000000..ed7f1c4
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/dao/ColumnTagDao.java
@@ -0,0 +1,27 @@
+package com.luoo.music.dao;
+
+import com.luoo.music.pojo.ColumnTag;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+public interface ColumnTagDao extends JpaRepository, JpaSpecificationExecutor {
+
+ @Query("SELECT ct FROM ColumnTag ct WHERE ct.columnId IN :columnIds ORDER BY ct.id")
+ List findByColumnIds(@Param("columnIds") List columnIds);
+
+ @Query("SELECT ct.columnId FROM ColumnTag ct WHERE ct.tagId IN :tags")
+ List findColumnIdsByTags(@Param("tags") List tags);
+
+ @Query("SELECT ct.tagId FROM ColumnTag ct WHERE ct.columnId = :id")
+ List findTagsByColumnId(@Param("id") String id);
+
+ @Query("DELETE FROM ColumnTag ct WHERE ct.columnId = :id")
+ int deleteByColumnId(@Param("id") String id);
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/SongTagDao.java b/luoo_music/src/main/java/com/luoo/music/dao/SongTagDao.java
new file mode 100644
index 0000000..7f4b572
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/dao/SongTagDao.java
@@ -0,0 +1,24 @@
+package com.luoo.music.dao;
+
+import com.luoo.music.pojo.SongTag;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+public interface SongTagDao extends JpaRepository, JpaSpecificationExecutor {
+
+ @Query("SELECT st.tagId FROM SongTag st WHERE st.songId = :id")
+ List findTagsBySongId(@Param("id") String id);
+
+ @Query("SELECT st FROM SongTag st WHERE st.songId IN :ids ORDER BY st.id ")
+ List findBySongId(@Param("ids") List ids);
+
+ @Query("DELETE FROM SongTag st WHERE st.songId = :id")
+ int deleteBySongId(@Param("id") String id);
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/dao/TagDao.java b/luoo_music/src/main/java/com/luoo/music/dao/TagDao.java
new file mode 100644
index 0000000..ac93711
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/dao/TagDao.java
@@ -0,0 +1,28 @@
+package com.luoo.music.dao;
+
+import com.luoo.music.pojo.Tag;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author locust
+ */
+public interface TagDao extends JpaRepository, JpaSpecificationExecutor{
+
+ List findByIdIn(Set ids);
+
+ /*@Query(value = "SELECT " +
+ " t1.id AS id, " +
+ "CASE " +
+ " WHEN t1.LEVEL = 1 THEN " +
+ " t1.name_ch ELSE CONCAT(( SELECT t2.name_ch FROM tb_tag_info t2 WHERE t2.id = t1.parent_id ), '-', t1.name_ch ) " +
+ " END AS name_cn " +
+ "FROM " +
+ " tb_tag_info t1 " +
+ "WHERE " +
+ " t1.id IN :ids", nativeQuery = true)
+ List findTagCustomByIds(@Param("ids") List ids);*/
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/CMSSong.java b/luoo_music/src/main/java/com/luoo/music/pojo/CMSSong.java
new file mode 100644
index 0000000..9c9f93a
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/CMSSong.java
@@ -0,0 +1,83 @@
+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 locust
+ */
+@Data
+@Entity
+@DynamicInsert
+@DynamicUpdate
+@Table(name = "tb_song_cms")
+@EntityListeners(AuditingEntityListener.class)
+public class CMSSong implements Serializable {
+
+ @Id
+ private String id;
+
+ /**
+ * 歌曲名称
+ */
+ private String name;
+ /**
+ * 歌手或乐队
+ */
+ private String artist;
+ /**
+ * 专辑
+ */
+ private String album;
+ /**
+ * 封面图片路径
+ */
+ private String picture;
+ /**
+ * 歌曲状态 0:停用,1:启用
+ */
+ private String state;
+ /**
+ * 文件大小
+ */
+ private Long size;
+ /**
+ * 歌曲时长
+ */
+ private Long duration;
+ /**
+ * 歌曲文件路径
+ */
+ private String url;
+ /**
+ * 歌词
+ */
+ private String lyric;
+ /**
+ * 上传人员ID
+ */
+ private String userId;
+ /**
+ * 创建日期
+ */
+ @CreatedDate
+ private LocalDateTime createTime;
+ /**
+ * 更新日期
+ */
+ @LastModifiedDate
+ private LocalDateTime updateTime;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/Column.java b/luoo_music/src/main/java/com/luoo/music/pojo/Column.java
index 980e429..da131b0 100644
--- a/luoo_music/src/main/java/com/luoo/music/pojo/Column.java
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/Column.java
@@ -1,80 +1,78 @@
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 Administrator
- *
+ * 期刊表
+ * @author locust
*/
+@Data
@Entity
@Table(name="tb_column")
+@DynamicInsert
+@DynamicUpdate
+@EntityListeners(AuditingEntityListener.class)
public class Column implements Serializable{
@Id
- private String id;//ID
-
-
-
- private String name;//专栏名称
- private String summary;//专栏简介
- private String userid;//用户ID
- private java.util.Date createtime;//申请日期
- private java.util.Date checktime;//审核日期
- private String state;//状态
-
-
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
-
- public String getSummary() {
- return summary;
- }
- public void setSummary(String summary) {
- this.summary = summary;
- }
-
- public String getUserid() {
- return userid;
- }
- public void setUserid(String userid) {
- this.userid = userid;
- }
-
- public java.util.Date getCreatetime() {
- return createtime;
- }
- public void setCreatetime(java.util.Date createtime) {
- this.createtime = createtime;
- }
-
- public java.util.Date getChecktime() {
- return checktime;
- }
- public void setChecktime(java.util.Date checktime) {
- this.checktime = checktime;
- }
-
- public String getState() {
- return state;
- }
- public void setState(String state) {
- this.state = state;
- }
-
+ private String id;
-
+ /**
+ * 期刊编号
+ */
+ private String number;
+ /**
+ * 期刊标题
+ */
+ private String name;
+ /**
+ * 期刊简介
+ */
+ private String summary;
+ /**
+ * 用户ID
+ */
+ private String userId;
+ /**
+ * 启停状态 停用:0,启用:1
+ */
+ private String state;
+ /**
+ * 发布状态 未发布:0,已发布:1
+ */
+ private String status;
+ /**
+ * 是否定时 否:0 是:1
+ */
+ private String scheduled;
+ /**
+ * 封面路径
+ */
+ private String coverPhoto;
+ /**
+ * 发布日期
+ */
+ private LocalDateTime pubTime;
+ /**
+ * 创建日期
+ */
+ @CreatedDate
+ private LocalDateTime createTime;
+ /**
+ * 更新日期
+ */
+ @LastModifiedDate
+ private LocalDateTime updateTime;
}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSong.java b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSong.java
new file mode 100644
index 0000000..c69fd8b
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSong.java
@@ -0,0 +1,23 @@
+package com.luoo.music.pojo;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * 期刊曲目关系表
+ * @author locust
+ */
+@Data
+@Entity
+@Table(name="tb_column_song")
+public class ColumnSong {
+
+ @Id
+ private String id;
+
+ private String columnId;
+ private String songId;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSongCount.java b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSongCount.java
new file mode 100644
index 0000000..b0ee0e9
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnSongCount.java
@@ -0,0 +1,12 @@
+package com.luoo.music.pojo;
+
+/**
+ * 自定义对象
+ * @author locust
+ */
+public interface ColumnSongCount {
+
+ String getColumnId();
+
+ Long getSongCount();
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/ColumnTag.java b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnTag.java
new file mode 100644
index 0000000..d52496b
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/ColumnTag.java
@@ -0,0 +1,23 @@
+package com.luoo.music.pojo;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * 期刊标签关系表
+ * @author locust
+ */
+@Data
+@Entity
+@Table(name="tb_column_tag")
+public class ColumnTag {
+
+ @Id
+ private String id;
+
+ private String columnId;
+ private String tagId;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/SongTag.java b/luoo_music/src/main/java/com/luoo/music/pojo/SongTag.java
new file mode 100644
index 0000000..eb242dd
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/SongTag.java
@@ -0,0 +1,23 @@
+package com.luoo.music.pojo;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * 曲目标签关系表
+ * @author locust
+ */
+@Data
+@Entity
+@Table(name="tb_song_tag")
+public class SongTag {
+
+ @Id
+ private String id;
+
+ private String songId;
+ private String tagId;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/Tag.java b/luoo_music/src/main/java/com/luoo/music/pojo/Tag.java
new file mode 100644
index 0000000..e10cd50
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/Tag.java
@@ -0,0 +1,94 @@
+package com.luoo.music.pojo;
+
+
+import lombok.Data;
+import org.hibernate.proxy.HibernateProxy;
+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;
+import java.util.Objects;
+
+/**
+ * 标签信息表
+ * @author locust
+ */
+@Data
+@Entity
+@Table(name = "tb_tag_info")
+@EntityListeners(AuditingEntityListener.class)
+public class Tag implements Serializable {
+ private static final long serialVersionUID = -5593148272164146667L;
+
+ @Id
+ private String id;
+
+ /**
+ * 层级(1=一级,2=二级)
+ */
+ private Integer level;
+
+ /**
+ * 父级ID(如果level=2, 必填)
+ */
+ private String parentId;
+
+ /**
+ * 标签中文名称
+ */
+ private String nameCh;
+
+ /**
+ * 标签英文名称
+ */
+ private String nameEn;
+
+ /**
+ * 状态: 0.禁用, 1.启用
+ */
+ private Integer state;
+
+ /**
+ * 创建人用户ID
+ */
+ private String creatorId;
+
+ /**
+ * 创建时间
+ */
+ @CreatedDate
+ private LocalDateTime createTime;
+
+ /**
+ * 更新人用户ID
+ */
+ private String updaterId;
+
+ /**
+ * 更新时间
+ */
+ @LastModifiedDate
+ private LocalDateTime updateTime;
+
+ @Override
+ public final boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ Class> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() : o.getClass();
+ Class> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
+ if (thisEffectiveClass != oEffectiveClass) return false;
+ Tag tag = (Tag) o;
+ return getId() != null && Objects.equals(getId(), tag.getId());
+ }
+
+ @Override
+ public final int hashCode() {
+ return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
+ }
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/pojo/TagCustom.java b/luoo_music/src/main/java/com/luoo/music/pojo/TagCustom.java
new file mode 100644
index 0000000..fc90b38
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/pojo/TagCustom.java
@@ -0,0 +1,12 @@
+package com.luoo.music.pojo;
+
+/**
+ * 自定义TAG对象
+ * @author locust
+ */
+public interface TagCustom {
+
+ String getId();
+
+ String getNameCh();
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnAddModel.java b/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnAddModel.java
new file mode 100644
index 0000000..67e633d
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnAddModel.java
@@ -0,0 +1,33 @@
+package com.luoo.music.request.cms;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+@Data
+@ApiModel(value = "增加或修改期刊对象")
+public class ColumnAddModel {
+
+ @ApiModelProperty(value = "期刊编号")
+ private String number;
+
+ @ApiModelProperty(value = "期刊标题")
+ private String name;
+
+ @ApiModelProperty(value = "发布人ID")
+ private String userId;
+
+ @ApiModelProperty(value = "关联标签,标签ID")
+ private List tags;
+
+ @ApiModelProperty(value = "关联歌曲,音乐ID")
+ private List songs;
+
+ @ApiModelProperty(value = "期刊内容")
+ private String summary;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnQueryModel.java b/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnQueryModel.java
new file mode 100644
index 0000000..6d19f93
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/request/cms/ColumnQueryModel.java
@@ -0,0 +1,35 @@
+package com.luoo.music.request.cms;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+@Data
+@ApiModel(value = "期刊请求对象")
+public class ColumnQueryModel {
+
+ @ApiModelProperty(value = "列表Tab,新建:0,已发布:1, 回收站:2")
+ private String tab = "0";
+
+ @ApiModelProperty(value = "关键词,期刊号或期刊标题")
+ private String keyword;
+
+ @ApiModelProperty(value = "发布人ID")
+ private String userId;
+
+ @ApiModelProperty(value = "开始时间")
+ private String start;
+
+ @ApiModelProperty(value = "结束时间")
+ private String end;
+
+ @ApiModelProperty(value = "标签ID")
+ private List tags;
+
+ private List columns;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/request/cms/SongAddModel.java b/luoo_music/src/main/java/com/luoo/music/request/cms/SongAddModel.java
new file mode 100644
index 0000000..8059261
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/request/cms/SongAddModel.java
@@ -0,0 +1,33 @@
+package com.luoo.music.request.cms;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+@Data
+@ApiModel(value = "增加或修改歌曲对象")
+public class SongAddModel {
+
+ @ApiModelProperty(value = "歌曲名称")
+ private String name;
+
+ @ApiModelProperty(value = "歌手")
+ private String artist;
+
+ @ApiModelProperty(value = "专辑")
+ private String album;
+
+ @ApiModelProperty(value = "歌词")
+ private String lyric;
+
+ @ApiModelProperty(value = "添加者ID")
+ private String userId;
+
+ @ApiModelProperty(value = "风格标签ID集合")
+ private List tags;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/request/cms/SongQueryModel.java b/luoo_music/src/main/java/com/luoo/music/request/cms/SongQueryModel.java
new file mode 100644
index 0000000..b4bd14a
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/request/cms/SongQueryModel.java
@@ -0,0 +1,25 @@
+package com.luoo.music.request.cms;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author locust
+ */
+@Data
+@ApiModel(value = "曲目请求对象")
+public class SongQueryModel {
+
+ @ApiModelProperty(value = "关键词")
+ private String keyword;
+
+ @ApiModelProperty(value = "发布者ID")
+ private String userId;
+
+ @ApiModelProperty(value = "开始时间")
+ private String start;
+
+ @ApiModelProperty(value = "结束时间")
+ private String end;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/response/cms/ColumnVO.java b/luoo_music/src/main/java/com/luoo/music/response/cms/ColumnVO.java
new file mode 100644
index 0000000..6b79917
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/response/cms/ColumnVO.java
@@ -0,0 +1,61 @@
+package com.luoo.music.response.cms;
+
+import com.luoo.music.response.cms.SongVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author locust
+ */
+@Data
+@ApiModel(description = "期刊信息")
+public class ColumnVO {
+
+ @ApiModelProperty(value = "主键ID", example = "123")
+ private String id;
+
+ @ApiModelProperty(value = "期刊编号", example = "123")
+ private String number;
+
+ @ApiModelProperty(value = "期刊标题", example = "123")
+ private String name;
+
+ @ApiModelProperty(value = "期刊封面", example = "123")
+ private String coverPhoto;
+
+ @ApiModelProperty(value = "期刊标签", example = "123")
+ private List tag;
+
+ @ApiModelProperty(value = "歌曲数", example = "123")
+ private long songCount;
+
+ @ApiModelProperty(value = "评论数", example = "123")
+ private long commentCount;
+
+ @ApiModelProperty(value = "播放数", example = "123")
+ private long playCount;
+
+ @ApiModelProperty(value = "发布作者", example = "123")
+ private String userId;//
+
+ @ApiModelProperty(value = "创建时间", example = "123")
+ private String createTime;
+
+ @ApiModelProperty(value = "发布时间", example = "123")
+ private String pubTime;
+
+ @ApiModelProperty(value = "期刊启停状态,0:停用,1:启用", example = "123")
+ private String state;
+
+ @ApiModelProperty(value = "期刊发布状态,0:待发布,1:已发布", example = "123")
+ private String status;
+
+ @ApiModelProperty(value = "期刊歌曲信息", example = "123")
+ private List songs;
+
+ @ApiModelProperty(value = "期刊简介信息", example = "123")
+ private String summary;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/response/cms/SongVO.java b/luoo_music/src/main/java/com/luoo/music/response/cms/SongVO.java
new file mode 100644
index 0000000..6b22a5a
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/response/cms/SongVO.java
@@ -0,0 +1,57 @@
+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 SongVO {
+
+ @ApiModelProperty(value = "主键ID", example = "123")
+ private String id;
+
+ @ApiModelProperty(value = "歌曲名称", example = "123")
+ private String name;
+
+ @ApiModelProperty(value = "歌手或乐队", example = "123")
+ private String artist;
+
+ @ApiModelProperty(value = "专辑", example = "123")
+ private String album;
+
+ @ApiModelProperty(value = "歌曲风格", example = "123")
+ private List tags;
+
+ @ApiModelProperty(value = "封面路径", example = "123")
+ private String picture;
+
+ @ApiModelProperty(value = "文件大小", example = "123")
+ private String size;
+
+ @ApiModelProperty(value = "歌曲时长", example = "123")
+ private String duration;
+
+ @ApiModelProperty(value = "关联期刊", example = "123")
+ private List column;
+
+ @ApiModelProperty(value = "修改时间", example = "123")
+ private String updateTime;
+
+ @ApiModelProperty(value = "歌曲启停状态,0:停用,1:启用", example = "123")
+ private String state;
+
+ @ApiModelProperty(value = "上传人员", example = "123")
+ private String userId;
+
+ @ApiModelProperty(value = "文件路径", example = "123")
+ private String url;
+
+ @ApiModelProperty(value = "歌词", example = "123")
+ private String lyric;
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/service/CMSColumnService.java b/luoo_music/src/main/java/com/luoo/music/service/CMSColumnService.java
new file mode 100644
index 0000000..b65c52b
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/service/CMSColumnService.java
@@ -0,0 +1,373 @@
+package com.luoo.music.service;
+
+import api.PageResult;
+import api.Result;
+import com.luoo.music.dao.*;
+import com.luoo.music.pojo.*;
+import com.luoo.music.request.cms.ColumnAddModel;
+import com.luoo.music.request.cms.ColumnQueryModel;
+import com.luoo.music.response.cms.ColumnVO;
+import com.luoo.music.response.cms.SongVO;
+import com.luoo.music.util.CommonUtil;
+import com.luoo.music.util.UploadUtil;
+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.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+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.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author locust
+ */
+@Service
+public class CMSColumnService {
+
+ @Autowired
+ private ColumnTagDao columnTagDao;
+ @Autowired
+ private ColumnDao columnDao;
+ @Autowired
+ private IdWorker idWorker;
+ @Autowired
+ private ColumnSongDao columnSongDao;
+ @Autowired
+ private TagDao tagDao;
+ @Autowired
+ private CMSSongDao songDao;
+
+ private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+
+ /**
+ * 分页 + 条件检索
+ * @param param
+ * @param page
+ * @param size
+ * @return
+ */
+ public Result search(ColumnQueryModel param, int page, int size) {
+ List result = new ArrayList<>();
+ Sort sort = new Sort(Sort.Direction.DESC, "createTime");
+ PageRequest pageRequest = PageRequest.of(page - 1, size, sort);
+ Page columnPage;
+ if (!Objects.isNull(param)) {
+ List columnIdsByTags = null;
+ if (!CollectionUtils.isEmpty(param.getTags())) {
+ columnIdsByTags = columnTagDao.findColumnIdsByTags(param.getTags());
+ }
+ param.setColumns(columnIdsByTags);
+ Specification columnSpecification = buildSearchSpecification(param);
+ columnPage = columnDao.findAll(columnSpecification, pageRequest);
+ } else {
+ columnPage = columnDao.findAll(pageRequest);
+ }
+ long totalElements = columnPage.getTotalElements();
+ List content = columnPage.getContent();
+ if (!CollectionUtils.isEmpty(content)) {
+ List ids = content.stream().map(Column::getId).collect(Collectors.toList());
+ Map songCountMap = songCountInfo(ids);
+ Map> columnTagMap = tagInfo(ids);
+ for (Column item : content) {
+ ColumnVO response = new ColumnVO();
+ response.setId(item.getId());
+ response.setNumber(item.getNumber());
+ response.setName(item.getName());
+ response.setCoverPhoto(item.getCoverPhoto());
+ response.setCreateTime(item.getCreateTime().format(formatter));
+ response.setState(item.getState());
+ response.setStatus(item.getStatus());
+ if (!Objects.isNull(item.getPubTime())) {
+ response.setPubTime(item.getPubTime().format(formatter));
+ }
+ // TODO 编号文字转换
+ response.setUserId(item.getUserId());
+ response.setSongCount(songCountMap.get(item.getId()));
+ response.setTag(columnTagMap.get(item.getId()));
+ if (!"1".equals(param.getTab())) {
+ response.setPlayCount(0);
+ response.setCommentCount(0);
+ } else {
+ // TODO 播放 评论 数
+ response.setPlayCount(0);
+ response.setCommentCount(0);
+ }
+ result.add(response);
+ }
+ }
+ return Result.success(new PageResult<>(totalElements, result));
+ }
+
+ /**
+ * 检索条件
+ * @param param
+ * @return
+ */
+ private Specification buildSearchSpecification(ColumnQueryModel param) {
+ return (Root root, CriteriaQuery> query, CriteriaBuilder builder) -> {
+ List predicateList = new ArrayList();
+ if("1".equals(param.getTab())) {
+ Predicate state = builder.equal(root.get("state"), "1");
+ Predicate status = builder.equal(root.get("status"), "1");
+ predicateList.add(builder.and(state, status));
+ } else if ("2".equals(param.getTab())) {
+ predicateList.add(builder.equal(root.get("state"), "0"));
+ } else {
+ Predicate state = builder.equal(root.get("state"), "1");
+ Predicate status = builder.equal(root.get("status"), "0");
+ predicateList.add(builder.and(state, status));
+ }
+ if(StringUtils.isNotBlank(param.getUserId())) {
+ predicateList.add(builder.equal(root.get("userId"), param.getUserId()));
+ }
+ if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) {
+ predicateList.add(builder.between(root.get("createTime"), param.getStart(), param.getEnd()));
+ }
+ if (!CollectionUtils.isEmpty(param.getColumns())) {
+ predicateList.add(root.get("id").in(param.getColumns()));
+ }
+ if(StringUtils.isNotBlank(param.getKeyword())) {
+ String likeExpression = "%" + param.getKeyword() + "%";
+ Predicate name = builder.like(root.get("number"), likeExpression);
+ Predicate summary = builder.like(root.get("name"), likeExpression);
+ predicateList.add(builder.or(name, summary));
+ }
+ return builder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+ };
+ }
+
+ /**
+ * 期刊的音乐数量
+ * @param ids
+ * @return
+ */
+ private Map songCountInfo(List ids) {
+ Map songCountMap = new HashMap<>();
+ if (!CollectionUtils.isEmpty(ids)) {
+ List columnSongCountList = columnSongDao.findSongCountByColumnIds(ids);
+ songCountMap = columnSongCountList.stream().collect(Collectors.toMap(ColumnSongCount::getColumnId, ColumnSongCount::getSongCount));
+ }
+ return songCountMap;
+ }
+
+ /**
+ * 期刊的标签信息
+ * @param ids
+ * @return
+ */
+ private Map> tagInfo(List ids) {
+ Map> columnTagMap = new HashMap<>();
+ List columnTagList = columnTagDao.findByColumnIds(ids);
+ Set tagIdSet = columnTagList.stream().map(ColumnTag::getTagId).collect(Collectors.toSet());
+ List tagList = tagDao.findByIdIn(tagIdSet);
+ Map idTagMap = tagList.stream().collect(Collectors.toMap(Tag::getId, obj -> obj));
+ List list;
+ for (ColumnTag item : columnTagList) {
+ String columnId = item.getColumnId();
+ if (columnTagMap.containsKey(columnId)) {
+ list = columnTagMap.get(columnId);
+ } else {
+ list = new ArrayList<>();
+ }
+ Tag tag = idTagMap.get(item.getTagId());
+ if (StringUtils.isNotBlank(tag.getParentId())) {
+ list.add(tag.getNameCh());
+ }
+ columnTagMap.put(columnId, list);
+ }
+ return columnTagMap;
+ }
+
+ /**
+ * 新增期刊
+ * @param param
+ * @param image
+ * @return
+ */
+ public Result add(ColumnAddModel param, MultipartFile image) {
+ String imagePath = UploadUtil.upload(image, UploadUtil.IMAGE_DIR);
+ Column column = buildColumn(null, param);
+ String id = String.valueOf(idWorker.nextId());
+ column.setId(id);
+ column.setCoverPhoto(imagePath);
+ columnDao.save(column);
+ batchSaveColumnRelatesInfo(id, param);
+ return Result.success();
+ }
+
+ private Column buildColumn(String id, ColumnAddModel param) {
+ Column column = new Column();
+ if (!StringUtils.isBlank(id)) {
+ column.setId(id);
+ }
+ column.setNumber(param.getNumber());
+ column.setName(param.getName());
+ column.setUserId(param.getUserId());
+ column.setSummary(param.getSummary());
+ return column;
+ }
+
+ /**
+ * 保存期刊的标签、音乐信息
+ * @param id
+ * @param param
+ */
+ private void batchSaveColumnRelatesInfo(String id, ColumnAddModel param) {
+ if (!CollectionUtils.isEmpty(param.getTags())) {
+ List columnTagList = new ArrayList<>();
+ for (String item : param.getTags()) {
+ ColumnTag columnTag = new ColumnTag();
+ columnTag.setId(String.valueOf(idWorker.nextId()));
+ columnTag.setColumnId(id);
+ columnTag.setTagId(item);
+ columnTagList.add(columnTag);
+ }
+ columnTagDao.saveAll(columnTagList);
+ }
+ if (!CollectionUtils.isEmpty(param.getSongs())) {
+ List columnSongList = new ArrayList<>();
+ for (String item : param.getSongs()) {
+ ColumnSong columnSong = new ColumnSong();
+ columnSong.setId(String.valueOf(idWorker.nextId()));
+ columnSong.setColumnId(id);
+ columnSong.setSongId(item);
+ }
+ columnSongDao.saveAll(columnSongList);
+ }
+ }
+
+ /**
+ * 查询期刊详情
+ * @param id
+ * @return
+ */
+ public Result findOne(String id) {
+ Column column = columnDao.findById(id).get();
+ ColumnVO response = new ColumnVO();
+ response.setId(column.getId());
+ response.setNumber(column.getNumber());
+ response.setName(column.getName());
+ response.setTag(columnTagDao.findTagsByColumnId(id));
+ response.setUserId(column.getUserId());
+ response.setCoverPhoto(column.getCoverPhoto());
+ response.setSongs(songInfo(column.getId()));
+ response.setSummary(column.getSummary());
+ return Result.success(response);
+ }
+
+ /**
+ * 期刊的音乐信息
+ * @param id
+ * @return
+ */
+ private List songInfo(String id) {
+ List list = new ArrayList<>();
+ List columnSongList = columnSongDao.findByColumnId(id);
+ if (!CollectionUtils.isEmpty(columnSongList)) {
+ Set songIdSet = columnSongList.stream().map(ColumnSong::getSongId).collect(Collectors.toSet());
+ List songList = songDao.findByIdIn(songIdSet);
+ Map idTagMap = songList.stream().collect(Collectors.toMap(CMSSong::getId, obj -> obj));
+ for (ColumnSong item : columnSongList) {
+ if (idTagMap.containsKey(item.getSongId())) {
+ CMSSong song = idTagMap.get(item.getSongId());
+ SongVO songVO = new SongVO();
+ songVO.setId(song.getId());
+ songVO.setPicture(song.getPicture());
+ songVO.setName(song.getName());
+ songVO.setArtist(song.getArtist());
+ songVO.setAlbum(song.getAlbum());
+ songVO.setDuration(CommonUtil.formatSongDuration(song.getDuration()));
+ songVO.setLyric(song.getLyric());
+ list.add(songVO);
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 更新期刊
+ * @param id
+ * @param param
+ * @param image
+ * @return
+ */
+ public Result update(String id, ColumnAddModel param, MultipartFile image) {
+ Column column = buildColumn(id, param);
+ Column oldColumn = columnDao.findById(id).get();
+ boolean bool = UploadUtil.fileHasChanged(oldColumn.getCoverPhoto(), image);
+ if (bool) {
+ String imagePath = UploadUtil.upload(image, UploadUtil.IMAGE_DIR);
+ column.setCoverPhoto(imagePath);
+ }
+ columnDao.save(column);
+ batchDeleteColumnRelatesInfo(id);
+ batchSaveColumnRelatesInfo(id, param);
+ return Result.success();
+ }
+
+ /**
+ * 删除期刊的标签、音乐信息
+ * @param id
+ */
+ private void batchDeleteColumnRelatesInfo(String id) {
+ columnTagDao.deleteByColumnId(id);
+ columnSongDao.deleteByColumnId(id);
+
+ }
+
+ /**
+ * 发布期刊
+ * @param id
+ * @param scheduled
+ * @param pubTimeStr
+ * @return
+ */
+ public Result publish(String id, String scheduled, String pubTimeStr) {
+ LocalDateTime pubTime = LocalDateTime.now();
+ if ("1".equals(scheduled)) {
+ if (StringUtils.isNotBlank(pubTimeStr)){
+ pubTime = LocalDateTime.parse(pubTimeStr, formatter);
+ columnDao.updateScheduledPubById(id, scheduled, pubTime);
+ }
+ }
+ columnDao.updatePubById(id, pubTime);
+ return Result.success();
+ }
+
+ /**
+ * 更新期刊启停状态
+ * @param id
+ * @param state
+ * @return
+ */
+ public Result updateColumnState(String id, String state) {
+ columnDao.updateColumnState(id, state);
+ return Result.success("更新成功");
+ }
+
+ /**
+ * 删除期刊
+ * @param id
+ * @return
+ */
+ public Result deleteById(String id) {
+ columnDao.deleteById(id);
+ batchDeleteColumnRelatesInfo(id);
+ return Result.success();
+ }
+
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/service/CMSSongService.java b/luoo_music/src/main/java/com/luoo/music/service/CMSSongService.java
new file mode 100644
index 0000000..1e27779
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/service/CMSSongService.java
@@ -0,0 +1,363 @@
+package com.luoo.music.service;
+
+import api.PageResult;
+import api.Result;
+import com.luoo.music.dao.*;
+import com.luoo.music.pojo.*;
+import com.luoo.music.request.cms.SongAddModel;
+import com.luoo.music.request.cms.SongQueryModel;
+import com.luoo.music.response.cms.SongVO;
+import com.luoo.music.util.CommonUtil;
+import com.luoo.music.util.UploadUtil;
+import org.apache.commons.lang.StringUtils;
+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 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 org.springframework.web.multipart.MultipartFile;
+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.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author locust
+ */
+@Service
+public class CMSSongService {
+
+ @Autowired
+ private CMSSongDao songDao;
+ @Autowired
+ private IdWorker idWorker;
+ @Autowired
+ private SongTagDao songTagDao;
+ @Autowired
+ private ColumnSongDao columnSongDao;
+ @Autowired
+ private ColumnDao columnDao;
+ @Autowired
+ private TagDao tagDao;
+
+ private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+
+ /**
+ * 分页 + 条件检索
+ * @param param
+ * @param page
+ * @param size
+ * @return
+ */
+ public Result search(SongQueryModel param, int page, int size) {
+ List result = new ArrayList<>();
+ // Sort sort = new Sort(Sort.Direction.DESC, "create_time");
+ // PageRequest pageRequest = PageRequest.of(page - 1, size, sort);
+ PageRequest pageRequest = PageRequest.of(page - 1, size);
+ Page songPage;
+ if (!Objects.isNull(param)) {
+ Specification columnSpecification = buildSearchSpecification(param);
+ songPage = songDao.findAll(columnSpecification, pageRequest);
+ } else {
+ songPage = songDao.findAll(pageRequest);
+ }
+ long totalElements = songPage.getTotalElements();
+ List content = songPage.getContent();
+ if (!CollectionUtils.isEmpty(content)) {
+ List ids = content.stream().map(CMSSong::getId).collect(Collectors.toList());
+ Map> songColumnMap = buildSongColumnInfo(ids);
+ Map> songTagMap = buildSongTagInfo(ids);
+ for (CMSSong item : content) {
+ SongVO response = new SongVO();
+ String id = item.getId();
+ response.setId(id);
+ response.setName(item.getName());
+ response.setArtist(item.getArtist());
+ response.setAlbum(item.getAlbum());
+ response.setTags(songTagMap.get(id));
+ response.setPicture(item.getPicture());
+ response.setSize(CommonUtil.formatSongSize(item.getSize()));
+ response.setDuration(CommonUtil.formatSongDuration(item.getDuration()));
+ response.setColumn(songColumnMap.get(id));
+ response.setUpdateTime(df.format(item.getUpdateTime()));
+ response.setState(item.getState());
+ response.setUserId(item.getUserId());
+ response.setUrl(item.getUrl());
+ result.add(response);
+ }
+ }
+ return Result.success(new PageResult<>(totalElements, result));
+ }
+
+ /**
+ * 检索条件
+ * @param param
+ * @return
+ */
+ private Specification buildSearchSpecification(SongQueryModel param) {
+ return (Root root, CriteriaQuery> query, CriteriaBuilder builder) -> {
+ List predicateList = new ArrayList();
+ if(StringUtils.isNotBlank(param.getUserId())) {
+ predicateList.add(builder.equal(root.get("user_id"), param.getUserId()));
+ }
+ if (StringUtils.isNotBlank(param.getStart()) && StringUtils.isNotBlank(param.getEnd())) {
+ predicateList.add(builder.between(root.get("create_time"), param.getStart(), param.getEnd()));
+ }
+ if(StringUtils.isNotBlank(param.getKeyword())) {
+ // 歌曲、歌手、专辑、歌词文本
+ String likeExpression = "%" + param.getKeyword() + "%";
+ Predicate name = builder.like(root.get("name"), likeExpression);
+ Predicate artist = builder.like(root.get("artist"), likeExpression);
+ Predicate album = builder.like(root.get("album"), likeExpression);
+ Predicate lyric = builder.like(root.get("lyric"), likeExpression);
+ predicateList.add(builder.or(name, artist, album, lyric));
+ }
+ return builder.and(predicateList.toArray(new Predicate[predicateList.size()]));
+ };
+ }
+
+ private Map> buildSongColumnInfo(List ids) {
+ Map> result = new HashMap<>();
+ List bySongId = columnSongDao.findBySongId(ids);
+ if (!CollectionUtils.isEmpty(bySongId)) {
+ Set idSet = bySongId.stream().map(ColumnSong::getColumnId).collect(Collectors.toSet());
+ List columnList = columnDao.findByIdIn(idSet);
+ Map idColumnMap = columnList.stream().collect(Collectors.toMap(Column::getId, obj -> obj));
+ for (ColumnSong item : bySongId) {
+ String songId = item.getSongId();
+ String columnId = item.getColumnId();
+ List list;
+ if (result.keySet().contains(songId)) {
+ list = result.get(songId);
+ } else {
+ list = new ArrayList<>();
+ }
+ if (idColumnMap.keySet().contains(columnId)) {
+ Column column = idColumnMap.get(columnId);
+ list.add(column.getNumber() + " " + column.getName());
+ }
+ result.put(songId, list);
+ }
+ }
+ return result;
+ }
+
+ private Map> buildSongTagInfo(List ids) {
+ Map> result = new HashMap<>();
+ List bySongId = songTagDao.findBySongId(ids);
+ if (!CollectionUtils.isEmpty(bySongId)) {
+ Set idSet = bySongId.stream().map(SongTag::getTagId).collect(Collectors.toSet());
+ List tagList = tagDao.findByIdIn(idSet);
+ Map idTagMap = tagList.stream().collect(Collectors.toMap(Tag::getId, obj -> obj));
+ for (SongTag item : bySongId) {
+ String songId = item.getSongId();
+ String tagId = item.getTagId();
+ List list;
+ if (result.keySet().contains(songId)) {
+ list = result.get(songId);
+ } else {
+ list = new ArrayList<>();
+ }
+ if (idTagMap.keySet().contains(tagId)) {
+ Tag tag = idTagMap.get(tagId);
+ list.add(tag.getNameCh());
+ }
+ result.put(songId, list);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 新增曲目
+ * @param param
+ * @param imageFile
+ * @param songFile
+ * @return
+ */
+ public Result add(SongAddModel param, MultipartFile imageFile, MultipartFile songFile) {
+ String imagePath= UploadUtil.upload(imageFile, UploadUtil.IMAGE_DIR);
+ String songPath = UploadUtil.upload(songFile, UploadUtil.SONG_DIR);
+ CMSSong song = new CMSSong();
+ String id = String.valueOf(idWorker.nextId());
+ song.setId(id);
+ song.setName(param.getName());
+ song.setArtist(param.getArtist());
+ 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);
+ batchSaveSongRelatesInfo(id, param);
+ return Result.success("新增成功");
+ }
+
+ /**
+ * 获取歌曲时长
+ * @param songPath
+ * @return
+ */
+ private 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 id
+ * @param param
+ */
+ private void batchSaveSongRelatesInfo(String id, SongAddModel param) {
+ if (!CollectionUtils.isEmpty(param.getTags())) {
+ List songTagList = new ArrayList<>();
+ for (String item : param.getTags()) {
+ SongTag songTag = new SongTag();
+ songTag.setId(String.valueOf(idWorker.nextId()));
+ songTag.setSongId(id);
+ songTag.setTagId(item);
+ songTagList.add(songTag);
+ }
+ songTagDao.saveAll(songTagList);
+ }
+ }
+
+ /**
+ * 查询曲目详情
+ * @param id
+ * @return
+ */
+ public Result findOne(String id) {
+ CMSSong song = songDao.findById(id).get();
+ SongVO response = new SongVO();
+ response.setId(song.getId());
+ response.setName(song.getName());
+ response.setArtist(song.getArtist());
+ response.setAlbum(song.getAlbum());
+ response.setTags(songTagDao.findTagsBySongId(id));
+ response.setPicture(song.getPicture());
+ response.setUrl(song.getUrl());
+ return Result.success(response);
+ }
+
+ /**
+ * 更新曲目
+ * @param id
+ * @param param
+ * @param imageFile
+ * @param songFile
+ * @return
+ */
+ public Result update(String id, SongAddModel param, MultipartFile imageFile, MultipartFile songFile) {
+ CMSSong oldSong = songDao.findById(id).get();
+ CMSSong song = new CMSSong();
+ song.setId(id);
+ song.setName(param.getName());
+ song.setArtist(param.getAlbum());
+ song.setAlbum(param.getAlbum());
+ song.setUserId(param.getUserId());
+ boolean imageBool = UploadUtil.fileHasChanged(oldSong.getPicture(), imageFile);
+ if (imageBool) {
+ String imagePath = UploadUtil.upload(imageFile, UploadUtil.IMAGE_DIR);
+ song.setPicture(imagePath);
+ }
+
+ boolean songBool = UploadUtil.fileHasChanged(oldSong.getUrl(), songFile);
+ if (songBool) {
+ String songPath = UploadUtil.upload(imageFile, UploadUtil.SONG_DIR);
+ song.setUrl(songPath);
+ song.setSize(songFile.isEmpty() ? 0L : songFile.getSize());
+ song.setDuration(getSongDuration(songPath));
+ }
+ songDao.save(song);
+ songTagDao.deleteBySongId(id);
+ batchSaveSongRelatesInfo(id, param);
+ return Result.success("更新成功");
+ }
+
+ /**
+ * 更新歌曲状态
+ * @param id
+ * @param state
+ * @return
+ */
+ public Result updateSongState(String id, String state) {
+ songDao.updateSongState(id, state);
+ return Result.success("更新成功");
+ }
+
+ /**
+ * 更新歌曲歌词
+ * @param id
+ * @param lyric
+ * @return
+ */
+ public Result updateSongLyric(String id, String lyric) {
+ songDao.updateSongLyric(id, lyric);
+ return Result.success("更新成功");
+ }
+
+ /**
+ * 批量上传歌曲
+ * @param files
+ * @return
+ */
+ public Result batchUpload(List files) {
+ for (MultipartFile file : files) {
+ CMSSong song = new CMSSong();
+ 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
+ * @return
+ */
+ public Result deleteById(String id) {
+ List columnsBySongId = columnSongDao.findColumnsBySongId(id);
+ if (CollectionUtils.isEmpty(columnsBySongId)) {
+ return Result.success("该歌曲被期刊使用,删除失败");
+ } else {
+ songDao.deleteById(id);
+ songTagDao.deleteBySongId(id);
+ return Result.success("该歌曲已被删除");
+ }
+ }
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/util/CommonUtil.java b/luoo_music/src/main/java/com/luoo/music/util/CommonUtil.java
new file mode 100644
index 0000000..fccc1fe
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/util/CommonUtil.java
@@ -0,0 +1,36 @@
+package com.luoo.music.util;
+
+import java.text.DecimalFormat;
+
+/**
+ * @author locust
+ */
+public class CommonUtil {
+
+ /**
+ * 文件大小格式
+ * @param size
+ * @return
+ */
+ public static String formatSongSize(long size){
+ DecimalFormat df = new DecimalFormat("#.00");
+ String fileSizeString = df.format((double) size / 1048576) + "MB";
+ return fileSizeString;
+ }
+
+ /**
+ * 歌曲长度格式
+ * @param duration
+ * @return
+ */
+ public static String formatSongDuration(long duration) {
+ long hours = duration / 3600000;
+ long minutes = (duration % 3600000) / 60000;
+ long seconds = (duration % 60000) / 1000;
+ if (hours == 0) {
+ return String.format("%02d:%02d", minutes, seconds);
+ } else {
+ return String.format("%02d:%02d:%02d", hours, minutes, seconds);
+ }
+ }
+}
diff --git a/luoo_music/src/main/java/com/luoo/music/util/UploadUtil.java b/luoo_music/src/main/java/com/luoo/music/util/UploadUtil.java
new file mode 100644
index 0000000..facf3df
--- /dev/null
+++ b/luoo_music/src/main/java/com/luoo/music/util/UploadUtil.java
@@ -0,0 +1,61 @@
+package com.luoo.music.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * @author locust
+ */
+public class UploadUtil {
+
+ public static String IMAGE_DIR = "./image/";
+ public static String SONG_DIR = "./song/";
+
+ /**
+ * 上传文件
+ * @param file
+ * @param uploadDir
+ * @return
+ */
+ public static String upload(MultipartFile file, String uploadDir) {
+ if (!file.isEmpty() && StringUtils.isNotBlank(uploadDir)) {
+ String pathPref = System.getProperty("user.dir");
+ try {
+ Path dirPath = Paths.get(pathPref, uploadDir);
+ if (!Files.exists(dirPath)) {
+ Files.createDirectories(dirPath);
+ }
+ byte[] bytes = file.getBytes();
+ Path filePath = Paths.get(pathPref, uploadDir, file.getOriginalFilename());
+ Files.write(filePath, bytes);
+ return filePath.toString();
+ } catch (Exception e) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 根据文件名称判断是否为同一文件
+ * @param oldPath
+ * @param file
+ * @return
+ */
+ public static boolean fileHasChanged(String oldPath, MultipartFile file) {
+ if (file.isEmpty()) {
+ return false;
+ }
+ String newFileName = file.getOriginalFilename();
+ Path path = FileSystems.getDefault().getPath(oldPath);
+ String oldFileName= path.getFileName().toString();
+ if (newFileName.equals(oldFileName)) {
+ return false;
+ }
+ return true;
+ }
+}