diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/express/ExpressService.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/express/ExpressService.java index d6438da63..8158d5b8a 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/express/ExpressService.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/express/ExpressService.java @@ -36,10 +36,10 @@ public void setProperties(ExpressProperties properties) { } /** - * 获取物流供应商名 + * 根据供应商编码获取物流供应商名称。 * - * @param vendorCode - * @return + * @param vendorCode 物流供应商编码 + * @return 供应商名称;未找到时返回 {@code null} */ public String getVendorName(String vendorCode) { for (Map item : properties.getVendors()) { @@ -54,11 +54,11 @@ public List> getVendors() { } /** - * 获取物流信息 + * 查询指定物流单的物流信息。未启用物流查询或查询失败时返回 {@code null}。 * - * @param expCode - * @param expNo - * @return + * @param expCode 物流供应商编码 + * @param expNo 物流单号 + * @return 物流信息;未启用或查询失败时返回 {@code null} */ public ExpressInfo getExpressInfo(String expCode, String expNo) { if (!properties.isEnable()) { @@ -79,9 +79,12 @@ public ExpressInfo getExpressInfo(String expCode, String expNo) { } /** - * Json方式 查询订单物流轨迹 + * 以 JSON 格式请求物流轨迹。 * - * @throws Exception + * @param expCode 物流供应商编码 + * @param expNo 物流单号 + * @return 物流查询接口返回的 JSON + * @throws Exception 请求编码或 HTTP 请求失败时抛出 */ private String getOrderTracesByJson(String expCode, String expNo) throws Exception { String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}"; @@ -96,17 +99,16 @@ private String getOrderTracesByJson(String expCode, String expNo) throws Excepti String result = HttpUtil.sendPost(ReqURL, params); - //根据公司业务处理返回的信息...... - return result; } /** - * MD5加密 + * 使用指定字符集计算字符串的 MD5 摘要。 * - * @param str 内容 - * @param charset 编码方式 - * @throws Exception + * @param str 待摘要的内容 + * @param charset 字符编码 + * @return 小写十六进制摘要 + * @throws Exception 无法获取 MD5 算法或字符编码时抛出 */ private String MD5(String str, String charset) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressProperties.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressProperties.java index 034cf963c..d65d82894 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressProperties.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressProperties.java @@ -6,6 +6,9 @@ import java.util.List; import java.util.Map; +/** + * 快递查询服务的配置属性,对应 {@code litemall.express} 配置项。 + */ @ConfigurationProperties(prefix = "litemall.express") public class ExpressProperties { private boolean enable; @@ -13,34 +16,74 @@ public class ExpressProperties { private String appKey; private List> vendors = new ArrayList<>(); + /** + * 返回是否启用快递查询。 + * + * @return 启用时为 {@code true} + */ public boolean isEnable() { return enable; } + /** + * 设置是否启用快递查询。 + * + * @param enable 是否启用 + */ public void setEnable(boolean enable) { this.enable = enable; } + /** + * 返回快递供应商列表。每项使用 {@code code} 和 {@code name} 分别表示供应商编码和名称。 + * + * @return 快递供应商配置列表 + */ public List> getVendors() { return vendors; } + /** + * 设置快递供应商列表。 + * + * @param vendors 快递供应商配置列表,每项包含供应商编码和名称 + */ public void setVendors(List> vendors) { this.vendors = vendors; } + /** + * 返回快递服务的应用密钥。 + * + * @return 应用密钥 + */ public String getAppKey() { return appKey; } + /** + * 设置快递服务的应用密钥。 + * + * @param appKey 应用密钥 + */ public void setAppKey(String appKey) { this.appKey = appKey; } + /** + * 返回快递服务的应用标识。 + * + * @return 应用标识 + */ public String getAppId() { return appId; } + /** + * 设置快递服务的应用标识。 + * + * @param appId 应用标识 + */ public void setAppId(String appId) { this.appId = appId; } diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderMapper.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderMapper.java index d964bdf5c..9d6f82813 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderMapper.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderMapper.java @@ -5,148 +5,152 @@ import org.linlinjava.litemall.db.domain.LitemallOrder; import org.linlinjava.litemall.db.domain.LitemallOrderExample; +/** + * 订单表(litemall_order)的 MyBatis Mapper 接口。 + * + *

方法由 MyBatis Generator 生成,分两类:xxxByExample 面向动态条件查询与批量操作, + * xxxByPrimaryKey 面向主键单条操作。本接口只负责 SQL 映射, + * 订单状态是否允许流转等业务规则在 LitemallOrderService 及其上层实现。 + * + *

注意:按主键或按条件的查询不会自动过滤 deleted 字段, + * 需要排除已逻辑删除的订单时,请使用 xxxWithLogicalDelete 系列或自行带 deleted 条件。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ public interface LitemallOrderMapper { /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件统计订单数量。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 匹配的记录数 */ long countByExample(LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件物理删除订单。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 影响行数;业务删除请改用 logicalDeleteByExample */ int deleteByExample(LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键物理删除订单。 + * @param id 订单主键 + * @return 影响行数;业务删除请改用 logicalDeleteByPrimaryKey */ int deleteByPrimaryKey(Integer id); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 插入一条订单,写入全部字段(null 会覆盖数据库默认值)。 + * @param record 订单实体,非 null + * @return 影响行数;业务插入请改用 insertSelective */ int insert(LitemallOrder record); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 插入一条订单,只写入对象中非 null 的字段,保留数据库默认值。 + * @param record 订单实体,非 null + * @return 影响行数;业务写入推荐使用本方法 */ int insertSelective(LitemallOrder record); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件查询单条订单。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 订单;无匹配时返回 null */ LitemallOrder selectOneByExample(LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件查询单条订单,只返回指定列。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @param selective 需要返回的列集合,不传表示全部列 + * @return 订单;无匹配时返回 null */ LitemallOrder selectOneByExampleSelective(@Param("example") LitemallOrderExample example, @Param("selective") LitemallOrder.Column ... selective); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件查询订单列表,只返回指定列,用于避免查询大字段。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @param selective 需要返回的列集合,不传表示全部列 + * @return 订单列表 */ List selectByExampleSelective(@Param("example") LitemallOrderExample example, @Param("selective") LitemallOrder.Column ... selective); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件查询订单列表。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 订单列表 */ List selectByExample(LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键查询单条订单,只返回指定列。 + * @param id 订单主键 + * @param selective 需要返回的列集合,不传表示全部列 + * @return 订单;不存在时返回 null */ LitemallOrder selectByPrimaryKeySelective(@Param("id") Integer id, @Param("selective") LitemallOrder.Column ... selective); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order + * 按主键查询单条订单。 * - * @mbg.generated + *

注意:本方法不过滤 deleted 字段,已逻辑删除的订单同样会返回; + * 下单校验、支付回调等场景应改用带 deleted = 0 条件的查询。 + * @param id 订单主键 + * @return 订单;记录不存在时返回 null,调用方必须判空 */ LitemallOrder selectByPrimaryKey(Integer id); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键查询单条订单,并显式指定是否包含已逻辑删除的记录。 + * @param id 订单主键 + * @param andLogicalDeleted true 只查已删除记录,false 只查未删除记录 + * @return 订单;不存在时返回 null */ LitemallOrder selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer id, @Param("andLogicalDeleted") boolean andLogicalDeleted); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件更新订单,只更新对象中非 null 的字段。 + * @param record 订单实体,非 null + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 影响行数 */ int updateByExampleSelective(@Param("record") LitemallOrder record, @Param("example") LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件更新订单全部字段,未赋值字段会被写成 null,慎用。 + * @param record 订单实体,非 null + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 影响行数;业务更新推荐 updateByExampleSelective */ int updateByExample(@Param("record") LitemallOrder record, @Param("example") LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键更新订单,只更新对象中非 null 的字段。 + * @param record 订单实体,非 null + * @return 影响行数;业务更新推荐使用本方法 */ int updateByPrimaryKeySelective(LitemallOrder record); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键更新订单全部字段。 + * @param record 订单实体,非 null + * @return 影响行数;未赋值字段会被覆盖,慎用 */ int updateByPrimaryKey(LitemallOrder record); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按条件逻辑删除订单(deleted 置 1),保留数据用于对账与审计。 + * @param example 查询条件(LitemallOrderExample),可为 null + * @return 影响行数 */ int logicalDeleteByExample(@Param("example") LitemallOrderExample example); /** - * This method was generated by MyBatis Generator. - * This method corresponds to the database table litemall_order - * - * @mbg.generated + * 按主键逻辑删除订单(deleted 置 1)。 + * @param id 订单主键 + * @return 影响行数 */ int logicalDeleteByPrimaryKey(Integer id); } \ No newline at end of file diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrder.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrder.java index 199083d63..69fe0859a 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrder.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrder.java @@ -5,300 +5,118 @@ import java.util.ArrayList; import java.util.Arrays; +/** + * 订单实体,对应数据库表 litemall_order。 + * + *

一条记录对应一次下单行为,金额字段之间的关系见 orderPrice / actualPrice 的字段注释; + * 订单状态由 OrderUtil 中的常量定义(101 待付款 → 201 待发货 → 301 待收货 → 401 已完成)。 + * 表使用逻辑删除:deleted = 0 有效、deleted = 1 已删除,查询必须显式过滤。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ public class LitemallOrder { - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_order - * - * @mbg.generated - */ + /** 逻辑删除“已删除”值(true),供 Example 条件构造器使用 */ public static final Boolean IS_DELETED = Deleted.IS_DELETED.value(); - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_order - * - * @mbg.generated - */ + /** 逻辑删除“未删除”值(false),供 Example 条件构造器使用 */ public static final Boolean NOT_DELETED = Deleted.NOT_DELETED.value(); - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.id - * - * @mbg.generated - */ + /** 主键,自增;订单商品、售后单等表以该值做外键关联 */ private Integer id; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.user_id - * - * @mbg.generated - */ + /** 下单用户 ID(litemall_user.id);非空 */ private Integer userId; /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.order_sn - * - * @mbg.generated + * 订单编号,业务唯一标识;格式为 yyyyMMdd + 6 位随机数,生成逻辑见 LitemallOrderService.generateOrderSn;非空,长度上限 63 */ private String orderSn; /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.order_status - * - * @mbg.generated + * 订单状态:101 待付款、102 用户取消、103 超时取消、201 待发货、202 退款中、203 已退款、204 团购超时、301 待收货、401 已完成、402 系统自动确认收货;非空 */ private Short orderStatus; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.aftersale_status - * - * @mbg.generated - */ + /** 售后状态:0 可申请、1 用户已申请、2 审核通过、3 退款成功、4 审核拒绝、5 用户已取消;默认 0 */ private Short aftersaleStatus; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.consignee - * - * @mbg.generated - */ + /** 收货人姓名,下单时快照;非空,长度上限 63 */ private String consignee; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.mobile - * - * @mbg.generated - */ + /** 收货人手机号,下单时快照;非空,长度上限 63 */ private String mobile; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.address - * - * @mbg.generated - */ + /** 收货详细地址,下单时快照;非空,长度上限 127 */ private String address; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.message - * - * @mbg.generated - */ + /** 买家留言;非空,默认空串,长度上限 512 */ private String message; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.goods_price - * - * @mbg.generated - */ + /** 商品总金额(未减优惠);非空 */ private BigDecimal goodsPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.freight_price - * - * @mbg.generated - */ + /** 配送费用;非空 */ private BigDecimal freightPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.coupon_price - * - * @mbg.generated - */ + /** 优惠券抵扣金额;非空 */ private BigDecimal couponPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.integral_price - * - * @mbg.generated - */ + /** 积分抵扣金额;非空 */ private BigDecimal integralPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.groupon_price - * - * @mbg.generated - */ + /** 团购优惠金额;非空 */ private BigDecimal grouponPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.order_price - * - * @mbg.generated - */ + /** 应付金额 = goods_price + freight_price - coupon_price;非空 */ private BigDecimal orderPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.actual_price - * - * @mbg.generated - */ + /** 实付金额 = order_price - integral_price;非空 */ private BigDecimal actualPrice; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.pay_id - * - * @mbg.generated - */ + /** 微信支付单号,支付回调时写入 */ private String payId; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.pay_time - * - * @mbg.generated - */ + /** 支付时间 */ private LocalDateTime payTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.ship_sn - * - * @mbg.generated - */ + /** 发货单号(快递单号) */ private String shipSn; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.ship_channel - * - * @mbg.generated - */ + /** 快递公司名称 */ private String shipChannel; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.ship_time - * - * @mbg.generated - */ + /** 发货时间 */ private LocalDateTime shipTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.refund_amount - * - * @mbg.generated - */ + /** 实际退款金额;可能小于实付金额 */ private BigDecimal refundAmount; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.refund_type - * - * @mbg.generated - */ + /** 退款方式(如微信原路退回) */ private String refundType; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.refund_content - * - * @mbg.generated - */ + /** 退款备注;长度上限 127 */ private String refundContent; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.refund_time - * - * @mbg.generated - */ + /** 退款时间 */ private LocalDateTime refundTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.confirm_time - * - * @mbg.generated - */ + /** 用户确认收货时间,评价超期判断依赖该字段 */ private LocalDateTime confirmTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.comments - * - * @mbg.generated - */ + /** 待评价商品数量;0 表示已全部评价;默认 0 */ private Short comments; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.end_time - * - * @mbg.generated - */ + /** 订单关闭时间(完成或取消时写入) */ private LocalDateTime endTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.add_time - * - * @mbg.generated - */ + /** 创建时间,由 Service 在写入时赋值 */ private LocalDateTime addTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.update_time - * - * @mbg.generated - */ + /** 更新时间,同时作为乐观锁的版本号,见 updateWithOptimisticLocker */ private LocalDateTime updateTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order.deleted - * - * @mbg.generated - */ + /** 逻辑删除标记:0 未删除、1 已删除;删除订单只置位,保留数据用于对账与售后 */ private Boolean deleted; /** diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrderGoods.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrderGoods.java index 8a996e6ea..ad98a0d31 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrderGoods.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallOrderGoods.java @@ -5,147 +5,62 @@ import java.util.ArrayList; import java.util.Arrays; +/** + * 订单商品实体,对应数据库表 litemall_order_goods。 + * + *

一个订单对应多条记录。下单时把商品名称、编号、单价、规格、图片复制一份存入本表, + * 形成“交易快照”:商品后续改名、改价、下架都不影响历史订单的展示与对账。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ public class LitemallOrderGoods { - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_order_goods - * - * @mbg.generated - */ + /** 逻辑删除“已删除”值(true),供 Example 条件构造器使用 */ public static final Boolean IS_DELETED = Deleted.IS_DELETED.value(); - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_order_goods - * - * @mbg.generated - */ + /** 逻辑删除“未删除”值(false),供 Example 条件构造器使用 */ public static final Boolean NOT_DELETED = Deleted.NOT_DELETED.value(); - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.id - * - * @mbg.generated - */ + /** 主键,自增 */ private Integer id; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.order_id - * - * @mbg.generated - */ + /** 所属订单 ID(litemall_order.id);非空 */ private Integer orderId; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.goods_id - * - * @mbg.generated - */ + /** 商品 ID(litemall_goods.id);非空 */ private Integer goodsId; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.goods_name - * - * @mbg.generated - */ + /** 下单时的商品名称快照;非空,长度上限 127 */ private String goodsName; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.goods_sn - * - * @mbg.generated - */ + /** 下单时的商品编号快照;非空,长度上限 63 */ private String goodsSn; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.product_id - * - * @mbg.generated - */ + /** 货品 ID(litemall_goods_product.id),同一商品不同规格对应不同货品;非空 */ private Integer productId; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.number - * - * @mbg.generated - */ + /** 购买数量;非空 */ private Short number; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.price - * - * @mbg.generated - */ + /** 下单时的商品单价快照;非空 */ private BigDecimal price; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.specifications - * - * @mbg.generated - */ + /** 规格列表,以 JSON 数组字符串存库(由 JsonStringArrayTypeHandler 转换);非空 */ private String[] specifications; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.pic_url - * - * @mbg.generated - */ + /** 下单时的商品图片快照;非空,长度上限 255 */ private String picUrl; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.comment - * - * @mbg.generated - */ + /** 评价标记:-1 已超期不可评价、0 可评价、其他值为 litemall_comment.id;默认 0 */ private Integer comment; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.add_time - * - * @mbg.generated - */ + /** 创建时间,由 Service 在写入时赋值 */ private LocalDateTime addTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.update_time - * - * @mbg.generated - */ + /** 更新时间,每次修改由 Service 刷新 */ private LocalDateTime updateTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_order_goods.deleted - * - * @mbg.generated - */ + /** 逻辑删除标记:0 未删除、1 已删除 */ private Boolean deleted; /** diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallUser.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallUser.java index 2da90579b..759c1d973 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallUser.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallUser.java @@ -5,174 +5,71 @@ import java.util.ArrayList; import java.util.Arrays; +/** + * 会员实体,对应数据库表 litemall_user。 + * + *

该表存放小程序与 H5 端注册的普通用户,与后台管理员(litemall_admin)是两套账号体系。 + * 表使用逻辑删除:deleted = 0 有效、deleted = 1 已删除,业务查询必须显式带 deleted = 0。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ public class LitemallUser { - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_user - * - * @mbg.generated - */ + /** 逻辑删除“已删除”值(true),供 Example 条件构造器使用 */ public static final Boolean IS_DELETED = Deleted.IS_DELETED.value(); - /** - * This field was generated by MyBatis Generator. - * This field corresponds to the database table litemall_user - * - * @mbg.generated - */ + /** 逻辑删除“未删除”值(false),供 Example 条件构造器使用 */ public static final Boolean NOT_DELETED = Deleted.NOT_DELETED.value(); - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.id - * - * @mbg.generated - */ + /** 主键,自增;订单、购物车、收货地址、收藏等表以该值做外键关联 */ private Integer id; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.username - * - * @mbg.generated - */ + /** 登录名称;非空,长度上限 63,全表唯一(唯一索引 user_name) */ private String username; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.password - * - * @mbg.generated - */ + /** 密码;后台建号时写入 BCrypt 哈希,小程序用户走微信登录自动注册通常为空串,禁止存明文 */ private String password; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.gender - * - * @mbg.generated - */ + /** 性别:0 未知、1 男、2 女(DB COMMENT 中“1男,1女”属笔误,以本注释为准);非空,默认 0 */ private Byte gender; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.birthday - * - * @mbg.generated - */ + /** 生日 */ private LocalDate birthday; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.last_login_time - * - * @mbg.generated - */ + /** 最近一次登录时间 */ private LocalDateTime lastLoginTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.last_login_ip - * - * @mbg.generated - */ + /** 最近一次登录IP地址;非空,长度上限 63 */ private String lastLoginIp; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.user_level - * - * @mbg.generated - */ + /** 用户等级:0 普通用户、1 VIP 用户、2 高级 VIP 用户;默认 0 */ private Byte userLevel; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.nickname - * - * @mbg.generated - */ + /** 昵称;非空,长度上限 63,展示在评价与订单页面 */ private String nickname; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.mobile - * - * @mbg.generated - */ + /** 手机号码;非空,长度上限 20,用于登录与订单通知 */ private String mobile; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.avatar - * - * @mbg.generated - */ + /** 头像图片地址;非空,长度上限 255 */ private String avatar; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.weixin_openid - * - * @mbg.generated - */ + /** 微信登录 openid,用于把微信账号与站内用户绑定 */ private String weixinOpenid; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.session_key - * - * @mbg.generated - */ + /** 微信登录会话密钥,只在服务端使用,禁止返回给前端 */ private String sessionKey; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.status - * - * @mbg.generated - */ + /** 账号状态:0 可用、1 禁用、2 注销;非空,默认 0,登录与下单前都会校验 */ private Byte status; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.add_time - * - * @mbg.generated - */ + /** 创建时间,由 Service 在写入时赋值 */ private LocalDateTime addTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.update_time - * - * @mbg.generated - */ + /** 更新时间,每次修改由 Service 刷新 */ private LocalDateTime updateTime; - /** - * - * This field was generated by MyBatis Generator. - * This field corresponds to the database column litemall_user.deleted - * - * @mbg.generated - */ + /** 逻辑删除标记:0 未删除、1 已删除;删除用户只置位不做物理删除,查询必须带 deleted = 0 */ private Boolean deleted; /** diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/mybatis/JsonIntegerArrayTypeHandler.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/mybatis/JsonIntegerArrayTypeHandler.java index 1c1e81880..866b1c42e 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/mybatis/JsonIntegerArrayTypeHandler.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/mybatis/JsonIntegerArrayTypeHandler.java @@ -9,8 +9,22 @@ import java.sql.ResultSet; import java.sql.SQLException; -/* - +/** + * Integer 数组与 JSON 字符串之间的 MyBatis 类型处理器。 + * + *

用于把数据库中以 JSON 形式存储的整型数组列映射为 Java 的 Integer[], + * 例如 litemall_admin.role_ids、litemall_topic.goods、litemall_coupon.goods_value。 + * 需要在 mybatis-generator/generatorConfig.xml 中通过 columnOverride 指定: + * + *

+ * <columnOverride column="role_ids" javaType="java.lang.Integer[]"
+ *     typeHandler="org.linlinjava.litemall.db.mybatis.JsonIntegerArrayTypeHandler"/>
+ * 
+ * + *

注意:序列化失败时 toJson 返回 "[]" 而不是抛异常,可能与“确实为空数组”混淆。 + * + * @author lvweihao0403 + * @since 1.0.0 */ public class JsonIntegerArrayTypeHandler extends BaseTypeHandler { private static final ObjectMapper mapper = new ObjectMapper(); diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/CouponVerifyService.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/CouponVerifyService.java index 72e56db17..ae3cab729 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/CouponVerifyService.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/CouponVerifyService.java @@ -22,12 +22,20 @@ public class CouponVerifyService { private LitemallGoodsService goodsService; /** - * 检测优惠券是否适合 + * 校验优惠券对当前订单是否可用,可用则返回券信息,否则返回 null。 * - * @param userId - * @param couponId - * @param checkedGoodsPrice - * @return + *

依次校验:券是否存在且未删除、归属是否正确、是否过期、 + * 商品或分类是否符合适用范围、券本身是否启用、是否达到最低消费。 + * 任何一步不通过都返回 null,不区分具体原因,调用方无法据此给出差异化提示; + * 若需要精确提示,应在调用方分段校验。 + * + * @param userId 下单用户 ID + * @param couponId 优惠券模板 ID(litemall_coupon.id) + * @param userCouponId 用户已领取的券记录 ID(litemall_coupon_user.id),可为 null, + * 为 null 时按 userId + couponId 查询一条可用记录 + * @param checkedGoodsPrice 购物车中参与结算的商品总价(已扣除不可用券商品) + * @param cartList 本次结算的购物车明细,用于计算适用范围与满减门槛 + * @return 可用的优惠券实体;不可用时返回 null */ public LitemallCoupon checkCoupon(Integer userId, Integer couponId, Integer userCouponId, BigDecimal checkedGoodsPrice, List cartList) { LitemallCoupon coupon = couponService.findById(couponId); diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallAftersaleService.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallAftersaleService.java index 17a0fe639..ff57d8c9c 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallAftersaleService.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallAftersaleService.java @@ -89,7 +89,16 @@ public int countByAftersaleSn(Integer userId, String aftersaleSn) { return (int) aftersaleMapper.countByExample(example); } - // TODO 这里应该产生一个唯一的编号,但是实际上这里仍然存在两个售后编号相同的可能性 + /** + * 生成售后编号:yyyyMMdd + 6 位随机数字。 + * + *

已知风险:编号生成后只做一次查重,并发申请时仍可能重复, + * 且 litemall_aftersale.aftersale_sn 没有唯一索引兜底; + * 后续应改为“日期 + 自增序列”等强唯一方案(原 TODO 已转入本注释)。 + * + * @param userId 申请售后的用户 ID,用于限定查重范围 + * @return 售后编号,形如 20261017004217 + */ public String generateAftersaleSn(Integer userId) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd"); String now = df.format(LocalDate.now()); diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java index d1f60e232..de5618df6 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java @@ -17,6 +17,18 @@ import java.time.format.DateTimeFormatter; import java.util.*; +/** + * 订单数据服务:封装 litemall_order 的读写、分页查询与按状态统计。 + * + *

本类只做数据访问与查询条件组装,不校验状态流转是否合法; + * 支付、发货、取消等规则由 admin-api / wx-api 层的业务服务调用本类完成。 + * + *

所有查询默认过滤 deleted = 0,删除操作只做逻辑删除(deleted = 1), + * 保留订单数据用于对账与售后追溯。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ @Service public class LitemallOrderService { @Resource @@ -24,28 +36,62 @@ public class LitemallOrderService { @Resource private OrderMapper orderMapper; + /** + * 新增订单,写入时自动补 addTime 与 updateTime。 + * + * @param order 订单实体,金额、状态由调用方填写 + * @return 影响行数 + */ public int add(LitemallOrder order) { order.setAddTime(LocalDateTime.now()); order.setUpdateTime(LocalDateTime.now()); return litemallOrderMapper.insertSelective(order); } + /** + * 统计某用户的订单总数。 + * + * @param userId 用户 ID + * @return 该用户的有效订单数(已过滤逻辑删除) + */ public int count(Integer userId) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false); return (int) litemallOrderMapper.countByExample(example); } + /** + * 按订单主键查询(不区分用户)。 + * + *

供支付回调、定时任务等内部流程使用,不过滤逻辑删除; + * 面向用户的查询请使用 findById(userId, orderId)。 + * + * @param orderId 订单主键 + * @return 订单;不存在时返回 null + */ public LitemallOrder findById(Integer orderId) { return litemallOrderMapper.selectByPrimaryKey(orderId); } + /** + * 按“用户 + 订单”查询,保证用户只能查到自己的订单,并过滤已逻辑删除的记录。 + * + * @param userId 用户 ID + * @param orderId 订单主键 + * @return 订单;不属于该用户或已删除时返回 null + */ public LitemallOrder findById(Integer userId, Integer orderId) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andIdEqualTo(orderId).andUserIdEqualTo(userId).andDeletedEqualTo(false); return litemallOrderMapper.selectOneByExample(example); } + /** + * 生成指定位数的纯数字随机串,仅用于拼接订单编号。 + * + * @param num 位数 + * @return 由 0-9 组成的定长字符串 + */ private String getRandomNum(Integer num) { String base = "0123456789"; Random random = new Random(); @@ -57,13 +103,30 @@ private String getRandomNum(Integer num) { return sb.toString(); } + /** + * 统计某用户下指定订单编号的记录数,用于生成编号时查重。 + * + * @param userId 用户 ID + * @param orderSn 订单编号 + * @return 匹配的记录数,0 表示编号可用 + */ public int countByOrderSn(Integer userId, String orderSn) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false); return (int) litemallOrderMapper.countByExample(example); } - // TODO 这里应该产生一个唯一的订单,但是实际上这里仍然存在两个订单相同的可能性 + /** + * 生成订单编号:yyyyMMdd + 6 位随机数字。 + * + *

生成后会查询该用户下是否已存在同一编号,重复则重新生成。 + * 已知风险:两次校验之间若有并发插入,仍可能产生重复编号, + * 且 litemall_order.order_sn 目前没有唯一索引兜底; + * 后续应改为“日期 + 自增序列”等强唯一方案(原 TODO 已转入本注释)。 + * + * @param userId 下单用户 ID,用于限定编号查重范围 + * @return 订单编号,形如 20261017004217 + */ public String generateOrderSn(Integer userId) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd"); String now = df.format(LocalDate.now()); @@ -74,6 +137,17 @@ public String generateOrderSn(Integer userId) { return orderSn; } + /** + * 按状态集合分页查询某用户的订单,默认按下单时间倒序。 + * + * @param userId 用户 ID + * @param orderStatus 订单状态集合,null 表示不限状态 + * @param page 页码,从 1 开始 + * @param limit 每页条数 + * @param sort 排序字段,与 order 同时非空时生效 + * @param order asc 或 desc + * @return 当前页订单列表 + */ public List queryByOrderStatus(Integer userId, List orderStatus, Integer page, Integer limit, String sort, String order) { LitemallOrderExample example = new LitemallOrderExample(); example.setOrderByClause(LitemallOrder.Column.addTime.desc()); @@ -91,6 +165,22 @@ public List queryByOrderStatus(Integer userId, List orderS return litemallOrderMapper.selectByExample(example); } + /** + * 后台多条件分页查询订单:用户、订单号、下单时间区间、状态集合。 + * + *

条件之间是“与”的关系;为空的参数不参与筛选。 + * + * @param userId 用户 ID,可为 null + * @param orderSn 订单编号,精确匹配 + * @param start 下单时间下限(含) + * @param end 下单时间上限(含) + * @param orderStatusArray 状态集合,null 或空表示不限 + * @param page 页码 + * @param limit 每页条数 + * @param sort 排序字段 + * @param order 排序方向 + * @return 当前页订单列表 + */ public List querySelective(Integer userId, String orderSn, LocalDateTime start, LocalDateTime end, List orderStatusArray, Integer page, Integer limit, String sort, String order) { LitemallOrderExample example = new LitemallOrderExample(); LitemallOrderExample.Criteria criteria = example.createCriteria(); @@ -120,33 +210,70 @@ public List querySelective(Integer userId, String orderSn, LocalD return litemallOrderMapper.selectByExample(example); } + /** + * 以 updateTime 作为版本号做乐观锁更新,避免并发写覆盖。 + * + *

调用方需传入“读取时的 updateTime”,方法内部会先把它刷新为当前时间再执行更新; + * 返回 0 表示该订单在读取后被其它事务修改过,应提示用户重试。 + * + * @param order 待更新订单,必须携带 id 与读取时的 updateTime + * @return 影响行数,0 表示版本冲突 + */ public int updateWithOptimisticLocker(LitemallOrder order) { LocalDateTime preUpdateTime = order.getUpdateTime(); order.setUpdateTime(LocalDateTime.now()); return orderMapper.updateWithOptimisticLocker(preUpdateTime, order); } + /** + * 按主键更新非 null 字段,不做乐观锁校验。 + * + * @param order 待更新订单,至少包含 id + * @return 影响行数 + */ public int updateSelective(LitemallOrder order) { return litemallOrderMapper.updateByPrimaryKeySelective(order); } + /** + * 逻辑删除订单:只把 deleted 置为 true,数据保留用于对账与售后。 + * + * @param id 订单主键 + */ public void deleteById(Integer id) { litemallOrderMapper.logicalDeleteByPrimaryKey(id); } + /** + * 统计全部有效订单数。 + * + * @return 订单总数(已过滤逻辑删除) + */ public int count() { LitemallOrderExample example = new LitemallOrderExample(); example.or().andDeletedEqualTo(false); return (int) litemallOrderMapper.countByExample(example); } + /** + * 查询超过指定分钟仍未支付的订单,供定时任务自动关闭。 + * + * @param minutes 超时分钟数 + * @return 待关闭的订单列表 + */ public List queryUnpaid(int minutes) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false); return litemallOrderMapper.selectByExample(example); } + /** + * 查询发货后超过指定天数仍未确认收货的订单,供系统自动确认收货。 + * + * @param days 允许的最大未确认天数 + * @return 待自动确认的订单列表 + */ public List queryUnconfirm(int days) { LocalDateTime now = LocalDateTime.now(); LocalDateTime expired = now.minusDays(days); @@ -155,12 +282,28 @@ public List queryUnconfirm(int days) { return litemallOrderMapper.selectByExample(example); } + /** + * 按订单编号查询(全局,不区分用户),供支付回调按商户订单号找回订单。 + * + * @param orderSn 订单编号 + * @return 订单;不存在时返回 null + */ public LitemallOrder findBySn(String orderSn) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andOrderSnEqualTo(orderSn).andDeletedEqualTo(false); return litemallOrderMapper.selectOneByExample(example); } + /** + * 统计用户在“我的订单”各页签的数量,用于页签角标。 + * + *

返回 Map 的键固定为:unpaid 待付款、unship 待发货、 + * unrecv 待收货、uncomment 待评价商品数(累加订单的 comments 字段)。 + * 键名是与前端约定的契约,不可随意改名。 + * + * @param userId 用户 ID + * @return 上述 4 个键的统计结果 + */ public Map orderInfo(Integer userId) { LitemallOrderExample example = new LitemallOrderExample(); example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false); @@ -180,7 +323,7 @@ public Map orderInfo(Integer userId) { } else if (OrderUtil.isConfirmStatus(order) || OrderUtil.isAutoConfirmStatus(order)) { uncomment += order.getComments(); } else { - // do nothing + // 已取消、已退款、已完成等状态不属于任何待办页签,不计入角标 } } @@ -193,6 +336,12 @@ public Map orderInfo(Integer userId) { } + /** + * 查询确认收货超过指定天数但仍有待评价商品的订单,用于关闭评价入口。 + * + * @param days 允许评价的最大天数 + * @return 待处理的订单列表 + */ public List queryComment(int days) { LocalDateTime now = LocalDateTime.now(); LocalDateTime expired = now.minusDays(days); @@ -201,6 +350,12 @@ public List queryComment(int days) { return litemallOrderMapper.selectByExample(example); } + /** + * 只更新订单的售后状态,避免整行覆盖其它字段。 + * + * @param orderId 订单主键 + * @param statusReject 售后状态码,取值见 LitemallOrder.aftersaleStatus 注释 + */ public void updateAftersaleStatus(Integer orderId, Short statusReject) { LitemallOrder order = new LitemallOrder(); order.setId(orderId); @@ -210,6 +365,24 @@ public void updateAftersaleStatus(Integer orderId, Short statusReject) { } + /** + * 后台订单列表查询:关联用户昵称与订单商品明细,返回分页 Map。 + * + *

返回结构固定为 list(OrderVo 列表)、total、page、limit、pages 五个键, + * 与前端表格分页组件约定一致。 + * + * @param nickname 用户昵称,模糊匹配 + * @param consignee 收货人,模糊匹配 + * @param orderSn 订单编号,精确匹配 + * @param start 下单时间下限 + * @param end 下单时间上限 + * @param orderStatusArray 状态集合 + * @param page 页码 + * @param limit 每页条数 + * @param sort 排序字段 + * @param order 排序方向 + * @return 含 list 与分页信息的 Map + */ public Map queryVoSelective(String nickname, String consignee, String orderSn, LocalDateTime start, LocalDateTime end, List orderStatusArray, Integer page, Integer limit, String sort, String order) { List querys = new ArrayList<>(4); if (!StringUtils.isEmpty(nickname)) { @@ -238,6 +411,8 @@ public Map queryVoSelective(String nickname, String consignee, S orderByClause = "o." + sort + " " + order +", o.id desc "; } + // 后台订单列表分两步查:先用条件筛出订单 id 并分页,再按 id 批量取明细; + // 原因是订单与订单商品是一对多,直接按明细行分页会让每页订单条数不准 PageHelper.startPage(page, limit); Page list1 = (Page) orderMapper.getOrderIds(query, orderByClause); List ids = new ArrayList<>(); @@ -246,6 +421,7 @@ public Map queryVoSelective(String nickname, String consignee, S ids.add(id); } + // 第二段:按上一步的 id 集合一次取回订单 + 用户 + 商品明细,避免 N+1 查询 List list2 = new ArrayList<>(); if (!ids.isEmpty()) { querys.add(" o.id in (" + StringUtils.collectionToDelimitedString(ids, ",") + ") "); diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/util/CouponConstant.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/util/CouponConstant.java index 99f088e22..b42102880 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/util/CouponConstant.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/util/CouponConstant.java @@ -1,18 +1,38 @@ package org.linlinjava.litemall.db.util; +/** + * 优惠券相关枚举值常量。 + * + *

与 litemall_coupon、litemall_coupon_user 表中的 tinyint 列一一对应, + * 数据库中没有外键约束,取值合法性由业务层保证。 + * + * @author lvweihao0403 + * @since 1.0.0 + */ public class CouponConstant { + /** 0 通用券:任意商品可用 */ public static final Short TYPE_COMMON = 0; + /** 1 注册赠券:新用户注册时发放 */ public static final Short TYPE_REGISTER = 1; + /** 2 口令券:凭口令领取 */ public static final Short TYPE_CODE = 2; + /** 0 全场通用 */ public static final Short GOODS_TYPE_ALL = 0; + /** 1 限定类目,适用范围见 litemall_coupon.goods_value */ public static final Short GOODS_TYPE_CATEGORY = 1; + /** 2 限定商品,适用范围见 litemall_coupon.goods_value */ public static final Short GOODS_TYPE_ARRAY = 2; + /** 0 正常可用 */ public static final Short STATUS_NORMAL = 0; + /** 1 已过期 */ public static final Short STATUS_EXPIRED = 1; + /** 2 已领完 */ public static final Short STATUS_OUT = 2; + /** 0 按领取后天数计算有效期,天数见 litemall_coupon.days */ public static final Short TIME_TYPE_DAYS = 0; + /** 1 按固定起止时间计算有效期,见 start_time / end_time */ public static final Short TIME_TYPE_TIME = 1; } diff --git a/litemall-db/src/main/java/org/linlinjava/litemall/db/util/OrderUtil.java b/litemall-db/src/main/java/org/linlinjava/litemall/db/util/OrderUtil.java index 15eadcc31..50e2634d7 100644 --- a/litemall-db/src/main/java/org/linlinjava/litemall/db/util/OrderUtil.java +++ b/litemall-db/src/main/java/org/linlinjava/litemall/db/util/OrderUtil.java @@ -5,7 +5,7 @@ import java.util.ArrayList; import java.util.List; -/* +/** * 订单流程:下单成功-》支付订单-》发货-》收货 * 订单状态: * 101 订单生成,未支付;102,下单未支付用户取消;103,下单未支付超期系统自动取消 @@ -18,20 +18,40 @@ * 当301商家已发货时,此时用户可以有确认收货 * 当401用户确认收货以后,此时用户可以进行的操作是退货、删除、去评价或者再次购买 * 当402系统自动确认收货以后,此时用户可以删除、去评价、或者再次购买 + * + * @author lvweihao0403 + * @since 1.0.0 */ public class OrderUtil { + /** 101 订单已生成、未支付;用户可付款或取消,超时后由系统置为 103 */ public static final Short STATUS_CREATE = 101; + /** 201 支付完成、商家未发货;此时用户可申请退款(202) */ public static final Short STATUS_PAY = 201; + /** 301 商家已发货、用户未收货;用户可确认收货(401),超时由系统置为 402 */ public static final Short STATUS_SHIP = 301; + /** 401 用户确认收货,订单正常结束 */ public static final Short STATUS_CONFIRM = 401; + /** 102 下单后用户主动取消 */ public static final Short STATUS_CANCEL = 102; + /** 103 下单后超时未支付,系统自动取消 */ public static final Short STATUS_AUTO_CANCEL = 103; + /** 104 管理员取消订单 */ public static final Short STATUS_ADMIN_CANCEL = 104; + /** 202 已付款未发货,用户申请退款,等待处理 */ public static final Short STATUS_REFUND = 202; + /** 203 退款已确认成功,订单可删除 */ public static final Short STATUS_REFUND_CONFIRM = 203; + /** 402 发货后超时未确认收货,系统自动确认,订单结束 */ public static final Short STATUS_AUTO_CONFIRM = 402; + /** + * 把订单状态码转换为中文文案,供后台列表与前端展示。 + * + * @param order 订单实体,orderStatus 不能为空 + * @return 状态中文文案 + * @throws IllegalStateException 状态码不在已知范围内时抛出 + */ public static String orderStatusText(LitemallOrder order) { int status = order.getOrderStatus().intValue(); @@ -79,6 +99,14 @@ public static String orderStatusText(LitemallOrder order) { } + /** + * 根据订单当前状态计算可用操作(支付、取消、退款、收货、评价等), + * 前端据此决定按钮的显示与置灰。 + * + * @param order 订单实体 + * @return 操作开关集合 + * @throws IllegalStateException 状态码未知时抛出 + */ public static OrderHandleOption build(LitemallOrder order) { int status = order.getOrderStatus().intValue(); OrderHandleOption handleOption = new OrderHandleOption(); @@ -115,6 +143,12 @@ public static OrderHandleOption build(LitemallOrder order) { return handleOption; } + /** + * 把前台页签类型转换为订单状态码集合。 + * + * @param showType 0 全部、1 待付款、2 待发货、3 待收货、4 待评价 + * @return 状态码集合;0 与未知类型返回 null,表示不限状态 + */ public static List orderStatus(Integer showType) { // 全部订单 if (showType == 0) { @@ -133,10 +167,9 @@ public static List orderStatus(Integer showType) { // 待收货订单 status.add((short) 301); } else if (showType.equals(4)) { - // 待评价订单 + // 待评价订单:仅 401 用户确认收货; + // 402 系统超时自动确认收货的订单不进入待评价列表(业务上不支持评价) status.add((short) 401); -// 系统超时自动取消,此时应该不支持评价 -// status.add((short)402); } else { return null; } diff --git a/litemall-db/src/main/resources/org/linlinjava/litemall/db/dao/OrderMapper.xml b/litemall-db/src/main/resources/org/linlinjava/litemall/db/dao/OrderMapper.xml index d1cdfd08d..16ad51cce 100644 --- a/litemall-db/src/main/resources/org/linlinjava/litemall/db/dao/OrderMapper.xml +++ b/litemall-db/src/main/resources/org/linlinjava/litemall/db/dao/OrderMapper.xml @@ -1,6 +1,12 @@ + update litemall_order @@ -98,9 +104,18 @@ deleted = #{order.deleted,jdbcType=BIT}, + where id = #{order.id,jdbcType=INTEGER} and update_time = #{lastUpdateTime,jdbcType=INTEGER} + select o.id, o.order_sn, o.order_status, o.actual_price, o.freight_price, o.add_time, o.message, o.consignee, o.address, o.mobile, o.pay_time, o.order_price, o.ship_channel, o.ship_sn, diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java index 93a8a730f..919eee2ba 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java @@ -36,7 +36,10 @@ import static org.linlinjava.litemall.wx.util.WxResponseCode.*; /** - * 鉴权服务 + * 微信小程序用户认证与账户管理控制器。 + *

+ * 提供账号登录、微信登录、注册、验证码申请、密码重置、 + * 手机号绑定及个人资料维护等接口。 */ @RestController @RequestMapping("/wx/auth") @@ -175,13 +178,13 @@ public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletReq /** - * 请求注册验证码 + * 请求发送用户注册短信验证码。 * - * TODO - * 这里需要一定机制防止短信验证码被滥用 + * @param body 包含手机号 mobile 的请求体 + * @return 请求处理结果;手机号为空或格式不正确时返回参数错误, + * 短信服务未启用或请求过于频繁时返回相应错误提示 * - * @param body 手机号码 { mobile } - * @return + * TODO:增加验证码请求频率限制等机制,防止短信验证码被滥用。 */ @PostMapping("regCaptcha") public Object registerCaptcha(@RequestBody String body) { @@ -325,13 +328,14 @@ public Object register(@RequestBody String body, HttpServletRequest request) { } /** - * 请求验证码 + * 请求发送指定手机号的短信验证码。 * - * TODO - * 这里需要一定机制防止短信验证码被滥用 + * @param userId 当前登录用户的用户 ID,由登录用户参数解析器注入 + * @param body 包含手机号 mobile 和验证码类型 type 的请求体 + * @return 请求处理结果;用户未登录、参数缺失或手机号格式错误时返回相应提示, + * 短信服务未启用或请求过于频繁时返回相应错误提示 * - * @param body 手机号码 { mobile: xxx, type: xxx } - * @return + * TODO:增加验证码请求频率限制等机制,防止短信验证码被滥用。 */ @PostMapping("captcha") public Object captcha(@LoginUser Integer userId, @RequestBody String body) { @@ -510,11 +514,11 @@ public Object profile(@LoginUser Integer userId, @RequestBody String body, HttpS } /** - * 微信手机号码绑定 + * 绑定当前登录用户的微信手机号。 * - * @param userId - * @param body - * @return + * @param userId 当前登录用户的用户 ID,由登录用户参数解析器注入 + * @param body 包含微信手机号加密数据 encryptedData 和初始向量 iv 的请求体 + * @return 绑定结果;用户未登录时返回未登录提示,更新失败时返回更新失败提示 */ @PostMapping("bindPhone") public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) { @@ -532,7 +536,12 @@ public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) { } return ResponseUtil.ok(); } - + /** + * 处理当前用户的退出登录请求。 + * + * @param userId 当前登录用户的用户 ID,由登录用户参数解析器注入 + * @return 退出登录处理结果;用户未登录时返回未登录提示 + */ @PostMapping("logout") public Object logout(@LoginUser Integer userId) { if (userId == null) { @@ -540,7 +549,12 @@ public Object logout(@LoginUser Integer userId) { } return ResponseUtil.ok(); } - + /** + * 查询当前登录用户的基本资料。 + * + * @param userId 当前登录用户的用户 ID,由登录用户参数解析器注入 + * @return 用户昵称、头像、性别和手机号;用户未登录时返回未登录提示 + */ @GetMapping("info") public Object info(@LoginUser Integer userId) { if (userId == null) {