GuDingZiChan/backend/src/controllers/inventoryController.ts

206 lines
7.3 KiB
TypeScript

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
)
}
}