Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mes-pda-scan
Project
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ximai
mes-pda-scan
Commits
755018cb
Commit
755018cb
authored
Aug 13, 2025
by
李驰骋
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持批号调整
parent
7a89b1dc
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
311 additions
and
96 deletions
+311
-96
th_TH.json
lang/th_TH.json
+1
-0
zh_CN.json
lang/zh_CN.json
+1
-0
scanning.vue
pages/dhd/scanning.vue
+14
-7
card.vue
pages/stockTransfer/components/card.vue
+17
-14
index.vue
pages/stockTransfer/index.vue
+177
-61
select.vue
pages/stockTransfer/select.vue
+101
-14
No files found.
lang/th_TH.json
View file @
755018cb
...
...
@@ -212,6 +212,7 @@
"该数据已存在"
:
"มีข้อมูลนี้อยู่แล้ว"
,
"请输入储位"
:
"กรุณาใส่ที่เก็บข้อมูล"
,
"库存调拨"
:
"การโอนสินค้าคงคลัง"
,
"至少需要录入一批调拨数据"
:
"จำเป็นต้องบันทึกข้อมูลการโอนอย่างน้อยหนึ่งล็อต"
,
"请输入调拨产品号"
:
"กรุณากรอกหมายเลขผลิตภัณฑ์"
,
"调拨明细"
:
"รายละเอียดการจัดสรร"
,
"当前储位"
:
"พื้นที่จัดเก็บปัจจุบัน"
,
...
...
lang/zh_CN.json
View file @
755018cb
...
...
@@ -212,6 +212,7 @@
"该数据已存在"
:
"该数据已存在"
,
"请输入储位"
:
"请输入储位"
,
"库存调拨"
:
"库存调拨"
,
"至少需要录入一批调拨数据"
:
"至少需要录入一批调拨数据"
,
"请输入调拨产品号"
:
"请输入调拨产品号"
,
"调拨明细"
:
"调拨明细"
,
"当前储位"
:
"当前储位"
,
...
...
pages/dhd/scanning.vue
View file @
755018cb
...
...
@@ -120,13 +120,20 @@ export default {
mb001
:
arr
[
4
]
})
// 生成批号:品号+客户+日期yyyyMMdd
const
today
=
new
Date
()
const
dateStr
=
today
.
getFullYear
().
toString
()
+
(
today
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
)
+
today
.
getDate
().
toString
().
padStart
(
2
,
'0'
)
const
customer
=
arr
[
0
]
// 使用供应商号作为客户,如果没有则使用默认值
const
batchNo
=
arr
[
4
]
+
customer
+
dateStr
// 根据mb022属性判断批次管理
let
batchNo
=
''
if
(
data
.
data
&&
data
.
data
.
invmb
.
mb022
===
'Y'
)
{
// 批次管理:生成批号:品号+客户+日期yyyyMMdd
const
today
=
new
Date
()
const
dateStr
=
today
.
getFullYear
().
toString
()
+
(
today
.
getMonth
()
+
1
).
toString
().
padStart
(
2
,
'0'
)
+
today
.
getDate
().
toString
().
padStart
(
2
,
'0'
)
const
customer
=
arr
[
0
]
// 使用供应商号作为客户,如果没有则使用默认值
batchNo
=
arr
[
4
]
+
customer
+
dateStr
}
else
{
// 非批次管理:使用默认批次号
batchNo
=
data
.
data
&&
data
.
data
.
defBatchNo
?
data
.
data
.
defBatchNo
:
''
}
this
.
goodsList
.
push
({
supplierNo
:
arr
[
0
],
...
...
pages/stockTransfer/components/card.vue
View file @
755018cb
...
...
@@ -6,13 +6,10 @@
<
view
class
=
"inventory-data"
>
{{
$t
(
'库存数'
)
}}
:
{{
info
.
ml005
}}
<
/view>
<
u
-
icon
v
-
if
=
"i == 0"
name
=
"plus"
size
=
"36"
@
click
=
"handleAdd"
><
/u-icon>
<
u
-
icon
v
-
else
name
=
"minus"
size
=
"36"
@
click
=
"handleDel"
><
/u-icon>
<
u
-
icon
v
-
if
=
"showDeleteButton"
name
=
"minus"
size
=
"36"
@
click
=
"handleDel"
><
/u-icon>
<
/view>
<
/view>
<
view
class
=
"batch-info"
>
<
view
class
=
"batch-text"
>
{{
$t
(
'批次号'
)
}}
:
{{
info
.
ml004
||
$t
(
'无批次号'
)
}}
<
/view>
<
/view>
<!--
移除批次号显示,因为现在按批次分组
-->
<
uni
-
forms
:
modelValue
=
"info"
:
label
-
width
=
"90"
label
-
align
=
"right"
>
<
uni
-
forms
-
item
:
label
=
"`${$t('调拨数')
}
:`"
>
<
uni
-
easyinput
v
-
model
=
"info.allocateQuantity"
type
=
"number"
trim
=
"all"
...
...
@@ -41,6 +38,14 @@
i
:
{
type
:
Number
,
default
:
0
}
,
batchIndex
:
{
type
:
Number
,
default
:
0
}
,
itemIndex
:
{
type
:
Number
,
default
:
0
}
}
,
data
()
{
...
...
@@ -49,6 +54,12 @@
storageRange
:
[],
}
}
,
computed
:
{
showDeleteButton
()
{
// 每个批次组的第一个项目不显示删除按钮
return
this
.
itemIndex
>
0
;
}
}
,
created
()
{
this
.
getWarehouseList
();
if
(
this
.
info
.
allocateWarehouse
)
{
...
...
@@ -127,15 +138,7 @@
}
}
.
batch
-
info
{
padding
:
12
rpx
24
rpx
;
border
-
bottom
:
1
px
solid
#
f0f0f0
;
.
batch
-
text
{
font
-
size
:
26
rpx
;
color
:
#
666
;
}
}
/* 移除批次信息样式 */
/deep/
.
uni
-
forms
{
.
uni
-
forms
-
item
{
...
...
pages/stockTransfer/index.vue
View file @
755018cb
...
...
@@ -17,28 +17,40 @@
<
/view>
<
view
class
=
"top-r"
>
<
view
class
=
"total-quantity"
>
{{
item
[
0
].
ml005
}}
ps
{{
getTotalQuantity
(
item
)
}}
ps
<
/view>
<
u
-
icon
name
=
"minus"
size
=
"32"
@
click
.
native
.
stop
=
"handleDelete(item, index)"
><
/u-icon>
<
/view>
<
/view>
<
view
class
=
"bottom"
>
<
view
class
=
"content"
v
-
for
=
"(ele, idx) in item"
:
key
=
"idx"
>
<
view
class
=
"left"
>
<
view
class
=
"text current-storage"
>
{{
$t
(
'当前储位'
)
}}
:
{{
`${ele.ml002
}
|${ele.ml003
}
`
}}
<
/view>
<
view
class
=
"text batch-no"
>
{{
$t
(
'批次号'
)
}}
:
{{
ele
.
ml004
||
$t
(
'无批次号'
)
}}
<!--
按批次分组显示
-->
<
view
class
=
"batch-group"
v
-
for
=
"(batchGroup, batchIndex) in getBatchGroups(item)"
:
key
=
"batchIndex"
>
<
view
class
=
"batch-header"
>
<
view
class
=
"batch-title"
>
{{
$t
(
'批次号'
)
}}
:
{{
batchGroup
.
batchNo
||
$t
(
'无批次号'
)
}}
<
/view>
<
view
class
=
"batch-total"
>
{{
getBatchStockTotal
(
batchGroup
.
items
)
}}
ps
<
/view>
<
/view>
<
view
class
=
"batch-content"
>
<
view
class
=
"content"
v
-
for
=
"(ele, idx) in batchGroup.items"
:
key
=
"idx"
>
<
view
class
=
"left"
>
<
view
class
=
"text current-storage"
>
{{
$t
(
'当前储位'
)
}}
:
{{
`${ele.ml002
}
|${ele.ml003
}
`
}}
<
/view>
<
view
class
=
"text transfer-storage"
>
{{
$t
(
'调入储位'
)
}}
:
{{
ele
.
allocateLocation
?
`${ele.allocateWarehouse
}
|${ele.allocateLocation
}
`
:
''
}}
<
/view>
<
/view>
<
view
class
=
"right"
>
{{
ele
.
allocateQuantity
?
ele
.
allocateQuantity
:
0
}}
ps
<
/view>
<
/view>
<
view
class
=
"text transfer-storage"
>
{{
$t
(
'调入储位'
)
}}
:
{{
ele
.
allocateLocation
?
`${ele.allocateWarehouse
}
|${ele.allocateLocation
}
`
:
''
}}
<!--
批次内分隔符
-->
<
view
class
=
"batch-separator"
v
-
if
=
"batchGroup.items.length > 1"
>
<
view
class
=
"separator-line"
><
/view>
<
view
class
=
"separator-text"
>
{{
$t
(
'同批次'
)
}}
<
/view>
<
view
class
=
"separator-line"
><
/view>
<
/view>
<
/view>
<
view
class
=
"right"
>
{{
ele
.
allocateQuantity
?
ele
.
allocateQuantity
:
0
}}
ps
<
/view>
<
/view>
<
/view>
<
/view>
...
...
@@ -63,6 +75,39 @@
}
}
,
methods
:
{
// 按批次分组数据
getBatchGroups
(
item
)
{
const
batchMap
=
{
}
;
item
.
forEach
(
ele
=>
{
const
batchNo
=
ele
.
ml004
||
'no-batch'
;
if
(
!
batchMap
[
batchNo
])
{
batchMap
[
batchNo
]
=
{
batchNo
:
ele
.
ml004
,
items
:
[]
}
;
}
batchMap
[
batchNo
].
items
.
push
(
ele
);
}
);
return
Object
.
values
(
batchMap
);
}
,
// 计算所有批次数量合计
getTotalQuantity
(
item
)
{
return
item
.
reduce
((
total
,
ele
)
=>
{
return
total
+
(
Number
(
ele
.
ml005
)
||
0
);
}
,
0
);
}
,
// 计算批次调拨总数
getBatchTotal
(
items
)
{
return
items
.
reduce
((
total
,
item
)
=>
{
return
total
+
(
Number
(
item
.
allocateQuantity
)
||
0
);
}
,
0
);
}
,
// 计算批次库存总数
getBatchStockTotal
(
items
)
{
return
items
.
reduce
((
total
,
item
)
=>
{
return
total
+
(
Number
(
item
.
ml005
)
||
0
);
}
,
0
);
}
,
getValue
(
data
)
{
const
index
=
this
.
numList
.
findIndex
((
item
)
=>
{
return
item
==
data
[
0
][
'ml001'
].
trim
();
...
...
@@ -122,46 +167,73 @@
if
(
this
.
list
.
length
==
0
)
{
return
this
.
$u
.
toast
(
i18n
.
t
(
'提交数据不能为空'
));
}
let
flag
=
false
;
// 检查每组产品是否至少录入了一批调拨数据
for
(
let
i
=
0
;
i
<
this
.
list
.
length
;
i
++
)
{
for
(
let
v
=
0
;
v
<
this
.
list
[
i
].
length
;
v
++
)
{
if
(
!
this
.
list
[
i
][
v
][
'allocateQuantity'
])
{
this
.
$u
.
toast
(
i18n
.
t
(
'调拨数不能为空'
));
flag
=
true
;
break
;
}
if
(
!
this
.
list
[
i
][
v
][
'allocateWarehouse'
])
{
this
.
$u
.
toast
(
i18n
.
t
(
'调入库存不能为空'
));
flag
=
true
;
const
item
=
this
.
list
[
i
];
let
hasValidTransfer
=
false
;
for
(
let
v
=
0
;
v
<
item
.
length
;
v
++
)
{
const
ele
=
item
[
v
]
;
const
allocateQuantity
=
Number
(
ele
.
allocateQuantity
)
||
0
;
if
(
allocateQuantity
>
0
&&
ele
.
allocateWarehouse
&&
ele
.
allocateLocation
)
{
hasValidTransfer
=
true
;
break
;
}
if
(
!
this
.
list
[
i
][
v
][
'allocateLocation'
])
{
this
.
$u
.
toast
(
i18n
.
t
(
'调入储位不能为空'
));
flag
=
true
;
break
;
}
if
(
!
hasValidTransfer
)
{
const
productName
=
`${item[0].ml001
}
${item[0].materialName
}
`
;
this
.
$u
.
toast
(
`${productName
}
${i18n.t('至少需要录入一批调拨数据')
}
`
);
return
;
}
}
// 收集所有有效的调拨数据(调拨数大于0且有完整的调拨信息)
let
validTransferData
=
[];
let
hasInvalidData
=
false
;
for
(
let
i
=
0
;
i
<
this
.
list
.
length
;
i
++
)
{
for
(
let
v
=
0
;
v
<
this
.
list
[
i
].
length
;
v
++
)
{
const
item
=
this
.
list
[
i
][
v
];
const
allocateQuantity
=
Number
(
item
.
allocateQuantity
)
||
0
;
// 如果调拨数大于0,则检查必填项
if
(
allocateQuantity
>
0
)
{
if
(
!
item
.
allocateWarehouse
)
{
this
.
$u
.
toast
(
i18n
.
t
(
'调入库存不能为空'
));
hasInvalidData
=
true
;
break
;
}
if
(
!
item
.
allocateLocation
)
{
this
.
$u
.
toast
(
i18n
.
t
(
'调入储位不能为空'
));
hasInvalidData
=
true
;
break
;
}
// 添加到有效数据中
validTransferData
.
push
({
allocateLocation
:
item
.
allocateLocation
,
allocateQuantity
:
item
.
allocateQuantity
,
allocateWarehouse
:
item
.
allocateWarehouse
,
location
:
item
.
ml003
,
materialNo
:
item
.
ml001
,
warehouse
:
item
.
ml002
,
materialName
:
item
.
materialName
,
batchNo
:
item
.
ml004
}
);
}
}
if
(
hasInvalidData
)
break
;
}
if
(
flag
)
{
if
(
hasInvalidData
)
{
return
;
}
const
params
=
this
.
list
.
map
((
item
)
=>
{
return
item
.
map
((
ele
)
=>
{
return
{
allocateLocation
:
ele
.
allocateLocation
,
allocateQuantity
:
ele
.
allocateQuantity
,
allocateWarehouse
:
ele
.
allocateWarehouse
,
location
:
ele
.
ml003
,
materialNo
:
ele
.
ml001
,
warehouse
:
ele
.
ml002
,
materialName
:
ele
.
materialName
,
batchNo
:
ele
.
ml004
}
}
)
}
).
flat
(
Infinity
);
this
.
loading
=
true
;
this
.
$u
.
api
.
transferConfirmApi
({
data
:
params
data
:
validTransferData
}
)
.
then
(
res
=>
{
this
.
loading
=
false
;
...
...
@@ -256,31 +328,75 @@
padding
:
12
rpx
;
box
-
sizing
:
border
-
box
;
.
content
{
padding
:
24
rpx
12
rpx
;
margin
-
bottom
:
16
rpx
;
display
:
flex
;
justify
-
content
:
space
-
between
;
font
-
size
:
28
rpx
;
background
-
color
:
#
f1f1f3
;
border
:
1
px
solid
#
d8dadf
;
border
-
radius
:
12
rpx
;
box
-
sizing
:
border
-
box
;
.
batch
-
group
{
margin
-
bottom
:
24
rpx
;
&
:
last
-
child
{
margin
-
bottom
:
0
;
}
.
left
{
.
text
{
.
batch
-
header
{
display
:
flex
;
justify
-
content
:
space
-
between
;
align
-
items
:
center
;
padding
:
16
rpx
12
rpx
;
background
-
color
:
#
f8f9fa
;
border
-
radius
:
8
rpx
;
margin
-
bottom
:
12
rpx
;
.
batch
-
title
{
font
-
size
:
28
rpx
;
font
-
weight
:
bold
;
color
:
#
333
;
}
.
batch
-
no
{
.
batch
-
total
{
font
-
size
:
26
rpx
;
color
:
#
666
;
margin
:
8
rpx
0
;
}
}
.
right
{
padding
-
right
:
28
rpx
;
.
batch
-
content
{
.
content
{
padding
:
24
rpx
12
rpx
;
margin
-
bottom
:
16
rpx
;
display
:
flex
;
justify
-
content
:
space
-
between
;
font
-
size
:
28
rpx
;
background
-
color
:
#
f1f1f3
;
border
:
1
px
solid
#
d8dadf
;
border
-
radius
:
12
rpx
;
box
-
sizing
:
border
-
box
;
.
left
{
.
text
{
font
-
size
:
28
rpx
;
}
}
.
right
{
padding
-
right
:
28
rpx
;
}
}
.
batch
-
separator
{
display
:
flex
;
align
-
items
:
center
;
margin
:
16
rpx
0
;
.
separator
-
line
{
flex
:
1
;
height
:
1
px
;
background
-
color
:
#
d8dadf
;
}
.
separator
-
text
{
padding
:
0
16
rpx
;
font
-
size
:
24
rpx
;
color
:
#
999
;
background
-
color
:
#
f1f1f3
;
}
}
}
}
}
...
...
pages/stockTransfer/select.vue
View file @
755018cb
...
...
@@ -6,8 +6,18 @@
{{
info
[
0
].
ml001
}}
|
{{
info
[
0
].
materialName
}}
</view>
<view
class=
"detail"
>
<Card
v-for=
"(item, index) in info"
:key=
"index"
:info=
"item"
:i=
"index"
@
handleAdd=
"handleAdd"
@
handleDel=
"handleDel"
/>
<!-- 按批次分组显示 -->
<view
class=
"batch-group"
v-for=
"(batchGroup, batchIndex) in getBatchGroups()"
:key=
"batchIndex"
>
<view
class=
"batch-header"
>
<view
class=
"batch-title"
>
{{
$t
(
'批次号'
)
}}
:
{{
batchGroup
.
batchNo
||
$t
(
'无批次号'
)
}}
</view>
<view
class=
"batch-actions"
>
<u-icon
name=
"plus"
size=
"36"
@
click=
"handleAddToBatch(batchGroup.batchNo)"
></u-icon>
</view>
</view>
<view
class=
"batch-content"
>
<Card
v-for=
"(item, index) in batchGroup.items"
:key=
"index"
:info=
"item"
:i=
"getItemIndex(item)"
:batchIndex=
"batchIndex"
:itemIndex=
"index"
@
handleAdd=
"handleAdd"
@
handleDel=
"handleDel"
/>
</view>
</view>
</view>
</view>
<view
class=
"footer"
>
...
...
@@ -34,24 +44,64 @@
}
},
methods
:
{
handleAdd
()
{
this
.
info
.
push
({
...
this
.
info
[
0
],
allocateQuantity
:
""
,
allocateWarehouse
:
""
,
allocateLocation
:
""
// 按批次分组数据
getBatchGroups
()
{
const
batchMap
=
{};
this
.
info
.
forEach
(
ele
=>
{
const
batchNo
=
ele
.
ml004
||
'no-batch'
;
if
(
!
batchMap
[
batchNo
])
{
batchMap
[
batchNo
]
=
{
batchNo
:
ele
.
ml004
,
items
:
[]
};
}
batchMap
[
batchNo
].
items
.
push
(
ele
);
});
return
Object
.
values
(
batchMap
);
},
// 获取项目在原始数组中的索引
getItemIndex
(
item
)
{
return
this
.
info
.
findIndex
(
info
=>
info
===
item
);
},
// 向指定批次添加新项目
handleAddToBatch
(
batchNo
)
{
const
baseItem
=
this
.
info
.
find
(
item
=>
(
item
.
ml004
||
'no-batch'
)
===
batchNo
);
if
(
baseItem
)
{
this
.
info
.
push
({
...
baseItem
,
allocateQuantity
:
""
,
allocateWarehouse
:
""
,
allocateLocation
:
""
});
}
},
handleAdd
()
{
// 保持原有逻辑,向第一个批次添加
const
firstBatch
=
this
.
getBatchGroups
()[
0
];
if
(
firstBatch
)
{
this
.
handleAddToBatch
(
firstBatch
.
batchNo
);
}
},
handleDel
(
index
)
{
this
.
info
.
splice
(
index
,
1
);
},
handleSubmit
()
{
const
num
=
this
.
info
.
reduce
((
pre
,
cur
)
=>
{
return
pre
+
Number
(
cur
.
allocateQuantity
);
},
0
);
if
(
num
>
this
.
info
[
0
].
ml005
)
{
return
this
.
$u
.
toast
(
i18n
.
t
(
'调拨总数不能大于库存数'
));
};
// 按批次分组验证调拨总数
const
batchGroups
=
this
.
getBatchGroups
();
for
(
let
batchGroup
of
batchGroups
)
{
const
batchTotal
=
batchGroup
.
items
.
reduce
((
total
,
item
)
=>
{
return
total
+
(
Number
(
item
.
allocateQuantity
)
||
0
);
},
0
);
// 计算该批次的库存总数
const
batchStockTotal
=
batchGroup
.
items
.
reduce
((
total
,
item
)
=>
{
return
total
+
(
Number
(
item
.
ml005
)
||
0
);
},
0
);
if
(
batchTotal
>
batchStockTotal
)
{
return
this
.
$u
.
toast
(
i18n
.
t
(
'调拨总数不能大于库存数'
));
}
}
let
pages
=
getCurrentPages
();
// 2. 上一页面实例
// 注意是length长度,所以要想得到上一页面的实例需要 -2
...
...
@@ -85,6 +135,43 @@
background-color
:
#f1f1f3
;
border
:
1px
solid
#d8dadf
;
border-radius
:
12rpx
;
.batch-group
{
margin-bottom
:
32rpx
;
&
:last-child
{
margin-bottom
:
0
;
}
.batch-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
16rpx
12rpx
;
background-color
:
#ffffff
;
border-radius
:
8rpx
;
margin-bottom
:
16rpx
;
border
:
1px
solid
#d8dadf
;
.batch-title
{
font-size
:
28rpx
;
font-weight
:
bold
;
color
:
#333
;
}
.batch-actions
{
display
:
flex
;
align-items
:
center
;
}
}
.batch-content
{
background-color
:
#ffffff
;
border-radius
:
8rpx
;
padding
:
12rpx
;
border
:
1px
solid
#d8dadf
;
}
}
}
}
...
...
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