更新完善页面
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
const { query, transaction } = require('../config/database')
|
||||
const { sanitizeInt } = require('../utils/validators')
|
||||
|
||||
function currentUserId(ctx) {
|
||||
return ctx.state.user ? ctx.state.user.id : null
|
||||
}
|
||||
|
||||
async function getCart(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
|
||||
const sql = `
|
||||
SELECT
|
||||
c.id,
|
||||
c.goods_id,
|
||||
c.quantity,
|
||||
c.weight,
|
||||
c.selected,
|
||||
g.name as goods_name,
|
||||
g.price,
|
||||
g.unit,
|
||||
g.stock,
|
||||
g.images,
|
||||
g.pricing_type
|
||||
FROM carts c
|
||||
LEFT JOIN goods g ON c.goods_id = g.id
|
||||
WHERE c.user_id = ? AND g.status != 0
|
||||
`
|
||||
|
||||
const items = await query(sql, [userId])
|
||||
|
||||
const cartItems = items.map(item => {
|
||||
let images = []
|
||||
try {
|
||||
images = item.images ? JSON.parse(item.images) : []
|
||||
} catch {}
|
||||
|
||||
return {
|
||||
id: item.goods_id,
|
||||
name: item.goods_name,
|
||||
price: parseFloat(item.price),
|
||||
unit: item.unit,
|
||||
stock: item.stock,
|
||||
images: images,
|
||||
pricingType: item.pricing_type,
|
||||
quantity: item.quantity,
|
||||
weight: item.weight,
|
||||
selected: item.selected === 1
|
||||
}
|
||||
})
|
||||
|
||||
ctx.body = { code: 200, data: cartItems }
|
||||
}
|
||||
|
||||
async function addToCart(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
const { goodsId, quantity, weight } = ctx.request.body || {}
|
||||
|
||||
if (!goodsId) {
|
||||
ctx.body = { code: 400, message: '缺少商品ID' }
|
||||
return
|
||||
}
|
||||
|
||||
const qty = sanitizeInt(quantity, 1, 1, 9999)
|
||||
if (qty === null) {
|
||||
ctx.body = { code: 400, message: '数量必须是 1-9999 之间的整数' }
|
||||
return
|
||||
}
|
||||
const wgt = weight !== undefined && weight !== null ? parseFloat(weight) : null
|
||||
if (wgt !== null && (isNaN(wgt) || wgt < 0)) {
|
||||
ctx.body = { code: 400, message: '重量必须为非负数' }
|
||||
return
|
||||
}
|
||||
|
||||
await transaction(async (conn) => {
|
||||
const [rows] = await conn.execute('SELECT * FROM carts WHERE user_id = ? AND goods_id = ? FOR UPDATE', [userId, goodsId])
|
||||
if (rows.length > 0) {
|
||||
await conn.execute('UPDATE carts SET quantity = quantity + ?, weight = ?, updated_at = NOW() WHERE user_id = ? AND goods_id = ?', [qty, wgt, userId, goodsId])
|
||||
} else {
|
||||
await conn.execute('INSERT INTO carts (user_id, goods_id, quantity, weight) VALUES (?, ?, ?, ?)', [userId, goodsId, qty, wgt])
|
||||
}
|
||||
})
|
||||
|
||||
ctx.body = { code: 200, message: '添加成功' }
|
||||
}
|
||||
|
||||
async function updateCartItem(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
const { goodsId, quantity, weight, selected } = ctx.request.body || {}
|
||||
|
||||
if (!goodsId) {
|
||||
ctx.body = { code: 400, message: '缺少商品ID' }
|
||||
return
|
||||
}
|
||||
|
||||
const updates = []
|
||||
const params = []
|
||||
|
||||
if (quantity !== undefined) {
|
||||
const qty = sanitizeInt(quantity, 1, 0, 9999)
|
||||
if (qty === null) {
|
||||
ctx.body = { code: 400, message: '数量必须是 0-9999 之间的整数' }
|
||||
return
|
||||
}
|
||||
updates.push('quantity = ?')
|
||||
params.push(qty)
|
||||
}
|
||||
|
||||
if (weight !== undefined) {
|
||||
const wgt = weight === null ? null : parseFloat(weight)
|
||||
if (wgt !== null && (isNaN(wgt) || wgt < 0)) {
|
||||
ctx.body = { code: 400, message: '重量必须为非负数' }
|
||||
return
|
||||
}
|
||||
updates.push('weight = ?')
|
||||
params.push(wgt)
|
||||
}
|
||||
|
||||
if (selected !== undefined) {
|
||||
updates.push('selected = ?')
|
||||
params.push(selected ? 1 : 0)
|
||||
}
|
||||
|
||||
if (updates.length === 0) {
|
||||
ctx.body = { code: 400, message: '没有需要更新的字段' }
|
||||
return
|
||||
}
|
||||
|
||||
params.push(userId, goodsId)
|
||||
|
||||
const result = await query(
|
||||
`UPDATE carts SET ${updates.join(', ')}, updated_at = NOW() WHERE user_id = ? AND goods_id = ?`,
|
||||
params
|
||||
)
|
||||
|
||||
if (result.affectedRows === 0) {
|
||||
ctx.body = { code: 404, message: '购物车中不存在该商品' }
|
||||
return
|
||||
}
|
||||
ctx.body = { code: 200, message: '更新成功' }
|
||||
}
|
||||
|
||||
async function removeFromCart(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
const { goodsId } = ctx.request.body || {}
|
||||
|
||||
if (!goodsId) {
|
||||
ctx.body = { code: 400, message: '缺少商品ID' }
|
||||
return
|
||||
}
|
||||
|
||||
await query('DELETE FROM carts WHERE user_id = ? AND goods_id = ?', [userId, goodsId])
|
||||
ctx.body = { code: 200, message: '删除成功' }
|
||||
}
|
||||
|
||||
async function clearCart(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
await query('DELETE FROM carts WHERE user_id = ?', [userId])
|
||||
ctx.body = { code: 200, message: '清空成功' }
|
||||
}
|
||||
|
||||
async function syncCart(ctx) {
|
||||
const userId = currentUserId(ctx)
|
||||
if (!userId) {
|
||||
ctx.status = 401
|
||||
ctx.body = { code: 401, message: '未登录' }
|
||||
return
|
||||
}
|
||||
const { cart } = ctx.request.body || {}
|
||||
|
||||
if (!Array.isArray(cart)) {
|
||||
ctx.body = { code: 400, message: '购物车数据格式错误' }
|
||||
return
|
||||
}
|
||||
if (cart.length > 100) {
|
||||
ctx.body = { code: 400, message: '购物车商品数不能超过 100' }
|
||||
return
|
||||
}
|
||||
|
||||
await transaction(async (conn) => {
|
||||
await conn.execute('DELETE FROM carts WHERE user_id = ?', [userId])
|
||||
if (cart.length > 0) {
|
||||
const values = cart.map(item => [
|
||||
userId,
|
||||
item.id || item.goods_id,
|
||||
sanitizeInt(item.quantity, 1, 1, 9999) || 1,
|
||||
item.weight || null,
|
||||
1
|
||||
])
|
||||
const placeholders = values.map(() => '(?, ?, ?, ?, ?)').join(', ')
|
||||
const flatParams = values.flat()
|
||||
await conn.execute(
|
||||
`INSERT INTO carts (user_id, goods_id, quantity, weight, selected) VALUES ${placeholders}`,
|
||||
flatParams
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
ctx.body = { code: 200, message: '同步成功' }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getCart,
|
||||
addToCart,
|
||||
updateCartItem,
|
||||
removeFromCart,
|
||||
clearCart,
|
||||
syncCart
|
||||
}
|
||||
Reference in New Issue
Block a user