|
|
@@ -2,7 +2,9 @@ package shop.alien.store.controller;
|
|
|
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import io.swagger.annotations.*;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
@@ -17,10 +19,12 @@ import shop.alien.entity.store.dto.CuisineComboDto;
|
|
|
import shop.alien.entity.store.dto.CuisineTypeResponseDto;
|
|
|
import shop.alien.entity.store.dto.TablewareFeeDto;
|
|
|
import shop.alien.entity.store.vo.PriceListVo;
|
|
|
+import shop.alien.mapper.StoreCuisineMapper;
|
|
|
import shop.alien.store.annotation.TrackEvent;
|
|
|
import shop.alien.store.service.StoreCuisineService;
|
|
|
import shop.alien.store.service.StoreInfoService;
|
|
|
import shop.alien.store.service.StorePriceService;
|
|
|
+import shop.alien.store.util.ai.AiContentModerationUtil;
|
|
|
import shop.alien.store.util.ai.AiGetPriceUtil;
|
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
@@ -51,15 +55,142 @@ public class StoreCuisineController {
|
|
|
|
|
|
private final StoreInfoService storeInfoService;
|
|
|
|
|
|
+ private final AiContentModerationUtil aiContentModerationUtil;
|
|
|
+
|
|
|
+ private final StoreCuisineMapper storeCuisineMapper;
|
|
|
+
|
|
|
@ApiOperation("新增美食套餐或单品")
|
|
|
@ApiOperationSupport(order = 1)
|
|
|
@PostMapping("/addCuisineCombo")
|
|
|
public R<StoreCuisine> addCuisineCombo(@RequestBody CuisineComboDto cuisineComboDto) {
|
|
|
- log.info("StoreCuisineController.save?storeCuisine={}", cuisineComboDto);
|
|
|
- if (storeCuisineService.addCuisineCombo(cuisineComboDto)) {
|
|
|
- return R.success("新增成功");
|
|
|
+ log.info("StoreCuisineController.addCuisineCombo?cuisineComboDto={}", cuisineComboDto);
|
|
|
+
|
|
|
+ // 参数验证
|
|
|
+ if (cuisineComboDto == null) {
|
|
|
+ log.error("新增美食套餐或单品失败:参数不能为空");
|
|
|
+ return R.fail("参数不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 保存数据
|
|
|
+ boolean saveResult = storeCuisineService.addCuisineCombo(cuisineComboDto);
|
|
|
+ if (!saveResult) {
|
|
|
+ log.error("新增美食套餐或单品失败:保存操作返回false");
|
|
|
+ return R.fail("新增失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 由于 addCuisineCombo 方法返回的是 boolean,我们需要通过查询获取保存后的记录
|
|
|
+ // 通过 storeId + name + cuisineType + 最新的创建时间 来查询,确保获取到刚保存的记录
|
|
|
+ StoreCuisine savedCuisine = null;
|
|
|
+ if (cuisineComboDto.getStoreId() != null && StringUtils.isNotEmpty(cuisineComboDto.getName())
|
|
|
+ && cuisineComboDto.getCuisineType() != null) {
|
|
|
+ LambdaQueryWrapper<StoreCuisine> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(StoreCuisine::getStoreId, cuisineComboDto.getStoreId())
|
|
|
+ .eq(StoreCuisine::getName, cuisineComboDto.getName())
|
|
|
+ .eq(StoreCuisine::getCuisineType, cuisineComboDto.getCuisineType())
|
|
|
+ .orderByDesc(StoreCuisine::getCreatedTime)
|
|
|
+ .last("LIMIT 1");
|
|
|
+ savedCuisine = storeCuisineService.getOne(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (savedCuisine == null) {
|
|
|
+ log.error("新增美食套餐或单品失败:保存后查询不到数据");
|
|
|
+ return R.fail("新增失败:数据保存异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将状态置为"审核中"(0)
|
|
|
+ LambdaUpdateWrapper<StoreCuisine> auditingWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ auditingWrapper.eq(StoreCuisine::getId, savedCuisine.getId());
|
|
|
+ auditingWrapper.set(StoreCuisine::getStatus, 0);
|
|
|
+ auditingWrapper.set(StoreCuisine::getRejectionReason, null);
|
|
|
+ auditingWrapper.set(StoreCuisine::getAuditTime, new Date());
|
|
|
+ storeCuisineMapper.update(null, auditingWrapper);
|
|
|
+
|
|
|
+ // 组装 AI 审核文本和图片
|
|
|
+ StringBuilder textContent = new StringBuilder();
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getName())) {
|
|
|
+ textContent.append(cuisineComboDto.getName()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getDetailContent())) {
|
|
|
+ textContent.append(cuisineComboDto.getDetailContent()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getDescription())) {
|
|
|
+ textContent.append(cuisineComboDto.getDescription()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getDishReview())) {
|
|
|
+ textContent.append(cuisineComboDto.getDishReview()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getExtraNote())) {
|
|
|
+ textContent.append(cuisineComboDto.getExtraNote()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getReserveRule())) {
|
|
|
+ textContent.append(cuisineComboDto.getReserveRule()).append(" ");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getUsageRule())) {
|
|
|
+ textContent.append(cuisineComboDto.getUsageRule()).append(" ");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> imageUrls = new ArrayList<>();
|
|
|
+
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getImages())) {
|
|
|
+ String[] urls = cuisineComboDto.getImages().split(",");
|
|
|
+ for (String url : urls) {
|
|
|
+ if (StringUtils.isNotEmpty(url.trim())) {
|
|
|
+ String trimmedUrl = url.trim();
|
|
|
+ imageUrls.add(trimmedUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotEmpty(cuisineComboDto.getImageContent())) {
|
|
|
+ String[] urls = cuisineComboDto.getImageContent().split(",");
|
|
|
+ for (String url : urls) {
|
|
|
+ if (StringUtils.isNotEmpty(url.trim())) {
|
|
|
+ String trimmedUrl = url.trim();
|
|
|
+ imageUrls.add(trimmedUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行AI审核
|
|
|
+ if (StringUtils.isNotEmpty(textContent.toString()) || imageUrls.size() > 0) {
|
|
|
+ AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(textContent.toString(), imageUrls);
|
|
|
+ boolean allPassed = (auditResult != null);
|
|
|
+
|
|
|
+ LambdaUpdateWrapper<StoreCuisine> auditUpdateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ auditUpdateWrapper.eq(StoreCuisine::getId, savedCuisine.getId());
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getRejectionReason, null);
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getAuditTime, new Date());
|
|
|
+
|
|
|
+ if (allPassed) {
|
|
|
+ // 审核通过 审核状态为1 上架状态为1 已上架
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getStatus, 1);
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getShelfStatus, 1);
|
|
|
+ log.info("AI审核通过,ID: {}", savedCuisine.getId());
|
|
|
+ } else {
|
|
|
+ // 审核拒绝 审核状态为2 上架状态为0 没有上下架状态
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getStatus, 2);
|
|
|
+ auditUpdateWrapper.set(StoreCuisine::getShelfStatus, 0);
|
|
|
+ log.info("AI审核拒绝,ID: {}", savedCuisine.getId());
|
|
|
+ }
|
|
|
+ storeCuisineMapper.update(null, auditUpdateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新查询一次,返回最新的数据
|
|
|
+ StoreCuisine finalCuisine = storeCuisineService.getById(savedCuisine.getId());
|
|
|
+ if (finalCuisine != null) {
|
|
|
+ log.info("新增成功,返回ID: {}", finalCuisine.getId());
|
|
|
+ return R.data(finalCuisine, "新增成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果查询失败,返回保存后的对象(至少包含ID)
|
|
|
+ log.warn("新增成功但最终查询失败,返回保存后的对象,ID: {}", savedCuisine.getId());
|
|
|
+ return R.data(savedCuisine, "新增成功");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("新增美食套餐或单品异常", e);
|
|
|
+ return R.fail("新增失败:" + e.getMessage());
|
|
|
}
|
|
|
- return R.fail("新增失败");
|
|
|
}
|
|
|
|
|
|
@ApiOperation("修改美食套餐或单品")
|