526 lines
18 KiB
Vue
526 lines
18 KiB
Vue
<template>
|
||
<div>
|
||
<el-dialog
|
||
v-if="visible"
|
||
title="添加装备/工具"
|
||
:visible.sync="visible"
|
||
width="1400px"
|
||
@close="onClose"
|
||
>
|
||
<!-- 搜索条件 -->
|
||
<el-form ref="queryForm" label-width="40px" inline :model="queryParams">
|
||
|
||
<el-form-item label="名称" prop="typeName">
|
||
<el-input v-model="queryParams.typeName" placeholder="请输入名称" clearable style="width: 202px"/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="规格型号" prop="typeModelName" label-width="70px">
|
||
<el-input v-model="queryParams.typeModelName" maxlength="20" placeholder="请输入规格型号" clearable style="width: 202px"/>
|
||
</el-form-item>
|
||
<el-form-item label="设备编码" prop="devCode" label-width="70px">
|
||
<el-input v-model="queryParams.devCode" maxlength="20" placeholder="请输入编码" clearable style="width: 202px"/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="分类" prop="devType" label-width="40px">
|
||
<el-select v-model="queryParams.devType" placeholder="请选择分类" clearable style="width: 202px">
|
||
<el-option label="装备" value="1" />
|
||
<el-option label="工具" value="2" />
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 新增:动态显示的管理模式下拉框 -->
|
||
<el-form-item
|
||
v-if="queryParams.devType === '2'"
|
||
label="管理模式"
|
||
label-width="70px"
|
||
prop="manageType"
|
||
>
|
||
<el-select
|
||
v-model="queryParams.manageType"
|
||
placeholder="请选择管理模式"
|
||
clearable
|
||
style="width: 202px"
|
||
>
|
||
<el-option label="编码设备" value="0"/>
|
||
<el-option label="数量设备" value="1"/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<!-- <!– 新增:装备分类下拉框 –>-->
|
||
<!-- <el-col :span="5">-->
|
||
<!-- <el-form-item label="装备类目" prop="equipmentCategory">-->
|
||
<!-- <el-cascader-->
|
||
<!-- v-model="queryParams.equipmentCategory"-->
|
||
<!-- :options="equipmentTreeData"-->
|
||
<!-- :props="equipmentCascaderProps"-->
|
||
<!-- placeholder="请选择装备类目"-->
|
||
<!-- clearable-->
|
||
<!-- filterable-->
|
||
<!-- popper-class="six-level-cascader"-->
|
||
<!-- @change="handleEquipmentCategoryChange"-->
|
||
<!-- />-->
|
||
<!-- </el-form-item>-->
|
||
<!-- </el-col>-->
|
||
<!-- <!– 新增:工具分类下拉框 –>-->
|
||
<!-- <el-col :span="5">-->
|
||
<!-- <el-form-item label="工具类目" prop="toolCategory">-->
|
||
<!-- <el-cascader-->
|
||
<!-- v-model="queryParams.toolCategory"-->
|
||
<!-- :options="toolTreeData"-->
|
||
<!-- :props="toolCascaderProps"-->
|
||
<!-- placeholder="请选择工具类目"-->
|
||
<!-- clearable-->
|
||
<!-- filterable-->
|
||
<!-- popper-class="six-level-cascader"-->
|
||
<!-- @change="handleToolCategoryChange"-->
|
||
<!-- />-->
|
||
<!-- </el-form-item>-->
|
||
<!-- </el-col>-->
|
||
<el-form-item style="float: right">
|
||
<el-button type="primary" size="small" @click="onHandleQuery">查询</el-button>
|
||
<el-button size="small" @click="onHandleReset">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 在修装备/工具列表 -->
|
||
<el-table
|
||
ref="itemTable"
|
||
:data="itemList"
|
||
row-key="id"
|
||
style="width: 100%"
|
||
border
|
||
stripe
|
||
size="small"
|
||
fit
|
||
height="546"
|
||
@selection-change="onSelectionChange"
|
||
>
|
||
<el-table-column type="selection" width="50" :selectable="selectable" :reserve-selection="true"/>
|
||
<el-table-column align="center" type="index" label="序号" width="100" />
|
||
<el-table-column align="center" prop="devType" label="分类" min-width="70" >
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.devType==1">{{ '装备' }}</span>
|
||
<span v-if="scope.row.devType==2">{{ '工具' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" prop="groupName" label="类目" min-width="80" />
|
||
<el-table-column align="center" prop="typeName" label="名称" min-width="80" />
|
||
<el-table-column align="center" prop="typeModelName" label="规格型号" min-width="100" />
|
||
<el-table-column align="center" prop="manageMode" label="管理模式" min-width="80" />
|
||
<el-table-column align="center" prop="devCode" label="设备编码" min-width="100" />
|
||
<el-table-column align="center" prop="inStockNum" label="在库数量" width="100" />
|
||
<el-table-column align="center" prop="status" label="预警情况" width="120" >
|
||
<template slot-scope="scope">
|
||
<span :class="scope.row.status.includes('告警')?'red':''">{{ scope.row.status }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" prop="scrapQuantity" label="申请退役数量" width="150">
|
||
<template slot-scope="scope">
|
||
<el-input-number
|
||
v-model="scope.row.scrapQuantity"
|
||
:min="1"
|
||
:max="scope.row.inStockNum"
|
||
size="small"
|
||
style="width: 100%"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 分页 -->
|
||
<div style="text-align: right; margin-top: 15px;">
|
||
<el-pagination
|
||
:current-page.sync="queryParams.pageNum"
|
||
:page-size.sync="queryParams.pageSize"
|
||
:page-sizes="[10, 20, 50]"
|
||
:total="total"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 操作按钮 -->
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="visible = false">取消</el-button>
|
||
<el-button type="primary" @click="openConfirm">确定</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<ConfirmationDialog ref="confirmationDlg" @confirm="onHandleConfirm" />
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getScrapItemListAPI } from '@/api/EquipmentRetireApply/index.js'
|
||
// 导入分类树接口(与之前项目保持一致)
|
||
import { getEquipmentTreeAPI } from '@/api/EquipmentConfig/index.js'
|
||
import { getTreeSelectApi } from '@/api/toolsManage/index.js'
|
||
import ConfirmationDialog from '@/views/business/components/ConfirmationDialog'
|
||
|
||
export default {
|
||
props: {
|
||
existingItems: {
|
||
type: Array,
|
||
default: () => []
|
||
}
|
||
},
|
||
components: { ConfirmationDialog },
|
||
data() {
|
||
return {
|
||
visible: false,
|
||
queryParams: {
|
||
name: '',
|
||
typeName:'',
|
||
devType: '',
|
||
manageType: '',
|
||
typeModelName: '',
|
||
devCode: '',
|
||
equipmentCategory: [], // 新增:装备分类路径(数组)
|
||
toolCategory: [], // 新增:工具分类路径(数组)
|
||
equipmentCategoryId: '', // 新增:装备分类ID(用于接口查询)
|
||
toolCategoryId: '', // 新增:工具分类ID(用于接口查询)
|
||
pageNum: 1,
|
||
pageSize: 10
|
||
},
|
||
itemList: [],
|
||
total: 0,
|
||
selectedItems: [],
|
||
allSelectedItems: [], // 保存所有页面的选中项
|
||
|
||
// // 新增:分类树相关数据
|
||
// equipmentTreeData: [], // 装备分类树
|
||
// toolTreeData: [], // 工具分类树
|
||
//
|
||
// // 装备分类级联配置
|
||
// equipmentCascaderProps: {
|
||
// value: 'id',
|
||
// label: 'name',
|
||
// children: 'children',
|
||
// checkStrictly: true,
|
||
// expandTrigger: 'click'
|
||
// },
|
||
//
|
||
// // 工具分类级联配置(匹配返回字段:typeId/typeName)
|
||
// toolCascaderProps: {
|
||
// value: 'typeId',
|
||
// label: 'typeName',
|
||
// children: 'children',
|
||
// checkStrictly: true,
|
||
// expandTrigger: 'click'
|
||
// }
|
||
}
|
||
},
|
||
watch: {
|
||
'queryParams.pageNum'() {
|
||
this.getItemList()
|
||
},
|
||
'queryParams.pageSize'() {
|
||
this.queryParams.pageNum = 1
|
||
this.getItemList()
|
||
},
|
||
// 分类切换时清空对应类目选择
|
||
'queryParams.devType'(val) {
|
||
if (val === '装备') {
|
||
this.queryParams.toolCategory = []
|
||
this.queryParams.toolCategoryId = ''
|
||
} else if (val === '工具') {
|
||
this.queryParams.equipmentCategory = []
|
||
this.queryParams.equipmentCategoryId = ''
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
// 初始化加载分类树数据
|
||
this.getEquipmentTree()
|
||
this.getToolTree()
|
||
},
|
||
methods: {
|
||
open() {
|
||
this.visible = true;
|
||
// 1. 清空选中项数组(关键)
|
||
this.selectedItems = [];
|
||
this.allSelectedItems = [];
|
||
// 2. 强制清空表格DOM层面的选中状态(解决reserve-selection残留)
|
||
if (this.$refs.itemTable) {
|
||
this.$refs.itemTable.clearSelection();
|
||
}
|
||
// 3. 重置页码并重新获取列表(确保每次打开都是第一页)
|
||
this.queryParams.pageNum = 1;
|
||
this.getItemList();
|
||
// 4. 强制更新表格,重新计算selectable状态
|
||
this.$nextTick(() => {
|
||
if (this.$refs.itemTable) this.$refs.itemTable.$forceUpdate();
|
||
});
|
||
},
|
||
|
||
async getItemList() {
|
||
try {
|
||
// 构造查询参数(传递分类ID)
|
||
const query = {
|
||
...this.queryParams,
|
||
// 只传递最终的分类ID,简化接口参数
|
||
equipmentCategory: this.queryParams.equipmentCategoryId,
|
||
toolCategory: this.queryParams.toolCategoryId,
|
||
manageType: this.queryParams.manageType,
|
||
// 新增:将规格型号和设备编码加入查询参数
|
||
typeModelName: this.queryParams.typeModelName,
|
||
devCode: this.queryParams.devCode,
|
||
typeName: this.queryParams.typeName,
|
||
}
|
||
const res = await getScrapItemListAPI(query)
|
||
this.itemList = (res.rows || []).map(item => ({
|
||
...item,
|
||
scrapQuantity: item.scrapQuantity || 1
|
||
}))
|
||
this.total = res.total || 0
|
||
} catch (error) {
|
||
this.$message.error('获取列表失败')
|
||
}
|
||
},
|
||
|
||
onHandleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getItemList()
|
||
},
|
||
|
||
onHandleReset() {
|
||
this.queryParams = {
|
||
name: '',
|
||
typeName: '',
|
||
devType: '',
|
||
manageType: '',
|
||
equipmentCategory: [],
|
||
toolCategory: [],
|
||
equipmentCategoryId: '',
|
||
toolCategoryId: '',
|
||
pageNum: 1,
|
||
pageSize: 10
|
||
}
|
||
this.selectedItems=[]
|
||
this.getItemList()
|
||
},
|
||
selectable(row) {
|
||
return !this.existingItems.some(item => item.id === row.id)
|
||
},
|
||
onSelectionChange(selection) {
|
||
this.selectedItems = selection
|
||
// 更新所有选中项:移除当前页未选中的,添加当前页新选中的
|
||
const currentPageKeyIds = this.itemList.map(item => item.keyId)
|
||
// 保留其他页面的选中项
|
||
this.allSelectedItems = this.allSelectedItems.filter(item => !currentPageKeyIds.includes(item.keyId))
|
||
// 添加当前页的选中项
|
||
this.allSelectedItems.push(...selection)
|
||
},
|
||
openConfirm() {
|
||
if (this.selectedItems.length === 0) {
|
||
this.$message.warning('请选择至少一项')
|
||
return
|
||
}
|
||
const invalidItems = this.selectedItems.filter(item => !item.scrapQuantity || item.scrapQuantity < 1)
|
||
if (invalidItems.length > 0) {
|
||
const invalidNames = invalidItems.map(item => item.typeModelName).join('、')
|
||
this.$message.warning(`以下项目的申请报废数量必须大于0:${invalidNames}`)
|
||
return
|
||
}
|
||
this.$refs.confirmationDlg.openDialog(this.selectedItems)
|
||
},
|
||
onHandleConfirm() {
|
||
|
||
// 检查申请报废数量是否有效
|
||
// const invalidItems = this.allSelectedItems.filter(item => !item.scrapQuantity || item.scrapQuantity < 1)
|
||
|
||
// 检查是否有重复的keyId
|
||
// const existingKeyIds = this.existingItems.map(item => item.keyId)
|
||
// const duplicates = this.allSelectedItems.filter(item => existingKeyIds.includes(item.keyId))
|
||
|
||
// if (duplicates.length > 0) {
|
||
// const duplicateNames = duplicates.map(item => item.typeModelName).join('、')
|
||
// this.$message.warning(`以下项目已存在,不能重复添加:${duplicateNames}`)
|
||
// return
|
||
// }
|
||
|
||
|
||
this.$emit('confirm', this.selectedItems)
|
||
this.visible = false
|
||
this.selectedItems = []
|
||
this.allSelectedItems = []
|
||
},
|
||
|
||
onClose() {
|
||
this.selectedItems = []
|
||
this.allSelectedItems = []
|
||
// 1. 重置查询参数(复用重置方法)
|
||
this.onHandleReset()
|
||
// 2. 清空弹窗显示状态
|
||
this.visible = false
|
||
|
||
},
|
||
|
||
// 新增:装备分类选择变化
|
||
handleEquipmentCategoryChange(value) {
|
||
if (value && value.length > 0) {
|
||
// 取最后一级分类ID
|
||
this.queryParams.equipmentCategoryId = String(value[value.length - 1])
|
||
} else {
|
||
this.queryParams.equipmentCategoryId = ''
|
||
}
|
||
},
|
||
|
||
// 新增:工具分类选择变化
|
||
handleToolCategoryChange(value) {
|
||
if (value && value.length > 0) {
|
||
// 取最后一级分类ID
|
||
this.queryParams.toolCategoryId = String(value[value.length - 1])
|
||
} else {
|
||
this.queryParams.toolCategoryId = ''
|
||
}
|
||
},
|
||
|
||
// 新增:处理分类树数据(适配六级分类)
|
||
processTreeData(data) {
|
||
return Array.isArray(data) ? data : data ? [data] : []
|
||
},
|
||
|
||
// 新增:递归处理装备分类节点(限制六级)
|
||
processEquipmentTree(data, currentLevel = 1) {
|
||
if (currentLevel > 6) return []
|
||
return data.map(item => {
|
||
const nodeId = item.typeId ? Number(item.typeId) : item.id ? Number(item.id) : ''
|
||
const processedItem = {
|
||
id: nodeId,
|
||
name: item.typeName || item.name,
|
||
level: currentLevel,
|
||
parentId: item.parentId ? Number(item.parentId) : null,
|
||
...item
|
||
}
|
||
if (item.children && item.children.length > 0 && currentLevel < 6) {
|
||
processedItem.children = this.processEquipmentTree(item.children, currentLevel + 1)
|
||
} else {
|
||
delete processedItem.children
|
||
}
|
||
return processedItem
|
||
})
|
||
},
|
||
|
||
// 新增:获取装备分类树数据
|
||
async getEquipmentTree() {
|
||
try {
|
||
const res = await getEquipmentTreeAPI()
|
||
if (res.code === 200) {
|
||
const rawTreeData = this.processTreeData(res.data)
|
||
this.equipmentTreeData = this.processEquipmentTree(rawTreeData)
|
||
} else {
|
||
this.$message.error(res.msg || '获取装备分类失败')
|
||
}
|
||
} catch (error) {
|
||
this.$message.error('获取装备分类数据失败:' + (error.message || '未知错误'))
|
||
}
|
||
},
|
||
|
||
// 新增:递归处理工具分类节点(限制六级)
|
||
processToolTree(data, currentLevel = 1) {
|
||
if (currentLevel > 6) return []
|
||
return data.map(item => {
|
||
const processedItem = { ...item }
|
||
if (item.children && item.children.length > 0 && currentLevel < 6) {
|
||
processedItem.children = this.processToolTree(item.children, currentLevel + 1)
|
||
} else {
|
||
delete processedItem.children // 超过六级移除子节点
|
||
}
|
||
return processedItem
|
||
})
|
||
},
|
||
|
||
// 新增:获取工具分类树数据
|
||
async getToolTree() {
|
||
try {
|
||
const res = await getTreeSelectApi()
|
||
if (res.code === 200) {
|
||
let rawData = res.data || []
|
||
this.toolTreeData = this.processToolTree(rawData)
|
||
} else {
|
||
this.$message.error(res.msg || '获取工具分类失败')
|
||
}
|
||
} catch (error) {
|
||
this.$message.error('获取工具分类数据失败:' + (error.message || '未知错误'))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
::v-deep .red {
|
||
color: red; /* Element UI官方危险色,比纯red更贴合UI风格 */
|
||
font-weight: 500; /* 可选:加粗突出告警文本 */
|
||
}
|
||
/* 六级分类级联选择器样式优化 */
|
||
::v-deep .six-level-cascader .el-cascader-menu {
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu__item {
|
||
position: relative;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
/* 各级分类缩进差异化 */
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='1'] .el-cascader-menu__item {
|
||
padding-left: 20px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='2'] .el-cascader-menu__item {
|
||
padding-left: 35px;
|
||
font-weight: 400;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='3'] .el-cascader-menu__item {
|
||
padding-left: 50px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='4'] .el-cascader-menu__item {
|
||
padding-left: 65px;
|
||
font-size: 13px;
|
||
color: #666;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='5'] .el-cascader-menu__item {
|
||
padding-left: 80px;
|
||
font-size: 12px;
|
||
color: #888;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='6'] .el-cascader-menu__item {
|
||
padding-left: 95px;
|
||
font-size: 12px;
|
||
color: #999;
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
/* 隐藏七级及以上分类 */
|
||
::v-deep .six-level-cascader .el-cascader-menu[data-level='7'] .el-cascader-menu__item {
|
||
display: none;
|
||
}
|
||
|
||
/* 滚动条样式优化 */
|
||
::v-deep .six-level-cascader .el-cascader-menu::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu::-webkit-scrollbar-track {
|
||
background: #f1f1f1;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
::v-deep .six-level-cascader .el-cascader-menu::-webkit-scrollbar-thumb {
|
||
background: #c1c1c1;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
/* 表单项间距优化 */
|
||
.el-form-item {
|
||
margin-bottom: 15px;
|
||
}
|
||
</style>
|