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
7f8b5b7f
Commit
7f8b5b7f
authored
Jul 27, 2026
by
wusiyi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev_logistic_sort_rule' into release_v2.31.0
parents
d366ea17
5627765b
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
657 additions
and
648 deletions
+657
-648
src/api/logistics.ts
+39
-16
src/types/api/logistics.ts
+27
-4
src/views/logistics/components/CreateSortingRuleDialog.vue
+449
-0
src/views/logistics/sortingConfiguration.vue
+142
-628
No files found.
src/api/logistics.ts
View file @
7f8b5b7f
...
...
@@ -11,7 +11,11 @@ import { AddDeclarationRuleObj } from '@/views/logistics/types/declarationRule'
import
{
LogisticsQuotation
}
from
'@/views/logistics/types/logisticsQuotation'
import
{
LogisticsPartitionObj
}
from
'@/views/logistics/types/logisticsPartition'
import
{
ShippingAddressObj
}
from
'@/views/logistics/types/shippingAddress'
import
{
IsortingInfo
}
from
'@/types/api/logistics'
import
{
IsortingInfo
,
SortingPortAreaItem
,
SortingPortOptionItem
,
}
from
'@/types/api/logistics'
export
interface
ILogisticsList
{
code
:
string
basicsName
:
string
...
...
@@ -168,9 +172,12 @@ export function getLogisticsWayListByCompanyId(companyId: number) {
}
// 获取tictok物流承运商
export
function
getTiktokCarrier
()
{
return
axios
.
get
<
never
,
BaseRespData
<
{
name
:
string
;
id
:
string
,
typeCode
:
string
,
label
:
string
}[]
>>
(
'logisticsWay/getTiktokShippingProvider'
,
)
return
axios
.
get
<
never
,
BaseRespData
<
{
name
:
string
;
id
:
string
;
typeCode
:
string
;
label
:
string
}[]
>
>
(
'logisticsWay/getTiktokShippingProvider'
)
}
/**
...
...
@@ -461,16 +468,14 @@ export function logisticsCompanyAllCodelist() {
'/logisticsCompany/allCodelist'
,
)
}
/**
分拣配置
*/
// 物流 分拣配置
export
function
getsortingConfigListApi
(
data
:
IsortingInfo
,
currentPage
:
number
,
pageSize
:
number
,
)
{
return
axios
.
post
<
never
,
BasePaginationData
<
IsortingInfo
>>
(
'logistics
/sortingC
onfig/list_page'
,
'logistics
-sort-port-c
onfig/list_page'
,
{
...
data
,
currentPage
,
...
...
@@ -481,34 +486,52 @@ export function getsortingConfigListApi(
// 详情
export
function
getSortingConfig
(
params
:
{
id
:
number
|
string
})
{
return
axios
.
get
<
never
,
BaseRespData
<
IsortingInfo
>>
(
'logistics
/sortingC
onfig/get'
,
'logistics
-sort-port-c
onfig/get'
,
{
params
},
)
}
export
function
createSortingApi
(
data
:
IsortingInfo
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'logistics
/sortingC
onfig/add'
,
'logistics
-sort-port-c
onfig/add'
,
data
,
)
}
export
function
updateSortingApi
(
data
:
IsortingInfo
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'logistics
/sortingC
onfig/update'
,
'logistics
-sort-port-c
onfig/update'
,
data
,
)
}
export
function
deleteSortingApi
(
params
:
{
ids
:
string
type
:
string
|
number
})
{
export
function
deleteSortingApi
(
params
:
{
id
:
number
})
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'logistics
/sortingC
onfig/delete'
,
'logistics
-sort-port-c
onfig/delete'
,
{
params
,
},
)
}
// 分拣配置 查询可用分拣口
export
function
getSortingPortAreaListApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
SortingPortAreaItem
[]
>>
(
'logistics-sort-port-config/area-list'
,
)
}
// 分拣口规则 条件类型
export
function
getSortPortConditionTypeListApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
SortingPortOptionItem
[]
>>
(
'logistics-sort-port-config/condition-type'
,
)
}
// 分拣口规则 操作符
export
function
getSortPortOperatorListApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
SortingPortOptionItem
[]
>>
(
'logistics-sort-port-config/operator-list'
,
)
}
// 物流跟踪 获取菜单树
export
function
logisticStatusList
()
{
return
axios
.
get
<
never
,
BaseRespData
<
LogisticsTrackingTree
[]
>>
(
...
...
src/types/api/logistics.ts
View file @
7f8b5b7f
...
...
@@ -15,11 +15,34 @@ export interface Ilogistics {
createTime
?:
string
updateTime
?:
string
|
null
}
export
interface
SortingPortCondition
{
id
?:
number
ruleId
?:
number
conditionType
:
string
operator
:
string
conditionValue
?:
string
|
number
|
string
[]
}
export
interface
IsortingInfo
{
id
?:
number
sorting
Facility
?:
string
|
null
sortingArea
:
number
|
null
sorting
Remark
?:
string
sortingArea
?
:
number
|
null
sortingAreaName
?:
string
|
null
serviceCode
:
string
|
null
type
?:
string
|
number
matchType
?:
1
|
2
sortNo
?:
number
conditions
?:
SortingPortCondition
[]
conditionsText
?:
string
}
export
interface
SortingPortAreaItem
{
code
:
number
desc
:
string
used
:
boolean
}
export
interface
SortingPortOptionItem
{
desc
:
string
code
:
string
used
?:
boolean
}
src/views/logistics/components/CreateSortingRuleDialog.vue
0 → 100644
View file @
7f8b5b7f
<
template
>
<ElDialog
v-model=
"visible"
:title=
"isEdit ? '编辑分拣口' : '新增分拣口'"
:close-on-click-modal=
"false"
width=
"800px"
destroy-on-close
>
<el-form
ref=
"formRef"
label-width=
"120px"
:model=
"form"
:rules=
"rules"
>
<el-form-item
label=
"分拣口说明"
prop=
"sortingRemark"
>
<el-input
v-model=
"form.sortingRemark"
style=
"width: 100%"
clearable
maxlength=
"100"
show-word-limit
placeholder=
"请输入分拣口说明"
/>
</el-form-item>
<el-form-item
label=
"分拣口"
prop=
"sortingArea"
>
<el-select
v-model=
"form.sortingArea"
style=
"width: 200px"
placeholder=
"请选择"
>
<el-option
v-for=
"item in areaList"
:key=
"item.code"
:label=
"item.desc"
:value=
"item.code"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"分拣口规则"
prop=
"conditions"
>
<div
class=
"sorting-rules"
>
<div
class=
"header"
>
<span
class=
"mr-10"
>
满足条件
</span>
<el-radio-group
v-model=
"form.matchType"
>
<el-radio
:value=
"1"
>
满足以下所有条件
</el-radio>
<el-radio
:value=
"2"
>
满足以下任一条件
</el-radio>
</el-radio-group>
</div>
<div
v-for=
"(item, index) in form.conditions"
:key=
"index"
class=
"content"
>
<el-select
v-model=
"item.conditionType"
style=
"width: 160px"
placeholder=
"请选择分拣口规则"
@
change=
"handleConditionTypeChange(item)"
>
<el-option
v-for=
"rule in getAvailableConditionTypes(index)"
:key=
"rule.code"
:label=
"rule.desc"
:value=
"rule.code"
/>
</el-select>
<el-select
v-model=
"item.operator"
style=
"width: 160px"
placeholder=
"请选择关系"
>
<el-option
v-for=
"operator in operatorList"
:key=
"operator.code"
:label=
"operator.desc"
:value=
"operator.code"
/>
</el-select>
<template
v-if=
"item.conditionType === 'order_platform'"
>
<el-select
v-model=
"item.conditionValue"
class=
"platform-select"
style=
"width: 160px"
placeholder=
"请选择平台"
filterable
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags=
"1"
clearable
popper-class=
"customize-select-style"
>
<el-option
v-for=
"platform in platformList"
:key=
"platform.type"
:label=
"platform.type"
:value=
"platform.type"
style=
"width: 160px"
>
<img
:src=
"`/images/icon/$
{platform.icon.split('/').pop()}`"
style="height: 20px; margin: 5px 10px 0 0"
/>
<span
:title=
"platform.type"
>
{{
platform
.
type
}}
</span>
</el-option>
</el-select>
</
template
>
<
template
v-else
>
<el-select
v-model=
"item.conditionValue"
class=
"platform-select"
style=
"width: 160px"
placeholder=
"请选择物流公司"
filterable
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags=
"1"
clearable
>
<el-option
v-for=
"logistics in logisticsMethodsList"
:key=
"logistics.code"
:label=
"logistics.basicsName"
:value=
"logistics.code"
/>
</el-select>
</
template
>
<el-button
v-if=
"
(form.conditions?.length ?? 0) <
(conditionTypeList?.length ?? 0)
"
type=
"primary"
class=
"rule-action-btn"
:icon=
"Plus"
size=
"small"
circle
@
click=
"addConditionItem"
/>
<el-button
v-if=
"(form.conditions?.length ?? 0) > 1"
color=
"#F56C6C"
class=
"rule-action-btn"
:icon=
"Minus"
size=
"small"
circle
plain
@
click=
"removeConditionItem(index)"
/>
</div>
</div>
</el-form-item>
<el-form-item
label=
"序号"
prop=
"sortNo"
>
<el-input-number
v-model=
"form.sortNo"
:min=
"1"
:max=
"999"
style=
"width: 200px"
step-strictly
controls-position=
"right"
placeholder=
"请输入序号"
/>
</el-form-item>
<el-form-item>
<span
class=
"item-info"
>
分拣配置逻辑冲突时,优先执行更小的序号
</span>
</el-form-item>
</el-form>
<
template
#
footer
>
<div
class=
"flex flex-center"
>
<el-button
@
click=
"visible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
确定
</el-button>
</div>
</
template
>
</ElDialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
}
from
'vue'
import
{
Plus
,
Minus
}
from
'@element-plus/icons-vue'
import
type
{
FormInstance
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
platformJson
from
'@/json/platform.json'
import
type
{
Ilogistics
,
IsortingInfo
,
SortingPortAreaItem
,
SortingPortCondition
,
SortingPortOptionItem
,
}
from
'@/types/api/logistics'
import
{
createSortingApi
,
updateSortingApi
,
getSortingConfig
,
getSortingPortAreaListApi
,
getSortPortConditionTypeListApi
,
getSortPortOperatorListApi
,
}
from
'@/api/logistics'
const
conditionTypeList
=
ref
<
SortingPortOptionItem
[]
>
()
const
operatorList
=
ref
<
SortingPortOptionItem
[]
>
()
defineProps
<
{
logisticsMethodsList
:
Ilogistics
[]
}
>
()
const
emit
=
defineEmits
<
{
success
:
[]
}
>
()
const
visible
=
ref
(
false
)
const
isEdit
=
ref
(
false
)
const
formRef
=
ref
<
FormInstance
>
()
const
areaList
=
ref
<
SortingPortAreaItem
[]
>
([])
const
editId
=
ref
<
number
>
()
const
createConditionItem
=
():
SortingPortCondition
=>
({
conditionType
:
''
,
operator
:
''
,
conditionValue
:
[],
})
const
createDefaultForm
=
():
IsortingInfo
=>
({
sortingRemark
:
''
,
sortingArea
:
null
,
sortingAreaName
:
''
,
matchType
:
1
,
sortNo
:
1
,
conditions
:
[
createConditionItem
()],
})
const
form
=
ref
<
IsortingInfo
>
(
createDefaultForm
())
const
getAvailableConditionTypes
=
(
currentIndex
:
number
)
=>
{
const
selectedFields
=
(
form
.
value
.
conditions
??
[])
.
filter
((
_
,
index
)
=>
index
!==
currentIndex
)
.
map
((
item
)
=>
item
.
conditionType
)
return
conditionTypeList
.
value
?.
filter
(
(
rule
)
=>
!
selectedFields
.
includes
(
rule
.
code
),
)
}
const
handleConditionTypeChange
=
(
item
:
SortingPortCondition
)
=>
{
item
.
conditionValue
=
[]
item
.
operator
=
'in'
}
const
validateConditions
=
(
_rule
:
unknown
,
_value
:
unknown
,
callback
:
(
error
?:
Error
)
=>
void
,
)
=>
{
const
items
=
form
.
value
.
conditions
??
[]
for
(
let
i
=
0
;
i
<
items
.
length
;
i
++
)
{
const
item
=
items
[
i
]
const
isValueValid
=
Array
.
isArray
(
item
.
conditionValue
)
&&
item
.
conditionValue
.
length
>
0
if
(
!
item
.
conditionType
||
!
isValueValid
||
!
item
.
operator
)
{
callback
(
new
Error
(
'请完善分拣口规则'
))
return
}
}
callback
()
}
const
rules
=
computed
(()
=>
({
sortingRemark
:
[
{
required
:
true
,
message
:
'请输入分拣口说明'
,
trigger
:
'blur'
},
],
sortingArea
:
[{
required
:
true
,
message
:
'请选择分拣口'
,
trigger
:
'change'
}],
conditions
:
[
{
validator
:
validateConditions
,
trigger
:
'blur'
},
{
required
:
true
,
message
:
'请完善分拣口规则'
,
trigger
:
'change'
},
],
sortNo
:
[{
required
:
true
,
message
:
'请输入序号'
,
trigger
:
'blur'
}],
}))
const
platformList
=
platformJson
const
formatConditionsForForm
=
(
conditions
:
SortingPortCondition
[])
=>
conditions
.
map
((
item
)
=>
({
...
item
,
conditionValue
:
typeof
item
.
conditionValue
===
'string'
?
item
.
conditionValue
.
split
(
','
).
filter
(
Boolean
)
:
Array
.
isArray
(
item
.
conditionValue
)
?
item
.
conditionValue
:
[],
}))
const
addConditionItem
=
()
=>
{
form
.
value
.
conditions
?.
push
(
createConditionItem
())
formRef
.
value
?.
validateField
(
'conditions'
)
}
const
removeConditionItem
=
(
index
:
number
)
=>
{
form
.
value
.
conditions
?.
splice
(
index
,
1
)
formRef
.
value
?.
validateField
(
'conditions'
)
}
const
loadAreaList
=
async
()
=>
{
const
res
=
await
getSortingPortAreaListApi
()
if
(
res
.
code
!==
200
)
return
if
(
!
isEdit
.
value
)
{
areaList
.
value
=
res
.
data
.
filter
((
item
)
=>
item
.
used
===
false
)
}
else
{
areaList
.
value
=
res
.
data
.
filter
(
(
item
)
=>
item
.
used
===
false
||
item
.
code
===
form
.
value
.
sortingArea
,
)
}
}
const
loadConditionTypeList
=
async
()
=>
{
const
res
=
await
getSortPortConditionTypeListApi
()
if
(
res
.
code
!==
200
)
return
conditionTypeList
.
value
=
res
.
data
}
const
loadOperatorList
=
async
()
=>
{
const
res
=
await
getSortPortOperatorListApi
()
if
(
res
.
code
!==
200
)
return
operatorList
.
value
=
res
.
data
}
const
handleSubmit
=
async
()
=>
{
await
formRef
.
value
?.
validate
()
const
submitData
:
IsortingInfo
=
{
...
form
.
value
,
conditions
:
(
form
.
value
.
conditions
??
[]).
map
(
(
item
):
SortingPortCondition
=>
({
...
item
,
conditionValue
:
Array
.
isArray
(
item
.
conditionValue
)
?
item
.
conditionValue
.
join
(
','
)
:
item
.
conditionValue
,
}),
),
}
const
res
=
isEdit
.
value
?
await
updateSortingApi
({
...
submitData
,
id
:
editId
.
value
})
:
await
createSortingApi
(
submitData
)
if
(
res
.
code
!==
200
)
return
ElMessage
.
success
(
isEdit
.
value
?
'编辑成功'
:
'新增成功'
)
visible
.
value
=
false
emit
(
'success'
)
}
const
open
=
async
(
item
?:
IsortingInfo
)
=>
{
isEdit
.
value
=
!!
item
editId
.
value
=
item
?.
id
form
.
value
=
createDefaultForm
()
await
Promise
.
all
([
loadConditionTypeList
(),
loadOperatorList
()])
if
(
item
?.
id
)
{
const
res
=
await
getSortingConfig
({
id
:
item
.
id
})
if
(
res
.
code
!==
200
)
return
const
conditions
=
formatConditionsForForm
(
res
.
data
.
conditions
??
[])
form
.
value
=
{
...
res
.
data
,
conditions
:
conditions
.
length
?
conditions
:
[
createConditionItem
()],
}
}
await
loadAreaList
()
visible
.
value
=
true
formRef
.
value
?.
clearValidate
()
}
defineExpose
({
open
})
</
script
>
<
style
scoped
lang=
"scss"
>
.item-info
{
font-size
:
12px
;
color
:
#666
;
line-height
:
1
;
margin-top
:
-15px
;
}
.sorting-rules
{
background-color
:
#eee
;
border-radius
:
3px
;
padding
:
5px
15px
;
width
:
100%
;
.header
{
font-size
:
12px
;
font-weight
:
500
;
display
:
flex
;
align-items
:
center
;
:deep(.el-radio__label)
{
font-size
:
12px
;
}
}
.content
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
margin-top
:
8px
;
&:first-of-type
{
margin-top
:
6px
;
}
}
.rule-action-btn
{
font-size
:
16px
;
}
.platform-select
{
:deep(.el-select__wrapper)
{
height
:
var
(
--el-component-size
);
min-height
:
var
(
--el-component-size
);
box-sizing
:
border-box
;
}
:deep
(
.el-select__selection
)
{
flex-wrap
:
nowrap
;
}
:deep
(
.el-select__selected-item
)
{
flex-shrink
:
1
;
min-width
:
0
;
overflow
:
hidden
;
}
:deep
(
.el-tag
)
{
max-width
:
100%
;
.el-tag__content
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
}
</
style
>
<
style
lang=
"scss"
>
.customize-select-style
{
.el-select-dropdown__list
{
width
:
500px
;
display
:
flex
;
flex-wrap
:
wrap
;
}
}
</
style
>
src/views/logistics/sortingConfiguration.vue
View file @
7f8b5b7f
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<div
class=
"flex-column h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<el-form
ref=
"searchFormRef"
inline
:model=
"searchForm"
>
<el-form-item
label=
"分拣口"
>
<el-select
v-model=
"searchForm.sortingArea"
clearable
style=
"width: 160px"
placeholder=
"请选择分拣口"
>
<el-option
v-for=
"item in sortingList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"分拣口说明"
>
<el-input
v-model=
"searchForm.sortingRemark"
placeholder=
"请输入分拣口说明"
clearable
style=
"width: 220px"
/>
</el-form-item>
<el-form-item>
<el-button
ref=
"searchBtnRef"
type=
"primary"
@
click=
"search"
>
查询
</el-button
>
<el-button
type=
"success"
@
click=
"createWarehouse"
>
新增
</el-button>
</el-form-item>
</el-form>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<div
v-loading=
"loading"
class=
"table-container"
>
<TableView
:paginated-data=
"tableData"
:columns=
"columns"
>
<template
#
operation=
"
{ row }">
<el-button
type=
"primary"
link
@
click=
"updateSorting(row)"
>
编辑
</el-button>
<el-button
type=
"danger"
link
@
click=
"handleBatchDelete(row)"
>
删除
</el-button>
</
template
>
</TableView>
</div>
</div>
<ElPagination
v-model:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:page-sizes=
"[100, 200, 300, 400, 500]"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"total"
style=
"margin: 10px auto 0; text-align: right"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
></ElPagination>
</div>
</div>
<CreateSortingRuleDialog
ref=
"createDialogRef"
:logistics-methods-list=
"logisticsMethodsList"
@
success=
"search"
/>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
Ilogistics
,
IsortingInfo
}
from
'@/types/api/logistics'
import
{
Edit
,
Delete
,
// CirclePlus,
QuestionFilled
,
}
from
'@element-plus/icons-vue'
import
platformJson
from
'@/json/platform.json'
// import useImagePreview from '@/utils/hooks/useImagePreview.'
// const { mouseoverImg, mouseleaveImg } = useImagePreview()
import
sortingImg
from
'@/assets/images/分拣口说明.png'
import
{
getsortingConfigListApi
,
// usableAllList,
createSortingApi
,
updateSortingApi
,
deleteSortingApi
,
getSorting
Config
,
getSorting
PortAreaListApi
,
}
from
'@/api/logistics'
import
{
allErpCodeListApi
}
from
'@/api/podCnOrder'
import
{
nextTick
,
ref
}
from
'vue'
import
{
ref
}
from
'vue'
import
CreateSortingRuleDialog
from
'./components/CreateSortingRuleDialog.vue'
import
{
useEnterKeyTrigger
}
from
'@/utils/hooks/useEnterKeyTrigger.ts'
import
TableView
from
'@/components/TableView.vue'
import
type
{
CustomColumn
}
from
'@/types/table'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
interface
InterForm
{
id
?:
number
sortingFacility
?:
string
|
null
sortingArea
:
number
|
null
sortingAreaName
?:
string
|
null
serviceCode
:
string
[]
}
const
searchForm
=
ref
({
sortingFacility
:
''
,
sortingArea
:
null
,
serviceCode
:
[],
})
const
selections
=
ref
<
IsortingInfo
[]
>
([])
const
formRef
=
ref
()
const
form
=
ref
<
InterForm
>
({
sortingFacility
:
''
,
sortingArea
:
null
,
sortingAreaName
:
''
,
serviceCode
:
[],
})
const
createData
=
ref
({
title
:
''
,
show
:
false
,
isEdit
:
false
,
form
:
{
sortingFacility
:
''
,
sortingArea
:
null
,
sortingAreaName
:
''
,
serviceCode
:
[],
},
})
const
activeName
=
ref
(
'1'
)
const
rules
=
computed
(()
=>
{
return
{
sortingFacility
:
[
{
required
:
true
,
message
:
'请输入分拣设备'
,
trigger
:
'blur'
},
],
sortingArea
:
[
{
required
:
true
,
message
:
'请选择分拣口'
,
trigger
:
'change'
},
],
serviceCode
:
[
const
columns
:
CustomColumn
<
IsortingInfo
>
[]
=
[
{
required
:
true
,
message
:
`请选择
${
activeName
.
value
==
'1'
?
'物流公司'
:
'平台'
}
`
,
trigger
:
'change'
,
key
:
'sortNo'
,
prop
:
'sortNo'
,
label
:
'序号'
,
width
:
100
,
align
:
'center'
,
},
],
}
{
key
:
'conditionsText'
,
prop
:
'conditionsText'
,
label
:
'分拣口规则'
,
minWidth
:
250
,
align
:
'left'
,
},
{
key
:
'sortingAreaName'
,
prop
:
'sortingAreaName'
,
label
:
'分拣口'
,
width
:
100
,
align
:
'center'
,
},
{
key
:
'sortingRemark'
,
prop
:
'sortingRemark'
,
label
:
'分拣口说明'
,
minWidth
:
200
,
align
:
'left'
,
},
{
key
:
'operation'
,
label
:
'操作'
,
width
:
130
,
align
:
'center'
,
slot
:
'operation'
,
},
]
const
searchForm
=
ref
({
sortingArea
:
null
,
sortingRemark
:
''
,
})
const
createDialogRef
=
ref
<
InstanceType
<
typeof
CreateSortingRuleDialog
>>
()
const
{
loading
,
currentPage
,
pageSize
,
total
,
...
...
@@ -87,8 +142,6 @@ const {
getsortingConfigListApi
(
{
...
searchForm
.
value
,
serviceCode
:
searchForm
.
value
.
serviceCode
.
join
(
','
),
type
:
activeName
.
value
,
},
page
,
pageSize
,
...
...
@@ -107,96 +160,21 @@ const getlogisticsMethods = async () => {
]
}
interface
interSorting
{
interface
SortingOption
{
label
:
string
value
:
number
}
const
sortingList
=
ref
<
interSorting
[]
>
([
{
label
:
'L1'
,
value
:
1
,
},
{
label
:
'R1'
,
value
:
2
,
},
{
label
:
'L2'
,
value
:
3
,
},
{
label
:
'R2'
,
value
:
4
,
},
{
label
:
'L3'
,
value
:
5
,
},
{
label
:
'R3'
,
value
:
6
,
},
{
label
:
'L4'
,
value
:
7
,
},
{
label
:
'R4'
,
value
:
8
,
},
{
label
:
'L5'
,
value
:
9
,
},
{
label
:
'R5'
,
value
:
10
,
},
{
label
:
'L6'
,
value
:
11
,
},
{
label
:
'R6'
,
value
:
12
,
},
{
label
:
'L7'
,
value
:
13
,
},
{
label
:
'R7'
,
value
:
14
,
},
{
label
:
'E0'
,
value
:
99
,
},
])
const
handleSelectionChange
=
(
data
:
IsortingInfo
[])
=>
{
selections
.
value
=
data
}
const
handleConfirm
=
async
()
=>
{
await
formRef
.
value
?.
validate
()
if
(
!
createData
.
value
.
isEdit
)
{
await
createSortingApi
({
...
form
.
value
,
serviceCode
:
form
.
value
.
serviceCode
.
join
(
','
),
type
:
activeName
.
value
,
})
}
else
{
await
updateSortingApi
({
...
form
.
value
,
serviceCode
:
form
.
value
.
serviceCode
.
join
(
','
),
type
:
activeName
.
value
,
})
}
createData
.
value
.
show
=
false
ElMessage
.
success
(
'操作成功'
)
await
search
()
const
sortingList
=
ref
<
SortingOption
[]
>
([])
const
getSortingList
=
async
()
=>
{
const
res
=
await
getSortingPortAreaListApi
()
sortingList
.
value
=
(
res
.
data
||
[]).
map
((
item
)
=>
({
label
:
item
.
desc
,
value
:
item
.
code
,
}))
}
const
handleBatchDelete
=
async
(
row
:
IsortingInfo
|
null
)
=>
{
if
(
!
row
&&
!
selections
.
value
.
length
)
{
if
(
!
row
?.
id
)
{
return
ElMessage
.
warning
(
'请选择要删除的数据'
)
}
await
ElMessageBox
.
confirm
(
'确定要删除吗?'
,
'提示'
,
{
...
...
@@ -204,503 +182,45 @@ const handleBatchDelete = async (row: IsortingInfo | null) => {
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
const
str
=
row
&&
row
.
id
?
row
.
id
?.
toString
()
:
selections
.
value
.
map
((
el
:
IsortingInfo
)
=>
el
.
id
).
join
(
','
)
await
deleteSortingApi
({
ids
:
str
,
type
:
activeName
.
value
})
await
deleteSortingApi
({
id
:
row
.
id
})
ElMessage
.
success
(
'删除成功'
)
search
()
}
// const addLogistics = () => {
// ElMessageBox.prompt('', '物流方式', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// inputErrorMessage: '请输入物流方式',
// inputPlaceholder: '请输入物流方式',
// }).then(({ value }: { value: string }) => {
// if (!value.trim()) {
// ElMessage.error('物流方式不能为空')
// return
// }
// if (form.value.serviceCode.includes(value)) {
// ElMessage.warning('物流方式已存在')
// return
// }
// form.value.serviceCode.push(value)
// ElMessage.success('添加成功')
// })
// }
const
createWarehouse
=
()
=>
{
createData
.
value
.
show
=
true
createData
.
value
.
isEdit
=
false
createData
.
value
.
title
=
'新增'
form
.
value
=
{
sortingFacility
:
''
,
sortingArea
:
null
,
sortingAreaName
:
''
,
serviceCode
:
[],
}
nextTick
(()
=>
{
formRef
.
value
?.
clearValidate
()
})
createDialogRef
.
value
?.
open
()
}
const
updateSorting
=
async
(
item
:
IsortingInfo
)
=>
{
const
updateSorting
=
(
item
:
IsortingInfo
)
=>
{
if
(
!
item
)
return
createData
.
value
.
show
=
true
createData
.
value
.
isEdit
=
true
createData
.
value
.
title
=
'修改'
const
res
=
await
getSortingConfig
({
id
:
item
.
id
as
number
|
string
})
if
(
res
.
code
!==
200
)
return
const
{
serviceCode
,
...
rest
}
=
res
.
data
form
.
value
=
{
...
rest
,
serviceCode
:
serviceCode
?
serviceCode
.
split
(
','
)
:
[],
}
nextTick
(()
=>
{
formRef
.
value
?.
clearValidate
()
})
}
getlogisticsMethods
()
const
sortingChange
=
(
v
:
number
)
=>
{
const
warehouse
=
sortingList
.
value
.
find
((
w
:
interSorting
)
=>
w
.
value
==
v
)
form
.
value
.
sortingAreaName
=
warehouse
?
warehouse
.
label
:
''
createDialogRef
.
value
?.
open
(
item
)
}
const
handleClick
=
()
=>
{
const
loading
=
ElLoading
.
service
({
fullscreen
:
true
,
text
:
'操作中...'
,
background
:
'rgba(0, 0, 0, 0.3)'
,
})
try
{
searchForm
.
value
=
{
sortingFacility
:
''
,
sortingArea
:
null
,
serviceCode
:
[],
}
search
()
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
close
()
}
}
onMounted
(
async
()
=>
{
await
Promise
.
all
([
getSortingList
(),
getlogisticsMethods
()])
})
const
searchFormRef
=
ref
()
const
searchBtnRef
=
ref
()
useEnterKeyTrigger
({
formRef
:
searchFormRef
,
btnRef
:
searchBtnRef
,
callback
:
(
event
:
KeyboardEvent
)
=>
{
console
.
log
(
'回车键被按下'
,
event
)
callback
:
()
=>
{
search
()
},
})
</
script
>
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<el-tabs
v-model=
"activeName"
type=
"card"
class=
"demo-tabs"
@
tab-change=
"handleClick"
>
<el-tab-pane
label=
"按物流方式分拣(优先级高)"
name=
"1"
class=
"flex-column h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<el-form
inline
:model=
"searchForm"
ref=
"searchFormRef"
>
<el-form-item
label=
"分拣设备"
>
<el-input
v-model
.
trim=
"searchForm.sortingFacility"
placeholder=
"分拣设备"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"分拣口"
>
<el-select
v-model=
"searchForm.sortingArea"
clearable
style=
"width: 160px"
>
<el-option
v-for=
"item in sortingList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"物流公司"
>
<el-select
v-model=
"searchForm.serviceCode"
clearable
filterable
multiple
collapse-tags
collapse-tags-tooltip
style=
"width: 220px"
>
<el-option
v-for=
"item in logisticsMethodsList"
:key=
"item.code"
:label=
"item.basicsName"
:value=
"item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"search"
ref=
"searchBtnRef"
>
查询
</el-button
>
<el-button
type=
"success"
@
click=
"createWarehouse"
>
新增
</el-button
>
<el-button
type=
"danger"
@
click=
"handleBatchDelete(null)"
>
删除
</el-button
>
</el-form-item>
</el-form>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<el-table
height=
"100%"
:data=
"tableData"
border
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
/>
<el-table-column
type=
"index"
label=
"序号"
width=
"60"
align=
"center"
/>
<el-table-column
align=
"center"
label=
"分拣设备"
show-overflow-tooltip
prop=
"sortingFacility"
></el-table-column>
<el-table-column
align=
"center"
label=
"分拣口名称"
prop=
"sortingAreaName"
>
</el-table-column>
<el-table-column
align=
"center"
label=
"物流公司"
show-overflow-tooltip
prop=
"serviceCode"
></el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"100"
>
<template
#
default=
"
{ row }">
<el-icon
size=
"24"
title=
"编辑"
color=
"#EF6C00"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"updateSorting(row)"
>
<Edit
/>
</el-icon>
<el-icon
size=
"24"
title=
"删除"
color=
"#f56c6c"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"handleBatchDelete(row)"
>
<Delete
/>
</el-icon>
</
template
>
</el-table-column>
</el-table>
</div>
<ElPagination
v-model:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:page-sizes=
"[100, 200, 300, 400, 500]"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"total"
style=
"margin: 10px auto 0; text-align: right"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
></ElPagination>
</div>
</el-tab-pane>
<el-tab-pane
label=
"按平台分拣(优先级低)"
name=
"2"
class=
"flex-column h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<el-form
inline
:model=
"searchForm"
>
<el-form-item
label=
"分拣设备"
>
<el-input
v-model
.
trim=
"searchForm.sortingFacility"
placeholder=
"分拣设备"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"分拣口"
>
<el-select
v-model=
"searchForm.sortingArea"
clearable
style=
"width: 160px"
>
<el-option
v-for=
"item in sortingList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"平台"
>
<el-select
v-model=
"searchForm.serviceCode"
clearable
filterable
multiple
collapse-tags
collapse-tags-tooltip
popper-class=
"customize-select-style"
style=
"width: 200px"
>
<el-option
v-for=
"item in platformJson"
:key=
"item.type"
:label=
"item.type"
:value=
"item.type"
>
<img
:src=
"`/images/icon/${item.icon.split('/').pop()}`"
style=
"height: 20px; margin: 5px 10px 0 0"
/>
<span
:title=
"item.type"
>
{{ item.type }}
</span></el-option
>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"search"
>
查询
</el-button>
<el-button
type=
"success"
@
click=
"createWarehouse"
>
新增
</el-button
>
<el-button
type=
"danger"
@
click=
"handleBatchDelete(null)"
>
删除
</el-button
>
</el-form-item>
</el-form>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<el-table
height=
"100%"
:data=
"tableData"
border
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
/>
<el-table-column
type=
"index"
label=
"序号"
width=
"60"
align=
"center"
/>
<el-table-column
align=
"center"
label=
"分拣设备"
show-overflow-tooltip
prop=
"sortingFacility"
></el-table-column>
<el-table-column
align=
"center"
label=
"分拣口名称"
prop=
"sortingAreaName"
>
</el-table-column>
<el-table-column
align=
"center"
label=
"平台"
show-overflow-tooltip
prop=
"serviceCode"
></el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"100"
>
<
template
#
default=
"{ row }"
>
<el-icon
size=
"24"
title=
"编辑"
color=
"#EF6C00"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"updateSorting(row)"
>
<Edit
/>
</el-icon>
<el-icon
size=
"24"
title=
"删除"
color=
"#f56c6c"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"handleBatchDelete(row)"
>
<Delete
/>
</el-icon>
</
template
>
</el-table-column>
</el-table>
</div>
<ElPagination
v-model:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:page-sizes=
"[100, 200, 300, 400, 500]"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"total"
style=
"margin: 10px auto 0; text-align: right"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
></ElPagination></div
></el-tab-pane>
</el-tabs>
<el-dialog
v-model=
"createData.show"
width=
"500px"
:title=
"createData.title"
>
<el-form
ref=
"formRef"
label-width=
"110px"
:rules=
"rules"
:model=
"form"
>
<el-form-item
label=
"分拣设备"
prop=
"sortingFacility"
>
<el-input
v-model
.
trim=
"form.sortingFacility"
placeholder=
"分拣设备"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"分拣口"
prop=
"sortingArea"
>
<div
class=
"flex"
>
<el-select
v-model=
"form.sortingArea"
clearable
style=
"width: 320px"
@
change=
"sortingChange"
>
<el-option
v-for=
"item in sortingList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
 
<el-popover
placement=
"bottom-start"
width=
"700"
trigger=
"click"
>
<img
:src=
"sortingImg"
alt=
"分拣口示意图"
style=
"width: 100%"
/>
<
template
#
reference
>
<el-icon
size=
"30"
color=
"#606266"
style=
"cursor: pointer"
>
<QuestionFilled
/>
</el-icon>
</
template
>
</el-popover>
<!-- <el-icon
size="30"
title="分拣口示意图"
style="cursor: pointer"
@click="mouseoverImg(ev, sortingImg, '700px', true, true)"
@mouseover="(ev:MouseEvent) => mouseoverImg(ev, sortingImg,'700px',true,true)"
@mouseleave="mouseleaveImg"
><QuestionFilled
/></el-icon> -->
</div>
</el-form-item>
<el-form-item
v-if=
"activeName == '1'"
label=
"物流公司"
prop=
"serviceCode"
>
<div
class=
"flex"
>
<el-select
v-model=
"form.serviceCode"
style=
"width: 320px"
clearable
filterable
multiple
>
<el-option
v-for=
"item in logisticsMethodsList"
:key=
"item.code"
:label=
"item.basicsName"
:value=
"item.code"
></el-option>
</el-select>
<!--  
<el-icon
color="#409eff"
size="30"
title="添加物流方式"
class="add-btn"
@click="addLogistics"
><CirclePlus
/></el-icon> -->
</div>
</el-form-item>
<el-form-item
label=
"平台"
v-else
prop=
"serviceCode"
>
<el-select
v-model=
"form.serviceCode"
clearable
filterable
multiple
popper-class=
"customize-select-style"
>
<el-option
v-for=
"item in platformJson"
:key=
"item.type"
:label=
"item.type"
:value=
"item.type"
>
<img
:src=
"`/images/icon/${item.icon.split('/').pop()}`"
style=
"height: 20px; margin: 5px 10px 0 0"
/>
<span
:title=
"item.type"
>
{{ item.type }}
</span></el-option
>
</el-select>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"createData.show = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleConfirm"
>
确定
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
style
scoped
lang=
"scss"
>
.
el-card
{
::v-deep(.el-card__body)
{
.
user-list
{
.table-container
{
height
:
100%
;
overflow
:
hidden
;
}
}
.customize-select-style
{
.el-select-dropdown__list
{
width
:
500px
;
display
:
flex
;
flex-wrap
:
wrap
;
.el-select-dropdown__item
{
width
:
160px
;
}
.el-card
{
::v-deep(.el-card__body)
{
height
:
100%
;
}
}
.manage
{
height
:
100%
;
display
:
flex
;
...
...
@@ -742,10 +262,4 @@ useEnterKeyTrigger({
}
}
}
.add-btn
:hover
{
cursor
:
pointer
;
}
.demo-tabs
{
height
:
100%
;
}
</
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