Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
iuav
admin
Commits
43f628eb
提交
43f628eb
authored
8月 10, 2023
作者:
龚洪江
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
功能:商品sku新增编辑
上级
65a8690f
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
472 行增加
和
280 行删除
+472
-280
index.tsx
...Goods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
+338
-95
index.tsx
...ges/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
+59
-118
index.scss
...ges/rentManage/rentGoods/rentAddOrEditOrDetail/index.scss
+0
-0
index.tsx
src/pages/rentManage/rentGoods/rentList/index.tsx
+3
-3
router.tsx
src/router/router.tsx
+72
-64
没有找到文件。
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
浏览文件 @
43f628eb
import
{
Button
,
Col
,
Form
,
Input
,
Row
,
Select
,
Table
,
Tag
}
from
'antd'
;
import
{
Button
,
Col
,
Form
,
Input
,
message
,
Row
,
Select
,
Table
,
Tag
}
from
'antd'
;
import
{
DeleteOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
useState
}
from
'react'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
{
isEmptyBol
,
regPriceNumber
}
from
'~/utils/validateUtils'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
{
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
}
from
'~/api/interface/goodsType'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
mallGoodsDetailsType
}
from
'~/api/interface/goodsType'
;
import
{
filterObjAttr
}
from
'~/utils'
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
...
...
@@ -18,13 +19,31 @@ type specificationFormListType = {
specificationValueList
:
{
name
:
string
;
id
:
number
;
specificationName
:
string
}[];
};
//规格表格类型
type
skuTableType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'priceStock'
];
type
skuTableType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'priceStock'
][
0
]
&
{
fileList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[];
};
//商品详情-返回类型
type
goodsDetailType
=
InterDataType
<
mallGoodsDetailsType
>
;
interface
selfProps
{
ref
:
any
;
goodsDetailsInfo
:
goodsDetailType
|
undefined
;
}
const
SkuInfo
=
()
=>
{
const
SkuInfo
=
forwardRef
<
any
,
selfProps
>
(({
goodsDetailsInfo
},
ref
)
=>
{
//规格项表单
const
[
form
]
=
Form
.
useForm
<
{
[
x
:
string
]:
string
}
>
();
//可编辑表格表单
const
[
skuValueForm
]
=
Form
.
useForm
<
{
[
x
:
string
]:
string
}
>
();
//表格数据
const
[
tableData
,
setTableData
]
=
useState
<
skuTableType
>
([]);
//
表格-列
const
[
tableData
,
setTableData
]
=
useState
<
(
skuTableType
&
{
[
key
:
string
]:
string
})[]
>
([]);
//
销售价格正则校验
const
salePriceValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
regPriceNumber
(
value
.
toString
()))
{
...
...
@@ -69,17 +88,22 @@ const SkuInfo = () => {
return
Promise
.
resolve
();
}
};
const
defaultColumns
:
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
inputType
?:
string
;
radioOption
?:
{
name
:
string
;
id
:
number
}[];
rules
?:
any
;
maxLength
?:
number
;
})[]
=
[
//表格-列
const
[
defaultColumns
,
setDefaultColumns
]
=
useState
<
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
inputType
?:
string
;
radioOption
?:
{
name
:
string
;
id
:
number
}[];
rules
?:
any
;
maxLength
?:
number
;
children
?:
any
;
})[]
>
([
{
title
:
'商品规格'
,
align
:
'center'
,
children
:
[],
},
{
title
:
'图片'
,
...
...
@@ -89,7 +113,7 @@ const SkuInfo = () => {
inputType
:
'uploader'
,
},
{
title
:
'
料
号'
,
title
:
'
sku编
号'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'skuNo'
,
...
...
@@ -119,50 +143,51 @@ const SkuInfo = () => {
rules
:
[{
required
:
false
,
validator
:
stockPriceValidator
}],
inputType
:
'number'
,
},
{
title
:
'操作'
,
align
:
'center'
,
width
:
'10%'
,
render
:
(
_text
:
string
,
_record
:
any
,
index
:
number
)
=>
<></>,
},
];
const
columns
=
defaultColumns
.
map
((
col
)
=>
{
if
(
!
col
.
editable
)
{
return
col
;
}
return
{
...
col
,
onCell
:
(
record
:
any
)
=>
({
record
,
dataIndex
:
col
.
dataIndex
,
title
:
col
.
title
,
editing
:
col
.
editable
,
radioOption
:
col
.
radioOption
,
inputType
:
col
.
inputType
,
uploadSuccess
:
col
.
inputType
===
'uploader'
?
uploadSuccess
:
undefined
,
rules
:
col
.
rules
,
}),
};
});
]);
const
covertColumns
=
()
=>
{
return
defaultColumns
.
map
((
col
)
=>
{
if
(
!
col
.
editable
)
{
return
col
;
}
return
{
...
col
,
onCell
:
(
record
:
any
)
=>
({
record
,
dataIndex
:
col
.
dataIndex
,
title
:
col
.
title
,
editing
:
col
.
editable
,
radioOption
:
col
.
radioOption
,
inputType
:
col
.
inputType
,
uploadSuccess
:
col
.
inputType
===
'uploader'
?
uploadSuccess
:
undefined
,
rules
:
col
.
rules
,
}),
};
});
};
//规格表单数组
const
[
specificationFormList
,
setSpecificationFormList
]
=
useState
<
specificationFormListType
[]
>
([
{
id
:
Math
.
random
(),
name
:
`spec
ification1
`
,
name
:
`spec
Name
`
,
optionList
:
[],
specificationValueList
:
[],
addSpecificationValueShow
:
false
,
},
]);
useImperativeHandle
(
ref
,
()
=>
({
submitSku
,
getForm
:
()
=>
skuValueForm
,
}));
//新增规格项目
const
addSpecificationClick
=
()
=>
{
setSpecificationFormList
([
...
specificationFormList
,
{
id
:
Math
.
random
(),
name
:
`spec
ification
${
specificationFormList
.
length
+
1
}
`
,
name
:
`spec
Name
${
specificationFormList
.
length
+
1
}
`
,
optionList
:
[],
specificationValueList
:
[],
addSpecificationValueShow
:
false
,
...
...
@@ -177,9 +202,11 @@ const SkuInfo = () => {
};
//规格项名称输入完成
const
specificationPressEnter
=
(
e
:
any
,
index
:
number
)
=>
{
specificationFormList
[
index
].
optionList
=
[{
label
:
e
.
target
.
value
,
value
:
e
.
target
.
value
}];
specificationFormList
[
index
].
optionList
=
e
.
target
.
value
?
[{
label
:
e
.
target
.
value
,
value
:
e
.
target
.
value
}]
:
[];
const
obj
=
Object
.
create
(
null
);
obj
[
specificationFormList
[
index
].
name
]
=
e
.
target
.
value
;
obj
[
specificationFormList
[
index
].
name
]
=
e
.
target
.
value
||
undefined
;
form
.
setFieldsValue
(
obj
);
setSpecificationFormList
([...
specificationFormList
]);
};
...
...
@@ -188,7 +215,14 @@ const SkuInfo = () => {
specificationFormList
[
index
].
addSpecificationValueShow
=
true
;
setSpecificationFormList
([...
specificationFormList
]);
};
//存在
const
specificationValuePressEnter
=
(
e
:
any
,
index
:
number
)
=>
{
const
isExist
=
specificationFormList
[
index
].
specificationValueList
.
some
(
(
v
)
=>
v
.
name
===
e
.
target
.
value
,
);
if
(
isExist
)
{
return
message
.
warning
(
'该规格值已存在'
);
}
specificationFormList
[
index
].
specificationValueList
.
push
({
id
:
Math
.
random
(),
name
:
e
.
target
.
value
,
...
...
@@ -213,42 +247,73 @@ const SkuInfo = () => {
//组合数据
const
combineSpecificationValue
=
()
=>
{
let
combineSpecificationList
:
any
=
[];
const
combineList
=
specificationFormList
.
reduce
((
pre
:
any
,
cur
,
currentIndex
)
=>
{
// 首次组合两个数据
if
(
currentIndex
===
0
&&
specificationFormList
.
length
>
1
)
{
combineSpecificationList
=
combineEvent
(
cur
.
specificationValueList
,
specificationFormList
[
currentIndex
+
1
].
specificationValueList
,
);
//二维数组拆分为对象
combineSpecificationList
=
getCombineObj
(
combineSpecificationList
);
// 两个数据以上的组合
}
else
if
(
currentIndex
<
specificationFormList
.
length
-
1
)
{
// 上一次的组合作为下一次组合的参数
combineSpecificationList
=
combineEvent
(
combineSpecificationList
,
specificationFormList
[
currentIndex
+
1
].
specificationValueList
,
);
//二维数组拆分为对象
combineSpecificationList
=
getCombineObj
(
combineSpecificationList
);
}
pre
=
combineSpecificationList
;
return
pre
;
},
[]);
console
.
log
(
'组合数据-->'
,
combineList
);
const
tableDataList
=
combineList
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
pre
.
push
(
cur
.
reduce
((
a
:
any
,
b
:
any
,
currentIndex
:
number
)
=>
{
let
tableDataList
:
any
=
[];
if
(
specificationFormList
.
length
>
1
)
{
const
combineList
=
specificationFormList
.
reduce
((
pre
:
any
,
cur
,
currentIndex
)
=>
{
// 首次组合两个数据
if
(
currentIndex
===
0
&&
specificationFormList
.
length
>
1
)
{
combineSpecificationList
=
combineEvent
(
cur
.
specificationValueList
,
specificationFormList
[
currentIndex
+
1
].
specificationValueList
,
);
//二维数组拆分为对象
combineSpecificationList
=
getCombineObj
(
combineSpecificationList
);
// 两个数据以上的组合
}
else
if
(
currentIndex
<
specificationFormList
.
length
-
1
&&
specificationFormList
[
currentIndex
+
1
].
specificationValueList
.
length
)
{
// 上一次的组合作为下一次组合的参数
combineSpecificationList
=
combineEvent
(
combineSpecificationList
,
specificationFormList
[
currentIndex
+
1
].
specificationValueList
,
);
//二维数组拆分为对象
combineSpecificationList
=
getCombineObj
(
combineSpecificationList
);
}
pre
=
combineSpecificationList
;
return
pre
;
},
[]);
tableDataList
=
combineList
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
const
tabCovertObj
=
cur
.
reduce
((
a
:
any
,
b
:
any
,
currentIndex
:
number
)
=>
{
a
[
'name'
+
(
currentIndex
+
1
)]
=
b
.
name
;
a
[
'specificationName'
+
(
currentIndex
+
1
)]
=
b
.
specificationName
;
a
[
'id'
]
=
Math
.
random
();
return
a
;
},
{}),
},
{});
//判断表格中是否已存在该条(缓存)
const
tableItemObj
=
tableData
.
find
((
i
)
=>
Object
.
getOwnPropertyNames
(
tabCovertObj
).
every
((
key
)
=>
i
[
key
]
===
tabCovertObj
[
key
]),
);
pre
.
push
({
...
tabCovertObj
,
id
:
tableItemObj
?
tableItemObj
.
id
:
Math
.
random
(),
//存在则用之前的id,不存在新建id
fileList
:
tableItemObj
?
tableItemObj
.
fileList
:
[],
});
return
pre
;
},
[]);
}
else
{
//当存在一个规格项时
tableDataList
=
specificationFormList
[
0
].
specificationValueList
.
map
((
v
)
=>
{
const
obj
=
Object
.
create
(
null
);
obj
[
'name1'
]
=
v
.
name
;
obj
[
'specificationName1'
]
=
v
.
specificationName
;
//判断表格中是否已存在该条(缓存)
const
tableItemObj
=
tableData
.
find
((
i
)
=>
Object
.
getOwnPropertyNames
(
obj
).
every
((
key
)
=>
i
[
key
]
===
obj
[
key
]),
);
obj
[
'id'
]
=
Math
.
random
();
return
tableItemObj
?
tableItemObj
:
obj
;
//存在则用之前的一条,不存在新建一条
});
}
if
(
tableDataList
.
length
)
{
//过滤规格值为空的
const
filterSpecificationFormList
=
specificationFormList
.
filter
(
(
v
)
=>
v
.
specificationValueList
.
length
,
);
return
pre
;
},
[]
);
console
.
log
(
'表格数据-->'
,
tableDataList
);
setTableData
(
tableDataList
);
setTableFormDefault
(
tableDataList
)
;
mergeTableRow
(
filterSpecificationFormList
);
}
setTableData
(
[...
tableDataList
]
);
};
//组合数据拆分为对象
...
...
@@ -268,12 +333,184 @@ const SkuInfo = () => {
},
[]);
};
//两数组排列组合(通用)
const
combineEvent
=
(
list1
:
any
,
list2
:
any
)
=>
{
return
list1
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
pre
.
concat
(
list2
.
map
((
v
:
any
)
=>
[
cur
,
v
])),
[]);
};
//表头拆分及合并列
const
mergeTableRow
=
(
filterSpecificationFormList
:
specificationFormListType
[])
=>
{
const
columns
=
filterSpecificationFormList
.
map
((
v
,
index
)
=>
({
title
:
v
.
optionList
[
0
].
value
,
dataIndex
:
'name'
+
(
index
+
1
),
align
:
'center'
,
onCell
:
(
_
:
any
,
i
:
number
)
=>
{
//合并列
if
(
index
<
filterSpecificationFormList
.
length
-
1
)
{
const
count
:
number
=
filterSpecificationFormList
.
slice
(
index
+
1
,
filterSpecificationFormList
.
length
)
.
reduce
((
pre
:
number
,
cur
)
=>
{
return
pre
*
cur
.
specificationValueList
.
length
;
},
1
);
return
{
rowSpan
:
count
!==
1
?
((
i
+
1
)
%
count
===
1
?
count
:
0
)
:
1
,
};
}
else
{
return
{
rowSpan
:
1
,
};
}
},
}));
defaultColumns
[
0
].
children
=
columns
;
setDefaultColumns
([...
defaultColumns
]);
};
//规格值上传图片返回
const
uploadSuccess
=
()
=>
{};
const
uploadSuccess
=
(
record
:
skuTableType
,
fileList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[],
)
=>
{
const
tableIndex
:
number
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
if
(
tableIndex
!==
-
1
)
{
tableData
[
tableIndex
].
fileList
=
fileList
;
const
obj
=
Object
.
create
(
null
);
obj
[
'skuImage'
+
record
.
id
]
=
fileList
.
length
?
fileList
[
0
].
url
:
undefined
;
skuValueForm
.
setFieldsValue
(
obj
);
setTableData
([...
tableData
]);
}
};
//提交验证
const
submitSku
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
form
.
validateFields
()
.
then
(()
=>
{
const
specificationFormItemIndex
=
specificationFormList
.
findIndex
(
(
v
)
=>
!
v
.
specificationValueList
.
length
,
);
if
(
specificationFormItemIndex
!==
-
1
)
{
return
message
.
warning
(
`请为规格项
${
specificationFormItemIndex
}
添加规格值`
);
}
else
{
//规格项数据转化
const
specAttrList
=
specificationFormList
.
map
((
v
)
=>
({
specName
:
v
.
optionList
[
0
].
value
,
id
:
goodsDetailsInfo
?
goodsDetailsInfo
.
specAttrList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)?.
id
:
undefined
,
specValuesList
:
v
.
specificationValueList
.
map
((
j
)
=>
({
specName
:
j
.
name
,
id
:
goodsDetailsInfo
?
goodsDetailsInfo
.
specAttrList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)
?.
specValuesList
.
find
((
i
)
=>
i
.
id
===
j
.
id
)?.
id
:
undefined
,
})),
}));
skuValueForm
.
validateFields
()
.
then
((
value
)
=>
{
//规格值数据转化
const
priceStock
=
tableData
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
//规格名,规格值组合类型
const
productSpec
=
specificationFormList
.
reduce
(
(
a
:
{
[
x
:
string
]:
string
},
b
,
currentIndex
)
=>
{
a
[
b
.
optionList
[
0
].
value
]
=
cur
[
'name'
+
(
currentIndex
+
1
)];
return
a
;
},
{},
);
pre
.
push
({
...
Object
.
getOwnPropertyNames
(
value
).
reduce
((
a
:
any
,
b
)
=>
{
if
(
b
.
includes
(
cur
.
id
))
{
a
[
b
.
replace
(
cur
.
id
,
''
)]
=
value
[
b
];
}
return
a
;
},
{}),
productSpec
:
JSON
.
stringify
(
productSpec
),
});
return
pre
;
},
[]);
resolve
({
priceStock
,
specAttrList
});
})
.
catch
((
err
)
=>
{
reject
(
err
);
});
}
})
.
catch
((
err
)
=>
{
reject
(
err
);
});
});
};
//排列组合规格值表单默认数据
const
setTableFormDefault
=
(
tableDataList
:
(
skuTableType
&
{
[
key
:
string
]:
string
})[])
=>
{
const
tableFormDefault
=
tableDataList
.
reduce
((
pre
:
any
,
cur
)
=>
{
return
{
...
pre
,
...
Object
.
getOwnPropertyNames
(
filterObjAttr
(
cur
,
[
'id'
])).
reduce
((
a
:
any
,
b
)
=>
{
a
[
b
+
cur
.
id
]
=
cur
[
b
];
return
a
;
},
{}),
};
},
{});
skuValueForm
.
setFieldsValue
(
tableFormDefault
);
};
useEffect
(()
=>
{
if
(
goodsDetailsInfo
)
{
//转化数据
const
covertSpecAttrList
=
goodsDetailsInfo
.
specAttrList
.
map
((
v
,
index
)
=>
({
id
:
v
.
id
,
name
:
'specName'
+
index
,
optionList
:
[{
label
:
v
.
specName
,
value
:
v
.
specName
}],
specificationValueList
:
v
.
specValuesList
.
map
((
i
)
=>
({
id
:
i
.
id
,
name
:
i
.
specName
,
specificationName
:
v
.
specName
,
})),
addSpecificationValueShow
:
false
,
}));
//规格项表单数据默认数据
const
specFormDefault
=
goodsDetailsInfo
.
specAttrList
.
reduce
(
(
pre
:
any
,
cur
:
any
,
currentIndex
)
=>
{
pre
[
'specName'
+
currentIndex
]
=
cur
.
specName
;
return
pre
;
},
{},
);
form
.
setFieldsValue
(
specFormDefault
);
setSpecificationFormList
([...
covertSpecAttrList
]);
mergeTableRow
(
covertSpecAttrList
);
const
tableDataList
:
(
skuTableType
&
{
[
key
:
string
]:
string
})[]
=
goodsDetailsInfo
.
priceStock
.
map
((
v
)
=>
({
id
:
v
.
id
,
salePrice
:
v
.
salePrice
,
skuImage
:
v
.
skuImage
,
skuNo
:
v
.
skuNo
,
stock
:
v
.
stock
,
channelPrice
:
v
.
channelPrice
,
fileList
:
v
.
skuImage
?
[{
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
url
:
v
.
skuImage
,
name
:
'规格图片'
}]
:
[],
...
Object
.
getOwnPropertyNames
(
JSON
.
parse
(
v
.
productSpec
)).
reduce
(
(
pre
:
any
,
cur
,
currentIndex
)
=>
{
pre
[
'name'
+
(
currentIndex
+
1
)]
=
JSON
.
parse
(
v
.
productSpec
)[
cur
];
pre
[
'specificationName'
+
(
currentIndex
+
1
)]
=
cur
;
return
pre
;
},
{},
),
}));
setTableFormDefault
(
tableDataList
);
setTableData
(
tableDataList
);
}
},
[
goodsDetailsInfo
]);
return
(
<
div
className=
'sku-info'
>
...
...
@@ -288,6 +525,7 @@ const SkuInfo = () => {
wrapperCol=
{
{
span
:
18
}
}
labelCol=
{
{
span
:
5
}
}
name=
{
v
.
name
}
rules=
{
[{
required
:
true
,
message
:
`请输入规格项${index + 1}`
}]
}
>
<
Select
placeholder=
'请输入规格项,按回车键完成'
...
...
@@ -382,22 +620,27 @@ const SkuInfo = () => {
</
Col
>
</
Row
>
</
Form
>
<
Form
>
<
Table
style=
{
{
marginTop
:
'10px'
}
}
rowKey=
'id'
columns=
{
columns
as
ColumnTypes
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
bordered
dataSource=
{
tableData
}
pagination=
{
false
}
/>
</
Form
>
{
tableData
.
length
?
(
<
Form
form=
{
skuValueForm
}
>
<
Table
style=
{
{
marginTop
:
'10px'
}
}
rowKey=
'id'
columns=
{
covertColumns
()
as
ColumnTypes
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
bordered
dataSource=
{
tableData
}
pagination=
{
false
}
size=
'small'
/>
</
Form
>
)
:
(
''
)
}
</
div
>
);
};
}
)
;
export
default
SkuInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
浏览文件 @
43f628eb
...
...
@@ -3,19 +3,13 @@ import { useEffect, useRef, useState } from 'react';
import
BaseInfo
from
'./components/baseInfo'
;
import
SkuInfo
from
'./components/skuInfo'
;
import
IntroduceInfo
from
'./components/introduceInfo'
;
import
SkuAddOrEditModal
from
'./components/skuAddOrEditModal'
;
import
'./index.scss'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
baseInfoType
}
from
'./components/baseInfo'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
mallGoodsDetailsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
mallGoodsDetailsType
}
from
'~/api/interface/goodsType'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
//商品sku规格类型
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品详情-返回类型
type
goodsDetailType
=
InterDataType
<
mallGoodsDetailsType
>
;
...
...
@@ -23,16 +17,9 @@ const GoodsAddOrEditOrDetail = () => {
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
const
[
searchParams
]
=
useSearchParams
();
const
skuInfoRef
=
useRef
<
any
>
();
//单位列表
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
const
[
tabSelectKeys
,
setTabSelectKeys
]
=
useState
<
string
>
(
'1'
);
//新增、编辑sku弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
<
boolean
>
(
false
);
//当前编辑sku
const
[
currentSku
,
setCurrentSku
]
=
useState
<
goodsSpecType
>
();
//skuTable数据
const
[
skuTable
,
setSkuTable
]
=
useState
<
goodsSpecType
[]
>
([]);
//商品介绍详情
const
[
goodsDetails
,
setGoodsDetails
]
=
useState
<
string
>
(
''
);
//商品id
...
...
@@ -40,30 +27,6 @@ const GoodsAddOrEditOrDetail = () => {
//商品详情
const
[
goodsDetailsInfo
,
setGoodsDetailsInfo
]
=
useState
<
goodsDetailType
>
();
//新增、编辑sku弹窗显示
// const addOrEditSkuClick = (record?: goodsSpecType) => {
// setCurrentSku(record ? { ...record } : undefined);
// setAddOrEditSkuModalShow(true);
// };
const
addOrEditSkuModalCancel
=
()
=>
{
setAddOrEditSkuModalShow
(
false
);
};
const
addOrEditSkuModalOk
=
(
values
:
goodsSpecType
)
=>
{
setAddOrEditSkuModalShow
(
false
);
const
skuTableIndex
:
number
=
skuTable
.
findIndex
((
v
)
=>
v
.
id
===
values
.
id
);
if
(
skuTableIndex
!==
-
1
)
{
skuTable
.
splice
(
skuTableIndex
,
1
,
values
);
setSkuTable
([...
skuTable
]);
}
else
{
setSkuTable
([...
skuTable
,
{
...
values
}]);
}
};
//sku删除
// const deleteSkuClick = (record: goodsSpecType) => {
// const skuIndex: number = skuTable.findIndex((v) => v.id === record.id);
// skuTable.splice(skuIndex, 1);
// setSkuTable([...skuTable]);
// };
//商品详情获取
const
getIntroduceInfo
=
(
richText
:
string
)
=>
{
setGoodsDetails
(
richText
);
...
...
@@ -78,18 +41,7 @@ const GoodsAddOrEditOrDetail = () => {
{
key
:
'2'
,
label
:
`商品规格`
,
children
:
(
// (旧)
// <SkuInfo
// addOrEditSkuClick={addOrEditSkuClick}
// skuTableData={skuTable}
// skuUnitList={skuUnitList}
// deleteSkuClick={deleteSkuClick}
// editSkuClick={addOrEditSkuClick}
// />
//(新)
<
SkuInfo
/>
),
children
:
<
SkuInfo
ref=
{
skuInfoRef
}
goodsDetailsInfo=
{
goodsDetailsInfo
}
/>,
},
{
key
:
'3'
,
...
...
@@ -117,11 +69,14 @@ const GoodsAddOrEditOrDetail = () => {
});
break
;
case
'2'
:
if
(
skuTable
.
length
)
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
}
else
{
message
.
warning
(
'请添加规格'
);
}
skuInfoRef
.
current
.
submitSku
()
.
then
(()
=>
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
})
.
catch
(()
=>
{
message
.
warning
(
'请添加规格'
);
});
break
;
case
'3'
:
break
;
...
...
@@ -136,62 +91,45 @@ const GoodsAddOrEditOrDetail = () => {
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
//单位列表
const
getSkuUnit
=
()
=>
{
GoodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//商品保存
const
saveGoods
=
()
=>
{
baseInfoRef
.
current
.
getForm
()
.
validateFields
()
.
then
((
values
:
baseInfoType
)
=>
{
if
(
skuTable
.
length
)
{
const
skuList
=
skuTable
.
map
((
v
)
=>
({
...
v
,
id
:
goodsDetailsInfo
?
goodsDetailsInfo
.
goodsSpecList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)?.
id
:
undefined
,
goodsSpecValuesList
:
v
.
goodsSpecValuesList
.
map
((
i
)
=>
({
...
i
,
id
:
goodsDetailsInfo
?
goodsDetailsInfo
.
goodsSpecList
.
find
((
j
)
=>
j
.
id
===
v
.
id
)
?.
goodsSpecValuesList
.
find
((
k
)
=>
k
.
id
===
i
.
id
)?.
id
:
undefined
,
goodsSpecId
:
goodsDetailsInfo
?
goodsDetailsInfo
.
goodsSpecList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)?.
id
:
undefined
,
})),
}));
const
addGoodsEditReq
=
{
...
filterObjAttr
(
values
,
[
'mainImgList'
,
'subImgList'
,
'videoList'
,
'categoryId'
]),
resourcesList
:
[
...
values
.
mainImgList
.
map
((
v
)
=>
({
type
:
0
,
url
:
v
.
url
})),
...(
values
.
subImgList
?.
map
((
v
)
=>
({
type
:
1
,
url
:
v
.
url
}))
||
[]),
...(
values
.
videoList
?.
map
((
v
)
=>
({
type
:
2
,
url
:
v
.
url
}))
||
[]),
],
categoryPrimaryId
:
values
.
categoryId
[
0
],
categorySubId
:
values
.
categoryId
.
length
===
2
?
values
.
categoryId
[
1
]
:
undefined
,
goodsDetails
,
goodsSpecList
:
skuList
,
id
:
goodsId
||
undefined
,
};
GoodsAPI
[
goodsId
?
'editMallGoods'
:
'addMallGoods'
](
addGoodsEditReq
).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsId
?
'编辑商城成功'
:
'新增商品成功'
);
navigate
(
-
1
);
}
});
}
else
{
message
.
warning
(
'商品规格未添加'
);
}
Promise
.
all
([
baseInfoRef
.
current
.
getForm
().
validateFields
(),
skuInfoRef
.
current
?
skuInfoRef
.
current
.
submitSku
()
:
getDefaultSku
(),
])
.
then
((
values
:
any
)
=>
{
const
addGoodsEditReq
=
{
...
filterObjAttr
(
values
[
0
],
[
'mainImgList'
,
'subImgList'
,
'videoList'
,
'categoryId'
]),
resourcesList
:
[
...
values
[
0
].
mainImgList
.
map
((
v
:
any
)
=>
({
type
:
0
,
url
:
v
.
url
})),
...(
values
[
0
].
subImgList
?.
map
((
v
:
any
)
=>
({
type
:
1
,
url
:
v
.
url
}))
||
[]),
...(
values
[
0
].
videoList
?.
map
((
v
:
any
)
=>
({
type
:
2
,
url
:
v
.
url
}))
||
[]),
],
categoryPrimaryId
:
values
[
0
].
categoryId
[
0
],
categorySubId
:
values
[
0
].
categoryId
.
length
===
2
?
values
[
0
].
categoryId
[
1
]
:
undefined
,
goodsDetails
,
...
values
[
1
],
id
:
goodsId
||
undefined
,
};
GoodsAPI
[
goodsId
?
'editMallGoods'
:
'addMallGoods'
](
addGoodsEditReq
).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsId
?
'编辑商品成功'
:
'新增商品成功'
);
navigate
(
-
1
);
}
});
})
.
catch
((
error
:
any
)
=>
{
message
.
error
(
error
.
errorFields
[
0
].
errors
[
0
]);
baseInfoRef
.
current
.
getForm
()
.
validateFields
()
.
then
(()
=>
{
setTabSelectKeys
(
'2'
);
})
.
catch
(()
=>
{
setTabSelectKeys
(
'1'
);
});
message
.
error
(
error
?.
errorFields
?.[
0
].
errors
[
0
]
||
error
);
});
};
//商品详情
...
...
@@ -207,7 +145,6 @@ const GoodsAddOrEditOrDetail = () => {
.
filter
((
v
)
=>
v
.
type
===
2
)
.
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
'video'
,
uid
:
v
.
id
,
url
:
v
.
url
}));
setGoodsDetailsInfo
(
JSON
.
parse
(
JSON
.
stringify
(
result
)));
setSkuTable
(
result
.
goodsSpecList
);
setGoodsDetails
(
result
.
goodsDetails
||
''
);
baseInfoRef
.
current
.
getForm
().
setFieldsValue
({
tradeName
:
result
.
tradeName
,
...
...
@@ -228,9 +165,21 @@ const GoodsAddOrEditOrDetail = () => {
baseInfoRef
.
current
.
mediaData
.
setVideoFileList
(
videoList
);
});
};
//编辑未点击规格时数据处理
const
getDefaultSku
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
goodsDetailsInfo
)
{
resolve
({
priceStock
:
goodsDetailsInfo
.
priceStock
,
specAttrList
:
goodsDetailsInfo
.
specAttrList
,
});
}
else
{
reject
(
'请上传商品规格'
);
}
});
};
useEffect
(()
=>
{
getSkuUnit
();
if
(
searchParams
.
get
(
'id'
))
{
setGoodsId
(
Number
(
searchParams
.
get
(
'id'
)));
getMallGoodsDetails
(
Number
(
searchParams
.
get
(
'id'
)));
...
...
@@ -258,14 +207,6 @@ const GoodsAddOrEditOrDetail = () => {
返回
</
Button
>
</
div
>
{
/*新增、编辑sku弹窗*/
}
<
SkuAddOrEditModal
open=
{
addOrEditSkuModalShow
}
onCancel=
{
addOrEditSkuModalCancel
}
onHandleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
currentSku=
{
currentSku
}
/>
</
div
>
);
};
...
...
src/pages/
mall
Manage/rentGoods/rentAddOrEditOrDetail/index.scss
→
src/pages/
rent
Manage/rentGoods/rentAddOrEditOrDetail/index.scss
浏览文件 @
43f628eb
File moved
src/pages/
mall
Manage/rentGoods/rentList/index.tsx
→
src/pages/
rent
Manage/rentGoods/rentList/index.tsx
浏览文件 @
43f628eb
...
...
@@ -188,19 +188,19 @@ const RentList = () => {
};
//新增商品
const
toAddRentGoods
=
()
=>
{
navigate
({
pathname
:
'/
mall
Manage/rentGoods/add'
});
navigate
({
pathname
:
'/
rent
Manage/rentGoods/add'
});
};
//编辑商品
const
toEditGoods
=
(
id
:
number
)
=>
{
navigate
({
pathname
:
'/
mall
Manage/rentGoods/edit'
,
pathname
:
'/
rent
Manage/rentGoods/edit'
,
search
:
`id=
${
id
}
`
,
});
};
//商品详情
const
toRentGoodsDetail
=
(
id
:
number
)
=>
{
navigate
({
pathname
:
'/
mall
Manage/rentGoods/detail'
,
pathname
:
'/
rent
Manage/rentGoods/detail'
,
search
:
`id=
${
id
}
&isDetail=1`
,
});
};
...
...
src/router/router.tsx
浏览文件 @
43f628eb
...
...
@@ -96,10 +96,13 @@ const ServiceDetailView = React.lazy(
const
ServiceIntroduceView
=
React
.
lazy
(
()
=>
import
(
'~/pages/mallManage/serviceManage/serviceIntroduce'
),
);
//服务介绍
const
RentListView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/rentGoods/rentList'
));
//租赁列表
const
RentListView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentGoods/rentList'
));
//租赁列表
const
RentAddOrEditOrDetailView
=
React
.
lazy
(
()
=>
import
(
'~/pages/
mall
Manage/rentGoods/rentAddOrEditOrDetail'
),
()
=>
import
(
'~/pages/
rent
Manage/rentGoods/rentAddOrEditOrDetail'
),
);
//租赁新增、编辑、详情
const
RentTypeView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentType'
));
//类型管理
const
MallGoodsView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/mallGoods/goodsList'
));
//商城商品
const
MallAddOrEditOrDetailView
=
React
.
lazy
(
()
=>
import
(
'~/pages/mallManage/mallGoods/goodsAddOrEditOrDetail'
),
...
...
@@ -614,49 +617,6 @@ export const routerList: Array<RouteObjectType> = [
},
},
{
path
:
'/mallManage/rentGoods'
,
element
:
withLoadingComponent
(<
RentListView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1030
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品'
,
},
},
{
path
:
'/mallManage/rentGoods/add'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10135
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品新增'
,
hidden
:
true
,
},
},
{
path
:
'/mallManage/rentGoods/edit'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10136
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品编辑'
,
hidden
:
true
,
},
},
{
path
:
'/mallManage/rentGoods/detail'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10136
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品详情'
,
hidden
:
true
,
},
},
{
path
:
'/mallManage/mallGoods'
,
element
:
withLoadingComponent
(<
MallGoodsView
/>),
errorElement
:
<
ErrorPage
/>,
...
...
@@ -730,25 +690,73 @@ export const routerList: Array<RouteObjectType> = [
title
:
'品牌管理'
,
},
},
// {
// path: '/mallManage/industryList',
// element: withLoadingComponent(<IndustryListView />),
// meta: {
// id: 10180,
// icon: <SmileOutlined />,
// title: '行业方案',
// },
// },
// {
// path: '/mallManage/industryDetail',
// element: withLoadingComponent(<IndustryDetailView />),
// meta: {
// id: 10190,
// icon: <SmileOutlined />,
// title: '行业详情',
// hidden: true,
// },
// },
],
},
{
path
:
'/rentManage'
,
element
:
<
LayoutView
/>,
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10001
,
icon
:
<
ShopOutlined
/>,
title
:
'租赁管理'
,
develop
:
true
,
},
children
:
[
{
path
:
'/rentManage/rentGoods'
,
element
:
withLoadingComponent
(<
RentListView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1030
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品'
,
},
},
{
path
:
'/rentManage/rentGoods/add'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10135
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品新增'
,
hidden
:
true
,
},
},
{
path
:
'/rentManage/rentGoods/edit'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10136
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品编辑'
,
hidden
:
true
,
},
},
{
path
:
'/rentManage/rentGoods/detail'
,
element
:
withLoadingComponent
(<
RentAddOrEditOrDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10136
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品详情'
,
hidden
:
true
,
},
},
{
path
:
'/rentManage/rentType'
,
element
:
withLoadingComponent
(<
RentTypeView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10137
,
icon
:
<
SmileOutlined
/>,
title
:
'类型管理'
,
develop
:
true
,
},
},
],
},
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论