feat: 恢复IT资产详情直接维护
This commit is contained in:
parent
963dcc06af
commit
f69406e888
@ -64,6 +64,34 @@ const includeStorageLocation = {
|
||||
}
|
||||
}
|
||||
|
||||
const EQUIPMENT_UPDATE_FIELD_LABELS: Record<string, string> = {
|
||||
equipment_code: '资产编码',
|
||||
equipment_name: '资产名称',
|
||||
equipment_model: '资产型号',
|
||||
equipment_type: '资产类型',
|
||||
asset_type_id: '资产分类',
|
||||
unit_price: '单价',
|
||||
total_quantity: '库存总数量',
|
||||
purchase_date: '采购日期',
|
||||
supplier: '供应商',
|
||||
description: '资产描述',
|
||||
storage_location_id: '存放地址'
|
||||
}
|
||||
|
||||
const buildEquipmentUpdateOperationDetails = (
|
||||
currentEquipment: Record<string, any>,
|
||||
updateData: Record<string, unknown>
|
||||
) => {
|
||||
const changedFields = Object.keys(EQUIPMENT_UPDATE_FIELD_LABELS).filter((field) =>
|
||||
Object.prototype.hasOwnProperty.call(updateData, field)
|
||||
)
|
||||
return `直接维护资产资料:${changedFields.map((field) => {
|
||||
const before = currentEquipment[field] ?? '-'
|
||||
const after = updateData[field] ?? '-'
|
||||
return `${EQUIPMENT_UPDATE_FIELD_LABELS[field]} ${before} → ${after}`
|
||||
}).join(';')}`
|
||||
}
|
||||
|
||||
const activeBorrowSelect = {
|
||||
borrow_records: {
|
||||
where: {
|
||||
@ -1334,6 +1362,19 @@ export const updateEquipment = async (req: Request, res: Response) => {
|
||||
await refreshParentTotalValueWithChildren(tx, currentEquipment.parent_id)
|
||||
}
|
||||
|
||||
const operator = res.locals.user
|
||||
await tx.operationLog.create({
|
||||
data: {
|
||||
user_id: operator?.id || null,
|
||||
username: operator?.username || operator?.name || '未知用户',
|
||||
operation_type: 'asset_basic_update',
|
||||
equipment_id: currentEquipment.id,
|
||||
equipment_code: currentEquipment.equipment_code,
|
||||
operation_details: buildEquipmentUpdateOperationDetails(currentEquipment, updateData),
|
||||
ip_address: req.ip || null
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
|
||||
@ -21,8 +21,9 @@ test('行政可以登记和审批但不能借还、调拨或挂载', () => {
|
||||
assert.ok(!permissions.includes(PERMISSIONS.ASSETS_MOUNT))
|
||||
})
|
||||
|
||||
test('IT可以流转、发起报废和盘点,但不能审批或管理用户', () => {
|
||||
test('IT可以直接维护资产资料、流转、发起报废和盘点,但不能审批或管理用户', () => {
|
||||
const permissions = getPermissionsForRole('it')
|
||||
assert.ok(permissions.includes(PERMISSIONS.ASSETS_CORRECT))
|
||||
assert.ok(permissions.includes(PERMISSIONS.ASSETS_BORROW))
|
||||
assert.ok(permissions.includes(PERMISSIONS.ASSETS_TRANSFER))
|
||||
assert.ok(permissions.includes(PERMISSIONS.ASSETS_PRINT_LABELS))
|
||||
|
||||
@ -45,6 +45,7 @@ const ROLE_PERMISSIONS: Record<UserRole, readonly Permission[]> = {
|
||||
],
|
||||
it: [
|
||||
PERMISSIONS.ASSETS_VIEW_ALL,
|
||||
PERMISSIONS.ASSETS_CORRECT,
|
||||
PERMISSIONS.ASSETS_BORROW,
|
||||
PERMISSIONS.ASSETS_TRANSFER,
|
||||
PERMISSIONS.ASSETS_MAINTENANCE,
|
||||
|
||||
@ -71,7 +71,12 @@
|
||||
|
||||
<div class="field-stack">
|
||||
<label class="field-label">使用部门</label>
|
||||
<select v-model="form.department_id" class="select" :disabled="isEdit || !canTransfer">
|
||||
<select
|
||||
v-model="form.department_id"
|
||||
class="select"
|
||||
:disabled="isEdit ? !canChangeDepartmentDirectly : !canTransfer"
|
||||
@change="handleDepartmentChange"
|
||||
>
|
||||
<option value="">请选择使用部门</option>
|
||||
<template v-for="department in departments" :key="department.id">
|
||||
<option :value="department.id">{{ department.name }}</option>
|
||||
@ -431,6 +436,7 @@ import { createEquipment, updateEquipment, getEquipmentDetail, generateEquipment
|
||||
import { getStorageLocationOptions } from '@/api/storageLocation'
|
||||
import { getAssetTypeOptions } from '@/api/assetType'
|
||||
import { getDepartmentOptions } from '@/api/department'
|
||||
import { batchTransfer } from '@/api/batch'
|
||||
import { getMaintenanceList, createMaintenance } from '@/api/maintenance'
|
||||
import { getEquipmentDisposalHistory, createDisposal } from '@/api/disposal'
|
||||
import type { Equipment, StorageLocation, AssetType, Department, CodeGenerationMode, EquipmentStatus } from '@/types'
|
||||
@ -507,6 +513,7 @@ const showDisposalForm = ref(false)
|
||||
const showBarcodePrint = ref(false)
|
||||
const currentEquipment = ref<Equipment | null>(null)
|
||||
const selectedDisposalItemIds = ref<number[]>([])
|
||||
const departmentTransferLoading = ref(false)
|
||||
|
||||
interface DisposalTreeItem {
|
||||
id: number
|
||||
@ -541,6 +548,10 @@ const canEditEquipmentCode = computed(() => {
|
||||
if (!isEdit.value) return true
|
||||
return canEditBasic.value && currentEquipment.value?.can_correct_code === true
|
||||
})
|
||||
const canChangeDepartmentDirectly = computed(() => {
|
||||
if (!isEdit.value || !canTransfer.value || departmentTransferLoading.value) return false
|
||||
return !currentEquipment.value?.parent_id
|
||||
})
|
||||
const canStartMaintenance = computed(() => {
|
||||
if (!canMaintain.value || !currentEquipment.value || currentEquipment.value.parent_id) return false
|
||||
return !['已借出', '维护中', '待报废', '已报废'].includes(currentEquipment.value.status)
|
||||
@ -856,6 +867,48 @@ const fetchDisposalRecords = async () => {
|
||||
} catch (error) { console.error('获取报废记录失败:', error) }
|
||||
}
|
||||
|
||||
const handleDepartmentChange = async () => {
|
||||
if (!isEdit.value || !currentEquipment.value) return
|
||||
|
||||
const currentDepartmentId = currentEquipment.value.department_id ?? undefined
|
||||
const targetDepartmentId = form.value.department_id ? Number(form.value.department_id) : undefined
|
||||
if (targetDepartmentId === currentDepartmentId) return
|
||||
|
||||
if (!targetDepartmentId) {
|
||||
form.value.department_id = currentDepartmentId
|
||||
alert('转为闲置请在资产管理列表中使用“批量转移”。')
|
||||
return
|
||||
}
|
||||
|
||||
const targetDepartment = departments.value.find((department) => department.id === targetDepartmentId)
|
||||
const confirmed = confirm(`确认将“${currentEquipment.value.equipment_name}”调拨至“${targetDepartment?.name || '所选部门'}”?`)
|
||||
if (!confirmed) {
|
||||
form.value.department_id = currentDepartmentId
|
||||
return
|
||||
}
|
||||
|
||||
departmentTransferLoading.value = true
|
||||
try {
|
||||
const response = await batchTransfer({
|
||||
equipment_ids: [currentEquipment.value.id],
|
||||
target_type: 'department',
|
||||
department_id: targetDepartmentId,
|
||||
reason: `详情页调拨:${currentEquipment.value.department?.name || '未分配部门'} → ${targetDepartment?.name || '所选部门'}`
|
||||
})
|
||||
const result = response.data?.results?.[0]
|
||||
if (!response.data || response.data.success_count !== 1 || result?.status !== 'success') {
|
||||
throw new Error(result?.message || '资产调拨失败')
|
||||
}
|
||||
await fetchEquipmentData()
|
||||
alert('使用部门已更新')
|
||||
} catch (error: any) {
|
||||
form.value.department_id = currentDepartmentId
|
||||
alert(error?.message || '资产调拨失败')
|
||||
} finally {
|
||||
departmentTransferLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const submitMaintenance = async () => {
|
||||
if (!canStartMaintenance.value) return
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user