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
0
Merge Requests
0
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
2b8b9c96
Commit
2b8b9c96
authored
Jul 20, 2026
by
wuqian
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into 'master'
Dev See merge request
!272
parents
6846d780
be024416
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
153 additions
and
40 deletions
+153
-40
components.d.ts
+2
-10
src/api/factoryOrderNew.ts
+6
-0
src/types/api/factoryOrderNew/index.ts
+5
-1
src/types/api/order/factoryOrderNew.ts
+3
-0
src/utils/websocket.ts
+1
-0
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
+16
-1
src/views/order/factoryOrderNew/index.vue
+102
-4
src/views/order/podUs/PodMakeOrder.vue
+18
-24
No files found.
components.d.ts
View file @
2b8b9c96
...
...
@@ -12,16 +12,12 @@ declare module 'vue' {
DatePicker
:
typeof
import
(
'./src/components/Form/DatePicker.vue'
)[
'default'
]
DateRangePicker
:
typeof
import
(
'./src/components/Form/DateRangePicker.vue'
)[
'default'
]
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElCard
:
typeof
import
(
'element-plus/es'
)[
'ElCard'
]
ElCarousel
:
typeof
import
(
'element-plus/es'
)[
'ElCarousel'
]
ElCarouselItem
:
typeof
import
(
'element-plus/es'
)[
'ElCarouselItem'
]
ElCheckbox
:
typeof
import
(
'element-plus/es'
)[
'ElCheckbox'
]
ElCheckboxGroup
:
typeof
import
(
'element-plus/es'
)[
'ElCheckboxGroup'
]
ElCol
:
typeof
import
(
'element-plus/es'
)[
'ElCol'
]
ElConfigProvider
:
typeof
import
(
'element-plus/es'
)[
'ElConfigProvider'
]
ElDatePicker
:
typeof
import
(
'element-plus/es'
)[
'ElDatePicker'
]
ElDescriptions
:
typeof
import
(
'element-plus/es'
)[
'ElDescriptions'
]
ElDescriptionsItem
:
typeof
import
(
'element-plus/es'
)[
'ElDescriptionsItem'
]
ElDialog
:
typeof
import
(
'element-plus/es'
)[
'ElDialog'
]
ElDrawer
:
typeof
import
(
'element-plus/es'
)[
'ElDrawer'
]
ElDropdown
:
typeof
import
(
'element-plus/es'
)[
'ElDropdown'
]
...
...
@@ -33,15 +29,12 @@ declare module 'vue' {
ElIcon
:
typeof
import
(
'element-plus/es'
)[
'ElIcon'
]
ElImage
:
typeof
import
(
'element-plus/es'
)[
'ElImage'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInputNumber
:
typeof
import
(
'element-plus/es'
)[
'ElInputNumber'
]
ElLink
:
typeof
import
(
'element-plus/es'
)[
'ElLink'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
ElPagination
:
typeof
import
(
'element-plus/es'
)[
'ElPagination'
]
ElPopover
:
typeof
import
(
'element-plus/es'
)[
'ElPopover'
]
ElRadio
:
typeof
import
(
'element-plus/es'
)[
'ElRadio'
]
ElRadioButton
:
typeof
import
(
'element-plus/es'
)[
'ElRadioButton'
]
ElRadioGroup
:
typeof
import
(
'element-plus/es'
)[
'ElRadioGroup'
]
ElRow
:
typeof
import
(
'element-plus/es'
)[
'ElRow'
]
ElSelect
:
typeof
import
(
'element-plus/es'
)[
'ElSelect'
]
ElSwitch
:
typeof
import
(
'element-plus/es'
)[
'ElSwitch'
]
ElTable
:
typeof
import
(
'element-plus/es'
)[
'ElTable'
]
...
...
@@ -49,13 +42,12 @@ declare module 'vue' {
ElTabPane
:
typeof
import
(
'element-plus/es'
)[
'ElTabPane'
]
ElTabs
:
typeof
import
(
'element-plus/es'
)[
'ElTabs'
]
ElTag
:
typeof
import
(
'element-plus/es'
)[
'ElTag'
]
ElTimeline
:
typeof
import
(
'element-plus/es'
)[
'ElTimeline'
]
ElTimelineItem
:
typeof
import
(
'element-plus/es'
)[
'ElTimelineItem'
]
ElTooltip
:
typeof
import
(
'element-plus/es'
)[
'ElTooltip'
]
ElTree
:
typeof
import
(
'element-plus/es'
)[
'ElTree'
]
El
Upload
:
typeof
import
(
'element-plus/es'
)[
'ElUpload
'
]
El
TreeSelect
:
typeof
import
(
'element-plus/es'
)[
'ElTreeSelect
'
]
Icon
:
typeof
import
(
'./src/components/Icon.vue'
)[
'default'
]
ImageView
:
typeof
import
(
'./src/components/ImageView.vue'
)[
'default'
]
LeftRightLayout
:
typeof
import
(
'./src/components/leftRightLayout.vue'
)[
'default'
]
LogList
:
typeof
import
(
'./src/components/LogList.vue'
)[
'default'
]
NavMenu
:
typeof
import
(
'./src/components/NavMenu.vue'
)[
'default'
]
NavMenuItem
:
typeof
import
(
'./src/components/NavMenuItem.vue'
)[
'default'
]
...
...
src/api/factoryOrderNew.ts
View file @
2b8b9c96
...
...
@@ -11,6 +11,7 @@ import type {
RestockData
,
SearchForm
,
StatusTreeNode
,
StatusListNode
,
}
from
'@/types/api/factoryOrderNew'
import
{
ResultInfoDataItem
}
from
'@/types/api/order/common'
import
{
ExportParams
}
from
'@/types/api/order/factoryOrderNew'
...
...
@@ -37,6 +38,11 @@ export function getPodOrderStateGroupListApi() {
'factory/podOrder/findStateGroupList'
,
)
}
export
function
getStatusPushApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
StatusListNode
[]
>>
(
'factory/podOrderOperation/get-operation-order-status'
,
)
}
export
function
getFactoryOrderNewListApi
(
data
:
SearchForm
,
...
...
src/types/api/factoryOrderNew/index.ts
View file @
2b8b9c96
...
...
@@ -3,9 +3,13 @@ export interface StatusTreeNode {
status
:
string
statusName
:
string
quantity
:
number
unit
?:
string
// 数量单位
children
:
StatusTreeNode
[]
|
null
}
export
interface
StatusListNode
{
status
:
string
statusName
:
string
}
export
interface
SearchForm
{
status
?:
string
pauseReason
?:
number
...
...
src/types/api/order/factoryOrderNew.ts
View file @
2b8b9c96
...
...
@@ -2,11 +2,13 @@ export interface StatusTreeNode {
status
:
string
statusName
:
string
quantity
:
number
unit
?:
string
// 数量单位
children
:
StatusTreeNode
[]
|
null
}
export
interface
SearchForm
{
status
?:
string
operationStatus
?:
string
|
string
[]
pauseReason
?:
number
platform
?:
string
craftCode
?:
string
|
string
[]
...
...
@@ -103,6 +105,7 @@ export interface FactoryOrderNewListData {
totalCustomsValue
?:
number
pauseStatus
?:
number
statusName
?:
string
finishTime
?:
string
thirdOrderNumber
?:
string
customTagList
?:
{
id
:
string
;
name
:
string
}[]
}
...
...
src/utils/websocket.ts
View file @
2b8b9c96
...
...
@@ -80,6 +80,7 @@ class Im {
private
_onWsOpen
():
void
{
console
.
log
(
'服务器连接成功'
)
this
.
num
=
0
localStorage
.
setItem
(
'socket_connect'
,
'online'
)
this
.
_onOpenCallback
?.()
this
.
_startHeartbeat
()
...
...
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
View file @
2b8b9c96
...
...
@@ -27,6 +27,17 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
]
const
specialLayoutStatuses
=
[
'BATCH_MANAGE'
,
'AWAITING_RESTOCK'
]
/** 左侧状态栏数量单位 */
const
STATUS_QUANTITY_UNIT
:
Record
<
string
,
string
>
=
{
PENDING_SCHEDULE
:
'件'
,
PENDING_PICK
:
'件'
,
PENDING_REPLENISH
:
'件'
,
IN_PRODUCTION
:
'件'
,
PENDING_PACKING
:
'件'
,
BATCH_MANAGE
:
'批'
,
AWAITING_RESTOCK
:
'个'
,
}
const
statusTree
=
ref
<
StatusTreeNode
[]
>
()
const
status
=
ref
<
string
>
(
'PENDING_RECEIVE'
)
const
pendingAcceptSubTab
=
ref
<
...
...
@@ -149,7 +160,11 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
hasPermission
||
(
isGroupContainer
&&
filteredChildren
.
length
>
0
)
)
{
result
.
push
({
...
node
,
children
:
filteredChildren
})
result
.
push
({
...
node
,
children
:
filteredChildren
,
unit
:
STATUS_QUANTITY_UNIT
[
node
.
status
]
??
'单'
,
})
}
}
return
result
...
...
src/views/order/factoryOrderNew/index.vue
View file @
2b8b9c96
...
...
@@ -28,7 +28,7 @@
"
class=
"tree-node-count"
>
{{
`(${data.quantity
}
)`
}}
{{
`(${data.quantity
}
${data.unit ?? '单'
}
)`
}}
<
/span
>
<
/div
>
<
span
...
...
@@ -62,7 +62,7 @@
class
=
"search-form"
:
model
=
"searchForm"
:
inline
=
"true"
label
-
width
=
"
7
0px"
label
-
width
=
"
11
0px"
>
<
ElFormItem
v
-
if
=
"status === 'ALL'"
label
=
"订单状态"
>
<
ElTreeSelect
...
...
@@ -178,7 +178,24 @@
width
=
"140px"
/>
<
/ElFormItem
>
<
ElFormItem
v
-
if
=
"status === 'PICKING'"
label
=
"操作单状态"
>
<
ElSelect
v
-
model
=
"searchFormOperationStatusSelect"
placeholder
=
"请选择"
clearable
multiple
collapse
-
tags
filterable
style
=
"width: 170px"
>
<
ElOption
v
-
for
=
"(item, index) in statusList"
:
key
=
"index"
:
value
=
"item.status"
:
label
=
"item.statusName"
><
/ElOption
>
<
/ElSelect
>
<
/ElFormItem
>
<
ElFormItem
label
=
"数量"
>
<
el
-
radio
-
group
v
-
model
=
"searchForm.multi"
>
<
el
-
radio
-
button
:
value
=
"false"
@
click
=
"toggleMulti(false)"
...
...
@@ -1241,6 +1258,7 @@
<
/template
>
<
script
setup
lang
=
"tsx"
>
import
dayjs
from
'dayjs'
import
{
ArrowDown
,
ArrowUp
,
...
...
@@ -1298,6 +1316,7 @@ import {
interceptUpdateApi
,
interceptSuccessApi
,
deliveryCompleteApi
,
getStatusPushApi
,
}
from
'@/api/factoryOrderNew'
import
{
getConfigApi
}
from
'@/api/order'
import
{
getLogisticsWayApi
}
from
'@/api/podUsOrder'
...
...
@@ -1329,6 +1348,7 @@ import ChangeWayDialog from '@/views/order/podCN/components/ChangeWayDialog.vue'
import
{
ResultInfoDataItem
}
from
'@/types/api/order/common'
import
type
{
FactoryOrderSearchQueryVisibilityContext
}
from
'@/types/api/factoryOrderNew/searchQueryVisibility'
import
type
{
StatusTreeNode
}
from
'@/types/api/order/factoryOrderNew'
import
type
{
StatusListNode
}
from
'@/types/api/factoryOrderNew'
import
{
useOrderDictionaries
}
from
'./hooks/useOrderDictionaries'
import
{
useOrderSearchForm
}
from
'./hooks/useOrderSearchForm'
import
{
useOrderStatusTree
}
from
'./hooks/useOrderStatusTree'
...
...
@@ -1456,7 +1476,17 @@ const searchFormStatusSelect = computed({
searchForm
.
value
.
status
=
arr
.
length
?
arr
.
join
(
','
)
:
undefined
}
,
}
)
const
searchFormOperationStatusSelect
=
computed
({
get
()
{
const
val
=
searchForm
.
value
.
operationStatus
if
(
!
val
)
return
[]
return
String
(
val
).
split
(
','
).
filter
(
Boolean
)
}
,
set
(
val
:
string
|
string
[]
|
undefined
)
{
const
arr
=
Array
.
isArray
(
val
)
?
val
:
val
?
[
val
]
:
[]
searchForm
.
value
.
operationStatus
=
arr
.
length
?
arr
.
join
(
','
)
:
undefined
}
,
}
)
getFactoryOrderSearchVisibilityContext
=
()
=>
({
status
:
searchForm
.
value
.
status
??
status
.
value
,
isCardLayout
:
isCardLayout
.
value
,
...
...
@@ -1699,11 +1729,28 @@ const handleStatusNodeClick = (node: { status: string }) => {
if
(
node
.
status
!==
'CANCELLED'
)
{
cancelledSubTab
.
value
=
1
}
if
(
node
.
status
===
'PICKING'
)
{
getOrderStatus
()
}
clearTableState
()
if
(
!
isSpecialLayout
.
value
)
{
refreshCurrentView
()
}
}
const
statusList
=
ref
<
StatusListNode
[]
>
([])
const
getOrderStatus
=
async
()
=>
{
try
{
const
res
=
await
getStatusPushApi
()
if
(
res
.
code
===
200
)
{
statusList
.
value
=
res
.
data
}
else
{
ElMessage
.
error
(
res
.
message
)
}
}
catch
(
error
)
{
console
.
error
(
error
)
ElMessage
.
error
(
'订单状态刷新失败'
)
}
}
const
handlePendingAcceptTabClick
=
(
tab
:
'PENDING_RECEIVE'
|
'ACCEPT_FAIL_OUT_OF_STOCK'
,
)
=>
handlePendingAcceptTabClickRaw
(
tab
,
refreshTableList
)
...
...
@@ -1896,6 +1943,29 @@ const mainColumns = computed(() => [
width
:
140
,
align
:
'center'
,
}
,
// 订单状态为已取消时隐藏延期时间列
...(
status
.
value
===
'CANCELLED'
?
[]
:
[
{
prop
:
'createTime'
,
label
:
'延期时间'
,
width
:
140
,
align
:
'center'
,
render
:
(
row
:
FactoryOrderNewListData
)
=>
{
const
delayText
=
getOrderDelayText
(
row
.
createTime
??
''
,
row
.
finishTime
??
''
,
row
.
status
??
''
,
)
return
(
<
div
style
=
{{
color
:
'red'
,
fontWeight
:
'bolder'
}}
>
{
delayText
}
<
/div
>
)
}
,
}
,
]),
{
prop
:
'logisticsWayName'
,
label
:
'物流类型'
,
...
...
@@ -2588,6 +2658,34 @@ const handleUpdateCustomsInfo = async () => {
await
nextTick
()
updateCustomsDialogRef
.
value
?.
resetForm
()
}
// 值为空:待接单和已取消状态
const
NULL_STATUSES
=
[
'PENDING_RECEIVE'
,
'CANCELLED'
]
// 终态订单:已完成/已归档
const
TERMINAL_ORDER_STATUSES
=
[
'COMPLETED'
,
'ARCHIVE'
]
const
getOrderDelayText
=
(
createTime
?:
string
|
null
,
finishTime
?:
string
|
null
,
statusValue
?:
string
|
null
,
)
=>
{
if
(
!
createTime
)
return
''
const
currentStatus
=
statusValue
??
''
if
(
TERMINAL_ORDER_STATUSES
.
includes
(
currentStatus
)
&&
!
finishTime
)
return
''
const
createAt
=
dayjs
(
createTime
)
if
(
!
createAt
.
isValid
())
return
''
// 终态订单用 finishTime - createTime 的差值
// 其他状态用 当前时间 - createTime 的差值
const
endTime
=
TERMINAL_ORDER_STATUSES
.
includes
(
currentStatus
)
&&
finishTime
?
dayjs
(
finishTime
)
:
dayjs
()
const
diffMinutes
=
Math
.
max
(
0
,
endTime
.
diff
(
createAt
,
'minute'
))
const
baseHours
=
Math
.
floor
(
diffMinutes
/
60
)
const
remainMinutes
=
diffMinutes
%
60
const
hours
=
baseHours
+
(
remainMinutes
>
30
?
1
:
0
)
const
result
=
!
NULL_STATUSES
.
includes
(
currentStatus
)
?
`${hours
}
h`
:
''
return
result
}
const
handleTransferToArrange
=
async
()
=>
{
if
(
!
ensureSelection
(
'请选择订单'
))
return
...
...
src/views/order/podUs/PodMakeOrder.vue
View file @
2b8b9c96
...
...
@@ -624,20 +624,16 @@ watch(visible, async (value: boolean) => {
if
(
userStore
.
user
?.
factory
.
id
)
{
try
{
// 断线自动重连成功时会走 open 回调重新订阅
await
socket
.
init
(
{
account
:
userStore
.
user
?.
account
.
toString
(),
factoryNo
:
userStore
.
user
?.
factory
.
id
.
toString
(),
},
messageChange
,
sendWsSubscribe
,
)
socket
.
send
({
code
:
props
.
wsOpenCode
,
factoryNo
:
userStore
.
user
?.
factory
.
id
,
warehouseId
:
warehouseId
.
value
,
packingId
:
props
.
wallType
===
'sort'
?
sortingAreaId
.
value
:
undefined
,
})
sendWsSubscribe
()
}
catch
(
error
)
{
console
.
error
(
error
)
}
...
...
@@ -1536,6 +1532,17 @@ const _warehouseId = ref<string | number>('')
const
sortingAreaList
=
ref
<
SortingList
[]
>
([])
const
sortingAreaId
=
ref
<
number
|
string
>
(
''
)
const
isAutoPrint
=
ref
<
boolean
>
(
false
)
// 当前配货区是否自动打单
// WS 消息订阅
const
sendWsSubscribe
=
(
factoryNo
?:
number
|
string
)
=>
{
const
no
=
factoryNo
??
userStore
.
user
?.
factory
.
id
if
(
!
no
)
return
socket
.
send
({
code
:
props
.
wsOpenCode
,
factoryNo
:
no
,
warehouseId
:
warehouseId
.
value
,
packingId
:
props
.
wallType
===
'sort'
?
sortingAreaId
.
value
:
undefined
,
})
}
// 配货分拣 更新配货区
const
syncSortingArea
=
(
packingId
:
number
|
string
,
...
...
@@ -1547,12 +1554,7 @@ const syncSortingArea = (
warehouseId
.
value
=
currentArea
.
warehouseId
sortingAreaId
.
value
=
packingId
isAutoPrint
.
value
=
currentArea
.
autoPrint
socket
.
send
({
code
:
props
.
wsOpenCode
,
factoryNo
,
warehouseId
:
warehouseId
.
value
,
packingId
:
sortingAreaId
.
value
,
})
sendWsSubscribe
(
factoryNo
)
}
// 配货分拣 手动切换配货区
const
handleSortingAreaChange
=
(
...
...
@@ -1582,11 +1584,7 @@ const handleWarehouseChange = (value: string | number) => {
}
warehouseId
.
value
=
value
emit
(
'set-warehouseId'
,
value
)
socket
.
send
({
code
:
props
.
wsOpenCode
,
factoryNo
:
userStore
.
user
?.
factory
.
id
,
warehouseId
:
warehouseId
.
value
,
})
sendWsSubscribe
()
_warehouseId
.
value
=
value
initOrderDetailBox
()
resetPlatform
()
...
...
@@ -1627,13 +1625,9 @@ const reconnectWebSocket = async () => {
factoryNo
:
userStore
.
user
?.
factory
.
id
.
toString
(),
},
messageChange
,
sendWsSubscribe
,
)
socket
.
send
({
code
:
props
.
wsOpenCode
,
factoryNo
:
userStore
.
user
?.
factory
.
id
,
warehouseId
:
warehouseId
.
value
,
packingId
:
sortingAreaId
.
value
,
})
sendWsSubscribe
()
}
catch
(
error
)
{
console
.
error
(
'WebSocket 重连失败:'
,
error
)
ElMessage
.
error
(
'WebSocket 重连失败,请稍后重试'
)
...
...
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