脚手架搭建到现在已经差不多了,下面我们要通过一个示例来展示一下我们的开发人员如何借助这个脚手架开始开发。我们要做一个订单管理的业务功能,代码包括scaffold-admin-ui项目要实现的代码,也要包含后台代码实现,同时包含所有的数据库设计。具体功能包括订单创建、订单查询、订单金额修改、订单列表查询(包含订单编码、用户手机号等查询条件)。希望能给大家带来帮助。
ALTER TABLE sys_user ADD COLUMN phone VARCHAR(15) COMMENT '用户手机号';
CREATE TABLE `order_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`order_no` varchar(32) NOT NULL COMMENT '订单编号(业务唯一)',
`user_id` bigint NOT NULL COMMENT '用户ID',
`amount` decimal(10,2) NOT NULL COMMENT '订单金额',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(1-待支付 2-已支付 3-已取消)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
在父工程 pom.xml
中添加模块:
<modules>
<module>scaffold-order</module>
</modules>
scaffold-order/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/example/scaffold/order/
│ │ ├── config/ # 配置类
│ │ ├── controller/ # OrderController.java
│ │ ├── entity/ # Order.java
│ │ ├── mapper/ # OrderMapper.java
│ │ ├── service/ # OrderService.java + impl
│ │ └── dto/ # OrderDTO.java, OrderQueryDTO.java
│ └── resources/
│ ├── mapper/ # OrderMapper.xml
│ └── application.yml
├── pom.xml
└── Dockerfile
@Data
@TableName("order_info")
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
private String orderNo;
private Long userId;
private BigDecimal amount;
private Integer status;
private Date createTime;
private Date updateTime;
}
public interface OrderMapper extends BaseMapper<Order> {
// 自定义复杂查询(示例:联表查询用户手机号)
@Select("SELECT o.*, u.phone FROM order_info o LEFT JOIN sys_user u ON o.user_id = u.id ${ew.customSqlSegment}")
List<OrderVO> selectOrderWithPhone(@Param(Constants.WRAPPER) QueryWrapper<Order> wrapper);
}
public interface OrderService extends IService<Order> {
String createOrder(OrderDTO dto);
void updateOrderAmount(String orderNo, BigDecimal amount);
Page<OrderVO> queryOrders(OrderQueryDTO queryDTO, Page<Order> page);
}
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Override
public String createOrder(OrderDTO dto) {
Order order = new Order();
BeanUtils.copyProperties(dto, order);
order.setOrderNo(generateOrderNo()); // 生成订单号逻辑
this.save(order);
return order.getOrderNo();
}
@Override
public void updateOrderAmount(String orderNo, BigDecimal amount) {
LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Order::getOrderNo, orderNo)
.set(Order::getAmount, amount);
this.update(wrapper);
}
@Override
public Page<OrderVO> queryOrders(OrderQueryDTO queryDTO, Page<Order> page) {
QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(queryDTO.getOrderNo()), "order_no", queryDTO.getOrderNo())
.eq(queryDTO.getUserId() != null, "user_id", queryDTO.getUserId())
.like(StringUtils.isNotBlank(queryDTO.getPhone()), "u.phone", queryDTO.getPhone());
return baseMapper.selectOrderWithPhone(page, wrapper);
}
private String generateOrderNo() {
return "ORD" + System.currentTimeMillis() + RandomUtil.randomNumbers(4);
}
}
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping
public Response<String> createOrder(@RequestBody OrderDTO dto) {
return Response.success(orderService.createOrder(dto));
}
@PutMapping("/amount")
public Response<Void> updateAmount(@RequestParam String orderNo,
@RequestParam BigDecimal amount) {
orderService.updateOrderAmount(orderNo, amount);
return Response.success();
}
@GetMapping("/list")
public Response<Page<OrderVO>> listOrders(OrderQueryDTO queryDTO,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
Page<Order> page = new Page<>(pageNum, pageSize);
return Response.success(orderService.queryOrders(queryDTO, page));
}
}
@Data
public class OrderDTO {
@NotNull(message = "用户ID不能为空")
private Long userId;
@DecimalMin(value = "0.01", message = "金额必须大于0")
private BigDecimal amount;
}
@Data
public class OrderQueryDTO {
private String orderNo;
private Long userId;
private String phone; // 用户手机号(联表查询用)
}
@Data
public class OrderVO extends Order {
private String phone; // 用户手机号(联表查询结果)
}
// src/router/index.ts
{
path: '/order',
name: 'Order',
component: () => import('@/views/order/OrderList.vue'),
meta: { requiresAuth: true }
}
// src/api/order.ts
import request from '@/utils/request'
export interface OrderVO {
id: number
orderNo: string
amount: number
status: number
phone: string
createTime: string
}
export const createOrder = (data: { userId: number; amount: number }) => {
return request.post<string>('/api/order', data)
}
export const updateOrderAmount = (orderNo: string, amount: number) => {
return request.put(`/api/order/amount?orderNo=${orderNo}&amount=${amount}`)
}
export const getOrderList = (params: {
orderNo?: string
phone?: string
page?: number
size?: number
}) => {
return request.get<PageResponse<OrderVO>>('/api/order/list', { params })
}
<!-- src/views/order/OrderList.vue -->
<template>
<div class="order-container">
<el-form :model="queryParams" inline>
<el-form-item label="订单号">
<el-input v-model="queryParams.orderNo" clearable />
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="queryParams.phone" clearable />
</el-form-item>
<el-button type="primary" @click="loadData">查询</el-button>
</el-form>
<el-table :data="orderList" border>
<el-table-column prop="orderNo" label="订单号" width="200" />
<el-table-column prop="amount" label="金额" align="right" />
<el-table-column prop="phone" label="用户手机号" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="statusMap[row.status].type">
{{ statusMap[row.status].label }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template #default="{ row }">
<el-button @click="showEditDialog(row)">改价</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="pagination.page"
:page-size="pagination.size"
:total="pagination.total"
@current-change="handlePageChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { getOrderList } from '@/api/order'
interface QueryParams {
orderNo?: string
phone?: string
}
const statusMap = {
1: { label: '待支付', type: 'warning' },
2: { label: '已支付', type: 'success' },
3: { label: '已取消', type: 'info' }
}
const orderList = ref<OrderVO[]>([])
const queryParams = reactive<QueryParams>({})
const pagination = reactive({
page: 1,
size: 10,
total: 0
})
const loadData = async () => {
const res = await getOrderList({
...queryParams,
page: pagination.page,
size: pagination.size
})
orderList.value = res.records
pagination.total = res.total
}
const handlePageChange = (page: number) => {
pagination.page = page
loadData()
}
// 初始化加载数据
loadData()
</script>
在 scaffold-gateway
模块的路由配置中添加订单服务路由:
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
services:
order-service:
image: scaffold-order:1.0.0
ports:
- "8082:8082"
depends_on:
- mysql
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/scaffold
创建订单:
POST /api/order
{ "userId": 1, "amount": 100.00 }
查询订单:
GET /api/order/list?phone=13800138000
修改金额:
PUT /api/order/amount?orderNo=ORD123456&amount=150.00
BigDecimal
类型避免浮点误差
通过以上步骤,您已完成完整的订单管理模块开发。后续可根据需求扩展状态流转、支付回调等功能。
本篇的分享就到这里了,感谢观看,如果对你有帮助,别忘了点赞+收藏+关注。