Merge branch 'refs/heads/main' into release-2024-04-25

release-2024-08-08
pikaqiudeshujia 5 months ago
commit 9d0ab8c0d7

@ -0,0 +1,43 @@
package com.luoo.music.config;
import com.luoo.music.service.CMSArticleService;
import com.luoo.music.util.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import java.time.LocalDateTime;
import java.util.Map;
/**
* @author Revers.
* @date 2024/05/27 20:32
* 广
**/
@Configuration
//@EnableScheduling
public class TimeReleaseScheduleTask {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private CMSArticleService cmsArticleService;
//每分钟的第30秒执行一次
@Scheduled(cron = "30 * * * * ?")
private void timeRelease() {
Map<String, LocalDateTime> schedlueMap = redisTemplate.opsForHash().entries(Constants.REDIS_KEY_ARTICLE_SCHEDULED);
if(schedlueMap != null && schedlueMap.size() > 0){
for (String key : schedlueMap.keySet()){
LocalDateTime scheduleTime = schedlueMap.get(key);
if(scheduleTime.isBefore(LocalDateTime.now())){
cmsArticleService.releaseArticle(key);
}
}
}
}
}

@ -11,8 +11,10 @@ import com.luoo.music.dto.request.FuzzySearchReq;
import com.luoo.music.dto.response.JournalRespDTO; import com.luoo.music.dto.response.JournalRespDTO;
import com.luoo.music.dto.response.SearchCategoryDTO; import com.luoo.music.dto.response.SearchCategoryDTO;
import com.luoo.music.dto.response.SongRespDTO; import com.luoo.music.dto.response.SongRespDTO;
import com.luoo.music.dto.response.TagDTO;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@ -23,10 +25,13 @@ import com.luoo.music.service.JournalService;
import com.luoo.music.service.JournalSongService; import com.luoo.music.service.JournalSongService;
import com.luoo.music.service.SearchService; import com.luoo.music.service.SearchService;
import com.luoo.music.service.TagService; import com.luoo.music.service.TagService;
import com.luoo.music.util.DeviceTypeUtil;
import annotation.GlobalInterceptor; import annotation.GlobalInterceptor;
import annotation.VerifyParam; import annotation.VerifyParam;
import api.PageResult; import api.PageResult;
import api.Result; import api.Result;
import dto.UserLoginDto;
/** /**
* *
@ -55,6 +60,9 @@ public class SearchController {
@Autowired @Autowired
private TagService tagService; private TagService tagService;
@Autowired
private JwtUtil jwtUtil;
@ApiOperation(value = "1.查询搜索大类", notes = "如 ‘民谣’,‘电子’") @ApiOperation(value = "1.查询搜索大类", notes = "如 ‘民谣’,‘电子’")
@GetMapping("/category") @GetMapping("/category")
@GlobalInterceptor @GlobalInterceptor
@ -64,12 +72,17 @@ public class SearchController {
@ApiOperation(value = "2.1 搜索歌曲", notes = "根据关键词模糊搜索歌曲") @ApiOperation(value = "2.1 搜索歌曲", notes = "根据关键词模糊搜索歌曲")
@GetMapping("/fuzzy/song") @GetMapping("/fuzzy/song")
@GlobalInterceptor(checkAppUserLogin = true) @GlobalInterceptor
public Result<PageResult<SongRespDTO>> fuzzySearchSong( public Result<PageResult<SongRespDTO>> fuzzySearchSong(
@RequestHeader(value = "Authorization", required = false) String authorization, @RequestHeader(value = "Authorization", required = false) String authorization,
@RequestHeader(value = "device_type", required = false) String deviceType,
@VerifyParam(required = true) FuzzySearchReq query) throws InterruptedException, ExecutionException { @VerifyParam(required = true) FuzzySearchReq query) throws InterruptedException, ExecutionException {
PageRequest pageRequest = PageRequest.of(getPageNum(query.getPageNum()), getPageSize(query.getPageSize())); UserLoginDto user = jwtUtil.getUserLoginDto(authorization);
if (!DeviceTypeUtil.isWeb(deviceType) && null == user) {
return Result.unauthorized(null);
}
PageRequest pageRequest = PageRequest.of(getPageNum(query.getPageNum()), getPageSize(query.getPageSize()));
List<JournalSong> pageResults=journalSongService.fuzzySearch(query.getKeyword(),pageRequest); List<JournalSong> pageResults=journalSongService.fuzzySearch(query.getKeyword(),pageRequest);
List<SongRespDTO> list = pageResults.stream().map(SongMapper::getSongRespDTO) List<SongRespDTO> list = pageResults.stream().map(SongMapper::getSongRespDTO)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -86,10 +99,16 @@ public class SearchController {
@ApiOperation(value = "2.2 搜索期刊", notes = "根据关键词模糊搜索期刊") @ApiOperation(value = "2.2 搜索期刊", notes = "根据关键词模糊搜索期刊")
@GetMapping("/fuzzy/journal") @GetMapping("/fuzzy/journal")
@GlobalInterceptor(checkAppUserLogin = true) @GlobalInterceptor
public Result<PageResult<JournalRespDTO>> fuzzySearchJournal( public Result<PageResult<JournalRespDTO>> fuzzySearchJournal(
@RequestHeader(value = "device_type", required = false) String deviceType,
@RequestHeader(value = "Authorization", required = false) String authorization, @RequestHeader(value = "Authorization", required = false) String authorization,
@VerifyParam(required = true) FuzzySearchReq query) throws InterruptedException, ExecutionException { @VerifyParam(required = true) FuzzySearchReq query) throws InterruptedException, ExecutionException {
UserLoginDto user = jwtUtil.getUserLoginDto(authorization);
if (!DeviceTypeUtil.isWeb(deviceType) && null == user) {
return Result.unauthorized(null);
}
PageRequest pageRequest = PageRequest.of(getPageNum(query.getPageNum()), getPageSize(query.getPageSize())); PageRequest pageRequest = PageRequest.of(getPageNum(query.getPageNum()), getPageSize(query.getPageSize()));
List<Journal> pageResults=journalService.fuzzySearch(query.getKeyword(),pageRequest); List<Journal> pageResults=journalService.fuzzySearch(query.getKeyword(),pageRequest);
List<JournalRespDTO> list = pageResults.stream().map(journalMapper::getJournalRespDTO) List<JournalRespDTO> list = pageResults.stream().map(journalMapper::getJournalRespDTO)
@ -99,10 +118,15 @@ public class SearchController {
@ApiOperation(value = "3.搜索自动补全", notes = "limit 默认查10条") @ApiOperation(value = "3.搜索自动补全", notes = "limit 默认查10条")
@GetMapping("/autoComplete") @GetMapping("/autoComplete")
@GlobalInterceptor(checkAppUserLogin = true) @GlobalInterceptor
public Result<List<String>> autoComplete( public Result<List<String>> autoComplete(
@RequestHeader(value = "Authorization", required = true) String authorization, @RequestHeader(value = "device_type", required = false) String deviceType,
@RequestHeader(value = "Authorization", required = false) String authorization,
@VerifyParam(required = true) AutoCompleteReq query) { @VerifyParam(required = true) AutoCompleteReq query) {
UserLoginDto user = jwtUtil.getUserLoginDto(authorization);
if (!DeviceTypeUtil.isWeb(deviceType) && null == user) {
return Result.unauthorized(null);
}
int limit = getLimit(query.getLimit()); int limit = getLimit(query.getLimit());
return Result.success(searchService.autoComplete(query.getQuery(), limit)); return Result.success(searchService.autoComplete(query.getQuery(), limit));
} }
@ -110,4 +134,11 @@ public class SearchController {
private int getLimit(Integer limit) { private int getLimit(Integer limit) {
return null == limit || 0 == limit ? DEFAULT_AUTO_COMPLETE_LIMIT : limit; return null == limit || 0 == limit ? DEFAULT_AUTO_COMPLETE_LIMIT : limit;
} }
@ApiOperation(value = "4.获取所有标签")
@GetMapping("/tag")
@GlobalInterceptor
public Result<List<TagDTO>> tag() {
return Result.success(tagService.findAllTags());
}
} }

@ -2,6 +2,9 @@ package com.luoo.music.controller;
import com.luoo.music.dto.mapper.SongMapper; import com.luoo.music.dto.mapper.SongMapper;
import com.luoo.music.dto.request.CollectQueryReq; import com.luoo.music.dto.request.CollectQueryReq;
import com.luoo.music.dto.request.FuzzySearchReq;
import com.luoo.music.dto.request.RandomTopicReq;
import com.luoo.music.dto.response.RandomTopicDTO;
import com.luoo.music.dto.response.SongRespDTO; import com.luoo.music.dto.response.SongRespDTO;
import com.luoo.music.pojo.JournalSong; import com.luoo.music.pojo.JournalSong;
import com.luoo.music.service.JournalService; import com.luoo.music.service.JournalService;
@ -165,6 +168,34 @@ public class SongController {
return Result.success(results); return Result.success(results);
} }
@ApiOperation(value = "3.1 获取随机播放歌曲主题")
@GetMapping("/randomTopic")
public Result<List<RandomTopicDTO>> randomTopic() {
return Result.success(journalSongService.getRandomTopic());
}
@ApiOperation(value = "3.2 按主题随机播放歌曲", notes = "雀乐主题FM")
@GetMapping("/random")
@GlobalInterceptor
public Result<List<SongRespDTO>> randomTopicSong(
@RequestHeader(value = "Authorization", required = false) String authorization,
@VerifyParam(required = true) RandomTopicReq query) {
if(!journalSongService.isValidTopic(query.getTopicId())) {
return random(authorization,query.getLimit());
}
List<JournalSong> songs = journalSongService.randomSongByTopic(query);
UserLoginDto user = jwtUtil.getUserLoginDto(authorization);
List<String> ids=songs.stream().map(JournalSong::getJournalNoSongId).collect(Collectors.toList());
Set<String> songCollectSet = null == user ? Collections.emptySet()
: userCollectInfoService.getCollectSet(user.getUserId(),ids, CollectTypeEnum.SONG);
List<SongRespDTO> results = songs.stream().map(s -> SongMapper.getSongRespDTO(s, songCollectSet))
.collect(Collectors.toList());
return Result.success(results);
}
@ApiOperation(value = "4.根据歌曲id查询歌曲信息") @ApiOperation(value = "4.根据歌曲id查询歌曲信息")
@GetMapping("/{id}") @GetMapping("/{id}")
@GlobalInterceptor @GlobalInterceptor

@ -97,5 +97,8 @@ public interface JournalDao extends JpaRepository<Journal,String>,JpaSpecificati
@Query(value = "select tbl.* from (select tbl1.* from tb_journal tbl1 where state='1' and is_publish='1' order by user_collect_count DESC LIMIT 50) tbl order by rand() limit 8", nativeQuery = true) @Query(value = "select tbl.* from (select tbl1.* from tb_journal tbl1 where state='1' and is_publish='1' order by user_collect_count DESC LIMIT 50) tbl order by rand() limit 8", nativeQuery = true)
List<Journal> recommend(); List<Journal> recommend();
@Query(value = "select j.journal_no from indie_music.tb_journal as j, indie_music.tb_journal_tag as jt where j.id=jt.journal_id and jt.tag_id in (select id from indie_music.tb_tag_info where name_ch in ?1)", nativeQuery = true)
List<Integer> getJournalNoByTags(List<String> tags);
} }

@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* @author locust * @author locust
@ -65,4 +66,7 @@ public interface JournalSongDao extends JpaRepository<JournalSong,String>, JpaSp
@Query(value = "select * from tb_journal_song tjs where journal_no = (select journal_no from tb_journal where id=?1) order by song_no", nativeQuery = true) @Query(value = "select * from tb_journal_song tjs where journal_no = (select journal_no from tb_journal where id=?1) order by song_no", nativeQuery = true)
List<JournalSong> findByJournalId(String journalId); List<JournalSong> findByJournalId(String journalId);
@Query(value = "select * from tb_journal_song where journal_no in ?1 order by rand() limit ?2 ", nativeQuery = true)
List<JournalSong> random(List<Integer> journalNos, Integer limit);
} }

@ -36,4 +36,7 @@ public interface TagDao extends JpaRepository<Tag, String>, JpaSpecificationExec
@Query(value = "select * from tb_tag_info where name_ch=?1 limit 1", nativeQuery = true) @Query(value = "select * from tb_tag_info where name_ch=?1 limit 1", nativeQuery = true)
Tag findByTagName(String tagName); Tag findByTagName(String tagName);
@Query(value = "select * from tb_tag_info where state=1 order by create_time", nativeQuery = true)
List<Tag> getAllValidTags();
} }

@ -0,0 +1,24 @@
package com.luoo.music.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import annotation.VerifyParam;
import enums.VerifyRegexEnum;
/**
*
*/
@Data
@ApiModel
public class RandomTopicReq implements Serializable {
private static final long serialVersionUID = 1L;
@VerifyParam(required = false)
@ApiModelProperty(value = "主题id", required = false)
private Integer topicId;
@VerifyParam(required = true, regex = VerifyRegexEnum.RANDOM_SONG_LIMIT)
@ApiModelProperty(value = "随机歌曲数最少1首最多30首", example = "10")
private Integer limit;
}

