Browse Source

0110

master
xuhuajiao 6 months ago
parent
commit
822884014d
  1. 12
      src/api/shelf/index.js
  2. 58
      src/api/stockTask/index.js
  3. 14
      src/assets/iconfonts/light/iconfont.css
  4. 2
      src/assets/iconfonts/light/iconfont.js
  5. 14
      src/assets/iconfonts/light/iconfont.json
  6. BIN
      src/assets/iconfonts/light/iconfont.ttf
  7. BIN
      src/assets/iconfonts/light/iconfont.woff
  8. BIN
      src/assets/iconfonts/light/iconfont.woff2
  9. 9
      src/utils/request.js
  10. 56
      src/views/components/bookSwiper.vue
  11. 45
      src/views/components/canvasPreview.vue
  12. 130
      src/views/home.vue
  13. 321
      src/views/visualCheck/checkManage/dataScreening/girdList.vue
  14. 155
      src/views/visualCheck/checkManage/dataScreening/index.vue
  15. 70
      src/views/visualCheck/checkManage/dataScreening/regionsList.vue
  16. 686
      src/views/visualCheck/checkManage/dataScreening/shelfList copy.vue
  17. 148
      src/views/visualCheck/checkManage/dataScreening/shelfList.vue
  18. 179
      src/views/visualCheck/checkManage/paramSetting/index.vue
  19. 37
      src/views/visualCheck/mixins/index.js
  20. 21
      src/views/visualCheck/venueDevice/bookshelf/index.vue

12
src/api/shelf/index.js

