上下架管理

This commit is contained in:
itcast 2025-11-16 18:06:27 +08:00
parent 99adbf483d
commit a1ad613736
4 changed files with 2054 additions and 0 deletions

View File

@ -0,0 +1,45 @@
import request from '@/utils/request'
// 查询装备上架列表
export function listEquipment(query) {
return request({
url: '/material-mall/upOrDown/equipment/list',
method: 'get',
params: query
})
}
// 查询下架装备列表(用于上架操作)
export function listDownEquipment(query) {
return request({
url: '/material-mall/upOrDown/equipment/downEquipmentList',
method: 'get',
params: query
})
}
// 装备下架
export function downEquipment(equipmentId) {
return request({
url: `/material-mall/upOrDown/equipment/down/${equipmentId}`,
method: 'post'
})
}
// 批量上架装备
export function batchUpEquipment(ids) {
return request({
url: '/material-mall/upOrDown/equipment/batch/up',
method: 'post',
data: ids
})
}
// 批量下架装备
export function batchDownEquipment(ids) {
return request({
url: '/material-mall/upOrDown/equipment/batch/down',
method: 'post',
data: ids
})
}

View File

@ -0,0 +1,72 @@
import request from '@/utils/request'
// 查询工具上架列表
export function listTool(query) {
return request({
url: '/material-mall/upOrDown/tool/list',
method: 'get',
params: query
})
}
// 查询数量工具列表
export function listNumberTool(query) {
return request({
url: '/material-mall/upOrDown/tool/numberToolList',
method: 'get',
params: query
})
}
// 上架数量工具
export function upToolByNumber(data) {
return request({
url: '/material-mall/upOrDown/tool/upByNumber',
method: 'post',
data: data
})
}
// 查询编码工具列表
export function listCodeTool(query) {
return request({
url: '/material-mall/upOrDown/tool/codeToolList',
method: 'get',
params: query
})
}
// 上架编码工具
export function upToolByCode(data) {
return request({
url: '/material-mall/upOrDown/tool/upByCode',
method: 'post',
data: data
})
}
// 下架工具
export function downTool(toolId) {
return request({
url: '/material-mall/upOrDown/tool/down/' + toolId,
method: 'post'
})
}
// 批量上架工具
export function batchUpTool(ids) {
return request({
url: '/material-mall/upOrDown/tool/batch/up',
method: 'post',
data: ids
})
}
// 批量下架工具
export function batchDownTool(ids) {
return request({
url: '/material-mall/upOrDown/tool/batch/down',
method: 'post',
data: ids
})
}

View File

