Browse Source

查漏补缺页面

master
xuhuajiao 6 months ago
parent
commit
6ef4e664ef
  1. 10
      src/assets/iconfonts/light/iconfont.css
  2. 2
      src/assets/iconfonts/light/iconfont.js
  3. 7
      src/assets/iconfonts/light/iconfont.json
  4. BIN
      src/assets/iconfonts/light/iconfont.ttf
  5. BIN
      src/assets/iconfonts/light/iconfont.woff
  6. BIN
      src/assets/iconfonts/light/iconfont.woff2
  7. BIN
      src/assets/images/shelf03-1.png
  8. BIN
      src/assets/images/shelf03.png
  9. BIN
      src/assets/images/shelf05.png
  10. BIN
      src/assets/images/shelf06.png
  11. 1
      src/views/visualCheck/checkManage/bookSearch/index.vue
  12. 265
      src/views/visualCheck/checkManage/bookshelfSearch/index.vue
  13. 137
      src/views/visualCheck/checkManage/checkLog/index.vue
  14. 27
      src/views/visualCheck/checkManage/checkPlan/index.vue
  15. 21
      src/views/visualCheck/checkManage/dataScreening/girdList.vue
  16. 20
      src/views/visualCheck/checkManage/dataScreening/shelfList.vue

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

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

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

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

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "10014347",
"name": "终止",
"font_class": "stop",
"unicode": "e714",
"unicode_decimal": 59156
},
{
"icon_id": "13446589",
"name": "状态",

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

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

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

BIN
src/assets/images/shelf03-1.png

After

Width: 48  |  Height: 192  |  Size: 2.1 KiB

BIN
src/assets/images/shelf03.png

Before

Width: 48  |  Height: 192  |  Size: 2.1 KiB

After

Width: 97  |  Height: 267  |  Size: 7.1 KiB

BIN
src/assets/images/shelf05.png

After

Width: 97  |  Height: 267  |  Size: 7.2 KiB

BIN
src/assets/images/shelf06.png

After

Width: 97  |  Height: 267  |  Size: 3.2 KiB

1
src/views/visualCheck/checkManage/bookSearch/index.vue

@ -244,6 +244,7 @@ export default {
]
},
tabIndex: 0,
defaultImg: defaultImg,
imageUrl: defaultImg
}
},

265
src/views/visualCheck/checkManage/bookshelfSearch/index.vue

@ -3,13 +3,11 @@
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.floorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 100px" @change="changeFloorValue">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in floorOptions" :key="item.key" :label="item.floorName" :value="item.id" />
<el-select v-model="selectFloorVal" clearable size="small" placeholder="楼层" class="filter-item" style="width: 80px" value-key="id" @change="changeBeforeFloor">
<el-option v-for="(item,index) in floorOptions" :key="index" :label="item.floorName" :value="item" />
</el-select>
<el-select v-model="query.regionId" clearable size="small" placeholder="区域" class="filter-item" style="width: 180px" @change="crud.toQuery">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in regionOptions" :key="item.key" :label="item.regionName" :value="item.id" />
<el-select v-model="selectRegionVal" clearable size="small" placeholder="区域" class="filter-item" style="width: 120px" value-key="id" @change="changeBeforeRegion">
<el-option v-for="(item,index) in regionOptions" :key="index" :label="item.regionName" :value="item" />
</el-select>
<el-input v-model="query.search" clearable size="small" placeholder="输入检索条件检索" prefix-icon="el-icon-search" style="width: 220px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" />
<rrOperation />
@ -38,8 +36,8 @@
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="regionName" label="层位名称" />
<el-table-column prop="regionCode" label="所属楼层" />
<el-table-column prop="floorName" label="所属区域" />
<el-table-column prop="floorName" label="所属楼层" />
<el-table-column prop="regionName" label="所属区域" />
<el-table-column prop="booksheflCount" label="盘点开关" align="center">
<!-- slot-scope="scope" -->
<template>
@ -69,9 +67,8 @@
</template>
</el-table-column>
<el-table-column prop="createTime" label="操作">
<!-- slot-scope="scope" -->
<template>
<el-button>定位</el-button>
<template slot-scope="scope">
<el-button @click="handlePosition(scope.row)">定位</el-button>
</template>
</el-table-column>
</el-table>
@ -79,25 +76,61 @@
<pagination v-if="crud.data.length!==0" />
</div>
<el-dialog class="positionDialog" append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseDialog" :visible="positionVisible" :title="positionTitle+' - 层位定位'">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<ul class="book-detail">
<li><span>所属机构</span>机构A</li>
<li><span>所属楼层</span>五楼</li>
<li><span>所属区域</span>区域A</li>
<li><span>所属书架</span>001排A面</li>
<li>
<i class="row-state no-state">未知</i>
<!-- <i class="row-state end-state">在架</i>
<i class="row-state cancel-state">错架</i>
<i class="row-state ing-state">错序</i> -->
</li>
</ul>
<div class="position-content">
<div class="position-left">
<h5>平面图</h5>
<div class="venue-preview">
<div v-show="currentMarkData && currentMarkData.signPoint ">
<canvas :id="`canvasPreview${currentMarkData && currentMarkData.id}`" :width="width" :height="height" />
</div>
<img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt="">
<img v-if="!currentMarkData" :src="imageUrl" :onerror="defaultImg" alt="">
</div>
</div>
<div class="position-right">
<h5>书架图</h5>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { FetchLibraryFloorListAll } from '@/api/floor/index'
import { FetchRegionAllByFloor } from '@/api/area/index'
import crudRegion from '@/api/area/index'
import { FetchInitLibraryRegionList } from '@/api/area/index'
import crudShelf from '@/api/shelf/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
import defaultImg from '@/assets/images/system/default-img.jpg'
import { fabric } from 'fabric'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
export default {
name: 'BookSearch',
components: { crudOperation, rrOperation, pagination },
cruds() {
return CRUD({ title: '架位检索', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
return CRUD({ title: '架位检索', url: 'api/bookShelf/initBookShelfList', crudMethod: { ...crudShelf }, sort: [], optShow: {
add: false,
edit: false,
del: false,
@ -115,7 +148,18 @@ export default {
del: ['admin', 'search:del']
},
floorOptions: [],
regionOptions: []
regionOptions: [],
selectFloorVal: null,
selectRegionVal: null,
positionVisible: false,
positionTitle: '001排A面01架1层',
currentMarkData: null,
defaultImg: defaultImg,
imageUrl: defaultImg,
canvasPreview: {},
width: 900,
height: 600,
drawWidth: 2 //
}
},
computed: {
@ -143,24 +187,63 @@ export default {
[CRUD.HOOK.afterValidateCU](crud) {
return false
},
changeBeforeFloor(val) {
if (val) {
this.selectFloorVal = val
this.crud.query.floorId = val.id
this.getInitLibraryRegionList(val.id)
}
},
changeBeforeRegion(val) {
if (val) {
this.selectRegionVal = val
this.crud.query.regionId = val.id
this.crud.toQuery()
}
},
//
getLibraryFloorListAll() {
FetchLibraryFloorListAll().then(res => {
this.floorOptions = res
if (this.floorOptions.length > 0) {
this.selectFloorVal = this.floorOptions[0]
this.crud.query.floorId = this.selectFloorVal.id
if (this.crud.query.floorId) {
this.getInitLibraryRegionList(this.crud.query.floorId)
}
}
}).catch(() => {
})
},
changeFloorValue(value) {
console.log(value)
this.crud.query.regionId = null
getInitLibraryRegionList(val) {
const params = {
'floorId': value
'floorId': val
}
FetchRegionAllByFloor(params).then(res => {
this.regionOptions = res
FetchInitLibraryRegionList(params).then(res => {
this.regionOptions = res.content
console.log('this.regionOptions', this.regionOptions)
if (this.regionOptions.length > 0) {
this.selectRegionVal = this.regionOptions[0]
this.crud.query.regionId = this.selectRegionVal.id
} else {
this.selectRegionVal = null
this.crud.query.regionId = null
}
this.crud.toQuery()
}).catch(() => {
})
},
// changeFloorValue(value) {
// console.log(value)
// this.crud.query.regionId = null
// const params = {
// 'floorId': value
// }
// FetchRegionAllByFloor(params).then(res => {
// this.regionOptions = res
// }).catch(() => {
// })
// },
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
@ -188,6 +271,10 @@ export default {
this.crud.downloadLoading = false
})
},
handlePosition(row) {
console.log('position', row)
this.positionVisible = true
},
handleCloseDialog() {
this.addBookShelfVisible = false
this.detailVisible = false
@ -195,6 +282,92 @@ export default {
this.crud.cancelCU()
this.$refs.form.resetFields()
}
this.positionVisible = false
},
initCanvasPreview(drawinfo) {
if (!this.currentMarkData) {
console.error('currentMarkData is null or undefined')
return
}
const canvasId = `canvasPreview${this.currentMarkData.id}`
this.canvasPreview = new fabric.Canvas(canvasId, {
skipTargetFind: false,
selectable: false,
selection: false
})
this.$nextTick(() => {
this.canvasPreview.selectionColor = 'rgba(0,0,0,0.05)'
this.loadDrawPreview(drawinfo)
this.canvasPreview.on('mouse:wheel', this.mouse)
})
},
//
mouse(e) {
if (undefined === e) return
let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvasPreview.getZoom()
zoom = Math.max(0.8, zoom)
// 1/10
zoom = Math.min(3, zoom)
// 3
const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
this.canvasPreview.zoomToPoint(zoomPoint, zoom)
},
//
loadDrawPreview(drawinfo) {
const self = this
const pointGroup = drawinfo.pointInfo
const imgInfo = drawinfo.imgInfo
imgInfo.src = self.imageUrl
//
fabric.util.enlivenObjects([imgInfo], objects => {
objects.forEach(o => {
o.selectable = false
o.hasControls = false
o.centeredScaling = false
self.canvasPreview.add(o)
})
//
pointGroup.forEach(async(item, index) => {
if (item.pointInfo !== '') {
const polygon = new fabric.Polygon(item.pointInfo, {
name: item.name,
stroke: 'rgba(196,43, 1, 1)',
strokeWidth: self.drawWidth,
fill: 'rgba(196,43, 1, 0.3)',
opacity: 1,
selectable: false,
hasBorders: false,
hasControls: false,
originX: 'left', //
originY: 'top' //
})
// polygon.index = index
self.canvasPreview.add(polygon)
polygon.on('mousedown', function(e) {
console.log('Rect ' + (index + 1) + ' clicked', e)
console.log('e.target.name', e.target.name)
})
polygon.on('mouseover', function(e) {
console.log('e', e)
console.log('e.target', e.target)
console.log('e.target.name', e.target.name)
this.set({ opacity: 0.3, hoverCursor: 'pointer' })
self.canvasPreview.renderAll()
})
//
polygon.on('mouseout', function() {
this.set({ opacity: 1 })
self.canvasPreview.renderAll()
})
}
})
})
self.canvasPreview.renderAll()
}
}
}
@ -206,4 +379,54 @@ export default {
margin-right: 20px;
}
}
.positionDialog{
::v-deep .el-dialog{
width: 1200px !important;
.el-dialog__body{
padding: 0 !important;
}
}
}
.book-detail{
position: relative;
display: flex;
justify-content: space-between;
padding: 10px 30px !important;
background-color: #F6F8FC;
li{
line-height: 40px;
span{
display: inline-block;
width: 60px;
text-align: right;
margin-right: 20px;
color: #0C0E1E;
}
i{
font-style: normal;
padding: 0 8px;
}
&:last-child{
width: 30%;
text-align: right;
}
}
}
.position-content{
display: flex;
justify-content: space-between;
padding: 20px 30px !important;
h5{
font-size: 18px;
color: #0C0E1E;
}
.position-left{
width: 600px;
overflow: hidden;
::v-deep .venue-preview{
height: 500px;
}
}
}
</style>

137
src/views/visualCheck/checkManage/checkLog/index.vue

@ -103,6 +103,76 @@
</div>
</el-dialog>
<el-dialog class="detailBook" append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseDialog" :visible="detailVisible" title="盘点详情">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div class="detail-tab tab-content">
<ul class="tab-nav">
<li :class="{'active-tab-nav': tabIndex === 0}" @click="changeDetailTab(0)">基础信息</li>
<li :class="{'active-tab-nav': tabIndex === 1}" @click="changeDetailTab(1)">层位盘点信息</li>
</ul>
<div v-if="tabIndex===0" class="detail-check">
<ul class="book-detail">
<li><span>盘点单号</span>P20241209001</li>
<li><span>盘点类型</span>全量盘点</li>
<li><span>目标位置</span>全部区域</li>
<li><span>目标数量</span>396 / 层位</li>
<li class="row-li"><span>备注</span></li>
<li><span>开始时间</span>2024-12-09 08:00:00</li>
<li><span>结束时间</span>2024-12-09 09:00:00</li>
<li class="row-li" style="margin-left: 30px;">
<i class="row-state soon-state">排队中</i>
<!-- <i class="row-state end-state">盘点中</i>
<i class="row-state cancel-state">已终止</i>
<i class="row-state ing-state">已完成</i> -->
</li>
</ul>
<div class="detail-other">
<ul class="book-detail">
<li class="row-li"><span>在架图书</span>40000 / </li>
<li><span>错架图书</span>30 / </li>
<li><span>错架率</span>0.75%</li>
<li><span>错序图书</span>5 / </li>
<li><span>错序率</span>0.01%</li>
</ul>
<div>
图表部分
</div>
</div>
</div>
<div v-if="tabIndex===1">
<el-table
ref="table"
class="archives-table"
:data="detailTable"
style="width: 100%;"
>
<el-table-column prop="regionCode" label="层位架" />
<el-table-column prop="floorName" label="楼层" />
<el-table-column prop="booksheflCount" label="区域" />
<el-table-column prop="booksheflCount" label="盘点详情" />
<el-table-column prop="booksheflCount" label="进度" />
<el-table-column prop="createTime" label="状态">
<!-- slot-scope="scope" -->
<template>
<span class="row-state row-warehousing state-active">排队中</span>
<!-- <span class="row-state row-binding state-active">盘点中</span>
<span class="row-state row-lending state-active">已终止</span>
<span class="row-state row-physical state-active">已完成</span> -->
</template>
</el-table-column>
</el-table>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" class="end-btn"><i class="iconfont icon-stop" />终止盘点</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="detailVisible=false">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
@ -148,6 +218,8 @@ export default {
{ key: '6', display_name: '层位盘点' }
],
tabIndex: 0,
detailVisible: false,
detailTable: [{}],
permission: {
add: ['admin', 'checkLog:add'],
edit: ['admin', 'checkLog:edit'],
@ -263,12 +335,75 @@ export default {
}).catch(() => {
})
},
handleDbClick() {
this.detailVisible = true
},
changeDetailTab(index) {
this.tabIndex = index
},
handleCloseDialog() {
this.detailVisible = false
}
}
}
</script>
<style lang="scss" scoped>
.detailBook {
::v-deep .el-dialog {
width: 1000px !important;
.el-dialog__body{
padding: 0 0 30px 0;
}
}
.detail-check{
padding: 20px 30px;
background-color: #F6F8FC;
}
.book-detail{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
li{
width: 50%;
line-height: 40px;
span{
display: inline-block;
width: 100px;
text-align: right;
margin-right: 20px;
color: #0C0E1E;
}
i{
font-style: normal;
padding: 0 8px;
}
&.row-li{
width: 100%
}
}
}
.end-btn{
width: auto !important;
padding: 0 10px;
border-color: #ED4A41;
background-color: #ED4A41;
}
.detail-other{
display: flex;
justify-content: space-between;
border-top: 1px solid #edeff3;
padding-top: 20px;
margin-top: 20px;
.book-detail{
width: 60%;
}
}
::v-deep .dialog-footer{
margin-top: 30px;
}
.archives-table td.el-table__cell .row-state{
margin: 0 !important;
}
}
</style>

27
src/views/visualCheck/checkManage/checkPlan/index.vue

@ -566,7 +566,7 @@ export default {
ids.push(val.id)
})
console.log(ids)
// crudRegion.del(ids).then(res => {
// crudStocktask.del(ids).then(res => {
// console.log(res)
// this.$message({ message: res, type: 'success', offset: 8 })
// this.crud.delAllLoading = false
@ -587,12 +587,25 @@ export default {
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// crudStocktask.FetchUpdateStockTaskStatus(data).then(res => {
// this.$message({ message: '', type: 'success', offset: 8 })
// this.crud.refresh()
// }).catch(() => {
// data.status = !data.status
// })
if (data.startTime) {
data.startTime = timeToTimestamp(data.startTime)
} else {
data.startTime = null
}
if (data.endTime) {
data.endTime = timeToTimestamp(data.endTime)
} else {
data.endTime = null
}
delete data.lastExecute
delete data.nextExecute
crudStocktask.FetchUpdateStockTaskStatus(data).then(res => {
this.$message({ message: '修改成功', type: 'success', offset: 8 })
this.crud.refresh()
}).catch(() => {
data.status = !data.status
})
}).catch(() => {
this.$message({ message: '已取消修改', offset: 8 })
data.status = data.status ? 0 : 1

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

@ -48,7 +48,7 @@
<div
v-for="(book,i) in bookNum"
:key="i"
class="book-item"
:class="['book-item', { 'red-active' : i===2} ,{ 'blue-active' : i===6}]"
@mouseenter="showPopover(index, i, $event)"
@mouseleave="hidePopover"
>
@ -592,7 +592,7 @@ export default {
width: calc(100% - 240px);
height: 130px;
margin-right: 5px;
padding: 0 12px;
padding: 0 16px 0 20px;
background: url('~@/assets/images/shelf02.png') repeat left top;
background-size: 10% 100%;
overflow: hidden;
@ -605,16 +605,17 @@ export default {
.book-item{
position: relative;
display: inline-block;
width: 24px;
height: 100px;
width: 42px;
height: 120px;
margin-top: 18px;
background: url('~@/assets/images/shelf03.png') no-repeat left top;
background-size: 100% 100%;
margin-left: -15px;
cursor: pointer;
span.book-name{
position: absolute;
left: 0;
top: 14px;
left: 13px;
top: 16px;
display: block;
height: 90px;
writing-mode:vertical-rl;
@ -622,6 +623,14 @@ export default {
white-space: nowrap;
text-overflow: ellipsis;
}
&.red-active{
background: url('~@/assets/images/shelf05.png') no-repeat left top;
background-size: 100% 100%;
}
&.blue-active{
background: url('~@/assets/images/shelf06.png') no-repeat left top;
background-size: 100% 100%;
}
}
}

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

@ -39,7 +39,7 @@
</div>
<!-- </div> -->
<div class="shelf-top">
<p v-for="(item,index) in rackNum" :key="index" :style="{width: `calc(${'100%/' + rackNum} - 4px )`}"><span>{{ index+1 + '架' }}</span></p>
<p v-for="(item,index) in reversedRackNum" :key="index" :style="{width: `calc(${'100%/' + rackNum} - 4px )`}"><span>{{ item + '架' }}</span></p>
</div>
<ul v-loading="listLoading" class="data-shelf-row">
<!-- :class="{ active: i === cellIndex }" -->
@ -169,7 +169,7 @@ export default {
regionName: null,
rowType: null,
bookShelfDetails: null,
booShelfGrid: null,
booShelfGrid: [],
cellInfo: {
gridName: null,
startSortmark: null,
@ -240,6 +240,20 @@ export default {
const h = '76px'
const w = '100%/' + this.rackNum
return { width: `calc(${w} )`, height: `calc(${h})` }
},
reversedRackNum() {
if (this.booShelfGrid && this.booShelfGrid.length > 0) {
console.log('ddd')
console.log('this.booShelfGrid[0].gridShelf', this.booShelfGrid[0].gridShelf)
if (this.booShelfGrid[0].gridShelf === '07') {
return Array.from({ length: this.rackNum }, (_, i) => this.rackNum - i).map(x => x.toString())
} else {
return Array.from({ length: this.rackNum }, (_, i) => i + 1).map(x => x.toString())
}
} else {
console.log('fff')
return []
}
}
},
async created() {
@ -305,6 +319,8 @@ export default {
const sortMethod = sortFunction[shelfType][floorType]
this.booShelfGrid = this[sortMethod](res)
console.log(this.booShelfGrid[0].gridShelf)
this.popoverVisible = Array(this.booShelfGrid.length).fill(false)
setTimeout(() => {
this.listLoading = false

Loading…
Cancel
Save