我的代码

发布时间 2023-07-02 01:38:10作者: 亦卿wish

@Slf4j
@Transactional
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

/**
 * 查询文章
 *
 * @param dto
 * @return
 */
@Override
public PageResponseResult findList(WmNewsPageReqDto dto) {

    //0.检查参数
    //分页检查
    dto.checkParam();

    //1.分页条件查询(其他条件查询时,查询出的内容都要实现分页功能!) :page,pageSize

// IPage page = new Page(dto.getPage(), dto.getSize());
Page page = new Page(dto.getPage(), dto.getSize()); //传入分页条件

    //创建条件构造器对象
    LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper();

    //2.页面可选的条件查询
    //2.1 文章状态查询
    if (dto.getStatus() != null) {
        lambdaQueryWrapper.eq(WmNews::getStatus, dto.getStatus());
    }

    //2.2 关键字查询(模糊查询)

// if (dto.getKeyword() != null){
if (StringUtils.isNotBlank(dto.getKeyword())) {
lambdaQueryWrapper.like(WmNews::getTitle, dto.getKeyword());
}

    //2.3 频道查询(精确查询)
    if (dto.getChannelId() != null) {
        lambdaQueryWrapper.eq(WmNews::getChannelId, dto.getChannelId());
    }

    //2.4 发布日期查询(日期范围)
    if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null) {
        lambdaQueryWrapper.between(WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate());
    }

    //3. 根据当前登录用户的用户id查询(通过任何条件的查询都是查询当前登录用户的文章信息.)
    lambdaQueryWrapper.eq(WmNews::getUserId, WmThreadLocal.getUser().getId());

    //4. 根据发布时间倒序查询

    lambdaQueryWrapper.orderByDesc(WmNews::getPublishTime);


    page = page(page, lambdaQueryWrapper);

    //返回结果(将查询到的结果封装为一个PageResponseResult对象并返回.)
    PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
    pageResponseResult.setData(page.getRecords());

    return pageResponseResult;

}


@Autowired
private WmNewsMaterialMapper wmNewsMaterialMapper;
@Autowired
private WmMaterialMapper wmMaterialMapper;


/**
 * 提交发布文章
 *
 * @param //dto
 * @return
 */

