Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
iuav
admin
Commits
3018428e
提交
3018428e
authored
8月 01, 2023
作者:
龚洪江
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop'
上级
f4a13cc2
903a4367
隐藏空白字符变更
内嵌
并排
正在显示
43 个修改的文件
包含
3508 行增加
和
606 行删除
+3508
-606
kustomization.yaml
kustomization/overlays/dev/kustomization.yaml
+1
-1
categoryManage.ts
src/api/interface/categoryManage.ts
+59
-0
commonType.ts
src/api/interface/commonType.ts
+12
-0
goodsType.ts
src/api/interface/goodsType.ts
+164
-0
systemManageType.ts
src/api/interface/systemManageType.ts
+82
-0
categoryManage.ts
src/api/modules/categoryManage.ts
+32
-0
common.ts
src/api/modules/common.ts
+14
-0
goodsAPI.ts
src/api/modules/goodsAPI.ts
+29
-1
systemManage.ts
src/api/modules/systemManage.ts
+20
-0
request.ts
src/api/request.ts
+1
-1
qr-code-icon.svg
src/assets/image/qr-code-icon.svg
+2
-0
index.tsx
src/components/EditableCell/index.tsx
+20
-4
index.scss
src/components/layout/index.scss
+1
-0
index.tsx
src/components/layout/title/index.tsx
+2
-4
index.tsx
.../categoryList/components/addOrEditCategoryModal/index.tsx
+122
-0
index.scss
src/pages/categoryManage/categoryList/index.scss
+7
-0
index.tsx
src/pages/categoryManage/categoryList/index.tsx
+482
-0
index.scss
src/pages/common/login/index.scss
+20
-0
index.tsx
src/pages/common/login/index.tsx
+137
-53
index.tsx
src/pages/customManage/customList/index.tsx
+1
-1
index.scss
...ods/goodsAddOrEditOrDetail/components/baseInfo/index.scss
+10
-0
index.tsx
...oods/goodsAddOrEditOrDetail/components/baseInfo/index.tsx
+248
-0
index.tsx
...goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
+21
-0
index.tsx
...sAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
+419
-0
index.tsx
...Goods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
+135
-0
index-old.tsx
...mallManage/mallGoods/goodsAddOrEditOrDetail/index-old.tsx
+308
-0
index.scss
...es/mallManage/mallGoods/goodsAddOrEditOrDetail/index.scss
+15
-10
index.tsx
...ges/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
+225
-264
index.scss
src/pages/mallManage/mallGoods/goodsDetails/index.scss
+25
-0
index.tsx
src/pages/mallManage/mallGoods/goodsDetails/index.tsx
+180
-0
index.tsx
src/pages/mallManage/mallGoods/goodsList/index.tsx
+116
-123
index.tsx
...yManage/companyDetail/components/addPeopleModal/index.tsx
+59
-0
index.tsx
...ge/companyDetail/components/transferLeaderModal/index.tsx
+75
-0
index.scss
...pages/systemManage/companyManage/companyDetail/index.scss
+21
-0
index.tsx
src/pages/systemManage/companyManage/companyDetail/index.tsx
+229
-0
index.tsx
...age/companyManage/companyList/comp/addEditModal/index.tsx
+90
-48
index.tsx
src/pages/systemManage/companyManage/companyList/index.tsx
+16
-9
index.ts
src/router/index.ts
+27
-31
privateRouter.tsx
src/router/privateRouter.tsx
+16
-10
router.tsx
src/router/router.tsx
+46
-19
index.ts
src/store/module/menu/index.ts
+6
-9
index.ts
src/store/module/userInfo/index.ts
+1
-18
validateUtils.ts
src/utils/validateUtils.ts
+12
-0
没有找到文件。
kustomization/overlays/dev/kustomization.yaml
浏览文件 @
3018428e
...
...
@@ -14,4 +14,4 @@ patches:
images
:
-
name
:
REGISTRY/NAMESPACE/IMAGE:TAG
newName
:
mmc-registry.cn-shenzhen.cr.aliyuncs.com/sharefly-dev/admin
newTag
:
0
76c71a473e24a5f127df294af6ea3eb20b5858c
newTag
:
0
63cc3527bbd3e1199f9aec0d902b1c76c712a0a
src/api/interface/categoryManage.ts
浏览文件 @
3018428e
...
...
@@ -72,3 +72,62 @@ export type categoryDetailsType = InterFunction<
>
;
//分类-关联列表
export
type
categoryRelevantType
=
InterFunction
<
{
id
:
number
;
type
:
number
},
any
>
;
//分类管理-分类列表(新)
type
categoryItemType
=
{
id
:
number
;
name
:
string
;
createTime
:
string
;
icon
:
string
;
description
:
string
;
subDTOList
:
(
Omit
<
categoryItemType
,
'createTime'
|
'icon'
|
'subDTOList'
|
'sort'
>
&
{
categoryPrimaryId
:
number
;
})[];
sort
:
number
;
};
export
type
categoryListRespType
=
InterItemFunction
<
{
id
?:
number
},
categoryItemType
[]
>
;
//分类管理-1级分类新增(新)
export
type
addPrimaryCategoryType
=
InterFunction
<
{
description
:
string
;
icon
:
string
;
name
:
string
;
},
any
>
;
//分类管理-1级分类编辑(新)
export
type
updatePrimaryCategoryType
=
InterFunction
<
{
description
:
string
;
icon
:
string
;
name
:
string
;
id
?:
number
;
},
any
>
;
//分类管理-1级分类删除(新)
export
type
deletePrimaryCategoryType
=
InterFunction
<
{
id
:
number
},
any
>
;
//分类管理-1级分类交换顺序(新)
export
type
exchangeType
=
InterFunction
<
{
id
:
number
;
sort
:
number
}[],
any
>
;
//分类管理-2级分类新增(新)
export
type
addSubCategoryType
=
InterFunction
<
{
categoryPrimaryId
:
number
;
description
:
string
;
name
:
string
;
},
any
>
;
//分类管理-2级分类编辑(新)
export
type
updateSubCategoryType
=
InterFunction
<
{
categoryPrimaryId
:
number
;
description
:
string
;
name
:
string
;
id
?:
number
;
},
any
>
;
//分类管理-2级分类删除(新)
export
type
deleteSubCategoryType
=
InterFunction
<
{
id
:
number
},
any
>
;
src/api/interface/commonType.ts
浏览文件 @
3018428e
...
...
@@ -11,6 +11,7 @@ export type BackEndLoginType = InterFunction<
phoneNum
:
string
;
userName
:
string
;
nickName
:
string
;
appUserAccountId
?:
number
;
companyInfoVO
:
{
id
:
number
;
companyType
:
number
;
...
...
@@ -23,6 +24,7 @@ export type BackEndLoginType = InterFunction<
companyUserName
:
string
;
phoneNum
:
string
;
remark
:
string
;
leader
:
number
;
};
roleInfo
:
{
id
:
number
;
...
...
@@ -157,3 +159,13 @@ export type batchRemoveBannerInfo = InterFunction<any, NonNullable<unknown>>;
export
type
removeBannerInfo
=
InterFunction
<
{
id
:
number
},
NonNullable
<
unknown
>>
;
// V1.0.1-banner-排序交换
export
type
exchangeBannerInfo
=
InterFunction
<
Array
<
any
>
,
NonNullable
<
unknown
>>
;
//手机号筛选小程序用户
export
type
getUserAccountByPhoneNumType
=
InterFunction
<
{
phoneNum
:
string
},
{
id
:
number
;
nickName
:
string
;
userName
:
string
;
phoneNum
:
string
;
uid
:
string
}[]
>
;
//获取小程序二维码
export
type
appletQRCodeType
=
InterFunction
<
{
page
:
string
;
scene
:
string
},
string
>
;
//登录信息-获取
export
type
getLoginInfoType
=
InterFunction
<
{
randomLoginCode
:
string
},
any
>
;
src/api/interface/goodsType.ts
浏览文件 @
3018428e
...
...
@@ -99,7 +99,171 @@ 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
>
;
//商品-新增(新)
export
type
addMallGoodsType
=
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
;
goodsSpecId
?:
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
;
goodsSpecId
:
number
;
}[];
id
:
any
;
mallGoodsId
:
number
;
must
:
number
;
skuUnitId
:
number
;
specName
:
string
;
}[];
id
:
number
;
labelShow
:
number
;
resourcesList
:
{
id
:
number
;
type
:
number
;
url
:
string
;
}[];
shelfStatus
:
number
;
tradeName
:
string
;
},
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/interface/systemManageType.ts
浏览文件 @
3018428e
...
...
@@ -130,6 +130,8 @@ export type listCompanyPage = InterListFunction<
phoneNum
:
string
;
province
:
string
;
remark
:
string
;
lat
:
number
;
lon
:
number
;
}
>
;
// 单位-新增
...
...
@@ -147,6 +149,8 @@ export type listCompanyAdd = InterFunction<
province
?:
string
;
remark
?:
string
;
area
?:
string
[];
lat
:
number
;
lon
:
number
;
},
NonNullable
<
unknown
>
>
;
...
...
@@ -165,6 +169,8 @@ export type listCompanyUpdate = InterFunction<
province
?:
string
;
remark
?:
string
;
area
?:
string
[];
lat
:
number
;
lon
:
number
;
},
NonNullable
<
unknown
>
>
;
...
...
@@ -184,6 +190,82 @@ export type listCompanyRemove = InterFunction<
},
NonNullable
<
unknown
>
>
;
//单位-详情
export
type
getCompanyInfoByIdType
=
InterFunction
<
{
id
:
number
},
{
address
:
string
;
city
:
string
;
companyName
:
string
;
companyType
:
number
;
companyUserName
:
string
;
district
:
string
;
fullName
:
string
;
id
:
number
;
phoneNum
:
string
;
province
:
string
;
remark
:
string
;
}
>
;
//单位-成员列表
export
type
listCompanyMembersType
=
InterItemFunction
<
{
companyInfoId
:
number
},
{
accountStatus
:
number
;
accountType
:
number
;
companyAuthStatus
:
number
;
companyName
:
string
;
cooperationTagVOS
:
{
createTime
:
string
;
id
:
number
;
tagDescription
:
string
;
tagImg
:
string
;
tagName
:
string
;
tagRequire
:
string
;
}[];
createTime
:
string
;
deleted
:
number
;
email
:
string
;
id
:
number
;
inviteCount
:
number
;
leader
:
number
;
nickName
:
string
;
phoneNum
:
string
;
portType
:
number
;
realNameAuthStatus
:
number
;
remark
:
string
;
source
:
number
;
uid
:
string
;
userImg
:
string
;
userName
:
string
;
userRcdVO
:
{
createTime
:
string
;
id
:
number
;
rcdNickname
:
string
;
rcdUserId
:
number
;
rcdUserName
:
string
;
remark
:
string
;
userAccountId
:
number
;
};
userSex
:
number
;
}[]
>
;
//单位-成员绑定
export
type
bindingCompanyMemberType
=
InterFunction
<
{
companyInfoId
:
number
;
userAccountId
:
number
},
any
>
;
//单位-成员解绑
export
type
unbindCompanyMemberType
=
InterFunction
<
{
companyInfoId
:
number
;
userAccountId
:
number
},
any
>
;
//单位-管理员转让
export
type
transferLeaderType
=
InterFunction
<
{
companyInfoId
:
number
;
fromUserAccountId
:
number
;
toUserAccountId
:
number
},
any
>
;
//账号权限-列表
export
type
listRoleInfoPageType
=
InterItemFunction
<
{
numberOrName
?:
string
},
...
...
src/api/modules/categoryManage.ts
浏览文件 @
3018428e
import
axios
from
'../request'
;
import
{
addPrimaryCategoryType
,
addSubCategoryType
,
categoryDetailsType
,
categoryListRespType
,
categoryListType
,
categoryRelevantType
,
deletePrimaryCategoryType
,
deleteSubCategoryType
,
directoryListType
,
directoryPageListType
,
exchangeType
,
updatePrimaryCategoryType
,
updateSubCategoryType
,
}
from
'~/api/interface/categoryManage'
;
export
class
CategoryManageAPI
{
...
...
@@ -97,4 +105,28 @@ export class CategoryManageAPI {
static
getRelevantBusiness
:
categoryRelevantType
=
(
params
)
=>
{
return
axios
.
get
(
'/pms/classify/queryRelevantBusiness'
,
{
params
});
};
// 分类管理-分类列表(新)
static
getCategoryRespList
:
categoryListRespType
=
(
data
)
=>
axios
.
post
(
'/pms/category/categoryList'
,
data
);
// 分类管理-1级分类新增(新)
static
addPrimaryCategory
:
addPrimaryCategoryType
=
(
data
)
=>
axios
.
post
(
'/pms/category/addPrimaryCategory'
,
data
);
// 分类管理-1级分类编辑(新)
static
updatePrimaryCategory
:
updatePrimaryCategoryType
=
(
data
)
=>
axios
.
post
(
'/pms/category/updatePrimaryCategory'
,
data
);
// 分类管理-1级分类删除(新)
static
deletePrimaryCategory
:
deletePrimaryCategoryType
=
(
params
)
=>
axios
.
get
(
'/pms/category/deletePrimaryCategory'
,
{
params
});
//分类管理-1级分类交换顺序
static
exchangeCategory
:
exchangeType
=
(
data
)
=>
axios
.
post
(
'/pms/category/exchange'
,
data
);
// 分类管理-2级分类新增(新)
static
addSubCategory
:
addSubCategoryType
=
(
data
)
=>
axios
.
post
(
'/pms/category/addSubCategory'
,
data
);
// 分类管理-2级分类编辑(新)
static
updateSubCategory
:
updateSubCategoryType
=
(
data
)
=>
axios
.
post
(
'/pms/category/updateSubCategory'
,
data
);
// 分类管理-2级分类删除(新)
static
deleteSubCategory
:
deleteSubCategoryType
=
(
params
)
=>
axios
.
get
(
'/pms/category/deleteSubCategory'
,
{
params
});
}
src/api/modules/common.ts
浏览文件 @
3018428e
import
axios
from
'../request'
;
import
{
appletQRCodeType
,
BackEndLoginType
,
batchRemoveBannerInfo
,
exchangeBannerInfo
,
getLoginInfoType
,
getUserAccountByPhoneNumType
,
insertBannerInfo
,
insertModuleInfo
,
listBannerInfoPage
,
...
...
@@ -70,4 +73,15 @@ export class CommonAPI {
// V1.0.1-banner-排序交换
static
exchangeBannerInfo
:
exchangeBannerInfo
=
(
params
)
=>
axios
.
post
(
'/release/module/exchangeBannerInfo'
,
params
);
//手机号筛选小程序用户
static
getUserAccountByPhoneNum
:
getUserAccountByPhoneNumType
=
(
params
)
=>
axios
.
get
(
'/userapp/user-account/getUserAccountByPhoneNum'
,
{
params
});
//获取小程序二维码
static
getAppletQRCode
:
appletQRCodeType
=
(
params
)
=>
{
return
axios
.
get
(
'/userapp/wx/getAppletQRCode'
,
{
params
});
};
//获取登录信息
static
getLoginInfo
:
getLoginInfoType
=
(
params
)
=>
axios
.
get
(
'/userapp/temp-auth/getLoginInfo'
,
{
params
});
}
src/api/modules/goodsAPI.ts
浏览文件 @
3018428e
import
{
addGoodsType
,
addMallGoodsType
,
batchOnShelfOrTakeDownType
,
batchRemoveWareInfoType
,
detailGoodsType
,
editGoodsType
,
editMallGoodsType
,
exchangeGoodsInfoType
,
listGoodsType
,
listPageGoodsInfoType
,
mallGoodsDetailsType
,
otherServiceType
,
removeMallGoodsType
,
skuUnitType
,
upOrDownShelfType
,
}
from
'~/api/interface/goodsType'
;
import
axios
from
'../request'
;
...
...
@@ -30,7 +36,7 @@ class GoodsAPI {
};
// 商品-单位
static
getSkuUnit
:
skuUnitType
=
()
=>
{
return
axios
.
get
(
'/pms/goods/getSkuUnit'
);
return
axios
.
get
(
'/pms/
mall/
goods/getSkuUnit'
);
};
// 商品-其它服务列表
static
getOtherServiceList
:
otherServiceType
=
()
=>
{
...
...
@@ -40,13 +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/api/modules/systemManage.ts
浏览文件 @
3018428e
import
{
bindingCompanyMemberType
,
deleteRoleInfoType
,
getCompanyInfoByIdType
,
getSecondDistrictInfo
,
insertBAccountType
,
insertRoleInfoType
,
listBAccountPageType
,
listCompanyAdd
,
listCompanyMembersType
,
listCompanyPage
,
listCompanyRemove
,
listCompanyUpdate
,
...
...
@@ -12,6 +15,8 @@ import {
listRoleInfoPageType
,
listRoleMenuInfoType
,
removeBAccountType
,
transferLeaderType
,
unbindCompanyMemberType
,
updateBAccountType
,
updatePasswordType
,
updateRoleInfoType
,
...
...
@@ -58,10 +63,25 @@ export class SystemManageAPI {
// 单位-删除
static
listCompanyRemove
:
listCompanyRemove
=
(
params
)
=>
axios
.
get
(
'/userapp/company/remove'
,
{
params
});
//单位-详情
static
getCompanyInfoById
:
getCompanyInfoByIdType
=
(
params
)
=>
axios
.
get
(
'/userapp/company/getCompanyInfoById'
,
{
params
});
// 单位-区域
static
getSecondDistrictInfo
:
getSecondDistrictInfo
=
(
params
)
=>
axios
.
get
(
'/pms/webDevice/getSecondDistrictInfo'
,
{
params
});
//单位-成员列表
static
getListCompanyMembers
:
listCompanyMembersType
=
(
params
)
=>
axios
.
get
(
'/userapp/company/listCompanyMembers'
,
{
params
});
//单位-成员绑定
static
bindingCompanyMember
:
bindingCompanyMemberType
=
(
params
)
=>
axios
.
get
(
'/userapp/company/bindingCompanyMember'
,
{
params
});
//单位-成员解除绑定
static
unbindCompanyMember
:
unbindCompanyMemberType
=
(
params
)
=>
axios
.
get
(
'/userapp/company/unbindCompanyMember'
,
{
params
});
//单位-管理员转让
static
transferLeader
:
transferLeaderType
=
(
params
)
=>
axios
.
get
(
'/userapp/company/transferLeader'
,
{
params
});
//账号权限-列表
static
getListRoleInfoPage
:
listRoleInfoPageType
=
(
data
)
=>
...
...
src/api/request.ts
浏览文件 @
3018428e
...
...
@@ -36,7 +36,7 @@ service.interceptors.response.use(
// 当接口返回正常时执行
if
(
status
===
200
)
{
// 如果不报错就直接返回数据
if
(
data
.
code
===
'200'
)
{
if
(
[
'200'
,
'7002'
].
includes
(
data
.
code
)
)
{
return
Promise
.
resolve
(
data
);
}
// 重新登录?
...
...
src/assets/image/qr-code-icon.svg
0 → 100644
浏览文件 @
3018428e
<svg
width=
"50"
height=
"50"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><defs><filter
x=
"-5.7%"
y=
"-8.7%"
width=
"112.4%"
height=
"117.4%"
filterUnits=
"objectBoundingBox"
id=
"a"
><feOffset
dx=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
/><feGaussianBlur
stdDeviation=
"7.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
/><feColorMatrix
values=
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"
in=
"shadowBlurOuter1"
/></filter><path
d=
"M2 0h327.586a1 1 0 01.707.293l49.414 49.414a1 1 0 01.293.707V268a2 2 0 01-2 2H2a2 2 0 01-2-2V2a2 2 0 012-2z"
id=
"b"
/></defs><g
transform=
"translate(-330)"
fill=
"none"
fill-rule=
"evenodd"
><rect
fill=
"#FFF"
width=
"380"
height=
"270"
rx=
"2"
/><path
d=
"M366.833 10.833v2.334h2.334v-2.334h-2.334zm-7 16.334h2.334V29.5h-2.334v-2.333zm9.334-9.334h2.333v2.334h-2.333v-2.334zm-9.334 4.667h2.334v2.333h-2.334V22.5zm4.667-4.667h2.333v2.334H364.5v-2.334zM351.667 8.5H361c.644 0 1.167.522 1.167 1.167V19c0 .644-.523 1.167-1.167 1.167h-9.333A1.167 1.167 0 01350.5 19V9.667c0-.645.522-1.167 1.167-1.167zm1.166 2.333v7h7v-7h-7zm2.334 2.334h2.333V15.5h-2.333v-2.333zm10.5-4.667h4.666c.645 0 1.167.522 1.167 1.167v4.666c0 .645-.522 1.167-1.167 1.167h-4.666a1.167 1.167 0 01-1.167-1.167V9.667c0-.645.522-1.167 1.167-1.167zm0 14h4.666c.645 0 1.167.522 1.167 1.167v4.666c0 .645-.522 1.167-1.167 1.167h-4.666a1.167 1.167 0 01-1.167-1.167v-4.666c0-.645.522-1.167 1.167-1.167zm1.166 2.333v2.334h2.334v-2.334h-2.334zM351.667 22.5h4.666c.645 0 1.167.522 1.167 1.167v4.666c0 .645-.522 1.167-1.167 1.167h-4.666a1.167 1.167 0 01-1.167-1.167v-4.666c0-.645.522-1.167 1.167-1.167zm1.166 2.333v2.334h2.334v-2.334h-2.334z"
opacity=
".5"
fill=
"#000"
fill-opacity=
".9"
/><use
fill=
"#000"
filter=
"url(#a)"
xlink:href=
"#b"
/><use
fill=
"#FFF"
xlink:href=
"#b"
/></g></svg>
\ No newline at end of file
src/components/EditableCell/index.tsx
浏览文件 @
3018428e
import
{
Form
,
InputNumber
,
Input
,
Select
}
from
'antd'
;
import
{
Form
,
InputNumber
,
Input
,
Select
,
Radio
}
from
'antd'
;
import
React
from
'react'
;
import
{
Uploader
}
from
'~/components/uploader'
;
import
{
UploadOutlined
}
from
'@ant-design/icons'
;
...
...
@@ -8,7 +8,7 @@ export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
editing
:
boolean
;
dataIndex
:
string
;
title
:
any
;
inputType
:
'number'
|
'text'
|
'select'
|
'uploader'
;
inputType
:
'number'
|
'text'
|
'select'
|
'uploader'
|
'radio'
|
'textArea'
;
record
:
any
;
index
:
number
;
children
:
React
.
ReactNode
;
...
...
@@ -16,8 +16,10 @@ export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
const
EditableCell
:
React
.
FC
<
EditableCellProps
&
{
selectOption
?:
{
name
:
string
;
id
:
number
}[];
radioOption
?:
{
name
:
string
;
id
:
number
}[];
uploadSuccess
?:
(
record
:
any
,
result
:
any
)
=>
void
;
rules
?:
any
;
maxLength
?:
number
;
}
>
=
({
editing
,
...
...
@@ -27,15 +29,17 @@ const EditableCell: React.FC<
record
,
index
,
selectOption
,
radioOption
,
uploadSuccess
,
children
,
rules
,
maxLength
,
...
restProps
})
=>
{
const
inputNode
=
()
=>
{
switch
(
inputType
)
{
case
'number'
:
return
<
InputNumber
/>;
return
<
InputNumber
placeholder=
{
`请输入${title}`
}
maxLength=
{
maxLength
}
/>;
case
'select'
:
return
(
<
Select
placeholder=
{
`请选择${title}`
}
style=
{
{
textAlign
:
'start'
}
}
>
...
...
@@ -58,8 +62,20 @@ const EditableCell: React.FC<
<
UploadOutlined
/>
</
Uploader
>
);
case
'radio'
:
return
(
<
Radio
.
Group
>
{
radioOption
?.
map
((
v
)
=>
(
<
Radio
value=
{
v
.
id
}
key=
{
v
.
id
}
>
{
v
.
name
}
</
Radio
>
))
}
</
Radio
.
Group
>
);
case
'textArea'
:
return
<
Input
.
TextArea
placeholder=
{
`请输入${title}`
}
maxLength=
{
maxLength
}
showCount
/>;
default
:
return
<
Input
placeholder=
{
`请输入${title}`
}
/>;
return
<
Input
placeholder=
{
`请输入${title}`
}
maxLength=
{
maxLength
}
/>;
}
};
return
(
...
...
src/components/layout/index.scss
浏览文件 @
3018428e
...
...
@@ -113,6 +113,7 @@ $page-background: #f3f6ff;
.logo-img
{
width
:
32px
;
height
:
32px
;
border-radius
:
4px
;
}
.logo-text
{
...
...
src/components/layout/title/index.tsx
浏览文件 @
3018428e
...
...
@@ -5,7 +5,6 @@ import { Button, Dropdown, MenuProps, Modal } from 'antd';
import
Logo
from
'../../../assets/icon/logo_big.png'
;
import
'./index.scss'
;
import
{
REMOVE_MENU
,
REMOVE_MENU_ID
,
SET_COLLAPSE
}
from
'~/store/module/menu'
;
import
{
REMOVE_ROLE_ID
}
from
'~/store/module/userInfo'
;
import
{
useDispatch
,
useSelector
}
from
'react-redux'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
Cookies
from
'js-cookie'
;
...
...
@@ -42,7 +41,6 @@ export function TitleView() {
Cookies
.
remove
(
'SHAREFLY-TOKEN'
);
dispatch
(
REMOVE_MENU
());
dispatch
(
REMOVE_MENU_ID
());
dispatch
(
REMOVE_ROLE_ID
());
},
});
}
}
...
...
@@ -62,8 +60,8 @@ export function TitleView() {
}
}
>
<
div
className=
'layout-logo'
>
<
img
className=
'logo-img'
src=
{
Logo
}
alt=
'云享飞'
/>
<
div
className=
'logo-text'
>
云享飞后台管理
</
div
>
<
img
src=
{
userInfo
.
companyInfoVO
.
brandLogo
||
Logo
}
className=
'logo-img'
alt=
'云享飞'
/>
<
div
className=
'logo-text'
>
{
userInfo
.
companyInfoVO
.
brandName
||
'云享飞管理后台'
}
</
div
>
<
div
onClick=
{
setMenuCollapsed
}
>
<
svg
className=
{
`hamburger ${isActive ? 'is-active' : ''}`
}
...
...
src/pages/categoryManage/categoryList/components/addOrEditCategoryModal/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
Form
,
Input
,
message
,
Modal
,
ModalProps
}
from
'antd'
;
import
{
FC
,
useEffect
,
useState
}
from
'react'
;
import
{
Uploader
}
from
'~/components/uploader'
;
import
{
UploadOutlined
}
from
'@ant-design/icons'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addPrimaryCategoryType
,
categoryListRespType
}
from
'~/api/interface/categoryManage'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
//分类列表返回类型
type
categoryType
=
InterDataType
<
categoryListRespType
>
[
'list'
];
//新增分类请求参数类型
type
addPrimaryCategoryParameter
=
InterReqType
<
addPrimaryCategoryType
>
;
interface
selfProps
{
onCancel
:
()
=>
void
;
onOK
:
()
=>
void
;
currentCategory
:
categoryType
[
0
]
|
undefined
;
}
const
AddOrEditCategoryModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
,
onOK
,
currentCategory
,
})
=>
{
const
[
form
]
=
Form
.
useForm
<
addPrimaryCategoryParameter
>
();
const
[
fileList
,
setFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[]
>
([]);
//上传成功
const
uploadSuccess
=
(
value
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[],
)
=>
{
form
.
setFieldValue
(
'icon'
,
value
[
0
].
url
);
setFileList
([...
value
]);
};
//提交
const
handleOk
=
()
=>
{
form
.
validateFields
().
then
((
values
:
any
)
=>
{
CategoryManageAPI
[
currentCategory
?
'updatePrimaryCategory'
:
'addPrimaryCategory'
]({
...
values
,
id
:
currentCategory
?
currentCategory
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'新增成功'
);
form
.
resetFields
();
setFileList
([]);
onOK
();
}
});
});
};
const
handleCancel
=
()
=>
{
form
.
resetFields
();
setFileList
([]);
onCancel
();
};
useEffect
(()
=>
{
if
(
currentCategory
)
{
form
.
setFieldsValue
({
name
:
currentCategory
.
name
,
icon
:
currentCategory
.
icon
,
description
:
currentCategory
.
description
||
undefined
,
});
setFileList
([
{
name
:
'categoryImg'
,
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
url
:
currentCategory
.
icon
,
},
]);
}
},
[
currentCategory
]);
return
(
<
Modal
open=
{
open
}
title=
{
currentCategory
?
'编辑分类'
:
'新增分类'
}
onCancel=
{
handleCancel
}
onOk=
{
handleOk
}
>
<
Form
wrapperCol=
{
{
span
:
16
}
}
labelCol=
{
{
span
:
4
}
}
form=
{
form
}
>
<
Form
.
Item
label=
'分类名称'
name=
'name'
rules=
{
[{
required
:
true
,
message
:
'请输入分类名称'
}]
}
>
<
Input
placeholder=
'请输入分类名称'
maxLength=
{
15
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'分类图标'
name=
'icon'
rules=
{
[{
required
:
true
,
message
:
'请上传分类图标'
}]
}
>
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
uploadSuccess
}
fileLength=
{
1
}
fileSize=
{
5
}
defaultFileList=
{
fileList
}
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'分类描述'
name=
'description'
>
<
Input
.
TextArea
placeholder=
'请输入分类描述'
rows=
{
4
}
maxLength=
{
70
}
showCount
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
AddOrEditCategoryModal
;
src/pages/categoryManage/categoryList/index.scss
0 → 100644
浏览文件 @
3018428e
.category-list
{
&
-row-bg
{
td
{
background-color
:
rgba
(
$color
:
#000000
,
$alpha
:
0
.1
)
!
important
;
}
}
}
src/pages/categoryManage/categoryList/index.tsx
0 → 100644
浏览文件 @
3018428e
import
SearchBox
from
'~/components/search-box'
;
import
{
Button
,
Form
,
Image
,
message
,
Modal
,
Radio
,
Table
,
Tooltip
}
from
'antd'
;
import
{
ArrowDownOutlined
,
ArrowUpOutlined
,
DownOutlined
,
PlusOutlined
,
RightOutlined
,
}
from
'@ant-design/icons'
;
import
{
categoryListRespType
}
from
'~/api/interface/categoryManage'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
{
InterDataType
,
PaginationProps
}
from
'~/api/interface'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
EditableCell
from
'~/components/EditableCell'
;
import
AddOrEditCategoryModal
from
'./components/addOrEditCategoryModal'
;
import
'./index.scss'
;
import
_
from
'lodash'
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
//分类列表返回类型
type
categoryType
=
InterDataType
<
categoryListRespType
>
[
'list'
];
const
CategoryList
=
()
=>
{
const
[
categoryTableForm
]
=
Form
.
useForm
<
any
>
();
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
<
React
.
Key
[]
>
([]);
//新增,编辑分类弹窗
const
[
addOrEditCategoryModalShow
,
setAddOrEditCategoryModalShow
]
=
useState
<
boolean
>
(
false
);
const
[
currentCategory
,
setCurrentCategory
]
=
useState
<
categoryType
[
0
]
>
();
const
[
loading
,
setLoading
]
=
useState
<
boolean
>
(
false
);
// 编辑的行
const
[
editingKey
,
setEditingKey
]
=
useState
<
number
[]
>
([]);
//展开的行
const
[
expandedRowKeys
,
setExpandedRowKeys
]
=
useState
<
number
[]
>
([]);
const
tableColumns
:
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
rules
?:
any
;
maxLength
?:
number
;
inputType
?:
string
;
})[]
=
[
{
title
:
'分类名称'
,
dataIndex
:
'name'
,
editable
:
true
,
width
:
'20%'
,
ellipsis
:
true
,
onHeaderCell
:
()
=>
({
style
:
{
textAlign
:
'center'
,
},
}),
rules
:
[{
required
:
true
,
message
:
'请输入分类名称'
}],
maxLength
:
15
,
render
:
(
text
:
string
,
record
:
any
)
=>
(
<
span
style=
{
{
marginLeft
:
record
.
subDTOList
&&
record
.
subDTOList
.
length
!=
0
?
'10px'
:
'24px'
,
}
}
>
{
text
}
</
span
>
),
},
{
title
:
'图片'
,
align
:
'center'
,
dataIndex
:
'icon'
,
render
:
(
url
:
string
)
=>
(
url
?
<
Image
src=
{
url
}
width=
{
40
}
height=
{
40
}
/>
:
''
),
},
{
title
:
'描述'
,
align
:
'center'
,
dataIndex
:
'description'
,
editable
:
true
,
width
:
'20%'
,
ellipsis
:
true
,
maxLength
:
70
,
inputType
:
'textArea'
,
render
:
(
text
:
string
)
=>
(
<
Tooltip
placement=
'topLeft'
title=
{
<
span
>
{
text
}
</
span
>
}
>
<
span
>
{
text
}
</
span
>
</
Tooltip
>
),
},
{
title
:
'创建时间'
,
align
:
'center'
,
dataIndex
:
'createTime'
,
},
{
title
:
'操作'
,
onHeaderCell
:
()
=>
({
style
:
{
textAlign
:
'center'
,
},
}),
onCell
:
()
=>
({
style
:
{
textAlign
:
'right'
,
},
}),
render
:
(
_text
:
string
,
record
:
any
)
=>
editingKey
.
some
((
id
:
number
)
=>
id
===
record
.
id
)
?
(
<>
<
Button
type=
'link'
onClick=
{
()
=>
addChildCategorySubmit
(
record
)
}
>
确定
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
addChildCategoryCancel
(
record
)
}
>
取消
</
Button
>
</>
)
:
(
<>
{
record
.
subDTOList
?
(
<
Button
type=
'link'
onClick=
{
()
=>
addChildrenCategory
(
record
)
}
>
新增子分类
</
Button
>
)
:
(
''
)
}
<
Button
type=
'link'
onClick=
{
()
=>
addOrEditCategoryModalShowClick
(
record
)
}
>
编辑
</
Button
>
<
Button
type=
'link'
danger
onClick=
{
()
=>
deleteCategory
(
record
)
}
>
删除
</
Button
>
</>
),
},
];
const
mergedColumns
=
tableColumns
.
map
((
col
:
any
)
=>
{
if
(
!
col
.
editable
)
{
return
col
;
}
return
{
...
col
,
onCell
:
(
record
:
categoryType
[
0
],
index
:
number
)
=>
({
record
,
index
,
dataIndex
:
col
.
dataIndex
,
title
:
col
.
title
,
editing
:
editingKey
.
some
((
id
:
number
)
=>
id
===
record
.
id
),
rules
:
col
.
rules
,
maxLength
:
col
.
maxLength
,
inputType
:
col
.
inputType
,
}),
};
});
const
[
tableData
,
setTableData
]
=
useState
<
categoryType
>
([]);
const
[
allTableData
,
setAllTableData
]
=
useState
<
categoryType
>
([]);
//分页
const
[
pagination
,
setPagination
]
=
useState
<
PaginationProps
&
{
totalCount
:
number
}
>
({
pageNo
:
1
,
pageSize
:
10
,
totalCount
:
0
,
});
//获取分类列表
const
getCategoryList
=
(
query
?:
PaginationProps
,
isAll
?:
boolean
)
=>
{
setLoading
(
true
);
CategoryManageAPI
.
getCategoryRespList
({
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
...
query
,
}).
then
(({
result
})
=>
{
setLoading
(
false
);
if
(
isAll
)
{
setAllTableData
(
result
.
list
?
[...
result
.
list
]
:
[]);
}
else
{
setTableData
(
result
.
list
?
[...
result
.
list
]
:
[]);
pagination
.
totalCount
=
result
.
totalCount
;
setPagination
(
pagination
);
}
});
};
const
paginationChange
=
(
pageNo
:
number
,
pageSize
:
number
)
=>
{
pagination
.
pageNo
=
pageNo
;
pagination
.
pageSize
=
pageSize
;
getCategoryList
();
};
// 排序选择
const
onSelectChange
=
(
record
:
categoryType
[
0
])
=>
{
setSelectedRowKeys
([
record
.
id
]);
};
//新增、编辑分类弹窗
const
addOrEditCategoryModalShowClick
=
(
record
?:
categoryType
[
0
]
|
any
)
=>
{
if
(
record
&&
!
record
.
subDTOList
)
{
setEditingKey
([...
editingKey
,
record
.
id
]);
const
defaultFormVal
=
Object
.
getOwnPropertyNames
(
record
).
reduce
((
pre
:
any
,
cur
:
string
)
=>
{
if
([
'name'
,
'description'
].
includes
(
cur
))
{
pre
[
cur
+
record
.
id
]
=
record
[
cur
];
}
return
pre
;
},
{});
categoryTableForm
.
setFieldsValue
(
defaultFormVal
);
}
else
{
setAddOrEditCategoryModalShow
(
true
);
setCurrentCategory
(
record
?
{
...
record
}
:
undefined
);
}
};
const
addOrEditCategoryModalCancel
=
()
=>
{
setAddOrEditCategoryModalShow
(
false
);
};
const
addOrEditCategoryModalOk
=
()
=>
{
setAddOrEditCategoryModalShow
(
false
);
getCategoryList
();
};
//删除分类
const
deleteCategory
=
(
record
:
categoryType
[
0
])
=>
{
Modal
.
confirm
({
title
:
'分类删除'
,
content
:
'确认删除这条分类?'
,
onOk
:
()
=>
{
console
.
log
(
'当前数据-->'
,
record
);
CategoryManageAPI
[
record
.
subDTOList
?
'deletePrimaryCategory'
:
'deleteSubCategory'
]({
id
:
record
.
id
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'删除成功'
);
if
(
pagination
.
pageNo
!==
1
&&
tableData
.
length
===
1
)
{
pagination
.
pageNo
-=
1
;
}
getCategoryList
();
getCategoryList
({
pageNo
:
1
,
pageSize
:
99999
},
true
);
}
});
},
});
};
//新增子分类
const
addChildrenCategory
=
(
record
:
categoryType
[
0
])
=>
{
const
categoryItemIndex
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
if
(
categoryItemIndex
!==
-
1
)
{
const
selfChildId
:
number
=
Math
.
random
();
tableData
[
categoryItemIndex
].
subDTOList
=
[
...
tableData
[
categoryItemIndex
].
subDTOList
,
{
id
:
selfChildId
,
name
:
''
,
description
:
''
,
categoryPrimaryId
:
record
.
id
},
];
tableData
.
splice
(
categoryItemIndex
,
1
,
tableData
[
categoryItemIndex
]);
setTableData
([...
tableData
]);
setEditingKey
([...
editingKey
,
selfChildId
]);
}
const
isExpend
:
boolean
=
expandedRowKeys
.
some
((
key
:
number
)
=>
key
===
record
.
id
);
if
(
!
isExpend
)
{
setExpandedRowKeys
([...
expandedRowKeys
,
record
.
id
]);
}
};
// 展开监听
const
onExpand
=
(
_expanded
:
boolean
,
record
:
categoryType
[
0
])
=>
{
const
index
=
expandedRowKeys
.
findIndex
((
item
:
any
)
=>
item
===
record
.
id
);
if
(
index
!==
-
1
)
{
expandedRowKeys
.
splice
(
index
,
1
);
}
else
{
expandedRowKeys
.
push
(
record
.
id
);
}
setExpandedRowKeys
([...
expandedRowKeys
]);
};
//提交新增子分类
const
addChildCategorySubmit
=
(
record
:
categoryType
[
0
][
'subDTOList'
][
0
])
=>
{
categoryTableForm
.
validateFields
([
'description'
+
record
.
id
,
'name'
+
record
.
id
])
.
then
((
values
)
=>
{
CategoryManageAPI
[
record
.
name
?
'updateSubCategory'
:
'addSubCategory'
]({
categoryPrimaryId
:
record
.
categoryPrimaryId
,
name
:
values
[
'name'
+
record
.
id
],
description
:
values
[
'description'
+
record
.
id
],
id
:
record
.
name
?
record
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
record
.
name
?
'编辑子分类成功'
:
'新增子分类成功'
);
const
editingKeyIndex
=
editingKey
.
findIndex
((
id
)
=>
id
===
record
.
id
);
if
(
editingKeyIndex
!==
-
1
)
{
editingKey
.
splice
(
editingKeyIndex
,
1
);
setEditingKey
([...
editingKey
]);
getCategoryList
();
}
}
});
});
};
//取消新增子分类
const
addChildCategoryCancel
=
(
record
:
categoryType
[
0
][
'subDTOList'
][
0
])
=>
{
const
tableIndex
:
number
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
categoryPrimaryId
);
if
(
tableIndex
!==
-
1
)
{
const
subDTOIndex
:
number
=
tableData
[
tableIndex
].
subDTOList
.
findIndex
(
(
v
)
=>
v
.
id
===
record
.
id
,
);
if
(
subDTOIndex
!==
-
1
)
{
//新增下的取消
if
(
!
record
.
name
)
{
tableData
[
tableIndex
].
subDTOList
.
splice
(
subDTOIndex
,
1
);
tableData
.
splice
(
tableIndex
,
1
,
tableData
[
tableIndex
]);
setTableData
([...
tableData
]);
}
//新增、编辑下的取消
const
editKeyIndex
=
editingKey
.
findIndex
((
id
)
=>
id
===
record
.
id
);
editingKey
.
splice
(
editKeyIndex
,
1
);
setEditingKey
([...
editingKey
]);
//新增下的取消
if
(
tableData
[
tableIndex
].
subDTOList
.
length
===
0
&&
!
record
.
name
)
{
const
expandedRowKeysIndex
=
expandedRowKeys
.
findIndex
(
(
id
)
=>
id
===
record
.
categoryPrimaryId
,
);
expandedRowKeys
.
splice
(
expandedRowKeysIndex
,
1
);
setExpandedRowKeys
([...
expandedRowKeys
]);
}
}
}
};
// 切换排序
const
handleSort
=
_
.
debounce
(
async
(
from
:
'up'
|
'down'
)
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
message
.
warning
(
'请选择需要排序的数据'
).
then
();
return
;
}
// 当前选项
const
id
=
selectedRowKeys
.
at
(
-
1
);
// 当前索引
const
index
=
allTableData
.
findIndex
((
i
)
=>
i
.
id
===
id
);
// 当前表格中的索引
const
tableIndex
=
tableData
.
findIndex
((
i
)
=>
i
.
id
===
id
);
// 第一条数据不能上移
if
(
index
===
0
&&
from
===
'up'
)
{
message
.
warning
(
'已是第一条数据'
).
then
();
return
;
}
// 最后一条数据不能下移
if
(
index
===
allTableData
.
length
-
1
&&
from
===
'down'
)
{
message
.
warning
(
'已是最后一条数据'
).
then
();
return
;
}
// 转换位置
const
res
=
await
CategoryManageAPI
.
exchangeCategory
(
from
===
'up'
?
[
{
id
:
allTableData
[
index
-
1
].
id
,
sort
:
allTableData
[
index
-
1
].
sort
},
{
id
:
allTableData
[
index
].
id
,
sort
:
allTableData
[
index
].
sort
},
]
:
[
{
id
:
allTableData
[
index
+
1
].
id
,
sort
:
allTableData
[
index
+
1
].
sort
},
{
id
:
allTableData
[
index
].
id
,
sort
:
allTableData
[
index
].
sort
},
],
);
if
(
res
&&
res
.
code
===
'200'
)
{
message
.
success
(
'操作成功'
).
then
();
// 如果是当前页的第一条数据
if
(
tableIndex
===
0
&&
from
===
'up'
)
{
paginationChange
(
pagination
.
pageNo
-
1
,
pagination
.
pageSize
);
getCategoryList
({
pageNo
:
1
,
pageSize
:
9999
},
true
);
return
;
}
// 如果是当前页的最后一条数据
if
(
tableIndex
===
tableData
.
length
-
1
&&
from
===
'down'
)
{
paginationChange
(
pagination
.
pageNo
+
1
,
pagination
.
pageSize
);
getCategoryList
({
pageNo
:
1
,
pageSize
:
9999
},
true
);
return
;
}
paginationChange
(
pagination
.
pageNo
,
pagination
.
pageSize
);
getCategoryList
({
pageNo
:
1
,
pageSize
:
9999
},
true
);
}
},
500
);
//防抖
// const debounce:<T extends ()=>T>= (func: T, delay: number)=> {
// let timeout: NodeJS.Timeout;
//
// return function (this: ThisParameterType<T>, ...args: Parameters<T>): ReturnType<T> {
// clearTimeout(timeout);
//
// timeout = setTimeout(() => {
// func.apply(this, args);
// }, delay);
// } as T;
// }
useEffect
(()
=>
{
getCategoryList
();
getCategoryList
({
pageNo
:
1
,
pageSize
:
99999
},
true
);
},
[]);
return
(
<
div
className=
'category-list'
>
<
SearchBox
child=
{
<>
<
Button
icon=
{
<
PlusOutlined
/>
}
type=
'primary'
onClick=
{
()
=>
addOrEditCategoryModalShowClick
()
}
>
新增分类
</
Button
>
<
Button
icon=
{
<
ArrowUpOutlined
/>
}
type=
'primary'
onClick=
{
()
=>
handleSort
(
'up'
)
}
></
Button
>
<
Button
icon=
{
<
ArrowDownOutlined
/>
}
type=
'primary'
onClick=
{
()
=>
handleSort
(
'down'
)
}
></
Button
>
</>
}
/>
<
Form
form=
{
categoryTableForm
}
component=
{
false
}
>
<
Table
bordered
rowSelection=
{
{
hideSelectAll
:
true
,
selectedRowKeys
,
renderCell
:
(
checked
:
boolean
,
record
:
categoryType
[
0
])
=>
{
console
.
log
(
'选中-->'
,
checked
);
return
(
<>
{
record
.
subDTOList
?
(
<
Radio
onChange=
{
()
=>
onSelectChange
(
record
)
}
checked=
{
checked
}
/>
)
:
(
''
)
}
</>
);
},
}
}
loading=
{
loading
}
rowKey=
'id'
columns=
{
mergedColumns
}
dataSource=
{
tableData
}
rowClassName=
{
(
record
:
categoryType
[
0
])
=>
{
if
(
record
.
subDTOList
)
{
return
''
;
}
return
'category-list-row-bg'
;
}
}
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} 条数据`
,
}
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
expandedRowKeys=
{
expandedRowKeys
}
onExpand=
{
(
expanded
:
boolean
,
record
:
categoryType
[
0
])
=>
onExpand
(
expanded
,
record
)
}
expandable=
{
{
rowExpandable
:
(
record
)
=>
{
if
(
record
.
subDTOList
&&
record
.
subDTOList
.
length
!=
0
)
{
return
true
;
}
return
false
;
},
expandIcon
:
({
expanded
,
onExpand
,
record
})
=>
{
if
(
expanded
&&
record
.
subDTOList
&&
record
.
subDTOList
.
length
!=
0
)
{
return
<
DownOutlined
onClick=
{
(
e
)
=>
onExpand
(
record
,
e
)
}
/>;
}
if
(
record
.
subDTOList
&&
record
.
subDTOList
.
length
!=
0
)
{
return
<
RightOutlined
onClick=
{
(
e
)
=>
onExpand
(
record
,
e
)
}
/>;
}
return
<></>;
},
}
}
childrenColumnName=
'subDTOList'
/>
</
Form
>
{
/*新增,编辑分类*/
}
<
AddOrEditCategoryModal
open=
{
addOrEditCategoryModalShow
}
onCancel=
{
addOrEditCategoryModalCancel
}
onOK=
{
addOrEditCategoryModalOk
}
currentCategory=
{
currentCategory
}
/>
</
div
>
);
};
export
default
CategoryList
;
src/pages/common/login/index.scss
浏览文件 @
3018428e
...
...
@@ -17,8 +17,16 @@ body {
box-shadow
:
0px
20px
30px
rgba
(
112
,
158
,
254
,
0
.45
);
display
:
flex
;
flex-wrap
:
wrap
;
position
:
relative
;
.login-flex
{
flex
:
1
;
position
:
relative
;
.qr-code-wrap
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
}
}
.login-content
{
text-align
:
center
;
...
...
@@ -37,6 +45,7 @@ body {
color
:
rgba
(
0
,
0
,
0
,
0
.5
);
}
}
.login-form
{
.login-image
{
margin
:
62px
auto
46px
;
...
...
@@ -79,5 +88,16 @@ body {
box-shadow
:
3px
3px
30px
#dddddd
;
}
}
.qrCode-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
}
.account-login-operate
{
position
:
absolute
;
top
:
10px
;
right
:
10px
;
}
}
}
src/pages/common/login/index.tsx
浏览文件 @
3018428e
import
{
Button
,
Checkbox
,
Form
,
I
nput
,
messag
e
}
from
'antd'
;
import
{
useEffect
}
from
'react'
;
import
{
Button
,
Checkbox
,
Form
,
I
mage
,
Input
,
message
,
QRCod
e
}
from
'antd'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
{
LockOutlined
,
UserOutlined
}
from
'@ant-design/icons'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
Cookies
from
'js-cookie'
;
...
...
@@ -10,18 +10,27 @@ import { CommonAPI } from '~/api';
import
{
useDispatch
}
from
'react-redux'
;
import
{
SET_USERINFO
}
from
'~/store/module/userInfo'
;
import
{
authRouterList
}
from
'~/router'
;
import
qrCodeIcon
from
'~/assets/image/qr-code-icon.svg'
;
// 请求的类型
type
ReqType
=
InterReqType
<
BackEndLoginType
>
;
//定时器暂存
let
time
:
NodeJS
.
Timer
;
function
LoginView
()
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment
// @ts-ignore
const
navigate
=
useNavigate
();
// redux
const
dispatch
=
useDispatch
();
// 表单钩子
const
[
form
]
=
Form
.
useForm
<
ReqType
>
();
//是否二维码登录
const
[
isLoginCode
,
setIsLoginCode
]
=
useState
<
boolean
>
(
false
);
//获取小程序二维码唯一标识
const
[
randomLoginCode
]
=
useState
<
string
>
(
parseInt
(
String
(
Math
.
random
()
*
10001
),
10
)
+
''
);
//小程序二维码地址
const
[
qrCodeUrl
,
setQrCodeUrl
]
=
useState
<
string
>
(
''
);
// 提交数据
const
onFinish
=
async
(
values
:
ReqType
)
=>
{
const
res
=
await
CommonAPI
.
BackEndLogin
({
...
...
@@ -29,6 +38,7 @@ function LoginView() {
passWord
:
values
?.
passWord
,
});
if
(
res
&&
res
.
code
===
'200'
)
{
message
.
success
(
'登录成功'
);
const
{
token
}
=
res
.
result
;
await
Cookies
.
set
(
'SHAREFLY-TOKEN'
,
token
);
// 记住密码
...
...
@@ -49,7 +59,50 @@ function LoginView() {
message
.
error
(
'登录失败,请检查账号信息'
);
}
};
//显示二维码登录方式
const
changeLoginUseEvent
=
()
=>
{
//第一次二维码
if
(
!
isLoginCode
&&
!
qrCodeUrl
)
{
CommonAPI
.
getAppletQRCode
({
page
:
'page-identity/identity-empower/index'
,
scene
:
`randomLoginCode=
${
randomLoginCode
}
&port=1`
,
}).
then
(({
result
})
=>
{
setQrCodeUrl
(
result
?
`data:image/png;base64,
${
result
}
`
:
''
);
time
=
setInterval
(()
=>
{
getLoginInfo
();
},
1000
);
});
}
else
if
(
!
isLoginCode
&&
qrCodeUrl
)
{
time
=
setInterval
(()
=>
{
getLoginInfo
();
},
1000
);
}
else
{
if
(
time
)
{
clearInterval
(
time
);
}
}
setIsLoginCode
(
!
isLoginCode
);
};
//二维码登录
const
getLoginInfo
=
()
=>
{
CommonAPI
.
getLoginInfo
({
randomLoginCode
}).
then
(
async
({
result
,
code
})
=>
{
if
(
code
===
'200'
)
{
clearInterval
(
time
);
message
.
success
(
'登录成功'
);
const
{
token
}
=
result
;
await
Cookies
.
set
(
'SHAREFLY-TOKEN'
,
token
);
dispatch
(
SET_USERINFO
(
result
));
localStorage
.
setItem
(
'roleId'
,
result
.
roleInfo
.
id
.
toString
());
authRouterList
().
then
((
value
:
any
)
=>
{
if
(
value
.
length
)
{
navigate
({
pathname
:
value
[
0
].
children
.
find
((
v
:
any
)
=>
!
v
.
meta
.
hidden
)?.
path
});
}
else
{
message
.
warning
(
'请先配置权限'
);
}
});
}
});
};
// componentDidMount
useEffect
(()
=>
{
// 是否保存密码
...
...
@@ -62,65 +115,96 @@ function LoginView() {
remember
:
Boolean
(
Cookies
.
get
(
'remember'
)),
});
},
[]);
return
(
<
div
className=
'login-warp'
>
<
div
className=
'login-view'
>
<
div
className=
'login-flex login-content'
>
<
div
className=
'login-title'
>
欢迎来到
</
div
>
<
div
className=
'login-text'
>
科比特 ·
云享飞管理平台
</
div
>
<
div
className=
'login-title'
></
div
>
<
div
className=
'login-text'
>
云享飞管理平台
</
div
>
<
div
className=
'login-detail'
>
让天空为世界所用
</
div
>
</
div
>
<
div
className=
'login-flex login-form'
>
<
div
className=
'login-image'
/>
<
div
className=
'login-input'
>
<
Form
name=
'basic'
form=
{
form
}
wrapperCol=
{
{
span
:
16
,
offset
:
4
}
}
initialValues=
{
{
remember
:
true
}
}
onFinish=
{
onFinish
}
autoComplete=
'off'
>
<
Form
.
Item
name=
'accountNo'
rules=
{
[{
required
:
true
,
message
:
'请输入用户名'
}]
}
>
<
Input
size=
'large'
prefix=
{
<
UserOutlined
/>
}
placeholder=
'请输入账号'
allowClear
/>
</
Form
.
Item
>
{
isLoginCode
?
(
<
div
className=
'qr-code-wrap'
>
{
qrCodeUrl
?
(
<
Image
src=
{
qrCodeUrl
}
alt=
''
width=
{
200
}
height=
{
200
}
preview=
{
false
}
/>
)
:
(
<
QRCode
value=
'https://ant.design/'
status=
'loading'
/>
)
}
</
div
>
)
:
(
<>
<
div
className=
'login-image'
/>
<
div
className=
'login-input'
>
<
Form
name=
'basic'
form=
{
form
}
wrapperCol=
{
{
span
:
16
,
offset
:
4
}
}
initialValues=
{
{
remember
:
true
}
}
onFinish=
{
onFinish
}
autoComplete=
'off'
>
<
Form
.
Item
name=
'accountNo'
rules=
{
[{
required
:
true
,
message
:
'请输入用户名'
}]
}
>
<
Input
size=
'large'
prefix=
{
<
UserOutlined
/>
}
placeholder=
'请输入账号'
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
name=
'passWord'
className=
'login-password'
rules=
{
[{
required
:
true
,
message
:
'请输入密码'
}]
}
>
<
Input
.
Password
size=
'large'
prefix=
{
<
LockOutlined
/>
}
placeholder=
'请输入密码'
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
name=
'passWord'
className=
'login-password'
rules=
{
[{
required
:
true
,
message
:
'请输入密码'
}]
}
>
<
Input
.
Password
size=
'large'
prefix=
{
<
LockOutlined
/>
}
placeholder=
'请输入密码'
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
name=
'remember'
className=
'login-remember'
valuePropName=
'checked'
wrapperCol=
{
{
offset
:
4
,
span
:
8
}
}
>
<
Checkbox
>
记住密码
</
Checkbox
>
</
Form
.
Item
>
<
Form
.
Item
name=
'remember'
className=
'login-remember'
valuePropName=
'checked'
wrapperCol=
{
{
offset
:
4
,
span
:
8
}
}
>
<
Checkbox
>
记住密码
</
Checkbox
>
</
Form
.
Item
>
<
Form
.
Item
wrapperCol=
{
{
offset
:
7
,
span
:
15
}
}
>
<
Button
type=
'primary'
htmlType=
'submit'
shape=
'round'
size=
'large'
className=
'login-submit'
>
登录
</
Button
>
</
Form
.
Item
>
</
Form
>
</
div
>
<
Form
.
Item
wrapperCol=
{
{
offset
:
7
,
span
:
15
}
}
>
<
Button
type=
'primary'
htmlType=
'submit'
shape=
'round'
size=
'large'
className=
'login-submit'
>
登录
</
Button
>
</
Form
.
Item
>
</
Form
>
</
div
>
</>
)
}
</
div
>
{
isLoginCode
?
(
<
div
className=
'account-login-operate'
>
<
Button
type=
'link'
onClick=
{
changeLoginUseEvent
}
>
使用账号登录
</
Button
>
</
div
>
)
:
(
<
div
className=
'qrCode-icon'
>
<
img
src=
{
qrCodeIcon
}
alt=
'icon'
onClick=
{
changeLoginUseEvent
}
/>
</
div
>
)
}
</
div
>
</
div
>
);
...
...
src/pages/customManage/customList/index.tsx
浏览文件 @
3018428e
...
...
@@ -239,7 +239,7 @@ function CustomListView() {
label: '手机号',
name: 'phoneNum',
type: 'input',
placeholder: '请输入
用户账
号',
placeholder: '请输入
手机
号',
},
{
label: '来源',
...
...
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/baseInfo/index.scss
0 → 100644
浏览文件 @
3018428e
.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
0 → 100644
浏览文件 @
3018428e
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
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'
];
interface
selfProps
{
ref
:
any
;
}
//基本信息表单类型
export
type
baseInfoType
=
{
tradeName
:
string
;
description
:
string
;
mainImgList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[];
subImgList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[];
videoList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[];
categoryId
:
number
[];
shelfStatus
:
number
;
labelShow
:
number
;
goodsLabel
:
string
;
};
const
BaseInfo
=
forwardRef
<
any
,
selfProps
>
((
_props
,
ref
)
=>
{
const
[
baseInfoForm
]
=
Form
.
useForm
<
baseInfoType
>
();
const
[
labelShow
,
setLabelShow
]
=
useState
<
boolean
>
(
false
);
//分类列表
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//主图
const
[
mainFileList
,
setMainFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[]
>
([]);
//副图
const
[
subFileList
,
setSubFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[]
>
([]);
//视频
const
[
videoFileList
,
setVideoFileList
]
=
useState
<
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[]
>
([]);
useImperativeHandle
(
ref
,
()
=>
({
getForm
:
()
=>
baseInfoForm
,
setLabelShow
:
(
value
:
boolean
)
=>
setLabelShow
(
value
),
mediaData
:
{
setMainFileList
,
setSubFileList
,
setVideoFileList
,
},
}));
//标签选中监听
const
labelRadioChange
=
(
e
:
RadioChangeEvent
)
=>
{
setLabelShow
(
!!
e
.
target
.
value
);
};
//上传结果
const
uploadSuccess
=
(
fileList
:
{
id
:
number
;
name
:
string
;
uid
:
number
;
url
:
string
;
}[],
type
:
string
,
)
=>
{
switch
(
type
)
{
case
'mainImgList'
:
setMainFileList
(
fileList
);
baseInfoForm
.
setFieldValue
(
'mainImgList'
,
fileList
);
break
;
case
'subImgList'
:
setSubFileList
(
fileList
);
baseInfoForm
.
setFieldValue
(
'subImgList'
,
fileList
);
break
;
case
'videoList'
:
setVideoFileList
(
fileList
);
baseInfoForm
.
setFieldValue
(
'videoList'
,
fileList
);
break
;
default
:
break
;
}
};
//分类列表
const
getCategoryList
=
()
=>
{
CategoryManageAPI
.
getCategoryRespList
({
pageNo
:
1
,
pageSize
:
99999
}).
then
(({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
});
};
//视频删除
const
deleteVideo
=
()
=>
{
setVideoFileList
([]);
baseInfoForm
.
setFieldValue
(
'videoList'
,
undefined
);
};
useEffect
(()
=>
{
getCategoryList
();
},
[]);
return
(
<
div
className=
'base-info'
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
8
}
}
form=
{
baseInfoForm
}
initialValues=
{
{
labelShow
:
0
,
shelfStatus
:
1
}
}
>
<
Form
.
Item
label=
'商品名称'
name=
'tradeName'
rules=
{
[{
required
:
true
,
message
:
'请输入商品名称'
}]
}
>
<
Input
placeholder=
'请输入商品名称'
maxLength=
{
50
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品描述'
name=
'description'
rules=
{
[{
required
:
true
,
message
:
'请输入商品描述'
}]
}
>
<
Input
.
TextArea
rows=
{
4
}
placeholder=
'请输入商品描述'
maxLength=
{
70
}
showCount
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品主图'
name=
'mainImgList'
rules=
{
[{
required
:
true
,
message
:
'请上传商品主图'
}]
}
>
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
(
fileList
)
=>
uploadSuccess
(
fileList
,
'mainImgList'
)
}
defaultFileList=
{
mainFileList
}
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品副图'
name=
'subImgList'
>
<
Uploader
fileUpload
listType=
'picture-card'
onChange=
{
(
fileList
)
=>
uploadSuccess
(
fileList
,
'subImgList'
)
}
defaultFileList=
{
subFileList
}
fileLength=
{
4
}
>
<
UploadOutlined
/>
</
Uploader
>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品视频'
name=
'videoList'
>
{
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=
'商品分类'
name=
'categoryId'
rules=
{
[{
required
:
true
,
message
:
'请选择商品分类'
}]
}
>
<
Cascader
placeholder=
'请选择商品分类'
options=
{
categoryList
}
fieldNames=
{
{
label
:
'name'
,
value
:
'id'
,
children
:
'subDTOList'
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'商品状态'
name=
'shelfStatus'
rules=
{
[{
required
:
true
,
message
:
'请选择商品状态'
}]
}
>
<
Select
placeholder=
'请选择商品状态'
>
<
Select
.
Option
value=
{
1
}
>
上架
</
Select
.
Option
>
<
Select
.
Option
value=
{
0
}
>
下架
</
Select
.
Option
>
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
'显示标签'
name=
'labelShow'
>
<
Radio
.
Group
onChange=
{
labelRadioChange
}
>
<
Radio
value=
{
1
}
>
显示
</
Radio
>
<
Radio
value=
{
0
}
>
不显示
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
{
labelShow
?
(
<
Form
.
Item
label=
'商品标签'
name=
'goodsLabel'
rules=
{
[{
required
:
true
,
message
:
'请输入商品标签'
}]
}
>
<
Input
placeholder=
'请输入商品标签'
maxLength=
{
10
}
/>
</
Form
.
Item
>
)
:
(
''
)
}
</
Form
>
</
div
>
);
});
export
default
BaseInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/introduceInfo/index.tsx
0 → 100644
浏览文件 @
3018428e
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
||
''
);
};
return
(
<
div
className=
'introduce-info'
>
<
RichText
richTextContent=
{
introduceInfo
}
height=
{
400
}
onChange=
{
richTextOnChange
}
/>
</
div
>
);
};
export
default
IntroduceInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuAddOrEditModal/index.tsx
0 → 100644
浏览文件 @
3018428e
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'
;
type
EditableTableProps
=
Parameters
<
typeof
Table
>
[
0
];
type
ColumnTypes
=
Exclude
<
EditableTableProps
[
'columns'
],
undefined
>
;
//商品sku规格类型
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//商品sku规格值类型
type
goodsSpecValuesType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
][
'goodsSpecValuesList'
][
0
]
&
{
fileList
:
any
};
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
interface
selfProps
{
onCancel
:
()
=>
void
;
onHandleOk
:
(
value
:
goodsSpecType
)
=>
void
;
skuUnitList
:
unitType
;
currentSku
:
goodsSpecType
|
undefined
;
}
const
SkuAddOrEditModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
,
onHandleOk
,
skuUnitList
,
currentSku
,
})
=>
{
const
[
goodsSpecForm
]
=
Form
.
useForm
<
Omit
<
goodsSpecType
,
'goodsSpecValuesList'
>>
();
const
[
goodsSpecValuesForm
]
=
Form
.
useForm
<
goodsSpecValuesType
>
();
//销售正则价格校验
const
salePriceValidator
=
(
_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
channelPriceValidator
=
(
_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
.
resolve
();
}
};
//库存正则校验
const
stockPriceValidator
=
(
_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
.
reject
(
new
Error
(
'请输入库存'
));
}
};
const
[
tableData
,
setTableData
]
=
useState
<
goodsSpecValuesType
[]
>
([
{
id
:
Math
.
random
(),
channelPrice
:
0
,
partNo
:
''
,
salePrice
:
0
,
showPrice
:
1
,
specValueImage
:
''
,
specValueName
:
''
,
stock
:
0
,
fileList
:
[],
},
]);
const
defaultColumns
:
(
ColumnTypes
[
number
]
&
{
editable
?:
boolean
;
dataIndex
?:
string
;
inputType
?:
string
;
radioOption
?:
{
name
:
string
;
id
:
number
}[];
rules
?:
any
;
maxLength
?:
number
;
})[]
=
[
{
title
:
'序号'
,
align
:
'center'
,
width
:
'5%'
,
render
:
(
_text
:
string
,
_record
:
any
,
index
:
number
)
=>
index
+
1
,
},
{
title
:
'图片'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'specValueImage'
,
inputType
:
'uploader'
,
},
{
title
:
'选项名称'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'specValueName'
,
rules
:
[{
required
:
true
,
message
:
'请输入选项名称'
}],
maxLength
:
30
,
},
{
title
:
'料号'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'partNo'
,
maxLength
:
30
,
},
{
title
:
'销售价'
,
align
:
'center'
,
editable
:
true
,
dataIndex
:
'salePrice'
,
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
:
true
,
validator
:
stockPriceValidator
}],
inputType
:
'number'
,
},
{
title
:
'是否显示'
,
editable
:
true
,
align
:
'center'
,
dataIndex
:
'showPrice'
,
inputType
:
'radio'
,
width
:
'18%'
,
radioOption
:
[
{
id
:
1
,
name
:
'显示'
},
{
id
:
0
,
name
:
'不显示'
},
],
},
{
title
:
'操作'
,
align
:
'center'
,
width
:
'10%'
,
render
:
(
_text
:
string
,
_record
:
any
,
index
:
number
)
=>
(
<>
{
tableData
.
length
-
1
===
index
?
(
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
addSkuDataRowClick
}
style=
{
{
marginRight
:
'10px'
}
}
></
Button
>
)
:
(
''
)
}
{
index
?
(
<
Button
type=
'primary'
icon=
{
<
MinusOutlined
/>
}
onClick=
{
()
=>
removeSkuDataRowClick
(
index
)
}
></
Button
>
)
:
(
''
)
}
</>
),
},
];
const
columns
=
defaultColumns
.
map
((
col
)
=>
{
if
(
!
col
.
editable
)
{
return
col
;
}
return
{
...
col
,
onCell
:
(
record
:
any
)
=>
({
record
,
dataIndex
:
col
.
dataIndex
,
title
:
col
.
title
,
editing
:
col
.
editable
,
radioOption
:
col
.
radioOption
,
inputType
:
col
.
inputType
,
uploadSuccess
:
col
.
inputType
===
'uploader'
?
uploadSuccess
:
undefined
,
rules
:
col
.
rules
,
}),
};
});
const
handleCancel
=
()
=>
{
clearForm
();
onCancel
();
};
const
clearForm
=
()
=>
{
goodsSpecForm
.
resetFields
();
goodsSpecValuesForm
.
resetFields
();
const
list
=
[
{
id
:
Math
.
random
(),
channelPrice
:
0
,
partNo
:
''
,
salePrice
:
0
,
showPrice
:
1
,
specValueImage
:
''
,
specValueName
:
''
,
stock
:
0
,
fileList
:
[],
},
];
const
obj
=
list
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
Object
.
getOwnPropertyNames
(
cur
).
forEach
((
key
:
string
)
=>
{
if
([
'showPrice'
].
includes
(
key
))
{
pre
[
key
+
cur
.
id
]
=
cur
[
key
];
}
});
return
pre
;
},
{});
goodsSpecValuesForm
.
setFieldsValue
(
obj
);
setTableData
(
list
);
};
//新增一行规格值
const
addSkuDataRowClick
=
()
=>
{
const
list
=
[
...
tableData
,
{
id
:
Math
.
random
(),
channelPrice
:
0
,
partNo
:
''
,
salePrice
:
0
,
showPrice
:
1
,
specValueImage
:
''
,
specValueName
:
''
,
stock
:
0
,
fileList
:
[],
},
];
setTableData
(
list
);
const
obj
=
list
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
Object
.
getOwnPropertyNames
(
cur
).
forEach
((
key
:
string
)
=>
{
if
([
'showPrice'
].
includes
(
key
))
{
pre
[
key
+
cur
.
id
]
=
cur
[
key
];
}
});
return
pre
;
},
{});
goodsSpecValuesForm
.
setFieldsValue
(
obj
);
};
//移除一行规格值
const
removeSkuDataRowClick
=
(
index
:
number
)
=>
{
tableData
.
splice
(
index
,
1
);
setTableData
([...
tableData
]);
};
//规格值上传图片返回
const
uploadSuccess
=
(
record
:
goodsSpecValuesType
,
value
:
any
)
=>
{
const
tableIndex
:
number
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
goodsSpecValuesForm
.
setFieldValue
(
'specValueImage'
+
record
.
id
,
value
.
length
?
value
[
0
].
url
:
undefined
,
);
if
(
tableIndex
!==
-
1
)
{
tableData
[
tableIndex
].
fileList
=
value
;
setTableData
([...
tableData
]);
}
};
//提交
const
handleOk
=
()
=>
{
Promise
.
all
([
goodsSpecForm
.
validateFields
(),
goodsSpecValuesForm
.
validateFields
()]).
then
(
(
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
))
{
pre
[
cur
]
=
values
[
1
][
cur
+
v
.
id
];
pre
.
id
=
v
.
id
;
}
return
pre
;
},
{});
});
onHandleOk
({
...
values
[
0
],
goodsSpecValuesList
,
id
:
currentSku
?.
id
||
Math
.
random
()
});
clearForm
();
},
);
};
useEffect
(()
=>
{
const
obj
=
tableData
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
Object
.
getOwnPropertyNames
(
cur
).
forEach
((
key
:
string
)
=>
{
if
([
'showPrice'
].
includes
(
key
))
{
pre
[
key
+
cur
.
id
]
=
cur
[
key
];
}
});
return
pre
;
},
{});
goodsSpecValuesForm
.
setFieldsValue
(
obj
);
if
(
currentSku
)
{
goodsSpecForm
.
setFieldsValue
(
filterObjAttr
(
currentSku
,
[
'goodsSpecValuesList'
]));
setTableData
(
currentSku
.
goodsSpecValuesList
.
map
((
v
:
any
)
=>
({
...
v
,
fileList
:
v
.
specValueImage
?
[
{
id
:
Math
.
random
(),
uid
:
Math
.
random
(),
url
:
v
.
specValueImage
,
name
:
'specValueImage'
,
},
]
:
[],
})),
);
const
goodsSpecValuesObj
=
currentSku
.
goodsSpecValuesList
.
reduce
((
pre
:
any
,
cur
:
any
)
=>
{
Object
.
getOwnPropertyNames
(
cur
)
.
filter
((
key
:
string
)
=>
key
!==
'id'
)
.
forEach
((
key
:
string
)
=>
{
pre
[
key
+
cur
.
id
]
=
cur
[
key
];
});
return
pre
;
},
{});
goodsSpecValuesForm
.
setFieldsValue
(
goodsSpecValuesObj
);
}
},
[
currentSku
]);
return
(
<
Modal
open=
{
open
}
title=
{
currentSku
?
'编辑规格'
:
'添加规格'
}
width=
{
1100
}
onCancel=
{
handleCancel
}
onOk=
{
handleOk
}
>
<
Form
labelCol=
{
{
span
:
2
}
}
wrapperCol=
{
{
span
:
22
}
}
initialValues=
{
{
chooseType
:
0
,
must
:
0
,
skuUnitId
:
skuUnitList
[
0
]?.
id
||
undefined
}
}
form=
{
goodsSpecForm
}
>
<
Form
.
Item
label=
'规格名称'
name=
'specName'
rules=
{
[{
required
:
true
,
message
:
'请输入规格名称'
}]
}
>
<
Input
placeholder=
'请输入规格名称'
maxLength=
{
30
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'规格值'
>
<
Form
component=
{
false
}
form=
{
goodsSpecValuesForm
}
>
<
Table
rowKey=
'id'
columns=
{
columns
as
ColumnTypes
}
components=
{
{
body
:
{
cell
:
EditableCell
,
},
}
}
bordered
dataSource=
{
tableData
}
pagination=
{
false
}
></
Table
>
</
Form
>
</
Form
.
Item
>
<
Form
.
Item
label=
'选择方式'
name=
'chooseType'
>
<
Radio
.
Group
>
<
Radio
value=
{
0
}
>
单选
</
Radio
>
<
Radio
value=
{
1
}
>
多选
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
'是否必选'
name=
'must'
>
<
Radio
.
Group
>
<
Radio
value=
{
0
}
>
非必选
</
Radio
>
<
Radio
value=
{
1
}
>
必选
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
'规格单位'
name=
'skuUnitId'
rules=
{
[{
required
:
true
,
message
:
'请选择规格单位'
}]
}
>
<
Select
placeholder=
'请选择规格单位'
>
{
skuUnitList
.
map
((
v
)
=>
(
<
Select
.
Option
value=
{
v
.
id
}
key=
{
v
.
id
}
>
{
v
.
unitName
}
</
Select
.
Option
>
))
}
</
Select
>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
SkuAddOrEditModal
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/components/skuInfo/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
Button
,
Popconfirm
,
Table
,
Tag
}
from
'antd'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
{
FC
,
useState
}
from
'react'
;
import
{
InterDataType
,
InterReqType
,
PaginationProps
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
//商品sku规格类型
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
interface
selfProps
{
addOrEditSkuClick
:
()
=>
void
;
skuTableData
:
goodsSpecType
[];
skuUnitList
:
unitType
;
deleteSkuClick
:
(
record
:
goodsSpecType
)
=>
void
;
editSkuClick
:
(
record
:
goodsSpecType
)
=>
void
;
}
const
SkuInfo
:
FC
<
selfProps
>
=
({
addOrEditSkuClick
,
skuTableData
,
skuUnitList
,
deleteSkuClick
,
editSkuClick
,
})
=>
{
const
tableColumns
:
ColumnsType
<
goodsSpecType
>
=
[
{
title
:
'序号'
,
align
:
'center'
,
render
:
(
_text
:
string
,
_record
,
index
:
number
)
=>
index
+
1
,
},
{
title
:
'规格名称'
,
align
:
'center'
,
dataIndex
:
'specName'
,
},
{
title
:
'选择方式'
,
align
:
'center'
,
dataIndex
:
'chooseType'
,
render
:
(
text
:
number
)
=>
(
text
?
'多选'
:
'单选'
),
},
{
title
:
'是否必选'
,
align
:
'center'
,
dataIndex
:
'must'
,
render
:
(
text
:
number
)
=>
(
text
?
'必选'
:
'非必选'
),
},
{
title
:
'规格单位'
,
align
:
'center'
,
dataIndex
:
'skuUnitId'
,
render
:
(
text
:
number
)
=>
skuUnitList
.
find
((
v
)
=>
v
.
id
===
text
)?.
unitName
||
''
,
},
{
title
:
'规格值'
,
align
:
'center'
,
dataIndex
:
'goodsSpecValuesList'
,
render
:
(
text
:
goodsSpecType
[
'goodsSpecValuesList'
])
=>
text
.
map
((
v
)
=>
(
<
Tag
key=
{
v
.
id
}
>
{
v
.
specValueName
}
{
v
.
partNo
?
`(${v.partNo})`
:
''
}
</
Tag
>
)),
},
{
title
:
'操作'
,
align
:
'center'
,
render
:
(
_text
:
string
,
record
)
=>
(
<>
<
Button
type=
'link'
onClick=
{
()
=>
editSkuClick
(
record
)
}
>
编辑
</
Button
>
<
Popconfirm
placement=
'topLeft'
title=
{
'删除规格'
}
description=
{
'确认删除该规格吗?'
}
onConfirm=
{
()
=>
deleteSkuClick
(
record
)
}
okText=
'确定'
cancelText=
'取消'
>
<
Button
type=
'link'
danger
>
删除
</
Button
>
</
Popconfirm
>
</>
),
},
];
const
[
pagination
,
setPagination
]
=
useState
<
PaginationProps
>
({
pageNo
:
1
,
pageSize
:
10
,
});
//分页
const
paginationChange
=
(
pageNo
:
number
,
pageSize
:
number
)
=>
{
pagination
.
pageNo
=
pageNo
;
pagination
.
pageSize
=
pageSize
;
setPagination
({
...
pagination
});
};
return
(
<
div
className=
'sku-info'
>
<
div
className=
'sku-info-operate'
style=
{
{
margin
:
' 20px 0 '
}
}
>
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
></
PlusOutlined
>
}
onClick=
{
()
=>
addOrEditSkuClick
()
}
>
添加规格
</
Button
>
</
div
>
<
Table
bordered
columns=
{
tableColumns
}
dataSource=
{
skuTableData
.
slice
(
(
pagination
.
pageNo
-
1
)
*
pagination
.
pageSize
,
pagination
.
pageNo
*
pagination
.
pageSize
,
)
}
rowKey=
'id'
pagination=
{
{
total
:
skuTableData
.
length
,
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} 条数据`
,
}
}
/>
</
div
>
);
};
export
default
SkuInfo
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index-old.tsx
0 → 100644
浏览文件 @
3018428e
import
BaseInfo
from
'~/components/goods/commonAddOrEdit/baseInfo'
;
import
StockSku
from
'~/components/goods/commonAddOrEdit/stockSku'
;
import
OtherInfo
from
'~/components/goods/commonAddOrEdit/otherInfo'
;
import
GoodsIntroduce
from
'~/components/goods/commonAddOrEdit/goodsIntroduce'
;
import
AddOrEditSkuModal
from
'~/components/goods/commonAddOrEdit/addOrEditSkuModal'
;
import
{
Button
,
message
}
from
'antd'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
'./index.scss'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
categoryListType
}
from
'~/api/interface/categoryManage'
;
import
{
customizeEntity
,
detailGoodsType
,
skuUnitType
,
specEntity
,
}
from
'~/api/interface/goodsType'
;
import
goodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
UploadFile
}
from
'antd/es/upload/interface'
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListType
>
[
'list'
];
//产品-规格单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品返回类型
type
goodsDetailType
=
InterDataType
<
detailGoodsType
>
;
const
GoodsAddOrEditOrDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
//基本信息ref
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
//当前目录
const
[
currentDesc
,
setCurrentDesc
]
=
useState
<
number
>
(
-
1
);
//分类
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//添加、编辑库存规格弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
(
false
);
//库存规格数据
const
[
specData
,
setSpecData
]
=
useState
<
specEntity
[]
>
([]);
const
[
goodsSpecCopy
,
setGoodsSpecCopy
]
=
useState
<
specEntity
[]
>
([]);
//产品规格-单位
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
//其它服务
const
[
otherService
,
setOtherService
]
=
useState
<
number
[]
>
([]);
// 当前操作行数据
const
[
curtRowData
,
setCurtRowData
]
=
useState
<
Partial
<
specEntity
>>
({});
//商品详情
const
[
goodsDetail
,
setGoodsDetail
]
=
useState
<
goodsDetailType
>
();
//产品介绍
const
[
productIntroduce
,
setProductIntroduce
]
=
useState
<
string
>
(
''
);
//是否商品详情
const
[
isDetail
,
setIsDetail
]
=
useState
<
boolean
>
(
false
);
//添加、编辑规格
const
addOrEditSkuShowEvent
=
(
record
?:
specEntity
)
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
setCurrentDesc
(
baseInfoForm
.
getFieldValue
(
'directoryId'
)
||
-
1
);
if
(
!
baseInfoForm
.
getFieldValue
(
'directoryId'
))
{
return
message
.
warning
(
'请先选择目录'
);
}
if
(
record
)
{
setCurtRowData
({
...
record
});
}
setAddOrEditSkuModalShow
(
true
);
};
//删除规格
const
deleteSkuEvent
=
(
record
:
specEntity
)
=>
{
const
index
=
specData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
specData
.
splice
(
index
,
1
);
setSpecData
([...
specData
]);
};
const
addOrEditSkuModalCancel
=
()
=>
{
setAddOrEditSkuModalShow
(
false
);
setCurtRowData
({});
};
const
addOrEditSkuModalOk
=
(
data
:
specEntity
)
=>
{
if
(
Object
.
keys
(
curtRowData
).
length
!=
0
)
{
const
index
:
number
=
specData
.
findIndex
((
i
)
=>
i
.
id
===
data
.
id
);
specData
.
splice
(
index
,
1
,
data
);
setSpecData
([...
specData
]);
}
else
{
setSpecData
([...
specData
,
data
]);
}
addOrEditSkuModalCancel
();
};
//根据目录获取分类列表
const
getCategoryList
=
(
directoryId
:
number
)
=>
{
CategoryManageAPI
.
getCategoryList
({
directoryId
,
type
:
4
,
pageSize
:
9999
,
pageNo
:
1
}).
then
(
({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
},
);
};
//产品-单位
const
getSkuUnit
=
()
=>
{
goodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//其它服务选择
const
otherServiceSelect
=
(
ids
:
number
[])
=>
{
setOtherService
(
ids
);
};
//获取产品详情
const
getRichText
=
(
html
?:
string
)
=>
{
setProductIntroduce
(
html
||
''
);
};
//商品详情
const
getGoodsDetail
=
(
goodsInfoId
:
number
)
=>
{
GoodsAPI
.
getGoodsDetail
({
goodsInfoId
,
type
:
0
}).
then
(({
result
})
=>
{
setGoodsDetail
(
result
);
getCategoryList
(
result
.
directoryId
);
const
specList
:
specEntity
[]
=
result
.
goodsSpec
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
// 自定义
if
(
cur
.
flag
===
1
)
{
const
cusList
:
customizeEntity
[]
=
cur
.
productSpecList
&&
cur
.
productSpecList
.
reduce
((
preProd
:
any
,
curProd
:
customizeEntity
,
index
:
number
)
=>
{
const
obj
:
UploadFile
=
{
uid
:
`img
${
index
}
`
,
status
:
'done'
,
url
:
curProd
.
specImage
,
name
:
'image'
,
};
preProd
.
push
({
...
curProd
,
fileList
:
[
obj
]
});
return
preProd
;
},
[]);
cur
.
customizeInfo
=
cusList
;
}
else
{
const
specId
:
number
[]
=
result
.
directoryId
===
2
?
cur
.
industrySpecList
&&
cur
.
industrySpecList
.
map
((
curIndu
:
any
)
=>
{
return
{
mallSpecId
:
curIndu
.
industrySpecId
,
specName
:
curIndu
.
specName
,
partNo
:
curIndu
.
partNo
,
id
:
curIndu
.
id
,
};
})
:
cur
.
productSpecList
&&
cur
.
productSpecList
.
map
((
item
:
any
)
=>
{
return
{
mallSpecId
:
item
.
productSpec
,
specName
:
item
.
specName
,
partNo
:
item
.
partNo
,
id
:
item
.
id
,
};
});
cur
.
specIds
=
specId
;
}
pre
.
push
({
...
cur
,
productName
:
cur
.
skuName
});
return
pre
;
},
[]);
setGoodsSpecCopy
(
result
.
goodsSpec
);
setOtherService
(
result
.
otherService
.
map
((
v
)
=>
v
.
saleServiceId
));
setSpecData
(
specList
);
});
};
//保存
const
saveSubmit
=
()
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
baseInfoForm
.
validateFields
().
then
((
values
:
any
)
=>
{
if
(
specData
.
length
===
0
)
{
return
message
.
warning
(
'清添加库存规格'
);
}
//主图
values
.
images
=
[
{
imgType
:
0
,
imgUrl
:
values
.
mainImg
[
0
].
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
values
.
mainImg
[
0
].
id
)
?
values
.
mainImg
[
0
].
id
:
undefined
:
undefined
,
},
];
//副图
if
(
values
.
subImg
)
{
values
.
images
.
push
(
...
values
.
subImg
.
map
((
v
:
any
)
=>
({
imgType
:
1
,
imgUrl
:
v
.
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
v
.
id
)
?
v
.
id
:
undefined
:
undefined
,
})),
);
}
//分类
values
.
categoryByOne
=
values
.
masterTypeId
[
0
];
values
.
categoryByTwo
=
values
.
masterTypeId
[
1
]
||
undefined
;
// 过滤对象属性
const
goodsSpecVO
:
specEntity
[]
=
specData
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
cur
.
customizeInfo
=
cur
.
customizeInfo
?.
reduce
((
cusPre
:
any
,
cusCur
:
customizeEntity
)
=>
{
const
bol
:
boolean
=
goodsSpecCopy
.
some
((
i
:
specEntity
)
=>
{
return
i
.
customizeInfo
?.
some
((
i
:
customizeEntity
)
=>
i
.
id
===
cusCur
.
id
);
});
cusPre
=
[
...
cusPre
,
bol
?
filterObjAttr
(
cusCur
,
[
'fileList'
])
:
filterObjAttr
(
cusCur
,
[
'id'
,
'fileList'
]),
];
return
cusPre
;
},
[]);
// 存在对象属性改变!
cur
.
specIds
=
cur
.
specIds
?.
reduce
((
preSpec
:
any
,
curSpec
:
any
)
=>
{
preSpec
=
[...
preSpec
,
filterObjAttr
(
curSpec
,
[
'specName'
,
'partNo'
])];
return
preSpec
;
},
[]);
// 是否新增
const
isAdd
:
boolean
=
goodsSpecCopy
.
every
((
i
:
specEntity
)
=>
i
.
id
!=
cur
.
id
);
// 是否修改了某一条
const
isEdit
:
boolean
=
goodsSpecCopy
.
every
(
(
i
:
specEntity
)
=>
i
.
categoryId
!=
cur
.
categoryId
,
);
pre
=
[
...
pre
,
!
isAdd
?
isEdit
?
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
,
'id'
])
:
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
])
:
filterObjAttr
(
cur
,
[
'id'
,
'skuName'
]),
];
return
pre
;
},
[]);
goodsAPI
[
goodsDetail
?
'editGoods'
:
'addGoods'
]({
...
filterObjAttr
(
values
,
[
'mainImg'
,
'subImg'
,
'video'
,
'masterTypeId'
,
'id'
,
'goodsDesc'
]),
productSpec
:
goodsSpecVO
,
goodsType
:
0
,
goodsDetailVO
:
{
goodsDesc
:
values
.
goodsDesc
,
productDesc
:
productIntroduce
},
otherService
:
otherService
,
id
:
goodsDetail
?
goodsDetail
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsDetail
?
'编辑成功'
:
'新增成功'
);
navigate
(
-
1
);
}
});
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
if
(
searchParams
.
get
(
'id'
))
{
getGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
}
setIsDetail
(
!!
searchParams
.
get
(
'isDetail'
));
getSkuUnit
();
},
[]);
return
(
<
div
className=
'goods-info'
>
{
/* 基本信息*/
}
<
BaseInfo
ref=
{
baseInfoRef
}
categoryList=
{
categoryList
}
getCategoryList=
{
getCategoryList
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
goodsType=
{
0
}
/>
{
/* 库存规格*/
}
<
StockSku
addOrEditSku=
{
addOrEditSkuShowEvent
}
specData=
{
specData
}
skuUnitList=
{
skuUnitList
}
deleteSku=
{
deleteSkuEvent
}
isDetail=
{
isDetail
}
/>
{
/*其它信息*/
}
<
OtherInfo
otherServiceSelect=
{
otherServiceSelect
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*产品介绍图*/
}
<
GoodsIntroduce
getRichText=
{
getRichText
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*库存规格,添加、编辑弹窗*/
}
<
AddOrEditSkuModal
currentDesc=
{
currentDesc
}
open=
{
addOrEditSkuModalShow
}
handleCancel=
{
addOrEditSkuModalCancel
}
handleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
curtRowData=
{
curtRowData
}
goodsType=
{
0
}
/>
<
div
className=
'goods-info-operate'
>
{
!
isDetail
&&
(
<
Button
type=
'primary'
onClick=
{
saveSubmit
}
>
保存
</
Button
>
)
}
<
Button
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
</
div
>
);
};
export
default
GoodsAddOrEditOrDetail
;
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.scss
浏览文件 @
3018428e
.goods-info
{
&
-operate
{
margin-top
:
50px
;
display
:
flex
;
justify-content
:
center
;
button
{
width
:
100px
;
height
:
40px
;
&
:first-child
{
margin-right
:
50px
;
.goods-operate-wrap
{
position
:
relative
;
.next-step
{
margin
:
20px
0
0
0px
;
text-align
:
center
;
button
{
&
:first-child
{
margin-right
:
20px
;
}
width
:
100px
;
}
}
.back-btn
{
position
:
absolute
;
right
:
0
;
top
:
0
;
}
}
src/pages/mallManage/mallGoods/goodsAddOrEditOrDetail/index.tsx
浏览文件 @
3018428e
import
BaseInfo
from
'~/components/goods/commonAddOrEdit/baseInfo'
;
import
StockSku
from
'~/components/goods/commonAddOrEdit/stockSku'
;
import
OtherInfo
from
'~/components/goods/commonAddOrEdit/otherInfo'
;
import
GoodsIntroduce
from
'~/components/goods/commonAddOrEdit/goodsIntroduce'
;
import
AddOrEditSkuModal
from
'~/components/goods/commonAddOrEdit/addOrEditSkuModal'
;
import
{
Button
,
message
}
from
'antd'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
'./index.scss'
;
import
{
Button
,
message
,
Tabs
,
TabsProps
}
from
'antd'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
categoryListType
}
from
'~/api/interface/categoryManage'
;
import
{
customizeEntity
,
detailGoodsType
,
skuUnitType
,
specEntity
,
}
from
'~/api/interface/goodsType'
;
import
goodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
filterObjAttr
}
from
'~/utils'
;
import
BaseInfo
from
'./components/baseInfo'
;
import
SkuInfo
from
'./components/skuInfo'
;
import
IntroduceInfo
from
'./components/introduceInfo'
;
import
SkuAddOrEditModal
from
'./components/skuAddOrEditModal'
;
import
'./index.scss'
;
import
{
useNavigate
,
useSearchParams
}
from
'react-router-dom'
;
import
{
baseInfoType
}
from
'./components/baseInfo'
;
import
{
InterDataType
,
InterReqType
}
from
'~/api/interface'
;
import
{
addMallGoodsType
,
mallGoodsDetailsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
UploadFile
}
from
'antd/es/upload/interface
'
;
import
{
filterObjAttr
}
from
'~/utils
'
;
//
分类返回
类型
type
categoryType
=
InterDataType
<
categoryListType
>
[
'list'
];
//
产品-规格
单位返回类型
//
商品sku规格
类型
type
goodsSpecType
=
Exclude
<
InterReqType
<
addMallGoodsType
>
,
undefined
>
[
'goodsSpecList'
][
0
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
//商品返回类型
type
goodsDetailType
=
InterDataType
<
detailGood
sType
>
;
//商品
详情-
返回类型
type
goodsDetailType
=
InterDataType
<
mallGoodsDetail
sType
>
;
const
GoodsAddOrEditOrDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
//基本信息ref
const
baseInfoRef
=
useRef
<
any
>
();
const
navigate
=
useNavigate
();
//当前目录
const
[
currentDesc
,
setCurrentDesc
]
=
useState
<
number
>
(
-
1
);
//分类
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//添加、编辑库存规格弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
(
false
);
//库存规格数据
const
[
specData
,
setSpecData
]
=
useState
<
specEntity
[]
>
([]);
const
[
goodsSpecCopy
,
setGoodsSpecCopy
]
=
useState
<
specEntity
[]
>
([]);
//产品规格-单位
const
[
searchParams
]
=
useSearchParams
();
//单位列表
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
//其它服务
const
[
otherService
,
setOtherService
]
=
useState
<
number
[]
>
([]);
// 当前操作行数据
const
[
curtRowData
,
setCurtRowData
]
=
useState
<
Partial
<
specEntity
>>
({});
const
[
tabSelectKeys
,
setTabSelectKeys
]
=
useState
<
string
>
(
'1'
);
//新增、编辑sku弹窗
const
[
addOrEditSkuModalShow
,
setAddOrEditSkuModalShow
]
=
useState
<
boolean
>
(
false
);
//当前编辑sku
const
[
currentSku
,
setCurrentSku
]
=
useState
<
goodsSpecType
>
();
//skuTable数据
const
[
skuTable
,
setSkuTable
]
=
useState
<
goodsSpecType
[]
>
([]);
//商品介绍详情
const
[
goodsDetails
,
setGoodsDetails
]
=
useState
<
string
>
(
''
);
//商品id
const
[
goodsId
,
setGoodsId
]
=
useState
<
number
>
(
0
);
//商品详情
const
[
goodsDetail
,
setGoodsDetail
]
=
useState
<
goodsDetailType
>
();
//产品介绍
const
[
productIntroduce
,
setProductIntroduce
]
=
useState
<
string
>
(
''
);
//是否商品详情
const
[
isDetail
,
setIsDetail
]
=
useState
<
boolean
>
(
false
);
const
[
goodsDetailsInfo
,
setGoodsDetailsInfo
]
=
useState
<
goodsDetailType
>
();
//添加、编辑规格
const
addOrEditSkuShowEvent
=
(
record
?:
specEntity
)
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
setCurrentDesc
(
baseInfoForm
.
getFieldValue
(
'directoryId'
)
||
-
1
);
if
(
!
baseInfoForm
.
getFieldValue
(
'directoryId'
))
{
return
message
.
warning
(
'请先选择目录'
);
}
if
(
record
)
{
setCurtRowData
({
...
record
});
}
//新增、编辑sku弹窗显示
const
addOrEditSkuClick
=
(
record
?:
goodsSpecType
)
=>
{
setCurrentSku
(
record
?
{
...
record
}
:
undefined
);
setAddOrEditSkuModalShow
(
true
);
};
//删除规格
const
deleteSkuEvent
=
(
record
:
specEntity
)
=>
{
const
index
=
specData
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
specData
.
splice
(
index
,
1
);
setSpecData
([...
specData
]);
};
const
addOrEditSkuModalCancel
=
()
=>
{
setAddOrEditSkuModalShow
(
false
);
setCurtRowData
({});
};
const
addOrEditSkuModalOk
=
(
data
:
specEntity
)
=>
{
if
(
Object
.
keys
(
curtRowData
).
length
!=
0
)
{
const
index
:
number
=
specData
.
findIndex
((
i
)
=>
i
.
id
===
data
.
id
);
specData
.
splice
(
index
,
1
,
data
);
setSpecData
([...
specData
]);
const
addOrEditSkuModalOk
=
(
values
:
goodsSpecType
)
=>
{
setAddOrEditSkuModalShow
(
false
);
const
skuTableIndex
:
number
=
skuTable
.
findIndex
((
v
)
=>
v
.
id
===
values
.
id
);
if
(
skuTableIndex
!==
-
1
)
{
skuTable
.
splice
(
skuTableIndex
,
1
,
values
);
setSkuTable
([...
skuTable
]);
}
else
{
setS
pecData
([...
specData
,
data
]);
setS
kuTable
([...
skuTable
,
{
...
values
}
]);
}
addOrEditSkuModalCancel
();
};
//根据目录获取分类列表
const
getCategoryList
=
(
directoryId
:
number
)
=>
{
CategoryManageAPI
.
getCategoryList
({
directoryId
,
type
:
4
,
pageSize
:
9999
,
pageNo
:
1
}).
then
(
({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
},
);
//sku删除
const
deleteSkuClick
=
(
record
:
goodsSpecType
)
=>
{
const
skuIndex
:
number
=
skuTable
.
findIndex
((
v
)
=>
v
.
id
===
record
.
id
);
skuTable
.
splice
(
skuIndex
,
1
);
setSkuTable
([...
skuTable
]);
};
//产品-单位
const
getSkuUnit
=
()
=>
{
goodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//其它服务选择
const
otherServiceSelect
=
(
ids
:
number
[])
=>
{
setOtherService
(
ids
);
//商品详情获取
const
getIntroduceInfo
=
(
richText
:
string
)
=>
{
setGoodsDetails
(
richText
);
};
//获取产品详情
const
getRichText
=
(
html
?:
string
)
=>
{
setProductIntroduce
(
html
||
''
);
const
tabItems
:
TabsProps
[
'items'
]
=
[
{
key
:
'1'
,
label
:
`基础信息`
,
children
:
<
BaseInfo
ref=
{
baseInfoRef
}
/>,
},
{
key
:
'2'
,
label
:
`商品规格`
,
children
:
(
<
SkuInfo
addOrEditSkuClick=
{
addOrEditSkuClick
}
skuTableData=
{
skuTable
}
skuUnitList=
{
skuUnitList
}
deleteSkuClick=
{
deleteSkuClick
}
editSkuClick=
{
addOrEditSkuClick
}
/>
),
},
{
key
:
'3'
,
label
:
`商品详情`
,
children
:
<
IntroduceInfo
onChange=
{
getIntroduceInfo
}
introduceInfo=
{
goodsDetails
}
/>,
},
];
//tab 切换
const
tabSelectChange
=
(
key
:
string
)
=>
{
setTabSelectKeys
(
key
);
};
//商品详情
const
getGoodsDetail
=
(
goodsInfoId
:
number
)
=>
{
GoodsAPI
.
getGoodsDetail
({
goodsInfoId
,
type
:
0
}).
then
(({
result
})
=>
{
setGoodsDetail
(
result
);
getCategoryList
(
result
.
directoryId
);
const
specList
:
specEntity
[]
=
result
.
goodsSpec
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
// 自定义
if
(
cur
.
flag
===
1
)
{
const
cusList
:
customizeEntity
[]
=
cur
.
productSpecList
&&
cur
.
productSpecList
.
reduce
((
preProd
:
any
,
curProd
:
customizeEntity
,
index
:
number
)
=>
{
const
obj
:
UploadFile
=
{
uid
:
`img
${
index
}
`
,
status
:
'done'
,
url
:
curProd
.
specImage
,
name
:
'image'
,
};
preProd
.
push
({
...
curProd
,
fileList
:
[
obj
]
});
return
preProd
;
},
[]);
cur
.
customizeInfo
=
cusList
;
//下一步
const
toNextStep
=
()
=>
{
switch
(
tabSelectKeys
)
{
case
'1'
:
baseInfoRef
.
current
.
getForm
()
.
validateFields
()
.
then
(()
=>
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
})
.
catch
((
error
:
any
)
=>
{
message
.
error
(
error
.
errorFields
[
0
].
errors
[
0
]);
});
break
;
case
'2'
:
if
(
skuTable
.
length
)
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
+
1
).
toString
());
}
else
{
const
specId
:
number
[]
=
result
.
directoryId
===
2
?
cur
.
industrySpecList
&&
cur
.
industrySpecList
.
map
((
curIndu
:
any
)
=>
{
return
{
mallSpecId
:
curIndu
.
industrySpecId
,
specName
:
curIndu
.
specName
,
partNo
:
curIndu
.
partNo
,
id
:
curIndu
.
id
,
};
})
:
cur
.
productSpecList
&&
cur
.
productSpecList
.
map
((
item
:
any
)
=>
{
return
{
mallSpecId
:
item
.
productSpec
,
specName
:
item
.
specName
,
partNo
:
item
.
partNo
,
id
:
item
.
id
,
};
});
cur
.
specIds
=
specId
;
message
.
warning
(
'请添加规格'
);
}
pre
.
push
({
...
cur
,
productName
:
cur
.
skuName
});
return
pre
;
},
[]);
setGoodsSpecCopy
(
result
.
goodsSpec
);
setOtherService
(
result
.
otherService
.
map
((
v
)
=>
v
.
saleServiceId
));
setSpecData
(
specList
);
break
;
case
'3'
:
break
;
default
:
break
;
}
};
//上一步
const
toBackStep
=
()
=>
{
setTabSelectKeys
((
Number
(
tabSelectKeys
)
-
1
).
toString
());
};
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
//单位列表
const
getSkuUnit
=
()
=>
{
GoodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//保存
const
saveSubmit
=
()
=>
{
const
baseInfoForm
=
baseInfoRef
.
current
.
baseInform
;
baseInfoForm
.
validateFields
().
then
((
values
:
any
)
=>
{
if
(
specData
.
length
===
0
)
{
return
message
.
warning
(
'清添加库存规格'
);
}
//主图
values
.
images
=
[
{
imgType
:
0
,
imgUrl
:
values
.
mainImg
[
0
].
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
values
.
mainImg
[
0
].
id
)
?
values
.
mainImg
[
0
].
id
:
undefined
:
undefined
,
},
];
//副图
if
(
values
.
subImg
)
{
values
.
images
.
push
(
...
values
.
subImg
.
map
((
v
:
any
)
=>
({
imgType
:
1
,
imgUrl
:
v
.
url
,
id
:
goodsDetail
?
goodsDetail
.
images
.
some
((
i
)
=>
i
.
id
===
v
.
id
)
?
v
.
id
:
undefined
//商品保存
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
,
})),
);
}
//分类
values
.
categoryByOne
=
values
.
masterTypeId
[
0
];
values
.
categoryByTwo
=
values
.
masterTypeId
[
1
]
||
undefined
;
// 过滤对象属性
const
goodsSpecVO
:
specEntity
[]
=
specData
.
reduce
((
pre
:
any
,
cur
:
specEntity
)
=>
{
cur
.
customizeInfo
=
cur
.
customizeInfo
?.
reduce
((
cusPre
:
any
,
cusCur
:
customizeEntity
)
=>
{
const
bol
:
boolean
=
goodsSpecCopy
.
some
((
i
:
specEntity
)
=>
{
return
i
.
customizeInfo
?.
some
((
i
:
customizeEntity
)
=>
i
.
id
===
cusCur
.
id
);
goodsSpecValuesList
:
v
.
goodsSpecValuesList
.
map
((
i
)
=>
({
...
i
,
id
:
goodsDetailsInfo
?
goodsDetailsInfo
.
goodsSpecList
.
find
((
j
)
=>
j
.
id
===
v
.
id
)
?.
goodsSpecValuesList
.
find
((
k
)
=>
k
.
id
===
i
.
id
)?.
id
:
undefined
,
goodsSpecId
:
goodsDetailsInfo
?
goodsDetailsInfo
.
goodsSpecList
.
find
((
i
)
=>
i
.
id
===
v
.
id
)?.
id
:
undefined
,
})),
}));
const
addGoodsEditReq
=
{
...
filterObjAttr
(
values
,
[
'mainImgList'
,
'subImgList'
,
'videoList'
,
'categoryId'
]),
resourcesList
:
[
...
values
.
mainImgList
.
map
((
v
)
=>
({
type
:
0
,
url
:
v
.
url
})),
...(
values
.
subImgList
?.
map
((
v
)
=>
({
type
:
1
,
url
:
v
.
url
}))
||
[]),
...(
values
.
videoList
?.
map
((
v
)
=>
({
type
:
2
,
url
:
v
.
url
}))
||
[]),
],
categoryPrimaryId
:
values
.
categoryId
[
0
],
categorySubId
:
values
.
categoryId
.
length
===
2
?
values
.
categoryId
[
1
]
:
undefined
,
goodsDetails
,
goodsSpecList
:
skuList
,
id
:
goodsId
||
undefined
,
};
GoodsAPI
[
goodsId
?
'editMallGoods'
:
'addMallGoods'
](
addGoodsEditReq
).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsId
?
'编辑商城成功'
:
'新增商品成功'
);
navigate
(
-
1
);
}
});
cusPre
=
[
...
cusPre
,
bol
?
filterObjAttr
(
cusCur
,
[
'fileList'
])
:
filterObjAttr
(
cusCur
,
[
'id'
,
'fileList'
]),
];
return
cusPre
;
},
[]);
// 存在对象属性改变!
cur
.
specIds
=
cur
.
specIds
?.
reduce
((
preSpec
:
any
,
curSpec
:
any
)
=>
{
preSpec
=
[...
preSpec
,
filterObjAttr
(
curSpec
,
[
'specName'
,
'partNo'
])];
return
preSpec
;
},
[]);
// 是否新增
const
isAdd
:
boolean
=
goodsSpecCopy
.
every
((
i
:
specEntity
)
=>
i
.
id
!=
cur
.
id
);
// 是否修改了某一条
const
isEdit
:
boolean
=
goodsSpecCopy
.
every
(
(
i
:
specEntity
)
=>
i
.
categoryId
!=
cur
.
categoryId
,
);
pre
=
[
...
pre
,
!
isAdd
?
isEdit
?
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
,
'id'
])
:
filterObjAttr
(
cur
,
[
'industrySpecList'
,
'productSpecList'
,
'skuName'
])
:
filterObjAttr
(
cur
,
[
'id'
,
'skuName'
]),
];
return
pre
;
},
[]);
goodsAPI
[
goodsDetail
?
'editGoods'
:
'addGoods'
]({
...
filterObjAttr
(
values
,
[
'mainImg'
,
'subImg'
,
'video'
,
'masterTypeId'
,
'id'
,
'goodsDesc'
]),
productSpec
:
goodsSpecVO
,
goodsType
:
0
,
goodsDetailVO
:
{
goodsDesc
:
values
.
goodsDesc
,
productDesc
:
productIntroduce
},
otherService
:
otherService
,
id
:
goodsDetail
?
goodsDetail
.
id
:
undefined
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
goodsDetail
?
'编辑成功'
:
'新增成功'
);
navigate
(
-
1
);
}
else
{
message
.
warning
(
'商品规格未添加'
);
}
})
.
catch
((
error
:
any
)
=>
{
message
.
error
(
error
.
errorFields
[
0
].
errors
[
0
]);
});
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
//商品详情
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
(
JSON
.
parse
(
JSON
.
stringify
(
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'
))
{
getGoodsDetail
(
Number
(
searchParams
.
get
(
'id'
)));
setGoodsId
(
Number
(
searchParams
.
get
(
'id'
)));
getMallGoodsDetails
(
Number
(
searchParams
.
get
(
'id'
)));
}
setIsDetail
(
!!
searchParams
.
get
(
'isDetail'
));
getSkuUnit
();
},
[]);
return
(
<
div
className=
'goods-info'
>
{
/* 基本信息*/
}
<
BaseInfo
ref=
{
baseInfoRef
}
categoryList=
{
categoryList
}
getCategoryList=
{
getCategoryList
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
goodsType=
{
0
}
/>
{
/* 库存规格*/
}
<
StockSku
addOrEditSku=
{
addOrEditSkuShowEvent
}
specData=
{
specData
}
skuUnitList=
{
skuUnitList
}
deleteSku=
{
deleteSkuEvent
}
isDetail=
{
isDetail
}
/>
{
/*其它信息*/
}
<
OtherInfo
otherServiceSelect=
{
otherServiceSelect
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*产品介绍图*/
}
<
GoodsIntroduce
getRichText=
{
getRichText
}
goodsDetail=
{
goodsDetail
}
isDetail=
{
isDetail
}
/>
{
/*库存规格,添加、编辑弹窗*/
}
<
AddOrEditSkuModal
currentDesc=
{
currentDesc
}
open=
{
addOrEditSkuModalShow
}
handleCancel=
{
addOrEditSkuModalCancel
}
handleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
curtRowData=
{
curtRowData
}
goodsType=
{
0
}
/>
<
div
className=
'goods-info-operate'
>
{
!
isDetail
&&
(
<
Button
type=
'primary'
onClick=
{
saveSubmit
}
>
保存
<
div
className=
'goods-operate-wrap'
>
<
Tabs
items=
{
tabItems
}
activeKey=
{
tabSelectKeys
}
onChange=
{
tabSelectChange
}
></
Tabs
>
<
div
className=
'next-step'
>
{
tabSelectKeys
!==
'1'
?
<
Button
onClick=
{
toBackStep
}
>
上一步
</
Button
>
:
''
}
{
tabSelectKeys
!==
'3'
?
(
<
Button
type=
'primary'
onClick=
{
toNextStep
}
>
下一步
</
Button
>
)
:
(
''
)
}
<
Button
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
<
div
className=
'back-btn'
>
<
Button
type=
'primary'
onClick=
{
saveGoods
}
style=
{
{
marginRight
:
'10px'
}
}
>
保存
</
Button
>
<
Button
type=
'default'
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
{
/*新增、编辑sku弹窗*/
}
<
SkuAddOrEditModal
open=
{
addOrEditSkuModalShow
}
onCancel=
{
addOrEditSkuModalCancel
}
onHandleOk=
{
addOrEditSkuModalOk
}
skuUnitList=
{
skuUnitList
}
currentSku=
{
currentSku
}
/>
</
div
>
);
};
...
...
src/pages/mallManage/mallGoods/goodsDetails/index.scss
0 → 100644
浏览文件 @
3018428e
.goods-detail
{
position
:
relative
;
&
-info
{
margin-bottom
:
20px
;
}
&
-sku
{
.sku-title
{
line-height
:
50px
;
font-weight
:
bold
;
font-size
:
14px
;
}
}
&
-introduce
{
.introduce-title
{
line-height
:
50px
;
font-weight
:
bold
;
font-size
:
14px
;
}
}
&
-operate
{
position
:
absolute
;
right
:
0
;
top
:
0
;
}
}
src/pages/mallManage/mallGoods/goodsDetails/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
useSearchParams
,
useNavigate
}
from
'react-router-dom'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
GoodsAPI
from
'~/api/modules/goodsAPI'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
mallGoodsDetailsType
,
skuUnitType
}
from
'~/api/interface/goodsType'
;
import
{
Badge
,
Button
,
Descriptions
,
Image
,
Table
,
Tag
}
from
'antd'
;
import
{
CategoryManageAPI
}
from
'~/api'
;
import
{
categoryListRespType
}
from
'~/api/interface/categoryManage'
;
import
'./index.scss'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
//详情返回类型
type
detailType
=
InterDataType
<
mallGoodsDetailsType
>
;
//分类返回类型
type
categoryType
=
InterDataType
<
categoryListRespType
>
[
'list'
];
//单位返回类型
type
unitType
=
InterDataType
<
skuUnitType
>
;
const
GoodsDetails
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
const
navigate
=
useNavigate
();
//分类列表
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
//单位列表
const
[
skuUnitList
,
setSkuUnitList
]
=
useState
<
unitType
>
([]);
const
[
goodsInfoDetails
,
setGoodsInfoDetails
]
=
useState
<
detailType
>
();
const
tableColumns
:
ColumnsType
<
detailType
[
'goodsSpecList'
][
0
]
>
=
[
{
title
:
'序号'
,
align
:
'center'
,
render
:
(
_text
:
string
,
_record
,
index
:
number
)
=>
index
+
1
,
},
{
title
:
'规格名称'
,
align
:
'center'
,
dataIndex
:
'specName'
,
},
{
title
:
'选择方式'
,
align
:
'center'
,
dataIndex
:
'chooseType'
,
render
:
(
text
:
number
)
=>
(
text
?
'多选'
:
'单选'
),
},
{
title
:
'是否必选'
,
align
:
'center'
,
dataIndex
:
'must'
,
render
:
(
text
:
number
)
=>
(
text
?
'必选'
:
'非必选'
),
},
{
title
:
'规格单位'
,
align
:
'center'
,
dataIndex
:
'skuUnitId'
,
render
:
(
text
:
number
)
=>
skuUnitList
.
find
((
v
)
=>
v
.
id
===
text
)?.
unitName
||
''
,
},
{
title
:
'规格值'
,
align
:
'center'
,
dataIndex
:
'goodsSpecValuesList'
,
render
:
(
text
:
detailType
[
'goodsSpecList'
][
0
][
'goodsSpecValuesList'
])
=>
text
.
map
((
v
)
=>
(
<
Tag
key=
{
v
.
id
}
>
{
v
.
specValueName
}
{
v
.
partNo
?
`(${v.partNo})`
:
''
}
</
Tag
>
)),
},
];
const
getGoodsDetails
=
(
id
:
number
)
=>
{
GoodsAPI
.
getMallGoodsDetails
({
id
}).
then
(({
result
})
=>
{
setGoodsInfoDetails
(
result
);
});
};
//分类列表
const
getCategoryList
=
()
=>
{
CategoryManageAPI
.
getCategoryRespList
({
pageNo
:
1
,
pageSize
:
99999
}).
then
(({
result
})
=>
{
setCategoryList
(
result
.
list
||
[]);
});
};
//单位列表
const
getSkuUnit
=
()
=>
{
GoodsAPI
.
getSkuUnit
().
then
(({
result
})
=>
{
setSkuUnitList
(
result
||
[]);
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
getGoodsDetails
(
Number
(
searchParams
.
get
(
'id'
)));
getCategoryList
();
getSkuUnit
();
},
[]);
return
(
<
div
className=
'goods-detail'
>
<
div
className=
'goods-detail-info'
>
<
Descriptions
title=
'基本信息'
bordered
>
<
Descriptions
.
Item
label=
'商品名称'
>
{
goodsInfoDetails
?.
tradeName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品副图'
>
{
goodsInfoDetails
?.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
1
)
.
map
((
v
)
=>
(
<
Image
src=
{
v
.
url
}
width=
{
50
}
height=
{
50
}
key=
{
v
.
id
}
/>
))
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品主图'
>
{
goodsInfoDetails
?.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
0
)
.
map
((
v
)
=>
(
<
Image
src=
{
v
.
url
}
width=
{
50
}
height=
{
50
}
key=
{
v
.
id
}
/>
))
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品标签'
>
{
goodsInfoDetails
?.
goodsLabel
||
'暂无'
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品分类'
>
{
categoryList
.
reduce
((
pre
:
string
[],
cur
)
=>
{
if
(
cur
.
id
===
goodsInfoDetails
?.
categoryPrimaryId
)
{
pre
.
push
(
cur
.
name
);
if
(
goodsInfoDetails
?.
categorySubId
)
{
pre
.
push
(
cur
.
subDTOList
.
find
((
v
)
=>
v
.
id
===
goodsInfoDetails
?.
categorySubId
)?.
name
||
''
,
);
}
}
return
pre
;
},
[])
.
join
(
'/'
)
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品状态'
>
<
Badge
status=
{
goodsInfoDetails
?.
shelfStatus
?
'processing'
:
'default'
}
text=
{
goodsInfoDetails
?.
shelfStatus
?
'上架中'
:
'已下架'
}
/>
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品视频'
span=
{
1
}
>
{
goodsInfoDetails
?.
resourcesList
.
filter
((
v
)
=>
v
.
type
===
2
)
.
map
((
v
)
=>
(
<
video
src=
{
v
.
url
}
key=
{
v
.
id
}
style=
{
{
width
:
'200px'
,
height
:
'200px'
}
}
controls
/>
))
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'商品描述'
>
{
goodsInfoDetails
?.
description
}
</
Descriptions
.
Item
>
</
Descriptions
>
</
div
>
<
div
className=
'goods-detail-sku'
>
<
div
className=
'sku-title'
>
商品规格
</
div
>
<
Table
bordered
columns=
{
tableColumns
}
dataSource=
{
goodsInfoDetails
?.
goodsSpecList
}
rowKey=
'id'
pagination=
{
false
}
></
Table
>
</
div
>
<
div
className=
'goods-detail-introduce'
>
<
div
className=
'introduce-title'
>
商品详情
</
div
>
<
div
className=
'introduce-content'
dangerouslySetInnerHTML=
{
{
__html
:
goodsInfoDetails
?.
goodsDetails
||
''
}
}
></
div
>
</
div
>
<
div
className=
'goods-detail-operate'
>
<
Button
type=
'primary'
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
</
div
>
);
};
export
default
GoodsDetails
;
src/pages/mallManage/mallGoods/goodsList/index.tsx
浏览文件 @
3018428e
...
...
@@ -2,30 +2,32 @@ 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'
;
import
{
useSelector
}
from
'react-redux'
;
import
_
from
'lodash'
;
//商品返回类型
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
const
searchRef
=
useRef
();
const
navigate
=
useNavigate
();
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
();
const
{
userInfo
}
=
useSelector
((
state
:
any
)
=>
state
.
UserInfo
);
const
tabList
=
[
{
key
:
'1'
,
...
...
@@ -41,26 +43,22 @@ const GoodsList = () => {
},
];
const
[
activeTabKey
,
setActiveTabKey
]
=
useState
<
string
>
(
'1'
);
//分类列表
const
[
categoryList
,
setCategoryList
]
=
useState
<
categoryType
>
([]);
const
[
searchColumns
,
setSearchColumns
]
=
useState
<
searchColumns
[]
>
([
{
label
:
'商品名称'
,
placeholder
:
'请输入商品名称'
,
name
:
'
goods
Name'
,
name
:
'
trade
Name'
,
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 +70,30 @@ 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'
,
width
:
'20%'
,
ellipsis
:
true
},
{
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
)
=>
(
width
:
'20%'
,
render
:
(
id
:
number
,
record
:
goodsType
[
0
])
=>
(
<>
<
Button
type=
'link'
onClick=
{
()
=>
toEditGoods
(
id
)
}
>
编辑
...
...
@@ -96,6 +101,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 +127,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
);
...
...
@@ -137,12 +151,13 @@ const GoodsList = () => {
const
paginationChange
=
(
pageNo
:
number
,
pageSize
:
number
)
=>
{
pagination
.
pageNo
=
pageNo
;
pagination
.
pageSize
=
pageSize
;
setSelectedRowKeys
([]);
setSearchParams
(
qs
.
stringify
({
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 +167,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
);
...
...
@@ -202,48 +213,36 @@ const GoodsList = () => {
const
toGoodsDetail
=
(
id
:
number
)
=>
{
navigate
({
pathname
:
'/mallManage/mallGoods/detail'
,
search
:
`id=
${
id
}
&isDetail=1
`
,
search
:
`id=
${
id
}
`
,
});
};
// 表格多选事件
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
;
...
...
@@ -257,11 +256,9 @@ const GoodsList = () => {
});
};
//上移
const
upGoodsClick
=
()
=>
{
const
upGoodsClick
=
_
.
debounce
(
()
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
message
.
warning
(
'请选择商品'
);
}
else
if
(
selectedRowKeys
.
length
>
1
)
{
message
.
warning
(
'最多选择一个商品'
);
}
else
{
const
index
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
selectedRowKeys
[
0
]);
const
allIndex
=
allGoods
.
findIndex
((
v
)
=>
v
.
id
===
selectedRowKeys
[
0
]);
...
...
@@ -276,7 +273,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 +284,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
,
}),
);
}
...
...
@@ -298,13 +295,11 @@ const GoodsList = () => {
);
}
}
};
}
,
500
)
;
//下移
const
downGoodsClick
=
()
=>
{
const
downGoodsClick
=
_
.
debounce
(
()
=>
{
if
(
selectedRowKeys
.
length
===
0
)
{
message
.
warning
(
'请选择商品'
);
}
else
if
(
selectedRowKeys
.
length
>
1
)
{
message
.
warning
(
'最多选择一个商品'
);
}
else
{
const
index
=
tableData
.
findIndex
((
v
)
=>
v
.
id
===
selectedRowKeys
[
0
]);
const
allIndex
=
allGoods
.
findIndex
((
v
)
=>
v
.
id
===
selectedRowKeys
[
0
]);
...
...
@@ -319,7 +314,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 +325,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
,
}),
);
}
...
...
@@ -341,48 +336,66 @@ const GoodsList = () => {
);
}
}
},
500
);
//分类列表
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
search=
{
searchColumns
}
child=
{
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
toAddMallGoods
}
>
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
toAddMallGoods
}
disabled=
{
!!
userInfo
.
roleInfo
.
superAdmin
}
>
新增商品
</
Button
>
}
...
...
@@ -396,6 +409,7 @@ const GoodsList = () => {
style=
{
{
marginRight
:
'10px'
}
}
icon=
{
<
ArrowUpOutlined
/>
}
onClick=
{
upGoodsClick
}
disabled=
{
!!
userInfo
.
roleInfo
.
superAdmin
}
>
上移
</
Button
>
...
...
@@ -404,33 +418,10 @@ const GoodsList = () => {
style=
{
{
marginRight
:
'10px'
}
}
icon=
{
<
ArrowDownOutlined
/>
}
onClick=
{
downGoodsClick
}
disabled=
{
!!
userInfo
.
roleInfo
.
superAdmin
}
>
下移
</
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 +431,8 @@ const GoodsList = () => {
rowSelection=
{
{
selectedRowKeys
,
onChange
:
onSelectChange
,
type
:
'radio'
,
hideSelectAll
:
true
,
}
}
loading=
{
loading
}
pagination=
{
{
...
...
src/pages/systemManage/companyManage/companyDetail/components/addPeopleModal/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
FC
,
useState
}
from
'react'
;
import
{
Form
,
message
,
Modal
,
ModalProps
,
Select
}
from
'antd'
;
import
{
CommonAPI
,
SystemManageAPI
}
from
'~/api'
;
interface
selfProps
{
onOk
:
()
=>
void
;
companyInfoId
:
number
;
}
const
AddPeopleModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onCancel
,
onOk
,
companyInfoId
})
=>
{
const
[
form
]
=
Form
.
useForm
<
{
userAccountId
:
number
}
>
();
const
[
options
,
setOptions
]
=
useState
<
{
label
:
string
;
value
:
number
;
key
:
string
}[]
>
([]);
const
handleOk
=
()
=>
{
form
.
validateFields
().
then
((
values
)
=>
{
SystemManageAPI
.
bindingCompanyMember
({
...
values
,
companyInfoId
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'绑定成功'
);
onOk
();
form
.
resetFields
();
}
});
});
};
//select 搜索
const
selectSearchEvent
=
(
value
:
string
)
=>
{
CommonAPI
.
getUserAccountByPhoneNum
({
phoneNum
:
value
}).
then
(({
result
})
=>
{
const
list
=
(
result
||
[]).
map
((
v
)
=>
({
label
:
v
.
phoneNum
+
`(
${
v
.
uid
}
)`
,
value
:
v
.
id
,
key
:
value
,
}));
setOptions
(
list
);
});
};
return
(
<
Modal
open=
{
open
}
title=
'添加成员'
onOk=
{
handleOk
}
onCancel=
{
onCancel
}
>
<
Form
form=
{
form
}
>
<
Form
.
Item
label=
'成员'
name=
'userAccountId'
rules=
{
[{
required
:
true
,
message
:
'请选择成员'
}]
}
>
<
Select
placeholder=
'请输入成员手机号码'
showSearch
onSearch=
{
selectSearchEvent
}
filterOption=
{
(
input
,
option
)
=>
(
option
?.
key
??
''
).
toLowerCase
().
includes
(
input
.
toLowerCase
())
}
options=
{
options
}
></
Select
>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
AddPeopleModal
;
src/pages/systemManage/companyManage/companyDetail/components/transferLeaderModal/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
Form
,
message
,
Modal
,
ModalProps
,
Select
}
from
'antd'
;
import
{
FC
,
useEffect
,
useState
}
from
'react'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
listCompanyMembersType
}
from
'~/api/interface/systemManageType'
;
//单位-成员列表返回类型
type
companyMembersType
=
InterDataType
<
listCompanyMembersType
>
[
'list'
];
interface
selfProps
{
onOk
:
()
=>
void
;
companyInfoId
:
number
;
currentCompanyMembers
:
companyMembersType
[
0
]
|
undefined
;
}
const
TransferLeaderModal
:
FC
<
ModalProps
&
selfProps
>
=
({
open
,
onOk
,
onCancel
,
companyInfoId
,
currentCompanyMembers
,
})
=>
{
const
[
form
]
=
Form
.
useForm
<
{
toUserAccountId
:
number
}
>
();
const
[
listCompanyMembers
,
setListCompanyMembers
]
=
useState
<
companyMembersType
>
([]);
const
handleOk
=
()
=>
{
form
.
validateFields
().
then
((
values
)
=>
{
if
(
currentCompanyMembers
)
{
SystemManageAPI
.
transferLeader
({
companyInfoId
,
fromUserAccountId
:
currentCompanyMembers
.
id
,
...
values
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'转让成功'
);
onOk
();
}
});
}
});
};
//单位成员列表
const
getListCompanyMembers
=
()
=>
{
SystemManageAPI
.
getListCompanyMembers
({
companyInfoId
,
pageNo
:
1
,
pageSize
:
999999
,
}).
then
(({
result
})
=>
{
setListCompanyMembers
((
result
.
list
||
[]).
filter
((
v
)
=>
!
v
.
leader
));
});
};
useEffect
(()
=>
{
if
(
currentCompanyMembers
)
{
getListCompanyMembers
();
}
},
[
currentCompanyMembers
]);
return
(
<
Modal
open=
{
open
}
title=
'转让管理员'
onCancel=
{
onCancel
}
onOk=
{
handleOk
}
>
<
Form
form=
{
form
}
>
<
Form
.
Item
label=
'转让人'
name=
'toUserAccountId'
>
<
Select
placeholder=
'请选择受让人'
filterOption=
{
(
input
,
option
)
=>
(
option
!
.
children
as
unknown
as
string
).
toLowerCase
().
includes
(
input
.
toLowerCase
())
}
>
{
listCompanyMembers
.
map
((
v
)
=>
(
<
Select
.
Option
key=
{
v
.
id
}
value=
{
v
.
id
}
>
{
v
.
phoneNum
}
(
{
v
.
uid
}
)
</
Select
.
Option
>
))
}
</
Select
>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
TransferLeaderModal
;
src/pages/systemManage/companyManage/companyDetail/index.scss
0 → 100644
浏览文件 @
3018428e
.company-detail
{
position
:
relative
;
&
-info
{
margin-bottom
:
20px
;
}
&
-people
{
&
-title
{
line-height
:
50px
;
font-weight
:
bold
;
font-size
:
14px
;
}
&
-operate
{
margin-bottom
:
10px
;
}
}
&
-operate
{
position
:
absolute
;
right
:
0
;
top
:
0
;
}
}
src/pages/systemManage/companyManage/companyDetail/index.tsx
0 → 100644
浏览文件 @
3018428e
import
{
useSearchParams
,
useNavigate
}
from
'react-router-dom'
;
import
{
useEffect
,
useState
}
from
'react'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
{
InterDataType
,
PaginationProps
}
from
'~/api/interface'
;
import
{
getCompanyInfoByIdType
,
listCompanyMembersType
}
from
'~/api/interface/systemManageType'
;
import
{
Button
,
Descriptions
,
message
,
Modal
,
Table
}
from
'antd'
;
import
'./index.scss'
;
import
{
ColumnsType
}
from
'antd/es/table'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
AddPeopleModal
from
'./components/addPeopleModal'
;
import
{
useSelector
}
from
'react-redux'
;
import
TransferLeaderModal
from
'~/pages/systemManage/companyManage/companyDetail/components/transferLeaderModal'
;
//单位详情-返回类型
type
companyDetailType
=
InterDataType
<
getCompanyInfoByIdType
>
;
//单位-成员列表返回类型
type
companyMembersType
=
InterDataType
<
listCompanyMembersType
>
[
'list'
];
const
CompanyDetail
=
()
=>
{
const
[
searchParams
]
=
useSearchParams
();
const
navigate
=
useNavigate
();
const
{
userInfo
}
=
useSelector
((
state
:
any
)
=>
state
.
UserInfo
);
const
tableColumns
:
ColumnsType
<
companyMembersType
[
0
]
>
=
[
{
title
:
'uid'
,
align
:
'center'
,
dataIndex
:
'uid'
,
},
{
title
:
'姓名'
,
align
:
'center'
,
dataIndex
:
'userName'
,
},
{
title
:
'角色'
,
align
:
'center'
,
dataIndex
:
'leader'
,
render
:
(
text
:
number
)
=>
(
text
?
'单位管理员'
:
'普通员工'
),
},
{
title
:
'手机号'
,
align
:
'center'
,
dataIndex
:
'phoneNum'
,
},
{
title
:
'操作'
,
width
:
'15%'
,
onHeaderCell
:
()
=>
({
style
:
{
textAlign
:
'center'
,
},
}),
render
:
(
_text
:
string
,
record
)
=>
(
<>
<
Button
type=
'link'
disabled=
{
!
userInfo
.
companyInfoVO
.
leader
||
!
record
.
leader
}
onClick=
{
()
=>
transferLeaderClick
(
record
)
}
>
转让
</
Button
>
<
Button
type=
'link'
disabled=
{
!
userInfo
.
companyInfoVO
.
leader
||
!!
record
.
leader
}
onClick=
{
()
=>
unbindCompanyClick
(
record
)
}
>
解绑
</
Button
>
</>
),
},
];
const
[
companyId
,
setCompanyId
]
=
useState
<
number
>
(
-
1
);
const
[
companyDetail
,
setCompanyDetail
]
=
useState
<
companyDetailType
>
();
const
[
pagination
,
setPagination
]
=
useState
<
PaginationProps
&
{
totalCount
:
number
}
>
({
pageNo
:
1
,
pageSize
:
10
,
totalCount
:
0
,
});
const
[
listCompanyMembers
,
setListCompanyMembers
]
=
useState
<
companyMembersType
>
([]);
const
[
currentCompanyMembers
,
setCurrentCompanyMembers
]
=
useState
<
companyMembersType
[
0
]
>
();
const
[
addPeopleModalShow
,
setAddPeopleModalShow
]
=
useState
<
boolean
>
(
false
);
const
[
transferLeaderModalShow
,
setTransferLeaderModalShow
]
=
useState
<
boolean
>
(
false
);
//单位详情
const
getCompanyDetailInfo
=
(
id
:
number
)
=>
{
SystemManageAPI
.
getCompanyInfoById
({
id
}).
then
(({
result
})
=>
{
setCompanyDetail
(
result
);
});
};
//单位成员列表
const
getListCompanyMembers
=
(
companyInfoId
:
number
)
=>
{
SystemManageAPI
.
getListCompanyMembers
({
companyInfoId
,
pageNo
:
pagination
.
pageNo
,
pageSize
:
pagination
.
pageSize
,
}).
then
(({
result
})
=>
{
pagination
.
totalCount
=
result
.
totalCount
;
setPagination
(
pagination
);
setListCompanyMembers
(
result
.
list
||
[]);
});
};
//分页
const
paginationChange
=
(
pageNo
:
number
,
pageSize
:
number
)
=>
{
pagination
.
pageNo
=
pageNo
;
pagination
.
pageSize
=
pageSize
;
getListCompanyMembers
(
companyId
);
};
//添加成员弹窗
const
addPeopleClick
=
()
=>
{
setAddPeopleModalShow
(
true
);
};
const
addPeopleModalOk
=
()
=>
{
getListCompanyMembers
(
companyId
);
setAddPeopleModalShow
(
false
);
};
const
addPeopleModalCancel
=
()
=>
{
setAddPeopleModalShow
(
false
);
};
//转让管理员弹窗
const
transferLeaderClick
=
(
record
:
companyMembersType
[
0
])
=>
{
setCurrentCompanyMembers
(
record
);
setTransferLeaderModalShow
(
true
);
};
const
transferLeaderModalCancel
=
()
=>
{
setTransferLeaderModalShow
(
false
);
};
const
transferLeaderModalOk
=
()
=>
{
setTransferLeaderModalShow
(
false
);
getListCompanyMembers
(
companyId
);
};
//接触绑定
const
unbindCompanyClick
=
(
record
:
companyMembersType
[
0
])
=>
{
Modal
.
confirm
({
title
:
'提示'
,
content
:
'确认解除绑定该成员?'
,
onOk
:
()
=>
{
SystemManageAPI
.
unbindCompanyMember
({
userAccountId
:
record
.
id
,
companyInfoId
:
companyId
,
}).
then
(({
code
})
=>
{
if
(
code
===
'200'
)
{
message
.
success
(
'解除成功'
);
if
(
pagination
.
pageNo
!==
1
&&
listCompanyMembers
?.
length
===
1
)
{
pagination
.
pageNo
-=
1
;
}
getListCompanyMembers
(
companyId
);
}
});
},
});
};
//返回
const
backRoute
=
()
=>
{
navigate
(
-
1
);
};
useEffect
(()
=>
{
setCompanyId
(
Number
(
searchParams
.
get
(
'id'
)));
getCompanyDetailInfo
(
Number
(
searchParams
.
get
(
'id'
)));
getListCompanyMembers
(
Number
(
searchParams
.
get
(
'id'
)));
},
[]);
return
(
<
div
className=
'company-detail'
>
<
div
className=
'company-detail-info'
>
<
Descriptions
title=
'基本信息'
bordered
column=
{
4
}
>
<
Descriptions
.
Item
label=
'单位名称'
>
{
companyDetail
?.
companyName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'详细地址'
>
{
companyDetail
?.
address
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'联系人'
>
{
companyDetail
?.
companyUserName
||
''
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
'联系电话'
>
{
companyDetail
?.
phoneNum
||
''
}
</
Descriptions
.
Item
>
</
Descriptions
>
</
div
>
<
div
className=
'company-detail-people'
>
<
div
className=
'company-detail-people-title'
>
成员信息
</
div
>
<
div
className=
'company-detail-people-operate'
>
<
Button
type=
'primary'
icon=
{
<
PlusOutlined
></
PlusOutlined
>
}
onClick=
{
addPeopleClick
}
disabled=
{
!
userInfo
.
companyInfoVO
.
leader
}
>
添加成员
</
Button
>
</
div
>
<
Table
bordered
columns=
{
tableColumns
}
dataSource=
{
listCompanyMembers
}
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} 条数据`
,
}
}
/>
</
div
>
<
div
className=
'company-detail-operate'
>
<
Button
type=
'primary'
onClick=
{
backRoute
}
>
返回
</
Button
>
</
div
>
{
/*添加成员*/
}
<
AddPeopleModal
open=
{
addPeopleModalShow
}
onCancel=
{
addPeopleModalCancel
}
onOk=
{
addPeopleModalOk
}
companyInfoId=
{
companyId
}
/>
{
/*转让管理员*/
}
<
TransferLeaderModal
open=
{
transferLeaderModalShow
}
onCancel=
{
transferLeaderModalCancel
}
onOk=
{
transferLeaderModalOk
}
companyInfoId=
{
companyId
}
currentCompanyMembers=
{
currentCompanyMembers
}
/>
</
div
>
);
};
export
default
CompanyDetail
;
src/pages/systemManage/companyManage/comp/addEditModal/index.tsx
→
src/pages/systemManage/companyManage/comp
anyList/comp
/addEditModal/index.tsx
浏览文件 @
3018428e
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
InterListType
,
InterReqType
}
from
'~/api/interface'
;
import
{
listCompanyAdd
,
listCompanyPage
}
from
'~/api/interface/systemManageType'
;
import
{
Cascader
,
Form
,
Input
,
message
,
Modal
}
from
'antd'
;
import
{
Button
,
Col
,
Form
,
Input
,
message
,
Modal
,
Row
}
from
'antd'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
DistrictData
from
'~/assets/json/district.json'
;
import
{
EnvironmentOutlined
}
from
'@ant-design/icons'
;
import
SelectMap
from
'~/components/select-map'
;
// 列表的类型
type
TableType
=
InterListType
<
listCompanyPage
>
;
// 请求的表单类型
type
ReqType
=
InterReqType
<
listCompanyAd
d
>
;
type
ReqType
=
Exclude
<
InterReqType
<
listCompanyAdd
>
,
undefine
d
>
;
// 传参类型
interface
propType
{
title
:
string
;
...
...
@@ -21,14 +22,15 @@ const AddEditModal: React.FC<propType> = (props) => {
const
{
title
,
open
,
closed
,
data
}
=
props
;
/// 表单钩子
const
[
form
]
=
Form
.
useForm
<
ReqType
>
();
// 地区
const
[
localList
,
setLocalList
]
=
useState
<
{
childInfo
:
any
[];
id
:
number
;
name
:
string
;
}[]
>
();
//选点信息
const
[
position
,
setPosition
]
=
useState
<
{
lat
:
number
;
lon
:
number
;
address
:
string
;
}
>
();
//地图选点弹窗
const
[
selectMapShow
,
setSelectMapShow
]
=
useState
<
boolean
>
(
false
);
// 关闭弹窗
const
handleCancel
=
()
=>
{
form
.
resetFields
();
...
...
@@ -39,13 +41,14 @@ const AddEditModal: React.FC<propType> = (props) => {
form
.
validateFields
()
.
then
(
async
(
values
)
=>
{
await
handleSubmit
({
...
values
,
province
:
values
?.
area
?.
at
(
0
),
city
:
values
?.
area
?.
at
(
1
),
district
:
values
?.
area
?.
at
(
2
),
companyType
:
data
?.
id
===
1
?
0
:
1
,
});
if
(
position
)
{
await
handleSubmit
({
...
values
,
lat
:
position
.
lat
,
lon
:
position
.
lon
,
companyType
:
data
?.
id
===
1
?
0
:
1
,
});
}
})
.
catch
((
err
)
=>
{
message
...
...
@@ -66,22 +69,40 @@ const AddEditModal: React.FC<propType> = (props) => {
handleCancel
();
}
};
// 获取地区信息
const
getSecondDistrictInfo
=
async
()
=>
{
setLocalList
(
DistrictData
||
[]);
const
selectMapShowClick
=
()
=>
{
setSelectMapShow
(
true
);
};
const
selectMapClose
=
()
=>
{
setSelectMapShow
(
false
);
};
const
selectMapSubmit
=
(
value
:
{
lat
:
number
;
lon
:
number
;
address
:
string
})
=>
{
form
.
setFieldValue
(
'address'
,
value
.
address
);
setPosition
(
value
);
setSelectMapShow
(
false
);
};
const
addressInputEvent
=
(
e
:
any
)
=>
{
if
(
position
)
{
position
.
address
=
e
.
target
.
value
;
form
.
setFieldValue
(
'address'
,
e
.
target
.
value
||
undefined
);
setPosition
({
...
position
});
}
};
// componentDidMount
useEffect
(()
=>
{
if
(
!
open
)
return
;
getSecondDistrictInfo
().
then
();
if
(
!
data
)
return
;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
form
.
setFieldsValue
({
...
data
,
area
:
[
data
?.
province
,
data
?.
city
,
data
?.
district
],
});
// console.log('data --->', data);
setPosition
({
address
:
data
.
address
,
lat
:
data
.
lat
,
lon
:
data
.
lon
,
});
},
[
open
]);
return
(
<
Modal
...
...
@@ -100,35 +121,55 @@ const AddEditModal: React.FC<propType> = (props) => {
>
<
Input
placeholder=
{
'请输入单位名称'
}
maxLength=
{
25
}
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'单位全称'
rules=
{
[{
required
:
false
,
message
:
'请输入单位全称'
}]
}
name=
'fullName'
>
<
Input
placeholder=
{
'请输入单位全称'
}
maxLength=
{
50
}
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'行政区划'
name=
'area'
rules=
{
[{
required
:
true
,
message
:
'请选择行政区划'
}]
}
>
<
Cascader
options=
{
localList
}
placeholder=
'请选择行政区划'
allowClear
fieldNames=
{
{
label
:
'name'
,
value
:
'name'
,
children
:
'childInfo'
,
}
}
/>
</
Form
.
Item
>
{
/*<Form.Item*/
}
{
/* label='单位全称'*/
}
{
/* rules={[{ required: false, message: '请输入单位全称' }]}*/
}
{
/* name='fullName'*/
}
{
/*>*/
}
{
/* <Input placeholder={'请输入单位全称'} maxLength={50} allowClear />*/
}
{
/*</Form.Item>*/
}
{
/*<Form.Item*/
}
{
/* label='行政区划'*/
}
{
/* name='area'*/
}
{
/* rules={[{ required: true, message: '请选择行政区划' }]}*/
}
{
/*>*/
}
{
/* <Cascader*/
}
{
/* options={localList}*/
}
{
/* placeholder='请选择行政区划'*/
}
{
/* allowClear*/
}
{
/* fieldNames={{*/
}
{
/* label: 'name',*/
}
{
/* value: 'name',*/
}
{
/* children: 'childInfo',*/
}
{
/* }}*/
}
{
/* />*/
}
{
/*</Form.Item>*/
}
<
Form
.
Item
label=
'详细地址'
name=
'address'
rules=
{
[{
required
:
true
,
message
:
'请输入详细地址'
}]
}
>
<
Input
.
TextArea
placeholder=
'请输入详细地址'
maxLength=
{
50
}
showCount
/>
{
/*<Input.TextArea placeholder='请输入详细地址' maxLength={50} showCount />*/
}
<
Row
justify=
'space-between'
>
{
position
?
(
<
Col
span=
{
21
}
>
<
Input
placeholder=
'请输入详细地址'
value=
{
position
.
address
}
onChange=
{
addressInputEvent
}
/>
</
Col
>
)
:
(
''
)
}
<
Col
span=
{
2
}
>
<
Button
icon=
{
<
EnvironmentOutlined
/>
}
type=
'primary'
onClick=
{
selectMapShowClick
}
></
Button
>
</
Col
>
</
Row
>
</
Form
.
Item
>
<
Form
.
Item
label=
'联系人'
name=
'companyUserName'
>
<
Input
placeholder=
'请输入联系人'
maxLength=
{
15
}
/>
...
...
@@ -152,6 +193,7 @@ const AddEditModal: React.FC<propType> = (props) => {
<
Form
.
Item
label=
'备注'
name=
'remark'
>
<
Input
.
TextArea
placeholder=
'请输入备注'
maxLength=
{
50
}
showCount
/>
</
Form
.
Item
>
<
SelectMap
open=
{
selectMapShow
}
closed=
{
selectMapClose
}
submit=
{
selectMapSubmit
}
/>
</
Form
>
</
Modal
>
);
...
...
src/pages/systemManage/companyManage/index.tsx
→
src/pages/systemManage/companyManage/
companyList/
index.tsx
浏览文件 @
3018428e
...
...
@@ -6,6 +6,7 @@ import { InterListType, InterReqType } from '~/api/interface';
import
{
ColumnsType
}
from
'antd/es/table'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
{
listCompanyPage
}
from
'~/api/interface/systemManageType'
;
import
{
useNavigate
}
from
'react-router-dom'
;
import
AddEditModal
from
'./comp/addEditModal'
;
// 列表的数据类型
...
...
@@ -16,6 +17,7 @@ type ReqType = InterReqType<listCompanyPage>;
let
query
:
ReqType
=
{};
const
CompanyManageView
=
()
=>
{
const
navigate
=
useNavigate
();
const
{
confirm
}
=
Modal
;
// 新增编辑弹窗是否开启
const
[
addEditModalVisible
,
setAddEditModalVisible
]
=
useState
(
false
);
...
...
@@ -63,7 +65,7 @@ const CompanyManageView = () => {
// 删除单位
const
handleDelete
=
(
value
:
TableType
[
0
])
=>
{
confirm
({
title
:
'提示'
,
title
:
'提示
(删除会造成该单位下的商品全部删除)
'
,
content
:
'是否删除该单位?'
,
onOk
:
async
()
=>
{
const
res
=
await
SystemManageAPI
.
listCompanyRemove
({
id
:
value
.
id
});
...
...
@@ -77,6 +79,14 @@ const CompanyManageView = () => {
},
});
};
//跳转单位详情
const
toCompanyDetail
=
(
record
:
TableType
[
0
])
=>
{
navigate
({
pathname
:
'/systemManage/companyDetail'
,
search
:
`id=
${
record
.
id
}
`
,
});
};
// componentDidMount
useEffect
(()
=>
{
query
=
{};
...
...
@@ -88,17 +98,11 @@ const CompanyManageView = () => {
title
:
'单位名称'
,
dataIndex
:
'companyName'
,
align
:
'center'
,
width
:
'
150px
'
,
width
:
'
20%
'
,
fixed
:
'left'
,
ellipsis
:
true
,
},
{
title
:
'行政区划'
,
dataIndex
:
'province'
,
align
:
'center'
,
render
:
(
_value
,
record
)
=>
`
${
record
.
province
}
/
${
record
.
city
}
/
${
record
.
district
}
`
,
},
{
title
:
'详细地址'
,
dataIndex
:
'address'
,
align
:
'center'
,
...
...
@@ -117,7 +121,7 @@ const CompanyManageView = () => {
},
{
title
:
'操作'
,
width
:
'
100px
'
,
width
:
'
20%
'
,
fixed
:
'right'
,
align
:
'center'
,
render
:
(
_text
,
record
)
=>
(
...
...
@@ -131,6 +135,9 @@ const CompanyManageView = () => {
>
变更
</
Button
>
<
Button
type=
'link'
onClick=
{
()
=>
toCompanyDetail
(
record
)
}
>
详情
</
Button
>
<
Button
type=
'link'
danger
...
...
src/router/index.ts
浏览文件 @
3018428e
...
...
@@ -3,44 +3,40 @@ import { RouteObjectType, routerList } from '~/router/router';
import
{
InterDataType
}
from
'~/api/interface'
;
import
{
listMenuInfoType
}
from
'~/api/interface/systemManageType'
;
import
{
SystemManageAPI
}
from
'~/api'
;
import
Cookies
from
'js-cookie'
;
import
{
store
}
from
'~/store'
;
import
{
SET_MENU
}
from
'~/store/module/menu'
;
//菜单类型
type
menuType
=
InterDataType
<
listMenuInfoType
>
;
// 缓存路由列表
let
routerListStore
:
any
[]
=
[];
// 获取用户权限路由列表
export
const
authRouterList
=
async
()
=>
{
if
(
localStorage
.
getItem
(
'roleId'
)
&&
Cookies
.
get
(
'SHAREFLY-TOKEN'
))
{
// 如果缓存中没有数据
if
(
routerListStore
.
length
===
0
)
{
// 加载路由数据
const
{
result
}
=
await
SystemManageAPI
.
getListRoleMenuInfo
({
roleId
:
Number
(
localStorage
.
getItem
(
'roleId'
)),
});
const
ids
:
number
[]
=
getAllKeys
([
result
]);
const
getRouteList
=
(
data
:
RouteObjectType
[])
=>
{
return
data
.
reduce
((
pre
:
RouteObjectType
[],
cur
)
=>
{
const
Obj
:
RouteObjectType
=
{
...
cur
};
if
(
ids
.
includes
(
Obj
.
meta
.
id
)
||
Obj
.
meta
.
hidden
)
{
if
(
Obj
.
children
)
{
Obj
.
children
=
[...
getRouteList
(
Obj
.
children
)];
}
pre
.
push
(
Obj
);
// 如果缓存中没有数据
if
(
store
.
getState
().
Menu
.
menuList
.
length
===
0
)
{
// 加载路由数据
const
{
result
}
=
await
SystemManageAPI
.
getListRoleMenuInfo
({
roleId
:
Number
(
localStorage
.
getItem
(
'roleId'
)),
});
const
ids
:
number
[]
=
getAllKeys
([
result
]);
const
getRouteList
=
(
data
:
RouteObjectType
[])
=>
{
return
data
.
reduce
((
pre
:
RouteObjectType
[],
cur
)
=>
{
const
Obj
:
RouteObjectType
=
{
...
cur
};
if
(
ids
.
includes
(
Obj
.
meta
.
id
)
||
Obj
.
meta
.
hidden
)
{
if
(
Obj
.
children
)
{
Obj
.
children
=
[...
getRouteList
(
Obj
.
children
)];
}
return
pre
;
},
[]);
};
const
arr
=
[...
getRouteList
(
routerList
)];
// 将路由数据存到store中
routerListStore
=
arr
;
// 完成后返回路由数据
return
Promise
.
resolve
(
arr
);
}
else
{
return
Promise
.
resolve
(
routerListStore
);
}
pre
.
push
(
Obj
);
}
return
pre
;
},
[]);
};
const
arr
=
[...
getRouteList
(
routerList
)];
// 将路由数据存到store中
store
.
dispatch
(
SET_MENU
(
arr
));
// 完成后返回路由数据
return
Promise
.
resolve
(
arr
);
}
else
{
return
Promise
.
resolve
(
store
.
getState
().
Menu
.
menuList
);
}
return
Promise
.
resolve
([]);
};
//获取全部节点
const
getAllKeys
=
(
data
:
menuType
[])
=>
{
...
...
src/router/privateRouter.tsx
浏览文件 @
3018428e
...
...
@@ -14,23 +14,29 @@ function PrivateRouter() {
// TODO: 判断是否登录 (需要改为实时获取地址栏的路由)
const
path
=
location
.
pathname
;
const
token
=
Cookies
.
get
(
'SHAREFLY-TOKEN'
);
const
roleId
=
localStorage
.
getItem
(
'roleId'
);
if
(
!
token
&&
path
!==
'/login'
)
{
navigate
(
'/login'
,
{
replace
:
true
});
return
;
}
if
(
roleId
&&
token
)
{
// 整合路由数据
authRouterList
().
then
((
value
)
=>
{
if
(
value
.
length
)
{
const
routes
=
[...
value
,
...
whiteRouterList
];
setRouter
(
routes
);
if
(
path
===
'/'
)
{
navigate
({
pathname
:
value
[
0
].
children
?.
find
((
v
:
any
)
=>
!
v
.
meta
.
hidden
)?.
path
});
}
}
else
{
message
.
warning
(
'该账号暂无权限'
);
navigate
(
'/login'
,
{
replace
:
true
});
}
});
}
};
useEffect
(()
=>
{
beforeEach
();
// 整合路由数据
authRouterList
().
then
((
value
)
=>
{
if
(
value
.
length
)
{
const
routes
=
[...
value
,
...
whiteRouterList
];
setRouter
(
routes
);
//不同账号登录时,重新更新路由(有瑕疵)
}
else
if
(
localStorage
.
getItem
(
'roleId'
))
{
message
.
warning
(
'该账号暂无权限'
);
navigate
(
'/login'
,
{
replace
:
true
});
}
});
},
[
location
.
pathname
]);
return
useRoutes
(
router
);
...
...
src/router/router.tsx
浏览文件 @
3018428e
...
...
@@ -91,13 +91,16 @@ const RentAddOrEditOrDetailView = React.lazy(
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'
));
//产品列表
const
ProduceDetailView
=
React
.
lazy
(
()
=>
import
(
'~/pages/mallManage/produceManage/produceDetail'
),
);
//产品详情
const
MakeListView
=
React
.
lazy
(()
=>
import
(
'~/pages/mallManage/makeManage/makeList'
));
// 分类管理
const
CategoryListView
=
React
.
lazy
(()
=>
import
(
'~/pages/categoryManage/categoryList'
));
const
CategoryManage
=
React
.
lazy
(()
=>
import
(
'~/pages/categoryManage/category'
));
const
CategoryDetail
=
React
.
lazy
(()
=>
import
(
'~/pages/categoryManage/category/detail'
));
// 目录管理
...
...
@@ -119,7 +122,10 @@ import TenderManageDetail from '~/pages/resourceManage/tenderManage/detail';
import
TenderManageFeedback
from
'~/pages/resourceManage/tenderManage/feedback'
;
import
BusinessCaseManage
from
'~/pages/resourceManage/businessCaseManage'
;
import
CustomIdentityView
from
'~/pages/customManage/customIdentity'
;
import
CompanyManageView
from
'~/pages/systemManage/companyManage'
;
import
CompanyListView
from
'~/pages/systemManage/companyManage/companyList'
;
//单位列表
const
CompanyDetailView
=
React
.
lazy
(
()
=>
import
(
'~/pages/systemManage/companyManage/companyDetail'
),
);
import
AccountLimit
from
'~/pages/systemManage/limitManage/roleList'
;
//账号权限
import
LimitInfo
from
'~/pages/systemManage/limitManage/limitInfo'
;
import
CustomListDetail
from
'~/pages/customManage/customList/detail'
;
//权限信息
...
...
@@ -467,16 +473,6 @@ export const routerList: Array<RouteObjectType> = [
},
children
:
[
{
path
:
'/mallManage/courseManage'
,
element
:
withLoadingComponent
(<
CourseManageView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1010
,
icon
:
<
BookOutlined
/>,
title
:
'课程管理'
,
},
},
{
path
:
'/mallManage/serviceList'
,
element
:
withLoadingComponent
(<
ServiceListView
/>),
errorElement
:
<
ErrorPage
/>,
...
...
@@ -585,7 +581,7 @@ export const routerList: Array<RouteObjectType> = [
},
{
path
:
'/mallManage/mallGoods/detail'
,
element
:
withLoadingComponent
(<
Mall
AddOrEditOrDetail
View
/>),
element
:
withLoadingComponent
(<
Mall
GoodsDetails
View
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
10146
,
...
...
@@ -687,8 +683,8 @@ export const routerList: Array<RouteObjectType> = [
},
},
{
path
:
'/categoryManage/
jobServicesCategory/4
'
,
element
:
withLoadingComponent
(<
Category
Manage
/>),
path
:
'/categoryManage/
categoryList
'
,
element
:
withLoadingComponent
(<
Category
ListView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1240
,
...
...
@@ -696,6 +692,16 @@ export const routerList: Array<RouteObjectType> = [
icon
:
<
AppstoreOutlined
/>,
},
},
// {
// path: '/categoryManage/jobServicesCategory/4',
// element: withLoadingComponent(<CategoryManage />),
// errorElement: <ErrorPage />,
// meta: {
// id: 1240,
// title: '产品商城分类',
// icon: <AppstoreOutlined />,
// },
// },
{
path
:
'/categoryManage/jobServicesCategory/0'
,
element
:
withLoadingComponent
(<
CategoryManage
/>),
...
...
@@ -903,7 +909,7 @@ export const routerList: Array<RouteObjectType> = [
meta
:
{
id
:
1600
,
icon
:
<
BankOutlined
/>,
title
:
'
飞手
培训'
,
title
:
'
执照
培训'
,
},
children
:
[
{
...
...
@@ -938,6 +944,16 @@ export const routerList: Array<RouteObjectType> = [
hidden
:
true
,
},
},
{
path
:
'/pilotTraining/courseManage'
,
element
:
withLoadingComponent
(<
CourseManageView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1010
,
icon
:
<
BookOutlined
/>,
title
:
'课程管理'
,
},
},
],
},
{
...
...
@@ -982,13 +998,24 @@ export const routerList: Array<RouteObjectType> = [
},
},
{
path
:
'/systemManage/company
Manage
'
,
element
:
withLoadingComponent
(<
Company
Manage
View
/>),
path
:
'/systemManage/company
List
'
,
element
:
withLoadingComponent
(<
Company
List
View
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1430
,
title
:
'单位管理'
,
title
:
'单位列表'
,
icon
:
<
BankOutlined
/>,
},
},
{
path
:
'/systemManage/companyDetail'
,
element
:
withLoadingComponent
(<
CompanyDetailView
/>),
errorElement
:
<
ErrorPage
/>,
meta
:
{
id
:
1440
,
title
:
'单位详情'
,
icon
:
<
BankOutlined
/>,
hidden
:
true
,
},
},
],
...
...
src/store/module/menu/index.ts
浏览文件 @
3018428e
import
{
createSlice
}
from
'@reduxjs/toolkit'
;
const
initialState
=
{
menuList
:
JSON
.
parse
(
localStorage
.
getItem
(
'SXTB-ADMIN-MENU-LIST'
)
as
string
)
||
[],
menuList
:
[],
collapsedActive
:
false
,
menuId
:
JSON
.
parse
(
localStorage
.
getItem
(
'SXTB-ADMIN-MENU-ID'
)
as
string
)
||
null
,
roleId
:
localStorage
.
getItem
(
'roleId'
)
?
Number
(
localStorage
.
getItem
(
'roleId'
))
:
-
1
,
};
export
const
menuSlice
=
createSlice
({
...
...
@@ -12,22 +12,19 @@ export const menuSlice = createSlice({
reducers
:
{
SET_MENU
(
state
,
action
)
{
state
.
menuList
=
action
.
payload
;
localStorage
.
setItem
(
'SXTB-ADMIN-MENU-LIST'
,
JSON
.
stringify
(
action
.
payload
));
},
SET_COLLAPSE
(
state
,
action
)
{
state
.
collapsedActive
=
action
.
payload
;
},
REMOVE_MENU
(
state
)
{
localStorage
.
setItem
(
'SXTB-ADMIN-MENU-LIST'
,
JSON
.
stringify
([]));
state
.
menuList
=
[];
},
SET_MENU_ID
(
state
,
action
)
{
localStorage
.
setItem
(
'SXTB-ADMIN-MENU-ID'
,
JSON
.
stringify
(
action
.
payload
))
;
state
.
menuId
=
action
.
payload
;
state
.
roleId
=
action
.
payload
;
localStorage
.
setItem
(
'roleId'
,
action
.
payload
)
;
},
REMOVE_MENU_ID
(
state
)
{
localStorage
.
setItem
(
'SXTB-ADMIN-MENU-ID'
,
JSON
.
stringify
(
null
));
state
.
menuId
=
null
;
REMOVE_MENU_ID
()
{
localStorage
.
removeItem
(
'roleId'
);
},
},
});
...
...
src/store/module/userInfo/index.ts
浏览文件 @
3018428e
...
...
@@ -2,8 +2,6 @@ import { createSlice } from '@reduxjs/toolkit';
const
initialState
=
{
userInfo
:
JSON
.
parse
(
localStorage
.
getItem
(
'SXTB-ADMIN-USER-INFO'
)
as
string
)
||
[],
roleId
:
-
1
,
roleList
:
[],
};
export
const
userInfoSlice
=
createSlice
({
...
...
@@ -14,24 +12,9 @@ export const userInfoSlice = createSlice({
state
.
userInfo
=
action
.
payload
;
localStorage
.
setItem
(
'SXTB-ADMIN-USER-INFO'
,
JSON
.
stringify
(
action
.
payload
));
},
SET_ROLE_ID
(
state
,
action
)
{
state
.
roleId
=
action
.
payload
;
localStorage
.
setItem
(
'roleId'
,
action
.
payload
);
},
REMOVE_ROLE_ID
()
{
localStorage
.
removeItem
(
'roleId'
);
},
SET_ROLE_LIST
(
state
,
action
)
{
state
.
roleList
=
action
.
payload
;
localStorage
.
setItem
(
'roleObj'
,
JSON
.
stringify
(
action
.
payload
));
},
REMOVE_ROLE_LIST
()
{
localStorage
.
removeItem
(
'roleObj'
);
},
},
});
export
const
{
SET_USERINFO
,
SET_ROLE_ID
,
SET_ROLE_LIST
,
REMOVE_ROLE_LIST
,
REMOVE_ROLE_ID
}
=
userInfoSlice
.
actions
;
export
const
{
SET_USERINFO
}
=
userInfoSlice
.
actions
;
export
const
UserInfo
=
userInfoSlice
.
reducer
;
src/utils/validateUtils.ts
浏览文件 @
3018428e
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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论