Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin-ci-test
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
test-ci
admin-ci-test
Commits
24da3ab0
提交
24da3ab0
authored
7月 21, 2023
作者:
龚洪江
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
功能:商城改版
上级
807c35cb
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
657 行增加
和
307 行删除
+657
-307
index.tsx
src/components/EditableCell/index.tsx
+14
-2
index.tsx
...oods/goodsAddOrEditOrDetail/components/baseInfo/index.tsx
+50
-0
index.tsx
...goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
+10
-0
index.tsx
...sAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
+143
-0
index.tsx
...Goods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
+52
-0
index-old.tsx
...mallManage/mallGoods/goodsAddOrEditOrDetail/index-old.tsx
+308
-0
index.scss
...es/mallManage/mallGoods/goodsAddOrEditOrDetail/index.scss
+15
-10
index.tsx
...ges/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
+54
-284
router.tsx
src/router/router.tsx
+11
-11
没有找到文件。
src/components/EditableCell/index.tsx
浏览文件 @
24da3ab0
import
{
Form
,
InputNumber
,
Input
,
Select
}
from
'antd'
;
import
{
Form
,
InputNumber
,
Input
,
Select
,
Radio
}
from
'antd'
;
import
React
from
'react'
;
import
{
Uploader
}
from
'~/components/uploader'
;
import
{
UploadOutlined
}
from
'@ant-design/icons'
;
...
...
@@ -8,7 +8,7 @@ export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
editing
:
boolean
;
dataIndex
:
string
;
title
:
any
;
inputType
:
'number'
|
'text'
|
'select'
|
'uploader'
;
inputType
:
'number'
|
'text'
|
'select'
|
'uploader'
|
'radio'
;
record
:
any
;
index
:
number
;
children
:
React
.
ReactNode
;
...
...
@@ -16,6 +16,7 @@ export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
const
EditableCell
:
React
.
FC
<
EditableCellProps
&
{
selectOption
?:
{
name
:
string
;
id
:
number
}[];
radioOption
?:
{
name
:
string
;
id
:
number
}[];
uploadSuccess
?:
(
record
:
any
,
result
:
any
)
=>
void
;
rules
?:
any
;
}
...
...
@@ -27,6 +28,7 @@ const EditableCell: React.FC<
record
,
index
,
selectOption
,
radioOption
,
uploadSuccess
,
children
,
rules
,
...
...
@@ -58,6 +60,16 @@ const EditableCell: React.FC<
<
UploadOutlined
/>
</
Uploader
>
);
case
'radio'
:
return
(
<
Radio
.
Group
>
{
radioOption
?.
map
((
v
)
=>
(
<
Radio
value=
{
v
.
id
}
key=
{
v
.
id
}
>
{
v
.
name
}
</
Radio
>
))
}
</
Radio
.
Group
>
);
default
:
return
<
Input
placeholder=
{
`请输入${title}`
}
/>;
}
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/baseInfo/index.tsx
0 → 100644
浏览文件 @
24da3ab0
import
{
Button
,
Cascader
,
Form
,
Input
,
Radio
,
Select
}
from
'antd'
;
import
{
Uploader
}
from
'~/components/uploader'
;
import
{
UploadOutlined
}
from
'@ant-design/icons'
;
const
BaseInfo
=
()
=>
{
const
[
baseInfoForm
]
=
Form
.
useForm
();
return
(
<
div
className=
'base-info'
>
<
Form
labelCol=
{
{
span
:
1
}
}
wrapperCol=
{
{
span
:
8
}
}
form=
{
baseInfoForm
}
>
<
Form
.
Item
label=
'商品名称'
>
<
Input
placeholder=
'请输入商品名称'
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品描述'
>
<
Input
.
TextArea
rows=
{
4
}
placeholder=
'请输入商品描述'
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品主图'
>
<
Uploader
fileUpload
listType=
'picture-card'
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品副图'
>
<
Uploader
fileUpload
listType=
'picture-card'
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
{
' '
}
<
Form
.
Item
label=
'商品视频'
>
<
Uploader
fileUpload
listType=
'text'
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
上传视频
</
Button
>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品分类'
>
<
Cascader
placeholder=
'请选择商品分类'
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品状态'
>
<
Select
placeholder=
'请选择商品状态'
>
<
Select
.
Option
>
上架
</
Select
.
Option
>
<
Select
.
Option
>
下架
</
Select
.
Option
>
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品标签'
>
<
Radio
.
Group
>
<
Radio
value=
{
1
}
>
显示
</
Radio
>
<
Radio
value=
{
0
}
>
不显示
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
</
Form
>
</
div
>
);
};
export
default
BaseInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
0 → 100644
浏览文件 @
24da3ab0
import
RichText
from
'~/components/richText'
;
const
IntroduceInfo
=
()
=>
{
return
(
<
div
className=
'introduce-info'
>
<
RichText
richTextContent=
''
height=
{
400
}
/>
</
div
>
);
};
export
default
IntroduceInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
0 → 100644
浏览文件 @
24da3ab0
import
{
Button
,
Form
,
Input
,
Modal
,
ModalProps
,
Radio
,
Select
,
Table
}
from
'antd'
;
import
{
FC
,
useState
}
from
'react'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
interface
selfProps
{
onCancel
:
()
=>
void
;
}
const
SkuAddOrEditModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
})
=>
{
const
[
tableData
]
=
useState
<
any
>
([{
id
:
1
}]);
const
defaultColumns
:
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
inputType
?:
string
;
radioOption
?:
{
name
:
string
;
id
:
number
}[];
})[]
=
[
{
title
:
'图片'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
''
,
inputType
:
'uploader'
,
},
{
title
:
'选项名称'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
''
,
},
{
title
:
'料号'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
''
,
},
{
title
:
'销售价'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
''
,
},
{
title
:
'渠道价'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
''
,
},
{
title
:
'库存'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
''
,
},
{
title
:
'是否显示'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
''
,
inputType
:
'radio'
,
width
:
'20%'
,
radioOption
:
[
{
id
:
1
,
name
:
'显示'
},
{
id
:
0
,
name
:
'不显示'
},
],
},
{
title
:
'操作'
,
align
:
'center'
,
width
:
'10%'
,
render
:
()
=>
(
<>
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
></
Button
>
</>
),
},
];
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
,
}),
};
});
const
handleCancel
=
()
=>
{
onCancel
();
};
return
(
<
Modal
open=
{
open
}
title=
'添加规格'
width=
{
1000
}
onCancel=
{
handleCancel
}
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
22
}
}
>
<
Form
.
Item
label=
'规格名称'
>
<
Input
placeholder=
'请输入规格名称'
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'规格值'
>
<
Form
component=
{
false
}
>
<
Table
rowKey=
'id'
columns=
{
columns
as
ColumnTypes
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
bordered
dataSource=
{
tableData
}
></
Table
>
</
Form
>
</
Form
.
Item
>
<
Form
.
Item
label=
'选择方式'
>
<
Radio
.
Group
>
<
Radio
>
单选
</
Radio
>
<
Radio
>
多选
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
'是否必选'
>
<
Radio
.
Group
>
<
Radio
>
非必选
</
Radio
>
<
Radio
>
必选
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
'规格单位'
>
<
Select
>
<
Select
.
Option
value=
{
0
}
>
件
</
Select
.
Option
>
</
Select
>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
SkuAddOrEditModal
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
0 → 100644
浏览文件 @
24da3ab0
import
{
Button
,
Table
}
from
'antd'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
{
FC
}
from
'react'
;
interface
selfProps
{
addOrEditSkuClick
:
()
=>
void
;
}
const
SkuInfo
:
FC
<
selfProps
>
=
({
addOrEditSkuClick
})
=>
{
const
TableColumns
:
ColumnsType
<
any
>
=
[
{
title
:
'序号'
,
align
:
'center'
,
},
{
title
:
'规格名称'
,
align
:
'center'
,
},
{
title
:
'选择方式'
,
align
:
'center'
,
},
{
title
:
'是否必选'
,
align
:
'center'
,
},
{
title
:
'规格单位'
,
align
:
'center'
,
},
{
title
:
'操作'
,
align
:
'center'
,
},
];
return
(
<
div
className=
'sku-info'
>
<
div
className=
'sku-info-operate'
style=
{
{
margin
:
' 20px 0 '
}
}
>
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
></
PlusOutlined
>
}
onClick=
{
()
=>
addOrEditSkuClick
()
}
>
添加规格
</
Button
>
</
div
>
<
Table
bordered
columns=
{
TableColumns
}
/>
</
div
>
);
};
export
default
SkuInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index-old.tsx
0 → 100644
浏览文件 @
24da3ab0
import
BaseInfo
from
'~/components/goods/commonAddOrEdit/baseInfo'
;
import
StockSku
from
'~/components/goods/commonAddOrEdit/stockSku'
;
import
OtherInfo
from
'~/components/goods/commonAddOrEdit/otherInfo'
;
import
GoodsIntroduce
from
'~/components/goods/commonAddOrEdit/goodsIntroduce'
;
import
AddOrEditSkuModal
from
'~/components/goods/commonAddOrEdit/addOrEditSkuModal'
;
import
{
Button
,
message
}
from
'antd'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
'./index.scss'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
categoryListType
}
from
'~/api/interface/categoryManage'
;
import
{
customizeEntity
,
detailGoodsType
,
skuUnitType
,
specEntity
,
}
from
'~/api/interface/goodsType'
;
import
goodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
UploadFile
}
from
'antd/es/upload/interface'
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListType
>
[
'list'
];
//产品-规格单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品返回类型
type
goodsDetailType
=
InterDataType
<
detailGoodsType
>
;
const
GoodsAddOrEditOrDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
//基本信息ref
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
//当前目录
const
[
currentDesc
,
setCurrentDesc
]
=
useState
<
number
>
(
-
1
);
//分类
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//添加、编辑库存规格弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
(
false
);
//库存规格数据
const
[
specData
,
setSpecData
]
=
useState
<
specEntity
[]
>
([]);
const
[
goodsSpecCopy
,
setGoodsSpecCopy
]
=
useState
<
specEntity
[]
>
([]);
//产品规格-单位
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
//其它服务
const
[
otherService
,
setOtherService
]
=
useState
<
number
[]
>
([]);
// 当前操作行数据
const
[
curtRowData
,
setCurtRowData
]
=
useState
<
Partial
<
specEntity
>>
({});
//商品详情
const
[
goodsDetail
,
setGoodsDetail
]
=
useState
<
goodsDetailType
>
();
//产品介绍
const
[
productIntroduce
,
setProductIntroduce
]
=
useState
<
string
>
(
''
);
//是否商品详情
const
[
isDetail
,
setIsDetail
]
=
useState
<
boolean
>
(
false
);
//添加、编辑规格
const
addOrEditSkuShowEvent
=
(
record
?:
specEntity
)
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
setCurrentDesc
(
baseInfoForm
.
getFieldValue
(
'directoryId'
)
||
-
1
);
if
(
!
baseInfoForm
.
getFieldValue
(
'directoryId'
))
{
return
message
.
warning
(
'请先选择目录'
);
}
if
(
record
)
{
setCurtRowData
({
...
record
});
}
setAddOrEditSkuModalShow
(
true
);
};
//删除规格
const
deleteSkuEvent
=
(
record
:
specEntity
)
=>
{
const
index
=
specData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
specData
.
splice
(
index
,
1
);
setSpecData
([...
specData
]);
};
const
addOrEditSkuModalCancel
=
()
=>
{
setAddOrEditSkuModalShow
(
false
);
setCurtRowData
({});
};
const
addOrEditSkuModalOk
=
(
data
:
specEntity
)
=>
{
if
(
Object
.
keys
(
curtRowData
).
length
!=
0
)
{
const
index
:
number
=
specData
.
findIndex
((
i
)
=>
i
.
id
===
data
.
id
);
specData
.
splice
(
index
,
1
,
data
);
setSpecData
([...
specData
]);
}
else
{
setSpecData
([...
specData
,
data
]);
}
addOrEditSkuModalCancel
();
};
//根据目录获取分类列表
const
getCategoryList
=
(
directoryId
:
number
)
=>
{
CategoryManageAPI
.
getCategoryList
({
directoryId
,
type
:
4
,
pageSize
:
9999
,
pageNo
:
1
}).
then
(
({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
},
);
};
//产品-单位
const
getSkuUnit
=
()
=>
{
goodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//其它服务选择
const
otherServiceSelect
=
(
ids
:
number
[])
=>
{
setOtherService
(
ids
);
};
//获取产品详情
const
getRichText
=
(
html
?:
string
)
=>
{
setProductIntroduce
(
html
||
''
);
};
//商品详情
const
getGoodsDetail
=
(
goodsInfoId
:
number
)
=>
{
GoodsAPI
.
getGoodsDetail
({
goodsInfoId
,
type
:
0
}).
then
(({
result
})
=>
{
setGoodsDetail
(
result
);
getCategoryList
(
result
.
directoryId
);
const
specList
:
specEntity
[]
=
result
.
goodsSpec
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
// 自定义
if
(
cur
.
flag
===
1
)
{
const
cusList
:
customizeEntity
[]
=
cur
.
productSpecList
&&
cur
.
productSpecList
.
reduce
((
preProd
:
any
,
curProd
:
customizeEntity
,
index
:
number
)
=>
{
const
obj
:
UploadFile
=
{
uid
:
`img
${
index
}
`
,
status
:
'done'
,
url
:
curProd
.
specImage
,
name
:
'image'
,
};
preProd
.
push
({
...
curProd
,
fileList
:
[
obj
]
});
return
preProd
;
},
[]);
cur
.
customizeInfo
=
cusList
;
}
else
{
const
specId
:
number
[]
=
result
.
directoryId
===
2
?
cur
.
industrySpecList
&&
cur
.
industrySpecList
.
map
((
curIndu
:
any
)
=>
{
return
{
mallSpecId
:
curIndu
.
industrySpecId
,
specName
:
curIndu
.
specName
,
partNo
:
curIndu
.
partNo
,
id
:
curIndu
.
id
,
};
})
:
cur
.
productSpecList
&&
cur
.
productSpecList
.
map
((
item
:
any
)
=>
{
return
{
mallSpecId
:
item
.
productSpec
,
specName
:
item
.
specName
,
partNo
:
item
.
partNo
,
id
:
item
.
id
,
};
});
cur
.
specIds
=
specId
;
}
pre
.
push
({
...
cur
,
productName
:
cur
.
skuName
});
return
pre
;
},
[]);
setGoodsSpecCopy
(
result
.
goodsSpec
);
setOtherService
(
result
.
otherService
.
map
((
v
)
=>
v
.
saleServiceId
));
setSpecData
(
specList
);
});
};
//保存
const
saveSubmit
=
()
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
baseInfoForm
.
validateFields
().
then
((
values
:
any
)
=>
{
if
(
specData
.
length
===
0
)
{
return
message
.
warning
(
'清添加库存规格'
);
}
//主图
values
.
images
=
[
{
imgType
:
0
,
imgUrl
:
values
.
mainImg
[
0
].
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
values
.
mainImg
[
0
].
id
)
?
values
.
mainImg
[
0
].
id
:
undefined
:
undefined
,
},
];
//副图
if
(
values
.
subImg
)
{
values
.
images
.
push
(
...
values
.
subImg
.
map
((
v
:
any
)
=>
({
imgType
:
1
,
imgUrl
:
v
.
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
v
.
id
)
?
v
.
id
:
undefined
:
undefined
,
})),
);
}
//分类
values
.
categoryByOne
=
values
.
masterTypeId
[
0
];
values
.
categoryByTwo
=
values
.
masterTypeId
[
1
]
||
undefined
;
// 过滤对象属性
const
goodsSpecVO
:
specEntity
[]
=
specData
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
cur
.
customizeInfo
=
cur
.
customizeInfo
?.
reduce
((
cusPre
:
any
,
cusCur
:
customizeEntity
)
=>
{
const
bol
:
boolean
=
goodsSpecCopy
.
some
((
i
:
specEntity
)
=>
{
return
i
.
customizeInfo
?.
some
((
i
:
customizeEntity
)
=>
i
.
id
===
cusCur
.
id
);
});
cusPre
=
[
...
cusPre
,
bol
?
filterObjAttr
(
cusCur
,
[
'fileList'
])
:
filterObjAttr
(
cusCur
,
[
'id'
,
'fileList'
]),
];
return
cusPre
;
},
[]);
// 存在对象属性改变!
cur
.
specIds
=
cur
.
specIds
?.
reduce
((
preSpec
:
any
,
curSpec
:
any
)
=>
{
preSpec
=
[...
preSpec
,
filterObjAttr
(
curSpec
,
[
'specName'
,
'partNo'
])];
return
preSpec
;
},
[]);
// 是否新增
const
isAdd
:
boolean
=
goodsSpecCopy
.
every
((
i
:
specEntity
)
=>
i
.
id
!=
cur
.
id
);
// 是否修改了某一条
const
isEdit
:
boolean
=
goodsSpecCopy
.
every
(
(
i
:
specEntity
)
=>
i
.
categoryId
!=
cur
.
categoryId
,
);
pre
=
[
...
pre
,
!
isAdd
?
isEdit
?
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
,
'id'
])
:
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
])
:
filterObjAttr
(
cur
,
[
'id'
,
'skuName'
]),
];
return
pre
;
},
[]);
goodsAPI
[
goodsDetail
?
'editGoods'
:
'addGoods'
]({
...
filterObjAttr
(
values
,
[
'mainImg'
,
'subImg'
,
'video'
,
'masterTypeId'
,
'id'
,
'goodsDesc'
]),
productSpec
:
goodsSpecVO
,
goodsType
:
0
,
goodsDetailVO
:
{
goodsDesc
:
values
.
goodsDesc
,
productDesc
:
productIntroduce
},
otherService
:
otherService
,
id
:
goodsDetail
?
goodsDetail
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsDetail
?
'编辑成功'
:
'新增成功'
);
navigate
(
-
1
);
}
});
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
if
(
searchParams
.
get
(
'id'
))
{
getGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
}
setIsDetail
(
!!
searchParams
.
get
(
'isDetail'
));
getSkuUnit
();
},
[]);
return
(
<
div
className=
'goods-info'
>
{
/* 基本信息*/
}
<
BaseInfo
ref=
{
baseInfoRef
}
categoryList=
{
categoryList
}
getCategoryList=
{
getCategoryList
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
goodsType=
{
0
}
/>
{
/* 库存规格*/
}
<
StockSku
addOrEditSku=
{
addOrEditSkuShowEvent
}
specData=
{
specData
}
skuUnitList=
{
skuUnitList
}
deleteSku=
{
deleteSkuEvent
}
isDetail=
{
isDetail
}
/>
{
/*其它信息*/
}
<
OtherInfo
otherServiceSelect=
{
otherServiceSelect
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*产品介绍图*/
}
<
GoodsIntroduce
getRichText=
{
getRichText
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*库存规格,添加、编辑弹窗*/
}
<
AddOrEditSkuModal
currentDesc=
{
currentDesc
}
open=
{
addOrEditSkuModalShow
}
handleCancel=
{
addOrEditSkuModalCancel
}
handleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
curtRowData=
{
curtRowData
}
goodsType=
{
0
}
/>
<
div
className=
'goods-info-operate'
>
{
!
isDetail
&&
(
<
Button
type=
'primary'
onClick=
{
saveSubmit
}
>
保存
</
Button
>
)
}
<
Button
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
</
div
>
);
};
export
default
GoodsAddOrEditOrDetail
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.scss
浏览文件 @
24da3ab0
.goods-info
{
&
-operate
{
margin-top
:
50px
;
display
:
flex
;
justify-content
:
center
;
button
{
width
:
100px
;
height
:
40px
;
&
:first-child
{
margin-right
:
50px
;
.goods-operate-wrap
{
position
:
relative
;
.next-step
{
margin
:
20px
0
0
0px
;
text-align
:
center
;
button
{
&
:first-child
{
margin-right
:
20px
;
}
width
:
100px
;
}
}
.back-btn
{
position
:
absolute
;
right
:
0
;
top
:
0
;
}
}
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
浏览文件 @
24da3ab0
import
BaseInfo
from
'~/components/goods/commonAddOrEdit/baseInfo'
;
import
StockSku
from
'~/components/goods/commonAddOrEdit/stockSku'
;
import
OtherInfo
from
'~/components/goods/commonAddOrEdit/otherInfo'
;
import
GoodsIntroduce
from
'~/components/goods/commonAddOrEdit/goodsIntroduce'
;
import
AddOrEditSkuModal
from
'~/components/goods/commonAddOrEdit/addOrEditSkuModal'
;
import
{
Button
,
message
}
from
'antd'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
Button
,
Tabs
,
TabsProps
}
from
'antd'
;
import
{
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
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
categoryListType
}
from
'~/api/interface/categoryManage'
;
import
{
customizeEntity
,
detailGoodsType
,
skuUnitType
,
specEntity
,
}
from
'~/api/interface/goodsType'
;
import
goodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
UploadFile
}
from
'antd/es/upload/interface'
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListType
>
[
'list'
];
//产品-规格单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品返回类型
type
goodsDetailType
=
InterDataType
<
detailGoodsType
>
;
import
{
useNavigate
}
from
'react-router-dom'
;
const
GoodsAddOrEditOrDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
//基本信息ref
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
//当前目录
const
[
currentDesc
,
setCurrentDesc
]
=
useState
<
number
>
(
-
1
);
//分类
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//添加、编辑库存规格弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
(
false
);
//库存规格数据
const
[
specData
,
setSpecData
]
=
useState
<
specEntity
[]
>
([]);
const
[
goodsSpecCopy
,
setGoodsSpecCopy
]
=
useState
<
specEntity
[]
>
([]);
//产品规格-单位
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
//其它服务
const
[
otherService
,
setOtherService
]
=
useState
<
number
[]
>
([]);
// 当前操作行数据
const
[
curtRowData
,
setCurtRowData
]
=
useState
<
Partial
<
specEntity
>>
({});
//商品详情
const
[
goodsDetail
,
setGoodsDetail
]
=
useState
<
goodsDetailType
>
();
//产品介绍
const
[
productIntroduce
,
setProductIntroduce
]
=
useState
<
string
>
(
''
);
//是否商品详情
const
[
isDetail
,
setIsDetail
]
=
useState
<
boolean
>
(
false
);
const
[
tabSelectKeys
,
setTabSelectKeys
]
=
useState
<
string
>
(
'1'
);
//新增、编辑sku弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
<
boolean
>
(
false
);
//添加、编辑规格
const
addOrEditSkuShowEvent
=
(
record
?:
specEntity
)
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
setCurrentDesc
(
baseInfoForm
.
getFieldValue
(
'directoryId'
)
||
-
1
);
if
(
!
baseInfoForm
.
getFieldValue
(
'directoryId'
))
{
return
message
.
warning
(
'请先选择目录'
);
}
if
(
record
)
{
setCurtRowData
({
...
record
});
}
//新增、编辑sku弹窗显示
const
addOrEditSkuClick
=
()
=>
{
setAddOrEditSkuModalShow
(
true
);
};
//删除规格
const
deleteSkuEvent
=
(
record
:
specEntity
)
=>
{
const
index
=
specData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
specData
.
splice
(
index
,
1
);
setSpecData
([...
specData
]);
};
const
addOrEditSkuModalCancel
=
()
=>
{
setAddOrEditSkuModalShow
(
false
);
setCurtRowData
({});
};
const
addOrEditSkuModalOk
=
(
data
:
specEntity
)
=>
{
if
(
Object
.
keys
(
curtRowData
).
length
!=
0
)
{
const
index
:
number
=
specData
.
findIndex
((
i
)
=>
i
.
id
===
data
.
id
);
specData
.
splice
(
index
,
1
,
data
);
setSpecData
([...
specData
]);
}
else
{
setSpecData
([...
specData
,
data
]);
}
addOrEditSkuModalCancel
();
};
//根据目录获取分类列表
const
getCategoryList
=
(
directoryId
:
number
)
=>
{
CategoryManageAPI
.
getCategoryList
({
directoryId
,
type
:
4
,
pageSize
:
9999
,
pageNo
:
1
}).
then
(
({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
},
);
//tab 切换
const
tabSelectChange
=
(
key
:
string
)
=>
{
setTabSelectKeys
(
key
);
};
//产品-单位
const
getSkuUnit
=
()
=>
{
goodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
//下一步
const
toNextStep
=
()
=>
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
};
//
其它服务选择
const
otherServiceSelect
=
(
ids
:
number
[]
)
=>
{
set
OtherService
(
ids
);
//
上一步
const
toBackStep
=
(
)
=>
{
set
TabSelectKeys
((
Number
(
tabSelectKeys
)
-
1
).
toString
()
);
};
//获取产品详情
const
getRichText
=
(
html
?:
string
)
=>
{
setProductIntroduce
(
html
||
''
);
};
//商品详情
const
getGoodsDetail
=
(
goodsInfoId
:
number
)
=>
{
GoodsAPI
.
getGoodsDetail
({
goodsInfoId
,
type
:
0
}).
then
(({
result
})
=>
{
setGoodsDetail
(
result
);
getCategoryList
(
result
.
directoryId
);
const
specList
:
specEntity
[]
=
result
.
goodsSpec
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
// 自定义
if
(
cur
.
flag
===
1
)
{
const
cusList
:
customizeEntity
[]
=
cur
.
productSpecList
&&
cur
.
productSpecList
.
reduce
((
preProd
:
any
,
curProd
:
customizeEntity
,
index
:
number
)
=>
{
const
obj
:
UploadFile
=
{
uid
:
`img
${
index
}
`
,
status
:
'done'
,
url
:
curProd
.
specImage
,
name
:
'image'
,
};
preProd
.
push
({
...
curProd
,
fileList
:
[
obj
]
});
return
preProd
;
},
[]);
cur
.
customizeInfo
=
cusList
;
}
else
{
const
specId
:
number
[]
=
result
.
directoryId
===
2
?
cur
.
industrySpecList
&&
cur
.
industrySpecList
.
map
((
curIndu
:
any
)
=>
{
return
{
mallSpecId
:
curIndu
.
industrySpecId
,
specName
:
curIndu
.
specName
,
partNo
:
curIndu
.
partNo
,
id
:
curIndu
.
id
,
};
})
:
cur
.
productSpecList
&&
cur
.
productSpecList
.
map
((
item
:
any
)
=>
{
return
{
mallSpecId
:
item
.
productSpec
,
specName
:
item
.
specName
,
partNo
:
item
.
partNo
,
id
:
item
.
id
,
};
});
cur
.
specIds
=
specId
;
}
pre
.
push
({
...
cur
,
productName
:
cur
.
skuName
});
return
pre
;
},
[]);
setGoodsSpecCopy
(
result
.
goodsSpec
);
setOtherService
(
result
.
otherService
.
map
((
v
)
=>
v
.
saleServiceId
));
setSpecData
(
specList
);
});
};
//保存
const
saveSubmit
=
()
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
baseInfoForm
.
validateFields
().
then
((
values
:
any
)
=>
{
if
(
specData
.
length
===
0
)
{
return
message
.
warning
(
'清添加库存规格'
);
}
//主图
values
.
images
=
[
{
imgType
:
0
,
imgUrl
:
values
.
mainImg
[
0
].
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
values
.
mainImg
[
0
].
id
)
?
values
.
mainImg
[
0
].
id
:
undefined
:
undefined
,
},
];
//副图
if
(
values
.
subImg
)
{
values
.
images
.
push
(
...
values
.
subImg
.
map
((
v
:
any
)
=>
({
imgType
:
1
,
imgUrl
:
v
.
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
v
.
id
)
?
v
.
id
:
undefined
:
undefined
,
})),
);
}
//分类
values
.
categoryByOne
=
values
.
masterTypeId
[
0
];
values
.
categoryByTwo
=
values
.
masterTypeId
[
1
]
||
undefined
;
// 过滤对象属性
const
goodsSpecVO
:
specEntity
[]
=
specData
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
cur
.
customizeInfo
=
cur
.
customizeInfo
?.
reduce
((
cusPre
:
any
,
cusCur
:
customizeEntity
)
=>
{
const
bol
:
boolean
=
goodsSpecCopy
.
some
((
i
:
specEntity
)
=>
{
return
i
.
customizeInfo
?.
some
((
i
:
customizeEntity
)
=>
i
.
id
===
cusCur
.
id
);
});
cusPre
=
[
...
cusPre
,
bol
?
filterObjAttr
(
cusCur
,
[
'fileList'
])
:
filterObjAttr
(
cusCur
,
[
'id'
,
'fileList'
]),
];
return
cusPre
;
},
[]);
// 存在对象属性改变!
cur
.
specIds
=
cur
.
specIds
?.
reduce
((
preSpec
:
any
,
curSpec
:
any
)
=>
{
preSpec
=
[...
preSpec
,
filterObjAttr
(
curSpec
,
[
'specName'
,
'partNo'
])];
return
preSpec
;
},
[]);
// 是否新增
const
isAdd
:
boolean
=
goodsSpecCopy
.
every
((
i
:
specEntity
)
=>
i
.
id
!=
cur
.
id
);
// 是否修改了某一条
const
isEdit
:
boolean
=
goodsSpecCopy
.
every
(
(
i
:
specEntity
)
=>
i
.
categoryId
!=
cur
.
categoryId
,
);
pre
=
[
...
pre
,
!
isAdd
?
isEdit
?
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
,
'id'
])
:
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
])
:
filterObjAttr
(
cur
,
[
'id'
,
'skuName'
]),
];
return
pre
;
},
[]);
goodsAPI
[
goodsDetail
?
'editGoods'
:
'addGoods'
]({
...
filterObjAttr
(
values
,
[
'mainImg'
,
'subImg'
,
'video'
,
'masterTypeId'
,
'id'
,
'goodsDesc'
]),
productSpec
:
goodsSpecVO
,
goodsType
:
0
,
goodsDetailVO
:
{
goodsDesc
:
values
.
goodsDesc
,
productDesc
:
productIntroduce
},
otherService
:
otherService
,
id
:
goodsDetail
?
goodsDetail
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsDetail
?
'编辑成功'
:
'新增成功'
);
navigate
(
-
1
);
}
});
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
if
(
searchParams
.
get
(
'id'
))
{
getGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
}
setIsDetail
(
!!
searchParams
.
get
(
'isDetail'
));
getSkuUnit
();
},
[]);
const
TabItems
:
TabsProps
[
'items'
]
=
[
{
key
:
'1'
,
label
:
`基础信息`
,
children
:
<
BaseInfo
/>,
},
{
key
:
'2'
,
label
:
`商品规格`
,
children
:
<
SkuInfo
addOrEditSkuClick=
{
addOrEditSkuClick
}
/>,
},
{
key
:
'3'
,
label
:
`商品详情`
,
children
:
<
IntroduceInfo
/>,
},
];
return
(
<
div
className=
'goods-info'
>
{
/* 基本信息*/
}
<
BaseInfo
ref=
{
baseInfoRef
}
categoryList=
{
categoryList
}
getCategoryList=
{
getCategoryList
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
goodsType=
{
0
}
/>
{
/* 库存规格*/
}
<
StockSku
addOrEditSku=
{
addOrEditSkuShowEvent
}
specData=
{
specData
}
skuUnitList=
{
skuUnitList
}
deleteSku=
{
deleteSkuEvent
}
isDetail=
{
isDetail
}
/>
{
/*其它信息*/
}
<
OtherInfo
otherServiceSelect=
{
otherServiceSelect
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*产品介绍图*/
}
<
GoodsIntroduce
getRichText=
{
getRichText
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*库存规格,添加、编辑弹窗*/
}
<
AddOrEditSkuModal
currentDesc=
{
currentDesc
}
open=
{
addOrEditSkuModalShow
}
handleCancel=
{
addOrEditSkuModalCancel
}
handleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
curtRowData=
{
curtRowData
}
goodsType=
{
0
}
/>
<
div
className=
'goods-info-operate'
>
{
!
isDetail
&&
(
<
Button
type=
'primary'
onClick=
{
saveSubmit
}
>
保存
<
div
className=
'goods-operate-wrap'
>
<
Tabs
items=
{
TabItems
}
activeKey=
{
tabSelectKeys
}
onChange=
{
tabSelectChange
}
></
Tabs
>
<
div
className=
'next-step'
>
{
tabSelectKeys
!==
'1'
?
<
Button
onClick=
{
toBackStep
}
>
上一步
</
Button
>
:
''
}
{
tabSelectKeys
!==
'3'
?
(
<
Button
type=
'primary'
onClick=
{
toNextStep
}
>
下一步
</
Button
>
)
:
(
<
Button
type=
'primary'
>
保存
</
Button
>
)
}
<
Button
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
<
div
className=
'back-btn'
>
<
Button
type=
'primary'
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
{
/*新增、编辑sku弹窗*/
}
<
SkuAddOrEditModal
open=
{
addOrEditSkuModalShow
}
onCancel=
{
addOrEditSkuModalCancel
}
/>
</
div
>
);
};
...
...
src/router/router.tsx
浏览文件 @
24da3ab0
...
...
@@ -467,16 +467,6 @@ export const routerList: Array<RouteObjectType> = [
},
children
:
[
{
path
:
'/mallManage/courseManage'
,
element
:
withLoadingComponent
(<
CourseManageView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1010
,
icon
:
<
BookOutlined
/>,
title
:
'课程管理'
,
},
},
{
path
:
'/mallManage/serviceList'
,
element
:
withLoadingComponent
(<
ServiceListView
/>),
errorElement
:
<
ErrorPage
/>,
...
...
@@ -903,7 +893,7 @@ export const routerList: Array<RouteObjectType> = [
meta
:
{
id
:
1600
,
icon
:
<
BankOutlined
/>,
title
:
'
飞手
培训'
,
title
:
'
执照
培训'
,
},
children
:
[
{
...
...
@@ -938,6 +928,16 @@ export const routerList: Array<RouteObjectType> = [
hidden
:
true
,
},
},
{
path
:
'/pilotTraining/courseManage'
,
element
:
withLoadingComponent
(<
CourseManageView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1010
,
icon
:
<
BookOutlined
/>,
title
:
'课程管理'
,
},
},
],
},
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论