feat:机器上可以查询全部订单
This commit is contained in:
1 parent
ec39c72f7e
commit
1bf4ad3dd8
8 files changed
+270
-1
No files matched your search
@@ -61,3 +61,9 @@ gen_code
|
||||
|
||||
### node ###
|
||||
node_modules
|
||||
|
||||
### AI 辅助工具 ###
|
||||
.video_agent
|
||||
.mimosa
|
||||
.v2c
|
||||
.zcode
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.bsd.pjcloud.hard.api.dto.hard;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 终端交易记录查询参数。
|
||||
*
|
||||
* 设备 ID 是唯一的数据范围入口:scope 为空或 DEVICE 时仅查询本机订单,
|
||||
* scope 为 MERCHANT 时按服务端解析的终端所属商户查询全部设备订单,
|
||||
* 客户端不能通过本接口指定其他商户或用户范围。
|
||||
*/
|
||||
@Data
|
||||
public class TerminalOrderRecordQueryDto {
|
||||
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
@Schema(description = "当前终端设备ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long hardId;
|
||||
|
||||
@Schema(description = "开始日期,格式 yyyy-MM-dd")
|
||||
private LocalDate startDate;
|
||||
|
||||
@Schema(description = "结束日期,格式 yyyy-MM-dd")
|
||||
private LocalDate endDate;
|
||||
|
||||
@Schema(description = "数据范围:DEVICE 仅本机(默认),MERCHANT 当前终端所属商户全部设备")
|
||||
private String scope;
|
||||
|
||||
@Schema(description = "订单状态编码集合,为空时查询全部状态")
|
||||
private List<String> orderStatusCodes;
|
||||
|
||||
@Schema(description = "用餐时段编码,为空或 -1 时不区分")
|
||||
private String hourType;
|
||||
}
|
||||
+3
@@ -26,4 +26,7 @@ public class VerificationRecordQueryDto {
|
||||
|
||||
@Schema(description = "核销类型,目前仅支持 RESERVATION 预约核销;为空时同样按预约核销查询")
|
||||
private String verificationType;
|
||||
|
||||
@Schema(description = "数据范围:DEVICE 仅本机(默认),MERCHANT 当前终端所属商户全部设备")
|
||||
private String scope;
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.bsd.pjcloud.hard.api.vo.android;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/** 终端交易记录展示对象,仅返回交易记录列表所需字段。 */
|
||||
@Data
|
||||
public class TerminalOrderRecordVo {
|
||||
|
||||
/** 订单主键。 */
|
||||
private Long orderId;
|
||||
|
||||
/** 业务订单号。 */
|
||||
private String orderNo;
|
||||
|
||||
/** 订单类型稳定编码。 */
|
||||
private String orderType;
|
||||
|
||||
/** 订单类型展示名称。 */
|
||||
private String orderTypeName;
|
||||
|
||||
/** 订单状态稳定编码。 */
|
||||
private String orderStatus;
|
||||
|
||||
/** 订单状态展示名称。 */
|
||||
private String orderStatusName;
|
||||
|
||||
/** 支付方式稳定编码。 */
|
||||
private String payType;
|
||||
|
||||
/** 支付方式展示名称。 */
|
||||
private String payTypeName;
|
||||
|
||||
/** 下单用户姓名。 */
|
||||
private String username;
|
||||
|
||||
/** 下单用户所属部门。 */
|
||||
private String userDeptName;
|
||||
|
||||
/** 订单商品摘要。 */
|
||||
private String productDesc;
|
||||
|
||||
/** 用餐时段编码。 */
|
||||
private String hourType;
|
||||
|
||||
/** 商品总金额(分)。 */
|
||||
private Integer totalPrice;
|
||||
|
||||
/** 额外支付(分)。 */
|
||||
private Integer extraPrice;
|
||||
|
||||
/** 实际支付(分)。 */
|
||||
private Integer payPrice;
|
||||
|
||||
/** 完成交易的设备名称;本机数据范围下与服务端解析的终端一致。 */
|
||||
private String hardName;
|
||||
|
||||
/** 下单时间。 */
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
+8
@@ -28,6 +28,7 @@ import com.bsd.pjcloud.hard.api.vo.HardInvoiceVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.manager.HardManagerVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.HardAdUserVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.ReservationMenuQueryVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.TerminalOrderRecordVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.VerificationRecordVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardAggregateOrderCodePayStatusVo;
|
||||
@@ -67,6 +68,7 @@ public class HardApiController {
|
||||
private final HardOrderTotalService hardOrderTotalService;
|
||||
private final ReservationMenuQueryService reservationMenuQueryService;
|
||||
private final VerificationRecordService verificationRecordService;
|
||||
private final TerminalOrderRecordService terminalOrderRecordService;
|
||||
private final HardTerminalFaceService hardTerminalFaceService;
|
||||
private final HardTerminalPrintService hardTerminalPrintService;
|
||||
|
||||
@@ -485,6 +487,12 @@ public class HardApiController {
|
||||
return R.ok(verificationRecordService.page(page, hardId, dto));
|
||||
}
|
||||
|
||||
@PostMapping("/order-record/page")
|
||||
@Operation(summary = "分页查询当前终端交易记录")
|
||||
public R<Page<TerminalOrderRecordVo>> orderRecordPage(@ParameterObject Page<?> page, @RequestHeader("DEVICE-ID") Long hardId, @Valid @RequestBody TerminalOrderRecordQueryDto dto) {
|
||||
return R.ok(terminalOrderRecordService.page(page, hardId, dto));
|
||||
}
|
||||
|
||||
@GetMapping("/chart-latitude")
|
||||
@Operation(summary = "统计每天、每周、每月、每年的交易人数和次数")
|
||||
public R<HardChartLatitudeVo> chartLatitude(@RequestParam Long merchantId) {
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.bsd.pjcloud.hard.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.hard.api.dto.hard.TerminalOrderRecordQueryDto;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.TerminalOrderRecordVo;
|
||||
|
||||
/** 终端交易记录查询服务。 */
|
||||
public interface TerminalOrderRecordService {
|
||||
|
||||
/**
|
||||
* 分页查询终端交易记录。
|
||||
*
|
||||
* @param page 分页参数,页码最小为 1、每页最大为 50
|
||||
* @param hardId 当前请求头中的设备主键
|
||||
* @param dto 数据范围、日期、状态和时段查询条件
|
||||
* @return 已按下单时间倒序排列的终端交易记录分页
|
||||
*/
|
||||
Page<TerminalOrderRecordVo> page(Page<?> page, Long hardId, TerminalOrderRecordQueryDto dto);
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package com.bsd.pjcloud.hard.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
|
||||
import com.bsd.pjcloud.hard.api.dto.hard.TerminalOrderRecordQueryDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
|
||||
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
|
||||
import com.bsd.pjcloud.hard.api.vo.android.TerminalOrderRecordVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
|
||||
import com.bsd.pjcloud.hard.service.HardManagerService;
|
||||
import com.bsd.pjcloud.hard.service.HardOrderService;
|
||||
import com.bsd.pjcloud.hard.service.TerminalOrderRecordService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** 终端交易记录查询服务,复用订单管理端分页查询保证范围、分页和用户信息口径一致。 */
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TerminalOrderRecordServiceImpl implements TerminalOrderRecordService {
|
||||
|
||||
/** 全部数据范围:按终端所属商户查询商户下全部设备的交易记录。 */
|
||||
private static final String SCOPE_MERCHANT = "MERCHANT";
|
||||
|
||||
/** 终端不区分用餐时段的编码。 */
|
||||
private static final String HOUR_TYPE_ALL = "-1";
|
||||
|
||||
/** 设备服务,用于校验请求设备存在并解析所属商户。 */
|
||||
private final HardManagerService hardManagerService;
|
||||
|
||||
/** 订单服务,用于按设备/商户、订单状态和下单时间分页查询。 */
|
||||
private final HardOrderService hardOrderService;
|
||||
|
||||
@Override
|
||||
public Page<TerminalOrderRecordVo> page(Page<?> page, Long hardId, TerminalOrderRecordQueryDto dto) {
|
||||
if (!Objects.equals(hardId, dto.getHardId())) {
|
||||
throw new RuntimeException("请求设备与查询设备不一致");
|
||||
}
|
||||
HardManagerEntity hard = hardManagerService.getById(hardId);
|
||||
if (hard == null) {
|
||||
throw new RuntimeException("设备不存在或无权访问");
|
||||
}
|
||||
|
||||
LocalDate startDate = ObjectUtil.defaultIfNull(dto.getStartDate(), LocalDate.now());
|
||||
LocalDate endDate = ObjectUtil.defaultIfNull(dto.getEndDate(), startDate);
|
||||
if (endDate.isBefore(startDate)) {
|
||||
throw new RuntimeException("结束日期不能早于开始日期");
|
||||
}
|
||||
|
||||
HardOrderDto query = new HardOrderDto();
|
||||
if (SCOPE_MERCHANT.equalsIgnoreCase(StrUtil.trimToEmpty(dto.getScope()))) {
|
||||
// 全部数据:范围来自服务端解析的终端所属商户,客户端不能自行指定商户。
|
||||
query.setMerchantId(hard.getMerchantId());
|
||||
} else {
|
||||
query.setHardId(hard.getId());
|
||||
}
|
||||
query.setCreateTimeList(new LocalDateTime[]{startDate.atStartOfDay(), endDate.atTime(23, 59, 59)});
|
||||
query.setOrderStatusCodes(dto.getOrderStatusCodes());
|
||||
if (StrUtil.isNotBlank(dto.getHourType()) && !HOUR_TYPE_ALL.equals(dto.getHourType().trim())) {
|
||||
query.setHourType(dto.getHourType().trim());
|
||||
}
|
||||
|
||||
long current = Math.max(1, page.getCurrent());
|
||||
long size = Math.min(50, Math.max(1, page.getSize()));
|
||||
// 订单范围、分页、用户和部门信息统一由订单服务处理,交易记录只负责转换展示字段。
|
||||
Page<HardOrderVo> source = hardOrderService.scopePageList(new Page<>(current, size), query, null);
|
||||
List<TerminalOrderRecordVo> records = source.getRecords().stream()
|
||||
.map(TerminalOrderRecordServiceImpl::convert)
|
||||
.toList();
|
||||
Page<TerminalOrderRecordVo> result = new Page<>(source.getCurrent(), source.getSize(), source.getTotal());
|
||||
result.setRecords(records);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将订单查询结果转换为终端交易记录展示对象。
|
||||
*
|
||||
* @param order 订单分页查询结果
|
||||
* @return 终端交易记录
|
||||
*/
|
||||
private static TerminalOrderRecordVo convert(HardOrderVo order) {
|
||||
TerminalOrderRecordVo vo = new TerminalOrderRecordVo();
|
||||
vo.setOrderId(order.getId());
|
||||
vo.setOrderNo(StrUtil.blankToDefault(order.getOrderNo(), String.valueOf(order.getId())));
|
||||
vo.setOrderType(order.getOrderType());
|
||||
HardOrderTypeEnum orderType = HardOrderTypeEnum.valueOfByType(order.getOrderType());
|
||||
vo.setOrderTypeName(orderType == null ? "其他类型" : orderType.getDescription());
|
||||
vo.setOrderStatus(order.getOrderStatus());
|
||||
// 状态枚举查找对未知编码抛异常,外卖/商城等终端外状态需安全降级。
|
||||
vo.setOrderStatusName(resolveStatusName(order.getOrderStatus()));
|
||||
vo.setPayType(order.getPayType());
|
||||
HardPayTypeEnum payType = HardPayTypeEnum.valueOfByType(order.getPayType());
|
||||
vo.setPayTypeName(payType == null ? "其他方式" : payType.getDescription());
|
||||
vo.setUsername(StrUtil.blankToDefault(order.getUsername(), "未知用户"));
|
||||
vo.setUserDeptName(order.getUserDeptName());
|
||||
vo.setProductDesc(StrUtil.blankToDefault(order.getProductDesc(), "未知商品"));
|
||||
vo.setHourType(order.getHourType());
|
||||
vo.setTotalPrice(ObjectUtil.defaultIfNull(order.getTotalPrice(), 0));
|
||||
vo.setExtraPrice(ObjectUtil.defaultIfNull(order.getExtraPrice(), 0));
|
||||
vo.setPayPrice(ObjectUtil.defaultIfNull(order.getPayPrice(), 0));
|
||||
vo.setHardName(order.getHardName());
|
||||
vo.setCreateTime(order.getCreateTime());
|
||||
return vo;
|
||||
}
|
||||
|
||||
/** 状态枚举 {@code valueOfByType} 对未知编码会抛异常,这里安全降级为通用名称。 */
|
||||
private static String resolveStatusName(String statusCode) {
|
||||
if (StrUtil.isBlank(statusCode)) {
|
||||
return "未知状态";
|
||||
}
|
||||
for (HardOrderStatusEnum status : HardOrderStatusEnum.values()) {
|
||||
if (Objects.equals(statusCode, status.getType())) {
|
||||
return status.getDescription();
|
||||
}
|
||||
}
|
||||
return "其他状态";
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -30,6 +30,9 @@ public class VerificationRecordServiceImpl implements VerificationRecordService
|
||||
/** 当前接口支持的预约核销类型协议值。 */
|
||||
private static final String TYPE_RESERVATION = "RESERVATION";
|
||||
|
||||
/** 全部数据范围:按终端所属商户查询商户下全部设备的核销记录。 */
|
||||
private static final String SCOPE_MERCHANT = "MERCHANT";
|
||||
|
||||
/** 设备服务,用于校验请求设备存在且与查询设备一致。 */
|
||||
private final HardManagerService hardManagerService;
|
||||
|
||||
@@ -64,7 +67,12 @@ public class VerificationRecordServiceImpl implements VerificationRecordService
|
||||
}
|
||||
|
||||
HardOrderDto query = new HardOrderDto();
|
||||
query.setHardId(hard.getId());
|
||||
if (SCOPE_MERCHANT.equalsIgnoreCase(StrUtil.trimToEmpty(dto.getScope()))) {
|
||||
// 全部数据:范围来自服务端解析的终端所属商户,客户端不能自行指定商户。
|
||||
query.setMerchantId(hard.getMerchantId());
|
||||
} else {
|
||||
query.setHardId(hard.getId());
|
||||
}
|
||||
query.setOrderType(HardOrderTypeEnum.RESERVE.getType());
|
||||
query.setApptIdOrApptRuleIdNotNull(true);
|
||||
query.setOrderStatusCodes(List.of(HardOrderStatusEnum.CANCEL.getType()));
|
||||
|
||||
Reference in new issue
Block a user