Repository navigation
Expand file tree
/
Copy pathserver.js
More file actions
134 lines (114 loc) · 4.64 KB
/
Copy pathserver.js
File metadata and controls
134 lines (114 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import http from 'http'
import { ProductRepo, CartRepo, OrderRepo } from '../repo/memoryRepo.js'
import { CatalogService } from '../services/catalog.js'
import { CartService } from '../services/cart.js'
import { OrderService } from '../services/order.js'
const productRepo = new ProductRepo()
const cartRepo = new CartRepo()
const orderRepo = new OrderRepo()
const catalogService = new CatalogService(productRepo)
const cartService = new CartService(cartRepo, productRepo)
const orderService = new OrderService(cartRepo, orderRepo, productRepo)
const readJson = async (req) => {
return new Promise((resolve, reject) => {
let body = ''
req.on('data', chunk => body += chunk)
req.on('end', () => {
try {
resolve(body ? JSON.parse(body) : {})
} catch (e) {
reject(e)
}
})
})
}
const sendJson = (res, status, data) => {
res.writeHead(status, { 'Content-Type': 'application/json' })
res.end(JSON.stringify(data))
}
const sendError = (res, code, message, status = 500) => {
sendJson(res, status, { code, message })
}
export function createServer() {
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`)
const pathname = url.pathname
try {
if (pathname === '/api/products' && req.method === 'GET') {
const name = url.searchParams.get('name')
const sort = url.searchParams.get('sort')
return sendJson(res, 200, catalogService.list(name, sort))
}
if (pathname === '/api/products' && req.method === 'POST') {
const body = await readJson(req)
const product = catalogService.addProduct(body)
return sendJson(res, 201, product)
}
if (pathname.startsWith('/api/products/') && req.method === 'GET') {
const id = pathname.split('/').pop()
const product = catalogService.getProduct(id)
if (!product) return sendError(res, 'NOT_FOUND', 'Product not found', 404)
return sendJson(res, 200, product)
}
if (pathname === '/api/cart/items' && req.method === 'POST') {
const body = await readJson(req)
// Mock user ID for dev
const userId = 'user_dev'
const cart = cartService.addToCart(userId, body.productId, body.quantity)
return sendJson(res, 200, cart)
}
if (pathname === '/api/cart/items' && req.method === 'GET') {
// Mock user ID for dev
const userId = 'user_dev'
const cart = cartService.getCart(userId)
return sendJson(res, 200, cart)
}
if (pathname.startsWith('/api/cart/items/') && req.method === 'DELETE') {
const productId = pathname.split('/').pop()
// Mock user ID for dev
const userId = 'user_dev'
const cart = cartService.removeItem(userId, productId)
return sendJson(res, 200, cart)
}
if (pathname === '/api/orders' && req.method === 'POST') {
const body = await readJson(req)
// Mock user ID for dev if not provided
const userId = body.userId || 'user_dev'
const order = orderService.createOrder(userId)
return sendJson(res, 201, order)
}
if (pathname === '/api/orders' && req.method === 'GET') {
const userId = url.searchParams.get('userId')
const list = orderService.listOrders(userId)
return sendJson(res, 200, list)
}
if (pathname.startsWith('/api/orders/') && req.method === 'GET') {
const id = pathname.split('/').pop()
const order = orderRepo.findById(id)
if (!order) return sendError(res, 'NOT_FOUND', 'Order not found', 404)
return sendJson(res, 200, order)
}
sendError(res, 'NOT_FOUND', 'Endpoint not found', 404)
} catch (e) {
if (e.message === 'CART_EMPTY')
return sendError(res, 'CART_EMPTY', '购物车为空', 400)
if (e.message === 'OUT_OF_STOCK')
return sendError(res, 'OUT_OF_STOCK', '库存不足', 409)
if (e.message === 'PRODUCT_NOT_FOUND')
return sendError(res, 'PRODUCT_NOT_FOUND', '商品不存在', 404)
if (e.message === 'CART_ITEM_NOT_FOUND')
return sendError(res, 'CART_ITEM_NOT_FOUND', '购物车中不存在该商品', 404)
if (e.message === 'MISSING_USER_ID')
return sendError(res, 'MISSING_USER_ID', '缺少 userId 参数', 400)
console.error(e)
sendError(res, 'INTERNAL_ERROR', e.message, 500)
}
})
return { server, services: { catalogService, cartService, orderService } }
}
if (process.argv[1] === new URL(import.meta.url).pathname) {
const { server } = createServer()
server.listen(3000, () => {
console.log('Server running on port 3000')
})
}