bonus-ui/src/views/EquipmentLedger/index.vue

2011 lines
66 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-row :gutter="24" class="main-content" type="justify">
<el-col :span="collapsed ? 1 : 5" class="tree-column" style="">
<div class="card-container" v-if="!collapsed" style="min-width: 100%">
<div class="card-header" v-if="!collapsed">
<el-form
ref="queryFormLeft"
v-show="showSearch"
:model="queryParams"
:rules="queryRules"
@submit.native.prevent
style="width: 100%"
>
<el-form-item prop="name" style="margin-bottom: unset">
<el-input
v-model="treeSearchKey"
placeholder="搜索"
@keyup.enter.native="getDeviceListByTreeSearch"
@input="getDeviceListByTreeSearch"
>
<template #suffix>
<div class="tree-search-buttons">
<el-button
icon="el-icon-search"
size="mini"
type="text"
@click="getDeviceListByTreeSearch"
title="查询"
@keyup.enter.native="getDeviceListByTreeSearch"
style="margin-left: 10px; font-size: 16px; color: #c0c4cc"
/>
<el-button
icon="el-icon-refresh"
size="mini"
@click="resetTreeSearch"
title="重置"
type="text"
style="margin-left: 10px; font-size: 16px; color: #c0c4cc"
/>
</div>
</template>
</el-input>
</el-form-item>
</el-form>
</div>
<!-- 树组件,折叠时隐藏 -->
<el-tree
v-show="!collapsed"
:data="treeData"
:props="defaultProps"
:indent="6"
@node-click="handleNodeClick"
:default-expanded-keys="defaultExpandedKeys"
node-key="id"
class="tree-container"
:loading="treeLoading"
/>
</div>
<div style="position: relative; width: 20px; height: calc(100vh - 130px); margin-left: 5px">
<!-- 右侧折叠/展开按钮 -->
<el-button
icon="el-icon-d-arrow-left"
size="mini"
@click="toggleCollapse"
class="collapse-btn"
:icon="collapsed ? 'el-icon-d-arrow-right' : 'el-icon-d-arrow-left'"
/>
</div>
</el-col>
<!-- 右侧列表和查询区域 -->
<el-col :span="collapsed ? 23 : 19" style="height: calc(100vh - 130px); transition: all 0.3s ease">
<div class="card-container">
<div class="card-header">
<!-- 搜索区域展开/收起按钮 -->
<div class="status-stats">
<span class="card-title">装备查询</span>
<div class="stat-item">
<span class="stat-label">在库</span>
<span class="stat-value">{{ inStock }}</span>
</div>
<div class="stat-item">
<span class="stat-label">自用</span>
<span class="stat-value">{{ ownUse }}</span>
</div>
<div class="stat-item">
<span class="stat-label">共享</span>
<span class="stat-value">{{ share }}</span>
</div>
<div class="stat-item">
<span class="stat-label">在修</span>
<span class="stat-value">{{ underRepair }}</span>
</div>
</div>
<el-button type="text" size="mini" @click="toggleSearch" class="search-toggle-btn">
<i :class="searchExpanded ? 'el-icon-up' : 'el-icon-down'"></i>
{{ searchExpanded ? '收起' : '展开' }}
</el-button>
</div>
<el-form
ref="queryForm"
label-width="110px"
v-show="showSearch"
:model="queryParams"
:rules="queryRules"
style="margin-top: 10px"
>
<!-- 始终显示的查询条件 -->
<el-row :gutter="15">
<!-- <el-col :span="6">
<el-form-item label="所属省份" prop="province">
<el-select
v-model="queryParams.province"
placeholder="请选择所属省份"
clearable
filterable
style="width: 100%"
>
<el-option v-for="item in provinceList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="6" v-if="hasChildrenPropertyUnit">
<el-form-item label="产权单位" prop="propertyUnitIds">
<el-cascader
clearable
v-model="queryParams.propertyUnitIds"
placeholder="请选择产权单位"
:options="propertyUnitList"
:props="{ label: 'label', value: 'id', children: 'children', checkStrictly: true }"
style="width: 100%"
@change="handleUnitChange"
/>
<!-- <el-select
v-model="queryParams.propertyUnitId"
placeholder="请选择产权单位"
clearable
filterable
style="width: 100%"
>
<el-option v-for="item in propertyUnitList" :key="item.id" :label="item.label" :value="item.id" />
</el-select> -->
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入装备名称" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="规格型号" prop="specificationModel">
<el-input v-model="queryParams.specificationModel" placeholder="请输入规格型号" clearable />
</el-form-item>
</el-col>
</el-row>
<!-- 可折叠的查询条件 -->
<div v-if="searchExpanded">
<el-row :gutter="15">
<el-col :span="6">
<el-form-item label="专业" prop="majorId">
<el-select
v-model="queryParams.majorId"
placeholder="请选择专业"
clearable
@change="majorChange"
style="width: 100%"
>
<el-option v-for="item in majorList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工序" prop="process">
<el-cascader
clearable
v-model="queryParams.process"
placeholder="请选择工序"
:options="processList"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择装备状态" clearable style="width: 100%">
<el-option label="在库" value="1"></el-option>
<el-option label="自用" value="2"></el-option>
<el-option label="共享" value="3"></el-option>
<el-option label="退役" value="4"></el-option>
<el-option label="维修" value="5"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备编码" prop="code">
<el-input v-model="queryParams.code" placeholder="请输入装备编码" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="生产日期" prop="productionDate">
<el-date-picker
v-model="queryParams.productionDate"
type="daterange"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
clearable
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="采购日期" prop="purchaseDate">
<el-date-picker
v-model="queryParams.purchaseDate"
type="daterange"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
clearable
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="资产原值(万元)" prop="originalValue">
<el-input-number
v-model="queryParams.minOriginalValue"
placeholder="资产原值(万元)"
clearable
:controls="false"
:min="0"
style="width: 150px"
/>
<span> - </span>
<el-input-number
v-model="queryParams.maxOriginalValue"
placeholder="资产原值(万元)"
clearable
:controls="false"
:min="0"
style="width: 150px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="原始编码" prop="originalCode">
<el-input v-model="queryParams.originalCode" placeholder="请输入装备原始编码" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="使用年限" prop="serviceLife">
<el-input v-model="queryParams.serviceLife" placeholder="请输入使用年限" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="生产厂商" prop="manufacturer">
<el-select
v-model="queryParams.manufacturer"
placeholder="请选择生产厂商"
clearable
style="width: 100%"
>
<el-option v-for="item in manufacturerList" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="特征项" prop="featureItem">
<el-input v-model="queryParams.featureItem" placeholder="请输入特征项" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="特征值" prop="featureValue">
<el-input v-model="queryParams.featureValue" placeholder="请输入特征值" clearable />
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
<!-- 状态统计和操作按钮 - 固定定位 -->
<div class="status-operation-bar sticky-bar">
<div class="operation-buttons">
<el-button icon="el-icon-refresh" style="float: right; margin-left: 20px" size="mini" @click="resetQuery">
重置
</el-button>
<el-button type="primary" style="float: right" icon="el-icon-search" size="mini" @click="getDeviceList">
查询
</el-button>
</div>
</div>
<!-- 装备列表表格 -->
<div class="card-container">
<el-row :gutter="10" class="mb8" style="display: flex; align-items: center">
<el-col :span="21">
<div class="card-header">
<div>
<span class="table-title">装备列表 </span>
<span class="table-count"> 共 {{ total }} 条记录</span>
</div>
<span>
<el-button
icon="el-icon-download"
style="float: right"
type="primary"
size="mini"
@click="exportData"
>
导出数据
</el-button>
</span>
</div>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getDeviceList"
:columns="columns2"
></right-toolbar>
</el-row>
<el-table
ref="tableRef"
:data="tableData"
:key="Date.now()"
@selection-change="handleSelectionChange"
v-loading="tableLoading"
border
stripe
height="546"
>
<el-table-column align="center" show-overflow-tooltip type="selection" width="50" />
<el-table-column align="center" show-overflow-tooltip type="index" label="序号" width="50" />
<el-table-column
v-for="(item, index) in columns2"
v-if="item.visible"
:key="index"
align="center"
show-overflow-tooltip
min-width="200"
:label="item.label"
:prop="item.prop"
>
<template v-slot="{ row }" v-if="item.prop == 'process'">
<span>{{ row.mainProcess }}{{ row.subProcess ? '>' + row.subProcess : '' }}</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'devType'">
<span>
{{ row.mainCategory ? row.mainCategory + '>' : '' }}
{{ row.branch ? row.subCategory : row.subCategory }}
<!-- {{ row.branch }}-->
</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'upDownStatus'">
<el-tag v-if="row.upDownStatus == 1" size="mini">上架</el-tag>
<el-tag v-if="row.upDownStatus == 0" size="mini" type="danger">下架</el-tag>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'status'">
<el-tag v-if="row.status == 1" type="success" size="mini">在库</el-tag>
<el-tag v-if="row.status == 2" size="mini">自用</el-tag>
<el-tag v-if="row.status == 3" size="mini">共享</el-tag>
<el-tag v-if="row.status == 4" size="mini" type="danger">退役</el-tag>
<el-tag v-if="row.status == 5" size="mini" type="warning">维修</el-tag>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'appearanceImages'">
<span style="color: #00a288; cursor: pointer" @click="handleView(row, 1)">查看</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'certificates'">
<span style="color: #00a288; cursor: pointer" @click="handleView(row, 2)">查看</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'inspectionReports'">
<span style="color: #00a288; cursor: pointer" @click="handleView(row, 3)">查看</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'purchaseInvoices'">
<span style="color: #00a288; cursor: pointer" @click="handleView(row, 4)">查看</span>
</template>
<template v-slot="{ row }" v-else-if="item.prop == 'fileImgList'">
<span style="color: #00a288; cursor: pointer" @click="handleFileListUpload(row)">报告管理</span>
</template>
<template v-slot="{ row }" v-else-if="/^feature(Item|Value)\d+$/.test(item.prop)">
<span>
{{ getFeatureValue(row, item.prop) }}
</span>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" min-width="200" label="操作">
<template slot-scope="scope">
<el-button type="text" @click="onHandlePreview(scope.row)">
<i class="el-icon-view"></i> 查看
</el-button>
<el-button type="text" icon="el-icon-edit" @click="onHandleEdit(scope.row)"> 编辑 </el-button>
<el-button type="text" icon="el-icon-delete" @click="onHandleDelete(scope.row)" style="color: red">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getDeviceList"
layout="total, sizes, prev, pager, next, jumper"
/>
</div>
</el-col>
</el-row>
<!-- 查看弹窗 -->
<el-dialog
:title="`查看装备 - ${formData.name || ''}`"
:visible.sync="previewDialogVisible"
width="70%"
:close-on-click-modal="false"
:before-close="handlePreviewClose"
>
<el-form
ref="previewForm"
:model="formData"
:rules="formRules"
label-width="120px"
size="small"
class="detail-form"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="公司名称" prop="companyName">
<el-input v-model="formData.companyName" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="施工主工序" prop="mainGx">
<el-input v-model="formData.mainGx" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="施工子工序" prop="childGx">
<el-input v-model="formData.childGx" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备大类" prop="devCategory">
<el-input v-model="formData.devCategory" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备小类" prop="devSubcategory">
<el-input v-model="formData.devSubcategory" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备名称" prop="name">
<el-input v-model="formData.name" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格型号" prop="devModel">
<el-input v-model="formData.devModel" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备编号" prop="code">
<el-input v-model="formData.code" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备状态" prop="changeStatus">
<el-select v-model="formData.changeStatus" disabled>
<el-option label="在库" value="1"></el-option>
<el-option label="在用" value="2"></el-option>
<el-option label="共享" value="3"></el-option>
<el-option label="退役" value="4"></el-option>
<el-option label="维修" value="5"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="上下架状态" prop="upDownStatus">
<el-select v-model="formData.upDownStatus" disabled>
<el-option label="上架" value="1"></el-option>
<el-option label="下架" value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="使用到期时间" prop="expireTime">
<el-input v-model="formData.expireTime" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计数单位" prop="unitName">
<el-input v-model="formData.unitName" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="产权单位" prop="propertyCompany">
<el-input v-model="formData.propertyCompany" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="资产原值(万元)" prop="buyPrice">
<el-input v-model="formData.buyPrice" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产日期" prop="productionDate">
<el-input v-model="formData.productionDate" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="使用年限" prop="workingHours">
<el-input v-model="formData.workingHours" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在项目" prop="onProject">
<el-input v-model="formData.onProject" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人" prop="person">
<el-input v-model="formData.person" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式" prop="personPhone">
<el-input v-model="formData.personPhone" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次维保日期" prop="nextCheckTime">
<el-input v-model="formData.nextCheckTime" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产厂商" prop="brand">
<el-input v-model="formData.brand" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handlePreviewClose">关闭</el-button>
</div>
</el-dialog>
<!-- 编辑弹窗 -->
<!-- 编辑弹窗 -->
<el-dialog
:title="`编辑装备 - ${formData.name || ''}`"
:visible.sync="editDialogVisible"
width="70%"
:close-on-click-modal="false"
:before-close="handleEditClose"
>
<el-form ref="editForm" :model="formData" :rules="formRules" label-width="120px" size="small" class="detail-form">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="公司名称" prop="companyName">
<el-input v-model="formData.companyName" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="施工主工序" prop="mainGx">
<el-input v-model="formData.mainGx" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="施工子工序" prop="childGx">
<el-input v-model="formData.childGx" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备大类" prop="devCategory">
<el-input v-model="formData.devCategory" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备小类" prop="devSubcategory">
<el-input v-model="formData.devSubcategory" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备名称" prop="name">
<el-input v-model="formData.name" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格型号" prop="devModel">
<el-input v-model="formData.devModel" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备编号" prop="code">
<el-input v-model="formData.code" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="装备状态" prop="changeStatus">
<el-select v-model="formData.changeStatus" placeholder="请选择装备状态">
<el-option label="在库" value="1"></el-option>
<el-option label="在用" value="2"></el-option>
<el-option label="共享" value="3"></el-option>
<el-option label="退役" value="4"></el-option>
<el-option label="维修" value="5"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="上下架状态" prop="upDownStatus">
<el-select v-model="formData.upDownStatus" placeholder="请选择上下架状态">
<el-option label="上架" value="1"></el-option>
<el-option label="下架" value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="使用到期时间" prop="expireTime">
<el-date-picker
v-model="formData.expireTime"
type="date"
placeholder="选择使用到期时间"
value-format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计数单位" prop="unitName">
<el-input v-model="formData.unitName" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="产权单位" prop="propertyCompany">
<el-input v-model="formData.propertyCompany" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="资产原值(万元)" prop="buyPrice">
<el-input v-model="formData.buyPrice" type="number" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出厂日期" prop="productionDate">
<el-date-picker
v-model="formData.productionDate"
type="date"
placeholder="选择出厂日期"
value-format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="使用年限" prop="workingHours">
<el-input v-model="formData.workingHours" type="number" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在项目" prop="onProject">
<el-input v-model="formData.onProject" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人" prop="person">
<el-input v-model="formData.person" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式" prop="personPhone">
<el-input v-model="formData.personPhone" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次维保日期" prop="nextCheckTime">
<el-date-picker
v-model="formData.nextCheckTime"
type="date"
placeholder="选择下次维保日期"
value-format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产厂商" prop="brand">
<el-input v-model="formData.brand" />
</el-form-item>
</el-col>
<el-col :span="12"></el-col>
<!-- 添加特征项按钮 -->
<el-col :span="24" style="text-align: center; margin-top: 10px">
<el-button
type="text"
size="small"
@click="addFeatureItem"
:disabled="formData.propertyVoList.length >= tableColumns"
>
<i class="el-icon-plus"></i> 添加特征项
</el-button>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleEditClose">取消</el-button>
<el-button type="primary" @click="submitEditForm">保存</el-button>
</div>
</el-dialog>
<!-- 弹框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">
<el-table :data="dialogList" fit highlight-current-row style="width: 100%" height="546">
<el-table-column type="index" width="55" label="序号" align="center" />
<el-table-column label="附件名称" prop="fileName" align="center">
<!-- 插槽 -->
<template v-slot="{ row }">
<span style="color: #00a288; cursor: pointer" @click="handleFile(row)">{{ row.fileName }}</span>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关 闭</el-button>
</span>
</el-dialog>
<!-- 报告管理 -->
<el-dialog title="报告管理" :visible.sync="openReport" width="900px" append-to-body>
<el-table :data="fileDataList" width="100%" height="350px">
<el-table-column label="序号" type="index" width="55" align="center" />
<el-table-column label="报告类型" align="center" prop="dictLabel" :show-overflow-tooltip="true">
<template v-slot="{ row }">
<span v-if="row.type == 1 || row.type == 2 || row.type == 3">
<span style="color: red">*</span>
{{ row.dictLabel }}
</span>
<span v-else>{{ row.dictLabel }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template slot-scope="{ row, $index }">
<div style="display: flex; align-items: center; justify-content: center">
<el-button
v-if="
(row.type == 1 && currentRow.appearanceImages.length > 0) ||
(row.type == 2 && currentRow.certificates.length > 0) ||
(row.type == 3 && currentRow.inspectionReports.length > 0) ||
(row.type == 4 && currentRow.purchaseInvoices.length > 0)
"
size="mini"
type="text"
@click="handleView(currentRow, row.type)"
>
查看
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-dialog>
<AddEquip ref="addEquipRef" @getList="getDeviceList" />
</div>
</template>
<script>
import {
getDeviceTreeAPI,
getDeviceListAPI,
updateDeviceUpDownAPI,
getDeviceStatusCountAPI,
delDevice,
updateDeviceAPI,
getDeviceDetailAPI,
getManufacturerSelectApi,
} from '@/api/EquipmentLedger/index.js'
import { firstLevel, secondAndThirdLevel } from '@/api/EquipmentEntryApply'
import { getMaxFeatureAPI, getProvinceListAPI } from '@/api/EquipmentLedger/equ-out.js'
import { deptTreeSelect } from '@/api/system/user'
import AddEquip from '@/views/stockManagement/entryApply/components/AddEquip'
export default {
name: 'EquipmentLedger',
components: { AddEquip },
data() {
return {
treeSearchKey: '', //用于存储左侧树搜索框内容
showSearch: true,
total: 0,
tableHeight: 500,
collapsed: false,
// 查询参数
queryParams: {
province: undefined, // 省份
propertyUnitId: undefined, // 产权单位
propertyUnitIds: [],
name: undefined, // 装备名称
specificationModel: undefined, // 规格型号
major: undefined, // 专业
process: undefined, // 工序
status: undefined, // 状态
code: undefined, // 编码
productionDate: undefined, // 生产日期
purchaseDate: undefined, // 采购日期
minOriginalValue: undefined, // 资产原值
maxOriginalValue: undefined, // 资产原值
originalCode: undefined, // 装备原始编码
serviceLife: undefined, // 使用年限
manufacturer: undefined, // 厂家
featureItem: undefined, // 特征项
featureValue: undefined, // 特征值
pageNum: 1,
pageSize: 10,
},
// 查询表单验证规则
queryRules: {},
// 树形结构配置
defaultProps: {
children: 'children',
label: 'name',
},
treeData: [],
defaultExpandedKeys: [], // 存储默认展开的节点 key
provinceList: [], // 所属省份
propertyUnitList: [], // 产权单位
majorList: [], // 专业
processList: [], // 工序
serviceLifeList: [], // 使用年限
manufacturerList: [], // 生产厂家
columns2: [],
columns: [
// { key: 0, label: `所属省份`, prop: 'province', visible: true },
{ key: 1, label: `产权单位`, prop: 'propertyUnit', visible: true },
{ key: 2, label: `专业`, prop: 'major', visible: true },
{ key: 3, label: `工序`, prop: 'process', visible: true },
{ key: 4, label: `装备类目`, prop: 'devType', visible: true },
{ key: 5, label: `装备名称`, prop: 'name', visible: true },
{ key: 6, label: `规格型号`, prop: 'specificationModel', visible: true },
{ key: 7, label: `装备编码`, prop: 'code', visible: true },
{ key: 8, label: `装备状态`, prop: 'status', visible: true },
// { key: 44, label: `上下架状态`, prop: 'upDownStatus', visible: true },
{ key: 9, label: `使用年限`, prop: 'serviceLife', visible: true },
{ key: 10, label: `使用项目`, prop: 'usingProject', visible: true },
{ key: 11, label: `使用到期时间`, prop: 'expirationTime', visible: true },
{ key: 12, label: `使用次数`, prop: 'usageCount', visible: true },
{ key: 13, label: `维修次数`, prop: 'repairCount', visible: true },
{ key: 14, label: `装备原始编码`, prop: 'originalCode', visible: true },
// { key: 15, label: `计量单位`, prop: 'unit', visible: true },
{ key: 16, label: `生产厂家`, prop: 'manufacturer', visible: true },
{ key: 17, label: `出厂日期`, prop: 'productionDate', visible: true },
{ key: 18, label: `采购日期`, prop: 'purchaseDate', visible: true },
{ key: 19, label: `资产原值(万元)`, prop: 'originalValue', visible: true },
{ key: 19, label: `资产净值(万元)`, prop: 'value', visible: true },
{ key: 20, label: `最大使用年限(年)`, prop: 'maxServiceLifeYears', visible: true },
{ key: 21, label: `下次维保日期`, prop: 'nextMaintenanceDate', visible: true },
{ key: 22, label: `相关配套资料`, prop: 'fileImgList', visible: true },
// { key: 22, label: `装备外观`, prop: 'appearanceImages', visible: true },
// { key: 23, label: `合格证`, prop: 'certificates', visible: true },
// { key: 24, label: `定期检验报告`, prop: 'inspectionReports', visible: true },
// { key: 25, label: `采购发票`, prop: 'purchaseInvoices', visible: true },
{ key: 26, label: `特征项1`, prop: 'featureItem1', visible: true },
{ key: 27, label: `特征值1`, prop: 'featureValue1', visible: true },
{ key: 28, label: `特征项2`, prop: 'featureItem2', visible: true },
{ key: 29, label: `特征值2`, prop: 'featureValue2', visible: true },
{ key: 30, label: `特征项3`, prop: 'featureItem3', visible: true },
{ key: 31, label: `特征值3`, prop: 'featureValue3', visible: true },
{ key: 32, label: `特征项4`, prop: 'featureItem4', visible: true },
{ key: 33, label: `特征值4`, prop: 'featureValue4', visible: true },
{ key: 34, label: `特征项5`, prop: 'featureItem5', visible: true },
{ key: 35, label: `特征值5`, prop: 'featureValue5', visible: true },
{ key: 36, label: `特征项6`, prop: 'featureItem6', visible: true },
{ key: 37, label: `特征值6`, prop: 'featureValue6', visible: true },
{ key: 38, label: `特征项7`, prop: 'featureItem7', visible: true },
{ key: 39, label: `特征值7`, prop: 'featureValue7', visible: true },
{ key: 40, label: `特征项8`, prop: 'featureItem8', visible: true },
{ key: 41, label: `特征值8`, prop: 'featureValue8', visible: true },
{ key: 42, label: `特征项9`, prop: 'featureItem9', visible: true },
{ key: 43, label: `特征值9`, prop: 'featureValue9', visible: true },
],
tableData: [],
tableColumns: 0,
selectedRows: [],
// 状态统计数据
inStock: 0,
ownUse: 0,
share: 0,
underRepair: 0,
// 加载状态
treeLoading: false,
tableLoading: false,
// 弹窗相关
previewDialogVisible: false,
editDialogVisible: false,
showFieldSetting: false, // 字段设置弹窗控制
// 搜索区域展开状态
searchExpanded: false,
selectedColumns: [],
// 表单数据
formData: {
maId: '',
companyName: '',
mainGx: '',
childGx: '',
devCategory: '',
devSubcategory: '',
name: '',
devModel: '',
code: '',
changeStatus: '',
upDownStatus: '',
expireTime: '',
unitName: '',
propertyCompany: '',
buyPrice: '',
productionDate: '',
workingHours: '',
onProject: '',
person: '',
personPhone: '',
nextCheckTime: '',
brand: '',
propertyVoList: [],
},
// 表单验证规则
formRules: {
name: [{ required: true, message: '请输入装备名称', trigger: 'blur' }],
code: [{ required: true, message: '请输入装备编号', trigger: 'blur' }],
changeStatus: [{ required: true, message: '请选择装备状态', trigger: 'change' }],
},
maxFeatureCount: 5, // 最大特征项数量限制
dialogVisible: false,
dialogTitle: '',
dialogList: [],
currentRow: {},
openReport: false,
fileDataList: [
{ dictLabel: '装备外观', type: '1' },
{ dictLabel: '合格证', type: '2' },
{ dictLabel: '检测证书', type: '3' },
{ dictLabel: '采购发票', type: '4' },
],
}
},
computed: {
hasChildrenPropertyUnit() {
const check = (list = []) => {
return list.some(item => {
return (
Array.isArray(item.children) &&
item.children.length > 0
) || check(item.children)
})
}
return check(this.propertyUnitList)
}
},
methods: {
handleUnitChange(value) {
if (value.length === 0) {
this.queryParams.propertyUnitId = undefined
return
}
this.queryParams.propertyUnitId = value[value.length - 1]
},
// 初始化:获取前两级节点的所有 key
initDefaultExpandedKeys() {
const keys = []
const traverse = (data, level) => {
data.forEach((node) => {
if (level <= 1) {
// 只展开第1级和第2级
keys.push(node.id) // 假设你的节点唯一标识是 `id`
if (node.children && node.children.length > 0) {
traverse(node.children, level + 1)
}
}
})
}
traverse(this.treeData, 1)
this.defaultExpandedKeys = keys
},
// 获取省份
getProvinceList() {
getProvinceListAPI().then((res) => {
this.provinceList = res.data
})
},
// 获取产权单位
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')
},
// 获取厂家
getManufacturerSelectList() {
getManufacturerSelectApi().then((res) => {
console.log('🚀 ~ getManufacturerSelectList ~ res:', res)
if (res.code === 200) {
this.manufacturerList = res.data
}
})
},
getFirstLevel() {
firstLevel().then((res) => {
if (res.code === 200) {
this.majorList = res.data
}
})
},
majorChange(item) {
if (!item) {
this.processList = []
this.queryParams.process = ''
} else {
secondAndThirdLevel({ firstLevelId: item }).then((res) => {
if (res.code === 200) {
this.processList = this.convertToSubTree(res.data)
}
})
}
},
convertToSubTree(list) {
const map = {}
const tree = []
// 构建节点映射
list.forEach((item) => {
map[item.value] = {
value: item.value.toString(),
label: item.label,
}
})
// 构建树形关系
list.forEach((item) => {
const current = map[item.value]
const parent = map[item.parentId]
if (parent) {
if (!parent.children) {
parent.children = []
}
parent.children.push(current)
} else {
tree.push(current)
}
})
return tree
},
// 切换折叠状态
toggleCollapse() {
this.collapsed = !this.collapsed
// 可以在这里添加折叠/展开的动画效果或其他逻辑
},
/**
* 切换搜索区域展开/收起状态
*/
toggleSearch() {
this.searchExpanded = !this.searchExpanded
this.searchExpanded ? (this.tableHeight = 320) : (this.tableHeight = 500)
},
/**
* 树形节点点击事件
*/
handleNodeClick(data) {
this.queryParams.typeId = data.id
this.getDeviceList()
},
/**
* 判断是否可选择
*/
isSelectable(row) {
return row.changeStatus === 1
},
/**
* 出库按钮
*/
onHandleOut() {
this.$router.push('/equipment/euq-out')
},
/**
* 重置查询条件
*/
resetQuery() {
this.$refs.queryForm.resetFields()
this.queryParams.minOriginalValue = ''
this.queryParams.maxOriginalValue = ''
this.queryParams.propertyUnitId = undefined
this.queryParams.pageNum = 1
this.getDeviceList()
},
/**
* 退库按钮
*/
onHandleIn() {
this.$router.push('/equipment-ledger-store/index')
},
/**
* 维修按钮
*/
onHandleRepair() {
this.$router.push('/equipment/equ-repair')
},
/**
* 退役按钮
*/
onHandleRetire() {
this.$router.push('/equipment/equ-retire')
},
onHandleReturn() {
this.$router.push('/equipment/equStore')
},
/**
* 导出数据
*/
exportData() {
this.$message.info('正在导出数据,请稍候...')
// 导出逻辑实现
try {
let fileName = `装备台账_${new Date().getTime()}.xLsx`
let url = '/material-mall/device/export'
const params = { ...this.queryParams }
console.log('🚀 ~ 导出 ~ params:', params)
this.download(url, params, fileName)
} catch (error) {
console.log('导出数据失败', error)
}
},
/**
* 获取左侧树形结构数据
*/
async getDeviceTree() {
try {
this.treeLoading = true
const res = await getDeviceTreeAPI()
this.treeData = res.data ? [res.data] : []
} catch (error) {
this.$message.error('获取树形结构失败:' + (error.message || '未知错误'))
console.error(error)
} finally {
this.treeLoading = false
}
},
/**
* 收集第一级和第二级节点的ID第三级默认不展开
*/
collectFirstAndSecondLevelKeys(nodes) {
if (!nodes || !nodes.length) return
nodes.forEach((firstLevelNode) => {
// 展开第一级节点
if (firstLevelNode.id) {
this.defaultExpandedKeys.push(firstLevelNode.id)
console.log(`展开第一级节点: ${firstLevelNode.name}, ID: ${firstLevelNode.id}`)
}
// 检查是否有子节点(第二级节点)
if (firstLevelNode.children && firstLevelNode.children.length) {
// 遍历所有第二级节点
firstLevelNode.children.forEach((secondLevelNode) => {
if (secondLevelNode.id) {
this.defaultExpandedKeys.push(secondLevelNode.id)
console.log(`展开第二级节点: ${secondLevelNode.name}, ID: ${secondLevelNode.id}`)
// 第三级及更深层级默认不展开(保持折叠状态)
}
})
}
})
},
/**
* 左侧树查询:匹配节点显示自身及下一级,但默认只显示到第二级
*/
async getDeviceListByTreeSearch() {
if (!this.treeSearchKey.trim) return
try {
// 1. 获取输入的查询关键词(去空格)
const searchKey = this.treeSearchKey ? this.treeSearchKey.trim() : ''
// 如果没有搜索关键词,则重置为原始树(显示到第二级)
if (!searchKey) {
await this.resetTreeSearch()
return
}
// 2. 重新获取原始树形数据
this.treeLoading = true
const res = await getDeviceTreeAPI()
const originalTreeData = res.data ? [res.data] : []
// 3. 筛选逻辑:匹配节点显示自身及下一级
const filteredTreeData = this.filterTreeWithNextLevel(originalTreeData, searchKey)
// 4. 收集所有匹配节点的ID用于默认展开
const expandedIds = []
this.collectMatchedNodeIds(filteredTreeData, searchKey, expandedIds)
// 5. 更新树形数据和默认展开节点
this.treeData = filteredTreeData
this.defaultExpandedKeys = expandedIds
// 6. 无匹配结果时提示
if (filteredTreeData.length === 0 || this.isTreeEmpty(filteredTreeData)) {
/* this.$message.info('未找到匹配的类型分支'); */
} else {
// this.$message.success(`找到 ${expandedIds.length} 个匹配项`);
}
} catch (error) {
// this.$message.error('树形查询失败:' + (error.message || '未知错误'));
console.error(error)
} finally {
this.treeLoading = false
}
},
/**
* 辅助方法:筛选节点并包含下一级
*/
filterTreeWithNextLevel(treeData, key) {
if (!treeData || !treeData.length) return []
return treeData
.map((node) => {
// 深拷贝节点
const newNode = { ...node }
const isNodeMatch = key ? node.name.includes(key) : true
if (isNodeMatch) {
// 匹配节点:保留所有直接子节点
if (newNode.children && newNode.children.length) {
// 保留第二级,但第三级及更深层级保持原样(默认不展开)
newNode.children = [...newNode.children]
}
return newNode
} else {
// 不匹配节点:检查子节点是否有匹配的
if (newNode.children && newNode.children.length) {
const filteredChildren = this.filterTreeWithNextLevel(newNode.children, key)
if (filteredChildren.length > 0) {
newNode.children = filteredChildren
return newNode
}
}
return null
}
})
.filter((node) => node !== null)
},
/**
* 辅助方法收集所有匹配关键词的节点ID用于默认展开
* @param {Array} treeData - 筛选后的树形数据
* @param {String} key - 查询关键词
* @param {Array} expandedIds - 存储展开节点ID的数组
*/
collectMatchedNodeIds(treeData, key, expandedIds) {
if (!treeData || !treeData.length) return
treeData.forEach((node) => {
// 若当前节点匹配关键词记录其ID用于展开
if (key ? node.name.includes(key) : true) {
if (node.id) expandedIds.push(node.id)
}
// 递归处理子级,确保深层子级的匹配节点也被收集
if (node.children && node.children.length) {
this.collectMatchedNodeIds(node.children, key, expandedIds)
}
})
},
/**
* 辅助方法:检查树是否为空(没有任何有效节点)
*/
isTreeEmpty(treeData) {
if (!treeData || !treeData.length) return true
// 递归检查所有节点
for (const node of treeData) {
if (node && node.id) {
return false // 发现有效节点
}
if (node.children && node.children.length) {
if (!this.isTreeEmpty(node.children)) {
return false // 子节点中有有效节点
}
}
}
return true
},
/**
* 左侧树重置:仅恢复树形原始状态(不联动右侧列表)
*/
/**
* 左侧树重置:恢复树形原始状态,默认显示到第二级
*/
async resetTreeSearch() {
try {
// 1. 清空左侧表单输入和查询参数
if (this.$refs.queryFormLeft) {
this.$refs.queryFormLeft.resetFields()
}
this.treeSearchKey = '' // 手动清空装备名称查询值
this.queryParams.typeId = undefined // 清空可能存在的节点ID缓存
// 2. 恢复原始树形数据,默认显示到第二级
this.treeLoading = true
const res = await getDeviceTreeAPI()
this.treeData = res.data ? [res.data] : []
// 重置默认展开的节点ID数组
this.defaultExpandedKeys = []
// 只展开第一级和第二级节点
// this.collectFirstAndSecondLevelKeys(this.treeData);
this.initDefaultExpandedKeys()
// this.$message.success('树形查询已重置');
} catch (error) {
// this.$message.error('树形重置失败:' + (error.message || '未知错误'));
console.error(error)
} finally {
this.treeLoading = false
}
},
/**
* 获取右侧列表数据
*/
async getDeviceList() {
try {
this.tableLoading = true
// 获取特征值数量
const featureResult = await getMaxFeatureAPI()
this.tableColumns = featureResult.data || 0
this.queryParams.startProductionDate = this.queryParams.productionDate ? this.queryParams.productionDate[0] : ''
this.queryParams.endProductionDate = this.queryParams.productionDate ? this.queryParams.productionDate[1] : ''
this.queryParams.startPurchaseDate = this.queryParams.purchaseDate ? this.queryParams.purchaseDate[0] : ''
this.queryParams.endPurchaseDate = this.queryParams.purchaseDate ? this.queryParams.purchaseDate[1] : ''
this.queryParams.subProcessId = (this.queryParams.process && this.queryParams.process[1]) || ''
delete this.queryParams.productionDate
delete this.queryParams.purchaseDate
// 获取设备列表
const listResult = await getDeviceListAPI(this.queryParams)
this.tableData = listResult.data?.rows || []
this.total = listResult.data?.total || 0
let maxLength = 0
this.tableData.forEach((item) => {
if (item.propertyVoList && item.propertyVoList.length > maxLength) {
maxLength = item.propertyVoList.length
}
})
maxLength = maxLength > 0 ? maxLength * 2 : 0
this.columns2 = this.columns.slice(0, this.columns.length - 18 + maxLength)
setTimeout(() => {
this.$refs.tableRef.doLayout()
}, 200)
} catch (error) {
// this.$message.error('获取设备列表失败:' + (error.message || '未知错误'))
console.error(error)
} finally {
this.tableLoading = false
}
},
/**
* 查看按钮
*/
async onHandlePreview(row) {
// this.formData = row
// this.previewDialogVisible = true
this.$router.push({ path: '/equipment/details', query: { id: row.maId } })
},
/**
* 关闭查看弹窗
*/
handlePreviewClose() {
this.previewDialogVisible = false
this.resetFormData()
},
/**
* 编辑按钮
*/
async onHandleEdit(row) {
console.log('🚀 ~ row:', row)
this.$refs.addEquipRef.openDialog(row.maId, 'edit')
},
/**
* 关闭编辑弹窗
*/
handleEditClose() {
this.editDialogVisible = false
this.resetFormData()
},
/**
* 重置表单数据
*/
resetFormData() {
this.formData = {
maId: '',
companyName: '',
mainGx: '',
childGx: '',
devCategory: '',
devSubcategory: '',
name: '',
devModel: '',
code: '',
changeStatus: '',
upDownStatus: '',
expireTime: '',
unitName: '',
propertyCompany: '',
buyPrice: '',
productionDate: '',
workingHours: '',
onProject: '',
person: '',
personPhone: '',
nextCheckTime: '',
brand: '',
propertyVoList: [],
}
},
/**
* 添加特征项
*/
addFeatureItem() {
if (!this.formData.propertyVoList) {
this.formData.propertyVoList = []
}
// 检查是否已达到最大数量限制
if (this.formData.propertyVoList.length >= this.maxFeatureCount) {
// this.$message.warning(`最多只能添加${this.maxFeatureCount}个特征项`)
return
}
this.formData.propertyVoList.push({
propertyName: '',
propertyValue: '',
})
},
/**
* 删除特征项
*/
removeFeatureItem(index) {
this.$confirm('确定要删除该特征项吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true,
showCancelButton: this.formData.propertyVoList.length > 1, // 至少保留一个特征项
})
.then(() => {
this.formData.propertyVoList.splice(index, 1)
})
.catch(() => {
// 取消删除,不做处理
})
},
/**
* 提交编辑表单
*/
async submitEditForm() {
this.$refs.editForm.validate(async (valid) => {
if (valid) {
try {
const res = await updateDeviceAPI(this.formData)
if (res.code === 200) {
this.$message.success('编辑成功')
this.handleEditClose()
this.getDeviceList()
} else {
this.$message.error(res.msg || '编辑失败')
}
} catch (error) {
this.$message.error('编辑操作失败:' + (error.message || '未知错误'))
console.error(error)
}
}
})
},
/**
* 删除按钮
*/
onHandleDelete(row) {
this.$confirm('确定要删除该装备吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(async () => {
try {
const res = await delDevice(row.maId)
if (res.code === 200) {
this.$message.success('删除成功')
this.getDeviceList()
}
} catch (error) {
this.$message.error('删除失败:' + (error.message || '未知错误'))
}
})
},
/**
* 装备上架按钮
*/
async onHandleDeviceUp() {
if (this.selectedRows.length === 0) {
this.$message.warning('请选择要上架的装备')
return
}
try {
const res = await updateDeviceUpDownAPI({
devIds: this.selectedRows.map((item) => item.maId).join(','),
status: 1,
})
this.selectedRows = []
if (res.code === 200) {
this.$message.success('装备上架成功')
this.getDeviceList()
} else {
this.$message.error(res.msg || '上架失败')
}
} catch (error) {
this.$message.error('上架操作失败:' + (error.message || '未知错误'))
console.error(error)
}
},
/**
* 装备下架按钮
*/
async onHandleDeviceDown() {
if (this.selectedRows.length === 0) {
this.$message.warning('请选择要下架的装备')
return
}
try {
const res = await updateDeviceUpDownAPI({
devIds: this.selectedRows.map((item) => item.maId).join(','),
status: 0,
})
this.selectedRows = []
if (res.code === 200) {
this.$message.success('装备下架成功')
this.getDeviceList()
} else {
this.$message.error(res.msg || '下架失败')
}
} catch (error) {
this.$message.error('下架操作失败:' + (error.message || '未知错误'))
console.error(error)
}
},
/**
* 多选框选中数据
*/
handleSelectionChange(selection) {
this.selectedRows = selection
},
/**
* 装备状态数量统计
*/
async getDeviceStatusCount() {
try {
const res = await getDeviceStatusCountAPI()
const { inStock, ownUse, share, underRepair } = res.data || {}
this.inStock = inStock || 0
this.ownUse = ownUse || 0
this.share = share || 0
this.underRepair = underRepair || 0
} catch (error) {
this.$message.error('获取状态统计失败:' + (error.message || '未知错误'))
console.error(error)
}
},
getFeatureValue(row, prop) {
const match = prop.match(/feature(Item|Value)(\d+)/)
if (!match) return '-'
const type = match[1] // 'Item' or 'Value'
const index = Number(match[2]) - 1
const list = row.propertyVoList || []
if (!list[index]) return '-'
return type === 'Item' ? list[index].propertyName : list[index].propertyValue
},
// 查看
handleView(row, type) {
if (type == 1) {
this.dialogTitle = '装备外观'
this.dialogList = row.appearanceImages || []
} else if (type == 2) {
this.dialogTitle = '合格证'
this.dialogList = row.certificates || []
} else if (type == 3) {
this.dialogTitle = '定期检验报告'
this.dialogList = row.inspectionReports || []
} else if (type == 4) {
this.dialogTitle = '采购发票'
this.dialogList = row.purchaseInvoices || []
}
this.dialogVisible = true
},
handleFile(row) {
// 打开文件预览
window.open(row.fileUrl, '_blank')
},
handleFileListUpload(row) {
this.currentRow = row
this.openReport = true
},
},
async created() {
await this.getDeptTreeSelect()
const params = this.$route.query
this.queryParams.propertyUnitId = params?.deptId || ''
if (params && params.parentId) {
this.queryParams.propertyUnitIds.push(Number(params.parentId))
if (params.deptId) {
this.queryParams.propertyUnitIds.push(Number(params.deptId))
}
} else if (params && params.deptId) {
this.queryParams.propertyUnitIds.push(Number(params.deptId))
}
this.getProvinceList()
this.getFirstLevel()
this.getManufacturerSelectList()
// 并行加载初始数据
await Promise.all([this.getDeviceTree(), this.getDeviceStatusCount()])
// 最后加载列表数据
await this.getDeviceList()
this.initDefaultExpandedKeys()
},
}
</script>
<style scoped lang="scss">
.app-container {
padding: 12px;
background-color: #f5f7fa;
height: calc(100vh - 84px);
}
/* 搜索区域收起/展开按钮 */
.search-toggle-btn {
color: #409eff;
padding: 5px 10px;
}
/* 固定操作栏样式 */
.sticky-bar {
position: sticky;
top: 0;
z-index: 10;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 字段设置弹窗样式 */
.field-setting-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
max-height: 400px;
overflow-y: auto;
padding-right: 10px;
}
.field-setting-group .el-checkbox {
width: calc(50% - 10px);
margin-bottom: 10px;
}
/* 原有样式保持不变 */
.page-header {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e4e7ed;
}
.page-title {
font-size: 20px;
color: #1f2d3d;
margin-bottom: 5px;
font-weight: 500;
}
.page-desc {
font-size: 14px;
color: #8392a5;
}
.card-container {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.card-container-btn {
/* 使用 clip-path 创建三角形形状 */
clip-path: polygon(0 0, 100% 50%, 0 100%);
width: 40px;
height: 70px;
background-color: red;
position: relative;
cursor: pointer;
transition: all 0.3s ease;
}
.card-header {
padding: 14px;
border-bottom: 1px solid #e4e7ed;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-title {
font-size: 15px;
color: #1f2d3d;
font-weight: 500;
}
.table-count {
font-size: 12px;
color: #8392a5;
}
.tree-container {
height: calc(100vh - 174px);
overflow: auto;
padding: 15px;
}
.tree-container::-webkit-scrollbar {
display: none;
}
.query-buttons {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10px;
}
.query-btn {
background-color: #409eff;
border-color: #409eff;
}
.reset-btn {
background-color: #f5f7fa;
color: #606266;
border-color: #dcdfe6;
}
.export-btn {
background-color: #67c23a;
border-color: #67c23a;
}
.status-operation-bar {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
padding: 15px 20px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.status-stats {
display: flex;
gap: 25px;
}
.stat-item {
display: flex;
align-items: center;
}
.stat-label {
color: #606266;
margin-right: 5px;
font-size: 14px;
}
.stat-value {
font-size: 16px;
font-weight: 500;
color: #1f2d3d;
}
.operation-buttons {
width: 100%;
}
.operation-btn {
display: inline-flex;
align-items: center;
gap: 4px;
}
.pagination-container {
padding: 15px 20px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.opt-btn {
padding: 5px 8px;
margin: 0 2px;
}
.view-btn {
color: #00a288;
}
.edit-btn {
color: #00a288;
}
.delete-btn {
color: #00a288;
}
/* 弹窗表单样式 */
.detail-form {
max-height: 60vh;
overflow-y: auto;
padding-right: 10px;
}
/* 滚动条美化 */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
/* 特征值输入框和删除按钮容器 */
.feature-value-container {
display: flex;
align-items: center;
gap: 8px;
}
.delete-feature-btn {
padding: 0;
height: 100%;
display: flex;
align-items: center;
}
/* 调整删除按钮位置 */
::v-deep .el-form-item__content {
display: flex;
align-items: center;
}
.col-center {
display: flex;
align-items: center; /* 垂直居中 */
/* 如果需要整列高度充满父容器可添加height: 100%; */
}
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 90px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 50%;
}
.card-container {
position: relative; /* 新增为按钮绝对定位提供参考 */
}
.collapse-btn {
/* 修改将按钮定位在右侧中间 */
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
background: white;
color: #606266;
padding: 2px;
z-index: 10; /* 确保按钮在最上层 */
}
/* 优化按钮悬停效果 */
.collapse-btn:hover {
background: white;
color: #409eff;
}
/* 折叠状态的样式和过渡动画 */
.tree-column {
transition: all 0.3s ease;
display: flex;
flex-direction: row;
}
::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;
}
}
.el-col-1 {
width: 1.5% !important;
}
</style>