@ -0,0 +1,14 @@
package com.luoo.music.dto.response;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class RandomTopicDTO implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
}

@ -2,14 +2,19 @@ package com.luoo.music.dto.response;
import java.io.Serializable; import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@Data @Data
@JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
public class TagDTO implements Serializable { public class TagDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID") @ApiModelProperty(value = "ID")
private String id; private String id;
@ApiModelProperty(value = "中文名") @ApiModelProperty(value = "中文名")
private String name; private String name;
@ApiModelProperty(value = "英文名")
private String engName;
} }

@ -33,7 +33,7 @@ public class ArticleRespDTO implements Serializable {
private String userId; private String userId;
@ApiModelProperty(value = "发布作者昵称") @ApiModelProperty(value = "发布作者昵称")
private String userName; private String userName;
@ApiModelProperty(value = "编辑日期,格式为: yyyy-MM-dd HH:mm:ss") @ApiModelProperty(value = "发布时间,格式为: yyyy-MM-dd HH:mm:ss")
private String date; private String date;
@ApiModelProperty(value = "是否定时发布 否0 是1") @ApiModelProperty(value = "是否定时发布 否0 是1")
@ -70,13 +70,13 @@ public class ArticleRespDTO implements Serializable {
response.setContent(article.getContent()); response.setContent(article.getContent());
response.setUserId(article.getUserId()); response.setUserId(article.getUserId());
response.setUserName(article.getUserName()); response.setUserName(article.getUserName());
response.setDate(article.getUpdateTime().format(DateTimeFormatter.ISO_DATE_TIME)); response.setDate(article.getPubTime().format(DateTimeFormatter.ISO_DATE_TIME));
response.setTotalCommentReply(article.getComment()); response.setTotalCommentReply(article.getComment());
response.setVistisNum(article.getVisits()); response.setVistisNum(article.getVisits());
response.setIsScheduled(article.getIsScheduled()); response.setIsScheduled(article.getIsScheduled());
response.setPubTime(article.getPubTime().format(DateTimeFormatter.ISO_DATE_TIME)); response.setPubTime(article.getPubTime().format(DateTimeFormatter.ISO_DATE_TIME));
response.setAllowCommit(article.getAllowCommit()); response.setAllowCommit(article.getAllowCommit());
response.setAutoPush("1".equals(article.getAutoPush())?true:false); response.setAutoPush("1".equals(article.getAutoPush()));
response.setSongId(article.getSongId()); response.setSongId(article.getSongId());
return response; return response;

@ -9,6 +9,8 @@ import org.springframework.stereotype.Component;
import com.luoo.music.dao.JournalDao; import com.luoo.music.dao.JournalDao;
import com.luoo.music.dto.request.JournalQueryReq; import com.luoo.music.dto.request.JournalQueryReq;
import com.luoo.music.pojo.Journal; import com.luoo.music.pojo.Journal;
import com.luoo.music.service.JournalSongService;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -22,12 +24,16 @@ public class CleanJournalCache {
@Autowired @Autowired
private JournalDao journalDao; private JournalDao journalDao;
@Autowired
private JournalSongService journalSongService;
@Async @Async
public void cleanCache() { public void cleanCache() {
try { try {
cacheChannel.evict("default", "journal_filter"); cacheChannel.evict("default", "journal_filter");
cacheChannel.clear(Constants.J2CACHE_REGION_JOURNAL_QUERY_PAGE); cacheChannel.clear(Constants.J2CACHE_REGION_JOURNAL_QUERY_PAGE);
cacheChannel.clear(Constants.J2CACHE_REGION_JOURNAL_QUERY_COUNT); cacheChannel.clear(Constants.J2CACHE_REGION_JOURNAL_QUERY_COUNT);
journalSongService.updateTopicMap();
}catch(Exception e) { }catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -47,6 +53,7 @@ public class CleanJournalCache {
String journalNo=optional.get().getJournalNo(); String journalNo=optional.get().getJournalNo();
cacheChannel.evict(constants.Constants.J2CACHE_REGION_JOURNAL_SONG_LIST, journalNo); cacheChannel.evict(constants.Constants.J2CACHE_REGION_JOURNAL_SONG_LIST, journalNo);
cacheChannel.evict(constants.Constants.J2CACHE_REGION_JOURNAL_NO,journalNo); cacheChannel.evict(constants.Constants.J2CACHE_REGION_JOURNAL_NO,journalNo);
journalSongService.updateTopicMap();
}catch(Exception e) { }catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

@ -1,17 +0,0 @@
package com.luoo.music.service;
import com.luoo.music.dao.ArticleDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Revers.
* @date 2024/02/21 16:32
**/
@Service
public class ArticleService {
@Autowired
private ArticleDao articleDao;
}

@ -77,11 +77,12 @@ public class CMSAdvertisementService {
ad.setIsDeleted("0"); ad.setIsDeleted("0");
UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId()); UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId());
if (!Objects.isNull(userInfo)) { if (Objects.isNull(userInfo))
return Result.failed("发布人ID无效");
ad.setUserId(userInfo.getId()); ad.setUserId(userInfo.getId());
ad.setUserName(userInfo.getName()); ad.setUserName(userInfo.getName());
ad.setUserType(userInfo.getType()); ad.setUserType(userInfo.getType());
}
Example<Advertisement> example = Example.of(ad, ExampleMatcher.matching() Example<Advertisement> example = Example.of(ad, ExampleMatcher.matching()
@ -92,10 +93,8 @@ public class CMSAdvertisementService {
.withIgnorePaths("updateTime") .withIgnorePaths("updateTime")
); );
if(!adDao.exists(example)) {
adDao.save(ad); adDao.save(ad);
cleanAdCache(ad.getId()); cleanAdCache(ad.getId());
}
return Result.success(); return Result.success();
} }
@ -233,7 +232,6 @@ public class CMSAdvertisementService {
return Result.failed("广告不存在"); return Result.failed("广告不存在");
} }
private List<AdvertisementRespDTO> getPageAdFromCache(int page , int size,String location){ private List<AdvertisementRespDTO> getPageAdFromCache(int page , int size,String location){
return (List<AdvertisementRespDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ADVERTISEMENT_PAGE, page+","+size, key -> getPageAd(page,size,location), false).getValue(); return (List<AdvertisementRespDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ADVERTISEMENT_PAGE, page+","+size, key -> getPageAd(page,size,location), false).getValue();
@ -255,8 +253,6 @@ public class CMSAdvertisementService {
} }
return result; return result;
} }
private String getAdFromCache(String id){ private String getAdFromCache(String id){
return (String) cacheChannel.get(constants.Constants.J2CACHE_REGION_ADVERTISEMENT, id, key -> getAdById(id), false).getValue(); return (String) cacheChannel.get(constants.Constants.J2CACHE_REGION_ADVERTISEMENT, id, key -> getAdById(id), false).getValue();
} }
@ -270,5 +266,4 @@ public class CMSAdvertisementService {
cacheChannel.clear(constants.Constants.J2CACHE_REGION_ADVERTISEMENT_PAGE); cacheChannel.clear(constants.Constants.J2CACHE_REGION_ADVERTISEMENT_PAGE);
} }
} }

