190 lines
6.0 KiB
TypeScript
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
|
|
)
|
|
}
|
|
}
|