diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuBatchStatusDTO.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuBatchStatusDTO.java new file mode 100644 index 000000000..e037d8f06 --- /dev/null +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuBatchStatusDTO.java @@ -0,0 +1,27 @@ +package com.bsd.pjcloud.canteen.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * 菜品列表:批量修改上架状态 + */ +@Data +@Schema(description = "批量修改菜品上架状态") +public class CanteenSpuBatchStatusDTO { + + @NotEmpty + @Schema(description = "菜品 SPU ID 列表") + private List ids; + + /** + * 0=上架,1=下架(与 spu_status 字典一致;不含回收 -1) + */ + @NotNull + @Schema(description = "目标状态:0上架 1下架") + private Integer status; +} diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuPriceDTO.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuPriceDTO.java new file mode 100644 index 000000000..0c2b7a86f --- /dev/null +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/dto/CanteenSpuPriceDTO.java @@ -0,0 +1,21 @@ +package com.bsd.pjcloud.canteen.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 仅更新菜品价格(不走 updateDeep,避免清空套餐组成) + */ +@Data +@Schema(description = "更新菜品价格") +public class CanteenSpuPriceDTO { + + @NotNull + @Schema(description = "菜品 SPU ID") + private Long id; + + @NotNull + @Schema(description = "价格(分)") + private Integer price; +} diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/CanteenSpuController.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/CanteenSpuController.java index 2de6f515f..5332e5fab 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/CanteenSpuController.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/CanteenSpuController.java @@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.canteen.constant.StockTypeEnum; import com.bsd.pjcloud.canteen.dto.CanteenDailySpuDTO; import com.bsd.pjcloud.canteen.dto.CanteenSpuBatchPicDTO; +import com.bsd.pjcloud.canteen.dto.CanteenSpuBatchStatusDTO; +import com.bsd.pjcloud.canteen.dto.CanteenSpuPriceDTO; import com.bsd.pjcloud.canteen.dto.CanteenSpuExportQuery; import com.bsd.pjcloud.canteen.dto.CanteenSpuImportExcel; import com.bsd.pjcloud.canteen.dto.CanteenSpuUpdateStockReqDTO; @@ -233,6 +235,48 @@ public class CanteenSpuController { return ok ? R.ok(null, "已更新 " + dto.getIds().size() + " 道菜封面") : R.failed("更新失败"); } + /** + * 批量修改上架状态(0上架 / 1下架) + */ + @Operation(summary = "批量修改菜品上架状态", description = "批量上架或下架") + @SysLog("批量修改菜品上架状态") + @PutMapping("/batchStatus") + @PreAuthorize("@pms.hasPermission('canteen_canteenSpu_edit')") + public R batchStatus(@RequestBody CanteenSpuBatchStatusDTO dto) { + if (CollUtil.isEmpty(dto.getIds())) { + return R.failed("请选择菜品"); + } + Integer status = dto.getStatus(); + if (status == null || (status != 0 && status != 1)) { + return R.failed("状态只能为上架(0)或下架(1)"); + } + boolean ok = canteenSpuService.update(Wrappers.lambdaUpdate() + .set(CanteenSpuEntity::getStatus, status) + .in(CanteenSpuEntity::getId, dto.getIds())); + String label = status == 0 ? "上架" : "下架"; + return ok ? R.ok(null, "已" + label + " " + dto.getIds().size() + " 道菜") : R.failed("更新失败"); + } + + /** + * 仅更新价格,不触碰套餐组成(供每日菜谱「按单品合计」等场景) + */ + @Operation(summary = "更新菜品价格", description = "仅更新价格字段") + @SysLog("更新菜品价格") + @PutMapping("/updatePrice") + @PreAuthorize("@pms.hasPermission('canteen_canteenSpu_edit')") + public R updatePrice(@RequestBody CanteenSpuPriceDTO dto) { + if (dto.getId() == null) { + return R.failed("菜品ID不能为空"); + } + if (dto.getPrice() == null || dto.getPrice() < 0) { + return R.failed("价格无效"); + } + boolean ok = canteenSpuService.update(Wrappers.lambdaUpdate() + .set(CanteenSpuEntity::getPrice, dto.getPrice()) + .eq(CanteenSpuEntity::getId, dto.getId())); + return ok ? R.ok(Boolean.TRUE, "价格已更新") : R.failed("更新失败"); + } + /** * 修改菜品spu * diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/CanteenDailyMenuService.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/CanteenDailyMenuService.java index d6b97a97f..6c5753a16 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/CanteenDailyMenuService.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/CanteenDailyMenuService.java @@ -107,7 +107,8 @@ public interface CanteenDailyMenuService extends IService口径与 hardware {@code listDailyMenuNetSold} 一致:CANTEEN_DAILY_MENU、 + *

口径与 hardware {@code listDailyMenuNetSold} 一致: + * App 每日菜谱 {@code CANTEEN_DAILY_MENU} + 消费机线下 {@code CANTEEN_SPU}/order_type=1; * 已支付/已完成,扣已完成售后;orderType=2→onlineSold,1→offlineSold。 * 当日无对应订单的菜谱行 sold 置 0。 * diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardCarMapper.xml b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardCarMapper.xml index 393434efd..754e60670 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardCarMapper.xml +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardCarMapper.xml @@ -1473,6 +1473,10 @@ 每日菜谱库存剩余:按用餐日 appt_use_date 统计净销量。 线上=order_type 2,线下=order_type 1;扣硬售后 status=50 的份数;不含 XFJ。 先按父购物车+商品汇总购买量,再扣退款,避免多行购物车重复扣退。 + 商品来源: + - App 每日菜谱预约:CANTEEN_DAILY_MENU + - 消费机线下购买:CANTEEN_SPU(createCard 默认来源),实时扣减已按当日菜谱分流到 offline_sold + 若只认 CANTEEN_DAILY_MENU,「按订单重算」会把消费机已售全部刷成 0。 -->