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
797aadc2
Commit
797aadc2
authored
May 29, 2025
by
linjinhong
Committed by
qinjianhui
May 29, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
物流报价和运费计算页面添加完成
parent
bfee1467
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1178 additions
and
211 deletions
+1178
-211
src/api/logistics.ts
+83
-11
src/components/CustomizeForm.tsx
+4
-2
src/components/Form.vue/AmountInput.vue
+8
-1
src/components/Form.vue/Select.vue
+2
-1
src/components/SearchForm.tsx
+13
-2
src/components/VxeTable.tsx
+59
-55
src/router/index.ts
+14
-1
src/router/menu.ts
+13
-3
src/types/api/index.ts
+1
-0
src/utils/hooks/usePageList.ts
+0
-1
src/views/logistics/logisticsCalculate.vue
+177
-0
src/views/logistics/logisticsPartition.vue
+531
-0
src/views/logistics/logisticsQuotation.vue
+273
-134
No files found.
src/api/logistics.ts
View file @
797aadc2
...
...
@@ -114,15 +114,15 @@ export function getlogisticsWayAllList() {
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/logisticsWay/all_list'
,
{})
}
//物流报价列表
export
function
getlogisticsQuotationList
()
{
return
axios
.
ge
t
<
never
,
BaseRespData
<
never
>>
(
export
function
getlogisticsQuotationList
(
params
:
any
)
{
return
axios
.
pos
t
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/list_page'
,
{}
,
params
,
)
}
//新增
export
function
addLogisticsQuotation
(
params
:
any
)
{
return
axios
.
ge
t
<
never
,
BaseRespData
<
never
>>
(
return
axios
.
pos
t
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/add'
,
params
,
)
...
...
@@ -142,24 +142,31 @@ export function deleteLogisticsQuotation(params: any) {
)
}
//导入
export
function
importLogisticsQuotation
(
params
:
any
)
{
return
axios
.
ge
t
<
never
,
BaseRespData
<
never
>>
(
export
function
importLogisticsQuotation
(
formData
:
any
)
{
return
axios
.
pos
t
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/import'
,
{
params
},
formData
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
},
)
}
//下载模版
export
function
exportLogisticsQuotationTemplate
(
params
:
any
)
{
export
function
downloadLogisticsQuotationTemplate
(
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/exportExcel'
,
{
params
},
{
responseType
:
'blob'
,
},
)
}
//根据ID查对象
export
function
getLogisticsQuotationByID
(
params
:
any
)
{
return
axios
.
ge
t
<
never
,
BaseRespData
<
never
>>
(
return
axios
.
pos
t
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/get'
,
{
params
}
,
params
,
)
}
...
...
@@ -193,3 +200,68 @@ export function deleteLogisticsCustomsRule(params: any) {
params
,
})
}
/**
* @description 物流分区
*/
//列表
export
function
getLogisticsZoneList
(
params
:
any
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/list'
,
params
,
)
}
//新增
export
function
addLogisticsZone
(
params
:
any
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/add'
,
params
,
)
}
//修改
export
function
updateLogisticsZone
(
params
:
any
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/update'
,
params
,
)
}
//删除
export
function
deleteLogisticsZone
(
params
:
any
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/delete'
,
params
,
)
}
//物流分区导入
export
function
importLogisticsZone
(
formData
:
any
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/import'
,
formData
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
},
)
}
//物流分区导入模板
export
function
exportExcelLogisticsZone
()
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsZone/exportExcel'
,
{
responseType
:
'blob'
,
},
)
}
/**
* @description 运费试算
*/
export
function
getLogisticsTrialCalculation
(
params
:
any
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/logistics/logisticsQuotation/logisticsTrialCalculation'
,
{
params
,
},
)
}
src/components/CustomizeForm.tsx
View file @
797aadc2
...
...
@@ -130,8 +130,8 @@ export default defineComponent({
await
formRef
.
value
?.
resetFields
()
}
function
refashConfig
(
showFields
:
string
[])
{
if
(
showFields
.
length
)
{
function
refashConfig
(
showFields
?
:
string
[])
{
if
(
showFields
?
.
length
)
{
const
filterArr
=
props
.
config
.
filter
((
item
)
=>
showFields
.
includes
(
item
.
prop
as
string
),
)
...
...
@@ -142,6 +142,8 @@ export default defineComponent({
]
.
filter
((
item
)
=>
!
item
.
fixed
)
.
concat
(
tableConfig
.
value
.
filter
((
item
)
=>
item
.
fixed
))
}
else
{
tableConfig
.
value
=
props
.
config
}
console
.
log
(
'tableConfig'
,
tableConfig
.
value
)
}
...
...
src/components/Form.vue/AmountInput.vue
View file @
797aadc2
...
...
@@ -9,9 +9,12 @@
@
input=
"iptFn"
>
<template
v-if=
"hasSuffix"
#
suffix
>
{{
suffix
}}
</
template
>
<
template
v-if=
"hasAppend"
#
append
>
<component
:is=
"appendRender"
/>
</
template
>
</el-input>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts
x
"
setup
>
import
{
isNumFloat
}
from
'@/utils/validate'
const
props
=
withDefaults
(
defineProps
<
{
...
...
@@ -20,6 +23,8 @@ const props = withDefaults(
placeholder
?:
string
size
?:
''
|
'default'
|
'small'
|
'large'
hasSuffix
?:
boolean
hasAppend
?:
boolean
appendRender
?:
()
=>
JSX
.
Element
isDisabled
?:
boolean
}
>
(),
{
...
...
@@ -29,6 +34,8 @@ const props = withDefaults(
size
:
'default'
,
hasSuffix
:
true
,
isDisabled
:
false
,
hasAppend
:
false
,
appendRender
:
null
,
},
)
const
emits
=
defineEmits
<
{
...
...
src/components/Form.vue/Select.vue
View file @
797aadc2
...
...
@@ -34,9 +34,10 @@ const props = withDefaults(
hasAllOptions
?:
boolean
labelIsValue
?:
boolean
// value 使用label字段
initChange
?:
boolean
// 首次是否触发change事件
modelValue
?:
string
|
number
modelValue
?:
string
|
number
|
string
[]
|
number
[]
isRefresh
?:
boolean
isValueKey
?:
boolean
load
?:
(
arg
:
(
val
:
boolean
)
=>
void
)
=>
void
// focus后再加载数据的
}
>
(),
{
...
...
src/components/SearchForm.tsx
View file @
797aadc2
...
...
@@ -104,12 +104,23 @@ export default defineComponent({
setup
(
props
,
{
emit
,
slots
,
attrs
})
{
const
formRef
=
ref
()
const
formWrapperRef
=
ref
()
const
searchForm
=
ref
<
ISearchForm
>
(
props
.
modelValue
||
{})
const
searchForm
=
ref
<
ISearchForm
>
({})
const
selectResult
=
ref
<
ISeachFormConfig
[]
>
([])
const
componentWidth
=
computed
(()
=>
props
.
size
===
'default'
?
200
:
220
,
)
watch
(
()
=>
props
.
modelValue
,
(
val
)
=>
{
searchForm
.
value
=
val
},
{
immediate
:
true
,
deep
:
true
,
},
)
function
initSeachForm
()
{
props
.
config
.
forEach
((
item
,
index
)
=>
{
if
(
componentDataTypeMap
.
has
(
item
.
type
as
EComponenetType
))
{
...
...
@@ -157,7 +168,7 @@ export default defineComponent({
<
div
style=
{
styles
.
wrapper
}
class=
"mt-15"
>
<
ElForm
{
...
getFormAttrs
.
value
}
ref=
{
el
=>
formRef
.
value
=
el
}
ref=
{
(
el
)
=>
(
formRef
.
value
=
el
)
}
class=
"w-full"
inline
model=
{
searchForm
.
value
}
...
...
src/components/VxeTable.tsx
View file @
797aadc2
import
{
VNode
}
from
'vue'
interface
ColumnAttrs
{
field
?:
string
title
?:
string
...
...
@@ -52,7 +51,7 @@ export default defineComponent({
},
},
emits
:
[
'update:modelValue'
,
'checkbox-change'
,
'getCheckboxRecords'
],
setup
(
props
,
{
emit
,
attrs
})
{
setup
(
props
,
{
emit
,
attrs
})
{
const
tableRef
=
ref
(
null
)
const
tableData
=
ref
<
Record
<
string
,
unknown
>
[]
>
([])
const
tableColumns
=
ref
<
TableColumn
[]
>
([])
...
...
@@ -79,9 +78,7 @@ export default defineComponent({
watch
(
()
=>
props
.
modelValue
,
(
val
)
=>
{
tableData
.
value
=
Array
.
isArray
(
val
)
?
val
:
[]
tableData
.
value
=
Array
.
isArray
(
val
)
?
val
:
[]
},
{
immediate
:
true
,
...
...
@@ -98,7 +95,7 @@ export default defineComponent({
}
}
}
//获取选中数据
const
getSelectEvent
=
()
=>
{
const
$table
=
tableRef
.
value
if
(
$table
)
{
...
...
@@ -106,6 +103,14 @@ export default defineComponent({
emit
(
'getCheckboxRecords'
,
selectRecords
)
}
}
//设置高亮行
const
selectRowEvent
=
(
row
:
TableRowData
)
=>
{
const
$table
=
tableRef
.
value
if
(
$table
)
{
console
.
log
(
110
,
row
)
$table
.
setCurrentRow
(
row
)
}
}
onMounted
(()
=>
{
getList
()
...
...
@@ -116,62 +121,61 @@ export default defineComponent({
tableData
,
tableColumns
,
editConfig
,
getSelectEvent
,
attrs
getSelectEvent
,
selectRowEvent
,
attrs
,
}
},
render
()
{
return
(
<
vxe
-
table
ref=
{
(
el
)
=>
this
.
tableRef
=
el
}
data=
{
this
.
tableData
}
height=
'100%'
edit
-
config=
{
this
.
editConfig
}
onCheckboxChange=
{
this
.
getSelectEvent
}
onCheckboxAll=
{
this
.
getSelectEvent
}
{
...
this
.
attrs
}
>
{
this
.
isShowCheckBox
&&
(
<
vxe
-
column
type=
"checkbox"
width=
"50"
align=
"center"
></
vxe
-
column
>
)
}
<
vxe
-
table
ref=
{
(
el
)
=>
(
this
.
tableRef
=
el
)
}
data=
{
this
.
tableData
}
height=
"100%"
edit
-
config=
{
this
.
editConfig
}
onCheckboxChange=
{
this
.
getSelectEvent
}
onCheckboxAll=
{
this
.
getSelectEvent
}
{
...
this
.
attrs
}
>
{
this
.
isShowCheckBox
&&
(
<
vxe
-
column
type=
"checkbox"
width=
"50"
align=
"center"
></
vxe
-
column
>
)
}
<
vxe
-
column
align=
"center"
type=
"seq"
width=
"50"
title=
"序号"
/>
{
this
.
tableColumns
.
map
((
item
:
TableColumn
,
index
:
number
)
=>
(
<
vxe
-
column
key=
{
index
}
field=
{
item
.
prop
}
title=
{
item
.
label
}
{
...
item
.
attrs
}
edit
-
render=
{
{}
}
>
{
{
...(()
=>
{
// 创建基础插槽配置
const
slots
:
Record
<
string
,
SlotFunction
>
=
{
// 默认的 default 插槽实现
default
:
({
row
})
=>
<
span
>
{
row
[
item
.
prop
]
}
</
span
>,
}
<
vxe
-
column
align=
"center"
type=
"seq"
width=
"50"
title=
"序号"
/>
{
this
.
tableColumns
.
map
((
item
:
TableColumn
,
index
:
number
)
=>
(
<
vxe
-
column
key=
{
index
}
field=
{
item
.
prop
}
title=
{
item
.
label
}
{
...
item
.
attrs
}
edit
-
render=
{
{}
}
>
{
{
...(()
=>
{
// 创建基础插槽配置
const
slots
:
Record
<
string
,
SlotFunction
>
=
{
// 默认的 default 插槽实现
default
:
({
row
})
=>
<
span
>
{
row
[
item
.
prop
]
}
</
span
>,
}
if
(
item
.
render
)
{
// 添加所有自定义插槽
Object
.
entries
(
item
.
render
).
forEach
(
([
slotName
,
renderFn
])
=>
{
if
(
renderFn
)
{
slots
[
slotName
]
=
(
scope
:
{
row
:
TableRowData
})
=>
renderFn
(
scope
)
}
},
)
}
if
(
item
.
render
)
{
// 添加所有自定义插槽
Object
.
entries
(
item
.
render
).
forEach
(
([
slotName
,
renderFn
])
=>
{
if
(
renderFn
)
{
slots
[
slotName
]
=
(
scope
:
{
row
:
TableRowData
})
=>
renderFn
(
scope
)
}
},
)
}
return
slots
})(),
}
}
</
vxe
-
column
>
))
}
</
vxe
-
table
>
return
slots
})(),
}
}
</
vxe
-
column
>
))
}
</
vxe
-
table
>
)
},
})
src/router/index.ts
View file @
797aadc2
...
...
@@ -183,7 +183,20 @@ const router = createRouter({
},
component
:
()
=>
import
(
'@/views/logistics/declarationRule.vue'
),
},
{
path
:
'/logistics/logisticsPartition'
,
meta
:
{
title
:
'物流分区'
,
},
component
:
()
=>
import
(
'@/views/logistics/logisticsPartition.vue'
),
},
{
path
:
'/logistics/logisticsCalculate'
,
meta
:
{
title
:
'运费试算'
,
},
component
:
()
=>
import
(
'@/views/logistics/logisticsCalculate.vue'
),
},
{
path
:
'/warehouse/manage'
,
meta
:
{
...
...
src/router/menu.ts
View file @
797aadc2
...
...
@@ -136,19 +136,29 @@ const menu: MenuItem[] = [
},
{
index
:
'/logistics/shippingAddress'
,
id
:
1
,
id
:
2
,
label
:
'发货地址'
,
},
{
index
:
'/logistics/logisticsQuotation'
,
id
:
1
,
id
:
3
,
label
:
'物流报价'
,
},
{
index
:
'/logistics/declarationRule'
,
id
:
1
,
id
:
4
,
label
:
'申报规则'
,
},
{
index
:
'/logistics/logisticsPartition'
,
id
:
5
,
label
:
'物流分区'
,
},
{
index
:
'/logistics/logisticsCalculate'
,
id
:
6
,
label
:
'运费试算'
,
},
],
},
// {
...
...
src/types/api/index.ts
View file @
797aadc2
...
...
@@ -12,6 +12,7 @@ export interface PaginationData<D> {
size
:
number
current
:
number
records
:
D
[]
data
?:
D
[]
}
export
interface
Statistics
<
D
>
{
sumNotPassNum
:
number
...
...
src/utils/hooks/usePageList.ts
View file @
797aadc2
...
...
@@ -44,7 +44,6 @@ export default function usePageList<T>(options: UsePageListOptions<T>) {
pageSize
.
value
=
res
.
size
data
.
value
=
res
.
records
}
console
.
log
(
7
,
data
.
value
)
}
catch
(
error
)
{
console
.
error
(
error
)
// showError(error)
...
...
src/views/logistics/logisticsCalculate.vue
0 → 100644
View file @
797aadc2
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<SearchForm
:config=
"searchConfig"
:isSearchBtn=
"false"
:isAddBtn=
"false"
:isDeleteBtn=
"false"
v-model=
"searchForm"
>
<template
#
ontherBtn
>
<div
style=
"margin-left: 10px; display: flex; gap: 10px"
>
<ElButton
@
click=
"search"
type=
"primary"
>
计算
</ElButton>
</div>
</
template
>
</SearchForm>
</div>
<div
v-loading=
"loading"
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<CustomizeTable
ref=
"tableRef"
v-model=
"tableData"
:config=
"tableConfig"
:merge-cells=
"mergeCells"
highlight-current-row
:isShowCheckBox=
"false"
border=
"full"
@
getCheckboxRecords=
"handleCheckboxRecords"
></CustomizeTable>
</div>
</div>
</div>
</template>
<
script
setup
lang=
"tsx"
>
import
{
getLogisticsTrialCalculation
}
from
'@/api/logistics'
import
type
{
LogisticsMethod
}
from
'@/types/api/logistics'
import
SearchForm
from
'@/components/SearchForm.tsx'
import
LogDialog
from
'./components/LogDialog.tsx'
import
CustomizeForm
from
'@/components/CustomizeForm.tsx'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
type
{
VxeTablePropTypes
}
from
'vxe-table'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
useValue
}
from
'./hooks/useValue'
import
{
showConfirm
}
from
'@/utils/ui'
import
{
Edit
}
from
'@element-plus/icons-vue'
const
[
searchForm
]
=
useValue
({
code
:
''
,
weight
:
''
})
const
tableRef
=
ref
(
null
)
const
selection
=
ref
([])
const
mergeCells
=
ref
<
VxeTablePropTypes
.
MergeCells
>
([])
const
tableData
=
ref
([])
const
searchConfig
=
ref
([
{
prop
:
'code'
,
type
:
'input'
,
label
:
'邮编'
,
attrs
:
{
placeholder
:
'请输入邮编'
,
},
},
{
prop
:
'weight'
,
type
:
'amountInput'
,
label
:
'重量'
,
attrs
:
{
placeholder
:
'请输入重量'
,
hasUnit
:
true
,
suffix
:
'g'
,
},
},
])
const
tableConfig
=
ref
([
{
prop
:
'logisticsWayName'
,
label
:
'物流名称'
,
attrs
:
{
align
:
'center'
,
width
:
100
,
},
},
{
prop
:
'warehouseName'
,
label
:
'发货仓库'
,
},
{
prop
:
'logisticsWayCode'
,
label
:
'物流编码'
,
},
{
prop
:
'partition'
,
label
:
'所在分区'
,
},
{
prop
:
'status'
,
label
:
'状态'
,
render
:
{
default
:
({
row
})
=>
{
return
(
<
div
style
=
{{
color
:
row
.
status
?
'#67c23a'
:
'#f56c6c'
}}
>
{
row
.
status
?
'成功'
:
'失败'
}
<
/div
>
)
},
},
},
{
prop
:
'payFreight'
,
label
:
'预计运费($)'
,
},
])
async
function
search
()
{
if
(
!
searchForm
.
value
.
code
)
{
ElMessage
.
warning
(
'请输入邮编'
)
return
}
if
(
!
searchForm
.
value
.
weight
)
{
ElMessage
.
warning
(
'请输入重量'
)
return
}
await
getList
(
searchForm
.
value
)
const
itemIndex
=
tableData
.
value
.
findIndex
((
item
)
=>
item
.
status
)
console
.
log
(
123
,
itemIndex
)
if
(
itemIndex
!==
-
1
)
{
nextTick
(()
=>
{
tableRef
.
value
?.
selectRowEvent
(
tableData
.
value
[
itemIndex
])
})
}
}
const
loading
=
ref
(
false
)
async
function
getList
(
data
?)
{
loading
.
value
=
true
try
{
const
res
=
await
getLogisticsTrialCalculation
({
...
data
,
})
tableData
.
value
=
[...
res
.
data
]
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
value
=
false
}
}
function
handleCheckboxRecords
(
value
:
never
[])
{
console
.
log
(
351
,
value
)
selection
.
value
=
value
}
</
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
;
}
</
style
>
src/views/logistics/logisticsPartition.vue
0 → 100644
View file @
797aadc2
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<SearchForm
:config=
"searchConfig"
@
search=
"search"
@
add=
"addDialog"
:isAddBtn=
"false"
@
delete=
"deleteFn"
v-model=
"searchForm"
>
<template
#
ontherBtn
>
<div
style=
"margin-left: 10px; display: flex; gap: 10px"
>
<ElButton
@
click=
"downloadExcel"
type=
"info"
plain
>
下载模版
</ElButton
>
<el-upload
class=
"upload-demo"
action
:show-file-list=
"false"
:before-upload=
"onBeforeUploadImage"
:http-request=
"exportExcel"
>
<ElButton
type=
"primary"
plain
>
导入
</ElButton>
</el-upload>
</div>
</
template
></SearchForm
>
</div>
<div
v-loading=
"loading"
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<CustomizeTable
v-model=
"tableData"
:config=
"tableConfig"
:merge-cells=
"mergeCells"
border=
"full"
@
getCheckboxRecords=
"handleCheckboxRecords"
></CustomizeTable>
</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>
<LogDialog
:title=
"editForm.id ? '编辑物流方式' : '新增物流方式'"
dialogWidth=
"1000px"
v-model=
"dialogVisible"
@
close=
"cancelFn"
>
<CustomizeForm
ref=
"editFormRef"
v-model=
"editForm"
:config=
"formConfig"
formItemWidth=
"100%"
>
</CustomizeForm>
<
template
#
footer
>
<div
style=
"text-align: center"
>
<ElButton
@
click=
"cancelFn"
>
取消
</ElButton>
<ElButton
type=
"primary"
@
click=
"save"
>
保存
</ElButton>
</div>
</
template
>
</LogDialog>
</template>
<
script
setup
lang=
"tsx"
>
import
{
getLogisticsZoneList
,
addLogisticsZone
,
updateLogisticsZone
,
deleteLogisticsZone
,
importLogisticsZone
,
exportExcelLogisticsZone
,
getlogisticsWayAllList
,
}
from
'@/api/logistics'
import
type
{
LogisticsMethod
}
from
'@/types/api/logistics'
import
SearchForm
from
'@/components/SearchForm.tsx'
import
LogDialog
from
'./components/LogDialog.tsx'
import
CustomizeForm
from
'@/components/CustomizeForm.tsx'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
type
{
VxeTablePropTypes
}
from
'vxe-table'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
useValue
}
from
'./hooks/useValue'
import
{
showConfirm
}
from
'@/utils/ui'
import
{
Edit
}
from
'@element-plus/icons-vue'
const
[
searchForm
]
=
useValue
({})
const
[
editForm
,
resetEditForm
]
=
useValue
({
logisticsList
:
[]
})
const
dialogVisible
=
ref
(
false
)
const
editFormRef
=
ref
(
null
)
const
selection
=
ref
([])
const
mergeCells
=
ref
<
VxeTablePropTypes
.
MergeCells
>
([])
const
tableData
=
ref
([])
const
searchConfig
=
ref
([
{
prop
:
'logisticsList'
,
type
:
'select'
,
label
:
'物流方式'
,
attrs
:
{
placeholder
:
'请选择物流方式'
,
multiple
:
true
,
value
:
'name'
,
label
:
'name'
,
collapseTags
:
true
,
collapseTagsTooltip
:
true
,
options
:
[],
},
},
{
prop
:
'codePrefix'
,
type
:
'input'
,
label
:
'邮编编码'
,
attrs
:
{
placeholder
:
'请输入邮编编码'
,
},
},
])
const
formConfig
=
ref
([
{
title
:
'物流基础信息'
},
{
prop
:
'zone1'
,
type
:
'input'
,
label
:
'ZONE 1'
,
attrs
:
{
placeholder
:
'请输入ZONE 1'
,
},
},
{
prop
:
'zone2'
,
type
:
'input'
,
label
:
'ZONE 2'
,
attrs
:
{
placeholder
:
'请输入ZONE 2'
,
},
},
{
prop
:
'zone3'
,
type
:
'input'
,
label
:
'ZONE 3'
,
attrs
:
{
placeholder
:
'请输入ZONE 3'
,
},
},
{
prop
:
'zone4'
,
type
:
'input'
,
label
:
'ZONE 4'
,
attrs
:
{
placeholder
:
'请输入ZONE 4'
,
},
},
{
prop
:
'zone5'
,
type
:
'input'
,
label
:
'ZONE 5'
,
attrs
:
{
placeholder
:
'请输入ZONE 5'
,
},
},
{
prop
:
'zone6'
,
type
:
'input'
,
label
:
'ZONE 6'
,
attrs
:
{
placeholder
:
'请输入ZONE 6'
,
},
},
{
prop
:
'zone7'
,
type
:
'input'
,
label
:
'ZONE 7'
,
attrs
:
{
placeholder
:
'请输入ZONE 7'
,
},
},
{
prop
:
'zone8'
,
type
:
'input'
,
label
:
'ZONE 8'
,
attrs
:
{
placeholder
:
'请输入ZONE 8'
,
},
},
{
prop
:
'zone9'
,
type
:
'input'
,
label
:
'ZONE 9'
,
attrs
:
{
placeholder
:
'请输入ZONE 9'
,
},
},
])
const
tableConfig
=
ref
([])
watch
(
()
=>
searchForm
.
value
,
(
val
)
=>
{
if
(
val
.
logisticsList
===
''
)
{
val
.
logisticsList
=
[]
}
},
{
immediate
:
true
,
deep
:
true
},
)
onMounted
(()
=>
{
// loading.value = true
getAllList
()
})
async
function
search
()
{
await
getList
(
searchForm
.
value
)
setCellStyle
()
}
function
getTableData
(
arr
)
{
// 防御式编程:处理非数组或空输入
if
(
!
Array
.
isArray
(
arr
)
||
arr
.
length
===
0
)
return
[]
// 使用 map 替代 forEach 实现不可变数据
return
arr
.
map
((
parentItem
)
=>
{
// 使用可选链 + 空值合并运算符处理嵌套数据
const
quotationList
=
parentItem
.
logisticsZoneList
??
[]
// 使用 Object.fromEntries 优化属性合并
quotationList
?.
forEach
((
el
)
=>
{
parentItem
[
el
.
logistics
]
=
{
codePrefix
:
el
.
codePrefix
||
''
,
highlight
:
el
.
highlight
,
}
})
// 返回新对象保持不可变性
return
{
...
parentItem
,
// 保留原属性
}
})
}
function
cancelFn
()
{
dialogVisible
.
value
=
false
editFormRef
.
value
?.
resetFields
()
resetEditForm
()
}
async
function
checkData
()
{
const
[
isValid
,
postData
]
=
await
Promise
.
all
([
new
Promise
<
boolean
>
((
resolve
)
=>
{
editFormRef
.
value
?.
validate
()
.
then
(()
=>
resolve
(
true
))
.
catch
((
err
)
=>
{
resolve
(
false
)
console
.
log
(
err
)
})
}),
new
Promise
<
LogisticsMethod
>
((
resolve
)
=>
{
const
params
=
{
...
editForm
.
value
}
resolve
(
params
)
}),
])
console
.
log
(
isValid
,
postData
)
return
{
isValid
,
postData
}
}
async
function
save
()
{
const
{
isValid
,
postData
}
=
await
checkData
()
if
(
isValid
)
{
try
{
if
(
!
postData
.
id
)
{
await
addLogisticsZone
({
...
postData
,
})
}
else
{
await
updateLogisticsZone
({
...
postData
,
})
}
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
,
offset
:
window
.
innerHeight
/
2
,
})
cancelFn
()
search
()
}
catch
(
e
)
{
return
}
}
}
function
addDialog
()
{
dialogVisible
.
value
=
true
}
async
function
deleteFn
()
{
if
(
!
selection
.
value
.
length
)
{
return
ElMessage
({
message
:
'请选择分区'
,
type
:
'warning'
,
})
}
try
{
await
showConfirm
(
'是否删除改分区下物流方式的邮编编码'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
}
catch
{
return
}
try
{
const
whiteList
=
[
'logisticsZoneList'
,
'zoneName'
,
'_X_ROW_KEY'
]
const
zomList
=
selection
.
value
.
map
((
item
)
=>
{
const
arr
=
[]
for
(
const
key
in
item
)
{
if
(
!
whiteList
.
includes
(
key
))
{
arr
.
push
(
key
)
}
}
return
[...
arr
]
})
const
params
=
{
logisticsList
:
zomList
[
0
],
zoneNameList
:
selection
.
value
.
map
((
item
)
=>
item
.
zoneName
),
}
await
deleteLogisticsZone
(
params
)
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
,
})
getList
(
searchForm
.
value
)
}
catch
(
e
)
{
getList
(
searchForm
.
value
)
// showError(e)
}
}
const
loading
=
ref
(
false
)
async
function
getList
(
data
?)
{
loading
.
value
=
true
try
{
const
res
=
await
getLogisticsZoneList
({
...
data
,
})
tableData
.
value
=
[...
res
.
data
]
try
{
const
arr
=
await
getTableData
(
tableData
.
value
)
const
whiteList
=
[
'logisticsZoneList'
,
'zoneName'
]
const
oldConfig
=
[
{
prop
:
'zoneName'
,
label
:
'分区'
,
},
]
const
newConfig
=
[]
if
(
arr
.
length
)
{
for
(
const
key
in
arr
[
0
])
{
if
(
!
whiteList
.
includes
(
key
))
{
newConfig
.
push
({
prop
:
key
,
label
:
key
,
render
:
{
default
:
({
row
})
=>
{
return
(
<
span
class
=
{
row
[
key
]?.
highlight
?
'tableCell'
:
'primaryCell'
}
>
{
row
[
key
]?.
codePrefix
}
<
/span
>
)
},
},
})
}
}
}
tableConfig
.
value
=
[...
oldConfig
,
...
newConfig
]
console
.
log
(
'tableConfig'
,
tableConfig
.
value
)
console
.
log
(
' tableData'
,
tableData
.
value
)
}
catch
(
e
)
{
console
.
log
(
e
)
}
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
loading
.
value
=
false
}
}
function
handleCheckboxRecords
(
value
:
never
[])
{
console
.
log
(
351
,
value
)
selection
.
value
=
value
}
function
setCellStyle
()
{
const
[
cell
,
primaryCell
]
=
[
'.tableCell'
,
'.primaryCell'
].
map
((
selector
)
=>
document
.
querySelectorAll
(
selector
),
)
console
.
log
(
404
,
cell
)
const
getAncestor
=
(
element
,
level
=
2
)
=>
{
let
current
=
element
while
(
level
--
>
0
&&
current
)
{
current
=
current
.
parentElement
}
return
current
||
null
}
const
safeSetBackground
=
(
element
,
color
)
=>
{
if
(
element
?.
style
&&
typeof
color
===
'string'
)
{
element
.
style
.
backgroundColor
=
color
}
}
if
(
cell
.
length
)
{
cell
.
forEach
((
item
)
=>
{
const
grandParent
=
getAncestor
(
item
)
safeSetBackground
(
grandParent
,
'#e6f7ff'
)
})
}
if
(
primaryCell
.
length
)
{
primaryCell
.
forEach
((
item
)
=>
{
const
grandParent
=
getAncestor
(
item
)
safeSetBackground
(
grandParent
,
'transparent'
)
})
}
}
async
function
getAllList
()
{
try
{
const
res
=
await
Promise
.
all
([
getlogisticsWayAllList
(),
getList
()])
// console.log(545, res)
searchConfig
.
value
[
0
].
attrs
!
.
options
=
[...(
res
[
0
]?.
data
||
[])]
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
function
onBeforeUploadImage
(
file
)
{
const
isIMAGE
=
file
.
type
==
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
if
(
!
isIMAGE
)
{
ElMessage
.
error
(
'上传文件只能是excel格式!'
)
}
return
isIMAGE
}
async
function
downloadExcel
()
{
try
{
const
res
=
await
exportExcelLogisticsZone
()
// console.log(483, data)
const
blob
=
new
Blob
([
res
])
// 2. 解析文件名(从响应头或自定义)
const
filename
=
'物流分区模版.xlsx'
// 3. 创建临时链接并触发下载
const
link
=
document
.
createElement
(
'a'
)
link
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
link
.
download
=
filename
link
.
click
()
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
async
function
exportExcel
(
file
)
{
try
{
const
formData
=
new
FormData
()
formData
.
append
(
'file'
,
file
.
file
)
const
res
=
await
importLogisticsZone
(
formData
)
if
(
res
.
code
===
200
)
{
ElMessage
.
success
(
'导入成功!'
)
getList
(
searchForm
.
value
)
}
}
catch
(
error
)
{
ElMessage
.
error
(
'导入失败!'
)
}
}
watch
(
()
=>
loading
.
value
,
(
val
)
=>
{
console
.
log
(
442
,
val
)
},
{
deep
:
true
,
immediate
:
true
},
)
</
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
;
}
</
style
>
src/views/logistics/logisticsQuotation.vue
View file @
797aadc2
...
...
@@ -9,26 +9,52 @@
v-model=
"searchForm"
>
<template
#
ontherBtn
>
<div
style=
"margin-left: 10px"
>
<div
style=
"margin-left: 10px
; display: flex; gap: 10px
"
>
<ElButton
@
click=
"downloadExcel"
type=
"info"
plain
>
下载模版
</ElButton
>
<ElButton
type=
"primary"
plain
@
click=
"exportExcel"
>
新增导入
</ElButton
<el-upload
class=
"upload-demo"
action
:show-file-list=
"false"
:before-upload=
"onBeforeUploadImage"
:http-request=
"exportExcel"
>
<ElButton
type=
"primary"
plain
@
click=
"exportExcel"
>
修改导入
</ElButton
<ElButton
type=
"primary"
plain
>
导入
</ElButton>
</el-upload>
<el-upload
class=
"upload-demo"
action
:show-file-list=
"false"
:before-upload=
"onBeforeUploadImage"
:http-request=
"updateExcel"
>
<ElButton
type=
"primary"
plain
>
更新
</ElButton>
</el-upload>
</div>
</
template
></SearchForm
>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
v-loading=
"loading"
>
<div
v-loading=
"loading"
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<CustomizeTable
v-model=
"tableData"
:config=
"tableConfig"
:merge-cells=
"mergeCells"
:seq-config=
"{
seqMethod: (row) => {
if (searchForm.logisticsList?.length) {
return row.row.seq
}
return row.seq
},
}"
border=
"full"
@
getCheckboxRecords=
"handleCheckboxRecords"
></CustomizeTable>
</div>
...
...
@@ -47,7 +73,7 @@
</div>
<LogDialog
:title=
"editForm.id ? '编辑物流
方式' : '新增物流方式
'"
:title=
"editForm.id ? '编辑物流
报价' : '新增物流报价
'"
dialogWidth=
"1000px"
v-model=
"dialogVisible"
@
close=
"cancelFn"
...
...
@@ -78,216 +104,241 @@ import {
updateLogisticsQuotation
,
deleteLogisticsQuotation
,
importLogisticsQuotation
,
export
LogisticsQuotationTemplate
,
download
LogisticsQuotationTemplate
,
}
from
'@/api/logistics'
import
type
{
LogisticsMethod
}
from
'@/types/api/logistics'
import
SearchForm
from
'@/components/SearchForm.tsx'
import
LogDialog
from
'./components/LogDialog.tsx'
import
CustomizeForm
from
'@/components/CustomizeForm.tsx'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
Select
from
'@/components/Form.vue/Select.vu
e'
import
type
{
VxeTablePropTypes
}
from
'vxe-tabl
e'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
useValue
}
from
'./hooks/useValue'
import
{
showConfirm
}
from
'@/utils/ui'
import
{
Edit
,
Delete
,
List
}
from
'@element-plus/icons-vue'
import
{
Edit
}
from
'@element-plus/icons-vue'
const
[
searchForm
]
=
useValue
({})
const
[
editForm
,
resetEditForm
]
=
useValue
<
LogisticsMethod
>
({
platformList
:
[{
platform
:
[],
logisticsName
:
''
}],
ruleRef
:
[{
ruleId
:
''
,
ruleName
:
''
}],
status
:
1
,
})
const
[
editForm
,
resetEditForm
]
=
useValue
({
unit
:
'oz'
})
const
{
loading
,
currentPage
,
pageSize
,
total
,
data
:
tableData
,
data
,
refresh
:
search
,
onCurrentPageChange
:
handleCurrentChange
,
onPageSizeChange
:
handleSizeChange
,
}
=
usePageList
({
query
:
(
page
,
pageSize
)
=>
// getlogisticsQuotationList({
// ...searchForm.value,
// pageSize: pageSize,
// currentPage: page,
// }).then(({ data }) => {
// console.log(130, data)
// return data
// }),
(()
=>
{})(),
getlogisticsQuotationList
({
...
searchForm
.
value
,
pageSize
:
pageSize
,
currentPage
:
page
,
}).
then
(({
data
})
=>
{
console
.
log
(
130
,
data
)
return
data
}),
})
const
dialogVisible
=
ref
(
false
)
const
editFormRef
=
ref
(
null
)
const
selection
=
ref
([])
const
mergeCells
=
ref
<
VxeTablePropTypes
.
MergeCells
>
([])
const
tableData
=
ref
([])
const
searchConfig
=
ref
([
{
prop
:
'
name
'
,
prop
:
'
logisticsList
'
,
type
:
'select'
,
label
:
'物流方式'
,
attrs
:
{
placeholder
:
'请选择物流方式'
,
multiple
:
true
,
value
:
'name'
,
label
:
'name'
,
collapseTags
:
true
,
collapseTagsTooltip
:
true
,
options
:
[],
},
},
])
const
formConfig
=
ref
([
{
title
:
'物流基础信息'
},
{
prop
:
'name'
,
prop
:
'logistics'
,
type
:
'select'
,
label
:
'物流方式'
,
attrs
:
{
placeholder
:
'请选择物流方式'
,
value
:
'name'
,
label
:
'name'
,
options
:
[],
disabled
:
editForm
.
value
?.[
'id'
]
?
true
:
false
,
onChange
:
(
val
,
id
)
=>
{
editForm
.
value
[
'logisticsId'
]
=
val
.
id
},
},
rules
:
[{
required
:
true
,
message
:
'请选择物流方式'
}],
},
{
prop
:
'rate'
,
type
:
'amountInput'
,
label
:
'Rate(oz/LB)'
,
attrs
:
{
placeholder
:
'请输入Rate(oz/LB)'
,
hasSuffix
:
false
,
hasAppend
:
true
,
appendRender
:
()
=>
{
return
h
(
ElSelect
,
{
modelValue
:
editForm
.
value
[
'unit'
],
'onUpdate:modelValue'
:
(
val
)
=>
(
editForm
.
value
[
'unit'
]
=
val
),
disabled
:
editForm
.
value
[
'id'
]
?
true
:
false
,
placeholder
:
'Select'
,
style
:
{
width
:
'115px'
},
},
()
=>
[
h
(
ElOption
,
{
label
:
'oz'
,
value
:
'oz'
}),
h
(
ElOption
,
{
label
:
'LB'
,
value
:
'LB'
}),
],
)
},
},
rules
:
[{
required
:
true
,
message
:
'请输入Rate'
}],
},
{
prop
:
'zone1'
,
type
:
'input'
,
label
:
'ZONE 1'
,
attrs
:
{
placeholder
:
'请输入
物流名称
'
,
placeholder
:
'请输入
ZONE 1
'
,
},
rules
:
[
{
required
:
true
,
message
:
'请输入物流名称'
,
},
],
},
{
prop
:
'
warehouseName
'
,
type
:
'
selec
t'
,
prop
:
'
zone2
'
,
type
:
'
inpu
t'
,
label
:
'ZONE 2'
,
attrs
:
{
placeholder
:
'请选择仓库名称'
,
options
:
[
{
label
:
'仓库1'
,
value
:
1
},
{
label
:
'仓库2'
,
value
:
2
},
],
placeholder
:
'请输入ZONE 2'
,
},
rules
:
[
{
required
:
true
,
message
:
'请选择仓库名称'
,
},
],
},
{
prop
:
'
ruleRefObj
'
,
prop
:
'
zone3
'
,
type
:
'input'
,
label
:
'ZONE 3'
,
attrs
:
{
placeholder
:
'请选择申报规则'
,
options
:
[
{
label
:
'仓库1'
,
value
:
1
},
{
label
:
'仓库2'
,
value
:
2
},
],
placeholder
:
'请输入ZONE 3'
,
},
rules
:
[
{
required
:
true
,
message
:
'请选择申报规则'
,
},
],
},
{
prop
:
'
serviceCode
'
,
prop
:
'
zone4
'
,
type
:
'input'
,
label
:
'ZONE 4'
,
attrs
:
{
placeholder
:
'请输入
物流编码
'
,
placeholder
:
'请输入
ZONE 4
'
,
},
rules
:
[
{
required
:
true
,
message
:
'请输入物流编码'
,
},
],
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone5
'
,
type
:
'input'
,
label
:
'ZONE 5'
,
attrs
:
{
placeholder
:
'请输入
查询网址
'
,
placeholder
:
'请输入
ZONE 5
'
,
},
rules
:
[
{
required
:
true
,
message
:
'请输入物流编码'
,
},
],
},
{
prop
:
'
status
'
,
prop
:
'
zone6
'
,
type
:
'input'
,
label
:
'ZONE 6'
,
attrs
:
{
placeholder
:
'请输入ZONE 6'
,
},
},
{
prop
:
'
status
'
,
prop
:
'
zone7
'
,
type
:
'input'
,
label
:
'ZONE 7'
,
attrs
:
{
placeholder
:
'请输入ZONE 7'
,
},
},
{
prop
:
'
status
'
,
prop
:
'
zone8
'
,
type
:
'input'
,
label
:
'ZONE 8'
,
attrs
:
{
placeholder
:
'请输入ZONE 8'
,
},
},
{
prop
:
'
status
'
,
prop
:
'
zone9
'
,
type
:
'input'
,
label
:
'ZONE 9'
,
attrs
:
{
placeholder
:
'请输入ZONE 9'
,
},
},
])
const
tableConfig
=
ref
([
{
prop
:
'name'
,
label
:
'Rate(oz/lb)'
,
prop
:
'rateType'
,
label
:
'Rate(oz/LB)'
,
attrs
:
{
align
:
'center'
,
width
:
100
,
},
},
{
prop
:
'
warehouseName
'
,
prop
:
'
rateG
'
,
label
:
'Rate(g)'
,
},
{
prop
:
'
serviceCode
'
,
prop
:
'
rateKg
'
,
label
:
'Rate(kg)'
,
},
{
prop
:
'
statu
s'
,
prop
:
'
logistic
s'
,
label
:
'Logistics'
,
},
{
prop
:
'
status
1'
,
prop
:
'
zone
1'
,
label
:
'ZONE 1'
,
},
{
prop
:
'
status
2'
,
prop
:
'
zone
2'
,
label
:
'ZONE 2'
,
},
{
prop
:
'
status2
'
,
prop
:
'
zone3
'
,
label
:
'ZONE 3'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone4
'
,
label
:
'ZONE 4'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone5
'
,
label
:
'ZONE 5'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone6
'
,
label
:
'ZONE 6'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone7
'
,
label
:
'ZONE 7'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone8
'
,
label
:
'ZONE 8'
,
},
{
prop
:
'
siteUrl
'
,
prop
:
'
zone9
'
,
label
:
'ZONE 9'
,
},
...
...
@@ -309,59 +360,87 @@ const tableConfig = ref([
>
<
Edit
/>
<
/el-icon
>
<
el
-
icon
size
=
"24"
title
=
"删除"
color
=
"#f56c6c"
style
=
"cursor: pointer; vertical-align: middle"
onclick
=
{()
=>
deleteWay
(
row
)}
>
<
Delete
/>
<
/el-icon
>
<
/div
>
),
},
},
])
watch
(
()
=>
searchForm
.
value
,
(
val
)
=>
{
if
(
val
.
logisticsList
===
''
)
{
val
.
logisticsList
=
[]
}
},
{
immediate
:
true
,
deep
:
true
},
)
watch
(
()
=>
data
.
value
,
(
val
)
=>
{
try
{
tableData
.
value
=
getTableData
(
val
)
if
(
searchForm
.
value
.
logisticsList
?.
length
)
{
let
startRow
=
0
mergeCells
.
value
=
[]
data
.
value
.
forEach
((
item
)
=>
{
if
(
item
.
logisticsQuotationList
?.
length
)
{
const
rowspan
=
item
.
logisticsQuotationList
.
length
for
(
let
col
=
0
;
col
<
5
;
col
++
)
{
mergeCells
.
value
.
push
({
row
:
startRow
,
col
:
col
,
rowspan
:
rowspan
,
colspan
:
1
,
})
}
startRow
+=
rowspan
}
})
}
}
catch
(
e
)
{
console
.
log
(
e
)
}
finally
{
// loading.value = false
}
},
{
immediate
:
true
,
deep
:
true
},
)
onMounted
(()
=>
{
// getAllList()
// loading.value = true
getAllList
()
})
const
loading
=
ref
(
false
)
function
getTableData
(
arr
)
{
const
newArr
=
[]
if
(
arr
.
length
)
{
arr
.
forEach
((
item
,
index
)
=>
{
if
(
item
.
logisticsQuotationList
?.
length
)
{
item
.
logisticsQuotationList
.
forEach
((
item
)
=>
{
item
.
seq
=
index
+
1
newArr
.
push
(
item
)
})
}
})
return
newArr
}
return
[]
}
function
cancelFn
()
{
dialogVisible
.
value
=
false
editFormRef
.
value
?.
resetFields
()
resetEditForm
()
}
async
function
deleteWay
(
item
)
{
try
{
await
showConfirm
(
'是否删除用户'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
}
catch
{
return
}
try
{
const
ids
=
[
item
.
id
].
join
(
','
)
await
deleteLogisticsQuotation
(
ids
)
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
,
})
search
()
}
catch
(
e
)
{
search
()
// showError(e)
}
}
async
function
editWay
(
item
:
LogisticsMethod
)
{
try
{
editForm
.
value
=
{
...
item
}
console
.
log
(
432
,
editForm
.
value
)
// formConfig.value[0].attrs!.disabled = true
// formConfig.value[1].attrs!.disabled = true
dialogVisible
.
value
=
true
}
catch
(
e
)
{
console
.
log
(
e
)
...
...
@@ -418,6 +497,7 @@ async function save() {
}
function
addDialog
()
{
dialogVisible
.
value
=
true
console
.
log
(
502
,
editForm
.
value
)
}
async
function
deleteFn
()
{
if
(
!
selection
.
value
.
length
)
{
...
...
@@ -457,18 +537,77 @@ function handleCheckboxRecords(value: never[]) {
async
function
getAllList
()
{
try
{
const
res
=
await
Promise
.
all
([
getlogisticsWayAllList
()])
searchConfig
.
value
[
0
].
attrs
.
options
=
[]
console
.
log
(
545
,
res
)
searchConfig
.
value
[
0
].
attrs
!
.
options
=
[...(
res
[
0
]?.
data
||
[])]
formConfig
.
value
[
0
].
attrs
!
.
options
=
[...(
res
[
0
]?.
data
||
[])]
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
function
onBeforeUploadImage
(
file
)
{
const
isIMAGE
=
file
.
type
==
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
if
(
!
isIMAGE
)
{
ElMessage
.
error
(
'上传文件只能是excel格式!'
)
}
return
isIMAGE
}
async
function
downloadExcel
()
{
try
{
const
res
=
await
downloadLogisticsQuotationTemplate
()
console
.
log
(
483
,
data
)
const
blob
=
new
Blob
([
res
])
// 2. 解析文件名(从响应头或自定义)
const
filename
=
'物流报价模版.xlsx'
// 3. 创建临时链接并触发下载
const
link
=
document
.
createElement
(
'a'
)
link
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
link
.
download
=
filename
link
.
click
()
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
async
function
exportExcel
(
file
)
{
try
{
const
formData
=
new
FormData
()
formData
.
append
(
'file'
,
file
.
file
)
formData
.
append
(
'type'
,
'add'
)
const
res
=
await
importLogisticsQuotation
(
formData
)
if
(
res
.
code
===
200
)
{
ElMessage
.
success
(
'导入成功!'
)
search
()
}
}
catch
(
error
)
{
ElMessage
.
error
(
'导入失败!'
)
}
}
async
function
updateExcel
(
file
)
{
try
{
const
formData
=
new
FormData
()
formData
.
append
(
'file'
,
file
.
file
)
formData
.
append
(
'type'
,
'update'
)
function
downloadExcel
()
{}
function
exportExcel
()
{}
const
res
=
await
importLogisticsQuotation
(
formData
)
if
(
res
.
code
===
200
)
{
ElMessage
.
success
(
'导入成功!'
)
search
()
}
}
catch
(
error
)
{
ElMessage
.
error
(
'导入失败!'
)
}
}
watch
(
editForm
,
()
=>
loading
.
value
,
(
val
)
=>
{
console
.
log
(
442
,
val
)
},
...
...
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