bonus-ui/src/views/EquipmentRetireApply/components/AddItemDialog.vue

489 lines
16 KiB
Vue
Raw Normal View History

2025-11-16 23:55:09 +08:00
<template>
<el-dialog
title="添加装备/工具"
:visible.sync="visible"
2025-11-25 19:07:50 +08:00
width="1400px"
2025-11-16 23:55:09 +08:00
@close="onClose"
>
<!-- 搜索条件 -->
2025-12-02 17:54:15 +08:00
<el-form ref="queryForm" label-width="40px" inline :model="queryParams">
2025-11-25 19:07:50 +08:00
<el-form-item label="名称" prop="typeName">
<el-input v-model="queryParams.typeName" placeholder="请输入名称" clearable style="width: 202px"/>
2025-11-16 23:55:09 +08:00
</el-form-item>
2025-11-25 19:07:50 +08:00
2025-12-02 17:54:15 +08:00
<el-form-item label="规格型号" prop="typeModelName" label-width="70px">
2025-11-25 19:07:50 +08:00
<el-input v-model="queryParams.typeModelName" maxlength="20" placeholder="请输入规格型号" clearable style="width: 202px"/>
</el-form-item>
2025-12-02 17:54:15 +08:00
<el-form-item label="设备编码" prop="devCode" label-width="70px">
2025-11-25 19:07:50 +08:00
<el-input v-model="queryParams.devCode" maxlength="20" placeholder="请输入编码" clearable style="width: 202px"/>
</el-form-item>
2025-12-02 17:54:15 +08:00
<el-form-item label="分类" prop="devType" label-width="40px">
2025-11-25 19:07:50 +08:00
<el-select v-model="queryParams.devType" placeholder="请选择分类" clearable style="width: 202px">
2025-11-21 14:01:43 +08:00
<el-option label="装备" value="1" />
<el-option label="工具" value="2" />
2025-11-16 23:55:09 +08:00
</el-select>
</el-form-item>
2025-11-25 19:07:50 +08:00
<!-- 新增动态显示的管理模式下拉框 -->
<el-form-item
v-if="queryParams.devType === '2'"
label="管理模式"
2025-12-02 17:54:15 +08:00
label-width="70px"
2025-11-25 19:07:50 +08:00
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>
2025-11-21 14:01:43 +08:00
<!-- &lt;!&ndash; 新增装备分类下拉框 &ndash;&gt;-->
<!-- <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>-->
<!-- &lt;!&ndash; 新增工具分类下拉框 &ndash;&gt;-->
<!-- <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>-->
2025-12-02 17:54:15 +08:00
<el-form-item style="float: right">
2025-11-16 23:55:09 +08:00
<el-button type="primary" size="small" @click="onHandleQuery">查询</el-button>
<el-button size="small" @click="onHandleReset">重置</el-button>
2025-11-25 19:07:50 +08:00
</el-form-item>
2025-11-16 23:55:09 +08:00
</el-form>
<!-- 在修装备/工具列表 -->
<el-table
ref="itemTable"
:data="itemList"
2025-12-08 15:28:33 +08:00
row-key="id"
2025-11-16 23:55:09 +08:00
style="width: 100%"
border
stripe
size="small"
fit
2025-12-04 11:29:53 +08:00
height="546"
2025-11-16 23:55:09 +08:00
@selection-change="onSelectionChange"
>
2025-12-08 15:28:33 +08:00
<el-table-column type="selection" width="50" :selectable="selectable" :reserve-selection="true"/>
2025-11-16 23:55:09 +08:00
<el-table-column align="center" type="index" label="序号" width="100" />
2025-11-25 19:07:50 +08:00
<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" />
2025-11-16 23:55:09 +08:00
<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" />
2025-12-08 15:28:33 +08:00
<el-table-column align="center" prop="scrapQuantity" label="申请退役数量" width="150">
2025-11-16 23:55:09 +08:00
<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>
<!-- 分页 -->
2025-11-21 14:01:43 +08:00
<div style="text-align: right; margin-top: 15px;">
2025-11-16 23:55:09 +08:00
<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="onHandleConfirm">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import { getScrapItemListAPI } from '@/api/EquipmentRetireApply/index.js'
2025-11-21 14:01:43 +08:00
// 导入分类树接口(与之前项目保持一致)
import { getEquipmentTreeAPI } from '@/api/EquipmentConfig/index.js'
import { getTreeSelectApi } from '@/api/toolsManage/index.js'
2025-11-16 23:55:09 +08:00
export default {
props: {
existingItems: {
type: Array,
default: () => []
}
},
data() {
return {
visible: false,
queryParams: {
name: '',
2025-11-25 19:07:50 +08:00
typeName:'',
2025-11-21 14:01:43 +08:00
devType: '',
2025-11-25 19:07:50 +08:00
manageType: '',
typeModelName: '',
devCode: '',
2025-11-21 14:01:43 +08:00
equipmentCategory: [], // 新增:装备分类路径(数组)
toolCategory: [], // 新增:工具分类路径(数组)
equipmentCategoryId: '', // 新增装备分类ID用于接口查询
toolCategoryId: '', // 新增工具分类ID用于接口查询
2025-11-16 23:55:09 +08:00
pageNum: 1,
pageSize: 10
},
itemList: [],
total: 0,
selectedItems: [],
2025-11-21 14:01:43 +08:00
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'
// }
2025-11-16 23:55:09 +08:00
}
},
watch: {
'queryParams.pageNum'() {
this.getItemList()
},
'queryParams.pageSize'() {
this.queryParams.pageNum = 1
this.getItemList()
2025-11-21 14:01:43 +08:00
},
// 分类切换时清空对应类目选择
'queryParams.devType'(val) {
if (val === '装备') {
this.queryParams.toolCategory = []
this.queryParams.toolCategoryId = ''
} else if (val === '工具') {
this.queryParams.equipmentCategory = []
this.queryParams.equipmentCategoryId = ''
}
2025-11-16 23:55:09 +08:00
}
},
2025-11-21 14:01:43 +08:00
created() {
// 初始化加载分类树数据
this.getEquipmentTree()
this.getToolTree()
},
2025-11-16 23:55:09 +08:00
methods: {
open() {
this.visible = true
this.getItemList()
},
async getItemList() {
try {
2025-11-21 14:01:43 +08:00
// 构造查询参数传递分类ID
const query = {
...this.queryParams,
// 只传递最终的分类ID简化接口参数
equipmentCategory: this.queryParams.equipmentCategoryId,
2025-11-25 19:07:50 +08:00
toolCategory: this.queryParams.toolCategoryId,
manageType: this.queryParams.manageType,
// 新增:将规格型号和设备编码加入查询参数
typeModelName: this.queryParams.typeModelName,
devCode: this.queryParams.devCode,
typeName: this.queryParams.typeName,
2025-11-21 14:01:43 +08:00
}
const res = await getScrapItemListAPI(query)
2025-11-16 23:55:09 +08:00
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: '',
2025-11-25 19:07:50 +08:00
typeName: '',
2025-11-21 14:01:43 +08:00
devType: '',
2025-11-25 19:07:50 +08:00
manageType: '',
2025-11-21 14:01:43 +08:00
equipmentCategory: [],
toolCategory: [],
equipmentCategoryId: '',
toolCategoryId: '',
2025-11-16 23:55:09 +08:00
pageNum: 1,
pageSize: 10
}
this.getItemList()
},
2025-12-08 15:28:33 +08:00
selectable(row) {
return !this.existingItems.some(item => item.keyId === row.keyId)
},
2025-11-16 23:55:09 +08:00
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)
},
onHandleConfirm() {
2025-12-08 15:28:33 +08:00
if (this.selectedItems.length === 0) {
2025-11-16 23:55:09 +08:00
this.$message.warning('请选择至少一项')
return
}
// 检查申请报废数量是否有效
2025-12-08 15:28:33 +08:00
// const invalidItems = this.allSelectedItems.filter(item => !item.scrapQuantity || item.scrapQuantity < 1)
const invalidItems = this.selectedItems.filter(item => !item.scrapQuantity || item.scrapQuantity < 1)
2025-11-16 23:55:09 +08:00
if (invalidItems.length > 0) {
const invalidNames = invalidItems.map(item => item.typeModelName).join('、')
this.$message.warning(`以下项目的申请报废数量必须大于0${invalidNames}`)
return
}
// 检查是否有重复的keyId
2025-12-08 15:28:33 +08:00
// 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
// }
2025-11-16 23:55:09 +08:00
2025-12-08 15:28:33 +08:00
this.$emit('confirm', this.selectedItems)
2025-11-16 23:55:09 +08:00
this.visible = false
this.selectedItems = []
this.allSelectedItems = []
},
onClose() {
this.selectedItems = []
this.allSelectedItems = []
2025-11-21 14:01:43 +08:00
},
// 新增:装备分类选择变化
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 || '未知错误'))
}
2025-11-16 23:55:09 +08:00
}
}
}
</script>
<style lang="scss" scoped>
2025-11-21 14:01:43 +08:00
/* 六级分类级联选择器样式优化 */
::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;
}
2025-11-16 23:55:09 +08:00
2025-11-21 14:01:43 +08:00
::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>