bonus-ui/src/views/EquipmentRetireApply/detail.vue

374 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-card style="margin-bottom: 20px">
<div slot="header" class="clearfix">
<span>{{ isNew ? '新增退役申请' : '退役申请明细' }}</span>
</div>
<!-- 基本信息 -->
<el-form ref="baseForm" :model="baseInfo" label-width="70px" inline style="height: 36px" >
<el-form-item label="申请单号" style="margin-bottom: 0; height: 36px">
<!-- 申请单号禁用的输入框 -->
<el-input
v-model="baseInfo.code"
placeholder="无"
disabled
:value="!isNew ? baseInfo.code : '新增'"
style="width: 240px;"
/>
</el-form-item>
<el-form-item label="任务状态">
<!-- 任务状态:禁用的输入框 + 标签样式 -->
<el-input
:value="getStatusLabel()"
disabled
style="background: transparent; border: none; padding-left: 0; width: 240px;"
>
</el-input>
</el-form-item>
<el-form-item label="申请人">
<!-- 申请人:禁用的输入框 -->
<el-input v-model="baseInfo.createUser" placeholder="无" disabled style="width: 240px;" />
</el-form-item>
<el-form-item label="申请时间">
<!-- 申请时间:禁用的输入框 -->
<el-input v-model="baseInfo.createTime" placeholder="无" disabled style="width: 240px;" />
</el-form-item>
</el-form>
</el-card>
<!-- 装备和工具列表 -->
<el-card>
<div class="detail-section">
<div class="section-header">
<el-col :span="4">
<span style="font-size: 20px; font-weight: 800">申请列表</span>
</el-col>
<el-col :span="20" style="display: flex; justify-content: flex-end">
<el-button type="primary" size="small" :disabled="!canEdit" @click="onHandleAddItem">
添加装备/工具
</el-button>
<!-- 操作按钮 -->
<el-button type="primary" size="small" :disabled="!canEdit" @click="onHandleSubmit">确认申请</el-button>
</el-col>
</div>
<el-table :data="detailList" style="width: 100%" border stripe size="small" fit>
<el-table-column align="center" type="index" label="序号" width="70" />
<el-table-column align="center" prop="type" label="分类" width="90" />
<el-table-column align="center" prop="typeName" label="类目" width="180" />
<el-table-column align="center" prop="typeModelName" label="规格型号" width="180" />
<el-table-column align="center" prop="manageMode" label="管理模式" width="120" />
<el-table-column align="center" prop="devCode" label="设备编码" min-width="120" />
<el-table-column v-if="isNew" align="center" prop="inStockNum" label="在库数量" width="80" />
<el-table-column align="center" prop="scrapQuantity" label="申请报废数量" width="120" />
<el-table-column align="center" prop="retireReason" label="退役原因" width="180">
<template slot-scope="scope">
<el-select
v-model="scope.row.retireReason"
placeholder="请选择退役原因"
size="small"
:disabled="!canEdit"
>
<el-option label="人为" value="人为"></el-option>
<el-option label="自然" value="自然"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="报废附件" width="140">
<template slot-scope="scope">
<div style="display: flex;align-items: center;justify-content: center;">
<el-upload
ref="upload"
:limit="1"
:headers="upload.headers"
:action="upload.url"
:show-file-list="false"
accept=".png, .jpg, .jpeg, .pdf, .doc, .docx"
:on-success="(res) => handleFileSuccess(res, scope.row)"
:auto-upload="true"
:disabled="!canEdit"
>
<el-button type="primary" size="mini" :disabled="!canEdit">上传附件</el-button>
</el-upload>
<el-button v-if="scope.row.bmFileInfos && scope.row.bmFileInfos.length > 0" type="text" size="mini" @click="picturePreview(scope.row)">
查看
</el-button>
</div>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="100">
<template slot-scope="scope">
<el-button type="danger" size="mini" :disabled="!canEdit" @click="onHandleDeleteItem(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 添加装备/工具弹窗 -->
<add-item-dialog
ref="addItemDialog"
:existing-items="detailList"
@confirm="onAddItemConfirm"
/>
</div>
</template>
<script>
import { getRetireApplyDetailAPI, submitRetireApplyTaskAPI } from '@/api/EquipmentRetireApply/index.js'
import AddItemDialog from './components/AddItemDialog'
import { getToken } from '@/utils/auth'
export default {
components: {
AddItemDialog
},
data() {
return {
isNew: false,
baseInfo: {
id: '',
code: '',
reviewStatus: '1',
createUser: '',
createTime: ''
},
detailList: [],
fileData: {},
upload: {
headers: { Authorization: 'Bearer ' + getToken() },
url: process.env.VUE_APP_BASE_API + '/file/upload'
}
}
},
computed: {
// 判断是否可以编辑(新增状态或待审批状态下可以编辑)
canEdit() {
// 如果是新增页面,允许编辑
if (this.isNew) return true;
// 从路由参数中获取 mode
const mode = this.$route.query.mode;
// 如果 mode 是 'edit',允许编辑;如果是 'view' 或其他值,不允许编辑
return mode === 'edit';
}
},
methods: {
async getDetail() {
const id = this.$route.params.id
if (id === 'new') {
this.isNew = true
this.baseInfo.createUser = this.$store.state.user?.nickName || '当前用户'
this.baseInfo.createTime = new Date().toLocaleString()
} else {
// 从query参数中获取任务基本信息
const taskInfoStr = this.$route.query.taskInfo
if (taskInfoStr) {
const taskInfo = JSON.parse(taskInfoStr)
this.baseInfo = {
id: taskInfo.id,
code: taskInfo.code,
reviewStatus: taskInfo.reviewStatus,
createUser: taskInfo.createUser,
createTime: taskInfo.createTime
}
}
// 调用API获取明细列表
const res = await getRetireApplyDetailAPI(id)
const data = res.data || []
// 所有数据都是明细项
this.detailList = data.map(item => ({
id: item.id,
keyId: item.keyId,
type: item.type,
typeId: item.typeId,
devType: item.devType,
groupName: item.groupName,
typeName: item.typeName,
typeModelName: item.typeModelName,
manageMode: item.manageMode,
devCode: item.devCode,
code: item.code,
inStockNum: item.inStockNum,
scrapQuantity: item.scrapNum,
retireReason: item.reasonVal,
bmFileInfos: item.bmFileInfos || [],
reviewStatus: item.reviewStatus // 审批状态
}))
}
},
onHandleAddItem() {
this.$refs.addItemDialog.open()
},
async onAddItemConfirm(items) {
// 确保新添加的项有bmFileInfos字段
const itemsWithFileInfo = items.map(item => ({
...item,
bmFileInfos: item.bmFileInfos || []
}))
this.detailList.push(...itemsWithFileInfo)
},
onHandleDeleteItem(row) {
this.$confirm('确定删除该项吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const index = this.detailList.indexOf(row)
if (index > -1) {
this.detailList.splice(index, 1)
}
this.$message.success('删除成功')
}).catch(() => {})
},
async onHandleSubmit() {
if (this.detailList.length === 0) {
this.$message.warning('请至少添加一项装备或工具')
return
}
try {
// 构建提交数据
const submitData = {
...this.baseInfo,
operationType: this.isNew ? 'add' : 'edit', // ✅ 区分新增或编辑
toBeScrapList: this.detailList.map(item => ({
keyId: item.keyId,
devCode: item.devCode,
type: item.type,
typeId: item.typeId,
devType: item.devType,
scrapNum: item.scrapQuantity,
reasonVal: item.retireReason,
bmFileInfos: item.bmFileInfos || []
}))
}
await submitRetireApplyTaskAPI(submitData)
this.$message.success('申请提交成功')
this.$router.push('/equipment/retire-apply/index')
} catch (error) {
this.$message.error('提交失败')
}
},
onHandleCancel() {
this.$router.back()
},
getStatusLabel() {
// 新增状态下显示待审批
if (this.isNew) {
return '待审批'
}
// 根据明细列表的审批状态计算任务状态
if (this.detailList.length === 0) {
return '待审批'
}
// 统计各状态的数量
const processedCount = this.detailList.filter(item => item.reviewStatus === '1' || item.reviewStatus === '2').length
const totalCount = this.detailList.length
if (processedCount === 0) {
// 一条都没处理
return '待审批'
} else if (processedCount === totalCount) {
// 全部处理完成
return '审批完成'
} else {
// 处理了部分
return '审批中'
}
},
getStatusType() {
// 根据任务状态返回标签类型
const label = this.getStatusLabel()
const typeMap = {
'待审批': 'warning',
'审批中': 'info',
'审批完成': 'success'
}
return typeMap[label] || 'info'
},
// 上传前保存行数据
beforeFileUpload(row) {
this.fileData = row
},
// 文件上传成功处理
handleFileSuccess(response, row) {
if (response.code === 200) {
// 初始化bmFileInfos数组
if (!row.bmFileInfos) {
row.bmFileInfos = []
}
// 添加上传的文件信息
const fileObj = {
name: response.data.name,
url: response.data.url
}
row.bmFileInfos = [fileObj]
this.$message.success('文件上传成功')
} else {
this.$message.error('文件上传失败')
}
},
// 图片查看
picturePreview(row) {
if (row.bmFileInfos && row.bmFileInfos.length > 0) {
const file = row.bmFileInfos[0]
const parts = file.name.split('.')
const extension = parts.pop()
if (extension === 'doc' || extension === 'docx' || extension === 'pdf') {
window.open(file.url, file.name)
} else {
this.$message.info('预览图片: ' + file.name)
}
}
}
},
created() {
this.getDetail()
}
}
</script>
<style lang="scss" scoped>
.box-card {
margin: 20px;
}
.detail-section {
margin: 30px 0;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
font-weight: 600;
font-size: 14px;
}
}
.action-buttons {
text-align: center;
margin-top: 30px;
}
</style>