Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
iuav
admin
Commits
196886f0
提交
196886f0
authored
8月 16, 2023
作者:
龚洪江
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
功能:租赁联调(100%)
上级
b26c4e6b
隐藏空白字符变更
内嵌
并排
正在显示
25 个修改的文件
包含
2054 行增加
和
139 行删除
+2054
-139
commonType.ts
src/api/interface/commonType.ts
+0
-1
goodsType.ts
src/api/interface/goodsType.ts
+0
-2
rentManageType.ts
src/api/interface/rentManageType.ts
+112
-9
systemManageType.ts
src/api/interface/systemManageType.ts
+41
-0
goodsAPI.ts
src/api/modules/goodsAPI.ts
+0
-5
rentManageAPI.ts
src/api/modules/rentManageAPI.ts
+25
-0
systemManage.ts
src/api/modules/systemManage.ts
+15
-0
index.tsx
src/components/EditableCell/index.tsx
+4
-2
index.scss
...ntGoods/rentAddOrEdit/components/accessoryList/index.scss
+7
-0
index.tsx
...entGoods/rentAddOrEdit/components/accessoryList/index.tsx
+199
-0
index.tsx
.../rentGoods/rentAddOrEdit/components/addressInfo/index.tsx
+175
-23
index.scss
...ntGoods/rentAddOrEdit/components/footerOperate/index.scss
+19
-0
index.tsx
...entGoods/rentAddOrEdit/components/footerOperate/index.tsx
+27
-0
index.tsx
...ge/rentGoods/rentAddOrEdit/components/goodsInfo/index.tsx
+40
-3
index.scss
...ge/rentGoods/rentAddOrEdit/components/rentAttr/index.scss
+10
-0
index.tsx
...age/rentGoods/rentAddOrEdit/components/rentAttr/index.tsx
+161
-31
index.tsx
...nage/rentGoods/rentAddOrEdit/components/skuInfo/index.tsx
+310
-9
index.scss
src/pages/rentManage/rentGoods/rentAddOrEdit/index.scss
+2
-13
index.tsx
src/pages/rentManage/rentGoods/rentAddOrEdit/index.tsx
+86
-4
index.tsx
src/pages/rentManage/rentGoods/rentDetail/index.tsx
+286
-0
index.scss
src/pages/rentManage/rentGoods/rentList/index.scss
+10
-0
index.tsx
src/pages/rentManage/rentGoods/rentList/index.tsx
+236
-24
index.tsx
.../addressManage/components/addOrEditAddressModal/index.tsx
+137
-0
index.tsx
src/pages/systemManage/addressManage/index.tsx
+125
-0
router.tsx
src/router/router.tsx
+27
-13
没有找到文件。
src/api/interface/commonType.ts
浏览文件 @
196886f0
...
...
@@ -177,5 +177,4 @@ type locationType = {
level
:
number
;
childInfo
:
locationType
[];
};
export
type
getSecondDistrictInfoType
=
InterFunction
<
any
,
locationType
[]
>
;
src/api/interface/goodsType.ts
浏览文件 @
196886f0
...
...
@@ -93,8 +93,6 @@ export type detailGoodsType = InterFunction<
id
:
number
;
}
>
;
//商品-其它服务列表
export
type
otherServiceType
=
InterFunction
<
any
,
{
id
:
number
;
saleServiceName
:
string
}[]
>
;
//商品-规格单位
export
type
skuUnitType
=
InterFunction
<
any
,
{
id
:
number
;
unitName
:
string
}[]
>
;
//商品-批量上下架
...
...
src/api/interface/rentManageType.ts
浏览文件 @
196886f0
...
...
@@ -48,22 +48,22 @@ export type addRentGoodsType = InterFunction<
deviceModeId
:
number
;
leasePartsList
:
{
name
:
string
;
number
:
number
;
price
:
number
}[];
level
:
number
;
logisticsCompany
:
number
;
logisticsCompany
:
string
;
maxLeaseTerm
:
number
;
minLeaseTerm
:
number
;
modeOfDelivery
:
number
;
priceStock
:
{
cashPledge
:
number
;
maxDaysRental
:
number
;
ninetyDaysRental
:
number
;
maxDaysRental
?
:
number
;
ninetyDaysRental
?
:
number
;
productSpec
:
string
;
sevenDaysRental
:
number
;
showPrice
:
number
;
skuImage
:
string
;
stock
:
number
;
sevenDaysRental
?
:
number
;
showPrice
?
:
number
;
skuImage
?
:
string
;
stock
?
:
number
;
stockOut
:
number
;
thirtyDaysRental
:
number
;
threeDaysRental
:
number
;
thirtyDaysRental
?
:
number
;
threeDaysRental
?
:
number
;
}[];
productDetails
:
string
;
productParam
:
string
;
...
...
@@ -78,5 +78,108 @@ export type addRentGoodsType = InterFunction<
},
any
>
;
//租赁商品-列表
type
rentGoodsType
=
{
brandInfoId
:
number
;
deviceModeId
:
number
;
leasePartsList
:
{
id
:
number
;
name
:
string
;
number
:
number
;
price
:
number
}[];
level
:
number
;
logisticsCompany
:
string
;
maxLeaseTerm
:
number
;
minLeaseTerm
:
number
;
modeOfDelivery
:
number
;
priceStock
:
{
cashPledge
:
number
;
maxDaysRental
?:
number
;
ninetyDaysRental
?:
number
;
productSpec
:
string
;
sevenDaysRental
?:
number
;
showPrice
?:
number
;
skuImage
?:
string
;
stock
?:
number
;
stockOut
:
number
;
thirtyDaysRental
?:
number
;
threeDaysRental
?:
number
;
id
:
number
;
}[];
productDetails
:
string
;
productParam
:
string
;
productTypeId
:
number
;
resourcesList
:
{
id
:
number
;
type
:
number
;
url
:
string
}[];
returnAddress
:
number
;
sellingPoint
:
string
;
shelfStatus
:
number
;
shipAddress
:
number
;
tradeName
:
string
;
specAttrList
:
{
id
:
number
;
specName
:
string
;
specValuesList
:
{
specName
:
string
;
id
:
number
}[];
}[];
id
:
number
;
createTime
:
string
;
};
export
type
leaseGoodsListType
=
InterItemFunction
<
{
brandInfoId
?:
number
;
districtCode
?:
number
;
productTypeId
?:
number
;
shelfStatus
?:
number
;
tradeName
?:
string
;
},
rentGoodsType
[]
>
;
//租赁-商品-编辑
export
type
editLeaseGoodsType
=
InterFunction
<
{
brandInfoId
:
number
;
deviceModeId
:
number
;
leasePartsList
:
{
id
?:
number
;
name
:
string
;
number
:
number
;
price
:
number
}[];
level
:
number
;
logisticsCompany
:
string
;
maxLeaseTerm
:
number
;
minLeaseTerm
:
number
;
modeOfDelivery
:
number
;
priceStock
:
{
cashPledge
:
number
;
maxDaysRental
?:
number
;
ninetyDaysRental
?:
number
;
productSpec
:
string
;
sevenDaysRental
?:
number
;
showPrice
?:
number
;
skuImage
?:
string
;
stock
?:
number
;
stockOut
:
number
;
thirtyDaysRental
?:
number
;
threeDaysRental
?:
number
;
id
?:
number
;
}[];
productDetails
:
string
;
productParam
:
string
;
productTypeId
:
number
;
resourcesList
:
{
type
:
number
;
url
:
string
}[];
returnAddress
:
number
;
sellingPoint
:
string
;
shelfStatus
:
number
;
shipAddress
:
number
;
tradeName
:
string
;
specAttrList
:
{
id
:
number
;
specName
:
string
;
specValuesList
:
{
id
:
number
;
specName
:
string
}[];
}[];
id
:
number
;
},
any
>
;
//租赁-商品-详情
export
type
leaseGoodsDetailsType
=
InterFunction
<
{
id
:
number
},
rentGoodsType
>
;
//租赁-商品-租期信息
export
type
leaseTermInfoType
=
InterFunction
<
any
,
{
id
:
number
;
leaseDate
:
string
}[]
>
;
//租赁-商品-物流-配送方式
export
type
otherServiceType
=
InterFunction
<
any
,
{
id
:
number
;
saleServiceName
:
string
}[]
>
;
//租赁-商品-上下架-批量
export
type
batchOnShelfOrTakeDownType
=
InterFunction
<
{
goodsIds
:
number
[];
status
:
number
},
any
>
;
//租赁-商品-删除-批量
export
type
batchRemoveWareInfoType
=
InterFunction
<
number
[],
any
>
;
src/api/interface/systemManageType.ts
浏览文件 @
196886f0
...
...
@@ -299,3 +299,44 @@ export type listMenuInfoType = InterFunction<any, menType>;
export
type
listRoleMenuInfoType
=
InterFunction
<
{
roleId
:
number
},
any
>
;
//账号权限-修改角色菜单权限
export
type
updateRoleMenuInfoType
=
InterFunction
<
{
menuInfoIds
:
number
[];
roleId
:
number
},
any
>
;
//地址管理-列表
export
type
addressListType
=
InterFunction
<
any
,
{
takeAddress
:
string
;
takeName
:
string
;
takePhone
:
string
;
takeRegion
:
string
;
type
:
number
;
id
:
number
;
districtCode
:
string
;
}[]
>
;
//地址管理-添加地址
export
type
addressInsetType
=
InterFunction
<
{
takeAddress
:
string
;
takeName
:
string
;
takePhone
:
string
;
takeRegion
:
string
;
type
:
number
;
districtCode
:
string
;
},
any
>
;
//地址管理-编辑地址
export
type
editAddressType
=
InterFunction
<
{
id
?:
number
;
takeAddress
:
string
;
takeName
:
string
;
takePhone
:
string
;
takeRegion
:
string
;
type
:
number
;
districtCode
:
string
;
},
any
>
;
//地址管理-删除地址
export
type
deleteAddressType
=
InterFunction
<
{
id
:
number
},
any
>
;
src/api/modules/goodsAPI.ts
浏览文件 @
196886f0
...
...
@@ -10,7 +10,6 @@ import {
listGoodsType
,
listPageGoodsInfoType
,
mallGoodsDetailsType
,
otherServiceType
,
removeMallGoodsType
,
skuUnitType
,
upOrDownShelfType
,
...
...
@@ -38,10 +37,6 @@ class GoodsAPI {
static
getSkuUnit
:
skuUnitType
=
()
=>
{
return
axios
.
get
(
'/pms/mall/goods/getSkuUnit'
);
};
// 商品-其它服务列表
static
getOtherServiceList
:
otherServiceType
=
()
=>
{
return
axios
.
get
(
'/pms/goods/listOtherService'
);
};
// 商品-批量上下架
static
batchOnShelfOrTakeDown
:
batchOnShelfOrTakeDownType
=
(
data
)
=>
{
return
axios
.
post
(
'/pms/goods/batchOnShelfOrTakeDown'
,
data
);
...
...
src/api/modules/rentManageAPI.ts
浏览文件 @
196886f0
...
...
@@ -2,16 +2,22 @@ import {
addRentGoodsType
,
addRentModeType
,
addType
,
batchRemoveWareInfoType
,
editBrandInfoType
,
editLeaseGoodsType
,
getTypeListType
,
leaseGoodsDetailsType
,
leaseGoodsListType
,
leaseTermInfoType
,
listBrandInfoType
,
otherServiceType
,
rentMakeAddType
,
rentModeListType
,
rentTypeEditType
,
rentTypeRemoveType
,
}
from
'~/api/interface/rentManageType'
;
import
axios
from
'../request'
;
import
{
batchOnShelfOrTakeDownType
}
from
'~/api/interface/goodsType'
;
export
class
RentManageAPI
{
//租赁-类型-新增
...
...
@@ -43,7 +49,26 @@ export class RentManageAPI {
// 租赁-商品-新增
static
addRentGoods
:
addRentGoodsType
=
(
data
)
=>
axios
.
post
(
'/pms/lease/goods/addLeaseGoods'
,
data
);
//租赁-商品-列表
static
getLeaseGoodsList
:
leaseGoodsListType
=
(
data
)
=>
axios
.
post
(
'/pms/lease/goods/leaseGoodsList'
,
data
);
//租赁-商品-编辑
static
editLeaseGoods
:
editLeaseGoodsType
=
(
data
)
=>
axios
.
post
(
'/pms/lease/goods/editLeaseGoods'
,
data
);
//租赁-商品-详情
static
getLeaseGoodsDetails
:
leaseGoodsDetailsType
=
(
params
)
=>
axios
.
get
(
'/pms/lease/goods/leaseGoodsDetails'
,
{
params
});
// 租赁-商品-租期信息
static
getLeaseTermInfo
:
leaseTermInfoType
=
()
=>
axios
.
post
(
'/pms/lease/goods/getLeaseTermInfo'
);
//租赁-商品-上下架-批量
static
batchOnShelfOrTakeDown
:
batchOnShelfOrTakeDownType
=
(
data
)
=>
axios
.
post
(
'/pms/lease/goods/batchOnShelfOrTakeDown'
,
data
);
////租赁-商品-删除-批量
static
batchRemoveWareInfo
:
batchRemoveWareInfoType
=
(
data
)
=>
axios
.
post
(
'/pms/lease/goods/batchRemoveWareInfo'
,
data
);
// 商品-其它服务列表
static
getOtherServiceList
:
otherServiceType
=
()
=>
{
return
axios
.
get
(
'/pms/goods/listOtherService'
);
};
}
src/api/modules/systemManage.ts
浏览文件 @
196886f0
import
{
addressInsetType
,
addressListType
,
bindingCompanyMemberType
,
deleteAddressType
,
deleteRoleInfoType
,
editAddressType
,
getCompanyInfoByIdType
,
getSecondDistrictInfo
,
insertBAccountType
,
...
...
@@ -104,4 +108,15 @@ export class SystemManageAPI {
//账号权限-修改角色菜单权限
static
updateRoleMenuInfo
:
updateRoleMenuInfoType
=
(
data
)
=>
axios
.
post
(
'/userapp/role/updateRoleMenuInfo'
,
data
);
// 地址管理-新增
static
addressInset
:
addressInsetType
=
(
data
)
=>
axios
.
post
(
'/oms/user-address/insert'
,
data
);
// 地址管理-列表
static
getAddressList
:
addressListType
=
(
data
)
=>
axios
.
post
(
'/oms/user-address/selectList'
,
data
);
// 地址管理-编辑
static
editAddress
:
editAddressType
=
(
data
)
=>
axios
.
post
(
'/oms/user-address/update'
,
data
);
// 地址管理-删除
static
deleteAddress
:
deleteAddressType
=
(
params
)
=>
axios
.
get
(
'/oms/user-address/deleteById'
,
{
params
});
}
src/components/EditableCell/index.tsx
浏览文件 @
196886f0
import
{
Form
,
InputNumber
,
Input
,
Select
,
Radio
}
from
'antd'
;
import
{
Form
,
InputNumber
,
Input
,
Select
,
Radio
,
Switch
}
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'
|
'radio'
|
'textArea'
;
inputType
:
'number'
|
'text'
|
'select'
|
'uploader'
|
'radio'
|
'textArea'
|
'switch'
;
record
:
any
;
index
:
number
;
children
:
React
.
ReactNode
;
...
...
@@ -82,6 +82,8 @@ const EditableCell: React.FC<
showCount
/>
);
case
'switch'
:
return
<
Switch
/>;
default
:
return
<
Input
placeholder=
{
`请输入${placeholder || title}`
}
maxLength=
{
maxLength
}
/>;
}
...
...
src/pages/rentManage/rentGoods/rentAddOrEdit/components/accessoryList/index.scss
0 → 100644
浏览文件 @
196886f0
.accessory-list
{
&
-title
{
font-size
:
15px
;
font-weight
:
bold
;
line-height
:
40px
;
}
}
src/pages/rentManage/rentGoods/rentAddOrEdit/components/accessoryList/index.tsx
0 → 100644
浏览文件 @
196886f0
import
'./index.scss'
;
import
{
Button
,
Col
,
Form
,
Row
,
Table
}
from
'antd'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addRentGoodsType
,
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
{
MinusOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
//租赁-清单类型
type
leasePartsListType
=
Exclude
<
InterReqType
<
addRentGoodsType
>
,
undefined
>
[
'leasePartsList'
][
0
]
&
{
id
?:
number
};
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
interface
selfProps
{
ref
:
any
;
rentGoodsDetails
:
rentGoodsDetailType
|
undefined
;
}
const
AccessoryList
=
forwardRef
<
any
,
selfProps
>
(({
rentGoodsDetails
},
ref
)
=>
{
const
[
accessoryTableForm
]
=
Form
.
useForm
<
{
[
x
:
string
]:
string
|
number
}
>
();
const
accessoryTableDefaultColumns
:
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
inputType
?:
string
;
rules
?:
any
;
maxLength
?:
number
;
})[]
=
[
{
title
:
'序号'
,
align
:
'center'
,
render
:
(
_
:
any
,
_record
:
any
,
index
:
number
)
=>
index
+
1
,
},
{
title
:
'名称'
,
editable
:
true
,
dataIndex
:
'name'
,
align
:
'center'
,
},
{
title
:
'数量'
,
editable
:
true
,
dataIndex
:
'number'
,
align
:
'center'
,
inputType
:
'number'
,
},
{
title
:
'参考价格'
,
editable
:
true
,
dataIndex
:
'price'
,
align
:
'center'
,
inputType
:
'number'
,
},
{
title
:
'操作'
,
align
:
'center'
,
render
:
(
_
:
any
,
_record
:
any
,
index
:
number
)
=>
(
<>
{
index
===
accessoryTableData
.
length
-
1
?
(
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
style=
{
{
marginRight
:
'5px'
}
}
onClick=
{
addAccessoryTableClick
}
></
Button
>
)
:
(
''
)
}
{
index
?
(
<
Button
type=
'primary'
icon=
{
<
MinusOutlined
/>
}
onClick=
{
()
=>
deleteAccessoryTableClick
(
index
)
}
></
Button
>
)
:
(
''
)
}
</>
),
},
];
const
accessoryTableColumns
=
accessoryTableDefaultColumns
.
map
((
col
)
=>
{
if
(
!
col
.
editable
)
{
return
col
;
}
return
{
...
col
,
onCell
:
(
record
:
any
)
=>
({
record
,
dataIndex
:
col
.
dataIndex
,
title
:
col
.
title
,
editing
:
col
.
editable
,
inputType
:
col
.
inputType
,
rules
:
col
.
rules
,
}),
};
});
const
[
accessoryTableData
,
setAccessoryTableData
]
=
useState
<
leasePartsListType
[]
>
([
{
id
:
Math
.
random
(),
name
:
''
,
number
:
0
,
price
:
0
},
]);
useImperativeHandle
(
ref
,
()
=>
({
accessoryTableFormSubmit
,
}));
//新加一行
const
addAccessoryTableClick
=
()
=>
{
setAccessoryTableData
([
...
accessoryTableData
,
{
id
:
Math
.
random
(),
name
:
''
,
number
:
0
,
price
:
0
},
]);
};
//删除一行
const
deleteAccessoryTableClick
=
(
index
:
number
)
=>
{
accessoryTableData
.
splice
(
index
,
1
);
setAccessoryTableData
([...
accessoryTableData
]);
};
//配件清单表单提交
const
accessoryTableFormSubmit
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
accessoryTableForm
.
validateFields
()
.
then
((
value
:
any
)
=>
{
resolve
(
accessoryTableData
.
reduce
((
pre
:
leasePartsListType
[],
cur
)
=>
{
if
(
value
[
'name'
+
cur
.
id
]
||
value
[
'price'
+
cur
.
id
]
||
value
[
'number'
+
cur
.
id
])
{
pre
.
push
({
name
:
value
[
'name'
+
cur
.
id
],
price
:
value
[
'price'
+
cur
.
id
],
number
:
value
[
'number'
+
cur
.
id
],
id
:
rentGoodsDetails
?
rentGoodsDetails
.
leasePartsList
.
some
((
v
)
=>
v
.
id
===
cur
.
id
)
?
cur
.
id
:
undefined
:
undefined
,
});
}
return
pre
;
},
[]),
);
})
.
catch
((
err
)
=>
{
reject
(
err
);
});
});
};
useEffect
(()
=>
{
if
(
rentGoodsDetails
)
{
if
(
rentGoodsDetails
.
leasePartsList
)
{
setAccessoryTableData
(
rentGoodsDetails
.
leasePartsList
);
const
defaultFormValue
:
{
[
x
:
string
]:
string
|
undefined
|
number
}
=
rentGoodsDetails
.
leasePartsList
.
reduce
(
(
pre
:
{
[
x
:
string
]:
string
|
undefined
|
number
},
cur
)
=>
{
pre
[
'name'
+
cur
.
id
]
=
cur
.
name
||
undefined
;
pre
[
'number'
+
cur
.
id
]
=
cur
.
number
||
undefined
;
pre
[
'price'
+
cur
.
id
]
=
cur
.
price
||
undefined
;
return
pre
;
},
{},
);
accessoryTableForm
.
setFieldsValue
(
defaultFormValue
);
}
}
},
[
rentGoodsDetails
]);
return
(
<
div
className=
'accessory-list'
>
<
div
className=
'accessory-list-title'
>
配件清单
</
div
>
<
Row
>
<
Col
span=
{
2
}
></
Col
>
<
Col
span=
{
11
}
>
<
Form
form=
{
accessoryTableForm
}
>
<
Table
columns=
{
accessoryTableColumns
as
ColumnTypes
}
bordered
dataSource=
{
accessoryTableData
}
rowKey=
'id'
pagination=
{
false
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
/>
</
Form
>
</
Col
>
</
Row
>
</
div
>
);
});
export
default
AccessoryList
;
src/pages/rentManage/rentGoods/rentAddOrEdit/components/addressInfo/index.tsx
浏览文件 @
196886f0
import
'./index.scss'
;
import
{
Form
,
Radio
,
Select
}
from
'antd'
;
import
{
Button
,
Col
,
Form
,
Radio
,
Row
,
Select
}
from
'antd'
;
import
{
OrderManageAPI
,
RentManageAPI
,
SystemManageAPI
}
from
'~/api'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
AddOrEditAddressModal
from
'~/pages/systemManage/addressManage/components/addOrEditAddressModal'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
const
AddressInfo
=
()
=>
{
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
interface
selfProps
{
ref
:
any
;
rentGoodsDetails
:
rentGoodsDetailType
|
undefined
;
}
const
AddressInfo
=
forwardRef
<
any
,
selfProps
>
(({
rentGoodsDetails
},
ref
)
=>
{
const
[
addressInfoForm
]
=
Form
.
useForm
<
{
shipAddress
:
number
;
returnAddress
:
number
;
logisticsCompany
:
string
;
modeOfDelivery
:
number
;
}
>
();
const
[
addOrEditAddressModalShow
,
setAddOrEditAddressModalShow
]
=
useState
<
boolean
>
(
false
);
const
[
addressOptionList
,
setAddressOptionList
]
=
useState
<
{
label
:
string
;
value
:
number
;
districtCode
:
string
}[]
>
([]);
const
[
expressOptionList
,
setExpressOptionList
]
=
useState
<
{
label
:
string
;
value
:
string
}[]
>
(
[],
);
//配送方式
const
[
shippingMethodList
,
setShippingMethodList
]
=
useState
<
{
id
:
number
;
saleServiceName
:
string
}[]
>
([]);
useImperativeHandle
(
ref
,
()
=>
({
addressInfoFormSubmit
,
}));
//地址列表
const
getAddressList
=
()
=>
{
SystemManageAPI
.
getAddressList
({}).
then
(({
result
})
=>
{
if
(
result
)
{
const
optionList
=
result
.
map
((
v
)
=>
({
label
:
v
.
takeName
+
v
.
takePhone
+
`(
${
v
.
takeRegion
.
split
(
'/'
).
join
(
''
)
+
v
.
takeAddress
}
)`
,
value
:
v
.
id
,
districtCode
:
v
.
districtCode
,
}));
const
addressItemObj
=
result
.
find
((
v
)
=>
v
.
type
===
1
);
if
(
addressItemObj
)
{
addressInfoForm
.
setFieldsValue
({
returnAddress
:
addressItemObj
.
id
,
shipAddress
:
addressItemObj
.
id
,
});
}
setAddressOptionList
(
optionList
);
}
});
};
//物流公司列表
const
getListExpressInfo
=
()
=>
{
OrderManageAPI
.
listExpressInfo
().
then
(({
result
})
=>
{
if
(
result
)
{
const
optionList
=
result
.
map
((
v
)
=>
({
label
:
v
.
exName
,
value
:
v
.
exCode
,
}));
setExpressOptionList
(
optionList
);
}
});
};
//物流-配送方式
const
getOtherService
=
()
=>
{
RentManageAPI
.
getOtherServiceList
().
then
(({
result
})
=>
{
setShippingMethodList
(
result
||
[]);
});
};
//物流表单提交
const
addressInfoFormSubmit
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
addressInfoForm
.
validateFields
()
.
then
((
values
)
=>
{
resolve
({
...
values
,
districtCode
:
addressOptionList
.
find
((
v
)
=>
v
.
value
===
values
.
shipAddress
)
?.
districtCode
,
});
})
.
then
((
err
)
=>
{
reject
(
err
);
});
});
};
//新增地址弹窗
const
addAddressClick
=
()
=>
[
setAddOrEditAddressModalShow
(
true
)];
const
addOrEditAddressModalOk
=
()
=>
{
getAddressList
();
setAddOrEditAddressModalShow
(
false
);
};
const
addOrEditAddressModalCancel
=
()
=>
{
setAddOrEditAddressModalShow
(
false
);
};
useEffect
(()
=>
{
getAddressList
();
getListExpressInfo
();
getOtherService
();
},
[]);
useEffect
(()
=>
{
if
(
rentGoodsDetails
)
{
addressInfoForm
.
setFieldsValue
({
shipAddress
:
rentGoodsDetails
.
shipAddress
,
returnAddress
:
rentGoodsDetails
.
returnAddress
,
logisticsCompany
:
rentGoodsDetails
.
logisticsCompany
,
modeOfDelivery
:
rentGoodsDetails
.
modeOfDelivery
,
});
}
},
[
rentGoodsDetails
]);
return
(
<
div
className=
'address-info'
>
<
div
className=
'address-info-title'
>
物流信息
</
div
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
10
}
}
>
<
Form
.
Item
label=
'发货地址'
>
<
Select
placeholder=
'请选择发货地址'
>
<
Select
.
Option
>
1
</
Select
.
Option
>
</
Select
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
10
}
}
form=
{
addressInfoForm
}
>
<
Form
.
Item
label=
'发货地址'
name=
'shipAddress'
rules=
{
[{
required
:
true
,
message
:
'请选择发货地址'
}]
}
>
<
Select
placeholder=
'请选择发货地址'
options=
{
addressOptionList
}
></
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
'归还地址'
>
<
Select
placeholder=
'请选择归还地址'
>
<
Select
.
Option
>
1
</
Select
.
Option
>
</
Select
>
<
Form
.
Item
>
<
Row
>
<
Col
span=
{
5
}
></
Col
>
<
Col
>
<
Button
type=
'link'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
addAddressClick
}
>
新增地址
</
Button
>
</
Col
>
</
Row
>
</
Form
.
Item
>
<
Form
.
Item
label=
'归还地址'
name=
'returnAddress'
rules=
{
[{
required
:
true
,
message
:
'请选择归还地址'
}]
}
>
<
Select
placeholder=
'请选择归还地址'
options=
{
addressOptionList
}
></
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
'寄出物流'
>
<
Select
placeholder=
'请选择寄出物流'
>
<
Select
.
Option
>
1
</
Select
.
Option
>
</
Select
>
<
Form
.
Item
>
<
Row
>
<
Col
span=
{
5
}
></
Col
>
<
Col
>
<
Button
type=
'link'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
addAddressClick
}
>
新增地址
</
Button
>
</
Col
>
</
Row
>
</
Form
.
Item
>
<
Form
.
Item
label=
'寄出物流'
>
<
Select
placeholder=
'请选择寄出物流'
>
<
Select
.
Option
>
1
</
Select
.
Option
>
</
Select
>
<
Form
.
Item
label=
'寄出物流'
name=
'logisticsCompany'
rules=
{
[{
required
:
true
,
message
:
'请选择寄出物流'
}]
}
>
<
Select
placeholder=
'请选择寄出物流'
options=
{
expressOptionList
}
></
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
'配送方式(寄出)'
>
<
Form
.
Item
label=
'配送方式(寄出)'
name=
'modeOfDelivery'
rules=
{
[{
required
:
true
,
message
:
'请选择配送方式(寄出)'
}]
}
>
<
Radio
.
Group
>
<
Radio
>
包邮
</
Radio
>
<
Radio
>
到付(租户支付)
</
Radio
>
{
shippingMethodList
.
map
((
v
)
=>
(
<
Radio
value=
{
v
.
id
}
key=
{
v
.
id
}
>
{
v
.
saleServiceName
}
</
Radio
>
))
}
</
Radio
.
Group
>
</
Form
.
Item
>
</
Form
>
<
AddOrEditAddressModal
open=
{
addOrEditAddressModalShow
}
onOk=
{
addOrEditAddressModalOk
}
onCancel=
{
addOrEditAddressModalCancel
}
/>
</
div
>
);
};
}
)
;
export
default
AddressInfo
;
src/pages/rentManage/rentGoods/rentAddOrEdit/components/footerOperate/index.scss
0 → 100644
浏览文件 @
196886f0
.rent-footer-operate
{
background
:
#fff
;
height
:
70px
;
position
:
fixed
;
bottom
:
10px
;
left
:
180px
;
right
:
10px
;
box-shadow
:
0
-5px
1px
-5px
rgba
(
0
,
0
,
0
,
0
.5
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
button
{
height
:
40px
;
width
:
80px
;
&
:first-child
{
margin-right
:
50px
;
}
}
}
src/pages/rentManage/rentGoods/rentAddOrEdit/components/footerOperate/index.tsx
0 → 100644
浏览文件 @
196886f0
import
'./index.scss'
;
import
{
Button
}
from
'antd'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
{
FC
}
from
'react'
;
interface
selfProps
{
saveRentGoods
:
()
=>
void
;
}
const
FooterOperate
:
FC
<
selfProps
>
=
({
saveRentGoods
})
=>
{
const
navigate
=
useNavigate
();
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
return
(
<
div
className=
'rent-footer-operate'
>
<
Button
onClick=
{
backRoute
}
>
返回
</
Button
>
<
Button
type=
'primary'
onClick=
{
saveRentGoods
}
>
保存
</
Button
>
</
div
>
);
};
export
default
FooterOperate
;
src/pages/rentManage/rentGoods/rentAddOrEdit/components/goodsInfo/index.tsx
浏览文件 @
196886f0
import
{
Form
,
Input
,
Radio
}
from
'antd'
;
import
'./index.scss'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
}
from
'react'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
type
goodsInfoForm
=
{
tradeName
:
string
;
sellingPoint
:
string
;
level
:
number
;
shelfStatus
:
number
;
};
interface
selfProps
{
ref
:
any
;
rentGoodsDetails
:
rentGoodsDetailType
|
undefined
;
}
const
GoodsInfo
=
(
)
=>
{
const
GoodsInfo
=
forwardRef
<
any
,
selfProps
>
(({
rentGoodsDetails
},
ref
)
=>
{
const
qualityList
=
[
{
label
:
'全新'
,
...
...
@@ -33,13 +42,41 @@ const GoodsInfo = () => {
];
const
[
form
]
=
Form
.
useForm
<
goodsInfoForm
>
();
useImperativeHandle
(
ref
,
()
=>
({
submitGoodsInfoForm
,
}));
const
submitGoodsInfoForm
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
form
.
validateFields
()
.
then
((
value
)
=>
{
resolve
(
value
);
})
.
catch
((
error
)
=>
{
reject
(
error
);
});
});
};
useEffect
(()
=>
{
if
(
rentGoodsDetails
)
{
form
.
setFieldsValue
({
tradeName
:
rentGoodsDetails
.
tradeName
,
sellingPoint
:
rentGoodsDetails
.
sellingPoint
,
level
:
rentGoodsDetails
.
level
,
shelfStatus
:
rentGoodsDetails
.
shelfStatus
,
});
}
},
[
rentGoodsDetails
]);
return
(
<
div
className=
'goods-info'
>
<
div
className=
'goods-info-title'
>
商品信息
</
div
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
10
}
}
initialValues=
{
{
level
:
0
}
}
initialValues=
{
{
level
:
0
,
shelfStatus
:
1
}
}
form=
{
form
}
>
<
Form
.
Item
...
...
@@ -74,5 +111,5 @@ const GoodsInfo = () => {
</
Form
>
</
div
>
);
};
}
)
;
export
default
GoodsInfo
;
src/pages/rentManage/rentGoods/rentAddOrEdit/components/rentAttr/index.scss
浏览文件 @
196886f0
...
...
@@ -4,4 +4,14 @@
font-weight
:
bold
;
line-height
:
40px
;
}
.rent-goods-video-wrap
{
position
:
relative
;
width
:
200px
;
img
{
position
:
absolute
;
right
:
0
;
top
:
0
;
transform
:
translate
(
50%
,-
25%
);
}
}
}
src/pages/rentManage/rentGoods/rentAddOrEdit/components/rentAttr/index.tsx
浏览文件 @
196886f0
import
'./index.scss'
;
import
{
Button
,
Form
,
Select
,
Table
}
from
'antd'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useState
}
from
'react'
;
import
{
MinusOutlined
,
PlusOutlined
,
UploadOutlined
}
from
'@ant-design/icons'
;
import
{
Uploader
}
from
'~/components/uploader'
;
import
RichText
from
'~/components/richText'
;
import
{
RentManageAPI
}
from
'../../../../../../api'
;
import
deletePng
from
'~/assets/image/delete.png'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
...
...
@@ -13,7 +19,8 @@ type RentAttrFormType = {
productTypeId
:
number
;
brandInfoId
:
number
;
deviceModeId
:
number
;
goodsImage
:
string
[];
mainImage
:
string
;
subImage
:
string
[];
goodsVideo
:
string
;
productDetails
:
string
;
};
...
...
@@ -23,8 +30,12 @@ type productParamType = {
productParamName
:
string
;
productParamValue
:
string
;
};
interface
selfProps
{
ref
:
any
;
rentGoodsDetails
:
rentGoodsDetailType
|
undefined
;
}
const
RentAttr
=
(
)
=>
{
const
RentAttr
=
forwardRef
<
any
,
selfProps
>
(({
rentGoodsDetails
},
ref
)
=>
{
//商品属性表单
const
[
rentAttrForm
]
=
Form
.
useForm
<
RentAttrFormType
>
();
//商品参数表单
...
...
@@ -103,8 +114,17 @@ const RentAttr = () => {
const
[
brandInfoList
,
setBrandInfoList
]
=
useState
<
{
label
:
string
;
value
:
number
}[]
>
([]);
//型号下拉列表
const
[
modeTypeList
,
setModeTypeList
]
=
useState
<
{
label
:
string
;
value
:
number
}[]
>
([]);
//商品图片文件列表
const
[
imgFileList
,
setImgFileList
]
=
useState
<
//商品主图文件列表
const
[
mainImgFileList
,
setMainImgFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[]
>
([]);
//商品副图文件列表
const
[
subImgFileList
,
setSubImgFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
...
...
@@ -112,6 +132,7 @@ const RentAttr = () => {
url
:
string
;
}[]
>
([]);
//商品视频文件列表
const
[
videoFileList
,
setVideoFileList
]
=
useState
<
{
...
...
@@ -122,6 +143,10 @@ const RentAttr = () => {
}[]
>
([]);
useImperativeHandle
(
ref
,
()
=>
({
submitAttrForm
,
}));
//商品参数新增
const
addParameterDataEvent
=
()
=>
{
setParameterTableData
([
...
...
@@ -181,12 +206,22 @@ const RentAttr = () => {
uid
:
number
;
url
:
string
;
}[],
type
:
string
,
)
=>
{
rentAttrForm
.
setFieldValue
(
'goodsImage'
,
value
.
map
((
v
)
=>
v
.
url
),
);
setImgFileList
(
value
);
switch
(
type
)
{
case
'mainImage'
:
rentAttrForm
.
setFieldValue
(
'mainImage'
,
value
[
0
].
url
);
setMainImgFileList
(
value
);
break
;
case
'subImage'
:
rentAttrForm
.
setFieldValue
(
'subImage'
,
value
.
map
((
v
)
=>
v
.
url
),
);
setSubImgFileList
(
value
);
break
;
default
:
}
};
//商品视频上传成功
const
videoUploadSuccess
=
(
...
...
@@ -200,6 +235,11 @@ const RentAttr = () => {
rentAttrForm
.
setFieldValue
(
'goodsVideo'
,
value
[
0
].
url
);
setVideoFileList
(
value
);
};
//商品视频删除
const
deleteVideo
=
()
=>
{
setVideoFileList
([]);
};
//商品参数表单验证
const
productParamFormSubmit
=
()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
...
...
@@ -209,8 +249,10 @@ const RentAttr = () => {
const
productParamList
=
parameterTableData
.
reduce
(
(
pre
:
{
[
key
:
string
]:
string
}[],
cur
)
=>
{
const
Obj
=
Object
.
create
(
null
);
Obj
[
values
[
'productParamName'
+
cur
.
id
]]
=
values
[
'productParamValue'
+
cur
.
id
];
pre
.
push
(
Obj
);
if
(
values
[
'productParamName'
+
cur
.
id
]
&&
values
[
'productParamValue'
+
cur
.
id
])
{
Obj
[
values
[
'productParamName'
+
cur
.
id
]]
=
values
[
'productParamValue'
+
cur
.
id
];
pre
.
push
(
Obj
);
}
return
pre
;
},
[],
...
...
@@ -223,11 +265,79 @@ const RentAttr = () => {
});
};
const
submitAttrForm
=
async
()
=>
{
try
{
const
values
:
any
[]
=
await
Promise
.
all
([
rentAttrForm
.
validateFields
(),
productParamFormSubmit
(),
]);
return
Promise
.
resolve
({
...
values
[
0
],
productParam
:
values
[
1
].
length
?
JSON
.
stringify
(
values
[
1
])
:
undefined
,
});
}
catch
(
e
)
{
return
Promise
.
reject
(
e
);
}
};
useEffect
(()
=>
{
getRentTypeList
();
getRentMakeList
();
},
[]);
//编辑回显
useEffect
(()
=>
{
if
(
rentGoodsDetails
)
{
rentAttrForm
.
setFieldsValue
({
productTypeId
:
rentGoodsDetails
.
productTypeId
,
brandInfoId
:
rentGoodsDetails
.
brandInfoId
,
deviceModeId
:
rentGoodsDetails
.
deviceModeId
,
mainImage
:
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
0
)[
0
].
url
,
subImage
:
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
).
length
?
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
).
map
((
v
)
=>
v
.
url
)
:
undefined
,
goodsVideo
:
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
2
).
length
?
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
2
)[
0
].
url
:
undefined
,
});
getRentModelList
(
rentGoodsDetails
.
brandInfoId
,
rentGoodsDetails
.
productTypeId
);
if
(
rentGoodsDetails
.
productParam
)
{
const
tableData
:
productParamType
[]
=
JSON
.
parse
(
rentGoodsDetails
.
productParam
).
map
(
(
v
:
{
[
x
:
string
]:
string
})
=>
({
productParamName
:
Object
.
getOwnPropertyNames
(
v
)[
0
],
productParamValue
:
v
[
Object
.
getOwnPropertyNames
(
v
)[
0
]],
id
:
Math
.
random
(),
}),
);
setParameterTableData
(
tableData
);
const
defaultFormValue
:
{
[
x
:
string
]:
string
}
=
tableData
.
reduce
(
(
pre
:
{
[
x
:
string
]:
string
},
cur
)
=>
{
pre
[
'productParamName'
+
cur
.
id
]
=
cur
.
productParamName
;
pre
[
'productParamValue'
+
cur
.
id
]
=
cur
.
productParamValue
;
return
pre
;
},
{},
);
productParamForm
.
setFieldsValue
(
defaultFormValue
);
}
setMainImgFileList
(
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
0
)
.
map
((
v
)
=>
({
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
name
:
'主图'
,
url
:
v
.
url
})),
);
setSubImgFileList
(
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
)
.
map
((
v
)
=>
({
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
name
:
'主图'
,
url
:
v
.
url
})),
);
setVideoFileList
(
rentGoodsDetails
.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
2
)
.
map
((
v
)
=>
({
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
name
:
'主图'
,
url
:
v
.
url
})),
);
}
},
[
rentGoodsDetails
]);
return
(
<
div
className=
'rent-attr'
>
<
div
className=
'rent-attr-title'
>
商品属性
</
div
>
...
...
@@ -278,42 +388,62 @@ const RentAttr = () => {
</
Form
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品
图片
'
name=
'
goods
Image'
rules=
{
[{
required
:
true
,
message
:
'请
选择商品图片
'
}]
}
label=
'商品
主图
'
name=
'
main
Image'
rules=
{
[{
required
:
true
,
message
:
'请
上传商品主图
'
}]
}
>
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
imgUploadSuccess
}
defaultFileList=
{
i
mgFileList
}
fileSize=
{
3
}
fileLength=
{
5
}
onChange=
{
(
fileList
)
=>
imgUploadSuccess
(
fileList
,
'mainImage'
)
}
defaultFileList=
{
mainI
mgFileList
}
fileSize=
{
2
}
fileLength=
{
1
}
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品
视频'
name=
'goodsVideo
'
>
<
Form
.
Item
label=
'商品
副图'
name=
'subImage
'
>
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
videoUploadSuccess
}
defaultFileList=
{
video
FileList
}
fileSize=
{
30
}
fileLength=
{
1
}
onChange=
{
(
fileList
)
=>
imgUploadSuccess
(
fileList
,
'subImage'
)
}
defaultFileList=
{
subImg
FileList
}
fileSize=
{
2
}
fileLength=
{
4
}
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品详情页'
name=
'productDetails'
rules=
{
[{
required
:
true
,
message
:
'请输入商品详情页'
}]
}
>
<
RichText
richTextContent=
''
/>
<
Form
.
Item
label=
'商品视频'
name=
'goodsVideo'
>
{
videoFileList
.
length
?
(
<
div
className=
'rent-goods-video-wrap'
>
<
video
src=
{
videoFileList
[
0
].
url
}
style=
{
{
width
:
'200px'
,
height
:
'200px'
}
}
controls
/>
<
img
src=
{
deletePng
}
alt=
'删除'
onClick=
{
deleteVideo
}
/>
</
div
>
)
:
(
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
videoUploadSuccess
}
defaultFileList=
{
videoFileList
}
fileSize=
{
30
}
fileLength=
{
1
}
fileType=
{
[
'video/mp4'
,
'video/avi'
,
'video/wmv'
,
'video/rmvb'
]
}
>
<
UploadOutlined
/>
</
Uploader
>
)
}
</
Form
.
Item
>
<
Form
.
Item
label=
'商品详情页'
name=
'productDetails'
>
<
RichText
richTextContent=
{
rentGoodsDetails
?.
productDetails
}
/>
</
Form
.
Item
>
</
Form
>
</
div
>
);
};
}
)
;
export
default
RentAttr
;
src/pages/rentManage/rentGoods/rentAddOrEdit/components/skuInfo/index.tsx
浏览文件 @
196886f0
...
...
@@ -3,18 +3,67 @@ import { Col, Form, Row, Select, Table } from 'antd';
import
CommonSkuInfo
from
'~/components/goods/commonSkuInfo'
;
import
{
forwardRef
,
useEffect
,
useImperativeHandle
,
useRef
,
useState
}
from
'react'
;
import
{
RentManageAPI
}
from
'~/api'
;
import
{
isEmptyBol
,
regPriceNumber
}
from
'~/utils/validateUtils'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addRentGoodsType
,
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
import
{
filterObjAttr
}
from
'~/utils'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
interface
selfProps
{
ref
:
any
;
rentGoodsDetails
:
rentGoodsDetailType
|
undefined
;
}
//规格表单数据类型
type
specificationFormListType
=
{
optionList
:
{
label
:
string
;
value
:
string
}[];
id
:
number
;
name
:
string
;
addSpecificationValueShow
:
boolean
;
specificationValueList
:
{
name
:
string
;
id
:
number
;
specificationName
:
string
}[];
};
//sku返回类型
type
priceStockType
=
(
Exclude
<
InterReqType
<
addRentGoodsType
>
,
undefined
>
[
'priceStock'
][
0
]
&
{
id
:
number
;
})[];
const
SkuInfo
=
forwardRef
<
any
,
selfProps
>
((
_props
,
ref
)
=>
{
const
SkuInfo
=
forwardRef
<
any
,
selfProps
>
((
{
rentGoodsDetails
}
,
ref
)
=>
{
const
[
form
]
=
Form
.
useForm
<
{
minLeaseTerm
:
number
;
maxLeaseTerm
:
number
}
>
();
const
commonSkuInfoRef
=
useRef
<
any
>
();
//库存正则校验
const
stockValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
/^
[
+
]{0,1}(\d
+
)
$/
.
test
(
value
.
toString
()))
{
if
(
value
>
99999999
||
value
<
0
)
{
return
Promise
.
reject
(
new
Error
(
'库存最大为99999999且大于0'
));
}
return
Promise
.
resolve
();
}
else
{
return
Promise
.
reject
(
new
Error
(
'请输入正整数'
));
}
}
else
{
return
Promise
.
resolve
();
}
};
//价格正则校验
const
priceValidator
=
(
_rules
:
any
,
value
:
number
)
=>
{
if
(
!
isEmptyBol
(
value
))
{
if
(
regPriceNumber
(
value
.
toString
()))
{
if
(
value
>
99999999
||
value
<
0
)
{
return
Promise
.
reject
(
new
Error
(
'价格最大为99999999且大于0'
));
}
return
Promise
.
resolve
();
}
else
{
return
Promise
.
reject
(
new
Error
(
'为整数且最多保留两位小数'
));
}
}
else
{
return
Promise
.
reject
(
new
Error
(
'请输入金额'
));
}
};
const
[
defaultColumns
,
setDefaultColumns
]
=
useState
<
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
...
...
@@ -33,18 +82,42 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
children
:
[],
},
{
title
:
'
押金
'
,
title
:
'
缺货
'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'skuImage'
,
inputType
:
'switch'
,
dataIndex
:
'stockOut'
,
},
{
title
:
(
<
div
>
<
span
style=
{
{
color
:
'red'
}
}
>
*
</
span
>
<
span
>
押金
</
span
>
</
div
>
),
align
:
'center'
,
editable
:
true
,
dataIndex
:
'cashPledge'
,
width
:
'15%'
,
placeholder
:
'押金'
,
rules
:
[{
required
:
false
,
validator
:
priceValidator
}],
},
{
title
:
'库存'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'stock'
,
width
:
'10%'
,
rules
:
[{
required
:
false
,
validator
:
stockValidator
}],
},
]);
const
[
tableData
,
setTableData
]
=
useState
<
any
>
([]);
const
[
tableData
,
setTableData
]
=
useState
<
priceStockType
>
([]);
//全部租期下拉
const
[
allLeaseTermInfoList
,
setAllLeaseTermInfoList
]
=
useState
<
{
label
:
string
;
value
:
number
;
key
:
string
;
}[]
>
([]);
// 低租期下拉
...
...
@@ -52,6 +125,7 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
{
label
:
string
;
value
:
number
;
key
:
string
;
}[]
>
([]);
//高租期下拉
...
...
@@ -59,11 +133,13 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
{
label
:
string
;
value
:
number
;
key
:
string
;
}[]
>
([]);
useImperativeHandle
(
ref
,
()
=>
({
getForm
:
()
=>
form
,
skuFormSubmit
,
}));
const
updateTableData
=
(
tableData
:
any
)
=>
{
...
...
@@ -77,7 +153,17 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
const
getLeaseTermInfo
=
()
=>
{
RentManageAPI
.
getLeaseTermInfo
().
then
(({
result
})
=>
{
if
(
result
)
{
const
optionList
=
result
.
map
((
v
)
=>
({
label
:
v
.
leaseDate
,
value
:
v
.
id
}));
const
optionList
=
result
.
map
((
v
,
index
)
=>
({
label
:
v
.
leaseDate
,
value
:
v
.
id
,
key
:
[
'threeDaysRental'
,
'sevenDaysRental'
,
'thirtyDaysRental'
,
'ninetyDaysRental'
,
'maxDaysRental'
,
][
index
],
}));
setLowLeaseTermInfoList
(
optionList
);
setUpLeaseTermInfoList
(
optionList
);
setAllLeaseTermInfoList
(
optionList
);
...
...
@@ -101,10 +187,18 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
setDefaultColumns
(
defaultColumns
.
concat
(
filterLeaseTermInfo
.
map
((
v
)
=>
({
title
:
v
.
label
,
title
:
(
<
div
>
<
span
style=
{
{
color
:
'red'
}
}
>
*
</
span
>
<
span
>
{
v
.
label
}
</
span
>
</
div
>
),
align
:
'center'
,
editable
:
true
,
dataIndex
:
v
.
label
,
dataIndex
:
v
.
key
,
width
:
'15%'
,
placeholder
:
`
${
v
.
label
}
租金价格`
,
rules
:
[{
required
:
false
,
validator
:
priceValidator
}],
})),
),
);
...
...
@@ -126,10 +220,18 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
setDefaultColumns
(
defaultColumns
.
concat
(
filterLeaseTermInfo
.
map
((
v
)
=>
({
title
:
v
.
label
,
title
:
(
<
div
>
<
span
style=
{
{
color
:
'red'
}
}
>
*
</
span
>
<
span
>
{
v
.
label
}
</
span
>
</
div
>
),
align
:
'center'
,
editable
:
true
,
dataIndex
:
v
.
label
,
dataIndex
:
v
.
key
,
width
:
'15%'
,
placeholder
:
`
${
v
.
label
}
租金价格`
,
rules
:
[{
required
:
false
,
validator
:
priceValidator
}],
})),
),
);
...
...
@@ -137,10 +239,209 @@ const SkuInfo = forwardRef<any, selfProps>((_props, ref) => {
}
};
const
skuFormSubmit
=
async
()
=>
{
try
{
const
values
:
any
[]
=
await
Promise
.
all
([
form
.
validateFields
(),
commonSkuInfoRef
.
current
.
getSpecificationValueForm
().
validateFields
(),
commonSkuInfoRef
.
current
.
getSpecificationForm
().
validateFields
(),
]);
const
specificationFormList
:
specificationFormListType
[]
=
commonSkuInfoRef
.
current
.
getSpecificationFormList
();
const
specificationFormItem
=
specificationFormList
.
find
(
(
v
)
=>
!
v
.
specificationValueList
.
length
,
);
if
(
specificationFormItem
)
{
return
Promise
.
reject
(
`请为规格项
${
specificationFormItem
.
optionList
[
0
].
value
}
添加规格值`
);
}
else
{
//规格项数据转化
const
specAttrList
=
specificationFormList
.
map
((
v
)
=>
({
specName
:
v
.
optionList
[
0
].
value
,
id
:
rentGoodsDetails
?
rentGoodsDetails
.
specAttrList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)?.
id
:
undefined
,
specValuesList
:
v
.
specificationValueList
.
map
((
j
)
=>
({
specName
:
j
.
name
,
id
:
rentGoodsDetails
?
rentGoodsDetails
.
specAttrList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)
?.
specValuesList
.
find
((
i
)
=>
i
.
id
===
j
.
id
)?.
id
:
undefined
,
})),
}));
//规格值数据转化
const
priceStock
:
priceStockType
=
tableData
.
reduce
((
pre
:
priceStockType
,
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
(
values
[
1
]).
reduce
((
a
:
any
,
b
)
=>
{
if
(
b
.
includes
(
cur
.
id
))
{
a
[
b
.
replace
(
cur
.
id
,
''
)]
=
values
[
1
][
b
];
}
return
a
;
},
{}),
productSpec
:
JSON
.
stringify
(
productSpec
),
});
return
pre
;
},
[]);
//获取租期内的最低价格
const
rentDateMinPrice
=
priceStock
.
reduce
((
pre
:
number
[],
cur
:
any
)
=>
{
[
'threeDaysRental'
,
'sevenDaysRental'
,
'thirtyDaysRental'
,
'ninetyDaysRental'
,
'maxDaysRental'
,
].
map
((
key
)
=>
{
if
(
cur
[
key
])
{
pre
.
push
(
Number
(
cur
[
key
]));
}
});
return
pre
;
},
[])
.
sort
((
a
,
b
)
=>
a
-
b
)[
0
];
return
Promise
.
resolve
({
...
values
[
0
],
priceStock
,
specAttrList
,
showPrice
:
rentDateMinPrice
,
});
}
}
catch
(
e
)
{
return
Promise
.
reject
(
e
);
}
};
//表头拆分及合并列
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
setTableFormDefault
=
(
tableDataList
:
any
)
=>
{
const
tableFormDefault
=
tableDataList
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
return
{
...
pre
,
...
Object
.
getOwnPropertyNames
(
filterObjAttr
(
cur
,
[
'id'
])).
reduce
((
a
:
any
,
b
)
=>
{
a
[
b
+
cur
.
id
]
=
cur
[
b
];
return
a
;
},
{}),
};
},
{});
commonSkuInfoRef
.
current
.
getSpecificationValueForm
().
setFieldsValue
(
tableFormDefault
);
};
useEffect
(()
=>
{
getLeaseTermInfo
();
},
[]);
useEffect
(()
=>
{
if
(
rentGoodsDetails
)
{
form
.
setFieldsValue
({
minLeaseTerm
:
rentGoodsDetails
.
minLeaseTerm
,
maxLeaseTerm
:
rentGoodsDetails
.
maxLeaseTerm
,
});
//转化数据
const
covertSpecAttrList
=
rentGoodsDetails
.
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
=
rentGoodsDetails
.
specAttrList
.
reduce
(
(
pre
:
any
,
cur
:
any
,
currentIndex
)
=>
{
pre
[
'specName'
+
currentIndex
]
=
cur
.
specName
;
return
pre
;
},
{},
);
commonSkuInfoRef
.
current
.
getSpecificationForm
().
setFieldsValue
(
specFormDefault
);
commonSkuInfoRef
.
current
.
updateSpecificationFormList
([...
covertSpecAttrList
]);
const
upLeaseTermInfoIndex
=
allLeaseTermInfoList
.
findIndex
(
(
v
)
=>
v
.
value
===
rentGoodsDetails
.
maxLeaseTerm
,
);
const
lowLeaseTermInfoIndex
=
allLeaseTermInfoList
.
findIndex
(
(
v
)
=>
v
.
value
===
rentGoodsDetails
.
minLeaseTerm
,
);
const
filterLeaseTermInfo
=
allLeaseTermInfoList
.
slice
(
lowLeaseTermInfoIndex
,
upLeaseTermInfoIndex
+
1
,
);
const
addColumnsList
:
any
=
filterLeaseTermInfo
.
map
((
v
)
=>
({
title
:
(
<
div
>
<
span
style=
{
{
color
:
'red'
}
}
>
*
</
span
>
<
span
>
{
v
.
label
}
</
span
>
</
div
>
),
align
:
'center'
,
editable
:
true
,
dataIndex
:
v
.
key
,
width
:
'15%'
,
placeholder
:
`
${
v
.
label
}
租金价格`
,
rules
:
[{
required
:
false
,
validator
:
priceValidator
}],
}));
defaultColumns
.
push
(...
addColumnsList
);
mergeTableRow
(
covertSpecAttrList
);
const
tableDataList
:
priceStockType
=
rentGoodsDetails
.
priceStock
.
map
((
v
)
=>
({
id
:
v
.
id
,
stockOut
:
!!
v
.
stockOut
,
stock
:
v
.
stock
||
undefined
,
threeDaysRental
:
v
.
threeDaysRental
||
undefined
,
sevenDaysRental
:
v
.
sevenDaysRental
||
undefined
,
thirtyDaysRental
:
v
.
thirtyDaysRental
||
undefined
,
ninetyDaysRental
:
v
.
ninetyDaysRental
||
undefined
,
maxDaysRental
:
v
.
maxDaysRental
||
undefined
,
cashPledge
:
v
.
cashPledge
,
...
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
);
}
},
[
rentGoodsDetails
]);
return
(
<
div
className=
'sku-info'
>
<
div
className=
'sku-info-title'
>
价格库存信息
</
div
>
...
...
src/pages/rentManage/rentGoods/rentAddOrEdit/index.scss
浏览文件 @
196886f0
.goods-info
{
&
-operate
{
margin-top
:
50px
;
display
:
flex
;
justify-content
:
center
;
button
{
width
:
100px
;
height
:
40px
;
&
:first-child
{
margin-right
:
50px
;
}
}
}
.rent-create-edit
{
padding-bottom
:
80px
;
}
src/pages/rentManage/rentGoods/rentAddOrEdit/index.tsx
浏览文件 @
196886f0
...
...
@@ -2,17 +2,99 @@ import GoodsInfo from './components/goodsInfo';
import
RentAttr
from
'./components/rentAttr'
;
import
SkuInfo
from
'./components/skuInfo'
;
import
AddressInfo
from
'./components/addressInfo'
;
import
FooterOperate
from
'./components/footerOperate'
;
import
AccessoryList
from
'./components/accessoryList'
;
import
'./index.scss'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
RentManageAPI
}
from
'~/api'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
{
message
}
from
'antd'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
const
RentAddOrEdit
=
()
=>
{
const
navigate
=
useNavigate
();
const
[
searchParams
]
=
useSearchParams
();
const
goodsInfoRef
=
useRef
<
any
>
();
const
rentAttrRef
=
useRef
<
any
>
();
const
skuInfoRef
=
useRef
<
any
>
();
const
accessoryListRef
=
useRef
<
any
>
();
const
addressInfoRef
=
useRef
<
any
>
();
//租赁商品-编辑-id
const
[
rentGoodsId
,
setRentGoodsId
]
=
useState
<
number
>
(
-
1
);
//租赁-编辑-商品详情
const
[
rentGoodsDetails
,
setRentGoodsDetails
]
=
useState
<
rentGoodsDetailType
>
();
// 保存
const
saveRentGoods
=
()
=>
{
Promise
.
all
([
goodsInfoRef
.
current
.
submitGoodsInfoForm
(),
rentAttrRef
.
current
.
submitAttrForm
(),
skuInfoRef
.
current
.
skuFormSubmit
(),
accessoryListRef
.
current
.
accessoryTableFormSubmit
(),
addressInfoRef
.
current
.
addressInfoFormSubmit
(),
]).
then
((
values
)
=>
{
const
resourcesList
=
[
{
type
:
0
,
url
:
values
[
1
].
mainImage
},
...(
values
[
1
].
subImage
?.
map
((
v
:
string
)
=>
({
type
:
1
,
url
:
v
}))
||
[]),
...(
values
[
1
].
goodsVideo
?
[{
type
:
2
,
url
:
values
[
1
].
goodsVideo
}]
:
[]),
];
values
[
2
].
priceStock
=
values
[
2
].
priceStock
.
map
((
v
:
any
)
=>
({
...
v
,
stockOut
:
v
.
stockOut
?
1
:
0
,
}));
RentManageAPI
[
rentGoodsId
?
'editLeaseGoods'
:
'addRentGoods'
]({
...
values
[
0
],
...
filterObjAttr
(
values
[
1
],
[
'goodsImage'
,
'goodsVideo'
]),
...
values
[
2
],
leasePartsList
:
values
[
3
],
...
values
[
4
],
resourcesList
,
id
:
rentGoodsId
?
rentGoodsId
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
rentGoodsId
?
'编辑成功'
:
'新增成功'
);
navigate
(
-
1
);
}
});
});
};
//获取租赁商品详情
const
getRentGoodsDetail
=
(
id
:
number
)
=>
{
RentManageAPI
.
getLeaseGoodsDetails
({
id
}).
then
(({
result
})
=>
{
if
(
result
)
{
setRentGoodsDetails
({
...
result
});
}
});
};
useEffect
(()
=>
{
if
(
searchParams
.
get
(
'id'
))
{
getRentGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
setRentGoodsId
(
Number
(
searchParams
.
get
(
'id'
)));
}
},
[]);
return
(
<
div
className=
'rent-create-edit'
>
{
/*商品信息*/
}
<
GoodsInfo
/>
<
GoodsInfo
ref=
{
goodsInfoRef
}
rentGoodsDetails=
{
rentGoodsDetails
}
/>
{
/*商品属性*/
}
<
RentAttr
/>
<
RentAttr
ref=
{
rentAttrRef
}
rentGoodsDetails=
{
rentGoodsDetails
}
/>
{
/*价格库存信息*/
}
<
SkuInfo
/>
<
SkuInfo
ref=
{
skuInfoRef
}
rentGoodsDetails=
{
rentGoodsDetails
}
/>
{
/*配件清单*/
}
<
AccessoryList
ref=
{
accessoryListRef
}
rentGoodsDetails=
{
rentGoodsDetails
}
/>
{
/*物流信息*/
}
<
AddressInfo
/>
<
AddressInfo
ref=
{
addressInfoRef
}
rentGoodsDetails=
{
rentGoodsDetails
}
/>
{
/*底部操作栏*/
}
<
FooterOperate
saveRentGoods=
{
saveRentGoods
}
/>
</
div
>
);
};
...
...
src/pages/rentManage/rentGoods/rentDetail/index.tsx
0 → 100644
浏览文件 @
196886f0
import
{
useSearchParams
,
useNavigate
}
from
'react-router-dom'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
{
RentManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
leaseGoodsDetailsType
}
from
'~/api/interface/rentManageType'
;
import
{
Badge
,
Button
,
Col
,
Descriptions
,
Image
,
Row
,
Switch
,
Table
}
from
'antd'
;
//租赁商品详情返回类型
type
rentGoodsDetailType
=
InterDataType
<
leaseGoodsDetailsType
>
;
//规格表单数据类型
type
specificationFormListType
=
{
optionList
:
{
label
:
string
;
value
:
string
}[];
id
:
number
;
name
:
string
;
addSpecificationValueShow
:
boolean
;
specificationValueList
:
{
name
:
string
;
id
:
number
;
specificationName
:
string
}[];
};
const
RentDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
const
navigate
=
useNavigate
();
//租赁-编辑-商品详情
const
[
rentGoodsDetails
,
setRentGoodsDetails
]
=
useState
<
rentGoodsDetailType
>
();
const
[
skuColumns
,
setSkuColumns
]
=
useState
<
any
>
([
{
title
:
'商品规格'
,
align
:
'center'
,
children
:
[],
},
{
title
:
'是否缺货'
,
align
:
'center'
,
dataIndex
:
'stockOut'
,
render
:
(
text
:
number
)
=>
<
Switch
checked=
{
!!
text
}
/>,
},
{
title
:
'押金'
,
align
:
'center'
,
dataIndex
:
'cashPledge'
,
render
:
(
text
:
number
)
=>
text
.
toLocaleString
()
+
'元'
,
},
{
title
:
'库存'
,
align
:
'center'
,
dataIndex
:
'stock'
,
},
]);
const
[
skuTableData
,
setSkuTableData
]
=
useState
<
(
rentGoodsDetailType
[
'priceStock'
][
0
]
&
{
[
x
:
string
]:
string
})[]
>
([]);
//全部租期
const
[
allLeaseTermInfoList
,
setAllLeaseTermInfoList
]
=
useState
<
{
label
:
string
;
value
:
number
;
key
:
string
;
}[]
>
([]);
//获取租赁商品详情
const
getRentGoodsDetail
=
(
id
:
number
)
=>
{
RentManageAPI
.
getLeaseGoodsDetails
({
id
}).
then
(({
result
})
=>
{
if
(
result
)
{
setRentGoodsDetails
({
...
result
});
//转化数据
const
covertSpecAttrList
=
result
.
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
upLeaseTermInfoIndex
=
allLeaseTermInfoList
.
findIndex
(
(
v
)
=>
v
.
value
===
result
.
maxLeaseTerm
,
);
const
lowLeaseTermInfoIndex
=
allLeaseTermInfoList
.
findIndex
(
(
v
)
=>
v
.
value
===
result
.
minLeaseTerm
,
);
const
filterLeaseTermInfo
=
allLeaseTermInfoList
.
slice
(
lowLeaseTermInfoIndex
,
upLeaseTermInfoIndex
+
1
,
);
const
addColumnsList
:
any
=
filterLeaseTermInfo
.
map
((
v
)
=>
({
title
:
v
.
label
,
align
:
'center'
,
dataIndex
:
v
.
key
,
width
:
'15%'
,
render
:
(
text
:
number
)
=>
text
.
toLocaleString
()
+
'元'
,
}));
skuColumns
.
push
(...
addColumnsList
);
mergeTableRow
(
covertSpecAttrList
);
const
tableDataList
:
(
rentGoodsDetailType
[
'priceStock'
][
0
]
&
{
[
x
:
string
]:
string
})[]
=
result
.
priceStock
.
map
((
v
)
=>
({
id
:
v
.
id
,
stockOut
:
!!
v
.
stockOut
,
stock
:
v
.
stock
||
undefined
,
threeDaysRental
:
v
.
threeDaysRental
||
undefined
,
sevenDaysRental
:
v
.
sevenDaysRental
||
undefined
,
thirtyDaysRental
:
v
.
thirtyDaysRental
||
undefined
,
ninetyDaysRental
:
v
.
ninetyDaysRental
||
undefined
,
maxDaysRental
:
v
.
maxDaysRental
||
undefined
,
cashPledge
:
v
.
cashPledge
,
...
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
;
},
{},
),
}));
setSkuTableData
(
tableDataList
);
}
});
};
//表头拆分及合并列
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
,
};
}
},
}));
skuColumns
[
0
].
children
=
columns
;
setSkuColumns
([...
skuColumns
]);
};
//租赁-商品-租期信息
const
getLeaseTermInfo
=
()
=>
{
RentManageAPI
.
getLeaseTermInfo
().
then
(({
result
})
=>
{
if
(
result
)
{
const
optionList
=
result
.
map
((
v
,
index
)
=>
({
label
:
v
.
leaseDate
,
value
:
v
.
id
,
key
:
[
'threeDaysRental'
,
'sevenDaysRental'
,
'thirtyDaysRental'
,
'ninetyDaysRental'
,
'maxDaysRental'
,
][
index
],
}));
setAllLeaseTermInfoList
(
optionList
);
}
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
getLeaseTermInfo
();
},
[]);
useEffect
(()
=>
{
if
(
allLeaseTermInfoList
.
length
)
{
getRentGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
}
},
[
allLeaseTermInfoList
]);
return
(
<
div
className=
'rent-detail'
>
<
Descriptions
title=
'商品信息'
bordered
column=
{
4
}
extra=
{
<
Button
type=
'primary'
onClick=
{
backRoute
}
>
返回
</
Button
>
}
>
<
Descriptions
.
Item
label=
'商品标题'
>
{
rentGoodsDetails
?.
tradeName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品卖点'
>
{
rentGoodsDetails
?.
sellingPoint
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品成新'
>
{
rentGoodsDetails
?.
level
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品状态'
>
<
Badge
status=
{
rentGoodsDetails
?.
shelfStatus
?
'processing'
:
'default'
}
text=
{
rentGoodsDetails
?.
shelfStatus
?
'上架中'
:
'仓库中'
}
/>
</
Descriptions
.
Item
>
</
Descriptions
>
<
Descriptions
title=
'商品属性'
bordered
column=
{
3
}
style=
{
{
marginTop
:
'10px'
}
}
>
<
Descriptions
.
Item
label=
'商品类型'
>
{
rentGoodsDetails
?.
productTypeId
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品品牌'
>
{
rentGoodsDetails
?.
brandInfoId
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品型号'
>
{
rentGoodsDetails
?.
deviceModeId
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品主图'
>
<
Image
src=
{
rentGoodsDetails
?.
resourcesList
.
find
((
v
)
=>
v
.
type
===
0
)?.
url
}
width=
{
50
}
/>
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品副图'
span=
{
2
}
>
{
rentGoodsDetails
?.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
).
length
?
rentGoodsDetails
?.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
)
.
map
((
v
)
=>
<
Image
src=
{
v
.
url
}
width=
{
50
}
height=
{
50
}
key=
{
v
.
id
}
/>)
:
'暂无'
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品视频'
>
{
rentGoodsDetails
?.
resourcesList
.
find
((
v
)
=>
v
.
type
===
2
)?.
url
?
(
<
video
src=
{
rentGoodsDetails
?.
resourcesList
.
find
((
v
)
=>
v
.
type
===
2
)?.
url
}
controls
style=
{
{
width
:
'100px'
,
height
:
'100px'
}
}
/>
)
:
(
'暂无'
)
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品参数'
>
{
rentGoodsDetails
?.
productParam
?
JSON
.
parse
(
rentGoodsDetails
?.
productParam
).
map
(
(
v
:
{
[
x
:
string
]:
string
},
index
:
number
)
=>
(
<
Row
key=
{
index
}
style=
{
{
lineHeight
:
'40px'
}
}
>
<
Col
>
{
Object
.
getOwnPropertyNames
(
v
)[
0
]
}
:
</
Col
>
<
Col
>
{
v
[
Object
.
getOwnPropertyNames
(
v
)[
0
]]
}
</
Col
>
</
Row
>
),
)
:
'暂无'
}
</
Descriptions
.
Item
>
</
Descriptions
>
<
Descriptions
title=
'价格库存信息'
column=
{
1
}
style=
{
{
marginTop
:
'10px'
}
}
>
<
Descriptions
.
Item
>
<
Table
style=
{
{
width
:
'100%'
}
}
bordered
columns=
{
skuColumns
}
dataSource=
{
skuTableData
}
pagination=
{
false
}
/>
</
Descriptions
.
Item
>
</
Descriptions
>
<
Descriptions
title=
'配件清单'
column=
{
1
}
style=
{
{
marginTop
:
'10px'
}
}
>
<
Descriptions
.
Item
>
<
Table
style=
{
{
width
:
'100%'
}
}
bordered
columns=
{
[
{
title
:
'名称'
,
dataIndex
:
'name'
,
align
:
'center'
,
},
{
title
:
'数量'
,
dataIndex
:
'number'
,
align
:
'center'
,
},
{
title
:
'价格'
,
dataIndex
:
'price'
,
align
:
'center'
,
render
:
(
text
:
number
)
=>
text
.
toLocaleString
()
+
'元'
,
},
]
}
dataSource=
{
rentGoodsDetails
?.
leasePartsList
}
pagination=
{
false
}
/>
</
Descriptions
.
Item
>
</
Descriptions
>
</
div
>
);
};
export
default
RentDetail
;
src/pages/rentManage/rentGoods/rentList/index.scss
0 → 100644
浏览文件 @
196886f0
.rent-goods-info
{
display
:
flex
;
.info-meta
{
margin-left
:
5px
;
word-break
:
break-all
;
.title
{
margin-bottom
:
10px
;
}
}
}
src/pages/rentManage/rentGoods/rentList/index.tsx
浏览文件 @
196886f0
import
SearchBox
,
{
searchColumns
as
searchColumnsType
}
from
'~/components/search-box'
;
import
{
Button
,
Card
,
Table
}
from
'antd'
;
import
{
Button
,
Card
,
Image
,
message
,
Modal
,
Table
}
from
'antd'
;
import
{
ArrowDownOutlined
,
ArrowUpOutlined
,
DeleteOutlined
,
PlusOutlined
,
}
from
'@ant-design/icons'
;
import
{
useState
}
from
'react'
;
import
{
use
Effect
,
use
State
}
from
'react'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
{
RentManageAPI
}
from
'../../../../api'
;
import
{
InterDataType
,
InterReqListType
,
PaginationProps
}
from
'../../../../api/interface'
;
import
{
leaseGoodsListType
}
from
'../../../../api/interface/rentManageType'
;
import
'./index.scss'
;
//租赁列表返回类型
type
rentGoodsType
=
InterDataType
<
leaseGoodsListType
>
[
'list'
];
//租赁列表参数类型
type
rentGoodsParametersType
=
Exclude
<
InterReqListType
<
leaseGoodsListType
>
,
undefined
>
;
const
RentList
=
()
=>
{
const
navigate
=
useNavigate
();
//类型下拉列表
const
[
rentTypeSelectList
,
setRentTypeSelectList
]
=
useState
<
{
label
:
string
;
value
:
number
}[]
>
(
[],
);
//品牌下拉列表
const
[
brandInfoList
,
setBrandInfoList
]
=
useState
<
{
label
:
string
;
value
:
number
}[]
>
([]);
const
searchColumns
:
searchColumnsType
[]
=
[
{
label
:
'商品名称'
,
name
:
''
,
name
:
'
tradeName
'
,
type
:
'input'
,
placeholder
:
'请输入商品名称'
,
},
{
label
:
'商品类型'
,
name
:
''
,
type
:
'
s
elect'
,
name
:
'
productTypeId
'
,
type
:
'
S
elect'
,
placeholder
:
'请选择商品类型'
,
options
:
[]
,
options
:
rentTypeSelectList
,
},
{
label
:
'商品品牌'
,
name
:
''
,
type
:
'
s
elect'
,
name
:
'
brandInfoId
'
,
type
:
'
S
elect'
,
placeholder
:
'请选择商品品牌'
,
options
:
[]
,
options
:
brandInfoList
,
},
];
const
tabList
=
[
{
key
:
'1'
,
...
...
@@ -49,57 +67,221 @@ const RentList = () => {
},
];
const
[
activeTabKey
,
setActiveTabKey
]
=
useState
<
string
>
(
'1'
);
const
tableColumns
:
ColumnsType
<
any
>
=
[
const
tableColumns
:
ColumnsType
<
rentGoodsType
[
0
]
>
=
[
{
title
:
'商品名称'
,
align
:
'center'
,
width
:
'30%'
,
onHeaderCell
:
()
=>
({
style
:
{
textAlign
:
'center'
,
},
}),
render
:
(
_
:
any
,
record
)
=>
(
<
div
className=
'rent-goods-info'
>
<
div
className=
'goods-img'
>
<
Image
src=
{
record
.
resourcesList
.
find
((
v
)
=>
v
.
type
===
0
)?.
url
}
width=
{
50
}
height=
{
50
}
/>
</
div
>
<
div
className=
'info-meta'
>
<
div
className=
'title'
>
{
record
.
tradeName
}
</
div
>
<
div
className=
'type'
>
{
rentTypeSelectList
.
find
((
v
)
=>
v
.
value
===
record
.
productTypeId
)?.
label
}
</
div
>
</
div
>
</
div
>
),
},
{
title
:
'押金范围'
,
align
:
'center'
,
dataIndex
:
'cashPledgeRange'
,
},
{
title
:
'租金范围(日)'
,
align
:
'center'
,
dataIndex
:
'rentalRange'
,
},
{
title
:
'库存'
,
align
:
'center'
,
dataIndex
:
'stock'
,
},
{
title
:
'
销量
'
,
title
:
'
创建时间
'
,
align
:
'center'
,
dataIndex
:
'createTime'
,
},
{
title
:
'
创建时间
'
,
title
:
'
状态
'
,
align
:
'center'
,
dataIndex
:
'shelfStatus'
,
render
:
(
text
:
number
)
=>
(
text
?
'上架'
:
'下架'
),
},
{
title
:
'操作'
,
align
:
'center'
,
width
:
'20%'
,
render
:
()
=>
(
render
:
(
_
:
any
,
record
)
=>
(
<>
<
Button
type=
'link'
>
编辑
</
Button
>
<
Button
type=
'link'
>
详情
</
Button
>
<
Button
type=
'link'
>
上架
</
Button
>
<
Button
type=
'link'
>
下架
</
Button
>
<
Button
type=
'link'
danger
>
<
Button
type=
'link'
onClick=
{
()
=>
toRentEdit
(
record
)
}
>
编辑
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
toRentDetail
(
record
)
}
>
详情
</
Button
>
<
Button
type=
'link'
disabled=
{
!!
record
.
shelfStatus
}
onClick=
{
()
=>
batchOnShelfOrTakeDownRequest
([
record
.
id
],
1
)
}
>
上架
</
Button
>
<
Button
type=
'link'
disabled=
{
!
record
.
shelfStatus
}
onClick=
{
()
=>
batchOnShelfOrTakeDownRequest
([
record
.
id
],
0
)
}
>
下架
</
Button
>
<
Button
type=
'link'
danger
onClick=
{
()
=>
batchRemoveWareInfoRequest
([
record
.
id
])
}
>
删除
</
Button
>
</>
),
},
];
const
[
tableData
]
=
useState
<
any
>
([{
id
:
1
}]);
const
[
tableData
,
setTableData
]
=
useState
<
rentGoodsType
>
([]);
const
[
pagination
,
setPagination
]
=
useState
<
PaginationProps
&
{
totalCount
:
number
}
>
({
pageNo
:
1
,
pageSize
:
10
,
totalCount
:
0
,
});
const
[
query
,
setQuery
]
=
useState
<
rentGoodsParametersType
>
({
shelfStatus
:
undefined
,
});
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
<
React
.
Key
[]
>
([]);
const
onTabChange
=
(
key
:
string
)
=>
{
pagination
.
pageNo
=
1
;
pagination
.
pageSize
=
10
;
setActiveTabKey
(
key
);
query
.
shelfStatus
=
key
===
'1'
?
undefined
:
key
===
'2'
?
1
:
0
;
setQuery
(
query
);
getRentGoodsList
(
query
);
};
//租赁商品列表
const
getRentGoodsList
=
(
query
?:
rentGoodsParametersType
)
=>
{
RentManageAPI
.
getLeaseGoodsList
({
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
...
query
,
}).
then
(({
result
})
=>
{
pagination
.
totalCount
=
result
.
totalCount
;
setPagination
({
...
pagination
});
setTableData
(
result
.
list
||
[]);
});
};
//新增,编辑租赁商品
const
addOrEditClick
=
()
=>
{
navigate
({
pathname
:
'/rentManage/rentGoods/add'
});
};
//分页
const
paginationChange
=
(
pageNo
:
number
,
pageSize
:
number
)
=>
{
pagination
.
pageNo
=
pageNo
;
pagination
.
pageSize
=
pageSize
;
getRentGoodsList
(
query
);
};
//筛选
const
searchSuccess
=
(
value
:
rentGoodsParametersType
)
=>
{
pagination
.
pageNo
=
1
;
pagination
.
pageSize
=
10
;
setQuery
(
value
);
getRentGoodsList
(
value
);
};
//获取类型列表
const
getRentTypeList
=
()
=>
{
RentManageAPI
.
getTypeList
({
pageNo
:
1
,
pageSize
:
99999
}).
then
(({
result
})
=>
{
if
(
result
.
list
)
{
setRentTypeSelectList
(
result
.
list
.
map
((
v
)
=>
({
value
:
v
.
id
,
label
:
v
.
name
})));
}
});
};
//品牌列表
const
getRentMakeList
=
()
=>
{
RentManageAPI
.
getListBrandInfo
({
pageNo
:
1
,
pageSize
:
99999
}).
then
(({
result
})
=>
{
if
(
result
.
list
)
{
const
optionList
=
result
.
list
.
map
((
v
)
=>
({
label
:
v
.
brandName
,
value
:
v
.
id
}));
setBrandInfoList
(
optionList
);
}
});
};
//跳转租赁商品编辑
const
toRentEdit
=
(
record
:
rentGoodsType
[
0
])
=>
{
navigate
({
pathname
:
'/rentManage/rentGoods/edit'
,
search
:
`id=
${
record
.
id
}
`
});
};
//跳转租赁详情
const
toRentDetail
=
(
record
:
rentGoodsType
[
0
])
=>
{
navigate
({
pathname
:
'/rentManage/rentGoods/detail'
,
search
:
`id=
${
record
.
id
}
`
});
};
//批量上下架操作
const
batchOnShelfOrTakeDownClick
=
(
status
:
number
)
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
message
.
warning
(
'请先选择租赁商品'
);
}
else
{
batchOnShelfOrTakeDownRequest
(
selectedRowKeys
as
number
[],
status
);
}
};
//批量上下架请求
const
batchOnShelfOrTakeDownRequest
=
(
goodsIds
:
number
[],
status
:
number
)
=>
{
RentManageAPI
.
batchOnShelfOrTakeDown
({
goodsIds
,
status
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
`
${
status
?
'上架'
:
'下架'
}
成功`
);
getRentGoodsList
(
query
);
setSelectedRowKeys
([]);
}
});
};
//批量删除操作
const
batchRemoveWareInfoClick
=
()
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
message
.
warning
(
'请先选择租赁商品'
);
}
else
{
batchRemoveWareInfoRequest
(
selectedRowKeys
as
number
[]);
}
};
//批量删除请求
const
batchRemoveWareInfoRequest
=
(
ids
:
number
[])
=>
{
Modal
.
confirm
({
title
:
'提示'
,
content
:
`确认删除
${
ids
.
length
>
1
?
'这些'
:
'该'
}
商品`
,
onOk
:
()
=>
{
RentManageAPI
.
batchRemoveWareInfo
(
ids
).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
if
(
ids
.
length
===
tableData
.
length
&&
pagination
.
pageNo
!==
1
)
{
pagination
.
pageNo
-=
1
;
}
getRentGoodsList
(
query
);
message
.
success
(
'删除成功'
);
}
});
},
});
};
//表格-选择
const
onSelectChange
=
(
newSelectedRowKeys
:
React
.
Key
[])
=>
{
setSelectedRowKeys
(
newSelectedRowKeys
);
};
useEffect
(()
=>
{
getRentGoodsList
();
getRentTypeList
();
getRentMakeList
();
},
[]);
return
(
<
div
className=
'rent-list'
>
...
...
@@ -110,20 +292,50 @@ const RentList = () => {
新增商品
</
Button
>
}
searchData=
{
searchSuccess
}
/>
<
Card
tabList=
{
tabList
}
activeTabKey=
{
activeTabKey
}
onTabChange=
{
onTabChange
}
>
<
div
className=
'table-operate'
style=
{
{
marginBottom
:
'10px'
}
}
>
<
Button
type=
'primary'
icon=
{
<
ArrowUpOutlined
/>
}
style=
{
{
marginRight
:
'10px'
}
}
>
<
Button
type=
'primary'
icon=
{
<
ArrowUpOutlined
/>
}
style=
{
{
marginRight
:
'10px'
}
}
onClick=
{
()
=>
batchOnShelfOrTakeDownClick
(
1
)
}
>
批量上架
</
Button
>
<
Button
type=
'primary'
icon=
{
<
ArrowDownOutlined
/>
}
style=
{
{
marginRight
:
'10px'
}
}
>
<
Button
type=
'primary'
icon=
{
<
ArrowDownOutlined
/>
}
style=
{
{
marginRight
:
'10px'
}
}
onClick=
{
()
=>
batchOnShelfOrTakeDownClick
(
0
)
}
>
批量下架
</
Button
>
<
Button
type=
'primary'
danger
icon=
{
<
DeleteOutlined
/>
}
>
<
Button
type=
'primary'
danger
icon=
{
<
DeleteOutlined
/>
}
onClick=
{
batchRemoveWareInfoClick
}
>
批量删除
</
Button
>
</
div
>
<
Table
bordered
columns=
{
tableColumns
}
rowKey=
'id'
dataSource=
{
tableData
}
/>
<
Table
columns=
{
tableColumns
}
rowKey=
'id'
dataSource=
{
tableData
}
pagination=
{
{
total
:
pagination
.
totalCount
,
pageSize
:
pagination
.
pageSize
,
current
:
pagination
.
pageNo
,
showSizeChanger
:
true
,
showQuickJumper
:
true
,
onChange
:
(
page
:
number
,
pageSize
:
number
)
=>
paginationChange
(
page
,
pageSize
),
showTotal
:
(
total
,
range
)
=>
`当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`
,
}
}
rowSelection=
{
{
selectedRowKeys
,
onChange
:
onSelectChange
}
}
/>
</
Card
>
</
div
>
);
...
...
src/pages/systemManage/addressManage/components/addOrEditAddressModal/index.tsx
0 → 100644
浏览文件 @
196886f0
import
{
Cascader
,
Form
,
Input
,
message
,
Modal
,
ModalProps
,
Switch
}
from
'antd'
;
import
{
FC
,
useEffect
}
from
'react'
;
import
districtData
from
'~/assets/json/district.json'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addressInsetType
,
addressListType
}
from
'~/api/interface/systemManageType'
;
import
{
SystemManageAPI
}
from
'~/api'
;
interface
selfProps
{
onOk
:
()
=>
void
;
onCancel
:
()
=>
void
;
currentAddressItem
?:
addressType
[
0
]
|
undefined
;
}
//新增地址参数类型
type
addAddressParameterType
=
Exclude
<
InterReqType
<
addressInsetType
>
,
undefined
>
;
//地址列表返回类型
type
addressType
=
InterDataType
<
addressListType
>
;
const
AddOrEditAddressModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
,
onOk
,
currentAddressItem
,
})
=>
{
const
[
form
]
=
Form
.
useForm
<
Omit
<
addAddressParameterType
,
'takeRegion'
|
'type'
|
'districtCode'
>
&
{
takeRegion
:
string
[];
type
:
boolean
;
districtCode
:
number
[];
}
>
();
const
handleOk
=
()
=>
{
form
.
validateFields
().
then
((
values
)
=>
{
SystemManageAPI
[
currentAddressItem
?
'editAddress'
:
'addressInset'
]({
...
values
,
districtCode
:
values
.
districtCode
[
2
].
toString
(),
takeRegion
:
getDistrictName
(
values
.
districtCode
),
type
:
values
.
type
?
1
:
0
,
id
:
currentAddressItem
?
currentAddressItem
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'新增地址成功'
);
form
.
resetFields
();
onOk
();
}
});
});
};
const
handleCancel
=
()
=>
{
onCancel
();
};
//根据省市区code查询省市区名称
const
getDistrictName
=
(
codeArr
:
number
[])
=>
{
const
getFlatDistrictData
=
(
districtData
:
any
[])
=>
{
return
districtData
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
pre
.
push
(
cur
);
if
(
cur
.
childInfo
)
{
pre
.
push
(...
getFlatDistrictData
(
cur
.
childInfo
));
}
return
pre
;
},
[]);
};
const
flatDistrictData
:
any
=
getFlatDistrictData
(
districtData
);
return
codeArr
.
map
((
v
)
=>
flatDistrictData
.
find
((
i
:
any
)
=>
i
.
id
===
v
)?.
name
).
join
(
'/'
);
};
useEffect
(()
=>
{
if
(
currentAddressItem
)
{
form
.
setFieldsValue
({
takeName
:
currentAddressItem
.
takeName
,
takePhone
:
currentAddressItem
.
takePhone
,
districtCode
:
[
Number
(
currentAddressItem
.
districtCode
.
substring
(
0
,
2
)
+
'0000'
),
Number
(
currentAddressItem
.
districtCode
.
substring
(
0
,
4
)
+
'00'
),
Number
(
currentAddressItem
.
districtCode
),
],
takeAddress
:
currentAddressItem
.
takeAddress
,
type
:
!!
currentAddressItem
.
type
,
});
}
},
[
currentAddressItem
]);
return
(
<
Modal
open=
{
open
}
title=
{
currentAddressItem
?
'编辑地址'
:
'新增地址'
}
onOk=
{
handleOk
}
onCancel=
{
handleCancel
}
>
<
Form
labelCol=
{
{
span
:
4
}
}
wrapperCol=
{
{
span
:
20
}
}
form=
{
form
}
>
<
Form
.
Item
label=
'姓名'
name=
'takeName'
rules=
{
[{
required
:
true
,
message
:
'请输入姓名'
}]
}
>
<
Input
placeholder=
'请输入姓名'
maxLength=
{
30
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'手机号'
name=
'takePhone'
rules=
{
[
{
required
:
true
,
message
:
'请输入手机号'
},
// 校验手机号
()
=>
({
validator
(
_
,
value
)
{
if
(
!
value
||
/^1
[
3-9
]\d
{9}$/
.
test
(
value
))
{
return
Promise
.
resolve
();
}
return
Promise
.
reject
(
'请输入正确的手机号'
);
},
}),
]
}
>
<
Input
placeholder=
'请输入手机号'
maxLength=
{
11
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'所在地区'
name=
'districtCode'
rules=
{
[{
required
:
true
,
message
:
'请选择所在地区'
}]
}
>
<
Cascader
placeholder=
'请选择所在地区'
options=
{
districtData
}
fieldNames=
{
{
label
:
'name'
,
value
:
'id'
,
children
:
'childInfo'
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'详细地址'
name=
'takeAddress'
rules=
{
[{
required
:
true
,
message
:
'请输入详细地址'
}]
}
>
<
Input
.
TextArea
rows=
{
4
}
showCount
placeholder=
'请输入详细地址'
maxLength=
{
70
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'设为默认地址'
name=
'type'
>
<
Switch
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
AddOrEditAddressModal
;
src/pages/systemManage/addressManage/index.tsx
0 → 100644
浏览文件 @
196886f0
import
SearchBox
from
'~/components/search-box'
;
import
{
Button
,
message
,
Modal
,
Table
}
from
'antd'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
AddOrEditAddressModal
from
'~/pages/systemManage/addressManage/components/addOrEditAddressModal'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
addressListType
}
from
'~/api/interface/systemManageType'
;
//地址列表返回类型
type
addressType
=
InterDataType
<
addressListType
>
;
const
AddressManage
=
()
=>
{
const
tableColumns
:
ColumnsType
<
addressType
[
0
]
>
=
[
{
title
:
'姓名'
,
align
:
'center'
,
dataIndex
:
'takeName'
,
},
{
title
:
'电话'
,
align
:
'center'
,
dataIndex
:
'takePhone'
,
},
{
title
:
'所在地区'
,
align
:
'center'
,
dataIndex
:
'takeRegion'
,
},
{
title
:
'详细地址'
,
align
:
'center'
,
dataIndex
:
'takeAddress'
,
},
{
title
:
'状态'
,
align
:
'center'
,
dataIndex
:
'type'
,
render
:
(
text
:
number
)
=>
(
text
?
'默认'
:
''
),
},
{
title
:
'操作'
,
align
:
'center'
,
render
:
(
_
:
any
,
record
)
=>
(
<>
<
Button
type=
'link'
onClick=
{
()
=>
addOrEditAddressModalClick
(
record
)
}
>
编辑
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
deleteAddressClick
(
record
)
}
>
删除
</
Button
>
</>
),
},
];
const
[
addressList
,
setAddressList
]
=
useState
<
addressType
>
([]);
const
[
addOrEditAddressModalShow
,
setAddOrEditAddressModalShow
]
=
useState
<
boolean
>
(
false
);
const
[
currentAddressItem
,
setCurrentAddressItem
]
=
useState
<
addressType
[
0
]
>
();
const
getAddressList
=
()
=>
{
SystemManageAPI
.
getAddressList
({}).
then
(({
result
})
=>
{
setAddressList
(
result
);
});
};
//新增,编辑地址
const
addOrEditAddressModalClick
=
(
record
?:
addressType
[
0
])
=>
{
setCurrentAddressItem
(
record
?
{
...
record
}
:
undefined
);
setAddOrEditAddressModalShow
(
true
);
};
const
addOrEditAddressModalCancel
=
()
=>
{
setAddOrEditAddressModalShow
(
false
);
};
const
addOrEditAddressModalOk
=
()
=>
{
getAddressList
();
setAddOrEditAddressModalShow
(
false
);
};
//地址删除
const
deleteAddressClick
=
(
record
:
addressType
[
0
])
=>
{
Modal
.
confirm
({
title
:
'提示'
,
content
:
'确认删除该地址吗?'
,
onOk
:
()
=>
{
SystemManageAPI
.
deleteAddress
({
id
:
record
.
id
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'删除成功'
);
getAddressList
();
}
});
},
});
};
useEffect
(()
=>
{
getAddressList
();
},
[]);
return
(
<
div
className=
'address-manage'
>
<
SearchBox
child=
{
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
()
=>
addOrEditAddressModalClick
()
}
>
新增地址
</
Button
>
}
/>
<
Table
bordered
columns=
{
tableColumns
}
dataSource=
{
addressList
}
rowKey=
'id'
/>
{
/*新增编辑地址*/
}
<
AddOrEditAddressModal
open=
{
addOrEditAddressModalShow
}
onCancel=
{
addOrEditAddressModalCancel
}
onOk=
{
addOrEditAddressModalOk
}
currentAddressItem=
{
currentAddressItem
}
/>
</
div
>
);
};
export
default
AddressManage
;
src/router/router.tsx
浏览文件 @
196886f0
...
...
@@ -35,6 +35,7 @@ import {
BankOutlined
,
VerifiedOutlined
,
AccountBookOutlined
,
EnvironmentOutlined
,
}
from
'@ant-design/icons'
;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...
...
@@ -98,7 +99,8 @@ const ServiceIntroduceView = React.lazy(
);
//服务介绍
const
RentListView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentGoods/rentList'
));
//租赁列表
const
RentAddOrEditView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentGoods/rentAddOrEdit'
));
//租赁新增、编辑、详情
const
RentAddOrEditView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentGoods/rentAddOrEdit'
));
//租赁新增、编辑
const
RentDetailView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentGoods/rentDetail'
));
//租赁详情
const
RentTypeView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentType'
));
//租赁-类型管理
const
RentMakeView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentMake'
));
//租赁-品牌管理
const
RentModeView
=
React
.
lazy
(()
=>
import
(
'~/pages/rentManage/rentMode'
));
//租赁-型号管理
...
...
@@ -106,7 +108,7 @@ const RentModeView = React.lazy(() => import('~/pages/rentManage/rentMode')); //
const
MallGoodsView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/mallGoods/goodsList'
));
//商城商品
const
MallAddOrEditOrDetailView
=
React
.
lazy
(
()
=>
import
(
'~/pages/mallManage/mallGoods/goodsAddOrEditOrDetail'
),
);
//商城商品新增、编辑
、租赁商品详情
);
//商城商品新增、编辑
const
MallGoodsDetailsView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/mallGoods/goodsDetails'
));
//商城商品(新)
const
ProduceListView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/produceManage/produceList'
));
//产品列表
...
...
@@ -153,6 +155,7 @@ const CompanyDetailView = React.lazy(
import
AccountLimit
from
'~/pages/systemManage/limitManage/roleList'
;
//账号权限
import
LimitInfo
from
'~/pages/systemManage/limitManage/limitInfo'
;
import
CustomListDetail
from
'~/pages/customManage/customList/detail'
;
const
AddressManageView
=
React
.
lazy
(()
=>
import
(
'~/pages/systemManage/addressManage'
));
// const IndustryListView = React.lazy(() => import('~/pages/mallManage/industryManage/industryList')); //行业列表
// const IndustryDetailView = React.lazy(
...
...
@@ -734,17 +737,17 @@ export const routerList: Array<RouteObjectType> = [
hidden
:
true
,
},
},
//
{
//
path: '/rentManage/rentGoods/detail',
// element: withLoadingComponent(<RentAddOrEdit
View />),
//
errorElement: <ErrorPage />,
//
meta: {
// id: 1013
6,
//
icon: <SmileOutlined />,
//
title: '租赁商品详情',
//
hidden: true,
//
},
//
},
{
path
:
'/rentManage/rentGoods/detail'
,
element
:
withLoadingComponent
(<
RentDetail
View
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1017
6
,
icon
:
<
SmileOutlined
/>,
title
:
'租赁商品详情'
,
hidden
:
true
,
},
},
{
path
:
'/rentManage/rentType'
,
element
:
withLoadingComponent
(<
RentTypeView
/>),
...
...
@@ -1163,6 +1166,17 @@ export const routerList: Array<RouteObjectType> = [
hidden
:
true
,
},
},
{
path
:
'/systemManage/addressManage'
,
element
:
withLoadingComponent
(<
AddressManageView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1450
,
title
:
'地址管理'
,
icon
:
<
EnvironmentOutlined
/>,
develop
:
true
,
},
},
],
},
];
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论