Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin-ci-test
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
test-ci
admin-ci-test
Commits
26a95c46
提交
26a95c46
authored
7月 27, 2023
作者:
龚洪江
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
功能:商品新增,商品编辑(联调完成)
上级
679b10ca
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
506 行增加
和
159 行删除
+506
-159
goodsType.ts
src/api/interface/goodsType.ts
+124
-1
goodsAPI.ts
src/api/modules/goodsAPI.ts
+24
-0
index.tsx
src/components/EditableCell/index.tsx
+1
-1
index.tsx
src/pages/categoryManage/categoryList/index.tsx
+0
-1
index.scss
...ods/goodsAddOrEditOrDetail/components/baseInfo/index.scss
+10
-0
index.tsx
...oods/goodsAddOrEditOrDetail/components/baseInfo/index.tsx
+43
-13
index.tsx
...goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
+13
-2
index.tsx
...sAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
+62
-13
index.tsx
...Goods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
+1
-1
index.tsx
...ges/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
+110
-10
index.tsx
src/pages/mallManage/mallGoods/goodsDetails/index.tsx
+4
-0
index.tsx
src/pages/mallManage/mallGoods/goodsList/index.tsx
+102
-117
validateUtils.ts
src/utils/validateUtils.ts
+12
-0
没有找到文件。
src/api/interface/goodsType.ts
浏览文件 @
26a95c46
...
...
@@ -99,8 +99,12 @@ export type otherServiceType = InterFunction<any, { id: number; saleServiceName:
export
type
skuUnitType
=
InterFunction
<
any
,
{
id
:
number
;
unitName
:
string
}[]
>
;
//商品-批量上下架
export
type
batchOnShelfOrTakeDownType
=
InterFunction
<
{
goodsIds
:
number
[];
status
:
number
},
any
>
;
//商品-单个上下架(新)
export
type
upOrDownShelfType
=
InterFunction
<
{
id
:
number
;
status
:
number
},
any
>
;
//商品批量删除
export
type
batchRemoveWareInfoType
=
InterFunction
<
number
[],
any
>
;
//商品-单个删除
export
type
removeMallGoodsType
=
InterFunction
<
{
id
:
number
},
any
>
;
//商品-上下移动
export
type
exchangeGoodsInfoType
=
InterFunction
<
{
firstId
:
number
;
secondId
:
number
},
any
>
;
...
...
@@ -116,7 +120,7 @@ export type addMallGoodsType = InterFunction<
chooseType
:
number
;
goodsSpecValuesList
:
{
channelPrice
?:
number
;
id
:
number
;
id
:
any
;
partNo
:
string
;
salePrice
:
number
;
showPrice
:
number
;
...
...
@@ -124,7 +128,44 @@ export type addMallGoodsType = InterFunction<
specValueName
:
string
;
stock
?:
number
;
}[];
id
:
any
;
mallGoodsId
:
number
;
must
:
number
;
skuUnitId
:
number
;
specName
:
string
;
}[];
labelShow
:
number
;
resourcesList
:
{
id
:
number
;
type
:
number
;
url
:
string
;
}[];
shelfStatus
:
number
;
tradeName
:
string
;
},
any
>
;
//商品-编辑(新)
export
type
editMallGoodsType
=
InterFunction
<
{
categoryPrimaryId
:
number
;
categorySubId
:
number
;
description
:
string
;
goodsDetails
:
string
;
goodsLabel
:
string
;
goodsSpecList
:
{
chooseType
:
number
;
goodsSpecValuesList
:
{
channelPrice
?:
number
;
id
:
any
;
partNo
:
string
;
salePrice
:
number
;
showPrice
:
number
;
specValueImage
:
string
;
specValueName
:
string
;
stock
?:
number
;
}[];
id
:
any
;
mallGoodsId
:
number
;
must
:
number
;
skuUnitId
:
number
;
...
...
@@ -142,3 +183,85 @@ export type addMallGoodsType = InterFunction<
},
any
>
;
//商品-列表(新)
export
type
listPageGoodsInfoType
=
InterItemFunction
<
{
categoryPrimaryId
?:
number
;
tradeName
?:
string
;
shelfStatus
?:
number
},
{
categoryPrimaryId
:
number
;
categorySubId
:
number
;
createTime
:
string
;
description
:
string
;
goodsDetails
:
string
;
goodsLabel
:
string
;
goodsSpecList
:
{
chooseType
:
number
;
goodsSpecValuesList
:
{
channelPrice
:
number
;
goodsSpecId
:
number
;
id
:
number
;
partNo
:
string
;
salePrice
:
number
;
showPrice
:
number
;
specValueImage
:
string
;
specValueName
:
string
;
stock
:
number
;
}[];
id
:
number
;
mallGoodsId
:
number
;
must
:
number
;
skuUnitId
:
number
;
specName
:
string
;
}[];
id
:
number
;
labelShow
:
number
;
resourcesList
:
{
id
:
number
;
type
:
number
;
url
:
string
;
}[];
shelfStatus
:
number
;
tradeName
:
string
;
userAccountId
:
number
;
}[]
>
;
//商城-详情(新)
export
type
mallGoodsDetailsType
=
InterFunction
<
{
id
:
number
},
{
categoryPrimaryId
:
number
;
categorySubId
:
number
;
createTime
:
string
;
description
:
string
;
goodsDetails
:
string
;
goodsLabel
:
string
;
goodsSpecList
:
{
chooseType
:
number
;
goodsSpecValuesList
:
{
channelPrice
:
number
;
goodsSpecId
:
number
;
id
:
number
;
partNo
:
string
;
salePrice
:
number
;
showPrice
:
number
;
specValueImage
:
string
;
specValueName
:
string
;
stock
:
number
;
}[];
id
:
number
;
mallGoodsId
:
number
;
must
:
number
;
skuUnitId
:
number
;
specName
:
string
;
}[];
id
:
number
;
labelShow
:
number
;
resourcesList
:
{
id
:
number
;
type
:
number
;
url
:
string
;
}[];
shelfStatus
:
number
;
tradeName
:
string
;
userAccountId
:
number
;
}
>
;
src/api/modules/goodsAPI.ts
浏览文件 @
26a95c46
...
...
@@ -5,10 +5,15 @@ import {
batchRemoveWareInfoType
,
detailGoodsType
,
editGoodsType
,
editMallGoodsType
,
exchangeGoodsInfoType
,
listGoodsType
,
listPageGoodsInfoType
,
mallGoodsDetailsType
,
otherServiceType
,
removeMallGoodsType
,
skuUnitType
,
upOrDownShelfType
,
}
from
'~/api/interface/goodsType'
;
import
axios
from
'../request'
;
...
...
@@ -41,16 +46,35 @@ class GoodsAPI {
static
batchOnShelfOrTakeDown
:
batchOnShelfOrTakeDownType
=
(
data
)
=>
{
return
axios
.
post
(
'/pms/goods/batchOnShelfOrTakeDown'
,
data
);
};
//商品-单个上下架(新)
static
upOrDownShelf
:
upOrDownShelfType
=
(
params
)
=>
axios
.
get
(
'/pms/mall/goods/upOrDownShelf'
,
{
params
});
// 商品-批量删除
static
batchRemoveWareInfo
:
batchRemoveWareInfoType
=
(
data
)
=>
{
return
axios
.
post
(
'/pms/goods/batchRemoveWareInfo'
,
data
);
};
//商品-单个删除
static
removeMallGoods
:
removeMallGoodsType
=
(
params
)
=>
axios
.
get
(
'/pms/mall/goods/removeMallGoods'
,
{
params
});
// 商品-上下移动
static
exchangeGoodsInfo
:
exchangeGoodsInfoType
=
(
params
)
=>
{
return
axios
.
get
(
'/pms/goods/exchangeGoodsInfo'
,
{
params
});
};
//商品-上下移动
static
exchange
:
exchangeGoodsInfoType
=
(
params
)
=>
axios
.
get
(
'/pms/mall/goods/exchange'
,
{
params
});
// 商品-新增(新)
static
addMallGoods
:
addMallGoodsType
=
(
data
)
=>
axios
.
post
(
'/pms/mall/goods/addMallGoods'
,
data
);
//商品-编辑(新)
static
editMallGoods
:
editMallGoodsType
=
(
data
)
=>
axios
.
post
(
'/pms/mall/goods/editMallGoods'
,
data
);
// 商品-列表(新)
static
getListPageGoodsInfo
:
listPageGoodsInfoType
=
(
data
)
=>
axios
.
post
(
'/pms/mall/goods/listPageGoodsInfo'
,
data
);
// 商品-详情(新)
static
getMallGoodsDetails
:
mallGoodsDetailsType
=
(
params
)
=>
axios
.
get
(
'/pms/mall/goods/mallGoodsDetails'
,
{
params
});
}
export
default
GoodsAPI
;
src/components/EditableCell/index.tsx
浏览文件 @
26a95c46
...
...
@@ -39,7 +39,7 @@ const EditableCell: React.FC<
const
inputNode
=
()
=>
{
switch
(
inputType
)
{
case
'number'
:
return
<
InputNumber
/>;
return
<
InputNumber
placeholder=
{
`请输入${title}`
}
maxLength=
{
maxLength
}
/>;
case
'select'
:
return
(
<
Select
placeholder=
{
`请选择${title}`
}
style=
{
{
textAlign
:
'start'
}
}
>
...
...
src/pages/categoryManage/categoryList/index.tsx
浏览文件 @
26a95c46
...
...
@@ -118,7 +118,6 @@ const CategoryList = () => {
)
:
(
''
)
}
<
Button
type=
'link'
>
详情
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
addOrEditCategoryModalShowClick
(
record
)
}
>
编辑
</
Button
>
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/baseInfo/index.scss
0 → 100644
浏览文件 @
26a95c46
.goods-video-wrap
{
position
:
relative
;
width
:
200px
;
img
{
position
:
absolute
;
right
:
0
;
top
:
0
;
transform
:
translate
(
50%
,-
25%
);
}
}
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/baseInfo/index.tsx
浏览文件 @
26a95c46
...
...
@@ -2,10 +2,12 @@ import { Button, Cascader, Form, Input, Radio, Select } from 'antd';
import
{
Uploader
}
from
'~/components/uploader'
;
import
type
{
RadioChangeEvent
}
from
'antd'
;
import
{
UploadOutlined
}
from
'@ant-design/icons'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
React
,
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
categoryListRespType
}
from
'~/api/interface/categoryManage'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
deletePng
from
'~/assets/image/delete.png'
;
import
'./index.scss'
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListRespType
>
[
'list'
];
...
...
@@ -76,6 +78,12 @@ const BaseInfo = forwardRef<any, selfProps>((_props, ref) => {
useImperativeHandle
(
ref
,
()
=>
({
getForm
:
()
=>
baseInfoForm
,
setLabelShow
:
(
value
:
boolean
)
=>
setLabelShow
(
value
),
mediaData
:
{
setMainFileList
,
setSubFileList
,
setVideoFileList
,
},
}));
//标签选中监听
...
...
@@ -115,6 +123,11 @@ const BaseInfo = forwardRef<any, selfProps>((_props, ref) => {
setCategoryList
(
result
.
list
||
[]);
});
};
//视频删除
const
deleteVideo
=
()
=>
{
setVideoFileList
([]);
baseInfoForm
.
setFieldValue
(
'videoList'
,
undefined
);
};
useEffect
(()
=>
{
getCategoryList
();
...
...
@@ -133,10 +146,14 @@ const BaseInfo = forwardRef<any, selfProps>((_props, ref) => {
name=
'tradeName'
rules=
{
[{
required
:
true
,
message
:
'请输入商品名称'
}]
}
>
<
Input
placeholder=
'请输入商品名称'
/>
<
Input
placeholder=
'请输入商品名称'
maxLength=
{
50
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品描述'
name=
'description'
>
<
Input
.
TextArea
rows=
{
4
}
placeholder=
'请输入商品描述'
/>
<
Form
.
Item
label=
'商品描述'
name=
'description'
rules=
{
[{
required
:
true
,
message
:
'请输入商品描述'
}]
}
>
<
Input
.
TextArea
rows=
{
4
}
placeholder=
'请输入商品描述'
maxLength=
{
70
}
showCount
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品主图'
...
...
@@ -163,14 +180,27 @@ const BaseInfo = forwardRef<any, selfProps>((_props, ref) => {
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品视频'
name=
'videoList'
>
<
Uploader
fileUpload
listType=
'text'
onChange=
{
(
fileList
)
=>
uploadSuccess
(
fileList
,
'videoList'
)
}
defaultFileList=
{
videoFileList
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
上传视频
</
Button
>
</
Uploader
>
{
videoFileList
.
length
?
(
<
div
className=
'goods-video-wrap'
>
<
video
src=
{
videoFileList
[
0
].
url
}
style=
{
{
width
:
'200px'
,
height
:
'200px'
}
}
controls
/>
<
img
src=
{
deletePng
}
alt=
'删除'
onClick=
{
deleteVideo
}
/>
</
div
>
)
:
(
<
Uploader
fileUpload
listType=
'text'
onChange=
{
(
fileList
)
=>
uploadSuccess
(
fileList
,
'videoList'
)
}
defaultFileList=
{
videoFileList
}
fileType=
{
[
'video/mp4'
,
'video/avi'
,
'video/wmv'
,
'video/rmvb'
]
}
fileSize=
{
50
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
上传视频
</
Button
>
</
Uploader
>
)
}
</
Form
.
Item
>
<
Form
.
Item
label=
'商品分类'
...
...
@@ -205,7 +235,7 @@ const BaseInfo = forwardRef<any, selfProps>((_props, ref) => {
name=
'goodsLabel'
rules=
{
[{
required
:
true
,
message
:
'请输入商品标签'
}]
}
>
<
Input
placeholder=
'请输入商品标签'
/>
<
Input
placeholder=
'请输入商品标签'
maxLength=
{
10
}
/>
</
Form
.
Item
>
)
:
(
''
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
浏览文件 @
26a95c46
import
RichText
from
'~/components/richText'
;
import
{
FC
}
from
'react'
;
interface
selfProps
{
onChange
:
(
html
:
string
)
=>
void
;
introduceInfo
:
string
;
}
const
IntroduceInfo
:
FC
<
selfProps
>
=
({
onChange
,
introduceInfo
})
=>
{
//富文本修改
const
richTextOnChange
=
(
html
?:
string
)
=>
{
onChange
(
html
||
''
);
};
const
IntroduceInfo
=
()
=>
{
return
(
<
div
className=
'introduce-info'
>
<
RichText
richTextContent=
''
height=
{
400
}
/>
<
RichText
richTextContent=
{
introduceInfo
}
height=
{
400
}
onChange=
{
richTextOnChange
}
/>
</
div
>
);
};
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
浏览文件 @
26a95c46
import
{
Button
,
Form
,
Input
,
message
,
Modal
,
ModalProps
,
Radio
,
Select
,
Table
}
from
'antd'
;
import
{
Button
,
Form
,
Input
,
Modal
,
ModalProps
,
Radio
,
Select
,
Table
}
from
'antd'
;
import
{
FC
,
useEffect
,
useState
}
from
'react'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
{
MinusOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
{
isEmptyBol
,
regPriceNumber
}
from
'~/utils/validateUtils'
;
import
_
from
'lodash'
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
//商品sku规格类型
type
goodsSpecType
=
InterReqType
<
addMallGoodsType
>
[
'goodsSpecList'
][
0
];
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//商品sku规格值类型
type
goodsSpecValuesType
=
InterReqType
<
addMallGoodsType
>
[
'goodsSpecList'
][
0
][
'goodsSpecValuesList'
]
&
{
fileList
:
any
};
type
goodsSpecValuesType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
][
'goodsSpecValuesList'
][
0
]
&
{
fileList
:
any
};
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
interface
selfProps
{
onCancel
:
()
=>
void
;
onOk
:
(
value
:
goodsSpecType
)
=>
void
;
on
Handle
Ok
:
(
value
:
goodsSpecType
)
=>
void
;
skuUnitList
:
unitType
;
currentSku
:
goodsSpecType
|
undefined
;
}
...
...
@@ -27,12 +31,49 @@ interface selfProps {
const
SkuAddOrEditModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
,
onOk
,
on
Handle
Ok
,
skuUnitList
,
currentSku
,
})
=>
{
const
[
goodsSpecForm
]
=
Form
.
useForm
<
Omit
<
goodsSpecType
,
'goodsSpecValuesList'
>>
();
const
[
goodsSpecValuesForm
]
=
Form
.
useForm
<
goodsSpecValuesType
[
0
]
>
();
const
[
goodsSpecValuesForm
]
=
Form
.
useForm
<
goodsSpecValuesType
>
();
//销售正则价格校验
const
salePriceValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
regPriceNumber
(
value
.
toString
()))
{
return
Promise
.
resolve
();
}
else
{
return
Promise
.
reject
(
new
Error
(
'为整数且最多保留两位小数'
));
}
}
else
{
return
Promise
.
reject
(
new
Error
(
'请输入销售价'
));
}
};
//渠道正则价格校验
const
channelPriceValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
regPriceNumber
(
value
.
toString
()))
{
return
Promise
.
resolve
();
}
else
{
return
Promise
.
reject
(
new
Error
(
'为整数且最多保留两位小数'
));
}
}
else
{
return
Promise
.
resolve
();
}
};
//库存正则校验
const
stockPriceValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
/^
[
+
]{0,1}(\d
+
)
$/
.
test
(
value
.
toString
()))
{
return
Promise
.
resolve
();
}
else
{
return
Promise
.
reject
(
new
Error
(
'请输入正整数'
));
}
}
else
{
return
Promise
.
resolve
();
}
};
const
[
tableData
,
setTableData
]
=
useState
<
goodsSpecValuesType
[]
>
([
{
...
...
@@ -53,6 +94,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
inputType
?:
string
;
radioOption
?:
{
name
:
string
;
id
:
number
}[];
rules
?:
any
;
maxLength
?:
number
;
})[]
=
[
{
title
:
'序号'
,
...
...
@@ -74,6 +116,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
editable
:
true
,
dataIndex
:
'specValueName'
,
rules
:
[{
required
:
true
,
message
:
'请输入选项名称'
}],
maxLength
:
30
,
},
{
title
:
'料号'
,
...
...
@@ -81,25 +124,31 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
editable
:
true
,
dataIndex
:
'partNo'
,
rules
:
[{
required
:
true
,
message
:
'请输入料号'
}],
maxLength
:
30
,
},
{
title
:
'销售价'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'salePrice'
,
rules
:
[{
required
:
true
,
message
:
'请输入销售号'
}],
rules
:
[{
required
:
true
,
validator
:
salePriceValidator
}],
inputType
:
'number'
,
},
{
title
:
'渠道价'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
'channelPrice'
,
rules
:
[{
required
:
false
,
validator
:
channelPriceValidator
}],
inputType
:
'number'
,
},
{
title
:
'库存'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
'stock'
,
rules
:
[{
required
:
false
,
validator
:
stockPriceValidator
}],
inputType
:
'number'
,
},
{
title
:
'是否显示'
,
...
...
@@ -107,7 +156,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
align
:
'center'
,
dataIndex
:
'showPrice'
,
inputType
:
'radio'
,
width
:
'
20
%'
,
width
:
'
18
%'
,
radioOption
:
[
{
id
:
1
,
name
:
'显示'
},
{
id
:
0
,
name
:
'不显示'
},
...
...
@@ -237,7 +286,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
//提交
const
handleOk
=
()
=>
{
Promise
.
all
([
goodsSpecForm
.
validateFields
(),
goodsSpecValuesForm
.
validateFields
()]).
then
(
(
values
)
=>
{
(
values
:
any
)
=>
{
const
goodsSpecValuesList
:
goodsSpecValuesType
[]
=
tableData
.
map
((
v
)
=>
{
return
Object
.
getOwnPropertyNames
(
v
).
reduce
((
pre
:
any
,
cur
:
string
)
=>
{
if
(
Object
.
getOwnPropertyNames
(
values
[
1
]).
includes
(
cur
+
v
.
id
))
{
...
...
@@ -247,7 +296,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
return
pre
;
},
{});
});
onOk
({
...
values
[
0
],
goodsSpecValuesList
,
id
:
currentSku
?.
id
||
Math
.
random
()
});
on
Handle
Ok
({
...
values
[
0
],
goodsSpecValuesList
,
id
:
currentSku
?.
id
||
Math
.
random
()
});
clearForm
();
},
);
...
...
@@ -294,7 +343,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
<
Modal
open=
{
open
}
title=
{
currentSku
?
'编辑规格'
:
'添加规格'
}
width=
{
1
0
00
}
width=
{
1
1
00
}
onCancel=
{
handleCancel
}
onOk=
{
handleOk
}
>
...
...
@@ -309,7 +358,7 @@ const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
name=
'specName'
rules=
{
[{
required
:
true
,
message
:
'请输入规格名称'
}]
}
>
<
Input
placeholder=
'请输入规格名称'
/>
<
Input
placeholder=
'请输入规格名称'
maxLength=
{
30
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'规格值'
>
<
Form
component=
{
false
}
form=
{
goodsSpecValuesForm
}
>
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
浏览文件 @
26a95c46
...
...
@@ -6,7 +6,7 @@ import { InterDataType, InterReqType } from '~/api/interface';
import
{
addMallGoodsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
//商品sku规格类型
type
goodsSpecType
=
InterReqType
<
addMallGoodsType
>
[
'goodsSpecList'
][
0
];
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
interface
selfProps
{
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
浏览文件 @
26a95c46
...
...
@@ -5,20 +5,24 @@ import SkuInfo from './components/skuInfo';
import
IntroduceInfo
from
'./components/introduceInfo'
;
import
SkuAddOrEditModal
from
'./components/skuAddOrEditModal'
;
import
'./index.scss'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
baseInfoType
}
from
'./components/baseInfo'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
{
addMallGoodsType
,
mallGoodsDetailsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
//商品sku规格类型
type
goodsSpecType
=
InterReqType
<
addMallGoodsType
>
[
'goodsSpecList'
][
0
];
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品详情-返回类型
type
goodsDetailType
=
InterDataType
<
mallGoodsDetailsType
>
;
const
GoodsAddOrEditOrDetail
=
()
=>
{
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
const
[
searchParams
]
=
useSearchParams
();
//单位列表
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
...
...
@@ -27,10 +31,14 @@ const GoodsAddOrEditOrDetail = () => {
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
<
boolean
>
(
false
);
//当前编辑sku
const
[
currentSku
,
setCurrentSku
]
=
useState
<
goodsSpecType
>
();
//基本信息暂存
const
[
baseInfo
,
setBaseInfo
]
=
useState
<
baseInfoType
>
();
//skuTable数据
const
[
skuTable
,
setSkuTable
]
=
useState
<
goodsSpecType
[]
>
([]);
//商品介绍详情
const
[
goodsDetails
,
setGoodsDetails
]
=
useState
<
string
>
(
''
);
//商品id
const
[
goodsId
,
setGoodsId
]
=
useState
<
number
>
(
0
);
//商品详情
const
[
goodsDetailsInfo
,
setGoodsDetailsInfo
]
=
useState
<
goodsDetailType
>
();
//新增、编辑sku弹窗显示
const
addOrEditSkuClick
=
(
record
?:
goodsSpecType
)
=>
{
...
...
@@ -56,6 +64,10 @@ const GoodsAddOrEditOrDetail = () => {
skuTable
.
splice
(
skuIndex
,
1
);
setSkuTable
([...
skuTable
]);
};
//商品详情获取
const
getIntroduceInfo
=
(
richText
:
string
)
=>
{
setGoodsDetails
(
richText
);
};
const
tabItems
:
TabsProps
[
'items'
]
=
[
{
...
...
@@ -79,7 +91,7 @@ const GoodsAddOrEditOrDetail = () => {
{
key
:
'3'
,
label
:
`商品详情`
,
children
:
<
IntroduceInfo
/>,
children
:
<
IntroduceInfo
onChange=
{
getIntroduceInfo
}
introduceInfo=
{
goodsDetails
}
/>,
},
];
...
...
@@ -94,8 +106,7 @@ const GoodsAddOrEditOrDetail = () => {
baseInfoRef
.
current
.
getForm
()
.
validateFields
()
.
then
((
value
:
baseInfoType
)
=>
{
setBaseInfo
(
value
);
.
then
(()
=>
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
})
.
catch
((
error
:
any
)
=>
{
...
...
@@ -129,8 +140,95 @@ const GoodsAddOrEditOrDetail = () => {
});
};
//商品保存
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
,
})),
}));
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
(
'商品规格未添加'
);
}
})
.
catch
((
error
:
any
)
=>
{
message
.
error
(
error
.
errorFields
[
0
].
errors
[
0
]);
});
};
//商品详情
const
getMallGoodsDetails
=
(
id
:
number
)
=>
{
GoodsAPI
.
getMallGoodsDetails
({
id
}).
then
(({
result
})
=>
{
const
mainImgList
=
result
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
0
)
.
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
'mainImg'
,
uid
:
v
.
id
,
url
:
v
.
url
}));
const
subImgList
=
result
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
)
.
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
'subImg'
,
uid
:
v
.
id
,
url
:
v
.
url
}));
const
videoList
=
result
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
2
)
.
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
'video'
,
uid
:
v
.
id
,
url
:
v
.
url
}));
setGoodsDetailsInfo
(
result
);
setSkuTable
(
result
.
goodsSpecList
);
setGoodsDetails
(
result
.
goodsDetails
||
''
);
baseInfoRef
.
current
.
getForm
().
setFieldsValue
({
tradeName
:
result
.
tradeName
,
description
:
result
.
description
||
undefined
,
mainImgList
,
subImgList
:
subImgList
.
length
?
subImgList
:
undefined
,
videoList
:
videoList
.
length
?
videoList
:
undefined
,
categoryId
:
result
.
categorySubId
?
[
result
.
categoryPrimaryId
,
result
.
categorySubId
]
:
[
result
.
categoryPrimaryId
],
shelfStatus
:
result
.
shelfStatus
,
labelShow
:
result
.
labelShow
,
goodsLabel
:
result
.
goodsLabel
||
undefined
,
});
baseInfoRef
.
current
.
setLabelShow
(
!!
result
.
labelShow
);
baseInfoRef
.
current
.
mediaData
.
setMainFileList
(
mainImgList
);
baseInfoRef
.
current
.
mediaData
.
setSubFileList
(
subImgList
);
baseInfoRef
.
current
.
mediaData
.
setVideoFileList
(
videoList
);
});
};
useEffect
(()
=>
{
getSkuUnit
();
if
(
searchParams
.
get
(
'id'
))
{
setGoodsId
(
Number
(
searchParams
.
get
(
'id'
)));
getMallGoodsDetails
(
Number
(
searchParams
.
get
(
'id'
)));
}
},
[]);
return
(
...
...
@@ -143,7 +241,9 @@ const GoodsAddOrEditOrDetail = () => {
下一步
</
Button
>
)
:
(
<
Button
type=
'primary'
>
保存
</
Button
>
<
Button
type=
'primary'
onClick=
{
saveGoods
}
>
保存
</
Button
>
)
}
</
div
>
<
div
className=
'back-btn'
>
...
...
@@ -155,7 +255,7 @@ const GoodsAddOrEditOrDetail = () => {
<
SkuAddOrEditModal
open=
{
addOrEditSkuModalShow
}
onCancel=
{
addOrEditSkuModalCancel
}
onOk=
{
addOrEditSkuModalOk
}
on
Handle
Ok=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
currentSku=
{
currentSku
}
/>
...
...
src/pages/mallManage/mallGoods/goodsDetails/index.tsx
0 → 100644
浏览文件 @
26a95c46
const
GoodsDetails
=
()
=>
{
return
<
div
className=
'goods-detail'
></
div
>;
};
export
default
GoodsDetails
;
src/pages/mallManage/mallGoods/goodsList/index.tsx
浏览文件 @
26a95c46
...
...
@@ -2,24 +2,22 @@ import SearchBox, { searchColumns } from '~/components/search-box';
import
React
,
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
Button
,
Card
,
Image
,
message
,
Modal
,
Table
}
from
'antd'
;
import
{
ArrowDownOutlined
,
ArrowUpOutlined
,
DeleteOutlined
,
PlusOutlined
,
}
from
'@ant-design/icons'
;
import
{
ArrowDownOutlined
,
ArrowUpOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
InterDataType
,
InterReqType
,
PaginationProps
}
from
'~/api/interface'
;
import
{
listGoodsType
}
from
'~/api/interface/goodsType'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
listPageGoodsInfoType
}
from
'~/api/interface/goodsType'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
qs
from
'query-string'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
categoryListRespType
}
from
'~/api/interface/categoryManage'
;
//商品返回类型
type
goodsType
=
InterDataType
<
list
Goods
Type
>
[
'list'
];
type
goodsType
=
InterDataType
<
list
PageGoodsInfo
Type
>
[
'list'
];
//商品列表筛选类型
type
goodsSearchParameters
=
Omit
<
InterReqType
<
listGoodsType
>
,
'goodsType'
>
;
type
goodsSearchParameters
=
InterReqType
<
listPageGoodsInfoType
>
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListRespType
>
[
'list'
];
const
GoodsList
=
()
=>
{
//筛选ref
...
...
@@ -41,6 +39,8 @@ const GoodsList = () => {
},
];
const
[
activeTabKey
,
setActiveTabKey
]
=
useState
<
string
>
(
'1'
);
//分类列表
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
const
[
searchColumns
,
setSearchColumns
]
=
useState
<
searchColumns
[]
>
([
{
label
:
'商品名称'
,
...
...
@@ -49,18 +49,12 @@ const GoodsList = () => {
type
:
'input'
,
},
{
label
:
'
所属目录
'
,
placeholder
:
'请选择
所属目录
'
,
name
:
'
directo
ryId'
,
label
:
'
商品类型
'
,
placeholder
:
'请选择
商品类别
'
,
name
:
'
categoryPrima
ryId'
,
type
:
'select'
,
options
:
[],
},
{
label
:
'创建时间'
,
placeholder
:
'请输入选择创建时间'
,
name
:
'time'
,
type
:
'rangePicker'
,
},
]);
const
tableColumns
:
ColumnsType
<
goodsType
[
0
]
>
=
[
{
...
...
@@ -72,23 +66,29 @@ const GoodsList = () => {
{
title
:
'图片'
,
align
:
'center'
,
dataIndex
:
'imgUrl'
,
render
:
(
text
:
string
)
=>
<
Image
src=
{
text
}
width=
{
50
}
height=
{
50
}
/>,
dataIndex
:
'resourcesList'
,
render
:
(
text
:
goodsType
[
0
][
'resourcesList'
])
=>
(
<
Image
src=
{
text
.
find
((
v
)
=>
v
.
type
===
0
)?.
url
||
''
}
width=
{
50
}
height=
{
50
}
/>
),
},
{
title
:
'商品名称'
,
align
:
'center'
,
dataIndex
:
'tradeName'
},
{
title
:
'商品类别'
,
align
:
'center'
,
render
:
(
_text
:
string
,
record
:
goodsType
[
0
])
=>
getCategoryStr
(
record
),
},
{
title
:
'商品名称'
,
align
:
'center'
,
dataIndex
:
'goodsName'
},
{
title
:
'所属目录'
,
align
:
'center'
,
dataIndex
:
'directoryName'
},
{
title
:
'创建时间'
,
align
:
'center'
,
dataIndex
:
'createTime'
},
{
title
:
'状态'
,
align
:
'center'
,
dataIndex
:
'status'
,
dataIndex
:
's
helfS
tatus'
,
render
:
(
text
:
number
)
=>
(
text
?
'上架'
:
'下架'
),
},
{
title
:
'操作'
,
align
:
'center'
,
dataIndex
:
'id'
,
render
:
(
id
:
number
)
=>
(
render
:
(
id
:
number
,
record
:
goodsType
[
0
]
)
=>
(
<>
<
Button
type=
'link'
onClick=
{
()
=>
toEditGoods
(
id
)
}
>
编辑
...
...
@@ -96,6 +96,15 @@ const GoodsList = () => {
<
Button
type=
'link'
onClick=
{
()
=>
toGoodsDetail
(
id
)
}
>
详情
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
upOrDownShelf
(
1
,
id
)
}
disabled=
{
!!
record
.
shelfStatus
}
>
上架
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
upOrDownShelf
(
0
,
id
)
}
disabled=
{
!
record
.
shelfStatus
}
>
下架
</
Button
>
<
Button
type=
'link'
danger
onClick=
{
()
=>
removeMallGoods
(
id
)
}
>
删除
</
Button
>
</>
),
},
...
...
@@ -113,20 +122,20 @@ const GoodsList = () => {
totalPage
:
1
,
});
//筛选
const
[
query
,
setQuery
]
=
useState
<
goodsSearchParameters
>
({
status
:
undefined
});
const
[
query
,
setQuery
]
=
useState
<
goodsSearchParameters
>
({
s
helfS
tatus
:
undefined
});
// 表格多选
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
<
React
.
Key
[]
>
([]);
const
onTabChange
=
(
key
:
string
)
=>
{
pagination
.
pageNo
=
1
;
pagination
.
pageSize
=
10
;
query
.
status
=
key
===
'1'
?
undefined
:
key
===
'2'
?
1
:
0
;
query
.
s
helfS
tatus
=
key
===
'1'
?
undefined
:
key
===
'2'
?
1
:
0
;
setSearchParams
(
qs
.
stringify
({
pageNo
:
1
,
pageSize
:
10
,
...
query
,
s
tatus
:
query
.
status
===
undefined
?
'all'
:
query
.
s
tatus
,
s
helfStatus
:
query
.
shelfStatus
===
undefined
?
'all'
:
query
.
shelfS
tatus
,
}),
);
getGoodsList
(
query
);
...
...
@@ -142,7 +151,7 @@ const GoodsList = () => {
pageNo
:
pageNo
,
pageSize
:
pageSize
,
...
query
,
s
tatus
:
query
.
status
===
undefined
?
'all'
:
query
.
s
tatus
,
s
helfStatus
:
query
.
shelfStatus
===
undefined
?
'all'
:
query
.
shelfS
tatus
,
}),
);
getGoodsList
(
query
);
...
...
@@ -152,28 +161,24 @@ const GoodsList = () => {
const
searchSuccess
=
(
data
:
any
)
=>
{
pagination
.
pageNo
=
1
;
pagination
.
pageSize
=
10
;
setQuery
({
...
filterObjAttr
(
data
,
[
'time'
]),
status
:
query
.
status
});
getGoodsList
({
...
filterObjAttr
(
data
,
[
'time'
]),
status
:
query
.
status
});
getGoodsList
(
{
...
filterObjAttr
(
data
,
[
'time'
]),
status
:
query
.
status
,
pageSize
:
9999
,
pageNo
:
1
},
true
,
);
setQuery
({
...
data
,
shelfStatus
:
query
.
shelfStatus
});
getGoodsList
({
...
data
,
shelfStatus
:
query
.
shelfStatus
});
getGoodsList
({
...
data
,
shelfStatus
:
query
.
shelfStatus
,
pageSize
:
9999
,
pageNo
:
1
},
true
);
setSearchParams
(
qs
.
stringify
({
pageNo
:
1
,
pageSize
:
10
,
...
filterObjAttr
(
data
,
[
'time'
]),
s
tatus
:
query
.
status
===
undefined
?
'all'
:
query
.
s
tatus
,
s
helfStatus
:
query
.
shelfStatus
===
undefined
?
'all'
:
query
.
shelfS
tatus
,
}),
);
};
//商品列表
const
getGoodsList
=
(
query
?:
goodsSearchParameters
,
isAll
?:
boolean
)
=>
{
setLoading
(
true
);
GoodsAPI
.
get
GoodsList
({
GoodsAPI
.
get
ListPageGoodsInfo
({
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
goodsType
:
0
,
...
query
,
}).
then
(({
result
})
=>
{
setLoading
(
false
);
...
...
@@ -200,50 +205,38 @@ const GoodsList = () => {
};
//商品详情
const
toGoodsDetail
=
(
id
:
number
)
=>
{
navigate
({
pathname
:
'/mallManage/mallGoods/detail'
,
search
:
`id=
${
id
}
&isDetail=1`
,
});
//
navigate({
//
pathname: '/mallManage/mallGoods/detail',
//
search: `id=${id}&isDetail=1`,
//
});
};
// 表格多选事件
const
onSelectChange
=
(
newSelectedRowKeys
:
React
.
Key
[])
=>
{
setSelectedRowKeys
(
newSelectedRowKeys
);
};
//获取目录列表
const
getDirectoryList
=
()
=>
{
CategoryManageAPI
.
getDirectoryListClone
({
type
:
4
}).
then
(({
result
})
=>
{
if
(
result
)
{
const
options
=
result
.
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
v
.
directoryName
}));
searchColumns
[
1
].
options
=
options
;
setSearchColumns
([...
searchColumns
]);
}
});
};
//商品-批量上下架
const
batchOnShelfOrTakeDown
=
(
status
:
number
)
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
return
message
.
warning
(
'请先选择商品'
);
}
GoodsAPI
.
batchOnShelfOrTakeDown
({
goodsIds
:
selectedRowKeys
as
number
[],
status
}).
then
(
({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
status
?
'上架成功'
:
'下架成功'
);
getGoodsList
(
query
);
setSelectedRowKeys
([]);
}
//商品-单个上下架
const
upOrDownShelf
=
(
status
:
number
,
id
:
number
)
=>
{
Modal
.
confirm
({
title
:
'提示'
,
content
:
`确认
${
status
?
'上架'
:
'下架'
}
该商品?`
,
onOk
:
()
=>
{
GoodsAPI
.
upOrDownShelf
({
id
,
status
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
status
?
'上架成功'
:
'下架成功'
);
getGoodsList
(
query
);
setSelectedRowKeys
([]);
}
});
},
);
}
);
};
//商品-删除
const
deleteGoods
=
()
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
return
message
.
warning
(
'请先选择商品'
);
}
const
removeMallGoods
=
(
id
:
number
)
=>
{
Modal
.
confirm
({
title
:
'提示'
,
content
:
'删除后数据将会丢失,确定删除吗?'
,
onOk
()
{
GoodsAPI
.
batchRemoveWareInfo
(
selectedRowKeys
as
number
[]
).
then
(({
code
})
=>
{
GoodsAPI
.
removeMallGoods
({
id
}
).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
if
(
pagination
.
pageNo
!==
1
&&
tableData
.
length
==
1
)
{
pagination
.
pageNo
-=
1
;
...
...
@@ -276,7 +269,7 @@ const GoodsList = () => {
:
tableData
.
filter
((
_v
,
i
)
=>
index
-
1
===
i
||
index
===
i
)
.
map
((
v
)
=>
({
id
:
v
.
id
}));
GoodsAPI
.
exchange
GoodsInfo
({
firstId
:
exReqData
[
0
].
id
,
secondId
:
exReqData
[
1
].
id
}).
then
(
GoodsAPI
.
exchange
({
firstId
:
exReqData
[
0
].
id
,
secondId
:
exReqData
[
1
].
id
}).
then
(
({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'上移成功'
);
...
...
@@ -287,7 +280,7 @@ const GoodsList = () => {
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
...
query
,
s
tatus
:
query
.
status
===
undefined
?
'all'
:
query
.
s
tatus
,
s
helfStatus
:
query
.
shelfStatus
===
undefined
?
'all'
:
query
.
shelfS
tatus
,
}),
);
}
...
...
@@ -319,7 +312,7 @@ const GoodsList = () => {
:
tableData
.
filter
((
_v
,
i
)
=>
index
+
1
===
i
||
index
===
i
)
.
map
((
v
)
=>
({
id
:
v
.
id
}));
GoodsAPI
.
exchange
GoodsInfo
({
firstId
:
exReqData
[
0
].
id
,
secondId
:
exReqData
[
1
].
id
}).
then
(
GoodsAPI
.
exchange
({
firstId
:
exReqData
[
0
].
id
,
secondId
:
exReqData
[
1
].
id
}).
then
(
({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'下移成功'
);
...
...
@@ -330,7 +323,7 @@ const GoodsList = () => {
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
...
query
,
s
tatus
:
query
.
status
===
undefined
?
'all'
:
query
.
s
tatus
,
s
helfStatus
:
query
.
shelfStatus
===
undefined
?
'all'
:
query
.
shelfS
tatus
,
}),
);
}
...
...
@@ -342,41 +335,55 @@ const GoodsList = () => {
}
}
};
//分类列表
const
getCategoryList
=
()
=>
{
CategoryManageAPI
.
getCategoryRespList
({
pageNo
:
1
,
pageSize
:
99999
}).
then
(({
result
})
=>
{
searchColumns
[
1
].
options
=
(
result
.
list
||
[]).
map
((
v
)
=>
({
id
:
v
.
id
,
name
:
v
.
name
}));
setSearchColumns
([...
searchColumns
]);
setCategoryList
(
result
.
list
||
[]);
});
};
//商品列表,分类组合
const
getCategoryStr
=
(
record
:
goodsType
[
0
])
=>
{
return
categoryList
.
reduce
((
pre
:
string
[],
cur
)
=>
{
if
(
cur
.
id
===
record
.
categoryPrimaryId
)
{
pre
.
push
(
cur
.
name
);
if
(
record
.
categorySubId
)
{
pre
.
push
(
cur
.
subDTOList
.
find
((
v
)
=>
v
.
id
===
record
.
categorySubId
)?.
name
||
''
);
}
}
return
pre
;
},
[])
.
join
(
'/'
);
};
useEffect
(()
=>
{
get
Direct
oryList
();
get
Categ
oryList
();
pagination
.
pageNo
=
Number
(
searchParams
.
get
(
'pageNo'
)
||
1
);
pagination
.
pageSize
=
Number
(
searchParams
.
get
(
'pageSize'
)
||
10
);
const
queryObj
=
{
goodsName
:
searchParams
.
get
(
'goodsName'
)
||
undefined
,
directoryId
:
searchParams
.
get
(
'directoryId'
)
?
Number
(
searchParams
.
get
(
'directoryId'
))
:
undefined
,
startTime
:
searchParams
.
get
(
'startTime'
)
||
undefined
,
endTime
:
searchParams
.
get
(
'endTime'
)
||
undefined
,
status
:
searchParams
.
get
(
'status'
)
===
'all'
||
searchParams
.
get
(
'status'
)
===
null
tradeName
:
searchParams
.
get
(
'goodsName'
)
||
undefined
,
shelfStatus
:
searchParams
.
get
(
'shelfStatus'
)
===
'all'
||
searchParams
.
get
(
'shelfStatus'
)
===
null
?
undefined
:
Number
(
searchParams
.
get
(
'status'
)),
:
Number
(
searchParams
.
get
(
's
helfS
tatus'
)),
};
getGoodsList
(
queryObj
);
getGoodsList
({
...
queryObj
,
pageNo
:
1
,
pageSize
:
9999
},
true
);
setActiveTabKey
(
searchParams
.
get
(
's
tatus'
)
===
'all'
||
searchParams
.
get
(
's
tatus'
)
===
null
searchParams
.
get
(
's
helfStatus'
)
===
'all'
||
searchParams
.
get
(
'shelfS
tatus'
)
===
null
?
'1'
:
Number
(
searchParams
.
get
(
'status'
))
===
1
:
Number
(
searchParams
.
get
(
's
helfS
tatus'
))
===
1
?
'2'
:
'3'
,
);
(
searchRef
.
current
as
any
).
getForm
().
setFieldsValue
({
goodsName
:
searchParams
.
get
(
'goodsName'
)
||
undefined
,
directoryId
:
searchParams
.
get
(
'directoryId'
)
?
Number
(
searchParams
.
get
(
'directoryId'
))
:
undefined
,
time
:
searchParams
.
get
(
'startTime'
)
?
[
searchParams
.
get
(
'startTime'
),
searchParams
.
get
(
'endTime'
)]
:
undefined
,
tradeName
:
searchParams
.
get
(
'goodsName'
)
||
undefined
,
});
},
[]);
return
(
<
div
className=
'goods-list'
>
<
SearchBox
...
...
@@ -407,30 +414,6 @@ const GoodsList = () => {
>
下移
</
Button
>
{
activeTabKey
!==
'2'
&&
(
<
Button
type=
'primary'
style=
{
{
marginRight
:
'10px'
}
}
icon=
{
<
ArrowUpOutlined
/>
}
onClick=
{
()
=>
batchOnShelfOrTakeDown
(
1
)
}
>
上架
</
Button
>
)
}
{
activeTabKey
!==
'3'
&&
(
<
Button
type=
'primary'
style=
{
{
marginRight
:
'10px'
}
}
icon=
{
<
ArrowDownOutlined
/>
}
onClick=
{
()
=>
batchOnShelfOrTakeDown
(
0
)
}
>
下架
</
Button
>
)
}
<
Button
danger
icon=
{
<
DeleteOutlined
/>
}
onClick=
{
deleteGoods
}
>
删除
</
Button
>
</
div
>
<
Table
columns=
{
tableColumns
}
...
...
@@ -440,6 +423,8 @@ const GoodsList = () => {
rowSelection=
{
{
selectedRowKeys
,
onChange
:
onSelectChange
,
type
:
'radio'
,
hideSelectAll
:
true
,
}
}
loading=
{
loading
}
pagination=
{
{
...
...
src/utils/validateUtils.ts
浏览文件 @
26a95c46
import
_
from
'lodash'
;
// 不能输入数字,其他可以输入
export
const
exceptNumber
=
(
val
:
any
)
=>
{
val
.
target
.
value
=
val
.
target
.
value
.
replace
(
/1
?(\d
|
([
1-9
]\d
+
))(
.
\d
+
)?
$/g
,
''
).
replace
(
/
\s
/g
,
''
);
...
...
@@ -105,3 +107,13 @@ export const maxLength6 = (val: any) => {
val
.
target
.
value
=
val
.
target
.
value
.
replace
(
/
\D
/g
,
''
);
}
};
//通用价格,且保留两位小数正则
export
const
regPriceNumber
=
(
value
:
string
):
boolean
=>
{
const
reg
=
/^
\d
+
(\.\d{1,2})?
$/
;
return
reg
.
test
(
value
);
};
//判断空值
export
const
isEmptyBol
=
(
value
:
any
):
boolean
=>
{
return
_
.
isNull
(
value
)
||
_
.
isNaN
(
value
)
||
_
.
isNull
(
value
)
||
_
.
isUndefined
(
value
);
};
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论