@ -16,15 +16,13 @@ import com.luoo.music.util.Constants;
import net.oschina.j2cache.CacheChannel; import net.oschina.j2cache.CacheChannel;
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.Example; import org.springframework.data.domain.*;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import util.IdWorker; import util.IdWorker;
@ -34,6 +32,7 @@ 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.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*; import java.util.*;
/** /**
@ -61,6 +60,9 @@ public class CMSArticleService {
@Autowired @Autowired
private CacheChannel cacheChannel; private CacheChannel cacheChannel;
@Autowired
private RedisTemplate redisTemplate;
public Result add(ArticleAddModel paramAdd) { public Result add(ArticleAddModel paramAdd) {
String image = null; String image = null;
@ -73,25 +75,6 @@ public class CMSArticleService {
} }
} }
Article article = buildArticle(paramAdd,image);
Example<Article> example = Example.of(article, ExampleMatcher.matching()
.withIgnorePaths("id")
.withIgnorePaths("image")
.withIgnorePaths("pubTime")
.withIgnorePaths("createTime")
.withIgnorePaths("updateTime")
);
if(!articleDao.exists(example)) {
articleDao.save(article);
cleanArticleCache(article.getId());
}
return Result.success();
}
private Article buildArticle(ArticleAddModel paramAdd,String image){
Article article = new Article(); Article article = new Article();
article.setId(String.valueOf(idWorker.nextId())); article.setId(String.valueOf(idWorker.nextId()));
article.setTitle(paramAdd.getTitle()); article.setTitle(paramAdd.getTitle());
@ -105,43 +88,53 @@ public class CMSArticleService {
UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId()); UserInfo userInfo = userClient.queryUserInfoById(paramAdd.getUserId());
if (!Objects.isNull(userInfo)) { if (Objects.isNull(userInfo))
return Result.failed("发布人ID无效");
article.setUserId(userInfo.getId()); article.setUserId(userInfo.getId());
article.setUserName(userInfo.getName()); article.setUserName(userInfo.getName());
article.setUserType(userInfo.getType()); article.setUserType(userInfo.getType());
}
article.setAllowCommit(paramAdd.getAllowCommit()); article.setAllowCommit(paramAdd.getAllowCommit());
article.setAutoPush(paramAdd.getAutoPush()?"1":"0");
if(paramAdd.getAutoPush()){
article.setAutoPush("1");
article.setIsPublish("1"); article.setIsPublish("1");
article.setPubTime(LocalDateTime.now()); article.setPubTime(LocalDateTime.now());
article.setIsScheduled(paramAdd.getIsScheduled()); article.setIsScheduled(paramAdd.getIsScheduled());
}else {
if (paramAdd.getPubTime() == null)
return Result.failed("定时发布但发布时间为空");
/* String pubTimeStr = paramAdd.getPubTime(); if(paramAdd.getPubTime().isBefore(LocalDateTime.now())){
LocalDateTime pubTime = LocalDateTime.now(); article.setAutoPush("0");
if ("1".equals(paramAdd.getIsScheduled())) { // 定时发布
if (StringUtils.isNotBlank(pubTimeStr)) {// 定时发布确定发布时间
pubTime = LocalDateTime.parse(pubTimeStr, Constants.formatter);
if(pubTime.isBefore(LocalDateTime.now())){ //发布时间比现在早
article.setState("1");
article.setIsPublish("1"); article.setIsPublish("1");
article.setPubTime(LocalDateTime.now()); article.setPubTime(LocalDateTime.now());
}else {//发布时间比现在晚 article.setIsScheduled("1");
article.setState("0"); }else {
article.setAutoPush("0");
article.setIsPublish("0"); article.setIsPublish("0");
article.setPubTime(pubTime); article.setPubTime(paramAdd.getPubTime());
article.setIsScheduled("0");
redisTemplate.opsForHash().put(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId(),paramAdd.getPubTime());
} }
}else { // 定时发布未确定发布时间
article.setState("1");
article.setIsPublish("1");
article.setPubTime(LocalDateTime.now());
} }
} else { //非定时发布
article.setState("1");
article.setIsPublish("1");
article.setPubTime(LocalDateTime.now());
}*/
return article;
Example<Article> example = Example.of(article, ExampleMatcher.matching()
.withIgnorePaths("id")
.withIgnorePaths("image")
.withIgnorePaths("pubTime")
.withIgnorePaths("createTime")
.withIgnorePaths("updateTime")
);
if(!articleDao.exists(example)) {
articleDao.save(article);
cleanArticleCache(article.getId());
}else {
redisTemplate.opsForHash().delete(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId());
}
return Result.success();
} }
private String moveArticleImage(String srcKey, String image) { private String moveArticleImage(String srcKey, String image) {
@ -163,6 +156,7 @@ public class CMSArticleService {
article.setIsDeleted("1"); article.setIsDeleted("1");
articleDao.save(article); articleDao.save(article);
cleanArticleCache(article.getId()); cleanArticleCache(article.getId());
redisTemplate.opsForHash().delete(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId());
return Result.success(); return Result.success();
} }
return Result.failed("文章不存在"); return Result.failed("文章不存在");
@ -200,23 +194,37 @@ public class CMSArticleService {
} }
article.setTitle(param.getTitle()); article.setTitle(param.getTitle());
article.setType(param.getType()); article.setType(param.getType());
article.setSummary(contentToSummary(param.getContent())); article.setSummary(contentToSummary(param.getContent()));
article.setContent(param.getContent()); article.setContent(param.getContent());
article.setAllowCommit(param.getAllowCommit()); article.setAllowCommit(param.getAllowCommit());
article.setAutoPush(param.getAutoPush()?"1":"0"); redisTemplate.opsForHash().delete(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId());
if(param.getAutoPush()){
article.setIsScheduled(param.getIsScheduled()); article.setAutoPush("1");
article.setIsPublish("1");
article.setPubTime(LocalDateTime.now());
article.setIsScheduled("1");
}else {
if (param.getPubTime() == null)
return Result.failed("定时发布但发布时间为空");
if(param.getPubTime().isBefore(LocalDateTime.now())){
article.setAutoPush("0");
article.setIsPublish("1");
article.setPubTime(LocalDateTime.now());
article.setIsScheduled("1");
}else {
article.setAutoPush("0");
article.setIsPublish("0");
article.setPubTime(param.getPubTime()); article.setPubTime(param.getPubTime());
article.setIsScheduled("0");
redisTemplate.opsForHash().put(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId(),param.getPubTime());
}
}
articleDao.save(article); articleDao.save(article);
cleanArticleCache(article.getId()); cleanArticleCache(article.getId());
//TODO: 发布方式
return Result.success(); return Result.success();
} }
@ -270,12 +278,20 @@ public class CMSArticleService {
return Result.success(new PageResult<>(Long.valueOf(pageArticleFromCache.size()), pageArticleFromCache)); return Result.success(new PageResult<>(Long.valueOf(pageArticleFromCache.size()), pageArticleFromCache));
} }
private Specification<Article> buildSearchSpecification() { //isFront : true 前台数据只显示Publish的
//isFront false 后台数据,全都显示
private Specification<Article> buildSearchSpecification(boolean isFrost) {
return (Root<Article> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> { return (Root<Article> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
List<Predicate> predicateList = new ArrayList<Predicate>(); List<Predicate> predicateList = new ArrayList<Predicate>();
Predicate isDeleted = builder.equal(root.get("isDeleted"), "0"); Predicate isDeleted = builder.equal(root.get("isDeleted"), "0");
if(isFrost){
Predicate isPublish = builder.equal(root.get("isPublish"), "1"); Predicate isPublish = builder.equal(root.get("isPublish"), "1");
predicateList.add(builder.and(isDeleted, isPublish)); predicateList.add(builder.and(isDeleted, isPublish));
}else {
predicateList.add(builder.and(isDeleted));
}
return builder.and(predicateList.toArray(new Predicate[predicateList.size()])); return builder.and(predicateList.toArray(new Predicate[predicateList.size()]));
}; };
} }
@ -293,14 +309,23 @@ public class CMSArticleService {
return cleanedString.length() >=150 ? cleanedString.substring(0,150):cleanedString; return cleanedString.length() >=150 ? cleanedString.substring(0,150):cleanedString;
} }
public void releaseArticle(String articleId){
Article article = JSON.parseObject(getArticleFromCache(articleId), Article.class);
if (article != null) {
article.setIsPublish("1");
article.setIsScheduled("1");
}
private List<ArticleRespDTO> getPageArticleFromCache(int page , int size){ articleDao.save(article);
cleanArticleCache(article.getId());
redisTemplate.opsForHash().delete(Constants.REDIS_KEY_ARTICLE_SCHEDULED,article.getId());
}
private List<ArticleRespDTO> getPageArticleFromCache(int page , int size){
return (List<ArticleRespDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ARTICLE_PAGE, page+","+size, key -> getPageArticle(page,size), false).getValue(); return (List<ArticleRespDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ARTICLE_PAGE, page+","+size, key -> getPageArticle(page,size), false).getValue();
} }
private List<ArticleDTO> getPageArticleDTOFromCache(int page , int size){ private List<ArticleDTO> getPageArticleDTOFromCache(int page , int size){
return (List<ArticleDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ARTICLE_DTO_PAGE, page+","+size, key -> getPageArticleDTO(page,size), false).getValue(); return (List<ArticleDTO>) cacheChannel.get(constants.Constants.J2CACHE_REGION_ARTICLE_DTO_PAGE, page+","+size, key -> getPageArticleDTO(page,size), false).getValue();
} }
@ -308,8 +333,8 @@ public class CMSArticleService {
private List<ArticleRespDTO> getPageArticle(int page , int size){ private List<ArticleRespDTO> getPageArticle(int page , int size){
List<ArticleRespDTO> result = new ArrayList<>(); List<ArticleRespDTO> result = new ArrayList<>();
PageRequest pageRequest = PageRequest.of(page - 1, size); PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("pubTime").descending());
Specification<Article> articleSpecification = buildSearchSpecification(); Specification<Article> articleSpecification = buildSearchSpecification(false);
Page<Article> ArticlePage = articleDao.findAll(articleSpecification,pageRequest); Page<Article> ArticlePage = articleDao.findAll(articleSpecification,pageRequest);
List<Article> content = ArticlePage.getContent(); List<Article> content = ArticlePage.getContent();
@ -325,8 +350,8 @@ public class CMSArticleService {
public List<ArticleDTO> getPageArticleDTO(int page,int size) { public List<ArticleDTO> getPageArticleDTO(int page,int size) {
List<ArticleDTO> result = new ArrayList<>(); List<ArticleDTO> result = new ArrayList<>();
PageRequest pageRequest = PageRequest.of(page - 1, size); PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("pubTime").descending());
Specification<Article> articleSpecification = buildSearchSpecification(); Specification<Article> articleSpecification = buildSearchSpecification(true);
Page<Article> ArticlePage = articleDao.findAll(articleSpecification,pageRequest); Page<Article> ArticlePage = articleDao.findAll(articleSpecification,pageRequest);
List<Article> content = ArticlePage.getContent(); List<Article> content = ArticlePage.getContent();
@ -337,7 +362,6 @@ public class CMSArticleService {
} }
} }
return result; return result;
} }
private String getArticleFromCache(String id){ private String getArticleFromCache(String id){
@ -351,5 +375,6 @@ public class CMSArticleService {
private void cleanArticleCache(String id){ private void cleanArticleCache(String id){
cacheChannel.evict(constants.Constants.J2CACHE_REGION_ARTICLE,id); cacheChannel.evict(constants.Constants.J2CACHE_REGION_ARTICLE,id);
cacheChannel.clear(constants.Constants.J2CACHE_REGION_ARTICLE_PAGE); cacheChannel.clear(constants.Constants.J2CACHE_REGION_ARTICLE_PAGE);
cacheChannel.clear(constants.Constants.J2CACHE_REGION_ARTICLE_DTO_PAGE);
} }
} }

@ -1,37 +1,84 @@
package com.luoo.music.service; package com.luoo.music.service;
import com.luoo.music.dao.JournalDao;
import com.luoo.music.dao.JournalSongDao; import com.luoo.music.dao.JournalSongDao;
import com.luoo.music.dto.mapper.SongMapper; import com.luoo.music.dto.mapper.SongMapper;
import com.luoo.music.dto.request.RandomTopicReq;
import com.luoo.music.dto.response.RandomTopicDTO;
import com.luoo.music.dto.response.SongRespDTO; import com.luoo.music.dto.response.SongRespDTO;
import com.luoo.music.pojo.JournalSong; import com.luoo.music.pojo.JournalSong;
import constants.Constants; import constants.Constants;
import lombok.extern.slf4j.Slf4j;
import net.oschina.j2cache.CacheChannel; import net.oschina.j2cache.CacheChannel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
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 javax.annotation.PostConstruct;
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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@Slf4j
public class JournalSongService { public class JournalSongService {
@Autowired @Autowired
private JournalSongDao journalSongDao; private JournalSongDao journalSongDao;
@Autowired
private JournalDao journalDao;
@Autowired @Autowired
private CacheChannel cacheChannel; private CacheChannel cacheChannel;
private List<RandomTopicDTO> randomTopicDTOs = new ArrayList<>();
private Map<Integer,List<Integer>> topicJournalMap = new HashMap<>();
private static final String TOPIC_FILE_PATH="topic.txt";
@PostConstruct
private void init() {
getLines(TOPIC_FILE_PATH).forEach(s->{
String[] segs=s.split("\\|");
Integer id=Integer.valueOf(segs[0]);
String name=segs[1];
List<String> tags=Arrays.stream(segs[2].split(",")).collect(Collectors.toList());
List<Integer> journalNos=getJournalNoByTags(tags);
randomTopicDTOs.add(new RandomTopicDTO(id,name));
topicJournalMap.put(id, journalNos);
});
}
private List<Integer> getJournalNoByTags(List<String> tags) {
return journalDao.getJournalNoByTags(tags);
}
private static List<String> getLines(String filePath) {
try (InputStream is = new ClassPathResource(filePath).getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));) {
return reader.lines().collect(Collectors.toList());
} catch (IOException e) {
log.error(e.getMessage());
}
return Collections.emptyList();
}
/** /**
* *
*/ */
@ -172,4 +219,26 @@ public class JournalSongService {
} }
}; };
} }
public List<RandomTopicDTO> getRandomTopic() {
return randomTopicDTOs;
}
public boolean isValidTopic(Integer topicId) {
return null!=topicId&&topicJournalMap.containsKey(topicId);
}
public List<JournalSong> randomSongByTopic(RandomTopicReq query) {
return journalSongDao.random(topicJournalMap.get(query.getTopicId()), query.getLimit());
}
public void updateTopicMap() {
getLines(TOPIC_FILE_PATH).forEach(s->{
String[] segs=s.split("\\|");
Integer id=Integer.valueOf(segs[0]);
List<String> tags=Arrays.stream(segs[2].split(",")).collect(Collectors.toList());
List<Integer> journalNos=getJournalNoByTags(tags);
topicJournalMap.put(id, journalNos);
});
}
} }

@ -58,4 +58,20 @@ public class TagService {
searchCategoryDTO.setThumbnail(Constants.TAG_RESOURCE_PREFIX + tag.getThumbnail()); searchCategoryDTO.setThumbnail(Constants.TAG_RESOURCE_PREFIX + tag.getThumbnail());
return searchCategoryDTO; return searchCategoryDTO;
} }
@SuppressWarnings("unchecked")
public List<TagDTO> findAllTags() {
return (List<TagDTO>) this.cacheChannel.get("default", "tags", key -> getAllTags(), false).getValue();
}
private List<TagDTO> getAllTags() {
return tagDao.getAllValidTags().stream().map(this::getTagDTO).collect(Collectors.toList());
}
private TagDTO getTagDTO(Tag tag) {
TagDTO tagDTO=new TagDTO();
tagDTO.setName(tag.getNameCh());
tagDTO.setId(tag.getId());
tagDTO.setEngName(tag.getNameEn());
return tagDTO;
}
} }

@ -40,4 +40,7 @@ public class Constants {
public static final String COMMA = ","; public static final String COMMA = ",";
// _ 下划线 // _ 下划线
public static final String UNDERSCORE = "_"; public static final String UNDERSCORE = "_";
public static final String REDIS_KEY_ARTICLE_SCHEDULED = "redis_key_article_scheduled";
} }

@ -0,0 +1,5 @@
1|力量之源|金属,朋克,说唱,摇滚
2|靡靡之音|民谣,流行,爵士,乡村,蓝调,雷鬼
3|情绪之下|后摇,世界音乐,古典,原声,口哨,轻音乐
4|黑暗之舞|暗潮,仙音,新民谣,黑暗民谣
5|节奏之魂|电子
Loading…
Cancel
Save