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
67ef1de4
Commit
67ef1de4
authored
Nov 26, 2025
by
linjinhong
Committed by
wusiyi
Dec 18, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:【工厂端】工厂端-供应模块新增供应商管理#1001007
parent
40cfb810
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
705 additions
and
692 deletions
+705
-692
src/api/supplier/supplierManagement.ts
+49
-6
src/components/VxeTable.tsx
+8
-0
src/views/supply/supplierManagement/components/LogisticsWaySelect.tsx
+0
-414
src/views/supply/supplierManagement/components/dialog.tsx
+2
-0
src/views/supply/supplierManagement/hooks/useValue.ts
+0
-14
src/views/supply/supplierManagement/index.vue
+572
-94
src/views/supply/supplierManagement/types/declarationRule.ts
+0
-40
src/views/supply/supplierManagement/types/index.ts
+74
-0
src/views/supply/supplierManagement/types/logistics.ts
+0
-62
src/views/supply/supplierManagement/types/logisticsPartition.ts
+0
-6
src/views/supply/supplierManagement/types/logisticsQuotation.ts
+0
-22
src/views/supply/supplierManagement/types/shippingAddress.ts
+0
-34
No files found.
src/api/supplier/supplierManagement.ts
View file @
67ef1de4
import
{
BasePaginationData
,
BaseRespData
}
from
'@/types/api'
import
{
BasePaginationData
,
BaseRespData
}
from
'@/types/api'
import
axios
from
'./../axios'
import
axios
from
'./../axios'
import
{
IListPage
,
IsupplierType
,
}
from
'@/views/supply/supplierManagement/types/index'
export
interface
IListPage
{
pageSize
:
number
|
string
currentPage
:
number
|
string
}
//供应商分页查询
//供应商分页查询
export
function
getSupplierListApi
(
params
:
IListPage
)
{
export
function
getSupplierListApi
(
params
:
IListPage
)
{
return
axios
.
pos
t
<
never
,
BasePaginationData
<
never
>>
(
return
axios
.
ge
t
<
never
,
BasePaginationData
<
never
>>
(
'/factory/supplier/list_page'
,
'/factory/supplier/list_page'
,
params
,
{
params
}
,
)
)
}
}
...
@@ -19,3 +19,46 @@ export function deleteSupplierApi(params: { ids: string }) {
...
@@ -19,3 +19,46 @@ export function deleteSupplierApi(params: { ids: string }) {
params
,
params
,
})
})
}
}
// 编辑回显接口
export
function
getSupplierDetailApi
(
id
:
string
|
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'factory/supplier/get'
,
{
params
:
{
id
},
})
}
// 根据分类id获取属性信息
export
function
getPropertyByCateIdApi
(
cateId
:
string
|
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/factory/supplier/getPropertyByCateId'
,
{
params
:
{
cateId
},
},
)
}
// 根据spu获取商品信息
export
function
getProductInfoBySpuApi
(
spu
:
string
|
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/factory/supplier/getProductInfoBySpu'
,
{
params
:
{
spu
},
},
)
}
// 获取币种接口
export
function
getBaseCurrencyInfoApi
()
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'factory/supplier/getBaseCurrencyInfo'
,
)
}
//新增
export
function
addSupplierApi
(
params
:
IsupplierType
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/factory/supplier/add'
,
params
)
}
//修改
export
function
updateSupplierApi
(
params
:
IsupplierType
)
{
return
axios
.
post
<
never
,
BaseRespData
<
never
>>
(
'/factory/supplier/update'
,
params
,
)
}
src/components/VxeTable.tsx
View file @
67ef1de4
...
@@ -110,6 +110,13 @@ export default defineComponent({
...
@@ -110,6 +110,13 @@ export default defineComponent({
emit
(
'getCheckboxRecords'
,
selectRecords
)
emit
(
'getCheckboxRecords'
,
selectRecords
)
}
}
}
}
//获取设置多选框
const
setCheckboxRow
=
(
row
:
TableRowData
,
checked
:
boolean
)
=>
{
const
$table
=
tableRef
.
value
if
(
$table
)
{
$table
.
setCheckboxRow
(
row
,
checked
)
}
}
//设置高亮行
//设置高亮行
const
selectRowEvent
=
(
row
:
TableRowData
)
=>
{
const
selectRowEvent
=
(
row
:
TableRowData
)
=>
{
const
$table
=
tableRef
.
value
const
$table
=
tableRef
.
value
...
@@ -129,6 +136,7 @@ export default defineComponent({
...
@@ -129,6 +136,7 @@ export default defineComponent({
editConfig
,
editConfig
,
getSelectEvent
,
getSelectEvent
,
selectRowEvent
,
selectRowEvent
,
setCheckboxRow
,
attrs
,
attrs
,
}
}
},
},
...
...
src/views/supply/supplierManagement/components/LogisticsWaySelect.tsx
deleted
100644 → 0
View file @
40cfb810
import
{
defineComponent
,
ref
}
from
'vue'
import
{
ElPopover
,
ElScrollbar
,
ElCheckbox
,
ElCheckboxGroup
,
ElRadioGroup
,
ElRadio
,
ElInput
,
}
from
'element-plus'
const
styles
=
{
searchForm
:
{
position
:
'relative'
,
},
titleBox
:
{
display
:
'flex'
,
padding
:
'10px 18px'
,
justifyContent
:
'space-between'
,
alignItems
:
'center'
,
},
checkboxGroup
:
{
display
:
'flex'
,
padding
:
'10px'
,
justifyContent
:
'flex-start'
,
flexWrap
:
'wrap'
,
backgroundColor
:
'#efefef'
,
},
checkbox
:
{
width
:
'33.3333%'
,
'margin-right'
:
'0px !important'
,
},
}
as
const
interface
ICompanyList
{
warehouseName
:
string
wayList
:
IwayList
[]
}
interface
IwayList
{
name
:
string
id
:
string
}
interface
IAllList
{
factoryId
?:
number
id
:
number
|
string
name
:
string
serviceCode
?:
string
siteUrl
?:
string
status
?:
number
uinuinWarehouseId
?:
number
|
null
updateTime
?:
string
warehouseId
?:
number
warehouseName
?:
string
wayList
?:
IwayList
[]
}
export
default
defineComponent
({
name
:
'CustomizeForm'
,
props
:
{
modelValue
:
{
type
:
[
Array
,
String
,
Number
]
as
PropType
<
(
string
|
number
)[]
|
string
|
number
>
,
default
:
()
=>
[],
// 可选:添加自定义验证器确保类型安全
validator
:
(
value
:
unknown
)
=>
{
return
(
Array
.
isArray
(
value
)
||
typeof
value
===
'string'
||
typeof
value
===
'number'
)
},
},
companyList
:
{
type
:
Array
as
PropType
<
IAllList
[]
|
ICompanyList
[]
>
,
default
:
()
=>
[],
},
isRadio
:
{
type
:
Boolean
,
default
:
false
,
},
valueKey
:
{
type
:
String
,
default
:
'id'
,
},
searchPlaceholder
:
{
type
:
String
,
default
:
'请搜索承运商'
,
},
startPlaceholder
:
{
type
:
String
,
default
:
'请选择物流方式'
,
},
startWidth
:
{
type
:
String
,
default
:
'100%'
,
},
},
emits
:
[
'update:modelValue'
],
setup
(
props
,
{
emit
})
{
const
companyList
=
ref
<
ICompanyList
[]
>
([])
const
templeCompanyList
=
ref
<
ICompanyList
[]
|
IwayList
[]
|
IAllList
[]
>
([])
const
allList
=
ref
<
IAllList
[]
>
([])
const
allWayLists
=
ref
<
IwayList
[]
>
([])
const
selectedList
=
ref
<
(
string
|
number
)[]
>
([])
const
selectedRadioList
=
ref
<
string
|
number
>
()
const
waysName
=
ref
(
''
)
const
searchName
=
ref
(
''
)
watch
(
()
=>
props
.
modelValue
,
(
newVal
)
=>
{
if
(
props
.
isRadio
)
{
allWayLists
.
value
=
props
.
companyList
.
flatMap
(
(
company
)
=>
company
.
wayList
,
)
as
IwayList
[]
if
(
props
.
valueKey
===
'id'
)
{
selectedRadioList
.
value
=
newVal
as
string
|
number
}
else
{
selectedRadioList
.
value
=
allWayLists
.
value
.
find
((
el
:
IwayList
)
=>
newVal
===
el
.
name
)
?.
id
||
''
}
}
else
{
selectedList
.
value
=
newVal
as
(
string
|
number
)[]
}
},
{
immediate
:
true
,
deep
:
true
,
},
)
watch
(
[
()
=>
selectedList
.
value
,
()
=>
props
.
companyList
,
()
=>
selectedRadioList
.
value
,
],
(
newVal
)
=>
{
if
(
props
.
isRadio
)
{
companyList
.
value
=
newVal
[
1
]
as
ICompanyList
[]
allWayLists
.
value
=
props
.
companyList
.
flatMap
(
(
company
)
=>
company
.
wayList
,
)
as
IwayList
[]
waysName
.
value
=
allWayLists
.
value
.
find
((
el
:
IwayList
)
=>
newVal
[
2
]
===
el
.
id
)
?.
name
||
''
if
(
props
.
valueKey
===
'id'
)
{
emit
(
'update:modelValue'
,
newVal
[
2
])
}
else
{
emit
(
'update:modelValue'
,
waysName
.
value
)
}
}
else
{
emit
(
'update:modelValue'
,
newVal
[
0
])
allList
.
value
=
newVal
[
1
]
as
IAllList
[]
companyList
.
value
=
transformData
(
newVal
[
1
]
as
IAllList
[])
if
(
newVal
[
1
]?.
length
)
{
waysName
.
value
=
(
newVal
[
1
]
as
IAllList
[])
.
filter
((
item
)
=>
{
if
(
newVal
[
0
].
includes
(
item
.
id
))
{
return
item
.
name
}
})
.
map
((
item
)
=>
item
.
name
)
.
join
(
','
)
// emit('waysName', res)
// console.log(87, waysName.value)
}
}
},
{
deep
:
true
,
immediate
:
true
},
)
const
handleClearSelection
=
()
=>
{
/* 1. 清空显示文本 */
waysName
.
value
=
''
/* 2. 清空双向绑定结果 */
if
(
props
.
isRadio
)
{
selectedRadioList
.
value
=
''
// 单选
emit
(
'update:modelValue'
,
''
)
}
else
{
selectedList
.
value
=
[]
// 多选
emit
(
'update:modelValue'
,
[])
}
/* 3. 可选:把搜索框也重置 */
searchName
.
value
=
''
}
function
setCheckAll
(
company
:
ICompanyList
,
event
:
boolean
)
{
if
(
event
)
{
selectedList
.
value
=
[
...
selectedList
.
value
,
...
company
.
wayList
.
map
((
item
)
=>
item
.
id
),
]
}
else
{
selectedList
.
value
=
selectedList
.
value
.
filter
(
(
item
)
=>
!
company
.
wayList
.
map
((
el
)
=>
el
.
id
).
includes
(
item
as
string
),
)
}
}
const
getCompanySelectedStatus
=
computed
(()
=>
{
const
statusMap
=
new
Map
()
companyList
.
value
.
forEach
((
company
:
ICompanyList
)
=>
{
const
allSelected
=
company
.
wayList
.
every
((
way
)
=>
selectedList
.
value
.
includes
(
way
.
id
),
)
statusMap
.
set
(
company
.
warehouseName
,
allSelected
)
})
return
(
company
:
ICompanyList
)
=>
statusMap
.
get
(
company
.
warehouseName
)
})
function
fuzzySearch
<
T
>
(
items
:
T
[],
searchTerm
:
string
,
key
:
keyof
T
=
'name'
as
keyof
T
,
):
T
[]
{
// 空搜索返回所有元素
if
(
!
searchTerm
.
trim
())
{
return
[...
items
]
}
// 将搜索词转为小写(不区分大小写)
const
searchLower
=
searchTerm
.
toLowerCase
()
return
items
.
filter
((
item
)
=>
{
// 获取属性值
const
value
=
item
[
key
]
// 确保属性值存在且为字符串
if
(
typeof
value
!==
'string'
)
return
false
// 将属性值转为小写并检查是否包含搜索词
return
value
.
toLowerCase
().
includes
(
searchLower
)
})
}
function
transformData
(
data
:
IAllList
[])
{
const
warehouseMap
=
new
Map
()
for
(
const
item
of
data
)
{
const
warehouseName
=
item
.
warehouseName
??
'未命名仓库'
if
(
!
warehouseMap
.
has
(
warehouseName
))
{
warehouseMap
.
set
(
warehouseName
,
new
Set
())
}
warehouseMap
.
get
(
warehouseName
).
add
({
name
:
item
.
name
,
id
:
item
.
id
})
}
const
result
:
{
warehouseName
:
string
wayList
:
{
name
:
string
;
id
:
string
}[]
}[]
=
[]
warehouseMap
.
forEach
((
children
,
parent
)
=>
{
result
.
push
({
warehouseName
:
parent
,
wayList
:
Array
.
from
(
children
),
})
})
return
result
}
return
()
=>
(
<
ElPopover
width=
"750px"
placement=
"bottom-start"
trigger=
"click"
popper
-
style=
{
{
padding
:
0
}
}
onUpdate
:
visible=
{
(
value
)
=>
{
if
(
value
)
searchName
.
value
=
''
}
}
v
-
slots=
{
{
reference
:
()
=>
(
<
ElInput
modelValue=
{
waysName
.
value
}
style=
{
{
width
:
props
.
startWidth
}
}
placeholder=
{
props
.
startPlaceholder
}
clearable
onClear=
{
handleClearSelection
}
/>
),
}
}
>
<
ElInput
modelValue=
{
searchName
.
value
}
onUpdate
:
modelValue=
{
(
value
)
=>
{
if
(
props
.
isRadio
)
{
templeCompanyList
.
value
=
fuzzySearch
(
allWayLists
.
value
,
value
)
}
else
{
templeCompanyList
.
value
=
fuzzySearch
(
allList
.
value
,
value
)
}
console
.
log
(
'templeCompanyList'
,
templeCompanyList
.
value
)
searchName
.
value
=
value
}
}
clearable
style=
{
{
width
:
'200px'
,
padding
:
'10px'
}
}
placeholder=
{
props
.
searchPlaceholder
}
/>
<
ElScrollbar
class=
"scroll-container"
maxHeight=
"450px"
style=
{
{
'border-top'
:
'1px solid #eee'
}
}
>
{
!
searchName
.
value
?
(
companyList
.
value
.
map
((
company
,
index
)
=>
(
<
div
class=
"companyBox"
key=
{
index
}
>
<
div
style=
{
styles
.
titleBox
}
>
<
div
class=
"title"
>
{
company
.
warehouseName
}
</
div
>
{
!
props
.
isRadio
&&
(
<
ElCheckbox
modelValue=
{
getCompanySelectedStatus
.
value
(
company
as
ICompanyList
,
)
}
onChange=
{
(
v
)
=>
setCheckAll
(
company
as
ICompanyList
,
v
as
boolean
)
}
class=
"selectAll"
>
全选
</
ElCheckbox
>
)
}
</
div
>
{
props
.
isRadio
?
(
<
ElRadioGroup
modelValue=
{
selectedRadioList
.
value
}
onUpdate
:
modelValue=
{
(
value
)
=>
{
console
.
log
(
'company'
,
value
)
selectedRadioList
.
value
=
value
as
string
|
number
}
}
style=
{
styles
.
checkboxGroup
}
>
{
company
.
wayList
?.
map
((
item
)
=>
(
<
div
title=
{
item
.
name
}
style=
{
styles
.
checkbox
}
>
<
ElRadio
label=
{
item
.
name
}
value=
{
item
.
id
}
key=
{
`item-${item.id}`
}
>
{
item
.
name
}
</
ElRadio
>
</
div
>
))
}
</
ElRadioGroup
>
)
:
(
<
ElCheckboxGroup
modelValue=
{
selectedList
.
value
}
onUpdate
:
modelValue=
{
(
value
)
=>
(
selectedList
.
value
=
value
)
}
style=
{
styles
.
checkboxGroup
}
>
{
(
company
as
ICompanyList
).
wayList
.
map
((
item
)
=>
(
<
div
title=
{
item
.
name
}
style=
{
styles
.
checkbox
}
>
<
ElCheckbox
label=
{
item
.
name
}
value=
{
item
.
id
}
key=
{
`item-${item.id}`
}
class=
"checkboxItem"
/>
</
div
>
))
}
</
ElCheckboxGroup
>
)
}
</
div
>
))
)
:
props
.
isRadio
?
(
<
ElRadioGroup
modelValue=
{
selectedRadioList
.
value
}
onUpdate
:
modelValue=
{
(
value
)
=>
{
console
.
log
(
'company'
,
value
)
selectedRadioList
.
value
=
value
as
string
|
number
}
}
style=
{
styles
.
checkboxGroup
}
>
{
(
templeCompanyList
.
value
as
IwayList
[]).
map
((
item
)
=>
(
<
div
title=
{
item
.
name
}
style=
{
styles
.
checkbox
}
>
<
ElRadio
label=
{
item
.
name
}
value=
{
item
.
id
}
key=
{
`item-${item.id}`
}
>
{
item
.
name
}
</
ElRadio
>
</
div
>
))
}
</
ElRadioGroup
>
)
:
(
<
ElCheckboxGroup
modelValue=
{
selectedList
.
value
}
onUpdate
:
modelValue=
{
(
value
)
=>
(
selectedList
.
value
=
value
)
}
style=
{
styles
.
checkboxGroup
}
>
{
(
templeCompanyList
.
value
as
IwayList
[]).
map
((
item
)
=>
(
<
div
title=
{
item
.
name
}
style=
{
styles
.
checkbox
}
>
<
ElCheckbox
label=
{
item
.
name
}
value=
{
item
.
id
}
key=
{
`item-${item.id}`
}
class=
"checkboxItem"
/>
</
div
>
))
}
</
ElCheckboxGroup
>
)
}
</
ElScrollbar
>
</
ElPopover
>
)
},
})
src/views/supply/supplierManagement/components/dialog.tsx
View file @
67ef1de4
...
@@ -32,6 +32,7 @@ export default defineComponent({
...
@@ -32,6 +32,7 @@ export default defineComponent({
return
()
=>
{
return
()
=>
{
return
(
return
(
<
div
>
<
ElDialog
<
ElDialog
ref=
{
formRef
}
ref=
{
formRef
}
v
-
model=
{
isShow
.
value
}
v
-
model=
{
isShow
.
value
}
...
@@ -49,6 +50,7 @@ export default defineComponent({
...
@@ -49,6 +50,7 @@ export default defineComponent({
{
slots
.
footer
?.()
}
{
slots
.
footer
?.()
}
</
div
>
</
div
>
</
ElDialog
>
</
ElDialog
>
</
div
>
)
)
}
}
},
},
...
...
src/views/supply/supplierManagement/hooks/useValue.ts
deleted
100644 → 0
View file @
40cfb810
import
{
Ref
,
ref
}
from
'vue'
import
{
cloneDeep
}
from
'lodash-es'
export
function
useValue
<
T
extends
object
>
(
initialValue
:
T
,
):
[
Ref
<
T
>
,
()
=>
void
]
{
const
value
=
ref
<
T
>
(
cloneDeep
(
initialValue
))
as
Ref
<
T
>
const
resetToDefault
=
()
=>
{
value
.
value
=
cloneDeep
(
initialValue
)
}
return
[
value
,
resetToDefault
]
}
src/views/supply/supplierManagement/index.vue
View file @
67ef1de4
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
width=
"75%"
width=
"75%"
>
>
<CustomizeForm
<CustomizeForm
v-loading=
"editLoading"
ref=
"editFormRef"
ref=
"editFormRef"
v-model=
"editForm"
v-model=
"editForm"
:config=
"formConfig"
:config=
"formConfig"
...
@@ -54,34 +55,81 @@
...
@@ -54,34 +55,81 @@
</Dialog>
</Dialog>
<Dialog
<Dialog
title=
"管理供应
商
价格"
title=
"管理供应价格"
v-model=
"piceDialogVisible"
v-model=
"p
r
iceDialogVisible"
width=
"65%"
width=
"65%"
v-loading=
"priceLoading"
@
close=
"cancelPiceFn"
@
close=
"cancelPiceFn"
teleported
>
>
<div
style=
"display: flex; margin-bottom: 10px"
>
<div
style=
"display: flex; margin-bottom: 10px"
>
<div
style=
"display: flex; align-items: center; gap: 20px"
>
<div
style=
"display: flex; align-items: center; gap: 20px"
>
<div><span
style=
"color: red"
>
*
</span>
结算币种
</div>
<div><span
style=
"color: red"
>
*
</span>
结算币种
</div>
<el-select
style=
"width: 300px; flex: 1"
></el-select>
<el-select
style=
"width: 300px; flex: 1"
v-model=
"currentGoods.currencyCode"
@
change=
"
(v:string) => {
currentGoods.currencyName =
currencyOptions?.find((el) => v == el.currencyCode)
?.currencyName || ''
console.log(73,currentGoods.currencyName);
}
"
>
<el-option
v-for=
"(item, index) in currencyOptions"
:key=
"index"
:label=
"`${item.currencyName}(${item.currencyCode})`"
:value=
"item.currencyCode"
>
</el-option>
</el-select>
</div>
</div>
</div>
</div>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showColorList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
颜色(Color)
颜色(Color)
</div>
</div>
<div
class=
"flex gap-2"
>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
color=
"#0000ff"
v-for=
"value in 8"
:key=
"value"
<el-tag
>
Tag {{ value }}
</el-tag
:title=
"`${item.cnname}(${item.enname})`"
:color=
"item.bgColor"
v-for=
"(item, index) in showColorList"
:key=
"index"
:style=
"{ color: item.fontColor }"
class=
"tabBox"
:class=
"{ active: colorIndex === item.code }"
@
click=
"optionSelection(item, 'color')"
>
{{ item.cnname }}({{ item.enname }})
</el-tag
>
>
</div>
</div>
</div>
</div>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
>
<div
style=
"border-top: 1px solid #eee; margin-bottom: 10px"
v-if=
"showSizeList.length"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
<div
style=
"font-size: 20px; font-weight: bold; margin: 10px 0"
>
尺码(Size)
尺码(Size)
</div>
</div>
<div
class=
"flex gap-2"
>
<div
class=
"flex"
style=
"flex-wrap: wrap; gap: 5px"
>
<el-tag
color=
"#0000ff"
v-for=
"value in 8"
:key=
"value"
<el-tag
>
Tag {{ value }}
</el-tag
class=
"tabBox"
color=
"#ffff87"
style=
"color: #333"
effect=
"dark"
type=
"info"
v-for=
"(item, index) in showSizeList"
:key=
"index"
:class=
"{ active: sizeIndex === item.code }"
@
click=
"optionSelection(item, 'size')"
>
{{ item.cnname }}
</el-tag
>
>
</div>
</div>
</div>
</div>
...
@@ -95,23 +143,29 @@
...
@@ -95,23 +143,29 @@
>
>
<div
style=
"margin: 10px 0"
>
<div
style=
"margin: 10px 0"
>
<el-input
<el-input
placeholder=
"请输入
更新
价格"
placeholder=
"请输入
供应
价格"
style=
"width: 200px; margin-right:
2
0px"
style=
"width: 200px; margin-right:
1
0px"
size=
"small"
size=
"small"
v-model=
"supplierPirce"
clearable
></el-input
></el-input
><ElButton
type=
"primary"
@
click=
"updatePrices"
size=
"small"
><ElButton
type=
"primary"
@
click=
"updatePrices"
size=
"small"
>
批量更新价格
</ElButton
>
批量更新供应价格
</ElButton
>
<span
style=
"color: #f56c6c; vertical-align: middle"
>
(请注意!该操作会覆盖已有供应价格)
</span
>
>
</div>
</div>
</div>
</div>
<CustomizeTable
<CustomizeTable
ref=
"tableRef"
border
border
style=
"margin-bottom: 20px"
style=
"margin-bottom: 20px"
v-model=
"picetableData"
v-model=
"p
r
icetableData"
:config=
"
supply
TableConfig"
:config=
"
price
TableConfig"
align=
"center"
align=
"center"
height=
"500px"
height=
"500px"
@
getCheckboxRecords=
"
handleCheckboxRecords
"
@
getCheckboxRecords=
"
selectPirce
"
></CustomizeTable>
></CustomizeTable>
<
template
#
footer
>
<
template
#
footer
>
<div
style=
"text-align: center"
>
<div
style=
"text-align: center"
>
...
@@ -130,6 +184,12 @@ defineOptions({
...
@@ -130,6 +184,12 @@ defineOptions({
import
{
import
{
getSupplierListApi
,
getSupplierListApi
,
deleteSupplierApi
,
deleteSupplierApi
,
getSupplierDetailApi
,
getPropertyByCateIdApi
,
getProductInfoBySpuApi
,
getBaseCurrencyInfoApi
,
addSupplierApi
,
updateSupplierApi
,
}
from
'@/api/supplier/supplierManagement.ts'
}
from
'@/api/supplier/supplierManagement.ts'
import
Dialog
from
'./components/dialog.tsx'
import
Dialog
from
'./components/dialog.tsx'
...
@@ -137,18 +197,24 @@ import CustomizeForm from '@/components/CustomizeForm.tsx'
...
@@ -137,18 +197,24 @@ import CustomizeForm from '@/components/CustomizeForm.tsx'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
CustomizeTable
from
'@/components/VxeTable.tsx'
import
{
IFormConfig
}
from
'@/components/CustomizeForm.tsx'
import
{
IFormConfig
}
from
'@/components/CustomizeForm.tsx'
import
usePageList
from
'@/utils/hooks/usePageList'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
useValue
}
from
'
.
/hooks/useValue'
import
{
useValue
}
from
'
@/utils
/hooks/useValue'
import
{
showConfirm
}
from
'@/utils/ui'
import
{
showConfirm
}
from
'@/utils/ui'
import
{
debounce
}
from
'lodash-es'
import
{
debounce
,
cloneDeep
}
from
'lodash-es'
import
{
AddDeclarationRuleObj
}
from
'./types/declarationRule'
import
{
Edit
,
CirclePlus
}
from
'@element-plus/icons-vue'
import
{
Edit
,
CirclePlus
}
from
'@element-plus/icons-vue'
import
{
TableColumn
}
from
'@/components/VxeTable'
import
{
TableColumn
}
from
'@/components/VxeTable'
import
{
IgoodsType
,
IsupplierType
,
IcurrencyCode
,
IcolorType
,
IsizeType
,
IPropertyResponseItem
,
Iprice
,
}
from
'./types/index.ts'
const
[
editForm
,
resetEditForm
]
=
useValue
<
AddDeclarationRuleObj
>
({
const
[
editForm
,
resetEditForm
]
=
useValue
<
IsupplierType
>
({})
type
:
1
,
currency
:
'USD'
,
})
const
{
const
{
loading
,
loading
,
currentPage
,
currentPage
,
...
@@ -169,14 +235,15 @@ const {
...
@@ -169,14 +235,15 @@ const {
}),
}),
})
})
const
dialogVisible
=
ref
(
false
)
const
dialogVisible
=
ref
(
false
)
const
editLoading
=
ref
(
false
)
const
goodsTableData
=
ref
([])
const
goodsTableData
=
ref
([])
const
supplierTableData
=
ref
([])
const
supplierTableData
=
ref
<
IgoodsType
[]
>
([])
const
piceDialogVisible
=
ref
(
false
)
const
p
r
iceDialogVisible
=
ref
(
false
)
const
p
icetableData
=
ref
([])
const
p
ricetableData
=
ref
<
Iprice
[]
>
([])
const
editFormRef
=
ref
<
InstanceType
<
typeof
CustomizeForm
>
|
null
>
(
null
)
const
editFormRef
=
ref
<
InstanceType
<
typeof
CustomizeForm
>
|
null
>
(
null
)
const
selection
=
ref
([])
const
selection
=
ref
<
Iprice
[]
>
([])
interface
IOption
{
interface
IOption
{
[
key
:
string
]:
unknown
[
key
:
string
]:
unknown
...
@@ -184,12 +251,12 @@ interface IOption {
...
@@ -184,12 +251,12 @@ interface IOption {
const
formConfig
=
computed
<
IFormConfig
[]
>
(()
=>
[
const
formConfig
=
computed
<
IFormConfig
[]
>
(()
=>
[
{
{
prop
:
'
n
ame'
,
prop
:
'
supplierN
ame'
,
type
:
'input'
,
type
:
'input'
,
label
:
'供应商名称'
,
label
:
'供应商名称'
,
attrs
:
{
attrs
:
{
placeholder
:
'请输入供应商名称'
,
placeholder
:
'请输入供应商名称'
,
width
:
'33%'
,
width
:
'33
.333
%'
,
},
},
rules
:
[
rules
:
[
{
{
...
@@ -199,12 +266,12 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -199,12 +266,12 @@ const formConfig = computed<IFormConfig[]>(() => [
],
],
},
},
{
{
prop
:
'
name
'
,
prop
:
'
contacts
'
,
type
:
'input'
,
type
:
'input'
,
label
:
'联系人'
,
label
:
'联系人'
,
attrs
:
{
attrs
:
{
placeholder
:
'请输入联系人'
,
placeholder
:
'请输入联系人'
,
width
:
'33%'
,
width
:
'33
.333
%'
,
},
},
rules
:
[
rules
:
[
{
{
...
@@ -214,12 +281,12 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -214,12 +281,12 @@ const formConfig = computed<IFormConfig[]>(() => [
],
],
},
},
{
{
prop
:
'
name
'
,
prop
:
'
contactsNumber
'
,
type
:
'input'
,
type
:
'input'
,
label
:
'联系电话'
,
label
:
'联系电话'
,
attrs
:
{
attrs
:
{
placeholder
:
'请输入联系电话'
,
placeholder
:
'请输入联系电话'
,
width
:
'33%'
,
width
:
'33
.333
%'
,
},
},
rules
:
[
rules
:
[
{
{
...
@@ -229,7 +296,7 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -229,7 +296,7 @@ const formConfig = computed<IFormConfig[]>(() => [
],
],
},
},
{
{
prop
:
'
name
'
,
prop
:
'
address
'
,
type
:
'input'
,
type
:
'input'
,
label
:
'地址'
,
label
:
'地址'
,
attrs
:
{
attrs
:
{
...
@@ -261,6 +328,7 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -261,6 +328,7 @@ const formConfig = computed<IFormConfig[]>(() => [
render
:
()
=>
{
render
:
()
=>
{
return
(
return
(
<
div
style
=
{{
width
:
'100%'
}}
>
<
div
style
=
{{
width
:
'100%'
}}
>
<
div
class
=
"flex"
style
=
{{
justifyContent
:
'space-between'
}}
>
<
div
<
div
style
=
{{
style
=
{{
display
:
'flex'
,
display
:
'flex'
,
...
@@ -281,6 +349,7 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -281,6 +349,7 @@ const formConfig = computed<IFormConfig[]>(() => [
placement
=
"right"
placement
=
"right"
trigger
=
"click"
trigger
=
"click"
width
=
"1050"
width
=
"1050"
disabled
=
{
isShowSearch
.
value
}
v
-
slots
=
{{
v
-
slots
=
{{
reference
:
()
=>
(
reference
:
()
=>
(
<
el
-
button
<
el
-
button
...
@@ -302,12 +371,18 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -302,12 +371,18 @@ const formConfig = computed<IFormConfig[]>(() => [
><
/CustomizeTable
>
><
/CustomizeTable
>
<
/el-popover
>
<
/el-popover
>
<
/div
>
<
/div
>
<
div
>
<
el
-
button
type
=
"danger"
onclick
=
{()
=>
deleteSupplyGoodsFn
()}
>
删除
<
/el-button
>
<
/div
>
<
/div
>
<
CustomizeTable
<
CustomizeTable
modelValue
=
{
supplierTableData
.
value
}
modelValue
=
{
supplierTableData
.
value
}
config
=
{
formTableConfig
.
value
}
config
=
{
formTableConfig
.
value
}
{...{
height
:
'
5
00px'
,
align
:
'center'
,
border
:
true
}}
{...{
height
:
'
4
00px'
,
align
:
'center'
,
border
:
true
}}
style
=
{{
marginBottom
:
'20px'
}}
style
=
{{
marginBottom
:
'20px'
}}
onGetCheckboxRecords
=
{(
v
)
=>
getSupplierItem
(
v
)}
><
/CustomizeTable
>
><
/CustomizeTable
>
<
/div
>
<
/div
>
)
)
...
@@ -317,20 +392,20 @@ const formConfig = computed<IFormConfig[]>(() => [
...
@@ -317,20 +392,20 @@ const formConfig = computed<IFormConfig[]>(() => [
const
tableConfig
=
ref
<
TableColumn
[]
>
([
const
tableConfig
=
ref
<
TableColumn
[]
>
([
{
{
prop
:
'
n
ame'
,
prop
:
'
supplierN
ame'
,
label
:
'供应商名称'
,
label
:
'供应商名称'
,
},
},
{
{
prop
:
'c
urrency
'
,
prop
:
'c
ontacts
'
,
label
:
'联系人'
,
label
:
'联系人'
,
},
},
{
{
prop
:
'
type
'
,
prop
:
'
contactsNumber
'
,
label
:
'联系电话'
,
label
:
'联系电话'
,
},
},
{
{
prop
:
'
logisticsWayId
'
,
prop
:
'
address
'
,
label
:
'地址'
,
label
:
'地址'
,
},
},
...
@@ -346,14 +421,14 @@ const tableConfig = ref<TableColumn[]>([
...
@@ -346,14 +421,14 @@ const tableConfig = ref<TableColumn[]>([
align
:
'center'
,
align
:
'center'
,
},
},
render
:
{
render
:
{
default
:
({
row
}:
{
row
:
AddDeclarationRuleObj
})
=>
(
default
:
({
row
}:
{
row
:
IsupplierType
})
=>
(
<
div
>
<
div
>
<
el
-
icon
<
el
-
icon
size
=
"24"
size
=
"24"
title
=
"编辑"
title
=
"编辑"
color
=
"#EF6C00"
color
=
"#EF6C00"
style
=
"cursor: pointer; vertical-align: middle"
style
=
"cursor: pointer; vertical-align: middle"
onclick
=
{()
=>
editSupplier
(
row
)}
onclick
=
{()
=>
editSupplier
(
row
.
id
as
string
)}
>
>
<
Edit
/>
<
Edit
/>
<
/el-icon
>
<
/el-icon
>
...
@@ -364,30 +439,42 @@ const tableConfig = ref<TableColumn[]>([
...
@@ -364,30 +439,42 @@ const tableConfig = ref<TableColumn[]>([
])
])
const
formTableConfig
=
ref
<
TableColumn
[]
>
([
const
formTableConfig
=
ref
<
TableColumn
[]
>
([
{
{
prop
:
'
n
ame'
,
prop
:
'
productN
ame'
,
label
:
'商品名称'
,
label
:
'商品名称'
,
},
},
{
{
prop
:
'
currency
'
,
prop
:
'
productNo
'
,
label
:
'款号'
,
label
:
'款号'
,
},
},
{
{
prop
:
'
type
'
,
prop
:
'
productSpu
'
,
label
:
'商品SPU'
,
label
:
'商品SPU'
,
},
},
{
{
prop
:
'
logisticsWayId
'
,
prop
:
'
productImage
'
,
label
:
'商品图片'
,
label
:
'商品图片'
,
render
:
{
default
:
({
row
}:
{
row
:
IgoodsType
})
=>
(
<
div
>
<
el
-
image
style
=
"width: 50px; height: 50px"
src
=
{
row
.
productImage
}
/
>
<
/div
>
),
},
},
},
{
{
prop
:
'
remark
'
,
prop
:
'
currencyCode
'
,
label
:
'币种'
,
label
:
'币种'
,
},
},
{
{
prop
:
'
remark
'
,
prop
:
'
supplyPrice
'
,
label
:
'供应价格'
,
label
:
'供应价格'
,
render
:
{
default
:
({
row
}:
{
row
:
IgoodsType
})
=>
(
<
div
>
{
getSupplyPrice
(
row
)}
<
/div
>
),
},
},
},
{
{
...
@@ -397,7 +484,7 @@ const formTableConfig = ref<TableColumn[]>([
...
@@ -397,7 +484,7 @@ const formTableConfig = ref<TableColumn[]>([
align
:
'center'
,
align
:
'center'
,
},
},
render
:
{
render
:
{
default
:
({
row
}:
{
row
:
AddDeclarationRuleObj
})
=>
(
default
:
({
row
}:
{
row
:
IgoodsType
})
=>
(
<
el
-
button
type
=
"primary"
onclick
=
{()
=>
addPice
(
row
)}
size
=
"small"
>
<
el
-
button
type
=
"primary"
onclick
=
{()
=>
addPice
(
row
)}
size
=
"small"
>
管理供应价格
管理供应价格
<
/el-button
>
<
/el-button
>
...
@@ -405,23 +492,31 @@ const formTableConfig = ref<TableColumn[]>([
...
@@ -405,23 +492,31 @@ const formTableConfig = ref<TableColumn[]>([
},
},
},
},
])
])
const
searchTableConfig
=
ref
<
TableColumn
[]
>
([
const
searchTableConfig
=
ref
<
TableColumn
[]
>
([
{
{
prop
:
'name'
,
prop
:
'name'
,
label
:
'商品名称'
,
label
:
'商品名称'
,
},
},
{
{
prop
:
'
currency
'
,
prop
:
'
productNo
'
,
label
:
'款号'
,
label
:
'款号'
,
},
},
{
{
prop
:
'
type
'
,
prop
:
'
sku
'
,
label
:
'商品SPU'
,
label
:
'商品SPU'
,
},
},
{
{
prop
:
'
logisticsWayId
'
,
prop
:
'
imgUrl
'
,
label
:
'商品图片'
,
label
:
'商品图片'
,
render
:
{
default
:
({
row
}:
{
row
:
IgoodsType
})
=>
(
<
div
>
<
el
-
image
style
=
"width: 50px; height: 50px"
src
=
{
row
.
imgUrl
}
/
>
<
/div
>
),
},
},
},
{
{
prop
:
'opeare'
,
prop
:
'opeare'
,
...
@@ -431,7 +526,7 @@ const searchTableConfig = ref<TableColumn[]>([
...
@@ -431,7 +526,7 @@ const searchTableConfig = ref<TableColumn[]>([
width
:
'65px'
,
width
:
'65px'
,
},
},
render
:
{
render
:
{
default
:
({
row
}:
{
row
:
AddDeclarationRuleObj
})
=>
(
default
:
({
row
}:
{
row
:
IgoodsType
})
=>
(
<
div
>
<
div
>
<
el
-
icon
<
el
-
icon
size
=
"24"
size
=
"24"
...
@@ -447,28 +542,46 @@ const searchTableConfig = ref<TableColumn[]>([
...
@@ -447,28 +542,46 @@ const searchTableConfig = ref<TableColumn[]>([
},
},
},
},
])
])
const
supplyTableConfig
=
ref
<
TableColumn
[]
>
([
const
priceTableConfig
=
ref
<
TableColumn
[]
>
([
{
{
prop
:
'name'
,
prop
:
'productItemImage'
,
label
:
'商品名称'
,
label
:
'SKU图片'
,
render
:
{
default
:
({
row
}:
{
row
:
Iprice
})
=>
(
<
div
>
<
el
-
image
style
=
"width: 50px; height: 50px"
src
=
{
row
.
productItemImage
}
/
>
<
/div
>
),
},
},
},
{
{
prop
:
'
currency
'
,
prop
:
'
productItemSku
'
,
label
:
'SKU码'
,
label
:
'SKU码'
,
},
},
{
{
prop
:
'opeare'
,
prop
:
'opeare'
,
label
:
'
操作
'
,
label
:
'
供应价格
'
,
attrs
:
{
attrs
:
{
align
:
'center'
,
align
:
'center'
,
width
:
'230px'
,
width
:
'230px'
,
},
},
render
:
{
render
:
{
default
:
({
row
}:
{
row
:
any
})
=>
(
default
:
({
row
}:
{
row
:
Iprice
})
=>
(
<
div
>
<
div
>
<
el
-
input
<
el
-
input
modelValue
=
{
row
.
pice
}
modelValue
=
{
row
.
supplyPrice
}
onInput
=
{(
v
:
string
|
number
)
=>
{
v
=
String
(
v
).
replace
(
/
[^\d
.
]
/g
,
''
)
const
parts
=
v
.
split
(
'.'
)
if
(
parts
.
length
>
2
)
v
=
parts
[
0
]
+
'.'
+
parts
.
slice
(
1
).
join
(
''
)
row
.
supplyPrice
=
Number
(
v
)
}}
clearable
placeholder
=
"请输入更新价格"
placeholder
=
"请输入更新价格"
style
=
"width: 200px; margin-right: 20px"
style
=
"width: 200px; margin-right: 20px"
size
=
"small"
size
=
"small"
...
@@ -486,6 +599,7 @@ const searchSupplierGoods = ref('')
...
@@ -486,6 +599,7 @@ const searchSupplierGoods = ref('')
*/
*/
function
cancelFn
()
{
function
cancelFn
()
{
dialogVisible
.
value
=
false
dialogVisible
.
value
=
false
searchSupplierGoods
.
value
=
''
editFormRef
.
value
?.
resetFields
()
editFormRef
.
value
?.
resetFields
()
resetEditForm
()
resetEditForm
()
}
}
...
@@ -493,32 +607,107 @@ function cancelFn() {
...
@@ -493,32 +607,107 @@ function cancelFn() {
* @description: 取消供应价格按钮
* @description: 取消供应价格按钮
*/
*/
function
cancelPiceFn
()
{
function
cancelPiceFn
()
{
piceDialogVisible
.
value
=
false
p
r
iceDialogVisible
.
value
=
false
}
}
function
savePiceFn
()
{}
function
savePiceFn
()
{
if
(
!
currentGoods
.
value
.
currencyCode
)
{
return
ElMessage
({
message
:
'请选择结算币种'
,
type
:
'warning'
,
})
}
const
hasEmptyPrice
=
pricetableData
.
value
.
some
(
(
item
)
=>
!
item
.
supplyPrice
||
String
(
item
.
supplyPrice
).
trim
()
===
''
||
Number
(
item
.
supplyPrice
)
<=
0
,
)
if
(
hasEmptyPrice
)
{
ElMessage
.
warning
(
'供应价格为必填项,且必须大于0'
)
return
}
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
,
})
supplierTableData
.
value
.
forEach
((
el
)
=>
{
if
(
el
.
id
===
currentGoods
.
value
.
id
)
{
el
.
currencyCode
=
currentGoods
.
value
.
currencyCode
el
.
currencyName
=
currentGoods
.
value
.
currencyName
el
.
supplierPriceItemList
=
[...
pricetableData
.
value
]
}
})
console
.
log
(
'supplierTableData'
,
supplierTableData
.
value
)
cancelPiceFn
()
}
/**
/**
* @description: 检查数据
* @description: 检查数据
*/
*/
async
function
checkData
()
{
async
function
checkData
():
Promise
<
{
const
[
isValid
,
postData
]
=
await
Promise
.
all
([
isValid
:
boolean
new
Promise
<
boolean
>
((
resolve
)
=>
{
postData
:
IsupplierType
editFormRef
.
value
}
>
{
?.
validate
()
try
{
.
then
(()
=>
resolve
(
true
))
// 1. 表单验证
.
catch
((
err
)
=>
{
await
editFormRef
.
value
?.
validate
()
resolve
(
false
)
console
.
log
(
err
)
// 2. 准备数据
const
postData
=
{
...
editForm
.
value
}
const
hasEmptyPriceItemList
=
supplierTableData
.
value
?.
some
(
(
product
)
=>
!
product
.
supplierPriceItemList
,
)
if
(
hasEmptyPriceItemList
)
{
ElMessage
({
message
:
'请填写所有供应价格'
,
type
:
'warning'
,
})
})
}),
return
{
isValid
:
false
,
postData
}
new
Promise
<
AddDeclarationRuleObj
>
((
resolve
)
=>
{
}
const
params
=
{
...
editForm
.
value
}
// 检查所有供应价格是否已填写
params
.
logisticsWay
=
params
.
logisticsWayId
?.
join
(
','
)
const
hasEmptyPrice
=
supplierTableData
.
value
?.
some
((
product
)
=>
resolve
(
params
)
product
.
supplierPriceItemList
?.
some
(
}),
(
item
)
=>
!
item
.
supplyPrice
&&
item
.
supplyPrice
!==
0
,
])
),
return
{
isValid
,
postData
}
)
console
.
log
(
656
,
hasEmptyPrice
)
// return
if
(
hasEmptyPrice
)
{
ElMessage
({
message
:
'请填写所有供应价格'
,
type
:
'warning'
,
})
return
{
isValid
:
false
,
postData
}
}
if
(
supplierTableData
.
value
?.
length
)
{
postData
.
supplierProductInfoList
=
[...
supplierTableData
.
value
].
map
(
(
el
)
=>
{
el
.
createTime
&&
delete
el
.
createTime
el
.
updateTime
&&
delete
el
.
updateTime
return
{
...
el
,
}
},
)
}
// 所有验证通过
return
{
isValid
:
true
,
postData
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
// 表单验证失败时,仍然返回数据
const
postData
=
{
...
editForm
.
value
}
return
{
isValid
:
false
,
postData
}
}
}
}
/**
/**
...
@@ -529,13 +718,13 @@ const saveSupplierFn = debounce(async () => {
...
@@ -529,13 +718,13 @@ const saveSupplierFn = debounce(async () => {
if
(
isValid
)
{
if
(
isValid
)
{
try
{
try
{
if
(
!
postData
.
id
)
{
if
(
!
postData
.
id
)
{
// await addLogisticsCustomsRule
({
await
addSupplierApi
({
//
...postData,
...
postData
,
//
})
})
}
else
{
}
else
{
// await updateLogisticsCustomsRule
({
await
updateSupplierApi
({
//
...postData,
...
postData
,
//
})
})
}
}
ElMessage
({
ElMessage
({
message
:
postData
.
id
?
'更新成功'
:
'新增成功'
,
message
:
postData
.
id
?
'更新成功'
:
'新增成功'
,
...
@@ -554,7 +743,6 @@ const saveSupplierFn = debounce(async () => {
...
@@ -554,7 +743,6 @@ const saveSupplierFn = debounce(async () => {
* @description: 获取选中数据
* @description: 获取选中数据
*/
*/
function
handleCheckboxRecords
(
value
:
never
[])
{
function
handleCheckboxRecords
(
value
:
never
[])
{
console
.
log
(
351
,
value
)
selection
.
value
=
value
selection
.
value
=
value
}
}
...
@@ -598,28 +786,312 @@ async function deleteFn() {
...
@@ -598,28 +786,312 @@ async function deleteFn() {
*/
*/
async
function
showDialog
()
{
async
function
showDialog
()
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
supplierTableData
.
value
=
[]
supplierSeletctions
.
value
=
[]
}
}
/**
/**
* @description: 编辑供应商
* @description: 编辑供应商
*/
*/
async
function
editSupplier
()
{
async
function
editSupplier
(
id
:
string
|
number
)
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
editLoading
.
value
=
true
supplierTableData
.
value
=
[]
supplierSeletctions
.
value
=
[]
try
{
const
{
data
}
=
await
getSupplierDetailApi
(
id
)
editForm
.
value
=
data
supplierTableData
.
value
=
cloneDeep
(
editForm
.
value
.
supplierProductInfoList
||
[],
).
map
((
product
)
=>
{
const
customMap
=
new
Map
(
product
.
customProductInfo
?.
customProductItemList
?.
map
((
item
)
=>
[
item
.
id
,
item
,
])
||
[],
)
product
.
supplierPriceItemList
?.
forEach
((
priceItem
)
=>
{
const
customItem
=
customMap
.
get
(
priceItem
.
productItemId
)
if
(
customItem
)
{
priceItem
.
propertyCode1
=
customItem
.
propertyCode1
priceItem
.
propertyCode2
=
customItem
.
propertyCode2
}
})
return
product
})
console
.
log
(
728
,
editForm
.
value
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
editLoading
.
value
=
false
}
}
}
const
goodsLoading
=
ref
(
false
)
const
goodsLoading
=
ref
(
false
)
function
searchSupplyGoodsFn
()
{
const
isShowSearch
=
ref
(
false
)
const
supplierSeletctions
=
ref
<
IgoodsType
[]
>
([])
async
function
searchSupplyGoodsFn
()
{
if
(
!
searchSupplierGoods
.
value
)
{
ElMessage
.
warning
(
'请输入SPU'
)
isShowSearch
.
value
=
true
return
}
else
{
isShowSearch
.
value
=
false
goodsLoading
.
value
=
true
goodsLoading
.
value
=
true
console
.
log
(
604
,
searchSupplierGoods
.
value
)
try
{
const
{
data
}
=
await
getProductInfoBySpuApi
(
searchSupplierGoods
.
value
)
goodsTableData
.
value
=
[
data
]
console
.
log
(
604
,
data
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
goodsLoading
.
value
=
false
}
}
}
}
function
addPice
()
{
function
deleteSupplyGoodsFn
()
{
piceDialogVisible
.
value
=
true
if
(
!
supplierSeletctions
.
value
.
length
)
{
return
ElMessage
.
warning
(
`请勾选商品`
)
}
const
deleteIds
=
supplierSeletctions
.
value
.
map
((
el
)
=>
el
.
productSpu
)
supplierTableData
.
value
=
supplierTableData
.
value
.
filter
(
(
el
)
=>
!
deleteIds
.
includes
(
el
.
productSpu
),
)
}
function
getSupplierItem
(
v
:
IgoodsType
[])
{
supplierSeletctions
.
value
=
v
}
}
function
addGoods
(
data
:
any
)
{
const
priceLoading
=
ref
(
false
)
const
currencyOptions
=
ref
<
IcurrencyCode
[]
>
([])
const
colorList
=
ref
<
IcolorType
[]
>
([])
const
showColorList
=
ref
<
IcolorType
[]
>
([])
const
sizeList
=
ref
<
IsizeType
[]
>
([])
const
showSizeList
=
ref
<
IsizeType
[]
>
([])
const
currentGoods
=
ref
()
async
function
addPice
(
product
:
IgoodsType
)
{
supplierPirce
.
value
=
''
colorIndex
.
value
=
null
sizeIndex
.
value
=
null
priceDialogVisible
.
value
=
true
priceLoading
.
value
=
true
currentGoods
.
value
=
cloneDeep
(
product
)
console
.
log
(
'product'
,
currentGoods
.
value
)
const
tempArr
=
product
.
supplierPriceItemList
||
product
.
customProductItemList
pricetableData
.
value
=
cloneDeep
(
tempArr
?.
map
((
el
)
=>
{
return
{
...
el
,
productItemImage
:
el
.
productItemImage
||
el
.
image
,
productItemSku
:
el
.
productItemSku
||
el
.
sku
,
productItemId
:
el
.
id
||
''
,
}
})
||
[],
)
try
{
const
[
currencyResponse
,
propertyResponse
]
=
await
Promise
.
all
([
getBaseCurrencyInfoApi
(),
getPropertyByCateIdApi
(
(
product
.
categoryId
||
product
.
customProductInfo
?.
categoryId
)
as
string
,
),
])
currencyOptions
.
value
=
currencyResponse
.
data
||
[]
const
propertyData
:
IPropertyResponseItem
[]
=
propertyResponse
.
data
||
[]
colorList
.
value
=
propertyData
.
find
((
el
)
=>
el
.
id
==
1
)?.
valueList
||
[]
sizeList
.
value
=
propertyData
.
find
((
el
)
=>
el
.
id
==
2
)?.
valueList
||
[]
if
(
!
currentGoods
.
value
.
propertyList
?.
length
)
{
currentGoods
.
value
.
propertyList
=
product
.
customProductInfo
?.
propertyList
}
// 创建属性映射
const
propertyMap
=
createPropertyMap
(
currentGoods
.
value
.
propertyList
||
[])
console
.
log
(
758
,
propertyMap
)
// 过滤显示的颜色和尺寸
showColorList
.
value
=
filterPropertyList
(
colorList
.
value
,
propertyMap
.
get
(
1
)
||
[],
)
showSizeList
.
value
=
filterPropertyList
(
sizeList
.
value
,
propertyMap
.
get
(
2
)
||
[],
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
finally
{
priceLoading
.
value
=
false
}
}
// 辅助函数:创建属性映射
function
createPropertyMap
(
propertyList
:
any
[]):
Map
<
number
,
number
[]
>
{
const
map
=
new
Map
<
number
,
number
[]
>
()
propertyList
.
forEach
((
item
)
=>
{
if
(
item
.
propertyId
&&
item
.
valueId
)
{
if
(
!
map
.
has
(
item
.
propertyId
))
{
map
.
set
(
item
.
propertyId
,
[])
}
map
.
get
(
item
.
propertyId
)
!
.
push
(
item
.
valueId
)
}
})
return
map
}
// 辅助函数:过滤属性列表
function
filterPropertyList
<
T
extends
{
id
?:
number
|
string
}
>
(
sourceList
:
T
[],
targetIds
:
number
[],
):
T
[]
{
return
sourceList
.
filter
((
item
)
=>
{
const
itemId
=
typeof
item
.
id
===
'string'
?
parseInt
(
item
.
id
)
:
item
.
id
return
itemId
!==
undefined
&&
targetIds
.
includes
(
itemId
as
number
)
})
}
function
addGoods
(
data
:
IgoodsType
)
{
// 使用 Set 进行快速查找(性能更好)
data
.
productImage
=
data
.
productImage
||
data
.
imgUrl
||
''
data
.
productSpu
=
data
.
productSpu
||
data
.
sku
||
''
data
.
productName
=
data
.
productName
||
data
.
name
||
''
data
.
currencyCode
=
''
data
.
currencyName
=
''
data
.
productId
=
data
.
id
||
undefined
const
idSet
=
new
Set
(
supplierTableData
.
value
.
map
((
item
)
=>
item
.
productSpu
))
if
(
idSet
.
has
(
data
.
productSpu
))
{
ElMessage
.
warning
(
`商品已存在,请勿重复添加`
)
return
}
supplierTableData
.
value
.
push
(
data
)
supplierTableData
.
value
.
push
(
data
)
ElMessage
.
success
(
'商品添加成功'
)
}
const
selectPirceList
=
ref
<
Iprice
[]
>
([])
const
supplierPirce
=
ref
(
''
)
function
selectPirce
(
value
:
never
[])
{
console
.
log
(
351
,
value
)
selectPirceList
.
value
=
value
}
function
updatePrices
()
{
if
(
!
supplierPirce
.
value
)
{
ElMessage
.
warning
(
`请输入供应价格`
)
return
}
if
(
selectPirceList
.
value
.
length
)
{
selectPirceList
.
value
.
forEach
((
el
)
=>
{
el
.
supplyPrice
=
supplierPirce
.
value
})
}
else
{
ElMessage
.
warning
(
`请先勾选需要修改价格的商品`
)
}
}
const
colorIndex
=
ref
()
const
sizeIndex
=
ref
()
const
tableRef
=
ref
()
const
optionSelection
=
(
row
:
IcolorType
,
type
:
'color'
|
'size'
)
=>
{
// 更新选中索引
updateSelectionIndex
(
row
,
type
)
// 更新表格选中状态
updateTableSelection
()
}
// 更新选中索引的函数
const
updateSelectionIndex
=
(
row
:
IcolorType
,
type
:
'color'
|
'size'
)
=>
{
if
(
type
===
'color'
)
{
colorIndex
.
value
=
colorIndex
.
value
===
row
.
code
?
null
:
row
.
code
}
else
if
(
type
===
'size'
)
{
sizeIndex
.
value
=
sizeIndex
.
value
===
row
.
code
?
null
:
row
.
code
}
}
// 更新表格选中状态的函数
const
updateTableSelection
=
()
=>
{
pricetableData
.
value
.
forEach
((
item
)
=>
{
tableRef
.
value
.
setCheckboxRow
(
item
,
false
)
})
const
rowsToSelect
=
getRowsToSelect
()
rowsToSelect
.
forEach
((
item
)
=>
{
tableRef
.
value
.
setCheckboxRow
(
item
,
true
)
})
console
.
log
(
'rowsToSelect'
,
rowsToSelect
)
selection
.
value
=
[...(
rowsToSelect
||
[])]
}
// 获取应该选中的行
const
getRowsToSelect
=
()
=>
{
return
pricetableData
.
value
.
filter
((
item
)
=>
{
if
(
colorIndex
.
value
&&
sizeIndex
.
value
)
{
return
(
item
.
propertyCode1
===
colorIndex
.
value
&&
item
.
propertyCode2
===
sizeIndex
.
value
)
}
if
(
colorIndex
.
value
)
{
return
item
.
propertyCode1
===
colorIndex
.
value
}
if
(
sizeIndex
.
value
)
{
return
item
.
propertyCode2
===
sizeIndex
.
value
}
return
false
})
}
function
getSupplyPrice
(
row
:
IgoodsType
)
{
let
range
=
''
const
arr
=
row
.
supplierPriceItemList
if
(
arr
?.
length
)
{
const
prices
=
arr
.
map
((
item
)
=>
{
// 尝试转换为数字
const
price
=
parseFloat
(
item
.
supplyPrice
as
string
)
return
isNaN
(
price
)
?
null
:
price
})
.
filter
((
price
)
=>
price
!==
null
)
as
number
[]
if
(
prices
.
length
===
0
)
{
range
=
''
// 或者根据需求返回默认值
}
// 计算最小值和最大值
const
minPrice
=
Math
.
min
(...
prices
)
const
maxPrice
=
Math
.
max
(...
prices
)
// 判断是否需要范围格式
if
(
minPrice
===
maxPrice
)
{
// 所有价格相同或只有一个价格
range
=
minPrice
.
toString
()
}
else
{
// 价格有范围
range
=
`
${
minPrice
}
-
${
maxPrice
}
`
}
}
else
{
range
=
''
}
row
.
supplyPriceRange
=
range
as
string
return
range
}
}
function
updatePrices
()
{}
watch
(
()
=>
currentGoods
.
value
,
(
value
)
=>
{
console
.
log
(
946
,
value
)
},
{
deep
:
true
},
)
onMounted
(()
=>
{
onMounted
(()
=>
{
getAllList
()
getAllList
()
...
@@ -643,4 +1115,10 @@ async function getAllList() {}
...
@@ -643,4 +1115,10 @@ async function getAllList() {}
.dialog-footer
{
.dialog-footer
{
text-align
:
center
;
text-align
:
center
;
}
}
.tabBox
{
cursor
:
pointer
;
}
.active
{
border
:
2px
solid
rgb
(
0
,
140
,
255
);
}
</
style
>
</
style
>
src/views/supply/supplierManagement/types/declarationRule.ts
deleted
100644 → 0
View file @
40cfb810
export
interface
DeclarationRuleList
{
countries
:
string
createTime
:
string
currency
:
string
defaulted
:
string
fixedValue
:
string
fixedWeight
:
string
id
:
number
name
:
string
orderPercent
:
number
remark
:
string
shops
:
string
type
:
number
valueUp
:
number
wayIds
:
string
wayNames
:
string
weightPercent
:
number
weightUp
:
number
}
export
interface
AddDeclarationRuleObj
{
currency
?:
string
fixedValue
?:
string
fixedWeight
?:
string
id
?:
number
limitAmountType
?:
string
limitWeightType
?:
string
name
?:
string
orderPercent
?:
number
|
string
|
null
remark
?:
string
shops
?:
string
type
?:
number
valueUp
?:
number
|
string
|
null
weightPercent
?:
number
|
string
|
null
weightUp
?:
number
|
string
|
null
logisticsWay
?:
string
logisticsWayId
?:
(
string
|
number
)[]
}
src/views/supply/supplierManagement/types/index.ts
0 → 100644
View file @
67ef1de4
export
interface
IListPage
{
pageSize
:
number
|
string
currentPage
:
number
|
string
}
export
interface
IgoodsType
{
imgUrl
?:
string
productImage
?:
string
sku
?:
string
productSpu
?:
string
productNo
?:
string
id
?:
string
productId
?:
string
categoryId
?:
string
currencyCode
?:
string
currencyName
?:
string
name
?:
string
productName
?:
string
createTime
?:
string
updateTime
?:
string
customProductItemList
?:
Iprice
[]
supplierPriceItemList
?:
Iprice
[]
customProductInfo
?:
IgoodsType
propertyList
?:
[]
supplyPriceRange
?:
string
}
export
interface
IsupplierType
{
supplierName
?:
string
contacts
?:
string
contactsNumber
?:
string
address
?:
string
id
?:
string
supplierProductInfoList
?:
IgoodsType
[]
remark
?:
string
}
export
interface
IcurrencyCode
{
currencyName
?:
string
currencyCode
?:
string
id
?:
string
}
export
interface
IcolorType
{
bgColor
?:
string
code
?:
string
fontColor
?:
string
cnname
?:
string
enname
?:
string
id
?:
string
|
number
}
export
interface
IsizeType
{
code
?:
string
cnname
?:
string
id
?:
string
|
number
}
export
interface
IPropertyResponseItem
{
id
:
string
|
number
valueList
:
IcolorType
[]
|
IsizeType
[]
}
export
interface
Iprice
{
productItemSku
?:
string
productItemImage
?:
string
sku
?:
string
id
?:
string
image
?:
string
supplyPrice
?:
string
|
number
propertyCode1
?:
string
propertyCode2
?:
string
productItemId
?:
string
}
export
interface
IListPage
{
pageSize
:
number
|
string
currentPage
:
number
|
string
}
src/views/supply/supplierManagement/types/logistics.ts
deleted
100644 → 0
View file @
40cfb810
export
interface
LogisticsMethod
{
id
?:
number
|
string
name
?:
string
warehouseId
?:
number
warehouseName
?:
string
companyId
?:
number
company
?:
string
serviceCode
?:
string
siteUrl
?:
string
status
:
number
|
string
platformList
:
platformObj
[]
ruleRef
:
ruleRefObj
ruleId
?:
string
|
number
ruleList
?:
ruleRefObj
[]
uinuinWarehouseId
?:
number
|
string
|
null
companyWarehouseCode
?:
number
|
string
|
null
}
export
interface
LogisticsMethodList
{
name
?:
string
status
?:
number
|
string
serviceCode
?:
number
|
string
pageSize
:
number
|
string
currentPage
:
number
|
string
}
export
interface
UpdateLogisticsMethodStatus
{
id
?:
number
|
string
status
?:
number
|
string
}
export
interface
LogisticsResponse
{
code
:
number
data
:
{
total
:
number
size
:
number
current
:
number
records
:
LogisticsMethod
[]
}
message
:
string
}
export
interface
platformObj
{
platform
:
string
logisticsName
:
string
|
number
showPlatform
:
(
string
|
number
)[]
}
interface
ruleRefObj
{
ruleId
:
string
|
number
ruleName
:
string
|
number
}
export
interface
LogisticsTrackingTree
{
name
:
string
status
:
number
num
:
number
}
export
interface
LogisticsTrackingParams
{
trackNumber
?:
number
|
string
shopNumber
?:
string
|
number
trackingStatus
?:
number
}
src/views/supply/supplierManagement/types/logisticsPartition.ts
deleted
100644 → 0
View file @
40cfb810
export
interface
LogisticsPartitionObj
{
zoneName
?:
string
logistics
?:
string
codePrefix
?:
string
logisticsId
?:
string
}
src/views/supply/supplierManagement/types/logisticsQuotation.ts
deleted
100644 → 0
View file @
40cfb810
export
interface
LogisticsQuotation
{
factoryId
?:
number
id
?:
number
logistics
?:
string
logisticsId
?:
number
rate
?:
number
rateG
?:
number
rateKg
?:
number
rateType
?:
string
seq
?:
number
unit
?:
string
zone1
?:
string
zone2
?:
string
zone3
?:
string
zone4
?:
string
zone5
?:
string
zone6
?:
string
zone7
?:
string
zone8
?:
string
zone9
?:
string
logisticsQuotationList
?:
LogisticsQuotation
[]
}
src/views/supply/supplierManagement/types/shippingAddress.ts
deleted
100644 → 0
View file @
40cfb810
export
interface
ShippingAddressObj
{
addressLine1
?:
string
addressLine2
?:
string
addressLine3
?:
string
city
?:
string
cityCode
?:
string
countryCode
?:
string
countryName
?:
string
createTime
?:
string
cspAccount
?:
string
district
?:
string
districtCode
?:
string
factoryId
?:
number
id
?:
number
phoneNumber
?:
string
postalCode
?:
string
rfcTaxId
?:
string
shipperName
?:
string
stateProvince
?:
string
stateProvinceAbbr
?:
string
swDefault
?:
boolean
updateTime
?:
string
checked
?:
boolean
}
export
interface
ICountryObj
{
aeCountryCode
:
string
continentCode
:
string
countryCode
:
string
id
:
number
nameCn
:
string
nameEn
:
string
needProviceAbbr
:
number
}
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