import type { Request, Response } from 'express' import { errorResponse, successResponse } from '../utils/response' import { assignUnassignedTaskItem, closeInventoryTask, createInventoryTask, deleteInventoryTask, getInventoryTaskDetail, getTaskUnassignedItems, listInventoryTasks, previewInventoryTask, submitAdminInventoryScan } from '../services/inventoryService' import { normalizeInventoryScopeInput } from '../utils/inventoryScope' const toOptionalNumber = (value: unknown) => { if (value === undefined || value === null || value === '') return null const numericValue = Number(value) return Number.isNaN(numericValue) ? null : numericValue } export const previewInventoryTaskController = async (req: Request, res: Response) => { try { const normalizedScope = normalizeInventoryScopeInput({ department_id: toOptionalNumber(req.body?.department_id), department_ids: req.body?.department_ids, asset_type_id: toOptionalNumber(req.body?.asset_type_id), asset_type_ids: req.body?.asset_type_ids, storage_location_id: toOptionalNumber(req.body?.storage_location_id), storage_location_ids: req.body?.storage_location_ids, person_id: toOptionalNumber(req.body?.person_id), person_ids: req.body?.person_ids }) const result = await previewInventoryTask(normalizedScope) successResponse(res, result, '预览成功') } catch (error: any) { errorResponse(res, error.message || '预览盘点任务失败', 422) } } export const createInventoryTaskController = async (req: Request, res: Response) => { try { const currentUserId = Number(res.locals.user?.id) if (!Number.isInteger(currentUserId) || currentUserId <= 0) { return errorResponse(res, '未获取到当前登录用户', 401) } const normalizedScope = normalizeInventoryScopeInput({ department_id: toOptionalNumber(req.body?.department_id), department_ids: req.body?.department_ids, asset_type_id: toOptionalNumber(req.body?.asset_type_id), asset_type_ids: req.body?.asset_type_ids, storage_location_id: toOptionalNumber(req.body?.storage_location_id), storage_location_ids: req.body?.storage_location_ids, person_id: toOptionalNumber(req.body?.person_id), person_ids: req.body?.person_ids }) const result = await createInventoryTask( { title: req.body?.title, description: req.body?.description, deadline_at: req.body?.deadline_at, department_ids: normalizedScope.departmentIds, asset_type_ids: normalizedScope.assetTypeIds, storage_location_ids: normalizedScope.storageLocationIds, person_ids: normalizedScope.personIds }, currentUserId ) successResponse(res, result, '创建成功') } catch (error: any) { errorResponse(res, error.message || '创建盘点任务失败', 422) } } export const getInventoryTaskListController = async (req: Request, res: Response) => { try { const page = Math.max(1, Number(req.query.page) || 1) const pageSize = Math.min(50, Math.max(1, Number(req.query.pageSize) || 10)) const result = await listInventoryTasks(page, pageSize) successResponse(res, result, '获取成功') } catch (error: any) { errorResponse(res, error.message || '获取盘点任务列表失败', 500) } } export const getInventoryTaskDetailController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) if (!Number.isInteger(taskId) || taskId <= 0) { return errorResponse(res, '盘点任务不存在', 404) } const result = await getInventoryTaskDetail(taskId) successResponse(res, result, '获取成功') } catch (error: any) { const message = error.message || '获取盘点任务详情失败' errorResponse(res, message, message.includes('不存在') ? 404 : 500) } } export const closeInventoryTaskController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) const currentUserId = Number(res.locals.user?.id) if (!Number.isInteger(taskId) || taskId <= 0) { return errorResponse(res, '盘点任务不存在', 404) } if (!Number.isInteger(currentUserId) || currentUserId <= 0) { return errorResponse(res, '未获取到当前登录用户', 401) } await closeInventoryTask(taskId, currentUserId) successResponse(res, null, '任务已关闭') } catch (error: any) { const message = error.message || '关闭盘点任务失败' errorResponse(res, message, message.includes('不存在') ? 404 : 500) } } export const deleteInventoryTaskController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) if (!Number.isInteger(taskId) || taskId <= 0) { return errorResponse(res, '盘点任务不存在', 404) } await deleteInventoryTask(taskId) successResponse(res, null, '任务已删除') } catch (error: any) { const message = error.message || '删除盘点任务失败' if (message.includes('不存在')) { return errorResponse(res, message, 404) } errorResponse(res, message, 422) } } export const getInventoryTaskUnassignedController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) if (!Number.isInteger(taskId) || taskId <= 0) { return errorResponse(res, '盘点任务不存在', 404) } const list = await getTaskUnassignedItems(taskId) successResponse(res, list, '获取成功') } catch (error: any) { errorResponse(res, error.message || '获取无人归属资产失败', 500) } } export const assignInventoryTaskUnassignedController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) const itemId = Number(req.params.itemId) const personId = Number(req.body?.person_id) if (!Number.isInteger(taskId) || taskId <= 0 || !Number.isInteger(itemId) || itemId <= 0) { return errorResponse(res, '待处理资产不存在', 404) } if (!Number.isInteger(personId) || personId <= 0) { return errorResponse(res, '目标人员不能为空', 422) } await assignUnassignedTaskItem(taskId, itemId, personId) successResponse(res, null, '分配成功') } catch (error: any) { const message = error.message || '分配无人归属资产失败' errorResponse(res, message, message.includes('不存在') ? 404 : 422) } } export const submitAdminInventoryScanController = async (req: Request, res: Response) => { try { const taskId = Number(req.params.id) const currentUserId = Number(res.locals.user?.id) const equipmentCode = String(req.body?.equipment_code || '').trim() if (!Number.isInteger(taskId) || taskId <= 0) { return errorResponse(res, '盘点任务不存在', 404) } if (!Number.isInteger(currentUserId) || currentUserId <= 0) { return errorResponse(res, '未获取到当前登录用户', 401) } if (!equipmentCode) { return errorResponse(res, '资产编码不能为空', 422) } const item = await submitAdminInventoryScan(taskId, equipmentCode, currentUserId) successResponse(res, item, '管理人员代扫成功') } catch (error: any) { const message = error.message || '管理人员扫码盘点失败' errorResponse( res, message, message.includes('不存在') ? 404 : message.includes('关闭') ? 403 : 422 ) } }