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
da894e8f
Commit
da894e8f
authored
Oct 28, 2025
by
linjinhong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:【工厂端】POD订单(US)实现自动排单#1000468
parent
99f0e989
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
620 additions
and
1 deletions
+620
-1
src/api/podUsSchedulingRules.ts
+32
-0
src/router/index.ts
+9
-1
src/router/menu.ts
+5
-0
src/views/order/components/dialog.tsx
+55
-0
src/views/order/podUsSchedulingRules/index.vue
+519
-0
No files found.
src/api/podUsSchedulingRules.ts
0 → 100644
View file @
da894e8f
import
axios
from
'@/api/axios.ts'
import
{
BasePaginationData
,
BaseRespData
}
from
'@/types/api'
// 新增规则
interface
BaseForm
{
id
?:
number
}
type
ParamKey
=
`param
${
number
}
`
type
ParamValue
=
string
|
number
|
boolean
|
null
|
undefined
type
PostData
=
BaseForm
&
Record
<
ParamKey
,
ParamValue
>
export
function
usArrangeRuleApi
(
data
:
PostData
)
{
return
axios
.
post
<
never
,
BasePaginationData
<
never
>>
(
'factory/podJomallOrderUs/usArrangeRule'
,
data
,
)
}
// 编辑规则
export
function
updateRuleByIdApi
(
data
:
PostData
)
{
return
axios
.
post
<
never
,
BasePaginationData
<
never
>>
(
'factory/podJomallOrderUsArrangeRule/updateRuleById'
,
data
,
)
}
// us规则列表
export
function
getByFactoryNoApi
(
data
:
{
factoryNo
:
number
})
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/factory/podJomallOrderUsArrangeRule/getByFactoryNo'
,
{
params
:
data
},
)
}
src/router/index.ts
View file @
da894e8f
...
...
@@ -88,7 +88,15 @@ const router = createRouter({
},
component
:
()
=>
import
(
'@/views/order/orderTracking/index.vue'
),
},
{
{
path
:
'/pod-us-order/podUsSchedulingRules'
,
meta
:
{
title
:
'POD(US)排单规则'
,
},
component
:
()
=>
import
(
'@/views/order/podUsSchedulingRules/index.vue'
),
},
{
path
:
'/pod-cn-order/orderTracking'
,
meta
:
{
title
:
'POD(CN)订单跟踪'
,
...
...
src/router/menu.ts
View file @
da894e8f
...
...
@@ -137,6 +137,11 @@ const menu: MenuItem[] = [
id
:
10
,
label
:
'POD(US)订单跟踪'
,
},
{
index
:
'/pod-us-order/podUsSchedulingRules'
,
id
:
11
,
label
:
'POD(US)排单规则'
,
},
],
},
...
...
src/views/order/components/dialog.tsx
0 → 100644
View file @
da894e8f
import
{
defineComponent
,
ref
}
from
'vue'
import
{
ElDialog
}
from
'element-plus'
export
default
defineComponent
({
name
:
'CustomizeForm'
,
props
:
{
modelValue
:
{
type
:
Boolean
,
default
:
false
,
},
title
:
{
type
:
String
,
default
:
''
,
},
dialogWidth
:
{
type
:
String
,
default
:
'600px'
,
},
},
emits
:
[
'update:modelValue'
,
'close'
],
setup
(
props
,
{
emit
,
attrs
,
slots
})
{
const
formRef
=
ref
<
InstanceType
<
typeof
ElDialog
>
|
null
>
(
null
)
const
isShow
=
ref
(
false
)
watch
(
()
=>
props
.
modelValue
,
(
val
)
=>
{
isShow
.
value
=
val
},
{
immediate
:
true
},
)
return
()
=>
{
return
(
<
ElDialog
ref=
{
formRef
}
v
-
model=
{
isShow
.
value
}
title=
{
props
.
title
}
width=
{
props
.
dialogWidth
}
onClose=
{
()
=>
{
emit
(
'close'
)
}
}
destroy
-
on
-
close=
{
true
}
close
-
on
-
click
-
modal=
{
false
}
{
...
attrs
}
>
<
div
class=
"dialog-form"
>
{
slots
.
default
?.()
}
{
slots
.
footer
?.()
}
</
div
>
</
ElDialog
>
)
}
},
})
src/views/order/podUsSchedulingRules/index.vue
0 → 100644
View file @
da894e8f
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<el-button
type=
"success"
@
click=
"addDialog"
>
{{
'新增'
}}
</el-button>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
v-loading=
"loading"
>
<el-row
:gutter=
"20"
>
<el-col
v-for=
"(item, index) in tableData as rowData[]"
:key=
"index"
>
<div
class=
"address-item"
>
<div
class=
"left"
>
<div
class=
"box"
>
所有生产单按
{{
getLabels
(
item
.
groupField
)
}}
进行自动排单
</div>
<div
class=
"box"
>
批次数量:
{{
item
.
arrangeMax
}}
</div>
<div
class=
"box"
>
每天
{{
item
.
hour
}}
时开始自动排单
</div>
</div>
<div
class=
"action"
>
<el-icon
size=
"24"
title=
"编辑"
color=
"#EF6C00"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"editAddress(item)"
>
<Edit
/>
</el-icon>
</div>
</div>
</el-col>
<el-col
:span=
"24"
v-if=
"tableData.length === 0"
>
<div
class=
"empty-box"
>
<el-empty
description=
"暂无排单规则"
/>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
<LogDialog
:title=
"editForm.id ? '编辑排单规则' : '新增排单规则'"
v-model=
"dialogVisible"
dialogWidth=
"1000px"
@
close=
"cancelFn"
width=
"800px"
>
<div
class=
"cardBox"
>
<el-form
class=
"form"
ref=
"editFormRef"
label-width=
"270"
:model=
"editForm"
>
<div
class=
"formBox"
>
<div
class=
"formContent"
>
<div
v-for=
"(item, index) in paramsList"
:key=
"index"
class=
"select-row"
>
<el-form-item
:label=
"index == 0 ? `所有生产单按` : '按'"
prop=
"appKey"
>
<el-select
v-model=
"paramsList[index]"
placeholder=
"请选择"
style=
"width: 200px"
@
change=
"disabledFn"
:disabled=
"index == 0"
>
<el-option
v-for=
"option in rulesList"
:key=
"option.value"
:label=
"option.label"
:value=
"option.value"
:disabled=
"option.disabled"
/>
</el-select>
<div
class=
"iconClass"
v-if=
"index
<
3
&&
paramsList
.
length
<
4
"
@
click=
"addSelect(index)"
>
<el-icon
color=
"#fff"
size=
"20"
>
<Plus
/></el-icon>
</div>
<div
class=
"iconClass"
v-if=
"index !== 0"
@
click=
"removeSelect(index)"
>
<el-icon
color=
"#fff"
size=
"20"
><Minus
/></el-icon>
</div>
</el-form-item>
</div>
<el-form-item
label=
"在每天"
prop=
"hour"
:rules=
"[
{
required: true,
message: '请选择时间',
trigger: ['change', 'blur'],
},
]"
>
<div
style=
"display: flex"
>
<el-select
v-model=
"editForm.hour"
placeholder=
"请选择时"
style=
"width: 200px"
>
<el-option
v-for=
"(_, index) in 24"
:key=
"index"
:label=
"index"
:value=
"index"
/>
</el-select>
<div
style=
"white-space: nowrap; margin-left: 10px; color: #606266"
>
时进行自动排单
</div>
</div>
</el-form-item>
<div
style=
"border-top: 1px solid; color: #dcdfe6; padding-top: 10px"
>
<el-form-item
label=
"自动排单一个批次里生产单的最大值为:"
prop=
"arrangeMax"
:rules=
"[
{
required: true,
message: '请输入数量',
trigger: ['blur'],
},
]"
>
<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"
>
烫画工艺自动排版:
</div>
<el-switch
v-model=
"editForm.isAuto"
@
change=
"changeSwitch"
active-text=
"是"
inactive-text=
"否"
inline-prompt
class=
"ml-2"
style=
"
--el-switch-on-color: #42b983;
--el-switch-off-color: #f56c6c;
"
/>
</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>
</div>
</div>
</div>
<el-form-item>
<ElButton
class=
"btn"
@
click=
"cancelFn"
>
取消
</ElButton>
<ElButton
class=
"btn"
type=
"primary"
@
click=
"save"
>
保存
</ElButton>
</el-form-item>
</div>
</div>
</el-form>
</div>
</LogDialog>
</
template
>
<
script
setup
lang=
"tsx"
>
defineOptions
({
name
:
'ShippingAddress'
,
})
import
{
usArrangeRuleApi
,
getByFactoryNoApi
,
updateRuleByIdApi
,
}
from
'@/api/podUsSchedulingRules.ts'
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'
const
editForm
=
ref
<
BaseForm
>
({
isAuto
:
false
})
const
tableData
=
ref
([])
import
userUserStore
from
'@/store/user'
const
userStore
=
userUserStore
()
const
userInfo
=
userStore
.
user
const
loading
=
ref
(
false
)
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
result
=
await
getByFactoryNoApi
({
factoryNo
:
userInfo
?.
factoryId
as
number
,
})
tableData
.
value
=
result
.
data
?
[
result
.
data
]
:
[]
console
.
log
(
231
,
tableData
.
value
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
value
=
false
}
}
onMounted
(()
=>
{
getList
()
})
const
dialogVisible
=
ref
(
false
)
const
editFormRef
=
ref
<
InstanceType
<
typeof
CustomizeForm
>
|
null
>
(
null
)
const
paramsList
=
ref
([
'craft_code'
])
const
rulesList
=
ref
([
{
label
:
'工艺'
,
value
:
'craft_code'
,
disabled
:
false
},
{
label
:
'款号'
,
value
:
'supplier_product_no'
,
disabled
:
false
},
{
label
:
'尺码'
,
value
:
'size'
,
disabled
:
false
},
{
label
:
'类型'
,
value
:
'customized_quantity'
,
disabled
:
false
},
])
/**
* @description: 取消按钮
*/
function
cancelFn
()
{
dialogVisible
.
value
=
false
editFormRef
.
value
?.
resetFields
()
}
/**
* @description: 编辑按钮
*/
async
function
editAddress
(
item
:
rowData
)
{
try
{
editForm
.
value
=
{
...
item
}
paramsList
.
value
=
item
.
groupField
.
split
(
';'
)
.
filter
((
value
)
=>
value
.
trim
()
!==
''
)
console
.
log
(
372
,
editForm
.
value
)
if
(
editForm
.
value
.
templateWidth
)
{
editForm
.
value
.
isAuto
=
true
}
dialogVisible
.
value
=
true
}
catch
(
e
)
{
console
.
log
(
e
)
}
}
/**
* @description: 检查数据
*/
interface
rowData
extends
BaseForm
{
groupField
:
string
}
interface
BaseForm
{
id
?:
number
hour
?:
number
arrangeMax
?:
number
isAuto
?:
boolean
factoryNo
?:
number
type
?:
string
templateWidth
?:
string
jobId
?:
string
}
type
ParamKey
=
`param
${
number
}
`
type
ParamValue
=
string
|
number
|
boolean
|
null
|
undefined
type
PostData
=
BaseForm
&
Record
<
ParamKey
,
ParamValue
>
async
function
checkData
()
{
// 先进行表单校验
const
isValid
=
await
new
Promise
<
boolean
>
((
resolve
)
=>
{
editFormRef
.
value
?.
validate
()
.
then
(()
=>
resolve
(
true
))
.
catch
((
err
)
=>
{
console
.
log
(
'表单校验失败:'
,
err
)
resolve
(
false
)
})
})
// 如果表单校验失败,直接返回,不处理数据
if
(
!
isValid
)
{
return
{
isValid
:
false
,
postData
:
null
}
}
// 表单校验通过后,再处理数据
const
postData
:
PostData
=
{
...
editForm
.
value
}
paramsList
.
value
.
forEach
((
el
:
ParamValue
,
index
:
number
)
=>
{
const
key
:
ParamKey
=
`param
${
index
+
1
}
`
if
(
el
)
{
postData
[
key
]
=
el
}
})
postData
.
factoryNo
=
userInfo
?.
factoryId
return
{
isValid
,
postData
}
}
/**
* @description: 保存按钮
*/
const
save
=
debounce
(
async
()
=>
{
const
{
isValid
,
postData
}
=
await
checkData
()
if
(
isValid
)
{
try
{
if
(
!
postData
?.
id
)
{
await
usArrangeRuleApi
({
...
postData
,
})
}
else
{
const
params
=
{
param
:
{
...
postData
},
id
:
postData
.
id
,
jobId
:
postData
.
jobId
,
}
params
.
param
.
id
&&
delete
params
.
param
.
id
params
.
param
.
jobId
&&
delete
params
.
param
.
jobId
await
updateRuleByIdApi
({
...
params
,
})
}
ElMessage
({
message
:
postData
?.
id
?
'更新成功'
:
'新增成功'
,
type
:
'success'
,
offset
:
window
.
innerHeight
/
2
,
})
getList
()
cancelFn
()
}
catch
(
e
)
{
return
}
}
},
200
)
const
disabledFn
=
()
=>
{
console
.
log
(
328
,
paramsList
.
value
)
rulesList
.
value
.
forEach
((
el
)
=>
{
if
(
paramsList
.
value
.
includes
(
el
.
value
))
{
el
.
disabled
=
true
}
else
{
el
.
disabled
=
false
}
})
}
const
addSelect
=
(
index
:
number
)
=>
{
paramsList
.
value
.
splice
(
index
+
1
,
0
,
''
)
disabledFn
()
}
const
removeSelect
=
(
index
:
number
)
=>
{
// selectItems.value.splice(index, 1)
paramsList
.
value
.
splice
(
index
,
1
)
disabledFn
()
}
const
getLabels
=
(
item
:
string
)
=>
{
if
(
!
item
)
return
''
const
ruleValues
=
new
Set
(
item
.
split
(
';'
))
return
rulesList
.
value
.
filter
((
rule
)
=>
ruleValues
.
has
(
rule
.
value
))
.
map
((
rule
)
=>
rule
.
label
)
.
join
(
','
)
}
/**
* @description: 新增按钮打开弹窗
*/
function
addDialog
()
{
editForm
.
value
=
{
isAuto
:
false
}
paramsList
.
value
=
[
'craft_code'
]
dialogVisible
.
value
=
true
}
const
changeSwitch
=
()
=>
{
editForm
.
value
.
type
=
undefined
editForm
.
value
.
templateWidth
=
undefined
}
</
script
>
<
style
lang=
"scss"
scoped
>
.header-filter-form
{
margin-bottom
:
20px
;
:deep(.el-form-item)
{
margin-right
:
14px
;
margin-bottom
:
10px
;
}
}
.user-operate-btn
{
margin-bottom
:
10px
;
}
.dialog-footer
{
text-align
:
center
;
}
:deep
()
{
.rowClass
{
background-color
:
red
;
}
}
.address-item
{
box-sizing
:
border-box
;
padding
:
10px
;
margin-bottom
:
10px
;
border
:
1px
solid
#ececec
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.check
{
margin-right
:
10px
;
}
.left
{
flex
:
1
;
flex-shrink
:
0
;
overflow
:
hidden
;
margin-right
:
10px
;
display
:
flex
;
.box
{
margin-right
:
20px
;
}
}
.address
{
margin-bottom
:
10px
;
font-size
:
14px
;
overflow
:
hidden
;
/* 确保超出的文本被裁剪 */
white-space
:
nowrap
;
/* 确保文本在一行内显示 */
text-overflow
:
ellipsis
;
/* 超出的文本显示为省略号 */
width
:
100%
;
}
.action
{
.iconView
{
}
}
.name
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
10px
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
p
{
flex
:
1
;
flex-shrink
:
0
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
margin
:
0
10px
;
font-size
:
14px
;
}
b
{
font-size
:
17px
;
}
span
{
margin
:
0
10px
;
font-size
:
14px
;
}
}
}
.iconClass
{
cursor
:
pointer
;
width
:
32px
;
height
:
32px
;
background-color
:
#409eff
;
text-align
:
center
;
border-radius
:
5px
;
margin-left
:
10px
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
</
style
>
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