苍穹外卖-DAT08

1.地址功能实现

具体功能

image-20260206154429235

2.下单功能

业务流程

image-20260206160718446

3.collection参数

取决于在 Java Mapper 接口里是怎么写的方法签名MyBatis 并没有强制规定它必须叫什么,而是根据你的传参方式有不同的“默认规则”

简单来说,collection 的值遵循以下 4 条铁律

最常见情况:只传了一个 List 参数,且没加注解

这是最“偷懒”也是最容易让人晕的情况。如果你在 Java 里只传了一个 List,MyBatis 会在内部自动把它包装起来,固定的 Key 就是 list

  • Java 代码:

    1
    2
    // 只有这一个参数,且没有 @Param 注解
    void insertBatch(List<OrderDetail> myDataList);
  • XML 写法: (必须写死为 “list”)

    1
    <foreach collection="list" ...>

推荐情况:使用了 @Param 注解 (最稳妥)

这是最佳实践。你给参数取了什么别名,XML 里就用什么名字。这种方式最清晰,不会搞混。

  • Java 代码:

    1
    2
    // 强制指定别名为 "myItems"
    void insertBatch(@Param("myItems") List<OrderDetail> anyName);
  • XML 写法: (必须和注解里的值一致)

    1
    <foreach collection="myItems" ...>

封装情况:传的是一个对象 (POJO) 或 Map

如果你传的是一个大对象(比如 OrderDTO),而 List 只是这个对象里的一个属性。

  • Java 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    class OrderDTO {
    private String shopName;
    private List<OrderDetail> detailList; // 属性名
    // getters...
    }

    // 此时入参是一个对象
    void insertBatch(OrderDTO dto);
  • XML 写法: (必须写该对象内部的属性名)

    1
    <foreach collection="detailList" ...>

数组情况:只传了一个数组 (Array)

如果你传的不是 List 而是 OrderDetail[] 数组。

  • Java 代码:

    1
    void insertBatch(OrderDetail[] array);
  • XML 写法: (必须写死为 “array”)

    1
    <foreach collection="array" ...>
Java 方法签名 (Mapper Interface) XML collection 的值 备注
void func(List<T> xxx) "list" 默认规则 (MyBatis 强制规定)
void func(T[] xxx) "array" 默认规则 (MyBatis 强制规定)
void func(@Param("abc") List<T> xxx) "abc" 自定义 (最推荐,清晰明了)
void func(UserDTO user) (UserDTO 里有个 List<Role> roles) "roles" 属性名 (直接用对象里的变量名)

当满足以下 3 个条件 时,不需要 @Param 也能直接用变量名:

  1. Java 版本:JDK 8 及以上。
  2. MyBatis 版本:3.4.1 及以上(增加了 useActualParamName 配置,默认为 true)。
  3. 编译器配置:编译时加了 -parameters 参数(Spring Boot 项目通常自带此 buff)。

4.订单支付

微信支付产品

image-20260207112022990

微信小程序支付流程图

image-20260207112839154

内网穿透

cpolar

1
https://dashboard.cpolar.com/get-started

微信支付跳过

服务端

OrderServiceImpl.java
修改前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
Long userId = BaseContext.getCurrentId();
User user = userMapper.getById(userId);
// 调用微信支付接口,生成预支付交易单
JSONObject jsonObject = weChatPayUtil.pay(
ordersPaymentDTO.getOrderNumber(),
new BigDecimal(0.01),
"苍穹外卖订单",
user.getOpenid()
);

if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
throw new OrderBusinessException("该订单已支付");
}

OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
vo.setPackageStr(jsonObject.getString("package"));
return vo;
}

修改后

1
2
3
4
5
6
7
8
9
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
Long userId = BaseContext.getCurrentId();
User user = userMapper.getById(userId);
// 跳过微信支付,直接修改订单状态
paySuccess(ordersPaymentDTO.getOrderNumber());

OrderPaymentVO vo = new OrderPaymentVO();
return vo;
}

UserOrderController.java

1
2
3
4
5
6
7
@PutMapping("/payment")
@ApiOperation("订单支付")
public Result payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
log.info("订单支付:{}", ordersPaymentDTO);
OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
return Result.success();
}

总结
✅ 删除了微信支付接口调用
✅ 直接调用 paySuccess() 更新订单状态
✅ 前端只需 code=1 即可跳转成功页
/notify/paySuccess 回调接口不再使用(可保留不动)

客户端

pages\pay\index.jshandleSave方法

修改内容

项目 原始代码 你修改后
调用接口 paymentOrder paymentOrder(不变)
微信支付 调用 wx.requestPayment ❌ 删除
跳转时机 微信支付成功后跳转 接口返回 code=1直接跳转

原始:

1
2
3
4
5
6
7
8
9
10
11
(0, _api.paymentOrder)(params).then(function (res) {
if (res.code === 1) {
wx.requestPayment({
// 微信支付参数...
success: function(res) {
// 支付成功后才跳转
uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId});
}
})
}
});

你修改后:

1
2
3
4
5
6
(0, _api.paymentOrder)(params).then(function (res) {
if (res.code === 1) {
// 跳过微信支付,直接跳转
uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId});
}
});

点击支付 → 调用后端接口 → 直接跳转成功页(不弹微信支付)