Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-platform
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
shenshaokai
jinfa-platform
Commits
3fcdf329
Commit
3fcdf329
authored
Aug 29, 2020
by
GuanHua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:店铺商城页面和分类商品加载的骨架屏组件
parent
11004e1e
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
810 additions
and
49 deletions
+810
-49
index.ts
config/shopRoutes/index.ts
+14
-0
app.tsx
src/app.tsx
+12
-6
menu.ts
src/locales/zh-CN/menu.ts
+2
-0
index.tsx
src/pages/lxMall/commodity/index.tsx
+1
-1
list.tsx
src/pages/lxMall/commodity/list.tsx
+4
-1
index.less
src/pages/lxMall/components/AboutUs/index.less
+19
-1
index.tsx
src/pages/lxMall/components/AboutUs/index.tsx
+39
-12
index.tsx
...ges/lxMall/components/Filter/components/UseArea/index.tsx
+0
-4
index.tsx
src/pages/lxMall/components/FloorAnchor/index.tsx
+3
-0
index.less
src/pages/lxMall/components/FloorSkeleton/index.less
+522
-0
index.tsx
src/pages/lxMall/components/FloorSkeleton/index.tsx
+144
-0
index.tsx
src/pages/lxMall/components/MainNav/index.tsx
+5
-3
index.tsx
src/pages/lxMall/index/index.tsx
+5
-3
LXShopLayout.tsx
src/pages/lxMall/layouts/LXShopLayout.tsx
+16
-4
index.tsx
src/pages/lxMall/shop/index.tsx
+20
-12
index.tsx
src/pages/shop/components/citySelect/index.tsx
+2
-2
request.ts
src/utils/request.ts
+2
-0
No files found.
config/shopRoutes/index.ts
View file @
3fcdf329
...
...
@@ -19,6 +19,20 @@ const shopRoute = {
component
:
'@/pages/lxMall/commodity'
,
},
{
// 积分商城
path
:
`/shop/pointsMall`
,
name
:
'shopPointsMall'
,
key
:
'shopPointsMall'
,
component
:
'@/pages/lxMall/pointsMall'
,
},
{
// 资讯
path
:
`/shop/infomation`
,
name
:
'shopInfomation'
,
key
:
'shopInfomation'
,
component
:
'@/pages/lxMall/information'
,
},
{
// 关于我们
path
:
`/shop/about`
,
name
:
'shopAbout'
,
...
...
src/app.tsx
View file @
3fcdf329
...
...
@@ -20,22 +20,28 @@ const userLoginLists = [
'/user/login'
,
'/user/register'
,
]
// let routeAuthUrls: any[] = []
// 路由白名单
const
whiteLists
=
[
...
userLoginLists
,
// 商城相关路由
const
mallLists
=
[
'/'
,
'/channelmall'
,
'/shop'
,
'/purchaseOnline'
,
'/pointsMall'
,
// '/memberCenter',
'/memberCenter/noAuth'
,
'/commodity'
,
'/shops'
,
'/shop/commodity/detail'
,
'/shop/commodity'
,
'/infomation'
,
]
// let routeAuthUrls: any[] = []
// 路由白名单
const
whiteLists
=
[
...
userLoginLists
,
...
mallLists
,
// '/memberCenter',
'/memberCenter/noAuth'
,
'/403'
,
'/404'
,
'/500'
,
...
...
src/locales/zh-CN/menu.ts
View file @
3fcdf329
...
...
@@ -14,9 +14,11 @@ export default {
'menu.shopCommodity'
:
'商品'
,
'menu.purchaseOnline'
:
'在线求购'
,
'menu.pointsMall'
:
'积分商城'
,
'menu.shopPointsMall'
:
'积分兑换'
,
'menu.shops'
:
'店铺'
,
'menu.shopAbout'
:
'关于我们'
,
'menu.infomation'
:
'资讯'
,
'menu.shopInfomation'
:
'资讯'
,
'menu.admin'
:
'管理页'
,
'menu.admin.sub-page'
:
'二级管理页'
,
'menu.login'
:
'登录'
,
...
...
src/pages/lxMall/commodity/index.tsx
View file @
3fcdf329
...
...
@@ -52,7 +52,7 @@ const Commodity: React.FC<CommodityPropsType> = (props) => {
const
[
totalCount
,
setTotalCount
]
=
useState
<
number
>
(
0
)
// const [filterParam, setFilterParam] = useState<filterQuery | {}>({})
const
filterConfig
=
[
FILTER_TYPE
.
commonlyUsed
,
FILTER_TYPE
.
category
,
FILTER_TYPE
.
style
,
FILTER_TYPE
.
brand
,
FILTER_TYPE
.
price
,
FILTER_TYPE
.
useArea
,
FILTER_TYPE
.
commodityType
]
console
.
log
(
layoutType
,
"layoutType"
)
useEffect
(()
=>
{
fetchCommodityList
()
},
[
filterParam
,
current
])
...
...
src/pages/lxMall/commodity/list.tsx
View file @
3fcdf329
import
React
from
'react'
import
cx
from
'classnames'
import
{
Skeleton
}
from
'antd'
import
{
GetSearchShopEnterpriseGetCommodityListResponseDetail
}
from
'@/services'
import
creditIcon
from
'@/assets/imgs/credit_icon.png'
import
styles
from
'./list.less'
...
...
@@ -50,7 +51,9 @@ const CommodityList: React.FC<CommodityListPropsType> = (props) => {
<
div
key=
{
item
.
id
}
className=
{
cx
(
styles
.
commodity_list_item
,
styles
.
row
)
}
>
<
a
href=
{
`/${layoutType === 'channel' ? 'channelmall' : 'shop'}/commodity/detail?id=${item.id}&type=${item.priceType}`
}
target=
"_blank"
>
<
div
className=
{
styles
.
goods_img
}
>
<
img
src=
{
item
.
commodityPic
||
"https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg"
}
/>
{
item
.
commodityPic
?
<
img
src=
{
item
.
commodityPic
}
/>
:
<
Skeleton
.
Image
style=
{
{
width
:
220
,
height
:
220
}
}
/>
}
</
div
>
<
div
className=
{
styles
.
info_box
}
>
{
...
...
src/pages/lxMall/components/AboutUs/index.less
View file @
3fcdf329
...
...
@@ -54,7 +54,7 @@
margin-left: 55px;
flex: 1;
width: 0;
padding-right: 68px;
//
padding-right: 68px;
&_tabs {
display: flex;
...
...
@@ -74,6 +74,23 @@
}
}
.honors_list {
display: flex;
flex-wrap: wrap;
margin: 0 -16px;
&_item {
width: 160px;
height: 107px;
margin: 30px 16px 0 16px;
&>img {
width: 160px;
height: 107px;
}
}
}
&_title {
font-size: 24px;
font-weight: 500;
...
...
@@ -83,6 +100,7 @@
&_brief {
color: #666666;
padding-right: 68px;
}
&_more {
...
...
src/pages/lxMall/components/AboutUs/index.tsx
View file @
3fcdf329
import
React
,
{
useState
}
from
'react'
import
React
,
{
useState
,
Fragment
}
from
'react'
import
cx
from
'classnames'
import
{
ArrowRightOutlined
}
from
'@ant-design/icons'
import
{
Carousel
}
from
'antd'
import
{
Carousel
,
Skeleton
}
from
'antd'
import
styles
from
'./index.less'
enum
TAB_TYPE
{
introduction
=
1
,
honors
=
2
}
const
AboutUs
:
React
.
FC
=
()
=>
{
const
[
aboutTab
,
setAboutTab
]
=
useState
<
number
>
(
1
)
//1:公司简介 2:资质荣誉
const
[
aboutTab
,
setAboutTab
]
=
useState
<
number
>
(
TAB_TYPE
.
introduction
)
//1:公司简介 2:资质荣誉
const
handleChangeAboutTab
=
(
tab
:
number
)
=>
{
if
(
aboutTab
!==
tab
)
{
...
...
@@ -14,8 +19,10 @@ const AboutUs: React.FC = () => {
}
}
const
list
=
Array
.
apply
({},
new
Array
(
6
))
return
(
<
div
className=
{
styles
.
channel_info_about
}
>
<
div
className=
{
styles
.
channel_info_about
}
id=
"about_us"
>
<
div
className=
{
styles
.
channel_info_about_container
}
>
<
div
className=
{
styles
.
channel_info_about_img
}
>
<
Carousel
className=
{
styles
.
channel_info_about_img_list
}
pauseOnDotsHover
>
...
...
@@ -40,14 +47,34 @@ const AboutUs: React.FC = () => {
<
div
className=
{
cx
(
styles
.
channel_info_about_info_tabs_item
,
aboutTab
===
1
?
styles
.
active
:
''
)
}
onClick=
{
()
=>
handleChangeAboutTab
(
1
)
}
>
公司简介
</
div
>
<
div
className=
{
cx
(
styles
.
channel_info_about_info_tabs_item
,
aboutTab
===
2
?
styles
.
active
:
''
)
}
onClick=
{
()
=>
handleChangeAboutTab
(
2
)
}
>
资质荣誉
</
div
>
</
div
>
<
div
className=
{
styles
.
channel_info_about_info_title
}
>
温州市龙昌皮具有限公司
</
div
>
<
p
className=
{
styles
.
channel_info_about_info_brief
}
>
公司位于温州,多年行业经验,专业经营各种成品真皮,包括全粒面牛皮,修面皮,漆色皮,打腊皮,水腊皮……二层皮胚,硅胶二层等,产品主要用于时尚女鞋、男鞋、箱包、皮带、服装、汽车内饰等高端皮具制品行业。
本着质量保证,品种多样,现货充足,款式新颖的经营特色和薄利多销的原则,为客户提供长期优质的服务!
</
p
>
<
p
>
同时公司长期寻找各皮厂合作,要求皮厂有自已的生产线及高性价比特色产品,可作为普通供应商合作,也可作为其核心经销商战略合作。欢迎来人来样,当面洽谈。
</
p
>
{
aboutTab
===
TAB_TYPE
.
introduction
?
(
<
Fragment
>
<
div
className=
{
styles
.
channel_info_about_info_title
}
>
温州市龙昌皮具有限公司
</
div
>
<
p
className=
{
styles
.
channel_info_about_info_brief
}
>
公司位于温州,多年行业经验,专业经营各种成品真皮,包括全粒面牛皮,修面皮,漆色皮,打腊皮,水腊皮……二层皮胚,硅胶二层等,产品主要用于时尚女鞋、男鞋、箱包、皮带、服装、汽车内饰等高端皮具制品行业。
本着质量保证,品种多样,现货充足,款式新颖的经营特色和薄利多销的原则,为客户提供长期优质的服务!
</
p
>
<
p
className=
{
styles
.
channel_info_about_info_brief
}
>
同时公司长期寻找各皮厂合作,要求皮厂有自已的生产线及高性价比特色产品,可作为普通供应商合作,也可作为其核心经销商战略合作。欢迎来人来样,当面洽谈。
</
p
>
</
Fragment
>
)
:
(
<
Fragment
>
<
div
className=
{
styles
.
honors_list
}
>
{
list
.
map
((
_
,
index
)
=>
(
<
div
key=
{
`honors_list_item_${index}`
}
className=
{
styles
.
honors_list_item
}
>
<
Skeleton
.
Image
style=
{
{
width
:
160
,
height
:
107
}
}
/>
</
div
>
))
}
</
div
>
</
Fragment
>
)
}
<
div
className=
{
styles
.
channel_info_about_info_more
}
>
<
span
>
查看更多
</
span
>
<
ArrowRightOutlined
/>
...
...
src/pages/lxMall/components/Filter/components/UseArea/index.tsx
View file @
3fcdf329
...
...
@@ -76,10 +76,6 @@ const UseArea: React.FC<UseAreaPropsType> = (props) => {
}
},
[
layoutType
])
useEffect
(()
=>
{
console
.
log
(
selectCity
,
"selectCity"
)
},
[
selectCity
])
const
initAreaData
=
(
data
:
GetSearchShopEnterpriseGetAreaResponse
)
=>
{
if
(
!!
data
)
{
return
data
.
map
(
item
=>
{
...
...
src/pages/lxMall/components/FloorAnchor/index.tsx
View file @
3fcdf329
...
...
@@ -17,6 +17,9 @@ const FloorAnchor: React.FC<FloorAnchorPropsType> = (props) => {
<
div
className=
"anchor_wrap"
>
<
Anchor
className=
"anchor"
offsetTop=
{
120
}
>
{
type
===
'shop'
&&
<
Anchor
.
Link
href=
{
`#about_us`
}
title=
"关于我们"
/>
}
{
anchorList
.
map
(
item
=>
(
<
Anchor
.
Link
key=
{
item
.
id
}
href=
{
`#floorline_${item.id}`
}
title=
{
item
.
name
}
/>
))
...
...
src/pages/lxMall/components/FloorSkeleton/index.less
0 → 100644
View file @
3fcdf329
.skeleton_image {
width: 100% !important;
height: 100% !important;
}
.shop_floor_line {
position: relative;
.floor_line_container {
padding-top: 42px;
padding-bottom: 40px;
border-bottom: 1px solid #f5f5f5;
width: 1200px;
margin: 0 auto;
.floor_line_body {
position: relative;
}
.floor_line_name {
line-height: 20px;
margin-bottom: 22px;
.floor_line_name_text {
font-size: 20px;
font-weight: bold;
color: #333333;
}
.floor_line_more {
float: right;
color: #666666;
font-size: 14px;
}
}
// 品类样式
.shop-floor-line-category {
position: absolute;
top: 0;
left: 0;
width: 240px;
height: 300px;
overflow: hidden;
z-index: 2;
.floor-line-category-banner {
width: 100%;
height: auto;
}
.recommend_category_list {
position: absolute;
display: flex;
flex-wrap: wrap;
width: 200px;
bottom: 20px;
left: 20px;
z-index: 5;
&_item {
width: 100px;
background: rgba(0, 0, 0, 0.65);
opacity: 0.9;
border: 1px solid rgba(255, 255, 255, 0.2);
&:hover {
background: rgba(0, 0, 0, 0.55);
}
.recommend_category_list_item_body {
display: flex;
align-items: center;
height: 32px;
justify-content: center;
color: #ffffff;
&>.text {
font-size: 12px;
width: 56px;
display: block;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&>.icon {
color: #999999;
font-size: 10px;
margin-left: 12px;
}
}
}
a {
color: #333333;
}
}
}
// 商品列表样式
.shop-floor-line-goods {
position: relative;
width: 1200px;
z-index: 1;
.goods_list {
display: flex;
min-height: 300px;
flex-wrap: wrap;
&_item {
width: 240px;
height: 300px;
padding-top: 20px;
margin: 0 0 -1px -1px;
border: 1px solid #f5f5f5;
&.empty {
background: #f5f5f5;
}
a {
outline: none;
}
.goods_img {
width: 200px;
height: 200px;
overflow: hidden;
margin: 0 auto;
&>img {
height: 100%;
display: block;
margin: 0 auto;
}
}
.goods_name {
font-size: 14px;
color: #333333;
text-align: left;
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
line-height: 14px;
padding: 0 20px;
margin-top: 15px;
}
.goods_price {
padding: 0 20px;
color: var(--mall_main_color);
margin-top: 16px;
line-height: 16px;
display: flex;
align-items: center;
&>.count {
margin-left: auto;
font-size: 12px;
color: #999999;
}
&>span {
font-size: 12px;
}
}
}
}
}
}
}
.floor_line {
position: relative;
.floor_line_container {
padding-top: 42px;
padding-bottom: 40px;
border-bottom: 1px solid #E5E5E5;
width: 1200px;
margin: 0 auto;
.floor_line_name {
line-height: 20px;
margin-bottom: 22px;
.floor_line_name_text {
font-size: 20px;
font-weight: bold;
color: #333333;
}
.floor_line_more {
float: right;
color: #666666;
font-size: 14px;
}
}
// 品类样式
.floor-line-category {
position: relative;
width: 152px;
height: 517px;
overflow: hidden;
.floor-line-category-banner {
height: 100%;
}
.recommend_category_list {
position: absolute;
width: 120px;
bottom: 20px;
left: 0;
z-index: 5;
&_item {
padding: 0 10px;
background: #ffffff;
&:hover {
background-color: #F5F5F5;
}
&:not(:last-child) {
.recommend_category_list_item_body {
border-bottom: 1px solid #F5F5F5;
}
}
.recommend_category_list_item_body {
display: flex;
align-items: center;
height: 36px;
padding-left: 10px;
&>.text {
color: #333333;
font-size: 12px;
flex: 1;
}
&>.icon {
color: rgba(0, 0, 0, .15);
}
}
}
a {
color: #333333;
}
}
}
// 楼层头部样式
.floor-line-header {
width: 100%;
height: 90px;
background-color: #ffffff;
border-bottom: 1px solid #F5F5F5;
padding-left: 21px;
display: flex;
.floor-line-header-count-info {
flex: 1;
display: flex;
align-items: center;
&-item {
margin-right: 30px;
font-size: 14px;
color: #333333;
&>span {
margin-right: 9px;
font-size: 16px;
font-weight: 500;
}
}
}
}
// 商品列表样式
.floor-line-goods {
width: 772px;
height: 428px;
background: #ffffff;
.goods_list {
display: flex;
flex-wrap: wrap;
&_item {
width: 150px;
height: 214px;
padding-top: 20px;
a {
outline: none;
}
.goods_img {
width: 120px;
height: 120px;
overflow: hidden;
margin: 0 auto;
&>img {
height: 100%;
display: block;
margin: 0 auto;
}
}
.goods_name {
font-size: 14px;
color: #333333;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
padding: 0 15px;
margin-top: 15px;
}
.goods_price {
text-align: center;
color: var(--mall_main_color);
margin-top: 16px;
padding: 0 15px;
line-height: 16px;
&>span {
font-size: 12px;
}
}
}
}
}
// 店铺列表样式
.floor-line-shop {
flex: 1;
background-color: #ffffff;
border-left: 1px solid #F5F5F5;
.shop_title {
height: 60px;
display: flex;
align-items: center;
font-size: 16px;
font-weight: 500;
padding-left: 20px;
border-bottom: 1px solid #F5F5F5;
}
.shop_list {
padding-top: 30px;
&_item {
display: flex;
align-items: center;
padding: 0 20px;
&:not(:last-child) {
margin-bottom: 30px;
}
.shop_logo {
width: 36px;
height: 36px;
overflow: hidden;
border-radius: 50%;
margin-right: 10px;
&>img {
height: 100%;
min-width: 100%;
}
}
.shop_name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
color: #333333;
}
}
}
}
// 品牌样式
.floor-line-brand {
width: 100%;
height: 100px;
background-color: #ffffff;
border-top: 1px solid #F5F5F5;
.brand_list {
display: flex;
&_item {
display: flex;
width: 200px;
height: 100px;
align-items: center;
justify-content: center;
&:not(:last-child) {
border-right: 1px solid #F5F5F5;
}
.brand_img_box {
width: 120px;
height: 60px;
&>img {
width: 100%;
height: 60px;
}
}
}
}
}
.floor-line-banner {
width: 500px;
height: 90px;
overflow: hidden;
margin-left: auto;
.floor-line-banner-item {
.floor-line-banner-item-img {
height: 100px;
width: auto;
display: block;
margin: 0 auto;
}
}
.ant-carousel .slick-dots-bottom {
bottom: 0;
margin-bottom: 15px;
justify-content: flex-start;
margin-left: 20px;
}
.ant-carousel .slick-dots li {
width: 5px;
height: 5px;
border-radius: 50%;
background: rgba(204, 204, 204, 1);
border: 1px solid rgba(204, 204, 204, 1);
&.slick-active {
border: 1px solid #fff;
background-color: #fff;
button {
background: transparent;
}
}
}
.ant-carousel .slick-slide {
text-align: center;
height: 90px;
line-height: 90px;
background: #364d79;
overflow: hidden;
}
.ant-carousel .slick-slide h3 {
color: #fff;
}
}
.floor_line_horizontal {
display: flex;
flex-direction: row;
}
.floor_line_vertical {
display: flex;
flex: 1;
flex-direction: column;
}
}
}
\ No newline at end of file
src/pages/lxMall/components/FloorSkeleton/index.tsx
0 → 100644
View file @
3fcdf329
import
React
from
'react'
import
{
RightOutlined
,
CaretRightOutlined
}
from
'@ant-design/icons'
import
{
Skeleton
}
from
'antd'
import
cx
from
'classnames'
import
{
LAYOUT_TYPE
}
from
'@/constants'
import
styles
from
'./index.less'
interface
FloorSkeletonPropsType
{
type
:
LAYOUT_TYPE
.
mall
|
LAYOUT_TYPE
.
shop
|
LAYOUT_TYPE
.
channel
}
const
FloorSkeleton
:
React
.
FC
<
FloorSkeletonPropsType
>
=
(
props
)
=>
{
const
{
type
}
=
props
let
dataList
=
Array
.
apply
({},
new
Array
(
9
))
let
goodsList
=
Array
.
apply
({},
new
Array
(
10
))
let
brandList
=
Array
.
apply
({},
new
Array
(
6
))
let
shopList
=
Array
.
apply
({},
new
Array
(
5
))
const
renderSkeleton
=
()
=>
{
switch
(
type
)
{
case
LAYOUT_TYPE
.
mall
:
return
(
<
div
className=
{
styles
.
floor_line
}
>
<
div
className=
{
styles
.
floor_line_container
}
>
<
div
className=
{
styles
.
floor_line_name
}
>
<
span
className=
{
styles
.
floor_line_name_text
}
><
Skeleton
.
Button
style=
{
{
width
:
200
}
}
active
/></
span
>
<
span
className=
{
styles
.
floor_line_more
}
><
Skeleton
.
Button
style=
{
{
width
:
200
}
}
active
/></
span
>
</
div
>
<
div
className=
{
styles
.
floor_line_body
}
>
<
div
className=
{
styles
.
floor_line_horizontal
}
>
<
section
className=
{
styles
[
"floor-line-category"
]
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
section
>
<
div
className=
{
styles
.
floor_line_vertical
}
>
<
section
className=
{
styles
[
"floor-line-header"
]
}
>
<
div
className=
{
styles
[
"floor-line-header-count-info"
]
}
>
<
div
className=
{
styles
[
"floor-line-header-count-info-item"
]
}
>
<
Skeleton
.
Button
style=
{
{
width
:
150
}
}
active
/>
</
div
>
<
div
className=
{
styles
[
"floor-line-header-count-info-item"
]
}
>
<
Skeleton
.
Button
style=
{
{
width
:
150
}
}
active
/>
</
div
>
<
section
className=
{
styles
[
"floor-line-banner"
]
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
section
>
</
div
>
</
section
>
<
div
className=
{
styles
.
floor_line_horizontal
}
>
<
section
className=
{
styles
[
"floor-line-goods"
]
}
>
<
div
className=
{
styles
.
goods_list
}
>
{
goodsList
.
map
((
_
,
index
)
=>
(
<
div
key=
{
`goods_list_item_${index}`
}
className=
{
styles
.
goods_list_item
}
>
<
div
className=
{
styles
.
goods_img
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
div
>
<
div
className=
{
styles
.
goods_name
}
>
<
Skeleton
.
Button
active
style=
{
{
width
:
120
,
height
:
24
}
}
/>
</
div
>
</
div
>
))
}
</
div
>
</
section
>
<
section
className=
{
styles
[
"floor-line-shop"
]
}
>
<
div
className=
{
styles
.
shop_title
}
><
Skeleton
.
Button
active
style=
{
{
width
:
120
,
height
:
24
}
}
/></
div
>
<
div
className=
{
styles
.
shop_list
}
>
{
shopList
.
map
((
_
,
index
)
=>
(
<
div
key=
{
`shop_list_item-${index}`
}
className=
{
styles
.
shop_list_item
}
>
<
div
className=
{
styles
.
shop_logo
}
><
Skeleton
.
Avatar
active
/></
div
>
<
div
className=
{
styles
.
shop_name
}
>
<
Skeleton
.
Button
active
style=
{
{
width
:
160
,
height
:
24
}
}
/>
</
div
>
</
div
>
))
}
</
div
>
</
section
>
</
div
>
</
div
>
</
div
>
<
section
className=
{
styles
[
"floor-line-brand"
]
}
>
<
div
className=
{
styles
.
brand_list
}
>
{
brandList
.
map
((
_
,
index
)
=>
(
<
div
className=
{
styles
.
brand_list_item
}
key=
{
`brand_list_item_${index}`
}
>
<
div
className=
{
styles
.
brand_img_box
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
div
>
</
div
>
))
}
</
div
>
</
section
>
</
div
>
</
div
>
</
div
>
)
case
LAYOUT_TYPE
.
shop
:
case
LAYOUT_TYPE
.
channel
:
return
(
<
div
className=
{
styles
.
shop_floor_line
}
>
<
div
className=
{
styles
.
floor_line_container
}
>
<
div
className=
{
styles
.
floor_line_name
}
>
<
span
className=
{
styles
.
floor_line_name_text
}
><
Skeleton
.
Button
style=
{
{
width
:
200
}
}
active
/></
span
>
<
span
className=
{
styles
.
floor_line_more
}
><
Skeleton
.
Button
style=
{
{
width
:
200
}
}
active
/></
span
>
</
div
>
<
div
className=
{
styles
.
floor_line_body
}
>
<
section
className=
{
styles
[
'shop-floor-line-category'
]
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
section
>
<
section
className=
{
styles
[
'shop-floor-line-goods'
]
}
>
<
div
className=
{
styles
.
goods_list
}
>
<
div
className=
{
cx
(
styles
.
goods_list_item
,
styles
.
empty
)
}
>
</
div
>
{
dataList
&&
dataList
.
map
((
_
,
index
)
=>
(
<
div
key=
{
`goods_list_item_${index}`
}
className=
{
styles
.
goods_list_item
}
>
<
div
className=
{
styles
.
goods_img
}
>
<
Skeleton
.
Button
active
className=
{
styles
.
skeleton_image
}
/>
</
div
>
<
div
className=
{
styles
.
goods_name
}
>
<
Skeleton
.
Input
active
style=
{
{
width
:
200
}
}
/>
</
div
>
</
div
>
))
}
</
div
>
</
section
>
</
div
>
</
div
>
</
div
>
)
}
}
return
renderSkeleton
()
}
export
default
FloorSkeleton
src/pages/lxMall/components/MainNav/index.tsx
View file @
3fcdf329
import
React
from
'react'
import
{
Link
}
from
'umi'
import
cx
from
'classnames'
import
{
LAYOUT_TYPE
}
from
'@/constants'
import
Category
from
'../Category'
import
styles
from
'./index.less'
interface
MainNavPropsType
{
menuData
:
any
;
pathname
:
string
;
type
:
"shop"
|
"mall"
|
"channel"
type
:
"shop"
|
"mall"
|
"channel"
,
shopId
?:
string
}
const
MainNav
:
React
.
FC
<
MainNavPropsType
>
=
(
props
)
=>
{
const
{
menuData
,
pathname
,
type
}
=
props
const
{
menuData
,
pathname
,
type
,
shopId
=
""
}
=
props
console
.
log
(
type
,
"type"
)
return
(
...
...
@@ -22,7 +24,7 @@ const MainNav: React.FC<MainNavPropsType> = (props) => {
{
menuData
&&
menuData
.
map
(
item
=>
!
item
.
hide
&&
(
<
li
className=
{
cx
(
styles
.
nav_item
,
item
.
path
===
pathname
?
styles
.
active
:
''
)
}
key=
{
item
.
key
}
>
<
Link
to=
{
item
.
path
}
>
{
item
.
name
}
</
Link
>
<
Link
to=
{
type
===
LAYOUT_TYPE
.
shop
?
`${item.path}?shopId=${shopId}`
:
item
.
path
}
>
{
item
.
name
}
</
Link
>
</
li
>
))
}
...
...
src/pages/lxMall/index/index.tsx
View file @
3fcdf329
...
...
@@ -6,8 +6,9 @@ import { inject, observer } from 'mobx-react'
import
FloorAnchor
from
'../components/FloorAnchor'
import
{
PublicApi
}
from
'@/services/api'
import
{
Advert
,
FloorLine
}
from
'lingxi-design-ui'
import
FloorSkeleton
from
'../components/FloorSkeleton'
import
{
GetTemplatePlatformFindAllFirstCategoryResponse
}
from
'@/services'
import
Loading
from
'../components/Loading
'
import
{
LAYOUT_TYPE
}
from
'@/constants
'
import
'./index.less'
interface
MallIndexPropsType
{
...
...
@@ -105,7 +106,7 @@ const MallIndex: React.FC<MallIndexPropsType> = (props) => {
</
FloorLine
.
FloorHeader
>
<
FloorLine
.
Horizontal
>
<
FloorLine
.
Goods
goodsList=
{
categoryDetail
.
goodsBOList
}
/>
<
FloorLine
.
Shops
shopsList=
{
categoryDetail
.
shopBOList
}
/>
<
FloorLine
.
Shops
shopsList=
{
categoryDetail
.
shopBOList
}
linkUrl=
{
`/shop?shopId=${btoa(JSON.stringify({ shopId: 2, meberId: 6 }))}`
}
/>
</
FloorLine
.
Horizontal
>
</
FloorLine
.
Vertical
>
</
FloorLine
.
Horizontal
>
...
...
@@ -119,6 +120,7 @@ const MallIndex: React.FC<MallIndexPropsType> = (props) => {
return
(
<
div
className=
"mall_index"
>
<
a
href=
{
`/shop?shopId=${btoa(JSON.stringify({ shopId: 2, memberId: 6 }))}`
}
>
店铺链接测试
</
a
>
{
useMemo
(()
=>
<
Advert
type=
"banner"
advertList=
{
firstAdvertList
}
hasQuickNav=
{
true
}
><
QuickNav
/></
Advert
>,
[
firstAdvertList
])
}
...
...
@@ -127,7 +129,7 @@ const MallIndex: React.FC<MallIndexPropsType> = (props) => {
useMemo
(()
=>
<
Advert
type=
"interact"
advertList=
{
secondAdvertList
}
/>,
[
secondAdvertList
])
}
{
categoryComponents
?
categoryComponents
:
<
Loading
/>
categoryComponents
?
categoryComponents
:
<
FloorSkeleton
type=
{
LAYOUT_TYPE
.
mall
}
/>
}
<
FindMore
/>
<
Information
/>
...
...
src/pages/lxMall/layouts/LXShopLayout.tsx
View file @
3fcdf329
...
...
@@ -3,7 +3,7 @@ import {
BasicLayoutProps
as
ProLayoutProps
,
getMenuData
}
from
'@ant-design/pro-layout'
;
import
{
useIntl
}
from
'umi'
;
import
{
useIntl
,
history
}
from
'umi'
;
import
TopBar
from
'../components/TopBar'
import
{
inject
,
observer
}
from
'mobx-react'
import
ShopHeader
from
'../components/ShopHeader'
...
...
@@ -21,12 +21,22 @@ interface LXMallLayoutPropsType {
SiteStore
?:
any
;
}
interface
queryType
{
shopId
:
number
;
memberId
:
number
;
}
const
LXShopLayout
:
React
.
FC
<
LXMallLayoutPropsType
>
=
(
props
)
=>
{
const
{
children
,
location
}
=
props
const
[
templateName
]
=
useState
<
string
>
(
'theme-shop-science'
)
const
{
shopId
}
=
location
.
query
const
[
query
,
setQuery
]
=
useState
<
any
>
({})
useEffect
(()
=>
{
console
.
log
(
'当前使用店铺模板'
)
let
queryParam
=
shopId
?
atob
(
shopId
)
:
undefined
queryParam
=
queryParam
?
JSON
.
parse
(
queryParam
)
:
{}
setQuery
(
queryParam
)
let
body
=
document
.
getElementsByTagName
(
'body'
)[
0
];
body
.
className
=
templateName
;
},
[])
...
...
@@ -40,12 +50,14 @@ const LXShopLayout: React.FC<LXMallLayoutPropsType> = (props) => {
<
TopBar
/>
<
div
className=
{
styles
.
content
}
>
<
ShopHeader
/>
<
MainNav
menuData=
{
menuData
}
pathname=
{
location
.
pathname
}
type=
"shop"
/>
<
MainNav
menuData=
{
menuData
}
pathname=
{
location
.
pathname
}
type=
"shop"
shopId=
{
shopId
}
/>
{
children
&&
React
.
Children
.
map
(
children
,
(
child
:
any
)
=>
{
return
React
.
cloneElement
(
child
,
{
layoutType
:
'shop'
layoutType
:
'shop'
,
shopId
:
query
.
shopId
,
memberId
:
query
.
memberId
},
);
})
...
...
src/pages/lxMall/shop/index.tsx
View file @
3fcdf329
...
...
@@ -2,20 +2,25 @@ import React, { useEffect, useMemo, useState } from 'react'
import
Information
from
'../components/Information'
import
FloorAnchor
from
'../components/FloorAnchor'
import
CommonTitle
from
'../components/CommonTitle'
import
FloorSkeleton
from
'../components/FloorSkeleton'
import
{
Advert
,
ShopFloorLine
}
from
'lingxi-design-ui'
import
AboutUs
from
'../components/AboutUs'
import
{
inject
,
observer
}
from
'mobx-react'
import
{
PublicApi
}
from
'@/services/api'
import
Loading
from
'../components/Loading
'
import
{
LAYOUT_TYPE
}
from
'@/constants
'
import
{
GetTemplatePlatformFindAllFirstCategoryResponse
}
from
'@/services'
import
styles
from
'./index.less'
interface
ChannelIndexPropsType
{
SiteStore
?:
any
;
location
:
any
memberId
:
number
;
shopId
:
number
;
}
const
ShopIndex
:
React
.
FC
<
ChannelIndexPropsType
>
=
(
props
)
=>
{
const
{
shopTemplateId
}
=
props
.
SiteStore
const
{
shopId
,
memberId
}
=
props
const
[
categoryList
,
setCategoryList
]
=
useState
<
GetTemplatePlatformFindAllFirstCategoryResponse
>
([])
const
[
firstAdvertList
,
setFirstAdvertList
]
=
useState
([])
const
[
secondAdvertList
,
setSecondAdvertList
]
=
useState
([])
...
...
@@ -30,7 +35,8 @@ const ShopIndex: React.FC<ChannelIndexPropsType> = (props) => {
const
findFirstAdvertsByType
=
()
=>
{
let
params
=
{
templateId
:
shopTemplateId
,
type
:
1
type
:
1
,
memberId
}
//@ts-ignore
PublicApi
.
getTemplateShopFindAdvertsByType
(
params
).
then
(
res
=>
{
...
...
@@ -43,7 +49,8 @@ const ShopIndex: React.FC<ChannelIndexPropsType> = (props) => {
const
findSecondAdvertsByType
=
()
=>
{
let
params
=
{
templateId
:
shopTemplateId
,
type
:
2
type
:
2
,
memberId
}
//@ts-ignore
PublicApi
.
getTemplateShopFindAdvertsByType
(
params
).
then
(
res
=>
{
...
...
@@ -58,7 +65,7 @@ const ShopIndex: React.FC<ChannelIndexPropsType> = (props) => {
*/
const
fetchFirstCategory
=
()
=>
{
return
new
Promise
((
resolve
)
=>
{
PublicApi
.
getTemplateShopFindAllFirstCategory
().
then
(
res
=>
{
PublicApi
.
getTemplateShopFindAllFirstCategory
(
{
memberId
}
).
then
(
res
=>
{
if
(
res
.
code
===
1000
)
{
setCategoryList
(
res
.
data
)
resolve
(
res
.
data
)
...
...
@@ -68,13 +75,14 @@ const ShopIndex: React.FC<ChannelIndexPropsType> = (props) => {
}
/**
* 获取一级品类详细信息
*/
* 获取一级品类详细信息
*/
const
fetchCategoryById
=
(
categoryId
)
=>
{
return
new
Promise
((
resolve
)
=>
{
let
param
=
{
templateId
:
shopTemplateId
,
categoryId
categoryId
,
memberId
}
// @ts-ignore
...
...
@@ -109,17 +117,17 @@ const ShopIndex: React.FC<ChannelIndexPropsType> = (props) => {
<
div
className=
{
styles
.
shop_index
}
>
<
div
className=
{
styles
.
banner
}
>
{
useMemo
(()
=>
<
Advert
type=
"banner"
advertList=
{
firstAdvertList
}
hasQuickNav=
{
false
}
/>,
[
firstAdvertList
])
useMemo
(()
=>
<
Advert
type=
"banner"
visible=
{
firstAdvertList
.
length
>
0
}
advertList=
{
firstAdvertList
}
hasQuickNav=
{
false
}
/>,
[
firstAdvertList
])
}
</
div
>
<
FloorAnchor
anchorList=
{
categoryList
}
type=
"shop"
/>
<
CommonTitle
title=
"关于我们"
type=
"primary"
/>
<
AboutUs
/>
<
CommonTitle
title=
"热销商品"
type=
"primary"
/>
{
categoryComponents
?
categoryComponents
:
<
Loading
/>
categoryComponents
?
categoryComponents
:
<
FloorSkeleton
type=
{
LAYOUT_TYPE
.
shop
}
/>
}
<
Advert
type=
"service"
advertList=
{
secondAdvertList
}
/>
<
CommonTitle
title=
"关于我们"
type=
"primary"
/>
<
AboutUs
/>
<
Advert
visible=
{
secondAdvertList
.
length
>
0
}
type=
"service"
advertList=
{
secondAdvertList
}
/>
<
Information
/>
</
div
>
)
...
...
src/pages/shop/components/citySelect/index.tsx
View file @
3fcdf329
...
...
@@ -37,7 +37,6 @@ const CityCascader: React.FC<CitySelectPropsType> = (props) => {
fetchAreaList
()
},
[])
const
getProviceById
=
(
id
:
number
)
=>
{
let
result
:
number
=
0
provinceData
&&
provinceData
.
map
(
item
=>
{
...
...
@@ -89,6 +88,7 @@ const CityCascader: React.FC<CitySelectPropsType> = (props) => {
}
setProvinceData
(
tempProvinceData
)
setCityData
(
tempCityData
)
}
...
...
@@ -154,7 +154,7 @@ const CityCascader: React.FC<CitySelectPropsType> = (props) => {
onChange=
{
(
value
)
=>
onSecondCityChange
(
value
,
item
.
provinceCode
,
item
.
index
)
}
placeholder=
"请选择"
>
{
(
item
.
provinceCode
&&
!
isEmpty
(
cityData
))
?
cityData
[
item
.
provinceCode
].
map
((
item
:
any
)
=>
(
{
(
item
.
provinceCode
&&
!
isEmpty
(
cityData
))
?
cityData
[
item
.
provinceCode
]
&&
cityData
[
item
.
provinceCode
]
.
map
((
item
:
any
)
=>
(
<
Option
value=
{
item
.
value
}
key=
{
item
.
value
}
>
{
item
.
lable
}
</
Option
>
))
:
null
}
</
Select
>
...
...
src/utils/request.ts
View file @
3fcdf329
...
...
@@ -109,6 +109,7 @@ class ApiRequest {
if
(
res
.
code
===
1101
)
{
removeAuth
()
history
.
replace
(
'/user/login'
)
message
.
destroy
()
message
.
error
(
res
.
message
)
return
false
}
...
...
@@ -119,6 +120,7 @@ class ApiRequest {
}
else
{
// 使用resolve将数据返回, 请求时需手动处理data为null的情况
resolve
(
res
)
message
.
destroy
()
message
.
error
(
res
.
message
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment