1.完善了栏目管理的两个保存接口,针对单个栏目则保存到缓存。等待整体保存之后则存储到数据库中(轮播大图根据ID保存,硬编码为4是轮播大图,必须保证数据库一致)

2.增加风格保存
3.增加了channelAppView接口,用于后台的栏目管理接口,appView改用为APP端使用
This commit is contained in:
2210088963 2025-03-24 09:11:50 +08:00
parent 9246ec9327
commit 344e856953
12 changed files with 276 additions and 21 deletions

View File

@ -55,3 +55,8 @@ alter table aijinan.live_report
1 autoLiveTask AutoLiveTask 0/30 * * * * ? 0 This is a test job 2025-02-08 10:55:23
2 likeSyncTask syncLikesToDatabase 0/15 * * * * ? 0 redis的点赞数存储在数据库中
3 likeSyncTask syncReportLikesToDatabase 0/15 * * * * ? 0 redis的点赞数存储在数据库中 2025-02-20 11:07:00
alter table aijinan.live_channel
add column title_show int default '0' COMMENT '是否显示别名 0 不显示 1显示';

View File

@ -59,6 +59,8 @@ public class ShiroConfig {
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/live/channel/appView", "anon");
filterMap.put("/webjars/**", "anon");
// filterMap.put("/druid/**", "anon");
filterMap.put("/app/**", "anon");

View File

@ -2,10 +2,18 @@ package com.platform.modules.live.controller;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.db.meta.Column;
import com.platform.modules.live.entity.LiveChannelComponentEntity;
import com.platform.modules.live.service.LiveChannelTenantService;
import com.platform.modules.live.service.impl.LiveChannelComponentServiceImpl;
import com.platform.modules.sys.dao.SysConfigDao;
import com.platform.modules.sys.entity.SysConfigEntity;
import com.platform.modules.sys.service.impl.SysConfigServiceImpl;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@ -42,6 +50,12 @@ import springfox.documentation.annotations.ApiIgnore;
public class LiveChannelController extends AbstractController{
@Autowired
private LiveChannelService liveChannelService;
@Autowired
private SysConfigServiceImpl sysConfigService;
@Autowired
private SysConfigDao sysConfigDao;
@Autowired
private LiveChannelComponentServiceImpl liveChannelComponentService;
@ -193,6 +207,16 @@ public class LiveChannelController extends AbstractController{
*
* @return 集合
*/
@PostMapping("/channelAppView")
public R channelAppView() {
return R.ok().put("appView",liveChannelService.channelAppView(copyOnWriteArrayList,liveChannelComponentEntity));
}
/**
* 查询APP端口现场大屏和栏目封装
*
* @return 集合
*/
@PostMapping("/appView")
public R appView() {
return R.ok().put("appView",liveChannelService.appView());
@ -224,6 +248,13 @@ public class LiveChannelController extends AbstractController{
return R.error("组件ID错误");
}
// 缓存待提交的栏目修改线程安全
public CopyOnWriteArrayList<LiveChannelEntity> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
public LiveChannelComponentEntity liveChannelComponentEntity = new LiveChannelComponentEntity();
/**
* 保存修改后的组件属性信息
* @param liveChannel 需要修改栏目的属性信息 根据ComponentType去区分是否为轮播大图
@ -232,33 +263,67 @@ public class LiveChannelController extends AbstractController{
@PostMapping("/saveMessage")
public R saveMessage(@RequestBody LiveChannelEntity liveChannel){
if(liveChannel.getComponentType().equals("lunbodatu")) {
LiveChannelComponentEntity liveChannelComponentEntity = new LiveChannelComponentEntity();
liveChannelComponentEntity.setId(liveChannel.getId());
liveChannelComponentEntity.setId(4);
liveChannelComponentEntity.setDefaultCount(liveChannel.getComponentCount());
liveChannelComponentService.updateById(liveChannelComponentEntity);
// liveChannelComponentService.updateById(liveChannelComponentEntity);
}else {
LiveChannelEntity entity = new LiveChannelEntity();
entity.setId(liveChannel.getId());
entity.setPriority(liveChannel.getPriority());
entity.setIsDisplay(liveChannel.getIsDisplay());
entity.setComponentType(liveChannel.getComponentType());
entity.setComponentLayout(liveChannel.getComponentLayout());
entity.setComponentCount(liveChannel.getComponentCount());
entity.setTitleSetting(liveChannel.getTitleSetting());
entity.setLastUpdateUser(getUserId());
entity.setLastUpdateDate(new Date());
liveChannelService.updateById(entity);
LiveChannelEntity liveChannelEntity = liveChannelService.selectById(liveChannel.getId());
liveChannelEntity = getLiveChannelEntity(liveChannelEntity,liveChannel);
// 使用同步块保证原子性检查删除旧值添加新值
// synchronized (copyOnWriteArrayList) {
// 删除所有相同ID的旧数据
LiveChannelEntity finalLiveChannelEntity = liveChannelEntity;
copyOnWriteArrayList.removeIf(e -> e.getId().equals(finalLiveChannelEntity.getId()));
// 添加新数据覆盖
copyOnWriteArrayList.add(liveChannelEntity);
// }
}
return R.ok();
}
private LiveChannelEntity getLiveChannelEntity(LiveChannelEntity liveChannelOld,LiveChannelEntity liveChannel) {
liveChannelOld.setId(liveChannel.getId());
liveChannelOld.setPriority(liveChannel.getPriority());
liveChannelOld.setIsDisplay(liveChannel.getIsDisplay());
liveChannelOld.setComponentType(liveChannel.getComponentType());
liveChannelOld.setComponentLayout(liveChannel.getComponentLayout());
liveChannelOld.setComponentCount(liveChannel.getComponentCount());
liveChannelOld.setTitleSetting(liveChannel.getTitleSetting());
liveChannelOld.setTitleShow(liveChannel.getTitleShow());
liveChannelOld.setLastUpdateUser(getUserId());
liveChannelOld.setLastUpdateDate(new Date());
return liveChannelOld;
}
/**
* 点击保存后更新信息同步到APP 暂未实现
* @return
*/
@GetMapping("/updateToAPP")
public R updateToAPP(){
public R updateToAPP( Integer style){
if(liveChannelComponentEntity.getId()!=null){
liveChannelComponentService.updateById(liveChannelComponentEntity);
}
if(CollectionUtil.isNotEmpty(copyOnWriteArrayList)) {
boolean isSuccess = liveChannelService.updateBatchById(copyOnWriteArrayList);
if(isSuccess){
copyOnWriteArrayList.clear();
}
}
if(style == 1 || style == 2 || style == 3){
String pageStyle = "PAGE_STYLE";
SysConfigEntity sysConfig = sysConfigDao.getPageStyle(pageStyle);
sysConfig.setValue(String.valueOf(style));
sysConfigDao.updateById(sysConfig);
}
return R.ok();
}

View File

@ -16,5 +16,6 @@ public class ChannelDTO {
private String componentLayout;
private String identify;
private List<LiveSceneDTO> liveScenes;
private Integer titleShow;
}

View File

@ -8,5 +8,6 @@ public class LiveSceneDTO {
private String title;
private String titleImage;
private Integer liveState;
private String liveImageShow;
}

View File

@ -79,6 +79,8 @@ public class LiveChannelEntity implements Serializable {
private String titleSetting; // 标题设置
private Integer titleShow;
@TableField(exist=false)
private LiveChannelComponentEntity liveChannelComponent;
@ -266,4 +268,12 @@ public class LiveChannelEntity implements Serializable {
public void setLiveChannelComponent(LiveChannelComponentEntity liveChannelComponent) {
this.liveChannelComponent = liveChannelComponent;
}
public Integer getTitleShow() {
return titleShow;
}
public void setTitleShow(Integer titleShow) {
this.titleShow = titleShow;
}
}

View File

@ -2,9 +2,11 @@ package com.platform.modules.live.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import com.baomidou.mybatisplus.service.IService;
import com.platform.common.utils.PageUtils;
import com.platform.modules.live.entity.LiveChannelComponentEntity;
import com.platform.modules.live.entity.LiveChannelEntity;
import net.sf.json.JSONArray;
@ -53,4 +55,6 @@ public interface LiveChannelService extends IService<LiveChannelEntity> {
HashMap<Object, Object> appView();
LiveChannelEntity getChannelComponent(Integer channelId);
HashMap<Object, Object> channelAppView(CopyOnWriteArrayList<LiveChannelEntity> list,LiveChannelComponentEntity liveChannel);
}

View File

@ -3,9 +3,13 @@ package com.platform.modules.live.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.platform.modules.live.dao.LiveChannelComponentDao;
import com.platform.modules.live.entity.LiveChannelComponentEntity;
import com.platform.modules.live.entity.LiveChannelEntity;
import com.platform.modules.live.service.LiveChannelComponentService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("liveChannelComponentService")
public class LiveChannelComponentServiceImpl extends ServiceImpl<LiveChannelComponentDao, LiveChannelComponentEntity> implements LiveChannelComponentService {
}

View File

@ -1,6 +1,7 @@
package com.platform.modules.live.service.impl;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -17,13 +18,9 @@ import com.platform.modules.plm.util.MaterialUtils;
import com.platform.modules.sys.dao.SysConfigDao;
import com.platform.modules.sys.entity.SysConfigEntity;
import com.platform.modules.sys.service.impl.SysConfigServiceImpl;
import io.swagger.models.auth.In;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanInfoFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
@ -370,6 +367,7 @@ private LiveChannelDao liveChannelDao;
return new PageUtils(page);
}
@Override
public HashMap<Object, Object> appView() {
@ -471,6 +469,135 @@ private LiveChannelDao liveChannelDao;
return map;
}
@Override
public HashMap<Object, Object> channelAppView(CopyOnWriteArrayList<LiveChannelEntity> copyOnWriteArrayList,LiveChannelComponentEntity liveChannelComponentEntity) {
HashMap<Object, Object> map = new HashMap<>();
//1.查询轮播大图
LiveChannelComponentEntity liveChannelComponent = liveChannelComponentService.selectOne(new EntityWrapper<LiveChannelComponentEntity>()
.eq("component_type", "lunbodatu"));
Integer count = liveChannelComponentEntity.getId() == null ? liveChannelComponent.getDefaultCount() : liveChannelComponentEntity.getDefaultCount();
List<LiveSceneEntity> sceneEntities = liveSceneService.selectList(new EntityWrapper<LiveSceneEntity>()
.eq("delete_flag", 0)
.eq("scene_state", SceneConstants.SCENE_PROD)
.eq("carousel_image", 1)
.last("limit " + count));
// LiveSceneEntity 转换为 LiveSceneDTO
List<LiveSceneDTO> liveScenes = sceneEntities.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
map.put("carouselScene", liveScenes);
// 2.按照栏目封装现场
Wrapper<LiveChannelEntity> wrapper = new EntityWrapper<LiveChannelEntity>()
.eq("is_delete", 0)
.eq("is_display", 1)
.orderBy("priority", false);
List<LiveChannelEntity> channelEntities = liveChannelService.selectList(wrapper);
// 如果缓存和数据库都有数据则以缓存中的数据覆盖数据库中的数据
if (CollectionUtils.isNotEmpty(channelEntities) && CollectionUtils.isNotEmpty(copyOnWriteArrayList)) {
Map<Integer, LiveChannelEntity> cachedMap = copyOnWriteArrayList.stream()
.collect(Collectors.toMap(LiveChannelEntity::getId, Function.identity()));
channelEntities.forEach(entity -> {
if (cachedMap.containsKey(entity.getId())) {
// 使用缓存中的数据覆盖数据库中的数据
LiveChannelEntity cachedEntity = cachedMap.get(entity.getId());
entity.setPriority(cachedEntity.getPriority());
entity.setIsDisplay(cachedEntity.getIsDisplay());
entity.setComponentType(cachedEntity.getComponentType());
entity.setComponentLayout(entity.getComponentLayout());
entity.setComponentCount(cachedEntity.getComponentCount());
entity.setTitleSetting(cachedEntity.getTitleSetting());
entity.setTitleShow(cachedEntity.getTitleShow());
}
});
}
// List<LiveChannelEntity> channelEntities = liveChannelService.selectList(wrapper);
List<ChannelDTO> collect = channelEntities.stream().map(this::convertToB).collect(Collectors.toList());
// 为每个 ChannelDTO 获取 liveScenes
if(CollectionUtils.isNotEmpty(collect)){
//遍历查询到的所有现场
collect.forEach(channelDTO -> {
// 获取当前频道的所有 LiveSceneChannelEntity
List<LiveSceneChannelEntity> entityList = liveSceneChannelService.selectList(
new EntityWrapper<LiveSceneChannelEntity>()
.eq("channel_id", channelDTO.getChannelId())
);
if(channelDTO.getComponentCount() == null) {
LiveChannelComponentEntity channelComponentEntity = liveChannelComponentService.selectOne(new EntityWrapper<LiveChannelComponentEntity>()
.eq("component_type", channelDTO.getComponentType()));
channelDTO.setComponentCount(channelComponentEntity.getDefaultCount());
}
List<LiveSceneEntity> liveSceneEntities= null;
if(CollectionUtils.isNotEmpty(entityList)) {
// 提取所有的 scene_id 并获取对应的 LiveSceneEntity
Set<Integer> sceneIds = entityList.stream()
.map(LiveSceneChannelEntity::getSceneId)
.collect(Collectors.toSet());
liveSceneEntities = liveSceneService.selectList(new EntityWrapper<LiveSceneEntity>()
.in("id", sceneIds)
.eq("delete_flag", 0)
.eq("scene_state", SceneConstants.SCENE_PROD)
.orderBy("priority", false)
.last("limit " + channelDTO.getComponentCount())
);
//1.重置当前栏目所有现场的channel_display字段为false
liveChannelDao.resetChannelDisplay(channelDTO.getChannelName());
//2.将所有查询到的现场的channel_display字段设置为true
liveSceneEntities.forEach(liveSceneEntity -> {
liveChannelDao.updateChannelDisplay(liveSceneEntity.getId());
liveSceneEntity.setTitleImage( MaterialUtils.getMaterialUrl(liveSceneEntity.getTitleImage(), foreignProperties.getMediaurl()));
});
}
// LiveSceneEntity 转换为 LiveSceneDTO
if(CollectionUtils.isNotEmpty(liveSceneEntities)){
List<LiveSceneDTO> scenes = liveSceneEntities.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
// 设置 ChannelDTO liveScenes 属性
channelDTO.setLiveScenes(scenes);
}
});
}
map.put("sceneGroupByChannel", collect);
//3.获取页面风格
String pageStyle = "PAGE_STYLE";
SysConfigEntity sysConfig = sysConfigDao.getPageStyle(pageStyle);
if(sysConfig == null){
sysConfig = new SysConfigEntity();
sysConfig.setKey("PAGE_STYLE");
sysConfig.setValue("1");
sysConfig.setRemark("页面风格(页面风格:基础蓝色、喜庆红色、哀悼灰色)");
sysConfigDao.insert(sysConfig);
}
map.put("pageStyle", sysConfig.getValue());
return map;
}
@Override
public LiveChannelEntity getChannelComponent(Integer channalId) {
@ -496,16 +623,19 @@ private LiveChannelDao liveChannelDao;
dto.setTitle(entity.getTitle());
dto.setTitleImage(entity.getTitleImage());
dto.setLiveState(entity.getLiveState());
dto.setLiveImageShow(MaterialUtils.getMaterialUrl(entity.getTitleImage(), foreignProperties.getMediaurl()));
return dto;
}
private ChannelDTO convertToB(LiveChannelEntity a) {
ChannelDTO channelDTO = new ChannelDTO();
channelDTO.setChannelId(a.getId());
channelDTO.setChannelName(a.getName());
channelDTO.setComponentCount(a.getComponentCount());
channelDTO.setComponentType(a.getComponentType());
channelDTO.setTitleSetting(a.getTitleSetting());
channelDTO.setTitleShow(a.getTitleShow());
channelDTO.setPriority(a.getPriority());
channelDTO.setIsDisplay(a.getIsDisplay());
channelDTO.setComponentLayout(a.getComponentLayout());

View File

@ -2524,7 +2524,6 @@ public class LiveSceneServiceImpl extends ServiceImpl<LiveSceneDao, LiveSceneEnt
}
List<SceneSortEntityVo> sceneEntityList = this.baseMapper.querySort(page, params);
if (null == sceneEntityList || sceneEntityList.size() == 0)
return null;
@ -2537,7 +2536,8 @@ public class LiveSceneServiceImpl extends ServiceImpl<LiveSceneDao, LiveSceneEnt
entity.setViewsShow(sceneCountVo == null ? 0 : sceneCountVo.getViewsShow());
// 设置导播台ID
entity.setCaster(entity.getCasterId());
});
entity.setTitleImageShow(MaterialUtils.getMaterialUrl(entity.getTitleImage(), foreignProperties.getMediaurl()));
});
// 设置机构名称
sceneEntityList.stream().

View File

@ -36,6 +36,12 @@ public class SceneSortEntityVo {
@NotBlank(message = "titleImage不能为空")
@ApiModelProperty(value = "标题图")
private String titleImage;
//标题图
@NotBlank(message = "titleImageShow不能为空")
@ApiModelProperty(value = "标题拼接图")
private String titleImageShow;
//视频地址
@NotBlank(message = "videoUrl")
@ApiModelProperty(value = "视频地址")

View File

@ -0,0 +1,27 @@
import com.platform.modules.live.utils.QrCodeUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class QrCodeTest {
public static void main(String[] args) {
try {
// 二维码内容
String content = "http://www.jay99.cn";
// Logo路径相对于类路径
String logoPath = "http://cdn.jay99.cn/logo.png";
// 是否压缩Logo
boolean needCompress = true;
// 生成二维码图片
BufferedImage qrImage = QrCodeUtils.createImage(content, logoPath, needCompress);
// 保存二维码图片到文件
File outputFile = new File("qrcode.png");
ImageIO.write(qrImage, "png", outputFile);
System.out.println("二维码生成成功,保存到 " + outputFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
}