Files
backmanager-server/routes/customers.js

211 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// routes/customers.js —— 客户管理 CRUD纯数据库操作权限由中间件层控制
const { pool } = require('../db')
// 提取分页参数
function pagination(query) {
const page = Math.max(Number(query.page) || 1, 1)
const pageSize = Math.min(Math.max(Number(query.pageSize) || 10, 1), 100)
const offset = (page - 1) * pageSize
return { page, pageSize, offset }
}
// GET /api/customers —— 列表(支持搜索、分页)
async function list(req, res) {
try {
const { page, pageSize, offset } = pagination(req.query)
const { name, phone, province, city, id } = req.query
let where = 'WHERE 1=1'
const params = []
// 数据范围过滤(由中间件注入 req.scope
if (req.scope && req.scope.sql) {
where += ' ' + req.scope.sql
params.push(...req.scope.params)
}
if (id) {
where += ' AND c.id = ?'
params.push(id)
}
if (name) {
where += ' AND c.name LIKE ?'
params.push(`%${name}%`)
}
if (phone) {
where += ' AND c.phone LIKE ?'
params.push(`%${phone}%`)
}
if (province) {
where += ' AND c.province = ?'
params.push(province)
}
if (city) {
where += ' AND c.city = ?'
params.push(city)
}
// 查总数
const [[{ total }]] = await pool.query(
`SELECT COUNT(*) AS total FROM customers c ${where}`,
params
)
// 查分页数据
const [rows] = await pool.query(
`SELECT c.*
FROM customers c
${where} ORDER BY c.id DESC LIMIT ? OFFSET ?`,
[...params, pageSize, offset]
)
res.json({
code: 0,
message: 'ok',
data: {
list: rows,
total,
page,
pageSize,
totalPages: Math.ceil(total / pageSize),
},
})
} catch (e) {
console.error('[customers list] error:', e)
res.status(500).json({ code: 500, message: e.message })
}
}
// GET /api/customers/:id —— 详情
async function detail(req, res) {
try {
let sql = 'SELECT * FROM customers WHERE id = ?'
const params = [req.params.id]
if (req.scope && req.scope.sql) {
sql += ' ' + req.scope.sql
params.push(...req.scope.params)
}
const [rows] = await pool.query(sql, params)
if (rows.length === 0) {
return res.status(404).json({ code: 404, message: '客户不存在' })
}
res.json({ code: 0, message: 'ok', data: rows[0] })
} catch (e) {
console.error('[customers detail] error:', e)
res.status(500).json({ code: 500, message: e.message })
}
}
// POST /api/customers —— 新增
async function create(req, res) {
const {
name, phone, province, city, district,
address, email, remark,
} = req.body || {}
if (!name) {
return res.status(400).json({ code: 400, message: '客户姓名必填' })
}
try {
const [result] = await pool.query(
`INSERT INTO customers (name, phone, province, city, district, address, email, remark)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[name, phone || null, province || null, city || null, district || null,
address || null, email || null, remark || null]
)
const [rows] = await pool.query('SELECT * FROM customers WHERE id = ?', [result.insertId])
res.json({ code: 0, message: 'ok', data: rows[0] })
} catch (e) {
console.error('[customers create] error:', e)
res.status(500).json({ code: 500, message: e.message })
}
}
// PUT /api/customers/:id —— 更新
async function update(req, res) {
const { id } = req.params
const fields = [
'name', 'phone', 'province', 'city', 'district',
'address', 'email', 'remark',
]
try {
// 确认记录存在且在数据范围内
let checkSql = 'SELECT id FROM customers WHERE id = ?'
let checkParams = [id] // let, 后续可能 push scope.params
if (req.scope && req.scope.sql) {
checkSql += ' ' + req.scope.sql
checkParams.push(...req.scope.params)
}
const [existing] = await pool.query(checkSql, checkParams)
if (existing.length === 0) {
return res.status(404).json({ code: 404, message: '客户不存在或无权操作' })
}
// 动态构建 SET 子句(只更新传入的字段)
const sets = []
const params = []
for (const f of fields) {
if (req.body[f] !== undefined) {
sets.push(`${f} = ?`)
params.push(req.body[f])
}
}
if (sets.length === 0) {
return res.status(400).json({ code: 400, message: '没有需要更新的字段' })
}
params.push(id)
await pool.query(`UPDATE customers SET ${sets.join(', ')} WHERE id = ?`, params)
const [rows] = await pool.query('SELECT * FROM customers WHERE id = ?', [id])
res.json({ code: 0, message: 'ok', data: rows[0] })
} catch (e) {
console.error('[customers update] error:', e)
res.status(500).json({ code: 500, message: e.message })
}
}
// DELETE /api/customers/:id —— 删除
async function remove(req, res) {
const { id } = req.params
try {
let checkSql = 'SELECT id FROM customers WHERE id = ?'
let checkParams = [id]
if (req.scope && req.scope.sql) {
checkSql += ' ' + req.scope.sql
checkParams.push(...req.scope.params)
}
const [existing] = await pool.query(checkSql, checkParams)
if (existing.length === 0) {
return res.status(404).json({ code: 404, message: '客户不存在或无权操作' })
}
await pool.query('DELETE FROM customers WHERE id = ?', [id])
res.json({ code: 0, message: 'ok' })
} catch (e) {
console.error('[customers delete] error:', e)
if (e.code === 'ER_ROW_IS_REFERENCED_2') {
return res.status(400).json({ code: 400, message: '该客户被合同或售后记录引用,无法删除' })
}
res.status(500).json({ code: 500, message: e.message })
}
}
// GET /api/customers/simple —— 简易加盟商列表(无数据范围限制,用于下拉选择)
async function simpleList(req, res) {
try {
const [rows] = await pool.query(
'SELECT id, name FROM customers ORDER BY id'
)
res.json({ code: 0, message: 'ok', data: rows })
} catch (e) {
console.error('[customers simpleList] error:', e)
res.status(500).json({ code: 500, message: e.message })
}
}
module.exports = { list, detail, create, update, remove, simpleList }