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
a38597cf
Commit
a38597cf
authored
Jul 29, 2026
by
wusiyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 添加质检流程 #1009863
parent
9bf605b9
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
352 additions
and
0 deletions
+352
-0
src/api/factoryOrderNew.ts
+37
-0
src/types/api/factoryOrderNew/index.ts
+16
-0
src/types/api/order/factoryOrderNew.ts
+2
-0
src/views/order/factoryOrderNew/component/QualityFailDialog.vue
+166
-0
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
+49
-0
src/views/order/factoryOrderNew/index.vue
+82
-0
No files found.
src/api/factoryOrderNew.ts
View file @
a38597cf
...
...
@@ -8,6 +8,8 @@ import type {
OrderInventoryData
,
PickCompleteData
,
ProductListData
,
QualityParams
,
QualityTypeItem
,
RestockData
,
SearchForm
,
StatusTreeNode
,
...
...
@@ -94,6 +96,26 @@ export function getPodOrderAcceptedStatisticsApi(
})
}
// 待质检 数量统计
export
function
getPodOrderQualityCountApi
(
data
:
SearchForm
,
pageSize
:
number
,
status
?:
string
,
)
{
return
axios
.
post
<
never
,
BaseRespData
<
{
qualityCount
?:
number
noQualityCount
?:
number
}
>
>
(
'factory/podOrderOperation/quality-count'
,
{
...
normalizePodOrderQueryPayload
({
...
data
}
as
Record
<
string
,
unknown
>
),
currentPage
:
1
,
pageSize
,
status
,
})
}
export
function
getFactoryOrderNewDetailApi
(
id
:
number
|
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
ProductListData
[]
>>
(
'factory/podOrderProduct/getListByPodOrderId'
,
...
...
@@ -707,3 +729,18 @@ export function deliveryCompleteApi(data: { id: number; version?: number }[]) {
{
orderParamList
:
data
},
)
}
/** 质检通过 / 质检不通过 */
export
function
qualityPodOrderOperationApi
(
data
:
QualityParams
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'factory/podOrderOperation/quality'
,
data
,
)
}
/** 质检不通过原因下拉 */
export
function
getQualityTypeApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
QualityTypeItem
[]
>>
(
'factory/podOrderOperation/quality-type'
,
)
}
src/types/api/factoryOrderNew/index.ts
View file @
a38597cf
...
...
@@ -51,6 +51,8 @@ export interface SearchForm {
/** list_page 排序方向:asc 正序,desc 倒序 */
order
?:
'asc'
|
'desc'
customerNo
?:
string
// 客户交运单号
/** 待质检子 tab:true 待质检,false 质检不通过 */
qualityPassed
?:
boolean
}
export
interface
FactoryOrderNewListData
{
...
...
@@ -304,3 +306,17 @@ export interface OrderInventoryData {
variantImage
?:
string
inventoryStatus
?:
number
}
/** 质检操作参数 */
export
interface
QualityParams
{
updateParams
:
{
id
:
number
;
version
?:
number
}[]
qualityIssues
:
string
qualify_problem_type
:
number
|
string
qualityPassed
:
boolean
}
/** 质检不通过原因 */
export
interface
QualityTypeItem
{
key
:
number
|
string
value
:
string
}
src/types/api/order/factoryOrderNew.ts
View file @
a38597cf
...
...
@@ -57,6 +57,8 @@ export interface SearchForm {
/** list_page 排序方向:asc 正序,desc 倒序 */
order
?:
'asc'
|
'desc'
customerNo
?:
string
// 客户交运单号
/** 待质检子 tab:true 待质检,false 质检不通过 */
qualityPassed
?:
boolean
}
export
interface
FactoryOrderNewListData
{
...
...
src/views/order/factoryOrderNew/component/QualityFailDialog.vue
0 → 100644
View file @
a38597cf
<
template
>
<ElDialog
v-model=
"visible"
:title=
"qualityPassed ? '质检通过' : '质检不通过'"
width=
"450px"
:close-on-click-modal=
"false"
:destroy-on-close=
"true"
@
close=
"handleClose"
>
<ElForm
ref=
"formRef"
:model=
"form"
:rules=
"rules"
>
<div
class=
"mb-10"
>
{{
qualityPassed
?
'确定质检通过吗?'
:
'确定质检不通过吗?'
}}
</div>
<ElFormItem
v-if=
"!qualityPassed"
label=
"原因"
prop=
"reasonKey"
>
<ElSelect
v-model=
"form.reasonKey"
placeholder=
"请选择不通过原因"
style=
"width: 100%"
clearable
filterable
@
change=
"handleReasonChange"
>
<ElOption
v-for=
"item in reasonOptions"
:key=
"item.key"
:label=
"item.value"
:value=
"item.key"
/>
</ElSelect>
</ElFormItem>
<ElFormItem
v-if=
"!qualityPassed && form.reasonKey === 5"
label=
"具体原因"
prop=
"qualify_problem_type"
>
<ElInput
v-model=
"form.qualify_problem_type"
placeholder=
"请输入不通过原因"
clearable
/>
</ElFormItem>
</ElForm>
<template
#
footer
>
<div
class=
"dialog-footer"
style=
"text-align: center"
>
<ElButton
@
click=
"visible = false"
>
取消
</ElButton>
<ElButton
type=
"primary"
:loading=
"submitLoading"
@
click=
"handleSubmit"
>
确认
</ElButton>
</div>
</
template
>
</ElDialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
computed
,
reactive
,
ref
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
getQualityTypeApi
,
qualityPodOrderOperationApi
,
}
from
'@/api/factoryOrderNew'
import
type
{
QualityTypeItem
}
from
'@/types/api/factoryOrderNew'
const
emit
=
defineEmits
<
{
success
:
[]
}
>
()
const
visible
=
ref
(
false
)
const
submitLoading
=
ref
(
false
)
const
qualityPassed
=
ref
(
true
)
const
formRef
=
ref
<
FormInstance
>
()
const
updateParams
=
ref
<
{
id
:
number
;
version
?:
number
}[]
>
([])
const
reasonOptions
=
ref
<
QualityTypeItem
[]
>
([])
const
form
=
reactive
<
{
reasonKey
:
number
|
string
|
undefined
qualify_problem_type
:
string
}
>
({
reasonKey
:
undefined
,
qualify_problem_type
:
''
,
})
const
rules
=
computed
<
FormRules
>
(()
=>
{
if
(
qualityPassed
.
value
)
return
{}
const
result
:
FormRules
=
{
reasonKey
:
[
{
required
:
true
,
message
:
'请选择不通过原因'
,
trigger
:
'change'
},
],
}
if
(
form
.
reasonKey
&&
form
.
reasonKey
===
5
)
{
result
.
qualify_problem_type
=
[
{
required
:
true
,
message
:
'请输入不通过原因'
,
trigger
:
'blur'
},
]
}
return
result
})
const
loadReasons
=
async
()
=>
{
try
{
const
res
=
await
getQualityTypeApi
()
reasonOptions
.
value
=
res
.
data
||
[]
}
catch
(
e
)
{
console
.
error
(
e
)
reasonOptions
.
value
=
[]
}
}
const
handleReasonChange
=
()
=>
{
form
.
qualify_problem_type
=
''
formRef
.
value
?.
clearValidate
(
'qualify_problem_type'
)
}
/** qualityPassed: true 质检通过,false 质检不通过 */
const
open
=
(
rows
:
{
id
:
number
;
version
?:
number
}[],
passed
:
boolean
)
=>
{
updateParams
.
value
=
rows
.
map
((
row
)
=>
({
id
:
row
.
id
,
version
:
row
.
version
,
}))
qualityPassed
.
value
=
passed
form
.
reasonKey
=
undefined
form
.
qualify_problem_type
=
''
visible
.
value
=
true
if
(
!
passed
)
void
loadReasons
()
}
const
handleClose
=
()
=>
{
formRef
.
value
?.
resetFields
()
reasonOptions
.
value
=
[]
}
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
if
(
!
qualityPassed
.
value
)
{
await
formRef
.
value
.
validate
()
}
const
selected
=
reasonOptions
.
value
.
find
(
(
item
)
=>
item
.
key
===
form
.
reasonKey
,
)
submitLoading
.
value
=
true
try
{
const
params
=
{
updateParams
:
updateParams
.
value
,
qualityIssues
:
qualityPassed
.
value
?
''
:
selected
?.
value
||
''
,
qualify_problem_type
:
qualityPassed
.
value
?
''
:
form
.
reasonKey
===
5
?
form
.
qualify_problem_type
:
(
form
.
reasonKey
as
number
|
string
),
qualityPassed
:
qualityPassed
.
value
,
}
console
.
log
(
params
)
return
const
res
=
await
qualityPodOrderOperationApi
(
params
)
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
'操作成功'
)
visible
.
value
=
false
emit
(
'success'
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
submitLoading
.
value
=
false
}
}
defineExpose
({
open
})
</
script
>
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
View file @
a38597cf
...
...
@@ -2,6 +2,7 @@ import { computed, ref, nextTick } from 'vue'
import
{
getCancelledOrderStatisticsApi
,
getPodOrderAcceptedStatisticsApi
,
getPodOrderQualityCountApi
,
getPodOrderStateGroupListApi
,
getSuspendStatisticsApi
,
}
from
'@/api/factoryOrderNew'
...
...
@@ -24,6 +25,7 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
'PENDING_REPLENISH'
,
'IN_PRODUCTION'
,
'PENDING_PACKING'
,
'PENDING_QUALITY'
,
]
const
specialLayoutStatuses
=
[
'BATCH_MANAGE'
,
'AWAITING_RESTOCK'
]
...
...
@@ -34,6 +36,7 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
PENDING_REPLENISH
:
'件'
,
IN_PRODUCTION
:
'件'
,
PENDING_PACKING
:
'件'
,
PENDING_RECEIVE
:
'件'
,
BATCH_MANAGE
:
'批'
,
AWAITING_RESTOCK
:
'个'
,
}
...
...
@@ -51,6 +54,15 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
pendingCount
:
0
,
acceptedOutOfStockCount
:
0
,
})
/** 待质检子 tab:待质检 / 质检不通过 */
const
qualitySubTab
=
ref
<
'PENDING_QUALITY'
|
'NO_QUALITY'
>
(
'PENDING_QUALITY'
)
const
qualityCounts
=
ref
<
{
qualityCount
?:
number
noQualityCount
?:
number
}
>
({
qualityCount
:
0
,
noQualityCount
:
0
,
})
const
suspendedTabs
=
ref
([
{
label
:
'客户拦截-取消订单'
,
...
...
@@ -87,6 +99,12 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
:
2
:
undefined
// 待质检子 tab:待质检 / 质检不通过
const
getListPageQualitySubStatus
=
()
=>
status
.
value
===
'PENDING_QUALITY'
?
qualitySubTab
.
value
===
'PENDING_QUALITY'
:
undefined
const
getPendingReceiveCounts
=
async
()
=>
{
try
{
const
res
=
await
getPodOrderAcceptedStatisticsApi
(
...
...
@@ -105,6 +123,23 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
}
}
const
getQualityCounts
=
async
()
=>
{
try
{
const
res
=
await
getPodOrderQualityCountApi
(
getQueryPayload
()
as
SearchForm
,
pageSize
.
value
,
status
.
value
,
)
if
(
res
.
code
!==
200
)
return
qualityCounts
.
value
=
res
.
data
||
{
qualityCount
:
0
,
noQualityCount
:
0
,
}
}
catch
(
e
)
{
console
.
error
(
e
)
}
}
const
getSuspendCounts
=
async
()
=>
{
try
{
const
res
=
await
getSuspendStatisticsApi
(
...
...
@@ -195,6 +230,15 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
refreshTableList
()
}
const
handleQualityTabClick
=
(
tab
:
'PENDING_QUALITY'
|
'NO_QUALITY'
,
refreshList
:
()
=>
void
,
)
=>
{
if
(
qualitySubTab
.
value
===
tab
)
return
qualitySubTab
.
value
=
tab
refreshList
()
}
const
toggleExpand
=
(
node
:
{
expanded
?:
boolean
})
=>
{
node
.
expanded
=
!
node
.
expanded
}
...
...
@@ -206,6 +250,8 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
status
,
pendingAcceptSubTab
,
pendingAcceptCounts
,
qualitySubTab
,
qualityCounts
,
suspendedTabs
,
suspendedSubTab
,
cancelledTabs
,
...
...
@@ -215,11 +261,14 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
isSpecialLayout
,
isTableLayout
,
getListPageAcceptedSubStatus
,
getListPageQualitySubStatus
,
getPendingReceiveCounts
,
getQualityCounts
,
getSuspendCounts
,
getCancelledCounts
,
loadStatusTreeCounts
,
handlePendingAcceptTabClick
,
handleQualityTabClick
,
toggleExpand
,
}
}
src/views/order/factoryOrderNew/index.vue
View file @
a38597cf
...
...
@@ -763,6 +763,32 @@
>
订单库存明细
<
/ElButto
n
>
<
/span
>
<!--
待质检
-->
<
span
v
-
if
=
"status === 'PENDING_QUALITY'"
class
=
"item"
>
<
ElButton
type
=
"primary"
@
click
=
"handleGetOrderInventoryDetail"
>
质检
<
/ElButton
>
<
/span
>
<
span
v
-
if
=
"status === 'PENDING_QUALITY'"
class
=
"item"
>
<
ElButton
type
=
"success"
@
click
=
"handleQuality(true)"
>
质检通过
<
/ElButton
>
<
/span
>
<
span
v
-
if
=
"
status === 'PENDING_QUALITY' && qualitySubTab === 'PENDING_QUALITY'
"
class
=
"item"
>
<
ElButton
type
=
"danger"
@
click
=
"handleQuality(false)"
>
质检不通过
<
/ElButton
>
<
/span
>
<
span
v
-
if
=
"status === 'PENDING_QUALITY'"
class
=
"item"
>
<
ElButton
type
=
"success"
@
click
=
"handleGetOrderInventoryDetail"
>
打印操作单
<
/ElButton
>
<
/span
>
<
/div
>
<
div
v
-
if
=
"status === 'SUSPEND'"
class
=
"status-subtabs"
>
<
div
...
...
@@ -808,6 +834,23 @@
<
/span
>
<
/div
>
<
/div
>
<
div
v
-
if
=
"status === 'PENDING_QUALITY'"
class
=
"status-subtabs"
>
<
div
class
=
"status-subtab"
:
class
=
"{ active: qualitySubTab === 'PENDING_QUALITY'
}
"
@
click
=
"handleQualityTabClick('PENDING_QUALITY')"
>
待质检
<
span
>
({{
qualityCounts
.
qualityCount
||
0
}}
)
<
/span
>
<
/div
>
<
div
class
=
"status-subtab"
:
class
=
"{ active: qualitySubTab === 'NO_QUALITY'
}
"
@
click
=
"handleQualityTabClick('NO_QUALITY')"
>
质检不通过
<
span
>
({{
qualityCounts
.
noQualityCount
||
0
}}
)
<
/span
>
<
/div
>
<
/div
>
<!--
批次管理
-->
<
BatchManageTable
v
-
if
=
"status === 'BATCH_MANAGE'"
ref
=
"batchManageRef"
/>
...
...
@@ -1050,6 +1093,10 @@
ref
=
"pickFailDialogRef"
@
success
=
"() => refreshCurrentView({ isRefreshTree: true
}
)"
/>
<
QualityFailDialog
ref
=
"qualityFailDialogRef"
@
success
=
"() => refreshCurrentView({ isRefreshTree: true
}
)"
/>
<
CreateLogisticDialog
ref
=
"createLogisticDialogRef"
...
...
@@ -1337,6 +1384,7 @@ import CancelOrderDialog from './component/CancelOrderDialog.vue'
import
SuspendDialog
from
'./component/SuspendDialog.vue'
import
PickCompleteDialog
from
'./component/PickCompleteDialog.vue'
import
PickFailDialog
from
'./component/PickFailDialog.vue'
import
QualityFailDialog
from
'./component/QualityFailDialog.vue'
import
CardLayout
from
'./component/CardLayout.vue'
import
BatchManageTable
from
'./component/BatchManageTable.vue'
import
WaitingRestockTable
from
'./component/WaitingRestockTable.vue'
...
...
@@ -1437,6 +1485,8 @@ const {
status
,
pendingAcceptSubTab
,
pendingAcceptCounts
,
qualitySubTab
,
qualityCounts
,
suspendedTabs
,
suspendedSubTab
,
// cancelledTabs,
...
...
@@ -1446,11 +1496,14 @@ const {
isSpecialLayout
,
isTableLayout
,
getListPageAcceptedSubStatus
,
getListPageQualitySubStatus
,
getPendingReceiveCounts
,
getQualityCounts
,
getSuspendCounts
,
// getCancelledCounts,
loadStatusTreeCounts
,
handlePendingAcceptTabClick
:
handlePendingAcceptTabClickRaw
,
handleQualityTabClick
:
handleQualityTabClickRaw
,
toggleExpand
,
}
=
useOrderStatusTree
({
getQueryPayload
,
...
...
@@ -1520,6 +1573,10 @@ const getListQueryPayload = () => {
payload
.
prop
=
defaultSort
.
prop
payload
.
order
=
defaultSort
.
order
}
const
qualityPassed
=
getListPageQualitySubStatus
()
if
(
qualityPassed
!==
undefined
)
{
payload
.
qualityPassed
=
qualityPassed
}
return
payload
}
...
...
@@ -1629,6 +1686,11 @@ const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => {
return
}
if
(
isCardLayout
.
value
)
{
if
(
status
.
value
===
'PENDING_QUALITY'
)
{
statusCurrentPageRef
.
value
=
currentPage
.
value
statusPageSizeRef
.
value
=
pageSize
.
value
void
getQualityCounts
()
}
cardLayoutRef
.
value
?.
clearSelection
()
nextTick
(()
=>
{
cardLayoutRef
.
value
?.
refresh
(
true
)
...
...
@@ -1741,6 +1803,9 @@ const handleStatusNodeClick = (node: { status: string }) => {
if
(
node
.
status
!==
'PENDING_RECEIVE'
)
{
pendingAcceptSubTab
.
value
=
'PENDING_RECEIVE'
}
if
(
node
.
status
!==
'PENDING_QUALITY'
)
{
qualitySubTab
.
value
=
'PENDING_QUALITY'
}
if
(
node
.
status
!==
'SUSPEND'
)
{
suspendedSubTab
.
value
=
1
}
...
...
@@ -1773,6 +1838,14 @@ const handlePendingAcceptTabClick = (
tab
:
'PENDING_RECEIVE'
|
'ACCEPT_FAIL_OUT_OF_STOCK'
,
)
=>
handlePendingAcceptTabClickRaw
(
tab
,
refreshTableList
)
const
handleQualityTabClick
=
(
tab
:
'PENDING_QUALITY'
|
'NO_QUALITY'
)
=>
handleQualityTabClickRaw
(
tab
,
()
=>
{
cardLayoutRef
.
value
?.
clearSelection
()
nextTick
(()
=>
{
cardLayoutRef
.
value
?.
refresh
(
true
)
}
)
}
)
const
handleSuspendTabClick
=
(
value
:
number
)
=>
{
if
(
suspendedSubTab
.
value
===
value
)
return
suspendedSubTab
.
value
=
value
...
...
@@ -2549,6 +2622,7 @@ const cancelOrderDialogRef = ref<InstanceType<typeof CancelOrderDialog>>()
const
suspendDialogRef
=
ref
<
InstanceType
<
typeof
SuspendDialog
>>
()
const
pickCompleteDialogRef
=
ref
<
InstanceType
<
typeof
PickCompleteDialog
>>
()
const
pickFailDialogRef
=
ref
<
InstanceType
<
typeof
PickFailDialog
>>
()
const
qualityFailDialogRef
=
ref
<
InstanceType
<
typeof
QualityFailDialog
>>
()
const
operateDetailsDialogRef
=
ref
()
const
arrangeDialogRef
=
ref
<
InstanceType
<
typeof
ArrangeDialog
>>
()
const
createLogisticDialogRef
=
ref
()
...
...
@@ -3573,6 +3647,12 @@ const handleInterceptionFail = async (row?: FactoryOrderNewListData) => {
const
handleGetOrderInventoryDetail
=
async
()
=>
{
orderInventoryDetailVisible
.
value
=
true
}
const
handleQuality
=
(
qualityPassed
:
boolean
)
=>
{
if
(
!
ensureSelection
())
return
const
rows
=
isCardLayout
.
value
?
cardSelectList
.
value
:
selectedRows
.
value
qualityFailDialogRef
.
value
?.
open
(
rows
,
qualityPassed
)
}
const
isEnableSorting
=
ref
(
false
)
// 获取功能开关
const
getFunctionSwitch
=
async
()
=>
{
...
...
@@ -3600,6 +3680,8 @@ onMounted(() => {
void
tableRef
.
value
if
(
status
.
value
===
'PENDING_RECEIVE'
)
{
getPendingReceiveCounts
()
}
else
if
(
status
.
value
===
'PENDING_QUALITY'
)
{
void
getQualityCounts
()
}
}
)
<
/script
>
...
...
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