@ -0,0 +1,830 @@
<template>
<div class="app-container">
<!-- 搜索表单 -->
<!-- 搜索表单 -->
<el-form
:inline="true"
label-width="80px"
label-position="right"
size="small"
ref="searchFormRef"
:model="searchParams"
>
<el-card class="search-box">
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 10px;">
<!-- 其他表单项保持不变 -->
<el-form-item prop="major" label="专业" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入"
v-model="searchParams.major"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<el-form-item prop="subProcess" label="工序" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入"
v-model="searchParams.subProcess"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<el-form-item prop="name" label="装备名称" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入"
v-model="searchParams.name"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<el-form-item prop="specificationModel" label="规格型号" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入"
v-model="searchParams.specificationModel"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<!-- 替换后的装备状态下拉框 -->
<el-form-item prop="status" label="装备状态" style="margin-bottom: 0; width: 320px">
<el-select
clearable
placeholder="请选择"
v-model="searchParams.status"
style="width: 100%; min-width: 200px;"
>
<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-form-item prop="code" label="装备编码" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入"
v-model="searchParams.code"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<!-- 按钮区域保持不变 -->
<div style="display: flex; gap: 10px; margin-left: auto;">
<el-button @click="getEquipmentList" size="mini" icon="el-icon-search" type="primary"
class="primary-lease">
查询
</el-button>
<el-button @click="onReset" icon="el-icon-refresh" size="mini" class="primary-lease">重置</el-button>
</div>
</div>
<el-row></el-row>
</el-card>
</el-form>
<!-- 数据列表 -->
<el-card class="content-box">
<el-row style="margin-bottom: 16px; display: flex; justify-content: flex-end; align-items: center; gap: 10px;">
<el-button
size="mini"
type="danger"
class="primary-lease"
@click="handleBatchDown"
:disabled="selectedRows.length === 0"
>
批量下架
</el-button>
<el-button
size="mini"
@click="equipment"
type="primary"
class="primary-lease"
>
添加上架装备
</el-button>
</el-row>
<div class="table-container">
<el-table
:data="equipmentList"
show-overflow-tooltip
border stripe height="100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column align="center" label="序号" type="index" width="80"/>
<el-table-column align="center" prop="province" label="所属省份"/>
<el-table-column align="center" prop="propertyUnit" label="产权单位"/>
<el-table-column align="center" prop="major" label="专业"/>
<el-table-column align="center" prop="subProcess" label="工序"/>
<el-table-column align="center" prop="subCategory" label="装备类目"/>
<el-table-column align="center" prop="name" label="装备名称"/>
<el-table-column align="center" prop="specificationModel" label="规格型号"/>
<el-table-column align="center" prop="code" label="装备编码"/>
<!-- 装备状态标签 -->
<el-table-column align="center" prop="status" label="装备状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.status == 1" type="success" size="mini">在库</el-tag>
<el-tag v-if="scope.row.status == 2" size="mini">自用</el-tag>
<el-tag v-if="scope.row.status == 3" size="mini">共享</el-tag>
<el-tag v-if="scope.row.status == 4" size="mini" type="danger">退役</el-tag>
<el-tag v-if="scope.row.status == 5" size="mini" type="warning" >维修</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="serviceLife" label="使用年限"/>
<el-table-column align="center" prop="usingProject" label="使用项目"/>
<el-table-column align="center" prop="expirationTime" label="使用到期时间"/>
<el-table-column align="center" prop="originalCode" label="装备原始编码"/>
<el-table-column align="center" prop="unit" label="计量单位"/>
<el-table-column align="center" prop="manufacturer" label="生产厂家"/>
<el-table-column align="center" prop="productionDate" label="出厂日期"/>
<el-table-column align="center" prop="purchaseDate" label="采购日期"/>
<el-table-column align="center" prop="originalValue" label="资产原值(元)"/>
<el-table-column align="center" prop="maxServiceLifeYears" label="最大使用年限(年)"/>
<el-table-column align="center" prop="nextMaintenanceDate" label="下次维保日期"/>
<el-table-column align="center" prop="appearanceImages" label="装备外观"/>
<el-table-column align="center" prop="certificates" label="合格证"/>
<el-table-column align="center" prop="inspectionReports" label="定期检验报告"/>
<el-table-column align="center" prop="purchaseInvoices" label="采购发票"/>
<el-table-column align="center" prop="feature1" label="特征项1"/>
<el-table-column align="center" prop="featureValue1" label="特征值1"/>
<el-table-column align="center" label="操作" :width="220">
<template slot-scope="scope">
<el-popconfirm
width="220"
icon="el-icon-info"
icon-color="#626AEF"
title="确定下架该装备吗?"
@confirm="handleDown(scope.row.maId)"
>
<template slot="reference">
<el-button size="small" type="danger" class="primary-lease" style="margin-left: 8px;">
下架
</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<div class="pagination-wrapper">
<el-pagination
background
layout="total,sizes,prev, pager, next"
:total="total"
:page-size="searchParams.pageSize"
:current-page="searchParams.pageNum"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 添加上架装备 -->
<el-dialog
width="1600px"
@close="handleDialogClose"
destroy-on-close
:title="dialogTitle"
:visible.sync="equipmentDialogVisible"
custom-class="simple-dialog"
>
<!-- 新增的搜索区域 -->
<el-form :inline="true" :model="searchParams" style="width: 100%; margin-bottom: 16px;">
<el-row style="display: flex; align-items: center; gap: 10px;">
<el-form-item label="装备名称" prop="name">
<el-input
v-model="searchParams.name"
placeholder="请输入"
clearable
style="width: 200px;"
/>
</el-form-item>
<el-form-item label="规格型号" prop="specificationModel">
<el-input
v-model="searchParams.specificationModel"
placeholder="输入内容"
clearable
style="width: 200px;"
/>
</el-form-item>
<el-form-item label="装备编码" prop="code">
<el-input
v-model="searchParams.code"
placeholder="输入内容"
clearable
style="width: 200px;"
/>
</el-form-item>
<el-button type="primary" @click="getListDownEquipment">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</el-row>
</el-form>
<!-- 表格区域 -->
<div class="table-container">
<div style="margin-bottom: 10px;">
<el-button
size="mini"
type="danger"
class="primary-lease"
@click="handleBatchUp"
:disabled="selectedRows.length === 0"
>
批量上架
</el-button>
</div>
<el-table
:data="downEquipmentList"
show-overflow-tooltip
border stripe height="100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column align="center" label="序号" type="index" width="80"/>
<el-table-column align="center" label="装备名称" prop="name"/>
<el-table-column align="center" label="规格型号" prop="specificationModel"/>
<el-table-column align="center" label="装备编码" prop="code"/>
<el-table-column align="center" label="计量单位" prop="unit"/>
<el-table-column align="center" label="生产厂家" prop="manufacturer"/>
<el-table-column align="center" label="出厂日期" prop="productionDate"/>
<el-table-column align="center" label="资产原值" prop="originalValue"/>
<!-- 装备状态标签 -->
<el-table-column align="center" prop="status" label="装备状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.status == 1" type="success" size="mini">在库</el-tag>
<el-tag v-if="scope.row.status == 2" size="mini">自用</el-tag>
<el-tag v-if="scope.row.status == 3" size="mini">共享</el-tag>
<el-tag v-if="scope.row.status == 4" size="mini" type="danger">退役</el-tag>
<el-tag v-if="scope.row.status == 5" size="mini" type="warning" >维修</el-tag>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<div class="pagination-wrapper">
<el-pagination
background
layout="total, prev, pager, next, jumper, ->, sizes"
:total="downTotal"
:page-size="searchParams.pageSize"
:current-page="searchParams.pageNum"
:page-sizes="[10, 20, 30, 50]"
@size-change="handleDownSizeChange"
@current-change="handleDownCurrentChange"
/>
</div>
</el-dialog>
</div>
</template>
<script>
import {
batchDownEquipment,
listDownEquipment,
listEquipment,
downEquipment,
batchUpEquipment
} from '@/api/EquipmentUpOrDown/equipment'
import {Message} from 'element-ui'
export default {
name: 'ProjectManagement',
data() {
return {
total: 0, //
downTotal: 0, //
equipmentList: [], //
downEquipmentList: [], //
selectedRows: [], //
dialogTitle: '添加装备',
equipmentDialogVisible: false,
submitLoading: false,
isAdd: true,
isView: false,
dialogSearchParams: {
toolCategory: ''
},
//
searchParams: {
major: '',
process: '',
name: '',
subProcess: '',
specificationModel: '',
status: '',
code: '',
pageSize: 10,
pageNum: 1
},
projectTypeList: []
}
},
mounted() {
this.getEquipmentList()
},
methods: {
//
async getEquipmentList() {
try {
const res = await listEquipment(this.searchParams)
if (res.code === 200) {
this.equipmentList = res.rows || []
this.total = res.total || 0
} else {
Message.error(res.message || '获取上架装备列表失败')
}
} catch (error) {
Message.error('网络错误,获取上架装备列表失败')
}
},
//
async getListDownEquipment() {
try {
const res = await listDownEquipment(this.searchParams)
if (res.code === 200) {
this.downEquipmentList = res.rows || []
this.downTotal = res.total || 0
} else {
Message.error(res.message || '获取待上架装备列表失败')
}
} catch (error) {
Message.error('网络错误,获取待上架装备列表失败')
}
},
//
onReset() {
this.searchParams = {
major: '',
process: '',
name: '',
specificationModel: '',
status: '',
code: '',
pageSize: this.searchParams.pageSize,
pageNum: 1
}
this.$refs.searchFormRef?.clearValidate()
this.getEquipmentList()
},
//
handleReset() {
this.searchParams = {
major: '',
process: '',
name: '',
specificationModel: '',
status: '',
code: '',
pageSize: 10,
pageNum: 1
}
this.$refs.searchFormRef?.clearValidate()
this.getListDownEquipment()
},
//
handleSelectionChange(selection) {
this.selectedRows = selection
},
//
equipment() {
this.isAdd = true
this.isView = false
this.dialogTitle = '添加上架装备'
this.$refs.addOrEditFormRef?.clearValidate()
this.equipmentDialogVisible = true
this.getListDownEquipment()
},
// 使maId
async handleDown(maId) {
try {
const res = await downEquipment(maId)
if (res.code === 200) {
Message.success('装备下架成功')
this.getEquipmentList()
} else {
Message.error(res.message || '装备下架失败')
}
} catch (error) {
Message.error('网络错误,装备下架失败')
}
},
//
async handleBatchDown() {
if (this.selectedRows.length === 0) {
Message.warning('请选择要下架的装备')
return
}
try {
await this.$confirm(
`确定下架选中的 ${this.selectedRows.length} 个装备吗?`,
'提示',
{
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消'
}
)
const ids = this.selectedRows.map(row => row.maId)
const res = await batchDownEquipment(ids)
if (res.code === 200) {
Message.success(`成功下架 ${this.selectedRows.length} 个装备`)
this.getEquipmentList()
this.selectedRows = []
} else {
Message.error(res.message || '批量下架失败')
}
} catch (error) {
if (error !== 'cancel') {
Message.error('网络错误,批量下架失败')
}
}
},
//
async handleBatchUp() {
if (this.selectedRows.length === 0) {
Message.warning('请选择要上架的装备')
return
}
try {
await this.$confirm(
`确定上架选中的 ${this.selectedRows.length} 个装备吗?`,
'提示',
{
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消'
}
)
const ids = this.selectedRows.map(row => row.maId)
const res = await batchUpEquipment(ids)
if (res.code === 200) {
Message.success(`成功上架 ${this.selectedRows.length} 个装备`)
this.getListDownEquipment()
this.getEquipmentList()
this.selectedRows = []
} else {
Message.error(res.message || '批量上架失败')
}
} catch (error) {
if (error !== 'cancel') {
Message.error('网络错误,批量上架失败')
}
}
},
//
handleDialogClose() {
this.isView = false
this.$refs.addOrEditFormRef?.clearValidate()
this.selectedRows = [] //
},
//
handleSizeChange(val) {
this.searchParams.pageSize = val
this.getEquipmentList()
},
//
handleCurrentChange(val) {
this.searchParams.pageNum = val
this.getEquipmentList()
},
//
handleDownSizeChange(val) {
this.searchParams.pageSize = val
this.getListDownEquipment()
},
//
handleDownCurrentChange(val) {
this.searchParams.pageNum = val
this.getListDownEquipment()
}
}
}
</script>
<style lang="scss" scoped>
/* 样式部分保持不变 */
::v-deep .upload-tip .el-form-item__label {
color: transparent;
}
.el-pagination {
justify-content: flex-end;
padding: 5px 0;
}
::v-deep .el-pagination.is-background .el-pager li.is-active {
background-color: #3cb4a6;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 6px;
width: 95%;
}
.img-list {
display: flex;
align-items: center;
.img-items {
width: 100px;
height: 100px;
margin-right: 8px;
position: relative;
img {
width: 100%;
height: 100%;
}
.mask-img {
visibility: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
.delete-icon {
font-size: 20px;
cursor: pointer;
z-index: 9;
color: #fff;
}
}
}
.img-items:hover .mask-img {
visibility: visible;
}
}
.app-container-content {
::v-deep .el-dialog {
display: flex !important;
flex-direction: column !important;
margin: 0 !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
max-height: 100vh !important;
.el-dialog__body {
flex: 1;
overflow-y: scroll !important;
padding: 20px 40px;
}
.dialog-content {
padding: 20px;
}
}
}
.search-box {
margin-bottom: 20px;
border-radius: 8px;
padding: 0;
::v-deep .el-card__body {
padding: 20px !important;
}
}
.el-form-item--small.el-form-item {
margin-bottom: 0px;
}
.content-box {
border-radius: 8px;
height: calc(100vh - 210px);
display: flex;
flex-direction: column;
overflow: hidden;
::v-deep .el-card__body {
display: flex !important;
flex-direction: column !important;
height: 100% !important;
padding: 20px;
}
.el-row:first-child {
margin-bottom: 16px;
flex-shrink: 0;
.el-col {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 12px;
}
}
.table-container {
flex: 1;
overflow: hidden;
margin-bottom: 0;
min-height: 0;
display: flex;
flex-direction: column;
}
.pagination-wrapper {
flex-shrink: 0;
padding-top: 6px;
margin-top: auto;
text-align: right;
::v-deep .pagination-container {
padding: 0px 20px !important;
margin-bottom: 30px;
}
}
::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;
}
}
}
.dialog-table {
border-radius: 6px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
::v-deep .el-table {
border-radius: 6px;
overflow: hidden;
&.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: 45px;
font-size: 14px;
border-bottom: 2px solid #e4e7ed;
}
}
.el-table__body {
tr {
transition: all 0.2s ease;
&:hover {
background-color: #f8f9fa;
}
td {
padding: 12px 8px;
font-size: 13px;
border-bottom: 1px solid #f0f2f5;
}
}
}
&.el-table--striped .el-table__body tr.el-table__row:hover > td.el-table__cell {
background-color: #CCF1E9 !important;
}
&::before {
display: none;
}
&::after {
display: none;
}
}
}
.simple-dialog {
.el-dialog__header {
padding: 15px 20px;
border-bottom: 1px solid #eee;
.el-dialog__title {
font-size: 16px;
font-weight: 600;
}
}
.el-dialog__body {
padding: 20px;
}
.el-dialog__footer {
padding: 10px 20px;
border-top: 1px solid #eee;
text-align: right;
}
}
.simple-form {
.el-form-item {
margin-bottom: 15px;
.el-form-item__label {
color: #333;
padding-right: 10px;
&::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
&.no-required::before {
content: '';
margin-right: 0;
}
}
}
.el-input, .el-select, .el-date-picker {
width: 100%;
}
.el-textarea {
width: 100%;
&:focus {
border-color: #1890ff;
}
}
}
.dialog-footer {
.cancel-btn {
margin-right: 10px;
}
.confirm-btn {
background-color: #1890ff;
border-color: #1890ff;
}
}
</style>

File diff suppressed because it is too large Load Diff