3.20

<template>
<div class="approval-management">
<div class="header">
<h2>领用审核</h2>
<div class="actions">
<el-button type="primary" @click="showAddDialog">新增申请</el-button>
<el-button type="success" @click="batchApprove" :disabled="selectedRecords.length === 0">批量通过</el-button>
<el-button type="danger" @click="batchReject" :disabled="selectedRecords.length === 0">批量驳回</el-button>
<el-button type="warning" @click="sendReminders">发送超时提醒</el-button>
<el-button type="info" @click="showStatistics">统计信息</el-button>
<el-button type="primary" @click="exportData">批量导出</el-button>
<el-button type="success" @click="showImportDialog">模版导入</el-button>
</div>
</div>

<!-- 搜索区域 -->
<div class="search-area">
<el-form :inline="true" :model="searchForm" class="search-form">
<el-form-item label="申请人">
<el-select v-model="searchForm.applicant" placeholder="请选择申请人" clearable filterable>
<el-option v-for="applicant in applicantList" :key="applicant" :label="applicant" :value="applicant"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备件名称">
<el-select v-model="searchForm.sparePartName" placeholder="请选择备件名称" clearable filterable>
<el-option v-for="name in sparePartNameList" :key="name" :label="name" :value="name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
<el-option label="待审核" value="待审核"></el-option>
<el-option label="已通过" value="已通过"></el-option>
<el-option label="已驳回" value="已驳回"></el-option>
<el-option label="已超时" value="已超时"></el-option>
</el-select>
</el-form-item>
<el-form-item label="申请类型">
<el-select v-model="searchForm.applicationType" placeholder="请选择类型" clearable>
<el-option label="维修申领" value="维修申领"></el-option>
<el-option label="维修借用" value="维修借用"></el-option>
</el-select>
</el-form-item>
<el-form-item label="紧急程度">
<el-select v-model="searchForm.urgencyLevel" placeholder="请选择紧急程度" clearable>
<el-option label="紧急" value="紧急"></el-option>
<el-option label="一般" value="一般"></el-option>
<el-option label="不紧急" value="不紧急"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchRecords">搜索</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
</div>

<!-- 快捷筛选 -->
<div class="quick-filters">
<el-button-group>
<el-button @click="filterByStatus('待审核')" :type="currentFilter === '待审核' ? 'primary' : ''">
待审核 ({{ getStatusCount('待审核') }})
</el-button>
<el-button @click="filterByStatus('已通过')" :type="currentFilter === '已通过' ? 'success' : ''">
已通过 ({{ getStatusCount('已通过') }})
</el-button>
<el-button @click="filterByStatus('已驳回')" :type="currentFilter === '已驳回' ? 'danger' : ''">
已驳回 ({{ getStatusCount('已驳回') }})
</el-button>
<el-button @click="showOverdue" :type="currentFilter === 'overdue' ? 'warning' : ''">
超时申请 ({{ overdueCount }})
</el-button>
<el-button @click="showAll" :type="currentFilter === 'all' ? 'info' : ''">
全部
</el-button>
</el-button-group>
</div>

