Commit 3fcdf329 authored by GuanHua's avatar GuanHua

feat:店铺商城页面和分类商品加载的骨架屏组件

parent 11004e1e
......@@ -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',
......
......@@ -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',
......
......@@ -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': '登录',
......
......@@ -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])
......
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}>
{
......
......@@ -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 {
......
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 />
......
......@@ -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 => {
......
......@@ -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} />
))
......
.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
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
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>
))
}
......
......@@ -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 />
......
......@@ -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
},
);
})
......
......@@ -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 >
)
......
......@@ -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>
......
......@@ -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)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment