虚拟货架

master
lion 12 months ago
parent f16bdd2339
commit 6b959462d7

@ -9,7 +9,7 @@ ENV='development'
VUE_APP_BASE_API = http://192.168.60.99:8004/
VUE_APP_UPLOAD_API = http://192.168.60.99:8004/api/admin/upload-file
VUE_APP_OA_URL= http://suzhouhedaooa.langye.net
VUE_APP_OA_URL= http://192.168.60.18:8001
VUE_APP_OA_URL_TYPE = '{"领用":"31","处置":"32","应急":"33"}'

@ -32,7 +32,7 @@
</el-upload>
<div class="title" style="margin-top: 10px;">数据预览</div>
<Table :data="tableList" :columns="table" style="margin-top: 10px;"></Table>
<Table :data="tableList" :columns="table" style="margin-top: 10px;height:400px;overflow: scroll;"></Table>
<div style="font-size: 12px;zoom: 0.8;">总共数据{{ tableList.length }}</div>
<el-button type="primary" size="small" style="margin-top: 10px;" @click="imports"></el-button>
</el-dialog>
@ -116,15 +116,17 @@ export default {
console.log(res)
this.$message({
type: 'success',
message: `成功导入${res.total}`
message: res.fail>0?`${res.fail}条未导入`:`成功导入${res.total}`
})
this.tableList = []
this.$emit('refresh')
})
}else{
console.log('importdata',this.tableList)
this.$emit('importdata',this.tableList)
}
this.hidden();
this.$emit('refresh')
}
},
computed: {},