<!-- 数据表格 -->
<el-table
:data="approvalRecords"
style="width: 100%"
@selection-change="handleSelectionChange"
v-loading="loading">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="applicationId" label="申请单号" width="150"></el-table-column>
<el-table-column prop="applicant" label="申请人" width="100"></el-table-column>
<el-table-column prop="department" label="部门" width="120"></el-table-column>
<el-table-column prop="sparePartName" label="备件名称" width="120"></el-table-column>
<el-table-column prop="sparePartModel" label="备件型号" width="120"></el-table-column>
<el-table-column prop="quantity" label="数量" width="80"></el-table-column>
<el-table-column prop="applicationType" label="申请类型" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.applicationType === '维修借用' ? 'warning' : 'info'">
{{ scope.row.applicationType }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="urgencyLevel" label="紧急程度" width="100">
<template slot-scope="scope">
<el-tag :type="getUrgencyType(scope.row.urgencyLevel)">
{{ scope.row.urgencyLevel }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="applicationDate" label="申请时间" width="150">
<template slot-scope="scope">
{{ formatDate(scope.row.applicationDate) }}
</template>
</el-table-column>
<el-table-column prop="expectedReturnDate" label="预计归还" width="150" v-if="showReturnDate">
<template slot-scope="scope">
<span v-if="scope.row.applicationType === '维修借用'">
{{ formatDate(scope.row.expectedReturnDate) }}
<el-tag v-if="isOverdue(scope.row)" type="danger" size="mini">已超时</el-tag>
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" width="250" fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click="viewRecord(scope.row)">查看</el-button>
<el-button size="mini" type="primary" @click="editRecord(scope.row)"
v-if="scope.row.status === '待审核'">编辑</el-button>
<el-button size="mini" type="success" @click="approveRecord(scope.row)"
v-if="scope.row.status === '待审核'">通过</el-button>
<el-button size="mini" type="danger" @click="rejectRecord(scope.row)"
v-if="scope.row.status === '待审核'">驳回</el-button>
<el-button size="mini" @click="viewTimeline(scope.row)">时间线</el-button>
</template>
</el-table-column>
</el-table>

<!-- 分页 -->
<div class="pagination">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>

<!-- 新增/编辑对话框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px">
<el-form :model="currentRecord" :rules="rules" ref="recordForm" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="申请人" prop="applicant">
<el-select v-model="currentRecord.applicant" placeholder="请选择申请人" filterable allow-create>
<el-option v-for="applicant in applicantList" :key="applicant" :label="applicant" :value="applicant"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门" prop="department">
<el-select v-model="currentRecord.department" placeholder="请选择部门" filterable allow-create>
<el-option v-for="dept in departmentList" :key="dept" :label="dept" :value="dept"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="需求车站" prop="station">
<el-input v-model="currentRecord.station"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属工区" prop="workArea">
<el-input v-model="currentRecord.workArea"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="备件名称" prop="sparePartName">
<el-select v-model="currentRecord.sparePartName" placeholder="请选择备件名称" filterable @change="onSparePartNameChange">
<el-option v-for="name in sparePartNameList" :key="name" :label="name" :value="name"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备件型号" prop="sparePartModel">
<el-select v-model="currentRecord.sparePartModel" placeholder="请选择备件型号" filterable>
<el-option v-for="model in sparePartModelList" :key="model" :label="model" :value="model"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="申请数量" prop="quantity">
<el-input-number v-model="currentRecord.quantity" :min="1"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="申请类型" prop="applicationType">
<el-select v-model="currentRecord.applicationType" placeholder="请选择" @change="onTypeChange">
<el-option label="维修申领" value="维修申领"></el-option>
<el-option label="维修借用" value="维修借用"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="故障设备" prop="faultEquipment">
<el-input v-model="currentRecord.faultEquipment"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="紧急程度" prop="urgencyLevel">
<el-select v-model="currentRecord.urgencyLevel" placeholder="请选择">
<el-option label="紧急" value="紧急"></el-option>
<el-option label="一般" value="一般"></el-option>
<el-option label="不紧急" value="不紧急"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="故障描述" prop="faultDescription">
<el-input type="textarea" v-model="currentRecord.faultDescription" :rows="3"></el-input>
</el-form-item>
<el-form-item label="申请原因" prop="applicationReason">
<el-input type="textarea" v-model="currentRecord.applicationReason" :rows="3"></el-input>
</el-form-item>

<!-- 维修借用特有字段 -->
<el-form-item v-if="currentRecord.applicationType === '维修借用'" label="预计归还时间" prop="expectedReturnDate">
<el-date-picker
v-model="currentRecord.expectedReturnDate"
type="datetime"
placeholder="选择日期时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
<div class="hint">维修借用需在48小时内归还</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveRecord">确定</el-button>
</div>
</el-dialog>

<!-- 审核对话框 -->
<el-dialog title="审核申请" :visible.sync="approvalDialogVisible" width="500px">
<el-form :model="approvalForm" ref="approvalForm" label-width="100px">
<el-form-item label="审核人" prop="approver">
<el-select v-model="approvalForm.approver" placeholder="请选择审核人" filterable allow-create>
<el-option v-for="approver in approverList" :key="approver" :label="approver" :value="approver"></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="comments">
<el-input type="textarea" v-model="approvalForm.comments" :rows="4"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="approvalDialogVisible = false">取消</el-button>
<el-button type="danger" @click="confirmReject">驳回</el-button>
<el-button type="success" @click="confirmApprove">通过</el-button>
</div>
</el-dialog>

<!-- 统计信息对话框 -->
<el-dialog title="审核统计" :visible.sync="statisticsDialogVisible" width="600px">
<div class="statistics-content">
<el-row :gutter="20">
<el-col :span="6" v-for="stat in statistics" :key="stat.status">
<div class="stat-card">
<div class="stat-number">{{ stat.count }}</div>
<div class="stat-label">{{ stat.status }}</div>
</div>
</el-col>
</el-row>
</div>
</el-dialog>

<!-- 导入对话框 -->
<el-dialog title="模版导入" :visible.sync="importDialogVisible" width="500px">
<div class="import-content">
<el-upload
ref="upload"
:action="uploadUrl"
:on-success="handleImportSuccess"
:on-error="handleImportError"
:before-upload="beforeUpload"
:auto-upload="false"
accept=".json"
:limit="1">
<el-button slot="trigger" size="small" type="primary">选择文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传导入</el-button>
<div slot="tip" class="el-upload__tip">只能上传 JSON 文件,且不超过 10MB</div>
</el-upload>
<div class="import-tips">
<h4>导入说明:</h4>
<p>1. 请确保 JSON 文件格式正确</p>
<p>2. 导入的数据将生成新的申请记录</p>
<p>3. 系统会自动生成新的申请单号</p>
<p>4. 导入过程中如有错误,会显示详细信息</p>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="importDialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import axios from 'axios'

export default {
name: 'ApprovalManagement',
data() {
return {
approvalRecords: [],
selectedRecords: [],
loading: false,
dialogVisible: false,
approvalDialogVisible: false,
statisticsDialogVisible: false,
importDialogVisible: false,
dialogTitle: '新增申请',
currentRecord: {},
approvalForm: {
approver: '',
comments: ''
},
currentApprovalId: null,
currentApprovalAction: '',
searchForm: {
applicant: '',
sparePartName: '',
status: '',
applicationType: '',
urgencyLevel: ''
},
currentFilter: 'all',
showReturnDate: false,
overdueCount: 0,
statistics: [],
currentPage: 1,
pageSize: 10,
total: 0,
uploadUrl: '/approval/import',
// 下拉选择数据
sparePartNameList: [],
sparePartModelList: [],
applicantList: [],
approverList: [],
departmentList: [],
rules: {
applicant: [{ required: true, message: '请输入申请人', trigger: 'blur' }],
department: [{ required: true, message: '请输入部门', trigger: 'blur' }],
sparePartName: [{ required: true, message: '请输入备件名称', trigger: 'blur' }],
sparePartModel: [{ required: true, message: '请输入备件型号', trigger: 'blur' }],
quantity: [{ required: true, message: '请输入申请数量', trigger: 'blur' }],
applicationType: [{ required: true, message: '请选择申请类型', trigger: 'change' }],
faultEquipment: [{ required: true, message: '请输入故障设备', trigger: 'blur' }],
urgencyLevel: [{ required: true, message: '请选择紧急程度', trigger: 'change' }],
faultDescription: [{ required: true, message: '请输入故障描述', trigger: 'blur' }],
applicationReason: [{ required: true, message: '请输入申请原因', trigger: 'blur' }]
}
}
},
mounted() {
this.loadApprovalRecords()
this.loadStatistics()
this.loadOverdueCount()
this.loadSparePartNames()
this.loadOperatorData()
},
methods: {
// 批量导出数据
async exportData() {
try {
const params = {}
if (this.currentFilter && this.currentFilter !== 'all' && this.currentFilter !== 'search' && this.currentFilter !== 'overdue') {
params.status = this.currentFilter
}

const response = await axios.get('/approval/export', {
params,
responseType: 'blob'
})

// 创建下载链接
const blob = new Blob([response.data], { type: 'application/json' })
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url

// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition']
let filename = 'approval_records.json'
if (contentDisposition) {
const filenameMatch = contentDisposition.match(/filename="(.+)"/)
if (filenameMatch) {
filename = filenameMatch[1]
}
}

link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)

this.$message.success('导出成功')
} catch (error) {
this.$message.error('导出失败')
}
},

// 显示导入对话框
showImportDialog() {
this.importDialogVisible = true
},

// 提交上传
submitUpload() {
this.$refs.upload.submit()
},

// 上传前检查
beforeUpload(file) {
const isJSON = file.type === 'application/json' || file.name.endsWith('.json')
const isLt10M = file.size / 1024 / 1024 < 10

if (!isJSON) {
this.$message.error('只能上传 JSON 文件!')
return false
}
if (!isLt10M) {
this.$message.error('文件大小不能超过 10MB!')
return false
}
return true
},

// 导入成功回调
handleImportSuccess(response) {
if (response.success) {
this.$message.success(`导入完成!成功:${response.successCount} 条,失败:${response.errorCount} 条`)
if (response.errorCount > 0 && response.errorMessages) {
this.$message.warning(`错误信息:${response.errorMessages}`)
}
this.loadApprovalRecords()
this.loadOperatorData()
this.importDialogVisible = false
} else {
this.$message.error(`导入失败:${response.message}`)
}
},

// 导入失败回调
handleImportError(error) {
this.$message.error('导入失败,请检查文件格式')
},

// 加载备件名称列表
async loadSparePartNames() {
try {
const response = await axios.get('/spare-parts/names')
this.sparePartNameList = response.data
} catch (error) {
console.error('加载备件名称失败', error)
}
},

// 加载操作人相关数据
async loadOperatorData() {
try {
const [applicants, approvers, departments] = await Promise.all([
axios.get('/operators/applicants'),
axios.get('/operators/approvers'),
axios.get('/operators/departments')
])
this.applicantList = applicants.data
this.approverList = approvers.data
this.departmentList = departments.data
} catch (error) {
console.error('加载操作人数据失败', error)
}
},

// 备件名称变化时加载对应型号
async onSparePartNameChange(partName) {
if (partName) {
try {
const response = await axios.get('/spare-parts/models', { params: { partName } })
this.sparePartModelList = response.data
} catch (error) {
console.error('加载备件型号失败', error)
}
} else {
this.sparePartModelList = []
}
this.currentRecord.sparePartModel = ''
},

// 加载审核记录
async loadApprovalRecords() {
this.loading = true
try {
const response = await axios.get('/approval')
this.approvalRecords = response.data
this.total = response.data.length
} catch (error) {
this.$message.error('加载数据失败')
} finally {
this.loading = false
}
},

// 加载统计信息
async loadStatistics() {
try {
const response = await axios.get('/approval/statistics')
this.statistics = response.data.map(item => ({
status: item[0],
count: item[1]
}))
} catch (error) {
console.error('加载统计信息失败', error)
}
},

// 加载超时申请数量
async loadOverdueCount() {
try {
const response = await axios.get('/approval/overdue')
this.overdueCount = response.data.length
} catch (error) {
console.error('加载超时申请失败', error)
}
},

// 搜索记录
async searchRecords() {
this.loading = true
try {
const params = {}
if (this.searchForm.applicant) params.applicant = this.searchForm.applicant
if (this.searchForm.sparePartName) params.sparePartName = this.searchForm.sparePartName
if (this.searchForm.status) params.status = this.searchForm.status
if (this.searchForm.applicationType) params.applicationType = this.searchForm.applicationType
if (this.searchForm.urgencyLevel) params.urgencyLevel = this.searchForm.urgencyLevel

const response = await axios.get('/approval/search', { params })
this.approvalRecords = response.data
this.total = response.data.length
this.currentFilter = 'search'
} catch (error) {
this.$message.error('搜索失败')
} finally {
this.loading = false
}
},

// 重置搜索
resetSearch() {
this.searchForm = {
applicant: '',
sparePartName: '',
status: '',
applicationType: '',
urgencyLevel: ''
}
this.loadApprovalRecords()
this.currentFilter = 'all'
},

// 按状态筛选
async filterByStatus(status) {
this.loading = true
try {
const response = await axios.get(`/approval/status/${status}`)
this.approvalRecords = response.data
this.total = response.data.length
this.currentFilter = status
} catch (error) {
this.$message.error('筛选失败')
} finally {
this.loading = false
}
},

// 显示超时申请
async showOverdue() {
this.loading = true
try {
const response = await axios.get('/approval/overdue')
this.approvalRecords = response.data
this.total = response.data.length
this.currentFilter = 'overdue'
} catch (error) {
this.$message.error('加载超时申请失败')
} finally {
this.loading = false
}
},

// 显示全部
showAll() {
this.loadApprovalRecords()
this.currentFilter = 'all'
},

// 获取状态数量
getStatusCount(status) {
const stat = this.statistics.find(s => s.status === status)
return stat ? stat.count : 0
},

// 显示新增对话框
showAddDialog() {
this.dialogTitle = '新增申请'
this.currentRecord = {}
this.sparePartModelList = []
this.dialogVisible = true
},

// 编辑记录
editRecord(record) {
this.dialogTitle = '编辑申请'
this.currentRecord = { ...record }
if (record.sparePartName) {
this.onSparePartNameChange(record.sparePartName)
}
this.dialogVisible = true
},

// 查看记录
viewRecord(record) {
this.$alert(JSON.stringify(record, null, 2), '申请详情', {
confirmButtonText: '确定'
})
},

// 保存记录
async saveRecord() {
this.$refs.recordForm.validate(async (valid) => {
if (valid) {
try {
if (this.currentRecord.id) {
await axios.put(`/approval/${this.currentRecord.id}`, this.currentRecord)
this.$message.success('更新成功')
} else {
await axios.post('/approval', this.currentRecord)
this.$message.success('创建成功')
}
this.dialogVisible = false
this.loadApprovalRecords()
this.loadOperatorData() // 重新加载操作人数据
} catch (error) {
this.$message.error('保存失败')
}
}
})
},

// 审核记录
approveRecord(record) {
this.currentApprovalId = record.id
this.currentApprovalAction = 'approve'
this.approvalForm = { approver: '', comments: '' }
this.approvalDialogVisible = true
},

// 驳回记录
rejectRecord(record) {
this.currentApprovalId = record.id
this.currentApprovalAction = 'reject'
this.approvalForm = { approver: '', comments: '' }
this.approvalDialogVisible = true
},

// 确认审核通过
async confirmApprove() {
try {
await axios.put(`/approval/${this.currentApprovalId}/approve`, this.approvalForm)
this.$message.success('审核通过')
this.approvalDialogVisible = false
this.loadApprovalRecords()
this.loadOperatorData() // 重新加载操作人数据
} catch (error) {
this.$message.error('审核失败')
}
},

// 确认驳回
async confirmReject() {
try {
await axios.put(`/approval/${this.currentApprovalId}/reject`, this.approvalForm)
this.$message.success('已驳回')
this.approvalDialogVisible = false
this.loadApprovalRecords()
this.loadOperatorData() // 重新加载操作人数据
} catch (error) {
this.$message.error('驳回失败')
}
},

// 批量审核通过
async batchApprove() {
if (this.selectedRecords.length === 0) {
this.$message.warning('请选择要审核的记录')
return
}

this.$prompt('请输入审核人', '批量审核通过', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(async ({ value }) => {
try {
const ids = this.selectedRecords.map(r => r.id)
await axios.put('/approval/batch-approve', {
ids: ids,
approver: value,
comments: '批量审核通过'
})
this.$message.success('批量审核成功')
this.loadApprovalRecords()
} catch (error) {
this.$message.error('批量审核失败')
}
})
},

// 批量驳回
async batchReject() {
if (this.selectedRecords.length === 0) {
this.$message.warning('请选择要驳回的记录')
return
}

this.$prompt('请输入驳回原因', '批量驳回', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(async ({ value }) => {
try {
const ids = this.selectedRecords.map(r => r.id)
await axios.put('/approval/batch-reject', {
ids: ids,
approver: '系统管理员',
comments: value
})
this.$message.success('批量驳回成功')
this.loadApprovalRecords()
} catch (error) {
this.$message.error('批量驳回失败')
}
})
},

// 发送超时提醒
sendReminders() {
this.$message.info('超时提醒功能开发中...')
},

// 显示统计信息
showStatistics() {
this.statisticsDialogVisible = true
},

// 查看时间线
viewTimeline(record) {
this.$message.info('时间线功能开发中...')
},

// 处理选择变化
handleSelectionChange(selection) {
this.selectedRecords = selection
},

// 处理分页大小变化
handleSizeChange(val) {
this.pageSize = val
this.loadApprovalRecords()
},

// 处理当前页变化
handleCurrentChange(val) {
this.currentPage = val
this.loadApprovalRecords()
},

// 申请类型变化
onTypeChange(value) {
this.showReturnDate = value === '维修借用'
},

// 获取状态类型
getStatusType(status) {
const statusMap = {
'待审核': 'warning',
'已通过': 'success',
'已驳回': 'danger',
'已超时': 'danger'
}
return statusMap[status] || 'info'
},

// 获取紧急程度类型
getUrgencyType(urgency) {
const urgencyMap = {
'紧急': 'danger',
'一般': 'warning',
'不紧急': 'success'
}
return urgencyMap[urgency] || 'info'
},

// 检查是否超时
isOverdue(record) {
if (record.applicationType === '维修借用' && record.expectedReturnDate) {
return new Date(record.expectedReturnDate) < new Date()
}
return false
},

// 格式化日期
formatDate(date) {
if (!date) return ''
return new Date(date).toLocaleString()
}
}
}
</script>

<style scoped>
.approval-management {
padding: 20px;
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.search-area {
background: #f5f5f5;
padding: 20px;
border-radius: 4px;
margin-bottom: 20px;
}

.search-form {
margin: 0;
}

.quick-filters {
margin-bottom: 20px;
}

.pagination {
margin-top: 20px;
text-align: right;
}

.statistics-content {
padding: 20px;
}

.stat-card {
text-align: center;
padding: 20px;
border: 1px solid #e4e7ed;
border-radius: 4px;
}

.stat-number {
font-size: 24px;
font-weight: bold;
color: #409eff;
}

.stat-label {
margin-top: 8px;
color: #606266;
}

.hint {
font-size: 12px;
color: #909399;
margin-top: 5px;
}

.import-content {
padding: 20px;
}

.import-tips {
margin-top: 20px;
padding: 15px;
background: #f5f7fa;
border-radius: 4px;
}

.import-tips h4 {
margin: 0 0 10px 0;
color: #303133;
}

.import-tips p {
margin: 5px 0;
color: #606266;
font-size: 14px;
}
</style>

 

posted @ 2025-03-20 23:44  混沌武士丞  阅读(4)  评论(0)    收藏  举报