@ -26,7 +26,7 @@ export function edit(data) {
export function del(ids) {
return request({
url: '',
url: 'api/bookShelf/delBookShelf',
method: 'post',
data: ids
})
@ -110,4 +110,12 @@ export function FetchFastDownShelf(ids) {
})
}
export default { add, edit, del, FetchInitBookShelfList, FetchBookShelfDetails, saveBookShelfSignPoint, FetchInitShelfGridByShelfId, FetcheEditSortmarkByGrid, FetchChangeOrderByGrid, FetchChangeCheckByGrid, FetchShelfGridAllByShelfId, FetchShelfAllByRegionId, FetchFastDownShelf }
// 根据书架和架位查看层架位
export function FetchShelfGridByShelfIdAndGridShelf(params) {
return request({
url: 'api/bookShelf/getShelfGridByShelfIdAndGridShelf' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { add, edit, del, FetchInitBookShelfList, FetchBookShelfDetails, saveBookShelfSignPoint, FetchInitShelfGridByShelfId, FetcheEditSortmarkByGrid, FetchChangeOrderByGrid, FetchChangeCheckByGrid, FetchShelfGridAllByShelfId, FetchShelfAllByRegionId, FetchFastDownShelf, FetchShelfGridByShelfIdAndGridShelf }

58
src/api/stockTask/index.js

@ -67,4 +67,60 @@ export function FetchInitHomeInfo(params) {
})
}
export default { add, edit, del, FetchUpdateStockTaskStatus, FetchInitSuggestTilting, FetchInitSetting, FetchEditSetting, FetchInitHomeInfo }
// 初始化盘点概况
export function FetchInitStockInfo(params) {
return request({
url: 'api/stocktask-task/initStockInfo' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 初始化热门图书
export function FetchInitHotBookList(params) {
return request({
url: 'api/stocktask-task/initHotBookList' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 初始化热门架位
export function FetchInitHotShelfList(params) {
return request({
url: 'api/stocktask-task/initHotShelfList' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 根据层架位id获取架位图书
export function FetchInitBookDetailsByGrids(params) {
return request({
url: 'api/stocktask-task/initBookDetailsByGrids' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// AI处理终端状态查询
export function FetchAITerminalStatusQuery(params) {
return request({
url: 'api/stocktask-task/AITerminalStatusQuery' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 根据书架和书架层获取盘点单信息
export function FetchBillByShelfIdAndGridShelf(params) {
return request({
url: 'api/stocktask-task/getBillByShelfIdAndGridShelf' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 根据盘点单号和层架位id获取是否完美切割
export function FetchIsGoodcutByBillNoAndGridId(params) {
return request({
url: 'api/stocktask-task/getIsGoodcutByBillNoAndGridId' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { add, edit, del, FetchUpdateStockTaskStatus, FetchInitSuggestTilting, FetchInitSetting, FetchEditSetting, FetchInitHomeInfo, FetchInitStockInfo, FetchInitHotBookList, FetchInitHotShelfList, FetchInitBookDetailsByGrids, FetchAITerminalStatusQuery, FetchBillByShelfIdAndGridShelf, FetchIsGoodcutByBillNoAndGridId }

14
src/assets/iconfonts/light/iconfont.css

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1735544677759') format('woff2'),
url('iconfont.woff?t=1735544677759') format('woff'),
url('iconfont.ttf?t=1735544677759') format('truetype');
src: url('iconfont.woff2?t=1736498949884') format('woff2'),
url('iconfont.woff?t=1736498949884') format('woff'),
url('iconfont.ttf?t=1736498949884') format('truetype');
}
.iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-zhongduanjiankong:before {
content: "\e691";
}
.icon-lianjieduankai:before {
content: "\e600";
}
.icon-stop:before {
content: "\e714";
}

2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File

14
src/assets/iconfonts/light/iconfont.json

@ -5,6 +5,20 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "18610501",
"name": "终端监控",
"font_class": "zhongduanjiankong",
"unicode": "e691",
"unicode_decimal": 59025
},
{
"icon_id": "10596948",
"name": "链接断开",
"font_class": "lianjieduankai",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "10014347",
"name": "终止",

BIN
src/assets/iconfonts/light/iconfont.ttf

BIN
src/assets/iconfonts/light/iconfont.woff

BIN
src/assets/iconfonts/light/iconfont.woff2

9
src/utils/request.js

@ -16,7 +16,7 @@ import Cookies from 'js-cookie'
// 创建axios实例
const service = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? window.g.ApiUrl : '/', // api 的 base_url
baseURL: '/', // api 的 base_url
// baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/', // api 的 base_url
timeout: Config.timeout // 请求超时时间
})
@ -27,6 +27,13 @@ service.interceptors.request.use(
if (getToken()) {
config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
if (config.urlType === 'device') {
config.baseURL = process.env.NODE_ENV === 'production' ? window.g.DevUrl : process.env.VUE_APP_DEVICE_API
} else {
config.baseURL = process.env.NODE_ENV === 'production' ? window.g.ApiUrl : '/'
}
config.headers['Content-Type'] = 'application/json'
return config
},

56
src/views/components/bookSwiper.vue

@ -46,11 +46,15 @@
height="150"
>
<el-table-column
prop="name"
prop="title"
:label="swiperActiveIndex === 1 ? '书架' :'书名'"
/>
>
<template slot-scope="scope">
{{ swiperActiveIndex === 0 ? scope.row.title : scope.row.grid_name }}
</template>
</el-table-column>
<el-table-column
prop="num"
prop="downNum"
label="出架册次"
width="80"
align="center"
@ -62,6 +66,7 @@
</template>
<script>
import { FetchInitHotBookList, FetchInitHotShelfList } from '@/api/stockTask/index'
import { mapGetters } from 'vuex'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
@ -75,12 +80,10 @@ export default {
const _this = this
return {
swiperActiveIndex: 0,
rightDataIndex: null,
swiperOptionContent: {
slidesPerView: 'auto',
on: {
slideChangeTransitionStart: function() {
_this.rightDataIndex = null
_this.swiperActiveIndex = this.activeIndex
_this.swiperTitle.slideTo(this.activeIndex, 500, false)
}
@ -91,30 +94,55 @@ export default {
freeMode: true
},
tabListData: [{ name: '热门图书' }, { name: '热门架位' }],
bookList: [
{ 'id': 1, 'name': '女帝英雄传', 'num': 10 },
{ 'id': 2, 'name': 'NBA赛场', 'num': 9 },
{ 'id': 3, 'name': 'CBA赛场', 'num': 8 },
{ 'id': 4, 'name': '贱客行', 'num': 7 },
{ 'id': 5, 'name': '龙凤奇侠传', 'num': 6 }
]
bookList: []
}
},
computed: {
...mapGetters([
'baseApi'
])
]),
swiperContent() {
return this.$refs.swiperContent.$el.swiper
},
swiperTitle() {
return this.$refs.swiperTitle.$el.swiper
}
},
mounted() {
if (this.swiperActiveIndex === 0) {
this.getInitHotBookList()
} else {
this.getInitHotShelfList()
}
},
methods: {
handleSlidClickFun(index) {
this.rightDataIndex = null
this.handleSlideToFun(index)
},
handleSlideToFun(index) {
this.bookList = []
this.swiperActiveIndex = index
if (this.swiperActiveIndex === 0) {
this.getInitHotBookList()
} else {
this.getInitHotShelfList()
}
this.swiperContent.slideTo(index, 500, false)
this.swiperTitle.slideTo(index, 500, false)
},
getInitHotBookList() {
FetchInitHotBookList().then(res => {
this.bookList = res
}).catch(() => {
})
},
getInitHotShelfList() {
FetchInitHotShelfList().then(res => {
this.bookList = res
}).catch(() => {
})
}
}
}
</script>

45
src/views/components/canvasPreview.vue

@ -20,11 +20,13 @@
</template>
<script>
import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
import defaultImg from '@/assets/images/system/default-img.jpg'
import { fabric } from 'fabric'
import { mapGetters } from 'vuex'
export default {
name: 'Mark',
mixins: [dataScreeningCrud],
props: {
currentMarkData: {
type: Object,
@ -143,10 +145,18 @@ export default {
id: item.id,
name: item.name,
floorId: item.floorId,
regionId: item.regionId,
rowType: item.rowType,
toward: item.toward,
floorName: item.floorName,
regionName: item.regionName,
shelfFloor: item.shelfFloor,
shelfShelf: item.shelfShelf,
errorOrderNum: item.errorOrderNum,
errorOrderProbo: item.errorOrderProbo,
errorShelfNum: item.errorShelfNum,
errorShelfProbo: item.errorShelfProbo,
onShelfNum: item.onShelfNum,
stroke: 'rgba(196,43, 1, 1)',
strokeWidth: self.drawWidth,
fill: 'rgba(196,43, 1, 1)',
@ -172,11 +182,13 @@ export default {
id: e.target.id,
name: e.target.name,
floorId: e.target.floorId,
regionId: e.target.regionId,
rowType: e.target.rowType,
toward: e.target.toward,
regionName: e.target.regionName,
floorName: e.target.floorName
}
console.log('toReigonsData', toReigonsData)
if (self.pagePreview === 'floor') {
self.handleToRegions(toReigonsData, tabIndex)
} else if (self.pagePreview === 'region') {
@ -188,41 +200,44 @@ export default {
})
polygon.on('mouseover', function(e) {
console.log('e', e)
console.log('e.target', e.target)
console.log('e.target.name', e.target.name)
console.log('e.target.rowType', e.target.rowType)
this.tooltipInfo = {
'id': e.target.id,
'name': e.target.name,
'rowType': e.target.rowType
'rowType': e.target.rowType,
'shelfFloor': e.target.shelfFloor,
'shelfShelf': e.target.shelfShelf,
'floorId': e.target.floorId,
'regionId': e.target.regionId,
'errorOrderNum': e.target.errorOrderNum,
'errorOrderProbo': e.target.errorOrderProbo,
'errorShelfNum': e.target.errorShelfNum,
'errorShelfProbo': e.target.errorShelfProbo,
'onShelfNum': e.target.onShelfNum
}
this.set({ opacity: 0.8, hoverCursor: 'pointer' })
// <span class="update-time">2024-11-28 09:46</span>
if (self.pagePreview === 'floor') {
document.getElementById('tooltip').innerHTML =
`<div class="tooltip-top">
<h4>${this.tooltipInfo.name}</h4>
<span class="update-time">2024-11-28 09:46</span>
</div>
<ul>
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
<li><p>在架</p><span><i>${this.tooltipInfo.onShelfNum}</i></span></li>
<li><p>错架</p><span><i>${this.tooltipInfo.errorShelfNum}</i></span> <span class="percentage">${this.tooltipInfo.errorShelfProbo}</span></li>
<li><p>错序</p><span><i>${this.tooltipInfo.errorOrderNum}</i></span><span class="percentage">${this.tooltipInfo.errorOrderProbo}</span></li>
</ul>`
} else if (self.pagePreview === 'region') {
document.getElementById('tooltip').innerHTML =
`<div class="tooltip-top">
<h4>书架概况</h4>
<span class="update-time">2024-11-28 09:46</span>
</div>
<ul>
<li><p>书架</p><span><i>${this.tooltipInfo.name}</i></span></li>
<li><p>规则</p><span><i>双面6*8</i></span></li>
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
<li><p>规则</p><span><i>${this.tooltipInfo.rowType === 1 ? '单面' : '双面'}${this.tooltipInfo.shelfFloor}*${this.tooltipInfo.shelfShelf}</i></span></li>
<li><p>在架</p><span><i>${this.tooltipInfo.onShelfNum}</i></span></li>
<li><p>错架</p><span><i>${this.tooltipInfo.errorShelfNum}</i></span> <span class="percentage">${this.tooltipInfo.errorShelfProbo}</span></li>
<li><p>错序</p><span><i>${this.tooltipInfo.errorOrderNum}</i></span><span class="percentage">${this.tooltipInfo.errorOrderProbo}</span></li>
</ul>`
}

130
src/views/home.vue

@ -74,8 +74,8 @@
<h3 class="home-item-title">
盘点概况
</h3>
<div v-if="lendData.otherData.length !== 0" class="chart-wrapper">
<lend-across :lend-data="lendData" />
<div v-if="taskStockLogData.length !== 0" class="chart-wrapper">
<taskStockLogEcharts :task-stock-log-data="taskStockLogData" />
</div>
<div v-else class="empty-main">
<svg-icon icon-class="empty" class-name="empty-img" />
@ -121,12 +121,13 @@
<script>
import PanelGroup from './dashboard/PanelGroup'
import lendAcross from '@/views/components/echarts/lendAcross.vue'
import taskStockLogEcharts from '@/views/components/echarts/taskStockLog.vue'
// import lendAcross from '@/views/components/echarts/lendAcross.vue'
// import catePie from '@/views/components/echarts/catePie.vue'
import typePie from '@/views/components/echarts/typePie.vue'
import bookSwiper from '@/views/components/bookSwiper.vue'
import serverProgress from '@/views/components/echarts/serverProgress.vue'
import { FetchInitHomeInfo } from '@/api/stockTask/index'
import { FetchInitHomeInfo, FetchInitStockInfo } from '@/api/stockTask/index'
import { FetchInitStockLogList } from '@/api/stockTaskLog/index'
import { FetchSystemInfo } from '@/api/home/cpu/index'
import { mapGetters } from 'vuex'
@ -135,7 +136,8 @@ export default {
name: 'Dashboard',
components: {
PanelGroup,
lendAcross,
// lendAcross,
taskStockLogEcharts,
// catePie,
bookSwiper,
typePie,
@ -149,6 +151,18 @@ export default {
gridCount: 0,
deviceCount: 0
},
taskStockLogData: [],
echartsTimer: null,
refreshtime: 10000,
systemTimer: null,
systemData: {
cpuPercentage: 0,
memPercentage: 0,
sysFilesPercentage: 0
},
stockLogCompletedData: [],
stockLogIncompleteData: [],
archivesTotalNum: 0,
flowableData: [],
flowableTabIndex: 0,
@ -163,17 +177,7 @@ export default {
addArcivesMonth: [],
addArcivesNum: [],
addArcivesNumFile: []
},
echartsTimer: null,
refreshtime: 10000,
systemTimer: null,
systemData: {
cpuPercentage: 0,
memPercentage: 0,
sysFilesPercentage: 0
},
stockLogCompletedData: [],
stockLogIncompleteData: []
}
}
},
computed: {
@ -185,6 +189,7 @@ export default {
this.handleMainData()
this.getSystemInfo()
this.getStockLog()
this.handleInitStockInfo()
},
mounted() {
// const _this = this
@ -248,15 +253,7 @@ export default {
this.stockLogIncompleteData = res.content.filter(item => [1, 2].includes(item.state))
})
},
toMoreProcess() {
this.$router.push({ path: '/user/center?activeIndex=2' })
},
handleMainData() {
// const fondsAffiliation = []
// fondsAffiliation.push(this.user.fonds.id.toString())
// const params = {
// fondsAffiliations: fondsAffiliation
// }
FetchInitHomeInfo().then(data => {
this.topObjectNum = {
regionCount: data.regionCount,
@ -264,81 +261,16 @@ export default {
gridCount: data.gridCount,
deviceCount: data.deviceCount
}
// this.flowableData = data.flows
// '', '', '', '', '', '', ''
// "archivesTotalNum archivesTagNum installNum storageNum borrowNum openNum entityNum approveNum
//
// this.lendData.archivesTotalNum = data.archivesTotalNum
// this.lendData.otherData = [
// data.archivesTagNum, data.installNum, data.storageNum, data.borrowNum, data.openNum, data.entityNum, data.approveNum
// ]
// //
// let maxCount = 0
// data.statisNumJSON.archives.forEach(archive => {
// if (archive.count > maxCount) {
// maxCount = archive.count
// }
// })
// data.statisNumJSON.singles.forEach(single => {
// if (single.count > maxCount) {
// maxCount = single.count
// }
// })
// this.addArcivesData.addArcivesMaxCount = maxCount
// const currentDate = new Date() //
// const currentYear = currentDate.getFullYear() //
// const currentMonth = currentDate.getMonth() // 0 11 1
// let startYear = currentYear - 1 //
// let startMonth = currentMonth + 1 // 1
// const result = [] //
// const xResult = []
// while (startYear < currentYear || startMonth <= currentMonth) {
// xResult.push(startYear + '/' + startMonth)
// result.push({ year: startYear, month: startMonth, archivesCount: 0, singlesCount: 0 })
// //
// startMonth += 1
// if (startMonth > 12) {
// startYear += 1
// startMonth = 1
// }
// }
// result.forEach(yearMonthObj => {
// data.statisNumJSON.archives.forEach(archive => {
// if (parseInt(archive.month) === yearMonthObj.month) {
// yearMonthObj.archivesCount = archive.count
// return
// }
// })
// data.statisNumJSON.singles.forEach(single => {
// if (parseInt(single.month) === yearMonthObj.month) {
// yearMonthObj.singlesCount = single.count
// return
// }
// })
// })
// this.addArcivesData.addArcivesMonth = xResult
// this.addArcivesData.addArcivesNum = result.map(function(obj) {
// return obj.archivesCount
// })
// this.addArcivesData.addArcivesNumFile = result.map(function(obj) {
// return obj.singlesCount
// })
// //
// for (const type in data.typeGroupBy) {
// if (data.typeGroupBy.hasOwnProperty(type)) {
// this.typeData.push({ name: type, value: data.typeGroupBy[type] })
// }
// }
})
},
handleInitStockInfo(params) {
FetchInitStockInfo(params).then(res => {
this.taskStockLogData = [
{ value: res.onShelfNum - res.errorShelfNum - res.errorOrderNum, name: '正常在架' },
{ value: res.errorShelfNum, name: '错架' },
{ value: res.errorOrderNum, name: '错序' }
]
}).catch(() => {
})
}
}

321
src/views/visualCheck/checkManage/dataScreening/girdList.vue

@ -25,18 +25,19 @@
<span class="left-bottom-line" />
<div class="gird-data-header">
<ul class="tab-nav">
<li v-for="(item,index) in tabListData" :key="index" :class="{ 'active-tab-nav': tabIndex == index }" @click="changeActiveTab(index)">{{ item.name }}<i /></li>
<!-- @click="changeActiveTab(index)" :class="{ 'active-tab-nav': tabIndex == index }-->
<li v-for="(item,index) in tabListData" :key="index" class="active-tab-nav">{{ item.name }}<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<div class="tag-info">
<!-- <div class="tag-info">
<p class="tag-sort">错序<i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-place">错架<i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-all">在架<i class="iconfont icon-zhuangtai2" />20</p>
</div>
</div> -->
<div class="time-update-cont">
<span class="time-left-txt">最后更新时间</span>
<el-button>2024-11-28 09:46</el-button>
<span v-if="checkDateLine.length !== 0" class="time-left-txt">最后更新时间</span>
<el-button>{{ checkDateLine[0].endTime }}</el-button>
<div class="time-update-line">
<el-timeline>
<el-timeline-item
@ -46,16 +47,16 @@
:type="activity.type"
:color="activity.color"
:size="activity.size"
:timestamp="activity.timestamp"
:timestamp="activity.endTime"
>
{{ activity.content }}
{{ computedStockType(activity.stockType) }}
</el-timeline-item>
</el-timeline>
</div>
</div>
<crudOperation :permission="permission">
<template v-slot:middle>
<el-select v-model="layerVal" clearable size="small" placeholder="架位" class="filter-item" style="width: 100px; margin-right: 10px;">
<el-select v-model="layerVal" size="small" placeholder="架位" class="filter-item" style="width: 100px; margin-right: 10px;" @change="changeShelfGetGrid">
<el-option v-for="item in rackOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-button v-permission="permission.add" class="check-btn" size="mini" @click="toAdd(5)">
@ -72,33 +73,33 @@
</crudOperation>
</div>
<div class="gird-data-book">
<div v-loading="shelfAllGridDataLoading" class="gird-data-book">
<div v-for="(item,index) in shelfAllGridData" :key="index" class="gird-layer">
<span class="gird-left-line" />
<span class="gird-right-line" />
<div class="layer-left">
<div class="layer-left-book">
<div
v-for="(book,i) in bookNum"
v-for="(book,i) in item.books"
:key="i"
:class="['book-item', { 'red-active' : i===2} ,{ 'blue-active' : i===6}]"
:class="['book-item', { 'red-active' : book.bookStatus === '错架'} ,{ 'blue-active' : book.bookStatus === '错序'}]"
@mouseenter="showPopover(index, i, $event)"
@mouseleave="hidePopover"
>
<span class="book-name">水浒传水浒传水浒传水浒传</span>
<span class="book-name">{{ book.bookName }}</span>
</div>
</div>
</div>
<div class="layer-right-handle">
<div class="layer-info-header">
<h4>{{ item.gridName }}</h4>
<span>2024-11-28 09:46</span>
<!-- <span>2024-11-28 09:46</span> -->
</div>
<div class="layer-right-content">
<div class="layer-tag-info">
<div class="tag-item tag-sort">错序<i class="iconfont icon-zhuangtai2" /><p>1</p><span>5.00%</span></div>
<div class="tag-item tag-place">错架<i class="iconfont icon-zhuangtai2" /><p>1</p><span>5.00%</span></div>
<div class="tag-item tag-all">在架<i class="iconfont icon-zhuangtai2" /><p>20</p></div>
<div class="tag-item tag-sort">错序<i class="iconfont icon-zhuangtai2" /><p>{{ baseStockData.length !==0 && baseStockData[index].errorOrderNum }}</p><span>{{ baseStockData.length !==0 && baseStockData[index].errorOrderProbo }}</span></div>
<div class="tag-item tag-place">错架<i class="iconfont icon-zhuangtai2" /><p>{{ baseStockData.length !==0 &&baseStockData[index].errorShelfNum }}</p><span>{{ baseStockData.length !==0 && baseStockData[index].errorShelfProbo }}</span></div>
<div class="tag-item tag-all">在架<i class="iconfont icon-zhuangtai2" /><p>{{ baseStockData.length !==0 && baseStockData[index].onShelfNum }}</p></div>
</div>
<div class="layer-handle">
<el-button size="mini" @click="handleDetail(item)">
@ -121,14 +122,15 @@
>
<div class="popover-content-set">
<div class="tooltip-top">
<h4>水浒传</h4>
<span class="tag-item tag-sort">错架</span>
<h4>{{ shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].bookName }}</h4>
<span v-if="shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].bookStatus === '错序'" class="tag-item tag-place">错序</span>
<span v-if="shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].bookStatus === '错架'" class="tag-item tag-sort">错架</span>
</div>
<ul>
<li><p>索书号</p><em>I247/163:03</em></li>
<li><p>ISBN</p><em>96532175632</em></li>
<li><p>著者</p><em>施耐庵</em></li>
<li><p>出版社</p><em>人民出版社</em></li>
<li><p>索书号</p><em>{{ shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].sortmark }}</em></li>
<li><p>ISBN</p><em>{{ shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].isbn }}</em></li>
<li><p>著者</p><em>{{ shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].bookAuthor }}</em></li>
<li><p>出版社</p><em>{{ shelfAllGridData[popoverIndex.layer].books[popoverIndex.book].bookPublish }}</em></li>
</ul>
</div>
</div>
@ -137,7 +139,7 @@
</div>
<!-- 详情 -->
<el-dialog class="dialog-grid-detail" append-to-body :close-on-click-modal="false" :visible.sync="detailVisible" title="001排A面01架1层 - 详情" @close="handleCloseDialog">
<el-dialog class="dialog-grid-detail" append-to-body :close-on-click-modal="false" :visible.sync="detailVisible" :title="detailCurrent.gridName +'- 详情'" @close="handleCloseDialog">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
@ -155,26 +157,33 @@
class="archives-table"
:data="detailTable"
style="width: 100%;"
height="calc(100vh - 329px)"
>
<el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column prop="regionCode" label="题名" />
<el-table-column prop="floorName" label="ISBN" />
<el-table-column prop="booksheflCount" label="索书号" />
<el-table-column prop="booksheflCount" label="条码" />
<el-table-column prop="booksheflCount" label="应在位置" />
<el-table-column prop="booksheflCount" label="盘点位置" />
<el-table-column prop="booksheflCount" label="盘点结果" align="center">
<template>
<span class="row-state row-lending state-active">错架</span>
<!-- <span class="row-state row-binding state-active">在架</span>
<span class="row-state row-physical state-active">错序</span> -->
<el-table-column prop="bookName" label="题名" min-width="110" show-overflow-tooltip />
<el-table-column prop="isbn" label="ISBN" />
<el-table-column prop="sortmark" label="索书号" />
<el-table-column prop="barcode" label="条码" />
<el-table-column prop="floorName" label="所在位置" min-width="160">
<template slot-scope="scope">
<span>
{{ getLocation(scope.row) }}
</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="完成时间">
<el-table-column prop="bookStatus" label="盘点结果" align="center">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
<span v-if="scope.row.bookStatus === '未知'" class="row-state row-warehousing">未知</span>
<span v-if="scope.row.bookStatus === '在架'" class="row-state row-binding state-active">在架</span>
<span v-if="scope.row.bookStatus === '错架'" class="row-state row-lending state-active">错架</span>
<span v-if="scope.row.bookStatus === '错序'" class="row-state row-physical state-active">错序</span>
</template>
</el-table-column>
<!-- <el-table-column prop="updateTime" label="盘点时间">
<template slot-scope="scope">
<div>{{ scope.row.updateTime | parseTime }}</div>
</template>
</el-table-column> -->
</el-table>
</div>
</div>
@ -195,8 +204,9 @@
</div>
<div class="setting-dialog">
<el-carousel indicator-position="outside">
<el-carousel-item v-for="item in 4" :key="item">
<img src="~@/assets/images/system/default-img.jpg" alt="">
<el-carousel-item v-for="item in bookImgData" :key="item">
{{ item }}
<img :src="item" alt="">
</el-carousel-item>
</el-carousel>
</div>
@ -206,7 +216,9 @@
</template>
<script>
import { FetchBookShelfDetails } from '@/api/shelf/index'
import { FetchInitStockInfo, FetchInitBookDetailsByGrids, FetchBillByShelfIdAndGridShelf, FetchIsGoodcutByBillNoAndGridId } from '@/api/stockTask/index'
import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
import { FetchBookShelfDetails, FetchShelfGridByShelfIdAndGridShelf } from '@/api/shelf/index'
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
@ -228,19 +240,22 @@ export default {
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), crud()],
mixins: [presenter(), header(), crud(), dataScreeningCrud],
data() {
return {
detailVisible: false,
detailImgVisible: false,
detailTable: [{}],
detailTable: [],
detailCurrent: {},
tabdialogIndex: 0,
listLoading: false,
tabIndex: 0,
floorTabIndex: 0,
regionTabIndex: 0,
floorName: null,
floorId: null,
regionName: null,
regionId: null,
gridRow: null,
gridShelf: null,
bookShelfDetails: null,
@ -271,27 +286,13 @@ export default {
color: '#0bbd87'
}, {
content: '手动盘点全局',
timestamp: '2024-11-08 09:46',
size: 'large'
}, {
content: '计划盘点全局',
timestamp: '2024-11-08 09:46',
size: 'large'
}, {
content: '计划盘点全局计划盘点全局计划盘点全局',
timestamp: '2024-11-08 09:46'
}, {
content: '计划盘点全局',
timestamp: '2024-11-08 09:46',
timestamp: '2024-12-18 09:46',
size: 'large'
}, {
content: '计划盘点全局',
timestamp: '2024-11-08 09:46'
}, {
content: '计划盘点全局',
timestamp: '2024-11-08 09:46',
size: 'large'
}]
}],
baseStockData: [],
shelfAllGridDataLoading: false,
billNoImg: null,
bookImgData: []
}
},
computed: {
@ -317,6 +318,7 @@ export default {
position: 'absolute'
}
}
},
async created() {
if (localStorage.getItem('dataScreenFloorTableIndex')) {
@ -337,16 +339,20 @@ export default {
}
// /
this.tabListData = dataScreenShelf.rowType === 1
? dataScreenShelf.toward === 1
? [{ name: 'A面' }]
: [{ name: 'B面' }]
: [{ name: 'A面' }, { name: 'B面' }]
this.tabListData = [{ name: dataScreenShelf.regionName + ' - ' + this.removeAreaPrefix(dataScreenShelf.gridName) }]
// dataScreenShelf.rowType === 1
// ? dataScreenShelf.toward === 1
// ? [{ name: 'A' }]
// : [{ name: 'B' }]
// : [{ name: 'A' }, { name: 'B' }]
this.tabIndex = dataScreenShelf.toward - 1
FetchBookShelfDetails({ 'shelfId': dataScreenShelf.shelfId }).then(res => {
this.layerNum = res.shelfFloor
this.rackNum = res.shelfShelf
this.floorId = res.floorId
this.regionId = res.regionId
this.bookShelfDetails = res
this.rackOptions = []
@ -354,6 +360,12 @@ export default {
this.rackOptions.push({ id: i, name: `0${i}` })
}
this.layerVal = parseInt(this.gridShelf) || ''
this.getInitStockInfo(this.shelfAllGridData)
this.getInitBookDetailsByGrids(this.shelfAllGridData)
this.getBillByShelfIdAndGridShelf(this.shelfAllGridData)
}).catch(() => {
})
}
@ -367,6 +379,96 @@ export default {
[CRUD.HOOK.afterValidateCU](crud) {
return true
},
computedStockType(stockType) {
switch (stockType) {
case 1:
return '全量盘点'
case 2:
return '区域盘点'
case 3:
return '计划盘点'
case 4:
return '书架盘点'
case 5:
return '架位盘点'
case 6:
return '层位盘点'
default:
return ''
}
},
removeAreaPrefix(gridNames) {
const index = gridNames.indexOf('面')
if (index !== -1) {
return gridNames.substring(0, index + 1)
}
return gridNames
},
getLocation(row) {
const parts = []
if (row.floorName) {
parts.push(row.floorName)
}
if (row.regionName) {
parts.push(row.regionName)
}
if (row.gridName) {
parts.push(row.gridName)
}
return parts.length > 0 ? parts.join('-') : '-'
},
getBillByShelfIdAndGridShelf(data) {
console.log('this.shelfAllGridData', data)
const params = {
'gridShelf': data[0].gridShelf,
'ShelfId': data[0].shelfId,
'size': 5
}
FetchBillByShelfIdAndGridShelf(params).then(res => {
console.log(res)
if (res) {
this.checkDateLine = res.sort((a, b) => {
return new Date(b.endTime) - new Date(a.endTime)
})
this.billNoImg = this.checkDateLine[0].stockBill
}
}).catch(() => {
})
},
async getInitStockInfo(data) {
const promises = data.map(item => {
const params = {
'floorId': this.floorId,
'regionId': this.regionId,
'shelfId': item.shelfId,
'gridId': item.id
}
return FetchInitStockInfo(params)
})
const results = await Promise.all(promises)
if (!Array.isArray(this.baseStockData)) {
this.baseStockData = []
}
this.baseStockData = this.baseStockData.concat(results)
},
getInitBookDetailsByGrids(data) {
const ids = data.map(item => item.id)
const params = {
'grids': ids.join(',')
}
FetchInitBookDetailsByGrids(params).then(res => {
console.log(res)
this.shelfAllGridData.forEach((item) => {
const gridId = item.id
if (res.hasOwnProperty(gridId)) {
// item.books = res[gridId]
this.$set(item, 'books', res[gridId])
}
})
console.log(this.shelfAllGridData)
}).catch(() => {
})
},
toAdd(type, item) {
this.$refs.eform.formVisible = true
if (type === 5) {
@ -382,13 +484,6 @@ export default {
this.$refs.eform.setData(type)
},
removeAreaPrefix(gridNames) {
const index = gridNames.indexOf('区')
if (index !== -1) {
return gridNames.substring(index + 1)
}
return gridNames
},
getInitShelfGridByShelfId(toward) {
this.listLoading = true
// rowType 1 2
@ -515,9 +610,42 @@ export default {
handleDetail(item) {
console.log('item', item)
this.detailVisible = true
this.detailTable = item.books
this.detailCurrent = item
},
handleViewImg() {
handleViewImg(item) {
this.detailImgVisible = true
console.log(this.detailCurrent.gridCode)
const params = {
'billNo': this.billNoImg,
'gridId': this.detailCurrent.id
}
FetchIsGoodcutByBillNoAndGridId(params).then(res => {
console.log(res)
// /PD20250102001/040011011/img_result/result_cut_1.jpg
// /PD20250102001/040011011/img_result/result_cut_2.jpg
// /PD20250102001/040011011/img_result/result_cut_3.jpg
// http://192.168.99.67:12010/api/fileRelevant/getImg?imgId=
if (res) {
// 2
// const url = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.billNoImg + '/' + this.detailCurrent.gridCod + '/img_result/result_cut_1.jpg'
// for (var i = 0; i < 2; i++) {
this.bookImgData = [
this.baseApi + '/api/fileRelevant/getImg?imgId=/' + this.billNoImg + '/' + this.detailCurrent.gridCode + '/img_result/result_cut_1.jpg',
this.baseApi + '/api/fileRelevant/getImg?imgId=/' + this.billNoImg + '/' + this.detailCurrent.gridCode + '/img_result/result_cut_2.jpg'
]
// }
} else {
// 3
this.bookImgData = [
this.baseApi + '/api/fileRelevant/getImg?imgId=/' + this.billNoImg + '/' + this.detailCurrent.gridCode + '/img_result/result_cut_1.jpg',
this.baseApi + '/api/fileRelevant/getImg?imgId=/' + this.billNoImg + '/' + this.detailCurrent.gridCode + '/img_result/result_cut_2.jpg',
this.baseApi + '/api/fileRelevant/getImg?imgId=/' + this.billNoImg + '/' + this.detailCurrent.gridCode + '/img_result/result_cut_3.jpg'
]
}
}).catch(() => {
})
},
handleCloseDialog() {
this.detailVisible = false
@ -530,7 +658,6 @@ export default {
localStorage.setItem('dataScreenShelf', JSON.stringify(data))
},
showPopover(layerIndex, bookIndex, event) {
console.log('bookIndex', bookIndex)
this.popoverIndex = { layer: layerIndex, book: bookIndex }
const bookElement = event.target //
const rect = bookElement.getBoundingClientRect() //
@ -557,6 +684,26 @@ export default {
},
changeDialogTab(index) {
this.tabdialogIndex = index
},
changeShelfGetGrid(val) {
console.log('val', val)
this.shelfAllGridDataLoading = true
const params = {
'gridShelf': '0' + val,
'shelfId': this.bookShelfDetails.id,
'toward': this.bookShelfDetails.toward,
'floorType': this.bookShelfDetails.floorType
}
FetchShelfGridByShelfIdAndGridShelf(params).then(res => {
this.shelfAllGridData = []
this.shelfAllGridData = res
this.getInitStockInfo(this.shelfAllGridData)
this.getInitBookDetailsByGrids(this.shelfAllGridData)
this.shelfAllGridDataLoading = false
}).catch(() => {
})
}
}
}
@ -611,6 +758,7 @@ export default {
top: 33px;
right: 20px;
z-index: 9999;
width: 250px;
max-height: 645px;
padding: 20px 30px;
background-color: #fff;
@ -752,7 +900,7 @@ export default {
.dialog-grid-detail{
::v-deep .el-dialog{
width: 936px !important;
width: 1200px !important;
.el-dialog__body{
padding: 0 !important;
}
@ -802,4 +950,25 @@ export default {
}
}
}
.venue-content {
.tab-content .tab-nav {
li{
cursor: default;
}
}
}
.popover-external-set{
ul li p{
width: 50px;
font-weight: bold;
text-align: right;
}
ul li span,
ul li em{
width: 140px;
display: block;
text-align: right;
font-style: normal;
}
}
</style>

155
src/views/visualCheck/checkManage/dataScreening/index.vue

@ -30,9 +30,9 @@
</ul>
<div class="total-data">
<span>楼层概况</span>
<p>区域1</p>
<p>书架4</p>
<p>摄像头12</p>
<p>区域{{ baseData.regionCount }}</p>
<p>书架{{ baseData.shelfCount }}</p>
<p>摄像头{{ baseData.deviceCount }}</p>
</div>
<CanvasPreview ref="previewRefs" v-loading="prewLoading" page-preview="floor" :current-mark-data="currentMarkData" :image-url="imageUrl" />
</div>
@ -41,19 +41,19 @@
<div class="lib-right-item lib-info">
<h4>场馆概况</h4>
<ul class="data-right-list">
<li><p>楼层</p><span><i>5</i></span></li>
<li><p>区域</p><span><i>25</i></span></li>
<li><p>书架</p><span><i>100</i></span></li>
<li><p>摄像头</p><span><i>300</i></span></li>
<li><p>楼层</p><span><i>{{ baseData.floorCount }}</i></span></li>
<li><p>区域</p><span><i>{{ baseData.regionCount }}</i></span></li>
<li><p>书架</p><span><i>{{ baseData.shelfCount }}</i></span></li>
<li><p>摄像头</p><span><i>{{ baseData.deviceCount }}</i></span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>盘点概况</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<!-- <div class="refresh-date">2024-11-28 09:46</div> -->
<ul class="data-right-list">
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
<li><p>在架</p><span><i>{{ baseStockData.onShelfNum }}</i></span></li>
<li><p>错架</p><span><i>{{ baseStockData.errorShelfNum }}</i></span> <span class="percentage">{{ baseStockData.errorShelfProbo }}</span></li>
<li><p>错序</p><span><i>{{ baseStockData.errorOrderNum }}</i></span><span class="percentage">{{ baseStockData.errorOrderProbo }}</span></li>
</ul>
</div>
<div class="lib-right-item">
@ -68,6 +68,8 @@
</template>
<script>
import { FetchInitStockInfo } from '@/api/stockTask/index'
import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
import { FetchInitLibraryRegionList } from '@/api/area/index'
import crudStockTaskLog from '@/api/stockTaskLog/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
@ -91,7 +93,7 @@ export default {
reset: false
}})
},
mixins: [presenter(), header(), crud()],
mixins: [presenter(), header(), crud(), dataScreeningCrud],
data() {
const _this = this
return {
@ -149,37 +151,89 @@ export default {
}
this.changeActiveTab(this.tabIndex)
//
const params = {
'floorId': this.floorOptions[this.tabIndex].id
}
this.handleInitStockInfo(params)
},
// //
// [CRUD.HOOK.beforeToAdd]() {
// if (this.crud.form.stockType === 1) {
// this.crud.form.stockTypeName = ''
// }
// Promise.all([
// crudStockTaskLog.FetchNewBillNo(),
// crudStockTaskLog.FetchStockGirdNum()
// ]).then(([newBillNoRes, stockGridNumRes]) => {
// this.crud.form.stockBill = newBillNoRes
// this.crud.form.stockGridNumName = stockGridNumRes + ' / '
// this.crud.form.stockGridNum = stockGridNumRes
// }).catch(error => {
// console.error(error)
// })
// },
// //
// [CRUD.HOOK.afterValidateCU](crud) {
// console.log(crud.form)
// delete crud.form.stockGridNumName
// delete crud.form.stockTypeName
// return true
// },
toAdd(type) {
this.$refs.eform.formVisible = true
this.$refs.eform.setData(type)
this.$refs.eform.form.stockRegion = '全部区域'
},
changeActiveTab(index) {
// changeActiveTab(index) {
// this.prewLoading = true
// if (this.$refs.previewRefs.canvasPreview.lowerCanvasEl) {
// this.$refs.previewRefs.canvasPreview.clear()
// this.$refs.previewRefs.canvasPreview.dispose()
// }
// this.allCoverData = []
// this.tabIndex = index
// const params = {
// 'floorId': this.floorOptions[index].id
// }
// FetchInitLibraryRegionList(params).then(res => {
// this.allCoverData = res.content
// if (this.floorOptions[index].floorMap) {
// this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.floorOptions[index].floorMap
// } else {
// this.imageUrl = this.defaultImg
// }
// if (this.allCoverData.length !== 0) {
// this.currentMarkData = this.allCoverData[0]
// const parsedSignPoints = this.allCoverData.map(item => {
// const signPoint = item.signPoint ? JSON.parse(item.signPoint) : null
// return {
// id: item.id,
// name: item.regionName,
// floorName: item.floorName,
// floorId: item.floorId,
// pointInfo: signPoint ? signPoint.pointInfo[0].pointInfo : null
// }
// })
// const imgInfo = JSON.parse(this.allCoverData[0].signPoint).imgInfo
// const result = {
// pointInfo: parsedSignPoints,
// imgInfo: imgInfo
// }
// console.log('result', result)
// this.$nextTick(() => {
// this.$refs.previewRefs.initCanvasPreview(result, this.tabIndex)
// })
// } else {
// this.currentMarkData = {}
// setTimeout(() => {
// this.prewLoading = false
// }, 500)
// }
// }).catch(() => {
// })
// },
async getInitStockInfo(data) {
const promises = data.map(item => {
const params = {
'floorId': this.floorOptions[this.tabIndex].id,
'regionId': item.id
}
return FetchInitStockInfo(params)
})
const results = await Promise.all(promises)
if (!Array.isArray(this.baseStockDataAllShelf)) {
this.baseStockDataAllShelf = []
}
// id
results.forEach((result, index) => {
result.id = data[index].id
})
this.baseStockDataAllShelf = this.baseStockDataAllShelf.concat(results)
return this.baseStockDataAllShelf
},
async changeActiveTab(index) {
this.prewLoading = true
if (this.$refs.previewRefs.canvasPreview.lowerCanvasEl) {
this.$refs.previewRefs.canvasPreview.clear()
@ -190,7 +244,9 @@ export default {
const params = {
'floorId': this.floorOptions[index].id
}
FetchInitLibraryRegionList(params).then(res => {
try {
const res = await FetchInitLibraryRegionList(params)
console.log(res)
this.allCoverData = res.content
if (this.floorOptions[index].floorMap) {
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.floorOptions[index].floorMap
@ -200,22 +256,33 @@ export default {
if (this.allCoverData.length !== 0) {
this.currentMarkData = this.allCoverData[0]
// const signPoint = this.allCoverData.find(item => item.signPoint !== null)?.signPoint
const imgInfo = JSON.parse(this.allCoverData[0].signPoint).imgInfo
const baseStockDataAllShelf = await this.getInitStockInfo(this.allCoverData)
const parsedSignPoints = this.allCoverData.map(item => {
const signPoint = JSON.parse(item.signPoint)
const signPoint = item.signPoint ? JSON.parse(item.signPoint) : null
return {
id: item.id,
name: item.regionName,
floorName: item.floorName,
floorId: item.floorId,
pointInfo: signPoint.pointInfo[0].pointInfo
pointInfo: signPoint ? signPoint.pointInfo[0].pointInfo : null
}
})
parsedSignPoints.forEach(parsedItem => {
const baseStockItem = baseStockDataAllShelf.find(baseItem => baseItem.id === parsedItem.id)
if (baseStockDataAllShelf) {
Object.assign(parsedItem, baseStockItem)
}
})
const imgInfo = JSON.parse(this.allCoverData[0].signPoint).imgInfo
const result = {
pointInfo: parsedSignPoints,
imgInfo: imgInfo
}
console.log('result', result)
this.$nextTick(() => {
this.$refs.previewRefs.initCanvasPreview(result, this.tabIndex)
})
@ -225,9 +292,11 @@ export default {
this.prewLoading = false
}, 500)
}
}).catch(() => {
})
} catch (error) {
console.error(error)
}
},
handleSlidClickFun(index) {
this.rightDataIndex = null
this.handleSlideToFun(index)

70
src/views/visualCheck/checkManage/dataScreening/regionsList.vue

@ -42,17 +42,17 @@
<div class="lib-right-item lib-info">
<h4>本区概况</h4>
<ul class="data-right-list">
<li><p>书架</p><span><i>100</i></span></li>
<li><p>摄像头</p><span><i>300</i></span></li>
<li><p>书架</p><span><i>{{ baseData.shelfCount }}</i></span></li>
<li><p>摄像头</p><span><i>{{ baseData.deviceCount }}</i></span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>本区盘点概况</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<!-- <div class="refresh-date">2024-11-28 09:46</div> -->
<ul class="data-right-list">
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
<li><p>在架</p><span><i>{{ baseStockData.onShelfNum }}</i></span></li>
<li><p>错架</p><span><i>{{ baseStockData.errorShelfNum }}</i></span> <span class="percentage">{{ baseStockData.errorShelfProbo }}</span></li>
<li><p>错序</p><span><i>{{ baseStockData.errorOrderNum }}</i></span><span class="percentage">{{ baseStockData.errorOrderProbo }}</span></li>
</ul>
</div>
<div class="lib-right-item">
@ -67,6 +67,8 @@
</template>
<script>
import { FetchInitStockInfo } from '@/api/stockTask/index'
import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
import crudRegion from '@/api/area/index'
import { FetchInitBookShelfList } from '@/api/shelf/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
@ -91,7 +93,7 @@ export default {
}
})
},
mixins: [presenter(), header(), crud()],
mixins: [presenter(), header(), crud(), dataScreeningCrud],
data() {
const _this = this
return {
@ -127,7 +129,8 @@ export default {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
}
},
baseStockDataAllShelf: []
}
},
computed: {
@ -164,6 +167,13 @@ export default {
this.floorName = this.regionOptions[index].floorName
this.tabIndex = index
this.changeActiveTab(index)
//
const params = {
'floorId': this.regionOptions[this.tabIndex].floorId,
'regionId': this.regionOptions[this.tabIndex].id
}
this.handleInitStockInfo(params)
},
//
[CRUD.HOOK.afterValidateCU](crud) {
@ -175,14 +185,36 @@ export default {
this.$refs.eform.form.stockRegion = this.regionOptions[this.tabIndex].floorName + this.regionOptions[this.tabIndex].regionName
this.$refs.eform.setData(type)
},
changeActiveTab(index) {
async getInitStockInfo(data) {
const promises = data.map(item => {
const params = {
'floorId': this.floorId,
'regionId': this.regionId,
'shelfId': item.shelfId
}
return FetchInitStockInfo(params)
})
const results = await Promise.all(promises)
if (!Array.isArray(this.baseStockDataAllShelf)) {
this.baseStockDataAllShelf = []
}
// id
results.forEach((result, index) => {
result.id = data[index].shelfId
})
this.baseStockDataAllShelf = this.baseStockDataAllShelf.concat(results)
return this.baseStockDataAllShelf
},
async changeActiveTab(index) {
this.prewLoading = true
this.tabIndex = index
const params = {
'floorId': this.regionOptions[index].floorId,
'regionId': this.regionOptions[index].id
}
FetchInitBookShelfList(params).then(res => {
try {
const res = await FetchInitBookShelfList(params)
console.log(res)
this.allCoverData = res.content
if (this.regionOptions[index].regionMap) {
@ -195,6 +227,7 @@ export default {
this.currentMarkData = this.regionOptions[index]
const signPoint = this.allCoverData.find(item => item.signPoint !== null)?.signPoint
const imgInfo = signPoint ? JSON.parse(signPoint).imgInfo : null
const baseStockDataAllShelf = await this.getInitStockInfo(this.allCoverData)
const parsedSignPoints = this.allCoverData.map(item => {
const signPoint = item.signPoint ? JSON.parse(item.signPoint) : null
return {
@ -204,13 +237,25 @@ export default {
toward: item.toward,
floorName: item.floorName,
regionName: item.regionName,
shelfFloor: item.shelfFloor,
shelfShelf: item.shelfShelf,
floorId: this.regionOptions[index].floorId,
regionId: this.regionOptions[index].id,
pointInfo: signPoint ? signPoint.pointInfo[0].pointInfo : null
}
})
parsedSignPoints.forEach(parsedItem => {
const baseStockItem = baseStockDataAllShelf.find(baseItem => baseItem.id === parsedItem.id)
if (baseStockItem) {
Object.assign(parsedItem, baseStockItem)
}
})
const result = {
pointInfo: parsedSignPoints,
imgInfo: imgInfo
}
console.log('result', result)
this.$nextTick(() => {
this.$refs.previewRefs.initCanvasPreview(result, this.tabIndex)
})
@ -220,8 +265,9 @@ export default {
this.prewLoading = false
}, 500)
}
}).catch(() => {
})
} catch (error) {
console.error(error)
}
},
handleSlidClickFun(index) {
this.rightDataIndex = null

686
src/views/visualCheck/checkManage/dataScreening/shelfList copy.vue

@ -1,686 +0,0 @@
<template>
<div class="app-container">
<div class="venue-header">
<h4 @click="handleToGrids"><i class="iconfont icon-shuju" />书架总览</h4>
<span class="bookshelf-area">{{ floorName }} - {{ regionName }}</span>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="venue-content">
<crudOperation :permission="permission">
<template v-slot:middle>
<el-select v-model="layerVal" clearable size="small" placeholder="楼层" class="filter-item" style="width: 100px; margin-right: 20px;">
<el-option v-for="item in layerOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-button v-permission="permission.add" size="mini" @click="crud.toAdd">
<i class="iconfont icon-shengchengpandiandan" />
书架盘点
</el-button>
</template>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
<div class="venue-left">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<!-- <div style="display: flex;justify-content: flex-start; align-items: center;"> -->
<swiper
ref="swiperTitle"
class="swiper-title"
:options="swiperOptionTitle"
:auto-update="true"
:auto-destroy="true"
:delete-instance-on-destroy="true"
:cleanup-styles-on-destroy="true"
>
<swiper-slide
v-for="(item, index) of tabListData"
ref="swiperSlideItem"
:key="'name' + index"
:iname="item.name"
class="swiper-slide-title"
>
<div
class="tab-name"
:class="{ active: index === swiperActiveIndex }"
@click="handleSlidClickFun(index)"
>
{{ item.name }}
</div>
</swiper-slide>
</swiper>
<div class="tag-info">
<p>错序1</p>
<p>错架1</p>
<p>在架20</p>
</div>
<!-- </div> -->
<swiper
ref="swiperContent"
class="swiper-content"
:options="swiperOptionContent"
:auto-update="true"
:auto-destroy="true"
:delete-instance-on-destroy="true"
:cleanup-styles-on-destroy="true"
>
<swiper-slide
v-for="(item, index) of tabListData"
:key="'content' + index"
class="swiper-slide-content"
>
<ul class="cabinet-row">
<li
v-for="(cell,i) in booShelfGrid"
:key="i"
class="cabinet-cell"
:style="cellStyle"
:class="{ active: i === cellIndex }"
@click="handleCellCurrent(cell,i)"
@mouseenter="showPopover(i)"
@mouseleave="hidePopover"
>
<span class="cell-name">{{ removeAreaPrefix(cell.gridName) }}</span>
<!-- v-if="popoverIndex === i" -->
<el-popover
v-if="popoverIndex === i"
ref="popover"
:visible="popoverVisible[i]"
width="400"
:style="popoverStyles[i]"
trigger="manual"
>
<div slot="reference" class="popover-content">
<div class="tooltip-top">
<h4>层位概况</h4>
<i class="update-time">2024-11-28 09:46</i>
</div>
<ul>
<li><p>层位</p><em class="percentage"><i style="color: #fff;">{{ removeAreaPrefix(cell.gridName) }}</i></em></li>
<li><p>在架</p><em><i>15000</i></em></li>
<li><p>错架</p><em><i>300</i></em> <em class="percentage">2.00%</em></li>
<li><p>错序</p><em><i>0</i></em><em class="percentage">0.00%</em></li>
</ul>
</div>
</el-popover>
</li>
</ul>
</swiper-slide>
</swiper>
</div>
</div>
<div class="venue-right">
<div class="lib-right-item lib-info">
<h4>本架概况</h4>
<ul class="data-right-list">
<li><p>书架</p><span><i>001</i></span></li>
<li><p>规则</p><span><i>双面 6 x 5</i></span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>本架盘点概况</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<ul class="data-right-list">
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
</ul>
</div>
</div>
</div>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="盘点单号" prop="taskName">
<el-input v-model="form.taskName" />
</el-form-item>
<el-form-item label="盘点类型" prop="taskType">
<el-input v-model="form.taskType" />
</el-form-item>
<el-form-item label="目标位置" prop="location">
<el-input v-model="form.location" />
</el-form-item>
<el-form-item label="目标数量" prop="number">
<el-input v-model="form.number" />
</el-form-item>
<el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" />
</el-form-item>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { FetchInitShelfGridByShelfId, FetchBookShelfDetails } from '@/api/shelf/index'
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import { mapGetters } from 'vuex'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null }
export default {
name: 'DataScreening',
components: { swiper, swiperSlide, crudOperation },
cruds() {
return CRUD({ title: '架位总览', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
add: false,
edit: false,
del: false,
download: false,
group: false,
reset: false
},
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
const _this = this
return {
floorName: null,
regionName: null,
bookShelfDetails: null,
booShelfGrid: null,
cellInfo: {
gridName: null,
startSortmark: null,
endSortmark: null,
cameraId: null
},
callNumVisible: false,
layerNum: 0,
rackNum: 0,
swiperActiveIndex: 0,
cellIndex: null,
swiperOptionContent: {
slidesPerView: 'auto',
on: {
slideChangeTransitionStart: function() {
_this.cellIndex = null
_this.swiperActiveIndex = this.activeIndex
console.log('activeIndexffff', this.swiperActiveIndex)
_this.swiperTitle.slideTo(this.activeIndex, 500, false)
}
}
},
swiperOptionTitle: {
slidesPerView: 'auto',
freeMode: true
},
layerVal: '001排',
layerOptions: [{ id: 1, name: '001排' }],
tabListData: [],
permission: {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
},
rules: {
taskName: [
{ required: true, message: '请输入盘点单号', trigger: 'blur' }
],
taskType: [
{ required: true, message: '请输入盘点类型', trigger: 'blur' }
],
location: [
{ required: true, message: '请输入目标位置', trigger: 'blur' }
],
number: [
{ required: true, message: '请输入目标数量', trigger: 'blur' }
]
},
popoverIndex: 1,
popoverVisible: [],
popoverStyles: []
}
},
computed: {
...mapGetters([
'user',
'baseApi'
]),
swiperContent() {
return this.$refs.swiperContent.$el.swiper
},
swiperTitle() {
return this.$refs.swiperTitle.$el.swiper
},
cellStyle: function() {
// const h = '100%/' + this.layerNum
// const w = '100%/' + this.rackNum
const h = '70px'
const w = '100%/' + this.rackNum
return { width: `calc(${w} - 4px )`, height: `calc(${h} - 2px)` }
}
},
async created() {
if (localStorage.getItem('dataScreenRegion')) {
const dataScreenRegion = JSON.parse(localStorage.getItem('dataScreenRegion'))
this.floorName = dataScreenRegion.floorName
this.regionName = dataScreenRegion.regionName
// /
this.tabListData = dataScreenRegion.rowType === 1
? dataScreenRegion.toward === 1
? [{ name: 'A面' }]
: [{ name: 'B面' }]
: [{ name: 'A面' }, { name: 'B面' }]
FetchBookShelfDetails({ 'shelfId': dataScreenRegion.id }).then(res => {
this.layerNum = res.shelfFloor
this.rackNum = res.shelfShelf
this.bookShelfDetails = res
this.getInitShelfGridByShelfId(this.bookShelfDetails.toward)
}).catch(() => {
})
}
},
methods: {
handleToGrids() {
this.$router.push({ path: '/dataScreening/gird', query: { }})
},
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return true
},
removeAreaPrefix(gridNames) {
const index = gridNames.indexOf('区')
if (index !== -1) {
return gridNames.substring(index + 1)
}
return gridNames
},
getInitShelfGridByShelfId(toward) {
// rowType 1 2
// toward 1 A 2 B
// shelfType 1 '1S'
// shelfType 2 'A1B1'
// shelfType 3 'B1A1'
// floorType 1 ''
// floorType 2 ''
FetchInitShelfGridByShelfId({ 'shelfId': this.bookShelfDetails.id, 'toward': toward }).then(res => {
const sortFunction = toward === 1 ? {
1: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
2: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
3: { 1: 'sortBookshelvesRightTop', 2: 'sortBookshelvesRightBottom' }
} : {
1: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
2: { 1: 'sortBookshelvesRightTop', 2: 'sortBookshelvesRightBottom' },
3: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' }
}
const shelfType = this.bookShelfDetails.shelfType
const floorType = this.bookShelfDetails.floorType
const sortMethod = sortFunction[shelfType][floorType]
this.booShelfGrid = this[sortMethod](res)
this.popoverVisible = Array(this.booShelfGrid.length).fill(false)
// this.popoverStyles = new Array(this.booShelfGrid.length).fill({ position: 'absolute', left: '20%', top: '48px' })
}).catch(() => {
})
},
// ,
sortBookshelvesLeftTop(data) {
const sortedData = []
const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.slice(-1))))
for (let i = 1; i <= maxFloor; i++) {
for (let j = 1; j <= maxShelf; j++) {
const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.slice(-1)) === j)
if (currentShelf) {
sortedData.push(currentShelf)
}
}
}
return sortedData
},
// ,,
sortBookshelvesRightTop(data) {
const sortedData = []
//
const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.match(/\d+$/)[0])))
for (let i = 1; i <= maxFloor; i++) {
//
for (let j = maxShelf; j >= 1; j--) {
const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.match(/\d+$/)[0]) === j)
if (currentShelf) {
sortedData.push(currentShelf)
}
}
}
return sortedData
},
// ,
sortBookshelvesLeftBottom(data) {
const sortedData = []
//
const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
//
const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.slice(-1))))
for (let i = maxFloor; i >= 1; i--) {
for (let j = 1; j <= maxShelf; j++) {
const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.slice(-1)) === j)
if (currentShelf) {
sortedData.push(currentShelf)
}
}
}
return sortedData
},
// ,
sortBookshelvesRightBottom(data) {
const sortedData = []
//
const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
const maxShelfPerFloor = data.map(item => parseInt(item.gridShelf.match(/\d+$/)[0]))
.reduce((acc, curr, index, arr) => {
const floor = parseInt(data[index].gridFloor)
if (!acc[floor]) acc[floor] = 1
if (acc[floor] < curr) acc[floor] = curr
return acc
}, {})
//
for (let i = maxFloor; i >= 1; i--) {
//
for (let j = maxShelfPerFloor[i] || 1; j >= 1; j--) {
const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.match(/\d+$/)[0]) === j)
if (currentShelf) {
sortedData.push(currentShelf)
}
}
}
return sortedData
},
handleSlidClickFun(index) {
this.cellIndex = null
this.handleSlideToFun(index)
if (localStorage.getItem('bookShelfDetails')) {
this.getInitShelfGridByShelfId(index + 1)
}
},
handleSlideToFun(index) {
this.swiperActiveIndex = index
this.swiperContent.slideTo(index, 500, false)
this.swiperTitle.slideTo(index, 500, false)
},
handleCellCurrent(item, index) {
console.log('index', index)
this.cellIndex = index
this.cellInfo = {
id: item.id,
gridName: item.gridName,
startSortmark: item.startSortmark,
endSortmark: item.endSortmark,
cameraId: item.cameraId,
check: item.isCheck,
order: item.isOrder
}
},
showPopover(index) {
this.popoverIndex = index
// popover
if (!this.popoverVisible[index]) {
this.$set(this.popoverVisible, index, true)
}
const lastColumnIndexes = []
const secondLastColumnIndexes = []
for (let i = 0; i < this.booShelfGrid.length; i++) {
//
const columnIndex = i % this.rackNum
// 5
if (columnIndex === this.rackNum - 1) {
lastColumnIndexes.push(i)
//
this.$set(this.popoverStyles, i, { position: 'absolute', left: '-140px', top: '48px' })
}
// 4
if (columnIndex === this.rackNum - 2) {
secondLastColumnIndexes.push(i)
//
this.$set(this.popoverStyles, i, { position: 'absolute', left: '-20px', top: '48px' })
}
}
},
hidePopover() {
this.popoverIndex = null
// popover
this.popoverVisible.forEach((isVisible, index) => {
if (isVisible) {
this.$set(this.popoverVisible, index, false)
}
})
}
}
}
</script>
<style lang="scss" scoped>
.container-right{
min-height: calc(100vh - 232px) !important;
}
.venue-content{
position: relative;
}
.crud-opts{
position: absolute;
right: 20px;
top: 10px;
}
.venue-left{
flex: 1;
margin-right: 0 !important;
.venue-preview{
height: 633px !important;
}
}
.venue-right{
display: flex;
flex-direction: column;
width: 400px;
padding: 50px 10px 20px 10px !important;
.lib-right-item{
position: relative;
padding-bottom: 10px;
margin-bottom: 10px;
border: 1px solid #E8F2FF;
border-radius: 4px;
h4{
padding: 6px 10px;
background-color: #E8F2FF;
color: #000;
line-height: 30px;
border-bottom: 1px solid #edeff3;
}
.refresh-date{
position: absolute;
right: 14px;
top: 10px;
font-size: 12px;
line-height: 30px;
}
}
}
.data-right-list {
padding-top: 10px;
li{
display: flex;
justify-content: flex-start;
align-items: center;
line-height: 36px;
p{
width: 80px;
font-weight: bold;
text-align: right;
}
span{
width: 140px;
display: block;
text-align: right;
i{
font-style: normal;
font-weight: bold;
padding: 0 10px;
color: #0348f3;
}
&.percentage{
width: auto;
}
}
}
}
.swiper-title{
::v-deep .swiper-wrapper{
margin: 10px 0;
border-bottom: 1px solid #EDEFF3;
}
}
.swiper-slide-title {
width: auto !important;
margin-right: 20px;
cursor: pointer;
.tab-name {
padding: 10px;
&.active {
color: #0348F3;
border-bottom: 3px solid #0348F3;
}
}
}
.swiper-content{
height: 610px;
}
.tag-info{
position: absolute;
right: 20px;
top: 34px;
display: flex;
justify-content: flex-start;
padding-left: 100px;
p{
margin-left: 20px;
margin-top: -4px;
font-size: 14px;
}
}
.cabinet-row .cabinet-cell{
background: url('~@/assets/images/shelf02.png') repeat-x left top;
background-size: 100% 100%;
border: none;
overflow: inherit;
cursor: pointer;
&::before{
content: "";
position: absolute;
left: 0;
top: 0;
width: 6px;
height: 68px;
background: url('~@/assets/images/shelf01.png') no-repeat left top;
background-size: 100% 100%;
}
&::after{
content: "";
position: absolute;
right: -4px;
top: 0;
width: 6px;
height: 68px;
background: url('~@/assets/images/shelf01.png') no-repeat left top;
background-size: 100% 100%;
}
span.cell-name{
position: initial !important;
transform: none;
line-height: 68px;
}
}
::v-deep .cabinet-row .cabinet-cell span.el-popover__reference-wrapper{
position: absolute !important;
left: 50% !important;
top: 20px !important;
transform: none;
width: 300px;
height: 210px;
background:rgba(0,0,0,.8);
color: #fff;
border-radius: 6px;
z-index: 99999999;
.popover-content{
.tooltip-top{
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
line-height: 40px;
padding: 0 10px;
border-bottom: 1px solid #fff;
}
.tooltip-top i{
font-style: normal;
font-size: 12px;
}
ul{
padding: 10px;
}
ul li{
display: flex;
justify-content: flex-start;
align-items: center;
line-height: 36px;
font-style: normal;
}
ul li p{
width: 80px;
font-weight: bold;
text-align: right;
}
ul li em{
width: 100px;
display: block;
text-align: right;
font-style: normal;
}
ul li i{
font-style: normal;
font-weight: bold;
padding: 0 10px;
color: #0348f3;
}
ul li em.percentage{
width: auto;
}
}
}
</style>

148
src/views/visualCheck/checkManage/dataScreening/shelfList.vue

@ -18,8 +18,8 @@
<div class="venue-content dataScreening-content">
<crudOperation :permission="permission">
<template v-slot:middle>
<el-select v-model="layerVal" clearable size="small" placeholder="楼层" class="filter-item" style="width: 100px; margin-right: 10px;">
<el-option v-for="item in layerOptions" :key="item.id" :label="item.name" :value="item.id" />
<el-select v-model="layerVal" size="small" placeholder="楼层" class="filter-item" style="width: 100px; margin-right: 10px;" value-key="id" @change="changeShelfGetGrid">
<el-option v-for="item in layerOptions" :key="item.id" :label="item.name" :value="item" />
</el-select>
<el-button v-permission="permission.add" class="check-btn" size="mini" @click="toAdd(4)">
<i class="iconfont icon-shengchengpandiandan" />
@ -43,9 +43,9 @@
<span class="tab-right-img" />
</ul>
<div class="tag-info">
<p class="tag-sort">错序<i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-place">错架<i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-all">在架<i class="iconfont icon-zhuangtai2" />20</p>
<p class="tag-sort">错序<i class="iconfont icon-zhuangtai2" /></p>
<p class="tag-place">错架<i class="iconfont icon-zhuangtai2" /></p>
<p class="tag-all">在架<i class="iconfont icon-zhuangtai2" /></p>
</div>
<!-- </div> -->
<div class="shelf-top" :style="rowStyle">
@ -65,9 +65,9 @@
>
<div class="mask" />
<div class="tag-info">
<p class="tag-sort"><i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-place"><i class="iconfont icon-zhuangtai2" />1</p>
<p class="tag-all"><i class="iconfont icon-zhuangtai2" />20</p>
<p class="tag-sort"><i class="iconfont icon-zhuangtai2" />{{ cell.errorOrderNum }}</p>
<p class="tag-place"><i class="iconfont icon-zhuangtai2" />{{ cell.errorShelfNum }}</p>
<p class="tag-all"><i class="iconfont icon-zhuangtai2" />{{ cell.onShelfNum }}</p>
</div>
<el-popover
v-if="popoverIndex === i"
@ -84,9 +84,9 @@
</div>
<ul>
<li><p>架位</p><em class="percentage"><i style="color: #fff;">{{ removeAreaPrefix(cell.gridName) }}</i></em></li>
<li><p>在架</p><em><i>15000</i></em></li>
<li><p>错架</p><em><i>300</i></em> <em class="percentage">2.00%</em></li>
<li><p>错序</p><em><i>0</i></em><em class="percentage">0.00%</em></li>
<li><p>在架</p><em><i>{{ itemStockData.onShelfNum }}</i></em></li>
<li><p>错架</p><em><i>{{ itemStockData.errorShelfNum }}</i></em> <em class="percentage">{{ itemStockData.errorShelfProbo }}</em></li>
<li><p>错序</p><em><i>{{ itemStockData.errorOrderNum }}</i></em><em class="percentage">{{ itemStockData.errorOrderProbo }}</em></li>
</ul>
</div>
</el-popover>
@ -98,17 +98,17 @@
<div class="lib-right-item lib-info">
<h4>书架概况</h4>
<ul class="data-right-list">
<li><p>书架</p><span><i>001</i></span></li>
<li><p>规格</p><span><i>双面 6 x 5</i></span></li>
<li><p>书架</p><span><i>{{ bookShelfDetails.shelfName }}</i></span></li>
<li><p>规格</p><span><i>{{ bookShelfDetails.rowType===1?'单面':'双面' }} {{ bookShelfDetails.shelfFloor }} x {{ bookShelfDetails.shelfShelf }}</i></span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>书架盘点概况</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<div class="refresh-date">{{ bookShelfDetails.update_time | parseTime }}</div>
<ul class="data-right-list">
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
<li><p>在架</p><span><i>{{ baseStockData.onShelfNum }}</i></span></li>
<li><p>错架</p><span><i>{{ baseStockData.errorShelfNum }}</i></span> <span class="percentage">{{ baseStockData.errorShelfProbo }}</span></li>
<li><p>错序</p><span><i>{{ baseStockData.errorOrderNum }}</i></span><span class="percentage">{{ baseStockData.errorOrderProbo }}</span></li>
</ul>
</div>
</div>
@ -118,7 +118,9 @@
</template>
<script>
import { FetchInitShelfGridByShelfId, FetchBookShelfDetails } from '@/api/shelf/index'
import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
import { FetchInitBookShelfList, FetchInitShelfGridByShelfId, FetchBookShelfDetails } from '@/api/shelf/index'
import { FetchInitStockInfo } from '@/api/stockTask/index'
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
@ -140,7 +142,7 @@ export default {
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), crud()],
mixins: [presenter(), header(), crud(), dataScreeningCrud],
data() {
const _this = this
return {
@ -149,9 +151,11 @@ export default {
floorTabIndex: 0,
regionTabIndex: 0,
floorName: null,
floorId: null,
regionName: null,
regionId: null,
rowType: null,
bookShelfDetails: null,
bookShelfDetails: {},
booShelfGrid: [],
cellInfo: {
gridName: null,
@ -179,8 +183,8 @@ export default {
slidesPerView: 'auto',
freeMode: true
},
layerVal: '001排',
layerOptions: [{ id: 1, name: '001排' }],
layerVal: null,
layerOptions: [],
tabListData: [],
permission: {
add: ['admin', 'floor:add'],
@ -190,7 +194,8 @@ export default {
popoverIndex: null,
popoverVisible: [],
popoverStyles: [],
activeColumns: {}
activeColumns: {},
itemStockData: {}
}
},
computed: {
@ -243,39 +248,77 @@ export default {
if (localStorage.getItem('dataScreenRegion')) {
const dataScreenRegion = JSON.parse(localStorage.getItem('dataScreenRegion'))
this.floorName = dataScreenRegion.floorName
this.floorId = dataScreenRegion.floorId
this.regionName = dataScreenRegion.regionName
this.regionId = dataScreenRegion.regionId
this.rowType = dataScreenRegion.rowType
this.initData(dataScreenRegion)
this.getInitBookShelfList(dataScreenRegion)
this.getInitStockInfo(dataScreenRegion)
}
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return true
},
initData(data) {
// /
this.tabListData = dataScreenRegion.rowType === 1
? dataScreenRegion.toward === 1
this.tabListData = data.rowType === 1
? data.toward === 1
? [{ name: 'A面' }]
: [{ name: 'B面' }]
: [{ name: 'A面' }, { name: 'B面' }]
this.tabIndex = this.$route.query.tabIndex ? this.$route.query.tabIndex : 0
FetchBookShelfDetails({ 'shelfId': dataScreenRegion.id }).then(res => {
this
FetchBookShelfDetails({ 'shelfId': data.id }).then(res => {
this.layerNum = res.shelfFloor
this.rackNum = res.shelfShelf
this.bookShelfDetails = res
if (this.$route.query.tabIndex) {
this.getInitShelfGridByShelfId(this.$route.query.tabIndex + 1)
this.getInitShelfGridByShelfId(this.bookShelfDetails.id, this.$route.query.tabIndex + 1)
} else {
this.getInitShelfGridByShelfId(this.bookShelfDetails.toward)
this.getInitShelfGridByShelfId(this.bookShelfDetails.id, this.bookShelfDetails.toward)
}
}).catch(() => {
})
}
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
getInitStockInfo(data) {
const params = {
'floorId': this.floorId,
'regionId': this.regionId,
'shelfId': data.id
}
this.handleInitStockInfo(params)
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return true
getInitBookShelfList(data) {
const params = { 'floorId': data.floorId, 'regionId': data.regionId }
FetchInitBookShelfList(params).then(res => {
this.layerOptions = res.content.map(item => {
return {
name: item.shelfName,
id: item.shelfId,
toward: item.toward,
rowType: item.rowType
}
})
this.layerVal = data
}).catch(() => {
})
},
changeShelfGetGrid(val) {
console.log('val', val)
this.initData(val)
this.getInitStockInfo(val)
},
toAdd(type) {
this.$refs.eform.formVisible = true
@ -286,7 +329,7 @@ export default {
removeAreaPrefix(gridNames) {
return gridNames.replace(/\d*区|\d*层/g, '')
},
getInitShelfGridByShelfId(toward) {
getInitShelfGridByShelfId(shelfId, toward) {
this.listLoading = true
// rowType 1 2
// toward 1 A 2 B
@ -295,7 +338,7 @@ export default {
// shelfType 3 'B1A1'
// floorType 1 ''
// floorType 2 ''
FetchInitShelfGridByShelfId({ 'shelfId': this.bookShelfDetails.id, 'toward': toward }).then(res => {
FetchInitShelfGridByShelfId({ 'shelfId': shelfId, 'toward': toward }).then(res => {
const sortFunction = toward === 1 ? {
1: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
2: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
@ -310,8 +353,6 @@ export default {
const sortMethod = sortFunction[shelfType][floorType]
this.booShelfGrid = this[sortMethod](res)
console.log('booShelfGrid', this.booShelfGrid)
this.popoverVisible = Array(this.booShelfGrid.length).fill(false)
setTimeout(() => {
this.listLoading = false
@ -396,7 +437,7 @@ export default {
changeActiveTab(index) {
this.tabIndex = index
this.cellIndex = null
this.getInitShelfGridByShelfId(index + 1)
this.getInitShelfGridByShelfId(this.layerVal.id, index + 1)
},
handleCellCurrent(item, index) {
console.log('index', index)
@ -410,7 +451,7 @@ export default {
shelfId: item.shelfId,
floorName: this.floorName,
regionName: this.regionName,
rowType: this.rowType,
rowType: this.layerVal.rowType,
toward: item.toward
}
this.currentShelfAllGrid = this.booShelfGrid.filter(gird => gird.gridShelf === item.gridShelf)
@ -418,6 +459,14 @@ export default {
},
handleToGrids(data, currentShelfAllGrid) {
this.$router.push({ path: '/dataScreening/gird' })
if (localStorage.getItem('dataScreenRegion')) {
const dataScreenRegion = JSON.parse(localStorage.getItem('dataScreenRegion'))
dataScreenRegion.rowType = this.layerVal.rowType
dataScreenRegion.toward = this.layerVal.toward
dataScreenRegion.name = this.layerVal.name
dataScreenRegion.id = this.layerVal.id
localStorage.setItem('dataScreenRegion', JSON.stringify(dataScreenRegion))
}
localStorage.setItem('dataScreenShelf', JSON.stringify(data))
localStorage.setItem('dataScreenShelfAllGrid', JSON.stringify(currentShelfAllGrid))
localStorage.setItem('dataScreenShelfTableIndex', this.tabIndex)
@ -454,6 +503,19 @@ export default {
}
const columnIndex = index % this.rackNum
this.activeColumns[columnIndex] = true
const params = {
'floorId': this.floorId,
'regionId': this.regionId,
'shelfId': this.bookShelfDetails.id,
'gridShelf': this.booShelfGrid[columnIndex].gridShelf
}
console.log(params)
// this.handleInitStockInfo(params)
FetchInitStockInfo(params).then(res => {
this.itemStockData = res
}).catch(() => {
})
},
isActiveColumn(index) {
const columnIndex = index % this.rackNum

179
src/views/visualCheck/checkManage/paramSetting/index.vue

@ -8,6 +8,7 @@
<el-form-item label="AI处理终端IP" prop="ip">
<el-input v-model="form.ip" placeholder="请输入IP地址,如:192.168.1.1" style="width: 300px;" />
</el-form-item>
<div v-if="form.ip" style="margin-left: 20px; margin-top: 6px; cursor: pointer;" @click="handleService"><i class="iconfont icon-bendiguajie" /></div>
<p style="line-height: 32px; margin-left: 20px; font-size: 12px;">设置成功后方可执行视觉盘点任务</p>
</el-row>
<el-row style="display: flex; justify-content: flex-start;">
@ -40,11 +41,56 @@
</div>
</div>
</el-dialog>
<el-dialog class="tip-dialog tip-middle-dialog" title="AI处理终端连接测试" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="serviceDialogVisible" :before-close="handleClose">
<div class="setting-dialog tip-service">
<i class="iconfont icon-lianjieduankai" />
<div class="tip-service-content">
<p>终端连接超时请检查配置是否正确或终端是否运行成功!</p>
<p>请尽快联系系统维护人员进行恢复</p>
</div>
</div>
</el-dialog>
<el-dialog class="tip-dialog tip-middle-dialog" title="AI处理终端连接测试" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="serviceContentDialogVisible" :before-close="handleClose">
<div class="setting-dialog service-all">
<div class="service-top-text"><i class="iconfont icon-zhongduanjiankong" />终端连接正常</div>
<ul>
<li>
<p :class="service.service_imgCamera.status === 'running' ? 'true-active' : 'false-active' ">图像采集</p>
<i v-if="service.service_imgCamera.status === 'running'" class="iconfont icon-shi" />
<i v-else class="iconfont icon-cuowu1" />
</li>
<li>
<p :class="service.service_imgProcess.status === 'running' ? 'true-active' : 'false-active' ">图像处理</p>
<i v-if="service.service_imgProcess.status === 'running'" class="iconfont icon-shi" />
<i v-else class="iconfont icon-cuowu1" />
</li>
<li>
<p :class="service.service_imgYolo.status === 'running' ? 'true-active' : 'false-active' ">图像识别</p>
<i v-if="service.service_imgYolo.status === 'running'" class="iconfont icon-shi" />
<i v-else class="iconfont icon-cuowu1" />
</li>
<li>
<p :class="service.service_imgOcr.status === 'running' ? 'true-active' : 'false-active' ">文字识别</p>
<i v-if="service.service_imgOcr.status === 'running'" class="iconfont icon-shi" />
<i v-else class="iconfont icon-cuowu1" />
</li>
<li>
<p :class="service.service_imgResult.status === 'running' ? 'true-active' : 'false-active' ">同步服务</p>
<i v-if="service.service_imgResult.status === 'running'" class="iconfont icon-shi" />
<i v-else class="iconfont icon-cuowu1" />
</li>
</ul>
<div v-if="isAllServicesRunning" class="service-bottom-text" style="color: rgb(18, 196, 122);">所有服务均正常运行请放心使用</div>
<div v-else class="service-bottom-text" style="color: #ED4A41;">请尽快联系系统维护人员进行恢复</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudStockTask from '@/api/stockTask/index'
import crudStockTask, { FetchAITerminalStatusQuery } from '@/api/stockTask/index'
import { encrypt } from '@/utils/rsaEncrypt'
import { verifyMaintenance } from '@/api/system/param'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
@ -96,13 +142,25 @@ export default {
maxNum: [
{ required: true, message: '层位占用上限不可为空', trigger: 'blur' }
]
},
serviceDialogVisible: false,
serviceContentDialogVisible: false,
service: {
'service_imgCamera': { 'last_heartbeat': 1736496962.2368362, 'status': '' },
'service_imgProcess': { 'last_heartbeat': 1736496960.8598323, 'status': '' },
'service_imgYolo': { 'last_heartbeat': 1736496961.953832, 'status': '' },
'service_imgOcr': { 'last_heartbeat': 1736496961.6238313, 'status': '' },
'service_imgResult': { 'last_heartbeat': 1736496963.4378026, 'status': '' }
}
}
},
computed: {
...mapGetters([
'baseApi'
])
]),
isAllServicesRunning() {
return Object.values(this.service).every(service => service.status === 'running')
}
},
created() {
crudStockTask.FetchInitSetting().then(res => {
@ -113,6 +171,24 @@ export default {
})
},
methods: {
handleService() {
FetchAITerminalStatusQuery({ 'ip': this.crud.form.ip }).then(res => {
// {
// "service_imgCamera":{"last_heartbeat":1736496962.2368362,"status":"running"},
// "service_imgProcess":{"last_heartbeat":1736496960.8598323,"status":"running"},
// "service_imgYolo":{"last_heartbeat":1736496961.953832,"status":"running"}
// "service_imgOcr":{"last_heartbeat":1736496961.6238313,"status":"running"},
// "service_imgResult":{"last_heartbeat":1736496963.4378026,"status":"running"},
// }
if (res) {
this.service = JSON.parse(res)
this.serviceContentDialogVisible = true
} else {
this.serviceDialogVisible = true
}
}).catch(() => {
})
},
[CRUD.HOOK.beforeToCU](crud, form, btn) {
if (this.showVerifyDialog) {
//
@ -167,6 +243,9 @@ export default {
this.$refs.verfiyForm.resetFields()
this.verifyDialogVisible = false
}
this.serviceContentDialogVisible = false
this.serviceDialogVisible = false
}
}
}
@ -176,4 +255,100 @@ export default {
::v-deep div.el-dialog__footer {
text-align: center;
}
.tip-service{
display: flex;
justify-content: center;
color: #0C0E1E;
font-size: 16px;
line-height: 40px;
padding: 40px !important;
.iconfont{
font-size: 30px;
margin-right: 10px;
color: #ED4A41;
}
p{
&:first-child{
color: #ED4A41;
}
}
}
.service-all{
text-align: center;
padding: 30px 0 30px 0 !important;
color: #0C0E1E;
ul{
display: flex;
justify-content: space-between;
padding: 60px 0 40px 0;
li{
position: relative;
&::before{
content: "";
position: absolute;
left: 50%;
top: -30px;
width: 1px;
height: 20px;
background-color: #9098a4;
margin-left: -1px;
}
p{
padding: 5px;
border: 1px solid #9098a4;
margin-bottom: 10px;
border-radius: 4px;
&.false-active{
border-color: #ED4A41;
color: #ED4A41;
}
&.true-active{
border-color: rgb(18, 196, 122);
color: rgb(18, 196, 122);
}
}
.iconfont::before{
margin-right: 0 !important;
}
.icon-cuowu1{
color: #ED4A41;
}
.icon-shi{
color: rgb(18, 196, 122);
}
}
}
.service-top-text{
position: relative;
font-size: 18px;
margin: 0 33px;
color: rgb(18, 196, 122);
i.iconfont{
font-size: 18px;
margin-right: 6px;
}
&::before{
content: "";
position: absolute;
left: 50%;
bottom: -30px;
width: 1px;
height: 20px;
background-color:#9098a4;
margin-left: -1px;
}
&::after{
content: "";
position: absolute;
left: 0;
bottom: -30px;
width: 100%;
height: 1px;
background-color: #9098a4;
margin-left: -1px;
}
}
}
</style>

37
src/views/visualCheck/mixins/index.js

@ -0,0 +1,37 @@
import { FetchInitHomeInfo, FetchInitStockInfo } from '@/api/stockTask/index'
import { mapGetters } from 'vuex'
export const dataScreeningCrud = {
mixins: [],
// 组件共用属性
data() {
return {
baseData: {},
baseStockData: {}
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
// 组件挂载时的共用方法
mounted() {
this.handleInitHomeInfo()
},
// 组件共用方法
methods: {
handleInitHomeInfo() {
FetchInitHomeInfo().then(res => {
this.baseData = res
}).catch(() => {
})
},
handleInitStockInfo(params) {
FetchInitStockInfo(params).then(res => {
this.baseStockData = res
}).catch(() => {
})
}
}
}

21
src/views/visualCheck/venueDevice/bookshelf/index.vue

@ -573,19 +573,18 @@ export default {
this.crud.delAllLoading = true
const ids = []
datas.forEach(val => {
ids.push(val.id)
ids.push(val.shelfId)
})
console.log(ids)
this.$message({ message: '等后面板块做完再做这个', type: 'error', offset: 8 })
// crudShelf.del(ids).then(res => {
// console.log(res)
// this.$message({ message: res, type: 'success', offset: 8 })
// this.crud.delAllLoading = false
// this.crud.refresh()
// }).catch(err => {
// this.crud.delAllLoading = false
// console.log(err)
// })
crudShelf.del(ids).then(res => {
console.log(res)
this.$message({ message: res, type: 'success', offset: 8 })
this.crud.delAllLoading = false
this.crud.refresh()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err)
})
}).catch(() => {
this.crud.delAllLoading = false
})

Loading…
Cancel
Save