Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
M
mini-wms
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
周海峰
mini-wms
Commits
8223901a
Commit
8223901a
authored
Dec 15, 2025
by
yubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修bug
parent
92fcc23b
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
154 行增加
和
91 行删除
+154
-91
ruoyi-admin-vue/src/views/inventory/orders/OutboundOrderFormWithItems.vue
+147
-86
ruoyi-inventory/src/main/resources/mapper/inventory/InventoryMapper.xml
+7
-5
没有找到文件。
ruoyi-admin-vue/src/views/inventory/orders/OutboundOrderFormWithItems.vue
View file @
8223901a
...
...
@@ -603,63 +603,155 @@ export default {
this
.
$set
(
row
,
'plannedQuantity'
,
1
);
}
},
syncDetails
(
strict
=
true
)
{
this
.
details
=
[];
let
validRows
=
[];
if
(
strict
)
{
validRows
=
this
.
inventoryList
.
filter
(
row
=>
{
const
availableQty
=
(
row
.
quantity
||
0
)
-
(
row
.
lockedQuantity
||
0
);
return
row
.
actualQuantity
!==
null
&&
row
.
actualQuantity
!==
undefined
&&
row
.
actualQuantity
>=
1
&&
row
.
actualQuantity
<=
availableQty
&&
row
.
plannedQuantity
!==
null
&&
row
.
plannedQuantity
!==
undefined
&&
row
.
plannedQuantity
>=
1
&&
row
.
plannedQuantity
<=
availableQty
&&
row
.
divisor
!==
null
&&
row
.
labelColor
!==
''
&&
row
.
voucherNumber
!==
''
&&
row
.
shippedBy
!==
''
;
});
}
else
{
validRows
=
this
.
inventoryList
.
filter
(
row
=>
{
return
row
.
actualQuantity
!==
null
||
row
.
plannedQuantity
!==
null
||
row
.
divisor
!==
null
||
row
.
labelColor
!==
''
||
row
.
unitPrice
!==
null
||
row
.
shippedBy
!==
''
||
row
.
voucherNumber
!==
''
||
row
.
remark
!==
''
;
});
// 改造后的 syncDetails:仅校验有实际数量的行,且有值才校验
syncDetails
(
strict
=
true
)
{
this
.
details
=
[];
const
errorMessages
=
[];
// 收集有值但不合规的字段提示
let
validRows
=
[];
// 第一步:先过滤出「实际数量有值」的行(核心:无实际数量的行直接排除)
const
rowsWithActualQty
=
this
.
inventoryList
.
filter
(
row
=>
{
return
row
.
actualQuantity
!==
null
&&
row
.
actualQuantity
!==
undefined
;
});
if
(
strict
&&
rowsWithActualQty
.
length
>
0
)
{
// 严格模式:仅校验有实际数量的行,且「有值才校验」
validRows
=
rowsWithActualQty
.
filter
((
row
,
index
)
=>
{
const
rowErrors
=
[];
const
rowName
=
`第
${
index
+
1
}
行【
${
row
.
materialName
||
'未知物料'
}
】`
;
const
availableQty
=
(
row
.
quantity
||
0
)
-
(
row
.
lockedQuantity
||
0
);
// 1. 实际数量(必校验,因为能走到这步说明有值)
if
(
row
.
actualQuantity
<
1
)
{
rowErrors
.
push
(
'实际数量不能小于1'
);
}
if
(
row
.
actualQuantity
>
availableQty
)
{
rowErrors
.
push
(
`实际数量不能超过可用库存(
${
availableQty
}
)`
);
}
validRows
.
forEach
(
row
=>
{
const
newDetail
=
{
inventoryId
:
row
.
inventoryId
,
materialId
:
row
.
materialId
||
this
.
form
.
materialId
,
materialName
:
row
.
materialName
||
this
.
form
.
materialName
||
''
,
batchId
:
row
.
batchId
||
row
.
batchCode
||
''
,
warehouseId
:
row
.
warehouseId
,
warehousesId
:
row
.
warehousesId
||
''
,
warehousesName
:
row
.
warehousesName
||
''
,
locationId
:
row
.
locationId
||
''
,
locationName
:
row
.
locationName
||
''
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
''
,
plannedQuantity
:
row
.
plannedQuantity
,
actualQuantity
:
row
.
actualQuantity
,
divisor
:
row
.
divisor
,
labelColor
:
row
.
labelColor
,
unitPrice
:
row
.
unitPrice
,
shippedBy
:
row
.
shippedBy
,
voucherNumber
:
row
.
voucherNumber
,
remark
:
row
.
remark
};
this
.
details
.
push
(
newDetail
);
// 2. 计划数量(有值才校验)
if
(
row
.
plannedQuantity
!==
null
&&
row
.
plannedQuantity
!==
undefined
)
{
if
(
row
.
plannedQuantity
<
1
)
{
rowErrors
.
push
(
'计划数量不能小于1'
);
}
if
(
row
.
plannedQuantity
>
availableQty
)
{
rowErrors
.
push
(
`计划数量不能超过可用库存(
${
availableQty
}
)`
);
}
}
// 3. 除数(有值才校验,无值不提示)
if
(
row
.
divisor
!==
null
&&
row
.
divisor
!==
undefined
)
{
// 若有值但为0/负数,可补充校验(按需)
if
(
row
.
divisor
<=
0
)
{
rowErrors
.
push
(
'换算率(除数)必须大于0'
);
}
}
// 4. 标签颜色(有值才校验,空字符串算不合规)
if
(
row
.
labelColor
!==
undefined
&&
row
.
labelColor
===
''
)
{
rowErrors
.
push
(
'请填写标签颜色'
);
}
// 5. 凭证号(有值才校验,空字符串算不合规)
if
(
row
.
voucherNumber
!==
undefined
&&
row
.
voucherNumber
===
''
)
{
rowErrors
.
push
(
'请填写凭证号'
);
}
// 6. 发货人(有值才校验,空字符串算不合规)
if
(
row
.
shippedBy
!==
undefined
&&
row
.
shippedBy
===
''
)
{
rowErrors
.
push
(
'请填写发货人'
);
}
// 收集当前行的错误(仅有值但不合规的字段)
if
(
rowErrors
.
length
>
0
)
{
errorMessages
.
push
(
`
${
rowName
}
:
${
rowErrors
.
join
(
'、'
)}
`
);
return
false
;
}
return
true
;
});
}
// 格式化通过校验的行并同步到details
validRows
.
forEach
(
row
=>
{
const
newDetail
=
{
inventoryId
:
row
.
inventoryId
,
materialId
:
row
.
materialId
||
this
.
form
.
materialId
,
materialName
:
row
.
materialName
||
this
.
form
.
materialName
||
''
,
batchId
:
row
.
batchId
||
row
.
batchCode
||
''
,
warehouseId
:
row
.
warehouseId
,
warehousesId
:
row
.
warehousesId
||
''
,
warehousesName
:
row
.
warehousesName
||
''
,
locationId
:
row
.
locationId
||
''
,
locationName
:
row
.
locationName
||
''
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
''
,
plannedQuantity
:
row
.
plannedQuantity
,
actualQuantity
:
row
.
actualQuantity
,
divisor
:
row
.
divisor
,
labelColor
:
row
.
labelColor
,
unitPrice
:
row
.
unitPrice
,
shippedBy
:
row
.
shippedBy
,
voucherNumber
:
row
.
voucherNumber
,
remark
:
row
.
remark
};
this
.
details
.
push
(
newDetail
);
});
// 返回错误信息,供提交方法使用
return
errorMessages
;
},
// 提交方法:集成精准提示
handleSubmit
()
{
// 1. 校验物料ID
if
(
!
this
.
form
.
materialId
?.
trim
())
{
this
.
$message
.
error
(
'请先选择物料ID'
);
return
;
}
// 2. 校验表单基础项
this
.
$refs
.
detailForm
.
validate
(
async
(
valid
)
=>
{
if
(
!
valid
)
{
this
.
$message
.
error
(
'表单校验失败,请检查必填项'
);
return
;
}
console
.
log
(
"syncDetails前"
,
this
.
details
);
// 执行明细校验,接收错误信息
const
detailErrors
=
this
.
syncDetails
(
true
);
console
.
log
(
"syncDetails后"
,
this
.
details
);
// 3. 提示有值但不合规的字段
if
(
detailErrors
.
length
>
0
)
{
this
.
$message
.
error
({
title
:
'明细数据校验失败'
,
message
:
detailErrors
.
join
(
'<br/>'
),
dangerouslyUseHTMLString
:
true
,
duration
:
15000
,
showClose
:
true
});
},
return
;
}
// 4. 兜底:有实际数量的行都校验通过,但无有效行(比如实际数量都
<
1
)
if
(
this
.
details
.
length
===
0
)
{
this
.
$message
.
error
(
'无有效明细数据,请检查实际数量及相关字段'
);
return
;
}
// 5. 组装提交数据
const
submitDetails
=
this
.
details
.
map
(
detail
=>
({
...
detail
,
materialName
:
this
.
form
.
materialName
||
detail
.
materialName
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
detail
.
outboundOrderId
,
materialId
:
this
.
form
.
materialId
||
detail
.
materialId
}));
console
.
log
(
'提交的明细数据:'
,
submitDetails
);
this
.
$emit
(
'submit'
,
submitDetails
);
this
.
$emit
(
'update:open'
,
false
);
});
},
removeDetail
(
row
)
{
this
.
details
=
this
.
details
.
filter
(
d
=>
d
.
inventoryId
!==
row
.
inventoryId
);
const
inventoryRow
=
this
.
inventoryList
.
find
(
item
=>
item
.
inventoryId
===
row
.
inventoryId
);
...
...
@@ -678,38 +770,7 @@ export default {
}
this
.
syncDetails
(
this
.
initDetails
.
length
===
0
);
},
handleSubmit
()
{
if
(
!
this
.
form
.
materialId
?.
trim
())
{
this
.
$message
.
error
(
'请先选择物料ID'
);
return
;
}
this
.
$refs
.
detailForm
.
validate
(
async
(
valid
)
=>
{
if
(
!
valid
)
{
this
.
$message
.
error
(
'表单校验失败,请检查必填项'
);
return
;
}
this
.
syncDetails
(
true
);
if
(
this
.
details
.
length
===
0
)
{
this
.
$message
.
error
(
'请填写实际数量并完善所有必填明细信息'
);
return
;
}
const
submitDetails
=
this
.
details
.
map
(
detail
=>
({
...
detail
,
materialName
:
this
.
form
.
materialName
||
detail
.
materialName
,
outboundOrderId
:
this
.
form
.
outboundOrderId
||
detail
.
outboundOrderId
,
materialId
:
this
.
form
.
materialId
||
detail
.
materialId
}));
console
.
log
(
'提交的明细数据:'
,
submitDetails
);
this
.
$emit
(
'submit'
,
submitDetails
);
this
.
$emit
(
'update:open'
,
false
);
});
},
handleClose
()
{
this
.
closeLoading
();
this
.
$nextTick
(()
=>
{
...
...
ruoyi-inventory/src/main/resources/mapper/inventory/InventoryMapper.xml
View file @
8223901a
...
...
@@ -556,24 +556,25 @@ and inventory_status = '1'
<select
id=
"selectInventoryTopTenByAmount"
resultType=
"java.util.Map"
>
select
m.material_name as name,
sum(i.quantity) as value
sum(i.quantity)
*i.unit_price
as value
from inventory i
left join materials m on i.material_id = m.id
where i.is_used = 1 and i.last_inbound_time
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
where i.is_used = 1 and i.
unit_price >0 and i.
last_inbound_time
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.last_inbound_time
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
order by sum(i.quantity) desc
order by sum(i.quantity)*i.unit_price desc
</select>
<select
id=
"selectInventoryTopTenByQuantity"
resultType=
"java.util.Map"
>
select
m.material_name as name,
sum(i.quantity)
*i.unit_price
as value
sum(i.quantity) as value
from inventory i
left join materials m on i.material_id = m.id
where i.is_used = 1 and i.last_inbound_time
>
= DATE_FORMAT(CURDATE(), '%Y-%m-01')
and i.last_inbound_time
<
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
group by m.material_name
order by sum(i.quantity)
*i.unit_price
desc
order by sum(i.quantity) desc
</select>
</mapper>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论