From 81f46a161dcb4991512b3b22f2511b0c757e30d8 Mon Sep 17 00:00:00 2001 From: zhangji <1315410739@qq.com> Date: Mon, 14 Jul 2025 09:11:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E8=B4=A7=E6=9F=9C=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/sku/dto/ProductSkuRespDTO.java | 9 + .../api/spu/dto/ProductSpuRespDTO.java | 13 + .../product/enums/ErrorCodeConstants.java | 3 + .../admin/device/DeviceController.java | 95 ++++++++ .../admin/device/vo/DevicePageReqVO.java | 34 +++ .../admin/device/vo/DeviceRespVO.java | 39 +++ .../admin/device/vo/DeviceSaveReqVO.java | 29 +++ .../admin/spu/ProductSpuController.java | 1 + .../admin/spu/vo/ProductSkuRespVO.java | 6 + .../admin/spu/vo/ProductSkuSaveReqVO.java | 6 + .../app/spu/AppProductSpuController.java | 26 ++ .../app/spu/vo/AppProductSpuPageReqVO.java | 6 + .../dal/dataobject/device/DeviceDO.java | 47 ++++ .../dal/dataobject/sku/ProductSkuDO.java | 9 + .../dal/mysql/device/DeviceMapper.java | 30 +++ .../dal/mysql/spu/ProductSpuMapper.java | 10 + .../product/service/device/DeviceService.java | 55 +++++ .../service/device/DeviceServiceImpl.java | 74 ++++++ .../service/spu/ProductSpuService.java | 2 + .../service/spu/ProductSpuServiceImpl.java | 15 ++ .../trade/enums/ErrorCodeConstants.java | 1 + .../app/order/AppTradeOrderController.http | 11 + .../service/order/bo/DispenseRequestBo.java | 26 ++ .../service/order/bo/DispenseResponseBo.java | 13 + .../handler/TradeDeviceOrderHandler.java | 230 ++++++++++++++++++ .../module/system/api/user/AdminUserApi.java | 1 + .../system/api/user/dto/AdminUserRespDTO.java | 4 + .../system/api/user/AdminUserApiImpl.java | 6 + .../admin/user/vo/user/UserImportExcelVO.java | 4 + .../admin/user/vo/user/UserRespVO.java | 4 + .../admin/user/vo/user/UserSaveReqVO.java | 4 + .../dal/dataobject/user/AdminUserDO.java | 5 + .../dal/mysql/user/AdminUserMapper.java | 3 + .../system/service/user/AdminUserService.java | 1 + .../service/user/AdminUserServiceImpl.java | 5 + .../src/main/resources/application-local.yaml | 4 +- .../src/main/resources/application-prod.yaml | 10 +- .../src/main/resources/application.yaml | 11 +- 38 files changed, 842 insertions(+), 10 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/DeviceController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DevicePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceSaveReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/device/DeviceDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/device/DeviceMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseRequestBo.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseResponseBo.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeDeviceOrderHandler.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index 338c4dd..5b515b0 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -51,6 +51,15 @@ public class ProductSkuRespDTO { * 库存 */ private Integer stock; + + /** + * 货道或柜门编号 + */ + private String cabinetChannel; + /** + * 通道类型 + */ + private String cabinetType; /** * 商品重量,单位:kg 千克 */ diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java index 60fb0bc..51f61ea 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.api.spu.dto; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTypesEnum; import lombok.Data; import java.util.List; @@ -42,6 +43,18 @@ public class ProductSpuRespDTO { */ private Integer status; + /** + * 商品类型 + * + * 枚举 {@link ProductSpuTypesEnum} + */ + private Integer types; + + /** + * 商品创建者 + */ + private String creator; + // ========== SKU 相关字段 ========= /** diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 3531b14..a81e0ce 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -53,4 +53,7 @@ public interface ErrorCodeConstants { ErrorCode FAVORITE_EXISTS = new ErrorCode(1_008_008_000, "该商品已经被收藏"); ErrorCode FAVORITE_NOT_EXISTS = new ErrorCode(1_008_008_001, "商品收藏不存在"); + // ========== 贩卖机信息 1-008-009-000 ========== + ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_008_009_000, "贩卖机信息不存在"); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/DeviceController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/DeviceController.java new file mode 100644 index 0000000..f86b7b9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/DeviceController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.product.controller.admin.device; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.product.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.module.product.service.device.DeviceService; + +@Tag(name = "管理后台 - 贩卖机信息") +@RestController +@RequestMapping("/product/device") +@Validated +public class DeviceController { + + @Resource + private DeviceService deviceService; + + @PostMapping("/create") + @Operation(summary = "创建贩卖机信息") + @PreAuthorize("@ss.hasPermission('product:device:create')") + public CommonResult createDevice(@Valid @RequestBody DeviceSaveReqVO createReqVO) { + return success(deviceService.createDevice(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新贩卖机信息") + @PreAuthorize("@ss.hasPermission('product:device:update')") + public CommonResult updateDevice(@Valid @RequestBody DeviceSaveReqVO updateReqVO) { + deviceService.updateDevice(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除贩卖机信息") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('product:device:delete')") + public CommonResult deleteDevice(@RequestParam("id") Long id) { + deviceService.deleteDevice(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得贩卖机信息") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:device:query')") + public CommonResult getDevice(@RequestParam("id") Long id) { + DeviceDO device = deviceService.getDevice(id); + return success(BeanUtils.toBean(device, DeviceRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得贩卖机信息分页") + @PreAuthorize("@ss.hasPermission('product:device:query')") + public CommonResult> getDevicePage(@Valid DevicePageReqVO pageReqVO) { + PageResult pageResult = deviceService.getDevicePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, DeviceRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出贩卖机信息 Excel") + @PreAuthorize("@ss.hasPermission('product:device:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportDeviceExcel(@Valid DevicePageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = deviceService.getDevicePage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "贩卖机信息.xls", "数据", DeviceRespVO.class, + BeanUtils.toBean(list, DeviceRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DevicePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DevicePageReqVO.java new file mode 100644 index 0000000..be92acf --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DevicePageReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.controller.admin.device.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 贩卖机信息分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DevicePageReqVO extends PageParam { + + @Schema(description = "设备名称", example = "王五") + private String name; + + @Schema(description = "设备IMEI", example = "371") + private String deviceId; + + @Schema(description = "访问商品地址", example = "https://www.iocoder.cn") + private String productUrl; + + @Schema(description = "文件地址", example = "https://www.iocoder.cn") + private String fileUrl; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceRespVO.java new file mode 100644 index 0000000..8b1e15e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.product.controller.admin.device.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 贩卖机信息 Response VO") +@Data +@ExcelIgnoreUnannotated +public class DeviceRespVO { + + @Schema(description = "表编号,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "25232") + @ExcelProperty("表编号,自增") + private Long id; + + @Schema(description = "设备名称", example = "王五") + @ExcelProperty("设备名称") + private String name; + + @Schema(description = "设备IMEI", requiredMode = Schema.RequiredMode.REQUIRED, example = "371") + @ExcelProperty("设备IMEI") + private String deviceId; + + @Schema(description = "访问商品地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") + @ExcelProperty("访问商品地址") + private String productUrl; + + @Schema(description = "文件地址", example = "https://www.iocoder.cn") + @ExcelProperty("文件地址") + private String fileUrl; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceSaveReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceSaveReqVO.java new file mode 100644 index 0000000..38848c5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/device/vo/DeviceSaveReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.admin.device.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 贩卖机信息新增/修改 Request VO") +@Data +public class DeviceSaveReqVO { + + @Schema(description = "表编号,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "25232") + private Long id; + + @Schema(description = "设备名称", example = "王五") + private String name; + + @Schema(description = "设备IMEI", requiredMode = Schema.RequiredMode.REQUIRED, example = "371") + @NotEmpty(message = "设备IMEI不能为空") + private String deviceId; + + @Schema(description = "访问商品地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") + @NotEmpty(message = "访问商品地址不能为空") + private String productUrl; + + @Schema(description = "文件地址", example = "https://www.iocoder.cn") + private String fileUrl; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index b6dd025..5d44b8f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -91,6 +91,7 @@ public class ProductSpuController { return success(ProductSpuConvert.INSTANCE.convert(spu, skus)); } + @GetMapping("/list-all-simple") @Operation(summary = "获得商品 SPU 精简列表") @PreAuthorize("@ss.hasPermission('product:spu:query')") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java index f977d33..5c7c713 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java @@ -45,6 +45,12 @@ public class ProductSkuRespVO { @Schema(description = "二级分销的佣金,单位:分", example = "19") private Integer secondBrokeragePrice; + @Schema(description = "货道或柜门编号", example = "1") + private String cabinetChannel; + + @Schema(description = "通道类型", example = "1") + private String cabinetType; + @Schema(description = "属性数组") private List properties; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java index 6aa703b..be5665e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java @@ -50,6 +50,12 @@ public class ProductSkuSaveReqVO { @Schema(description = "二级分销的佣金,单位:分", example = "19") private Integer secondBrokeragePrice; + @Schema(description = "货道或柜门编号", example = "1") + private String cabinetChannel; + + @Schema(description = "通道类型", example = "1") + private String cabinetType; + @Schema(description = "属性数组") private List properties; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index b09cfda..2a80982 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuSimpleRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuRespVO; @@ -13,9 +14,12 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -48,6 +52,28 @@ public class AppProductSpuController { @Resource private ProductBrowseHistoryService productBrowseHistoryService; + @Resource + private AdminUserApi adminUserApi; + + + @GetMapping("/get-spu-url") + @Operation(summary = "获取商品请求地址") + @Parameter(name = "deviceId", description = "设备IMEI", required = true) + @PermitAll + public String getUrl(String deviceId) { + //查询用户表 + AdminUserRespDTO user = adminUserApi.getUserByDeviceid(Long.valueOf(deviceId)); + return "/app-api/product/spu/list-all?"+user.getId(); + } + + @GetMapping("/list-all") + @Operation(summary = "获取商品列表") + @PreAuthorize("@ss.hasPermission('product:spu:query')") + public CommonResult> getSpuList(String creator) { + List list = productSpuService.getSpuListByCreator(creator); + return success(BeanUtils.toBean(list, AppProductSpuRespVO.class)); + } + @GetMapping("/list-by-ids") @Operation(summary = "获得商品 SPU 列表") @Parameter(name = "ids", description = "编号列表", required = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java index d16c330..12eb02f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java @@ -27,6 +27,12 @@ public class AppProductSpuPageReqVO extends PageParam { @Schema(description = "创建人id", example = "1") private String creator; + /** + * 设备IMEI + */ + @Schema(description = "设备IMEI", example = "123456") + private String deviceId; + @Schema(description = "商品类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer types; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/device/DeviceDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/device/DeviceDO.java new file mode 100644 index 0000000..7baabb3 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/device/DeviceDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.device; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 贩卖机信息 DO + * + * @author 小如之家 + */ +@TableName("product_device") +@KeySequence("product_device_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceDO extends BaseDO { + + /** + * 表编号,自增 + */ + @TableId + private Long id; + /** + * 设备名称 + */ + private String name; + /** + * 设备IMEI + */ + private String deviceId; + /** + * 访问商品地址 + */ + private String productUrl; + /** + * 文件地址 + */ + private String fileUrl; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 267756a..4940198 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -94,6 +94,15 @@ public class ProductSkuDO extends BaseDO { */ private Integer salesCount; + /** + * 货道或柜门编号 + */ + private String cabinetChannel; + /** + * 通道类型 + */ + private String cabinetType; + /** * 商品属性 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/device/DeviceMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/device/DeviceMapper.java new file mode 100644 index 0000000..43215f4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/device/DeviceMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.dal.mysql.device; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.product.dal.dataobject.device.DeviceDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.product.controller.admin.device.vo.*; + +/** + * 贩卖机信息 Mapper + * + * @author 小如之家 + */ +@Mapper +public interface DeviceMapper extends BaseMapperX { + + default PageResult selectPage(DevicePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(DeviceDO::getName, reqVO.getName()) + .eqIfPresent(DeviceDO::getDeviceId, reqVO.getDeviceId()) + .eqIfPresent(DeviceDO::getProductUrl, reqVO.getProductUrl()) + .eqIfPresent(DeviceDO::getFileUrl, reqVO.getFileUrl()) + .betweenIfPresent(DeviceDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(DeviceDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index c9b3028..185826e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -17,6 +17,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import org.apache.ibatis.annotations.Mapper; import org.apache.poi.ss.formula.functions.T; +import java.util.List; import java.util.Objects; import java.util.Set; @@ -204,4 +205,13 @@ public interface ProductSpuMapper extends BaseMapperX { query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } } + + default List getSpuListByCreator(String creator){ + LambdaQueryWrapperX query = new LambdaQueryWrapperX() + //根据创建人查询商品 + .eqIfPresent(ProductSpuDO::getCreator, creator); + // 上架状态 且有库存 + query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); + return selectList(query); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceService.java new file mode 100644 index 0000000..1ff3e79 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.product.service.device; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.product.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 贩卖机信息 Service 接口 + * + * @author 小如之家 + */ +public interface DeviceService { + + /** + * 创建贩卖机信息 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDevice(@Valid DeviceSaveReqVO createReqVO); + + /** + * 更新贩卖机信息 + * + * @param updateReqVO 更新信息 + */ + void updateDevice(@Valid DeviceSaveReqVO updateReqVO); + + /** + * 删除贩卖机信息 + * + * @param id 编号 + */ + void deleteDevice(Long id); + + /** + * 获得贩卖机信息 + * + * @param id 编号 + * @return 贩卖机信息 + */ + DeviceDO getDevice(Long id); + + /** + * 获得贩卖机信息分页 + * + * @param pageReqVO 分页查询 + * @return 贩卖机信息分页 + */ + PageResult getDevicePage(DevicePageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceServiceImpl.java new file mode 100644 index 0000000..96de46d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/device/DeviceServiceImpl.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.product.service.device; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.product.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.product.dal.mysql.device.DeviceMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 贩卖机信息 Service 实现类 + * + * @author 小如之家 + */ +@Service +@Validated +public class DeviceServiceImpl implements DeviceService { + + @Resource + private DeviceMapper deviceMapper; + + @Override + public Long createDevice(DeviceSaveReqVO createReqVO) { + // 插入 + DeviceDO device = BeanUtils.toBean(createReqVO, DeviceDO.class); + deviceMapper.insert(device); + // 返回 + return device.getId(); + } + + @Override + public void updateDevice(DeviceSaveReqVO updateReqVO) { + // 校验存在 + validateDeviceExists(updateReqVO.getId()); + // 更新 + DeviceDO updateObj = BeanUtils.toBean(updateReqVO, DeviceDO.class); + deviceMapper.updateById(updateObj); + } + + @Override + public void deleteDevice(Long id) { + // 校验存在 + validateDeviceExists(id); + // 删除 + deviceMapper.deleteById(id); + } + + private void validateDeviceExists(Long id) { + if (deviceMapper.selectById(id) == null) { + throw exception(DEVICE_NOT_EXISTS); + } + } + + @Override + public DeviceDO getDevice(Long id) { + return deviceMapper.selectById(id); + } + + @Override + public PageResult getDevicePage(DevicePageReqVO pageReqVO) { + return deviceMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 55070e0..fc06a98 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -145,4 +145,6 @@ public interface ProductSpuService { void updateBrowseCount(Long id, int incrCount); PageResult getSpuPageWithCreator(ProductSpuPageReqVO pageVO); + + List getSpuListByCreator(String creator); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index e8ae9e1..20e7103 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -20,6 +20,8 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.google.common.collect.Maps; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -54,6 +56,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Resource private ProductCategoryService categoryService; + @Resource + private AdminUserApi adminUserApi; + @Override @Transactional(rollbackFor = Exception.class) public Long createSpu(ProductSpuSaveReqVO createReqVO) { @@ -163,6 +168,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { return productSpuMapper.selectPageWithCreator(pageVO); } + @Override + public List getSpuListByCreator(String creator) { + return productSpuMapper.getSpuListByCreator(creator); + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteSpu(Long id) { @@ -231,6 +241,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { .setStatus(CommonStatusEnum.ENABLE.getStatus()).setParentIds(pageReqVO.getCategoryIds())); categoryIds.addAll(convertList(categoryChildren, ProductCategoryDO::getId)); } + if (null!=pageReqVO.getDeviceId()){ + //查询用户 + AdminUserRespDTO user = adminUserApi.getUserByDeviceid(Long.valueOf(pageReqVO.getDeviceId())); + pageReqVO.setCreator(user.getId().toString()); + } // 分页查询 return productSpuMapper.selectPage(pageReqVO, categoryIds); } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 1e65aec..fce0bd3 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -38,6 +38,7 @@ public interface ErrorCodeConstants { ErrorCode ORDER_CANCEL_PAID_FAIL = new ErrorCode(1_011_000_033, "交易订单取消支付失败,原因:订单不是【{}】状态"); ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_034, "交易订单自提失败,原因:你没有核销该门店订单的权限"); ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_035, "交易订单创建失败,原因:用户积分不足"); + ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_OVERPAY = new ErrorCode(1_011_000_036, "提货柜订单完成失败,订单不是【已支付】状态"); // ========== After Sale 模块 1-011-000-100 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http index f51ddff..6881a1e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -48,6 +48,17 @@ tenant-id: {{appTenantId}} "receiverMobile": "15601691300" } +### /trade-order/update-paid 更新订单为已支付 +POST {{appApi}}/trade/order/update-paid +Content-Type: application/json +Authorization: Bearer {{appToken}} +tenant-id: {{appTenantId}} + +{ + "merchantOrderId": "241", + "payOrderId": 20 +} + ### 获得订单交易的分页 GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 Authorization: Bearer {{appToken}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseRequestBo.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseRequestBo.java new file mode 100644 index 0000000..7bd7f5b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseRequestBo.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.trade.service.order.bo; + +import lombok.Data; + +/** + * 货道机发货请求 + */ +@Data +public class DispenseRequestBo { + //设备IMEI + private String deviceId; + + //参数格式:T,C&N,C&N,C&N + // T:通道类型(1:货道,2:货道带调货检测:0x30:柜门:0x31:柜门带反馈) + // C:货道或柜门编号,多个货道同时出货逗号分隔 =(1--80)指定货道出货 + // N:出货数量 + private String message; + + public DispenseRequestBo(String deviceId, String message) { + this.deviceId = deviceId; + this.message = message; + } + + public DispenseRequestBo() { + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseResponseBo.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseResponseBo.java new file mode 100644 index 0000000..4ab9f14 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/DispenseResponseBo.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.trade.service.order.bo; + +import lombok.Data; + +/** + * 货道机发货请求 + */ +@Data +public class DispenseResponseBo { + private int code; + private String msg; + private String data; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeDeviceOrderHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeDeviceOrderHandler.java new file mode 100644 index 0000000..eceb078 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeDeviceOrderHandler.java @@ -0,0 +1,230 @@ +package cn.iocoder.yudao.module.trade.service.order.handler; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTypesEnum; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; +import cn.iocoder.yudao.module.trade.service.order.bo.DispenseRequestBo; +import cn.iocoder.yudao.module.trade.service.order.bo.DispenseResponseBo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_RECEIVE_FAIL_STATUS_NOT_OVERPAY; + +/** + * 优惠劵的 {@link TradeOrderHandler} 实现类 + * + * @author 芋道源码 + */ +@Component +@Slf4j +public class TradeDeviceOrderHandler implements TradeOrderHandler { + + @Resource + @Lazy // 延迟加载,避免循环依赖 + private TradeOrderUpdateService orderUpdateService; + @Resource + private TradeOrderQueryService orderQueryService; + + @Resource + private ProductSpuApi productSpuApi; + + @Resource + private ProductSkuApi productSkuApi; + + @Resource + private AdminUserApi adminUserApi; + + @Resource + private TradeOrderMapper tradeOrderMapper; + + // TOKEN + @Value("${xr.cabinet.token}") + private String token; + + //API_URL + @Value("${xr.cabinet.api_url}") + private String api_url; + + + + @Override + public void afterPayOrder(TradeOrderDO order, List orderItems) { + //商品SPU ID列表 + List spuIds = orderItems.stream() + .map(TradeOrderItemDO::getSpuId) + .distinct() + .collect(Collectors.toList()); +// if(null==spuIds && spuIds.size()<=0){ +// System.out.println("商品SPU ID列表 为空"); +// return; +// } + //查询spu表 + List spuList = productSpuApi.getSpuList(spuIds); + //判断商品类型是否有不是提货柜商品的 + if (CollUtil.isNotEmpty(spuList)) { + boolean hasNonDevice = spuList.stream() + .anyMatch(spu -> !ProductSpuTypesEnum.ENABLE.getTypes().equals(spu.getTypes())); + if (hasNonDevice) { + //订单中包含非提货柜商品 + log.error("订单中包含非提货柜商品"); + }else { + //判断是不是有不同机器的订单(一个创建人是一台机器) + boolean isSingleCreator = spuList.stream() + .map(ProductSpuRespDTO::getCreator) //获取每个商品的Creator + .distinct() //去重Creator + .count() == 1; // 判断是否只有一个唯一的创建人 + if (isSingleCreator) { + // 只有一个Creator的逻辑处理 + System.out.println("订单明细中只有一个商品创建人"); + //查询商品创建人的设备IMEI + AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(spuList.get(0).getCreator())); + if (user == null|| user.getDeviceId() == null){ + return; + } + //获取商品通道 + List skuIds = orderItems.stream() + .map(TradeOrderItemDO::getSkuId) + .distinct() + .collect(Collectors.toList()); + if(CollUtil.isEmpty(skuIds)){ + return; + } + List skuList = productSkuApi.getSkuList(skuIds); + //判断是不是有不同通道类型的订单 + boolean isSingleCabinetType = skuList.stream() + .map(ProductSkuRespDTO::getCabinetType) //获取每个商品的Creator + .distinct() //去重Creator + .count() == 1; // 判断是否只有一个唯一的创建人 + if (isSingleCabinetType) { + DispenseRequestBo request = new DispenseRequestBo(); + request.setDeviceId(user.getDeviceId()); + StringBuilder message= new StringBuilder(skuList.get(0).getCabinetType() + ","); + //遍历订单明细 + for (int i = 0; i < orderItems.size(); i++) { + TradeOrderItemDO orderItem = orderItems.get(i); + ProductSkuRespDTO sku = productSkuApi.getSku(orderItem.getSkuId()); + message.append(sku.getCabinetChannel()).append("&").append(orderItem.getCount()); + if (i != orderItems.size() - 1) { + message.append(","); + } + } + request.setMessage(message.toString()); + // 设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("Authorization", token); + + // 创建请求实体 + HttpEntity requestEntity = new HttpEntity<>(request, headers); + + // 创建RestTemplate + RestTemplate restTemplate = new RestTemplate(); + + try { + // 发送请求并解析响应 + ResponseEntity response = restTemplate.exchange( + api_url, + HttpMethod.POST, + requestEntity, + DispenseResponseBo.class + ); + + DispenseResponseBo body = response.getBody(); + if (body != null) { + System.out.println("响应结果: " + body); + if (body.getCode() == 0) { + System.out.println("出货成功!详情: " + body.getData()); + } else { + System.out.println("操作失败!原因: " + body.getMsg()); + log.error("订单--{}:[出货失败]:原因: {}",order.getNo(), body.getMsg()); + } + } + // 3. 更新 TradeOrderDO 状态为已完成 + TradeOrderDO tradeOrderDO = tradeOrderMapper.selectById(order.getId()); + int updateCount = tradeOrderMapper.updateByIdAndStatus(tradeOrderDO.getId(), tradeOrderDO.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()).setReceiveTime(LocalDateTime.now())); + if (updateCount == 0) { + throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_OVERPAY); + } + } catch (Exception e) { + System.err.println("请求异常: " + e.getMessage()); + log.error("订单--{}:[出货异常]:原因: {}",order.getNo(), e.getMessage()); + } + }else { + System.out.println("订单明细中包含多个通道类型"); + log.error("订单:{},明细中包含多个通道类型",order.getNo()); + } + } else { + System.out.println("订单明细中包含多个商品创建人"); + log.error("订单:{},明细中包含多个商品创建人",order.getNo()); + } + } + }else { + System.out.println("提货柜订单spu列表为空"); + } + + } + + public static void main(String[] args) { + String API_URL = "http://116.148.200.224:9527/ots/multiDispense"; + String TOKEN = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhcHAxIiwiaWF0IjoxNzQ5MTMzNzE5LCJleHAiOjIwNjAxNzM3MTl9.u2VUKxPxE2H8xldabMVRYSJKf6LN-XZfbcfyj1T7czI"; + + // 创建请求对象 + DispenseRequestBo request = new DispenseRequestBo("869667070337387", "1,11&1,12&1,13&1"); + + // 设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("Authorization", TOKEN); + + // 创建请求实体 + HttpEntity requestEntity = new HttpEntity<>(request, headers); + + // 创建RestTemplate + RestTemplate restTemplate = new RestTemplate(); + + try { + // 发送请求并解析响应 + ResponseEntity response = restTemplate.exchange( + API_URL, + HttpMethod.POST, + requestEntity, + DispenseResponseBo.class + ); + + DispenseResponseBo body = response.getBody(); + if (body != null) { + System.out.println("响应结果: " + body); + if (body.getCode() == 0) { + System.out.println("出货成功!详情: " + body.getData()); + } else { + System.out.println("操作失败!原因: " + body.getMsg()); + } + } + } catch (Exception e) { + System.err.println("请求异常: " + e.getMessage()); + } + } + +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index 507fb4b..9e330f2 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -86,4 +86,5 @@ public interface AdminUserApi { */ void validateUserList(Collection ids); + AdminUserRespDTO getUserByDeviceid(Long deviceid); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java index d86f3e5..d429fdf 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java @@ -21,6 +21,10 @@ public class AdminUserRespDTO { * 用户昵称 */ private String nickname; + /** + * 设备IMEI + */ + private String deviceId; /** * 帐号状态 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index 169bf11..e96a992 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -83,4 +83,10 @@ public class AdminUserApiImpl implements AdminUserApi { userService.validateUserList(ids); } + @Override + public AdminUserRespDTO getUserByDeviceid(Long deviceid) { + AdminUserDO user = userService.getUserByDeviceid(deviceid); + return BeanUtils.toBean(user, AdminUserRespDTO.class); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportExcelVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportExcelVO.java index a360f1a..a3e51c6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportExcelVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportExcelVO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -43,4 +44,7 @@ public class UserImportExcelVO { @DictFormat(DictTypeConstants.COMMON_STATUS) private Integer status; + @ExcelProperty("设备IMEI") + private String deviceId; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java index 2837318..3433875 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -56,6 +57,9 @@ public class UserRespVO{ @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") private String avatar; + @Schema(description = "设备IMEI", example = "12345678910") + private String deviceId; + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty(value = "帐号状态", converter = DictConvert.class) @DictFormat(DictTypeConstants.COMMON_STATUS) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java index 827f5e9..c52a6ca 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java @@ -64,6 +64,10 @@ public class UserSaveReqVO { @DiffLogField(name = "用户头像") private String avatar; + @Schema(description = "设备IMEI", example = "12345678910") + @DiffLogField(name = "设备IMEI") + private String deviceId; + // ========== 仅【创建】时,需要传递的字段 ========== @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java index 2f07a30..12d229b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java @@ -78,6 +78,11 @@ public class AdminUserDO extends TenantBaseDO { * 用户头像 */ private String avatar; + + /** + * 设备IMEI + */ + private String deviceId; /** * 帐号状态 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index c0c9be8..c29115a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -48,4 +48,7 @@ public interface AdminUserMapper extends BaseMapperX { return selectList(AdminUserDO::getDeptId, deptIds); } + default AdminUserDO getUserByDeviceid(Long deviceid){ + return selectOne(AdminUserDO::getDeviceId, deviceid); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index a695a40..b13a3bf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -216,4 +216,5 @@ public interface AdminUserService { */ boolean isPasswordMatch(String rawPassword, String encodedPassword); + AdminUserDO getUserByDeviceid(Long deviceid); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 040802c..3d92ef7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -518,6 +518,11 @@ public class AdminUserServiceImpl implements AdminUserService { return passwordEncoder.matches(rawPassword, encodedPassword); } + @Override + public AdminUserDO getUserByDeviceid(Long deviceid) { + return userMapper.getUserByDeviceid(deviceid); + } + /** * 对密码进行加密 * diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 57e1ec0..570ff9d 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -46,7 +46,7 @@ spring: primary: master datasource: master: - url: jdbc:mysql://121.40.41.196:3306/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 + url: jdbc:mysql://123.157.250.162:11294/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 @@ -64,7 +64,7 @@ spring: # password: Yudao@2024 # OpenGauss 连接的示例 slave: # 模拟从库,可根据自己需要修改 lazy: true # 开启懒加载,保证启动速度 - url: jdbc:mysql://121.40.41.196:3306/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://123.157.250.162:11294/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true username: xr password: zd5ecNxeXHZxkWs8 # tdengine: # IoT 数据库(需要 IoT 物联网再开启噢!) diff --git a/yudao-server/src/main/resources/application-prod.yaml b/yudao-server/src/main/resources/application-prod.yaml index 22bd583..5e6fd5b 100644 --- a/yudao-server/src/main/resources/application-prod.yaml +++ b/yudao-server/src/main/resources/application-prod.yaml @@ -45,7 +45,7 @@ spring: primary: master datasource: master: - url: jdbc:mysql://127.0.0.1:3306/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 + url: jdbc:mysql://127.0.0.1:11294/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 @@ -63,7 +63,7 @@ spring: # password: Yudao@2024 # OpenGauss 连接的示例 slave: # 模拟从库,可根据自己需要修改 lazy: true # 开启懒加载,保证启动速度 - url: jdbc:mysql://127.0.0.1:3306/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://127.0.0.1:11294/xr?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true username: xr password: zd5ecNxeXHZxkWs8 @@ -199,8 +199,8 @@ wx: # secret: 6f270509224a7ae1296bbf1c8cb97aed # appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的) # secret: 4a1a04e07f6a4a0751b39c3064a92c8b - appid: wxf6854db3b11da676 # 测试号(puhui 提供的) - secret: 0de4b956c64885468e8c06e824134e72 + appid: wx741ef9b42243284a # 测试号(puhui 提供的) + secret: 3b211e4bf0eeaaf27c8a369bcd10c9fb config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀 @@ -211,7 +211,7 @@ wx: # 芋道配置项,设置当前项目所有自定义的配置 yudao: captcha: - enable: true # 本地环境,暂时关闭图片验证码,方便登录等接口的测试; + enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试; security: mock-enable: true pay: diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 4e8564d..339af30 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -3,8 +3,8 @@ spring: name: yudao-server profiles: - active: prod -# active: local +# active: prod + active: local main: allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 @@ -362,4 +362,9 @@ yudao: debug: false # 插件配置 TODO 芋艿:【IOT】需要处理下 pf4j: - pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录 \ No newline at end of file + pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录 + +xr: + cabinet: + token: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhcHAxIiwiaWF0IjoxNzQ5MTMzNzE5LCJleHAiOjIwNjAxNzM3MTl9.u2VUKxPxE2H8xldabMVRYSJKf6LN-XZfbcfyj1T7czI' + api_url: 'http://116.148.200.224:9527/ots/multiDispense' \ No newline at end of file