300 lines
9.0 KiB
TypeScript
300 lines
9.0 KiB
TypeScript
/**
|
|
* 供应商API接口
|
|
* 作者: 阿瑞
|
|
* 功能: 提供供应商数据的查询和创建接口
|
|
* 版本: 2.0.0
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { RequestWithDB, connectTeamDB } from '@/lib/db';
|
|
import { SupplierStatus } from '@/models/team/types/ISupplier';
|
|
|
|
/**
|
|
* 为请求添加团队信息
|
|
* @param req 原始请求对象
|
|
* @param teamCode 团队代码
|
|
* @returns 包含团队信息的新请求对象
|
|
*/
|
|
const addTeamInfoToRequest = (req: NextRequest, teamCode: string): NextRequest => {
|
|
// 创建新的请求对象
|
|
const teamReq = new NextRequest(req.url, {
|
|
method: req.method,
|
|
headers: new Headers(req.headers),
|
|
body: req.body,
|
|
cache: req.cache,
|
|
credentials: req.credentials,
|
|
integrity: req.integrity,
|
|
keepalive: req.keepalive,
|
|
mode: req.mode,
|
|
redirect: req.redirect,
|
|
referrer: req.referrer,
|
|
referrerPolicy: req.referrerPolicy
|
|
});
|
|
|
|
// 添加团队ID信息
|
|
teamReq.headers.set('x-team-id', teamCode);
|
|
|
|
return teamReq;
|
|
};
|
|
|
|
/**
|
|
* 从请求路径中提取团队代码
|
|
* @param req 请求对象
|
|
* @returns 团队代码
|
|
*/
|
|
const extractTeamCodeFromPath = (req: NextRequest): string => {
|
|
// 路径格式: /api/team/[teamCode]/suppliers
|
|
const pathParts = req.nextUrl.pathname.split('/');
|
|
// 团队代码位于索引3的位置
|
|
return pathParts[3] || '';
|
|
};
|
|
|
|
/**
|
|
* GET 获取供应商列表
|
|
*/
|
|
const getSuppliers = async (req: RequestWithDB, params?: Record<string, unknown>) => {
|
|
const teamCode = params?.teamCode as string;
|
|
|
|
// 获取查询参数
|
|
const url = new URL(req.url);
|
|
const page = parseInt(url.searchParams.get('page') || '1');
|
|
const pageSize = parseInt(url.searchParams.get('pageSize') || '10');
|
|
const keyword = url.searchParams.get('keyword') || '';
|
|
const status = url.searchParams.get('status') !== null ? parseInt(url.searchParams.get('status') as string) : null;
|
|
const level = url.searchParams.get('level') || null;
|
|
const type = url.searchParams.get('type') || null;
|
|
|
|
// 计算偏移量
|
|
const offset = (page - 1) * pageSize;
|
|
|
|
try {
|
|
console.log(`开始查询团队[${teamCode}]供应商列表, 页码:${page}, 每页:${pageSize}`);
|
|
|
|
// 构建查询条件
|
|
const conditions = [];
|
|
const queryParams = [];
|
|
|
|
if (keyword) {
|
|
conditions.push('(name LIKE ? OR JSON_EXTRACT(contact, "$.contactPerson") LIKE ? OR JSON_EXTRACT(contact, "$.phone") LIKE ?)');
|
|
queryParams.push(`%${keyword}%`, `%${keyword}%`, `%${keyword}%`);
|
|
}
|
|
|
|
if (status !== null) {
|
|
conditions.push('status = ?');
|
|
queryParams.push(status);
|
|
}
|
|
|
|
if (level) {
|
|
conditions.push('level = ?');
|
|
queryParams.push(level);
|
|
}
|
|
|
|
if (type) {
|
|
conditions.push('type = ?');
|
|
queryParams.push(type);
|
|
}
|
|
|
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
|
|
// 使用数据库连接
|
|
const connection = req.db;
|
|
|
|
// 查询总数
|
|
const countSql = `SELECT COUNT(*) as total FROM suppliers ${whereClause}`;
|
|
const [totalRows] = await connection.query(countSql, queryParams);
|
|
|
|
const total = (totalRows as Array<{ total: number }>)[0].total;
|
|
|
|
// 查询分页数据
|
|
const querySql = `
|
|
SELECT
|
|
id, \`order\`, name, contact, status, level, type, remark,
|
|
created_at as createdAt, updated_at as updatedAt
|
|
FROM suppliers ${whereClause}
|
|
ORDER BY \`order\` ASC, id ASC
|
|
LIMIT ? OFFSET ?
|
|
`;
|
|
|
|
// 添加分页参数
|
|
const paginatedParams = [...queryParams, pageSize, offset];
|
|
|
|
const [rows] = await connection.query(querySql, paginatedParams);
|
|
|
|
console.log(`查询团队[${teamCode}]供应商列表成功, 总数:${total}`);
|
|
|
|
// 查询所有不同的供应商级别和类型,用于前端筛选
|
|
const [levelRows] = await connection.query('SELECT DISTINCT level FROM suppliers WHERE level IS NOT NULL AND level != ""');
|
|
const [typeRows] = await connection.query('SELECT DISTINCT type FROM suppliers WHERE type IS NOT NULL AND type != ""');
|
|
|
|
// 转换结果
|
|
const levels = Array.isArray(levelRows) ? levelRows.map((row) => (row as unknown as { level: string }).level).filter(Boolean) : [];
|
|
const types = Array.isArray(typeRows) ? typeRows.map((row) => (row as unknown as { type: string }).type).filter(Boolean) : [];
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
total,
|
|
suppliers: Array.isArray(rows) ? rows : [],
|
|
filters: {
|
|
levels,
|
|
types
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error(`获取团队[${teamCode}]供应商列表失败:`, error);
|
|
return NextResponse.json(
|
|
{ success: false, error: '获取供应商列表失败' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* POST 创建供应商
|
|
*/
|
|
const createSupplier = async (req: RequestWithDB, params?: Record<string, unknown>) => {
|
|
const teamCode = params?.teamCode as string;
|
|
|
|
// 获取请求数据
|
|
const data = await req.json();
|
|
|
|
// 验证必填字段
|
|
if (!data.name) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '供应商名称为必填字段' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
try {
|
|
console.log(`开始创建团队[${teamCode}]供应商, 名称:${data.name}`);
|
|
|
|
// 使用数据库连接
|
|
const connection = req.db;
|
|
|
|
try {
|
|
await connection.beginTransaction();
|
|
|
|
// 检查供应商名称是否已存在
|
|
const [existingSuppliers] = await connection.query(
|
|
'SELECT id FROM suppliers WHERE name = ?',
|
|
[data.name]
|
|
);
|
|
|
|
if (Array.isArray(existingSuppliers) && existingSuppliers.length > 0) {
|
|
await connection.rollback();
|
|
return NextResponse.json(
|
|
{ success: false, error: '该供应商名称已存在' },
|
|
{ status: 409 }
|
|
);
|
|
}
|
|
|
|
// 处理联系方式字段
|
|
let contactJson = null;
|
|
if (data.contact) {
|
|
contactJson = JSON.stringify(data.contact);
|
|
}
|
|
|
|
// 插入供应商记录
|
|
const insertSql = `
|
|
INSERT INTO suppliers (
|
|
\`order\`, name, contact, status, level, type, remark, created_at, updated_at
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
|
|
`;
|
|
|
|
const [result] = await connection.query(insertSql, [
|
|
data.order || 0,
|
|
data.name,
|
|
contactJson,
|
|
data.status !== undefined ? data.status : SupplierStatus.ENABLED,
|
|
data.level || null,
|
|
data.type || null,
|
|
data.remark || null
|
|
]);
|
|
|
|
const insertId = (result as { insertId: number }).insertId;
|
|
|
|
// 查询新插入的供应商信息
|
|
const [newSupplierRows] = await connection.query(
|
|
`SELECT
|
|
id, \`order\`, name, contact, status, level, type, remark,
|
|
created_at as createdAt, updated_at as updatedAt
|
|
FROM suppliers WHERE id = ?`,
|
|
[insertId]
|
|
);
|
|
|
|
// 提交事务
|
|
await connection.commit();
|
|
|
|
console.log(`创建团队[${teamCode}]供应商成功, ID:${insertId}`);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: '供应商创建成功',
|
|
supplier: Array.isArray(newSupplierRows) && newSupplierRows.length > 0 ? newSupplierRows[0] : null
|
|
});
|
|
} catch (error) {
|
|
// 发生错误时回滚事务
|
|
await connection.rollback();
|
|
throw error;
|
|
}
|
|
} catch (error) {
|
|
console.error(`创建团队[${teamCode}]供应商失败:`, error);
|
|
return NextResponse.json(
|
|
{ success: false, error: '创建供应商失败' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
};
|
|
|
|
// 导出处理函数
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
// 从URL路径中提取团队代码
|
|
const teamCode = extractTeamCodeFromPath(req);
|
|
|
|
if (!teamCode) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '无效的团队代码' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// 添加团队信息到请求
|
|
const teamReq = addTeamInfoToRequest(req, teamCode);
|
|
|
|
// 使用新版的connectTeamDB中间件处理请求
|
|
return connectTeamDB(getSuppliers)(teamReq, { teamCode });
|
|
} catch (error) {
|
|
console.error('处理供应商列表请求失败:', error);
|
|
return NextResponse.json(
|
|
{ success: false, error: '处理请求失败' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
// 从URL路径中提取团队代码
|
|
const teamCode = extractTeamCodeFromPath(req);
|
|
|
|
if (!teamCode) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '无效的团队代码' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// 添加团队信息到请求
|
|
const teamReq = addTeamInfoToRequest(req, teamCode);
|
|
|
|
// 使用新版的connectTeamDB中间件处理请求
|
|
return connectTeamDB(createSupplier)(teamReq, { teamCode });
|
|
} catch (error) {
|
|
console.error('处理供应商创建请求失败:', error);
|
|
return NextResponse.json(
|
|
{ success: false, error: '处理请求失败' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|