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
63026784
Commit
63026784
authored
Jan 21, 2026
by
qinjianhui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 备货完成功能开发
parent
e212c47d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
551 additions
and
38 deletions
+551
-38
src/api/stockingOrder.ts
+32
-0
src/types/api/supply/stockingOrder.ts
+7
-0
src/views/supply/stockingOrder/AddStockingOrderDialog.vue
+56
-5
src/views/supply/stockingOrder/SupplierDispatchOrder.vue
+0
-27
src/views/supply/stockingOrder/SupplierDispatchOrderDialog.vue
+417
-0
src/views/supply/stockingOrder/index.vue
+39
-6
No files found.
src/api/stockingOrder.ts
View file @
63026784
...
...
@@ -81,3 +81,35 @@ export function submitStockingOrderAuditApi(ids: string) {
},
)
}
export
function
rejectedStockingOrderApi
(
params
:
{
id
:
number
|
string
turnDownReason
:
string
})
{
return
axios
.
get
<
never
,
BaseRespData
<
void
>>
(
'factory/supply/stockingUpManage/rejected'
,
{
params
,
},
)
}
export
function
supplierDispatchApi
(
data
:
{
manageId
:
number
|
string
manageNo
:
string
warehouseId
:
number
|
string
warehouseName
:
string
expectDeliveryTime
:
string
detailsList
:
StockingOrderProduct
[]
})
{
return
axios
.
post
<
never
,
BaseRespData
<
void
>>
(
'factory/supply/stockingUpWarehouseApply/add'
,
data
,
)
}
export
function
stockingCompleteApi
(
id
:
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
void
>>
(
`factory/supply/stockingUpManage/delivery?id=
${
id
}
`
,
)
}
src/types/api/supply/stockingOrder.ts
View file @
63026784
...
...
@@ -83,7 +83,10 @@ export interface AddStockingOrderForm {
currencyName
?:
string
remark
?:
string
status
?:
number
submission
?:
boolean
detailsList
?:
StockingOrderProduct
[]
examineStatus
?:
number
// 审核状态:1通过,0驳回
rejectReason
?:
string
// 驳回原因
}
// 备货单商品
...
...
@@ -99,6 +102,10 @@ export interface StockingOrderProduct {
currencyName
?:
string
totalPrice
?:
number
|
string
shipmentQuantity
?:
number
|
string
buyStored
?:
number
// 供应商发货相关字段
remainingQuantity
?:
number
// 剩余待发货数量
currentShipQuantity
?:
number
|
string
// 本次发货数量
}
export
interface
RelatedDocumentList
{}
...
...
src/views/supply/stockingOrder/AddStockingOrderDialog.vue
View file @
63026784
...
...
@@ -228,7 +228,7 @@
v-if=
"editOrderType === 'add' || editOrderType === 'edit'"
size=
"large"
type=
"primary"
@
click=
"handleSave"
@
click=
"handleSave
(false)
"
>
保存
</ElButton
>
<ElButton
...
...
@@ -243,10 +243,14 @@
v-if=
"editOrderType === 'audit'"
size=
"large"
type=
"success"
@
click=
"handleSave"
@
click=
"handleSave
(false)
"
>
审核通过
</ElButton
>
<ElButton
v-if=
"editOrderType === 'audit'"
size=
"large"
type=
"danger"
<ElButton
v-if=
"editOrderType === 'audit'"
size=
"large"
type=
"danger"
@
click=
"handleReject"
>
审核驳回
</ElButton
>
</div>
...
...
@@ -268,6 +272,7 @@ import {
addStockingOrderApi
,
getProductBySkuApi
,
getStockingOrderDetailByIdApi
,
rejectedStockingOrderApi
,
}
from
'@/api/stockingOrder'
import
ImageView
from
'@/components/ImageView.vue'
import
{
BigNumber
}
from
'bignumber.js'
...
...
@@ -528,7 +533,7 @@ const handleCancel = () => {
visible
.
value
=
false
}
const
handleSave
=
async
()
=>
{
const
handleSave
=
async
(
isSubmit
:
boolean
=
false
)
=>
{
if
(
!
formRef
.
value
)
return
try
{
...
...
@@ -573,6 +578,7 @@ const handleSave = async () => {
warehouseName
,
stockingUpUserName
,
totalPrice
:
totalAmount
.
value
,
submission
:
props
.
editOrderType
===
'audit'
?
undefined
:
isSubmit
,
})
if
(
res
.
code
!==
200
)
{
ElMessage
.
warning
(
res
.
message
)
...
...
@@ -588,7 +594,52 @@ const handleSave = async () => {
}
}
const
handleSaveAndSubmit
=
async
()
=>
{}
const
handleSaveAndSubmit
=
async
()
=>
{
await
handleSave
(
true
)
}
const
handleReject
=
async
()
=>
{
if
(
!
props
.
editId
)
return
try
{
const
{
value
:
rejectReason
}
=
await
ElMessageBox
.
prompt
(
'请输入驳回原因'
,
'审核驳回'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
inputType
:
'textarea'
,
inputPlaceholder
:
'请输入驳回原因'
,
inputValidator
:
(
val
)
=>
{
if
(
!
val
||
!
val
.
trim
())
{
return
'驳回原因不能为空'
}
return
true
},
},
)
const
loading
=
ElLoading
.
service
({
lock
:
true
,
text
:
'加载中...'
,
background
:
'rgba(0, 0, 0, 0.7)'
,
})
try
{
const
res
=
await
rejectedStockingOrderApi
({
id
:
props
.
editId
,
turnDownReason
:
rejectReason
.
trim
(),
})
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
'驳回成功'
)
emit
(
'refresh'
)
visible
.
value
=
false
}
finally
{
loading
.
close
()
}
}
catch
{
// 用户取消操作,不做处理
}
}
const
resetForm
=
()
=>
{
formRef
.
value
?.
resetFields
()
...
...
src/views/supply/stockingOrder/SupplierDispatchOrder.vue
deleted
100644 → 0
View file @
e212c47d
<
template
>
<ElDialog
v-model=
"visible"
title=
"供应商发货"
width=
"1400px"
top=
"15vh"
:close-on-click-modal=
"false"
destroy-on-close
>
<div
class=
"supplier-dispatch-order-page card h-100 flex overflow-hidden"
></div>
</ElDialog>
</
template
>
<
script
setup
lang=
"tsx"
>
const
props
=
defineProps
<
{
visible
:
boolean
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update:visible'
,
value
:
boolean
):
void
(
e
:
'refresh'
):
void
}
>
()
const
visible
=
computed
({
get
:
()
=>
props
.
visible
,
set
:
(
val
)
=>
emit
(
'update:visible'
,
val
),
})
</
script
>
src/views/supply/stockingOrder/SupplierDispatchOrderDialog.vue
0 → 100644
View file @
63026784
<
template
>
<ElDialog
v-model=
"visible"
title=
"供应商发货"
width=
"1400px"
top=
"10vh"
:close-on-click-modal=
"false"
destroy-on-close
>
<div
class=
"supplier-dispatch-order-page"
>
<div
class=
"form-section"
>
<ElForm
ref=
"formRef"
:model=
"formData"
label-width=
"110px"
inline
>
<div
class=
"form-row"
>
<ElFormItem
label=
"备货单号"
class=
"form-item"
>
<ElInput
v-model=
"formData.stockingUpManageNo"
disabled
placeholder=
"系统自动带出"
style=
"width: 100%"
/>
</ElFormItem>
<ElFormItem
label=
"备货仓库"
prop=
"warehouseId"
class=
"form-item"
:rules=
"[
{
required: true,
message: '请选择备货仓库',
trigger: 'change',
},
]"
>
<ElSelect
v-model=
"formData.warehouseId"
placeholder=
"请选择"
filterable
clearable
style=
"width: 100%"
>
<ElOption
v-for=
"item in warehouseList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"预计到货日期"
prop=
"expectDeliveryTime"
class=
"form-item"
:rules=
"[
{
required: true,
message: '请选择预计到货日期',
trigger: 'change',
},
]"
>
<ElDatePicker
v-model=
"formData.expectDeliveryTime"
type=
"datetime"
placeholder=
"请选择"
value-format=
"YYYY-MM-DD HH:mm:ss"
clearable
style=
"width: 100%"
/>
</ElFormItem>
</div>
</ElForm>
</div>
<div
class=
"table-section"
>
<TableView
ref=
"tableViewRef"
:paginated-data=
"formData.detailsList"
:serial-numberable=
"true"
:columns=
"tableColumns"
:selectionable=
"true"
@
selection-change=
"handleSelectionChange"
>
<template
#
currentShipQuantity=
"
{ row }">
<ElInput
v-model=
"row.currentShipQuantity"
clearable
size=
"small"
type=
"number"
:min=
"0"
style=
"width: 100px"
/>
</
template
>
</TableView>
</div>
<div
class=
"action-section"
>
<ElButton
type=
"success"
@
click=
"handleAutoFillQuantity"
>
剩余待发货数量>>本次发货数量
</ElButton>
<ElButton
type=
"danger"
@
click=
"handleDeleteSelected"
>
删除
</ElButton>
</div>
</div>
<
template
#
footer
>
<div
class=
"dialog-footer"
>
<ElButton
size=
"large"
@
click=
"visible = false"
>
取消
</ElButton>
<ElButton
size=
"large"
type=
"danger"
@
click=
"handleDispatch"
>
发货
</ElButton>
</div>
</
template
>
</ElDialog>
</template>
<
script
setup
lang=
"tsx"
>
import
{
ref
,
computed
,
watch
}
from
'vue'
import
type
{
FormInstance
}
from
'element-plus'
import
type
{
TableData
,
StockingOrderProduct
,
AddStockingOrderForm
,
}
from
'@/types/api/supply/stockingOrder'
import
type
{
WarehouseListData
}
from
'@/types'
import
{
getStockingOrderDetailByIdApi
,
supplierDispatchApi
,
}
from
'@/api/stockingOrder'
import
ImageView
from
'@/components/ImageView.vue'
import
TableView
from
'@/components/TableView.vue'
import
{
BigNumber
}
from
'bignumber.js'
const
props
=
defineProps
<
{
visible
:
boolean
selectedRow
:
TableData
|
null
warehouseList
:
WarehouseListData
[]
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update:visible'
,
value
:
boolean
):
void
(
e
:
'refresh'
):
void
}
>
()
const
visible
=
computed
({
get
:
()
=>
props
.
visible
,
set
:
(
val
)
=>
emit
(
'update:visible'
,
val
),
})
const
formRef
=
ref
<
FormInstance
>
()
const
formData
=
ref
<
AddStockingOrderForm
>
({
stockingUpManageNo
:
''
,
warehouseId
:
undefined
as
number
|
undefined
,
expectDeliveryTime
:
''
,
detailsList
:
[],
})
const
selectedProducts
=
ref
<
StockingOrderProduct
[]
>
([])
const
tableColumns
=
computed
(()
=>
[
{
label
:
'SKU图片'
,
prop
:
'skuImage'
,
width
:
100
,
align
:
'center'
,
render
:
(
item
:
StockingOrderProduct
)
=>
(
<
ImageView
src
=
{
item
.
warehouseSkuImage
}
width
=
"50px"
height
=
"50px"
/>
),
},
{
label
:
'商品名称'
,
prop
:
'warehouseSkuName'
,
minWidth
:
150
,
align
:
'left'
,
showOverflowTooltip
:
true
,
},
{
label
:
'款号'
,
prop
:
'productNo'
,
width
:
120
,
align
:
'center'
,
},
{
label
:
'库存SKU'
,
prop
:
'warehouseSku'
,
width
:
180
,
align
:
'center'
,
},
{
label
:
'备货数量'
,
prop
:
'buyAmount'
,
width
:
100
,
align
:
'right'
,
},
{
label
:
'已入库数量'
,
prop
:
'buyStored'
,
width
:
100
,
align
:
'right'
,
render
:
(
item
:
StockingOrderProduct
)
=>
(
<
span
style
=
"color: #409EFF; font-weight: 500;"
>
{
item
.
buyStored
??
0
}
<
/span
>
),
},
{
label
:
'已发货数量'
,
prop
:
'shipmentQuantity'
,
width
:
100
,
align
:
'right'
,
render
:
(
item
:
StockingOrderProduct
)
=>
(
<
span
style
=
"color: #E6A23C; font-weight: 500;"
>
{
item
.
shipmentQuantity
??
0
}
<
/span
>
),
},
{
label
:
'剩余待发货数量'
,
prop
:
'remainingQuantity'
,
width
:
140
,
align
:
'right'
,
render
:
(
item
:
StockingOrderProduct
)
=>
(
<
span
style
=
"color: #F56C6C; font-weight: 500;"
>
{
item
.
remainingQuantity
??
0
}
<
/span
>
),
},
{
label
:
'本次发货数量'
,
slot
:
'currentShipQuantity'
,
width
:
140
,
align
:
'center'
,
},
])
const
handleAutoFillQuantity
=
()
=>
{
if
(
selectedProducts
.
value
.
length
===
0
)
{
ElMessage
.
warning
(
'请选择要自动填充的商品'
)
return
}
selectedProducts
.
value
.
forEach
((
item
)
=>
{
if
(
item
.
remainingQuantity
&&
item
.
remainingQuantity
>
0
)
{
item
.
currentShipQuantity
=
item
.
remainingQuantity
}
})
}
const
handleSelectionChange
=
(
selection
:
StockingOrderProduct
[])
=>
{
selectedProducts
.
value
=
selection
}
const
handleDeleteSelected
=
()
=>
{
if
(
selectedProducts
.
value
.
length
===
0
)
{
ElMessage
.
warning
(
'请先选择要删除的商品'
)
return
}
const
selectedSkus
=
selectedProducts
.
value
.
map
((
item
)
=>
item
.
warehouseSku
)
formData
.
value
.
detailsList
=
formData
.
value
.
detailsList
?.
filter
(
(
item
)
=>
!
selectedSkus
.
includes
(
item
.
warehouseSku
),
)
selectedProducts
.
value
=
[]
}
const
handleDispatch
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
}
catch
{
return
}
if
(
formData
.
value
.
detailsList
?.
length
===
0
)
{
ElMessage
.
warning
(
'没有可发货的商品'
)
return
}
for
(
const
item
of
formData
.
value
.
detailsList
||
[])
{
if
(
!
item
.
currentShipQuantity
)
{
ElMessage
.
warning
(
'请填写本次发货数量'
)
return
}
if
(
Number
(
item
.
currentShipQuantity
)
>
(
item
.
remainingQuantity
??
0
))
{
try
{
await
ElMessageBox
.
confirm
(
`库存SKU:
${
item
.
warehouseSku
}
本次发货数量大于剩余待发货数量,是否确认发货?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
},
)
}
catch
{
return
}
}
}
const
loading
=
ElLoading
.
service
({
lock
:
true
,
text
:
'正在提交...'
,
background
:
'rgba(0, 0, 0, 0.7)'
,
})
try
{
const
res
=
await
supplierDispatchApi
({
manageId
:
props
.
selectedRow
?.
id
as
number
,
manageNo
:
formData
.
value
.
stockingUpManageNo
as
string
,
warehouseId
:
formData
.
value
.
warehouseId
as
number
,
warehouseName
:
formData
.
value
.
warehouseName
as
string
,
expectDeliveryTime
:
formData
.
value
.
expectDeliveryTime
as
string
,
detailsList
:
formData
.
value
.
detailsList
?.
map
((
e
)
=>
({
...
e
,
shipmentQuantity
:
Number
(
e
.
currentShipQuantity
??
0
),
currentShipQuantity
:
undefined
,
remainingQuantity
:
undefined
,
}))
||
[],
})
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
'发货成功'
)
emit
(
'refresh'
)
visible
.
value
=
false
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
loading
.
close
()
}
}
const
loadProductList
=
async
()
=>
{
if
(
!
props
.
selectedRow
?.
id
)
return
const
loading
=
ElLoading
.
service
({
lock
:
true
,
text
:
'加载中...'
,
background
:
'rgba(0, 0, 0, 0.7)'
,
})
try
{
const
res
=
await
getStockingOrderDetailByIdApi
(
props
.
selectedRow
.
id
)
if
(
res
.
code
!==
200
)
{
ElMessage
.
warning
(
res
.
message
)
return
}
const
{
stockingUpManageNo
,
warehouseId
,
detailsList
,
warehouseName
}
=
res
.
data
formData
.
value
=
{
stockingUpManageNo
,
warehouseId
,
warehouseName
,
detailsList
:
detailsList
?.
map
((
item
)
=>
({
...
item
,
remainingQuantity
:
new
BigNumber
(
item
.
buyAmount
||
0
)
.
minus
(
item
.
shipmentQuantity
||
0
)
.
toNumber
(),
currentShipQuantity
:
undefined
,
})),
}
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
loading
.
close
()
}
}
watch
(
visible
,
(
val
)
=>
{
if
(
val
&&
props
.
selectedRow
)
{
loadProductList
()
}
})
</
script
>
<
style
lang=
"scss"
scoped
>
.supplier-dispatch-order-page
{
.form-section
{
margin-bottom
:
16px
;
.form-row
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
10px
;
}
.form-item
{
flex
:
1
;
min-width
:
280px
;
max-width
:
350px
;
}
:deep
(
.el-select
),
:deep
(
.el-input
),
:deep
(
.el-date-editor
)
{
width
:
100%
;
}
}
.table-section
{
height
:
450px
;
border
:
1px
solid
#ebeef5
;
border-radius
:
4px
;
}
.action-section
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
margin-top
:
16px
;
}
}
.dialog-footer
{
text-align
:
center
;
}
.field-error
{
color
:
#f56c6c
;
font-size
:
12px
;
line-height
:
1
;
margin-top
:
2px
;
}
</
style
>
src/views/supply/stockingOrder/index.vue
View file @
63026784
...
...
@@ -161,9 +161,7 @@
>
提交审核
<
/ElButto
n
>
<
/span
>
<
span
v
-
if
=
"status === 'STOCKING_UP'"
class
=
"item"
>
<
ElButton
type
=
"warning"
>
备货完成
<
/ElButton
>
<
/span
>
<
span
class
=
"item"
>
<
ElButton
type
=
"success"
>
添加内部便签
<
/ElButton
>
<
/span
>
...
...
@@ -221,9 +219,10 @@
:
edit
-
id
=
"selectedRow?.id"
@
refresh
=
"onRefresh"
/>
<
SupplierDispatchOrder
<
SupplierDispatchOrder
Dialog
v
-
model
:
visible
=
"supplierDispatchOrderVisible"
:
selected
-
row
=
"selectedRow"
:
warehouse
-
list
=
"warehouseList"
@
refresh
=
"onRefresh"
/>
<
/div
>
...
...
@@ -232,12 +231,13 @@
import
{
computed
,
ref
}
from
'vue'
import
{
getStockingOrderListApi
,
stockingCompleteApi
,
submitStockingOrderAuditApi
,
}
from
'@/api/stockingOrder'
import
TableView
from
'@/components/TableView.vue'
import
StockingOrderDetailTabs
from
'./StockingOrderDetailTabs.vue'
import
AddStockingOrderDialog
from
'./AddStockingOrderDialog.vue'
import
SupplierDispatchOrder
from
'./SupplierDispatchOrder
.vue'
import
SupplierDispatchOrder
Dialog
from
'./SupplierDispatchOrderDialog
.vue'
import
{
TreeData
,
SearchForm
,
...
...
@@ -394,7 +394,7 @@ const tableColumns = computed(() => {
{
label
:
'操作'
,
prop
:
'operation'
,
width
:
1
4
0
,
width
:
1
8
0
,
align
:
'center'
,
fixed
:
'right'
,
render
:
(
row
:
TableData
)
=>
{
...
...
@@ -427,6 +427,15 @@ const tableColumns = computed(() => {
供应商发货
<
/ElButton
>
)
}
{
row
.
status
===
'STOCKING_UP'
&&
(
<
ElButton
link
type
=
"warning"
onClick
=
{()
=>
stockingComplete
(
row
)
}
>
备货完成
<
/ElButton
>
)
}
<
/span
>
)
}
,
...
...
@@ -562,6 +571,30 @@ const handleSupplierDispatchOrder = (row: TableData) => {
selectedRow
.
value
=
row
supplierDispatchOrderVisible
.
value
=
true
}
const
stockingComplete
=
async
(
row
:
TableData
)
=>
{
try
{
await
ElMessageBox
.
confirm
(
'备货完成将把未完成入库申请单自动取消,是否继续对选中的订单操作备货完成?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
}
,
)
}
catch
{
return
}
try
{
const
res
=
await
stockingCompleteApi
(
row
.
id
)
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
'备货完成成功'
)
search
()
loadTreeData
()
}
catch
(
e
)
{
console
.
error
(
e
)
}
}
// 新增备货单弹窗
const
addDialogVisible
=
ref
(
false
)
const
handleAddOrder
=
()
=>
{
...
...
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