Commit f27dbf13 by wusiyi

feat: 工厂订单new新增生产扫码 #1008656

parent 7bb0575c
...@@ -54,7 +54,6 @@ declare module 'vue' { ...@@ -54,7 +54,6 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag'] ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline'] ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree'] ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
......
...@@ -535,6 +535,14 @@ export function completeDeliveryApi(ids: (number | string)[]) { ...@@ -535,6 +535,14 @@ export function completeDeliveryApi(ids: (number | string)[]) {
) )
} }
// 生产扫码
export function productionScanApi(id: number | string, status: string) {
return axios.get<never, BaseRespData<never>>(
'factory/podOrderOperation/scan-produce',
{ params: { id, status } },
)
}
export function applyForProductByIdApi(id: string, url: string) { export function applyForProductByIdApi(id: string, url: string) {
return axios.get<never, BaseRespData<operateOrderListData[]>>(url, { return axios.get<never, BaseRespData<operateOrderListData[]>>(url, {
params: { podProductId: id }, params: { podProductId: id },
......
...@@ -45,7 +45,11 @@ ...@@ -45,7 +45,11 @@
</div> </div>
<div class="right"> <div class="right">
<div <div
v-if="['fastProduction', 'fastReceipt'].includes(fastKey)" v-if="
['fastProduction', 'fastReceipt', 'productionScan'].includes(
fastKey,
)
"
class="input" class="input"
> >
<el-input <el-input
...@@ -70,10 +74,7 @@ ...@@ -70,10 +74,7 @@
{{ detail?.userMark }} {{ detail?.userMark }}
</div> </div>
</div> </div>
<div <div :title="String(detail?.factoryOrderNumber)" class="div-item">
:title="String(detail?.factoryOrderNumber)"
class="div-item"
>
<span class="div-item-label" style="font-size: 18px" <span class="div-item-label" style="font-size: 18px"
>订单号:</span >订单号:</span
> >
...@@ -145,8 +146,9 @@ ...@@ -145,8 +146,9 @@
> >
<span class="div-item-label">挂起前状态:</span> <span class="div-item-label">挂起前状态:</span>
<div class="div-item-value"> <div class="div-item-value">
<ElTag v-if="detail.statusName" type="primary">{{ detail.statusName || '' }}</ElTag <ElTag v-if="detail.statusName" type="primary">{{
> detail.statusName || ''
}}</ElTag>
</div> </div>
</div> </div>
<div <div
...@@ -237,8 +239,11 @@ ...@@ -237,8 +239,11 @@
<div class="btn"> <div class="btn">
<div <div
:style="{ :style="{
visibility: visibility: [
fastKey === 'fastProduction' || fastKey === 'fastReceipt' 'fastProduction',
'fastReceipt',
'productionScan',
].includes(fastKey)
? 'visible' ? 'visible'
: 'hidden', : 'hidden',
}" }"
...@@ -250,7 +255,11 @@ ...@@ -250,7 +255,11 @@
type="success" type="success"
@click="changeStatus" @click="changeStatus"
> >
{{ fastKey === 'fastProduction' ? '生产完成' : '快捷入库' }} {{
['fastProduction', 'productionScan'].includes(fastKey)
? '生产完成'
: '快捷入库'
}}
</el-button> </el-button>
<div class="check"> <div class="check">
<el-checkbox v-model="isAutoSure"> 自动完成上一单 </el-checkbox> <el-checkbox v-model="isAutoSure"> 自动完成上一单 </el-checkbox>
...@@ -320,7 +329,7 @@ interface HistoryDataItem { ...@@ -320,7 +329,7 @@ interface HistoryDataItem {
finished: boolean finished: boolean
} }
const title = computed(() => { const title = computed(() => {
if (props.fastKey === 'fastProduction') { if (['fastProduction', 'productionScan'].includes(props.fastKey)) {
return '快捷生产' return '快捷生产'
} else if (props.fastKey === 'fastReceipt') { } else if (props.fastKey === 'fastReceipt') {
return '快捷入库' return '快捷入库'
...@@ -334,6 +343,7 @@ export type FastProductionDetail = PodOrderRes & { ...@@ -334,6 +343,7 @@ export type FastProductionDetail = PodOrderRes & {
podOrderNo?: string | null podOrderNo?: string | null
podOrderProductId?: number | null podOrderProductId?: number | null
statusName?: string | null statusName?: string | null
productMark?: string | null
} }
const trackingNumberRef = ref() const trackingNumberRef = ref()
const historyData = ref<HistoryDataItem[]>([]) const historyData = ref<HistoryDataItem[]>([])
...@@ -400,6 +410,10 @@ const props = withDefaults( ...@@ -400,6 +410,10 @@ const props = withDefaults(
pleaseScanTip?: string pleaseScanTip?: string
/** 扫码输入为空时音频/提示文案 */ /** 扫码输入为空时音频/提示文案 */
searchInputAudioTip?: string searchInputAudioTip?: string
/** 是否限制扫码 */
isLimitScan?: boolean
/** 限制扫码的提示 */
limitScanMessage?: string
}>(), }>(),
{ {
type: 0, type: 0,
...@@ -415,7 +429,8 @@ const props = withDefaults( ...@@ -415,7 +429,8 @@ const props = withDefaults(
notFoundMessage: '生产单不存在', notFoundMessage: '生产单不存在',
pendingOrderLabel: '生产单号', pendingOrderLabel: '生产单号',
pleaseScanTip: '请扫码生产单号', pleaseScanTip: '请扫码生产单号',
searchInputAudioTip: '请录入生产单号', searchInputAudioTip: '请录入生产单号???',
isLimitScan: false,
queryApi: (orderNumber: string) => getSubOrderBySubOrderNumber(orderNumber), queryApi: (orderNumber: string) => getSubOrderBySubOrderNumber(orderNumber),
completeApi: (ids: number[], detailData: Record<string, unknown>) => completeApi: (ids: number[], detailData: Record<string, unknown>) =>
productionQueryApi(ids[0], Number(detailData.podJomallOrderCnId || -1)), productionQueryApi(ids[0], Number(detailData.podJomallOrderCnId || -1)),
...@@ -509,7 +524,9 @@ watch( ...@@ -509,7 +524,9 @@ watch(
const len = historyData.value const len = historyData.value
if ( if (
len.length > 0 && len.length > 0 &&
(props.fastKey === 'fastProduction' || props.fastKey === 'fastReceipt') ['fastProduction', 'fastReceipt', 'productionScan'].includes(
props.fastKey,
)
) { ) {
confirmQuery(len, 0) confirmQuery(len, 0)
} }
...@@ -541,7 +558,9 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => { ...@@ -541,7 +558,9 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => {
const el = len[i] const el = len[i]
showConfirm( showConfirm(
`${props.pendingOrderLabel} ${el.orderNumber} ${ `${props.pendingOrderLabel} ${el.orderNumber} ${
props.fastKey === 'fastProduction' ? '未生产' : '未入库' ['fastProduction', 'productionScan'].includes(props.fastKey)
? '未生产'
: '未入库'
}完成,取消则不提醒?`, }完成,取消则不提醒?`,
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
...@@ -628,6 +647,24 @@ const setData = async (orderNumber: string) => { ...@@ -628,6 +647,24 @@ const setData = async (orderNumber: string) => {
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
} catch (e) { } catch (e) {
console.error(e) console.error(e)
const err = e as BaseRespData<{
inventory: number
producingQuantity: number
availableInventory: number
}>
if (err?.code === 301) {
await ElMessageBox.alert(
`库存不足,无法进入生产!请联系仓库管理人员核对库存。<br/>库存数量:${err.data?.inventory},生产中的数量:${err.data?.producingQuantity}<span style="color: red">可调配库存:${err.data?.availableInventory}</span>`,
'提示',
{
type: 'warning',
dangerouslyUseHTMLString: true,
},
).then(() => {
localStorage.setItem(props.historyStorageKey, JSON.stringify([]))
})
}
detail.value = { detail.value = {
id: -1, id: -1,
podJomallOrderCnId: -1, podJomallOrderCnId: -1,
...@@ -742,6 +779,21 @@ const trackCodeInput = async () => { ...@@ -742,6 +779,21 @@ const trackCodeInput = async () => {
} }
detail.value = normalizeDetail(res.data) detail.value = normalizeDetail(res.data)
if (props.isLimitScan) {
if (
detail.value.productMark &&
['custom_normal', 'normal'].includes(detail.value.productMark)
) {
detail.value = { id: -1, podJomallOrderCnId: -1, imgList: [] }
localStorage.setItem(props.historyStorageKey, JSON.stringify([]))
return showConfirm(props.limitScanMessage || '', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
}
}
if (isDownloadImage.value) { if (isDownloadImage.value) {
download() download()
} }
......
<template> <template>
<div class="page card h-100 flex-gap-10 overflow-hidden flex"> <div class="page card h-100 flex-gap-10 overflow-hidden flex">
<div
class="order-status-wrapper"
:class="{ 'is-collapsed': statusSidebarCollapsed }"
>
<div class="order-status"> <div class="order-status">
<ElTree <ElTree
ref="treeRef" ref="treeRef"
...@@ -40,6 +44,17 @@ ...@@ -40,6 +44,17 @@
</template> </template>
</ElTree> </ElTree>
</div> </div>
<div
class="sidebar-toggle"
title="收起/展开"
@click="toggleStatusSidebar"
>
<span
class="sidebar-toggle-icon"
:class="{ 'is-collapsed': statusSidebarCollapsed }"
/>
</div>
</div>
<div class="order-content flex-1 flex-column overflow-hidden"> <div class="order-content flex-1 flex-column overflow-hidden">
<div v-if="!isSpecialLayout" class="header"> <div v-if="!isSpecialLayout" class="header">
<div class="header-filter-form"> <div class="header-filter-form">
...@@ -551,6 +566,16 @@ ...@@ -551,6 +566,16 @@
>拣胚完成</ElButton >拣胚完成</ElButton
> >
</span> </span>
<span
v-if="['PENDING_PICK', 'PENDING_REPLENISH'].includes(status)"
class="item"
>
<ElButton
type="warning"
@click="handleQuickProduction('productionScan')"
>生产扫码</ElButton
>
</span>
<span v-if="status === 'PENDING_PICK'" class="item"> <span v-if="status === 'PENDING_PICK'" class="item">
<ElButton type="danger" @click="handlePickFail">拣胚失败</ElButton> <ElButton type="danger" @click="handlePickFail">拣胚失败</ElButton>
</span> </span>
...@@ -566,7 +591,7 @@ ...@@ -566,7 +591,7 @@
</span> </span>
<span v-if="status === 'PENDING_PACKING'" class="item"> <span v-if="status === 'PENDING_PACKING'" class="item">
<ElButton type="success" @click="handleSeedingWall" <ElButton type="success" @click="handleSeedingWall"
>播种墙配货</ElButton >配货打单</ElButton
> >
</span> </span>
<span v-if="status === 'PENDING_PACKING'" class="item"> <span v-if="status === 'PENDING_PACKING'" class="item">
...@@ -584,7 +609,9 @@ ...@@ -584,7 +609,9 @@
> >
</span> </span>
<span v-if="status === 'IN_PRODUCTION'" class="item"> <span v-if="status === 'IN_PRODUCTION'" class="item">
<ElButton type="success" @click="handleQuickProduction" <ElButton
type="success"
@click="handleQuickProduction('fastProduction')"
>快捷生产</ElButton >快捷生产</ElButton
> >
</span> </span>
...@@ -992,6 +1019,8 @@ ...@@ -992,6 +1019,8 @@
:fast-key="fastKey" :fast-key="fastKey"
:default-auto-sure="true" :default-auto-sure="true"
:show-operation-no-row="true" :show-operation-no-row="true"
:is-limit-scan="isLimitScan"
limit-scan-message="G和CB类的操作单无效操作"
not-found-message="操作单不存在" not-found-message="操作单不存在"
pending-order-label="操作单号" pending-order-label="操作单号"
please-scan-tip="请扫码操作单号" please-scan-tip="请扫码操作单号"
...@@ -1177,6 +1206,7 @@ import { ...@@ -1177,6 +1206,7 @@ import {
updateReceiverAddressApi, updateReceiverAddressApi,
updateRemarkApi, updateRemarkApi,
completeDeliveryApi, completeDeliveryApi,
productionScanApi,
getByOperationNoLogApi, getByOperationNoLogApi,
listByNoPodOrderApi, listByNoPodOrderApi,
orderWeighingPodOrderApi, orderWeighingPodOrderApi,
...@@ -1228,6 +1258,11 @@ import { ElTag } from 'element-plus' ...@@ -1228,6 +1258,11 @@ import { ElTag } from 'element-plus'
const resultInfo = ref<ResultInfoDataItem[]>([]) const resultInfo = ref<ResultInfoDataItem[]>([])
const resultRefs = ref() const resultRefs = ref()
const statusSidebarCollapsed = ref(false)
const toggleStatusSidebar = () => {
statusSidebarCollapsed.value = !statusSidebarCollapsed.value
}
const batchManageRef = ref<InstanceType<typeof BatchManageTable>>() const batchManageRef = ref<InstanceType<typeof BatchManageTable>>()
const waitingRestockRef = ref<InstanceType<typeof WaitingRestockTable>>() const waitingRestockRef = ref<InstanceType<typeof WaitingRestockTable>>()
const cardLayoutRef = ref<InstanceType<typeof CardLayout>>() const cardLayoutRef = ref<InstanceType<typeof CardLayout>>()
...@@ -2857,10 +2892,16 @@ const handleReplenishFail = () => { ...@@ -2857,10 +2892,16 @@ const handleReplenishFail = () => {
} }
const getOperationByNo = (operationNo: string) => const getOperationByNo = (operationNo: string) =>
getByOperationNoLogApi(operationNo) as Promise<{ data?: unknown }> getByOperationNoLogApi(operationNo) as Promise<{ data?: unknown }>
const completeOperationById = (ids: number[]) => completeDeliveryApi(ids) const completeOperationById = (ids: number[]) =>
fastKey.value === 'productionScan'
? productionScanApi(ids[0], status.value)
: completeDeliveryApi(ids)
const downloadOperationById = (ids: number[]) => const downloadOperationById = (ids: number[]) =>
downloadOperationMaterialApi(ids) downloadOperationMaterialApi(ids)
const handleFastProductionSuccess = (data: ResultInfoDataItem[]) => { const handleFastProductionSuccess = (data: ResultInfoDataItem[]) => {
if (fastKey.value === 'productionScan') {
return
}
const result = data[0] const result = data[0]
if (!result.status) { if (!result.status) {
ElMessageBox.alert( ElMessageBox.alert(
...@@ -2889,6 +2930,7 @@ const fastClose = () => { ...@@ -2889,6 +2930,7 @@ const fastClose = () => {
refreshCurrentView({ isRefreshTree: true }) refreshCurrentView({ isRefreshTree: true })
} }
const handleViewDetail = async (item: operateOrderListData) => { const handleViewDetail = async (item: operateOrderListData) => {
isLimitScan.value = false
const loading = ElLoading.service({ const loading = ElLoading.service({
fullscreen: true, fullscreen: true,
text: '加载中...', text: '加载中...',
...@@ -2906,9 +2948,11 @@ const handleViewDetail = async (item: operateOrderListData) => { ...@@ -2906,9 +2948,11 @@ const handleViewDetail = async (item: operateOrderListData) => {
loading.close() loading.close()
} }
} }
const handleQuickProduction = () => { const isLimitScan = ref(false)
const handleQuickProduction = (key: 'fastProduction' | 'productionScan') => {
detailVisible.value = true detailVisible.value = true
fastKey.value = 'fastProduction' fastKey.value = key
isLimitScan.value = true
detailData.value = {} detailData.value = {}
} }
const handleSinglePrint = () => { const handleSinglePrint = () => {
...@@ -3033,8 +3077,76 @@ onMounted(() => { ...@@ -3033,8 +3077,76 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
gap: 2px; gap: 2px;
} }
.order-status-wrapper {
position: relative;
flex-shrink: 0;
width: 180px;
transition: width 0.3s ease;
&.is-collapsed {
width: 0;
.order-status {
opacity: 0;
visibility: hidden;
}
}
}
.sidebar-toggle {
position: absolute;
top: 50%;
right: -12px;
transform: translateY(-50%);
z-index: 10;
width: 12px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border: 1px solid #dcdfe6;
border-left: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
box-shadow: 1px 0 4px rgba(0, 0, 0, 0.06);
user-select: none;
&:hover {
background: #f5f7fa;
.sidebar-toggle-icon {
border-right-color: #409eff;
&.is-collapsed {
border-right-color: transparent;
border-left-color: #409eff;
}
}
}
}
.sidebar-toggle-icon {
display: block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 6px solid #909399;
transition: border-color 0.2s;
&.is-collapsed {
border-right: none;
border-left: 6px solid #909399;
}
}
.order-status { .order-status {
width: 180px; width: 180px;
height: 100%;
overflow: auto;
transition: opacity 0.3s ease;
:deep(.el-tree-node__content) { :deep(.el-tree-node__content) {
height: 30px; height: 30px;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
> >
<template #header> <template #header>
<div class="title"> <div class="title">
<span>播种墙配货</span> <span>{{ isNewOrder ? '配货打单' : '播种墙配货' }}</span>
<span v-if="socketConnect === 'online'" class="online">[在线]</span> <span v-if="socketConnect === 'online'" class="online">[在线]</span>
<span v-else class="offline">[离线]</span> <span v-else class="offline">[离线]</span>
<ElButton <ElButton
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment