You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
udiwms-vue-frame/src/views/collect/IocCollectOrderVerify.vue

855 lines
27 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<el-form :model="filterQuery" class="order-el-form" ref="formData" label-width="120px" @submit.native.prevent>
<el-card>
<el-row :gutter="0" style="margin-top: 15px">
<el-col :span="24" align="right">
<el-button-group>
<el-button
type="primary"
:disabled="!orderData.billNo"
@click.native="abandonOrder()"
>取消校验
</el-button>
<!--<el-button-->
<!-- type="primary"-->
<!-- :disabled="!orderData.billNo"-->
<!-- @click.native="cancelCheckOrder()"-->
<!--&gt;取消校验-->
<!--</el-button>-->
<el-button
type="primary"
:disabled="!orderData.billNo"
@click.native="confirmCheckOrder()"
>校验完成
</el-button>
</el-button-group>
</el-col>
</el-row>
<div style="border: 1px solid #ebeef5;border-radius: 2px;margin-top: 15px;padding: 15px"
v-loading="this.loading"
>
<el-row :gutter="0" style="margin-top: 5px">
<el-col :span="20">
<el-form-item prop="code" :label="scanTip" label-width="80px">
<el-input
id="inputer"
@focus="getInputFocus($event)"
@keypress.enter.native="enterKey($event)"
ref="inputRef"
style="ime-mode: disabled"
type="tel"
:placeholder="this.placeholder"
v-model="scanCode"
></el-input>
<!-- :disabled="scanDisabled"-->
</el-form-item>
</el-col>
<el-col :span="4">
<el-button-group style="display: flex;">
<el-button
type="primary"
size="mini"
icon="el-icon-search"
@click.native.stop="enterKey($event)"
style="margin-left: 15px"
>
</el-button>
<!-- :disabled="!formData.billNo || (this.formDataVisible != null && this.formDataVisible.scanType == 1)"-->
<el-button type="primary"
@click="addGs"
>ALT+29
</el-button>
<el-button
type="primary"
size="mini"
icon="el-icon-delete"
@click.native.stop="clear()"
>清空
</el-button>
</el-button-group>
</el-col>
</el-row>
<el-alert
v-if="successVisible "
:title="scanTitle"
:type="scanResultType"
:closable="false"
:dangerouslyUseHTMLString="true"
:description="result"
>
</el-alert>
<el-alert
v-if="errVisible "
title="错误信息:"
type="error"
:closable="false"
:dangerouslyUseHTMLString="true"
:description="errResult"
>
</el-alert>
</div>
<el-descriptions title="单据信息" :column="4" border style="margin-top: 15px">
<el-descriptions-item label="业务单号">{{ orderData.billNo }}</el-descriptions-item>
<el-descriptions-item label="发货方">{{ orderData.shipperName }}</el-descriptions-item>
<el-descriptions-item label="收货方">{{ orderData.fromCorpName }}</el-descriptions-item>
<el-descriptions-item label="单据类型">{{ orderData.busTypeName }}</el-descriptions-item>
<el-descriptions-item label="来源系统">{{ orderData.fromType }}</el-descriptions-item>
<el-descriptions-item label="单据时间">{{ orderData.billTime }}</el-descriptions-item>
<el-descriptions-item label="单据备注">{{ orderData.remark }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-tabs type="border-card" style="margin: 15px">
<!--单据业务详情-->
<el-tab-pane>
<span slot="label">单据 {{ orderData.billNo }}-追溯码详情</span>
<el-table :data="detailList" style="width: 100%;" highlight-current-row="true" border ref="multipleTable"
:row-style="rowStyle"
>
<el-table-column label="序号" type="index"></el-table-column>
<el-table-column label="追溯码" prop="code" width="160"></el-table-column> <el-table-column label="药品通用名称" prop="cpmctymc" width="110"></el-table-column>
<el-table-column label="包装规格" prop="ggxh" width="110"></el-table-column>
<el-table-column label="批次号" prop="batchNo"></el-table-column>
<el-table-column label="生产日期" prop="productDate"></el-table-column>
<el-table-column label="失效日期" prop="expireDate"></el-table-column>
<el-table-column label="序列号" prop="serialNo"></el-table-column>
<el-table-column label="药品编码" prop="nameCode"></el-table-column>
<!--<el-table-column label="扫码数量" prop="scanActCount"></el-table-column>-->
<el-table-column label="批准文号" prop="zczbhhzbapzbh"></el-table-column>
</el-table>
<el-row style="text-align: right;font-size: 12px;margin-top: 10px">
<el-col span="24">
<div style="float: right">
<!--<td>-->
<!-- <div style="background-color: #F56C6C;width: 10px;height: 10px;"></div>-->
<!--</td>-->
<!--<td><span style="color: #6d6d6d;"><pre>未赋码 </pre></span></td>-->
<td>
<div style="background-color: #E6A23C;width: 10px;height: 10px;"></div>
</td>
<td>
<span style="color: #6d6d6d;"><pre>替换码 </pre></span>
</td>
<td>
<div style="background-color: #67C23A;width: 10px;height: 10px;"></div>
</td>
<td>
<span style="color: #6d6d6d;"><pre>已校验</pre></span>
</td>
</div>
</el-col>
</el-row>
<pagination
v-show="resultTotal>0"
:total="resultTotal"
:limit.sync="codeQuery.limit"
:page.sync="codeQuery.page"
@pagination="getPage()"
></pagination>
<!-- 在表格下方添加说明 -->
</el-tab-pane>
<el-tab-pane label="整单详情">
<CollectFinishOrderBackupDetail
v-if="panelALive"
:prescribeData="curRow"
></CollectFinishOrderBackupDetail>
</el-tab-pane>
</el-tabs>
</el-form>
</div>
</template>
<script>
import { getCodeEndList } from '@/api/collect/IoCollectCodeSelect'
import { orderFinish } from '@/api/collect/collectOrder'
import selectPrescribeDialog from '@/views/collect/selectCollectOrderDialog'
import CollectFinishOrderBackupDetail from "./CollectFinishOrderBackupDetail"
import {
commitCheckCodeOrder,
deleteCodes,
scanCheckCodeOrder,
scanCheckCodeReplace
} from '@/api/collect/splitCreateOrder'
import { isBlank } from '@/utils/strUtil'
export default {
name: 'IocCollectOrderVerify',
props: {
resetKey: {
type: Function,
required: true
}
},
components: { selectPrescribeDialog,CollectFinishOrderBackupDetail },
data() {
return {
resultTotal: 0,
scanTip: '单据录入:',
placeholder: '请输入单据号进行扫码校验',
scanTitle: '扫码结果:',
scanResultType: 'success',
result: '\n',
errVisible: false,
loading: false,
successVisible: true,
errResult: '',
scanCode: '',
filterQuery: {
code: '',
billNo: null,
codeList: []
},
orderData: {},
curRow: null,
codeList: [],
//1/7 新增数据
orderQuery: {
page: 1,
limit: 10,
billNo: null,
tagStatus: 3,
workPlaceCode: null,
busType: null
},
codeQuery: {
billNo: null,
code: null,
selectType: 2,
page: 1,
limit: 10
},
workplaceId: null,
busType: null,
detailList: [],
checkCodeList: [],
checkCodeEndList: [],
panelALive: false,
ws: null,
}
},
methods: {
enterKey() {
this.errResult = ''
if (this.orderData.billNo == null) {
this.enterBillNoKey()
return
}
if (this.scanCode.includes("DMOENTER")) {
this.confirmCheckOrder()
this.scanCode = ''
return
}else if (this.scanCode.includes("DMOCANCEL")) {
this.abandonOrder()
this.scanCode = ''
return
}else if (this.scanCode.includes("DMODEL")) {
// this.deleteCode()
this.scanCode = ''
return
}
this.check()
},
check() {
this.errResult = ''
this.filterQuery.code = this.scanCode.trim()
if (this.filterQuery.code.includes(';')) {
const codeArray = this.filterQuery.code.split(';')
this.filterQuery.codeList = codeArray
this.filterQuery.code = ''
this.filterQuery.billNo = this.orderData.billNo
// 处理多码的情况
this.batchVailCode(this.filterQuery)
return
}
if (this.filterQuery.code) {
if (!this.parseString(this.filterQuery.code)) {
this.$refs.inputRef.focus()
this.$refs.inputRef.select()
this.$message.error('无效追溯码')
return
}
}
//单码校验
this.filterQuery.codeList = []
this.filterQuery.billNo = this.orderData.billNo
this.verifyCode(this.filterQuery)
// this.getInputFocus()
},
batchVailCode(params) {
this.$refs.inputRef.focus()
this.$refs.inputRef.select()
this.verifyCode(params)
},
enterBillNoKey(billNo) {
if (isBlank(billNo)){
this.orderQuery.code = billNo
}else {
this.orderQuery.code = this.scanCode
}
this.orderQuery.workPlaceCode = this.workplaceId
this.orderQuery.busType = this.busType
orderFinish(this.orderQuery).then(res => {
if (res.code == 20000) {
this.placeholder = '已选入单据,请扫描追溯码进行校验'
this.scanTip = '扫码校验'
this.orderData = res.data.list[0]
this.curRow = res.data.list[0]
this.filterQuery.billNo = this.orderData.billNo
this.refreshCodesPanel()
this.initData()
this.getResultDetailList()
} else {
this.$message.error(res.message)
}
})
},
refreshCodesPanel() {
this.panelALive = false
this.$nextTick(() => {
this.panelALive = true
})
},
getPage(){
this.codeQuery.selectType = 1
this.getResultDetailList()
},
getResultDetailList() {
this.codeQuery.billNo = this.orderData.billNo
getCodeEndList(this.codeQuery).then((res) => {
if (res.code === 20000) {
this.detailList = res.data.list || []
this.checkCodeList = this.detailList.map(item => item.code)
this.resultTotal = res.data.total || 0
this.codeQuery.selectType = 2
} else {
this.$message.error(res.message)
this.detailList = []
this.resultTotal = 0
}
}).catch((error) => {
this.$message.error(error.message)
this.detailList = []
// this.resultTotal = 0;
})
},
getInputFocus(event) {
// event.currentTarget.select();
this.$nextTick(() => {
this.$refs.inputRef.focus()
this.$refs.inputRef.select()
})
},
verifyCode(query) {
scanCheckCodeOrder(query).then(res => {
if (res.code == 20000) {
if (Array.isArray(res.data)) {
this.printCodeResultList(res.data)
this.codeQuery.selectType = 1
this.getResultDetailList()
let codeList = res.data
let filterCodeList = codeList.filter(item => item.status === 5).map(item => item.code)
if (filterCodeList.length > 0) {
query.codeList = filterCodeList
this.replaceCode(query, 1)
}
this.scanCode = ""
} else {
this.verifyFinish(1, res.data, res.message)
this.checkCodeEndList.push(query.code)
this.codeQuery.selectType = 1
this.getResultDetailList()
//码不对 全部码
this.$message.success('校验成功')
}
} else if (res.code == 503) {
this.replaceCode(query, 2)
} else if (res.code == 504) {
//追溯码不存在 是否执行更换
this.$confirm('追溯码校验超出是否继续添加', '提示', {
confirmButtonText: '添加',
cancelButtonText: '取消',
type: 'warning',
center: true,
closeOnPressEscape: false,//按下 ESC 键关闭弹窗
closeOnClickModal: false,//点击遮罩关闭弹窗
distinguishCancelAndClose: true//区分取消与关闭
}).then(() => {
scanCheckCodeReplace(query).then(res => {
if (res.code == 20000) {
this.scanCode = ''
this.orderData.checkCodeConfirm = res.data.checkCodeConfirm
this.codeQuery.selectType = 1
this.getResultDetailList()
this.getInputFocus()
this.initData()
this.$message.success('添加成功')
} else {
this.$message.error('添加失败')
}
})
})
} else {
if (Array.isArray(res.data)) {
this.scanCode = ''
this.getInputFocus()
} else {
this.scanCode = ''
this.getInputFocus()
this.printCodeError(res.message)
// this.verifyFinish(2, res.data, res.message)
this.$message.error(res.message)
}
}
})
},
replaceCode(query, type) {
let title = ''
if (type == 1) {
const codeStr = query.codeList.join('\n')
title = `${codeStr}该追溯码不存在是否继续添加`
} else {
title = '该追溯码不存在是否继续添加'
}
//追溯码不存在 是否执行更换
this.$confirm(title, '提示', {
confirmButtonText: '添加',
cancelButtonText: '取消',
type: 'warning',
center: true,
closeOnPressEscape: false,//按下 ESC 键关闭弹窗
closeOnClickModal: false,//点击遮罩关闭弹窗
distinguishCancelAndClose: true//区分取消与关闭
}).then(() => {
scanCheckCodeReplace(query).then(res => {
if (res.code == 20000) {
this.scanCode = ''
this.orderData.checkCodeConfirm = res.data.checkCodeConfirm
this.codeQuery.selectType = 1
this.getResultDetailList()
this.getInputFocus()
this.$message.success('添加成功')
this.initData()
} else {
this.$message.error('添加失败')
}
})
}).catch(() => {
this.scanCode = ''
this.getInputFocus()
})
},
verifyFinish(val, data, message) {
if (val == 1) {
this.errVisible = false
this.successVisible = true
this.printCodeResult(data, message)
} else {
this.errVisible = true
this.successVisible = false
this.errResult = data + '追溯码不存在'
}
this.scanCode = ''
this.getInputFocus()
},
printCodeResult(data, message) {
const resultParts = []
if (data.udi) {
resultParts.push('层级标识: ' + data.udi)
}
if (data.cpmctymc) {
resultParts.push(data.productType == 2 ? '药品通用名称' : '产品通用名称: ' + data.cpmctymc)
}
if (data.batchNo) {
resultParts.push('批次号: ' + data.batchNo)
}
if (data.produceDate) {
resultParts.push('生产日期: ' + data.produceDate)
}
if (data.expireDate) {
resultParts.push('失效日期: ' + data.expireDate)
}
if (data.serialNo) {
resultParts.push('序列号: ' + data.serialNo)
}
if (data.productType == 2) {
if (data.bzgg) {
resultParts.push('包装规格: ' + data.bzgg)
}
} else {
if (data.ggxh) {
resultParts.push('规格型号: ' + data.ggxh)
}
}
if (data.prepnSpec) {
resultParts.push('制剂规格: ' + data.prepnSpec)
}
if (data.prepnUnit) {
resultParts.push('剂型: ' + data.prepnUnit)
}
if (data.packUnit) {
resultParts.push('计量单位: ' + data.packUnit)
}
this.scanTitle = '扫码结果:' + data.code
this.result = resultParts.join(' , ')
if (message == 'success') {
this.scanResultType = 'success'
}
},
async printCodeResultList(vailCodeResultResponses) {
this.errResult = ''
this.result = ''
this.successVisible = false
this.errVisible = false
this.scanTitle = '扫码结果:'
for (let i = 0; i < vailCodeResultResponses.length; i++) {
let data = vailCodeResultResponses[i]
if (data.status == 1) {
this.scanResultType = 'success'
this.result = this.result + (isBlank(this.result) ? '' : ';') + vailCodeResultResponses[i].code + ':' + vailCodeResultResponses[i].sucMsg
} else if (data.status == 2 || data.status == 3) {
this.errResult = this.errResult + '\n' + vailCodeResultResponses[i].code + ':' + vailCodeResultResponses[i].errMsg
} else if (data.status == 5) {
this.scanResultType = 'warning'
this.result = this.result + (isBlank(this.result) ? '' : ';') + vailCodeResultResponses[i].code + ':' + vailCodeResultResponses[i].errMsg
}
}
if (!isBlank(this.result)) {
this.successVisible = true
}
if (!isBlank(this.errResult)) {
this.errVisible = true
}
},
async printCodeError(rsponses){
this.successVisible = false
this.errVisible = true
this.errResult = rsponses
},
parseString(str) {
// 1. 判断是否以 "MA" 开头
if (str.startsWith('MA')) {
return true
}
// 2. 判断是否以 "01" 开头且长度大于等于 18
if (str.startsWith('01') && str.length >= 18) {
return true
}
// 3. 判断是否以 "#" 开头且 "#" 的个数大于等于 4
if (str.startsWith('#') && (str.match(/#/g) || []).length >= 4) {
return true
}
// 4. 判断是否以 "8" 开头且长度为 20 位
if (str.startsWith('8') && str.length === 20) {
return true
}
// 5. 判断是否以 "11", "17", "21", 或 "10" 开头
const prefixes = ['11', '17', '21', '10']
if (prefixes.some(prefix => str.startsWith(prefix))) {
return true
}
// 如果没有任何条件满足,返回 false
return false
},
confirmCheckOrder() {
if (this.orderData.checkCodeConfirm == 1) {
//追溯码不存在 是否执行更换
this.$confirm('当前单据存在可替换追溯码是否替换完成校验', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true,
closeOnPressEscape: false,//按下 ESC 键关闭弹窗
closeOnClickModal: false,//点击遮罩关闭弹窗
distinguishCancelAndClose: true//区分取消与关闭
}).then(() => {
this.commit()
}).catch(() => {
})
} else {
this.commit()
}
},
commit() {
commitCheckCodeOrder(this.filterQuery).then(res => {
if (res.code == 20000) {
this.init()
this.$message.success('校验完成')
} else {
// if (this.orderData.checkCodeConfirm == 1) {
// this.init()
// }
this.$message.error(res.message)
}
}).catch(() => {
})
},
// cancelCheckOrder(){
// this.codeQuery.selectType = 2
// this.$confirm('是否取消当前单据校验', '提示', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// type: 'warning',
// center: true,
// closeOnPressEscape: false,//按下 ESC 键关闭弹窗
// closeOnClickModal: false,//点击遮罩关闭弹窗
// distinguishCancelAndClose: true//区分取消与关闭
// }).then(() => {
// this.getResultDetailList()
// this.initData()
// this.$message.success("取消成功")
// }).catch(() => {
//
// })
//
// },
abandonOrder(){
let query = {
billNo : this.orderData.billNo,
selectType : 2
}
this.$confirm('是否取消当前单据校验', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true,
closeOnPressEscape: false,//按下 ESC 键关闭弹窗
closeOnClickModal: false,//点击遮罩关闭弹窗
distinguishCancelAndClose: true//区分取消与关闭
}).then(() => {
deleteCodes(query).then(res => {
if (res.code == 20000){
this.init()
this.$message.success("取消成功")
}else {
this.$message.success(res.message)
}
})
}).catch(() => {
})
},
initData(){
this.scanCode = ''
this.$refs.inputRef.focus()
this.$refs.inputRef.select()
this.successVisible = true
this.errVisible = false
this.errResult = ''
this.result = ''
this.scanResultType = 'success'
},
init() {
this.scanCode = ''
this.orderData = {}
this.detailList = []
this.checkCodeList = []
this.checkCodeEndList = []
this.scanTip = '单据录入:'
this.placeholder = '请输入单据号进行扫码校验'
this.scanTitle = '扫码结果:'
this.curRow = null
this.successVisible = true
this.errVisible = false
this.errResult = ''
this.result = '\n'
this.scanResultType = 'success'
this.orderQuery = {
page: 1,
limit: 10,
billNo: null,
tagStatus: 3,
workPlaceCode: null,
busType: null
}
this.codeQuery = {
billNo: null,
code: null,
selectType: 2,
page: 1,
limit: 10
}
this.filterQuery = {
code: '',
billNo: null,
codeList: []
}
if (this.$route.query.workplaceId != null) {
this.workplaceId = Number(this.$route.query.workplaceId)
}
if (this.$route.query.busType != null) {
this.busType = this.$route.query.busType
}
this.panelALive = false
},
clear() {
this.init()
},
rowStyle({row, rowIndex}) {
let rowBackground = {}
if (row.scanCodeCheckStatus == 1) {
rowBackground.color = '#56a717'
}
if (row.scanCodeCheckStatus == 3) {
rowBackground.color = '#E6A23C';
}
rowBackground.height = "38px"
return rowBackground;
},
//WebSocket
//处理事件
handleRecCodesEvent(event) {
console.log('接收 recCodes event:', event.detail.recCodes);
if (this.orderData.billNo == null) {
this.$message.error("请先选入单据!");
return
}
this.filterQuery.codeList = event.detail.recCodes
this.filterQuery.code = ''
this.filterQuery.billNo = this.orderData.billNo
this.batchVailCode(this.filterQuery)
},
handleVisibilityChange() {
if (document.visibilityState === 'visible') {
console.log('用户切回到了单据校验页面');
if (this.ws == null || this.ws.readyState === WebSocket.CLOSED) {
this.ws = new WebSocket("ws://127.0.0.1:9988");
const self = this;
this.ws.onopen = function (evt) {
console.log("单据校验 WebSocket 连接中 ...");
self.socketListener()
};
}
} else {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.close();
console.log("关闭 单据校验 websocket成功")
}
}
},
socketListener() {
let lastScanTime = Date.now();
let scanBuffer = [];
let scanTimeout = null;
const SCAN_TIMEOUT = 1000; // 1秒间隔表示扫码结束的判定标准
const self = this;
console.log("启用监听")
this.ws.onmessage = function (event) {
let scanData = event.data; // 获取扫码数据
let currentTime = Date.now();
console.log(scanData)
// 如果时间间隔超过预设的阈值,表示这是一次新的扫码
if (currentTime - lastScanTime > SCAN_TIMEOUT) {
// 处理上一次完整的扫码数据
if (scanBuffer.length > 0) {
self.handleScanComplete(scanBuffer);
}
// 清空缓冲区,开始新的扫码
scanBuffer = [];
}
// 重置上一次扫码的时间
lastScanTime = currentTime;
// 将数据添加到缓冲区
scanBuffer.push(scanData);
// 如果已经有一个定时器在等待,可以清除它
if (scanTimeout) {
clearTimeout(scanTimeout);
}
// 设置新的定时器,等待指定的时间后执行扫码结束处理
scanTimeout = setTimeout(() => {
// 定时器到时,处理扫码结束
self.handleScanComplete(scanBuffer);
scanBuffer = [];
}, SCAN_TIMEOUT);
};
},
handleScanComplete(fullScanData) {
console.log("Scan complete:", fullScanData.join(";"));
if (this.orderData.billNo == null ) {
this.enterBillNoKey(fullScanData[0])
return;
}
let params = {
codeList: fullScanData,
};
if (this.orderData.billNo == null) {
this.$message.error("请先选入单据!");
return
}
this.filterQuery.codeList = fullScanData
this.filterQuery.code = ''
this.filterQuery.billNo = this.orderData.billNo
this.batchVailCode(this.filterQuery)
},
},
watch: {
resetKey(newVal, oldVal) {
this.$refs.inputRef.focus()
}
},
created() {
if (this.$route.query.workplaceId != null) {
this.workplaceId = Number(this.$route.query.workplaceId)
}
if (this.$route.query.busType != null) {
this.busType = this.$route.query.busType
}
this.init()
},
mounted() {
this.getInputFocus()
if (window.navigator.userAgent.indexOf("GLXP_PC") != -1) {
window.removeEventListener('djjy', this.handleRecCodesEvent);
window.addEventListener('djjy', this.handleRecCodesEvent);
}
document.addEventListener('visibilitychange', this.handleVisibilityChange);
},
beforeDestroy() {
window.removeEventListener('djjy', this.handleRecCodesEvent);
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
this.ws.close();
this.ws.onclose = function (evt) {
console.log("单据校验 Connection closed.");
};
},
}
</script>
<style scoped>
</style>