feat(basic): 新增AI微单类型支持

- 在SourceType枚举中新增AI_CAM类型及其判断方法
- 在ProductType枚举中新增AI_CAM_PHOTO_SET类型
- 扩展SourceMapper接口及XML实现删除指定faceId和type的关联记录功能
- 更新AppAiCamServiceImpl服务逻辑,在添加新关联前先删除旧记录
- 修改GoodsServiceImpl以识别并处理AI微单类型的商品名称前缀
- 在FaceServiceImpl中增加对AI微单内容的查询与展示逻辑
- 优化face相关素材分类展示,确保AI微单正确归类显示
This commit is contained in:
2025-12-05 19:58:53 +08:00
parent 1f4a16f0e6
commit 125fadd6c5
7 changed files with 71 additions and 3 deletions

View File

@@ -16,7 +16,12 @@ public enum SourceType {
/** /**
* 图片类型 * 图片类型
*/ */
IMAGE(2, "图片"); IMAGE(2, "图片"),
/**
* AI微单类型
*/
AI_CAM(3, "AI微单");
private final int code; private final int code;
private final String description; private final String description;
@@ -68,4 +73,14 @@ public enum SourceType {
public static boolean isImage(Integer code) { public static boolean isImage(Integer code) {
return code != null && code == IMAGE.code; return code != null && code == IMAGE.code;
} }
/**
* 判断给定的代码是否为AI微单类型
*
* @param code 类型代码
* @return true-是AI微单,false-不是AI微单
*/
public static boolean isAiCam(Integer code) {
return code != null && code == AI_CAM.code;
}
} }

View File

@@ -156,4 +156,12 @@ public interface SourceMapper {
* @return source实体列表 * @return source实体列表
*/ */
List<SourceEntity> listByFaceSampleIdsAndType(List<Long> faceSampleIds, Integer type); List<SourceEntity> listByFaceSampleIdsAndType(List<Long> faceSampleIds, Integer type);
/**
* 删除指定faceId和type的member_source关联记录
* @param faceId 人脸ID
* @param type 素材类型
* @return 删除的记录数
*/
int deleteRelationsByFaceIdAndType(Long faceId, Integer type);
} }

View File

@@ -17,6 +17,7 @@ public enum ProductType {
// 照片类 // 照片类
PHOTO("PHOTO", "照片", ProductCategory.PHOTO), PHOTO("PHOTO", "照片", ProductCategory.PHOTO),
PHOTO_SET("PHOTO_SET", "照片集", ProductCategory.PHOTO), PHOTO_SET("PHOTO_SET", "照片集", ProductCategory.PHOTO),
AI_CAM_PHOTO_SET("AI_CAM_PHOTO_SET", "照片集", ProductCategory.PHOTO),
PHOTO_LOG("PHOTO_LOG", "pLog图", ProductCategory.PHOTO), PHOTO_LOG("PHOTO_LOG", "pLog图", ProductCategory.PHOTO),
// 视频类(素材视频) // 视频类(素材视频)

View File

@@ -183,6 +183,10 @@ public class AppAiCamServiceImpl implements AppAiCamService {
throw new IllegalArgumentException("Face未关联会员: faceId=" + faceId); throw new IllegalArgumentException("Face未关联会员: faceId=" + faceId);
} }
// 删除该faceId对应的旧的type=3关系
int deleted = sourceMapper.deleteRelationsByFaceIdAndType(faceId, AI_CAM_SOURCE_TYPE);
log.info("删除faceId={}的旧AI相机关联记录: {}条", faceId, deleted);
// 构建MemberSourceEntity列表 // 构建MemberSourceEntity列表
List<MemberSourceEntity> relations = sourceIds.stream().map(sourceId -> { List<MemberSourceEntity> relations = sourceIds.stream().map(sourceId -> {
MemberSourceEntity entity = new MemberSourceEntity(); MemberSourceEntity entity = new MemberSourceEntity();
@@ -197,6 +201,9 @@ public class AppAiCamServiceImpl implements AppAiCamService {
}).collect(Collectors.toList()); }).collect(Collectors.toList());
// 批量插入 // 批量插入
return sourceMapper.addRelations(relations); int inserted = sourceMapper.addRelations(relations);
log.info("为faceId={}添加新AI相机关联记录: {}条", faceId, inserted);
return inserted;
} }
} }

View File

@@ -127,6 +127,8 @@ public class GoodsServiceImpl implements GoodsService {
goodsNamePrefix = "录像"; goodsNamePrefix = "录像";
} else if (sourceType == 2) { } else if (sourceType == 2) {
goodsNamePrefix = "图片"; goodsNamePrefix = "图片";
} else if (sourceType == 3) {
goodsNamePrefix = "微单";
} else { } else {
goodsNamePrefix = "其他类型"; goodsNamePrefix = "其他类型";
} }

View File

