diff --git a/null/download/4b42fe607ca640f19ff4f64892a29d2f_订单售后数据.xlsx b/null/download/4b42fe607ca640f19ff4f64892a29d2f_订单售后数据.xlsx new file mode 100644 index 000000000..f6549ffeb Binary files /dev/null and b/null/download/4b42fe607ca640f19ff4f64892a29d2f_订单售后数据.xlsx differ diff --git a/null/download/5450a70ed0e242d097893399e35219f8_会员信息数据.xlsx b/null/download/5450a70ed0e242d097893399e35219f8_会员信息数据.xlsx new file mode 100644 index 000000000..f54a040fc Binary files /dev/null and b/null/download/5450a70ed0e242d097893399e35219f8_会员信息数据.xlsx differ diff --git a/null/download/6e97b755e28945a39ada2fe0b7754369_会员信息数据.xlsx b/null/download/6e97b755e28945a39ada2fe0b7754369_会员信息数据.xlsx new file mode 100644 index 000000000..33d70421e Binary files /dev/null and b/null/download/6e97b755e28945a39ada2fe0b7754369_会员信息数据.xlsx differ diff --git a/null/download/b69ecabeb1974f959a6e55e84f7e8d4e_订单售后数据.xlsx b/null/download/b69ecabeb1974f959a6e55e84f7e8d4e_订单售后数据.xlsx new file mode 100644 index 000000000..d94e8327f Binary files /dev/null and b/null/download/b69ecabeb1974f959a6e55e84f7e8d4e_订单售后数据.xlsx differ diff --git a/null/download/df88302945b34951a404d615d8211ef2_订单售后数据.xlsx b/null/download/df88302945b34951a404d615d8211ef2_订单售后数据.xlsx new file mode 100644 index 000000000..7a778b33e Binary files /dev/null and b/null/download/df88302945b34951a404d615d8211ef2_订单售后数据.xlsx differ diff --git a/qrcode/1930206182499577858.png b/qrcode/1930206182499577858.png new file mode 100644 index 000000000..19eac2e6c Binary files /dev/null and b/qrcode/1930206182499577858.png differ diff --git a/qrcode/1931192482732077058.png b/qrcode/1931192482732077058.png new file mode 100644 index 000000000..fb72cb737 Binary files /dev/null and b/qrcode/1931192482732077058.png differ diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 55c5a5415..b5276f501 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -159,6 +159,8 @@ tenant: - pms_product_snapshot - pms_sku - pms_sku_snapshot + - oms_verification_codes + - oms_verification_logs # MyBatisPlus配置 diff --git a/ruoyi-modules/ruoyi-order/pom.xml b/ruoyi-modules/ruoyi-order/pom.xml index 0984f34d1..2caa69b34 100644 --- a/ruoyi-modules/ruoyi-order/pom.xml +++ b/ruoyi-modules/ruoyi-order/pom.xml @@ -97,7 +97,6 @@ org.dromara ruoyi-common-sse - org.dromara ruoyi-member @@ -137,6 +136,28 @@ org.springframework.boot spring-boot-starter-data-jpa + + org.dromara + ruoyi-system + + + + com.google.zxing + core + 3.4.1 + + + com.google.zxing + javase + 3.4.1 + + + + cn.hutool + hutool-all + 5.8.22 + + diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/OrderController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/OrderController.java index 75f0ed11c..74518c063 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/OrderController.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/OrderController.java @@ -57,11 +57,17 @@ public class OrderController extends BaseController { +// @ApiOperation("查询订单列表") +// @PostMapping("/list") +// public R> list(@RequestBody OrderBo query, Page page) { +// Page list = service.page(page,query.toWrapper() ); +// return R.ok(convert.toVO(list)); +// } + @ApiOperation("查询订单列表") @PostMapping("/list") - public R> list(@RequestBody OrderBo query, Page page) { - Page list = service.page(page,query.toWrapper() ); - return R.ok(convert.toVO(list)); + public R> list1(@RequestBody OrderBo query, Page page){ + return R.ok(orderService.getlist(page,query)); } // @ApiOperation("查询订单表列表") @@ -81,7 +87,7 @@ public class OrderController extends BaseController { @ApiOperation("导出订单表列表") @Log(title = "订单售后", businessType = BusinessType.EXPORT) - @GetMapping("export") + @PostMapping("export") public ResponseEntity export(OrderBo query) { List list = service.list(query.toWrapper()); ExcelUtil util = new ExcelUtil<>(OrderVO.class); @@ -137,7 +143,7 @@ public class OrderController extends BaseController { throw new RuntimeException("发货失败"); }finally { try{ - redisService.unLock(redisKey, redisValue);; + redisService.unLock(redisKey, redisValue); }catch (Exception e){ log.error("", e); } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/VerificationCodeController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/VerificationCodeController.java new file mode 100644 index 000000000..b749a0781 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/controller/VerificationCodeController.java @@ -0,0 +1,44 @@ +package com.wzj.soopin.order.controller; + +import com.wzj.soopin.order.service.VerificationCodeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.dromara.common.core.domain.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * 核销码相关接口 + */ +@Api(tags = "核销码接口") +@RestController +@RequestMapping("/oms/verification") +public class VerificationCodeController { + + @Autowired + private VerificationCodeService verificationCodeService; + + + /** + * 生成核销码 + */ + @GetMapping("/generate/{orderId}") + @ApiOperation("生成核销码") + public R generateCode(@PathVariable Long orderId) { + return verificationCodeService.generateVerificationCode(orderId); + } + + /** + * 扫码核销接口 + * @param codeValue 核销码 + * @param usedMerchantId 使用商家ID + * @return 核销结果z + */ + @PostMapping("/verify") + @ApiOperation("扫码核销接口") + public R verifyCode(@RequestParam String codeValue, + @RequestParam Long usedMerchantId) { + return verificationCodeService.verifyCode(codeValue, usedMerchantId); + } + +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/bo/OrderBo.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/bo/OrderBo.java index 27bb44fb3..e67ecc705 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/bo/OrderBo.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/bo/OrderBo.java @@ -25,6 +25,9 @@ public class OrderBo { @ApiModelProperty("订单编号") private String orderSn; + @ApiModelProperty("租户id") + private String tenantId; + @ApiModelProperty("用户帐号 精确匹配") private String memberUsernameLike; @@ -125,20 +128,8 @@ public class OrderBo { if (orderSn != null) { queryWrapper.eq(Order::getOrderSn, orderSn); } - if (totalAmount != null) { - queryWrapper.eq(Order::getTotalAmount, totalAmount); - } - if (purchasePrice != null) { - queryWrapper.eq(Order::getPurchasePrice, purchasePrice); - } - if (payAmount != null) { - queryWrapper.eq(Order::getPayAmount, payAmount); - } - if (merchantNote != null) { - queryWrapper.eq(Order::getMerchantNote, merchantNote); - } - if (freightAmount != null) { - queryWrapper.eq(Order::getFreightAmount, freightAmount); + if (tenantId != null) { + queryWrapper.eq(Order::getTenantId, tenantId); } if (payType != null) { queryWrapper.eq(Order::getPayType, payType); @@ -149,61 +140,12 @@ public class OrderBo { if (aftersaleStatus != null) { queryWrapper.eq(Order::getAftersaleStatus, aftersaleStatus); } - if (deliveryCompany != null &&!deliveryCompany.isEmpty()) { - queryWrapper.eq(Order::getDeliveryCompany, deliveryCompany); - } - if (deliverySn != null &&!deliverySn.isEmpty()) { - queryWrapper.eq(Order::getDeliverySn, deliverySn); - } - if (autoConfirmDay != null) { - queryWrapper.eq(Order::getAutoConfirmDay, autoConfirmDay); - } if (receiverPhone != null &&!receiverPhone.isEmpty()) { queryWrapper.eq(Order::getReceiverPhone, receiverPhone); } - if (receiverPostCode != null &&!receiverPostCode.isEmpty()) { - queryWrapper.eq(Order::getReceiverPostCode, receiverPostCode); - } - if (receiverProvince != null &&!receiverProvince.isEmpty()) { - queryWrapper.eq(Order::getReceiverProvince, receiverProvince); - } - if (receiverCity != null &&!receiverCity.isEmpty()) { - queryWrapper.eq(Order::getReceiverCity, receiverCity); - } - if (receiverDistrict != null &&!receiverDistrict.isEmpty()) { - queryWrapper.eq(Order::getReceiverDistrict, receiverDistrict); - } - if (receiverProvinceId != null) { - queryWrapper.eq(Order::getReceiverProvinceId, receiverProvinceId); - } - if (receiverCityId != null) { - queryWrapper.eq(Order::getReceiverCityId, receiverCityId); - } - if (receiverDistrictId != null) { - queryWrapper.eq(Order::getReceiverDistrictId, receiverDistrictId); - } - if (receiverDetailAddress != null &&!receiverDetailAddress.isEmpty()) { - queryWrapper.eq(Order::getReceiverDetailAddress, receiverDetailAddress); - } - if (note != null &&!note.isEmpty()) { - queryWrapper.eq(Order::getNote, note); - } - if (confirmStatus != null) { - queryWrapper.eq(Order::getConfirmStatus, confirmStatus); - } if (deleteStatus != null) { queryWrapper.eq(Order::getDeleteStatus, deleteStatus); } - if (paymentTime != null) { - queryWrapper.eq(Order::getPaymentTime, paymentTime); - } - if (deliveryTime != null) { - queryWrapper.eq(Order::getDeliveryTime, deliveryTime); - } - if (receiveTime != null) { - queryWrapper.eq(Order::getReceiveTime, receiveTime); - } - // 时间范围查询 if (startTime != null && endTime != null) { diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java index f0bd40f42..0bcf66609 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java @@ -34,6 +34,9 @@ public class Order extends BaseAudit { @ApiModelProperty("支付id") private Long payId; + @ApiModelProperty("租户id") + private String tenantId; + @ApiModelProperty("订单编号") @Excel(name = "订单编号") private String orderSn; @@ -164,5 +167,11 @@ public class Order extends BaseAudit { @ApiModelProperty("优惠券金额") private BigDecimal couponAmount; + @ApiModelProperty("核销时间") + private LocalDateTime usedTime; + + @ApiModelProperty("核销码url") + private String codeUrl; + } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/OrderItem.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/OrderItem.java index e6726d3c5..d0102dbfd 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/OrderItem.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/OrderItem.java @@ -24,8 +24,7 @@ public class OrderItem extends BaseAudit { @ApiModelProperty("ID") @TableId(type = IdType.ASSIGN_ID) private Long id; - @Excel(name = "商家备注") - private String merchantNote; + @ApiModelProperty("订单id") @Excel(name = "订单id") private Long orderId; diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationCodes.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationCodes.java new file mode 100644 index 000000000..545d05659 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationCodes.java @@ -0,0 +1,48 @@ +package com.wzj.soopin.order.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.dromara.common.core.domain.model.BaseAudit; + +import java.time.LocalDateTime; + +@ApiModel(description="核销码表对象") +@Data +@TableName("oms_verification_codes") +public class VerificationCodes extends BaseAudit { + + @ApiModelProperty("ID") + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("核销码") + private String code; + + @ApiModelProperty("关联订单id") + private Long orderId; + + @ApiModelProperty("是否使用") + private Integer status; + + @ApiModelProperty("用户id") + private Long memberId; + + @ApiModelProperty("用户昵称") + private String memberName ; + + @ApiModelProperty("使用时间") + private LocalDateTime usedTime; + + @ApiModelProperty("使用商家id") + private Long usedMerchantId; + + @ApiModelProperty("过期时间") + private LocalDateTime expireTime; + + + +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationLogs.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationLogs.java new file mode 100644 index 000000000..393c4c9bb --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/VerificationLogs.java @@ -0,0 +1,40 @@ +package com.wzj.soopin.order.domain.entity; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.dromara.common.core.domain.model.BaseAudit; + +import java.time.LocalDateTime; + +@ApiModel(description="核销日志表对象") +@Data +@TableName("oms_verification_logs") +public class VerificationLogs extends BaseAudit { + + @ApiModelProperty("ID") + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("核销码id") + private Long codeId; + + @ApiModelProperty("订单id") + private Long orderId; + + @ApiModelProperty("商家ID") + private Long merchantId; + + @ApiModelProperty("核销时间") + private LocalDateTime verificationTime; + + @ApiModelProperty("核销结果") + private Integer result; + + @ApiModelProperty("失败原因") + private String reason; +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/vo/OrderVO.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/vo/OrderVO.java index 31e3320e3..472ff3c85 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/vo/OrderVO.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/vo/OrderVO.java @@ -28,6 +28,8 @@ public class OrderVO extends BaseAudit { /** MEMBER_ID */ @Excel(name = "MEMBER_ID") private Long memberId; + /** 租户id */ + private String tenantId; /** 用户帐号 */ @Excel(name = "用户帐号") private String memberUsername; @@ -118,4 +120,26 @@ public class OrderVO extends BaseAudit { @Excel(name = "确认收货时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private LocalDateTime receiveTime; private List items; + + @Excel(name = "用户昵称") + private String memberNickname; + @Excel(name = "用户手机号") + private String memberPhoneEncrypted; + + @Excel(name = "卖家昵称") + private String tenantContactName; + @Excel(name = "卖家手机号") + private String tenantContactPhone; + + @Excel(name = "item ID") + private Long itemId; + @Excel(name = "商品id") + private Long productId; + @Excel(name = "商品品牌") + private Long productBrandId; + @Excel(name = "商品名称") + private String productName; + @Excel(name = "商品价格") + private BigDecimal productPrice; + } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderItemMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderItemMapper.java index b2a6600e3..4e07a81b9 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderItemMapper.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderItemMapper.java @@ -16,7 +16,7 @@ import java.util.List; */ public interface OrderItemMapper extends BaseMapper { - IPage selectOrderItem(@Param("query") OrderItemQuery query, IPage pageParam); +// IPage selectOrderItem(@Param("query") OrderItemQuery query, IPage pageParam); /** * 查询订单中所包含的商品列表 * diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java index 7003af7a7..725af5028 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java @@ -3,6 +3,9 @@ package com.wzj.soopin.order.mapper; import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.wzj.soopin.order.domain.bo.OrderBo; import com.wzj.soopin.order.domain.entity.Order; import com.wzj.soopin.order.domain.entity.SystemStatistics; import com.wzj.soopin.order.domain.form.ManagerOrderQueryForm; @@ -47,4 +50,10 @@ public interface OrderMapper extends BaseMapper { SystemStatistics statNewAndDeal(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); int statDealMember(@Param("startTime") LocalDateTime startTime,@Param("endTime") LocalDateTime endTime); + + + IPage getlist(@Param("page") Page page,@Param("query") OrderBo query); + + +// IPage getlist(@Param("page") Page objectPage, @Param("query") OrderBo query); } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationCodesMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationCodesMapper.java new file mode 100644 index 000000000..b1eb4a6d1 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationCodesMapper.java @@ -0,0 +1,12 @@ +package com.wzj.soopin.order.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.wzj.soopin.order.domain.entity.VerificationCodes; +import org.apache.ibatis.annotations.Select; + +import java.time.LocalDateTime; +import java.util.List; + +public interface VerificationCodesMapper extends BaseMapper { + +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationLogsMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationLogsMapper.java new file mode 100644 index 000000000..9e63a3d51 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/VerificationLogsMapper.java @@ -0,0 +1,7 @@ +package com.wzj.soopin.order.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.wzj.soopin.order.domain.entity.VerificationLogs; + +public interface VerificationLogsMapper extends BaseMapper { +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/OrderService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/OrderService.java index 9e068c49f..d9a3a1deb 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/OrderService.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/OrderService.java @@ -1,7 +1,18 @@ package com.wzj.soopin.order.service; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.wzj.soopin.order.domain.bo.OrderBo; import com.wzj.soopin.order.domain.entity.Order; +import com.wzj.soopin.order.domain.vo.OrderVO; +import com.wzj.soopin.order.domain.vo.PageVO; public interface OrderService extends IService { + + + IPage getlist(Page page, OrderBo query); + +// IPage getlist(PageVO pageVO, OrderBo query); } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationCodeService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationCodeService.java new file mode 100644 index 000000000..f561185d5 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationCodeService.java @@ -0,0 +1,13 @@ +package com.wzj.soopin.order.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wzj.soopin.order.domain.entity.VerificationCodes; +import org.dromara.common.core.domain.R; + +public interface VerificationCodeService extends IService { + + + R generateVerificationCode(Long orderId); + + R verifyCode(String codeValue, Long usedMerchantId); +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationLogsService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationLogsService.java new file mode 100644 index 000000000..195799e73 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/VerificationLogsService.java @@ -0,0 +1,7 @@ +package com.wzj.soopin.order.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wzj.soopin.order.domain.entity.VerificationLogs; + +public interface VerificationLogsService extends IService { +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderItemServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderItemServiceImpl.java index 9dcdf167b..dc64c61b2 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderItemServiceImpl.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderItemServiceImpl.java @@ -174,8 +174,8 @@ public class OrderItemServiceImpl extends ServiceImpl pagelist(OrderItemQuery query, PageVO page) { - IPage pageParam = PageUtil.initPage(page); - return orderItemMapper.selectOrderItem(query, pageParam); - } +// public IPage pagelist(OrderItemQuery query, PageVO page) { +// IPage pageParam = PageUtil.initPage(page); +// return orderItemMapper.selectOrderItem(query, pageParam); +// } } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java index d0230fb18..20f3fd32f 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java @@ -1,7 +1,9 @@ package com.wzj.soopin.order.service.impl; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; @@ -13,6 +15,7 @@ import com.wzj.soopin.goods.mapper.SkuMapper; import com.wzj.soopin.member.domain.po.Member; import com.wzj.soopin.order.convert.OrderConvert; import com.wzj.soopin.order.convert.OrderOperateHistoryConvert; +import com.wzj.soopin.order.domain.bo.OrderBo; import com.wzj.soopin.order.domain.entity.Order; import com.wzj.soopin.order.domain.entity.OrderDeliveryHistory; import com.wzj.soopin.order.domain.entity.OrderItem; @@ -26,12 +29,14 @@ import com.wzj.soopin.order.mapper.OrderItemMapper; import com.wzj.soopin.order.mapper.OrderMapper; import com.wzj.soopin.order.mapper.OrderOperateHistoryMapper; import com.wzj.soopin.order.service.OrderService; +import com.wzj.soopin.order.utils.PageUtil; import com.wzj.soopin.order.utils.SecurityUtils; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.event.Constants; import org.dromara.common.core.utils.PhoneUtils; +import org.dromara.system.domain.SysOperLog; +import org.dromara.system.mapper.SysOperLogMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -80,6 +85,9 @@ public class OrderServiceImpl extends ServiceImpl implements @Autowired private OrderOperateHistoryConvert historyConvert; + @Autowired + private SysOperLogMapper sysOperLogMapper; + /** * 查询订单表 * @@ -234,7 +242,7 @@ public class OrderServiceImpl extends ServiceImpl implements return affectedRows > 0 ? R.ok(order) : R.fail("删除失败"); } - public Page queryOrderPage(OrderH5Query query, Pageable pageReq) { + public PageImpl queryOrderPage(OrderH5Query query, Pageable pageReq) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("member_id", SecurityUtils.getUserId()); IPage page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(); @@ -388,13 +396,18 @@ public class OrderServiceImpl extends ServiceImpl implements * @param orderId 订单id * @return 结果 */ - public List log(Long orderId) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.eq(OrderOperateHistory::getOrderId, orderId); - wrapper.in(OrderOperateHistory::getOrderStatus, Arrays.asList(0, 1, 2, 3, 4)); - wrapper.orderByDesc(OrderOperateHistory::getCreateTime); - List historyList = orderOperateHistoryMapper.selectList(wrapper); - return historyList; + public List log(Long orderId) { +// LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); +// wrapper.eq(OrderOperateHistory::getOrderId, orderId); +// wrapper.in(OrderOperateHistory::getOrderStatus, Arrays.asList(0, 1, 2, 3, 4)); +// wrapper.orderByDesc(OrderOperateHistory::getCreateTime); +// List historyList = orderOperateHistoryMapper.selectList(wrapper); +// return historyList; + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysOperLog::getTitle, "订单表"); + wrapper.eq(SysOperLog::getOperatorType, 1); + return sysOperLogMapper.selectList(wrapper); } public R decryptPhone(Long orderId) { @@ -430,4 +443,15 @@ public class OrderServiceImpl extends ServiceImpl implements } } + @Override + public IPage getlist(Page page, OrderBo query) { + IPage resultPage = orderMapper.getlist(page,query); + return resultPage; + } + +// @Override +// public IPage getlist(PageVO pageVO, OrderBo query) { +// IPage resultPage = orderMapper.getlist(PageUtil.initPage(pageVO),query); +// return resultPage; +// } } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationCodeServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationCodeServiceImpl.java new file mode 100644 index 000000000..0df398a86 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationCodeServiceImpl.java @@ -0,0 +1,208 @@ +package com.wzj.soopin.order.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wzj.soopin.order.domain.entity.Order; +import com.wzj.soopin.order.domain.entity.VerificationCodes; +import com.wzj.soopin.order.domain.entity.VerificationLogs; +import com.wzj.soopin.order.mapper.OrderMapper; +import com.wzj.soopin.order.mapper.VerificationCodesMapper; +import com.wzj.soopin.order.mapper.VerificationLogsMapper; +import com.wzj.soopin.order.service.VerificationCodeService; +import com.wzj.soopin.order.utils.QrCodeGenerator; +import com.wzj.soopin.order.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; +import org.dromara.common.core.domain.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +public class VerificationCodeServiceImpl extends ServiceImpl implements VerificationCodeService{ + + + + @Autowired + private VerificationCodesMapper codeMapper; + @Autowired + private OrderMapper orderMapper; + @Autowired + private QrCodeGenerator qrCodeGenerator; + + @Autowired + private VerificationLogsMapper logMapper; + + /** + * 生成核销码并关联订单 + * + * @return + */ + @Override + public R generateVerificationCode(Long orderId) { + // 校验订单状态 + Order order = orderMapper.selectById(orderId); + if (order == null || order.getStatus() != 6) { + return R.fail("订单状态异常"); + } + + // 生成唯一核销码 + String codeValue = generateUniqueCode(); + + // 核销码过期时间(7天后过期) + LocalDateTime expireTime = LocalDateTime.now().plusDays(7); + + // 保存核销码到数据库 + VerificationCodes code = new VerificationCodes(); + code.setMemberId(order.getMemberId()); + code.setMemberName(order.getMemberUsername()); + code.setCode(codeValue); + code.setOrderId(orderId); + code.setExpireTime(expireTime); + code.setCreateTime(LocalDateTime.now()); + code.setStatus(0); // 未使用状态 + int insertResult = codeMapper.insert(code); + + if (insertResult != 1) { + return R.fail("核销码生成失败"); + } + + // 构建保存路径 + String filePath = "qrcode/" + orderId + ".png"; + String qrCodeUrl = qrCodeGenerator.generateQrCode( + "核销码:" + codeValue + ",订单ID:" + orderId, + 200, + 200, + filePath + ); + // 打印生成后的二维码URL + log.info("生成的二维码URL: {}", qrCodeUrl); + if (qrCodeUrl == null) { + log.error("二维码生成失败"); + } + + + // 将二维码URL保存到订单表中 + order.setCodeUrl(qrCodeUrl); + orderMapper.updateById(order); + return R.ok("核销码生成成功", code); + } + + @Override + public R verifyCode(String codeValue, Long usedMerchantId) { + // 参数校验 + if (StringUtils.isBlank(codeValue) || usedMerchantId == null) { + recordVerificationLog(null, null, usedMerchantId, 0, "参数不能为空"); + return R.fail("参数不能为空"); + } + + // 查询核销码 + VerificationCodes code = codeMapper.selectOne( + new LambdaQueryWrapper().eq(VerificationCodes::getCode, codeValue) + ); + if (code == null) { + recordVerificationLog(null, null, usedMerchantId, 0, "核销码不存在"); + return R.fail("核销码不存在"); + } + + // 检查核销码状态 + if (code.getStatus() == 1) { + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, "核销码已使用"); + return R.fail("核销码已使用"); + } + + if (code.getStatus() == 2) { + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, "核销码已过期"); + return R.fail("核销码已过期"); + } + + // 检查订单状态 + Order order = orderMapper.selectById(code.getOrderId()); + if (order == null || order.getStatus() != 6) { + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, "订单状态异常,无法核销"); + return R.fail("订单状态异常,无法核销"); + } + + // 检查核销码是否过期 + if (LocalDateTime.now().isAfter(code.getExpireTime())) { + // 更新状态为已过期 + code.setStatus(3); + codeMapper.updateById(code); + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, "核销码已过期"); + return R.fail("核销码已过期"); + } + + // 检查该订单是否已经核销过 + VerificationLogs existingLog = logMapper.selectOne( + new LambdaQueryWrapper() + .eq(VerificationLogs::getOrderId, code.getOrderId()) + .eq(VerificationLogs::getResult, 1) // 只检查成功核销的记录 + ); + + if (existingLog != null) { + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, + "该订单已被核销,核销时间:" + existingLog.getVerificationTime()); + return R.fail("该订单已被核销,核销时间:" + existingLog.getVerificationTime()); + } + + // 执行核销 + code.setStatus(1); // 已使用 + code.setUsedTime(LocalDateTime.now()); + code.setUsedMerchantId(usedMerchantId); + int result = codeMapper.updateById(code); + + if (result != 1) { + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 0, "核销失败,请重试"); + return R.fail("核销失败,请重试"); + } + + // 更新订单状态 + order.setStatus(7); // 已核销 + order.setUsedTime(LocalDateTime.now()); + orderMapper.updateById(order); + + // 记录核销日志(成功) + recordVerificationLog(code.getId(), code.getOrderId(), usedMerchantId, 1, null); + + // 返回核销成功信息 + Map resultData = new HashMap<>(); + resultData.put("orderId", order.getId()); + resultData.put("orderSn", order.getOrderSn()); + resultData.put("used_time", order.getUsedTime()); + resultData.put("code_url", order.getCodeUrl()); + + return R.ok("核销成功", resultData); + } + + + /** + * 记录核销日志 + * @param codeId 核销码ID + * @param orderId 订单ID + * @param merchantId 商户ID + * @param result 结果:1成功,0失败 + * @param reason 失败原因 + */ + private void recordVerificationLog(Long codeId, Long orderId, Long merchantId, Integer result, String reason) { + VerificationLogs log = new VerificationLogs(); + log.setCodeId(codeId); + log.setOrderId(orderId); + log.setMerchantId(merchantId); + log.setVerificationTime(LocalDateTime.now()); + log.setResult(result); + log.setReason(reason); + logMapper.insert(log); + } + + /** + * 生成唯一核销码 + */ + private String generateUniqueCode() { + String uuid = java.util.UUID.randomUUID().toString().replaceAll("-", ""); + return uuid.substring(0, 16).toUpperCase(); + } +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationLogsServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationLogsServiceImpl.java new file mode 100644 index 000000000..775239deb --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/VerificationLogsServiceImpl.java @@ -0,0 +1,11 @@ +package com.wzj.soopin.order.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wzj.soopin.order.domain.entity.VerificationLogs; +import com.wzj.soopin.order.mapper.VerificationLogsMapper; +import com.wzj.soopin.order.service.VerificationLogsService; +import org.springframework.stereotype.Service; + +@Service +public class VerificationLogsServiceImpl extends ServiceImpl implements VerificationLogsService { +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/QrCodeGenerator.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/QrCodeGenerator.java new file mode 100644 index 000000000..cc1a266c3 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/QrCodeGenerator.java @@ -0,0 +1,105 @@ +package com.wzj.soopin.order.utils; + +import com.google.zxing.*; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.HybridBinarizer; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.QRCodeReader; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.annotations.Comment; +import org.springframework.stereotype.Component; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.io.File; + +@Component +@Slf4j +public class QrCodeGenerator { + + /** + * 生成二维码图片并保存到指定路径 + * @param content 二维码内容 + * @param width 图片宽度 + * @param height 图片高度 + * @param filePath 保存路径 + */ + + + public String generateQrCode(String content, int width, int height, String filePath) { + try { + // 检查并创建目录 + File dir = new File(filePath).getParentFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + Map hints = new HashMap<>(); + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix); + Path path = Paths.get(filePath); + MatrixToImageWriter.writeToPath(bitMatrix, "png", path); + return filePath; + } catch (WriterException | IOException e) { + // 记录异常信息 + log.error("生成二维码时出现异常: {}", e.getMessage()); + e.printStackTrace(); + return null; + } + } + + /** + * 生成二维码图片字节数组 + * @param content 二维码内容 + * @param width 图片宽度 + * @param height 图片高度 + * @return 二维码图片字节数组 + */ + public byte[] generateQrCodeImage(String content, int width, int height) { + try { + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + Map hints = new HashMap<>(); + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix); + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + javax.imageio.ImageIO.write(bufferedImage, "png", bos); + return bos.toByteArray(); + } catch (WriterException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 解析二维码图片 + * @param filePath 二维码图片路径 + * @return 二维码内容 + */ + public String decodeQrCode(String filePath) { + try { + BufferedImage bufferedImage = ImageIO.read(new File(filePath)); + int width = bufferedImage.getWidth(); + int height = bufferedImage.getHeight(); + int[] pixels = new int[width * height]; + bufferedImage.getRGB(0, 0, width, height, pixels, 0, width); + LuminanceSource source = new RGBLuminanceSource(width, height, pixels); + HybridBinarizer hybridBinarizer = new HybridBinarizer(source); + BinaryBitmap binaryBitmap = new BinaryBitmap(hybridBinarizer); + MultiFormatReader reader = new MultiFormatReader(); + Result result = reader.decode(binaryBitmap); + return result.getText(); + } catch (IOException | com.google.zxing.NotFoundException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/SnowflakeIdGenerator.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/SnowflakeIdGenerator.java new file mode 100644 index 000000000..c9bcafba4 --- /dev/null +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/utils/SnowflakeIdGenerator.java @@ -0,0 +1,95 @@ +package com.wzj.soopin.order.utils; + +public class SnowflakeIdGenerator { + // 起始时间戳(可以设置项目上线时间等固定时间,单位毫秒) + private static final long START_TIMESTAMP = 1609459200000L; // 2021-01-01 00:00:00 + // 机器ID所占位数 + private static final long WORKER_ID_BITS = 5L; + // 数据中心ID所占位数 + private static final long DATA_CENTER_ID_BITS = 5L; + // 序列号所占位数 + private static final long SEQUENCE_BITS = 12L; + // 最大的机器ID,2的WORKER_ID_BITS次方减1 + private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS); + // 最大的数据中心ID,2的DATA_CENTER_ID_BITS次方减1 + private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS); + // 序列号最大值,2的SEQUENCE_BITS次方减1 + private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); + // 时间戳左移(WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)位 + private static final long TIMESTAMP_LEFT_SHIFT = WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS; + // 机器ID左移(DATA_CENTER_ID_BITS + SEQUENCE_BITS)位 + private static final long WORKER_ID_SHIFT = DATA_CENTER_ID_BITS + SEQUENCE_BITS; + // 数据中心ID左移SEQUENCE_BITS位 + private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS; + // 当前机器ID + private long workerId; + // 当前数据中心ID + private long dataCenterId; + // 序列号 + private long sequence = 0L; + // 上次生成ID的时间戳 + private long lastTimestamp = -1L; + /** + * 构造函数 + * @param workerId 机器ID(取值范围0 - MAX_WORKER_ID) + * @param dataCenterId 数据中心ID(取值范围0 - MAX_DATA_CENTER_ID ) + */ + public SnowflakeIdGenerator(long workerId, long dataCenterId) { + if (workerId > MAX_WORKER_ID || workerId < 0) { + throw new IllegalArgumentException(String.format("Worker ID can't be greater than %d or less than 0", MAX_WORKER_ID)); + } + if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) { + throw new IllegalArgumentException(String.format("Data center ID can't be greater than %d or less than 0", MAX_DATA_CENTER_ID)); + } + this.workerId = workerId; + this.dataCenterId = dataCenterId; + } + /** + * 生成唯一ID + * @return 生成的唯一ID + */ + public synchronized long nextId() { + long timestamp = timeGen(); + // 若当前时间小于上一次生成ID的时间戳,说明系统时钟回退过,抛出异常 + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + // 同一毫秒内生成,则序列号递增 + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & SEQUENCE_MASK; + // 序列号溢出,等待到下一毫秒 + if (sequence == 0) { + timestamp = tilNextMillis(lastTimestamp); + } + } else { + // 不同毫秒生成,序列号重置为0 + sequence = 0L; + } + // 记录上一次生成ID的时间戳 + lastTimestamp = timestamp; + // 生成唯一ID + return ((timestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT) | + (workerId << WORKER_ID_SHIFT) | + (dataCenterId << DATA_CENTER_ID_SHIFT) | + sequence; + } + /** + * 获取当前时间戳(单位:毫秒) + * @return 当前时间戳 + */ + private long timeGen() { + return System.currentTimeMillis(); + } + /** + * 等待直到下一个毫秒 + * @param lastTimestamp 上一次生成ID的时间戳 + * @return 下一个毫秒的时间戳 + */ + private long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } +} diff --git a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/OrderMapper.xml b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/OrderMapper.xml index 84d63b148..66f6d544a 100644 --- a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/OrderMapper.xml +++ b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/OrderMapper.xml @@ -264,4 +264,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where status in (1,2,3) and create_time between #{startTime} and #{endTime} + + +