[!简介]
当然可以。我们来创建一个更复杂的例子,涉及到多层嵌套对象、数组、和自定义类型。这个例子将模拟一个在线商店的订单系统。
首先,我们定义一些复杂的类型:
import { Elysia, t } from 'elysia';
// 自定义类型
const ProductType = t.Enum(['Physical', 'Digital', 'Service']);
// 商品类型
const Product = t.Object({
id: t.String(),
name: t.String(),
price: t.Number(),
type: ProductType,
attributes: t.Record(t.String(), t.Any())
});
// 地址类型
const Address = t.Object({
street: t.String(),
city: t.String(),
state: t.String(),
country: t.String(),
zipCode: t.String()
});
// 客户类型
const Customer = t.Object({
id: t.String(),
name: t.String(),
email: t.String(),
phone: t.Optional(t.String()),
address: Address
});
// 订单项类型
const OrderItem = t.Object({
product: Product,
quantity: t.Number(),
customizations: t.Optional(t.Array(t.String()))
});
// 支付信息类型
const PaymentInfo = t.Object({
method: t.Enum(['CreditCard', 'PayPal', 'BankTransfer']),
transactionId: t.String(),
amount: t.Number()
});
// 完整的订单类型
const Order = t.Object({
orderId: t.String(),
customer: Customer,
items: t.Array(OrderItem),
totalAmount: t.Number(),
status: t.Enum(['Pending', 'Processing', 'Shipped', 'Delivered']),
paymentInfo: PaymentInfo,
notes: t.Optional(t.String()),
createdAt: t.String(),
lastUpdated: t.String()
});现在,我们创建一个处理订单的路由:
const app = new Elysia();
app.post('/process-order', ({ body }) => {
// 复杂的订单处理逻辑
const order = body;
// 验证订单
if (order.items.length === 0) {
return { error: 'Order must contain at least one item' };
}
// 计算总金额
const calculatedTotal = order.items.reduce((total, item) =>
total + (item.product.price * item.quantity), 0);
if (calculatedTotal !== order.totalAmount) {
return { error: 'Total amount mismatch' };
}
// 处理每个订单项
order.items.forEach(item => {
if (item.product.type === 'Physical') {
// 检查库存
checkInventory(item.product.id, item.quantity);
} else if (item.product.type === 'Digital') {
// 准备数字下载链接
prepareDigitalDownload(item.product.id);
}
});
// 处理支付
processPayment(order.paymentInfo);
// 更新订单状态
order.status = 'Processing';
order.lastUpdated = new Date().toISOString();
// 保存订单到数据库
saveOrderToDatabase(order);
// 发送确认邮件
sendOrderConfirmationEmail(order.customer.email, order);
return {
message: 'Order processed successfully',
orderId: order.orderId
};
}, {
body: Order
});
app.listen(3000);
// 模拟的辅助函数
function checkInventory(productId: string, quantity: number) {
console.log(`Checking inventory for product ${productId}, quantity: ${quantity}`);
}
function prepareDigitalDownload(productId: string) {
console.log(`Preparing digital download for product ${productId}`);
}
function processPayment(paymentInfo: any) {
console.log(`Processing payment: ${JSON.stringify(paymentInfo)}`);
}
function saveOrderToDatabase(order: any) {
console.log(`Saving order to database: ${order.orderId}`);
}
function sendOrderConfirmationEmail(email: string, order: any) {
console.log(`Sending confirmation email to ${email} for order ${order.orderId}`);
}这个例子展示了如何处理一个非常复杂的订单对象。订单包含了客户信息、多个订单项(每个都有自己的产品信息和定制选项)、支付信息等。
在 HTMX 中,你可以这样触发这个复杂的请求:
<button hx-post="/process-order"
hx-trigger="click"
hx-vals='{"orderId":"ORD12345","customer":{"id":"CUST789","name":"Alice Johnson","email":"alice@example.com","address":{"street":"123 Main St","city":"Springfield","state":"IL","country":"USA","zipCode":"62701"}},"items":[{"product":{"id":"PROD1","name":"Laptop","price":999.99,"type":"Physical","attributes":{"brand":"TechBrand","model":"X1"}},"quantity":1},{"product":{"id":"PROD2","name":"Software License","price":199.99,"type":"Digital","attributes":{"version":"2.0"}},"quantity":1,"customizations":["Extra User"]}],"totalAmount":1199.98,"status":"Pending","paymentInfo":{"method":"CreditCard","transactionId":"TXN987654","amount":1199.98},"createdAt":"2023-06-15T10:30:00Z","lastUpdated":"2023-06-15T10:30:00Z"}'>
Process Order
</button>这个例子展示了如何处理非常复杂的参数结构。它包括:
- 多层嵌套对象(如客户信息中的地址)
- 数组(订单项)
- 枚举类型(产品类型、订单状态、支付方式)
- 可选字段(客户电话、订单备注)
- 自定义类型(如 Product, Address 等)
在实际应用中,你可能需要将这个复杂的 JSON 数据分解成多个表单字段,或者使用 JavaScript 来动态构建这个对象。此外,服务器端的处理逻辑也可能更加复杂,包括数据库操作、第三方 API 调用等。
这个例子展示了 TypeScript 和 Elysia 如何优雅地处理复杂的数据结构,同时也展示了如何在后端实现复杂的业务逻辑。