GuDingZiChan/backend/src/controllers/publicInventoryController.ts
2026-03-23 11:54:41 +08:00

190 lines
6.0 KiB
TypeScript

import type { Request, Response } from 'express'
import { errorResponse, successResponse } from '../utils/response'
import {
confirmInventoryParticipant,
getInventoryTaskPublicInfo,
getParticipantItems,
getParticipantTaskContext,
searchTaskParticipants,
submitInventoryException,
submitInventoryScan
} from '../services/inventoryService'
const INVENTORY_SESSION_KEY = 'inventoryParticipant'
const getInventorySession = (req: Request) => ((req.session as any)?.[INVENTORY_SESSION_KEY] || null) as
| {
taskId: number
participantId: number
publicToken: string
}
| null
const setInventorySession = (
req: Request,
payload: {
taskId: number
participantId: number
publicToken: string
}
) => {
;(req.session as any)[INVENTORY_SESSION_KEY] = payload
}
const clearInventorySession = (req: Request) => {
if ((req.session as any)?.[INVENTORY_SESSION_KEY]) {
delete (req.session as any)[INVENTORY_SESSION_KEY]
}
}
const ensureInventorySession = async (req: Request) => {
const session = getInventorySession(req)
if (!session) {
throw new Error('盘点会话不存在,请重新确认身份')
}
const taskContext = await getParticipantTaskContext(session.taskId, session.participantId)
if (taskContext.task.public_token !== session.publicToken) {
clearInventorySession(req)
throw new Error('盘点会话已失效,请重新确认身份')
}
return {
session,
...taskContext
}
}
export const getPublicInventoryTaskController = async (req: Request, res: Response) => {
try {
const data = await getInventoryTaskPublicInfo(req.params.token)
successResponse(res, data, '获取成功')
} catch (error: any) {
const message = error.message || '获取盘点任务失败'
errorResponse(res, message, message.includes('不存在') ? 404 : 500)
}
}
export const searchPublicInventoryParticipantsController = async (req: Request, res: Response) => {
try {
const keyword = typeof req.query.keyword === 'string' ? req.query.keyword : ''
const list = await searchTaskParticipants(req.params.token, keyword)
successResponse(res, list, '获取成功')
} catch (error: any) {
const message = error.message || '搜索盘点人员失败'
errorResponse(res, message, message.includes('不存在') ? 404 : 500)
}
}
export const confirmPublicInventoryParticipantController = async (req: Request, res: Response) => {
try {
const participantId = Number(req.body?.participant_id)
if (!Number.isInteger(participantId) || participantId <= 0) {
return errorResponse(res, '请选择盘点人员', 422)
}
const data = await confirmInventoryParticipant(req.params.token, participantId)
setInventorySession(req, {
taskId: data.task_id,
participantId: data.participant_id,
publicToken: req.params.token
})
successResponse(res, data, '确认成功')
} catch (error: any) {
const message = error.message || '确认盘点身份失败'
errorResponse(res, message, message.includes('不存在') ? 404 : 422)
}
}
export const getPublicInventoryMeController = async (req: Request, res: Response) => {
try {
const { task, participant } = await ensureInventorySession(req)
successResponse(
res,
{
task: {
id: task.id,
title: task.title,
status: task.status,
scope_department_name: task.scope_department_name,
scope_asset_type_name: task.scope_asset_type_name,
completed_count: task.completed_count,
exception_count: task.exception_count,
items_count: task.items_count,
closed_at: task.closed_at
},
participant
},
'获取成功'
)
} catch (error: any) {
const message = error.message || '获取盘点会话失败'
errorResponse(res, message, message.includes('不存在') ? 404 : 401)
}
}
export const getPublicInventoryItemsController = async (req: Request, res: Response) => {
try {
const { task, participant } = await ensureInventorySession(req)
const data = await getParticipantItems(task.id, participant.id)
successResponse(res, data, '获取成功')
} catch (error: any) {
const message = error.message || '获取盘点资产失败'
errorResponse(res, message, message.includes('不存在') ? 404 : 401)
}
}
export const submitPublicInventoryScanController = async (req: Request, res: Response) => {
try {
const { task, participant } = await ensureInventorySession(req)
if (task.status === 'closed') {
return errorResponse(res, '盘点任务已关闭', 403)
}
const equipmentCode = String(req.body?.equipment_code || '').trim()
if (!equipmentCode) {
return errorResponse(res, '资产编码不能为空', 422)
}
const data = await submitInventoryScan(task.id, participant.id, equipmentCode)
successResponse(res, data, '盘点成功')
} catch (error: any) {
const message = error.message || '提交盘点结果失败'
errorResponse(
res,
message,
message.includes('盘点范围') || message.includes('不能为空') ? 422 : message.includes('不存在') ? 404 : 401
)
}
}
export const submitPublicInventoryExceptionController = async (req: Request, res: Response) => {
try {
const { task, participant } = await ensureInventorySession(req)
if (task.status === 'closed') {
return errorResponse(res, '盘点任务已关闭', 403)
}
const itemId = Number(req.params.itemId)
if (!Number.isInteger(itemId) || itemId <= 0) {
return errorResponse(res, '盘点资产不存在', 404)
}
await submitInventoryException(
task.id,
participant.id,
itemId,
String(req.body?.exception_type || ''),
req.body?.exception_note
)
successResponse(res, null, '异常已提交')
} catch (error: any) {
const message = error.message || '提交盘点异常失败'
errorResponse(
res,
message,
message.includes('不存在') ? 404 : message.includes('无效') ? 422 : 401
)
}
}