255 lines
7.8 KiB
TypeScript
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 || '获取报废历史失败')
|
|
}
|
|
}
|