Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
factory_front
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qinjianhui
factory_front
Commits
d2f79600
Commit
d2f79600
authored
Aug 19, 2026
by
wusiyi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev_inventory_sorting' into 'dev'
Dev inventory sorting See merge request
!304
parents
9bf605b9
3753306a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1740 additions
and
63 deletions
+1740
-63
src/types/api/order.ts
+0
-1
src/views/order/allocationSortingRule/components/addDialog.vue
+1
-19
src/views/order/allocationSortingRule/index.vue
+0
-8
src/views/order/factoryOrderNew/component/InventorySorting.vue
+1702
-0
src/views/order/factoryOrderNew/index.vue
+37
-35
No files found.
src/types/api/order.ts
View file @
d2f79600
...
@@ -318,7 +318,6 @@ export interface SortingRuleDetail {
...
@@ -318,7 +318,6 @@ export interface SortingRuleDetail {
warehouseId
:
number
warehouseId
:
number
warehouseName
:
string
warehouseName
:
string
matchType
:
1
|
2
//匹配类型:1=所有条件(且) 2=任一条件(或)
matchType
:
1
|
2
//匹配类型:1=所有条件(且) 2=任一条件(或)
autoPrint
:
boolean
// 自动打单
defaultFlag
:
boolean
// 默认分拣区
defaultFlag
:
boolean
// 默认分拣区
secondScan
:
boolean
// 二次扫码
secondScan
:
boolean
// 二次扫码
conditions
:
SortingRuleCondition
[]
// 配货规则
conditions
:
SortingRuleCondition
[]
// 配货规则
...
...
src/views/order/allocationSortingRule/components/addDialog.vue
View file @
d2f79600
...
@@ -199,21 +199,6 @@
...
@@ -199,21 +199,6 @@
</div>
</div>
</el-form-item>
</el-form-item>
<el-form-item
label=
"自动打单"
prop=
"autoPrint"
>
<el-switch
v-model=
"form.autoPrint"
size=
"large"
placeholder=
"请选择是否自动打单"
/>
</el-form-item>
<el-form-item>
<span
v-if=
"form.autoPrint"
class=
"item-info"
>
开启后,配货分拣订单配齐时,自动打单,打单后订单状态转为待发货。
</span>
<span
v-else
class=
"item-info"
>
关闭后,配货分拣订单配齐后仍在待配货状态,经过配货打单后订单状态转为待发货。
</span>
</el-form-item>
<el-form-item
label=
"是否对接二次扫码设备"
prop=
"secondScan"
>
<el-form-item
label=
"是否对接二次扫码设备"
prop=
"secondScan"
>
<el-select
<el-select
v-model=
"form.secondScan"
v-model=
"form.secondScan"
...
@@ -308,7 +293,6 @@ const form = ref<SortingRuleDetail>({
...
@@ -308,7 +293,6 @@ const form = ref<SortingRuleDetail>({
],
],
secondScan
:
false
,
secondScan
:
false
,
sortNo
:
1
,
sortNo
:
1
,
autoPrint
:
false
,
warehouseId
:
0
,
warehouseId
:
0
,
warehouseName
:
''
,
warehouseName
:
''
,
defaultFlag
:
false
,
defaultFlag
:
false
,
...
@@ -396,9 +380,7 @@ const rules = computed(() => {
...
@@ -396,9 +380,7 @@ const rules = computed(() => {
{
required
:
true
,
message
:
'请输入配货区说明'
,
trigger
:
'blur'
},
{
required
:
true
,
message
:
'请输入配货区说明'
,
trigger
:
'blur'
},
],
],
areaCode
:
[{
required
:
true
,
message
:
'请选择配货区'
,
trigger
:
'change'
}],
areaCode
:
[{
required
:
true
,
message
:
'请选择配货区'
,
trigger
:
'change'
}],
autoPrint
:
[
{
required
:
true
,
message
:
'请选择是否自动打单'
,
trigger
:
'change'
},
],
secondScan
:
[
secondScan
:
[
{
{
required
:
true
,
required
:
true
,
...
...
src/views/order/allocationSortingRule/index.vue
View file @
d2f79600
...
@@ -214,14 +214,6 @@ const columns: CustomColumn<SortingList>[] = [
...
@@ -214,14 +214,6 @@ const columns: CustomColumn<SortingList>[] = [
align
:
'left'
,
align
:
'left'
,
},
},
{
{
key
:
'autoPrint'
,
prop
:
'autoPrint'
,
label
:
'自动打单'
,
width
:
100
,
align
:
'center'
,
slot
:
'autoPrint'
,
},
{
key
:
'warehouseName'
,
key
:
'warehouseName'
,
prop
:
'warehouseName'
,
prop
:
'warehouseName'
,
label
:
'仓库'
,
label
:
'仓库'
,
...
...
src/views/order/factoryOrderNew/component/InventorySorting.vue
0 → 100644
View file @
d2f79600
<
template
>
<ElDialog
v-model=
"visible"
fullscreen
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
@
opened=
"handleOpened"
@
close=
"onClose"
>
<template
#
header
>
<div
class=
"header-bar"
>
<div
class=
"title"
>
<span>
配货分拣
</span>
<span
v-if=
"socketConnect === 'online'"
class=
"online"
>
[在线]
</span>
<span
v-else
class=
"offline"
>
[离线]
</span>
<ElButton
class=
"reconnect-btn"
:class=
"
{ 'is-hidden': socketConnect !== 'offline' }"
type="success"
size="small"
:icon="Refresh"
@click="reconnectWebSocket"
>
刷新
</ElButton>
</div>
<ElCheckbox
v-model=
"isAutoPrint"
class=
"auto-print-checkbox"
>
配齐后自动打印面单,扫下一单配货完成并清空箱子
</ElCheckbox>
</div>
</
template
>
<div
class=
"pod-make-order-content"
>
<div
class=
"left-content"
>
<div
class=
"head-form"
>
<div
class=
"form-item"
>
<ElSelect
v-model=
"sheetPrinter"
placeholder=
"请选择打印机"
style=
"width: 200px"
@
change=
"handlePrinterChange"
>
<ElOption
v-for=
"item in printDeviceList"
:key=
"item"
:label=
"item"
:value=
"item"
/>
</ElSelect>
</div>
<div
class=
"form-item"
>
<ElSelect
v-model=
"sortingAreaId"
placeholder=
"请选择配货区"
style=
"width: 250px"
@
change=
"handleSortingAreaChange"
>
<ElOption
v-for=
"item in sortingAreaList"
:key=
"item.id"
:label=
"item.areaName + ' - ' + item.warehouseName"
:value=
"item.id"
/>
</ElSelect>
</div>
<div
class=
"form-item"
style=
"flex: 1"
>
<ElInput
ref=
"productionOrderRef"
v-model=
"productionOrder"
placeholder=
"请输入操作单号/生产单号"
clearable
style=
"width: 100%"
@
keyup
.
enter=
"handleSearch"
/>
</div>
<div
class=
"form-item"
>
<ElButton
type=
"primary"
@
click=
"handleSearch"
>
查询
</ElButton>
</div>
<div
class=
"form-item"
>
<ElButton
type=
"danger"
@
click=
"clearAllBox"
>
清空所有箱子
</ElButton>
</div>
</div>
<div
class=
"basic-info"
>
<div
class=
"basic-info-item"
>
<span>
物流跟踪号:
</span>
<span>
{{ podOrderDetailsData?.trackingNumber }}
</span>
</div>
<div
class=
"basic-info-item"
>
<span>
店铺单号:
</span>
<span>
{{ podOrderDetailsData?.shopNumber }}
</span>
</div>
<div
class=
"basic-info-item"
>
<span>
商品总数量:
</span>
<span>
{{ podOrderDetailsData?.purchaseNumber }}
</span>
</div>
<div
class=
"basic-info-item"
>
<span>
拣货数量:
</span>
<span>
{{ podOrderDetailsData?.pickingNumber }}
</span>
</div>
<!-- <div class="basic-info-item">
<span>物流公司:</span>
<span></span>
</div>
<div class="basic-info-item">
<span>物流方式:</span>
<span></span>
</div> -->
<div
class=
"basic-info-item"
:title=
"podOrderDetailsData?.shipmentsNote"
>
<span>
客户发货备注:
</span>
<span>
{{ podOrderDetailsData?.shipmentsNote }}
</span>
</div>
<div
class=
"basic-info-item"
>
<span>
订单号:
</span>
<span>
{{ podOrderDetailsData?.factoryOrderNumber }}
</span>
</div>
</div>
<div
class=
"table-content"
>
<TableView
ref=
"tableRef"
:paginated-data=
"podOrderDetailsData?.productList || []"
:columns=
"podOrderDetailsColumns"
highlight-current-row
@
row-click=
"handleRowClick"
>
<
template
#
image=
"{ row }"
>
<div
v-if=
"row.previewImgs?.length"
style=
"display: flex; flex-wrap: nowrap"
>
<div
v-for=
"img in row.previewImgs"
:key=
"img"
style=
"cursor: pointer; margin-right: 5px; flex: 1"
@
click
.
stop=
"handleCurrentChange(img.url)"
>
<img
v-if=
"img.url"
:src=
"img.url"
alt=
""
/>
</div>
</div>
</
template
>
<
template
#
verifyResult=
"{ row }"
>
<el-icon
v-if=
"row.power"
style=
"color: #00cc00; font-size: 24px; font-weight: 900"
><Check
/></el-icon>
</
template
>
</TableView>
</div>
</div>
<div
class=
"right-panel"
>
<div
class=
"sorting-area-content"
>
{{
(sortingAreaList.find((item) => item.id === sortingAreaId)
?.areaName || '') +
' - ' +
(sortingAreaList.find((item) => item.id === sortingAreaId)
?.warehouseName || '')
}}
</div>
<div
class=
"platform-filter"
>
<span>
平台
</span>
<ElSelect
v-model=
"platform"
placeholder=
"请选择"
clearable
filterable
style=
"width: 250px"
>
<ElOption
v-for=
"(item, index) in platformList"
:key=
"index"
:label=
"item.type"
:value=
"item.type"
>
<img
:src=
"`/images/icon/${item.icon.split('/').pop()}`"
style=
"height: 20px; margin: 5px 10px 0 0"
/>
<span
:title=
"item.type"
>
{{ item.type }}
</span>
</ElOption>
</ElSelect>
<ElButton
type=
"primary"
@
click=
"handlePlatformChange"
>
查询
</ElButton>
<ElButton
@
click=
"resetPlatform"
>
重置
</ElButton>
</div>
<div
class=
"flex right-panel-body"
>
<div
class=
"middle-content"
>
<div
class=
"box-top"
>
<div
v-if=
"boxIndex !== 0"
class=
"box-top-item"
>
<span
class=
"box-top-item-box-index"
>
{{ boxIndex }}
</span>
<span
class=
"box-top-item-box-index-text"
>
号箱
</span>
<span
v-if=
"
podOrderDetailsData?.pickingNumber !==
podOrderDetailsData?.purchaseNumber
"
style=
"font-size: 30px; white-space: nowrap"
>
放入第
</span
>
<div
class=
"box-top-item-box-index-number"
:style=
"{
color:
podOrderDetailsData?.pickingNumber ===
podOrderDetailsData?.purchaseNumber
? 'rgb(0, 255, 0)'
: '',
}"
>
{{ podOrderDetailsData?.pickingNumber }}
</div>
<span
v-if=
"
podOrderDetailsData?.pickingNumber != null &&
podOrderDetailsData?.purchaseNumber != null &&
podOrderDetailsData.pickingNumber ===
podOrderDetailsData.purchaseNumber
"
style=
"font-size: 30px; white-space: nowrap"
>
件商品已配齐
</span
>
<span
v-else
style=
"font-size: 30px"
>
件商品
</span>
</div>
<div
v-else
class=
"box-top-item-box-index-text"
>
单件商品
<span
style=
"color: rgb(0, 255, 0)"
>
(配齐)
</span
>
,不占用播种墙
</div>
<div
class=
"box-top-item-status"
>
<span
v-if=
"
isAutoPrint &&
podOrderDetailsData?.pickingNumber &&
podOrderDetailsData?.purchaseNumber &&
podOrderDetailsData?.pickingNumber ===
podOrderDetailsData?.purchaseNumber
"
>
<span
v-if=
"podOrderDetailsData?.printResult"
>
面单{{
renderPrintResult(podOrderDetailsData?.printResult)
}}
</span>
<span
v-else
>
面单打印中。。。
</span>
</span>
<span
v-else
>
验货中。。。
</span>
</div>
<div
class=
"box-top-item-btn"
>
<ElButton
type=
"primary"
@
click=
"
podOrderDetailsData && print(podOrderDetailsData, true)
"
>
手动打印
</ElButton
>
<ElButton
type=
"success"
@
click=
"handlePrintFinish"
>
打单完成
</ElButton
>
<ElButton
:disabled=
"boxIndex === 0"
type=
"danger"
@
click=
"handleClearBox"
>
清空箱子
</ElButton
>
</div>
<div
v-if=
"
podOrderDetailsData?.productList?.length &&
podOrderDetailsData?.productList?.length > 1
"
class=
"multiple-title"
>
<span
class=
"multiple-title-text"
>
多
</span>
</div>
</div>
<div
class=
"order-image"
>
<img
:src=
"coverImage"
alt=
""
/>
</div>
</div>
<div
class=
"right-content"
>
<div
class=
"box-list"
>
<div
v-for=
"(item, index) in podBoxList"
:key=
"item.box"
class=
"box-list-item"
:class=
"{
active: item.box && boxIndex == item.box,
isNull: !item.data,
'platform-matched':
platformMatchedBoxes &&
item.box &&
platformMatchedBoxes.includes(item.box),
}"
@
click=
"handleBoxClick(item)"
>
<span
style=
"font-weight: bold"
:title=
"index + 1 + '号箱'"
>
{{ index + 1 }}
</span>
<span
v-if=
"item.data?.pickingNumber"
class=
"number"
>
{{ item.data?.pickingNumber }}/{{ item.data.purchaseNumber }}
</span>
<div
v-if=
"
item.data &&
item.data.productList?.some(
(e) =>
e.productMark === 'custom_normal' ||
e.productMark === 'normal',
)
"
class=
"cb-product-mark"
>
<div
class=
"red-circle"
></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</ElDialog>
</template>
<
script
setup
lang=
"tsx"
>
import
{
computed
,
nextTick
,
ref
,
watch
}
from
'vue'
import
useLodop
from
'@/utils/hooks/useLodop'
import
TableView
from
'@/components/TableView.vue'
import
type
{
WebSocketMessage
}
from
'@/utils/websocket'
import
{
OrderData
,
PodMakeOrderData
,
ProductList
,
}
from
'@/types/api/podMakeOrder'
import
useOrderStore
from
'@/store/order'
import
{
clearBoxApi
,
clearAllBoxApi
,
getPackingDataApi
,
getPodBoxListApi
,
submitInspectionApi
,
}
from
'@/api/podUsOrder'
import
{
getSortingRuleListApi
}
from
'@/api/order'
import
useUserStore
from
'@/store/user'
import
{
Check
,
Refresh
}
from
'@element-plus/icons-vue'
import
socket
from
'@/utils/websocket'
import
{
WarehouseListData
}
from
'@/types/index'
import
{
ElButton
,
ElIcon
,
ElTag
}
from
'element-plus'
import
{
BaseRespData
}
from
'@/types/api'
import
type
{
SortingList
}
from
'@/types/api/order'
import
{
showError
}
from
'@/utils/ui.ts'
import
platformJson
from
'@/json/platform.json'
const
{
getCLodop
}
=
useLodop
()
const
props
=
defineProps
<
{
modelValue
:
boolean
printOrder
:
(
data
:
OrderData
,
callback
:
(
status
:
boolean
)
=>
void
)
=>
void
warehouseList
:
WarehouseListData
[]
}
>
()
const
WS_OPEN_CODE
=
'STARTORDERNEWPODTOP'
const
WS_CLOSE_CODE
=
'ENDORDERNEWPODTOP'
const
INIT_URL
=
'factory/podOrderPacking/local/getPodBoxOrderDetails'
// 配货分拣自动打单缓存key 默认关闭
const
AUTO_PRINT_CACHE_KEY
=
'inventorySortingAutoPrint'
// 配货分拣配货区缓存key
const
SORTING_AREA_CACHE_KEY
=
'localSortingAreaId'
const
emit
=
defineEmits
([
'update:modelValue'
,
'set-printer'
,
'refresh'
])
const
visible
=
computed
({
get
()
{
return
props
.
modelValue
},
set
(
value
)
{
emit
(
'update:modelValue'
,
value
)
},
})
const
printDeviceList
=
ref
<
string
[]
>
([])
const
sheetPrinter
=
ref
<
string
>
(
''
)
const
productionOrder
=
ref
<
string
>
(
''
)
const
podOrderDetailsData
=
ref
<
OrderData
>
()
const
operationStatusMap
:
Record
<
string
,
string
>
=
{
PENDING_PACKING
:
'待配货'
,
PENDING_SCHEDULE
:
'待排单'
,
PENDING_REPLENISH
:
'待补胚'
,
PENDING_PICK
:
'待拣胚'
,
IN_PRODUCTION
:
'生产中'
,
PACKING_COMPLETED
:
'配货完成'
,
COMPLETED
:
'已完成'
,
CANCELLED
:
'已取消'
,
ARCHIVE
:
'已归档'
,
}
const
operationStatusTagMap
:
Record
<
string
,
{
type
?:
'success'
|
'warning'
|
'info'
|
'danger'
|
'primary'
style
?:
{
backgroundColor
:
string
;
color
:
string
;
borderColor
:
string
}
}
>
=
{
PENDING_PACKING
:
{
type
:
'warning'
},
PENDING_SCHEDULE
:
{
type
:
'info'
},
PENDING_REPLENISH
:
{
style
:
{
backgroundColor
:
'#E6A23C'
,
color
:
'#FFFFFF'
,
borderColor
:
'#E6A23C'
,
},
},
PENDING_PICK
:
{
style
:
{
backgroundColor
:
'#409EFF'
,
color
:
'#FFFFFF'
,
borderColor
:
'#409EFF'
,
},
},
IN_PRODUCTION
:
{
type
:
'primary'
},
PACKING_COMPLETED
:
{
type
:
'success'
},
COMPLETED
:
{
type
:
'success'
},
CANCELLED
:
{
type
:
'danger'
},
ARCHIVE
:
{
style
:
{
backgroundColor
:
'#909399'
,
color
:
'#FFFFFF'
,
borderColor
:
'#909399'
,
},
},
}
const
parseOperationNo
=
(
operationNoWithStatus
:
string
)
=>
{
const
match
=
operationNoWithStatus
.
match
(
/^
([^
_
]
+
)
_
(
.+
)
$/
)
if
(
!
match
)
return
{
operationNo
:
operationNoWithStatus
,
status
:
''
,
statusText
:
''
}
const
[,
operationNo
,
status
]
=
match
const
statusText
=
operationStatusMap
[
status
]
||
status
return
{
operationNo
,
status
,
statusText
}
}
const
podOrderDetailsColumns
=
computed
(()
=>
[
{
label
:
'图片'
,
prop
:
'image'
,
width
:
250
,
slot
:
'image'
,
align
:
'center'
,
},
{
label
:
'操作单号'
,
prop
:
'operationNos'
,
width
:
180
,
align
:
'center'
,
render
:
(
row
:
ProductList
)
=>
{
return
(
<
div
>
{
row
.
operationNos
?.
split
(
','
).
map
((
item
)
=>
{
const
{
operationNo
,
status
,
statusText
}
=
parseOperationNo
(
item
)
const
{
type
,
style
}
=
operationStatusTagMap
[
status
]
||
{}
return
(
<
div
>
{
operationNo
}
{
statusText
&&
(
<
ElTag
size
=
"small"
type
=
{
type
}
style
=
{{
marginLeft
:
'6px'
,
...
style
}}
>
{
statusText
}
<
/ElTag
>
)}
<
/div
>
)
})}
<
/div
>
)
},
},
{
label
:
'库存 SKU'
,
prop
:
'thirdSkuCode'
,
width
:
180
,
align
:
'center'
,
},
{
label
:
'variant SKU'
,
prop
:
'variantSku'
,
width
:
160
,
align
:
'center'
,
},
{
label
:
'商品名称'
,
prop
:
'productName'
,
minWidth
:
100
,
},
{
label
:
'购买数量'
,
prop
:
'purchaseNumber'
,
width
:
90
,
align
:
'center'
,
fixed
:
'right'
,
},
{
label
:
'拣货数量'
,
prop
:
'count'
,
width
:
90
,
align
:
'center'
,
fixed
:
'right'
,
},
{
label
:
'验证结果'
,
slot
:
'verifyResult'
,
width
:
90
,
align
:
'center'
,
fixed
:
'right'
,
},
])
const
boxChange
=
ref
<
boolean
>
(
false
)
const
boxIndex
=
ref
<
number
|
null
>
(
null
)
const
orderStore
=
useOrderStore
()
const
isLock
=
ref
<
boolean
>
(
false
)
const
productionOrderRef
=
ref
()
const
socketConnect
=
computed
(()
=>
orderStore
.
socketConnect
)
const
podBoxList
=
computed
(()
=>
{
return
orderStore
.
podBoxList
})
const
coverImage
=
ref
<
string
>
(
''
)
let
currentCode
=
''
const
tableRef
=
ref
()
watch
(
visible
,
async
(
value
:
boolean
)
=>
{
if
(
value
)
{
podOrderDetailsData
.
value
=
{}
currentCode
=
''
resetPlatform
()
await
getSortingAreaList
()
warehouseId
.
value
=
''
sortingAreaId
.
value
=
''
const
localRaw
=
localStorage
.
getItem
(
SORTING_AREA_CACHE_KEY
)
||
''
const
localData
=
localRaw
?
JSON
.
parse
(
localRaw
)
:
''
const
localSortingAreaId
=
localData
.
sortingAreaId
const
localWarehouseId
=
localData
.
warehouseId
const
hit
=
sortingAreaList
.
value
.
find
(
(
item
)
=>
item
.
id
===
localSortingAreaId
&&
item
.
warehouseId
===
localWarehouseId
,
)
if
(
hit
)
{
sortingAreaId
.
value
=
hit
.
id
warehouseId
.
value
=
hit
.
warehouseId
}
else
{
const
defaultArea
=
sortingAreaList
.
value
.
find
(
(
item
)
=>
item
.
defaultWarehouse
===
1
&&
item
.
areaCode
===
'AREA_0'
,
)
||
sortingAreaList
.
value
[
0
]
sortingAreaId
.
value
=
defaultArea
.
id
warehouseId
.
value
=
defaultArea
.
warehouseId
}
if
(
userStore
.
user
?.
factory
.
id
)
{
try
{
// 断线自动重连成功时会走 open 回调重新订阅
await
socket
.
init
(
{
account
:
userStore
.
user
?.
account
.
toString
(),
factoryNo
:
userStore
.
user
?.
factory
.
id
.
toString
(),
},
messageChange
,
sendWsSubscribe
,
)
sendWsSubscribe
()
}
catch
(
error
)
{
console
.
error
(
error
)
}
}
initOrderDetailBox
()
initPrintDevice
()
const
locaclPrinter
=
localStorage
.
getItem
(
'sheetPrinter'
)
if
(
locaclPrinter
)
sheetPrinter
.
value
=
JSON
.
parse
(
locaclPrinter
)
emit
(
'set-printer'
,
sheetPrinter
.
value
)
}
else
{
if
(
userStore
.
user
?.
factory
.
id
)
{
socket
.
send
({
code
:
WS_CLOSE_CODE
,
factoryNo
:
userStore
.
user
?.
factory
.
id
,
warehouseId
:
warehouseId
.
value
,
packingId
:
sortingAreaId
.
value
,
})
socket
.
close
()
}
}
})
watch
(
boxIndex
,
()
=>
{
// if (value) {
const
bool
=
!
boxChange
.
value
boxChange
.
value
=
false
renderItemBox
(
bool
)
// }
})
watch
(
podBoxList
,
(
value
)
=>
{
if
(
value
)
{
const
item
=
value
.
find
((
item
)
=>
item
.
box
===
podBoxIndex
.
value
)
if
(
item
?.
data
)
{
renderItemBox
(
true
)
}
else
{
// 0 号箱为单件,不在播种墙列表中,不应清空当前单件数据
if
(
boxIndex
.
value
===
podBoxIndex
.
value
&&
boxIndex
.
value
!==
0
)
{
podOrderDetailsData
.
value
=
{}
boxIndex
.
value
=
null
}
}
}
},
{
deep
:
true
},
)
watch
(
()
=>
podOrderDetailsData
.
value
,
(
val
)
=>
{
if
(
val
&&
val
.
productList
?.
length
)
val
.
productList
.
forEach
((
el
)
=>
{
if
(
!
el
.
previewImgs
)
{
if
(
el
.
productMark
===
'custom_normal'
||
el
.
productMark
===
'normal'
)
{
el
.
previewImgs
=
[{
url
:
el
.
variantImage
||
''
}]
}
else
{
el
.
previewImgs
=
el
.
imageAry
&&
JSON
.
parse
(
el
.
imageAry
).
length
>
0
?
JSON
.
parse
(
el
.
imageAry
)
:
[{
url
:
el
.
variantImage
}]
}
}
})
},
{
deep
:
true
},
)
const
podBoxIndex
=
computed
(()
=>
orderStore
.
podBoxIndex
)
let
renderLock
=
false
let
pickFinishedAlertToken
=
0
const
renderItemBox
=
(
bool
:
boolean
)
=>
{
if
(
!
podBoxList
.
value
||
podBoxList
.
value
.
length
===
0
||
!
boxIndex
.
value
||
(
bool
&&
boxIndex
.
value
!==
podBoxIndex
.
value
)
)
return
if
(
renderLock
)
return
renderLock
=
true
let
boxItem
=
podBoxList
.
value
?.
find
((
item
)
=>
item
.
box
===
boxIndex
.
value
)
if
(
!
boxItem
)
boxItem
=
{
data
:
{
productList
:
[]
}
}
const
{
data
}
=
boxItem
data
?.
productList
?.
forEach
((
el
)
=>
{
if
(
!
el
.
previewImgs
||
!
el
.
previewImgs
.
length
)
{
if
(
el
.
productMark
===
'custom_normal'
||
el
.
productMark
===
'normal'
)
{
el
.
previewImgs
=
[{
url
:
el
.
variantImage
||
''
}]
}
else
{
el
.
previewImgs
=
JSON
.
parse
(
el
.
imageAry
||
'[]'
)
}
}
})
if
(
!
data
)
{
renderLock
=
false
currentCode
=
''
podOrderDetailsData
.
value
=
{}
return
}
const
{
productList
=
[]
}
=
data
const
pickingNumber
=
productList
.
reduce
((
prev
,
product
)
=>
{
return
prev
+
(
product
.
count
||
0
)
},
0
)
data
.
pickingNumber
=
pickingNumber
// coverImage.value = productList[0].previewImgs?.[0]?.url || ''
for
(
const
product
of
productList
)
{
if
(
product
.
count
===
product
.
purchaseNumber
)
{
product
.
power
=
true
}
}
if
(
currentCode
)
{
if
(
!
currentCode
.
startsWith
(
'JM'
))
{
const
parts
=
currentCode
.
split
(
'_'
)
currentCode
=
parts
.
length
>
3
&&
parts
[
3
].
startsWith
(
'OP'
)
?
parts
[
3
]
:
parts
.
length
>
1
?
parts
[
1
]
:
parts
[
0
]
}
for
(
const
product
of
productList
)
{
if
(
product
.
thirdSkuCode
===
currentCode
||
(
product
.
operationNos
&&
product
.
operationNos
.
includes
(
currentCode
))
)
{
if
(
coverImage
.
value
!==
product
.
previewImgs
?.[
0
]?.
url
)
{
coverImage
.
value
=
product
.
previewImgs
?.[
0
]?.
url
||
''
}
nextTick
(()
=>
{
tableRef
.
value
?.
setCurrentRow
(
product
)
})
break
}
}
currentCode
=
''
}
else
{
// 切换箱子,默认展示第一张图片
// coverImage.value = productList[0]?.previewImgs?.[0]?.url || ''
}
podOrderDetailsData
.
value
=
data
if
(
productList
.
every
((
item
)
=>
item
.
power
))
{
if
(
userStore
.
user
?.
id
!==
boxItem
.
fromUser
)
return
// 配货分拣 非自动打单的配货区: 不打印 不打单完成; 自动打单的配货区: 打印成功后打单完成
if
(
!
isAutoPrint
.
value
)
{
renderLock
=
false
return
}
print
(
data
,
false
,
()
=>
{
renderLock
=
false
})
}
else
{
renderLock
=
false
}
}
const
messageChange
=
(
data
:
WebSocketMessage
)
=>
{
if
(
!
data
)
return
const
{
code
,
...
more
}
=
data
// 过滤非本配货区的数据
if
(
sortingAreaId
.
value
&&
more
.
txt
&&
JSON
.
parse
(
more
.
txt
as
string
)?.
packingId
!==
sortingAreaId
.
value
)
{
return
}
// 扫码进箱
if
(
code
===
'FACTORY_POD_ORDER_TOP_PRINT_ORDER'
)
{
try
{
if
(
typeof
more
.
txt
===
'string'
)
{
console
.
log
(
'%conWebSocketMessage'
,
'font-size: 20px; color: red;'
,
JSON
.
parse
(
more
.
txt
),
more
.
fromUser
,
)
}
}
catch
(
e
)
{
console
.
error
(
e
)
}
console
.
log
(
'WebSocketMessage'
,
more
)
setPodBoxList
(
more
)
}
// 清空箱子
else
if
(
code
===
'FACTORY_POD_ORDER_TOP_BOX_FLUSH'
)
{
try
{
if
(
typeof
more
.
txt
===
'string'
)
{
console
.
log
(
'%conWebSocketMessage'
,
'font-size: 20px; color: green;'
,
JSON
.
parse
(
more
.
txt
),
more
.
fromUser
,
)
}
}
catch
(
e
)
{
console
.
error
(
e
)
}
initOrderDetailBox
()
}
}
const
setPodBoxList
=
(
data
:
WebSocketMessage
)
=>
{
const
obj
=
data
.
txt
if
(
obj
&&
typeof
obj
===
'string'
)
{
const
parsedData
=
JSON
.
parse
(
obj
)
parsedData
.
fromUser
=
data
.
fromUser
orderStore
.
setPodBoxList
({
url
:
INIT_URL
,
...
parsedData
,
})
}
}
const
initPrintDevice
=
()
=>
{
const
lodop
=
getCLodop
(
null
,
null
)
if
(
!
lodop
)
return
const
arr
=
[]
// 获取打印机数量
const
length
=
lodop
.
GET_PRINTER_COUNT
()
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
// 根据设备序号获取设备名
const
name
=
lodop
.
GET_PRINTER_NAME
(
i
)
arr
.
push
(
name
)
}
console
.
log
(
'arr'
,
arr
,
lodop
.
GET_PRINTER_NAME
(
1
))
// 获取默认打印机
sheetPrinter
.
value
=
lodop
.
GET_PRINTER_NAME
(
0
)
printDeviceList
.
value
=
arr
}
const
handleSearch
=
()
=>
{
resetPlatform
()
const
code
=
productionOrder
.
value
if
(
!
code
)
{
ElMessage
.
warning
(
'请输入生产单号'
)
productionOrderRef
.
value
.
focus
()
return
}
if
(
isLock
.
value
)
{
ElMessage
.
warning
(
'请稍后再试'
)
productionOrderRef
.
value
.
focus
()
return
}
productionOrder
.
value
=
''
isLock
.
value
=
true
const
everyPower
=
podOrderDetailsData
.
value
&&
podOrderDetailsData
.
value
?.
productList
?.
every
((
item
)
=>
item
.
power
)
if
(
!
isAutoPrint
.
value
)
{
getPackingData
(
code
)
return
}
if
(
everyPower
)
{
/**
* printSuccess 打印成功
* printFail 打印失败
* printIng 打印中
* notPrintSuccess 未能获取打印状态
*/
// 配货分拣:开启自动打单且打印成功,提交;不开启自动打单,不提示
if
(
podOrderDetailsData
.
value
?.
printResult
===
'printSuccess'
&&
isAutoPrint
.
value
)
{
submitInspection
(()
=>
{
getPackingData
(
code
)
})
}
else
{
ElMessage
.
warning
(
'未获取到打印结果'
)
isLock
.
value
=
false
}
}
else
{
getPackingData
(
code
)
}
}
const
userStore
=
useUserStore
()
const
getPackingData
=
async
(
code
:
string
)
=>
{
const
loading
=
ElLoading
.
service
({
fullscreen
:
true
,
text
:
'加载中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
currentCode
=
code
try
{
const
factoryNo
=
userStore
.
user
?.
factory
.
id
if
(
!
factoryNo
)
{
isLock
.
value
=
false
productionOrder
.
value
=
''
return
}
const
url
=
'factory/podOrderPacking/top/putPackingSafe'
const
params
=
{
podOperationNo
:
code
,
box
:
boxIndex
.
value
,
factoryNo
,
}
const
res
=
await
getPackingDataApi
(
url
,
params
)
if
(
res
.
code
!==
200
)
{
ElMessage
.
warning
(
res
.
message
)
isLock
.
value
=
false
productionOrder
.
value
=
''
return
}
const
{
box
,
data
,
packingId
,
factoryNo
:
respFactoryNo
}
=
res
.
data
const
area
=
sortingAreaList
.
value
.
find
((
item
)
=>
item
.
id
==
packingId
)
const
areaChanged
=
sortingAreaId
.
value
!=
packingId
||
(
!!
area
&&
warehouseId
.
value
!=
area
.
warehouseId
)
handleSortingAreaChange
(
packingId
as
number
,
respFactoryNo
??
factoryNo
,
'scan'
,
)
if
(
areaChanged
)
{
await
initOrderDetailBox
(
'scan'
)
}
boxChange
.
value
=
true
boxIndex
.
value
=
box
as
number
if
(
boxIndex
.
value
==
0
)
{
const
orderData
=
data
as
OrderData
orderData
.
productList
?.
forEach
((
el
)
=>
{
if
(
!
el
.
previewImgs
||
!
el
.
previewImgs
.
length
)
{
if
(
el
.
productMark
===
'custom_normal'
||
el
.
productMark
===
'normal'
)
{
el
.
previewImgs
=
[{
url
:
el
.
variantImage
||
''
}]
}
else
{
el
.
previewImgs
=
el
.
imageAry
&&
JSON
.
parse
(
el
.
imageAry
).
length
>
0
?
JSON
.
parse
(
el
.
imageAry
)
:
[{
url
:
el
.
variantImage
}]
}
}
})
podOrderDetailsData
.
value
=
orderData
podOrderDetailsData
.
value
.
fromUser
=
userStore
.
user
?.
id
const
list
=
podOrderDetailsData
.
value
.
productList
if
(
list
?.
length
)
{
await
nextTick
()
tableRef
.
value
?.
setCurrentRow
(
list
[
0
])
coverImage
.
value
=
list
[
0
].
previewImgs
?.[
0
]?.
url
||
''
for
(
const
product
of
list
)
{
if
(
product
.
count
===
product
.
purchaseNumber
)
{
product
.
power
=
true
print
(
orderData
,
false
,
()
=>
{
renderLock
=
false
})
}
}
}
}
}
catch
(
error
)
{
const
err
=
error
as
BaseRespData
<
{
inventory
:
number
producingQuantity
:
number
availableInventory
:
number
thirdSkuCode
?:
string
packingId
?:
number
box
?:
number
}
>
if
(
err
.
code
===
208
)
{
loading
.
close
()
const
{
packingId
,
box
}
=
err
.
data
const
area
=
sortingAreaList
.
value
.
find
((
item
)
=>
item
.
id
===
packingId
)
await
ElMessageBox
.
alert
(
`重复扫码!该操作单已在仓库:
${
area
?.
warehouseName
}
,
<
br
/>
配货区:
$
{
area
?.
areaName
}
,箱子:
$
{
box
}
中存在!
`,
'提示',
{
confirmButtonText: '确定',
dangerouslyUseHTMLString: true,
},
)
return
}
if (err?.code === 301) {
loading.close()
await ElMessageBox.alert(
`
$
{
err
.
data
?.
thirdSkuCode
}
库存不足,无法进入生产!请联系仓库管理人员核对库存。
<
br
/>
库存数量:
$
{
err
.
data
?.
inventory
}
,生产中的数量:
$
{
err
.
data
?.
producingQuantity
}
,
<
span
style
=
"color: red"
>
可调配库存:
$
{
err
.
data
?.
availableInventory
}
<
/span>`
,
'提示'
,
{
type
:
'warning'
,
dangerouslyUseHTMLString
:
true
,
},
)
return
}
showError
(
err
.
message
)
}
finally
{
isLock
.
value
=
false
productionOrder
.
value
=
''
loading
.
close
()
productionOrderRef
.
value
.
focus
()
}
}
// 提交打单
const
submitInspection
=
async
(
callback
:
()
=>
void
)
=>
{
const
factoryNo
=
userStore
.
user
?.
factory
.
id
if
(
!
factoryNo
)
{
return
}
try
{
const
url
=
'factory/podOrderPacking/podPrintOrderComplete'
let
params
=
{}
params
=
{
orderParamList
:
[{
id
:
podOrderDetailsData
.
value
?.
id
}],
}
const
res
=
await
submitInspectionApi
(
url
,
params
,
boxIndex
.
value
,
warehouseId
.
value
,
sortingAreaId
.
value
,
)
// if (res.code !== 200) return
ElMessage
.
warning
(
res
.
message
)
isLock
.
value
=
false
coverImage
.
value
=
''
podOrderDetailsData
.
value
=
{}
productionOrderRef
.
value
.
focus
()
callback
&&
callback
()
}
catch
(
error
)
{
isLock
.
value
=
false
renderLock
=
false
productionOrderRef
.
value
.
focus
()
console
.
error
(
error
)
}
}
const
isBillLading
=
ref
<
boolean
>
(
false
)
const
initOrderDetailBox
=
async
(
type
:
'scan'
|
'manual'
=
'manual'
)
=>
{
const
factoryNo
=
userStore
.
user
?.
factory
.
id
if
(
!
factoryNo
)
{
return
}
const
loading
=
ElLoading
.
service
({
fullscreen
:
true
,
text
:
'加载中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
try
{
const
url
=
INIT_URL
const
res
=
await
getPodBoxListApi
(
url
,
factoryNo
,
warehouseId
.
value
,
sortingAreaId
.
value
,
)
if
(
res
.
code
!==
200
)
{
ElMessage
.
warning
(
res
.
message
)
return
}
orderStore
.
setPodBoxList
({
url
,
boxList
:
res
.
data
,
fromUser
:
userStore
.
user
?
userStore
.
user
.
id
:
0
,
factoryNo
,
warehouseId
:
warehouseId
.
value
,
})
const
boxList
=
res
.
data
.
map
((
item
)
=>
{
if
(
item
.
data
)
{
if
(
!
item
.
data
.
filePath
)
{
isBillLading
.
value
=
true
}
else
{
isBillLading
.
value
=
false
}
const
productList
=
item
?.
data
?.
productList
||
[]
const
pickingNumber
=
productList
.
reduce
((
prev
,
product
)
=>
{
if
(
product
.
count
===
product
.
purchaseNumber
)
{
product
.
power
=
true
}
if
(
product
.
count
)
{
return
prev
+
product
.
count
}
return
prev
},
0
)
item
.
data
.
pickingNumber
=
pickingNumber
}
return
item
})
// 当 boxIndex.value 为 0 时,不更新列表数据,防止单件数据丢失
if
(
boxIndex
.
value
!==
0
)
{
const
currentBox
=
boxIndex
.
value
const
currentBoxItem
=
currentBox
?
boxList
.
find
((
item
)
=>
item
.
box
===
currentBox
&&
item
.
data
)
:
undefined
const
fallbackItem
=
boxList
.
find
((
item
)
=>
item
.
data
)
const
targetItem
=
currentBoxItem
||
fallbackItem
podOrderDetailsData
.
value
=
targetItem
?.
data
||
undefined
boxIndex
.
value
=
targetItem
?.
box
||
null
podOrderDetailsData
.
value
?.
productList
?.
forEach
((
el
)
=>
{
if
(
!
el
.
previewImgs
)
{
if
(
el
.
productMark
===
'custom_normal'
||
el
.
productMark
===
'normal'
)
{
el
.
previewImgs
=
[{
url
:
el
.
variantImage
||
''
}]
}
else
{
el
.
previewImgs
=
el
.
imageAry
&&
JSON
.
parse
(
el
.
imageAry
).
length
>
0
?
JSON
.
parse
(
el
.
imageAry
)
:
[{
url
:
el
.
variantImage
}]
}
}
})
if
(
type
!==
'scan'
)
{
coverImage
.
value
=
podOrderDetailsData
.
value
?.
productList
?.[
0
]?.
previewImgs
?.[
0
].
url
||
''
}
if
(
podOrderDetailsData
.
value
&&
podOrderDetailsData
.
value
.
pickingNumber
===
podOrderDetailsData
.
value
.
purchaseNumber
)
{
podOrderDetailsData
.
value
.
printResult
=
'notPrintSuccess'
}
}
const
pickFinished
=
boxList
.
filter
((
item
)
=>
{
return
item
.
data
?.
productList
?.
every
((
product
)
=>
product
.
power
)
})
// 配货分拣 扫码切换配货区且配货完成 不提示
const
boxs
=
pickFinished
.
map
((
item
)
=>
item
.
box
)
if
(
type
===
'manual'
&&
boxs
.
length
>
0
)
{
nextTick
(
async
()
=>
{
const
token
=
++
pickFinishedAlertToken
if
(
token
>
1
)
{
ElMessageBox
.
close
()
}
try
{
await
ElMessageBox
.
alert
(
`检测到
${
boxs
.
join
(
','
)}
号箱验货完成,请及时处理`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
},
)
if
(
token
!==
pickFinishedAlertToken
)
return
productionOrderRef
.
value
.
focus
()
}
catch
(
error
)
{
if
(
token
!==
pickFinishedAlertToken
)
return
productionOrderRef
.
value
.
focus
()
console
.
error
(
error
)
}
})
}
renderLock
=
false
productionOrder
.
value
=
''
isLock
.
value
=
false
productionOrderRef
.
value
.
focus
()
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
loading
.
close
()
}
}
const
renderPrintResult
=
(
printResult
:
string
)
=>
{
switch
(
printResult
)
{
case
'printSuccess'
:
return
'打印成功'
case
'printFail'
:
return
'打印失败'
case
'printIng'
:
return
'打印中'
case
'notPrintSuccess'
:
return
'未能获取打印状态'
default
:
return
'未知'
}
}
const
handleOpened
=
()
=>
{
productionOrderRef
.
value
.
focus
()
}
const
onClose
=
()
=>
{
emit
(
'refresh'
)
}
const
handleBoxClick
=
(
item
:
PodMakeOrderData
)
=>
{
const
{
box
,
data
}
=
item
if
(
box
==
0
)
return
isBillLading
.
value
=
!
data
?.
filePath
boxIndex
.
value
=
box
||
null
boxChange
.
value
=
true
productionOrderRef
.
value
.
focus
()
}
const
handleClearBox
=
async
()
=>
{
try
{
if
(
!
boxIndex
.
value
)
{
ElMessage
.
warning
(
'请选择箱子'
)
return
}
await
ElMessageBox
.
alert
(
'确定清空当前箱子吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
})
}
catch
{
return
}
const
factoryNo
=
userStore
.
user
?.
factory
.
id
if
(
!
factoryNo
)
{
return
}
try
{
const
url
=
'factory/podOrderPacking/local/delPodBoxOrderDetailsByBox'
const
res
=
await
clearBoxApi
(
url
,
factoryNo
,
boxIndex
.
value
||
null
,
warehouseId
.
value
,
sortingAreaId
.
value
,
)
if
(
res
.
code
!==
200
)
{
ElMessage
.
warning
(
res
.
message
)
return
}
ElMessage
.
success
(
'清空成功'
)
boxIndex
.
value
=
null
podOrderDetailsData
.
value
=
{}
coverImage
.
value
=
''
productionOrderRef
.
value
.
focus
()
}
catch
(
error
)
{
productionOrderRef
.
value
.
focus
()
console
.
error
(
error
)
}
}
const
handlePrintFinish
=
async
()
=>
{
if
(
podOrderDetailsData
.
value
?.
productList
?.
length
)
{
const
{
productList
}
=
podOrderDetailsData
.
value
const
bool
=
productList
.
some
((
el
)
=>
!
el
.
power
)
if
(
bool
)
{
try
{
await
ElMessageBox
.
alert
(
'商品数量未配齐无法打单完成,请检查!'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
},
)
}
catch
{
return
}
}
else
{
try
{
await
ElMessageBox
.
alert
(
'确定打单完成吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
})
submitInspection
(()
=>
{
productionOrderRef
.
value
.
focus
()
})
}
catch
{
productionOrderRef
.
value
.
focus
()
return
}
}
}
else
{
try
{
await
ElMessageBox
.
alert
(
'未检测到商品,请检查!'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
})
}
catch
{
return
}
}
}
const
handlePrinterChange
=
(
value
:
string
)
=>
{
emit
(
'set-printer'
,
value
)
}
/** 已自动打印过的订单,避免 WS 回写清掉 printResult 后重复打印 */
const
autoPrintedIds
=
new
Set
<
number
>
()
const
print
=
(
data
:
OrderData
,
forcePrint
=
false
,
callback
?:
()
=>
void
)
=>
{
const
_boxIndex
=
boxIndex
.
value
const
orderId
=
data
.
id
if
(
!
forcePrint
&&
(
data
.
printResult
||
(
orderId
!=
null
&&
autoPrintedIds
.
has
(
orderId
)))
)
{
callback
&&
callback
()
return
}
if
(
!
forcePrint
&&
orderId
!=
null
)
autoPrintedIds
.
add
(
orderId
)
props
.
printOrder
(
data
,
(
status
:
boolean
)
=>
{
if
(
!
status
&&
orderId
!=
null
)
autoPrintedIds
.
delete
(
orderId
)
callback
&&
callback
()
const
item
=
podBoxList
.
value
?.
find
((
item
)
=>
item
.
box
===
_boxIndex
)
if
(
item
&&
item
.
data
)
{
if
(
status
)
{
item
.
data
.
printResult
=
'printSuccess'
}
else
{
item
.
data
.
printResult
=
'printFail'
}
}
if
(
_boxIndex
==
0
)
{
if
(
status
)
{
;(
podOrderDetailsData
.
value
as
OrderData
).
printResult
=
'printSuccess'
}
else
{
;(
podOrderDetailsData
.
value
as
OrderData
).
printResult
=
'printFail'
}
return
}
const
factoryNo
=
userStore
.
user
?.
factory
.
id
if
(
!
factoryNo
)
return
if
(
!
warehouseId
.
value
)
{
return
ElMessage
.
warning
(
'请选择仓库'
)
}
orderStore
.
setPodBoxList
({
url
:
INIT_URL
,
fromUser
:
userStore
.
user
?
userStore
.
user
.
id
:
0
,
boxList
:
item
?
(
item
.
data
as
PodMakeOrderData
[])
:
null
,
factoryNo
,
box
:
_boxIndex
||
undefined
,
warehouseId
:
warehouseId
.
value
,
})
})
}
const
clearAllBox
=
async
()
=>
{
try
{
await
ElMessageBox
.
alert
(
'确定清空所有箱子吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
})
}
catch
{
productionOrderRef
.
value
.
focus
()
return
}
try
{
const
url
=
'factory/podOrderPacking/local/delPodBoxOrderDetails'
const
res
=
await
clearAllBoxApi
(
url
,
warehouseId
.
value
,
userStore
.
user
?.
factory
.
id
,
sortingAreaId
.
value
,
)
if
(
res
.
code
!==
200
)
return
productionOrderRef
.
value
.
focus
()
podOrderDetailsData
.
value
=
{}
coverImage
.
value
=
''
boxIndex
.
value
=
null
}
catch
(
error
)
{
productionOrderRef
.
value
.
focus
()
console
.
error
(
error
)
}
}
const
handleRowClick
=
(
row
:
ProductList
)
=>
{
console
.
log
(
907
,
row
)
coverImage
.
value
=
row
.
previewImgs
?.[
0
]?.
url
||
''
productionOrderRef
.
value
.
focus
()
}
const
handleCurrentChange
=
(
url
:
string
)
=>
{
if
(
url
)
{
coverImage
.
value
=
url
||
''
}
}
const
warehouseId
=
ref
<
string
|
number
>
(
''
)
const
sortingAreaList
=
ref
<
SortingList
[]
>
([])
const
sortingAreaId
=
ref
<
number
|
string
>
(
''
)
const
isAutoPrint
=
ref
(
localStorage
.
getItem
(
AUTO_PRINT_CACHE_KEY
)
===
'true'
)
// 配货分拣自动打单缓存监听
watch
(
isAutoPrint
,
(
val
)
=>
{
localStorage
.
setItem
(
AUTO_PRINT_CACHE_KEY
,
String
(
val
))
})
// WS 消息订阅
const
sendWsSubscribe
=
(
factoryNo
?:
number
|
string
)
=>
{
const
no
=
factoryNo
??
userStore
.
user
?.
factory
.
id
if
(
!
no
)
return
socket
.
send
({
code
:
WS_OPEN_CODE
,
factoryNo
:
no
,
warehouseId
:
warehouseId
.
value
,
packingId
:
sortingAreaId
.
value
,
})
}
// 配货分拣 更新配货区
const
syncSortingArea
=
(
packingId
:
number
|
string
,
factoryNo
:
number
|
string
,
)
=>
{
const
currentArea
=
sortingAreaList
.
value
.
find
((
item
)
=>
item
.
id
==
packingId
)
if
(
!
currentArea
)
return
warehouseId
.
value
=
currentArea
.
warehouseId
sortingAreaId
.
value
=
packingId
sendWsSubscribe
(
factoryNo
)
}
// 配货分拣 手动切换配货区
const
handleSortingAreaChange
=
(
value
:
string
|
number
,
factoryNo
?:
number
|
string
,
type
:
'scan'
|
'manual'
=
'manual'
,
)
=>
{
const
no
=
factoryNo
??
userStore
.
user
?.
factory
.
id
if
(
!
no
)
return
syncSortingArea
(
value
,
no
)
localStorage
.
setItem
(
SORTING_AREA_CACHE_KEY
,
JSON
.
stringify
({
warehouseId
:
warehouseId
.
value
,
sortingAreaId
:
sortingAreaId
.
value
,
}),
)
initOrderDetailBox
(
type
)
resetPlatform
()
}
const
reconnectWebSocket
=
async
()
=>
{
if
(
!
userStore
.
user
?.
factory
.
id
)
return
try
{
await
socket
.
init
(
{
account
:
userStore
.
user
?.
account
.
toString
(),
factoryNo
:
userStore
.
user
?.
factory
.
id
.
toString
(),
},
messageChange
,
sendWsSubscribe
,
)
sendWsSubscribe
()
}
catch
(
error
)
{
console
.
error
(
'WebSocket 重连失败:'
,
error
)
ElMessage
.
error
(
'WebSocket 重连失败,请稍后重试'
)
}
}
// 配货分拣 获取配货区列表
const
getSortingAreaList
=
async
()
=>
{
const
res
=
await
getSortingRuleListApi
({})
if
(
res
.
code
!==
200
)
return
sortingAreaList
.
value
=
res
.
data
.
records
}
// 筛选查询平台
const
platformList
=
computed
(
()
=>
platformJson
.
filter
((
item
)
=>
item
.
type
===
'TIKTOK'
),
// platformJson,
)
const
platform
=
ref
<
string
>
(
''
)
const
queriedPlatform
=
ref
<
string
>
(
''
)
const
platformMatchedBoxes
=
computed
(()
=>
{
if
(
!
queriedPlatform
.
value
)
return
null
return
(
podBoxList
.
value
||
[])
.
filter
(
(
item
)
=>
item
.
data
?.
platform
?.
toUpperCase
()
===
queriedPlatform
.
value
.
toUpperCase
(),
)
.
map
((
item
)
=>
item
.
box
)
.
filter
((
box
):
box
is
number
=>
box
!=
null
&&
box
!==
0
)
})
const
handlePlatformChange
=
()
=>
{
if
(
!
platform
.
value
)
{
ElMessage
.
warning
(
'请选择平台'
)
return
}
queriedPlatform
.
value
=
platform
.
value
}
const
resetPlatform
=
()
=>
{
platform
.
value
=
''
queriedPlatform
.
value
=
''
}
</
script
>
<
style
scoped
lang=
"scss"
>
.header-bar
{
display
:
flex
;
align-items
:
center
;
gap
:
16px
;
}
.title
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
}
.reconnect-btn.is-hidden
{
visibility
:
hidden
;
pointer-events
:
none
;
}
.auto-print-checkbox
{
font-weight
:
400
;
}
.online
{
color
:
green
;
font-size
:
14px
;
font-weight
:
600
;
}
.offline
{
color
:
red
;
font-size
:
14px
;
font-weight
:
600
;
}
.pod-make-order-content
{
display
:
flex
;
height
:
100%
;
overflow
:
hidden
;
gap
:
10px
;
}
.left-content
{
display
:
flex
;
flex-direction
:
column
;
gap
:
10px
;
width
:
calc
(
100%
-
900px
-
20px
);
}
.head-form
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
}
.table-content
{
flex
:
1
;
overflow
:
hidden
;
}
.right-panel
{
display
:
flex
;
flex-direction
:
column
;
flex
:
1
;
min-height
:
0
;
overflow
:
hidden
;
.platform-filter
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
width
:
100%
;
margin-bottom
:
5px
;
}
.right-panel-body
{
min-height
:
0
;
overflow
:
hidden
;
}
}
.sorting-area-content
{
border
:
2px
solid
#666
;
padding
:
10px
;
margin-bottom
:
10px
;
width
:
100%
;
height
:
80px
;
font-size
:
35px
;
color
:
red
;
font-weight
:
600
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.middle-content
{
width
:
500px
;
display
:
flex
;
flex-direction
:
column
;
gap
:
5px
;
}
.right-content
{
width
:
400px
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
}
.basic-info
{
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
1
fr
);
gap
:
10px
;
.basic-info-item
{
display
:
flex
;
align-items
:
center
;
overflow
:
hidden
;
span
:
last-child
{
flex
:
1
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
.box-top
{
position
:
relative
;
border
:
1px
solid
#ddd
;
background
:
rgb
(
50
50
50
);
border-radius
:
5px
;
padding
:
10px
15px
;
box-sizing
:
border-box
;
font-size
:
16px
;
color
:
#fff
;
overflow
:
hidden
;
}
.multiple-title
{
position
:
absolute
;
top
:
0
;
right
:
0
;
&::after
{
position
:
absolute
;
top
:
-31px
;
right
:
-30px
;
content
:
''
;
border-width
:
30px
;
border-style
:
solid
;
border-color
:
transparent
transparent
red
transparent
;
transform
:
rotate
(
45deg
);
}
.multiple-title-text
{
position
:
absolute
;
z-index
:
2
;
color
:
#fff
;
left
:
-20px
;
}
}
.box-top-item
{
display
:
flex
;
height
:
80px
;
align-items
:
center
;
margin-bottom
:
10px
;
}
.box-top-item-box-index
{
font-size
:
60px
;
color
:
red
;
text-align
:
center
;
flex
:
1
;
font-weight
:
600
;
white-space
:
nowrap
;
}
.box-top-item-box-index-text
{
margin-right
:
15px
;
font-size
:
30px
;
white-space
:
nowrap
;
}
.box-top-item-box-index-number
{
font-size
:
60px
;
color
:
red
;
display
:
inline-block
;
text-align
:
center
;
flex
:
1
;
font-weight
:
600
;
}
.box-top-item-status
{
margin-bottom
:
15px
;
}
.order-image
{
flex
:
1
;
overflow
:
auto
;
border
:
1px
solid
#ddd
;
background
:
#eee
;
}
.box-list
{
display
:
grid
;
grid-template-columns
:
repeat
(
7
,
50px
);
gap
:
8px
;
position
:
relative
;
}
.box-list-item
{
position
:
relative
;
border
:
1px
solid
#ddd
;
cursor
:
pointer
;
font-size
:
18px
;
line-height
:
30px
;
height
:
46px
;
text-align
:
center
;
box-sizing
:
border-box
;
border-radius
:
5px
;
&:not(.isNull)
{
background
:
#819aff
;
color
:
#fff
;
}
&
.active
{
background
:
#ff9900
;
color
:
#fff
;
}
&
.platform-matched
{
background
:
rgb
(
177
,
19
,
19
);
color
:
#fff
;
}
.number
{
position
:
absolute
;
bottom
:
3px
;
right
:
0
;
left
:
0
;
text-align
:
center
;
font-size
:
12px
;
line-height
:
14px
;
color
:
#ddd
;
}
}
.cb-product-mark
{
position
:
absolute
;
top
:
0
;
right
:
0
;
.red-circle
{
width
:
8px
;
height
:
8px
;
border-radius
:
50%
;
background-color
:
red
;
}
}
</
style
>
src/views/order/factoryOrderNew/index.vue
View file @
d2f79600
...
@@ -608,9 +608,9 @@
...
@@ -608,9 +608,9 @@
>
>
<
/span
>
<
/span
>
<
span
v
-
if
=
"status === 'IN_PRODUCTION' && isEnableSorting"
class
=
"item"
>
<
span
v
-
if
=
"status === 'IN_PRODUCTION' && isEnableSorting"
class
=
"item"
>
<
ElButton
type
=
"primary"
@
click
=
"handle
SeedingWall('sort')"
<
ElButton
type
=
"primary"
@
click
=
"handle
InventorySorting"
>
>
配货分拣
<
/ElButto
n
配货分拣
>
<
/ElButton
>
<
/span
>
<
/span
>
<
span
<
span
v
-
if
=
"
v
-
if
=
"
...
@@ -1111,18 +1111,22 @@
...
@@ -1111,18 +1111,22 @@
v
-
model
=
"podOrderVisible"
v
-
model
=
"podOrderVisible"
:
print
-
order
=
"printOrder"
:
print
-
order
=
"printOrder"
:
warehouse
-
list
=
"warehouseList"
:
warehouse
-
list
=
"warehouseList"
:
title
=
"wallType === 'print' ? '配货打单' : '配货分拣'
"
title
=
"配货打单
"
:
is
-
new
-
order
=
"true"
:
is
-
new
-
order
=
"true"
:
wall
-
type
=
"wallType"
wall
-
type
=
"print"
:
ws
-
open
-
code
=
"
ws
-
open
-
code
=
"STARTORDERNEWPOD"
wallType === 'print' ? 'STARTORDERNEWPOD' : 'STARTORDERNEWPODTOP'
ws
-
close
-
code
=
"ENDORDERNEWPOD"
"
:
ws
-
close
-
code
=
"
wallType === 'print' ? 'ENDORDERNEWPOD' : 'ENDORDERNEWPODTOP'
"
init
-
url
=
"factory/podOrderPacking/local/getPodBoxOrderDetails"
init
-
url
=
"factory/podOrderPacking/local/getPodBoxOrderDetails"
@
set
-
printer
=
"handlePrinterChange"
@
set
-
printer
=
"handlePrinterChange"
@
set
-
warehouse
-
id
=
"handleWarehouseIdChange"
@
set
-
warehouse
-
id
=
"handlePrintWarehouseIdChange"
@
refresh
=
"() => refreshCurrentView({ isRefreshTree: true
}
)"
/>
<!--
配货分拣
-->
<
InventorySorting
v
-
model
=
"inventorySortingVisible"
:
print
-
order
=
"printOrder"
:
warehouse
-
list
=
"warehouseList"
@
set
-
printer
=
"handlePrinterChange"
@
refresh
=
"() => refreshCurrentView({ isRefreshTree: true
}
)"
@
refresh
=
"() => refreshCurrentView({ isRefreshTree: true
}
)"
/>
/>
<
PodDistributionOrder
<
PodDistributionOrder
...
@@ -1347,6 +1351,7 @@ import UpdateCustomDeclarationInfoDialog from '@/views/order/components/UpdateCu
...
@@ -1347,6 +1351,7 @@ import UpdateCustomDeclarationInfoDialog from '@/views/order/components/UpdateCu
import
WeightDialog
from
'@/views/order/components/WeightDialog.vue'
import
WeightDialog
from
'@/views/order/components/WeightDialog.vue'
import
FastProduction
from
'@/views/order/components/FastProduction.vue'
import
FastProduction
from
'@/views/order/components/FastProduction.vue'
import
PodMakeOrder
from
'@/views/order/podUs/PodMakeOrder.vue'
import
PodMakeOrder
from
'@/views/order/podUs/PodMakeOrder.vue'
import
InventorySorting
from
'./component/InventorySorting.vue'
import
PodDistributionOrder
from
'@/views/order/podCN/PodDistributionOrder.vue'
import
PodDistributionOrder
from
'@/views/order/podCN/PodDistributionOrder.vue'
import
PrintWarehouseSkuTag
from
'@/views/order/components/printWarehouseSkuTag.vue'
import
PrintWarehouseSkuTag
from
'@/views/order/components/printWarehouseSkuTag.vue'
import
UpdateAddress
from
'@/views/order/podCN/components/updateAddress.vue'
import
UpdateAddress
from
'@/views/order/podCN/components/updateAddress.vue'
...
@@ -1524,9 +1529,9 @@ const getListQueryPayload = () => {
...
@@ -1524,9 +1529,9 @@ const getListQueryPayload = () => {
}
}
const
getCraft
=
async
()
=>
{
const
getCraft
=
async
()
=>
{
const
res
=
await
getPodOrderCraftApi
()
const
res
=
await
getPodOrderCraftApi
()
const
data
:
CraftListData
[]
=
res
.
data
const
data
:
CraftListData
[]
=
res
.
data
podCraftList
.
value
=
data
.
map
((
item
:
CraftListData
)
=>
({
podCraftList
.
value
=
data
.
map
((
item
:
CraftListData
)
=>
({
id
:
item
.
craftCode
,
id
:
item
.
craftCode
,
name
:
item
.
craftName
,
name
:
item
.
craftName
,
warehouseName
:
processTypeMap
[
item
.
craftType
]
??
'其他'
,
warehouseName
:
processTypeMap
[
item
.
craftType
]
??
'其他'
,
...
@@ -1930,19 +1935,19 @@ const mainColumns = computed(() => [
...
@@ -1930,19 +1935,19 @@ const mainColumns = computed(() => [
}
,
}
,
{
{
prop
:
'statusName'
,
prop
:
'statusName'
,
label
:
'挂起前状态'
,
label
:
'挂起前状态'
,
minWidth
:
120
,
minWidth
:
120
,
hidden
:
status
.
value
!==
'SUSPEND'
,
hidden
:
status
.
value
!==
'SUSPEND'
,
align
:
'center'
align
:
'center'
,
}
,
}
,
{
{
prop
:
'statusName'
,
prop
:
'statusName'
,
hidden
:
status
.
value
===
'SUSPEND'
,
hidden
:
status
.
value
===
'SUSPEND'
,
label
:
'订单状态'
,
label
:
'订单状态'
,
minWidth
:
120
,
minWidth
:
120
,
align
:
'center'
,
align
:
'center'
,
render
:
(
row
:
FactoryOrderNewListData
)
=>
{
render
:
(
row
:
FactoryOrderNewListData
)
=>
{
return
<
span
>
{
row
.
pause
?
'挂起'
:
row
.
statusName
}
<
/span
>
return
<
span
>
{
row
.
pause
?
'挂起'
:
row
.
statusName
}
<
/span
>
}
,
}
,
}
,
}
,
{
{
...
@@ -2879,22 +2884,15 @@ const handleSingleConfirmOrder = (row: FactoryOrderNewListData) => {
...
@@ -2879,22 +2884,15 @@ const handleSingleConfirmOrder = (row: FactoryOrderNewListData) => {
confirmOrderDialogRef
.
value
?.
open
([
row
.
id
])
confirmOrderDialogRef
.
value
?.
open
([
row
.
id
])
}
}
const
podOrderVisible
=
ref
(
false
)
const
podOrderVisible
=
ref
(
false
)
const
inventorySortingVisible
=
ref
(
false
)
const
podDistributionOrderVisible
=
ref
(
false
)
const
podDistributionOrderVisible
=
ref
(
false
)
const
sheetPrinter
=
ref
(
''
)
const
sheetPrinter
=
ref
(
''
)
const
handlePrinterChange
=
(
value
:
string
)
=>
{
const
handlePrinterChange
=
(
value
:
string
)
=>
{
sheetPrinter
.
value
=
value
sheetPrinter
.
value
=
value
localStorage
.
setItem
(
'sheetPrinter'
,
JSON
.
stringify
(
value
))
localStorage
.
setItem
(
'sheetPrinter'
,
JSON
.
stringify
(
value
))
}
}
const
handleWarehouseIdChange
=
(
const
handlePrintWarehouseIdChange
=
(
value
:
string
|
number
)
=>
{
value
:
localStorage
.
setItem
(
'localNewWarehouseId'
,
JSON
.
stringify
(
value
))
|
string
|
{
warehouseId
:
string
|
number
;
sortingAreaId
:
string
|
number
}
,
)
=>
{
if
(
wallType
.
value
===
'print'
)
{
localStorage
.
setItem
(
'localNewWarehouseId'
,
JSON
.
stringify
(
value
))
}
else
if
(
wallType
.
value
===
'sort'
)
{
localStorage
.
setItem
(
'localSortingAreaId'
,
JSON
.
stringify
(
value
))
}
}
}
const
mapOrderParamListToSubmitItems
=
(
const
mapOrderParamListToSubmitItems
=
(
orderParamList
:
{
id
:
number
;
dataVersion
?:
number
}
[],
orderParamList
:
{
id
:
number
;
dataVersion
?:
number
}
[],
...
@@ -2915,22 +2913,26 @@ const getPrintLogisticLabelFactory = (id?: number) =>
...
@@ -2915,22 +2913,26 @@ const getPrintLogisticLabelFactory = (id?: number) =>
getfaceSimplexFileApi
([
id
??
0
])
getfaceSimplexFileApi
([
id
??
0
])
const
{
getCLodop
}
=
useLodop
()
const
{
getCLodop
}
=
useLodop
()
const
wallType
=
ref
<
'print'
|
'sort'
>
(
'print'
)
const
wallType
=
ref
<
'print'
>
(
'print'
)
const
handleSeedingWall
=
(
type
:
'print'
|
'sort'
)
=>
{
const
handleSeedingWall
=
(
type
:
'print'
)
=>
{
wallType
.
value
=
type
wallType
.
value
=
type
const
lodop
=
getCLodop
(
null
,
null
)
const
lodop
=
getCLodop
(
null
,
null
)
if
(
!
lodop
)
return
if
(
!
lodop
)
return
sheetPrinter
.
value
=
lodop
.
GET_PRINTER_NAME
(
0
)
sheetPrinter
.
value
=
lodop
.
GET_PRINTER_NAME
(
0
)
podOrderVisible
.
value
=
true
podOrderVisible
.
value
=
true
}
}
// 点击打开配货分拣弹窗
const
handleInventorySorting
=
()
=>
{
const
lodop
=
getCLodop
(
null
,
null
)
if
(
!
lodop
)
return
sheetPrinter
.
value
=
lodop
.
GET_PRINTER_NAME
(
0
)
inventorySortingVisible
.
value
=
true
}
/** LODOP 单例不可并发,打印串行 */
/** LODOP 单例不可并发,打印串行 */
let
printOrderChain
:
Promise
<
void
>
=
Promise
.
resolve
()
let
printOrderChain
:
Promise
<
void
>
=
Promise
.
resolve
()
const
printOrder
=
(
const
printOrder
=
(
data
:
OrderData
,
callback
:
(
status
:
boolean
)
=>
void
)
=>
{
data
:
OrderData
,
callback
:
(
status
:
boolean
)
=>
void
,
)
=>
{
const
run
=
async
()
=>
{
const
run
=
async
()
=>
{
const
lodop
=
getCLodop
(
null
,
null
)
const
lodop
=
getCLodop
(
null
,
null
)
if
(
!
lodop
)
{
if
(
!
lodop
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment