From e2c4c99ff1a9a3de82e3e9c39866f99105dbb3e5 Mon Sep 17 00:00:00 2001 From: Haiyi <1021441632@qq.com> Date: Tue, 6 Dec 2022 14:37:59 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(ID1000738):=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E6=8B=86=E5=88=86=EF=BC=9A=E5=86=85=E9=83=A8=E5=95=86=E5=9F=8E?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=8C=E7=BA=A7=E9=9D=A2=E6=96=99=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E3=80=81=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc | 4 +- src/api/index.ts | 10 ++ src/components/sideBar/index.module.scss | 28 +++- src/components/sideBar/index.tsx | 47 ++++-- .../components/productClass/index.module.scss | 143 ++++++++++++++++++ .../index/components/productClass/index.tsx | 126 +++++++++++++++ src/pages/index/index.tsx | 14 ++ 7 files changed, 358 insertions(+), 14 deletions(-) create mode 100644 src/pages/index/components/productClass/index.module.scss create mode 100644 src/pages/index/components/productClass/index.tsx diff --git a/.eslintrc b/.eslintrc index ef3a582..77b65f8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,6 +8,8 @@ "no-prototype-builtins": "off", "import/first": "off", "react/no-children-prop": "off", - "import/no-commonjs": "off" + "import/no-commonjs": "off", + "no-use-before-define": "off", + "@typescript-eslint/no-use-before-define": ["error"] } } diff --git a/src/api/index.ts b/src/api/index.ts index 4991e71..267b142 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -74,3 +74,13 @@ export const ProductListApi = () => { method: 'get', }) } + +/** + * 获取面料种类子分类 + */ +export const GetClassList = () => { + return useRequest({ + url: '/v2/mp/product/kind/sub/list', + method: 'get', + }) +} diff --git a/src/components/sideBar/index.module.scss b/src/components/sideBar/index.module.scss index 6e71db2..dbd6d7f 100644 --- a/src/components/sideBar/index.module.scss +++ b/src/components/sideBar/index.module.scss @@ -70,10 +70,34 @@ .sideBar_con { flex: 1; + min-width: 0; + position: relative; + padding-top: 90px; + .product_class { + width: 100%; + position: absolute; + top: 0; + z-index: 999; + } .sideBar_con_scroll { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } } +.nosideBar_con{ + flex: 1; + min-width: 0; + position: relative; + .product_class { + width: 100%; + position: absolute; + top: 0; + z-index: 999; + } + .sideBar_con_scroll { + width: 100%; + height: 100%; + } +} } \ No newline at end of file diff --git a/src/components/sideBar/index.tsx b/src/components/sideBar/index.tsx index a17cb66..6c9adac 100644 --- a/src/components/sideBar/index.tsx +++ b/src/components/sideBar/index.tsx @@ -7,6 +7,8 @@ import type { StatusParam } from '../infiniteScroll' import InfiniteScroll from '../infiniteScroll' import LoadingCard from '../loadingCard' import styles from './index.module.scss' +import ProductClass from '@/pages/index/components/productClass' +import { GetClassList } from '@/api/index' interface Params { list?: any[] @@ -20,6 +22,7 @@ interface Params { selfOnScrolltolower?: () => void hasMore?: true | false statusMore?: StatusParam + selectClass?: (val: number) => void } const SideBar = ({ list = [], @@ -33,6 +36,7 @@ const SideBar = ({ selfOnScrolltolower, hasMore = true, statusMore = 0, + selectClass, }: Params) => { const num_half = useRef(0) @@ -76,21 +80,37 @@ const SideBar = ({ }) }, []) + // 二级面料系列分类 + const [openClass, setOpenClass] = useState(false) + const [classList, setClassList] = useState([]) + const [classId, setClassId] = useState(-1) + const { fetchData } = GetClassList() + const getClassData = async(id) => { + const res = await fetchData({ id }) + if (res.success) { + if (res.data?.list.length > 0) { + res.data.list = [{ id: -1, name: '全部' }, ...res.data.list] + } + setClassList(() => res.data?.list) + console.log('res.data?.list=>', res.data?.list) + } + } + useEffect(() => { + if (selected) { getClassData(selected) } + }, [selected]) + + const getSelectClass = (id) => { + selectClass?.(id) + setClassId(() => id) + } + const clickEvent = ({ item, index }: { item; index: number }) => { setSelected(item.id) sideBarOnClick?.(item) computeSelectTab(index) + setClassId(-1) + selectClass?.(-1) } - - const [currentIndex, setcurrentIndex] = useState(0) - useMemo(() => { - Taro.nextTick(() => { - let index = 0 - index = list.findIndex((item) => { return item.id == selected }) - setcurrentIndex(currentIndex) - }) - }, [selected]) - return ( <> @@ -116,7 +136,12 @@ const SideBar = ({ }) } - + 0 ? styles.sideBar_con : styles.nosideBar_con)}> + {classList.length > 0 && ( + + setOpenClass(val)} onSelect={getSelectClass} defaultSelectId={classId} /> + + )} selfOnScrolltolower?.()} refresherTriggered={refresherTriggered} refresherEnabled selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}> {children} diff --git a/src/pages/index/components/productClass/index.module.scss b/src/pages/index/components/productClass/index.module.scss new file mode 100644 index 0000000..ba556c7 --- /dev/null +++ b/src/pages/index/components/productClass/index.module.scss @@ -0,0 +1,143 @@ +.class_main { + position: relative; + height: 100%; +} +.product_class_main_line { + width: 100%; + height: 80px; + position: absolute; + top: 0; + left: 0; + // display: flex; + // align-items: center; + margin-bottom: 20px; + background-color: #fff; + .product_class_scroll { + box-sizing: border-box; + padding: 6px 90px 0 20px; + .product_class_list { + white-space: nowrap; + display: flex; + box-sizing: border-box; + .product_class_item { + height: 56px; + line-height: 56px; + padding: 0 15px; + background: #f5f5f5; + border-radius: 29px; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; + color: rgba(0, 0, 0, 0.8); + box-sizing: border-box; + max-width: 260px; + // @include common_ellipsis; + margin: 0 8px 16px 8px; + } + .product_class_item_selected { + border: 1px solid #3c78f4; + color: #3c78f4; + background: #ecf2ff; + box-sizing: border-box; + } + } + } + .product_class_more { + position: absolute; + right: 0; + top: 0; + width: 88px; + height: 100%; + background-color: #fff; + box-shadow: -7px 0px 7px -5px rgba(0, 0, 0, 0.16); + line-height: 100%; + display: flex; + align-items: center; + .zhankai{ + margin-left: 15px; + } + .product_class_more_icon { + margin-left: 20px; + display: inline-block; + transform: rotate(90deg); + font-size: 30px; + color: rgba(0, 0, 0, 0.5); + } + } +} + +.product_class_main_block { + width: 100%; + height: 100%; + box-sizing: border-box; + position: absolute; + top: 0; + left: 0; + .product_class_block_con { + max-height: 500px; + background-color: #fff; + z-index: 999; + position: relative; + } + .product_class_scroll { + box-sizing: border-box; + max-height: 500px; + padding: 0 20px; + padding: 6px 20px 0 20px; + .product_class_list { + // display: flex; + // flex-wrap: wrap; + box-sizing: border-box; + display: grid; + grid-template-columns: auto auto auto; + .product_class_item { + width: 169px; + height: 56px; + line-height: 56px; + text-align: center; + padding: 0 15px; + background: #f5f5f5; + border-radius: 29px; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; + color: rgba(0, 0, 0, 0.8); + margin: 0 8px 16px 8px; + box-sizing: border-box; + max-width: 260px; + @include common_ellipsis(1); + } + .product_class_item_selected { + border: 1px solid #3c78f4; + color: #3c78f4; + background: #ecf2ff; + box-sizing: border-box; + } + } + } + .product_class_close { + font-size: 24px; + color: rgba(0, 0, 0, 0.6); + // text-align: center; + padding-bottom: 20px; + display: flex; + justify-content: center; + // .product_class_close_icon { + // display: inline-block; + // transform: rotate(-90deg); + // font-size: 27px; + // color: rgba(0, 0, 0, 0.5); + // padding: 0 10px; + // } + } + .product_class_block_mask { + position: absolute; + top: 0; + height: 100%; + width: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 100; + } +} diff --git a/src/pages/index/components/productClass/index.tsx b/src/pages/index/components/productClass/index.tsx new file mode 100644 index 0000000..049d459 --- /dev/null +++ b/src/pages/index/components/productClass/index.tsx @@ -0,0 +1,126 @@ +import { ScrollView, View } from '@tarojs/components' +import classnames from 'classnames' +import { memo, useCallback, useEffect, useState } from 'react' +import styles from './index.module.scss' +import IconFont from '@/components/iconfont/iconfont' + +interface Param { + open: boolean + onOpenClick?: (val: boolean) => void + onSelect?: (id: number) => void + list?: { name: string; id: number }[] + defaultSelectId: number +} + +type ParamProduct = Omit + +const ProductClassLine = memo((option: ParamProduct) => { + const { onOpenClick, defaultSelectId = 0, onSelect, list = [] } = option + const [selectInfo, setSelectInfo] = useState({ + selected: 0, // 当前选中的id + tabId: 0, // 需要滚动到的id + }) + + console.log('刷新了') + + useEffect(() => { + let data: { item: any; index: number } = { item: null, index: 0 } + list?.filter((item, index) => { + if (item.id == defaultSelectId) { + data = { item, index } + } + }) + if (data.item) { + const num = data.index > 0 ? data.index - 1 : 0 + console.log('获取数据::', list[num].id) + setSelectInfo(e => ({ ...e, tabId: list[num].id, selected: data.item.id })) + } + }, [defaultSelectId, list]) + + const clickEvent = ({ item, index }: { item: any; index: number }) => { + const num = index > 0 ? index - 1 : 0 + setSelectInfo(e => ({ ...e, tabId: list[num].id, selected: item.id })) + onSelect?.(item.id) + } + + return ( + + + + {list?.map((item, index) => ( + clickEvent({ item, index })} + key={item.id} + > + {item.name} + + ))} + + + onOpenClick?.(true)}> + + + + ) +}) + +ProductClassLine.displayName = 'ProductClassLine' + +const ProductClassBlock = (option: ParamProduct & { open: boolean }) => { + const { onOpenClick, defaultSelectId = 0, onSelect, list = [], open } = option + const [selectInfo, setSelectInfo] = useState(0) + + useEffect(() => { + setSelectInfo(defaultSelectId) + }, [defaultSelectId]) + + const clickEvent = (item) => { + setSelectInfo(item.id) + onSelect?.(item.id) + } + return ( + <> + + + + + {list?.map(item => ( + clickEvent(item)} + key={item.id} + > + {item.name} + + ))} + + + onOpenClick?.(false)}> + 点击收起 + + + onOpenClick?.(false)}> + + + ) +} + +const PrcductSub = (option: Param) => { + const { open = false, onOpenClick, onSelect, list, defaultSelectId } = option + const getSelect = useCallback((id) => { + onSelect?.(id) + }, []) + const openClick = useCallback((val) => { + onOpenClick?.(val) + }, []) + return ( + <> + + + + + + ) +} diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index b88d332..6083a5d 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -13,6 +13,7 @@ import { ClientListApi, MpProductColorList, MpShoppingCartProductColorList } fro import { dataLoadingStatus, getFilterData } from '@/common/util' const Index = () => { + const product_kind_id_ref = useRef(0) // 获取客户 const [clienList, setclienList] = useState([]) const { fetchData: listFetchData } = ClientListApi() @@ -43,6 +44,7 @@ const Index = () => { if (res.data?.list) { setKindData({ ...kindData, list: res.data.list, defaultId: res.data.list[0].id }) setFiltrate({ ...filtrate, product_kind_id: res.data.list[0].id }) + product_kind_id_ref.current = res.data.list[0].id } } @@ -67,6 +69,7 @@ const Index = () => { pageNum.current.page = 1 setProductData({ list: [], total: 0 }) setFiltrate(list => ({ ...list, size: 5, product_kind_id: e.id })) + product_kind_id_ref.current = e.id }, []) // 上拉加载数据 @@ -326,6 +329,16 @@ const Index = () => { } }) + // 获取二级分类 + const product_kind_id_next_ref = useRef(0) + const getSelectClassId = useCallback((id) => { + pageNum.current.page = 1 + setProductData({ list: [], total: 0 }) + const kind_id = id == -1 ? product_kind_id_ref.current : id + product_kind_id_next_ref.current = id + setFiltrate(list => ({ ...list, size: 5, product_kind_id: kind_id })) + }, []) + return ( // setShowShopCart(showShopCart)}> @@ -347,6 +360,7 @@ const Index = () => { selfOnScrolltolower={getScrolltolower} sideBarOnClick={getProductKindId} heightItem={150} + selectClass={getSelectClassId} refresherTriggered={refresherTriggeredStatus} selfOnRefresherRefresh={() => getRefresherRefresh()} >