@ -79,13 +79,13 @@
</div>
</div>
</template>
<template v-slot:suozaicangku_id>
<template v-slot:storages_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>所在仓库
</div>
<div class="xy-table-item-content">
<el-select @change="changeCk" v-model="form.suozaicangku_id" style="width: 300px;" placeholder="请选择所在仓库">
<el-select @change="changeCk" v-model="form.storages_id" style="width: 300px;" placeholder="请选择所在仓库">
<el-option
v-for="item in cangkuList"
:key="item.id"
@ -118,10 +118,12 @@
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>入库时间
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 300px;" v-model="form.rukushijian" type="date" placeholder="选择入库时间"
<div class="xy-table-item-content">
<el-input v-model="form.rukushijian" placeholder="请填写入库时间" clearable style="width: 300px;"></el-input>
<!-- <el-date-picker style="width: 300px;" v-model="form.rukushijian" type="date" placeholder="选择入库时间"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-date-picker> -->
</div>
</div>
</template>
@ -212,7 +214,85 @@
style="width: 300px;"></el-input>
</div>
</div>
</template>
</template>
<template v-slot:wuzidaima>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>物资代码
</div>
<div class="xy-table-item-content">
<el-input v-model="form.wuzidaima" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:yuanwuzimingcheng>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>原资产名称
</div>
<div class="xy-table-item-content">
<el-input v-model="form.yuanwuzimingcheng" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:shengchanriqi>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>生产日期
</div>
<div class="xy-table-item-content">
<el-input v-model="form.shengchanriqi" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:chubeifangshi>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>储备方式
</div>
<div class="xy-table-item-content">
<el-input v-model="form.chubeifangshi" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:zijinlaiyuan>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>资金来源
</div>
<div class="xy-table-item-content">
<el-input v-model="form.zijinlaiyuan" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:chubeicengji>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>储备层级
</div>
<div class="xy-table-item-content">
<el-input v-model="form.chubeicengji" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template>
<!-- <template v-slot:shifouzhanshi>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>shifouzhanshi
</div>
<div class="xy-table-item-content">
<el-input v-model="form.shifouzhanshi" placeholder="请输入" clearable
style="width: 300px;"></el-input>
</div>
</div>
</template> -->
@ -270,7 +350,7 @@
zhuangtai:'',
jiliangdanwei:'',
suozaicangku:'',
suozaicangku_id:'',
storages_id:'',
suozaihuojia:'',
rukushijian:'',
zichanyuanzhi:'',
@ -279,7 +359,14 @@
shifouweigudingzichan:'',
gudingzichanbianma:'',
jishuziliao:[],
beizhu:''
beizhu:'',
wuzidaima:'',
yuanwuzimingcheng:'',
shengchanriqi:'',
chubeifangshi:'',
zijinlaiyuan:'',
chubeicengji:'',
shifouzhanshi:''
},
rules: {
wuzibianma: [{
@ -337,7 +424,7 @@
zhuangtai:res?.zhuangtai,
jiliangdanwei:res?.jiliangdanwei,
suozaicangku:res?.suozaicangku,
suozaicangku_id:res.suozaicangku_id?parseInt(res.suozaicangku_id):'',
storages_id:res.storages_id?parseInt(res.storages_id):'',
suozaihuojia:res?.suozaihuojia,
rukushijian:res?.rukushijian,
zichanyuanzhi:res?.zichanyuanzhi,
@ -346,7 +433,14 @@
shifouweigudingzichan:res?.shifouweigudingzichan,
gudingzichanbianma:res?.gudingzichanbianma,
jishuziliao:res?.jishuziliao,
beizhu:res?.beizhu
beizhu:res?.beizhu,
wuzidaima:res?.wuzidaima,
yuanwuzimingcheng:res?.yuanwuzimingcheng,
shengchanriqi:res?.shengchanriqi,
chubeifangshi:res?.chubeifangshi,
zijinlaiyuan:res?.zijinlaiyuan,
chubeicengji:res?.chubeicengji,
shifouzhanshi:res?.shifouzhanshi
}
if(res.jishuziliao_upload_details){
for(var j of res.jishuziliao_upload_details){
@ -363,7 +457,7 @@
this.cangkuList.map(item=>{
if(e===item.id){
this.form.suozaicangku = item.cangkumingcheng
this.form.suozaicangku_id = item.id
this.form.storages_id = item.id
}
})
}

@ -6,8 +6,8 @@
<slot>
<div style="display: flex;justify-content: flex-start;flex-wrap: wrap;">
<Input v-model="select.keyword" style="width: 200px;margin-right: 10px;" placeholder="关键词搜索" />
<Select v-model="select.suozaicangku" style="width: 200px;margin-right: 10px;" placeholder="所在仓库" clearable>
<Option v-for="item in cangkuList" :key="item.id" :value="item.cangkumingcheng">{{ item.cangkumingcheng }}</Option>
<Select v-model="select.storages_id" style="width: 200px;margin-right: 10px;" placeholder="所在仓库" clearable>
<Option v-for="item in cangkuList" :key="item.id" :value="item.id">{{ item.cangkumingcheng }}</Option>
</Select>
<Button type="primary" @click="getindex"></Button>
<Button icon="ios-add" type="primary" style="margin-left: 10px;"
@ -115,7 +115,7 @@
pageSize: 10,
pageIndex: 1,
keyword: "",
suozaicangku:''
storages_id:''
},
cangkuList:[],
customForm: {
@ -177,7 +177,7 @@
{
label: "所在仓库",
width: 180,
prop: 'materialstorages_details.cangkumingcheng',
prop: 'storages_id_materialstorages_id_relation.cangkumingcheng',
align: 'center'
},
// {
@ -257,9 +257,9 @@
"value": this.select.keyword
},
{
"key": "suozaicangku",
"key": "storages_id",
"op": "eq",
"value": this.select.suozaicangku?this.select.suozaicangku:''
"value": this.select.storages_id?this.select.storages_id:''
},
],
@ -337,9 +337,9 @@
let headers = this.table.map(i => {
if(i.type==='index'){
}else if(i.prop==='materialstorages_details.cangkumingcheng'){
}else if(i.prop==='storages_id_materialstorages_id_relation.cangkumingcheng'){
return {
key: 'suozaicangku',
key: 'storages_id',
title: i.label
}
}else{

@ -0,0 +1,170 @@
<template>
<div>
<xy-dialog ref="dialog" :width='70' :is-show.sync="isShow" type="form" :title="type==='add'?'新增':'编辑'" :form="form"
:rules="rules" @submit="submit">
<template v-slot:storage_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>所属仓库
</div>
<div class="xy-table-item-content">
<el-select v-model="form.storage_id" style="width:300px" placeholder="请选择">
<el-option v-for="item in StorageList" :key="item.id" :label="item.cangkumingcheng" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:huojiamingcheng>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>货架名称
</div>
<div class="xy-table-item-content">
<el-input style="width:300px" v-model="form.huojiamingcheng"></el-input>
</div>
</div>
</template>
<template v-slot:area_x>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>标识区域x
</div>
<div class="xy-table-item-content">
<el-input style="width:300px" type="number" v-model="form.area_x"></el-input>
</div>
</div>
</template>
<template v-slot:area_y>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>标识区域y
</div>
<div class="xy-table-item-content">
<el-input style="width:300px" type="number" v-model="form.area_y"></el-input>
</div>
</div>
</template>
<template v-slot:tag_content>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>标识内容
</div>
<div class="xy-table-item-content">
<el-input style="width:300px" v-model="form.tag_content"></el-input>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
save,
show
} from "@/api/system/baseForm.js"
import {
getparameteritem
} from "@/api/system/dictionary.js"
import {
Message
} from 'element-ui'
export default {
data() {
return {
isShow: false,
type: 'add',
id: '',
tableName: 'shelfs',
StorageList: [],
form: {
storage_id: '',
huojiamingcheng: '',
area_x: 0,
area_y: 0,
tag_content: '',
},
rules: {
storage_id: [{
required: true,
message: '请选择所属仓库'
}],
huojiamingcheng: [{
required: true,
message: '请填写货架名称'
}]
},
}
},
created() {
},
methods: {
async getDetail() {
const res = await show({
id: this.id,
table_name: this.tableName
})
this.$integrateData(this.form, res)
this.form.area_x = res.area_x?res.area_x:0
this.form.area_y = res.area_y?res.area_y:0
},
submit() {
if (this.type === 'add') {
save({
table_name: this.tableName,
...this.form
}).then(res => {
Message({
type: 'success',
message: '新增成功'
})
this.$emit('refresh')
this.isShow = false
})
return
}
if (this.type === 'editor') {
save({
id: this.id,
table_name: this.tableName,
...this.form
}).then(res => {
Message({
type: 'success',
message: '编辑成功'
})
this.$emit('refresh')
this.isShow = false
})
}
},
},
watch: {
isShow(newVal) {
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
}
} else {
this.id = ''
this.$refs['dialog'].reset()
}
},
}
}
</script>
<style scoped lang="scss">
::v-deep .xy-table-item-label {
min-width: 160px !important
}
</style>

@ -0,0 +1,161 @@
<template>
<div>
<div ref="lxHeader">
<lx-header icon="md-apps" text="货架管理" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<slot>
<div style="display: flex;justify-content: flex-start;flex-wrap: wrap;">
<Input v-model="select.huojiamingcheng" style="width: 200px;margin-right: 10px;" placeholder="名称搜索" />
<Select @on-change="clearType" v-model="select.storage_id" style="width: 200px;margin-right: 10px;" placeholder="所在区域" clearable>
<Option v-for="item in StorageList" :key="item.id" :value="item.id">{{ item.cangkumingcheng }}</Option>
</Select>
<Button type="primary" @click="select.page=1,getList()"></Button>
<Button type="primary" style="margin-left: 10px;" @click="$refs['addShelf'].type='add',
$refs['addShelf'].StorageList = StorageList,
$refs['addShelf'].isShow=true">添加</Button>
<!-- <Button icon="ios-add" type="primary" style="margin-left: 10px;"
@click="$refs['imports'].show()">导入</Button> -->
</div>
</slot>
</lx-header>
</div>
<xy-table :list="list" :total="total" @pageSizeChange="pageSizeChange" @pageIndexChange="pageChange"
:table-item="table">
<template v-slot:btns>
<el-table-column fixed="right" label="操作" align="center" width="120" header-align="center">
<template slot-scope="scope">
<div>
<Button type="primary" size="small" @click="$refs['addShelf'].type='editor',
$refs['addShelf'].id=scope.row.id,$refs['addShelf'].StorageList = StorageList,
$refs['addShelf'].isShow=true">编辑</Button>
<Poptip transfer confirm title="确认要删除吗?" @on-ok="delRow(scope.row.id)">
<Button type="primary" style="margin-left: 10px;" size="small" ghost>删除</Button>
</Poptip>
</div>
</template>
</el-table-column>
</template>
</xy-table>
<addShelf ref="addShelf" @refresh="getList"></addShelf>
</div>
</template>
<script>
import {
index,
destroy
} from "@/api/system/baseForm.js"
import { getStorehouseStorageList } from '@/api/system/storehouseType'
import addShelf from './components/addShelf.vue'
import {
getparameteritem
} from "@/api/system/dictionary.js"
export default {
components: {
addShelf,
},
data() {
return {
select: {
page: 1,
page_size: 10,
huojiamingcheng: '',
table_name: 'shelfs',
storage_id:''
},
total: 0,
list: [],
StorageList:[],
table: [{
label: '序号',
type: 'index',
fixed: 'left',
width: 80,
}, {
label: '所属仓库',
prop: 'storage_id_materialstorages_id_relation.cangkumingcheng',
align: 'left',
fixed: 'left'
}, {
label: '货架名称',
prop: 'huojiamingcheng',
// width: 120,
}, {
label: '创建日期',
prop: 'created_at',
width: 120,
formatter: (cell, data, value) => {
return value ? value.substring(0, 10) : ''
}
}],
}
},
created() {
this.getStorageList()
this.getList()
},
methods: {
clearType(e){
if(e){
this.select.storage_id = e
}else{
this.select.storage_id = ''
}
},
async getStorageList() {
const res = await index({
page:1,
page_size:999,
table_name:'materialstorages'
});
this.StorageList = res.data
console.log("this.StorageList",this.StorageList)
},
async getList() {
const res = await index({
...this.select,
filter: [{
key:'huojiamingcheng',
op:'like',
value:this.select.huojiamingcheng
},{
key:'storage_id',
op:'eq',
value:this.select.storage_id
}],
})
this.list = res.data
this.total = res.total
},
pageChange(e) {
this.select.page = e
this.getList()
},
pageSizeChange(e){
this.select.page_size = e
this.getList()
},
delRow(id) {
if (id) {
destroy({
id: id,
table_name: this.select.table_name,
}).then(res => {
this.$message({
type: 'success',
message: '删除成功'
})
this.getList()
})
}
},
}
}
</script>
<style>
</style>

@ -1,24 +1,20 @@
<template>
<div>
<xy-dialog ref="dialog" :width='70' :is-show.sync="isShow" type="form" :title="type==='add'?'新增':'编辑'"
:form="form" :rules="rules" @submit="submit">
<template v-slot:storehouses_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>仓库类型
</div>
<div class="xy-table-item-content">
<el-select v-model="form.storehouses_id" style="width:300px" placeholder="请选择">
<el-option
v-for="item in typelist"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</div>
</div>
<xy-dialog ref="dialog" :width='70' :is-show.sync="isShow" type="form" :title="type==='add'?'新增':'编辑'" :form="form"
:rules="rules" @submit="submit">
<template v-slot:storehouses_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>仓库类型
</div>
<div class="xy-table-item-content">
<el-select v-model="form.storehouses_id" style="width:300px" placeholder="请选择">
<el-option v-for="item in typelist" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:cangkumingcheng>
<div class="xy-table-item">
@ -47,14 +43,10 @@
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>所在区域
</div>
<div class="xy-table-item-content">
<el-select v-model="form.suozaiquyu" @change="changeQuyu" style="width:300px" placeholder="请选择">
<el-option
v-for="item in areaList"
:key="item.id"
:label="item.value"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="form.suozaiquyu" @change="changeQuyu" style="width:300px" placeholder="请选择">
<el-option v-for="item in areaList" :key="item.id" :label="item.value" :value="item.value">
</el-option>
</el-select>
</div>
</div>
</template>
@ -64,7 +56,8 @@
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>建设年代
</div>
<div class="xy-table-item-content">
<el-date-picker style="width:300px" value-format="yyyy" format="yyyy" v-model="form.jiansheniandai" type="year" placeholder="选择年">
<el-date-picker style="width:300px" value-format="yyyy" format="yyyy" v-model="form.jiansheniandai"
type="year" placeholder="选择年">
</el-date-picker>
</div>
</div>
@ -141,6 +134,21 @@
</div>
</div>
</template>
<template v-slot:image_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;"></span>仓库概览图
</div>
<div class="xy-table-item-content">
<el-upload class="upload-demo" :action="action" :on-success="handleSuccess" :on-remove="handleRemove"
multiple :limit="10" :file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</div>
</div>
</template>
</xy-dialog>
</div>
@ -150,10 +158,10 @@
import {
save,
show
} from "@/api/system/baseForm.js"
import {
getparameteritem
} from "@/api/system/dictionary.js"
} from "@/api/system/baseForm.js"
import {
getparameteritem
} from "@/api/system/dictionary.js"
import {
Message
} from 'element-ui'
@ -163,17 +171,19 @@
return {
isShow: false,
type: 'add',
id: '',
tableName: 'materialstorages',
// flood_storages
areaList:[],
typelist:[],
id: '',
action:`${process.env.VUE_APP_UPLOAD_API}`,
fileList:[],
tableName: 'materialstorages',
// flood_storages
areaList: [],
typelist: [],
mapparams: {
zoom: 11,
},
mapform: [],
form: {
storehouses_id:'',
form: {
storehouses_id: '',
cangkumingcheng: '',
cangkubianma: '',
suozaiquyu: '',
@ -184,13 +194,14 @@
cangkudizhi: '',
jingdu: '',
weidu: '',
cangkujianjie: '',
quyu_id:''
cangkujianjie: '',
image_id: '',
quyu_id: ''
},
rules: {
type_id: [{
required: true,
message: '请填写仓库名称'
rules: {
type_id: [{
required: true,
message: '请填写仓库名称'
}],
cangkumingcheng: [{
required: true,
@ -204,26 +215,26 @@
this.getArea()
},
methods: {
getArea(){
getparameteritem("area").then(res=>{
this.areaList = res.detail
})
},
changeQuyu(e){
if(e){
this.areaList.map(item=>{
if(e===item.value){
this.form.suozaiquyu = item.value
this.form.quyu_id = item.id
}
})
}else{
this.form.suozaiquyu = ''
this.form.quyu_id = ''
}
},
setTableName(e){
this.tableName = e?e:'materialstorages'
getArea() {
getparameteritem("area").then(res => {
this.areaList = res.detail
})
},
changeQuyu(e) {
if (e) {
this.areaList.map(item => {
if (e === item.value) {
this.form.suozaiquyu = item.value
this.form.quyu_id = item.id
}
})
} else {
this.form.suozaiquyu = ''
this.form.quyu_id = ''
}
},
setTableName(e) {
this.tableName = e ? e : 'materialstorages'
},
async getDetail() {
const res = await show({
@ -231,10 +242,32 @@
table_name: this.tableName
})
this.$integrateData(this.form, res)
this.mapform = [res.jingdu, res.weidu, res.cangkudizhi]
this.mapform = [res.jingdu, res.weidu, res.cangkudizhi]
if(res.image_id_uploads_id_relation){
this.fileList.push(res.image_id_uploads_id_relation)
}
},
handleRemove(file, fileList) {
this.fileList = fileList
},
handleSuccess(response, file, fileList) {
this.fileList = fileList
},
submit() {
console.log(this.fileList)
this.form.image_id = ''
if (this.fileList.length > 0) {
for (var g of this.fileList) {
if (g.response) {
this.form.image_id = g.response.id
} else {
this.form.image_id = g.id
}
}
} else {
this.form.image_id = ''
}
submit() {
if (this.type === 'add') {
save({
table_name: this.tableName,
@ -276,7 +309,8 @@
} else {
this.id = ''
this.type = ''
this.mapform = []
this.mapform = []
this.fileList = []
this.$refs['dialog'].reset()
}
},

@ -11,7 +11,7 @@
<Select @on-change="clearArea" v-model="select.area" style="width: 200px;margin-right: 10px;" placeholder="所在区域" clearable>
<Option v-for="item in areaList" :key="item.id" :value="item.id">{{ item.value }}</Option>
</Select>
<Button type="primary" @click="getList"></Button>
<Button type="primary" @click="select.page=1,getList()"></Button>
<Button type="primary" style="margin-left: 10px;" @click="$refs['addStorage'].type='add',
$refs['addStorage'].typelist = typelist,
$refs['addStorage'].isShow=true">添加</Button>

@ -0,0 +1,440 @@
<template>
<el-container class="main-container" style="margin-left:0!important">
<!-- 左侧仓库列表 -->
<!-- 左侧仓库列表 -->
<el-aside width="250px" class="repository-aside">
<div class="aside-header">
<h3>仓库列表</h3>
</div>
<el-menu :default-active="activeRepository" class="repository-menu" @select="handleSelectRepository">
<el-menu-item v-for="repo in repositories" :key="repo.id" :index="repo.id.toString()">
<span>{{ repo.cangkumingcheng }}</span>
</el-menu-item>
</el-menu>
</el-aside>
<!-- 右侧概览图和货架点位展示区 -->
<el-main class="repository-main">
<div v-if="currentRepository" class="preview-container">
<div class="preview-wrapper">
<!-- 有概览图时显示图片和货架点位 -->
<div v-if="currentRepository.image_id_uploads_id_relation" class="preview-image" :style="{
backgroundImage: `url(${currentRepository.image_id_uploads_id_relation.url})`,
}">
<!-- 货架点位 -->
<div v-for="shelf in shelves" :key="shelf.id" class="shelf-point" :style="{
left: `${shelf.area_x}%`,
top: `${shelf.area_y}%`
}" @click="handleShelfClick(shelf)"></div>
<!-- 物资信息浮窗 -->
<div v-if="showMaterialInfo" class="material-info-popup" :style="{
left: `${selectedShelf.area_x}%`,
top: calculatePopupPosition(selectedShelf.area_y)
}">
<div class="popup-header">
<span>{{selectedShelf.huojiamingcheng}}</span>
<el-button type="text" icon="el-icon-close" @click="showMaterialInfo = false"></el-button>
</div>
<xy-table :list="materialList" :isPage='false' :table-item="materialTable">
<template v-slot:btns>
<div></div>
</template>
</xy-table>
<!-- <el-table :data="materialList" size="small" style="width: 100%" :max-height="300">
<el-table-column prop="name" label="物资名称"></el-table-column>
<el-table-column prop="quantity" label="数量"></el-table-column>
<el-table-column prop="unit" label="单位"></el-table-column>
<el-table-column prop="status" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.status === '正常' ? 'success' : 'warning'">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
</el-table> -->
</div>
</div>
<!-- 无概览图时显示提示 -->
<div v-else class="no-preview">
<el-empty description="该仓库还没有概览图">
<!-- <el-button type="primary" @click="handleAddImage"></el-button> -->
</el-empty>
</div>
</div>
</div>
<!-- 未选择仓库时显示提示 -->
<div v-else class="no-selection">
<el-empty description="请选择一个仓库"></el-empty>
</div>
</el-main>
<!-- 加载中遮罩 -->
<!-- <el-loading
:visible.sync="loading"
fullscreen
></el-loading> -->
</el-container>
</template>
<script>
import {
index
} from "@/api/system/baseForm.js"
export default {
name: 'RepositoryPreview',
data() {
return {
//
repositories: [], //
activeRepository: '', // ID
currentRepository: null, //
//
shelves: [], //
selectedShelf: null, //
showMaterialInfo: false, //
materialList: [], //
loading: false, //
materialTable:[{
label: '序号',
type: 'index',
fixed: 'left',
width: 80
},
{
label: "物资编码",
width: 120,
prop: 'wuzibianma',
align: 'center',
},
{
label: "资产名称",
width: 180,
prop: 'zichanmingcheng',
align: 'left'
},
{
label: "物资类型",
width: 180,
prop: 'wuzileixing',
align: 'center'
},
{
label: "计量单位",
width: 180,
prop: 'jiliangdanwei',
align: 'center'
},
{
label: "库存",
width: 180,
prop: 'inventorys_total',
align: 'center'
}
]
}
},
methods: {
//
async fetchRepositories() {
try {
this.loading = true;
// API
const res = await index({
page: 1,
page_size: 999,
table_name: 'materialstorages',
})
this.repositories = res.data.reverse();
} catch (error) {
this.$message.error('获取仓库列表失败');
} finally {
this.loading = false;
}
},
//
async fetchShelfData(repositoryId) {
try {
this.loading = true;
// API
const res = await index({
page: 1,
page_size: 999,
table_name: 'shelfs',
filter: [{
key: 'storage_id',
op: 'eq',
value: repositoryId
}],
})
this.shelves = res.data;
} catch (error) {
this.$message.error('获取货架数据失败');
this.shelves = [];
} finally {
this.loading = false;
}
},
//
async fetchMaterialInfo(shelfId) {
try {
this.loading = true;
// API
const res = await index({
page_size: 999,
page: 1,
table_name: 'material_infos',
filter: [{
"key": "suozaihuojia",
"op": "eq",
"value": shelfId
},
{
"key": "storages_id",
"op": "eq",
"value": this.currentRepository.id
},
],
})
this.materialList = res.data;
} catch (error) {
this.$message.error('获取物资信息失败');
this.materialList = [];
} finally {
this.loading = false;
}
},
//
async handleSelectRepository(index) {
this.activeRepository = index;
this.currentRepository = this.repositories.find(
repo => repo.id.toString() === index
);
if (this.currentRepository) {
this.showMaterialInfo = false; //
await this.fetchShelfData(this.currentRepository.id);
}
},
//
async handleShelfClick(shelf) {
this.selectedShelf = shelf;
// await this.fetchMaterialInfo(shelf.id);
await this.fetchMaterialInfo(shelf.huojiamingcheng);
this.showMaterialInfo = true;
},
//
async handleAddImage() {
//
try {
const formData = new FormData();
// ...
await this.$http.post(
`/api/repositories/${this.currentRepository.id}/image`,
formData
);
this.$message.success('上传成功');
await this.fetchRepositories(); //
} catch (error) {
this.$message.error('上传失败');
}
},
//
//
calculatePopupPosition(y) {
const position = parseFloat(y);
//
const imageHeight = this.$el.querySelector('.preview-image').offsetHeight;
const popupHeight = 300; //
//
if (position > 50) {
return `calc(${position}% - ${popupHeight + 20}px)`;
}
return `calc(${position}% + 20px)`;
},
//
handleResize() {
//
if (this.showMaterialInfo) {
//
this.$nextTick(() => {
if (this.selectedShelf) {
const newPosition = this.calculatePopupPosition(this.selectedShelf.area_y);
//
}
});
}
}
},
//
async created() {
await this.fetchRepositories();
},
mounted() {
//
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
//
window.removeEventListener('resize', this.handleResize);
}
}
</script>
<style scoped>
/* 主容器样式 */
.main-container {
height: 100vh;
width: 100%;
display: flex;
overflow: hidden;
}
/* 左侧栏样式 */
.repository-aside {
flex-shrink: 0;
background-color: #f5f7fa;
border-right: 1px solid #e6e6e6;
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
}
.aside-header {
padding: 20px;
border-bottom: 1px solid #e6e6e6;
flex-shrink: 0;
}
.aside-header h3 {
margin: 0;
color: #303133;
}
.repository-menu {
border-right: none;
flex: 1;
}
/* 右侧主要内容区样式 */
.repository-main {
flex: 1;
height: 100%;
overflow-y: auto;
padding: 20px;
background-color: #fff;
}
.preview-container {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.preview-wrapper {
width: 100%;
position: relative;
padding-top: 56.25%;
/* 16:9 比例 */
}
.preview-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
border-radius: 4px;
background-color: #f5f7fa;
}
/* 调整货架点位的定位,因为现在是相对于实际图片区域定位 */
.shelf-point {
position: absolute;
width: 20px;
height: 20px;
background-color: rgba(64, 158, 255, 0.7);
border: 2px solid #409EFF;
border-radius: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
transition: all 0.3s;
/* 确保点位在图片区域内正确定位 */
z-index: 2;
}
/* 调整物资信息浮窗的样式 */
.material-info-popup {
position: absolute;
background: white;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
min-width: 400px;
transform: translateX(-50%);
z-index: 1000;
/* 确保浮窗始终显示在最上层 */
z-index: 3;
}
/* 响应式布局 */
@media screen and (max-width: 768px) {
.main-container {
flex-direction: column;
}
.repository-aside {
width: 100% !important;
height: auto;
max-height: 40vh;
}
.repository-main {
height: 60vh;
}
.preview-wrapper {
padding-top: 75%;
/* 移动端使用 4:3 比例 */
}
.material-info-popup {
min-width: 300px;
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
max-width: 90%;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
/* 大屏幕优化 */
@media screen and (min-width: 1920px) {
.preview-wrapper {
max-width: 1920px;
margin: 0 auto;
}
}
</style>
Loading…
Cancel
Save