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
5ac50c9e
Commit
5ac50c9e
authored
Mar 26, 2026
by
qinjianhui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 拣胚完成
parent
71f385c2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
236 additions
and
120 deletions
+236
-120
public/iconfont/demo_index.html
+26
-3
public/iconfont/iconfont.css
+7
-3
public/iconfont/iconfont.js
+0
-0
public/iconfont/iconfont.json
+7
-0
public/iconfont/iconfont.ttf
+0
-0
public/iconfont/iconfont.woff
+0
-0
public/iconfont/iconfont.woff2
+0
-0
src/api/factoryOrderNew.ts
+22
-3
src/components/Icon.vue
+3
-3
src/types/api/factoryOrderNew.ts
+9
-7
src/views/order/factoryOrderNew/component/ConfirmOrderDialog.vue
+12
-6
src/views/order/factoryOrderNew/component/PickCompleteDialog.vue
+141
-90
src/views/order/factoryOrderNew/index.vue
+9
-5
No files found.
public/iconfont/demo_index.html
View file @
5ac50c9e
...
...
@@ -55,6 +55,12 @@
<ul
class=
"icon_lists dib-box"
>
<li
class=
"dib"
>
<span
class=
"icon iconfont"
>

</span>
<div
class=
"name"
>
提示
</div>
<div
class=
"code-name"
>
&
#xe605;
</div>
</li>
<li
class=
"dib"
>
<span
class=
"icon iconfont"
>

