bonus-ui/src/views/EquipmentLedger/components/equ-store.vue

700 lines
23 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">
<div class="card">
<div class="page-header">
<el-button type="text" icon="el-icon-arrow-left" @click="goBack">返回</el-button>
<span class="page-title">装备退库</span>
</div>
<el-form ref="outFormRef" :model="outForm" :rules="outFormRules" label-width="130px" inline size="small">
<el-form-item label="需求单位" prop="propertyUnitId">
<el-select
v-model="outForm.propertyUnitId"
placeholder="请选择需求单位"
clearable
filterable
style="width: 240px"
>
<el-option v-for="item in propertyUnitList" :key="item.id" :label="item.label" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item label="使用项目" prop="proCode">
<el-select
clearable
style="width: 240px"
placeholder="请选择使用项目"
v-model="outForm.proCode"
@change="onChangeProCode"
>
<el-option :key="item.proCode" :label="item.proName" :value="item.proCode" v-for="item in useProjectList"/>
</el-select>
</el-form-item>
<el-form-item label="项目类型" prop="proType">
<el-input style="width: 240px" disabled v-model="proTypeName"/>
</el-form-item>
<el-form-item label="电压等级" prop="voltageLevel">
<el-input style="width: 240px" disabled v-model="voltageLevel"/>
</el-form-item>
<el-form-item label="项目所在省" prop="proProvince">
<el-input style="width: 240px" disabled v-model="outForm.proProvince"/>
</el-form-item>
<el-form-item label="项目所在市" prop="proCity">
<el-input style="width: 240px" disabled v-model="outForm.proCity"/>
</el-form-item>
<el-form-item label="项目所在区/县" prop="proCounty">
<el-input style="width: 240px" disabled v-model="outForm.proCounty"/>
</el-form-item>
<el-form-item label="详细地址" prop="proLocation">
<el-input v-model="outForm.proLocation" placeholder="请输入详细地址" clearable style="width: 240px"/>
</el-form-item>
</el-form>
</div>
<div class="card" style="margin-top: 10px">
<el-row :gutter="0">
<el-col :span="12"><span style="font-weight: 800">装备退库列表</span></el-col>
<el-col :span="12" style="text-align: end">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="onHandleAddEquipment">新增装备退库</el-button>
<el-button size="mini" type="primary" @click="onHandleSubmit"> 确定退库</el-button>
</el-col>
</el-row>
<el-table :data="selectedEquipment" border stripe height="546">
<el-table-column label="序号" type="index" align="center" width="55"/>
<el-table-column prop="name" label="装备名称" align="center"/>
<el-table-column prop="devCategory" label="装备类目" align="center">
<template slot-scope="{ row }">
<span>
{{ row.mainCategory ? row.mainCategory + '>' : '' }}
{{ row.branch ? row.subCategory + '>' : row.subCategory }}{{ row.branch }}
</span>
</template>
</el-table-column>
<el-table-column prop="specificationModel" label="规格型号" align="center"/>
<el-table-column prop="code" label="装备编码" align="center"/>
<el-table-column label="入库数量" align="center">
<template slot-scope="{ row }">
<!-- <el-input-number
clearable
style="width: 240px"
placeholder="请输入入库数量"
v-model="row.inNum"
:controls="false"
/> -->
<span>1</span>
</template>
</el-table-column>
<el-table-column prop="status" label="装备状态" align="center">
<template slot-scope="{ row }">
<span v-if="row.status == 1" size="mini">在库</span>
<span v-if="row.status == 2" size="mini">自用</span>
<span v-if="row.status == 3" size="mini">共享</span>
<span v-if="row.status == 5" size="mini">维修</span>
</template>
</el-table-column>
<el-table-column label="使用到期日期" align="center" width="180">
<template slot-scope="scope">
<el-date-picker
type="date"
v-model="scope.row.useTime"
placeholder="选择使用日期"
value-format="yyyy-MM-dd"
:class="{ 'error-border': scope.row.validationError && scope.row.validationError.useTime }"
style="width: 150px"
/>
<span class="error-text" v-if="scope.row.validationError && scope.row.validationError.useTime">
使用到期日期不能为空
</span>
</template>
</el-table-column>
<!-- 是否维修 -->
<el-table-column label="是否维修" align="center">
<template slot-scope="{ row }">
<el-select v-model="row.changeStatus" placeholder="请选择是否维修">
<el-option label="否" value="1"/>
<el-option label="是" value="5"/>
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="danger" size="mini" @click="onHandleDelete(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog title="添加装备" :visible.sync="addEquipmentVisible" width="90%" @close="handleDialogClose">
<el-form :inline="true" label-width="auto">
<el-row>
<el-col :span="6">
<el-form-item label="装备名称" prop="devName">
<el-input
clearable
style="width: 100%"
placeholder="请输入装备名称"
v-model="addEquipmentQueryParams.devName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-button size="mini" type="primary" @click="onHandleAddEquipmentQuery">查询</el-button>
<el-button size="mini" plain @click="onHandleAddEquipmentReset">重置</el-button>
<el-button size="mini" type="primary" @click="onHandleAddEquipmentConfirm"> 确定添加</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-table
:data="addEquipmentList"
border
@selection-change="handleSelectionAddEquipment"
ref="equipmentTable"
:row-key="(row) => row.devId"
height="546"
>
<el-table-column label="序号" type="index" align="center" width="55"/>
<el-table-column width="55" align="center" type="selection"/>
<el-table-column width="160" show-overflow-tooltip prop="propertyUnit" label="公司名称" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="name" label="装备名称" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="specificationModel" label="装备型号" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="code" label="装备编号" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="unit" label="计数单位" align="center"/>
<el-table-column align="center" show-overflow-tooltip prop="status" label="状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.status == 2" size="mini">自用</el-tag>
<el-tag v-if="scope.row.status == 3" size="mini"> 共享</el-tag>
</template>
</el-table-column>
<el-table-column width="160" show-overflow-tooltip prop="propertyUnit" label="产权单位" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="originalValue" label="资产原值(万元)" align="center"/>
<el-table-column width="160" show-overflow-tooltip prop="productDate" label="出厂日期" align="center"/>
<el-table-column
width="160"
show-overflow-tooltip
prop="maxServiceLifeYears"
label="最大使用年限"
align="center"
/>
<el-table-column width="160" show-overflow-tooltip prop="usingProject" label="使用项目" align="center"/>
<el-table-column
width="160"
show-overflow-tooltip
prop="nextMaintenanceDate"
label="下次检验日期"
align="center"
/>
<el-table-column width="160" show-overflow-tooltip prop="manufacturer" label="生产厂商" align="center"/>
<template v-for="item in tableColumns">
<!-- 特征项列 -->
<el-table-column :key="`item-${item}`" align="center" show-overflow-tooltip :label="`特征项${item}`">
<template slot-scope="{ row }">
<span v-if="row.propertyVoList && row.propertyVoList.length > 0">
<span v-if="item - 1 < row.propertyVoList.length">
{{ row.propertyVoList[item - 1].propertyName || '-' }}
</span>
</span>
<span v-else> - </span>
</template>
</el-table-column>
<!-- 特征值列 -->
<el-table-column :key="`value-${item}`" align="center" show-overflow-tooltip :label="`特征值${item}`">
<template slot-scope="{ row }">
<span v-if="row.propertyVoList && row.propertyVoList.length > 0">
<span v-if="item - 1 < row.propertyVoList.length">
{{ row.propertyVoList[item - 1].propertyValue || '-' }}
</span>
</span>
<span v-else> - </span>
</template>
</el-table-column>
</template>
</el-table>
<pagination
:total="addEquipmentTotal"
@pagination="handlePaginationChange"
:page.sync="addEquipmentQueryParams.pageNum"
:limit.sync="addEquipmentQueryParams.pageSize"
/>
</el-dialog>
</div>
</template>
<script>
import { regionData } from 'element-china-area-data'
import {
getMaxFeatureAPI,
getUseProjectListAPI,
getVoltageListAPI,
addProjectOutAPI
} from '@/api/EquipmentLedger/equ-out'
import { getDeviceListAPI } from '@/api/EquipmentLedger/index.js'
import { deptTreeSelect } from '@/api/system/user'
import { addProjectStoreAPI } from '@/api/EquipmentLedger/equ-store.js'
import { getApprovalInstanceByBusiness } from '@/api/approval'
export default {
data() {
return {
addEquipmentVisible: false,
// 存储所有已选择的装备ID用于跨页回显
selectedIds: new Set(),
// 当前弹窗中选择的装备详情
currentDialogSelected: [],
// 入库表单
outForm: {
type: 1, // 入库
status: '', // 变更状态
proCode: '', // 使用项目id
proName: '', // 使用项目名称
proType: '', // 项目类型
voltageLevel: '', // 电压等级
proProvince: '', // 项目所在省
proCity: '', // 项目所在市
proCounty: '', // 项目所在区/县
proLocation: '', // 详细地址
propertyUnitId: '' // 属性单位ID
},
// 入库表单规则
outFormRules: {
propertyUnitId: [{ required: true, message: '请选择需求单位', trigger: 'change' }],
status: [{ required: true, message: '请选择变更状态', trigger: 'change' }],
proCode: [{ required: true, message: '请选择使用项目', trigger: 'change' }],
proType: [{ required: true, message: '请选择项目类型', trigger: 'change' }],
voltageLevel: [{ required: true, message: '请选择电压等级', trigger: 'change' }],
proProvince: [{ required: true, message: '请选择项目所在省', trigger: 'change' }],
proCity: [{ required: true, message: '请选择项目所在市', trigger: 'change' }],
proCounty: [{ required: true, message: '请选择项目所在区/县', trigger: 'change' }],
proLocation: [{ required: true, message: '请选择详细地址', trigger: 'change' }]
},
equipmentList: [],
propertyUnitList: [], // 产权单位
provinceList: [],
cityList: [],
countyList: [],
selectedEquipment: [],
// 可选择的变更设备查询条件
addEquipmentQueryParams: {
pageNum: 1,
pageSize: 10,
devName: '',
status: '2',
companyId: '',
proId: ''
},
// 可选择的变更设备列表
addEquipmentList: [],
tableColumns: 0,
addEquipmentTotal: 0,
useProjectList: [], // 使用项目下拉选
voltageList: [], // 电压等级下拉选
proTypeName: '', // 项目类型名称
voltageLevel: ''
}
},
created() {
this.getUseProjectList()
this.getDeptTreeSelect()
this.provinceList = regionData
},
methods: {
// 返回上一页
goBack() {
this.$router.go(-1)
},
// 获取产权单位
getDeptTreeSelect() {
deptTreeSelect().then((res) => {
this.propertyUnitList = this.filterTree(res.data)
console.log('🚀 ~ getDeptTreeSelect ~ this.propertyUnitList:', this.propertyUnitList)
})
},
filterTree(nodes) {
return nodes
.map((node) => {
if (node.children) {
node.children = this.filterTree(node.children)
}
return node
})
.filter((node) => node.status !== '1')
},
// 获取可选择的变更设备列表
getSelectEquipmentList() {
return new Promise((resolve) => {
getDeviceListAPI(this.addEquipmentQueryParams).then((res) => {
this.addEquipmentList = res.data.rows || []
this.addEquipmentTotal = res.data.total || 0
this.getMaxFeature()
// 数据加载完成后设置选中状态
this.$nextTick(() => {
setTimeout(() => {
this.setTableSelection()
resolve()
}, 0)
})
})
})
},
// 分页变化处理
handlePaginationChange() {
this.getSelectEquipmentList()
},
// 设置表格选中状态(回显已选择项)
setTableSelection() {
if (!this.$refs.equipmentTable || !this.addEquipmentList.length) return
// 先清除当前页选中状态
this.$refs.equipmentTable.clearSelection()
// 遍历当前页数据,对已选中的项进行勾选
this.addEquipmentList.forEach((item) => {
if (this.selectedIds.has(item.devId)) {
setTimeout(() => {
this.$refs.equipmentTable.toggleRowSelection(item, true)
}, 0)
}
})
},
// 获取列表表头特征值数量
async getMaxFeature() {
const res = await getMaxFeatureAPI()
this.tableColumns = res.data
},
// 获取使用项目的下拉选
async getUseProjectList() {
const res = await getUseProjectListAPI()
const result = await getVoltageListAPI()
this.useProjectList = res.data
this.voltageList = result.data
},
// 查询可选择的变更设备列表
onHandleAddEquipmentQuery() {
this.addEquipmentQueryParams.pageNum = 1
this.getSelectEquipmentList()
},
// 重置可选择的变更设备列表
onHandleAddEquipmentReset() {
this.addEquipmentQueryParams = {
pageNum: 1,
pageSize: 10,
devName: '',
status: '2',
companyId: '',
proId: this.addEquipmentQueryParams.proId || '' // 保留项目ID
}
this.getSelectEquipmentList()
},
// 表单重置
resetForm() {
this.$refs.outFormRef.resetFields()
this.equipmentList = []
this.selectedEquipment = []
this.selectedIds.clear()
},
// 验证表单数据
validateForm() {
let isValid = true
// 验证已选择的装备
this.selectedEquipment.forEach((row) => {
row.validationError = {}
// 验证使用到期日期
if (!row.useTime) {
row.validationError.useTime = true
isValid = false
}
})
return isValid
},
// 提交表单
submitForm() {
// 先验证表格数据
if (!this.validateForm()) {
return
}
this.$refs.outFormRef.validate(async(valid) => {
if (valid) {
if (this.selectedEquipment.length === 0) {
this.$modal.msgError('请至少添加一个装备')
return
}
// 组装参数
const params = { ...this.outForm, jsonData: '' }
const jsonData = this.selectedEquipment.map((item) => {
return {
devId: item.maId,
useTime: item.useTime,
changeStatus: item.changeStatus
}
})
params.jsonData = JSON.stringify(jsonData)
console.log('params', params)
try {
const res = await addProjectStoreAPI(params)
if (res.code === 200) {
// 提交成功后获取退库申请ID
let returnId = null
if (typeof res.data === 'number') {
returnId = res.data
} else if (res.data && typeof res.data === 'object' && res.data.id) {
returnId = res.data.id
}
console.log('退库申请ID:', returnId, '返回数据:', res.data)
// 查询审批实例,如果不存在则会自动创建
try {
const approvalRes = await getApprovalInstanceByBusiness('EQUIPMENT_RETURN', returnId)
console.log('审批实例查询结果:', approvalRes)
if (approvalRes && approvalRes.data) {
this.$modal.msgSuccess('申请已提交,请等待审批')
this.$router.push({
path: '/equipment/manage/equipment-ledger'
})
}
} catch (error) {
console.error('查询审批实例失败:', error)
this.$modal.msgSuccess('申请已提交,请等待审批')
this.$router.push({
path: '/equipment/manage/equipment-ledger'
})
}
} else {
this.$modal.msgError(res.msg)
}
} catch (error) {
console.error('提交失败:', error)
this.$modal.msgError('提交失败: ' + error.message)
}
}
})
},
// 添加装备
onHandleAddEquipment() {
if (!this.addEquipmentQueryParams.proId) {
this.$modal.msgError('请选择使用项目')
return
}
this.getSelectEquipmentList().then(() => {
this.addEquipmentVisible = true
})
},
// 删除单条装备
onHandleDelete(index) {
const removedItem = this.selectedEquipment.splice(index, 1)[0]
this.selectedIds.delete(removedItem.devId)
if (this.addEquipmentVisible) {
this.setTableSelection()
}
},
// 批量移除装备
removeSelectedEquipment() {
if (this.selectedEquipment.length === 0) {
this.$modal.msgWarning('请选择要移除的装备')
return
}
this.$modal.confirm('确认移除选中的装备吗?').then(() => {
// 清除所有选中ID
this.selectedEquipment.forEach((item) => {
this.selectedIds.delete(item.devId)
})
this.selectedEquipment = []
// 更新弹窗选择状态
if (this.addEquipmentVisible) {
this.setTableSelection()
}
})
},
// 选择变化处理
handleSelectionAddEquipment(selection) {
// 更新当前弹窗中的选择详情
this.currentDialogSelected = selection.map((item) => ({
...item,
useTime: '',
validationError: {}
}))
// 更新选中ID集合
this.selectedIds.clear()
selection.forEach((item) => {
this.selectedIds.add(item.devId)
})
},
// 确定添加
onHandleAddEquipmentConfirm() {
if (this.currentDialogSelected.length === 0) {
this.$modal.msgWarning('请选择要添加的装备')
return
}
// 过滤掉已添加的装备,避免重复
const newItems = this.currentDialogSelected.filter(
(newItem) => !this.selectedEquipment.some((existing) => existing.devId === newItem.devId)
)
if (newItems.length > 0) {
this.selectedEquipment = [...this.selectedEquipment, ...newItems]
this.$modal.msgSuccess('成功添加 ' + newItems.length + ' 个装备')
this.selectedEquipment.forEach((item) => {
this.$set(item, 'changeStatus', '1');
})
} else {
this.$modal.msgError('所选装备已添加')
}
this.addEquipmentVisible = false
},
// 处理弹窗关闭
handleDialogClose() {
// 保留选择状态,下次打开仍能看到之前的选择
},
// 选择使用项目
onChangeProCode(value) {
this.outForm.proCode = value
this.addEquipmentQueryParams.proId = value
const item = this.useProjectList.find((item) => item.proCode === value)
if (item) {
this.outForm.proName = item.proName
const { proTypeName, proType, voltage, city, county, province } = item
this.proTypeName = proTypeName
this.outForm.proType = proType
this.outForm.voltageLevel = voltage
this.voltageLevel = voltage + 'kV'
this.outForm.proProvince = province
this.outForm.proCity = city
this.outForm.proCounty = county
}
},
// 选择省份
onChangeProvince(value) {
if (!value) {
this.cityList = []
return
}
this.cityList = this.provinceList.find((item) => item.label === value)?.children || []
},
// 选择城市
onChangeCity(value) {
if (!value) {
this.countyList = []
return
}
this.countyList = this.cityList.find((item) => item.label === value)?.children || []
},
// 确定变更
onHandleSubmit() {
this.submitForm()
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
background-color: #f2f2f2;
}
.card {
padding: 15px;
background-color: #fff;
border-radius: 8px;
}
.page-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e6e6e6;
.page-title {
font-size: 18px;
font-weight: 600;
margin-left: 10px;
color: #303133;
}
}
::v-deep .el-table {
margin-top: 15px;
}
::v-deep .el-form-item {
margin-bottom: 18px;
}
.error-border {
border-color: #f56c6c !important;
}
.error-text {
color: #f56c6c;
font-size: 12px;
margin-top: 4px;
display: inline-block;
}
::v-deep .el-table {
// 启用斑马纹
&.el-table--striped .el-table__body {
tr.el-table__row--striped td {
background-color: #f6fbfa !important; // 浅紫色
}
}
.el-table__header {
background: #e9f0ee;
th {
background: #e9f0ee !important;
color: #606266;
font-weight: 600;
height: 50px;
}
}
&.el-table--striped .el-table__body tr.el-table__row:hover > td.el-table__cell {
background-color: #ccf1e9 !important;
}
}
</style>