Browse Source

盘点

master
xuhuajiao 2 weeks ago
parent
commit
1b94f911dc
  1. 1
      .env.development
  2. 1
      .env.production
  3. 6
      public/static/config.js
  4. 10
      src/api/stockTaskLog/index.js
  5. 2
      src/views/components/hkVideo.vue
  6. 135
      src/views/visualCheck/checkManage/checkLog/index.vue
  7. 179
      src/views/visualCheck/checkManage/dataScreening/module/form.vue

1
.env.development

@ -6,6 +6,7 @@ ENV = 'development'
VUE_APP_BASE_API = 'http://192.168.99.72:12010'
#VUE_APP_BASE_API = 'http://192.168.99.86:12010'
#VUE_APP_BASE_API = 'http://27.19.205.234:17070'
VUE_APP_WEBRTCSTREAMER_API = '127.0.0.1:8000'
# 是否启用 babel-plugin-dynamic-import-node插件

1
.env.production

@ -5,6 +5,7 @@ ENV = 'production'
#VUE_APP_BASE_API = 'http://192.168.3.220:12010'
VUE_APP_BASE_API = 'http://192.168.99.86:12010'
VUE_APP_WEBRTCSTREAMER_API = '127.0.0.1:8000'
# 如果接口是 http 形式, wss 需要改为 ws
#VUE_APP_WS_API = 'ws://27.16.212.58:11100'
#VUE_APP_CAMERA_API = '192.168.99.107:3000'

6
public/static/config.js

@ -2,9 +2,5 @@ window.g = {
AXIOS_TIMEOUT: 10000,
//ApiUrl: 'http://192.168.3.220:12010', // 江夏配置服务器地址,
ApiUrl: 'http://192.168.99.86:12010', // 配置服务器地址,
// ParentPage: { // 后续看需求配置
// CrossDomainProxyUrl: '/Home/CrossDomainProxy',
// BtnsApi: '/api/services/app/Authorization/GetBtns',
// OrgsApi: '/api/services/app/authorization/GetOrgsByUserId'
// },
ApiWebRtcServerUrl: '127.0.0.1:8000' // 配置视频数据流服务器地址,
}

10
src/api/stockTaskLog/index.js