@@ -536,20 +536,28 @@ public class FaceServiceImpl implements FaceService {
List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery); List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery);
ContentPageVO sourceVideoContent = new ContentPageVO(); ContentPageVO sourceVideoContent = new ContentPageVO();
ContentPageVO sourceImageContent = new ContentPageVO(); ContentPageVO sourceImageContent = new ContentPageVO();
ContentPageVO sourceAiCamContent = new ContentPageVO();
sourceVideoContent.setName("录像集"); sourceVideoContent.setName("录像集");
sourceImageContent.setName("照片集"); sourceImageContent.setName("照片集");
sourceAiCamContent.setName("AI微单");
sourceVideoContent.setSort(9999); sourceVideoContent.setSort(9999);
sourceImageContent.setSort(9999); sourceImageContent.setSort(9999);
sourceAiCamContent.setSort(9999);
sourceVideoContent.setScenicId(face.getScenicId()); sourceVideoContent.setScenicId(face.getScenicId());
sourceImageContent.setScenicId(face.getScenicId()); sourceImageContent.setScenicId(face.getScenicId());
sourceAiCamContent.setScenicId(face.getScenicId());
sourceVideoContent.setGoodsType(1); sourceVideoContent.setGoodsType(1);
sourceImageContent.setGoodsType(2); sourceImageContent.setGoodsType(2);
sourceAiCamContent.setGoodsType(3);
sourceVideoContent.setContentType(2); sourceVideoContent.setContentType(2);
sourceImageContent.setContentType(2); sourceImageContent.setContentType(2);
sourceAiCamContent.setContentType(2);
sourceVideoContent.setLockType(-1); sourceVideoContent.setLockType(-1);
sourceImageContent.setLockType(-1); sourceImageContent.setLockType(-1);
sourceAiCamContent.setLockType(-1);
sourceVideoContent.setGroup("直出原片"); sourceVideoContent.setGroup("直出原片");
sourceImageContent.setGroup("直出原片"); sourceImageContent.setGroup("直出原片");
sourceAiCamContent.setGroup("直出原片");
if (!scenicConfigFacade.isDisableSourceImage(face.getScenicId())) { if (!scenicConfigFacade.isDisableSourceImage(face.getScenicId())) {
IsBuyRespVO isBuyRespVO = orderBiz.isBuy(face.getScenicId(), userId, faceId, SourceType.IMAGE.getCode(), faceId); IsBuyRespVO isBuyRespVO = orderBiz.isBuy(face.getScenicId(), userId, faceId, SourceType.IMAGE.getCode(), faceId);
sourceImageContent.setSourceType(isBuyRespVO.getGoodsType()); sourceImageContent.setSourceType(isBuyRespVO.getGoodsType());
@@ -588,18 +596,40 @@ public class FaceServiceImpl implements FaceService {
sourceVideoContent.setFreeCount((int) freeCount); sourceVideoContent.setFreeCount((int) freeCount);
contentList.add(sourceVideoContent); contentList.add(sourceVideoContent);
} }
// AI微单:只有存在type=3的数据时才添加
boolean hasAiCam = sourceList.stream().anyMatch(source -> source.getType() == 3);
if (hasAiCam) {
IsBuyRespVO isBuyRespVO = orderBiz.isBuy(face.getScenicId(), userId, faceId, SourceType.AI_CAM.getCode(), faceId);
sourceAiCamContent.setSourceType(isBuyRespVO.getGoodsType());
sourceAiCamContent.setContentId(isBuyRespVO.getGoodsId());
if (isBuyRespVO.isBuy()) {
sourceAiCamContent.setIsBuy(1);
} else {
sourceAiCamContent.setIsBuy(0);
}
// AI微单有数据才显示,所以lockType固定为-1
sourceAiCamContent.setLockType(-1);
List<MemberSourceEntity> relations = memberRelationRepository.listSourceByFaceRelation(faceId, 3);
long freeCount = relations.stream().filter(entity -> Integer.valueOf(1).equals(entity.getIsFree())).count();
sourceAiCamContent.setFreeCount((int) freeCount);
contentList.add(sourceAiCamContent);
}
sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).forEach((type, list) -> { sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).forEach((type, list) -> {
if (type == 1) { if (type == 1) {
sourceVideoContent.setSourceType(1); sourceVideoContent.setSourceType(1);
sourceVideoContent.setLockType(-1); sourceVideoContent.setLockType(-1);
sourceVideoContent.setTemplateCoverUrl(list.getFirst().getUrl()); sourceVideoContent.setTemplateCoverUrl(list.getFirst().getUrl());
} else { } else if (type == 2) {
sourceImageContent.setSourceType(2); sourceImageContent.setSourceType(2);
sourceImageContent.setLockType(-1); sourceImageContent.setLockType(-1);
sourceImageContent.setTemplateCoverUrl(list.getFirst().getUrl()); sourceImageContent.setTemplateCoverUrl(list.getFirst().getUrl());
if (StringUtils.isBlank(sourceVideoContent.getTemplateCoverUrl())) { if (StringUtils.isBlank(sourceVideoContent.getTemplateCoverUrl())) {
sourceVideoContent.setTemplateCoverUrl(list.getFirst().getUrl()); sourceVideoContent.setTemplateCoverUrl(list.getFirst().getUrl());
} }
} else if (type == 3) {
sourceAiCamContent.setSourceType(13);
sourceAiCamContent.setLockType(-1);
sourceAiCamContent.setTemplateCoverUrl(list.getFirst().getUrl());
} }
}); });
return contentList; return contentList;

View File

@@ -496,4 +496,9 @@
AND `type` = #{type} AND `type` = #{type}
ORDER BY create_time DESC ORDER BY create_time DESC
</select> </select>
<delete id="deleteRelationsByFaceIdAndType">
DELETE FROM member_source
WHERE face_id = #{faceId} AND `type` = #{type}
</delete>
</mapper> </mapper>