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
0
Merge Requests
0
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
da3010e2
Commit
da3010e2
authored
Aug 22, 2025
by
zhuzhequan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加生产单查询功能
parent
7a0fd357
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
607 additions
and
1 deletions
+607
-1
components.d.ts
+2
-0
src/api/podOrder.ts
+12
-0
src/assets/images/saoma.png
+0
-0
src/components/SideBar.vue
+12
-1
src/components/searchProdOrder.vue
+567
-0
src/types/api/podOrder.ts
+14
-0
No files found.
components.d.ts
View file @
da3010e2
...
@@ -32,6 +32,7 @@ declare module 'vue' {
...
@@ -32,6 +32,7 @@ declare module 'vue' {
ElImage
:
typeof
import
(
'element-plus/es'
)[
'ElImage'
]
ElImage
:
typeof
import
(
'element-plus/es'
)[
'ElImage'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInputNumber
:
typeof
import
(
'element-plus/es'
)[
'ElInputNumber'
]
ElInputNumber
:
typeof
import
(
'element-plus/es'
)[
'ElInputNumber'
]
ElLink
:
typeof
import
(
'element-plus/es'
)[
'ElLink'
]
ElMenu
:
typeof
import
(
'element-plus/es'
)[
'ElMenu'
]
ElMenu
:
typeof
import
(
'element-plus/es'
)[
'ElMenu'
]
ElMenuItem
:
typeof
import
(
'element-plus/es'
)[
'ElMenuItem'
]
ElMenuItem
:
typeof
import
(
'element-plus/es'
)[
'ElMenuItem'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
...
@@ -62,6 +63,7 @@ declare module 'vue' {
...
@@ -62,6 +63,7 @@ declare module 'vue' {
RightClickMenu
:
typeof
import
(
'./src/components/RightClickMenu.vue'
)[
'default'
]
RightClickMenu
:
typeof
import
(
'./src/components/RightClickMenu.vue'
)[
'default'
]
RouterLink
:
typeof
import
(
'vue-router'
)[
'RouterLink'
]
RouterLink
:
typeof
import
(
'vue-router'
)[
'RouterLink'
]
RouterView
:
typeof
import
(
'vue-router'
)[
'RouterView'
]
RouterView
:
typeof
import
(
'vue-router'
)[
'RouterView'
]
SearchProdOrder
:
typeof
import
(
'./src/components/searchProdOrder.vue'
)[
'default'
]
Select
:
typeof
import
(
'./src/components/Form/Select.vue'
)[
'default'
]
Select
:
typeof
import
(
'./src/components/Form/Select.vue'
)[
'default'
]
ShipmentOrderDetail
:
typeof
import
(
'./src/components/ShipmentOrderDetail.vue'
)[
'default'
]
ShipmentOrderDetail
:
typeof
import
(
'./src/components/ShipmentOrderDetail.vue'
)[
'default'
]
SideBar
:
typeof
import
(
'./src/components/SideBar.vue'
)[
'default'
]
SideBar
:
typeof
import
(
'./src/components/SideBar.vue'
)[
'default'
]
...
...
src/api/podOrder.ts
View file @
da3010e2
...
@@ -36,6 +36,18 @@ export function getSubOrderBySubOrderNumber(thirdSubOrderNumber: string) {
...
@@ -36,6 +36,18 @@ export function getSubOrderBySubOrderNumber(thirdSubOrderNumber: string) {
},
},
)
)
}
}
export
function
getSubOrderBySubOrder
(
factorySubOrderNumber
:
string
,
orderFrom
:
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
PodProductList
>>
(
'factory/podJomallOrderProductCnUs/getSubOrderBySubOrderNumber'
,
{
params
:
{
factorySubOrderNumber
,
orderFrom
,
},
},
)
}
export
function
refreshJMProductInfo
(
data
:
number
[])
{
export
function
refreshJMProductInfo
(
data
:
number
[])
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'factory/podJomallOrder/refreshJomallPodProduct '
,
'factory/podJomallOrder/refreshJomallPodProduct '
,
...
...
src/assets/images/saoma.png
0 → 100644
View file @
da3010e2
8.93 KB
src/components/SideBar.vue
View file @
da3010e2
...
@@ -11,6 +11,13 @@
...
@@ -11,6 +11,13 @@
>
>
<img
src=
"../assets/images/printer.png"
width=
"24"
height=
"24"
/>
<img
src=
"../assets/images/printer.png"
width=
"24"
height=
"24"
/>
</div>
</div>
<div
title=
"生产单查询"
class=
"tool-item"
@
click=
"searchVisible = true"
>
<img
src=
"../assets/images/saoma.png"
width=
"24"
height=
"24"
/>
</div>
</div>
</div>
<!-- 格式工具 -->
<!-- 格式工具 -->
...
@@ -130,13 +137,16 @@
...
@@ -130,13 +137,16 @@
</TableView>
</TableView>
</el-dialog>
</el-dialog>
</span>
</span>
<el-dialog
v-model=
"searchVisible"
title=
"生产单查询"
width=
"100%"
fullscreen
>
<SearchProductOrder
v-if=
"searchVisible"
/>
</el-dialog>
<!-- 预览图片 -->
<!-- 预览图片 -->
<el-dialog
v-model=
"dialogVisible"
width=
"35%"
>
<el-dialog
v-model=
"dialogVisible"
width=
"35%"
>
<img
:src=
"dialogImageUrl"
alt=
"商品预览图片"
/>
<img
:src=
"dialogImageUrl"
alt=
"商品预览图片"
/>
</el-dialog>
</el-dialog>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
SearchProductOrder
from
'./searchProdOrder.vue'
import
{
ref
,
watch
,
computed
}
from
'vue'
import
{
ref
,
watch
,
computed
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
...
@@ -148,6 +158,7 @@ import { LogisticBill } from '@/types/api/podMakeOrder'
...
@@ -148,6 +158,7 @@ import { LogisticBill } from '@/types/api/podMakeOrder'
import
TableView
from
'@/components/TableView.vue'
import
TableView
from
'@/components/TableView.vue'
const
formatDrawer
=
ref
(
false
)
const
formatDrawer
=
ref
(
false
)
const
searchVisible
=
ref
(
false
)
const
getLogisticDrawer
=
ref
(
false
)
const
getLogisticDrawer
=
ref
(
false
)
const
textareaT
=
ref
(
''
)
const
textareaT
=
ref
(
''
)
...
...
src/components/searchProdOrder.vue
0 → 100644
View file @
da3010e2
<
script
setup
lang=
"ts"
>
import
{
getSubOrderBySubOrder
}
from
'@/api/podOrder.ts'
import
{
SearchOrderRes
}
from
'@/types/api/podOrder.ts'
import
{
nextTick
,
ref
}
from
'vue'
import
{
DocumentCopy
}
from
'@element-plus/icons-vue'
import
{
copyText
}
from
'@/utils'
defineProps
({
detailData
:
{
default
:
null
,
type
:
Object
,
},
})
const
type
=
{
'A'
:
'正面'
,
'B'
:
'反面'
,
'C'
:
'左边'
,
'D'
:
'右边'
,
}
const
imageList
=
ref
<
{
sort
:
number
title
?:
'A'
|
'B'
|
'C'
|
'D'
url
?:
string
}[]
>
([])
const
detail
=
ref
<
SearchOrderRes
>
({
imgList
:
[],
id
:
0
,
})
type
AudioKey
=
keyof
typeof
audios
// 创建一个类型,确保 key 只能是 audios 对象的键之一
const
TrackingNumber
=
ref
(
''
)
const
trackingNumberRef
=
ref
(
null
)
const
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
,
}
const
playAudio
=
(
key
:
AudioKey
,
message
?:
string
)
=>
{
let
text
=
''
switch
(
key
)
{
case
'weight_search_success'
:
text
=
''
break
case
'weight_search_error'
:
text
=
'请录入生产单号'
break
case
'weight_success'
:
text
=
''
break
case
'weight_repeat'
:
text
=
'称重复录入'
break
default
:
text
=
'请录入跟踪号或重量'
break
}
if
(
message
||
text
)
ElMessage
.
warning
(
message
||
text
)
const
audio
=
new
Audio
()
if
(
audios
[
key
])
{
audio
.
src
=
audios
[
key
]
// 获取对应 key 的音频路径
audio
.
play
().
catch
((
err
)
=>
console
.
error
(
'Audio play failed:'
,
err
))
// 捕获音频播放失败的错误
}
else
{
console
.
error
(
`No audio found for key:
${
key
}
`
)
}
}
const
trackcodeInput
=
async
()
=>
{
if
(
!
TrackingNumber
.
value
)
{
// ElMessage.warning('请扫描生产单号')
playAudio
(
'weight_search_error'
)
return
}
const
user
=
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
||
'{}'
)
const
orderNumber
=
TrackingNumber
.
value
// if (user.factory?.countryCode.toLowerCase() !== 'us') {
// const regex = /^[A-Z]{4}_/ //是否以四个大写字母加下划线开头
// if (regex.test(orderNumber)) {
// orderNumber =
// orderNumber.split('_')[0] +
// '-' +
// orderNumber.split('_')[orderNumber.split('_').length - 1]
// }
// }
try
{
const
res
=
await
getSubOrderBySubOrder
(
orderNumber
,
user
.
factory
?.
countryCode
.
toLowerCase
())
if
(
!
res
.
data
)
{
return
ElMessage
.
error
(
'生产单不存在'
)
}
res
.
data
.
inputNum
=
TrackingNumber
.
value
TrackingNumber
.
value
=
''
if
(
typeof
res
.
data
.
imageAry
===
'string'
)
{
imageList
.
value
=
JSON
.
parse
(
res
.
data
.
imageAry
)
}
else
{
imageList
.
value
=
[]
}
const
d
=
JSON
.
parse
(
JSON
.
stringify
(
res
.
data
))
if
(
d
.
note
)
{
d
.
note
=
JSON
.
parse
(
d
.
note
)
}
else
{
d
.
note
=
[]
}
detail
.
value
=
d
playAudio
(
'weight_search_success'
)
nextTick
(()
=>
{
if
(
trackingNumberRef
.
value
)
{
;(
trackingNumberRef
.
value
as
HTMLInputElement
).
focus
()
}
})
}
catch
(
e
)
{
console
.
error
(
e
)
nextTick
(()
=>
{
if
(
trackingNumberRef
.
value
)
{
;(
trackingNumberRef
.
value
as
HTMLInputElement
).
focus
()
}
})
}
}
</
script
>
<
template
>
<div
class=
"detail-div"
>
<div
class=
"detail-content"
>
<div
class=
"left"
>
<div
v-if=
"imageList.length > 0"
class=
"left-images"
>
<div
v-for=
"(item, index) in imageList"
:key=
"index"
class=
"img-box"
>
<b
v-if=
"item.title"
>
{{
item
.
title
}}
(
{{
type
[
item
.
title
]
}}
)
</b>
<img
:src=
"item.url"
alt=
""
>
</div>
</div>
</div>
<div
class=
"right"
>
<div
v-if=
"!detailData || Object.keys(detailData).length === 0"
class=
"input"
>
<el-input
ref=
"trackingNumberRef"
v-model=
"TrackingNumber"
placeholder=
"扫描枪输入第三方订单号"
style=
"width: 660px; margin-right: 10px"
clearable
@
keydown
.
enter=
"trackcodeInput()"
></el-input>
<el-button
type=
"primary"
@
click=
"trackcodeInput()"
>
查询
</el-button>
</div>
<div
class=
"div-text"
>
<b>
生产单信息
</b>
<div
class=
"div-content"
>
<h2
style=
"text-align: center;color: black;font-size: 16px;width: 100%;"
>
{{
detail
.
inputNum
}}
</h2>
<div
:title=
"detail?.factorySubOrderNumber"
class=
"div-item"
>
<span>
生产单号
</span>
<p>
{{
detail
?.
factorySubOrderNumber
}}
</p>
<el-icon
v-if=
"detail?.factorySubOrderNumber"
class=
"copy"
style=
"cursor:pointer;"
@
click=
"copyText(detail.factorySubOrderNumber)"
>
<DocumentCopy
/>
</el-icon>
</div>
<div
:title=
"detail?.shopNumber"
class=
"div-item"
>
<span>
店铺单号
</span>
<p>
{{
detail
?.
shopNumber
}}
</p>
<el-icon
v-if=
"detail?.shopNumber"
class=
"copy"
style=
"cursor:pointer;"
@
click=
"copyText(detail.shopNumber)"
>
<DocumentCopy
/>
</el-icon>
</div>
<div
:title=
"detail?.thirdSubOrderNumber || ''"
class=
"div-item"
>
<span>
第三方生产单号
</span>
<p>
{{
detail
?.
thirdSubOrderNumber
}}
</p>
<el-icon
v-if=
"detail?.thirdSubOrderNumber"
class=
"copy"
style=
"cursor:pointer;"
@
click=
"copyText(detail.thirdSubOrderNumber)"
>
<DocumentCopy
/>
</el-icon>
</div>
<div
:title=
"String(detail?.process)"
class=
"div-item"
>
<span>
生产工艺
</span>
<p>
{{
detail
?.
craftName
}}
</p>
</div>
<div
:title=
"detail?.createTime"
class=
"div-item"
>
<span>
创建时间
</span>
<p>
{{
detail
?.
createTime
}}
</p>
</div>
<div
:title=
"detail?.baseSku"
class=
"div-item"
>
<span>
基版
</span>
<p>
{{
detail
?.
baseSku
}}
</p>
</div>
<div
:title=
"String(detail?.supplierItemNo)"
class=
"div-item"
>
<span>
货号
</span>
<p>
{{
detail
?.
supplierItemNo
}}
</p>
</div>
<div
:title=
"String(detail?.size)"
class=
"div-item"
>
<span>
尺寸
</span>
<p>
{{
detail
?.
size
}}
</p>
</div>
<!--
<div
:title=
"detail?.variantSku"
class=
"div-item"
>
-->
<!--
<span>
变体SKU
</span>
-->
<!--
<p>
{{
detail
?.
variantSku
}}
</p>
-->
<!--
</div>
-->
<div
:title=
"String(detail?.faceCount)"
class=
"div-item"
>
<span>
打印面数
</span>
<p
v-if=
"detail?.num || imageList.length"
style=
"color: red"
>
{{
detail
?.
faceCount
}}
(
{{
imageList
.
map
(
el
=>
el
.
title
).
join
(
'+'
)
}}
)
</p>
</div>
</div>
</div>
<div
class=
"div-text"
style=
"
flex: 1;
margin-top: 15px;
flex-shrink: 0;
display: flex;
flex-direction: column;
"
>
<div
style=
"height: 100%"
class=
"div-content"
>
<b
style=
"position: absolute; top: -12px"
>
客户留言信息
</b>
<div
v-for=
"(item, index) in detail?.note"
:key=
"index"
class=
"div-item"
>
<span>
{{
item
.
prop
}}
:
</span>
<p>
{{
item
.
value
}}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.copy
{
font-weight
:
bold
;
margin-left
:
5px
;
}
::v-deep
.el-dialog__body
{
box-sizing
:
border-box
;
flex
:
1
;
flex-shrink
:
0
;
overflow
:
hidden
;
}
::v-deep
.el-dialog
{
display
:
flex
;
height
:
calc
(
100%
-
50px
);
margin-top
:
50px
;
flex-direction
:
column
;
}
.sure-btn
{
position
:
absolute
;
right
:
62px
;
top
:
14px
;
}
.detail-div
{
display
:
flex
;
height
:
92vh
;
flex-direction
:
column
;
justify-content
:
space-between
;
.detail-images
{
.scroll-list
{
background
:
#ececec
;
display
:
flex
;
height
:
100px
;
width
:
100%
;
padding
:
5px
;
.scroll-content
{
margin-left
:
10px
;
overflow-x
:
auto
;
overflow-y
:
hidden
;
flex
:
1
;
display
:
flex
;
flex-wrap
:
nowrap
;
flex-shrink
:
0
;
.scroll-item
{
height
:
100%
;
min-width
:
100px
;
background
:
white
;
margin-right
:
5px
;
}
}
.img-title
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
background
:
white
;
padding
:
10px
;
b
{
text-align
:
center
;
color
:
black
;
font-weight
:
bold
;
font-size
:
16px
;
margin-bottom
:
15px
;
}
.id
{
display
:
flex
;
align-items
:
center
;
padding
:
3px
5px
;
background
:
#ececec
;
justify-content
:
center
;
img
{
width
:
15px
;
margin-right
:
8px
;
}
}
}
}
}
.detail-content
{
display
:
flex
;
width
:
100%
;
flex
:
1
;
margin-bottom
:
10px
;
flex-shrink
:
0
;
justify-content
:
space-between
;
}
.right
{
width
:
500px
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
.btn
{
margin
:
20px
0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
height
:
50px
;
width
:
100%
;
.btn-sure,
.btn-down
{
width
:
49%
;
position
:
relative
;
.check
{
position
:
absolute
;
width
:
144px
;
height
:
100%
;
background
:
transparent
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
right
:
0
;
top
:
1px
;
}
}
}
.div-text
{
.div-content
{
display
:
flex
;
flex-wrap
:
wrap
;
justify-content
:
space-between
;
align-items
:
flex-start
;
padding
:
15px
10px
;
box-sizing
:
border-box
;
text-align
:
center
;
.div-item
{
width
:
100%
;
margin-bottom
:
10px
;
display
:
flex
;
align-items
:
center
;
font-size
:
16px
!important
;
p
{
font-weight
:
400
;
color
:
black
;
}
span
{
display
:
inline-block
;
text-align
:
right
;
width
:
140px
;
}
span
::after
{
content
:
':'
;
margin
:
0
3px
;
}
}
}
b
{
position
:
relative
;
background
:
white
;
top
:
9px
;
left
:
13px
;
padding
:
0
10px
;
font-size
:
18px
;
color
:
black
;
z-index
:
3
;
}
.div-content
{
position
:
relative
;
border
:
1px
solid
#ececec
;
}
}
.input
{
display
:
flex
;
align-items
:
center
;
margin
:
30px
0
;
}
}
.left
{
flex
:
1
;
flex-shrink
:
0
;
margin-right
:
20px
;
overflow
:
hidden
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.left-image
{
display
:
flex
;
height
:
100%
;
flex-direction
:
column
;
justify-content
:
center
;
img
{
height
:
auto
;
width
:
100%
;
max-height
:
90%
;
}
b
{
color
:
black
;
font-size
:
18px
;
margin-bottom
:
15px
;
}
}
.left-images
{
display
:
flex
;
width
:
95%
;
height
:
100%
;
gap
:
10px
;
justify-content
:
center
;
.img-box
{
display
:
flex
;
flex-direction
:
column
;
gap
:
10px
;
width
:
50%
;
height
:
100%
;
b
{
font-size
:
26px
;
font-weight
:
normal
;
}
img
{
flex
:
1
;
flex-shrink
:
0
;
object-fit
:
cover
;
overflow
:
hidden
;
}
}
b
{
color
:
black
;
text-align
:
center
;
margin-bottom
:
15px
;
}
}
}
}
::v-deep
.el-carousel__container
{
height
:
100%
;
}
::v-deep
.el-form-item__label
{
font-weight
:
bold
;
color
:
white
;
}
::v-deep
.el-dialog__title
{
font-weight
:
bold
;
font-size
:
37px
;
color
:
black
;
position
:
relative
;
left
:
47%
;
top
:
13px
;
}
.btn
{
position
:
relative
;
::v-deep
.el-button
{
span
{
position
:
relative
;
left
:
-30px
;
}
}
.check
{
::v-deep
.el-checkbox__inner
{
background-color
:
transparent
!important
;
border-color
:
white
!important
;
width
:
12px
;
height
:
12px
;
}
::v-deep
.el-checkbox__inner
::after
{
left
:
3px
;
}
::v-deep
.el-checkbox__label
{
padding-left
:
5px
;
font-size
:
12px
;
color
:
white
!important
;
}
}
}
.warning
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#ff9900
;
margin-left
:
10px
;
cursor
:
pointer
;
}
</
style
>
src/types/api/podOrder.ts
View file @
da3010e2
...
@@ -123,6 +123,20 @@ export interface PodOrderRes extends PodProductList {
...
@@ -123,6 +123,20 @@ export interface PodOrderRes extends PodProductList {
note
?:
Array
<
{
prop
:
string
|
number
;
value
:
string
|
number
}
>
note
?:
Array
<
{
prop
:
string
|
number
;
value
:
string
|
number
}
>
imgList
:
ImgList
imgList
:
ImgList
}
}
export
interface
SearchOrderRes
extends
PodProductList
{
expectDeliveryTime
?:
string
|
null
thirdOrderNumber
?:
string
|
null
startStockingTime
?:
string
|
null
userMark
?:
string
|
null
color
?:
string
|
null
size
?:
string
|
null
note
?:
Array
<
{
prop
:
string
|
number
;
value
:
string
|
number
}
>
imgList
:
{
url
:
string
title
?:
string
}[]
}
export
interface
ShipmentOrderRes
{
export
interface
ShipmentOrderRes
{
factoryOrderNumber
?:
string
factoryOrderNumber
?:
string
thirdSubOrderNumber
?:
string
thirdSubOrderNumber
?:
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