@ -100,4 +100,12 @@ export function add(data) {
})
}
export default { del, FetchStopStockBill, FetchInitStockLogList, FetchInitStockLogDetails, FetchProgressByStockBillAndGridCode, FetchInitStockTaskDetails, FetchNewBillNo, FetchStockGirdNum, FetchTotalGirdNum, add }
// 获取目标可盘层架信息
export function FetchStockGirdSuccess(params) {
return request({
url: 'api/stocktask-task/getStockGirdSuccess' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { del, FetchStopStockBill, FetchInitStockLogList, FetchInitStockLogDetails, FetchProgressByStockBillAndGridCode, FetchInitStockTaskDetails, FetchNewBillNo, FetchStockGirdNum, FetchTotalGirdNum, add, FetchStockGirdSuccess }

2
src/views/components/hkVideo.vue

@ -50,6 +50,8 @@ export default {
})
},
initVideo() {
const linkSrc = process.env.NODE_ENV === 'production' ? window.g.ApiWebRtcServerUrl : process.env.VUE_APP_WEBRTCSTREAMER_API
this.camera_ip = linkSrc
// videovideoID
// 127.0.0.1:8000webrtc-streamerIP8000
// eslint-disable-next-line no-undef

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

@ -88,10 +88,11 @@
</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">
<el-dialog :class="unreachable.length !== 0 ? 'stock-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">
<div class="setting-dialog" style="display: flex; justify-content: flex-start;">
<div :style=" {'width': unreachable.length !== 0 ? '670px':''}">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="盘点单号" prop="stockBill">
<el-input v-model="form.stockBill" disabled />
@ -102,8 +103,30 @@
<el-form-item label="目标位置" prop="stockRegion">
<el-input v-model="form.stockRegion" disabled />
</el-form-item>
<el-form-item label="目标数量" prop="stockGridNumName">
<el-input v-model="form.stockGridNumName" disabled />
<el-form-item
class="stockGridNumName-style"
label="目标数量"
prop="stockGridNumName"
>
<span v-if="stockInfoLoading" class="el-icon-loading" />
<!-- <el-input v-else disabled v-html="form.stockGridNumName" /> -->
<div v-else style="display: flex; justify-content: flex-start;">
<el-input disabled v-html="form.stockGridNumName" />
<el-popover
class="stock-popover"
placement="top-start"
width="250"
trigger="hover"
>
<div>
<span style="display:block; font-weight: bold; margin-bottom: 10px;">A / B / C 层位 </span>
A开启盘点功能 当前可盘点 层位数量<br>
B开启盘点功能 当前不可盘点 层为数量<br>
C具备盘点功能的 层位数量
</div>
<i slot="reference" class="iconfont icon-zhuyi-lan" />
</el-popover>
</div>
</el-form-item>
<el-row>
<el-form-item label="备注" prop="stockRemarks">
@ -111,9 +134,34 @@
</el-form-item>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<div slot="footer" class="dialog-footer" style="padding-right: 20px;">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
<el-button :disabled="isBtnDisabled" :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div>
</div>
<div v-if="unreachable.length !== 0" style="width: 500px; margin-left: 10px;">
<div class="stock-info-tips">
<p>注意系统检查到有参与本次盘点的摄像头无法连接<i>{{ reachable.length }}</i>/个层架位可盘点</p>
<span>不可盘点具体情况如下</span>
</div>
<div style="display: flex; justify-content: space-between;">
<el-card class="box-card">
<div slot="header">
<span>无法连接的摄像头 <i style="color: #f53f3f; font-weight: bold; font-style: normal;">{{ ipStatusFalseNum }}</i> /)</span>
</div>
<div v-for="(item,index) in ipStatusFalse" :key="index" class="stock-info-item">
<span> {{ item.ip }} </span>
</div>
</el-card>
<el-card class="box-card">
<div slot="header">
<span>无法盘点的层架位 <i style="color: #f53f3f; font-weight: bold; font-style: normal;">{{ unreachable.length }}</i> /</span>
</div>
<div v-for="(item,index) in unreachable" :key="index" class="stock-info-item">
<span> {{ item.gridName }} </span>
</div>
</el-card>
</div>
</div>
</div>
</el-dialog>
@ -204,6 +252,7 @@
<span>{{ scope.row.progress !== null ? scope.row.progress : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="progress" label="备注" min-width="140" :show-overflow-tooltip="true" />
<el-table-column prop="state" label="状态" width="80">
<template slot-scope="scope">
<span v-if="scope.row.state === 0" class="row-state row-lending state-active">已终止</span>
@ -250,7 +299,7 @@ import { mapGetters } from 'vuex'
import { parseTime, saveAs, getBlob } from '@/utils/index'
import qs from 'qs'
const defaultForm = { stockTypeName: '全量盘点', stockType: 1, stockBill: null, stockRegion: '全部区域', stockGridNum: null, stockGridNumName: null, totalGridNum: null, stockRemarks: null, regionId: null, shelfId: null, gridShelf: null, gridId: null }
const defaultForm = { stockTypeName: '全量盘点', stockType: 1, stockBill: null, stockRegion: '全部区域', stockGridNum: null, stockGridNumName: null, totalGridNum: null, stockRemarks: null, regionId: null, shelfId: null, gridShelf: null, gridId: null, reableGridIds: [], unReableGridIds: [] }
export default {
name: 'CheckLog',
components: { crudOperation, rrOperation, pagination, taskStockLogEcharts, DateRangePicker },
@ -313,7 +362,14 @@ export default {
stockGridNumName: [
{ required: true, message: '请输入目标数量', trigger: 'blur' }
]
}
},
stockInfo: null,
ipStatusList: [],
ipStatusFalseNum: 0,
unreachable: [],
reachable: [],
isBtnDisabled: true,
stockInfoLoading: false
}
},
computed: {
@ -333,6 +389,8 @@ export default {
}
},
[CRUD.HOOK.afterRefresh](crud) {
this.isBtnDisabled = true
this.stockInfoLoading = false
},
//
[CRUD.HOOK.beforeToAdd]() {
@ -345,19 +403,65 @@ export default {
'shelfId': null
}
}
Promise.all([
this.stockInfoLoading = true
const stockInfoPromise = crudStockTaskLog.FetchStockGirdSuccess()
.then(stockInfo => {
this.stockInfoLoading = false
return stockInfo
})
.catch(error => {
this.stockInfoLoading = false
console.error('stockInfo 接口失败:', error)
throw error
})
const otherPromises = [
crudStockTaskLog.FetchNewBillNo(),
crudStockTaskLog.FetchStockGirdNum(),
crudStockTaskLog.FetchTotalGirdNum(params)
]).then(([newBillNoRes, stockGridNumRes, totalGirdNumRes]) => {
]
Promise.all([stockInfoPromise, ...otherPromises])
.then(([stockInfo, newBillNoRes, stockGridNumRes, totalGirdNumRes]) => {
console.log('stockInfo', stockInfo)
this.stockInfo = stockInfo
const ipStatusList = stockInfo
? Object.entries(stockInfo.ipReachableCache).map(([ip, status]) => ({ ip, status }))
: []
this.ipStatusList = ipStatusList
this.ipStatusFalse = this.ipStatusList.filter(item => !item.status)
this.ipStatusFalseNum = this.ipStatusList.filter(item => !item.status).length
// this.reachable = [{ gridName: '111' }, { gridName: '222' }]
this.reachable = stockInfo.reachable
this.unreachable = stockInfo.unreachable
// this.unreachable = []
if (stockInfo && this.reachable.length !== 0) {
this.isBtnDisabled = false
} else {
this.isBtnDisabled = true
}
this.crud.form.stockBill = newBillNoRes
this.crud.form.stockGridNumName = stockGridNumRes + ' / ' + totalGirdNumRes + ' 层位'
this.crud.form.stockGridNumName = stockInfo
? `<span style="color: #00b42a;">${this.reachable.length}</span> /
<span style="color: #f53f3f;">${this.unreachable.length}</span> /
${totalGirdNumRes} 层位`
: '数据加载失败'
this.crud.form.stockGridNum = stockGridNumRes
this.crud.form.totalGridNum = totalGirdNumRes
}).catch(error => {
console.error(error)
})
.catch(error => {
console.error('整体请求失败:', error)
this.isBtnDisabled = true
})
},
[CRUD.HOOK.afterAddCancel]() {
this.isBtnDisabled = true
this.stockInfoLoading = false
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
},
@ -366,6 +470,8 @@ export default {
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
crud.form.reableGridIds = this.reachable.map(item => item.gridId)
crud.form.unReableGridIds = this.unreachable.map(item => item.gridId)
delete crud.form.stockGridNumName
delete crud.form.stockTypeName
return true
@ -469,6 +575,8 @@ export default {
handleCloseDialog() {
this.detailVisible = false
this.tabIndex = 0
this.isBtnDisabled = true
this.stockInfoLoading = false
},
toDelete() {
this.$confirm('此操作将删除当前盘点单任务<span>你是否还要继续?</span>', '提示', {
@ -628,4 +736,5 @@ export default {
}
}
}
</style>

179
src/views/visualCheck/checkManage/dataScreening/module/form.vue

@ -1,8 +1,9 @@
<template>
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseForm" :visible="formVisible" title="新增盘点">
<el-dialog :class="unreachable.length !== 0 ? 'stock-dialog':''" append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseForm" :visible="formVisible" title="新增盘点">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div class="setting-dialog" style="display: flex; justify-content: flex-start;">
<div :style=" {'width': unreachable.length !== 0 ? '670px':''}">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="盘点单号" prop="stockBill">
<el-input v-model="form.stockBill" disabled style="width: 240px;" />
@ -13,8 +14,30 @@
<el-form-item label="目标位置" prop="stockRegion">
<el-input v-model="form.stockRegion" disabled style="width: 240px;" />
</el-form-item>
<el-form-item label="目标数量" prop="stockGridNumName">
<el-input v-model="form.stockGridNumName" disabled style="width: 240px;" />
<el-form-item
class="stockGridNumName-style"
label="目标数量"
prop="stockGridNumName"
>
<span v-if="stockInfoLoading" class="el-icon-loading" />
<!-- <el-input v-else disabled v-html="form.stockGridNumName" /> -->
<div v-else style="display: flex; justify-content: flex-start;">
<el-input disabled v-html="form.stockGridNumName" />
<el-popover
class="stock-popover"
placement="top-start"
width="250"
trigger="hover"
>
<div>
<span style="display:block; font-weight: bold; margin-bottom: 10px;">A / B / C 层位 </span>
A开启盘点功能 当前可盘点 层位数量<br>
B开启盘点功能 当前不可盘点 层为数量<br>
C具备盘点功能的 层位数量
</div>
<i slot="reference" class="iconfont icon-zhuyi-lan" />
</el-popover>
</div>
</el-form-item>
<el-row>
<el-form-item label="备注" prop="stockRemarks">
@ -24,7 +47,32 @@
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="handleCloseForm">取消</el-button>
<el-button :loading="saveLoading" type="primary" @click="handleComfiredEditing">保存</el-button>
<el-button :disabled="isBtnDisabled" :loading="saveLoading" type="primary" @click="handleComfiredEditing">保存</el-button>
</div>
</div>
<div v-if="unreachable.length !== 0" style="width: 500px; margin-left: 10px;">
<div class="stock-info-tips">
<p>注意系统检查到有参与本次盘点的摄像头无法连接<i>{{ reachable.length }}</i>/个层架位可盘点</p>
<span>不可盘点具体情况如下</span>
</div>
<div style="display: flex; justify-content: space-between;">
<el-card class="box-card">
<div slot="header">
<span>无法连接的摄像头 <i style="color: #f53f3f; font-weight: bold; font-style: normal;">{{ ipStatusFalseNum }}</i> /)</span>
</div>
<div v-for="(item,index) in ipStatusFalse" :key="index" class="stock-info-item">
<span> {{ item.ip }} </span>
</div>
</el-card>
<el-card class="box-card">
<div slot="header">
<span>无法盘点的层架位 <i style="color: #f53f3f; font-weight: bold; font-style: normal;">{{ unreachable.length }}</i> /</span>
</div>
<div v-for="(item,index) in unreachable" :key="index" class="stock-info-item">
<span> {{ item.gridName }} </span>
</div>
</el-card>
</div>
</div>
</div>
</el-dialog>
@ -34,7 +82,7 @@
import crudStockTaskLog from '@/api/stockTaskLog/index'
import CRUD, { form } from '@crud/crud'
const defaultForm = { stockTypeName: '', stockType: null, stockBill: null, stockRegion: '', stockGridNum: null, stockGridNumName: null, totalGridNum: null, stockRemarks: null, regionId: null, shelfId: null, gridShelf: null, gridId: null, toward: null }
const defaultForm = { stockTypeName: '', stockType: null, stockBill: null, stockRegion: '', stockGridNum: null, stockGridNumName: null, totalGridNum: null, stockRemarks: null, regionId: null, shelfId: null, gridShelf: null, gridId: null, toward: null, reableGridIds: [], unReableGridIds: [] }
export default {
name: 'DataForm',
mixins: [
@ -60,7 +108,14 @@ export default {
stockGridNumName: [
{ required: true, message: '请输入目标数量', trigger: 'blur' }
]
}
},
stockInfo: null,
ipStatusList: [],
ipStatusFalseNum: 0,
unreachable: [],
reachable: [],
isBtnDisabled: true,
stockInfoLoading: false
}
},
methods: {
@ -111,11 +166,26 @@ export default {
const { regionId, shelfId, gridShelf, gridId, toward, stockTypeName } = typeMap[type] || {}
const params = { regionId, shelfId, gridShelf, gridId, toward }
this.form.stockTypeName = stockTypeName
Promise.all([
this.stockInfoLoading = true
const stockInfoPromise = crudStockTaskLog.FetchStockGirdSuccess(params)
.then(stockInfo => {
this.stockInfoLoading = false
return stockInfo
})
.catch(error => {
this.stockInfoLoading = false
console.error('stockInfo 接口失败:', error)
throw error
})
const otherPromises = [
crudStockTaskLog.FetchNewBillNo(),
crudStockTaskLog.FetchStockGirdNum(params),
crudStockTaskLog.FetchTotalGirdNum(params)
]).then(([newBillNoRes, stockGridNumRes, totalGirdNumRes]) => {
]
Promise.all([stockInfoPromise, ...otherPromises]).then(([stockInfo, newBillNoRes, stockGridNumRes, totalGirdNumRes]) => {
if (stockGridNumRes === 0) {
if (this.form.stockType === 6) {
this.$message({ message: '当前层位不可盘点', type: 'error', offset: 8 })
@ -129,12 +199,39 @@ export default {
this.formVisible = true
}
}
console.log('stockInfo', stockInfo)
this.stockInfo = stockInfo
const ipStatusList = stockInfo
? Object.entries(stockInfo.ipReachableCache).map(([ip, status]) => ({ ip, status }))
: []
this.ipStatusList = ipStatusList
this.ipStatusFalse = this.ipStatusList.filter(item => !item.status)
this.ipStatusFalseNum = this.ipStatusList.filter(item => !item.status).length
// this.reachable = [{ gridName: '111' }, { gridName: '222' }]
this.reachable = stockInfo.reachable
this.unreachable = stockInfo.unreachable
// this.unreachable = []
if (stockInfo && this.reachable.length !== 0) {
this.isBtnDisabled = false
} else {
this.isBtnDisabled = true
}
this.form.stockBill = newBillNoRes
this.crud.form.stockGridNumName = stockGridNumRes + ' / ' + totalGirdNumRes + ' 层位'
// this.crud.form.stockGridNumName = stockGridNumRes + ' / ' + totalGirdNumRes + ' '
this.crud.form.stockGridNumName = stockInfo
? `<span style="color: #00b42a;">${this.reachable.length}</span> /
<span style="color: #f53f3f;">${this.unreachable.length}</span> /
${totalGirdNumRes} 层位`
: '数据加载失败'
this.crud.form.stockGridNum = stockGridNumRes
this.crud.form.totalGridNum = totalGirdNumRes
}).catch(error => {
console.error(error)
this.isBtnDisabled = true
})
},
handleCloseForm() {
@ -172,13 +269,75 @@ export default {
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
crud.form.reableGridIds = this.reachable.map(item => item.gridId)
crud.form.unReableGridIds = this.unreachable.map(item => item.gridId)
delete crud.form.stockGridNumName
delete crud.form.stockTypeName
return true
},
[CRUD.HOOK.afterAddCancel]() {
this.isBtnDisabled = true
this.stockInfoLoading = false
}
}
}
</script>
<style lang="scss" scoped>
.stock-dialog{
::v-deep .el-dialog{
width: 1220px !important;
}
}
.stockGridNumName-style{
::v-deep .el-form-item__content{
width: auto !important;
padding: 0 10px;
.stock-popover{
display: inline-block;
margin-left: 6px;
color: #0348f3;
}
}
}
.stock-info-tips{
line-height: 24px;
margin-bottom: 20px;
p{
color: #0c0e1e;
i{
display: inline-block;
padding: 0 4px;
font-weight: bold;
font-style: normal;
color: #00b42a;
}
}
span{
display: block;
}
}
::v-deep .el-card {
flex: 1;
margin-right: 15px;
.el-card__header{
color: #0c0e1e;
// font-size: 16px;
background-color: #fff !important;
border-bottom: 1px solid #ebeef5 !important;
}
.el-card__body{
height: 180px;
overflow: hidden;
overflow-y: scroll;
}
.stock-info-item{
display: flex; justify-content: space-between; padding: 4px 20px;
span{
display: block;
height: 26px;
line-height: 26px;
}
}
}
</style>
Loading…
Cancel
Save