1
This commit is contained in:
3
.env.dev
3
.env.dev
@@ -13,8 +13,9 @@ VUE_APP_TITLE = 智能监控分析系统
|
||||
|
||||
# 芋道管理系统/开发环境
|
||||
# VUE_APP_BASE_API = 'http://192.168.8.22:48080'
|
||||
# VUE_APP_BASE_API = 'http://172.16.33.65:48082'
|
||||
# VUE_APP_BASE_API = 'http://172.16.32.236:48080'
|
||||
VUE_APP_BASE_API = 'http://192.168.0.31:48080'
|
||||
# VUE_APP_BASE_API = 'http://100.64.0.32:48080'
|
||||
|
||||
# 路由懒加载
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
||||
72
src/api/areavisual/overview.js
Normal file
72
src/api/areavisual/overview.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取区域列表
|
||||
export function getAreaList(params) {
|
||||
return request({
|
||||
url: '/wms/region/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取区域空满数量
|
||||
export function postAllAreaInfo(data) {
|
||||
return request({
|
||||
url: '/wms/region/lsit/count',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取指定库区库位信息
|
||||
export function postAreaInfo(data) {
|
||||
return request({
|
||||
url: '/wms/line-edge-library/list/region',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取区域总览
|
||||
export function postAllAreaOverview(data) {
|
||||
return request({
|
||||
url: '/wms/line-edge-library/line/count',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除能源实时数据库plc相关
|
||||
export function deleteEnergyPlc(id) {
|
||||
return request({
|
||||
url: '/base/energy-plc/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取关联表编码
|
||||
export function getCode() {
|
||||
return request({
|
||||
url: '/base/energy-plc/getCode',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得能源实时数据库plc相关分页
|
||||
export function getEnergyPlcPage(data) {
|
||||
return request({
|
||||
url: '/base/energy-plc/page',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 导出能源实时数据库plc相关 Excel
|
||||
export function exportEnergyPlcExcel(query) {
|
||||
return request({
|
||||
url: '/base/energy-plc/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
63
src/api/areavisual/record.js
Normal file
63
src/api/areavisual/record.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取出入库历史任务分页
|
||||
export function getRecordPage(params) {
|
||||
return request({
|
||||
url: '/wms/job-main-task-history/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取巷道列表
|
||||
export function getLaneList(params) {
|
||||
return request({
|
||||
url: '/wms/lane/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 更新能源实时数据库plc相关
|
||||
export function updateEnergyPlc(data) {
|
||||
return request({
|
||||
url: '/base/energy-plc/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除能源实时数据库plc相关
|
||||
export function deleteEnergyPlc(id) {
|
||||
return request({
|
||||
url: '/base/energy-plc/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取关联表编码
|
||||
export function getCode() {
|
||||
return request({
|
||||
url: '/base/energy-plc/getCode',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得能源实时数据库plc相关分页
|
||||
export function getEnergyPlcPage(data) {
|
||||
return request({
|
||||
url: '/base/energy-plc/page',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 导出能源实时数据库plc相关 Excel
|
||||
export function exportEnergyPlcExcel(query) {
|
||||
return request({
|
||||
url: '/base/energy-plc/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
125
src/views/areavisual/overview/components/ringChart.vue
Normal file
125
src/views/areavisual/overview/components/ringChart.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div
|
||||
:class="className"
|
||||
:style="{ height: height, width: width, marginLeft: '10px' }" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
require('echarts/theme/macarons'); // echarts theme
|
||||
import resize from '@/utils/chartMixins/resize';
|
||||
|
||||
const animationDuration = 1000;
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '300px',
|
||||
},
|
||||
ringData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
targetId: '',
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$el, 'macarons');
|
||||
const _this = this;
|
||||
this.chart.setOption({
|
||||
title: {
|
||||
text: this.title
|
||||
? '{space|}{tip|}{space|}{value|' + this.title + '}'
|
||||
: '',
|
||||
textStyle: {
|
||||
rich: {
|
||||
tip: {
|
||||
width: 6,
|
||||
height: 6,
|
||||
borderRadius: 50,
|
||||
backgroundColor: '#288AFF',
|
||||
},
|
||||
space: {
|
||||
width: 8,
|
||||
},
|
||||
value: {
|
||||
fontSize: 14,
|
||||
color: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
color: ['#33B36B', '#3A8DFF', '#F59A23'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
crossStyle: {
|
||||
color: '#999',
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['当前满位', '当前空位', '在途'],
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
// name: '投入',
|
||||
type: 'pie',
|
||||
radius: '50%',
|
||||
data: [
|
||||
{
|
||||
name: '当前满位',
|
||||
value: this.ringData.occupiedQuantity
|
||||
},
|
||||
{
|
||||
name: '当前空位',
|
||||
value: this.ringData.idleQuantity
|
||||
},
|
||||
{
|
||||
name: '在途',
|
||||
value: this.ringData.transitQuantity
|
||||
},
|
||||
],
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
262
src/views/areavisual/overview/index.vue
Normal file
262
src/views/areavisual/overview/index.vue
Normal file
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row class="overview-container">
|
||||
<el-col :span="4" class="overview-container-left">
|
||||
<el-row style="font-size: 18px; font-weight: bold; line-height: 36px">库区选择</el-row>
|
||||
<el-input
|
||||
v-model="areaSearchForm.regionName"
|
||||
placeholder="库区名称"
|
||||
@blur="getArea"
|
||||
clearable
|
||||
/>
|
||||
<el-tree
|
||||
:data="areaList"
|
||||
:node-key="'id'"
|
||||
:props="{label: 'regionName'}"
|
||||
@node-click="nodeClick"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="16" v-if="changeType === 0" class="overview-container-main">
|
||||
<el-row>
|
||||
<el-col :span="8" class="allarea-box" v-for="item in allAreaList" :key="item.id">
|
||||
<div class="areainfo-box">
|
||||
<div class="areainfo-box-header">
|
||||
{{ item.regionName }}
|
||||
</div>
|
||||
<div class="areainfo-box-line">
|
||||
<div class="areainfo-box-line-item" :style="{width: `${(item.occupiedQuantity / (item.totalInventory + item.transitQuantity) * 100).toFixed(2)}%`, backgroundColor: '#33B36B'}"></div>
|
||||
<div class="areainfo-box-line-item" :style="{width: `${(item.idleQuantity / (item.totalInventory + item.transitQuantity) * 100).toFixed(2)}%`, backgroundColor: '#3A8DFF'}"></div>
|
||||
<div class="areainfo-box-line-item" :style="{width: `${(item.transitQuantity / (item.totalInventory + item.transitQuantity) * 100).toFixed(2)}%`, backgroundColor: '#F59A23'}"></div>
|
||||
</div>
|
||||
<el-row class="areainfo-box-info">
|
||||
<el-col class="areainfo-box-info-item" :span="6">
|
||||
<p class="areainfo-box-info-item-count">{{item.totalInventory}}</p>
|
||||
<p class="areainfo-box-info-item-title">库位总数</p>
|
||||
</el-col>
|
||||
<el-col class="areainfo-box-info-item" :span="6">
|
||||
<p class="areainfo-box-info-item-count" style="color: #33B36B">{{item.occupiedQuantity}}</p>
|
||||
<p class="areainfo-box-info-item-title">占</p>
|
||||
</el-col>
|
||||
<el-col class="areainfo-box-info-item" :span="6">
|
||||
<p class="areainfo-box-info-item-count" style="color: #3A8DFF">{{item.idleQuantity}}</p>
|
||||
<p class="areainfo-box-info-item-title">空</p>
|
||||
</el-col>
|
||||
<el-col class="areainfo-box-info-item" :span="6">
|
||||
<p class="areainfo-box-info-item-count" style="color: #F59A23">{{item.transitQuantity}}</p>
|
||||
<p class="areainfo-box-info-item-title">在途</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="4" v-if="changeType === 0" class="overview-container-right">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClickRight">
|
||||
<el-tab-pane label="概览" name="first">
|
||||
<el-row class="overview-container-right-alloverview">
|
||||
<el-col class="overview-container-right-alloverview-item" :span="8">
|
||||
<p class="overview-container-right-alloverview-item-count">{{allAreaInfo.totalInventory}}</p>
|
||||
<p class="overview-container-right-alloverview-item-title">库位总数</p>
|
||||
</el-col>
|
||||
<el-col class="overview-container-right-alloverview-item" :span="8">
|
||||
<p class="overview-container-right-alloverview-item-count">{{allAreaInfo.occupiedQuantity}}</p>
|
||||
<p class="overview-container-right-alloverview-item-title">当前满位</p>
|
||||
</el-col>
|
||||
<el-col class="overview-container-right-alloverview-item" :span="8">
|
||||
<p class="overview-container-right-alloverview-item-count">{{allAreaInfo.idleQuantity}}</p>
|
||||
<p class="overview-container-right-alloverview-item-title">当前空位</p>
|
||||
</el-col>
|
||||
<el-col class="overview-container-right-alloverview-item" :span="8">
|
||||
<p class="overview-container-right-alloverview-item-count">{{allAreaInfo.transitQuantity}}</p>
|
||||
<p class="overview-container-right-alloverview-item-title">在途</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ringChart :ring-data="allAreaInfo" ref="ringChart" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="在途任务" name="second">在途任务</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
<el-col :span="20" v-if="changeType === 1" class="overview-container-main"></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import basicPage from '@/mixins/basic-page';
|
||||
import ringChart from './components/ringChart.vue';
|
||||
import { getAreaList, postAllAreaInfo, postAllAreaOverview, postAreaInfo } from '@/api/areavisual/overview';
|
||||
|
||||
export default {
|
||||
name: 'overview',
|
||||
// mixins: [basicPage],
|
||||
data() {
|
||||
return {
|
||||
areaList: [
|
||||
{
|
||||
id: 0,
|
||||
regionName: "全部库区"
|
||||
}
|
||||
],
|
||||
areaSearchForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 100,
|
||||
regionName: ''
|
||||
},
|
||||
changeType: 0,
|
||||
allAreaList: [],
|
||||
allAreaInfo: {
|
||||
totalInventory: 0,
|
||||
occupiedQuantity: 0,
|
||||
idleQuantity: 0,
|
||||
transitQuantity: 0
|
||||
},
|
||||
areaInfo: [],
|
||||
activeName: 'first'
|
||||
};
|
||||
},
|
||||
components: {
|
||||
ringChart
|
||||
},
|
||||
async created() {
|
||||
this.getArea()
|
||||
this.getAllAreaInfo()
|
||||
this.getAllAreaOverview()
|
||||
},
|
||||
watch: {
|
||||
activeName: (val) => {
|
||||
if (val === 'first') {
|
||||
this.getAllAreaOverview()
|
||||
} else if (val === 'second') {
|
||||
this.getNowTaskList()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取库区列表
|
||||
async getArea() {
|
||||
const res = await getAreaList(this.areaSearchForm)
|
||||
if (res.code === 0 && res.data) {
|
||||
this.areaList = [
|
||||
{
|
||||
id: 0,
|
||||
regionName: "全部库区"
|
||||
}
|
||||
],
|
||||
this.areaList.push(...(res.data.list))
|
||||
}
|
||||
},
|
||||
// 库区选择
|
||||
nodeClick(data, node, components) {
|
||||
if (data.id === 0) {
|
||||
this.changeType = 0
|
||||
this.activeName = 'first'
|
||||
this.getAllAreaInfo()
|
||||
} else {
|
||||
this.changeType = 1
|
||||
this.getAreaInfo(data.id)
|
||||
}
|
||||
},
|
||||
// 获取全部库区概览信息
|
||||
async getAllAreaInfo() {
|
||||
const res = await postAllAreaInfo([])
|
||||
console.log(res)
|
||||
if (res.code === 0 && res.data) {
|
||||
this.allAreaList = res.data
|
||||
}
|
||||
},
|
||||
// 获取库区概览
|
||||
async getAllAreaOverview() {
|
||||
const res = await postAllAreaOverview([])
|
||||
console.log(res)
|
||||
if (res.code === 0 && res.data) {
|
||||
this.allAreaInfo = res.data
|
||||
this.$refs.ringChart.initChart();
|
||||
}
|
||||
},
|
||||
// 获取在途任务
|
||||
async getNowTaskList() {},
|
||||
// 获取单库区信息
|
||||
async getAreaInfo (id) {
|
||||
const res = await postAreaInfo({id})
|
||||
console.log(res)
|
||||
if (res.code === 0 && res.data) {
|
||||
this.areaInfo = res.data
|
||||
}
|
||||
},
|
||||
// 全部库区右侧分页点击
|
||||
handleClickRight (tab, event) {
|
||||
console.log(tab, event)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.overview-container {
|
||||
max-height: calc(100vh - 120px - 8px);
|
||||
overflow: scroll;
|
||||
.overview-container-left {
|
||||
padding-right: 12px;
|
||||
}
|
||||
.overview-container-main {
|
||||
.allarea-box {
|
||||
padding: 10px;
|
||||
.areainfo-box {
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
.areainfo-box-header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap; /* 禁止换行 */
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 溢出部分显示省略号 */
|
||||
}
|
||||
.areainfo-box-line {
|
||||
width: 100%;
|
||||
.areainfo-box-line-item {
|
||||
height: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.areainfo-box-info {
|
||||
.areainfo-box-info-item {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
.areainfo-box-info-item-count {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.overview-container-right {
|
||||
.overview-container-right-alloverview {
|
||||
.overview-container-right-alloverview-item {
|
||||
text-align: center;
|
||||
.overview-container-right-alloverview-item-count {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.el-tree-node__content {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
.el-tree-node__label {
|
||||
display: block;
|
||||
width: calc(100% - 24px);
|
||||
text-align: center;
|
||||
white-space: nowrap; /* 禁止换行 */
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 溢出部分显示省略号 */
|
||||
}
|
||||
</style>
|
||||
519
src/views/areavisual/record/components/RecordDrawer.vue
Normal file
519
src/views/areavisual/record/components/RecordDrawer.vue
Normal file
@@ -0,0 +1,519 @@
|
||||
<!--
|
||||
filename: EquipmentDrawer.vue
|
||||
author: liubin
|
||||
date: 2023-08-22 14:38:56
|
||||
description:
|
||||
-->
|
||||
|
||||
<template>
|
||||
<el-drawer
|
||||
:visible="visible"
|
||||
:show-close="false"
|
||||
:wrapper-closable="false"
|
||||
class="drawer"
|
||||
custom-class="mes-drawer"
|
||||
size="60%"
|
||||
@closed="$emit('destroy')">
|
||||
<SmallTitle slot="title">
|
||||
{{
|
||||
mode.includes('detail')
|
||||
? '详情'
|
||||
: mode.includes('edit')
|
||||
? '编辑'
|
||||
: '新增'
|
||||
}}
|
||||
</SmallTitle>
|
||||
|
||||
<div class="drawer-body flex">
|
||||
<div class="drawer-body__content">
|
||||
<section v-for="(section, index) in sections" :key="section.key">
|
||||
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle>
|
||||
|
||||
<div
|
||||
class="form-part"
|
||||
v-if="section.key == 'base'"
|
||||
style="margin-bottom: 32px">
|
||||
<el-skeleton v-if="!showForm" animated />
|
||||
<!-- <EquipmentInfoForm
|
||||
key="drawer-dialog-form"
|
||||
v-if="showForm"
|
||||
:disabled="mode.includes('detail')"
|
||||
:sync-filelist="syncFileListFlag"
|
||||
v-model="form" /> -->
|
||||
</div>
|
||||
|
||||
<div v-if="section.key == 'attrs'" style="margin-top: 12px">
|
||||
<base-table
|
||||
v-loading="attrListLoading"
|
||||
:table-props="section.props"
|
||||
:page="attrQuery?.params.pageNo || 1"
|
||||
:limit="attrQuery?.params.pageSize || 10"
|
||||
:table-data="list"
|
||||
:add-button-show="mode.includes('detail') ? null : '添加属性'"
|
||||
@emitButtonClick="handleAddAttr"
|
||||
@emitFun="handleEmitFun">
|
||||
<method-btn
|
||||
v-if="section.tableBtn"
|
||||
slot="handleBtn"
|
||||
label="操作"
|
||||
:method-list="tableBtn"
|
||||
@clickBtn="handleTableBtnClick" />
|
||||
</base-table>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="attrQuery.params.pageNo"
|
||||
:limit.sync="attrQuery.params.pageSize"
|
||||
@pagination="getAttrList" />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="drawer-body__footer">
|
||||
<el-button style="" @click="handleCancel">取消</el-button>
|
||||
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button v-else type="primary" @click="handleConfirm">确定</el-button>
|
||||
<!-- sections的第二项必须是 属性列表 -->
|
||||
<!-- <el-button
|
||||
v-if="sections[1].allowAdd"
|
||||
type="primary"
|
||||
@click="handleAddAttr">
|
||||
添加属性
|
||||
</el-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
const SmallTitle = {
|
||||
name: 'SmallTitle',
|
||||
props: ['size'],
|
||||
components: {},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {},
|
||||
render: function (h) {
|
||||
return h(
|
||||
'span',
|
||||
{
|
||||
class: 'small-title',
|
||||
style: {
|
||||
fontSize: '18px',
|
||||
lineHeight:
|
||||
this.size == 'lg' ? '24px' : this.size == 'sm' ? '18px' : '20px',
|
||||
fontWeight: 500,
|
||||
fontFamily: '微软雅黑, Microsoft YaHei, Arial, Helvetica, sans-serif',
|
||||
},
|
||||
},
|
||||
this.$slots.default
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
components: { SmallTitle },
|
||||
props: ['sections', 'mode', 'dataId'], // dataId 作为一个通用的存放id的字段
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
showForm: false,
|
||||
btnLoading: false,
|
||||
total: 0,
|
||||
form: {},
|
||||
list: [],
|
||||
attrTitle: '',
|
||||
attrForm: {
|
||||
id: null,
|
||||
equipmentId: null,
|
||||
name: '',
|
||||
value: '',
|
||||
},
|
||||
attrFormVisible: false,
|
||||
attrRows: [
|
||||
[
|
||||
{
|
||||
input: true,
|
||||
label: '属性名称',
|
||||
prop: 'name',
|
||||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: true,
|
||||
label: '属性值',
|
||||
prop: 'value',
|
||||
},
|
||||
],
|
||||
],
|
||||
attrQuery: {
|
||||
params: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
}, // 属性列表的请求
|
||||
infoQuery: null, // 基本信息的请求
|
||||
attrFormSubmitting: false,
|
||||
attrListLoading: false,
|
||||
syncFileListFlag: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formRows() {
|
||||
return this.sections[0].rows.map((row) => {
|
||||
return row.map((col) => {
|
||||
if (col.key == 'eq-pics') {
|
||||
// 重置图片的位置
|
||||
return {
|
||||
...col,
|
||||
bind: {
|
||||
...col.bind,
|
||||
},
|
||||
style: {
|
||||
left: 0,
|
||||
right: 'unset',
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
bind: {
|
||||
...col.bind,
|
||||
// 详情 模式下,禁用各种输入
|
||||
disabled: this.mode == 'detail',
|
||||
},
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
tableBtn() {
|
||||
return this.mode == 'detail' ? [] : this.sections[1].tableBtn;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
for (const section of this.sections) {
|
||||
// 请求具体信息
|
||||
if ('url' in section) {
|
||||
const query = {
|
||||
url: section.url,
|
||||
method: section.method || 'get',
|
||||
params: section.queryParams || null,
|
||||
data: section.data || null,
|
||||
};
|
||||
this.$axios(query).then(({ data }) => {
|
||||
if (section.key == 'base') {
|
||||
this.form = data;
|
||||
// this.form = {
|
||||
// code: 'gj',
|
||||
// name: '下片机',
|
||||
// enName: 'unload',
|
||||
// abbr: '',
|
||||
// equipmentTypeId: 21084,
|
||||
// remark: '备注',
|
||||
// id: '1712367395052384257',
|
||||
// createTime: 1697095176000,
|
||||
// enterTime: 0,
|
||||
// productionTime: 0,
|
||||
// files: [
|
||||
// {
|
||||
// fileName: '测试.xlsx',
|
||||
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0108%2F0f0c6f30j00r5cle9000sc000hs00gtc.jpg&thumbnail=660x2147483647&quality=80&type=jpg',
|
||||
// fileType: 1
|
||||
// },
|
||||
// {
|
||||
// fileName: '测试2.xlsx',
|
||||
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0415%2F2cd23619j00racb96000kc000hs00hsc.jpg&thumbnail=660x2147483647&quality=80&type=jpg',
|
||||
// fileType: 1
|
||||
// },
|
||||
// {
|
||||
// fileName: '测试3.xlsx',
|
||||
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1fea91a0-d088-409e-b145-e0e61254b28b%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=2e0fe7d1de7f54adff3007efe133d67c',
|
||||
// fileType: 1
|
||||
// },
|
||||
// {
|
||||
// fileName: '测试4.xlsx',
|
||||
// fileUrl: 'https://pics5.baidu.com/feed/b7003af33a87e950cdfb4b4546eed044faf2b40d.jpeg?token=1d7484cfe4b014dd201f8c8725cab945',
|
||||
// fileType: 2
|
||||
// },
|
||||
// {
|
||||
// fileName: '测试5.xlsx',
|
||||
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fe3500876-9c46-4b70-8d37-4799520cdd13%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=4abc1df930e62730e5361a7d3765e0f2',
|
||||
// fileType: 2
|
||||
// },
|
||||
// ],
|
||||
// tvalue: 0,
|
||||
// processingTime: 0,
|
||||
// manufacturer: '',
|
||||
// spec: '',
|
||||
// description: '描述',
|
||||
// };
|
||||
this.showForm = true;
|
||||
this.infoQuery = query;
|
||||
} else if (section.key == 'attrs') {
|
||||
this.attrQuery = query;
|
||||
this.list = data.list;
|
||||
this.total = data.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTableBtnClick({ type, data }) {
|
||||
switch (type) {
|
||||
case 'edit':
|
||||
this.handleEditAttr(data.id);
|
||||
break;
|
||||
case 'delete':
|
||||
this.handleDeleteAttr(data.id);
|
||||
break;
|
||||
}
|
||||
},
|
||||
async handleConfirm() {
|
||||
this.btnLoading = true;
|
||||
this.syncFileListFlag = Math.random();
|
||||
|
||||
this.$nextTick(async () => {
|
||||
const { code, data } = await this.$axios({
|
||||
url: this.sections[0].urlUpdate,
|
||||
method: 'put',
|
||||
data: this.form,
|
||||
});
|
||||
if (code == 0) {
|
||||
this.$modal.msgSuccess('更新成功');
|
||||
this.$emit('refreshDataList');
|
||||
}
|
||||
|
||||
this.btnLoading = false;
|
||||
this.handleCancel();
|
||||
});
|
||||
},
|
||||
|
||||
handleEmitFun(val) {
|
||||
console.log('handleEmitFun', val);
|
||||
},
|
||||
|
||||
init() {
|
||||
this.visible = true;
|
||||
},
|
||||
|
||||
async getAttrList() {
|
||||
this.attrListLoading = true;
|
||||
const res = await this.$axios(this.attrQuery);
|
||||
if (res.code == 0) {
|
||||
this.list = res.data.list;
|
||||
this.total = res.data.total;
|
||||
}
|
||||
this.attrListLoading = false;
|
||||
},
|
||||
|
||||
// 保存表单
|
||||
handleSave() {
|
||||
this.$refs['form'][0].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const isEdit = this.mode == 'edit';
|
||||
await this.$axios({
|
||||
url: this.sections[0][isEdit ? 'urlUpdate' : 'urlCreate'],
|
||||
method: isEdit ? 'put' : 'post',
|
||||
data: this.form,
|
||||
});
|
||||
this.$modal.msgSuccess(`${isEdit ? '更新' : '创建'}成功`);
|
||||
this.visible = false;
|
||||
this.$emit('refreshDataList');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
this.visible = false;
|
||||
},
|
||||
|
||||
// 开启编辑
|
||||
toggleEdit() {
|
||||
this.$emit('update-mode', 'edit');
|
||||
},
|
||||
|
||||
// 新增属性
|
||||
handleAddAttr() {
|
||||
if (!this.dataId) return this.$message.warning('请先创建设备信息');
|
||||
this.attrForm = {
|
||||
id: null,
|
||||
equipmentId: this.dataId,
|
||||
name: '',
|
||||
value: '',
|
||||
};
|
||||
this.attrTitle = '添加设备属性';
|
||||
this.attrFormVisible = true;
|
||||
},
|
||||
|
||||
// 编辑属性
|
||||
async handleEditAttr(attrId) {
|
||||
const res = await this.$axios({
|
||||
url: this.sections[1].urlDetail,
|
||||
method: 'get',
|
||||
params: { id: attrId },
|
||||
});
|
||||
if (res.code == 0) {
|
||||
this.attrForm = res.data;
|
||||
this.attrTitle = '编辑设备属性';
|
||||
this.attrFormVisible = true;
|
||||
}
|
||||
},
|
||||
|
||||
// 删除属性
|
||||
handleDeleteAttr(attrId) {
|
||||
this.$confirm('确定删除该属性?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
const res = await this.$axios({
|
||||
url: this.sections[1].urlDelete,
|
||||
method: 'delete',
|
||||
params: { id: attrId },
|
||||
});
|
||||
if (res.code == 0) {
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getAttrList();
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
// 提交属性表
|
||||
submitAttrForm() {
|
||||
this.$refs['attrForm'].validate(async (valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const isEdit = this.attrForm.id != null;
|
||||
this.attrFormSubmitting = true;
|
||||
const res = await this.$axios({
|
||||
url: isEdit
|
||||
? this.sections[1].urlUpdate
|
||||
: this.sections[1].urlCreate,
|
||||
method: isEdit ? 'put' : 'post',
|
||||
data: this.attrForm,
|
||||
});
|
||||
|
||||
if (res.code == 0) {
|
||||
this.closeAttrForm();
|
||||
this.$message({
|
||||
message: `${isEdit ? '更新' : '创建'}成功`,
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getAttrList();
|
||||
},
|
||||
});
|
||||
}
|
||||
this.attrFormSubmitting = false;
|
||||
} catch (err) {
|
||||
this.$message({
|
||||
message: err,
|
||||
type: 'error',
|
||||
duration: 1500,
|
||||
});
|
||||
this.attrFormSubmitting = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
closeAttrForm() {
|
||||
this.attrFormVisible = false;
|
||||
},
|
||||
|
||||
handleClick(raw) {
|
||||
if (raw.type === 'delete') {
|
||||
this.$confirm(
|
||||
`确定对${
|
||||
raw.data.name
|
||||
? '[名称=' + raw.data.name + ']'
|
||||
: '[序号=' + raw.data._pageIndex + ']'
|
||||
}进行删除操作?`,
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
deleteProductAttr(raw.data.id).then(({ data }) => {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getList();
|
||||
},
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
} else {
|
||||
this.addNew(raw.data.id);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drawer >>> .el-drawer {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
.drawer >>> .el-drawer__header {
|
||||
margin: 0;
|
||||
padding: 32px 32px 24px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.small-title::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 4px;
|
||||
height: 22px;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
background-color: #0b58ff;
|
||||
}
|
||||
|
||||
.drawer-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.drawer-body__content {
|
||||
flex: 1;
|
||||
/* background: #eee; */
|
||||
padding: 20px 30px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.drawer-body__footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 18px;
|
||||
}
|
||||
</style>
|
||||
277
src/views/areavisual/record/index.vue
Normal file
277
src/views/areavisual/record/index.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索工作栏 -->
|
||||
<SearchBar
|
||||
:formConfigs="searchBarFormConfig"
|
||||
ref="search-bar"
|
||||
isFold
|
||||
@headBtnClick="handleSearchBarBtnClick" />
|
||||
|
||||
<!-- 列表 -->
|
||||
<base-table
|
||||
:table-props="tableProps"
|
||||
:page="queryParams.pageNo"
|
||||
:limit="queryParams.pageSize"
|
||||
:table-data="list"
|
||||
@emitFun="handleEmitFun">
|
||||
<method-btn
|
||||
v-if="tableBtn.length"
|
||||
slot="handleBtn"
|
||||
:width="120"
|
||||
label="操作"
|
||||
:method-list="tableBtn"
|
||||
@clickBtn="handleTableBtnClick" />
|
||||
</base-table>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNo"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 设备 详情 - 编辑 -->
|
||||
<RecordDrawer
|
||||
v-if="open"
|
||||
ref="drawer"
|
||||
:mode="editMode"
|
||||
@update-mode="editMode = $event"
|
||||
:data-id="form.id"
|
||||
@refreshDataList="getList"
|
||||
@cancel="cancelEdit"
|
||||
@destroy="cancelEdit" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
||||
import RecordDrawer from './components/RecordDrawer';
|
||||
import { getRecordPage, getLaneList } from '@/api/areavisual/record';
|
||||
|
||||
export default {
|
||||
name: 'Equipment',
|
||||
components: {
|
||||
RecordDrawer,
|
||||
},
|
||||
mixins: [basicPageMixin],
|
||||
data() {
|
||||
return {
|
||||
searchBarKeys: ['name', 'code'],
|
||||
// this.$auth.hasPermi(`base:equipment:update`)
|
||||
tableBtn: [
|
||||
{
|
||||
type: 'detail',
|
||||
btnName: '详情'
|
||||
}
|
||||
].filter((v) => v),
|
||||
tableProps: [
|
||||
{
|
||||
prop: 'recordCode',
|
||||
label: '出/入库单编号',
|
||||
fixed: true,
|
||||
width: 180,
|
||||
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
||||
// showOverflowtooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '业务类型',
|
||||
filter: (val) => val === 1 ? '出库' : '入库',
|
||||
},
|
||||
{
|
||||
width: 180,
|
||||
prop: 'recordTime',
|
||||
label: '出/入库时间',
|
||||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss')
|
||||
},
|
||||
{ prop: 'recordArea', label: '出/入库库区' },
|
||||
{ prop: 'recordLane', label: '出/入库巷道' },
|
||||
{ prop: 'recordRegion', label: '出/入库库位号' },
|
||||
{ prop: 'target', label: '搬运对象' },
|
||||
{ prop: 'productName', label: '产品名称' },
|
||||
{ prop: 'specification', label: '型号规格' },
|
||||
{ prop: 'recordMan', label: '出/入库人' },
|
||||
{ prop: 'remark', label: '备注' }
|
||||
],
|
||||
searchBarFormConfig: [
|
||||
{
|
||||
type: 'input',
|
||||
label: '关键字',
|
||||
placeholder: '请输入出/入库编码、产品名称、规格型号、库位号',
|
||||
param: 'query',
|
||||
width: 350
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '业务类型',
|
||||
selectOptions: [
|
||||
{
|
||||
id: '1',
|
||||
name:'出库'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name:'入库'
|
||||
},
|
||||
],
|
||||
placeholder: '请选择业务类型',
|
||||
param: 'type',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '出/入库巷道',
|
||||
selectOptions: [],
|
||||
placeholder: '请选择出/入库巷道',
|
||||
param: 'recordLane',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '来源',
|
||||
selectOptions: [
|
||||
{
|
||||
id: '1',
|
||||
name:'WMS'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name:'MES'
|
||||
},
|
||||
],
|
||||
placeholder: '请选择来源',
|
||||
param: 'source',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '出/入库人',
|
||||
selectOptions: [],
|
||||
placeholder: '请选择出/入库人',
|
||||
param: 'recordMan',
|
||||
},
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '出/入库时间',
|
||||
placeholder: '请选择出/入库时间',
|
||||
param: 'recordTime',
|
||||
dateType: 'datetimerange',
|
||||
rangeSeparator: '至'
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '载具类型',
|
||||
selectOptions: [
|
||||
{
|
||||
id: '1',
|
||||
name:'AGV'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name:'人工叉车'
|
||||
},
|
||||
],
|
||||
placeholder: '请选择载具类型',
|
||||
param: 'vehicleType',
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '重置',
|
||||
name: 'reset',
|
||||
color: 'info',
|
||||
}
|
||||
],
|
||||
editVisible: false,
|
||||
editMode: 'detail', // 'edit', 'detail'
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
query: '',
|
||||
type: '',
|
||||
source: '',
|
||||
recordLane: '',
|
||||
recordMan: '',
|
||||
recordTime: '',
|
||||
vehicleType: ''
|
||||
},
|
||||
form: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getLane()
|
||||
this.getList();
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
// 执行查询
|
||||
getRecordPage(this.queryParams).then((response) => {
|
||||
console.log(response)
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
async getLane() {
|
||||
const res = await getLaneList({
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
if (res.code === 0 && res.data) {
|
||||
console.log(res.data)
|
||||
this.searchBarFormConfig[2].selectOptions = res.data.list.map(item => {
|
||||
return { id: item.id, name: item.lane }
|
||||
})
|
||||
console.log(this.searchBarFormConfig)
|
||||
}
|
||||
},
|
||||
/** 取消按钮 */
|
||||
cancel() {
|
||||
this.open = false;
|
||||
},
|
||||
// /** 导出按钮操作 */
|
||||
// handleExport() {
|
||||
// // 处理查询参数
|
||||
// let params = { ...this.queryParams };
|
||||
// params.pageNo = undefined;
|
||||
// params.pageSize = undefined;
|
||||
// this.$modal
|
||||
// .confirm('是否确认导出所有设备数据项?')
|
||||
// .then(() => {
|
||||
// this.exportLoading = true;
|
||||
// return exportEquipmentExcel(params);
|
||||
// })
|
||||
// .then((response) => {
|
||||
// this.$download.excel(response, '设备.xls');
|
||||
// this.exportLoading = false;
|
||||
// })
|
||||
// .catch(() => {});
|
||||
// },
|
||||
handleTableBtnClick ({data, type}) {
|
||||
switch (type) {
|
||||
case 'detail':
|
||||
this.viewDetail(data.id)
|
||||
}
|
||||
},
|
||||
// 查看详情
|
||||
viewDetail(id) {
|
||||
this.editMode = 'detail';
|
||||
this.open = true;
|
||||
this.form.id = id;
|
||||
this.$nextTick(() => {
|
||||
this.$refs['drawer'].init();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user