bonus-ui/src/views/EquipmentLedger/components/euq-out.vue

714 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="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="auto" size="small">
<el-row :gutter="20" type="flex">
<el-col>
<!-- <el-form-item label="变更状态为" prop="status">
<el-radio-group v-model="outForm.status">
<el-radio label="0">自用</el-radio>
<el-radio label="1">共享</el-radio>
</el-radio-group>
</el-form-item> -->
<el-button size="mini" style="margin-bottom: 20px" type="primary" :disabled="!selectedEquipment.length" @click="onHandleSubmit"
>确定提交
</el-button
>
<el-button size="mini" plain>取消</el-button>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col>
<el-form-item label="需求单位:" prop="useUint">
<el-input v-model="outForm.useUint" placeholder="请输入需求单位" :disabled="outForm.status=='0'" clearable/>
</el-form-item>
</el-col>
<el-col>
<el-form-item label="使用项目:" prop="proCode">
<el-select
clearable
style="width: 100%"
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-col>
<el-col>
<el-form-item label="项目类型:" prop="proType">
<el-select clearable style="width: 100%" placeholder="请选择项目类型" v-model="outForm.proType">
<el-option value="0" label="线路"/>
<el-option value="1" label="电缆"/>
<el-option value="2" label="变电"/>
</el-select>
</el-form-item>
</el-col>
<el-col>
<el-form-item label="电压等级:" prop="voltageLevel">
<el-select
clearable
style="width: 100%"
placeholder="请选择电压等级:"
v-model="outForm.voltageLevel"
>
<el-option
:key="item.voltage"
:value="item.voltage"
:label="`${item.voltage}kV`"
v-for="item in voltageList"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col>
<el-form-item label="项目所在省:" prop="proProvince">
<el-select
clearable
style="width: 100%"
placeholder="请选择项目所在省"
v-model="outForm.proProvince"
@change="onChangeProvince"
>
<el-option
:key="item.value"
:label="item.label"
:value="item.label"
v-for="item in provinceList"
/>
</el-select>
</el-form-item>
</el-col>
<el-col>
<el-form-item label="项目所在市:" prop="proCity">
<el-select
clearable
style="width: 100%"
placeholder="请选择项目所在市"
v-model="outForm.proCity"
@change="onChangeCity"
>
<el-option
:key="item.value"
:label="item.label"
:value="item.label"
v-for="item in cityList"
/>
</el-select>
</el-form-item>
</el-col>
<el-col>
<el-form-item label="项目所在区/县:" prop="proCounty">
<el-select
clearable
style="width: 100%"
placeholder="请选择项目所在区/县"
v-model="outForm.proCounty"
>
<el-option
:key="item.value"
:label="item.label"
:value="item.label"
v-for="item in countyList"
/>
</el-select>
</el-form-item>
</el-col>
<el-col>
<el-form-item label="详细地址:" prop="proLocation">
<el-input v-model="outForm.proLocation" placeholder="请输入详细地址" clearable/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="6">
<el-form-item label="联系人:" prop="userName">
<el-input v-model="outForm.userName" placeholder="请输入联系人" clearable/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="联系方式:" prop="userPhone">
<el-input v-model="outForm.userPhone" placeholder="请输入联系方式" clearable maxlength="11"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 10px">
<el-button v-if="!maIds" size="mini" type="primary" @click="onHandleAddEquipment">新增装备出库</el-button>
<el-button size="mini" plain @click="clearSelectedEquipment" style="margin-left: 10px">清空已选</el-button>
</el-row>
</el-form>
<el-table :data="selectedEquipment" border stripe :max-height="500">
<el-table-column label="序号" type="index" align="center" width="55"/>
<el-table-column prop="name" label="装备名称" align="center"/>
<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-date-picker
type="date"
v-model="row.useTime"
placeholder="选择使用日期"
value-format="yyyy-MM-dd"
/>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="{ row, $index }">
<el-button
type="text"
size="mini"
@click="removeSelectedItem($index)"
style="color: #f56c6c;"
>
移除
</el-button>
</template>
</el-table-column>
</el-table>
<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="name">
<el-input
clearable
style="width: 100%"
placeholder="请输入装备名称"
v-model="addEquipmentQueryParams.name"
/>
</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
stripe
@selection-change="handleSelectionAddEquipment"
ref="equipmentTable"
:row-key="row => row.devId"
> <!-- 关键修复添加row-key属性 -->
<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="changeStatus" label="状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.status == 1" size="mini">在库</el-tag>
<el-tag v-if="scope.row.status == 2 || scope.row.status == 3" size="mini">
在用
</el-tag>
<el-tag v-if="scope.row.status == 5" 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 store from '@/store'
import { regionData } from 'element-china-area-data'
import {
getSelectEquipmentListAPI,
getMaxFeatureAPI,
getUseProjectListAPI,
getVoltageListAPI,
addProjectOutAPI
} from '@/api/EquipmentLedger/equ-out'
import { getDeviceListAPI, getDeviceByMaIdsApi } from '@/api/EquipmentLedger/index.js'
export default {
data() {
return {
addEquipmentVisible: false,
// 存储所有已选择的装备ID用于跨页回显
selectedIds: new Set(),
// 当前弹窗中选择的装备详情
currentDialogSelected: [],
// 已选择的装备列表
selectedEquipment: [],
// 出库表单
outForm: {
type: 2, // 出库
status: '0', // 变更状态
proCode: '', // 使用项目id
proName: '', // 使用项目名称
proType: '', // 项目类型
voltageLevel: '', // 电压等级
proProvince: '', // 项目所在省
proCity: '', // 项目所在市
proCounty: '', // 项目所在区/县
proLocation: '', // 详细地址
useUint: '', // 需求单位
userName: '', // 联系人
userPhone: '' // 联系方式
},
// 出库表单规则
outFormRules: {
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: 'blur' }],
useUint: [{ required: true, message: '请输入需求单位', trigger: 'blur' }],
userName: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
userPhone: [
{ required: true, message: '请输入联系方式', trigger: 'blur' },
{
pattern: /^1[3456789]\d{9}$/,
message: '请输入正确的手机号码',
trigger: 'blur',
},
]
},
provinceList: [],
cityList: [],
countyList: [],
// 可选择的变更设备查询条件
addEquipmentQueryParams: {
pageNum: 1,
pageSize: 10,
name: '',
status: '1',
companyId: ''
},
// 可选择的变更设备列表
addEquipmentList: [],
tableColumns: 0,
addEquipmentTotal: 0,
useProjectList: [], // 使用项目下拉选
voltageList: [], // 电压等级下拉选
maIds: '' // 共享出库传过来的maIds
}
},
created() {
this.maIds = this.$route.query ? this.$route.query.maIds : ''
if (this.maIds) {
this.getList()
}
console.log(store.getters.roles)
this.getUseProjectList()
this.outForm.status == '0' ? this.outForm.useUint = sessionStorage.getItem('deptName') : ''
this.provinceList = regionData
},
methods: {
// 返回上一页
goBack() {
this.$router.go(-1)
},
async getList() {
try {
const res = await getDeviceByMaIdsApi(this.maIds)
this.selectedEquipment = res.data
} catch (error) {
console.log('🚀 ~ getList ~ error:', error)
}
},
// 获取可选择的变更设备列表
getSelectEquipmentList() {
return new Promise((resolve) => {
getDeviceListAPI(this.addEquipmentQueryParams).then((res) => {
this.addEquipmentList = res.data.rows
this.addEquipmentTotal = res.data.total
this.getMaxFeature()
// 延迟执行确保DOM完全渲染
this.$nextTick(() => {
setTimeout(() => {
this.setTableSelection()
resolve()
}, 0)
})
})
})
},
// 分页变化处理
handlePaginationChange() {
this.getSelectEquipmentList()
},
// 设置表格选中状态(核心回显逻辑)
setTableSelection() {
if (!this.$refs.equipmentTable || !this.addEquipmentList || this.addEquipmentList.length === 0) {
return
}
// 先清除所有选择再重新设置
this.$refs.equipmentTable.clearSelection()
// 遍历当前页数据,对已选中的项进行勾选
this.selectedEquipment.forEach(item => {
if (this.selectedIds.has(item.devId)) {
// 使用setTimeout确保每次勾选都被正确处理
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,
name: '',
status: '1',
companyId: ''
}
this.getSelectEquipmentList()
},
// 清空已选装备
clearSelectedEquipment() {
this.selectedEquipment = []
this.currentDialogSelected = []
this.selectedIds.clear()
// 清空后同步更新弹窗中的选择状态
if (this.addEquipmentVisible) {
this.$nextTick(() => {
this.$refs.equipmentTable.clearSelection()
})
}
this.$message.success('已清空所有选择的装备')
},
// 提交表单
submitForm() {
this.$refs.outFormRef.validate(async(valid) => {
if (valid) {
if (this.selectedEquipment.length === 0) {
this.$message.error('请至少添加一个装备')
return
}
// 组装参数
const params = { ...this.outForm, jsonData: '' }
const jsonData = this.selectedEquipment.map((item) => {
return {
devId: item.devId,
useTime: item.useTime
}
})
if (this.maIds) {
params.status = '3'
} else {
params.status = '2'
}
params.jsonData = JSON.stringify(jsonData)
console.log('params', params)
const res = await addProjectOutAPI(params)
if (res.code === 200) {
this.$message.success('状态变更成功')
this.$router.go(-1)
} else {
this.$message.error(res.msg)
}
}
})
},
// 添加装备
onHandleAddEquipment() {
// 打开弹窗时重新设置选中状态
this.getSelectEquipmentList().then(() => {
this.addEquipmentVisible = true
this.$nextTick(() => {
this.setTableSelection()
})
})
},
// 选择变化处理(核心选中逻辑)
handleSelectionAddEquipment(selection) {
// 更新当前弹窗中的选择详情
this.currentDialogSelected = selection.map(item => ({ ...item, useTime: '' }))
/* // 更新选中ID集合
this.selectedIds.clear()
selection.forEach(item => {
this.selectedIds.add(item.devId)
}) */
},
// 确定添加 - 实现追加功能
onHandleAddEquipmentConfirm() {
if (this.currentDialogSelected.length === 0) {
this.$message.warning('请选择要添加的装备')
return
}
// 找出之前未选择过的装备(避免重复添加)
const newItems = this.currentDialogSelected.filter(newItem =>
!this.selectedEquipment.some(existing => existing.devId === newItem.devId)
)
if (newItems.length > 0) {
newItems.forEach(item => {
item.devId = item.maId
})
console.log('🚀 ~ onHandleAddEquipmentConfirm ~ newItems:', newItems)
// 追加新选择的装备
this.selectedEquipment = [...this.selectedEquipment, ...newItems]
this.$message.success(`成功添加 ${newItems.length} 个装备`)
} else {
this.$message.info('所选装备已全部添加,没有新装备可添加')
}
this.addEquipmentVisible = false
},
// 处理弹窗关闭
handleDialogClose() {
// 弹窗关闭时不清空选择状态,下次打开仍保留
},
// 移除已选择的项
removeSelectedItem(index) {
// 从已选择列表中移除
const removedItem = this.selectedEquipment.splice(index, 1)[0]
// 同时从ID集合和弹窗选择列表中移除
this.selectedIds.delete(removedItem.devId)
this.currentDialogSelected = this.currentDialogSelected.filter(
item => item.devId !== removedItem.devId
)
// 移除后同步更新弹窗中的选择状态
if (this.addEquipmentVisible) {
this.setTableSelection()
}
},
// 选择使用项目
onChangeProCode(value) {
this.outForm.proCode = value
this.outForm.proName = this.useProjectList.find((item) => item.proCode === value)?.proName || ''
},
// 选择省份
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;
}
.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;
}
}
.equipment-actions {
margin: 15px 0;
text-align: left;
}
.form-actions {
margin-top: 30px;
text-align: right;
::v-deep .el-form-item__content {
text-align: right;
}
}
::v-deep .el-table {
margin-top: 15px;
}
::v-deep .el-form-item {
margin-bottom: 18px;
}
::v-deep .el-input-number {
width: 100%;
}
::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>