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
eb72b9a0
Commit
eb72b9a0
authored
Dec 05, 2025
by
qinjianhui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into 'master'
Dev See merge request
!119
parents
bbbe0ed5
f84c5115
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1772 additions
and
246 deletions
+1772
-246
src/api/logistics.ts
+2
-0
src/api/podCnOrder.ts
+35
-9
src/api/podUsOrder.ts
+7
-1
src/types/api/podCnOrder.ts
+8
-0
src/types/api/podMakeOrder.ts
+1
-0
src/types/api/podUsOrder.ts
+7
-0
src/views/logistics/logisticsTracking.vue
+176
-1
src/views/logistics/types/logistics.ts
+3
-0
src/views/order/podCN/PodDistributionOrder.vue
+5
-0
src/views/order/podCN/PodMakeOrder.vue
+29
-4
src/views/order/podCN/SuperPodMakeOrder.vue
+29
-20
src/views/order/podCN/components/WeightDialog.vue
+336
-0
src/views/order/podCN/components/weigh.ts
+366
-0
src/views/order/podCN/index.vue
+242
-20
src/views/order/podUs/index.vue
+245
-45
src/views/order/podUsSchedulingRules/index.vue
+169
-47
src/views/supply/supplierManagement/index.vue
+106
-98
src/views/supply/supplierManagement/types/index.ts
+6
-1
No files found.
src/api/logistics.ts
View file @
eb72b9a0
...
...
@@ -63,6 +63,8 @@ export interface ILogisticsCompany {
authCode
:
string
|
null
// varchar(500)
redirectUri
:
string
|
null
// varchar(256)
createTime
:
string
|
null
// timestamp
orderStatus
:
string
|
null
// varchar(60)
signTime
:
string
|
null
// timestamp
vat
:
string
|
null
// varchar(60)
ioss
:
string
|
null
// varchar(60)
basicType
:
number
// int(11)
...
...
src/api/podCnOrder.ts
View file @
eb72b9a0
...
...
@@ -38,6 +38,11 @@ export function syncReceiverAddress(data: number[]) {
)
}
export
function
getEmployeeListApi
()
{
return
axios
.
get
(
`/factory/factoryUser/list`
)
}
// 播种墙配货 扫码放入箱子
export
function
getPackingCnDataApi
(
code
:
string
,
...
...
@@ -147,19 +152,13 @@ export function getCardOrderList(
)
}
export
function
batchCheckPrintPodCn
(
ids
:
string
)
{
export
function
batchCheckPrintPodCn
(
ids
:
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
PrintData
[]
>>
(
`/factory/podJomallOrderCn/batchCheckPrintPodCn?ids=
${
ids
}
`
,
)
}
export
function
batchCheckPrintPodUs
(
ids
:
string
)
{
export
function
batchCheckPrintPodUs
(
ids
:
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
PrintData
[]
>>
(
`/factory/podJomallOrderUs/batchCheckPrintPodUs?ids=
${
ids
}
`
,
)
...
...
@@ -565,10 +564,11 @@ export function getListCraftApi() {
}
// 批量下载 列表
export
function
batchDownloadApi
(
currentPage
:
number
,
pageSize
:
number
)
{
export
function
batchDownloadApi
(
params
:
SearchForm
,
currentPage
:
number
,
pageSize
:
number
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
`factory/podBatchDownload/cn/list_page`
,
{
...
params
,
currentPage
,
pageSize
,
},
...
...
@@ -723,3 +723,29 @@ export function getCustomTagListCnApi() {
`factory/podJomallOrderCn/getCustomTagList`
,
)
}
// 根据店铺单号或跟踪号查询订单
export
function
listByNoApi
(
params
:
{
type
:
string
no
:
string
logisticsCompanyCode
?:
string
})
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
`factory/podJomallOrderCn/listByNo`
,
{
params
},
)
}
//保存称重分拣
export
function
orderWeighingApi
(
params
:
{
podCnWeighingParams
:
{
id
?:
string
;
outWarehouseWeight
?:
string
}[]
})
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'factory/podJomallOrderCn/orderWeighing'
,
params
,
)
}
//获取物流公司
export
function
allErpCodeListApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/logisticsCompany/allErpCodeList'
,
)
}
src/api/podUsOrder.ts
View file @
eb72b9a0
...
...
@@ -477,10 +477,11 @@ export function getListCraftApi() {
}
// 批量下载 列表
export
function
batchDownloadApi
(
currentPage
:
number
,
pageSize
:
number
)
{
export
function
batchDownloadApi
(
params
:
SearchForm
,
currentPage
:
number
,
pageSize
:
number
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
`factory/podBatchDownload/us/list_page`
,
{
...
params
,
currentPage
,
pageSize
,
},
...
...
@@ -625,6 +626,11 @@ export function getAccountCodeByFactoryIdApi(params: { token: string }) {
export
function
getLogisticsWayApi
()
{
return
axios
.
get
(
`logisticsWay/usableAllList`
)
}
export
function
getEmployeeListApi
()
{
return
axios
.
get
(
`/factory/factoryUser/list`
)
}
// 打印拣货单item
export
function
printPickPdfByBatchNumberApi
(
params
:
{
batchArrangeNumber
:
string
...
...
src/types/api/podCnOrder.ts
View file @
eb72b9a0
...
...
@@ -46,7 +46,14 @@ export interface SearchForm {
tagsId
?:
string
source
?:
string
size
?:
string
logisticsCompanyCode
?:
string
tagsIdArr
?:
(
number
|
null
)[]
craftType
?:
string
downloadStatus
?:
number
syntheticStatus
?:
number
automaticComposing
?:
number
employeeId
?:
number
blocking
?:
boolean
}
export
interface
PodCnOrderListData
{
id
:
number
...
...
@@ -113,6 +120,7 @@ export interface ProductList {
variantImage
?:
string
craftPrice
?:
number
craftCode
?:
string
craftType
?:
string
previewImgs
?:
[]
platform
?:
string
imageAry
?:
string
...
...
src/types/api/podMakeOrder.ts
View file @
eb72b9a0
...
...
@@ -29,6 +29,7 @@ export interface OrderData {
remark
?:
string
version
?:
number
factoryOrderNumber
?:
number
|
string
replaceShipment
?:
number
|
string
orderParamList
?:
IorderItem
[]
}
export
interface
IorderItem
{
...
...
src/types/api/podUsOrder.ts
View file @
eb72b9a0
...
...
@@ -44,6 +44,12 @@ export interface SearchForm {
size
?:
string
tagsIdArr
?:
(
number
|
null
)[]
replaceShipment
?:
number
|
null
craftType
?:
string
downloadStatus
?:
number
syntheticStatus
?:
number
automaticComposing
?:
number
employeeId
?:
number
blocking
?:
boolean
}
export
interface
PodUsOrderListData
{
id
:
number
...
...
@@ -113,6 +119,7 @@ export interface ProductList {
variantImage
?:
string
craftPrice
?:
number
craftCode
?:
string
craftType
?:
string
platform
?:
string
imageAry
?:
string
previewImgs
?:
[]
...
...
src/views/logistics/logisticsTracking.vue
View file @
eb72b9a0
...
...
@@ -27,6 +27,23 @@
<
template
#
top
>
<
el
-
card
>
<
el
-
form
inline
:
model
=
"searchForm"
ref
=
"searchFormRef"
>
<
el
-
form
-
item
label
=
"创建时间"
>
<
el
-
date
-
picker
v
-
model
=
"tradingTime"
:
shortcuts
=
"pickerOptions.shortcuts"
:
default
-
time
=
"[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
type
=
"datetimerange"
start
-
placeholder
=
"开始时间"
end
-
placeholder
=
"结束时间"
clearable
style
=
"width: 260px"
format
=
"YYYY-MM-DD HH:mm:ss"
value
-
format
=
"YYYY-MM-DD HH:mm:ss"
/>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"物流跟踪号"
>
<
el
-
input
v
-
model
=
"searchForm.trackNumber"
...
...
@@ -87,6 +104,9 @@
<
template
#
shipmentType
=
"{ row
}
"
>
{{
[
'自有物流'
,
'工厂物流'
][
row
.
shipmentType
]
}}
<
/template
>
<
template
#
shippingAge
=
"{ row
}
"
>
{{
getShippingAge
(
row
)
}}
<
/template
>
<
/TableView
>
<
/div
>
<
div
class
=
"pagination"
>
...
...
@@ -139,7 +159,124 @@ const searchForm = ref<SearchForm>({
shopNumber
:
''
,
trackNumber
:
''
,
}
)
function
getStartTime
()
{
const
date
=
new
Date
()
const
year
=
date
.
getFullYear
()
const
month
=
date
.
getMonth
()
+
1
const
day
=
date
.
getDate
()
return
`${year
}
-${month
}
-${day
}
00:00:00`
}
const
tradingTime
=
ref
<
string
[]
>
([])
const
pickerOptions
=
{
shortcuts
:
[
{
text
:
'今日'
,
value
:
()
=>
{
const
start
=
new
Date
(
new
Date
(
getStartTime
()).
getTime
())
const
end
=
new
Date
()
return
[
start
,
end
]
}
,
}
,
{
text
:
'昨天'
,
value
:
()
=>
{
const
start
=
new
Date
()
const
end
=
new
Date
(
new
Date
(
getStartTime
()).
getTime
()
-
1
)
start
.
setTime
(
end
.
getTime
()
-
3600
*
1000
*
24
*
1
+
1
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'最近7天'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
(
getStartTime
())
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
6
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'最近14天'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
(
getStartTime
())
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
13
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'最近30天'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
(
getStartTime
())
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
29
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'本星期'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
()
const
nowDay
=
new
Date
().
getDay
()
-
1
start
.
setTime
(
new
Date
(
getStartTime
()).
getTime
()
-
3600
*
1000
*
24
*
nowDay
,
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'上星期'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
()
const
nowDay
=
new
Date
().
getDay
()
-
1
end
.
setTime
(
new
Date
(
getStartTime
()).
getTime
()
-
3600
*
1000
*
24
*
nowDay
-
1
,
)
start
.
setTime
(
end
.
getTime
()
-
3600
*
1000
*
24
*
7
+
1
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'这个月'
,
value
:
()
=>
{
const
end
=
new
Date
()
const
start
=
new
Date
()
const
nowDate
=
new
Date
().
getDate
()
-
1
start
.
setTime
(
new
Date
(
getStartTime
()).
getTime
()
-
3600
*
1000
*
24
*
nowDate
,
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'上个月'
,
value
:
()
=>
{
const
date
=
new
Date
()
let
year
=
date
.
getFullYear
()
let
month
=
date
.
getMonth
()
const
end
=
new
Date
(
new
Date
(
`${year
}
-${month + 1
}
-1 00:00:00`
).
getTime
()
-
1
,
)
if
(
month
===
0
)
{
month
=
12
year
=
year
-
1
}
const
start
=
new
Date
(
new
Date
(
`${year
}
-${month
}
-1 00:00:00`
).
getTime
(),
)
return
[
start
,
end
]
}
,
}
,
{
text
:
'历史'
,
value
:
()
=>
{
return
[
''
,
''
]
}
,
}
,
],
}
const
treeData
=
ref
<
LogisticsTrackingTree
[]
>
()
const
treeRef
=
ref
<
InstanceType
<
typeof
ElTree
>>
()
const
tableRef
=
ref
<
{
internalIsMore
?:
boolean
}
>
()
...
...
@@ -183,6 +320,19 @@ const tableColumns = computed(() => {
align
:
'center'
,
}
,
{
label
:
'创建时间'
,
prop
:
'createTime'
,
width
:
200
,
align
:
'center'
,
}
,
{
label
:
'发货时效(天)'
,
prop
:
'shippingAge'
,
slot
:
'shippingAge'
,
width
:
120
,
align
:
'center'
,
}
,
{
label
:
'订单状态'
,
prop
:
'orderStatus'
,
slot
:
'orderStatus'
,
...
...
@@ -261,13 +411,38 @@ const getTree = async () => {
console
.
error
(
e
)
}
}
/** 计算发货时效(天)
* 已签收 → 停止计时
* <12h = 0天;≥12h & <24h = 1天;≥48h = 2天 ...
*/
function
getShippingAge
(
row
:
ILogisticsCompany
):
number
{
// 成功签收就固定: 已签收时间 - 创建时间
if
(
row
.
orderStatus
===
'COMPLETE'
)
{
const
signTime
=
new
Date
(
row
.
signTime
??
0
).
getTime
()
const
createTime
=
new
Date
(
row
.
createTime
??
0
).
getTime
()
return
msToDays
(
signTime
-
createTime
)
}
// 未签收:当前时间 - 创建时间
const
now
=
Date
.
now
()
const
create
=
new
Date
(
row
.
createTime
??
0
).
getTime
()
return
msToDays
(
now
-
create
)
}
/** 毫秒 → 天数(≥12h 向下取整) */
function
msToDays
(
ms
:
number
):
number
{
const
hours
=
ms
/
(
1000
*
60
*
60
)
if
(
hours
<
12
)
return
0
return
Math
.
floor
(
hours
/
24
)
}
// 列表查询
async
function
getData
()
{
const
res
=
await
logisticsTrackingPage
({
trackingStatus
:
nodeId
.
value
,
shopNumber
:
searchForm
.
value
.
shopNumber
,
trackNumber
:
searchForm
.
value
.
trackNumber
,
startTime
:
tradingTime
.
value
&&
tradingTime
.
value
[
0
],
endTime
:
tradingTime
.
value
&&
tradingTime
.
value
[
1
],
queryDateType
:
tradingTime
.
value
&&
1
,
}
)
leftData
.
value
=
res
.
data
.
records
pagination
.
value
.
total
=
res
.
data
.
total
...
...
src/views/logistics/types/logistics.ts
View file @
eb72b9a0
...
...
@@ -59,4 +59,7 @@ export interface LogisticsTrackingParams {
trackNumber
?:
number
|
string
shopNumber
?:
string
|
number
trackingStatus
?:
number
startTime
?:
string
endTime
?:
string
queryDateType
?:
number
|
string
}
src/views/order/podCN/PodDistributionOrder.vue
View file @
eb72b9a0
...
...
@@ -399,6 +399,11 @@ watch(visible, async (value: boolean) => {
_warehouseId
.
value
=
hit
?
localId
:
props
.
warehouseList
[
0
].
id
initPrintDevice
()
inputActive
()
const
locaclPrinter
=
localStorage
.
getItem
(
'sheetPrinter'
)
if
(
locaclPrinter
)
sheetPrinter
.
value
=
JSON
.
parse
(
locaclPrinter
)
emit
(
'set-printer'
,
sheetPrinter
.
value
)
}
})
watch
(
...
...
src/views/order/podCN/PodMakeOrder.vue
View file @
eb72b9a0
...
...
@@ -375,6 +375,8 @@ watch(visible, async (value: boolean) => {
if
(
value
)
{
podOrderDetailsData
.
value
=
{}
currentCode
=
''
currentItem
.
value
=
{}
const
localRaw
=
sessionStorage
.
getItem
(
'locaclCnWarehouseId'
)
const
localId
=
localRaw
?
JSON
.
parse
(
localRaw
)
:
''
/* 先找一次,确认本地值是否存在于列表 */
...
...
@@ -400,6 +402,13 @@ watch(visible, async (value: boolean) => {
console
.
error
(
error
)
}
}
console
.
log
(
8888
,
currentItem
.
value
,
currentCode
,
podOrderDetailsData
.
value
,
boxIndex
.
value
,
)
initOrderDetailBox
()
initPrintDevice
()
...
...
@@ -422,6 +431,11 @@ watch(boxIndex, (value: number | null) => {
const
bool
=
!
boxChange
.
value
boxChange
.
value
=
false
console
.
log
(
'boxChange'
,
bool
,
value
)
const
item
=
podBoxList
.
value
?.
find
((
item
)
=>
item
.
box
===
value
)
currentItem
.
value
=
item
?.
data
as
OrderData
console
.
log
(
'currentItem.value'
,
currentItem
.
value
)
renderItemBox
(
bool
)
}
})
...
...
@@ -431,6 +445,7 @@ watch(
if
(
value
)
{
const
item
=
value
.
find
((
item
)
=>
item
.
box
===
podBoxIndex
.
value
)
console
.
log
(
'podBoxList'
,
value
,
podBoxIndex
.
value
,
item
)
currentItem
.
value
=
item
?.
data
as
OrderData
if
(
item
?.
data
)
{
renderItemBox
(
true
)
}
else
{
...
...
@@ -838,19 +853,23 @@ const handleOpened = () => {
productionOrderRef
.
value
.
focus
()
}
const
handleClose
=
(
done
:
()
=>
void
)
=>
{
console
.
log
(
999
,
currentItem
.
value
)
nextStep
(()
=>
{
done
()
})
}
,
currentItem
.
value
)
}
const
onClose
=
()
=>
{
// orderStore.clearPodBox()
emit
(
'refresh'
)
}
// 下一步
const
nextStep
=
async
(
callback
:
()
=>
void
)
=>
{
const
nextStep
=
async
(
callback
:
()
=>
void
,
data
?:
OrderData
)
=>
{
const
everyPicked
=
podOrderDetailsData
.
value
?.
productList
?.
every
(
(
item
)
=>
item
.
count
===
item
.
purchaseNumber
,
)
console
.
log
(
854
,
data
)
if
(
everyPicked
&&
(
podOrderDetailsData
.
value
?.
printResult
===
'printSuccess'
||
...
...
@@ -858,7 +877,9 @@ const nextStep = async (callback: () => void) => {
)
{
try
{
await
ElMessageBox
.
alert
(
'当前订单验货完成并打印面单成功,是否转至已完成'
,
`当前订单验货完成并打印面单成功,是否转至
${
data
?.
replaceShipment
==
1
?
'待称重'
:
'已完成'
}
`,
'提示',
{
confirmButtonText: '确定',
...
...
@@ -876,8 +897,12 @@ const nextStep = async (callback: () => void) => {
callback && callback()
}
}
const currentItem = ref<OrderData>({})
const handleBoxClick = (item: PodMakeOrderData) => {
const { box, data } = item
console.log('data11111111', data)
currentItem.value = item as OrderData
isBillLading.value = !data?.filePath
nextStep(() => {
if (!data) {
...
...
@@ -887,7 +912,7 @@ const handleBoxClick = (item: PodMakeOrderData) => {
boxIndex.value = box || null
boxChange.value = true
productionOrderRef.value.focus()
})
}
, currentItem.value
)
}
const handleClearBox = async () => {
try {
...
...
src/views/order/podCN/SuperPodMakeOrder.vue
View file @
eb72b9a0
...
...
@@ -97,11 +97,11 @@
@
row-click=
"handleRowClick"
>
<
template
#
image=
"{ row }"
>
<div
style=
"display: flex; flex-wrap: nowrap"
>
<div
style=
"display: flex; flex-wrap: nowrap"
>
<div
v-for=
"img in row.productMark!=='normal'?row.previewImgs:[
{url:row.variantImage}]"
v-for=
"img in row.productMark !== 'normal'
? row.previewImgs
: [
{ url: row.variantImage }]"
:key="img"
@click.stop="handleCurrentChange(img.url)"
style="cursor: pointer; margin-right: 5px; flex: 1"
...
...
@@ -156,12 +156,7 @@
@
click=
"podOrderDetailsData && print(podOrderDetailsData, true)"
>
手动打印
</ElButton
>
<ElButton
type=
"primary"
@
click=
"printNormal"
>
普货拣货
</ElButton
>
<ElButton
type=
"primary"
@
click=
"printNormal"
>
普货拣货
</ElButton>
<ElButton
type=
"success"
@
click=
"handlePrintFinish"
>
打单完成
</ElButton
>
...
...
@@ -328,6 +323,7 @@ watch(visible, async (value: boolean) => {
if
(
value
)
{
podOrderDetailsData
.
value
=
{}
currentCode
=
''
currentItem
.
value
=
{}
if
(
userStore
.
user
?.
factory
.
id
)
{
try
{
await
socket
.
init
(
...
...
@@ -350,6 +346,7 @@ watch(visible, async (value: boolean) => {
initPrintDevice
()
const
locaclPrinter
=
localStorage
.
getItem
(
'sheetPrinter'
)
if
(
locaclPrinter
)
sheetPrinter
.
value
=
JSON
.
parse
(
locaclPrinter
)
emit
(
'set-printer'
,
sheetPrinter
.
value
)
}
else
{
if
(
userStore
.
user
?.
factory
.
id
)
{
socket
.
send
({
...
...
@@ -365,6 +362,9 @@ watch(boxIndex, (value: number | null) => {
const
bool
=
!
boxChange
.
value
boxChange
.
value
=
false
console
.
log
(
'boxChange'
,
bool
,
value
)
const
item
=
podBoxList
.
value
?.
find
((
item
)
=>
item
.
box
===
value
)
currentItem
.
value
=
item
?.
data
as
OrderData
renderItemBox
(
bool
)
}
})
...
...
@@ -374,6 +374,8 @@ watch(
if
(
value
)
{
const
item
=
value
.
find
((
item
)
=>
item
.
box
===
podBoxIndex
.
value
)
console
.
log
(
'podBoxList'
,
value
,
podBoxIndex
.
value
,
item
)
currentItem
.
value
=
item
?.
data
as
OrderData
if
(
item
?.
data
)
{
renderItemBox
(
true
)
}
else
{
...
...
@@ -486,8 +488,8 @@ const messageChange = (data: WebSocketMessage) => {
}
const
printNormal
=
async
()
=>
{
const
arr
:
(
number
|
undefined
)[]
=
[]
;
(
podBoxList
.
value
||
[]).
forEach
((
item
:
PodMakeOrderData
)
=>
{
const
arr
:
(
number
|
undefined
)[]
=
[]
;
(
podBoxList
.
value
||
[]).
forEach
((
item
:
PodMakeOrderData
)
=>
{
if
(
item
.
data
)
{
if
(
item
.
data
.
productList
&&
item
.
data
.
productList
.
length
>
0
)
{
const
flag
=
item
.
data
.
productList
.
some
((
item1
)
=>
{
...
...
@@ -659,8 +661,8 @@ const initOrderDetailBox = async () => {
ElMessage
.
warning
(
res
.
message
)
return
}
res
.
data
.
forEach
(
r
=>
{
r
.
data
?.
productList
?.
forEach
(
d
=>
{
res
.
data
.
forEach
(
(
r
)
=>
{
r
.
data
?.
productList
?.
forEach
(
(
d
)
=>
{
if
(
d
.
productMark
===
'normal'
)
{
d
.
previewImgs
=
[{
url
:
d
.
variantImage
||
''
}]
}
else
{
...
...
@@ -764,14 +766,14 @@ const handleOpened = () => {
const
handleClose
=
(
done
:
()
=>
void
)
=>
{
nextStep
(()
=>
{
done
()
})
}
,
currentItem
.
value
)
}
const
onClose
=
()
=>
{
// orderStore.clearPodBox()
emit
(
'refresh'
)
}
// 下一步
const
nextStep
=
async
(
callback
:
()
=>
void
)
=>
{
const
nextStep
=
async
(
callback
:
()
=>
void
,
data
?:
OrderData
)
=>
{
const
everyPicked
=
podOrderDetailsData
.
value
?.
productList
?.
every
(
(
item
)
=>
item
.
count
===
item
.
purchaseNumber
,
)
...
...
@@ -782,7 +784,9 @@ const nextStep = async (callback: () => void) => {
)
{
try
{
await
ElMessageBox
.
alert
(
'当前订单验货完成并打印面单成功,是否转至已完成'
,
`当前订单验货完成并打印面单成功,是否转至
${
data
?.
replaceShipment
==
0
?
'已完成'
:
'待称重'
}
`,
'提示',
{
confirmButtonText: '确定',
...
...
@@ -800,9 +804,13 @@ const nextStep = async (callback: () => void) => {
callback && callback()
}
}
const currentItem = ref<OrderData>({})
const handleBoxClick = (item: PodMakeOrderData) => {
const { box, data } = item
isBillLading.value = !data?.filePath
currentItem.value = data as OrderData
nextStep(() => {
if (!data) {
ElMessage.warning('暂无数据')
...
...
@@ -811,7 +819,7 @@ const handleBoxClick = (item: PodMakeOrderData) => {
boxIndex.value = box || null
boxChange.value = true
productionOrderRef.value.focus()
})
}
, currentItem.value
)
}
const handleClearBox = async () => {
try {
...
...
@@ -920,8 +928,9 @@ const clearAllBox = async () => {
}
const handleRowClick = (row: ProductList) => {
console.log(907, row)
const
previewImages
=
row
.
productMark
!==
'normal'
?
row
.
previewImgs
:[{
url
:
row
.
variantImage
}]
coverImage
.
value
=
previewImages
?.[
0
]?.
url
||
''
const previewImages =
row.productMark !== 'normal' ? row.previewImgs : [{ url: row.variantImage }]
coverImage.value = previewImages?.[0]?.url || ''
productionOrderRef.value.focus()
}
const handleCurrentChange = (url: string) => {
...
...
src/views/order/podCN/components/WeightDialog.vue
0 → 100644
View file @
eb72b9a0
<
template
>
<div>
<el-dialog
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
title=
"称重分拣"
:before-close=
"handleClose"
v-model=
"isweight"
width=
"1200px"
>
<div
style=
"
display: flex;
justify-content: space-between;
margin-bottom: 10px;
gap: 10px;
"
>
<el-select
style=
"width: 100px; height: 100%; margin-right: 5px"
v-model=
"selectType"
placeholder=
""
>
<el-option
label=
"跟踪号"
value=
"trackingNumber"
></el-option>
<el-option
label=
"店铺单号"
value=
"shopNumber"
></el-option>
</el-select>
<input
class=
"inputWeight"
@
keyup
.
enter=
"weightChange"
style=
"flex: 1; border: 3px solid blue"
ref=
"weighInput"
:placeholder=
"
weight.weightInput
? selectType === 'trackingNumber'
? '请输入跟踪号'
: '请输入店铺单号'
: '请输入重量'
"
v-model
.
lazy=
"weightText"
/>
<el-select
style=
"flex: 1"
v-model=
"logisticsCompanyCode"
placeholder=
"物流公司"
filterable
clearable
>
<el-option
v-for=
"(item, index) in allCodelist"
:key=
"index"
:label=
"item.basicsName"
:value=
"item.code"
></el-option>
</el-select>
<el-button
type=
"primary"
@
click=
"weightChange"
>
查询
</el-button>
</div>
<div>
<CustomizeTable
ref=
"tableRef"
border
:isShowCheckBox=
"false"
v-model=
"tableData"
height=
"400px"
:config=
"tableConfig"
align=
"center"
:row-config=
"
{ isCurrent: true }"
>
</CustomizeTable>
</div>
<div
class=
"statistics"
style=
"display: flex; margin-top: 10px"
>
<div
class=
"number"
>
<span>
数量
</span>
<span
style=
"color: red"
>
{{
tableData
.
length
}}
</span>
</div>
<div
class=
"warehouse-weight"
style=
"margin-left: 10px"
>
<span>
出库总重量:
</span>
<span
style=
"color: red"
>
{{
warehouseWeightTotal
()
||
0
}}
(g)
</span>
</div>
</div>
<template
#
footer
>
<div
style=
"display: flex; justify-content: center"
>
<el-button
@
click=
"handleClose()"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"weightGet"
>
确定
</el-button>
</div>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
lang=
"tsx"
>
interface
IpodCnWeighingParams
{
id
?:
string
outWarehouseWeight
?:
string
weight
?:
string
trackingNumber
?:
string
shopNumber
?:
string
platform
?:
string
logisticsCompanyName
?:
string
logisticsCompanyId
?:
string
wgap
?:
number
|
string
}
interface
ILogisticsList
{
code
:
string
basicsName
:
string
apiData
:
unknown
}
import
BigNumber
from
'bignumber.js'
import
weight
from
'../components/weigh.js'
import
{
listByNoApi
,
orderWeighingApi
,
allErpCodeListApi
,
}
from
'@/api/podCnOrder'
// import { logisticsCompanyAllCodelist } from '@/api/logistics.ts'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
{
TableColumn
}
from
'@/components/VxeTable'
const
tableData
=
ref
<
IpodCnWeighingParams
[]
>
([])
const
isweight
=
ref
(
false
)
const
selectType
=
ref
(
'trackingNumber'
)
const
logisticsCompanyCode
=
ref
(
''
)
const
weighInput
=
ref
()
const
weightText
=
ref
(
''
)
const
allCodelist
=
ref
<
ILogisticsList
[]
>
([])
const
tableRef
=
ref
()
const
tableConfig
=
ref
<
TableColumn
[]
>
([
{
prop
:
'trackingNumber'
,
label
:
'跟踪号'
,
attrs
:
{
minWidth
:
120
,
},
},
{
prop
:
'shopNumber'
,
label
:
'店铺单号'
,
attrs
:
{
minWidth
:
120
,
},
},
{
prop
:
'platform'
,
label
:
'销售平台'
,
attrs
:
{
width
:
120
,
},
},
{
prop
:
'logisticsCompanyName'
,
label
:
'物流公司'
,
attrs
:
{
width
:
120
,
},
},
{
prop
:
'weight'
,
label
:
'系统重量(g)'
,
attrs
:
{
width
:
100
,
},
},
{
prop
:
'outWarehouseWeight'
,
label
:
'出库重量(g)'
,
attrs
:
{
width
:
100
,
},
},
{
prop
:
'wgap'
,
label
:
'重量差(g)'
,
attrs
:
{
width
:
100
,
},
},
{
prop
:
'opeare'
,
label
:
'操作'
,
attrs
:
{
align
:
'center'
,
width
:
80
,
},
render
:
{
default
:
({
row
}:
{
row
:
IpodCnWeighingParams
})
=>
(
<
div
>
<
el
-
button
type
=
"danger"
onclick
=
{()
=>
deleteFn
(
row
)}
>
删除
<
/el-button
>
<
/div
>
),
},
},
])
const
emits
=
defineEmits
<
{
(
e
:
'updateList'
):
void
}
>
()
const
getlogisticsCompanyAllCodelist
=
async
()
=>
{
try
{
const
res
=
await
allErpCodeListApi
()
if
(
res
.
code
!==
200
)
return
allCodelist
.
value
=
res
.
data
}
catch
(
e
)
{
console
.
error
(
e
)
}
}
const
warehouseWeightTotal
=
():
number
=>
{
if
(
!
tableData
.
value
)
return
0
return
Number
(
tableData
.
value
.
reduce
((
prev
:
BigNumber
,
cur
:
IpodCnWeighingParams
)
=>
{
const
weight
=
new
BigNumber
(
cur
.
outWarehouseWeight
||
0
)
return
prev
.
plus
(
weight
)
},
new
BigNumber
(
0
))
.
toFixed
(
2
),
// 保留两位小数
)
}
const
handleClose
=
()
=>
{
isweight
.
value
=
false
}
const
weightChange
=
async
()
=>
{
const
noValue
=
weightText
.
value
if
(
!
noValue
)
return
weight
.
playAudio
(
'weight_search_error'
)
if
(
weight
.
weightInput
)
{
if
(
noValue
.
length
<
7
)
return
weight
.
playAudio
(
'weight_search_error'
,
`没有该
${
selectType
.
value
===
'trackingNumber'
?
'跟踪号'
:
'店铺单号'
}
相关的订单`
,
)
}
weightText
.
value
=
''
console
.
log
(
343
,
weight
.
weightInput
)
const
loading
=
ElLoading
.
service
({
fullscreen
:
true
,
text
:
'操作中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
try
{
const
params
:
{
type
:
string
no
:
string
logisticsCompanyCode
?:
string
}
=
{
type
:
selectType
.
value
,
no
:
noValue
,
}
if
(
logisticsCompanyCode
.
value
)
params
.
logisticsCompanyCode
=
logisticsCompanyCode
.
value
weight
.
check
(
noValue
,
listByNoApi
,
params
,
(
arr
)
=>
{
tableData
.
value
=
[...
arr
]
if
(
!
(
noValue
.
length
<
7
))
{
tableData
.
value
.
forEach
((
el
)
=>
{
if
(
el
.
trackingNumber
===
noValue
||
el
.
shopNumber
===
noValue
)
{
console
.
log
(
1111
,
el
)
tableRef
.
value
?.
selectRowEvent
(
el
)
}
})
}
console
.
log
(
284
,
arr
)
},
selectType
.
value
,
)
weighInput
.
value
?.
focus
()
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
close
()
}
console
.
log
(
'weightChange'
)
}
const
weightGet
=
async
()
=>
{
if
(
tableData
.
value
.
length
<
1
)
{
ElMessage
.
warning
(
'当前没有可提交的数据!'
)
return
}
for
(
const
iterator
of
tableData
.
value
)
{
if
(
!
iterator
.
outWarehouseWeight
)
{
ElMessage
.
warning
(
'跟踪号:'
+
iterator
.
trackingNumber
+
'的出库重量为空'
)
return
}
}
const
loading
=
ElLoading
.
service
({
fullscreen
:
true
,
text
:
'操作中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
try
{
await
orderWeighingApi
({
podCnWeighingParams
:
tableData
.
value
})
ElMessage
.
success
(
'保存称重分拣成功'
)
handleClose
()
emits
(
'updateList'
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
close
()
}
}
const
open
=
()
=>
{
isweight
.
value
=
true
weight
.
clear
()
tableData
.
value
=
[]
selectType
.
value
=
'trackingNumber'
logisticsCompanyCode
.
value
=
''
weightText
.
value
=
''
getlogisticsCompanyAllCodelist
()
}
const
deleteFn
=
(
row
:
IpodCnWeighingParams
)
=>
{
tableData
.
value
=
tableData
.
value
.
filter
((
el
)
=>
el
.
id
!==
row
.
id
)
weight
.
updatedList
(
tableData
.
value
)
}
defineExpose
({
open
,
})
</
script
>
<
style
scoped
></
style
>
src/views/order/podCN/components/weigh.ts
0 → 100644
View file @
eb72b9a0
// Lock 基类
class
Lock
{
public
isLock
:
boolean
constructor
()
{
this
.
isLock
=
false
}
lock
():
void
{
this
.
isLock
=
true
}
unlock
():
void
{
this
.
isLock
=
false
}
}
import
{
ElMessage
}
from
'element-plus'
import
BigNumber
from
'bignumber.js'
// 定义数据类型
interface
WeighItem
{
id
?:
string
outWarehouseWeight
?:
string
status
?:
string
trackingNumber
?:
string
shopNumber
?:
string
platform
?:
string
logisticsCompanyName
?:
string
logisticsCompanyCode
?:
string
logisticsCompanyId
?:
string
wgap
?:
number
|
string
weight
?:
string
}
interface
SearchItem
{
type
:
string
no
:
string
logisticsCompanyCode
?:
string
}
interface
Data
{
data
:
WeighItem
[]
code
:
number
}
type
AudioKey
=
|
'weight_warning'
|
'weight_success'
|
'weight_repeat'
|
'weight_search_error'
|
'weight_search_success'
type
AudioFiles
=
Record
<
AudioKey
,
string
>
// API 响应类型
class
Weigh
extends
Lock
{
public
weightInput
:
boolean
public
list
:
WeighItem
[]
public
selectType
:
string
private
audios
:
AudioFiles
private
audioElements
:
Map
<
AudioKey
,
HTMLAudioElement
>
constructor
()
{
super
()
this
.
weightInput
=
true
this
.
selectType
=
'trackingNumber'
this
.
list
=
[]
this
.
audios
=
{
weight_warning
:
new
URL
(
'@/assets/audio/weight_warning.mp3'
,
import
.
meta
.
url
,
).
href
,
weight_success
:
new
URL
(
'@/assets/audio/weight_success.mp3'
,
import
.
meta
.
url
,
).
href
,
weight_repeat
:
new
URL
(
'@/assets/audio/weight_repeat.mp3'
,
import
.
meta
.
url
,
).
href
,
weight_search_error
:
new
URL
(
'@/assets/audio/weight_search_error.mp3'
,
import
.
meta
.
url
,
).
href
,
weight_search_success
:
new
URL
(
'@/assets/audio/weight_search_success.mp3'
,
import
.
meta
.
url
,
).
href
,
}
this
.
audioElements
=
new
Map
()
this
.
preloadAudios
()
}
// 预加载音频文件
private
preloadAudios
():
void
{
Object
.
entries
(
this
.
audios
).
forEach
(([
key
,
src
])
=>
{
const
audio
=
new
Audio
()
audio
.
src
=
src
audio
.
preload
=
'auto'
this
.
audioElements
.
set
(
key
as
AudioKey
,
audio
)
})
}
clear
():
void
{
this
.
list
=
[]
this
.
weightInput
=
true
this
.
selectType
=
'trackingNumber'
}
updatedList
(
data
:
WeighItem
[])
{
this
.
weightInput
=
true
this
.
list
=
[...
data
]
}
// 去重逻辑优化
private
deduplicate
(
value
:
string
,
callback
?:
(
list
:
WeighItem
[])
=>
void
,
):
boolean
{
const
existingIndex
=
this
.
list
.
findIndex
(
(
item
)
=>
item
.
trackingNumber
===
value
,
)
if
(
existingIndex
!==
-
1
)
{
const
[
existingItem
]
=
this
.
list
.
splice
(
existingIndex
,
1
)
this
.
list
.
unshift
(
existingItem
)
callback
?.(
this
.
list
)
this
.
playAudio
(
'weight_repeat'
)
return
true
}
return
false
}
check
(
value
:
string
,
apiCall
:
(
params
:
SearchItem
)
=>
Promise
<
Data
>
,
params
:
SearchItem
,
callback
?:
(
list
:
WeighItem
[])
=>
void
,
type
?:
string
,
):
void
{
this
.
selectType
=
type
as
string
// 空值检查
if
(
!
value
?.
trim
())
{
this
.
playAudio
(
'weight_warning'
)
return
}
// 防止重复提交
if
(
this
.
isLock
)
return
this
.
lock
()
try
{
// 判断输入类型并处理
if
(
this
.
isWeightInput
(
value
))
{
this
.
processWeightInput
(
value
,
callback
)
}
else
{
this
.
processTrackingNumberInput
(
value
,
apiCall
,
params
,
callback
)
}
}
catch
(
error
)
{
console
.
error
(
'称重处理错误:'
,
error
)
this
.
playAudio
(
'weight_search_error'
)
}
finally
{
this
.
unlock
()
}
}
private
isWeightInput
(
value
:
string
):
boolean
{
return
value
.
length
<
7
}
private
processWeightInput
(
value
:
string
,
callback
?:
(
list
:
WeighItem
[])
=>
void
,
):
void
{
// 验证数字格式
if
(
isNaN
(
Number
(
value
))
||
Number
(
value
)
<=
0
)
{
this
.
playAudio
(
'weight_warning'
,
'请录入正确的重量'
)
return
}
console
.
log
(
'currentItem'
,
this
.
list
)
if
(
!
this
.
list
.
length
)
{
this
.
playAudio
(
'weight_warning'
,
`请录入
${
this
.
selectType
===
'trackingNumber'
?
'跟踪号'
:
'店铺单号'
}
`
,
)
return
}
// 检查是否已录入重量
if
(
!
this
.
hasPendingWeights
())
{
this
.
playAudio
(
'weight_warning'
,
`请录入
${
this
.
selectType
===
'trackingNumber'
?
'跟踪号'
:
'店铺单号'
}
`
,
)
return
}
this
.
list
=
this
.
list
.
map
((
el
)
=>
{
if
(
!
el
.
outWarehouseWeight
)
{
// 确保输入值也是BigNumber处理过的
const
valueNum
=
Number
(
value
)
||
0
const
weightNum
=
Number
(
el
.
weight
)
||
0
const
wgap
=
new
BigNumber
(
valueNum
)
.
minus
(
weightNum
)
.
abs
()
.
decimalPlaces
(
2
,
BigNumber
.
ROUND_HALF_UP
)
// 明确指定四舍五入规则
.
toNumber
()
return
{
...
el
,
outWarehouseWeight
:
value
,
wgap
:
wgap
,
}
}
return
el
})
// 更新重量信息
callback
?.(
this
.
list
)
this
.
weightInput
=
true
this
.
playAudio
(
'weight_success'
)
}
private
async
processTrackingNumberInput
(
value
:
string
,
apiCall
:
(
params
:
SearchItem
)
=>
Promise
<
Data
>
,
params
:
SearchItem
,
callback
?:
(
list
:
WeighItem
[])
=>
void
,
):
Promise
<
void
>
{
// 检查重量录入状态
if
(
!
this
.
weightInput
)
{
this
.
playAudio
(
'weight_warning'
,
'请录入重量'
)
return
}
// 去重检查
if
(
this
.
deduplicate
(
value
,
callback
))
{
return
}
try
{
const
response
=
await
apiCall
(
params
)
console
.
log
(
211
,
response
)
const
{
data
}
=
response
if
(
!
data
.
length
)
{
this
.
playAudio
(
'weight_search_error'
,
'查询失败'
)
return
}
// const waitWeighingList = data.filter(
// (el) => el.status === 'WAIT_WEIGHING',
// )
// if (waitWeighingList.length === 0) {
// this.playAudio(
// 'weight_search_error',
// `必须是待称重状态的订单下的${
// this.selectType === 'trackingNumber' ? '跟踪号' : '店铺单号'
// }才能使用`,
// )
// return
// }
if
(
this
.
list
?.
length
)
{
const
firstLogisticsCode
=
data
[
0
]?.
logisticsCompanyCode
const
hasDifferentLogistics
=
this
.
list
.
some
(
(
el
)
=>
// 如果两个代码不都是undefined,并且它们不相等
!
(
el
.
logisticsCompanyCode
===
undefined
&&
firstLogisticsCode
===
undefined
)
&&
el
.
logisticsCompanyCode
!==
firstLogisticsCode
,
)
if
(
hasDifferentLogistics
)
{
this
.
playAudio
(
'weight_search_error'
,
'当前查询的订单不属于所选择的物流公司,请核实后再试'
,
)
return
}
}
// 最终去重检查
if
(
this
.
deduplicate
(
(
data
[
0
]
as
WeighItem
).
trackingNumber
as
string
,
callback
,
)
)
{
return
}
// 添加新项目
this
.
addNewItem
(
data
,
callback
)
}
catch
(
error
)
{
console
.
error
(
'跟踪号查询错误:'
,
error
)
// this.playAudio('weight_search_error')
}
}
private
addNewItem
(
data
:
WeighItem
[],
callback
?:
(
list
:
WeighItem
[])
=>
void
,
):
void
{
const
newArr
=
data
.
map
((
el
)
=>
{
return
{
...
el
,
outWarehouseWeight
:
''
,
wgap
:
''
,
}
})
this
.
list
=
[...
newArr
,
...
this
.
list
]
this
.
weightInput
=
false
callback
?.(
this
.
list
)
this
.
playAudio
(
'weight_search_success'
)
}
playAudio
(
key
:
AudioKey
,
message
?:
string
):
void
{
const
messageMap
:
Record
<
AudioKey
,
string
>
=
{
weight_warning
:
`请录入
${
this
.
selectType
===
'trackingNumber'
?
'跟踪号'
:
'店铺单号'
}
或重量`
,
weight_success
:
''
,
weight_repeat
:
'重复录入'
,
weight_search_error
:
`请录入
${
this
.
selectType
===
'trackingNumber'
?
'跟踪号'
:
'店铺单号'
}
或重量`
,
weight_search_success
:
''
,
}
const
displayMessage
=
message
||
messageMap
[
key
]
if
(
displayMessage
)
{
console
.
log
(
displayMessage
)
ElMessage
.
warning
(
displayMessage
)
}
// 使用预加载的音频元素
const
audio
=
this
.
audioElements
.
get
(
key
)
if
(
audio
)
{
audio
.
currentTime
=
0
// 重置播放位置
audio
.
play
().
catch
((
error
)
=>
{
console
.
warn
(
`音频播放失败:
${
key
}
`
,
error
)
})
}
}
hasPendingWeights
():
boolean
{
return
this
.
list
.
some
((
item
)
=>
!
item
.
outWarehouseWeight
)
}
getTotalWeight
():
number
{
return
this
.
list
.
reduce
((
total
,
item
)
=>
{
return
(
total
+
(
item
.
outWarehouseWeight
?
Number
(
item
.
outWarehouseWeight
)
:
0
)
)
},
0
)
}
}
export
default
new
Weigh
()
src/views/order/podCN/index.vue
View file @
eb72b9a0
...
...
@@ -10,7 +10,108 @@
label-position=
"right"
label-width=
"70px"
>
<ElFormItem
label=
"仓库"
>
<!-- 批量下载 -->
<ElFormItem
label=
"创建时间"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<el-date-picker
v-model=
"timeRange"
:teleported=
"false"
:default-time=
"[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"datetimerange"
style=
"width: 280px"
:shortcuts=
"pickerOptions.shortcuts"
start-placeholder=
"开始时间"
end-placeholder=
"结束时间"
clearable
>
</el-date-picker>
</ElFormItem>
<ElFormItem
label=
"创建人"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.employeeId"
placeholder=
"请选择"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in employeeList"
:key=
"index"
:value=
"item.id"
:label=
"item.account"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"工艺类型"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.craftType"
placeholder=
"请选择"
clearable
filterable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in processType"
:key=
"index"
:value=
"item.value"
:label=
"item.label"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"下载状态"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.downloadStatus"
placeholder=
"下载状态"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['未下载', '已下载']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"排版状态"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.syntheticStatus"
placeholder=
"排版状态"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['否', '是']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"自动排版"
v-if=
"status === 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.automaticComposing"
placeholder=
"自动排版"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['否', '是']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"仓库"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.warehouseId"
clearable
...
...
@@ -26,7 +127,7 @@
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"平台"
>
<ElFormItem
label=
"平台"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.platform"
value-key=
""
...
...
@@ -52,7 +153,7 @@
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"工艺"
>
<ElFormItem
label=
"工艺"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<LogisticsWaySelect
v-model=
"searchForm.craftCode"
:company-list=
"craftList"
...
...
@@ -61,7 +162,7 @@
start-placeholder=
"请选择工艺名称"
></LogisticsWaySelect>
</ElFormItem>
<ElFormItem
label=
"库存SKU"
>
<ElFormItem
label=
"库存SKU"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElInput
v-model
.
trim=
"searchForm.thirdSkuCode"
placeholder=
"库存SKU"
...
...
@@ -69,7 +170,7 @@
style=
"width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem
label=
"款号"
>
<ElFormItem
label=
"款号"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElInput
v-model
.
trim=
"searchForm.supplierProductNo"
placeholder=
"款号"
...
...
@@ -85,7 +186,7 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"生产单号"
>
<ElFormItem
label=
"生产单号"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElInput
v-model
.
trim=
"searchForm.factorySubOrderNumber"
placeholder=
"生产单号"
...
...
@@ -93,7 +194,7 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"店铺单号"
>
<ElFormItem
label=
"店铺单号"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElInput
v-model
.
trim=
"searchForm.shopNumber"
placeholder=
"店铺单号"
...
...
@@ -101,7 +202,7 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"尺码类型"
>
<ElFormItem
label=
"尺码类型"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElSelect
v-model=
"searchForm.sizeType"
clearable
...
...
@@ -117,7 +218,7 @@
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"排序"
>
<ElFormItem
label=
"排序"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<el-select
v-model=
"searchForm.order"
clearable
...
...
@@ -128,7 +229,7 @@
<el-option
value=
"desc"
label=
"倒序"
></el-option>
</el-select>
</ElFormItem>
<ElFormItem
label=
"类型"
>
<ElFormItem
label=
"类型"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<el-radio-group
v-model=
"searchForm.customizedQuantity"
@
click
.
stop=
"(e: Event) => handleRadioGroupClick(e)"
...
...
@@ -137,7 +238,7 @@
<el-radio-button
value=
"multiple"
>
多面
</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem
label=
"数量"
>
<ElFormItem
label=
"数量"
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<el-radio-group
v-model=
"searchForm.multi"
@
click
.
stop=
"(e: Event) => handleMultiRadioGroupClick(e)"
...
...
@@ -146,7 +247,7 @@
<el-radio-button
:value=
"true"
>
多件
</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem>
<ElFormItem
v-if=
"status !== 'BATCH_DOWNLOAD'"
>
<ElPopover
placement=
"bottom"
width=
"600"
trigger=
"click"
>
<ElForm
ref=
"searchFormPopoverRef"
...
...
@@ -381,6 +482,43 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"自有物流公司"
>
<ElSelect
v-model=
"searchForm.logisticsCompanyCode"
placeholder=
"请选择"
clearable
filterable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in allCodelist"
:key=
"index"
:value=
"item.code"
:label=
"item.basicsName"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
v-if=
"status !== 'CANCEL' && status !== 'INTERCEPTED'"
label=
"拦截订单"
>
<ElSelect
v-model=
"searchForm.blocking"
placeholder=
"请选择"
clearable
filterable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(_, index) in ['否', '是']"
:key=
"index"
:value=
"!!index"
:label=
"index === 0 ? '否' : '是'"
></ElOption>
</ElSelect>
</ElFormItem>
</ElForm>
<template
#
reference
>
<el-button
type=
"warning"
@
click=
"searchVisible = !searchVisible"
>
...
...
@@ -662,7 +800,7 @@
<ElButton
type=
"success"
@
click=
"toBePicking"
>
转至生产
</ElButton>
</span>
<span
v-if=
"status === 'TO_BE_ARRANGE'"
class=
"item"
>
<ElButton
type=
"warning"
@
click=
"showArrange(2)"
>
排单
完成
</ElButton>
<ElButton
type=
"warning"
@
click=
"showArrange(2)"
>
排单
</ElButton>
</span>
<span
v-if=
"status !== 'BATCH_DOWNLOAD' && status !== 'WAIT_SHIPMENT'"
...
...
@@ -804,6 +942,11 @@
>
批量删除
</ElButton
>
</span>
<span
v-if=
"status === 'WAIT_WEIGHING'"
class=
"item"
>
<ElButton
type=
"success"
@
click=
"weightDialogRef.open()"
>
称重分拣
</ElButton
>
</span>
<span
v-if=
"status === 'WAIT_SHIPMENT'"
class=
"item"
>
<ElButton
type=
"warning"
@
click=
"showPrintSku"
>
打印库存sku标签
</ElButton
...
...
@@ -2548,8 +2691,18 @@
"
><
/ChangeWayDialog
>
<
print
-
warehouse
-
sku
-
tag
ref
=
"printWarehouseSkuDialogRef"
/>
<
weight
-
dialog
ref
=
"weightDialogRef"
@
update
-
list
=
"
() => {
search()
loadTabData()
}
"
/>
<
/template
>
<
script
setup
lang
=
"ts"
>
<
script
setup
lang
=
"tsx"
>
import
WeightDialog
from
'./components/WeightDialog.vue'
import
{
getUserMarkList
}
from
'@/api/common'
import
LogisticsWaySelect
from
'../../logistics/components/LogisticsWaySelect.tsx'
import
PrintWarehouseSkuTag
from
'../components/printWarehouseSkuTag.vue'
...
...
@@ -2615,8 +2768,11 @@ import {
getCustomTagListCnApi
,
printNormalPdf
,
changeLogisticsApi
,
getEmployeeListApi
,
allErpCodeListApi
,
}
from
'@/api/podCnOrder'
// import
{
logisticsCompanyAllCodelist
}
from
'@/api/logistics.ts'
import
{
BaseRespData
}
from
'@/types/api'
import
ChangeWayDialog
from
'./components/ChangeWayDialog.vue'
import
UpdateAddress
from
'./components/updateAddress.vue'
...
...
@@ -2688,7 +2844,7 @@ const isSuperFactory: boolean = userStore.user?.factory.dropShipping || false
const
tabsNav
=
ref
<
Tab
[]
>
()
const
isAuto
=
ref
(
true
)
const
printWarehouseSkuDialogRef
=
ref
()
const
weightDialogRef
=
ref
()
const
calculatedPrice
=
(
item
:
ProductList
)
=>
{
const
templatePrice
=
new
BigNumber
(
item
.
templatePrice
||
0
)
const
craftPrice
=
new
BigNumber
(
item
.
craftPrice
||
0
)
...
...
@@ -2740,6 +2896,7 @@ const sourceList = [
}
,
]
const
sizes
=
[
'FS'
,
'XS'
,
'S'
,
'M'
,
'L'
,
'XL'
,
'XXL'
,
'3XL'
,
'4XL'
,
'5XL'
]
const
employeeList
=
ref
<
{
account
:
string
;
id
:
number
}
[]
>
([])
const
exportData
=
()
=>
{
exportVisible
.
value
=
true
...
...
@@ -3491,6 +3648,37 @@ const tableColumns = computed(() => {
align
:
'center'
,
}
,
{
label
:
'工艺类型'
,
width
:
150
,
prop
:
'craftType'
,
align
:
'center'
,
render
:
(
item
:
ProductList
)
=>
{
if
(
!
item
.
craftType
)
{
return
(
<
div
>
<
span
>-<
/span
>
<
/div
>
)
}
// 分割字符串并查找对应的 label
const
labels
=
item
.
craftType
.
split
(
','
)
.
map
((
type
)
=>
type
.
trim
())
.
map
(
(
type
)
=>
processType
.
value
.
find
((
e
)
=>
e
.
value
===
type
)?.
label
||
type
,
)
.
filter
(
Boolean
)
return
(
<
div
>
<
span
>
{
labels
.
join
(
','
)
}
<
/span
>
<
/div
>
)
}
,
}
,
{
label
:
'失败原因'
,
minWidth
:
250
,
prop
:
'failReason'
,
...
...
@@ -3645,6 +3833,13 @@ const asyncOrderAddress = async () => {
}
}
const
getEmployeeList
=
async
()
=>
{
const
{
data
}
=
await
getEmployeeListApi
()
employeeList
.
value
=
data
}
getEmployeeList
()
const
changeTab
=
(
item
:
Tab
)
=>
{
status
.
value
=
item
.
status
||
''
localStorage
.
setItem
(
'podCnStatus'
,
item
.
status
as
string
)
...
...
@@ -3735,7 +3930,13 @@ const {
baseparams
.
tagsIdArr
&&
delete
baseparams
.
tagsIdArr
// 批量下载
if
(
status
.
value
===
'BATCH_DOWNLOAD'
)
{
return
batchDownloadApi
(
page
,
pageSize
).
then
((
res
)
=>
{
return
batchDownloadApi
(
{
...
baseparams
,
}
,
page
,
pageSize
,
).
then
((
res
)
=>
{
return
res
.
data
}
)
as
never
}
else
if
(
...
...
@@ -4496,7 +4697,7 @@ const showArrange = async (type: number, data?: PodCnOrderListData) => {
if
(
bool
)
{
try
{
await
ElMessageBox
.
confirm
(
'选中排单的生产单存在多个工艺, 是否继续排单?'
,
'选中排单的生产单存在多个工艺
类型
, 是否继续排单?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
...
...
@@ -4520,10 +4721,10 @@ function hasDifferentCraftCodeWithSet(items: ProductList[]) {
const
seen
=
new
Set
()
for
(
const
item
of
items
)
{
if
(
seen
.
has
(
item
.
craft
Cod
e
))
{
if
(
seen
.
has
(
item
.
craft
Typ
e
))
{
if
(
seen
.
size
>
1
)
return
true
}
else
{
seen
.
add
(
item
.
craft
Cod
e
)
seen
.
add
(
item
.
craft
Typ
e
)
if
(
seen
.
size
>
1
)
return
true
}
}
...
...
@@ -5095,7 +5296,11 @@ const loadWarehouseList = async () => {
console
.
error
(
e
)
}
}
const
processType
=
ref
([
interface
ProcessTypeData
{
label
:
string
value
:
string
}
const
processType
=
ref
<
ProcessTypeData
[]
>
([
{
label
:
'烫画'
,
value
:
'TH'
,
...
...
@@ -5153,6 +5358,22 @@ const getCustomTagList = async () => {
}
}
interface
ILogisticsList
{
code
:
string
basicsName
:
string
apiData
:
unknown
}
const
allCodelist
=
ref
<
ILogisticsList
[]
>
([])
const
getlogisticsCompanyAllCodelist
=
async
()
=>
{
try
{
const
res
=
await
allErpCodeListApi
()
if
(
res
.
code
!==
200
)
return
allCodelist
.
value
=
res
.
data
}
catch
(
e
)
{
console
.
error
(
e
)
}
}
function
tooltipContent
(
arr
:
{
name
:
string
}
[])
{
return
arr
.
map
((
tag
)
=>
tag
.
name
).
join
(
'、'
)
}
...
...
@@ -5249,6 +5470,7 @@ onMounted(() => {
loadWarehouseList
()
getCustomTagList
()
loadCraftList
()
getlogisticsCompanyAllCodelist
()
}
)
const
handleShipmentAreaCommand
=
(
command
:
number
)
=>
{
...
...
src/views/order/podUs/index.vue
View file @
eb72b9a0
...
...
@@ -10,8 +10,122 @@
size=
"default"
inline
>
<!-- 批量下载 -->
<ElFormItem
label=
"创建时间"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<el-date-picker
v-model=
"timeRange"
:teleported=
"false"
:default-time=
"[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"datetimerange"
style=
"width: 280px"
:shortcuts=
"pickerOptions.shortcuts"
start-placeholder=
"开始时间"
end-placeholder=
"结束时间"
clearable
>
</el-date-picker>
</ElFormItem>
<ElFormItem
label=
"创建人"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.employeeId"
placeholder=
"请选择"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in employeeList"
:key=
"index"
:value=
"item.id"
:label=
"item.account"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"工艺类型"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.craftType"
placeholder=
"请选择"
clearable
filterable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in processType"
:key=
"index"
:value=
"item.value"
:label=
"item.label"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"下载状态"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.downloadStatus"
placeholder=
"下载状态"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['未下载', '已下载']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"排版状态"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.syntheticStatus"
placeholder=
"排版状态"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['否', '是']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"自动排版"
v-if=
"
status === 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.automaticComposing"
placeholder=
"自动排版"
clearable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(item, index) in ['否', '是']"
:key=
"index"
:value=
"index"
:label=
"item"
></ElOption>
</ElSelect>
</ElFormItem>
<!--
<div>
-->
<ElFormItem
label=
"仓库"
>
<ElFormItem
label=
"仓库"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.warehouseId"
clearable
...
...
@@ -28,7 +142,9 @@
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"工艺"
>
<ElFormItem
label=
"工艺"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<LogisticsWaySelect
v-model=
"searchForm.craftCode"
:company-list=
"craftList"
...
...
@@ -37,7 +153,9 @@
start-placeholder=
"请选择工艺名称"
></LogisticsWaySelect>
</ElFormItem>
<ElFormItem
label=
"库存SKU"
>
<ElFormItem
label=
"库存SKU"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElInput
v-model
.
trim=
"searchForm.thirdSkuCode"
placeholder=
"库存SKU"
...
...
@@ -45,7 +163,9 @@
style=
"width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem
label=
"款号"
>
<ElFormItem
label=
"款号"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElInput
v-model=
"searchForm.supplierProductNo"
placeholder=
"款号"
...
...
@@ -61,7 +181,9 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"生产单号"
>
<ElFormItem
label=
"生产单号"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElInput
v-model=
"searchForm.factorySubOrderNumber"
placeholder=
"生产单号"
...
...
@@ -69,7 +191,9 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"店铺单号"
>
<ElFormItem
label=
"店铺单号"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElInput
v-model=
"searchForm.shopNumber"
placeholder=
"店铺单号"
...
...
@@ -77,7 +201,9 @@
style=
"width: 150px"
/>
</ElFormItem>
<ElFormItem
label=
"尺码类型"
>
<ElFormItem
label=
"尺码类型"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.sizeType"
clearable
...
...
@@ -93,7 +219,9 @@
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"平台"
>
<ElFormItem
label=
"平台"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElSelect
v-model=
"searchForm.platform"
value-key=
""
...
...
@@ -119,7 +247,9 @@
</ElSelect>
</ElFormItem>
<!--
</div>
-->
<ElFormItem
label=
"类型"
>
<ElFormItem
label=
"类型"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<el-radio-group
v-model=
"searchForm.customizedQuantity"
@
click
.
stop=
"(e: Event) => handleRadioGroupClick(e)"
...
...
@@ -129,7 +259,9 @@
<el-radio-button
label=
"normal"
>
普品
</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem
label=
"数量"
>
<ElFormItem
label=
"数量"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<el-radio-group
v-model=
"searchForm.multi"
@
click
.
stop=
"(e: Event) => handleMultiRadioGroupClick(e)"
...
...
@@ -139,7 +271,9 @@
</el-radio-group>
</ElFormItem>
<ElFormItem>
<ElPopover
placement=
"bottom"
width=
"600"
trigger=
"click"
>
<ElPopover
placement=
"bottom"
width=
"600"
trigger=
"click"
v-if=
"
status !== 'BATCH_DOWNLOAD'
"
>
<ElForm
ref=
"searchFormPopoverRef"
:model=
"searchForm"
...
...
@@ -362,6 +496,26 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
label=
"拦截订单"
v-if=
"status !== 'CANCEL' && status !== 'INTERCEPTED'"
>
<ElSelect
v-model=
"searchForm.blocking"
placeholder=
"请选择"
clearable
filterable
:teleported=
"false"
style=
"width: 150px"
>
<ElOption
v-for=
"(_, index) in ['否', '是']"
:key=
"index"
:value=
"!!index"
:label=
"index === 0 ? '否' : '是'"
></ElOption>
</ElSelect>
</ElFormItem>
</ElForm>
<template
#
reference
>
<el-button
type=
"warning"
@
click=
"searchVisible = !searchVisible"
>
...
...
@@ -684,7 +838,7 @@
</ElFormItem>
<ElFormItem
v-if=
"status === 'TO_BE_ARRANGE'"
>
<span
class=
"item"
>
<ElButton
type=
"warning"
@
click=
"showArrange(2)"
>
排单
完成
</ElButton>
<ElButton
type=
"warning"
@
click=
"showArrange(2)"
>
排单
</ElButton>
</span>
</ElFormItem>
<ElFormItem
...
...
@@ -2910,7 +3064,7 @@
:
uploadList
=
"uploadList"
><
/uploadBox
>
<
/template
>
<
script
setup
lang
=
"ts"
>
<
script
setup
lang
=
"ts
x
"
>
import
LogisticsWaySelect
from
'../../logistics/components/LogisticsWaySelect.tsx'
import
{
getUserMarkList
}
from
'@/api/common'
// import
{
AnyObject
}
from
'@/types/api/warehouse'
...
...
@@ -2990,6 +3144,7 @@ import {
getLogisticsWayApi
,
printNormalPickPdfApi
,
updatePRNDownloadStatus
,
getEmployeeListApi
,
}
from
'@/api/podUsOrder'
import
{
BaseRespData
}
from
'@/types/api'
...
...
@@ -3026,7 +3181,7 @@ import {
CircleCheckFilled
,
}
from
'@element-plus/icons-vue'
import
{
Column
,
ElFormItem
,
ElMessage
}
from
'element-plus'
import
{
computed
,
onMounted
,
ref
,
nextTick
,
reactive
}
from
'vue'
import
{
computed
,
onMounted
,
ref
,
nextTick
,
reactive
}
from
'vue'
import
FastProduction
from
'./FastProduction.vue'
import
{
filePath
}
from
'@/api/axios'
import
PodMakeOrder
from
'./PodMakeOrder.vue'
...
...
@@ -3087,6 +3242,7 @@ const printWarehouseSkuDialogRef = ref()
const
isAuto
=
ref
(
true
)
const
countryList
=
ref
([])
const
logisticsWayList
=
ref
<
{
name
:
string
;
id
:
number
}
[]
>
([])
const
employeeList
=
ref
<
{
account
:
string
;
id
:
number
}
[]
>
([])
const
currentRow
=
ref
<
AddressInfo
>
({
receiverName
:
''
,
receiverPhone
:
''
,
...
...
@@ -3535,6 +3691,36 @@ const handleReComposingDesign = async () => {
typesettingRow
.
value
=
undefined
}
}
interface
ProcessTypeData
{
label
:
string
value
:
string
}
const
processType
=
ref
<
ProcessTypeData
[]
>
([
{
label
:
'烫画'
,
value
:
'TH'
,
}
,
{
label
:
'直喷'
,
value
:
'ZP'
,
}
,
{
label
:
'刺绣'
,
value
:
'CX'
,
}
,
{
label
:
'雕刻'
,
value
:
'DK'
,
}
,
{
label
:
'白胚'
,
value
:
'BP'
,
}
,
{
label
:
'其他'
,
value
:
'QT'
,
}
,
])
const
tableColumns
=
computed
(()
=>
{
let
arr
=
[]
if
(
status
.
value
===
'BATCH_DOWNLOAD'
)
{
...
...
@@ -3570,6 +3756,34 @@ const tableColumns = computed(() => {
prop
:
'employeeAccount'
,
align
:
'center'
,
}
,
{
label
:
'工艺类型'
,
width
:
150
,
prop
:
'craftType'
,
align
:
'center'
,
render
:
(
item
:
ProductList
)
=>
{
if
(
!
item
.
craftType
)
{
return
(
<
div
>
<
span
>-<
/span
>
<
/div
>
)
}
// 分割字符串并查找对应的 label
const
labels
=
item
.
craftType
.
split
(
','
)
.
map
(
type
=>
type
.
trim
())
.
map
(
type
=>
processType
.
value
.
find
(
e
=>
e
.
value
===
type
)?.
label
||
type
)
.
filter
(
Boolean
)
return
(
<
div
>
<
span
>
{
labels
.
join
(
','
)
}
<
/span
>
<
/div
>
)
}
}
,
{
label
:
'创建时间'
,
...
...
@@ -3594,7 +3808,7 @@ const tableColumns = computed(() => {
}
,
{
label
:
'失败原因'
,
minWidth
:
2
5
0
,
minWidth
:
2
0
0
,
prop
:
'failReason'
,
slot
:
'failReason'
,
align
:
'left'
,
...
...
@@ -3918,7 +4132,11 @@ const {
baseparams
.
tagsIdArr
&&
delete
baseparams
.
tagsIdArr
// 批量下载
if
(
status
.
value
===
'BATCH_DOWNLOAD'
)
{
return
batchDownloadApi
(
page
,
pageSize
).
then
((
res
)
=>
{
const
params
=
{
...
baseparams
}
return
batchDownloadApi
(
params
,
page
,
pageSize
).
then
((
res
)
=>
{
return
res
.
data
}
)
as
never
}
else
if
(
...
...
@@ -5023,7 +5241,7 @@ const showArrange = async (type: number, data?: PodUsOrderListData) => {
if
(
bool
)
{
try
{
await
ElMessageBox
.
confirm
(
'选中排单的生产单存在多个工艺, 是否继续排单?'
,
'选中排单的生产单存在多个工艺
类型
, 是否继续排单?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
...
...
@@ -5047,10 +5265,10 @@ function hasDifferentCraftCodeWithSet(items: ProductList[]) {
const
seen
=
new
Set
()
for
(
const
item
of
items
)
{
if
(
seen
.
has
(
item
.
craft
Cod
e
))
{
if
(
seen
.
has
(
item
.
craft
Typ
e
))
{
if
(
seen
.
size
>
1
)
return
true
}
else
{
seen
.
add
(
item
.
craft
Cod
e
)
seen
.
add
(
item
.
craft
Typ
e
)
if
(
seen
.
size
>
1
)
return
true
}
}
...
...
@@ -5877,32 +6095,7 @@ const loadWarehouseList = async () => {
console
.
error
(
e
)
}
}
const
processType
=
ref
([
{
label
:
'烫画'
,
value
:
'TH'
,
}
,
{
label
:
'直喷'
,
value
:
'ZP'
,
}
,
{
label
:
'刺绣'
,
value
:
'CX'
,
}
,
{
label
:
'雕刻'
,
value
:
'DK'
,
}
,
{
label
:
'白胚'
,
value
:
'BP'
,
}
,
{
label
:
'其他'
,
value
:
'QT'
,
}
,
])
// 获取工艺列表
const
craftList
=
ref
<
IAllList
[]
>
([])
...
...
@@ -6476,8 +6669,15 @@ const getLogisticsWay = async () => {
logisticsWayList
.
value
=
data
}
const
getEmployeeList
=
async
()
=>
{
const
{
data
}
=
await
getEmployeeListApi
()
employeeList
.
value
=
data
}
getPermission
()
getLogisticsWay
()
getEmployeeList
()
const
globalProperties
=
getCurrentInstance
()?.
appContext
.
config
.
globalProperties
// 获取全局挂载
...
...
src/views/order/podUsSchedulingRules/index.vue
View file @
eb72b9a0
...
...
@@ -14,7 +14,8 @@
<div
class=
"box"
>
所有生产单按
{{
getLabels
(
item
.
groupField
)
}}
进行自动排单
</div>
<div
class=
"box"
>
批次数量:
{{
item
.
arrangeMax
}}
</div>
<div
class=
"box"
>
烫画批次数量:
{{
item
.
thArrangeMax
}}
</div>
<div
class=
"box"
>
非烫画批次数量:
{{
item
.
arrangeMax
}}
</div>
<div
class=
"box"
>
每天
{{
getTime
(
item
)
}}
开始自动排单
</div>
</div>
<div
class=
"action"
>
...
...
@@ -154,31 +155,6 @@
<div
style=
"border-top: 1px solid; color: #dcdfe6; padding-top: 10px"
>
<el-form-item
label=
"自动排单一个批次里生产单的最大值为:"
prop=
"arrangeMax"
:rules=
"[
{
required: true,
message: '请输入数量',
trigger: ['blur'],
},
{
pattern: /^\d+$/,
message: '请输入整数',
trigger: ['blur', 'change'],
},
]"
>
<el-input
v-model=
"editForm.arrangeMax"
style=
"width: 200px"
placeholder=
"请输入数量"
></el-input>
</el-form-item>
<div
style=
"color: #f56c6c; margin: 10px 0"
>
注:系统限制烫画工艺一个批次不超过50个生产单!
</div>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"color: #606266; margin-right: 10px"
>
烫画工艺自动排版:
...
...
@@ -195,9 +171,12 @@
--el-switch-off-color: #f56c6c;
"
/>
</div>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"color: #606266; margin-right: 10px"
>
状态:
</div>
<div
style=
"color: #606266; margin-left: 155px; margin-right: 10px"
>
状态:
</div>
<el-switch
v-model=
"editForm.status"
active-value=
"ACTIVE"
...
...
@@ -212,20 +191,109 @@
"
/>
</div>
<div
v-if=
"editForm.isAuto"
>
<div
label=
"排版类型:"
>
<el-radio-group
v-model=
"editForm.type"
>
<el-radio
label=
"tiff"
>
tiff排版
</el-radio>
<el-radio
label=
"png"
>
png排版
</el-radio>
</el-radio-group>
</div>
<div
label=
"排版宽度:"
>
<el-radio-group
v-model=
"editForm.templateWidth"
>
<el-radio
:value=
"42"
>
40+2cm
</el-radio>
<el-radio
:value=
"60"
>
60cm
</el-radio>
</el-radio-group>
<el-row
:gutter=
"40"
>
<el-col
:span=
"380"
>
<el-form-item
label=
"排版类型:"
prop=
"type"
label-width=
"100"
:rules=
"
editForm.isAuto
? [
{
required: true,
message: '请选择排版类型',
trigger: 'change',
},
]
: []
"
>
<el-radio-group
v-model=
"editForm.type"
:required=
"editForm.isAuto"
@
change=
"() =>
{
if (editForm.thArrangeMax) {
editFormRef?.validateField('thArrangeMax')
}
}"
>
<el-radio
label=
"tiff"
>
tiff排版
</el-radio>
<el-radio
label=
"png"
>
png排版
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"排版宽度:"
prop=
"templateWidth"
label-width=
"100"
:rules=
"
editForm.isAuto
? [
{
required: true,
message: '请选择排版宽度',
trigger: 'change',
},
]
: []
"
>
<el-radio-group
v-model=
"editForm.templateWidth"
:required=
"editForm.isAuto"
>
<el-radio
:value=
"42"
>
40+2cm
</el-radio>
<el-radio
:value=
"60"
>
60cm
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<div
style=
"color: #f56c6c; margin: 5px 0"
>
<!-- 注:系统限制烫画工艺一个批次不超过50个生产单! -->
注:系统限制烫画工艺排TIFF类型一个批次生产单件数不超过40,排PNG类型一个批次生产单件数不超过100!
</div>
</div>
<el-form-item
label=
"烫画类工艺自动排单一个批次里生产单件数的最大值为:"
prop=
"thArrangeMax"
label-width=
"380"
:rules=
"thArrangeMaxRules"
>
<el-input
v-model=
"editForm.thArrangeMax"
style=
"width: 200px"
placeholder=
"请输入数量"
></el-input>
</el-form-item>
<el-form-item
label=
"非烫画类工艺自动排单一个批次里生产单件数的最大值为:"
prop=
"arrangeMax"
label-width=
"380"
:rules=
"[
{
required: true,
message: '请输入数量',
trigger: ['blur'],
},
{
pattern: /^\d+$/,
message: '请输入整数',
trigger: ['blur', 'change'],
},
]"
>
<el-input
v-model=
"editForm.arrangeMax"
style=
"width: 200px"
placeholder=
"请输入数量"
></el-input>
</el-form-item>
</div>
<el-form-item>
...
...
@@ -252,9 +320,11 @@ import {
import
{
Plus
,
Minus
}
from
'@element-plus/icons-vue'
import
LogDialog
from
'.././components/dialog.tsx'
import
CustomizeForm
from
'@/components/CustomizeForm.tsx'
import
{
Edit
}
from
'@element-plus/icons-vue'
import
{
debounce
}
from
'lodash-es'
import
type
{
FormInstance
}
from
'element-plus'
import
{
computed
}
from
'vue'
import
type
{
FormItemRule
}
from
'element-plus'
const
editForm
=
ref
<
BaseForm
>
({
isAuto
:
false
,
status
:
'ACTIVE'
})
const
tableData
=
ref
([])
...
...
@@ -284,18 +354,69 @@ onMounted(() => {
const
dialogVisible
=
ref
(
false
)
const
editFormRef
=
ref
<
InstanceType
<
typeof
CustomizeForm
>
|
null
>
(
null
)
const
editFormRef
=
ref
<
FormInstance
|
null
>
(
null
)
const
paramsList
=
ref
([
'craft_type'
])
const
rulesList
=
ref
([
{
label
:
'工艺'
,
value
:
'craft_type'
,
disabled
:
false
},
{
label
:
'款号'
,
value
:
'supplier_product_no'
,
disabled
:
false
},
{
label
:
'尺码'
,
value
:
'size'
,
disabled
:
false
},
{
label
:
'类型'
,
value
:
'customized_quantity'
,
disabled
:
false
},
{
label
:
'工艺
类型
'
,
value
:
'craft_type'
,
disabled
:
false
},
{
label
:
'
库存
款号'
,
value
:
'supplier_product_no'
,
disabled
:
false
},
{
label
:
'
产品
尺码'
,
value
:
'size'
,
disabled
:
false
},
{
label
:
'
定制
类型'
,
value
:
'customized_quantity'
,
disabled
:
false
},
])
/**
* @description: 烫画类工艺自动排单最大值的校验规则
*/
const
thArrangeMaxRules
=
computed
(()
=>
{
return
[
{
required
:
true
,
message
:
'请输入数量'
,
trigger
:
[
'blur'
],
},
{
pattern
:
/^
\d
+$/
,
message
:
'请输入整数'
,
trigger
:
[
'blur'
,
'change'
],
},
{
validator
:
(
_rule
:
FormItemRule
,
value
:
string
|
number
|
undefined
,
callback
:
(
error
?:
Error
)
=>
void
)
=>
{
if
(
!
value
)
{
callback
()
return
}
const
numValue
=
Number
(
value
)
if
(
isNaN
(
numValue
))
{
callback
()
return
}
if
(
editForm
.
value
.
type
===
'tiff'
)
{
if
(
numValue
>
40
)
{
callback
(
new
Error
(
'排版类型为TIFF时,最大值不能超过40'
))
}
else
{
callback
()
}
}
else
if
(
editForm
.
value
.
type
===
'png'
)
{
if
(
numValue
>
100
)
{
callback
(
new
Error
(
'排版类型为PNG时,最大值不能超过100'
))
}
else
{
callback
()
}
}
else
{
callback
()
}
},
trigger
:
[
'blur'
,
'change'
],
},
]
})
/**
* @description: 取消按钮
*/
function
cancelFn
()
{
...
...
@@ -335,6 +456,7 @@ interface rowData extends BaseForm {
interface
BaseForm
{
id
?:
number
time
?:
string
thArrangeMax
?:
number
arrangeMax
?:
number
isAuto
?:
boolean
factoryNo
?:
number
...
...
@@ -457,7 +579,7 @@ const getLabels = (item: string) => {
* @description: 新增按钮打开弹窗
*/
function
addDialog
()
{
editForm
.
value
=
{
isAuto
:
fals
e
}
editForm
.
value
=
{
isAuto
:
tru
e
}
paramsList
.
value
=
[
'craft_type'
]
dialogVisible
.
value
=
true
}
...
...
src/views/supply/supplierManagement/index.vue
View file @
eb72b9a0
...
...
@@ -49,7 +49,9 @@
<div
style=
"text-align: center"
>
<ElButton
@
click=
"cancelFn"
>
取消
</ElButton>
<ElButton
type=
"primary"
@
click=
"saveSupplierFn"
>
保存
</ElButton>
<ElButton
type=
"primary"
:loading=
"saveLoading"
@
click=
"saveSupplierFn"
>
保存
</ElButton
>
</div>
</
template
>
</Dialog>
...
...
@@ -58,17 +60,17 @@
title=
"管理供应价格"
v-model=
"priceDialogVisible"
width=
"65%"
v-loading=
"priceLoading"
@
close=
"cancelPiceFn"
teleported
>
<div
style=
"display: flex; margin-bottom: 10px"
>
<div
style=
"display: flex; align-items: center; gap: 20px"
>
<div><span
style=
"color: red"
>
*
</span>
结算币种
</div>
<el-select
style=
"width: 300px; flex: 1"
v-model=
"currentGoods.currencyCode"
@
change=
"
<div
v-loading=
"priceLoading"
>
<div
style=
"display: flex; margin-bottom: 10px"
>
<div
style=
"display: flex; align-items: center; gap: 20px"
>
<div><span
style=
"color: red"
>
*
</span>
结算币种
</div>
<el-select
style=
"width: 300px; flex: 1"
v-model=
"currentGoods.currencyCode"
@
change=
"
(v:string) => {
currentGoods.currencyName =
...
...
@@ -78,95 +80,96 @@
}
"
>
<el-option
v-for=
"(item, index) in currencyOptions"
:key=
"index"
:label=
"`${item.currencyName}(${item.currencyCode})`"
:value=
"item.currencyCode"
>
</el-option>
</el-select>
</div>
</div>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showColorList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
颜色(Color)
</div>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
:title=
"`${item.cnname}(${item.enname})`"
:color=
"item.bgColor"
v-for=
"(item, index) in showColorList"
:key=
"index"
:style=
"{ color: item.fontColor }"
class=
"tabBox"
:class=
"{ active: colorIndex === item.code }"
@
click=
"optionSelection(item, 'color')"
>
{{ item.cnname }}({{ item.enname }})
</el-tag
>
<el-option
v-for=
"(item, index) in currencyOptions"
:key=
"index"
:label=
"`${item.currencyName}(${item.currencyCode})`"
:value=
"item.currencyCode"
>
</el-option>
</el-select>
</div>
</div>
</div>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showSizeList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
尺码(Size)
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showColorList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
颜色(Color)
</div>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
:title=
"`${item.cnname}(${item.enname})`"
:color=
"item.bgColor"
v-for=
"(item, index) in showColorList"
:key=
"index"
:style=
"{ color: item.fontColor }"
class=
"tabBox"
:class=
"{ active: colorIndex === item.code }"
@
click=
"optionSelection(item, 'color')"
>
{{ item.cnname }}({{ item.enname }})
</el-tag
>
</div>
</div>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
class=
"tabBox"
color=
"#ffff87"
style=
"color: #333"
effect=
"dark"
type=
"info"
v-for=
"(item, index) in showSizeList"
:key=
"index"
:class=
"{ active: sizeIndex === item.code }"
@
click=
"optionSelection(item, 'size')"
>
{{ item.cnname }}
</el-tag
>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showSizeList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
尺码(Size)
</div>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
class=
"tabBox"
color=
"#ffff87"
style=
"color: #333"
effect=
"dark"
type=
"info"
v-for=
"(item, index) in showSizeList"
:key=
"index"
:class=
"{ active: sizeIndex === item.code }"
@
click=
"optionSelection(item, 'size')"
>
{{ item.cnname }}
</el-tag
>
</div>
</div>
</div>
<div
style=
"
display: flex
;
justify-content: end;
border-top: 1px solid #eee;
"
>
<div
style=
"margin: 10px 0"
>
<el-input
placeholder=
"请输入供应价格
"
style=
"width: 200px; margin-right: 10px
"
size=
"small
"
v-model=
"supplierPirce"
clearable
></el-input
><ElButton
type=
"primary"
@
click=
"updatePrices"
size=
"small"
>
批量更新供应价格
</ElButton
>
<span
style=
"color: #f56c6c; vertical-align: middle"
>
(请注意!该操作会覆盖已有供应价格)
</span
>
<div
style=
"
display: flex;
justify-content: end
;
border-top: 1px solid #eee;
"
>
<div
style=
"margin: 10px 0"
>
<el-input
placeholder=
"请输入供应价格"
style=
"width: 200px; margin-right: 10px
"
size=
"small
"
v-model=
"supplierPirce
"
clearable
></el-input
><ElButton
type=
"primary"
@
click=
"updatePrices"
size=
"small"
>
批量更新供应价格
</ElButton
>
<span
style=
"color: #f56c6c; vertical-align: middle"
>
(请注意!该操作会覆盖已有供应价格)
</span
>
</div
>
</div>
<CustomizeTable
ref=
"tableRef"
border
style=
"margin-bottom: 20px"
v-model=
"pricetableData"
:config=
"priceTableConfig"
align=
"center"
height=
"500px"
@
getCheckboxRecords=
"selectPirce"
></CustomizeTable>
</div>
<CustomizeTable
ref=
"tableRef"
border
style=
"margin-bottom: 20px"
v-model=
"pricetableData"
:config=
"priceTableConfig"
align=
"center"
height=
"500px"
@
getCheckboxRecords=
"selectPirce"
></CustomizeTable>
<
template
#
footer
>
<div
style=
"text-align: center"
>
<ElButton
@
click=
"cancelPiceFn"
>
取消
</ElButton>
...
...
@@ -212,6 +215,7 @@ import {
IsizeType
,
IPropertyResponseItem
,
Iprice
,
IPropertyItem
,
}
from
'./types/index.ts'
const
[
editForm
,
resetEditForm
]
=
useValue
<
IsupplierType
>
({})
...
...
@@ -658,6 +662,7 @@ function savePiceFn() {
/**
* @description: 检查数据
*/
const
saveLoading
=
ref
(
false
)
async
function
checkData
():
Promise
<
{
isValid
:
boolean
postData
:
IsupplierType
...
...
@@ -722,9 +727,10 @@ async function checkData(): Promise<{
* @description: 保存按钮
*/
const
saveSupplierFn
=
debounce
(
async
()
=>
{
const
{
isValid
,
postData
}
=
await
checkData
()
if
(
isValid
)
{
try
{
saveLoading
.
value
=
true
try
{
const
{
isValid
,
postData
}
=
await
checkData
()
if
(
isValid
)
{
if
(
!
postData
.
id
)
{
await
addSupplierApi
({
...
postData
,
...
...
@@ -741,9 +747,11 @@ const saveSupplierFn = debounce(async () => {
cancelFn
()
search
()
}
catch
(
e
)
{
return
}
}
catch
(
e
)
{
return
}
finally
{
saveLoading
.
value
=
false
}
},
400
)
...
...
@@ -945,7 +953,7 @@ async function addPice(product: IgoodsType) {
}
// 辅助函数:创建属性映射
function
createPropertyMap
(
propertyList
:
any
[]):
Map
<
number
,
number
[]
>
{
function
createPropertyMap
(
propertyList
:
IPropertyItem
[]):
Map
<
number
,
number
[]
>
{
const
map
=
new
Map
<
number
,
number
[]
>
()
propertyList
.
forEach
((
item
)
=>
{
...
...
src/views/supply/supplierManagement/types/index.ts
View file @
eb72b9a0
...
...
@@ -20,7 +20,7 @@ export interface IgoodsType {
customProductItemList
?:
Iprice
[]
supplierPriceItemList
?:
Iprice
[]
customProductInfo
?:
IgoodsType
propertyList
?:
[]
propertyList
?:
IPropertyItem
[]
supplyPriceRange
?:
string
}
export
interface
IsupplierType
{
...
...
@@ -57,6 +57,11 @@ export interface IPropertyResponseItem {
valueList
:
IcolorType
[]
|
IsizeType
[]
}
export
interface
IPropertyItem
{
propertyId
?:
number
valueId
?:
number
}
export
interface
Iprice
{
productItemSku
?:
string
productItemImage
?:
string
...
...
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