GuDingZiChan/backend/src/controllers/disposalController.ts
2026-03-10 16:19:47 +08:00

255 lines
7.8 KiB
TypeScript

import { Request, Response } from 'express'
import prisma from '../utils/prisma'
import { successResponse, errorResponse } from '../utils/response'
import { logOperation } from './operationLogController'
// 创建报废申请
export const createDisposal = async (req: Request, res: Response) => {
try {
const { equipment_id, disposal_reason, disposal_method, estimated_value, notes } = req.body
const userId = res.locals.user?.id
if (!userId) {
return errorResponse(res, '用户未登录', 401)
}
const equipment = await prisma.equipment.findUnique({
where: { id: Number(equipment_id) }
})
if (!equipment) {
return errorResponse(res, '资产不存在', 404)
}
if (equipment.status === '已借出') {
return errorResponse(res, '资产已借出,无法申请报废')
}
if (equipment.status === '待报废' || equipment.status === '已报废') {
return errorResponse(res, '资产已在报废流程中')
}
const disposal = await prisma.disposalRecord.create({
data: {
equipment_id: equipment.id,
equipment_code: equipment.equipment_code,
disposal_reason,
disposal_method,
estimated_value: Number(estimated_value) || 0,
applied_by: userId,
notes
}
})
await prisma.equipment.update({
where: { id: equipment.id },
data: { status: '待报废' }
})
// 记录操作日志
const username = res.locals.user?.username || res.locals.user?.name || 'unknown'
await logOperation(
userId,
username,
'报废申请',
`申请报废资产 ${equipment.equipment_name}(${equipment.equipment_code}),原因:${disposal_reason},处置方式:${disposal_method}`,
equipment.id,
equipment.equipment_code,
req.ip
)
successResponse(res, disposal, '报废申请创建成功')
} catch (error: any) {
console.error('[创建报废申请失败]', error)
errorResponse(res, error.message || '创建报废申请失败')
}
}
// 获取报废记录列表
export const getDisposalList = async (req: Request, res: Response) => {
try {
const { page = 1, pageSize = 10, status, keyword, equipment_id } = req.query
const skip = (Number(page) - 1) * Number(pageSize)
const where: any = {}
if (status) where.status = status
if (equipment_id) where.equipment_id = Number(equipment_id)
if (keyword) {
where.OR = [
{ equipment_code: { contains: String(keyword) } },
{ disposal_reason: { contains: String(keyword) } }
]
}
const [list, total] = await Promise.all([
prisma.disposalRecord.findMany({
where,
skip,
take: Number(pageSize),
orderBy: { created_at: 'desc' },
include: {
equipment: { select: { equipment_name: true, equipment_type: true, unit_price: true } },
applier: { select: { id: true, name: true, username: true } },
approver: { select: { id: true, name: true, username: true } }
}
}),
prisma.disposalRecord.count({ where })
])
successResponse(res, { list, total, page: Number(page), pageSize: Number(pageSize) }, '获取成功')
} catch (error: any) {
errorResponse(res, error.message || '获取报废记录列表失败')
}
}
// 获取报废记录详情
export const getDisposalDetail = async (req: Request, res: Response) => {
try {
const { id } = req.params
const disposal = await prisma.disposalRecord.findUnique({
where: { id: Number(id) },
include: {
equipment: true,
applier: { select: { id: true, name: true, username: true } },
approver: { select: { id: true, name: true, username: true } }
}
})
if (!disposal) {
return errorResponse(res, '报废记录不存在', 404)
}
successResponse(res, disposal, '获取成功')
} catch (error: any) {
errorResponse(res, error.message || '获取报废记录详情失败')
}
}
// 审批报废申请
export const approveDisposal = async (req: Request, res: Response) => {
try {
const { id } = req.params
const { approved, reject_reason } = req.body
const userId = res.locals.user?.id
if (!userId) {
return errorResponse(res, '用户未登录', 401)
}
const disposal = await prisma.disposalRecord.findUnique({
where: { id: Number(id) },
include: { equipment: true }
})
if (!disposal) {
return errorResponse(res, '报废记录不存在', 404)
}
if (disposal.status !== 'pending') {
return errorResponse(res, '该申请已处理')
}
if (approved) {
await prisma.disposalRecord.update({
where: { id: Number(id) },
data: { status: 'approved', approved_by: userId, approved_at: new Date() }
})
} else {
await prisma.disposalRecord.update({
where: { id: Number(id) },
data: { status: 'rejected', approved_by: userId, approved_at: new Date(), notes: reject_reason }
})
await prisma.equipment.update({
where: { id: disposal.equipment_id },
data: { status: '可用' }
})
}
// 记录操作日志
const username = res.locals.user?.username || res.locals.user?.name || 'unknown'
await logOperation(
userId,
username,
approved ? '报废审批通过' : '报废审批驳回',
`${approved ? '批准' : '驳回'}资产 ${disposal.equipment?.equipment_name || ''}(${disposal.equipment_code}) 的报废申请${!approved && reject_reason ? `,原因:${reject_reason}` : ''}`,
disposal.equipment_id,
disposal.equipment_code,
req.ip
)
successResponse(res, null, approved ? '审批通过' : '已驳回')
} catch (error: any) {
errorResponse(res, error.message || '审批失败')
}
}
// 完成报废处置
export const completeDisposal = async (req: Request, res: Response) => {
try {
const { id } = req.params
const { actual_value, notes } = req.body
const disposal = await prisma.disposalRecord.findUnique({
where: { id: Number(id) }
})
if (!disposal) {
return errorResponse(res, '报废记录不存在', 404)
}
if (disposal.status !== 'approved') {
return errorResponse(res, '只有已审批的申请才能完成处置')
}
await prisma.disposalRecord.update({
where: { id: Number(id) },
data: {
status: 'completed',
actual_value: actual_value !== undefined ? Number(actual_value) : disposal.estimated_value,
completed_at: new Date(),
notes: notes || disposal.notes
}
})
await prisma.equipment.update({
where: { id: disposal.equipment_id },
data: { status: '已报废' }
})
// 记录操作日志
const userId = res.locals.user?.id
const username = res.locals.user?.username || res.locals.user?.name || 'unknown'
await logOperation(
userId,
username,
'报废完成',
`完成资产 (${disposal.equipment_code}) 的报废处置,实际残值:¥${actual_value !== undefined ? actual_value : disposal.estimated_value}`,
disposal.equipment_id,
disposal.equipment_code,
req.ip
)
successResponse(res, null, '报废处置完成')
} catch (error: any) {
errorResponse(res, error.message || '完成报废处置失败')
}
}
// 获取资产的报废历史
export const getEquipmentDisposalHistory = async (req: Request, res: Response) => {
try {
const { equipment_id } = req.params
const history = await prisma.disposalRecord.findMany({
where: { equipment_id: Number(equipment_id) },
orderBy: { created_at: 'desc' },
include: {
applier: { select: { id: true, name: true } },
approver: { select: { id: true, name: true } }
}
})
successResponse(res, history, '获取成功')
} catch (error: any) {
errorResponse(res, error.message || '获取报废历史失败')
}
}