@Override
public ResponseResult submitNews(WmNewsDto dto) {

    //0 条件判断,判断文章是否为空,根据dto准备文章数据.
    if (dto == null) {
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }

    //1.保存或修改文章(提交文章或保存为草稿)
    //新建一个文章对象,拷贝dto中的内容到该对象
    WmNews wmNews = new WmNews();
    //复制对象的属性值,属性拷贝--->属性名称和类型相同时才能拷贝.
    BeanUtils.copyProperties(dto, wmNews);  //将dto中的内容全部封装进文章对象wmNews中.

    // 此时dto中的images和wmNews中的images类型不一样,不可直接拷贝,需要将结合中的元素拼接为一个完整字符串以后才能拷贝.
    //2.图片的拷贝  List--->String
    //[abc.png,def.png]--->"abc.png,def.png"
    if (dto.getImages() != null && dto.getImages().size() > 0) {

// List imageList = dto.getImages();
// String imageStr = StringUtils.join(imageList, ",");
String imageStr = StringUtils.join(dto.getImages(), ",");
wmNews.setImages(imageStr); // 这里只是将imageStr这个字符串拷贝给wmNews的images,而不是拷贝给content,content需要进行后续业务逻辑处理.
}

    //1.3 补全该WmNews对象的其他属性
    wmNews.setUserId(WmThreadLocal.getUser().getId()); //从本地线程中获取当前用户的id.
    wmNews.setCreatedTime(new Date()); //创建时间为当前时间
    wmNews.setSubmitedTime(new Date()); //提交时间为当前时间
    //默认上架  0下架   1上架
    wmNews.setEnable(1);


    //2 判断该文章是否已经存在id
    if (dto.getId() == null) {
        //2.1 不存在id  新增文章业务
        this.save(wmNews);
        //或者
        // save(wmNews);
    } else {
        //2.2 存在id  修改文章业务
        //删除原来的文章图片和素材的关系

// wmNewsMaterialMapper.delete(Wrappers.lambdaQuery(WmNewsMaterial.class)
// .eq(WmNewsMaterial::getNewsId, wmNews.getId()));
wmNewsMaterialMapper.delete(Wrappers.lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
//修改文章(更新该WmNews对象中的信息)
this.updateById(wmNews);
}

    //以上不管是修改文章还是新增文章,都要判断下一步是否要保存为草稿.

    //3 判断是否要保存为草稿
    // status状态  草稿为0   提交为1

// if (dto.getStatus()==0)
// if (dto.getStatus().equals(0))
if (dto.getStatus().equals(WmNews.Status.NORMAL.getCode())) {
//是草稿,操作结束,返回结果
return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

    //4 如果不是要保存为草稿,①保存文章内容和素材的关系,②保存文章封面的图片和素材的关系

    //4.1 保存文章内容和图片素材的关系,此时要获取到文章内容content
    // 如果选择文章封面类型为自动,则根据规则展示封面图片.如果不是选择为自动,则需要另外上传图片作为封面内容来展示.
    //   只需要对类型选择为自动的情况下进行业务逻辑处理.
    //type  文章封面类型 0 无图   1 单图   3 多图   -1 自动


    //文章发布页面的内容填写完毕后,当用户点击发布或者保存为草稿时,此时dto会出纳递给控制层,到业务层时,进行一系列处理,将dto数据以及要补全的数据打包为一个json数据对象,然后进行其他的业务逻辑处理,将对应的结果响应在页面中.
    //**************获取文章内容中的图片信息.用于关联保存文章内容和图片素材的关系***************

/*
TODO: 前端将用户发布文章时填写的数据一起封装为一个WmNewsDto对象,然后将该对象传给控制层!
TODO: 此时可通过在controller层打印输出dto的内容等方式,查看此时前端传过来的dto的数据类型:

查看此时WmNewsDto的数据类型,dto中的内容为:(可以看出该对象的content内容的类型和格式!)
小括号中的内容为该对象的所有内容:
WmNewsDto(
    id=null,
    title=一只小猫咪,
    channelId=2,
    labels=小猫,
    publishTime=Sat Jul 01 13:24:33 CST 2023,
    content=[
        {"type":"text","value":"在这只小猫咪前面的内容"},
        {"type":"image","value":"http://192.168.200.128:9000/leadnews/2023/06/29/9b3266e2e86b414d8d732d1b9c914c9e.jpg"},
        {"type":"text","value":"在这只小猫咪后面的内容"},
        {"type":"image","value":"http://192.168.200.128:9000/leadnews/2023/06/29/df3b9b4dbb6542229f8d8b21fb3df935.jpg"},
        {"type":"text","value":"这是正文内容"}
    ],
    type=3,
    submitedTime=null,
    status=1,
    images=[
        http://192.168.200.128:9000/leadnews/2023/06/29/a9eb7a51db1a45ac86355e21e0241a26.jpg,
        http://192.168.200.128:9000/leadnews/2023/06/29/ad75bf803ffe43fcb57190462d747b45.jpg,
        http://192.168.200.128:9000/leadnews/2023/06/29/6f81043f40a340c2bde6e30c43f32ced.jpg
    ]
)

*/

    //创建一个文章内容列表,用于保存从dto中获取的图片素材信息.
    List<String> contentImages = new ArrayList<>();
    //获取dto中的图片内容,用于下面的业务逻辑处理.
    List<String> dtoImages = dto.getImages();

    //4.2 判断内容content是否存在(content是否为空!),只有内容不为空的情况下,才能对文章进行"存入草稿"或者"提交审核"操作.

// String dtoContent = dto.getContent();
if (StringUtils.isNotBlank(dto.getContent())) {
List maps = JSONArray.parseArray(dto.getContent(), Map.class); // 取出所有的键值对,存入Map中.
//遍历解析到的每一个map,取出每一个map中的type为image的value的内容,存入contentImagesList列表中.
for (Map map : maps) {
//{
// "type": "image",
// "value": "http://192.168.200.128:9000/leadnews/2022/05/19/8bbffbb3d336dbac7.jpg"
//}
if (map.get("type").equals("image")) {
contentImages.add(map.get("value").toString());
}
}
} else {
return ResponseResult.errorResult(AppHttpCodeEnum.MATERIAL_CONTENT_ISBLANK);
}

    //4.3 保存文章内容和图片素材的关系
    saveWmNewsMaterial(contentImages, wmNews.getId(), WemediaConstants.WM_CONTENT_REFERENCE);


    //4.4 保存文章封面和图片素材的关系
    //获取文章封面的图片
    //图片封面类型为自动时,此时不需要用户上传任何封面图片,dto里的images=[]或者说dto.getImages(),即dtoImages=[].
    if (dto.getType() == -1) {
        if (contentImages.size() >= 3) {
            //如果内容中的图片数量大于等于3--->三图
            wmNews.setType(WemediaConstants.WM_NEWS_MANY_IMAGE);
            //设置封面的图片
            dtoImages = contentImages.subList(0, 3); //将文章内容里的前三张图片设置为封面图片.

        } else if (contentImages.size() >= 1) {
            //如果内容中的图片数量大于等于1   一图
            wmNews.setType(WemediaConstants.WM_NEWS_SINGLE_IMAGE);
            //images.addAll(contentImages.subList(0, 1));
            dtoImages = Arrays.asList(contentImages.get(0));
        } else {
            //如果其他情况:无图
            wmNews.setType(WemediaConstants.WM_NEWS_NONE_IMAGE);
        }
    }

    //如果选择的封面类型不是自动时,此时需要用户上传封面图片,dto里的images=[?,?,...]或者说dto.getImages(),即dtoImages=[?,?,...].
    //此时可选择为无图,单图或者三图.dtoImages里的图片即为封面图片.


//处理封面图片判断图片是存在的,若存在,将图片的地址(字符串String类型)赋给wmNews对象展示为前端页面的封面图片.
//实体类WmNews中的images里面存放的就是用于展示在封面的图片的url地址,多个url对应多个封面图片.
    if (CollectionUtils.isNotEmpty(dtoImages)) {
    // 把list转为String
    wmNews.setImages(StringUtils.join(dtoImages, ","));
}

    //更新自媒体文章
    this.updateById(wmNews);

    //调用方法保存文章封面图片和素材的关系
    saveWmNewsMaterial(dtoImages, wmNews.getId(), WemediaConstants.WM_COVER_REFERENCE);

    //返回结果
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}




/**
 * 批量保存自媒体文章和素材的关系
 *
 * @param //imageList 图片的地址  用来反查素材id
 * @param //wmNewsId  自媒体文章id
 * @param //type      引用类型 0 内容引用    1 主图引用
 */
private ResponseResult saveWmNewsMaterial(List<String> imageList, Integer wmNewsId, Integer type) {
    //1. 判断集合是否为空
    if (CollectionUtils.isEmpty(imageList)) {
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
    }

    //2. 根据图片的url地址,反查素材的id
    List<Integer> ids = new ArrayList<>();
    for (String url : imageList) {
        Integer id = wmMaterialMapper.selectOne(Wrappers.lambdaQuery(WmMaterial.class)
                .eq(WmMaterial::getUrl, url)).getId();
        ids.add(id);
    }


    //3. 遍历素材id,创建文章素材关系对象的列表,批量保存文章素材关系.
    List<WmNewsMaterial> list = new ArrayList<>();
    for (Integer id : ids) {
        WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
        wmNewsMaterial.setMaterialId(id);//素材id
        wmNewsMaterial.setNewsId(wmNewsId);//文章id
        wmNewsMaterial.setType(type); // 引用类型---> 内容引用/主图引用

        list.add(wmNewsMaterial);
    }
    wmNewsMaterialMapper.saveBatch(list);

    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

}