package com.backendsys.modules.material.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.backendsys.exception.CustException; import com.backendsys.modules.common.config.security.utils.SecurityUtil; import com.backendsys.modules.material.dao.MaterialCategoryDao; import com.backendsys.modules.material.dao.MaterialDao; import com.backendsys.modules.material.dao.MaterialTagDao; import com.backendsys.modules.material.entity.Material; import com.backendsys.modules.material.entity.MaterialCategory; import com.backendsys.modules.material.entity.MaterialTag; import com.backendsys.modules.material.service.MaterialService; import com.backendsys.modules.system.dao.SysUserRolePermissionRelationDao; import com.backendsys.modules.system.dao.SysUserRoleRelationDao; import com.backendsys.modules.system.entity.SysUserRole; import com.backendsys.modules.system.service.SysUserRoleService; import com.backendsys.modules.upload.service.SysFileService; import com.backendsys.modules.upload.utils.ObjectKey.ObjectKeyEntity; import com.backendsys.modules.upload.utils.ObjectKey.ObjectKeyUtil; import com.backendsys.modules.upload.utils.UploadUtil; import com.backendsys.utils.response.PageEntity; import com.backendsys.utils.response.PageInfoResult; import com.backendsys.utils.v2.PageUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @Service public class MaterialServiceImpl implements MaterialService { @Autowired private ObjectKeyUtil objectKeyUtil; @Autowired private MaterialDao materialDao; @Autowired private MaterialTagDao materialTagDao; @Autowired private MaterialCategoryDao materialCategoryDao; @Autowired private SysFileService sysFileService; @Autowired private SysUserRoleService sysUserRoleService; @Autowired private SysUserRoleRelationDao sysUserRoleRelationDao; @Autowired private SysUserRolePermissionRelationDao sysUserRolePermissionRelationDao; private List getMaterialTagByIds(String tag_ids) { if (StrUtil.isEmpty(tag_ids)) return null; LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(MaterialTag::getId, tag_ids.split(",")); wrapper.orderByDesc(MaterialTag::getSort); return materialTagDao.selectList(wrapper); } /** * 获取素材列表 */ @Override public PageEntity selectMaterialList(Material material) { PageUtils.startPage(); // 分页 List> list = materialDao.selectMaterialList(material); // 1) 完成分页实体渲染 PageEntity pageEntity = new PageInfoResult(list).toEntity(); if (!list.isEmpty()) { // 2) 分页列表格式化 list = list.stream().map(item -> { // 新增字段:标签列表 String tag_ids = Convert.toStr(item.get("tag_ids")); List materialTagList = getMaterialTagByIds(tag_ids); item.put("tag_list", materialTagList); return item; }).collect(Collectors.toList()); // 3) 分页实体重新赋值 List objectList = list.stream().map(item -> (Object) item).collect(Collectors.toList()); pageEntity.setList(objectList); } return pageEntity; } /** * 获取素材详情 */ @Override public Material selectMaterialDetail(Material material) { Material detail = materialDao.selectMaterialDetail(material); if (detail == null) throw new CustException("素材不存在"); // [新增字段] 标签列表 List materialTagList = getMaterialTagByIds(detail.getTag_ids()); detail.setTag_list(materialTagList); // 权限控制: // [DB] 获得当前用户的角色关系(集合) List userRoleIds = sysUserRoleRelationDao.selectUserRoleIds(SecurityUtil.getUserId()); // - ('20.1.5', '20.1', '下载素材', null) List rolePermissionIds = new ArrayList<>(); if (userRoleIds.size() > 0) { // [DB] 获得当前用户角色的权限 (集合) rolePermissionIds = sysUserRolePermissionRelationDao.selectUserRolePermissionIdsByRoleIds(userRoleIds); rolePermissionIds = rolePermissionIds.stream().distinct().collect(Collectors.toList()); } // 判断是否具备权限 if (!rolePermissionIds.contains("20.1.5")) { detail.setFile_url("Unauthorized"); detail.setPan_baidu_url("Unauthorized"); } return detail; } /** * 创建素材 */ @Override @Transactional(rollbackFor = Exception.class) public Map insertMaterial(Material material) { MaterialCategory materialCategory = materialCategoryDao.selectById(material.getCategory_id()); if (materialCategory == null) throw new CustException("素材分类不存在"); // [Filter] tag_id 过滤掉空值和 0 String cleaned = Optional.ofNullable(material.getTag_ids()) .orElse("") .replaceAll("\\b0\\b,?", "") .replaceAll(",{2,}", ",") .replaceAll("^,|,$", ""); material.setTag_ids(cleaned); // 生成缩略图,并填充缩略图地址 if (StrUtil.isNotEmpty(material.getImage_url())) { ObjectKeyEntity objectKeyEntity = objectKeyUtil.urlToObjectKey(material.getImage_url()); if (objectKeyEntity != null) { String image_thumb_url = UploadUtil.getImageThumbUrl(material.getImage_url(), objectKeyEntity.getTarget(), 276, 155); material.setImage_thumb_url(image_thumb_url); } } materialDao.insertMaterial(material); return Map.of("material_id", material.getMaterial_id()); } /** * 编辑素材 */ @Override @Transactional(rollbackFor = Exception.class) public Map updateMaterial(Material material) { Material detail = materialDao.selectById(material.getMaterial_id()); if (detail == null) throw new CustException("素材不存在"); if (material.getCategory_id() != null) { MaterialCategory materialCategory = materialCategoryDao.selectById(material.getCategory_id()); if (materialCategory == null) throw new CustException("素材分类不存在"); } // [Filter] tag_id 过滤掉空值和 0 String cleaned = Optional.ofNullable(material.getTag_ids()) .orElse("") .replaceAll("\\b0\\b,?", "") .replaceAll(",{2,}", ",") .replaceAll("^,|,$", ""); material.setTag_ids(cleaned); // 编辑的时候,如果素材图片有修改,需要删除之前的图片 // 生成缩略图,并填充缩略图地址 if (StrUtil.isNotEmpty(material.getImage_url())) { ObjectKeyEntity objectKeyEntity = objectKeyUtil.urlToObjectKey(material.getImage_url()); if (objectKeyEntity != null) { String image_thumb_url = UploadUtil.getImageThumbUrl(material.getImage_url(), objectKeyEntity.getTarget(), 276, 155); material.setImage_thumb_url(image_thumb_url); } } materialDao.updateMaterial(material); return Map.of("material_id", material.getMaterial_id()); }; /** * 删除素材 */ @Override @Transactional(rollbackFor = Exception.class) public Map deleteMaterial(Material material) { Material detail = materialDao.selectById(material.getMaterial_id()); if (detail == null) throw new CustException("素材不存在"); // 删除的时候,同时删除对象存储中的素材图片 (异步) ObjectKeyEntity image_url_object = objectKeyUtil.urlToObjectKey(detail.getImage_url()); ObjectKeyEntity file_url_object = objectKeyUtil.urlToObjectKey(detail.getFile_url()); CompletableFuture.runAsync(() -> { sysFileService.deleteObject(image_url_object.getObject_key(), image_url_object.getTarget()); sysFileService.deleteObject(file_url_object.getObject_key(), file_url_object.getTarget()); }); materialDao.deleteMaterial(material); return Map.of("material_id", material.getMaterial_id()); } }