feat:重构"食堂菜品购买统计"+"食堂菜品部门统计"菜单统计预约核销订单+线下购买订单

feat:增加机器的每日菜谱库存扣款
feat:增加订单"退回到核销前"按钮
This commit is contained in:
dzc committed 2026-08-24 18:39:59 +08:00
1 parent 8d31f20cec
commit d1cd86dfa4
92 files changed
+9628 -454

No files matched your search

@@ -0,0 +1,26 @@
package com.bsd.pjcloud.thirdparty.api.feign;
import com.bsd.pjcloud.common.core.constant.ServiceNameConstants;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.feign.annotation.NoToken;
import com.bsd.pjcloud.thirdparty.dto.pay.ThirdPaymentTaskDispatchDto;
import com.bsd.pjcloud.thirdparty.vo.pay.ThirdPaymentTaskDispatchVo;
import jakarta.validation.Valid;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* Quartz 调用 thirdparty 支付任务分发器的内部 Feign 契约。
*/
@FeignClient(contextId = "remoteThirdPaymentTaskService", value = ServiceNameConstants.THIRDPARTY_SERVICE)
public interface RemoteThirdPaymentTaskService {
/**
* 同步请求 thirdparty 接收一批任务,渠道调用由已取得租约的 Worker 异步执行。
* @param dto 固定任务类型、批量上限和触发来源
* @return 接收、领取、繁忙和积压统计
*/
@NoToken
@PostMapping("/third-payment-task/inner/dispatch")
R<ThirdPaymentTaskDispatchVo> dispatch(@Valid @RequestBody ThirdPaymentTaskDispatchDto dto);
}
@@ -0,0 +1,35 @@
package com.bsd.pjcloud.thirdparty.constant.pay;
import lombok.Getter;
/**
* 任务执行状态;状态只由任务 Worker 按租约条件推进。
*/
@Getter
public enum ThirdPaymentTaskStatusEnum {
/** 已创建、等待首次执行。 */
READY("READY"),
/** 已被某个 Worker 租约领取。 */
PROCESSING("PROCESSING"),
/** 外部结果未收敛,等待退避重试。 */
RETRY("RETRY"),
/** 已完成。 */
SUCCESS("SUCCESS"),
/** 确定性错误终止。 */
FAILED("FAILED"),
/** 达到告警阈值但仍允许继续重试。 */
ALERT("ALERT"),
/** 被业务明确取消。 */
CANCELLED("CANCELLED");
/** 任务表持久化编码。 */
private final String code;
/**
* 创建任务状态。
* @param code 持久化编码
*/
ThirdPaymentTaskStatusEnum(String code) {
this.code = code;
}
}
@@ -0,0 +1,66 @@
package com.bsd.pjcloud.thirdparty.constant.pay;
import lombok.Getter;
/**
* 第三方支付任务类型;编码持久化到 {@code third_payment_task.task_type},不可随意修改。
*/
@Getter
public enum ThirdPaymentTaskTypeEnum {
/** 支付订单创建或创建结果补偿。 */
PAY_CREATE("PAY_CREATE"),
/** App、订单码支付查单。 */
PAY_QUERY("PAY_QUERY"),
/** 普通退款查单。 */
REFUND_QUERY("REFUND_QUERY"),
/** 普通退款创建结果补偿。 */
REFUND_CREATE("REFUND_CREATE"),
/** 微信或支付宝分账创建/阶段推进。 */
FZ_CREATE("FZ_CREATE"),
/** 支付宝直付通确认结算;只推进确认结算阶段。 */
FZ_SETTLE_CONFIRM("FZ_SETTLE_CONFIRM"),
/** 支付宝直付通平台抽佣提交;成功受理后必须继续查询。 */
FZ_ROYALTY("FZ_ROYALTY"),
/** 支付宝直付通平台抽佣结果查询;只有最终成功才完成分账。 */
FZ_ROYALTY_QUERY("FZ_ROYALTY_QUERY"),
/** 分账查单。 */
FZ_QUERY("FZ_QUERY"),
/** 分账退款查单。 */
FZ_REFUND_QUERY("FZ_REFUND_QUERY"),
/** 支付或退款后的业务回调补偿。 */
BIZ_CALLBACK("BIZ_CALLBACK"),
/** 聚合支付会话补偿。 */
AGGREGATE_SESSION("AGGREGATE_SESSION"),
/** 历史订单码查单并在渠道确认后关闭。 */
PAY_CLOSE("PAY_CLOSE"),
/** 历史聚合支付会话本地关闭。 */
AGGREGATE_CLOSE("AGGREGATE_CLOSE"),
/** 对账任务预留类型。 */
RECONCILE("RECONCILE");
/** 任务表持久化编码。 */
private final String code;
/**
* 创建任务类型。
* @param code 持久化编码
*/
ThirdPaymentTaskTypeEnum(String code) {
this.code = code;
}
/**
* 按持久化编码解析任务类型。
* @param code 请求或数据库中的任务编码
* @return 匹配的任务类型
* @throws IllegalArgumentException 编码为空或未知时抛出
*/
public static ThirdPaymentTaskTypeEnum fromCode(String code) {
for (ThirdPaymentTaskTypeEnum value : values()) {
if (value.code.equals(code)) {
return value;
}
}
throw new IllegalArgumentException("不支持的支付任务类型:" + code);
}
}
@@ -6,6 +6,11 @@ import lombok.Data;
@Data
public class ThirdMiniRemotePayDto extends ThirdMiniAppPayDto {
/**
* 远程业务订单的可信收款商户 ID,由业务订单服务端读取并传递,禁止由客户端伪造。
*/
private Long mchId;
/**
* 用户id不能为空
*/
@@ -0,0 +1,26 @@
package com.bsd.pjcloud.thirdparty.dto.pay;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Quartz 分发支付任务的内部请求;不携带订单金额、密钥等敏感业务数据。
*/
@Data
public class ThirdPaymentTaskDispatchDto {
/** 本次分发动作编码。 */
@NotBlank(message = "任务动作不能为空")
private String taskType;
/** 最大领取数量。 */
@Min(value = 1, message = "批量大小必须大于0")
@Max(value = 500, message = "批量大小不能超过500")
private Integer batchSize = 100;
/** 触发来源,固定任务由 Quartz 传入。 */
private String triggerSource = "QUARTZ";
/** Quartz 触发时间。 */
private LocalDateTime triggerTime;
}
@@ -0,0 +1,50 @@
package com.bsd.pjcloud.thirdparty.entity.pay;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.bsd.pjcloud.common.core.util.TenantTable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 支付任务单次执行日志,只允许保存脱敏快照。
*/
@Data
@TenantTable
@TableName("third_payment_task_attempt")
@EqualsAndHashCode(callSuper = true)
public class ThirdPaymentTaskAttemptEntity extends Model<ThirdPaymentTaskAttemptEntity> {
/** 尝试主键。 */
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/** 任务主键。 */
private Long taskId;
/** 租户ID。 */
private Long tenantId;
/** 任务内序号。 */
private Integer attemptNo;
/** 触发来源。 */
private String triggerSource;
/** Worker实例标识。 */
private String workerId;
/** 执行租约令牌。 */
private String leaseToken;
/** 脱敏请求快照。 */
private String requestSnapshot;
/** 脱敏响应快照。 */
private String responseSnapshot;
/** 外部状态。 */
private String externalStatus;
/** 错误码。 */
private String errorCode;
/** 错误摘要。 */
private String errorMessage;
/** 开始时间。 */
private LocalDateTime startedTime;
/** 结束时间。 */
private LocalDateTime finishedTime;
}
@@ -0,0 +1,82 @@
package com.bsd.pjcloud.thirdparty.entity.pay;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.bsd.pjcloud.common.core.util.TenantTable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 支付任务事实,保存跨进程恢复所需的稳定业务号、租约和最近错误。
*/
@Data
@TenantTable
@TableName("third_payment_task")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "第三方支付任务")
public class ThirdPaymentTaskEntity extends Model<ThirdPaymentTaskEntity> {
/** 任务主键。 */
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/** 租户ID。 */
private Long tenantId;
/** 任务类型持久化编码。 */
private String taskType;
/** 租户内稳定幂等键。 */
private String taskKey;
/** 支付订单主键。 */
private Long payOrderId;
/** 分账订单主键。 */
private Long fzOrderId;
/** 聚合会话主键。 */
private Long aggregateSessionId;
/** 稳定支付单号。 */
private String payNo;
/** 稳定退款单号。 */
private String refundNo;
/** 稳定分账单号。 */
private String fzNo;
/** 稳定聚合会话号。 */
private String aggregateNo;
/** 当前任务状态。 */
private String status;
/** 下一次可执行时间。 */
private LocalDateTime nextRunTime;
/** 优先级,越大越优先。 */
private Integer priority;
/** Worker实例标识。 */
private String leaseOwner;
/** 当前租约令牌。 */
private String leaseToken;
/** 租约到期时间。 */
private LocalDateTime leaseExpireTime;
/** 累计尝试次数。 */
private Integer attemptCount;
/** 最近外部渠道状态。 */
private String lastExternalStatus;
/** 最近错误码。 */
private String lastErrorCode;
/** 最近错误摘要。 */
private String lastErrorMessage;
/** 任务终态时间。 */
private LocalDateTime finishedTime;
/** 创建人。 */
@TableField(fill = FieldFill.INSERT)
private String createBy;
/** 创建时间。 */
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/** 修改人。 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/** 修改时间。 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/** 逻辑删除标记。 */
@TableLogic
@TableField(fill = FieldFill.INSERT)
private String delFlag;
}
@@ -91,6 +91,11 @@ public class ThirdMiniWechatRefundQueryVo {
*/
private Long refund_fee;
/**
* 微信支付 V3 退款查询状态,取值为 SUCCESS、CLOSED、PROCESSING 或 ABNORMAL;旧 V2 字段保持兼容。
*/
private String refund_status;
public boolean isHttpSucess() {
return ObjectUtil.equals(ThirdMiniWechatRefundQueryVo.SUCCESS, err_code) || ObjectUtil.isEmpty(err_code);
}
@@ -3,13 +3,110 @@ package com.bsd.pjcloud.thirdparty.vo.pay;
import com.bsd.pjcloud.thirdparty.entity.pay.ThirdPayOrderEntity;
import lombok.Data;
/**
* 第三方支付订单管理端视图,补充商户与分账阶段信息且不暴露商户支付密钥快照。
*/
@Data
public class ThirdPayOrderVo extends ThirdPayOrderEntity {
/**
* 支付订单所属商户名称,来源于商户管理服务;商户已删除或不可见时为空。
*/
private String mchName;
/**
* 支付用户姓名,来源于用户服务;匿名支付或用户已不存在时为空。
*/
private String username;
/**
* 支付用户手机号,来源于用户服务;匿名支付或未登记手机号时为空。
*/
private String userPhone;
/**
* 支付宝直付通二级商户标识,来源于订单创建时保存的商户配置快照;非支付宝订单为空。
*/
private String smid;
/**
* 分账订单持久化状态编码,沿用 third_fz_order.status;未创建分账记录时为空。
*/
private String fzStatus;
/**
* 支付宝确认结算阶段状态;微信为 NOT_APPLICABLE,未启用分账为 NOT_CONFIGURED。
*/
private String settleConfirmStatus;
/**
* 平台抽佣阶段状态,取值为 PENDING、PROCESSING、SUCCESS、FAILED 或 NOT_CONFIGURED。
*/
private String royaltyStatus;
/**
* 退分账阶段状态,取值为 NOT_STARTED、PROCESSING、SUCCESS、FAILED 或 NOT_CONFIGURED。
*/
private String fzRefundStatus;
/**
* 支付宝确认结算请求 JSON;尚未发起或非支付宝订单时为空。
*/
private String settleConfirmReq;
/**
* 支付宝确认结算响应 JSON;尚未获得响应或非支付宝订单时为空。
*/
private String settleConfirmRes;
/**
* 支付宝确认结算错误 JSON;无错误或非支付宝订单时为空。
*/
private String settleConfirmError;
/**
* 平台抽佣请求 JSON,支付宝和微信均从结构化分账快照读取。
*/
private String royaltyReq;
/**
* 平台抽佣响应 JSON,支付宝和微信均从结构化分账快照读取。
*/
private String royaltyRes;
/**
* 平台抽佣错误 JSON;无错误时为空。
*/
private String royaltyError;
/**
* 退分账请求 JSON,来源于分账退款阶段快照或兼容的历史请求字段。
*/
private String fzRefundReq;
/**
* 退分账响应 JSON,来源于分账退款阶段快照或兼容的历史响应字段。
*/
private String fzRefundRes;
/**
* 退分账错误 JSON;无错误时为空。
*/
private String fzRefundError;
/** 当前支付主任务状态,来源于 third_payment_task;无任务时为空。 */
private String taskStatus;
/** 当前支付主任务主键,管理端人工重试必须使用该 ID 而不是支付订单主键。 */
private Long taskId;
/** 当前支付主任务下一次执行时间,来源于任务表。 */
private java.time.LocalDateTime taskNextRunTime;
/** 当前支付主任务累计尝试次数。 */
private Integer taskAttemptCount;
/** 当前支付主任务最近错误摘要,已限制长度且不含密钥。 */
private String taskLastError;
}
@@ -0,0 +1,22 @@
package com.bsd.pjcloud.thirdparty.vo.pay;
import lombok.Builder;
import lombok.Data;
/**
* thirdparty 任务分发结果,供 Quartz 判断服务是否接受本轮触发。
*/
@Data
@Builder
public class ThirdPaymentTaskDispatchVo {
/** 已接收任务数。 */
private int acceptedCount;
/** 成功取得租约的任务数。 */
private int claimedCount;
/** 当前 Worker 正在执行数量。 */
private int processingCount;
/** 队列是否达到容量上限。 */
private boolean busy;
/** 当前待执行任务积压量。 */
private long backlogCount;
}