</span>
<div
class=
"name"
>
查看详情
</div>
<div
class=
"code-name"
>
&
#xe62e;
</div>
...
...
@@ -132,9 +138,9 @@
<pre><code
class=
"language-css"
>
@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=17
2907702537
8') format('woff2'),
url('iconfont.woff?t=17
2907702537
8') format('woff'),
url('iconfont.ttf?t=17
2907702537
8') format('truetype');
src: url('iconfont.woff2?t=17
7449687201
8') format('woff2'),
url('iconfont.woff?t=17
7449687201
8') format('woff'),
url('iconfont.ttf?t=17
7449687201
8') format('truetype');
}
</code></pre>
<h3
id=
"-iconfont-"
>
第二步:定义使用 iconfont 的样式
</h3>
...
...
@@ -161,6 +167,15 @@
<ul
class=
"icon_lists dib-box"
>
<li
class=
"dib"
>
<span
class=
"icon iconfont icon-tishi"
></span>
<div
class=
"name"
>
提示
</div>
<div
class=
"code-name"
>
.icon-tishi
</div>
</li>
<li
class=
"dib"
>
<span
class=
"icon iconfont icon-chakanxiangqing"
></span>
<div
class=
"name"
>
查看详情
...
...
@@ -279,6 +294,14 @@
<li
class=
"dib"
>
<svg
class=
"icon svg-icon"
aria-hidden=
"true"
>
<use
xlink:href=
"#icon-tishi"
></use>
</svg>
<div
class=
"name"
>
提示
</div>
<div
class=
"code-name"
>
#icon-tishi
</div>
</li>
<li
class=
"dib"
>
<svg
class=
"icon svg-icon"
aria-hidden=
"true"
>
<use
xlink:href=
"#icon-chakanxiangqing"
></use>
</svg>
<div
class=
"name"
>
查看详情
</div>
...
...
public/iconfont/iconfont.css
View file @
5ac50c9e
@font-face
{
font-family
:
"iconfont"
;
/* Project id 4462827 */
src
:
url('iconfont.woff2?t=17
2907702537
8')
format
(
'woff2'
),
url('iconfont.woff?t=17
2907702537
8')
format
(
'woff'
),
url('iconfont.ttf?t=17
2907702537
8')
format
(
'truetype'
);
src
:
url('iconfont.woff2?t=17
7449687201
8')
format
(
'woff2'
),
url('iconfont.woff?t=17
7449687201
8')
format
(
'woff'
),
url('iconfont.ttf?t=17
7449687201
8')
format
(
'truetype'
);
}
.iconfont
{
...
...
@@ -13,6 +13,10 @@
-moz-osx-font-smoothing
:
grayscale
;
}
.icon-tishi
:before
{
content
:
"\e605"
;
}
.icon-chakanxiangqing
:before
{
content
:
"\e62e"
;
}
...
...
public/iconfont/iconfont.js
View file @
5ac50c9e
This diff is collapsed.
Click to expand it.
public/iconfont/iconfont.json
View file @
5ac50c9e
...
...
@@ -6,6 +6,13 @@
"description"
:
""
,
"glyphs"
:
[
{
"icon_id"
:
"3833188"
,
"name"
:
"提示"
,
"font_class"
:
"tishi"
,
"unicode"
:
"e605"
,
"unicode_decimal"
:
58885
},
{
"icon_id"
:
"22718987"
,
"name"
:
"查看详情"
,
"font_class"
:
"chakanxiangqing"
,
...
...
public/iconfont/iconfont.ttf
View file @
5ac50c9e
No preview for this file type
public/iconfont/iconfont.woff
View file @
5ac50c9e
No preview for this file type
public/iconfont/iconfont.woff2
View file @
5ac50c9e
No preview for this file type
src/api/factoryOrderNew.ts
View file @
5ac50c9e
...
...
@@ -107,6 +107,7 @@ export function transferOldFlowApi(ids: (number | string)[]) {
export
function
confirmOrderWithWarehouseApi
(
ids
:
(
number
|
string
)[],
warehouseId
:
number
|
string
,
warehouseName
:
string
,
)
{
return
axios
.
post
<
never
,
...
...
@@ -118,7 +119,11 @@ export function confirmOrderWithWarehouseApi(
status
?:
boolean
}[]
>
>
(
'factory/podOrder/ordersAccepted'
,
{
podOrderIds
:
ids
,
warehouseId
})
>
(
'factory/podOrder/ordersAccepted'
,
{
podOrderIds
:
ids
,
warehouseId
,
warehouseName
,
})
}
export
function
cancelOrderWithReasonApi
(
...
...
@@ -188,9 +193,23 @@ export function restockCheckApi(id: number | string) {
)
}
export
function
pickCompleteByIdsDataApi
(
ids
:
(
number
|
string
)[])
{
return
axios
.
post
<
never
,
BaseRespData
<
{
overallMessage
?:
string
pickingSituationList
?:
PickCompleteData
[]
allAvailableOrderIds
?:
number
[]
partialAvailableOrderIds
?:
number
[]
unavailableOrderIds
?:
number
[]
}
>
>
(
'factory/podOrderOperation/getPickingSituation'
,
ids
)
}
export
function
pickCompleteApi
(
ids
:
(
number
|
string
)[])
{
return
axios
.
post
<
never
,
BaseRespData
<
PickCompleteData
[]
>>
(
'factory/podOrderOperation/
listByIds
'
,
return
axios
.
post
<
never
,
BaseRespData
<
void
>>
(
'factory/podOrderOperation/
pickingComplete
'
,
ids
,
)
}
...
...
src/components/Icon.vue
View file @
5ac50c9e
<
template
>
<i
v-if=
"unicodeIcon"
class=
"
erpIconfont erp
unicode-icon"
class=
"
iconfont factory
unicode-icon"
v-html=
"unicodeIcon"
></i>
<svg
v-else
class=
"svg-icon
erp
"
aria-hidden=
"true"
>
<svg
v-else
class=
"svg-icon
factory
"
aria-hidden=
"true"
>
<slot
name=
"title"
></slot>
<use
:xlink:href=
"svgIcon"
></use>
</svg>
...
...
@@ -19,7 +19,7 @@ const props = defineProps({
}
})
const
unicodeIcon
=
computed
(()
=>
{
if
(
props
.
name
.
match
(
/^x
[
a-f0-9
]{4}
$/
))
{
if
(
props
.
name
.
match
(
/^x
[
a-f0-9
]{4
,
}
$/
))
{
return
`&#
${
props
.
name
}
;`
}
return
undefined
...
...
src/types/api/factoryOrderNew.ts
View file @
5ac50c9e
...
...
@@ -210,14 +210,16 @@ export interface PickCompleteData {
warehouseName
?:
string
skuImage
?:
string
productName
?:
string
s
tyle
No
?:
string
stockSku
?:
string
pick
Quantity
?:
number
available
Stock
?:
number
stockQuantit
y
?:
number
s
upplierProduct
No
?:
string
thirdSkuCode
?:
string
selected
Quantity
?:
number
available
Inventory
?:
number
inventor
y
?:
number
producingQuantity
?:
number
occupiedQuantity
?:
number
pickStatus
?:
'success'
|
'partial'
|
'fail'
occupyInventory
?:
number
pickingStatus
?:
string
availableOrderIds
?:
number
[]
allOrderIds
?:
number
[]
}
export
interface
PickFailData
{
...
...
src/views/order/factoryOrderNew/component/ConfirmOrderDialog.vue
View file @
5ac50c9e
...
...
@@ -42,12 +42,14 @@ import { confirmOrderWithWarehouseApi } from '@/api/factoryOrderNew'
import
type
{
WarehouseListData
}
from
'@/types'
const
emit
=
defineEmits
<
{
success
:
[
data
:
{
factoryOrderNumber
?:
string
message
?:
string
id
:
number
|
string
status
?:
boolean
}[]]
success
:
[
data
:
{
factoryOrderNumber
?:
string
message
?:
string
id
:
number
|
string
status
?:
boolean
}[],
]
}
>
()
const
visible
=
ref
(
false
)
...
...
@@ -89,11 +91,15 @@ const handleClose = () => {
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
await
formRef
.
value
.
validate
()
const
warehouseName
=
warehouseList
.
value
.
find
(
(
item
)
=>
item
.
id
===
form
.
warehouseId
,
)?.
name
submitLoading
.
value
=
true
try
{
const
res
=
await
confirmOrderWithWarehouseApi
(
orderIds
.
value
,
form
.
warehouseId
,
warehouseName
||
''
,
)
if
(
res
.
code
!==
200
)
return
visible
.
value
=
false
...
...
src/views/order/factoryOrderNew/component/PickCompleteDialog.vue
View file @
5ac50c9e
...
...
@@ -2,64 +2,73 @@
<ElDialog
v-model=
"visible"
title=
"拣胚完成"
width=
"1
2
00px"
width=
"1
4
00px"
:close-on-click-modal=
"false"
@
close=
"handleClose"
>
<div
class=
"pick-complete-actions"
style=
"margin-bottom: 10px"
>
<span
class=
"item"
>
<ElButton
type=
"success"
@
click=
"handleCreateInbound"
>
创建入库单
</ElButton>
</span>
</div>
<div
class=
"table-view"
>
<TableView
:paginated-data=
"tableData"
:columns=
"columns"
serial-numberable
selectionable
>
<template
#
skuImage=
"
{ row }">
<el-image
v-if=
"row.variantImage"
:src=
"row.variantImage"
style=
"width: 50px; height: 50px"
fit=
"contain"
:preview-src-list=
"[row.variantImage]"
preview-teleported
/>
</
template
>
<
template
#
pickQuantity=
"{ row }"
>
<span
style=
"color: #e6a23c; font-weight: bold"
>
{{
row
.
pickQuantity
}}
</span>
</
template
>
<
template
#
pickStatus=
"{ row }"
>
<span
v-if=
"row.pickStatus === 'fail'"
style=
"color: #f56c6c"
>
✕ 无法拣胚
</span>
<span
v-else-if=
"row.pickStatus === 'partial'"
class=
"item"
>
<ElButton
type=
"warning"
size=
"small"
>
调整拣胚顺序
</ElButton>
</span>
<span
v-else
style=
"color: #67c23a"
>
✓ 直接拣胚
</span>
</
template
>
</TableView>
<div
v-if=
"pickData"
class=
"pick-order-data"
>
<div
class=
"pick-order-data-message"
>
<Icon
style=
"width: 24px; height: 24px"
name=
"tishi"
/>
<span>
{{
pickData
.
overallMessage
}}
!
</span>
</div>
<div
class=
"pick-complete-actions"
style=
"margin-bottom: 10px"
>
<span
class=
"item"
>
<ElButton
type=
"success"
@
click=
"handleCreateInbound"
>
创建入库单
</ElButton>
</span>
</div>
<div
class=
"table-view"
>
<TableView
:paginated-data=
"pickData.pickingSituationList"
:columns=
"columns"
serial-numberable
selectionable
@
selection-change=
"handleSelectionChange"
>
<template
#
skuImage=
"
{ row }">
<el-image
v-if=
"row.skuImage"
:src=
"row.skuImage"
style=
"width: 50px; height: 50px"
fit=
"contain"
:preview-src-list=
"[row.skuImage]"
preview-teleported
/>
</
template
>
<
template
#
pickQuantity=
"{ row }"
>
<span
style=
"color: #e6a23c; font-weight: bold"
>
{{
row
.
selectedQuantity
}}
</span>
</
template
>
<
template
#
pickStatus=
"{ row }"
>
<span
v-if=
"row.pickingStatus === 'fail'"
style=
"color: #f56c6c; font-weight: 500"
>
✕ 无法拣胚
</span>
<span
v-else-if=
"row.pickingStatus === 'partial'"
class=
"item"
>
<ElButton
type=
"warning"
size=
"small"
>
调整拣胚顺序
</ElButton>
</span>
<span
v-else-if=
"row.pickingStatus === 'success'"
style=
"color: #67c23a; font-weight: 500"
>
✓ 直接拣胚
</span>
<span
v-else
style=
"color: #999; font-weight: 500"
>
未知状态
</span>
</
template
>
</TableView>
</div>
</div>
<
template
#
footer
>
<div
class=
"dialog-footer"
style=
"text-align: center"
>
<span
class=
"item"
>
<ElButton
@
click=
"visible = false"
>
取消
</ElButton>
</span>
<span
class=
"item"
>
<ElButton
type=
"primary"
:loading=
"submitLoading"
@
click=
"handleSubmit"
>
确定
</ElButton>
<ElButton
type=
"primary"
@
click=
"handleSubmit"
>
确定
</ElButton>
</span>
</div>
</
template
>
...
...
@@ -69,26 +78,33 @@
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
import
{
pickCompleteApi
}
from
'@/api/factoryOrderNew'
import
{
pickCompleteByIdsDataApi
,
pickCompleteApi
,
}
from
'@/api/factoryOrderNew'
import
type
{
PickCompleteData
}
from
'@/types/api/factoryOrderNew'
import
TableView
from
'@/components/TableView.vue'
import
type
{
CustomColumn
}
from
'@/types/table'
import
Icon
from
'@/components/Icon.vue'
interface
PickData
{
overallMessage
?:
string
pickingSituationList
?:
PickCompleteData
[]
allAvailableOrderIds
?:
number
[]
partialAvailableOrderIds
?:
number
[]
unavailableOrderIds
?:
number
[]
}
const
emit
=
defineEmits
<
{
success
:
[]
}
>
()
const
visible
=
ref
(
false
)
const
submitLoading
=
ref
(
false
)
const
tableData
=
ref
<
PickCompleteData
[]
>
([])
const
orderIds
=
ref
<
(
number
|
string
)[]
>
([])
const
pickData
=
ref
<
PickData
|
null
>
(
null
)
const
selections
=
ref
<
PickCompleteData
[]
>
([])
const
columns
:
CustomColumn
<
PickCompleteData
>
[]
=
[
const
columns
=
[
{
key
:
'warehouseName'
,
prop
:
'warehouseName'
,
label
:
'仓库名称'
,
minWidth
:
1
0
0
,
minWidth
:
1
2
0
,
},
{
key
:
'skuImage'
,
...
...
@@ -104,48 +120,55 @@ const columns: CustomColumn<PickCompleteData>[] = [
minWidth
:
120
,
showOverflowTooltip
:
true
,
},
{
key
:
'styleNo'
,
prop
:
'styleNo'
,
label
:
'款号'
,
minWidth
:
80
},
{
key
:
'stockSku'
,
prop
:
'stockSku'
,
label
:
'库存SKU'
,
minWidth
:
120
},
{
key
:
'pickQuantity'
,
prop
:
'pickQuantity'
,
label
:
'本次拣胚数量'
,
minWidth
:
110
,
prop
:
'supplierProductNo'
,
label
:
'款号'
,
width
:
100
,
align
:
'center'
,
},
{
key
:
'thirdSkuCode'
,
prop
:
'thirdSkuCode'
,
label
:
'库存SKU'
,
align
:
'center'
,
width
:
180
,
},
{
key
:
'selectedQuantity'
,
prop
:
'selectedQuantity'
,
label
:
'本次拣胚数量'
,
width
:
110
,
align
:
'right'
,
slot
:
'pickQuantity'
,
},
{
key
:
'availableStock'
,
prop
:
'availableStock'
,
prop
:
'availableInventory'
,
label
:
'可调配库存'
,
minW
idth
:
100
,
align
:
'
center
'
,
w
idth
:
100
,
align
:
'
right
'
,
},
{
key
:
'stockQuantity'
,
prop
:
'stockQuantity'
,
prop
:
'inventory'
,
label
:
'库存数量'
,
minW
idth
:
90
,
align
:
'
center
'
,
w
idth
:
90
,
align
:
'
right
'
,
},
{
key
:
'producingQuantity'
,
prop
:
'producingQuantity'
,
label
:
'生产中数量'
,
minW
idth
:
100
,
align
:
'
center
'
,
w
idth
:
100
,
align
:
'
right
'
,
},
{
key
:
'occupiedQuantity'
,
prop
:
'occupiedQuantity'
,
prop
:
'occupyInventory'
,
label
:
'占用数量'
,
minW
idth
:
90
,
align
:
'
center
'
,
w
idth
:
90
,
align
:
'
right
'
,
},
{
key
:
'pickStatus'
,
label
:
'拣胚情况'
,
minW
idth
:
130
,
w
idth
:
130
,
align
:
'center'
,
fixed
:
'right'
,
slot
:
'pickStatus'
,
...
...
@@ -153,34 +176,54 @@ const columns: CustomColumn<PickCompleteData>[] = [
]
const
open
=
async
(
ids
:
(
number
|
string
)[])
=>
{
orderIds
.
value
=
ids
visible
.
value
=
true
selections
.
value
=
[]
pickData
.
value
=
null
const
loading
=
ElLoading
.
service
({
text
:
'操作中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
try
{
const
res
=
await
pickCompleteApi
(
ids
)
tableData
.
value
=
res
.
data
||
[]
}
catch
(
_e
)
{
tableData
.
value
=
[]
const
res
=
await
pickCompleteByIdsDataApi
(
ids
)
if
(
res
.
code
!==
200
)
return
pickData
.
value
=
res
.
data
||
null
visible
.
value
=
true
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
loading
.
close
()
}
}
const
handleClose
=
()
=>
{
tableData
.
value
=
[]
pickData
.
value
=
null
}
const
handleCreateInbound
=
()
=>
{
ElMessage
.
info
(
'创建入库单功能待实现'
)
}
const
handleSelectionChange
=
(
selection
:
PickCompleteData
[])
=>
{
selections
.
value
=
selection
}
const
handleSubmit
=
async
()
=>
{
submitLoading
.
value
=
true
const
loading
=
ElLoading
.
service
({
text
:
'操作中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
const
orderIds
=
pickData
.
value
?.
pickingSituationList
?.
map
((
item
)
=>
item
.
availableOrderIds
)
.
flat
()
try
{
const
res
=
await
pickCompleteApi
(
orderIds
as
(
number
|
string
)[])
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
'拣胚完成'
)
visible
.
value
=
false
emit
(
'success'
)
}
catch
(
_
e
)
{
ElMessage
.
error
(
'操作失败'
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
submitLoading
.
value
=
false
loading
.
close
()
}
}
...
...
@@ -191,4 +234,12 @@ defineExpose({ open })
.table-view
{
height
:
600px
;
}
.pick-order-data-message
{
font-size
:
14px
;
color
:
#f56c6c
;
margin-bottom
:
10px
;
font-weight
:
bold
;
display
:
flex
;
align-items
:
center
;
}
</
style
>
src/views/order/factoryOrderNew/index.vue
View file @
5ac50c9e
...
...
@@ -714,9 +714,9 @@
<!--
表格布局
-->
<
div
v
-
if
=
"isTableLayout"
class
=
"table-content"
>
<
splitDiv
v
-
loading
=
"loading"
size
=
"55"
>
<
splitDiv
size
=
"55"
>
<
template
#
top
>
<
div
class
=
"table-list flex-1 overflow-hidden"
>
<
div
v
-
loading
=
"loading"
class
=
"table-list flex-1 overflow-hidden"
>
<
TableView
ref
=
"tableRef"
highlight
-
current
-
row
...
...
@@ -763,7 +763,7 @@
@
tab
-
click
=
"handleTabClick"
>
<
el
-
tab
-
pane
name
=
"product"
label
=
"包含商品"
>
<
div
class
=
"sub-table-wrapper"
>
<
div
v
-
loading
=
"subLoading"
class
=
"sub-table-wrapper"
>
<
TableView
:
paginated
-
data
=
"productList"
:
columns
=
"productColumns"
...
...
@@ -772,7 +772,7 @@
<
/div
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
name
=
"log"
label
=
"操作日志"
>
<
div
class
=
"detail-table-content"
>
<
div
v
-
loading
=
"subLoading"
class
=
"detail-table-content"
>
<
LogList
:
log
-
list
=
"logList"
/>
<
div
v
-
if
=
"!logList.length"
class
=
"empty-content"
>
暂无数据
...
...
@@ -935,6 +935,7 @@ const cardLayoutStatuses = [
'PENDING_PACKING'
,
]
const
specialLayoutStatuses
=
[
'BATCH_MANAGE'
,
'AWAITING_RESTOCK'
]
const
subLoading
=
ref
(
false
)
const
isCardLayout
=
computed
(()
=>
cardLayoutStatuses
.
includes
(
status
.
value
))
const
isSpecialLayout
=
computed
(()
=>
specialLayoutStatuses
.
includes
(
status
.
value
),
...
...
@@ -1578,6 +1579,7 @@ const getOrderDetailsById = async (tabName?: 'product' | 'log') => {
const
id
=
currentRow
.
value
.
id
const
isSuspend
=
status
.
value
===
'SUSPEND'
const
effectiveTab
=
tabName
??
activeTab
.
value
subLoading
.
value
=
true
try
{
if
(
effectiveTab
===
'product'
)
{
productList
.
value
=
[]
...
...
@@ -1594,6 +1596,8 @@ const getOrderDetailsById = async (tabName?: 'product' | 'log') => {
}
}
catch
(
e
)
{
console
.
error
(
e
)
}
finally
{
subLoading
.
value
=
false
}
}
watch
(
currentRow
,
(
row
)
=>
{
...
...
@@ -2031,7 +2035,7 @@ const handlePrintPickOrder = async () => {
}
}
const
handlePickComplete
=
()
=>
{
//
if (!ensureSelection()) return
if
(
!
ensureSelection
())
return
pickCompleteDialogRef
.
value
?.
open
(
getSelectedIds
())
}
const
handlePickFail
=
()
=>
{
...
...
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